0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026 #include <linux/slab.h>
0027
0028 #include "dm_services.h"
0029
0030 #include "include/logger_interface.h"
0031
0032 #include "irq_service_dce60.h"
0033 #include "../dce110/irq_service_dce110.h"
0034
0035 #include "dce/dce_6_0_d.h"
0036 #include "dce/dce_6_0_sh_mask.h"
0037
0038 #include "ivsrcid/ivsrcid_vislands30.h"
0039
0040 #define VISLANDS30_IV_SRCID_D1_VBLANK 1
0041 #define VISLANDS30_IV_SRCID_D2_VBLANK 2
0042 #define VISLANDS30_IV_SRCID_D3_VBLANK 3
0043 #define VISLANDS30_IV_SRCID_D4_VBLANK 4
0044 #define VISLANDS30_IV_SRCID_D5_VBLANK 5
0045 #define VISLANDS30_IV_SRCID_D6_VBLANK 6
0046
0047 #include "dc_types.h"
0048
0049 static bool hpd_ack(
0050 struct irq_service *irq_service,
0051 const struct irq_source_info *info)
0052 {
0053 uint32_t addr = info->status_reg;
0054 uint32_t value = dm_read_reg(irq_service->ctx, addr);
0055 uint32_t current_status =
0056 get_reg_field_value(
0057 value,
0058 DC_HPD1_INT_STATUS,
0059 DC_HPD1_SENSE_DELAYED);
0060
0061 dal_irq_service_ack_generic(irq_service, info);
0062
0063 value = dm_read_reg(irq_service->ctx, info->enable_reg);
0064
0065 set_reg_field_value(
0066 value,
0067 current_status ? 0 : 1,
0068 DC_HPD1_INT_CONTROL,
0069 DC_HPD1_INT_POLARITY);
0070
0071 dm_write_reg(irq_service->ctx, info->enable_reg, value);
0072
0073 return true;
0074 }
0075
0076 static const struct irq_source_info_funcs hpd_irq_info_funcs = {
0077 .set = NULL,
0078 .ack = hpd_ack
0079 };
0080
0081 static const struct irq_source_info_funcs hpd_rx_irq_info_funcs = {
0082 .set = NULL,
0083 .ack = NULL
0084 };
0085
0086 static const struct irq_source_info_funcs pflip_irq_info_funcs = {
0087 .set = NULL,
0088 .ack = NULL
0089 };
0090
0091 static const struct irq_source_info_funcs vblank_irq_info_funcs = {
0092 .set = dce110_vblank_set,
0093 .ack = NULL
0094 };
0095
0096 static const struct irq_source_info_funcs vblank_irq_info_funcs_dce60 = {
0097 .set = NULL,
0098 .ack = NULL
0099 };
0100
0101 #define hpd_int_entry(reg_num)\
0102 [DC_IRQ_SOURCE_INVALID + reg_num] = {\
0103 .enable_reg = mmDC_HPD ## reg_num ## _INT_CONTROL,\
0104 .enable_mask = DC_HPD1_INT_CONTROL__DC_HPD1_INT_EN_MASK,\
0105 .enable_value = {\
0106 DC_HPD1_INT_CONTROL__DC_HPD1_INT_EN_MASK,\
0107 ~DC_HPD1_INT_CONTROL__DC_HPD1_INT_EN_MASK\
0108 },\
0109 .ack_reg = mmDC_HPD ## reg_num ## _INT_CONTROL,\
0110 .ack_mask = DC_HPD1_INT_CONTROL__DC_HPD1_INT_ACK_MASK,\
0111 .ack_value = DC_HPD1_INT_CONTROL__DC_HPD1_INT_ACK_MASK,\
0112 .status_reg = mmDC_HPD ## reg_num ## _INT_STATUS,\
0113 .funcs = &hpd_irq_info_funcs\
0114 }
0115
0116 #define hpd_rx_int_entry(reg_num)\
0117 [DC_IRQ_SOURCE_HPD6 + reg_num] = {\
0118 .enable_reg = mmDC_HPD ## reg_num ## _INT_CONTROL,\
0119 .enable_mask = DC_HPD1_INT_CONTROL__DC_HPD1_RX_INT_EN_MASK,\
0120 .enable_value = {\
0121 DC_HPD1_INT_CONTROL__DC_HPD1_RX_INT_EN_MASK,\
0122 ~DC_HPD1_INT_CONTROL__DC_HPD1_RX_INT_EN_MASK },\
0123 .ack_reg = mmDC_HPD ## reg_num ## _INT_CONTROL,\
0124 .ack_mask = DC_HPD1_INT_CONTROL__DC_HPD1_RX_INT_ACK_MASK,\
0125 .ack_value = DC_HPD1_INT_CONTROL__DC_HPD1_RX_INT_ACK_MASK,\
0126 .status_reg = mmDC_HPD ## reg_num ## _INT_STATUS,\
0127 .funcs = &hpd_rx_irq_info_funcs\
0128 }
0129
0130 #define pflip_int_entry(reg_num)\
0131 [DC_IRQ_SOURCE_PFLIP1 + reg_num] = {\
0132 .enable_reg = mmDCP ## reg_num ## _GRPH_INTERRUPT_CONTROL,\
0133 .enable_mask =\
0134 GRPH_INTERRUPT_CONTROL__GRPH_PFLIP_INT_MASK_MASK,\
0135 .enable_value = {\
0136 GRPH_INTERRUPT_CONTROL__GRPH_PFLIP_INT_MASK_MASK,\
0137 ~GRPH_INTERRUPT_CONTROL__GRPH_PFLIP_INT_MASK_MASK},\
0138 .ack_reg = mmDCP ## reg_num ## _GRPH_INTERRUPT_STATUS,\
0139 .ack_mask = GRPH_INTERRUPT_STATUS__GRPH_PFLIP_INT_CLEAR_MASK,\
0140 .ack_value = GRPH_INTERRUPT_STATUS__GRPH_PFLIP_INT_CLEAR_MASK,\
0141 .status_reg = mmDCP ## reg_num ##_GRPH_INTERRUPT_STATUS,\
0142 .funcs = &pflip_irq_info_funcs\
0143 }
0144
0145 #define vupdate_int_entry(reg_num)\
0146 [DC_IRQ_SOURCE_VUPDATE1 + reg_num] = {\
0147 .enable_reg = mmCRTC ## reg_num ## _CRTC_INTERRUPT_CONTROL,\
0148 .enable_mask =\
0149 CRTC_INTERRUPT_CONTROL__CRTC_V_UPDATE_INT_MSK_MASK,\
0150 .enable_value = {\
0151 CRTC_INTERRUPT_CONTROL__CRTC_V_UPDATE_INT_MSK_MASK,\
0152 ~CRTC_INTERRUPT_CONTROL__CRTC_V_UPDATE_INT_MSK_MASK},\
0153 .ack_reg = mmCRTC ## reg_num ## _CRTC_V_UPDATE_INT_STATUS,\
0154 .ack_mask =\
0155 CRTC_V_UPDATE_INT_STATUS__CRTC_V_UPDATE_INT_CLEAR_MASK,\
0156 .ack_value =\
0157 CRTC_V_UPDATE_INT_STATUS__CRTC_V_UPDATE_INT_CLEAR_MASK,\
0158 .funcs = &vblank_irq_info_funcs\
0159 }
0160
0161 #define vblank_int_entry(reg_num)\
0162 [DC_IRQ_SOURCE_VBLANK1 + reg_num] = {\
0163 .enable_reg = mmLB ## reg_num ## _INT_MASK,\
0164 .enable_mask =\
0165 INT_MASK__VBLANK_INT_MASK,\
0166 .enable_value = {\
0167 INT_MASK__VBLANK_INT_MASK,\
0168 ~INT_MASK__VBLANK_INT_MASK},\
0169 .ack_reg = mmLB ## reg_num ## _VBLANK_STATUS,\
0170 .ack_mask =\
0171 VBLANK_STATUS__VBLANK_ACK_MASK,\
0172 .ack_value =\
0173 VBLANK_STATUS__VBLANK_ACK_MASK,\
0174 .funcs = &vblank_irq_info_funcs_dce60\
0175 }
0176
0177 #define dummy_irq_entry() \
0178 {\
0179 .funcs = &dummy_irq_info_funcs\
0180 }
0181
0182 #define i2c_int_entry(reg_num) \
0183 [DC_IRQ_SOURCE_I2C_DDC ## reg_num] = dummy_irq_entry()
0184
0185 #define dp_sink_int_entry(reg_num) \
0186 [DC_IRQ_SOURCE_DPSINK ## reg_num] = dummy_irq_entry()
0187
0188 #define gpio_pad_int_entry(reg_num) \
0189 [DC_IRQ_SOURCE_GPIOPAD ## reg_num] = dummy_irq_entry()
0190
0191 #define dc_underflow_int_entry(reg_num) \
0192 [DC_IRQ_SOURCE_DC ## reg_num ## UNDERFLOW] = dummy_irq_entry()
0193
0194
0195 static const struct irq_source_info_funcs dummy_irq_info_funcs = {
0196 .set = dal_irq_service_dummy_set,
0197 .ack = dal_irq_service_dummy_ack
0198 };
0199
0200 static const struct irq_source_info
0201 irq_source_info_dce60[DAL_IRQ_SOURCES_NUMBER] = {
0202 [DC_IRQ_SOURCE_INVALID] = dummy_irq_entry(),
0203 hpd_int_entry(1),
0204 hpd_int_entry(2),
0205 hpd_int_entry(3),
0206 hpd_int_entry(4),
0207 hpd_int_entry(5),
0208 hpd_int_entry(6),
0209 hpd_rx_int_entry(1),
0210 hpd_rx_int_entry(2),
0211 hpd_rx_int_entry(3),
0212 hpd_rx_int_entry(4),
0213 hpd_rx_int_entry(5),
0214 hpd_rx_int_entry(6),
0215 i2c_int_entry(1),
0216 i2c_int_entry(2),
0217 i2c_int_entry(3),
0218 i2c_int_entry(4),
0219 i2c_int_entry(5),
0220 i2c_int_entry(6),
0221 dp_sink_int_entry(1),
0222 dp_sink_int_entry(2),
0223 dp_sink_int_entry(3),
0224 dp_sink_int_entry(4),
0225 dp_sink_int_entry(5),
0226 dp_sink_int_entry(6),
0227 [DC_IRQ_SOURCE_TIMER] = dummy_irq_entry(),
0228 pflip_int_entry(0),
0229 pflip_int_entry(1),
0230 pflip_int_entry(2),
0231 pflip_int_entry(3),
0232 pflip_int_entry(4),
0233 pflip_int_entry(5),
0234 [DC_IRQ_SOURCE_PFLIP_UNDERLAY0] = dummy_irq_entry(),
0235 gpio_pad_int_entry(0),
0236 gpio_pad_int_entry(1),
0237 gpio_pad_int_entry(2),
0238 gpio_pad_int_entry(3),
0239 gpio_pad_int_entry(4),
0240 gpio_pad_int_entry(5),
0241 gpio_pad_int_entry(6),
0242 gpio_pad_int_entry(7),
0243 gpio_pad_int_entry(8),
0244 gpio_pad_int_entry(9),
0245 gpio_pad_int_entry(10),
0246 gpio_pad_int_entry(11),
0247 gpio_pad_int_entry(12),
0248 gpio_pad_int_entry(13),
0249 gpio_pad_int_entry(14),
0250 gpio_pad_int_entry(15),
0251 gpio_pad_int_entry(16),
0252 gpio_pad_int_entry(17),
0253 gpio_pad_int_entry(18),
0254 gpio_pad_int_entry(19),
0255 gpio_pad_int_entry(20),
0256 gpio_pad_int_entry(21),
0257 gpio_pad_int_entry(22),
0258 gpio_pad_int_entry(23),
0259 gpio_pad_int_entry(24),
0260 gpio_pad_int_entry(25),
0261 gpio_pad_int_entry(26),
0262 gpio_pad_int_entry(27),
0263 gpio_pad_int_entry(28),
0264 gpio_pad_int_entry(29),
0265 gpio_pad_int_entry(30),
0266 dc_underflow_int_entry(1),
0267 dc_underflow_int_entry(2),
0268 dc_underflow_int_entry(3),
0269 dc_underflow_int_entry(4),
0270 dc_underflow_int_entry(5),
0271 dc_underflow_int_entry(6),
0272 [DC_IRQ_SOURCE_DMCU_SCP] = dummy_irq_entry(),
0273 [DC_IRQ_SOURCE_VBIOS_SW] = dummy_irq_entry(),
0274 vupdate_int_entry(0),
0275 vupdate_int_entry(1),
0276 vupdate_int_entry(2),
0277 vupdate_int_entry(3),
0278 vupdate_int_entry(4),
0279 vupdate_int_entry(5),
0280 vblank_int_entry(0),
0281 vblank_int_entry(1),
0282 vblank_int_entry(2),
0283 vblank_int_entry(3),
0284 vblank_int_entry(4),
0285 vblank_int_entry(5),
0286 };
0287
0288 enum dc_irq_source to_dal_irq_source_dce60(
0289 struct irq_service *irq_service,
0290 uint32_t src_id,
0291 uint32_t ext_id)
0292 {
0293 switch (src_id) {
0294 case VISLANDS30_IV_SRCID_D1_VBLANK:
0295 return DC_IRQ_SOURCE_VBLANK1;
0296 case VISLANDS30_IV_SRCID_D2_VBLANK:
0297 return DC_IRQ_SOURCE_VBLANK2;
0298 case VISLANDS30_IV_SRCID_D3_VBLANK:
0299 return DC_IRQ_SOURCE_VBLANK3;
0300 case VISLANDS30_IV_SRCID_D4_VBLANK:
0301 return DC_IRQ_SOURCE_VBLANK4;
0302 case VISLANDS30_IV_SRCID_D5_VBLANK:
0303 return DC_IRQ_SOURCE_VBLANK5;
0304 case VISLANDS30_IV_SRCID_D6_VBLANK:
0305 return DC_IRQ_SOURCE_VBLANK6;
0306 case VISLANDS30_IV_SRCID_D1_V_UPDATE_INT:
0307 return DC_IRQ_SOURCE_VUPDATE1;
0308 case VISLANDS30_IV_SRCID_D2_V_UPDATE_INT:
0309 return DC_IRQ_SOURCE_VUPDATE2;
0310 case VISLANDS30_IV_SRCID_D3_V_UPDATE_INT:
0311 return DC_IRQ_SOURCE_VUPDATE3;
0312 case VISLANDS30_IV_SRCID_D4_V_UPDATE_INT:
0313 return DC_IRQ_SOURCE_VUPDATE4;
0314 case VISLANDS30_IV_SRCID_D5_V_UPDATE_INT:
0315 return DC_IRQ_SOURCE_VUPDATE5;
0316 case VISLANDS30_IV_SRCID_D6_V_UPDATE_INT:
0317 return DC_IRQ_SOURCE_VUPDATE6;
0318 case VISLANDS30_IV_SRCID_D1_GRPH_PFLIP:
0319 return DC_IRQ_SOURCE_PFLIP1;
0320 case VISLANDS30_IV_SRCID_D2_GRPH_PFLIP:
0321 return DC_IRQ_SOURCE_PFLIP2;
0322 case VISLANDS30_IV_SRCID_D3_GRPH_PFLIP:
0323 return DC_IRQ_SOURCE_PFLIP3;
0324 case VISLANDS30_IV_SRCID_D4_GRPH_PFLIP:
0325 return DC_IRQ_SOURCE_PFLIP4;
0326 case VISLANDS30_IV_SRCID_D5_GRPH_PFLIP:
0327 return DC_IRQ_SOURCE_PFLIP5;
0328 case VISLANDS30_IV_SRCID_D6_GRPH_PFLIP:
0329 return DC_IRQ_SOURCE_PFLIP6;
0330
0331 case VISLANDS30_IV_SRCID_HOTPLUG_DETECT_A:
0332
0333 switch (ext_id) {
0334 case VISLANDS30_IV_EXTID_HOTPLUG_DETECT_A:
0335 return DC_IRQ_SOURCE_HPD1;
0336 case VISLANDS30_IV_EXTID_HOTPLUG_DETECT_B:
0337 return DC_IRQ_SOURCE_HPD2;
0338 case VISLANDS30_IV_EXTID_HOTPLUG_DETECT_C:
0339 return DC_IRQ_SOURCE_HPD3;
0340 case VISLANDS30_IV_EXTID_HOTPLUG_DETECT_D:
0341 return DC_IRQ_SOURCE_HPD4;
0342 case VISLANDS30_IV_EXTID_HOTPLUG_DETECT_E:
0343 return DC_IRQ_SOURCE_HPD5;
0344 case VISLANDS30_IV_EXTID_HOTPLUG_DETECT_F:
0345 return DC_IRQ_SOURCE_HPD6;
0346 case VISLANDS30_IV_EXTID_HPD_RX_A:
0347 return DC_IRQ_SOURCE_HPD1RX;
0348 case VISLANDS30_IV_EXTID_HPD_RX_B:
0349 return DC_IRQ_SOURCE_HPD2RX;
0350 case VISLANDS30_IV_EXTID_HPD_RX_C:
0351 return DC_IRQ_SOURCE_HPD3RX;
0352 case VISLANDS30_IV_EXTID_HPD_RX_D:
0353 return DC_IRQ_SOURCE_HPD4RX;
0354 case VISLANDS30_IV_EXTID_HPD_RX_E:
0355 return DC_IRQ_SOURCE_HPD5RX;
0356 case VISLANDS30_IV_EXTID_HPD_RX_F:
0357 return DC_IRQ_SOURCE_HPD6RX;
0358 default:
0359 return DC_IRQ_SOURCE_INVALID;
0360 }
0361 break;
0362
0363 default:
0364 return DC_IRQ_SOURCE_INVALID;
0365 }
0366 }
0367
0368 static const struct irq_service_funcs irq_service_funcs_dce60 = {
0369 .to_dal_irq_source = to_dal_irq_source_dce60
0370 };
0371
0372 static void dce60_irq_construct(
0373 struct irq_service *irq_service,
0374 struct irq_service_init_data *init_data)
0375 {
0376 dal_irq_service_construct(irq_service, init_data);
0377
0378 irq_service->info = irq_source_info_dce60;
0379 irq_service->funcs = &irq_service_funcs_dce60;
0380 }
0381
0382 struct irq_service *dal_irq_service_dce60_create(
0383 struct irq_service_init_data *init_data)
0384 {
0385 struct irq_service *irq_service = kzalloc(sizeof(*irq_service),
0386 GFP_KERNEL);
0387
0388 if (!irq_service)
0389 return NULL;
0390
0391 dce60_irq_construct(irq_service, init_data);
0392 return irq_service;
0393 }
0394
0395