Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Copyright 2020 Mauro Rossi <issor.oruam@gmail.com>
0003  *
0004  * Permission is hereby granted, free of charge, to any person obtaining a
0005  * copy of this software and associated documentation files (the "Software"),
0006  * to deal in the Software without restriction, including without limitation
0007  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
0008  * and/or sell copies of the Software, and to permit persons to whom the
0009  * Software is furnished to do so, subject to the following conditions:
0010  *
0011  * The above copyright notice and this permission notice shall be included in
0012  * all copies or substantial portions of the Software.
0013  *
0014  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
0015  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0016  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
0017  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
0018  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
0019  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
0020  * OTHER DEALINGS IN THE SOFTWARE.
0021  *
0022  * Authors: AMD
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         /* generic src_id for all HPD and HPDRX interrupts */
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