drm/i915/cnl: Add AUX-F support
authorRodrigo Vivi <rodrigo.vivi@intel.com>
Mon, 29 Jan 2018 23:22:15 +0000 (15:22 -0800)
committerRodrigo Vivi <rodrigo.vivi@intel.com>
Tue, 30 Jan 2018 18:24:14 +0000 (10:24 -0800)
On some Cannonlake SKUs we have a dedicated Aux for port F,
that is only the full split between port A and port E.

There is still no Aux E for Port E, as in previous platforms,
because port_E still means shared lanes with port A.

v2: Rebase.
v3: Add couple missed PORT_F cases on intel_dp.
v4: Rebase and fix commit message.
v5: Squash Imre's "drm/i915: Add missing AUX_F power well string"
v6: Rebase on top of display headers rework.
v7: s/IS_CANNONLAKE/IS_CNL_WITH_PORT_F (DK)
v8: Fix Aux bits for Port F (DK)
v9: Fix VBT definition of Port F (DK).
v10: Squash power well addition to this patch to avoid
     warns as pointed by DK.
v11: Clean up squashed commit message. (David)
v12: Remove unnecessary handling for older platforms (DK)
     Adding AUX_F to PG2 following other existent ones. (DK)

Cc: David Weinehall <david.weinehall@linux.intel.com>
Cc: Dhinakaran Pandiyan <dhinakaran.pandiyan@intel.com>
Cc: Lucas De Marchi <lucas.demarchi@intel.com>
Cc: Imre Deak <imre.deak@intel.com>
Cc: Manasi Navare <manasi.d.navare@intel.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Reviewed-by: David Weinehall <david.weinehall@linux.intel.com>
Reviewed-by: Dhinakaran Pandiyan <dhinakaran.pandiyan@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20180129232223.766-2-rodrigo.vivi@intel.com
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/i915_irq.c
drivers/gpu/drm/i915/i915_reg.h
drivers/gpu/drm/i915/intel_display.h
drivers/gpu/drm/i915/intel_dp.c
drivers/gpu/drm/i915/intel_runtime_pm.c

index 8b5c1a839655ae5d093e882b43f09f85c6b40f8c..d29f95d8999a5eb47e613142a679a3abcd085aaa 100644 (file)
@@ -1255,6 +1255,7 @@ enum modeset_restore {
 #define DP_AUX_B 0x10
 #define DP_AUX_C 0x20
 #define DP_AUX_D 0x30
+#define DP_AUX_F 0x60
 
 #define DDC_PIN_B  0x05
 #define DDC_PIN_C  0x04
index 85c46a25265d17a8240561d666136cba8c8d54df..79fadb50ab69b13d523ea87400af17ae3b51ee51 100644 (file)
@@ -2585,6 +2585,9 @@ gen8_de_irq_handler(struct drm_i915_private *dev_priv, u32 master_ctl)
                                            GEN9_AUX_CHANNEL_C |
                                            GEN9_AUX_CHANNEL_D;
 
+                       if (IS_CNL_WITH_PORT_F(dev_priv))
+                               tmp_mask |= CNL_AUX_CHANNEL_F;
+
                        if (iir & tmp_mask) {
                                dp_aux_irq_handler(dev_priv);
                                found = true;
@@ -3617,6 +3620,9 @@ static void gen8_de_irq_postinstall(struct drm_i915_private *dev_priv)
                de_pipe_masked |= GEN8_DE_PIPE_IRQ_FAULT_ERRORS;
        }
 
+       if (IS_CNL_WITH_PORT_F(dev_priv))
+               de_port_masked |= CNL_AUX_CHANNEL_F;
+
        de_pipe_enables = de_pipe_masked | GEN8_PIPE_VBLANK |
                                           GEN8_PIPE_FIFO_UNDERRUN;
 
index b06db954c79fc673e9a7b3026df24c8175618b14..98b4d8357a4c001e7ffc3c5a1f2fadf3b46a1d2d 100644 (file)
@@ -1312,6 +1312,7 @@ enum i915_power_well_id {
        CNL_DISP_PW_AUX_B = GLK_DISP_PW_AUX_B,
        CNL_DISP_PW_AUX_C = GLK_DISP_PW_AUX_C,
        CNL_DISP_PW_AUX_D,
+       CNL_DISP_PW_AUX_F,
 
        SKL_DISP_PW_1 = 14,
        SKL_DISP_PW_2,
@@ -5283,6 +5284,13 @@ enum {
 #define _DPD_AUX_CH_DATA4      (dev_priv->info.display_mmio_offset + 0x64320)
 #define _DPD_AUX_CH_DATA5      (dev_priv->info.display_mmio_offset + 0x64324)
 
+#define _DPF_AUX_CH_CTL                (dev_priv->info.display_mmio_offset + 0x64510)
+#define _DPF_AUX_CH_DATA1      (dev_priv->info.display_mmio_offset + 0x64514)
+#define _DPF_AUX_CH_DATA2      (dev_priv->info.display_mmio_offset + 0x64518)
+#define _DPF_AUX_CH_DATA3      (dev_priv->info.display_mmio_offset + 0x6451c)
+#define _DPF_AUX_CH_DATA4      (dev_priv->info.display_mmio_offset + 0x64520)
+#define _DPF_AUX_CH_DATA5      (dev_priv->info.display_mmio_offset + 0x64524)
+
 #define DP_AUX_CH_CTL(port)    _MMIO_PORT(port, _DPA_AUX_CH_CTL, _DPB_AUX_CH_CTL)
 #define DP_AUX_CH_DATA(port, i)        _MMIO(_PORT(port, _DPA_AUX_CH_DATA1, _DPB_AUX_CH_DATA1) + (i) * 4) /* 5 registers */
 
@@ -6938,6 +6946,7 @@ enum {
 #define GEN8_DE_PORT_IMR _MMIO(0x44444)
 #define GEN8_DE_PORT_IIR _MMIO(0x44448)
 #define GEN8_DE_PORT_IER _MMIO(0x4444c)
+#define  CNL_AUX_CHANNEL_F             (1 << 28)
 #define  GEN9_AUX_CHANNEL_D            (1 << 27)
 #define  GEN9_AUX_CHANNEL_C            (1 << 26)
 #define  GEN9_AUX_CHANNEL_B            (1 << 25)
index e47638931b5149ca97a9ee1b2b31c22ff1b2a40a..30fa2041a45ff44c3cf1de8ca616e9b3fdd46a3e 100644 (file)
@@ -172,6 +172,7 @@ enum intel_display_power_domain {
        POWER_DOMAIN_AUX_B,
        POWER_DOMAIN_AUX_C,
        POWER_DOMAIN_AUX_D,
+       POWER_DOMAIN_AUX_F,
        POWER_DOMAIN_GMBUS,
        POWER_DOMAIN_MODESET,
        POWER_DOMAIN_GT_IRQ,
index 48342a85e500dc5a5226719682593c6c9178e2d6..ba0bbce742a5bd3446843d9dfcf069a7d48004d6 100644 (file)
@@ -1299,6 +1299,9 @@ static enum port intel_aux_port(struct drm_i915_private *dev_priv,
        case DP_AUX_D:
                aux_port = PORT_D;
                break;
+       case DP_AUX_F:
+               aux_port = PORT_F;
+               break;
        default:
                MISSING_CASE(info->alternate_aux_channel);
                aux_port = PORT_A;
@@ -5998,6 +6001,9 @@ intel_dp_init_connector_port_info(struct intel_digital_port *intel_dig_port)
                /* FIXME: Check VBT for actual wiring of PORT E */
                intel_dp->aux_power_domain = POWER_DOMAIN_AUX_D;
                break;
+       case PORT_F:
+               intel_dp->aux_power_domain = POWER_DOMAIN_AUX_F;
+               break;
        default:
                MISSING_CASE(encoder->port);
        }
index 5b1aa4b9c72c61ab860fba22554392c69ab33d6e..a274e930f04569f21650cf7ab4d4ea8f23a1dc98 100644 (file)
@@ -124,6 +124,8 @@ intel_display_power_domain_str(enum intel_display_power_domain domain)
                return "AUX_C";
        case POWER_DOMAIN_AUX_D:
                return "AUX_D";
+       case POWER_DOMAIN_AUX_F:
+               return "AUX_F";
        case POWER_DOMAIN_GMBUS:
                return "GMBUS";
        case POWER_DOMAIN_INIT:
@@ -1828,6 +1830,7 @@ void intel_display_power_put(struct drm_i915_private *dev_priv,
        BIT_ULL(POWER_DOMAIN_AUX_B) |                       \
        BIT_ULL(POWER_DOMAIN_AUX_C) |                   \
        BIT_ULL(POWER_DOMAIN_AUX_D) |                   \
+       BIT_ULL(POWER_DOMAIN_AUX_F) |                   \
        BIT_ULL(POWER_DOMAIN_AUDIO) |                   \
        BIT_ULL(POWER_DOMAIN_VGA) |                             \
        BIT_ULL(POWER_DOMAIN_INIT))
@@ -1855,6 +1858,9 @@ void intel_display_power_put(struct drm_i915_private *dev_priv,
 #define CNL_DISPLAY_AUX_D_POWER_DOMAINS (              \
        BIT_ULL(POWER_DOMAIN_AUX_D) |                   \
        BIT_ULL(POWER_DOMAIN_INIT))
+#define CNL_DISPLAY_AUX_F_POWER_DOMAINS (              \
+       BIT_ULL(POWER_DOMAIN_AUX_F) |                   \
+       BIT_ULL(POWER_DOMAIN_INIT))
 #define CNL_DISPLAY_DC_OFF_POWER_DOMAINS (             \
        CNL_DISPLAY_POWERWELL_2_POWER_DOMAINS |         \
        BIT_ULL(POWER_DOMAIN_GT_IRQ) |                  \
@@ -2405,6 +2411,12 @@ static struct i915_power_well cnl_power_wells[] = {
                .ops = &hsw_power_well_ops,
                .id = SKL_DISP_PW_DDI_D,
        },
+       {
+               .name = "AUX F",
+               .domains = CNL_DISPLAY_AUX_F_POWER_DOMAINS,
+               .ops = &hsw_power_well_ops,
+               .id = CNL_DISP_PW_AUX_F,
+       },
 };
 
 static int
@@ -2520,6 +2532,16 @@ int intel_power_domains_init(struct drm_i915_private *dev_priv)
                set_power_wells(power_domains, skl_power_wells);
        } else if (IS_CANNONLAKE(dev_priv)) {
                set_power_wells(power_domains, cnl_power_wells);
+
+               /*
+                * Aux IO is getting enabled for all ports
+                * regardless the presence or use. So, in order to avoid
+                * timeouts, lets remove it from the list
+                * for the SKUs without port F.
+                */
+               if (!IS_CNL_WITH_PORT_F(dev_priv))
+                       power_domains->power_well_count -= 1;
+
        } else if (IS_BROXTON(dev_priv)) {
                set_power_wells(power_domains, bxt_power_wells);
        } else if (IS_GEMINILAKE(dev_priv)) {