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_dcn201.c (10363B)


      1/*
      2 * Copyright 2018 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 "dm_services.h"
     27
     28#include "include/logger_interface.h"
     29
     30#include "../dce110/irq_service_dce110.h"
     31
     32#include "dcn/dcn_2_0_3_offset.h"
     33#include "dcn/dcn_2_0_3_sh_mask.h"
     34
     35#include "cyan_skillfish_ip_offset.h"
     36#include "soc15_hw_ip.h"
     37
     38#include "irq_service_dcn201.h"
     39
     40#include "ivsrcid/dcn/irqsrcs_dcn_1_0.h"
     41
     42static enum dc_irq_source to_dal_irq_source_dcn201(struct irq_service *irq_service,
     43						   uint32_t src_id,
     44						   uint32_t ext_id)
     45{
     46	switch (src_id) {
     47	case DCN_1_0__SRCID__DC_D1_OTG_VSTARTUP:
     48		return DC_IRQ_SOURCE_VBLANK1;
     49	case DCN_1_0__SRCID__DC_D2_OTG_VSTARTUP:
     50		return DC_IRQ_SOURCE_VBLANK2;
     51	case DCN_1_0__SRCID__OTG1_VERTICAL_INTERRUPT0_CONTROL:
     52		return DC_IRQ_SOURCE_DC1_VLINE0;
     53	case DCN_1_0__SRCID__OTG2_VERTICAL_INTERRUPT0_CONTROL:
     54		return DC_IRQ_SOURCE_DC2_VLINE0;
     55	case DCN_1_0__SRCID__HUBP0_FLIP_INTERRUPT:
     56		return DC_IRQ_SOURCE_PFLIP1;
     57	case DCN_1_0__SRCID__HUBP1_FLIP_INTERRUPT:
     58		return DC_IRQ_SOURCE_PFLIP2;
     59	case DCN_1_0__SRCID__OTG0_IHC_V_UPDATE_NO_LOCK_INTERRUPT:
     60		return DC_IRQ_SOURCE_VUPDATE1;
     61	case DCN_1_0__SRCID__OTG1_IHC_V_UPDATE_NO_LOCK_INTERRUPT:
     62		return DC_IRQ_SOURCE_VUPDATE2;
     63	case DCN_1_0__SRCID__DC_HPD1_INT:
     64		/* generic src_id for all HPD and HPDRX interrupts */
     65		switch (ext_id) {
     66		case DCN_1_0__CTXID__DC_HPD1_INT:
     67			return DC_IRQ_SOURCE_HPD1;
     68		case DCN_1_0__CTXID__DC_HPD2_INT:
     69			return DC_IRQ_SOURCE_HPD2;
     70		case DCN_1_0__CTXID__DC_HPD1_RX_INT:
     71			return DC_IRQ_SOURCE_HPD1RX;
     72		case DCN_1_0__CTXID__DC_HPD2_RX_INT:
     73			return DC_IRQ_SOURCE_HPD2RX;
     74		default:
     75			return DC_IRQ_SOURCE_INVALID;
     76		}
     77		break;
     78
     79	default:
     80		return DC_IRQ_SOURCE_INVALID;
     81	}
     82	return DC_IRQ_SOURCE_INVALID;
     83}
     84
     85static bool hpd_ack(
     86	struct irq_service *irq_service,
     87	const struct irq_source_info *info)
     88{
     89	uint32_t addr = info->status_reg;
     90	uint32_t value = dm_read_reg(irq_service->ctx, addr);
     91	uint32_t current_status =
     92		get_reg_field_value(
     93			value,
     94			HPD0_DC_HPD_INT_STATUS,
     95			DC_HPD_SENSE_DELAYED);
     96
     97	dal_irq_service_ack_generic(irq_service, info);
     98
     99	value = dm_read_reg(irq_service->ctx, info->enable_reg);
    100
    101	set_reg_field_value(
    102		value,
    103		current_status ? 0 : 1,
    104		HPD0_DC_HPD_INT_CONTROL,
    105		DC_HPD_INT_POLARITY);
    106
    107	dm_write_reg(irq_service->ctx, info->enable_reg, value);
    108
    109	return true;
    110}
    111
    112static const struct irq_source_info_funcs hpd_irq_info_funcs = {
    113	.set = NULL,
    114	.ack = hpd_ack
    115};
    116
    117static const struct irq_source_info_funcs hpd_rx_irq_info_funcs = {
    118	.set = NULL,
    119	.ack = NULL
    120};
    121
    122static const struct irq_source_info_funcs pflip_irq_info_funcs = {
    123	.set = NULL,
    124	.ack = NULL
    125};
    126
    127static const struct irq_source_info_funcs vblank_irq_info_funcs = {
    128	.set = NULL,
    129	.ack = NULL
    130};
    131
    132static const struct irq_source_info_funcs vline0_irq_info_funcs = {
    133	.set = NULL,
    134	.ack = NULL
    135};
    136static const struct irq_source_info_funcs vupdate_no_lock_irq_info_funcs = {
    137	.set = NULL,
    138	.ack = NULL
    139};
    140
    141#undef BASE_INNER
    142#define BASE_INNER(seg) DMU_BASE__INST0_SEG ## seg
    143
    144#define BASE(seg) BASE_INNER(seg)
    145
    146/* compile time expand base address. */
    147#define BASE(seg) \
    148	BASE_INNER(seg)
    149
    150#define SRI(reg_name, block, id)\
    151	BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
    152					mm ## block ## id ## _ ## reg_name
    153
    154#define IRQ_REG_ENTRY(block, reg_num, reg1, mask1, reg2, mask2)\
    155	.enable_reg = SRI(reg1, block, reg_num),\
    156	.enable_mask = \
    157		block ## reg_num ## _ ## reg1 ## __ ## mask1 ## _MASK,\
    158	.enable_value = {\
    159		block ## reg_num ## _ ## reg1 ## __ ## mask1 ## _MASK,\
    160		~block ## reg_num ## _ ## reg1 ## __ ## mask1 ## _MASK \
    161	},\
    162	.ack_reg = SRI(reg2, block, reg_num),\
    163	.ack_mask = \
    164		block ## reg_num ## _ ## reg2 ## __ ## mask2 ## _MASK,\
    165	.ack_value = \
    166		block ## reg_num ## _ ## reg2 ## __ ## mask2 ## _MASK \
    167
    168#define hpd_int_entry(reg_num)\
    169	[DC_IRQ_SOURCE_HPD1 + reg_num] = {\
    170		IRQ_REG_ENTRY(HPD, reg_num,\
    171			DC_HPD_INT_CONTROL, DC_HPD_INT_EN,\
    172			DC_HPD_INT_CONTROL, DC_HPD_INT_ACK),\
    173		.status_reg = SRI(DC_HPD_INT_STATUS, HPD, reg_num),\
    174		.funcs = &hpd_irq_info_funcs\
    175	}
    176
    177#define hpd_rx_int_entry(reg_num)\
    178	[DC_IRQ_SOURCE_HPD1RX + reg_num] = {\
    179		IRQ_REG_ENTRY(HPD, reg_num,\
    180			DC_HPD_INT_CONTROL, DC_HPD_RX_INT_EN,\
    181			DC_HPD_INT_CONTROL, DC_HPD_RX_INT_ACK),\
    182		.status_reg = SRI(DC_HPD_INT_STATUS, HPD, reg_num),\
    183		.funcs = &hpd_rx_irq_info_funcs\
    184	}
    185#define pflip_int_entry(reg_num)\
    186	[DC_IRQ_SOURCE_PFLIP1 + reg_num] = {\
    187		IRQ_REG_ENTRY(HUBPREQ, reg_num,\
    188			DCSURF_SURFACE_FLIP_INTERRUPT, SURFACE_FLIP_INT_MASK,\
    189			DCSURF_SURFACE_FLIP_INTERRUPT, SURFACE_FLIP_CLEAR),\
    190		.funcs = &pflip_irq_info_funcs\
    191	}
    192
    193#define vupdate_int_entry(reg_num)\
    194	[DC_IRQ_SOURCE_VUPDATE1 + reg_num] = {\
    195		IRQ_REG_ENTRY(OTG, reg_num,\
    196			OTG_GLOBAL_SYNC_STATUS, VUPDATE_INT_EN,\
    197			OTG_GLOBAL_SYNC_STATUS, VUPDATE_EVENT_CLEAR),\
    198		.funcs = &vblank_irq_info_funcs\
    199	}
    200
    201/* vupdate_no_lock_int_entry maps to DC_IRQ_SOURCE_VUPDATEx, to match semantic
    202 * of DCE's DC_IRQ_SOURCE_VUPDATEx.
    203 */
    204#define vupdate_no_lock_int_entry(reg_num)\
    205	[DC_IRQ_SOURCE_VUPDATE1 + reg_num] = {\
    206		IRQ_REG_ENTRY(OTG, reg_num,\
    207			OTG_GLOBAL_SYNC_STATUS, VUPDATE_NO_LOCK_INT_EN,\
    208			OTG_GLOBAL_SYNC_STATUS, VUPDATE_NO_LOCK_EVENT_CLEAR),\
    209		.funcs = &vupdate_no_lock_irq_info_funcs\
    210	}
    211#define vblank_int_entry(reg_num)\
    212	[DC_IRQ_SOURCE_VBLANK1 + reg_num] = {\
    213		IRQ_REG_ENTRY(OTG, reg_num,\
    214			OTG_GLOBAL_SYNC_STATUS, VSTARTUP_INT_EN,\
    215			OTG_GLOBAL_SYNC_STATUS, VSTARTUP_EVENT_CLEAR),\
    216		.funcs = &vblank_irq_info_funcs\
    217	}
    218
    219#define vline0_int_entry(reg_num)\
    220	[DC_IRQ_SOURCE_DC1_VLINE0 + reg_num] = {\
    221		IRQ_REG_ENTRY(OTG, reg_num,\
    222			OTG_VERTICAL_INTERRUPT0_CONTROL, OTG_VERTICAL_INTERRUPT0_INT_ENABLE,\
    223			OTG_VERTICAL_INTERRUPT0_CONTROL, OTG_VERTICAL_INTERRUPT0_CLEAR),\
    224		.funcs = &vline0_irq_info_funcs\
    225	}
    226
    227#define dummy_irq_entry() \
    228	{\
    229		.funcs = &dummy_irq_info_funcs\
    230	}
    231
    232#define i2c_int_entry(reg_num) \
    233	[DC_IRQ_SOURCE_I2C_DDC ## reg_num] = dummy_irq_entry()
    234
    235#define dp_sink_int_entry(reg_num) \
    236	[DC_IRQ_SOURCE_DPSINK ## reg_num] = dummy_irq_entry()
    237
    238#define gpio_pad_int_entry(reg_num) \
    239	[DC_IRQ_SOURCE_GPIOPAD ## reg_num] = dummy_irq_entry()
    240
    241#define dc_underflow_int_entry(reg_num) \
    242	[DC_IRQ_SOURCE_DC ## reg_num ## UNDERFLOW] = dummy_irq_entry()
    243
    244static const struct irq_source_info_funcs dummy_irq_info_funcs = {
    245	.set = dal_irq_service_dummy_set,
    246	.ack = dal_irq_service_dummy_ack
    247};
    248
    249static const struct irq_source_info
    250irq_source_info_dcn201[DAL_IRQ_SOURCES_NUMBER] = {
    251	[DC_IRQ_SOURCE_INVALID] = dummy_irq_entry(),
    252	hpd_int_entry(0),
    253	hpd_int_entry(1),
    254	dummy_irq_entry(),
    255	dummy_irq_entry(),
    256	dummy_irq_entry(),
    257	dummy_irq_entry(),
    258	hpd_rx_int_entry(0),
    259	hpd_rx_int_entry(1),
    260	dummy_irq_entry(),
    261	dummy_irq_entry(),
    262	dummy_irq_entry(),
    263	dummy_irq_entry(),
    264	i2c_int_entry(1),
    265	i2c_int_entry(2),
    266	dummy_irq_entry(),
    267	dummy_irq_entry(),
    268	dummy_irq_entry(),
    269	dummy_irq_entry(),
    270	dp_sink_int_entry(1),
    271	dp_sink_int_entry(2),
    272	dummy_irq_entry(),
    273	dummy_irq_entry(),
    274	dummy_irq_entry(),
    275	dummy_irq_entry(),
    276	[DC_IRQ_SOURCE_TIMER] = dummy_irq_entry(),
    277	pflip_int_entry(0),
    278	pflip_int_entry(1),
    279	pflip_int_entry(2),
    280	pflip_int_entry(3),
    281	[DC_IRQ_SOURCE_PFLIP5] = dummy_irq_entry(),
    282	[DC_IRQ_SOURCE_PFLIP6] = dummy_irq_entry(),
    283	[DC_IRQ_SOURCE_PFLIP_UNDERLAY0] = dummy_irq_entry(),
    284	gpio_pad_int_entry(0),
    285	gpio_pad_int_entry(1),
    286	gpio_pad_int_entry(2),
    287	gpio_pad_int_entry(3),
    288	gpio_pad_int_entry(4),
    289	gpio_pad_int_entry(5),
    290	gpio_pad_int_entry(6),
    291	gpio_pad_int_entry(7),
    292	gpio_pad_int_entry(8),
    293	gpio_pad_int_entry(9),
    294	gpio_pad_int_entry(10),
    295	gpio_pad_int_entry(11),
    296	gpio_pad_int_entry(12),
    297	gpio_pad_int_entry(13),
    298	gpio_pad_int_entry(14),
    299	gpio_pad_int_entry(15),
    300	gpio_pad_int_entry(16),
    301	gpio_pad_int_entry(17),
    302	gpio_pad_int_entry(18),
    303	gpio_pad_int_entry(19),
    304	gpio_pad_int_entry(20),
    305	gpio_pad_int_entry(21),
    306	gpio_pad_int_entry(22),
    307	gpio_pad_int_entry(23),
    308	gpio_pad_int_entry(24),
    309	gpio_pad_int_entry(25),
    310	gpio_pad_int_entry(26),
    311	gpio_pad_int_entry(27),
    312	gpio_pad_int_entry(28),
    313	gpio_pad_int_entry(29),
    314	gpio_pad_int_entry(30),
    315	dc_underflow_int_entry(1),
    316	dc_underflow_int_entry(2),
    317	dummy_irq_entry(),
    318	dummy_irq_entry(),
    319	dummy_irq_entry(),
    320	dummy_irq_entry(),
    321	[DC_IRQ_SOURCE_DMCU_SCP] = dummy_irq_entry(),
    322	[DC_IRQ_SOURCE_VBIOS_SW] = dummy_irq_entry(),
    323	vupdate_no_lock_int_entry(0),
    324	vupdate_no_lock_int_entry(1),
    325	dummy_irq_entry(),
    326	dummy_irq_entry(),
    327	dummy_irq_entry(),
    328	dummy_irq_entry(),
    329	vblank_int_entry(0),
    330	vblank_int_entry(1),
    331	dummy_irq_entry(),
    332	dummy_irq_entry(),
    333	dummy_irq_entry(),
    334	dummy_irq_entry(),
    335	vline0_int_entry(0),
    336	vline0_int_entry(1),
    337	dummy_irq_entry(),
    338	dummy_irq_entry(),
    339	dummy_irq_entry(),
    340	dummy_irq_entry(),
    341};
    342
    343static const struct irq_service_funcs irq_service_funcs_dcn201 = {
    344		.to_dal_irq_source = to_dal_irq_source_dcn201
    345};
    346
    347static void dcn201_irq_construct(
    348	struct irq_service *irq_service,
    349	struct irq_service_init_data *init_data)
    350{
    351	dal_irq_service_construct(irq_service, init_data);
    352
    353	irq_service->info = irq_source_info_dcn201;
    354	irq_service->funcs = &irq_service_funcs_dcn201;
    355}
    356
    357struct irq_service *dal_irq_service_dcn201_create(
    358	struct irq_service_init_data *init_data)
    359{
    360	struct irq_service *irq_service = kzalloc(sizeof(*irq_service),
    361						  GFP_KERNEL);
    362
    363	if (!irq_service)
    364		return NULL;
    365
    366	dcn201_irq_construct(irq_service, init_data);
    367	return irq_service;
    368}