2019-06-14 18:58:04

by Jeffrey Hugo

[permalink] [raw]
Subject: [PATCH 0/2] MSM8998 MTP Display

Since we are trying to get the GPU and display hardware in the SoC
supported, it would be nice to be able to put the output on the
integrated panel for the reference platform. To do so, we need support
in the Truly driver to support the specific panel variant for the
MSM8998 MTP. This series adds taht support.

Jeffrey Hugo (2):
dt-bindings: display: truly: Add MSM8998 MTP panel
drm/panel: truly: Add MSM8998 MTP support

.../bindings/display/truly,nt35597.txt | 7 +-
drivers/gpu/drm/panel/panel-truly-nt35597.c | 149 +++++++++++++-----
2 files changed, 116 insertions(+), 40 deletions(-)

--
2.17.1


2019-06-14 19:02:59

by Jeffrey Hugo

[permalink] [raw]
Subject: [PATCH 1/2] dt-bindings: display: truly: Add MSM8998 MTP panel

The MSM8998 MTP uses the Truly display driver for its panel, but the
configuration differs slightly from the existing SDM845. Add a compatible
to account for the differences.

Signed-off-by: Jeffrey Hugo <[email protected]>
---
.../devicetree/bindings/display/truly,nt35597.txt | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/display/truly,nt35597.txt b/Documentation/devicetree/bindings/display/truly,nt35597.txt
index f39c77ee36ea..fda36c1ad3c3 100644
--- a/Documentation/devicetree/bindings/display/truly,nt35597.txt
+++ b/Documentation/devicetree/bindings/display/truly,nt35597.txt
@@ -1,10 +1,11 @@
Truly model NT35597 DSI display driver

-The Truly NT35597 is a generic display driver, currently only configured
-for use in the 2K display on the Qualcomm SDM845 MTP board.
+The Truly NT35597 is a generic display driver used for the Qualcomm reference
+platforms.

Required properties:
-- compatible: should be "truly,nt35597-2K-display"
+- compatible: should be "truly,nt35597-2K-display" (SDM845)
+ "truly,nt35597-wqhd-cmd-dsc-display" (MSM8998)
- vdda-supply: phandle of the regulator that provides the supply voltage
Power IC supply
- vdispp-supply: phandle of the regulator that provides the supply voltage
--
2.17.1

2019-06-14 19:04:01

by Jeffrey Hugo

[permalink] [raw]
Subject: [PATCH 2/2] drm/panel: truly: Add MSM8998 MTP support

The MSM8998 MTP is the MSM8998 reference platform, and like the SDM845 MTP
it uses the Truly NT35587 Display driver. However, unlike the SDM845 MTP,
the instance in the MSM8998 MTP is a single DSI interface, command mode
type panel that supports a WQHD resolution and requires DSC compression.

Add support for the MSM8998 MTP by extending the driver to handle both
configurations.

Note that the delay after the reset has been de-asserted has been extended
to 100 ms. Through experimentation, it has been determined that the
MSM8998 instance requires a 50 ms delay between reset de-assert and sending
configuration commands for the display to work. Significantly shorter
than that, and timeouts/errors occur signaling a non-working display.
Shorter than 50 ms, but in the ball park, results in no "loud" errors, but
nothing is displayed. 100 ms is used since double the minimum should
guarantee enough delay for the device to finish whatever reset processing
seems necessary, while also providing a safe buffer incase the experimental
measurement was somehow not accurate enough for everyone.

Signed-off-by: Jeffrey Hugo <[email protected]>
---
drivers/gpu/drm/panel/panel-truly-nt35597.c | 149 +++++++++++++++-----
1 file changed, 112 insertions(+), 37 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-truly-nt35597.c b/drivers/gpu/drm/panel/panel-truly-nt35597.c
index 77e1311b7c69..5ee76acb8f49 100644
--- a/drivers/gpu/drm/panel/panel-truly-nt35597.c
+++ b/drivers/gpu/drm/panel/panel-truly-nt35597.c
@@ -49,6 +49,8 @@ struct nt35597_config {
const struct cmd_set *panel_on_cmds;
u32 num_on_cmds;
const struct drm_display_mode *dm;
+ bool dual_dsi; /* true if panel uses two dsi connections */
+ bool cmd_type; /* true if panel is command mode type, not video mode */
};

struct truly_nt35597 {
@@ -63,6 +65,7 @@ struct truly_nt35597 {
struct backlight_device *backlight;

struct mipi_dsi_device *dsi[2];
+ int num_dsi;

const struct nt35597_config *config;
bool prepared;
@@ -223,12 +226,42 @@ static const struct cmd_set qcom_2k_panel_magic_cmds[] = {
{ { 0xFB, 0x01 }, 2 },
};

+static const struct cmd_set qcom_wqhd_cmd_dsc_panel_magic_cmds[] = {
+ { { 0xff, 0x10 }, 2 },
+ { { 0xfb, 0x01 }, 2 },
+ { { 0xba, 0x03 }, 2 },
+ { { 0xe5, 0x01 }, 2 },
+ { { 0xb0, 0x03 }, 2 },
+ { { 0xff, 0x28 }, 2 },
+ { { 0x7a, 0x02 }, 2 },
+ { { 0xfb, 0x01 }, 2 },
+ { { 0xff, 0x10 }, 2 },
+ { { 0xfb, 0x01 }, 2 },
+ { { 0xc0, 0x03 }, 2 },
+ { { 0xbb, 0x10 }, 2 },
+ { { 0xff, 0xe0 }, 2 },
+ { { 0xfb, 0x01 }, 2 },
+ { { 0x6b, 0x3d }, 2 },
+ { { 0x6c, 0x3d }, 2 },
+ { { 0x6d, 0x3d }, 2 },
+ { { 0x6e, 0x3d }, 2 },
+ { { 0x6f, 0x3d }, 2 },
+ { { 0x35, 0x02 }, 2 },
+ { { 0x36, 0x72 }, 2 },
+ { { 0x37, 0x10 }, 2 },
+ { { 0x08, 0xc0 }, 2 },
+ { { 0xff, 0x24 }, 2 },
+ { { 0xfb, 0x01 }, 2 },
+ { { 0xc6, 0x06 }, 2 },
+ { { 0xff, 0x10 }, 2 },
+};
+
static int truly_dcs_write(struct drm_panel *panel, u32 command)
{
struct truly_nt35597 *ctx = panel_to_ctx(panel);
- int i, ret;
+ int i, ret = 0;

- for (i = 0; i < ARRAY_SIZE(ctx->dsi); i++) {
+ for (i = 0; i < ctx->num_dsi; i++) {
ret = mipi_dsi_dcs_write(ctx->dsi[i], command, NULL, 0);
if (ret < 0) {
DRM_DEV_ERROR(ctx->dev,
@@ -247,7 +280,7 @@ static int truly_dcs_write_buf(struct drm_panel *panel,
int ret = 0;
int i;

- for (i = 0; i < ARRAY_SIZE(ctx->dsi); i++) {
+ for (i = 0; i < ctx->num_dsi; i++) {
ret = mipi_dsi_dcs_write_buffer(ctx->dsi[i], buf, size);
if (ret < 0) {
DRM_DEV_ERROR(ctx->dev,
@@ -284,7 +317,7 @@ static int truly_35597_power_on(struct truly_nt35597 *ctx)
gpiod_set_value(ctx->reset_gpio, 1);
usleep_range(10000, 20000);
gpiod_set_value(ctx->reset_gpio, 0);
- usleep_range(10000, 20000);
+ msleep(100);

return 0;
}
@@ -342,7 +375,8 @@ static int truly_nt35597_unprepare(struct drm_panel *panel)
return 0;

ctx->dsi[0]->mode_flags = 0;
- ctx->dsi[1]->mode_flags = 0;
+ if (ctx->config->dual_dsi)
+ ctx->dsi[1]->mode_flags = 0;

ret = truly_dcs_write(panel, MIPI_DCS_SET_DISPLAY_OFF);
if (ret < 0) {
@@ -384,10 +418,12 @@ static int truly_nt35597_prepare(struct drm_panel *panel)
if (ret < 0)
return ret;

+ config = ctx->config;
+
ctx->dsi[0]->mode_flags |= MIPI_DSI_MODE_LPM;
- ctx->dsi[1]->mode_flags |= MIPI_DSI_MODE_LPM;
+ if (config->dual_dsi)
+ ctx->dsi[1]->mode_flags |= MIPI_DSI_MODE_LPM;

- config = ctx->config;
panel_on_cmds = config->panel_on_cmds;
num_cmds = config->num_on_cmds;

@@ -515,8 +551,10 @@ static int truly_nt35597_panel_add(struct truly_nt35597 *ctx)
return PTR_ERR(ctx->mode_gpio);
}

- /* dual port */
- gpiod_set_value(ctx->mode_gpio, 0);
+ if (config->dual_dsi)
+ gpiod_set_value(ctx->mode_gpio, 0);
+ else
+ gpiod_set_value(ctx->mode_gpio, 1);

drm_panel_init(&ctx->panel);
ctx->panel.dev = dev;
@@ -541,6 +579,21 @@ static const struct drm_display_mode qcom_sdm845_mtp_2k_mode = {
.flags = 0,
};

+static const struct drm_display_mode qcom_msm8998_mtp_wqhd_mode = {
+ .name = "1440x2560",
+ .clock = 113447,
+ .hdisplay = 1440,
+ .hsync_start = 1440 + 154,
+ .hsync_end = 1440 + 154 + 32,
+ .htotal = 1440 + 154 + 32 + 68,
+ .vdisplay = 2560,
+ .vsync_start = 2560 + 8,
+ .vsync_end = 2560 + 8 + 1,
+ .vtotal = 2560 + 8 + 1 + 7,
+ .vrefresh = 60,
+ .flags = 0,
+};
+
static const struct nt35597_config nt35597_dir = {
.width_mm = 74,
.height_mm = 131,
@@ -548,13 +601,24 @@ static const struct nt35597_config nt35597_dir = {
.dm = &qcom_sdm845_mtp_2k_mode,
.panel_on_cmds = qcom_2k_panel_magic_cmds,
.num_on_cmds = ARRAY_SIZE(qcom_2k_panel_magic_cmds),
+ .dual_dsi = true,
+};
+
+static const struct nt35597_config msm8998_mtp = {
+ .width_mm = 74,
+ .height_mm = 131,
+ .panel_name = "qcom_msm8998_mtp_wqhd_panel",
+ .dm = &qcom_msm8998_mtp_wqhd_mode,
+ .panel_on_cmds = qcom_wqhd_cmd_dsc_panel_magic_cmds,
+ .num_on_cmds = ARRAY_SIZE(qcom_wqhd_cmd_dsc_panel_magic_cmds),
+ .cmd_type = true,
};

static int truly_nt35597_probe(struct mipi_dsi_device *dsi)
{
struct device *dev = &dsi->dev;
struct truly_nt35597 *ctx;
- struct mipi_dsi_device *dsi1_device;
+ struct mipi_dsi_device *dsi1_device = NULL;
struct device_node *dsi1;
struct mipi_dsi_host *dsi1_host;
struct mipi_dsi_device *dsi_dev;
@@ -572,13 +636,6 @@ static int truly_nt35597_probe(struct mipi_dsi_device *dsi)
if (!ctx)
return -ENOMEM;

- /*
- * This device represents itself as one with two input ports which are
- * fed by the output ports of the two DSI controllers . The DSI0 is
- * the master controller and has most of the panel related info in its
- * child node.
- */
-
ctx->config = of_device_get_match_data(dev);

if (!ctx->config) {
@@ -586,25 +643,36 @@ static int truly_nt35597_probe(struct mipi_dsi_device *dsi)
return -ENODEV;
}

- dsi1 = of_graph_get_remote_node(dsi->dev.of_node, 1, -1);
- if (!dsi1) {
- DRM_DEV_ERROR(dev,
- "failed to get remote node for dsi1_device\n");
- return -ENODEV;
- }
+ ctx->num_dsi = 1;
+ /*
+ * This device represents itself as one with two input ports which are
+ * fed by the output ports of the two DSI controllers . The DSI0 is
+ * the master controller and has most of the panel related info in its
+ * child node.
+ */
+ if (ctx->config->dual_dsi) {
+ ctx->num_dsi = 2;

- dsi1_host = of_find_mipi_dsi_host_by_node(dsi1);
- of_node_put(dsi1);
- if (!dsi1_host) {
- DRM_DEV_ERROR(dev, "failed to find dsi host\n");
- return -EPROBE_DEFER;
- }
+ dsi1 = of_graph_get_remote_node(dsi->dev.of_node, 1, -1);
+ if (!dsi1) {
+ DRM_DEV_ERROR(dev,
+ "failed to get remote node for dsi1_device\n");
+ return -ENODEV;
+ }
+
+ dsi1_host = of_find_mipi_dsi_host_by_node(dsi1);
+ of_node_put(dsi1);
+ if (!dsi1_host) {
+ DRM_DEV_ERROR(dev, "failed to find dsi host\n");
+ return -EPROBE_DEFER;
+ }

- /* register the second DSI device */
- dsi1_device = mipi_dsi_device_register_full(dsi1_host, &info);
- if (IS_ERR(dsi1_device)) {
- DRM_DEV_ERROR(dev, "failed to create dsi device\n");
- return PTR_ERR(dsi1_device);
+ /* register the second DSI device */
+ dsi1_device = mipi_dsi_device_register_full(dsi1_host, &info);
+ if (IS_ERR(dsi1_device)) {
+ DRM_DEV_ERROR(dev, "failed to create dsi device\n");
+ return PTR_ERR(dsi1_device);
+ }
}

mipi_dsi_set_drvdata(dsi, ctx);
@@ -619,12 +687,14 @@ static int truly_nt35597_probe(struct mipi_dsi_device *dsi)
goto err_panel_add;
}

- for (i = 0; i < ARRAY_SIZE(ctx->dsi); i++) {
+ for (i = 0; i < ctx->num_dsi; i++) {
dsi_dev = ctx->dsi[i];
dsi_dev->lanes = 4;
dsi_dev->format = MIPI_DSI_FMT_RGB888;
- dsi_dev->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_LPM |
+ dsi_dev->mode_flags = MIPI_DSI_MODE_LPM |
MIPI_DSI_CLOCK_NON_CONTINUOUS;
+ if (!ctx->config->cmd_type)
+ dsi_dev->mode_flags |= MIPI_DSI_MODE_VIDEO;
ret = mipi_dsi_attach(dsi_dev);
if (ret < 0) {
DRM_DEV_ERROR(dev,
@@ -638,7 +708,8 @@ static int truly_nt35597_probe(struct mipi_dsi_device *dsi)
err_dsi_attach:
drm_panel_remove(&ctx->panel);
err_panel_add:
- mipi_dsi_device_unregister(dsi1_device);
+ if (ctx->config->dual_dsi)
+ mipi_dsi_device_unregister(dsi1_device);
return ret;
}

@@ -662,6 +733,10 @@ static const struct of_device_id truly_nt35597_of_match[] = {
.compatible = "truly,nt35597-2K-display",
.data = &nt35597_dir,
},
+ {
+ .compatible = "truly,nt35597-wqhd-cmd-dsc-display",
+ .data = &msm8998_mtp,
+ },
{ }
};
MODULE_DEVICE_TABLE(of, truly_nt35597_of_match);
--
2.17.1

2019-06-21 17:32:48

by Jeffrey Hugo

[permalink] [raw]
Subject: Re: [PATCH 0/2] MSM8998 MTP Display

On Fri, Jun 14, 2019 at 12:55 PM Jeffrey Hugo <[email protected]> wrote:
>
> Since we are trying to get the GPU and display hardware in the SoC
> supported, it would be nice to be able to put the output on the
> integrated panel for the reference platform. To do so, we need support
> in the Truly driver to support the specific panel variant for the
> MSM8998 MTP. This series adds taht support.
>
> Jeffrey Hugo (2):
> dt-bindings: display: truly: Add MSM8998 MTP panel
> drm/panel: truly: Add MSM8998 MTP support

Lets actually hold off on this series. I thought I could solve an
issue in the DSI driver, but thats not working out like how I'd hoped.
I may need to rework this.

2019-06-21 17:44:17

by Sam Ravnborg

[permalink] [raw]
Subject: Re: [PATCH 0/2] MSM8998 MTP Display

Hi Jeffrey.

On Fri, Jun 21, 2019 at 11:31:50AM -0600, Jeffrey Hugo wrote:
> On Fri, Jun 14, 2019 at 12:55 PM Jeffrey Hugo <[email protected]> wrote:
> >
> > Since we are trying to get the GPU and display hardware in the SoC
> > supported, it would be nice to be able to put the output on the
> > integrated panel for the reference platform. To do so, we need support
> > in the Truly driver to support the specific panel variant for the
> > MSM8998 MTP. This series adds taht support.
> >
> > Jeffrey Hugo (2):
> > dt-bindings: display: truly: Add MSM8998 MTP panel
> > drm/panel: truly: Add MSM8998 MTP support
>
> Lets actually hold off on this series. I thought I could solve an
> issue in the DSI driver, but thats not working out like how I'd hoped.
> I may need to rework this.

Thanks for the heads up, and good luck with it.
Despite the missing response on this patchset please do not hesitate
to post an updated version or another patchset in the future.

Sam