Commit 37ab0810 authored by Shashank Sharma's avatar Shashank Sharma Committed by Daniel Vetter

drm/i915/bxt: DSI enable for BXT

This patch contains following changes:
1. MIPI device ready changes to support dsi_pre_enable. Changes
   are specific to BXT device ready sequence. Added check for
   ULPS mode(No effects on VLV).
2. Changes in dsi_enable to pick BXT port control register.
3. Changes in dsi_pre_enable to restrict DPIO programming for VLV

v2: Fixed Jani's review comments. Removed the changes in VLV/CHV
    code. Fixed the macros to get proper port offsets.

v3: Rebased on latest drm-nightly branch. Fixed Jani's review comments.
Signed-off-by: default avatarShashank Sharma <shashank.sharma@intel.com>
Signed-off-by: default avatarUma Shankar <uma.shankar@intel.com>
Reviewed-by: default avatarJani Nikula <jani.nikula@intel.com>
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
parent 7d4aefd0
...@@ -7588,6 +7588,13 @@ enum skl_disp_power_wells { ...@@ -7588,6 +7588,13 @@ enum skl_disp_power_wells {
#define _MIPIA_PORT_CTRL (VLV_DISPLAY_BASE + 0x61190) #define _MIPIA_PORT_CTRL (VLV_DISPLAY_BASE + 0x61190)
#define _MIPIC_PORT_CTRL (VLV_DISPLAY_BASE + 0x61700) #define _MIPIC_PORT_CTRL (VLV_DISPLAY_BASE + 0x61700)
#define MIPI_PORT_CTRL(port) _MIPI_PORT(port, _MIPIA_PORT_CTRL, _MIPIC_PORT_CTRL) #define MIPI_PORT_CTRL(port) _MIPI_PORT(port, _MIPIA_PORT_CTRL, _MIPIC_PORT_CTRL)
/* BXT port control */
#define _BXT_MIPIA_PORT_CTRL 0x6B0C0
#define _BXT_MIPIC_PORT_CTRL 0x6B8C0
#define BXT_MIPI_PORT_CTRL(tc) _MIPI_PORT(tc, _BXT_MIPIA_PORT_CTRL, \
_BXT_MIPIC_PORT_CTRL)
#define DPI_ENABLE (1 << 31) /* A + C */ #define DPI_ENABLE (1 << 31) /* A + C */
#define MIPIA_MIPI4DPHY_DELAY_COUNT_SHIFT 27 #define MIPIA_MIPI4DPHY_DELAY_COUNT_SHIFT 27
#define MIPIA_MIPI4DPHY_DELAY_COUNT_MASK (0xf << 27) #define MIPIA_MIPI4DPHY_DELAY_COUNT_MASK (0xf << 27)
......
...@@ -282,58 +282,46 @@ static bool intel_dsi_compute_config(struct intel_encoder *encoder, ...@@ -282,58 +282,46 @@ static bool intel_dsi_compute_config(struct intel_encoder *encoder,
return true; return true;
} }
static void intel_dsi_port_enable(struct intel_encoder *encoder) static void bxt_dsi_device_ready(struct intel_encoder *encoder)
{ {
struct drm_device *dev = encoder->base.dev; struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
enum port port; enum port port;
u32 temp; u32 val;
if (intel_dsi->dual_link == DSI_DUAL_LINK_FRONT_BACK) { DRM_DEBUG_KMS("\n");
temp = I915_READ(VLV_CHICKEN_3);
temp &= ~PIXEL_OVERLAP_CNT_MASK |
intel_dsi->pixel_overlap <<
PIXEL_OVERLAP_CNT_SHIFT;
I915_WRITE(VLV_CHICKEN_3, temp);
}
/* Exit Low power state in 4 steps*/
for_each_dsi_port(port, intel_dsi->ports) { for_each_dsi_port(port, intel_dsi->ports) {
temp = I915_READ(MIPI_PORT_CTRL(port));
temp &= ~LANE_CONFIGURATION_MASK;
temp &= ~DUAL_LINK_MODE_MASK;
if (intel_dsi->ports == ((1 << PORT_A) | (1 << PORT_C))) { /* 1. Enable MIPI PHY transparent latch */
temp |= (intel_dsi->dual_link - 1) val = I915_READ(BXT_MIPI_PORT_CTRL(port));
<< DUAL_LINK_MODE_SHIFT; I915_WRITE(BXT_MIPI_PORT_CTRL(port), val | LP_OUTPUT_HOLD);
temp |= intel_crtc->pipe ? usleep_range(2000, 2500);
LANE_CONFIGURATION_DUAL_LINK_B :
LANE_CONFIGURATION_DUAL_LINK_A;
}
/* assert ip_tg_enable signal */
I915_WRITE(MIPI_PORT_CTRL(port), temp | DPI_ENABLE);
POSTING_READ(MIPI_PORT_CTRL(port));
}
}
static void intel_dsi_port_disable(struct intel_encoder *encoder) /* 2. Enter ULPS */
{ val = I915_READ(MIPI_DEVICE_READY(port));
struct drm_device *dev = encoder->base.dev; val &= ~ULPS_STATE_MASK;
struct drm_i915_private *dev_priv = dev->dev_private; val |= (ULPS_STATE_ENTER | DEVICE_READY);
struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); I915_WRITE(MIPI_DEVICE_READY(port), val);
enum port port; usleep_range(2, 3);
u32 temp;
/* 3. Exit ULPS */
val = I915_READ(MIPI_DEVICE_READY(port));
val &= ~ULPS_STATE_MASK;
val |= (ULPS_STATE_EXIT | DEVICE_READY);
I915_WRITE(MIPI_DEVICE_READY(port), val);
usleep_range(1000, 1500);
for_each_dsi_port(port, intel_dsi->ports) { /* Clear ULPS and set device ready */
/* de-assert ip_tg_enable signal */ val = I915_READ(MIPI_DEVICE_READY(port));
temp = I915_READ(MIPI_PORT_CTRL(port)); val &= ~ULPS_STATE_MASK;
I915_WRITE(MIPI_PORT_CTRL(port), temp & ~DPI_ENABLE); val |= DEVICE_READY;
POSTING_READ(MIPI_PORT_CTRL(port)); I915_WRITE(MIPI_DEVICE_READY(port), val);
} }
} }
static void intel_dsi_device_ready(struct intel_encoder *encoder) static void vlv_dsi_device_ready(struct intel_encoder *encoder)
{ {
struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
...@@ -372,6 +360,72 @@ static void intel_dsi_device_ready(struct intel_encoder *encoder) ...@@ -372,6 +360,72 @@ static void intel_dsi_device_ready(struct intel_encoder *encoder)
} }
} }
static void intel_dsi_device_ready(struct intel_encoder *encoder)
{
struct drm_device *dev = encoder->base.dev;
if (IS_VALLEYVIEW(dev))
vlv_dsi_device_ready(encoder);
else if (IS_BROXTON(dev))
bxt_dsi_device_ready(encoder);
}
static void intel_dsi_port_enable(struct intel_encoder *encoder)
{
struct drm_device *dev = encoder->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
enum port port;
u32 temp;
u32 port_ctrl;
if (intel_dsi->dual_link == DSI_DUAL_LINK_FRONT_BACK) {
temp = I915_READ(VLV_CHICKEN_3);
temp &= ~PIXEL_OVERLAP_CNT_MASK |
intel_dsi->pixel_overlap <<
PIXEL_OVERLAP_CNT_SHIFT;
I915_WRITE(VLV_CHICKEN_3, temp);
}
for_each_dsi_port(port, intel_dsi->ports) {
port_ctrl = IS_BROXTON(dev) ? BXT_MIPI_PORT_CTRL(port) :
MIPI_PORT_CTRL(port);
temp = I915_READ(port_ctrl);
temp &= ~LANE_CONFIGURATION_MASK;
temp &= ~DUAL_LINK_MODE_MASK;
if (intel_dsi->ports == ((1 << PORT_A) | (1 << PORT_C))) {
temp |= (intel_dsi->dual_link - 1)
<< DUAL_LINK_MODE_SHIFT;
temp |= intel_crtc->pipe ?
LANE_CONFIGURATION_DUAL_LINK_B :
LANE_CONFIGURATION_DUAL_LINK_A;
}
/* assert ip_tg_enable signal */
I915_WRITE(port_ctrl, temp | DPI_ENABLE);
POSTING_READ(port_ctrl);
}
}
static void intel_dsi_port_disable(struct intel_encoder *encoder)
{
struct drm_device *dev = encoder->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
enum port port;
u32 temp;
for_each_dsi_port(port, intel_dsi->ports) {
/* de-assert ip_tg_enable signal */
temp = I915_READ(MIPI_PORT_CTRL(port));
I915_WRITE(MIPI_PORT_CTRL(port), temp & ~DPI_ENABLE);
POSTING_READ(MIPI_PORT_CTRL(port));
}
}
static void intel_dsi_enable(struct intel_encoder *encoder) static void intel_dsi_enable(struct intel_encoder *encoder)
{ {
struct drm_device *dev = encoder->base.dev; struct drm_device *dev = encoder->base.dev;
...@@ -419,19 +473,24 @@ static void intel_dsi_pre_enable(struct intel_encoder *encoder) ...@@ -419,19 +473,24 @@ static void intel_dsi_pre_enable(struct intel_encoder *encoder)
msleep(intel_dsi->panel_on_delay); msleep(intel_dsi->panel_on_delay);
/* Disable DPOunit clock gating, can stall pipe if (IS_VALLEYVIEW(dev)) {
* and we need DPLL REFA always enabled */ /*
tmp = I915_READ(DPLL(pipe)); * Disable DPOunit clock gating, can stall pipe
tmp |= DPLL_REF_CLK_ENABLE_VLV; * and we need DPLL REFA always enabled
I915_WRITE(DPLL(pipe), tmp); */
tmp = I915_READ(DPLL(pipe));
/* update the hw state for DPLL */ tmp |= DPLL_REF_CLK_ENABLE_VLV;
intel_crtc->config->dpll_hw_state.dpll = DPLL_INTEGRATED_REF_CLK_VLV | I915_WRITE(DPLL(pipe), tmp);
DPLL_REF_CLK_ENABLE_VLV | DPLL_VGA_MODE_DIS;
/* update the hw state for DPLL */
tmp = I915_READ(DSPCLK_GATE_D); intel_crtc->config->dpll_hw_state.dpll =
tmp |= DPOUNIT_CLOCK_GATE_DISABLE; DPLL_INTEGRATED_REF_CLK_VLV |
I915_WRITE(DSPCLK_GATE_D, tmp); DPLL_REF_CLK_ENABLE_VLV | DPLL_VGA_MODE_DIS;
tmp = I915_READ(DSPCLK_GATE_D);
tmp |= DPOUNIT_CLOCK_GATE_DISABLE;
I915_WRITE(DSPCLK_GATE_D, tmp);
}
/* put device in ready state */ /* put device in ready state */
intel_dsi_device_ready(encoder); intel_dsi_device_ready(encoder);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment