summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_dsi_cmd.c
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2015-01-10 08:46:24 +1000
committerDave Airlie <airlied@redhat.com>2015-01-10 08:46:24 +1000
commitadc31849b27fefeca6c225d3895143a2ec6970fa (patch)
tree96644dea69278efbdd0f0fac52202203a67030fa /drivers/gpu/drm/i915/intel_dsi_cmd.c
parentc93546a5e32bd788c22aefa072385f3784551c13 (diff)
parent0e2cfc005b376ed7b5c9a9fc466b5842fcc18cc7 (diff)
downloadlinux-adc31849b27fefeca6c225d3895143a2ec6970fa.tar.gz
linux-adc31849b27fefeca6c225d3895143a2ec6970fa.tar.bz2
linux-adc31849b27fefeca6c225d3895143a2ec6970fa.zip
Merge tag 'drm-intel-next-2014-12-19' of git://anongit.freedesktop.org/drm-intel into drm-next
- plane handling refactoring from Matt Roper and Gustavo Padovan in prep for atomic updates - fixes and more patches for the seqno to request transformation from John - docbook for fbc from Rodrigo - prep work for dual-link dsi from Gaurav Signh - crc fixes from Ville - special ggtt views infrastructure from Tvrtko Ursulin - shadow patch copying for the cmd parser from Brad Volkin - execlist and full ppgtt by default on gen8, for testing for now * tag 'drm-intel-next-2014-12-19' of git://anongit.freedesktop.org/drm-intel: (131 commits) drm/i915: Update DRIVER_DATE to 20141219 drm/i915: Hold runtime PM during plane commit drm/i915: Organize bind_vma funcs drm/i915: Organize INSTDONE report for future. drm/i915: Organize PDP regs report for future. drm/i915: Organize PPGTT init drm/i915: Organize Fence registers for future enablement. drm/i915: tame the chattermouth (v2) drm/i915: Warn about missing context state workarounds only once drm/i915: Use true PPGTT in Gen8+ when execlists are enabled drm/i915: Skip gunit save/restore for cherryview drm/i915/chv: Use timeout mode for RC6 on chv drm/i915: Add GPGPU_THREADS_DISPATCHED to the register whitelist drm/i915: Tidy up execbuffer command parsing code drm/i915: Mark shadow batch buffers as purgeable drm/i915: Use batch length instead of object size in command parser drm/i915: Use batch pools with the command parser drm/i915: Implement a framework for batch buffer pools drm/i915: fix use after free during eDP encoder destroying drm/i915/skl: Skylake also supports DP MST ...
Diffstat (limited to 'drivers/gpu/drm/i915/intel_dsi_cmd.c')
-rw-r--r--drivers/gpu/drm/i915/intel_dsi_cmd.c141
1 files changed, 68 insertions, 73 deletions
diff --git a/drivers/gpu/drm/i915/intel_dsi_cmd.c b/drivers/gpu/drm/i915/intel_dsi_cmd.c
index f4767fd2ebeb..562811c1a9d2 100644
--- a/drivers/gpu/drm/i915/intel_dsi_cmd.c
+++ b/drivers/gpu/drm/i915/intel_dsi_cmd.c
@@ -48,21 +48,19 @@
* For memory writes, these should probably be used for performance.
*/
-static void print_stat(struct intel_dsi *intel_dsi)
+static void print_stat(struct intel_dsi *intel_dsi, enum port port)
{
struct drm_encoder *encoder = &intel_dsi->base.base;
struct drm_device *dev = encoder->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
- enum pipe pipe = intel_crtc->pipe;
u32 val;
- val = I915_READ(MIPI_INTR_STAT(pipe));
+ val = I915_READ(MIPI_INTR_STAT(port));
#define STAT_BIT(val, bit) (val) & (bit) ? " " #bit : ""
- DRM_DEBUG_KMS("MIPI_INTR_STAT(%d) = %08x"
+ DRM_DEBUG_KMS("MIPI_INTR_STAT(%c) = %08x"
"%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s"
- "\n", pipe, val,
+ "\n", port_name(port), val,
STAT_BIT(val, TEARING_EFFECT),
STAT_BIT(val, SPL_PKT_SENT_INTERRUPT),
STAT_BIT(val, GEN_READ_DATA_AVAIL),
@@ -104,34 +102,31 @@ enum dsi_type {
};
/* enable or disable command mode hs transmissions */
-void dsi_hs_mode_enable(struct intel_dsi *intel_dsi, bool enable)
+void dsi_hs_mode_enable(struct intel_dsi *intel_dsi, bool enable,
+ enum port port)
{
struct drm_encoder *encoder = &intel_dsi->base.base;
struct drm_device *dev = encoder->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
- enum pipe pipe = intel_crtc->pipe;
u32 temp;
u32 mask = DBI_FIFO_EMPTY;
- if (wait_for((I915_READ(MIPI_GEN_FIFO_STAT(pipe)) & mask) == mask, 50))
+ if (wait_for((I915_READ(MIPI_GEN_FIFO_STAT(port)) & mask) == mask, 50))
DRM_ERROR("Timeout waiting for DBI FIFO empty\n");
- temp = I915_READ(MIPI_HS_LP_DBI_ENABLE(pipe));
+ temp = I915_READ(MIPI_HS_LP_DBI_ENABLE(port));
temp &= DBI_HS_LP_MODE_MASK;
- I915_WRITE(MIPI_HS_LP_DBI_ENABLE(pipe), enable ? DBI_HS_MODE : DBI_LP_MODE);
+ I915_WRITE(MIPI_HS_LP_DBI_ENABLE(port), enable ? DBI_HS_MODE : DBI_LP_MODE);
intel_dsi->hs = enable;
}
static int dsi_vc_send_short(struct intel_dsi *intel_dsi, int channel,
- u8 data_type, u16 data)
+ u8 data_type, u16 data, enum port port)
{
struct drm_encoder *encoder = &intel_dsi->base.base;
struct drm_device *dev = encoder->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
- enum pipe pipe = intel_crtc->pipe;
u32 ctrl_reg;
u32 ctrl;
u32 mask;
@@ -140,16 +135,16 @@ static int dsi_vc_send_short(struct intel_dsi *intel_dsi, int channel,
channel, data_type, data);
if (intel_dsi->hs) {
- ctrl_reg = MIPI_HS_GEN_CTRL(pipe);
+ ctrl_reg = MIPI_HS_GEN_CTRL(port);
mask = HS_CTRL_FIFO_FULL;
} else {
- ctrl_reg = MIPI_LP_GEN_CTRL(pipe);
+ ctrl_reg = MIPI_LP_GEN_CTRL(port);
mask = LP_CTRL_FIFO_FULL;
}
- if (wait_for((I915_READ(MIPI_GEN_FIFO_STAT(pipe)) & mask) == 0, 50)) {
+ if (wait_for((I915_READ(MIPI_GEN_FIFO_STAT(port)) & mask) == 0, 50)) {
DRM_ERROR("Timeout waiting for HS/LP CTRL FIFO !full\n");
- print_stat(intel_dsi);
+ print_stat(intel_dsi, port);
}
/*
@@ -167,13 +162,11 @@ static int dsi_vc_send_short(struct intel_dsi *intel_dsi, int channel,
}
static int dsi_vc_send_long(struct intel_dsi *intel_dsi, int channel,
- u8 data_type, const u8 *data, int len)
+ u8 data_type, const u8 *data, int len, enum port port)
{
struct drm_encoder *encoder = &intel_dsi->base.base;
struct drm_device *dev = encoder->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
- enum pipe pipe = intel_crtc->pipe;
u32 data_reg;
int i, j, n;
u32 mask;
@@ -182,14 +175,14 @@ static int dsi_vc_send_long(struct intel_dsi *intel_dsi, int channel,
channel, data_type, len);
if (intel_dsi->hs) {
- data_reg = MIPI_HS_GEN_DATA(pipe);
+ data_reg = MIPI_HS_GEN_DATA(port);
mask = HS_DATA_FIFO_FULL;
} else {
- data_reg = MIPI_LP_GEN_DATA(pipe);
+ data_reg = MIPI_LP_GEN_DATA(port);
mask = LP_DATA_FIFO_FULL;
}
- if (wait_for((I915_READ(MIPI_GEN_FIFO_STAT(pipe)) & mask) == 0, 50))
+ if (wait_for((I915_READ(MIPI_GEN_FIFO_STAT(port)) & mask) == 0, 50))
DRM_ERROR("Timeout waiting for HS/LP DATA FIFO !full\n");
for (i = 0; i < len; i += n) {
@@ -204,12 +197,12 @@ static int dsi_vc_send_long(struct intel_dsi *intel_dsi, int channel,
* dwords, then wait for not set, then continue. */
}
- return dsi_vc_send_short(intel_dsi, channel, data_type, len);
+ return dsi_vc_send_short(intel_dsi, channel, data_type, len, port);
}
static int dsi_vc_write_common(struct intel_dsi *intel_dsi,
int channel, const u8 *data, int len,
- enum dsi_type type)
+ enum dsi_type type, enum port port)
{
int ret;
@@ -217,50 +210,54 @@ static int dsi_vc_write_common(struct intel_dsi *intel_dsi,
BUG_ON(type == DSI_GENERIC);
ret = dsi_vc_send_short(intel_dsi, channel,
MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM,
- 0);
+ 0, port);
} else if (len == 1) {
ret = dsi_vc_send_short(intel_dsi, channel,
type == DSI_GENERIC ?
MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM :
- MIPI_DSI_DCS_SHORT_WRITE, data[0]);
+ MIPI_DSI_DCS_SHORT_WRITE, data[0],
+ port);
} else if (len == 2) {
ret = dsi_vc_send_short(intel_dsi, channel,
type == DSI_GENERIC ?
MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM :
MIPI_DSI_DCS_SHORT_WRITE_PARAM,
- (data[1] << 8) | data[0]);
+ (data[1] << 8) | data[0], port);
} else {
ret = dsi_vc_send_long(intel_dsi, channel,
- type == DSI_GENERIC ?
- MIPI_DSI_GENERIC_LONG_WRITE :
- MIPI_DSI_DCS_LONG_WRITE, data, len);
+ type == DSI_GENERIC ?
+ MIPI_DSI_GENERIC_LONG_WRITE :
+ MIPI_DSI_DCS_LONG_WRITE, data, len,
+ port);
}
return ret;
}
int dsi_vc_dcs_write(struct intel_dsi *intel_dsi, int channel,
- const u8 *data, int len)
+ const u8 *data, int len, enum port port)
{
- return dsi_vc_write_common(intel_dsi, channel, data, len, DSI_DCS);
+ return dsi_vc_write_common(intel_dsi, channel, data, len, DSI_DCS,
+ port);
}
int dsi_vc_generic_write(struct intel_dsi *intel_dsi, int channel,
- const u8 *data, int len)
+ const u8 *data, int len, enum port port)
{
- return dsi_vc_write_common(intel_dsi, channel, data, len, DSI_GENERIC);
+ return dsi_vc_write_common(intel_dsi, channel, data, len, DSI_GENERIC,
+ port);
}
static int dsi_vc_dcs_send_read_request(struct intel_dsi *intel_dsi,
- int channel, u8 dcs_cmd)
+ int channel, u8 dcs_cmd, enum port port)
{
return dsi_vc_send_short(intel_dsi, channel, MIPI_DSI_DCS_READ,
- dcs_cmd);
+ dcs_cmd, port);
}
static int dsi_vc_generic_send_read_request(struct intel_dsi *intel_dsi,
int channel, u8 *reqdata,
- int reqlen)
+ int reqlen, enum port port)
{
u16 data;
u8 data_type;
@@ -282,24 +279,22 @@ static int dsi_vc_generic_send_read_request(struct intel_dsi *intel_dsi,
BUG();
}
- return dsi_vc_send_short(intel_dsi, channel, data_type, data);
+ return dsi_vc_send_short(intel_dsi, channel, data_type, data, port);
}
static int dsi_read_data_return(struct intel_dsi *intel_dsi,
- u8 *buf, int buflen)
+ u8 *buf, int buflen, enum port port)
{
struct drm_encoder *encoder = &intel_dsi->base.base;
struct drm_device *dev = encoder->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
- enum pipe pipe = intel_crtc->pipe;
int i, len = 0;
u32 data_reg, val;
if (intel_dsi->hs) {
- data_reg = MIPI_HS_GEN_DATA(pipe);
+ data_reg = MIPI_HS_GEN_DATA(port);
} else {
- data_reg = MIPI_LP_GEN_DATA(pipe);
+ data_reg = MIPI_LP_GEN_DATA(port);
}
while (len < buflen) {
@@ -312,13 +307,11 @@ static int dsi_read_data_return(struct intel_dsi *intel_dsi,
}
int dsi_vc_dcs_read(struct intel_dsi *intel_dsi, int channel, u8 dcs_cmd,
- u8 *buf, int buflen)
+ u8 *buf, int buflen, enum port port)
{
struct drm_encoder *encoder = &intel_dsi->base.base;
struct drm_device *dev = encoder->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
- enum pipe pipe = intel_crtc->pipe;
u32 mask;
int ret;
@@ -327,17 +320,17 @@ int dsi_vc_dcs_read(struct intel_dsi *intel_dsi, int channel, u8 dcs_cmd,
* longer than MIPI_MAX_RETURN_PKT_SIZE
*/
- I915_WRITE(MIPI_INTR_STAT(pipe), GEN_READ_DATA_AVAIL);
+ I915_WRITE(MIPI_INTR_STAT(port), GEN_READ_DATA_AVAIL);
- ret = dsi_vc_dcs_send_read_request(intel_dsi, channel, dcs_cmd);
+ ret = dsi_vc_dcs_send_read_request(intel_dsi, channel, dcs_cmd, port);
if (ret)
return ret;
mask = GEN_READ_DATA_AVAIL;
- if (wait_for((I915_READ(MIPI_INTR_STAT(pipe)) & mask) == mask, 50))
+ if (wait_for((I915_READ(MIPI_INTR_STAT(port)) & mask) == mask, 50))
DRM_ERROR("Timeout waiting for read data.\n");
- ret = dsi_read_data_return(intel_dsi, buf, buflen);
+ ret = dsi_read_data_return(intel_dsi, buf, buflen, port);
if (ret < 0)
return ret;
@@ -348,13 +341,11 @@ int dsi_vc_dcs_read(struct intel_dsi *intel_dsi, int channel, u8 dcs_cmd,
}
int dsi_vc_generic_read(struct intel_dsi *intel_dsi, int channel,
- u8 *reqdata, int reqlen, u8 *buf, int buflen)
+ u8 *reqdata, int reqlen, u8 *buf, int buflen, enum port port)
{
struct drm_encoder *encoder = &intel_dsi->base.base;
struct drm_device *dev = encoder->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
- enum pipe pipe = intel_crtc->pipe;
u32 mask;
int ret;
@@ -363,18 +354,18 @@ int dsi_vc_generic_read(struct intel_dsi *intel_dsi, int channel,
* longer than MIPI_MAX_RETURN_PKT_SIZE
*/
- I915_WRITE(MIPI_INTR_STAT(pipe), GEN_READ_DATA_AVAIL);
+ I915_WRITE(MIPI_INTR_STAT(port), GEN_READ_DATA_AVAIL);
ret = dsi_vc_generic_send_read_request(intel_dsi, channel, reqdata,
- reqlen);
+ reqlen, port);
if (ret)
return ret;
mask = GEN_READ_DATA_AVAIL;
- if (wait_for((I915_READ(MIPI_INTR_STAT(pipe)) & mask) == mask, 50))
+ if (wait_for((I915_READ(MIPI_INTR_STAT(port)) & mask) == mask, 50))
DRM_ERROR("Timeout waiting for read data.\n");
- ret = dsi_read_data_return(intel_dsi, buf, buflen);
+ ret = dsi_read_data_return(intel_dsi, buf, buflen, port);
if (ret < 0)
return ret;
@@ -394,8 +385,7 @@ int dpi_send_cmd(struct intel_dsi *intel_dsi, u32 cmd, bool hs)
struct drm_encoder *encoder = &intel_dsi->base.base;
struct drm_device *dev = encoder->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
- enum pipe pipe = intel_crtc->pipe;
+ enum port port;
u32 mask;
/* XXX: pipe, hs */
@@ -404,18 +394,23 @@ int dpi_send_cmd(struct intel_dsi *intel_dsi, u32 cmd, bool hs)
else
cmd |= DPI_LP_MODE;
- /* clear bit */
- I915_WRITE(MIPI_INTR_STAT(pipe), SPL_PKT_SENT_INTERRUPT);
+ for_each_dsi_port(port, intel_dsi->ports) {
+ /* clear bit */
+ I915_WRITE(MIPI_INTR_STAT(port), SPL_PKT_SENT_INTERRUPT);
- /* XXX: old code skips write if control unchanged */
- if (cmd == I915_READ(MIPI_DPI_CONTROL(pipe)))
- DRM_ERROR("Same special packet %02x twice in a row.\n", cmd);
+ /* XXX: old code skips write if control unchanged */
+ if (cmd == I915_READ(MIPI_DPI_CONTROL(port)))
+ DRM_ERROR("Same special packet %02x twice in a row.\n",
+ cmd);
- I915_WRITE(MIPI_DPI_CONTROL(pipe), cmd);
+ I915_WRITE(MIPI_DPI_CONTROL(port), cmd);
- mask = SPL_PKT_SENT_INTERRUPT;
- if (wait_for((I915_READ(MIPI_INTR_STAT(pipe)) & mask) == mask, 100))
- DRM_ERROR("Video mode command 0x%08x send failed.\n", cmd);
+ mask = SPL_PKT_SENT_INTERRUPT;
+ if (wait_for((I915_READ(MIPI_INTR_STAT(port)) & mask) == mask,
+ 100))
+ DRM_ERROR("Video mode command 0x%08x send failed.\n",
+ cmd);
+ }
return 0;
}
@@ -426,12 +421,12 @@ void wait_for_dsi_fifo_empty(struct intel_dsi *intel_dsi)
struct drm_device *dev = encoder->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
- enum pipe pipe = intel_crtc->pipe;
+ enum port port = intel_dsi_pipe_to_port(intel_crtc->pipe);
u32 mask;
mask = LP_CTRL_FIFO_EMPTY | HS_CTRL_FIFO_EMPTY |
LP_DATA_FIFO_EMPTY | HS_DATA_FIFO_EMPTY;
- if (wait_for((I915_READ(MIPI_GEN_FIFO_STAT(pipe)) & mask) == mask, 100))
+ if (wait_for((I915_READ(MIPI_GEN_FIFO_STAT(port)) & mask) == mask, 100))
DRM_ERROR("DPI FIFOs are not empty\n");
}