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_dce120.c (8222B)


      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_dce120.h"
     33#include "../dce110/irq_service_dce110.h"
     34
     35#include "dce/dce_12_0_offset.h"
     36#include "dce/dce_12_0_sh_mask.h"
     37#include "soc15_hw_ip.h"
     38#include "vega10_ip_offset.h"
     39
     40#include "ivsrcid/ivsrcid_vislands30.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			HPD0_DC_HPD_INT_STATUS,
     52			DC_HPD_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		HPD0_DC_HPD_INT_CONTROL,
     62		DC_HPD_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 BASE_INNER(seg) \
     95	DCE_BASE__INST0_SEG ## seg
     96
     97#define BASE(seg) \
     98	BASE_INNER(seg)
     99
    100#define SRI(reg_name, block, id)\
    101	BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
    102			mm ## block ## id ## _ ## reg_name
    103
    104
    105#define IRQ_REG_ENTRY(block, reg_num, reg1, mask1, reg2, mask2)\
    106	.enable_reg = SRI(reg1, block, reg_num),\
    107	.enable_mask = \
    108		block ## reg_num ## _ ## reg1 ## __ ## mask1 ## _MASK,\
    109	.enable_value = {\
    110		block ## reg_num ## _ ## reg1 ## __ ## mask1 ## _MASK,\
    111		~block ## reg_num ## _ ## reg1 ## __ ## mask1 ## _MASK \
    112	},\
    113	.ack_reg = SRI(reg2, block, reg_num),\
    114	.ack_mask = \
    115		block ## reg_num ## _ ## reg2 ## __ ## mask2 ## _MASK,\
    116	.ack_value = \
    117		block ## reg_num ## _ ## reg2 ## __ ## mask2 ## _MASK \
    118
    119#define hpd_int_entry(reg_num)\
    120	[DC_IRQ_SOURCE_HPD1 + reg_num] = {\
    121		IRQ_REG_ENTRY(HPD, reg_num,\
    122			DC_HPD_INT_CONTROL, DC_HPD_INT_EN,\
    123			DC_HPD_INT_CONTROL, DC_HPD_INT_ACK),\
    124		.status_reg = SRI(DC_HPD_INT_STATUS, HPD, reg_num),\
    125		.funcs = &hpd_irq_info_funcs\
    126	}
    127
    128#define hpd_rx_int_entry(reg_num)\
    129	[DC_IRQ_SOURCE_HPD1RX + reg_num] = {\
    130		IRQ_REG_ENTRY(HPD, reg_num,\
    131			DC_HPD_INT_CONTROL, DC_HPD_RX_INT_EN,\
    132			DC_HPD_INT_CONTROL, DC_HPD_RX_INT_ACK),\
    133		.status_reg = SRI(DC_HPD_INT_STATUS, HPD, reg_num),\
    134		.funcs = &hpd_rx_irq_info_funcs\
    135	}
    136#define pflip_int_entry(reg_num)\
    137	[DC_IRQ_SOURCE_PFLIP1 + reg_num] = {\
    138		IRQ_REG_ENTRY(DCP, reg_num, \
    139			GRPH_INTERRUPT_CONTROL, GRPH_PFLIP_INT_MASK, \
    140			GRPH_INTERRUPT_STATUS, GRPH_PFLIP_INT_CLEAR),\
    141		.status_reg = SRI(GRPH_INTERRUPT_STATUS, DCP, reg_num),\
    142		.funcs = &pflip_irq_info_funcs\
    143	}
    144
    145#define vupdate_int_entry(reg_num)\
    146	[DC_IRQ_SOURCE_VUPDATE1 + reg_num] = {\
    147		IRQ_REG_ENTRY(CRTC, reg_num,\
    148			CRTC_INTERRUPT_CONTROL, CRTC_V_UPDATE_INT_MSK,\
    149			CRTC_V_UPDATE_INT_STATUS, CRTC_V_UPDATE_INT_CLEAR),\
    150		.funcs = &vupdate_irq_info_funcs\
    151	}
    152
    153#define vblank_int_entry(reg_num)\
    154	[DC_IRQ_SOURCE_VBLANK1 + reg_num] = {\
    155		IRQ_REG_ENTRY(CRTC, reg_num,\
    156				CRTC_VERTICAL_INTERRUPT0_CONTROL, CRTC_VERTICAL_INTERRUPT0_INT_ENABLE,\
    157				CRTC_VERTICAL_INTERRUPT0_CONTROL, CRTC_VERTICAL_INTERRUPT0_CLEAR),\
    158		.funcs = &vblank_irq_info_funcs,\
    159		.src_id = VISLANDS30_IV_SRCID_D1_VERTICAL_INTERRUPT0 + reg_num\
    160	}
    161
    162#define dummy_irq_entry() \
    163	{\
    164		.funcs = &dummy_irq_info_funcs\
    165	}
    166
    167#define i2c_int_entry(reg_num) \
    168	[DC_IRQ_SOURCE_I2C_DDC ## reg_num] = dummy_irq_entry()
    169
    170#define dp_sink_int_entry(reg_num) \
    171	[DC_IRQ_SOURCE_DPSINK ## reg_num] = dummy_irq_entry()
    172
    173#define gpio_pad_int_entry(reg_num) \
    174	[DC_IRQ_SOURCE_GPIOPAD ## reg_num] = dummy_irq_entry()
    175
    176#define dc_underflow_int_entry(reg_num) \
    177	[DC_IRQ_SOURCE_DC ## reg_num ## UNDERFLOW] = dummy_irq_entry()
    178
    179static const struct irq_source_info_funcs dummy_irq_info_funcs = {
    180	.set = dal_irq_service_dummy_set,
    181	.ack = dal_irq_service_dummy_ack
    182};
    183
    184static const struct irq_source_info
    185irq_source_info_dce120[DAL_IRQ_SOURCES_NUMBER] = {
    186	[DC_IRQ_SOURCE_INVALID] = dummy_irq_entry(),
    187	hpd_int_entry(0),
    188	hpd_int_entry(1),
    189	hpd_int_entry(2),
    190	hpd_int_entry(3),
    191	hpd_int_entry(4),
    192	hpd_int_entry(5),
    193	hpd_rx_int_entry(0),
    194	hpd_rx_int_entry(1),
    195	hpd_rx_int_entry(2),
    196	hpd_rx_int_entry(3),
    197	hpd_rx_int_entry(4),
    198	hpd_rx_int_entry(5),
    199	i2c_int_entry(1),
    200	i2c_int_entry(2),
    201	i2c_int_entry(3),
    202	i2c_int_entry(4),
    203	i2c_int_entry(5),
    204	i2c_int_entry(6),
    205	dp_sink_int_entry(1),
    206	dp_sink_int_entry(2),
    207	dp_sink_int_entry(3),
    208	dp_sink_int_entry(4),
    209	dp_sink_int_entry(5),
    210	dp_sink_int_entry(6),
    211	[DC_IRQ_SOURCE_TIMER] = dummy_irq_entry(),
    212	pflip_int_entry(0),
    213	pflip_int_entry(1),
    214	pflip_int_entry(2),
    215	pflip_int_entry(3),
    216	pflip_int_entry(4),
    217	pflip_int_entry(5),
    218	[DC_IRQ_SOURCE_PFLIP_UNDERLAY0] = dummy_irq_entry(),
    219	gpio_pad_int_entry(0),
    220	gpio_pad_int_entry(1),
    221	gpio_pad_int_entry(2),
    222	gpio_pad_int_entry(3),
    223	gpio_pad_int_entry(4),
    224	gpio_pad_int_entry(5),
    225	gpio_pad_int_entry(6),
    226	gpio_pad_int_entry(7),
    227	gpio_pad_int_entry(8),
    228	gpio_pad_int_entry(9),
    229	gpio_pad_int_entry(10),
    230	gpio_pad_int_entry(11),
    231	gpio_pad_int_entry(12),
    232	gpio_pad_int_entry(13),
    233	gpio_pad_int_entry(14),
    234	gpio_pad_int_entry(15),
    235	gpio_pad_int_entry(16),
    236	gpio_pad_int_entry(17),
    237	gpio_pad_int_entry(18),
    238	gpio_pad_int_entry(19),
    239	gpio_pad_int_entry(20),
    240	gpio_pad_int_entry(21),
    241	gpio_pad_int_entry(22),
    242	gpio_pad_int_entry(23),
    243	gpio_pad_int_entry(24),
    244	gpio_pad_int_entry(25),
    245	gpio_pad_int_entry(26),
    246	gpio_pad_int_entry(27),
    247	gpio_pad_int_entry(28),
    248	gpio_pad_int_entry(29),
    249	gpio_pad_int_entry(30),
    250	dc_underflow_int_entry(1),
    251	dc_underflow_int_entry(2),
    252	dc_underflow_int_entry(3),
    253	dc_underflow_int_entry(4),
    254	dc_underflow_int_entry(5),
    255	dc_underflow_int_entry(6),
    256	[DC_IRQ_SOURCE_DMCU_SCP] = dummy_irq_entry(),
    257	[DC_IRQ_SOURCE_VBIOS_SW] = dummy_irq_entry(),
    258	vupdate_int_entry(0),
    259	vupdate_int_entry(1),
    260	vupdate_int_entry(2),
    261	vupdate_int_entry(3),
    262	vupdate_int_entry(4),
    263	vupdate_int_entry(5),
    264	vblank_int_entry(0),
    265	vblank_int_entry(1),
    266	vblank_int_entry(2),
    267	vblank_int_entry(3),
    268	vblank_int_entry(4),
    269	vblank_int_entry(5),
    270};
    271
    272static const struct irq_service_funcs irq_service_funcs_dce120 = {
    273		.to_dal_irq_source = to_dal_irq_source_dce110
    274};
    275
    276static void dce120_irq_construct(
    277	struct irq_service *irq_service,
    278	struct irq_service_init_data *init_data)
    279{
    280	dal_irq_service_construct(irq_service, init_data);
    281
    282	irq_service->info = irq_source_info_dce120;
    283	irq_service->funcs = &irq_service_funcs_dce120;
    284}
    285
    286struct irq_service *dal_irq_service_dce120_create(
    287	struct irq_service_init_data *init_data)
    288{
    289	struct irq_service *irq_service = kzalloc(sizeof(*irq_service),
    290						  GFP_KERNEL);
    291
    292	if (!irq_service)
    293		return NULL;
    294
    295	dce120_irq_construct(irq_service, init_data);
    296	return irq_service;
    297}