[Why]
amdgpu_dm.c requires changes for SI chipsets init and irq handlers registration

[How]
SI support: load_dmcu_fw(), amdgpu_dm_initialize_drm_device(), dm_early_init()
Add DCE6 specific dce60_register_irq_handlers() function

(v1) NOTE: As per Kaveri and older amdgpu.dc=1 kernel cmdline is required

(v2) fix for bc011f9 ("drm/amdgpu: Change SI/CI gfx/sdma/smu init sequence")
     remove CHIP_HAINAN support since it does not have physical DCE6 module

(v3) fix vblank irq support for DCE6 using ad hoc dce60_register_irq_handlers()
     replicating for vblank irq the behavior of dce110_register_irq_handlers()
     as per commit b57de80 ("drm/amd/display: Register on VLBLANK ISR.")

(v4) updated due to following kernel 5.2 commit:
     b2fddb13 ("drm/amd/display: Drop underlay plane support")

Signed-off-by: Mauro Rossi <issor.or...@gmail.com>
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 114 ++++++++++++++++++
 1 file changed, 114 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 0bc333798cd6..df46cf7cb374 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -1064,6 +1064,12 @@ static int load_dmcu_fw(struct amdgpu_device *adev)
        const struct dmcu_firmware_header_v1_0 *hdr;
 
        switch(adev->asic_type) {
+#if defined(CONFIG_DRM_AMD_DC_SI)
+       case CHIP_TAHITI:
+       case CHIP_PITCAIRN:
+       case CHIP_VERDE:
+       case CHIP_OLAND:
+#endif
        case CHIP_BONAIRE:
        case CHIP_HAWAII:
        case CHIP_KAVERI:
@@ -2472,6 +2478,89 @@ static void register_hpd_handlers(struct amdgpu_device 
*adev)
        }
 }
 
+#if defined(CONFIG_DRM_AMD_DC_SI)
+/* Register IRQ sources and initialize IRQ callbacks */
+static int dce60_register_irq_handlers(struct amdgpu_device *adev)
+{
+       struct dc *dc = adev->dm.dc;
+       struct common_irq_params *c_irq_params;
+       struct dc_interrupt_params int_params = {0};
+       int r;
+       int i;
+       unsigned client_id = AMDGPU_IRQ_CLIENTID_LEGACY;
+
+       int_params.requested_polarity = INTERRUPT_POLARITY_DEFAULT;
+       int_params.current_polarity = INTERRUPT_POLARITY_DEFAULT;
+
+       /*
+        * Actions of amdgpu_irq_add_id():
+        * 1. Register a set() function with base driver.
+        *    Base driver will call set() function to enable/disable an
+        *    interrupt in DC hardware.
+        * 2. Register amdgpu_dm_irq_handler().
+        *    Base driver will call amdgpu_dm_irq_handler() for ALL interrupts
+        *    coming from DC hardware.
+        *    amdgpu_dm_irq_handler() will re-direct the interrupt to DC
+        *    for acknowledging and handling. */
+
+       /* Use VBLANK interrupt */
+       for (i = 0; i < adev->mode_info.num_crtc; i++) {
+               r = amdgpu_irq_add_id(adev, client_id, i+1 , &adev->crtc_irq);
+               if (r) {
+                       DRM_ERROR("Failed to add crtc irq id!\n");
+                       return r;
+               }
+
+               int_params.int_context = INTERRUPT_HIGH_IRQ_CONTEXT;
+               int_params.irq_source =
+                       dc_interrupt_to_irq_source(dc, i+1 , 0);
+
+               c_irq_params = &adev->dm.vblank_params[int_params.irq_source - 
DC_IRQ_SOURCE_VBLANK1];
+
+               c_irq_params->adev = adev;
+               c_irq_params->irq_src = int_params.irq_source;
+
+               amdgpu_dm_irq_register_interrupt(adev, &int_params,
+                               dm_crtc_high_irq, c_irq_params);
+       }
+
+       /* Use GRPH_PFLIP interrupt */
+       for (i = VISLANDS30_IV_SRCID_D1_GRPH_PFLIP;
+                       i <= VISLANDS30_IV_SRCID_D6_GRPH_PFLIP; i += 2) {
+               r = amdgpu_irq_add_id(adev, client_id, i, &adev->pageflip_irq);
+               if (r) {
+                       DRM_ERROR("Failed to add page flip irq id!\n");
+                       return r;
+               }
+
+               int_params.int_context = INTERRUPT_HIGH_IRQ_CONTEXT;
+               int_params.irq_source =
+                       dc_interrupt_to_irq_source(dc, i, 0);
+
+               c_irq_params = &adev->dm.pflip_params[int_params.irq_source - 
DC_IRQ_SOURCE_PFLIP_FIRST];
+
+               c_irq_params->adev = adev;
+               c_irq_params->irq_src = int_params.irq_source;
+
+               amdgpu_dm_irq_register_interrupt(adev, &int_params,
+                               dm_pflip_high_irq, c_irq_params);
+
+       }
+
+       /* HPD */
+       r = amdgpu_irq_add_id(adev, client_id,
+                       VISLANDS30_IV_SRCID_HOTPLUG_DETECT_A, &adev->hpd_irq);
+       if (r) {
+               DRM_ERROR("Failed to add hpd irq id!\n");
+               return r;
+       }
+
+       register_hpd_handlers(adev);
+
+       return 0;
+}
+#endif
+
 /* Register IRQ sources and initialize IRQ callbacks */
 static int dce110_register_irq_handlers(struct amdgpu_device *adev)
 {
@@ -3203,6 +3292,17 @@ static int amdgpu_dm_initialize_drm_device(struct 
amdgpu_device *adev)
 
        /* Software is initialized. Now we can register interrupt handlers. */
        switch (adev->asic_type) {
+#if defined(CONFIG_DRM_AMD_DC_SI)
+       case CHIP_TAHITI:
+       case CHIP_PITCAIRN:
+       case CHIP_VERDE:
+       case CHIP_OLAND:
+               if (dce60_register_irq_handlers(dm->adev)) {
+                       DRM_ERROR("DM: Failed to initialize IRQ\n");
+                       goto fail;
+               }
+               break;
+#endif
        case CHIP_BONAIRE:
        case CHIP_HAWAII:
        case CHIP_KAVERI:
@@ -3400,6 +3500,20 @@ static int dm_early_init(void *handle)
        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 
        switch (adev->asic_type) {
+#if defined(CONFIG_DRM_AMD_DC_SI)
+       case CHIP_TAHITI:
+       case CHIP_PITCAIRN:
+       case CHIP_VERDE:
+               adev->mode_info.num_crtc = 6;
+               adev->mode_info.num_hpd = 6;
+               adev->mode_info.num_dig = 6;
+               break;
+       case CHIP_OLAND:
+               adev->mode_info.num_crtc = 2;
+               adev->mode_info.num_hpd = 2;
+               adev->mode_info.num_dig = 2;
+               break;
+#endif
        case CHIP_BONAIRE:
        case CHIP_HAWAII:
                adev->mode_info.num_crtc = 6;
-- 
2.25.1

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Reply via email to