summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/tegra/dsi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/tegra/dsi.c')
-rw-r--r--drivers/gpu/drm/tegra/dsi.c73
1 files changed, 32 insertions, 41 deletions
diff --git a/drivers/gpu/drm/tegra/dsi.c b/drivers/gpu/drm/tegra/dsi.c
index db606e151afc..175f5f9937b0 100644
--- a/drivers/gpu/drm/tegra/dsi.c
+++ b/drivers/gpu/drm/tegra/dsi.c
@@ -22,6 +22,7 @@
#include <drm/drm_file.h>
#include <drm/drm_mipi_dsi.h>
#include <drm/drm_panel.h>
+#include <drm/drm_print.h>
#include <drm/drm_simple_kms_helper.h>
#include "dc.h"
@@ -545,12 +546,19 @@ static void tegra_dsi_configure(struct tegra_dsi *dsi, unsigned int pipe,
/* horizontal back porch */
hbp = (mode->htotal - mode->hsync_end) * mul / div;
- if ((dsi->flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE) == 0)
- hbp += hsw;
-
/* horizontal front porch */
hfp = (mode->hsync_start - mode->hdisplay) * mul / div;
+ if (dsi->master || dsi->slave) {
+ hact /= 2;
+ hsw /= 2;
+ hbp /= 2;
+ hfp /= 2;
+ }
+
+ if ((dsi->flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE) == 0)
+ hbp += hsw;
+
/* subtract packet overhead */
hsw -= 10;
hbp -= 14;
@@ -560,11 +568,6 @@ static void tegra_dsi_configure(struct tegra_dsi *dsi, unsigned int pipe,
tegra_dsi_writel(dsi, hact << 16 | hbp, DSI_PKT_LEN_2_3);
tegra_dsi_writel(dsi, hfp, DSI_PKT_LEN_4_5);
tegra_dsi_writel(dsi, 0x0f0f << 16, DSI_PKT_LEN_6_7);
-
- /* set SOL delay (for non-burst mode only) */
- tegra_dsi_writel(dsi, 8 * mul / div, DSI_SOL_DELAY);
-
- /* TODO: implement ganged mode */
} else {
u16 bytes;
@@ -586,29 +589,28 @@ static void tegra_dsi_configure(struct tegra_dsi *dsi, unsigned int pipe,
value = MIPI_DCS_WRITE_MEMORY_START << 8 |
MIPI_DCS_WRITE_MEMORY_CONTINUE;
tegra_dsi_writel(dsi, value, DSI_DCS_CMDS);
+ }
- /* set SOL delay */
- if (dsi->master || dsi->slave) {
- unsigned long delay, bclk, bclk_ganged;
- unsigned int lanes = state->lanes;
-
- /* SOL to valid, valid to FIFO and FIFO write delay */
- delay = 4 + 4 + 2;
- delay = DIV_ROUND_UP(delay * mul, div * lanes);
- /* FIFO read delay */
- delay = delay + 6;
-
- bclk = DIV_ROUND_UP(mode->htotal * mul, div * lanes);
- bclk_ganged = DIV_ROUND_UP(bclk * lanes / 2, lanes);
- value = bclk - bclk_ganged + delay + 20;
- } else {
- /* TODO: revisit for non-ganged mode */
- value = 8 * mul / div;
- }
+ /* set SOL delay */
+ if (dsi->master || dsi->slave) {
+ unsigned long delay, bclk, bclk_ganged;
+ unsigned int lanes = state->lanes;
+
+ /* SOL to valid, valid to FIFO and FIFO write delay */
+ delay = 4 + 4 + 2;
+ delay = DIV_ROUND_UP(delay * mul, div * lanes);
+ /* FIFO read delay */
+ delay = delay + 6;
- tegra_dsi_writel(dsi, value, DSI_SOL_DELAY);
+ bclk = DIV_ROUND_UP(mode->htotal * mul, div * lanes);
+ bclk_ganged = DIV_ROUND_UP(bclk * lanes / 2, lanes);
+ value = bclk - bclk_ganged + delay + 20;
+ } else {
+ value = 8 * mul / div;
}
+ tegra_dsi_writel(dsi, value, DSI_SOL_DELAY);
+
if (dsi->slave) {
tegra_dsi_configure(dsi->slave, pipe, mode);
@@ -812,7 +814,7 @@ static const struct drm_connector_funcs tegra_dsi_connector_funcs = {
static enum drm_mode_status
tegra_dsi_connector_mode_valid(struct drm_connector *connector,
- struct drm_display_mode *mode)
+ const struct drm_display_mode *mode)
{
return MODE_OK;
}
@@ -913,15 +915,6 @@ static void tegra_dsi_encoder_enable(struct drm_encoder *encoder)
u32 value;
int err;
- /* If the bootloader enabled DSI it needs to be disabled
- * in order for the panel initialization commands to be
- * properly sent.
- */
- value = tegra_dsi_readl(dsi, DSI_POWER_CONTROL);
-
- if (value & DSI_POWER_CONTROL_ENABLE)
- tegra_dsi_disable(dsi);
-
err = tegra_dsi_prepare(dsi);
if (err < 0) {
dev_err(dsi->dev, "failed to prepare: %d\n", err);
@@ -1564,7 +1557,6 @@ static int tegra_dsi_ganged_probe(struct tegra_dsi *dsi)
static int tegra_dsi_probe(struct platform_device *pdev)
{
struct tegra_dsi *dsi;
- struct resource *regs;
int err;
dsi = devm_kzalloc(&pdev->dev, sizeof(*dsi), GFP_KERNEL);
@@ -1636,8 +1628,7 @@ static int tegra_dsi_probe(struct platform_device *pdev)
goto remove;
}
- regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- dsi->regs = devm_ioremap_resource(&pdev->dev, regs);
+ dsi->regs = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(dsi->regs)) {
err = PTR_ERR(dsi->regs);
goto remove;
@@ -1713,5 +1704,5 @@ struct platform_driver tegra_dsi_driver = {
.of_match_table = tegra_dsi_of_match,
},
.probe = tegra_dsi_probe,
- .remove_new = tegra_dsi_remove,
+ .remove = tegra_dsi_remove,
};