summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/msm/dsi/dsi_host.c
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2023-10-23 18:29:18 +1000
committerDave Airlie <airlied@redhat.com>2023-10-23 18:29:18 +1000
commit3f5ba636d6987ddffeaa056dea1c524da63912f3 (patch)
tree7e30f36deb4a566fdb4b24113d486633b694d270 /drivers/gpu/drm/msm/dsi/dsi_host.c
parent7cd62eab9babd1fed9c497141650b31168f4f430 (diff)
parentb08d26dac1a1075c874f40ee02ec8ddc39e20146 (diff)
downloadlinux-3f5ba636d6987ddffeaa056dea1c524da63912f3.tar.gz
linux-3f5ba636d6987ddffeaa056dea1c524da63912f3.tar.bz2
linux-3f5ba636d6987ddffeaa056dea1c524da63912f3.zip
Merge tag 'drm-msm-next-2023-10-17' of https://gitlab.freedesktop.org/drm/msm into drm-next
Updates for v6.7 DP: - use existing helpers for DPCD handling instead of open-coded functions - set the subconnector type according to the plugged cable / dongle skip validity check for DP CTS EDID checksum DPU: - continued migration of feature flags to use core revision checks - reworked interrupts code to use '0' as NO_IRQ, removed raw IRQ indices from log / trace output gpu: - a7xx support (a730, a740) - fixes and additional speedbins for a635, a643 core: - decouple msm_drv from kms to more cleanly support headless devices (like imx5+a2xx) From: Rob Clark <robdclark@gmail.com> Link: https://patchwork.freedesktop.org/patch/msgid/CAF6AEGvzkBL2_OgyOeP_b6rVEjrNdfm8jcKzaB04HqHyT5jYwA@mail.gmail.com Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/msm/dsi/dsi_host.c')
-rw-r--r--drivers/gpu/drm/msm/dsi/dsi_host.c47
1 files changed, 36 insertions, 11 deletions
diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c
index 3d6fb708dc22..deeecdfd6c4e 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_host.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
@@ -147,6 +147,7 @@ struct msm_dsi_host {
/* DSI 6G TX buffer*/
struct drm_gem_object *tx_gem_obj;
+ struct msm_gem_address_space *aspace;
/* DSI v2 TX buffer */
void *tx_buf;
@@ -710,6 +711,15 @@ static void dsi_ctrl_disable(struct msm_dsi_host *msm_host)
dsi_write(msm_host, REG_DSI_CTRL, 0);
}
+bool msm_dsi_host_is_wide_bus_enabled(struct mipi_dsi_host *host)
+{
+ struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
+
+ return msm_host->dsc &&
+ (msm_host->cfg_hnd->major == MSM_DSI_VER_MAJOR_6G &&
+ msm_host->cfg_hnd->minor >= MSM_DSI_6G_VER_MINOR_V2_5_0);
+}
+
static void dsi_ctrl_enable(struct msm_dsi_host *msm_host,
struct msm_dsi_phy_shared_timings *phy_shared_timings, struct msm_dsi_phy *phy)
{
@@ -753,10 +763,16 @@ static void dsi_ctrl_enable(struct msm_dsi_host *msm_host,
data |= DSI_CMD_CFG1_INSERT_DCS_COMMAND;
dsi_write(msm_host, REG_DSI_CMD_CFG1, data);
- if (msm_host->cfg_hnd->major == MSM_DSI_VER_MAJOR_6G &&
- msm_host->cfg_hnd->minor >= MSM_DSI_6G_VER_MINOR_V1_3) {
+ if (cfg_hnd->major == MSM_DSI_VER_MAJOR_6G) {
data = dsi_read(msm_host, REG_DSI_CMD_MODE_MDP_CTRL2);
- data |= DSI_CMD_MODE_MDP_CTRL2_BURST_MODE;
+
+ if (cfg_hnd->minor >= MSM_DSI_6G_VER_MINOR_V1_3)
+ data |= DSI_CMD_MODE_MDP_CTRL2_BURST_MODE;
+
+ /* TODO: Allow for video-mode support once tested/fixed */
+ if (msm_dsi_host_is_wide_bus_enabled(&msm_host->base))
+ data |= DSI_CMD_MODE_MDP_CTRL2_DATABUS_WIDEN;
+
dsi_write(msm_host, REG_DSI_CMD_MODE_MDP_CTRL2, data);
}
}
@@ -894,6 +910,7 @@ static void dsi_timing_setup(struct msm_dsi_host *msm_host, bool is_bonded_dsi)
u32 hdisplay = mode->hdisplay;
u32 wc;
int ret;
+ bool wide_bus_enabled = msm_dsi_host_is_wide_bus_enabled(&msm_host->base);
DBG("");
@@ -914,6 +931,7 @@ static void dsi_timing_setup(struct msm_dsi_host *msm_host, bool is_bonded_dsi)
if (msm_host->dsc) {
struct drm_dsc_config *dsc = msm_host->dsc;
+ u32 bytes_per_pclk;
/* update dsc params with timing params */
if (!dsc || !mode->hdisplay || !mode->vdisplay) {
@@ -937,7 +955,13 @@ static void dsi_timing_setup(struct msm_dsi_host *msm_host, bool is_bonded_dsi)
* pulse width same
*/
h_total -= hdisplay;
- hdisplay = DIV_ROUND_UP(msm_dsc_get_bytes_per_line(msm_host->dsc), 3);
+ if (wide_bus_enabled && !(msm_host->mode_flags & MIPI_DSI_MODE_VIDEO))
+ bytes_per_pclk = 6;
+ else
+ bytes_per_pclk = 3;
+
+ hdisplay = DIV_ROUND_UP(msm_dsc_get_bytes_per_line(msm_host->dsc), bytes_per_pclk);
+
h_total += hdisplay;
ha_end = ha_start + hdisplay;
}
@@ -1111,8 +1135,10 @@ int dsi_tx_buf_alloc_6g(struct msm_dsi_host *msm_host, int size)
uint64_t iova;
u8 *data;
+ msm_host->aspace = msm_gem_address_space_get(priv->kms->aspace);
+
data = msm_gem_kernel_new(dev, size, MSM_BO_WC,
- priv->kms->aspace,
+ msm_host->aspace,
&msm_host->tx_gem_obj, &iova);
if (IS_ERR(data)) {
@@ -1141,10 +1167,10 @@ int dsi_tx_buf_alloc_v2(struct msm_dsi_host *msm_host, int size)
return 0;
}
-static void dsi_tx_buf_free(struct msm_dsi_host *msm_host)
+void msm_dsi_tx_buf_free(struct mipi_dsi_host *host)
{
+ struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
struct drm_device *dev = msm_host->dev;
- struct msm_drm_private *priv;
/*
* This is possible if we're tearing down before we've had a chance to
@@ -1155,11 +1181,11 @@ static void dsi_tx_buf_free(struct msm_dsi_host *msm_host)
if (!dev)
return;
- priv = dev->dev_private;
if (msm_host->tx_gem_obj) {
- msm_gem_unpin_iova(msm_host->tx_gem_obj, priv->kms->aspace);
- drm_gem_object_put(msm_host->tx_gem_obj);
+ msm_gem_kernel_put(msm_host->tx_gem_obj, msm_host->aspace);
+ msm_gem_address_space_put(msm_host->aspace);
msm_host->tx_gem_obj = NULL;
+ msm_host->aspace = NULL;
}
if (msm_host->tx_buf)
@@ -1945,7 +1971,6 @@ void msm_dsi_host_destroy(struct mipi_dsi_host *host)
struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
DBG("");
- dsi_tx_buf_free(msm_host);
if (msm_host->workqueue) {
destroy_workqueue(msm_host->workqueue);
msm_host->workqueue = NULL;