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: Shashank Sharma <shashank.sharma@intel.com> Signed-off-by: Uma Shankar <uma.shankar@intel.com> Reviewed-by: Jani Nikula <jani.nikula@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
This commit is contained in:
parent
7d4aefd0a9
commit
37ab0810c9
|
@ -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,
|
||||||
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;
|
/* 2. Enter ULPS */
|
||||||
}
|
val = I915_READ(MIPI_DEVICE_READY(port));
|
||||||
/* assert ip_tg_enable signal */
|
val &= ~ULPS_STATE_MASK;
|
||||||
I915_WRITE(MIPI_PORT_CTRL(port), temp | DPI_ENABLE);
|
val |= (ULPS_STATE_ENTER | DEVICE_READY);
|
||||||
POSTING_READ(MIPI_PORT_CTRL(port));
|
I915_WRITE(MIPI_DEVICE_READY(port), val);
|
||||||
|
usleep_range(2, 3);
|
||||||
|
|
||||||
|
/* 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);
|
||||||
|
|
||||||
|
/* Clear ULPS and set device ready */
|
||||||
|
val = I915_READ(MIPI_DEVICE_READY(port));
|
||||||
|
val &= ~ULPS_STATE_MASK;
|
||||||
|
val |= DEVICE_READY;
|
||||||
|
I915_WRITE(MIPI_DEVICE_READY(port), val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void intel_dsi_port_disable(struct intel_encoder *encoder)
|
static void vlv_dsi_device_ready(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_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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
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 */
|
/*
|
||||||
|
* Disable DPOunit clock gating, can stall pipe
|
||||||
|
* and we need DPLL REFA always enabled
|
||||||
|
*/
|
||||||
tmp = I915_READ(DPLL(pipe));
|
tmp = I915_READ(DPLL(pipe));
|
||||||
tmp |= DPLL_REF_CLK_ENABLE_VLV;
|
tmp |= DPLL_REF_CLK_ENABLE_VLV;
|
||||||
I915_WRITE(DPLL(pipe), tmp);
|
I915_WRITE(DPLL(pipe), tmp);
|
||||||
|
|
||||||
/* update the hw state for DPLL */
|
/* update the hw state for DPLL */
|
||||||
intel_crtc->config->dpll_hw_state.dpll = DPLL_INTEGRATED_REF_CLK_VLV |
|
intel_crtc->config->dpll_hw_state.dpll =
|
||||||
|
DPLL_INTEGRATED_REF_CLK_VLV |
|
||||||
DPLL_REF_CLK_ENABLE_VLV | DPLL_VGA_MODE_DIS;
|
DPLL_REF_CLK_ENABLE_VLV | DPLL_VGA_MODE_DIS;
|
||||||
|
|
||||||
tmp = I915_READ(DSPCLK_GATE_D);
|
tmp = I915_READ(DSPCLK_GATE_D);
|
||||||
tmp |= DPOUNIT_CLOCK_GATE_DISABLE;
|
tmp |= DPOUNIT_CLOCK_GATE_DISABLE;
|
||||||
I915_WRITE(DSPCLK_GATE_D, tmp);
|
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);
|
||||||
|
|
Loading…
Reference in New Issue