cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

irq_service_dce80.c (9105B)


      1/*
      2 * Copyright 2012-15 Advanced Micro Devices, Inc.
      3 *
      4 * Permission is hereby granted, free of charge, to any person obtaining a
      5 * copy of this software and associated documentation files (the "Software"),
      6 * to deal in the Software without restriction, including without limitation
      7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      8 * and/or sell copies of the Software, and to permit persons to whom the
      9 * Software is furnished to do so, subject to the following conditions:
     10 *
     11 * The above copyright notice and this permission notice shall be included in
     12 * all copies or substantial portions of the Software.
     13 *
     14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
     18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
     19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
     20 * OTHER DEALINGS IN THE SOFTWARE.
     21 *
     22 * Authors: AMD
     23 *
     24 */
     25
     26#include <linux/slab.h>
     27
     28#include "dm_services.h"
     29
     30#include "include/logger_interface.h"
     31
     32#include "irq_service_dce80.h"
     33#include "../dce110/irq_service_dce110.h"
     34
     35#include "dce/dce_8_0_d.h"
     36#include "dce/dce_8_0_sh_mask.h"
     37
     38#include "ivsrcid/ivsrcid_vislands30.h"
     39
     40#include "dc_types.h"
     41
     42static bool hpd_ack(
     43	struct irq_service *irq_service,
     44	const struct irq_source_info *info)
     45{
     46	uint32_t addr = info->status_reg;
     47	uint32_t value = dm_read_reg(irq_service->ctx, addr);
     48	uint32_t current_status =
     49		get_reg_field_value(
     50			value,
     51			DC_HPD1_INT_STATUS,
     52			DC_HPD1_SENSE_DELAYED);
     53
     54	dal_irq_service_ack_generic(irq_service, info);
     55
     56	value = dm_read_reg(irq_service->ctx, info->enable_reg);
     57
     58	set_reg_field_value(
     59		value,
     60		current_status ? 0 : 1,
     61		DC_HPD1_INT_CONTROL,
     62		DC_HPD1_INT_POLARITY);
     63
     64	dm_write_reg(irq_service->ctx, info->enable_reg, value);
     65
     66	return true;
     67}
     68
     69static const struct irq_source_info_funcs hpd_irq_info_funcs = {
     70	.set = NULL,
     71	.ack = hpd_ack
     72};
     73
     74static const struct irq_source_info_funcs hpd_rx_irq_info_funcs = {
     75	.set = NULL,
     76	.ack = NULL
     77};
     78
     79static const struct irq_source_info_funcs pflip_irq_info_funcs = {
     80	.set = NULL,
     81	.ack = NULL
     82};
     83
     84static const struct irq_source_info_funcs vblank_irq_info_funcs = {
     85	.set = dce110_vblank_set,
     86	.ack = NULL
     87};
     88
     89static const struct irq_source_info_funcs vupdate_irq_info_funcs = {
     90	.set = NULL,
     91	.ack = NULL
     92};
     93
     94#define hpd_int_entry(reg_num)\
     95	[DC_IRQ_SOURCE_INVALID + reg_num] = {\
     96		.enable_reg = mmDC_HPD ## reg_num ## _INT_CONTROL,\
     97		.enable_mask = DC_HPD1_INT_CONTROL__DC_HPD1_INT_EN_MASK,\
     98		.enable_value = {\
     99			DC_HPD1_INT_CONTROL__DC_HPD1_INT_EN_MASK,\
    100			~DC_HPD1_INT_CONTROL__DC_HPD1_INT_EN_MASK\
    101		},\
    102		.ack_reg = mmDC_HPD ## reg_num ## _INT_CONTROL,\
    103		.ack_mask = DC_HPD1_INT_CONTROL__DC_HPD1_INT_ACK_MASK,\
    104		.ack_value = DC_HPD1_INT_CONTROL__DC_HPD1_INT_ACK_MASK,\
    105		.status_reg = mmDC_HPD ## reg_num ## _INT_STATUS,\
    106		.funcs = &hpd_irq_info_funcs\
    107	}
    108
    109#define hpd_rx_int_entry(reg_num)\
    110	[DC_IRQ_SOURCE_HPD6 + reg_num] = {\
    111		.enable_reg = mmDC_HPD ## reg_num ## _INT_CONTROL,\
    112		.enable_mask = DC_HPD1_INT_CONTROL__DC_HPD1_RX_INT_EN_MASK,\
    113		.enable_value = {\
    114				DC_HPD1_INT_CONTROL__DC_HPD1_RX_INT_EN_MASK,\
    115			~DC_HPD1_INT_CONTROL__DC_HPD1_RX_INT_EN_MASK },\
    116		.ack_reg = mmDC_HPD ## reg_num ## _INT_CONTROL,\
    117		.ack_mask = DC_HPD1_INT_CONTROL__DC_HPD1_RX_INT_ACK_MASK,\
    118		.ack_value = DC_HPD1_INT_CONTROL__DC_HPD1_RX_INT_ACK_MASK,\
    119		.status_reg = mmDC_HPD ## reg_num ## _INT_STATUS,\
    120		.funcs = &hpd_rx_irq_info_funcs\
    121	}
    122
    123#define pflip_int_entry(reg_num)\
    124	[DC_IRQ_SOURCE_PFLIP1 + reg_num] = {\
    125		.enable_reg = mmDCP ## reg_num ## _GRPH_INTERRUPT_CONTROL,\
    126		.enable_mask =\
    127		GRPH_INTERRUPT_CONTROL__GRPH_PFLIP_INT_MASK_MASK,\
    128		.enable_value = {\
    129			GRPH_INTERRUPT_CONTROL__GRPH_PFLIP_INT_MASK_MASK,\
    130			~GRPH_INTERRUPT_CONTROL__GRPH_PFLIP_INT_MASK_MASK},\
    131		.ack_reg = mmDCP ## reg_num ## _GRPH_INTERRUPT_STATUS,\
    132		.ack_mask = GRPH_INTERRUPT_STATUS__GRPH_PFLIP_INT_CLEAR_MASK,\
    133		.ack_value = GRPH_INTERRUPT_STATUS__GRPH_PFLIP_INT_CLEAR_MASK,\
    134		.status_reg = mmDCP ## reg_num ##_GRPH_INTERRUPT_STATUS,\
    135		.funcs = &pflip_irq_info_funcs\
    136 	}
    137
    138#define vupdate_int_entry(reg_num)\
    139	[DC_IRQ_SOURCE_VUPDATE1 + reg_num] = {\
    140		.enable_reg = mmCRTC ## reg_num ## _CRTC_INTERRUPT_CONTROL,\
    141		.enable_mask =\
    142		CRTC_INTERRUPT_CONTROL__CRTC_V_UPDATE_INT_MSK_MASK,\
    143		.enable_value = {\
    144			CRTC_INTERRUPT_CONTROL__CRTC_V_UPDATE_INT_MSK_MASK,\
    145			~CRTC_INTERRUPT_CONTROL__CRTC_V_UPDATE_INT_MSK_MASK},\
    146		.ack_reg = mmCRTC ## reg_num ## _CRTC_V_UPDATE_INT_STATUS,\
    147		.ack_mask =\
    148		CRTC_V_UPDATE_INT_STATUS__CRTC_V_UPDATE_INT_CLEAR_MASK,\
    149		.ack_value =\
    150		CRTC_V_UPDATE_INT_STATUS__CRTC_V_UPDATE_INT_CLEAR_MASK,\
    151		.funcs = &vupdate_irq_info_funcs\
    152	}
    153
    154#define vblank_int_entry(reg_num)\
    155	[DC_IRQ_SOURCE_VBLANK1 + reg_num] = {\
    156		.enable_reg = mmCRTC ## reg_num ## _CRTC_VERTICAL_INTERRUPT0_CONTROL,\
    157		.enable_mask =\
    158		CRTC_VERTICAL_INTERRUPT0_CONTROL__CRTC_VERTICAL_INTERRUPT0_INT_ENABLE_MASK,\
    159		.enable_value = {\
    160			CRTC_VERTICAL_INTERRUPT0_CONTROL__CRTC_VERTICAL_INTERRUPT0_INT_ENABLE_MASK,\
    161			~CRTC_VERTICAL_INTERRUPT0_CONTROL__CRTC_VERTICAL_INTERRUPT0_INT_ENABLE_MASK},\
    162		.ack_reg = mmCRTC ## reg_num ## _CRTC_VERTICAL_INTERRUPT0_CONTROL,\
    163		.ack_mask =\
    164		CRTC_VERTICAL_INTERRUPT0_CONTROL__CRTC_VERTICAL_INTERRUPT0_CLEAR_MASK,\
    165		.ack_value =\
    166		CRTC_VERTICAL_INTERRUPT0_CONTROL__CRTC_VERTICAL_INTERRUPT0_CLEAR_MASK,\
    167		.funcs = &vblank_irq_info_funcs,\
    168		.src_id = VISLANDS30_IV_SRCID_D1_VERTICAL_INTERRUPT0 + reg_num\
    169	}
    170
    171#define dummy_irq_entry() \
    172	{\
    173		.funcs = &dummy_irq_info_funcs\
    174	}
    175
    176#define i2c_int_entry(reg_num) \
    177	[DC_IRQ_SOURCE_I2C_DDC ## reg_num] = dummy_irq_entry()
    178
    179#define dp_sink_int_entry(reg_num) \
    180	[DC_IRQ_SOURCE_DPSINK ## reg_num] = dummy_irq_entry()
    181
    182#define gpio_pad_int_entry(reg_num) \
    183	[DC_IRQ_SOURCE_GPIOPAD ## reg_num] = dummy_irq_entry()
    184
    185#define dc_underflow_int_entry(reg_num) \
    186	[DC_IRQ_SOURCE_DC ## reg_num ## UNDERFLOW] = dummy_irq_entry()
    187
    188
    189static const struct irq_source_info_funcs dummy_irq_info_funcs = {
    190	.set = dal_irq_service_dummy_set,
    191	.ack = dal_irq_service_dummy_ack
    192};
    193
    194static const struct irq_source_info
    195irq_source_info_dce80[DAL_IRQ_SOURCES_NUMBER] = {
    196	[DC_IRQ_SOURCE_INVALID] = dummy_irq_entry(),
    197	hpd_int_entry(1),
    198	hpd_int_entry(2),
    199	hpd_int_entry(3),
    200	hpd_int_entry(4),
    201	hpd_int_entry(5),
    202	hpd_int_entry(6),
    203	hpd_rx_int_entry(1),
    204	hpd_rx_int_entry(2),
    205	hpd_rx_int_entry(3),
    206	hpd_rx_int_entry(4),
    207	hpd_rx_int_entry(5),
    208	hpd_rx_int_entry(6),
    209	i2c_int_entry(1),
    210	i2c_int_entry(2),
    211	i2c_int_entry(3),
    212	i2c_int_entry(4),
    213	i2c_int_entry(5),
    214	i2c_int_entry(6),
    215	dp_sink_int_entry(1),
    216	dp_sink_int_entry(2),
    217	dp_sink_int_entry(3),
    218	dp_sink_int_entry(4),
    219	dp_sink_int_entry(5),
    220	dp_sink_int_entry(6),
    221	[DC_IRQ_SOURCE_TIMER] = dummy_irq_entry(),
    222	pflip_int_entry(0),
    223	pflip_int_entry(1),
    224	pflip_int_entry(2),
    225	pflip_int_entry(3),
    226	pflip_int_entry(4),
    227	pflip_int_entry(5),
    228	[DC_IRQ_SOURCE_PFLIP_UNDERLAY0] = dummy_irq_entry(),
    229	gpio_pad_int_entry(0),
    230	gpio_pad_int_entry(1),
    231	gpio_pad_int_entry(2),
    232	gpio_pad_int_entry(3),
    233	gpio_pad_int_entry(4),
    234	gpio_pad_int_entry(5),
    235	gpio_pad_int_entry(6),
    236	gpio_pad_int_entry(7),
    237	gpio_pad_int_entry(8),
    238	gpio_pad_int_entry(9),
    239	gpio_pad_int_entry(10),
    240	gpio_pad_int_entry(11),
    241	gpio_pad_int_entry(12),
    242	gpio_pad_int_entry(13),
    243	gpio_pad_int_entry(14),
    244	gpio_pad_int_entry(15),
    245	gpio_pad_int_entry(16),
    246	gpio_pad_int_entry(17),
    247	gpio_pad_int_entry(18),
    248	gpio_pad_int_entry(19),
    249	gpio_pad_int_entry(20),
    250	gpio_pad_int_entry(21),
    251	gpio_pad_int_entry(22),
    252	gpio_pad_int_entry(23),
    253	gpio_pad_int_entry(24),
    254	gpio_pad_int_entry(25),
    255	gpio_pad_int_entry(26),
    256	gpio_pad_int_entry(27),
    257	gpio_pad_int_entry(28),
    258	gpio_pad_int_entry(29),
    259	gpio_pad_int_entry(30),
    260	dc_underflow_int_entry(1),
    261	dc_underflow_int_entry(2),
    262	dc_underflow_int_entry(3),
    263	dc_underflow_int_entry(4),
    264	dc_underflow_int_entry(5),
    265	dc_underflow_int_entry(6),
    266	[DC_IRQ_SOURCE_DMCU_SCP] = dummy_irq_entry(),
    267	[DC_IRQ_SOURCE_VBIOS_SW] = dummy_irq_entry(),
    268	vupdate_int_entry(0),
    269	vupdate_int_entry(1),
    270	vupdate_int_entry(2),
    271	vupdate_int_entry(3),
    272	vupdate_int_entry(4),
    273	vupdate_int_entry(5),
    274	vblank_int_entry(0),
    275	vblank_int_entry(1),
    276	vblank_int_entry(2),
    277	vblank_int_entry(3),
    278	vblank_int_entry(4),
    279	vblank_int_entry(5),
    280};
    281
    282static const struct irq_service_funcs irq_service_funcs_dce80 = {
    283		.to_dal_irq_source = to_dal_irq_source_dce110
    284};
    285
    286static void dce80_irq_construct(
    287	struct irq_service *irq_service,
    288	struct irq_service_init_data *init_data)
    289{
    290	dal_irq_service_construct(irq_service, init_data);
    291
    292	irq_service->info = irq_source_info_dce80;
    293	irq_service->funcs = &irq_service_funcs_dce80;
    294}
    295
    296struct irq_service *dal_irq_service_dce80_create(
    297	struct irq_service_init_data *init_data)
    298{
    299	struct irq_service *irq_service = kzalloc(sizeof(*irq_service),
    300						  GFP_KERNEL);
    301
    302	if (!irq_service)
    303		return NULL;
    304
    305	dce80_irq_construct(irq_service, init_data);
    306	return irq_service;
    307}
    308
    309