From: Tomi Valkeinen <[email protected]>
Hi,
These add support for DSI on V4H SoC (r8a779g0) and DP for Whitehawk
board.
I'm sending the full series for clarity.
Changes to v4:
- Changes in "clk: renesas: r8a779g0: Add display related clocks":
* Fix formatting
* Use R8A779G0_CLK_VIOBUSD2 as the source for all video related
clocks.
Tomi
Tomi Valkeinen (7):
dt-bindings: display: renesas,du: Provide bindings for r8a779g0
dt-bindings: display: bridge: renesas,dsi-csi2-tx: Add r8a779g0
clk: renesas: r8a779g0: Add display related clocks
arm64: dts: renesas: r8a779g0: Add display related nodes
arm64: dts: renesas: white-hawk-cpu: Add DP output support
drm: rcar-du: Add r8a779g0 support
drm: rcar-du: dsi: Add r8A779g0 support
.../display/bridge/renesas,dsi-csi2-tx.yaml | 3 +-
.../bindings/display/renesas,du.yaml | 2 +
.../dts/renesas/r8a779g0-white-hawk-cpu.dtsi | 94 ++++
arch/arm64/boot/dts/renesas/r8a779g0.dtsi | 130 +++++
drivers/clk/renesas/r8a779g0-cpg-mssr.c | 9 +
drivers/gpu/drm/rcar-du/rcar_du_drv.c | 22 +
drivers/gpu/drm/rcar-du/rcar_du_group.c | 2 +-
drivers/gpu/drm/rcar-du/rcar_mipi_dsi.c | 497 +++++++++++++-----
drivers/gpu/drm/rcar-du/rcar_mipi_dsi_regs.h | 6 +-
9 files changed, 635 insertions(+), 130 deletions(-)
--
2.34.1
Add support for DU on r8a779g0, which is identical to DU on r8a779a0.
Signed-off-by: Tomi Valkeinen <[email protected]>
Reviewed-by: Kieran Bingham <[email protected]>
Reviewed-by: Laurent Pinchart <[email protected]>
---
drivers/gpu/drm/rcar-du/rcar_du_drv.c | 22 ++++++++++++++++++++++
drivers/gpu/drm/rcar-du/rcar_du_group.c | 2 +-
2 files changed, 23 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.c b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
index d003e8d9e7a2..46c60a2d710d 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_drv.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
@@ -524,6 +524,27 @@ static const struct rcar_du_device_info rcar_du_r8a779a0_info = {
.dsi_clk_mask = BIT(1) | BIT(0),
};
+static const struct rcar_du_device_info rcar_du_r8a779g0_info = {
+ .gen = 4,
+ .features = RCAR_DU_FEATURE_CRTC_IRQ
+ | RCAR_DU_FEATURE_VSP1_SOURCE
+ | RCAR_DU_FEATURE_NO_BLENDING,
+ .channels_mask = BIT(1) | BIT(0),
+ .routes = {
+ /* R8A779G0 has two MIPI DSI outputs. */
+ [RCAR_DU_OUTPUT_DSI0] = {
+ .possible_crtcs = BIT(0),
+ .port = 0,
+ },
+ [RCAR_DU_OUTPUT_DSI1] = {
+ .possible_crtcs = BIT(1),
+ .port = 1,
+ },
+ },
+ .num_rpf = 5,
+ .dsi_clk_mask = BIT(1) | BIT(0),
+};
+
static const struct of_device_id rcar_du_of_table[] = {
{ .compatible = "renesas,du-r8a7742", .data = &rcar_du_r8a7790_info },
{ .compatible = "renesas,du-r8a7743", .data = &rzg1_du_r8a7743_info },
@@ -549,6 +570,7 @@ static const struct of_device_id rcar_du_of_table[] = {
{ .compatible = "renesas,du-r8a77990", .data = &rcar_du_r8a7799x_info },
{ .compatible = "renesas,du-r8a77995", .data = &rcar_du_r8a7799x_info },
{ .compatible = "renesas,du-r8a779a0", .data = &rcar_du_r8a779a0_info },
+ { .compatible = "renesas,du-r8a779g0", .data = &rcar_du_r8a779g0_info },
{ }
};
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_group.c b/drivers/gpu/drm/rcar-du/rcar_du_group.c
index 1fe8581577ed..6da01760ede5 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_group.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_group.c
@@ -107,7 +107,7 @@ static void rcar_du_group_setup_didsr(struct rcar_du_group *rgrp)
*/
rcrtc = rcdu->crtcs;
num_crtcs = rcdu->num_crtcs;
- } else if (rcdu->info->gen == 3 && rgrp->num_crtcs > 1) {
+ } else if (rcdu->info->gen >= 3 && rgrp->num_crtcs > 1) {
/*
* On Gen3 dot clocks are setup through per-group registers,
* only available when the group has two channels.
--
2.34.1
Add DSI support for r8a779g0. The main differences to r8a779a0 are in
the PLL and PHTW setups.
Signed-off-by: Tomi Valkeinen <[email protected]>
Reviewed-by: Laurent Pinchart <[email protected]>
---
drivers/gpu/drm/rcar-du/rcar_mipi_dsi.c | 497 ++++++++++++++-----
drivers/gpu/drm/rcar-du/rcar_mipi_dsi_regs.h | 6 +-
2 files changed, 375 insertions(+), 128 deletions(-)
diff --git a/drivers/gpu/drm/rcar-du/rcar_mipi_dsi.c b/drivers/gpu/drm/rcar-du/rcar_mipi_dsi.c
index a7f2b7f66a17..e10e4d4b89a2 100644
--- a/drivers/gpu/drm/rcar-du/rcar_mipi_dsi.c
+++ b/drivers/gpu/drm/rcar-du/rcar_mipi_dsi.c
@@ -9,6 +9,7 @@
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/iopoll.h>
+#include <linux/math64.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
@@ -28,6 +29,31 @@
#include "rcar_mipi_dsi.h"
#include "rcar_mipi_dsi_regs.h"
+#define MHZ(v) ((u32)((v) * 1000000U))
+
+enum rcar_mipi_dsi_hw_model {
+ RCAR_DSI_V3U,
+ RCAR_DSI_V4H,
+};
+
+struct rcar_mipi_dsi_device_info {
+ enum rcar_mipi_dsi_hw_model model;
+
+ const struct dsi_clk_config *clk_cfg;
+
+ u8 clockset2_m_offset;
+
+ u8 n_min;
+ u8 n_max;
+ u8 n_mul;
+ unsigned long fpfd_min;
+ unsigned long fpfd_max;
+ u16 m_min;
+ u16 m_max;
+ unsigned long fout_min;
+ unsigned long fout_max;
+};
+
struct rcar_mipi_dsi {
struct device *dev;
const struct rcar_mipi_dsi_device_info *info;
@@ -50,6 +76,17 @@ struct rcar_mipi_dsi {
unsigned int lanes;
};
+struct dsi_setup_info {
+ unsigned long hsfreq;
+ u16 hsfreqrange;
+
+ unsigned long fout;
+ u16 m;
+ u16 n;
+ u16 vclk_divider;
+ const struct dsi_clk_config *clkset;
+};
+
static inline struct rcar_mipi_dsi *
bridge_to_rcar_mipi_dsi(struct drm_bridge *bridge)
{
@@ -62,65 +99,78 @@ host_to_rcar_mipi_dsi(struct mipi_dsi_host *host)
return container_of(host, struct rcar_mipi_dsi, host);
}
-static const u32 phtw[] = {
- 0x01020114, 0x01600115, /* General testing */
- 0x01030116, 0x0102011d, /* General testing */
- 0x011101a4, 0x018601a4, /* 1Gbps testing */
- 0x014201a0, 0x010001a3, /* 1Gbps testing */
- 0x0101011f, /* 1Gbps testing */
-};
-
-static const u32 phtw2[] = {
- 0x010c0130, 0x010c0140, /* General testing */
- 0x010c0150, 0x010c0180, /* General testing */
- 0x010c0190,
- 0x010a0160, 0x010a0170,
- 0x01800164, 0x01800174, /* 1Gbps testing */
-};
-
static const u32 hsfreqrange_table[][2] = {
- { 80000000U, 0x00 }, { 90000000U, 0x10 }, { 100000000U, 0x20 },
- { 110000000U, 0x30 }, { 120000000U, 0x01 }, { 130000000U, 0x11 },
- { 140000000U, 0x21 }, { 150000000U, 0x31 }, { 160000000U, 0x02 },
- { 170000000U, 0x12 }, { 180000000U, 0x22 }, { 190000000U, 0x32 },
- { 205000000U, 0x03 }, { 220000000U, 0x13 }, { 235000000U, 0x23 },
- { 250000000U, 0x33 }, { 275000000U, 0x04 }, { 300000000U, 0x14 },
- { 325000000U, 0x25 }, { 350000000U, 0x35 }, { 400000000U, 0x05 },
- { 450000000U, 0x16 }, { 500000000U, 0x26 }, { 550000000U, 0x37 },
- { 600000000U, 0x07 }, { 650000000U, 0x18 }, { 700000000U, 0x28 },
- { 750000000U, 0x39 }, { 800000000U, 0x09 }, { 850000000U, 0x19 },
- { 900000000U, 0x29 }, { 950000000U, 0x3a }, { 1000000000U, 0x0a },
- { 1050000000U, 0x1a }, { 1100000000U, 0x2a }, { 1150000000U, 0x3b },
- { 1200000000U, 0x0b }, { 1250000000U, 0x1b }, { 1300000000U, 0x2b },
- { 1350000000U, 0x3c }, { 1400000000U, 0x0c }, { 1450000000U, 0x1c },
- { 1500000000U, 0x2c }, { 1550000000U, 0x3d }, { 1600000000U, 0x0d },
- { 1650000000U, 0x1d }, { 1700000000U, 0x2e }, { 1750000000U, 0x3e },
- { 1800000000U, 0x0e }, { 1850000000U, 0x1e }, { 1900000000U, 0x2f },
- { 1950000000U, 0x3f }, { 2000000000U, 0x0f }, { 2050000000U, 0x40 },
- { 2100000000U, 0x41 }, { 2150000000U, 0x42 }, { 2200000000U, 0x43 },
- { 2250000000U, 0x44 }, { 2300000000U, 0x45 }, { 2350000000U, 0x46 },
- { 2400000000U, 0x47 }, { 2450000000U, 0x48 }, { 2500000000U, 0x49 },
+ { MHZ(80), 0x00 }, { MHZ(90), 0x10 }, { MHZ(100), 0x20 },
+ { MHZ(110), 0x30 }, { MHZ(120), 0x01 }, { MHZ(130), 0x11 },
+ { MHZ(140), 0x21 }, { MHZ(150), 0x31 }, { MHZ(160), 0x02 },
+ { MHZ(170), 0x12 }, { MHZ(180), 0x22 }, { MHZ(190), 0x32 },
+ { MHZ(205), 0x03 }, { MHZ(220), 0x13 }, { MHZ(235), 0x23 },
+ { MHZ(250), 0x33 }, { MHZ(275), 0x04 }, { MHZ(300), 0x14 },
+ { MHZ(325), 0x25 }, { MHZ(350), 0x35 }, { MHZ(400), 0x05 },
+ { MHZ(450), 0x16 }, { MHZ(500), 0x26 }, { MHZ(550), 0x37 },
+ { MHZ(600), 0x07 }, { MHZ(650), 0x18 }, { MHZ(700), 0x28 },
+ { MHZ(750), 0x39 }, { MHZ(800), 0x09 }, { MHZ(850), 0x19 },
+ { MHZ(900), 0x29 }, { MHZ(950), 0x3a }, { MHZ(1000), 0x0a },
+ { MHZ(1050), 0x1a }, { MHZ(1100), 0x2a }, { MHZ(1150), 0x3b },
+ { MHZ(1200), 0x0b }, { MHZ(1250), 0x1b }, { MHZ(1300), 0x2b },
+ { MHZ(1350), 0x3c }, { MHZ(1400), 0x0c }, { MHZ(1450), 0x1c },
+ { MHZ(1500), 0x2c }, { MHZ(1550), 0x3d }, { MHZ(1600), 0x0d },
+ { MHZ(1650), 0x1d }, { MHZ(1700), 0x2e }, { MHZ(1750), 0x3e },
+ { MHZ(1800), 0x0e }, { MHZ(1850), 0x1e }, { MHZ(1900), 0x2f },
+ { MHZ(1950), 0x3f }, { MHZ(2000), 0x0f }, { MHZ(2050), 0x40 },
+ { MHZ(2100), 0x41 }, { MHZ(2150), 0x42 }, { MHZ(2200), 0x43 },
+ { MHZ(2250), 0x44 }, { MHZ(2300), 0x45 }, { MHZ(2350), 0x46 },
+ { MHZ(2400), 0x47 }, { MHZ(2450), 0x48 }, { MHZ(2500), 0x49 },
{ /* sentinel */ },
};
-struct vco_cntrl_value {
+struct dsi_clk_config {
u32 min_freq;
u32 max_freq;
- u16 value;
+ u8 vco_cntrl;
+ u8 cpbias_cntrl;
+ u8 gmp_cntrl;
+ u8 int_cntrl;
+ u8 prop_cntrl;
};
-static const struct vco_cntrl_value vco_cntrl_table[] = {
- { .min_freq = 40000000U, .max_freq = 55000000U, .value = 0x3f },
- { .min_freq = 52500000U, .max_freq = 80000000U, .value = 0x39 },
- { .min_freq = 80000000U, .max_freq = 110000000U, .value = 0x2f },
- { .min_freq = 105000000U, .max_freq = 160000000U, .value = 0x29 },
- { .min_freq = 160000000U, .max_freq = 220000000U, .value = 0x1f },
- { .min_freq = 210000000U, .max_freq = 320000000U, .value = 0x19 },
- { .min_freq = 320000000U, .max_freq = 440000000U, .value = 0x0f },
- { .min_freq = 420000000U, .max_freq = 660000000U, .value = 0x09 },
- { .min_freq = 630000000U, .max_freq = 1149000000U, .value = 0x03 },
- { .min_freq = 1100000000U, .max_freq = 1152000000U, .value = 0x01 },
- { .min_freq = 1150000000U, .max_freq = 1250000000U, .value = 0x01 },
+static const struct dsi_clk_config dsi_clk_cfg_v3u[] = {
+ { MHZ(40), MHZ(55), 0x3f, 0x10, 0x01, 0x00, 0x0b },
+ { MHZ(52.5), MHZ(80), 0x39, 0x10, 0x01, 0x00, 0x0b },
+ { MHZ(80), MHZ(110), 0x2f, 0x10, 0x01, 0x00, 0x0b },
+ { MHZ(105), MHZ(160), 0x29, 0x10, 0x01, 0x00, 0x0b },
+ { MHZ(160), MHZ(220), 0x1f, 0x10, 0x01, 0x00, 0x0b },
+ { MHZ(210), MHZ(320), 0x19, 0x10, 0x01, 0x00, 0x0b },
+ { MHZ(320), MHZ(440), 0x0f, 0x10, 0x01, 0x00, 0x0b },
+ { MHZ(420), MHZ(660), 0x09, 0x10, 0x01, 0x00, 0x0b },
+ { MHZ(630), MHZ(1149), 0x03, 0x10, 0x01, 0x00, 0x0b },
+ { MHZ(1100), MHZ(1152), 0x01, 0x10, 0x01, 0x00, 0x0b },
+ { MHZ(1150), MHZ(1250), 0x01, 0x10, 0x01, 0x00, 0x0c },
+ { /* sentinel */ },
+};
+
+static const struct dsi_clk_config dsi_clk_cfg_v4h[] = {
+ { MHZ(40), MHZ(45.31), 0x2b, 0x00, 0x00, 0x08, 0x0a },
+ { MHZ(45.31), MHZ(54.66), 0x28, 0x00, 0x00, 0x08, 0x0a },
+ { MHZ(54.66), MHZ(62.5), 0x28, 0x00, 0x00, 0x08, 0x0a },
+ { MHZ(62.5), MHZ(75), 0x27, 0x00, 0x00, 0x08, 0x0a },
+ { MHZ(75), MHZ(90.63), 0x23, 0x00, 0x00, 0x08, 0x0a },
+ { MHZ(90.63), MHZ(109.37), 0x20, 0x00, 0x00, 0x08, 0x0a },
+ { MHZ(109.37), MHZ(125), 0x20, 0x00, 0x00, 0x08, 0x0a },
+ { MHZ(125), MHZ(150), 0x1f, 0x00, 0x00, 0x08, 0x0a },
+ { MHZ(150), MHZ(181.25), 0x1b, 0x00, 0x00, 0x08, 0x0a },
+ { MHZ(181.25), MHZ(218.75), 0x18, 0x00, 0x00, 0x08, 0x0a },
+ { MHZ(218.75), MHZ(250), 0x18, 0x00, 0x00, 0x08, 0x0a },
+ { MHZ(250), MHZ(300), 0x17, 0x00, 0x00, 0x08, 0x0a },
+ { MHZ(300), MHZ(362.5), 0x13, 0x00, 0x00, 0x08, 0x0a },
+ { MHZ(362.5), MHZ(455.48), 0x10, 0x00, 0x00, 0x08, 0x0a },
+ { MHZ(455.48), MHZ(500), 0x10, 0x00, 0x00, 0x08, 0x0a },
+ { MHZ(500), MHZ(600), 0x0f, 0x00, 0x00, 0x08, 0x0a },
+ { MHZ(600), MHZ(725), 0x0b, 0x00, 0x00, 0x08, 0x0a },
+ { MHZ(725), MHZ(875), 0x08, 0x00, 0x00, 0x08, 0x0a },
+ { MHZ(875), MHZ(1000), 0x08, 0x00, 0x00, 0x08, 0x0a },
+ { MHZ(1000), MHZ(1200), 0x07, 0x00, 0x00, 0x08, 0x0a },
+ { MHZ(1200), MHZ(1250), 0x03, 0x00, 0x00, 0x08, 0x0a },
{ /* sentinel */ },
};
@@ -144,7 +194,7 @@ static void rcar_mipi_dsi_set(struct rcar_mipi_dsi *dsi, u32 reg, u32 set)
rcar_mipi_dsi_write(dsi, reg, rcar_mipi_dsi_read(dsi, reg) | set);
}
-static int rcar_mipi_dsi_phtw_test(struct rcar_mipi_dsi *dsi, u32 phtw)
+static int rcar_mipi_dsi_write_phtw(struct rcar_mipi_dsi *dsi, u32 phtw)
{
u32 status;
int ret;
@@ -163,32 +213,181 @@ static int rcar_mipi_dsi_phtw_test(struct rcar_mipi_dsi *dsi, u32 phtw)
return ret;
}
+static int rcar_mipi_dsi_write_phtw_arr(struct rcar_mipi_dsi *dsi,
+ const u32 *phtw, unsigned int size)
+{
+ for (unsigned int i = 0; i < size; i++) {
+ int ret = rcar_mipi_dsi_write_phtw(dsi, phtw[i]);
+
+ if (ret < 0)
+ return ret;
+ }
+
+ return 0;
+}
+
+#define WRITE_PHTW(...) \
+ ({ \
+ static const u32 phtw[] = { __VA_ARGS__ }; \
+ int ret; \
+ ret = rcar_mipi_dsi_write_phtw_arr(dsi, phtw, \
+ ARRAY_SIZE(phtw)); \
+ ret; \
+ })
+
+static int rcar_mipi_dsi_init_phtw_v3u(struct rcar_mipi_dsi *dsi)
+{
+ return WRITE_PHTW(0x01020114, 0x01600115, 0x01030116, 0x0102011d,
+ 0x011101a4, 0x018601a4, 0x014201a0, 0x010001a3,
+ 0x0101011f);
+}
+
+static int rcar_mipi_dsi_post_init_phtw_v3u(struct rcar_mipi_dsi *dsi)
+{
+ return WRITE_PHTW(0x010c0130, 0x010c0140, 0x010c0150, 0x010c0180,
+ 0x010c0190, 0x010a0160, 0x010a0170, 0x01800164,
+ 0x01800174);
+}
+
+static int rcar_mipi_dsi_init_phtw_v4h(struct rcar_mipi_dsi *dsi,
+ const struct dsi_setup_info *setup_info)
+{
+ int ret;
+
+ if (setup_info->hsfreq < MHZ(450)) {
+ ret = WRITE_PHTW(0x01010100, 0x011b01ac);
+ if (ret)
+ return ret;
+ }
+
+ ret = WRITE_PHTW(0x01010100, 0x01030173, 0x01000174, 0x01500175,
+ 0x01030176, 0x01040166, 0x010201ad);
+ if (ret)
+ return ret;
+
+ if (setup_info->hsfreq <= MHZ(1000))
+ ret = WRITE_PHTW(0x01020100, 0x01910170, 0x01020171,
+ 0x01110172);
+ else if (setup_info->hsfreq <= MHZ(1500))
+ ret = WRITE_PHTW(0x01020100, 0x01980170, 0x01030171,
+ 0x01100172);
+ else if (setup_info->hsfreq <= MHZ(2500))
+ ret = WRITE_PHTW(0x01020100, 0x0144016b, 0x01000172);
+ else
+ return -EINVAL;
+
+ if (ret)
+ return ret;
+
+ if (dsi->lanes <= 1) {
+ ret = WRITE_PHTW(0x01070100, 0x010e010b);
+ if (ret)
+ return ret;
+ }
+
+ if (dsi->lanes <= 2) {
+ ret = WRITE_PHTW(0x01090100, 0x010e010b);
+ if (ret)
+ return ret;
+ }
+
+ if (dsi->lanes <= 3) {
+ ret = WRITE_PHTW(0x010b0100, 0x010e010b);
+ if (ret)
+ return ret;
+ }
+
+ if (setup_info->hsfreq <= MHZ(1500)) {
+ ret = WRITE_PHTW(0x01010100, 0x01c0016e);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+static int
+rcar_mipi_dsi_post_init_phtw_v4h(struct rcar_mipi_dsi *dsi,
+ const struct dsi_setup_info *setup_info)
+{
+ u32 status;
+ int ret;
+
+ if (setup_info->hsfreq <= MHZ(1500)) {
+ WRITE_PHTW(0x01020100, 0x00000180);
+
+ ret = read_poll_timeout(rcar_mipi_dsi_read, status,
+ status & PHTR_TEST, 2000, 10000, false,
+ dsi, PHTR);
+ if (ret < 0) {
+ dev_err(dsi->dev, "failed to test PHTR\n");
+ return ret;
+ }
+
+ WRITE_PHTW(0x01010100, 0x0100016e);
+ }
+
+ return 0;
+}
+
/* -----------------------------------------------------------------------------
* Hardware Setup
*/
-struct dsi_setup_info {
- unsigned long fout;
- u16 vco_cntrl;
- u16 prop_cntrl;
- u16 hsfreqrange;
- u16 div;
- unsigned int m;
- unsigned int n;
-};
+static void rcar_mipi_dsi_pll_calc(struct rcar_mipi_dsi *dsi,
+ unsigned long fin_rate,
+ unsigned long fout_target,
+ struct dsi_setup_info *setup_info)
+{
+ unsigned int best_err = -1;
+ const struct rcar_mipi_dsi_device_info *info = dsi->info;
+
+ for (unsigned int n = info->n_min; n <= info->n_max; n++) {
+ unsigned long fpfd;
+
+ fpfd = fin_rate / n;
+
+ if (fpfd < info->fpfd_min || fpfd > info->fpfd_max)
+ continue;
+
+ for (unsigned int m = info->m_min; m <= info->m_max; m++) {
+ unsigned int err;
+ u64 fout;
+
+ fout = div64_u64((u64)fpfd * m, dsi->info->n_mul);
+
+ if (fout < info->fout_min || fout > info->fout_max)
+ continue;
+
+ fout = div64_u64(fout, setup_info->vclk_divider);
+
+ if (fout < setup_info->clkset->min_freq ||
+ fout > setup_info->clkset->max_freq)
+ continue;
+
+ err = abs((long)(fout - fout_target) * 10000 /
+ (long)fout_target);
+ if (err < best_err) {
+ setup_info->m = m;
+ setup_info->n = n;
+ setup_info->fout = (unsigned long)fout;
+ best_err = err;
+
+ if (err == 0)
+ return;
+ }
+ }
+ }
+}
static void rcar_mipi_dsi_parameters_calc(struct rcar_mipi_dsi *dsi,
struct clk *clk, unsigned long target,
struct dsi_setup_info *setup_info)
{
- const struct vco_cntrl_value *vco_cntrl;
+ const struct dsi_clk_config *clk_cfg;
unsigned long fout_target;
- unsigned long fin, fout;
- unsigned long hsfreq;
- unsigned int best_err = -1;
- unsigned int divider;
- unsigned int n;
+ unsigned long fin_rate;
unsigned int i;
unsigned int err;
@@ -198,70 +397,53 @@ static void rcar_mipi_dsi_parameters_calc(struct rcar_mipi_dsi *dsi,
*/
fout_target = target * mipi_dsi_pixel_format_to_bpp(dsi->format)
/ (2 * dsi->lanes);
- if (fout_target < 40000000 || fout_target > 1250000000)
+ if (fout_target < MHZ(40) || fout_target > MHZ(1250))
return;
- /* Find vco_cntrl */
- for (vco_cntrl = vco_cntrl_table; vco_cntrl->min_freq != 0; vco_cntrl++) {
- if (fout_target > vco_cntrl->min_freq &&
- fout_target <= vco_cntrl->max_freq) {
- setup_info->vco_cntrl = vco_cntrl->value;
- if (fout_target >= 1150000000)
- setup_info->prop_cntrl = 0x0c;
- else
- setup_info->prop_cntrl = 0x0b;
+ /* Find PLL settings */
+ for (clk_cfg = dsi->info->clk_cfg; clk_cfg->min_freq != 0; clk_cfg++) {
+ if (fout_target > clk_cfg->min_freq &&
+ fout_target <= clk_cfg->max_freq) {
+ setup_info->clkset = clk_cfg;
break;
}
}
- /* Add divider */
- setup_info->div = (setup_info->vco_cntrl & 0x30) >> 4;
+ fin_rate = clk_get_rate(clk);
+
+ switch (dsi->info->model) {
+ case RCAR_DSI_V3U:
+ default:
+ setup_info->vclk_divider = 1 << ((clk_cfg->vco_cntrl >> 4) & 0x3);
+ break;
+
+ case RCAR_DSI_V4H:
+ setup_info->vclk_divider = 1 << (((clk_cfg->vco_cntrl >> 3) & 0x7) + 1);
+ break;
+ }
+
+ rcar_mipi_dsi_pll_calc(dsi, fin_rate, fout_target, setup_info);
/* Find hsfreqrange */
- hsfreq = fout_target * 2;
+ setup_info->hsfreq = setup_info->fout * 2;
for (i = 0; i < ARRAY_SIZE(hsfreqrange_table); i++) {
- if (hsfreqrange_table[i][0] >= hsfreq) {
+ if (hsfreqrange_table[i][0] >= setup_info->hsfreq) {
setup_info->hsfreqrange = hsfreqrange_table[i][1];
break;
}
}
- /*
- * Calculate n and m for PLL clock
- * Following the HW manual the ranges of n and m are
- * n = [3-8] and m = [64-625]
- */
- fin = clk_get_rate(clk);
- divider = 1 << setup_info->div;
- for (n = 3; n < 9; n++) {
- unsigned long fpfd;
- unsigned int m;
-
- fpfd = fin / n;
-
- for (m = 64; m < 626; m++) {
- fout = fpfd * m / divider;
- err = abs((long)(fout - fout_target) * 10000 /
- (long)fout_target);
- if (err < best_err) {
- setup_info->m = m - 2;
- setup_info->n = n - 1;
- setup_info->fout = fout;
- best_err = err;
- if (err == 0)
- goto done;
- }
- }
- }
+ err = abs((long)(setup_info->fout - fout_target) * 10000 / (long)fout_target);
-done:
dev_dbg(dsi->dev,
- "%pC %lu Hz -> Fout %lu Hz (target %lu Hz, error %d.%02u%%), PLL M/N/DIV %u/%u/%u\n",
- clk, fin, setup_info->fout, fout_target, best_err / 100,
- best_err % 100, setup_info->m, setup_info->n, setup_info->div);
+ "Fout = %u * %lu / (%u * %u * %u) = %lu (target %lu Hz, error %d.%02u%%)\n",
+ setup_info->m, fin_rate, dsi->info->n_mul, setup_info->n,
+ setup_info->vclk_divider, setup_info->fout, fout_target,
+ err / 100, err % 100);
+
dev_dbg(dsi->dev,
"vco_cntrl = 0x%x\tprop_cntrl = 0x%x\thsfreqrange = 0x%x\n",
- setup_info->vco_cntrl, setup_info->prop_cntrl,
+ clk_cfg->vco_cntrl, clk_cfg->prop_cntrl,
setup_info->hsfreqrange);
}
@@ -324,7 +506,7 @@ static int rcar_mipi_dsi_startup(struct rcar_mipi_dsi *dsi,
{
struct dsi_setup_info setup_info = {};
unsigned int timeout;
- int ret, i;
+ int ret;
int dsi_format;
u32 phy_setup;
u32 clockset2, clockset3;
@@ -360,10 +542,19 @@ static int rcar_mipi_dsi_startup(struct rcar_mipi_dsi *dsi,
phy_setup |= PHYSETUP_HSFREQRANGE(setup_info.hsfreqrange);
rcar_mipi_dsi_write(dsi, PHYSETUP, phy_setup);
- for (i = 0; i < ARRAY_SIZE(phtw); i++) {
- ret = rcar_mipi_dsi_phtw_test(dsi, phtw[i]);
+ switch (dsi->info->model) {
+ case RCAR_DSI_V3U:
+ default:
+ ret = rcar_mipi_dsi_init_phtw_v3u(dsi);
if (ret < 0)
return ret;
+ break;
+
+ case RCAR_DSI_V4H:
+ ret = rcar_mipi_dsi_init_phtw_v4h(dsi, &setup_info);
+ if (ret < 0)
+ return ret;
+ break;
}
/* PLL Clock Setting */
@@ -371,12 +562,13 @@ static int rcar_mipi_dsi_startup(struct rcar_mipi_dsi *dsi,
rcar_mipi_dsi_set(dsi, CLOCKSET1, CLOCKSET1_SHADOW_CLEAR);
rcar_mipi_dsi_clr(dsi, CLOCKSET1, CLOCKSET1_SHADOW_CLEAR);
- clockset2 = CLOCKSET2_M(setup_info.m) | CLOCKSET2_N(setup_info.n)
- | CLOCKSET2_VCO_CNTRL(setup_info.vco_cntrl);
- clockset3 = CLOCKSET3_PROP_CNTRL(setup_info.prop_cntrl)
- | CLOCKSET3_INT_CNTRL(0)
- | CLOCKSET3_CPBIAS_CNTRL(0x10)
- | CLOCKSET3_GMP_CNTRL(1);
+ clockset2 = CLOCKSET2_M(setup_info.m - dsi->info->clockset2_m_offset)
+ | CLOCKSET2_N(setup_info.n - 1)
+ | CLOCKSET2_VCO_CNTRL(setup_info.clkset->vco_cntrl);
+ clockset3 = CLOCKSET3_PROP_CNTRL(setup_info.clkset->prop_cntrl)
+ | CLOCKSET3_INT_CNTRL(setup_info.clkset->int_cntrl)
+ | CLOCKSET3_CPBIAS_CNTRL(setup_info.clkset->cpbias_cntrl)
+ | CLOCKSET3_GMP_CNTRL(setup_info.clkset->gmp_cntrl);
rcar_mipi_dsi_write(dsi, CLOCKSET2, clockset2);
rcar_mipi_dsi_write(dsi, CLOCKSET3, clockset3);
@@ -407,10 +599,19 @@ static int rcar_mipi_dsi_startup(struct rcar_mipi_dsi *dsi,
return -ETIMEDOUT;
}
- for (i = 0; i < ARRAY_SIZE(phtw2); i++) {
- ret = rcar_mipi_dsi_phtw_test(dsi, phtw2[i]);
+ switch (dsi->info->model) {
+ case RCAR_DSI_V3U:
+ default:
+ ret = rcar_mipi_dsi_post_init_phtw_v3u(dsi);
+ if (ret < 0)
+ return ret;
+ break;
+
+ case RCAR_DSI_V4H:
+ ret = rcar_mipi_dsi_post_init_phtw_v4h(dsi, &setup_info);
if (ret < 0)
return ret;
+ break;
}
/* Enable DOT clock */
@@ -427,8 +628,19 @@ static int rcar_mipi_dsi_startup(struct rcar_mipi_dsi *dsi,
dev_warn(dsi->dev, "unsupported format");
return -EINVAL;
}
- vclkset |= VCLKSET_COLOR_RGB | VCLKSET_DIV(setup_info.div)
- | VCLKSET_LANE(dsi->lanes - 1);
+
+ vclkset |= VCLKSET_COLOR_RGB | VCLKSET_LANE(dsi->lanes - 1);
+
+ switch (dsi->info->model) {
+ case RCAR_DSI_V3U:
+ default:
+ vclkset |= VCLKSET_DIV_V3U(__ffs(setup_info.vclk_divider));
+ break;
+
+ case RCAR_DSI_V4H:
+ vclkset |= VCLKSET_DIV_V4H(__ffs(setup_info.vclk_divider) - 1);
+ break;
+ }
rcar_mipi_dsi_write(dsi, VCLKSET, vclkset);
@@ -841,8 +1053,39 @@ static int rcar_mipi_dsi_remove(struct platform_device *pdev)
return 0;
}
+static const struct rcar_mipi_dsi_device_info v3u_data = {
+ .model = RCAR_DSI_V3U,
+ .clk_cfg = dsi_clk_cfg_v3u,
+ .clockset2_m_offset = 2,
+ .n_min = 3,
+ .n_max = 8,
+ .n_mul = 1,
+ .fpfd_min = MHZ(2),
+ .fpfd_max = MHZ(8),
+ .m_min = 64,
+ .m_max = 625,
+ .fout_min = MHZ(320),
+ .fout_max = MHZ(1250),
+};
+
+static const struct rcar_mipi_dsi_device_info v4h_data = {
+ .model = RCAR_DSI_V4H,
+ .clk_cfg = dsi_clk_cfg_v4h,
+ .clockset2_m_offset = 0,
+ .n_min = 1,
+ .n_max = 8,
+ .n_mul = 2,
+ .fpfd_min = MHZ(8),
+ .fpfd_max = MHZ(24),
+ .m_min = 167,
+ .m_max = 1000,
+ .fout_min = MHZ(2000),
+ .fout_max = MHZ(4000),
+};
+
static const struct of_device_id rcar_mipi_dsi_of_table[] = {
- { .compatible = "renesas,r8a779a0-dsi-csi2-tx" },
+ { .compatible = "renesas,r8a779a0-dsi-csi2-tx", .data = &v3u_data },
+ { .compatible = "renesas,r8a779g0-dsi-csi2-tx", .data = &v4h_data },
{ }
};
diff --git a/drivers/gpu/drm/rcar-du/rcar_mipi_dsi_regs.h b/drivers/gpu/drm/rcar-du/rcar_mipi_dsi_regs.h
index 2eaca54636f3..f8114d11f2d1 100644
--- a/drivers/gpu/drm/rcar-du/rcar_mipi_dsi_regs.h
+++ b/drivers/gpu/drm/rcar-du/rcar_mipi_dsi_regs.h
@@ -122,7 +122,8 @@
#define VCLKSET_CKEN (1 << 16)
#define VCLKSET_COLOR_RGB (0 << 8)
#define VCLKSET_COLOR_YCC (1 << 8)
-#define VCLKSET_DIV(x) (((x) & 0x3) << 4)
+#define VCLKSET_DIV_V3U(x) (((x) & 0x3) << 4)
+#define VCLKSET_DIV_V4H(x) (((x) & 0x7) << 4)
#define VCLKSET_BPP_16 (0 << 2)
#define VCLKSET_BPP_18 (1 << 2)
#define VCLKSET_BPP_18L (2 << 2)
@@ -166,6 +167,9 @@
#define PHTW_CWEN (1 << 8)
#define PHTW_TESTDIN_CODE(x) (((x) & 0xff) << 0)
+#define PHTR 0x1038
+#define PHTR_TEST (1 << 16)
+
#define PHTC 0x103c
#define PHTC_TESTCLR (1 << 0)
--
2.34.1
Add DT nodes needed for the mini DP connector. The DP is driven by
sn65dsi86, which in turn gets the pixel data from the SoC via DSI.
Signed-off-by: Tomi Valkeinen <[email protected]>
Reviewed-by: Kieran Bingham <[email protected]>
Reviewed-by: Laurent Pinchart <[email protected]>
---
.../dts/renesas/r8a779g0-white-hawk-cpu.dtsi | 94 +++++++++++++++++++
1 file changed, 94 insertions(+)
diff --git a/arch/arm64/boot/dts/renesas/r8a779g0-white-hawk-cpu.dtsi b/arch/arm64/boot/dts/renesas/r8a779g0-white-hawk-cpu.dtsi
index c10740aee9f6..8aab859aac7a 100644
--- a/arch/arm64/boot/dts/renesas/r8a779g0-white-hawk-cpu.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a779g0-white-hawk-cpu.dtsi
@@ -97,6 +97,15 @@ memory@600000000 {
reg = <0x6 0x00000000 0x1 0x00000000>;
};
+ reg_1p2v: regulator-1p2v {
+ compatible = "regulator-fixed";
+ regulator-name = "fixed-1.2V";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
reg_1p8v: regulator-1p8v {
compatible = "regulator-fixed";
regulator-name = "fixed-1.8V";
@@ -114,6 +123,24 @@ reg_3p3v: regulator-3p3v {
regulator-boot-on;
regulator-always-on;
};
+
+ mini-dp-con {
+ compatible = "dp-connector";
+ label = "CN5";
+ type = "mini";
+
+ port {
+ mini_dp_con_in: endpoint {
+ remote-endpoint = <&sn65dsi86_out>;
+ };
+ };
+ };
+
+ sn65dsi86_refclk: clk-x6 {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <38400000>;
+ };
};
&avb0 {
@@ -134,6 +161,23 @@ phy0: ethernet-phy@0 {
};
};
+&dsi0 {
+ status = "okay";
+
+ ports {
+ port@1 {
+ dsi0_out: endpoint {
+ remote-endpoint = <&sn65dsi86_in>;
+ data-lanes = <1 2 3 4>;
+ };
+ };
+ };
+};
+
+&du {
+ status = "okay";
+};
+
&extal_clk {
clock-frequency = <16666666>;
};
@@ -172,6 +216,51 @@ eeprom@50 {
};
};
+&i2c1 {
+ pinctrl-0 = <&i2c1_pins>;
+ pinctrl-names = "default";
+
+ status = "okay";
+ clock-frequency = <400000>;
+
+ bridge@2c {
+ compatible = "ti,sn65dsi86";
+ reg = <0x2c>;
+
+ clocks = <&sn65dsi86_refclk>;
+ clock-names = "refclk";
+
+ interrupt-parent = <&intc_ex>;
+ interrupts = <0 IRQ_TYPE_LEVEL_HIGH>;
+
+ enable-gpios = <&gpio1 26 GPIO_ACTIVE_HIGH>;
+
+ vccio-supply = <®_1p8v>;
+ vpll-supply = <®_1p8v>;
+ vcca-supply = <®_1p2v>;
+ vcc-supply = <®_1p2v>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ sn65dsi86_in: endpoint {
+ remote-endpoint = <&dsi0_out>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+ sn65dsi86_out: endpoint {
+ remote-endpoint = <&mini_dp_con_in>;
+ };
+ };
+ };
+ };
+};
+
&mmc0 {
pinctrl-0 = <&mmc_pins>;
pinctrl-1 = <&mmc_pins>;
@@ -221,6 +310,11 @@ i2c0_pins: i2c0 {
function = "i2c0";
};
+ i2c1_pins: i2c1 {
+ groups = "i2c1";
+ function = "i2c1";
+ };
+
keys_pins: keys {
pins = "GP_5_0", "GP_5_1", "GP_5_2";
bias-pull-up;
--
2.34.1
Quoting Tomi Valkeinen (2022-12-01 09:56:31)
> Add DSI support for r8a779g0. The main differences to r8a779a0 are in
> the PLL and PHTW setups.
>
> Signed-off-by: Tomi Valkeinen <[email protected]>
> Reviewed-by: Laurent Pinchart <[email protected]>
Now that the differences I saw about the PHTW values are understood, I'm
happy.
I like the MHZ() macro for readability too.
Reviewed-by: Kieran Bingham <[email protected]>
> ---
> drivers/gpu/drm/rcar-du/rcar_mipi_dsi.c | 497 ++++++++++++++-----
> drivers/gpu/drm/rcar-du/rcar_mipi_dsi_regs.h | 6 +-
> 2 files changed, 375 insertions(+), 128 deletions(-)
>
> diff --git a/drivers/gpu/drm/rcar-du/rcar_mipi_dsi.c b/drivers/gpu/drm/rcar-du/rcar_mipi_dsi.c
> index a7f2b7f66a17..e10e4d4b89a2 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_mipi_dsi.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_mipi_dsi.c
> @@ -9,6 +9,7 @@
> #include <linux/delay.h>
> #include <linux/io.h>
> #include <linux/iopoll.h>
> +#include <linux/math64.h>
> #include <linux/module.h>
> #include <linux/of.h>
> #include <linux/of_device.h>
> @@ -28,6 +29,31 @@
> #include "rcar_mipi_dsi.h"
> #include "rcar_mipi_dsi_regs.h"
>
> +#define MHZ(v) ((u32)((v) * 1000000U))
> +
> +enum rcar_mipi_dsi_hw_model {
> + RCAR_DSI_V3U,
> + RCAR_DSI_V4H,
> +};
> +
> +struct rcar_mipi_dsi_device_info {
> + enum rcar_mipi_dsi_hw_model model;
> +
> + const struct dsi_clk_config *clk_cfg;
> +
> + u8 clockset2_m_offset;
> +
> + u8 n_min;
> + u8 n_max;
> + u8 n_mul;
> + unsigned long fpfd_min;
> + unsigned long fpfd_max;
> + u16 m_min;
> + u16 m_max;
> + unsigned long fout_min;
> + unsigned long fout_max;
> +};
> +
> struct rcar_mipi_dsi {
> struct device *dev;
> const struct rcar_mipi_dsi_device_info *info;
> @@ -50,6 +76,17 @@ struct rcar_mipi_dsi {
> unsigned int lanes;
> };
>
> +struct dsi_setup_info {
> + unsigned long hsfreq;
> + u16 hsfreqrange;
> +
> + unsigned long fout;
> + u16 m;
> + u16 n;
> + u16 vclk_divider;
> + const struct dsi_clk_config *clkset;
> +};
> +
> static inline struct rcar_mipi_dsi *
> bridge_to_rcar_mipi_dsi(struct drm_bridge *bridge)
> {
> @@ -62,65 +99,78 @@ host_to_rcar_mipi_dsi(struct mipi_dsi_host *host)
> return container_of(host, struct rcar_mipi_dsi, host);
> }
>
> -static const u32 phtw[] = {
> - 0x01020114, 0x01600115, /* General testing */
> - 0x01030116, 0x0102011d, /* General testing */
> - 0x011101a4, 0x018601a4, /* 1Gbps testing */
> - 0x014201a0, 0x010001a3, /* 1Gbps testing */
> - 0x0101011f, /* 1Gbps testing */
> -};
> -
> -static const u32 phtw2[] = {
> - 0x010c0130, 0x010c0140, /* General testing */
> - 0x010c0150, 0x010c0180, /* General testing */
> - 0x010c0190,
> - 0x010a0160, 0x010a0170,
> - 0x01800164, 0x01800174, /* 1Gbps testing */
> -};
> -
> static const u32 hsfreqrange_table[][2] = {
> - { 80000000U, 0x00 }, { 90000000U, 0x10 }, { 100000000U, 0x20 },
> - { 110000000U, 0x30 }, { 120000000U, 0x01 }, { 130000000U, 0x11 },
> - { 140000000U, 0x21 }, { 150000000U, 0x31 }, { 160000000U, 0x02 },
> - { 170000000U, 0x12 }, { 180000000U, 0x22 }, { 190000000U, 0x32 },
> - { 205000000U, 0x03 }, { 220000000U, 0x13 }, { 235000000U, 0x23 },
> - { 250000000U, 0x33 }, { 275000000U, 0x04 }, { 300000000U, 0x14 },
> - { 325000000U, 0x25 }, { 350000000U, 0x35 }, { 400000000U, 0x05 },
> - { 450000000U, 0x16 }, { 500000000U, 0x26 }, { 550000000U, 0x37 },
> - { 600000000U, 0x07 }, { 650000000U, 0x18 }, { 700000000U, 0x28 },
> - { 750000000U, 0x39 }, { 800000000U, 0x09 }, { 850000000U, 0x19 },
> - { 900000000U, 0x29 }, { 950000000U, 0x3a }, { 1000000000U, 0x0a },
> - { 1050000000U, 0x1a }, { 1100000000U, 0x2a }, { 1150000000U, 0x3b },
> - { 1200000000U, 0x0b }, { 1250000000U, 0x1b }, { 1300000000U, 0x2b },
> - { 1350000000U, 0x3c }, { 1400000000U, 0x0c }, { 1450000000U, 0x1c },
> - { 1500000000U, 0x2c }, { 1550000000U, 0x3d }, { 1600000000U, 0x0d },
> - { 1650000000U, 0x1d }, { 1700000000U, 0x2e }, { 1750000000U, 0x3e },
> - { 1800000000U, 0x0e }, { 1850000000U, 0x1e }, { 1900000000U, 0x2f },
> - { 1950000000U, 0x3f }, { 2000000000U, 0x0f }, { 2050000000U, 0x40 },
> - { 2100000000U, 0x41 }, { 2150000000U, 0x42 }, { 2200000000U, 0x43 },
> - { 2250000000U, 0x44 }, { 2300000000U, 0x45 }, { 2350000000U, 0x46 },
> - { 2400000000U, 0x47 }, { 2450000000U, 0x48 }, { 2500000000U, 0x49 },
> + { MHZ(80), 0x00 }, { MHZ(90), 0x10 }, { MHZ(100), 0x20 },
> + { MHZ(110), 0x30 }, { MHZ(120), 0x01 }, { MHZ(130), 0x11 },
> + { MHZ(140), 0x21 }, { MHZ(150), 0x31 }, { MHZ(160), 0x02 },
> + { MHZ(170), 0x12 }, { MHZ(180), 0x22 }, { MHZ(190), 0x32 },
> + { MHZ(205), 0x03 }, { MHZ(220), 0x13 }, { MHZ(235), 0x23 },
> + { MHZ(250), 0x33 }, { MHZ(275), 0x04 }, { MHZ(300), 0x14 },
> + { MHZ(325), 0x25 }, { MHZ(350), 0x35 }, { MHZ(400), 0x05 },
> + { MHZ(450), 0x16 }, { MHZ(500), 0x26 }, { MHZ(550), 0x37 },
> + { MHZ(600), 0x07 }, { MHZ(650), 0x18 }, { MHZ(700), 0x28 },
> + { MHZ(750), 0x39 }, { MHZ(800), 0x09 }, { MHZ(850), 0x19 },
> + { MHZ(900), 0x29 }, { MHZ(950), 0x3a }, { MHZ(1000), 0x0a },
> + { MHZ(1050), 0x1a }, { MHZ(1100), 0x2a }, { MHZ(1150), 0x3b },
> + { MHZ(1200), 0x0b }, { MHZ(1250), 0x1b }, { MHZ(1300), 0x2b },
> + { MHZ(1350), 0x3c }, { MHZ(1400), 0x0c }, { MHZ(1450), 0x1c },
> + { MHZ(1500), 0x2c }, { MHZ(1550), 0x3d }, { MHZ(1600), 0x0d },
> + { MHZ(1650), 0x1d }, { MHZ(1700), 0x2e }, { MHZ(1750), 0x3e },
> + { MHZ(1800), 0x0e }, { MHZ(1850), 0x1e }, { MHZ(1900), 0x2f },
> + { MHZ(1950), 0x3f }, { MHZ(2000), 0x0f }, { MHZ(2050), 0x40 },
> + { MHZ(2100), 0x41 }, { MHZ(2150), 0x42 }, { MHZ(2200), 0x43 },
> + { MHZ(2250), 0x44 }, { MHZ(2300), 0x45 }, { MHZ(2350), 0x46 },
> + { MHZ(2400), 0x47 }, { MHZ(2450), 0x48 }, { MHZ(2500), 0x49 },
> { /* sentinel */ },
> };
>
> -struct vco_cntrl_value {
> +struct dsi_clk_config {
> u32 min_freq;
> u32 max_freq;
> - u16 value;
> + u8 vco_cntrl;
> + u8 cpbias_cntrl;
> + u8 gmp_cntrl;
> + u8 int_cntrl;
> + u8 prop_cntrl;
> };
>
> -static const struct vco_cntrl_value vco_cntrl_table[] = {
> - { .min_freq = 40000000U, .max_freq = 55000000U, .value = 0x3f },
> - { .min_freq = 52500000U, .max_freq = 80000000U, .value = 0x39 },
> - { .min_freq = 80000000U, .max_freq = 110000000U, .value = 0x2f },
> - { .min_freq = 105000000U, .max_freq = 160000000U, .value = 0x29 },
> - { .min_freq = 160000000U, .max_freq = 220000000U, .value = 0x1f },
> - { .min_freq = 210000000U, .max_freq = 320000000U, .value = 0x19 },
> - { .min_freq = 320000000U, .max_freq = 440000000U, .value = 0x0f },
> - { .min_freq = 420000000U, .max_freq = 660000000U, .value = 0x09 },
> - { .min_freq = 630000000U, .max_freq = 1149000000U, .value = 0x03 },
> - { .min_freq = 1100000000U, .max_freq = 1152000000U, .value = 0x01 },
> - { .min_freq = 1150000000U, .max_freq = 1250000000U, .value = 0x01 },
> +static const struct dsi_clk_config dsi_clk_cfg_v3u[] = {
> + { MHZ(40), MHZ(55), 0x3f, 0x10, 0x01, 0x00, 0x0b },
> + { MHZ(52.5), MHZ(80), 0x39, 0x10, 0x01, 0x00, 0x0b },
> + { MHZ(80), MHZ(110), 0x2f, 0x10, 0x01, 0x00, 0x0b },
> + { MHZ(105), MHZ(160), 0x29, 0x10, 0x01, 0x00, 0x0b },
> + { MHZ(160), MHZ(220), 0x1f, 0x10, 0x01, 0x00, 0x0b },
> + { MHZ(210), MHZ(320), 0x19, 0x10, 0x01, 0x00, 0x0b },
> + { MHZ(320), MHZ(440), 0x0f, 0x10, 0x01, 0x00, 0x0b },
> + { MHZ(420), MHZ(660), 0x09, 0x10, 0x01, 0x00, 0x0b },
> + { MHZ(630), MHZ(1149), 0x03, 0x10, 0x01, 0x00, 0x0b },
> + { MHZ(1100), MHZ(1152), 0x01, 0x10, 0x01, 0x00, 0x0b },
> + { MHZ(1150), MHZ(1250), 0x01, 0x10, 0x01, 0x00, 0x0c },
> + { /* sentinel */ },
> +};
> +
> +static const struct dsi_clk_config dsi_clk_cfg_v4h[] = {
> + { MHZ(40), MHZ(45.31), 0x2b, 0x00, 0x00, 0x08, 0x0a },
> + { MHZ(45.31), MHZ(54.66), 0x28, 0x00, 0x00, 0x08, 0x0a },
> + { MHZ(54.66), MHZ(62.5), 0x28, 0x00, 0x00, 0x08, 0x0a },
> + { MHZ(62.5), MHZ(75), 0x27, 0x00, 0x00, 0x08, 0x0a },
> + { MHZ(75), MHZ(90.63), 0x23, 0x00, 0x00, 0x08, 0x0a },
> + { MHZ(90.63), MHZ(109.37), 0x20, 0x00, 0x00, 0x08, 0x0a },
> + { MHZ(109.37), MHZ(125), 0x20, 0x00, 0x00, 0x08, 0x0a },
> + { MHZ(125), MHZ(150), 0x1f, 0x00, 0x00, 0x08, 0x0a },
> + { MHZ(150), MHZ(181.25), 0x1b, 0x00, 0x00, 0x08, 0x0a },
> + { MHZ(181.25), MHZ(218.75), 0x18, 0x00, 0x00, 0x08, 0x0a },
> + { MHZ(218.75), MHZ(250), 0x18, 0x00, 0x00, 0x08, 0x0a },
> + { MHZ(250), MHZ(300), 0x17, 0x00, 0x00, 0x08, 0x0a },
> + { MHZ(300), MHZ(362.5), 0x13, 0x00, 0x00, 0x08, 0x0a },
> + { MHZ(362.5), MHZ(455.48), 0x10, 0x00, 0x00, 0x08, 0x0a },
> + { MHZ(455.48), MHZ(500), 0x10, 0x00, 0x00, 0x08, 0x0a },
> + { MHZ(500), MHZ(600), 0x0f, 0x00, 0x00, 0x08, 0x0a },
> + { MHZ(600), MHZ(725), 0x0b, 0x00, 0x00, 0x08, 0x0a },
> + { MHZ(725), MHZ(875), 0x08, 0x00, 0x00, 0x08, 0x0a },
> + { MHZ(875), MHZ(1000), 0x08, 0x00, 0x00, 0x08, 0x0a },
> + { MHZ(1000), MHZ(1200), 0x07, 0x00, 0x00, 0x08, 0x0a },
> + { MHZ(1200), MHZ(1250), 0x03, 0x00, 0x00, 0x08, 0x0a },
> { /* sentinel */ },
> };
>
> @@ -144,7 +194,7 @@ static void rcar_mipi_dsi_set(struct rcar_mipi_dsi *dsi, u32 reg, u32 set)
> rcar_mipi_dsi_write(dsi, reg, rcar_mipi_dsi_read(dsi, reg) | set);
> }
>
> -static int rcar_mipi_dsi_phtw_test(struct rcar_mipi_dsi *dsi, u32 phtw)
> +static int rcar_mipi_dsi_write_phtw(struct rcar_mipi_dsi *dsi, u32 phtw)
> {
> u32 status;
> int ret;
> @@ -163,32 +213,181 @@ static int rcar_mipi_dsi_phtw_test(struct rcar_mipi_dsi *dsi, u32 phtw)
> return ret;
> }
>
> +static int rcar_mipi_dsi_write_phtw_arr(struct rcar_mipi_dsi *dsi,
> + const u32 *phtw, unsigned int size)
> +{
> + for (unsigned int i = 0; i < size; i++) {
> + int ret = rcar_mipi_dsi_write_phtw(dsi, phtw[i]);
> +
> + if (ret < 0)
> + return ret;
> + }
> +
> + return 0;
> +}
> +
> +#define WRITE_PHTW(...) \
> + ({ \
> + static const u32 phtw[] = { __VA_ARGS__ }; \
> + int ret; \
> + ret = rcar_mipi_dsi_write_phtw_arr(dsi, phtw, \
> + ARRAY_SIZE(phtw)); \
> + ret; \
> + })
> +
> +static int rcar_mipi_dsi_init_phtw_v3u(struct rcar_mipi_dsi *dsi)
> +{
> + return WRITE_PHTW(0x01020114, 0x01600115, 0x01030116, 0x0102011d,
> + 0x011101a4, 0x018601a4, 0x014201a0, 0x010001a3,
> + 0x0101011f);
> +}
> +
> +static int rcar_mipi_dsi_post_init_phtw_v3u(struct rcar_mipi_dsi *dsi)
> +{
> + return WRITE_PHTW(0x010c0130, 0x010c0140, 0x010c0150, 0x010c0180,
> + 0x010c0190, 0x010a0160, 0x010a0170, 0x01800164,
> + 0x01800174);
> +}
> +
> +static int rcar_mipi_dsi_init_phtw_v4h(struct rcar_mipi_dsi *dsi,
> + const struct dsi_setup_info *setup_info)
> +{
> + int ret;
> +
> + if (setup_info->hsfreq < MHZ(450)) {
> + ret = WRITE_PHTW(0x01010100, 0x011b01ac);
> + if (ret)
> + return ret;
> + }
> +
> + ret = WRITE_PHTW(0x01010100, 0x01030173, 0x01000174, 0x01500175,
> + 0x01030176, 0x01040166, 0x010201ad);
> + if (ret)
> + return ret;
> +
> + if (setup_info->hsfreq <= MHZ(1000))
> + ret = WRITE_PHTW(0x01020100, 0x01910170, 0x01020171,
> + 0x01110172);
> + else if (setup_info->hsfreq <= MHZ(1500))
> + ret = WRITE_PHTW(0x01020100, 0x01980170, 0x01030171,
> + 0x01100172);
> + else if (setup_info->hsfreq <= MHZ(2500))
> + ret = WRITE_PHTW(0x01020100, 0x0144016b, 0x01000172);
> + else
> + return -EINVAL;
> +
> + if (ret)
> + return ret;
> +
> + if (dsi->lanes <= 1) {
> + ret = WRITE_PHTW(0x01070100, 0x010e010b);
> + if (ret)
> + return ret;
> + }
> +
> + if (dsi->lanes <= 2) {
> + ret = WRITE_PHTW(0x01090100, 0x010e010b);
> + if (ret)
> + return ret;
> + }
> +
> + if (dsi->lanes <= 3) {
> + ret = WRITE_PHTW(0x010b0100, 0x010e010b);
> + if (ret)
> + return ret;
> + }
> +
> + if (setup_info->hsfreq <= MHZ(1500)) {
> + ret = WRITE_PHTW(0x01010100, 0x01c0016e);
> + if (ret)
> + return ret;
> + }
> +
> + return 0;
> +}
> +
> +static int
> +rcar_mipi_dsi_post_init_phtw_v4h(struct rcar_mipi_dsi *dsi,
> + const struct dsi_setup_info *setup_info)
> +{
> + u32 status;
> + int ret;
> +
> + if (setup_info->hsfreq <= MHZ(1500)) {
> + WRITE_PHTW(0x01020100, 0x00000180);
> +
> + ret = read_poll_timeout(rcar_mipi_dsi_read, status,
> + status & PHTR_TEST, 2000, 10000, false,
> + dsi, PHTR);
> + if (ret < 0) {
> + dev_err(dsi->dev, "failed to test PHTR\n");
> + return ret;
> + }
> +
> + WRITE_PHTW(0x01010100, 0x0100016e);
> + }
> +
> + return 0;
> +}
> +
> /* -----------------------------------------------------------------------------
> * Hardware Setup
> */
>
> -struct dsi_setup_info {
> - unsigned long fout;
> - u16 vco_cntrl;
> - u16 prop_cntrl;
> - u16 hsfreqrange;
> - u16 div;
> - unsigned int m;
> - unsigned int n;
> -};
> +static void rcar_mipi_dsi_pll_calc(struct rcar_mipi_dsi *dsi,
> + unsigned long fin_rate,
> + unsigned long fout_target,
> + struct dsi_setup_info *setup_info)
> +{
> + unsigned int best_err = -1;
> + const struct rcar_mipi_dsi_device_info *info = dsi->info;
> +
> + for (unsigned int n = info->n_min; n <= info->n_max; n++) {
> + unsigned long fpfd;
> +
> + fpfd = fin_rate / n;
> +
> + if (fpfd < info->fpfd_min || fpfd > info->fpfd_max)
> + continue;
> +
> + for (unsigned int m = info->m_min; m <= info->m_max; m++) {
> + unsigned int err;
> + u64 fout;
> +
> + fout = div64_u64((u64)fpfd * m, dsi->info->n_mul);
> +
> + if (fout < info->fout_min || fout > info->fout_max)
> + continue;
> +
> + fout = div64_u64(fout, setup_info->vclk_divider);
> +
> + if (fout < setup_info->clkset->min_freq ||
> + fout > setup_info->clkset->max_freq)
> + continue;
> +
> + err = abs((long)(fout - fout_target) * 10000 /
> + (long)fout_target);
> + if (err < best_err) {
> + setup_info->m = m;
> + setup_info->n = n;
> + setup_info->fout = (unsigned long)fout;
> + best_err = err;
> +
> + if (err == 0)
> + return;
> + }
> + }
> + }
> +}
>
> static void rcar_mipi_dsi_parameters_calc(struct rcar_mipi_dsi *dsi,
> struct clk *clk, unsigned long target,
> struct dsi_setup_info *setup_info)
> {
>
> - const struct vco_cntrl_value *vco_cntrl;
> + const struct dsi_clk_config *clk_cfg;
> unsigned long fout_target;
> - unsigned long fin, fout;
> - unsigned long hsfreq;
> - unsigned int best_err = -1;
> - unsigned int divider;
> - unsigned int n;
> + unsigned long fin_rate;
> unsigned int i;
> unsigned int err;
>
> @@ -198,70 +397,53 @@ static void rcar_mipi_dsi_parameters_calc(struct rcar_mipi_dsi *dsi,
> */
> fout_target = target * mipi_dsi_pixel_format_to_bpp(dsi->format)
> / (2 * dsi->lanes);
> - if (fout_target < 40000000 || fout_target > 1250000000)
> + if (fout_target < MHZ(40) || fout_target > MHZ(1250))
> return;
>
> - /* Find vco_cntrl */
> - for (vco_cntrl = vco_cntrl_table; vco_cntrl->min_freq != 0; vco_cntrl++) {
> - if (fout_target > vco_cntrl->min_freq &&
> - fout_target <= vco_cntrl->max_freq) {
> - setup_info->vco_cntrl = vco_cntrl->value;
> - if (fout_target >= 1150000000)
> - setup_info->prop_cntrl = 0x0c;
> - else
> - setup_info->prop_cntrl = 0x0b;
> + /* Find PLL settings */
> + for (clk_cfg = dsi->info->clk_cfg; clk_cfg->min_freq != 0; clk_cfg++) {
> + if (fout_target > clk_cfg->min_freq &&
> + fout_target <= clk_cfg->max_freq) {
> + setup_info->clkset = clk_cfg;
> break;
> }
> }
>
> - /* Add divider */
> - setup_info->div = (setup_info->vco_cntrl & 0x30) >> 4;
> + fin_rate = clk_get_rate(clk);
> +
> + switch (dsi->info->model) {
> + case RCAR_DSI_V3U:
> + default:
> + setup_info->vclk_divider = 1 << ((clk_cfg->vco_cntrl >> 4) & 0x3);
> + break;
> +
> + case RCAR_DSI_V4H:
> + setup_info->vclk_divider = 1 << (((clk_cfg->vco_cntrl >> 3) & 0x7) + 1);
> + break;
> + }
> +
> + rcar_mipi_dsi_pll_calc(dsi, fin_rate, fout_target, setup_info);
>
> /* Find hsfreqrange */
> - hsfreq = fout_target * 2;
> + setup_info->hsfreq = setup_info->fout * 2;
> for (i = 0; i < ARRAY_SIZE(hsfreqrange_table); i++) {
> - if (hsfreqrange_table[i][0] >= hsfreq) {
> + if (hsfreqrange_table[i][0] >= setup_info->hsfreq) {
> setup_info->hsfreqrange = hsfreqrange_table[i][1];
> break;
> }
> }
>
> - /*
> - * Calculate n and m for PLL clock
> - * Following the HW manual the ranges of n and m are
> - * n = [3-8] and m = [64-625]
> - */
> - fin = clk_get_rate(clk);
> - divider = 1 << setup_info->div;
> - for (n = 3; n < 9; n++) {
> - unsigned long fpfd;
> - unsigned int m;
> -
> - fpfd = fin / n;
> -
> - for (m = 64; m < 626; m++) {
> - fout = fpfd * m / divider;
> - err = abs((long)(fout - fout_target) * 10000 /
> - (long)fout_target);
> - if (err < best_err) {
> - setup_info->m = m - 2;
> - setup_info->n = n - 1;
> - setup_info->fout = fout;
> - best_err = err;
> - if (err == 0)
> - goto done;
> - }
> - }
> - }
> + err = abs((long)(setup_info->fout - fout_target) * 10000 / (long)fout_target);
>
> -done:
> dev_dbg(dsi->dev,
> - "%pC %lu Hz -> Fout %lu Hz (target %lu Hz, error %d.%02u%%), PLL M/N/DIV %u/%u/%u\n",
> - clk, fin, setup_info->fout, fout_target, best_err / 100,
> - best_err % 100, setup_info->m, setup_info->n, setup_info->div);
> + "Fout = %u * %lu / (%u * %u * %u) = %lu (target %lu Hz, error %d.%02u%%)\n",
> + setup_info->m, fin_rate, dsi->info->n_mul, setup_info->n,
> + setup_info->vclk_divider, setup_info->fout, fout_target,
> + err / 100, err % 100);
> +
> dev_dbg(dsi->dev,
> "vco_cntrl = 0x%x\tprop_cntrl = 0x%x\thsfreqrange = 0x%x\n",
> - setup_info->vco_cntrl, setup_info->prop_cntrl,
> + clk_cfg->vco_cntrl, clk_cfg->prop_cntrl,
> setup_info->hsfreqrange);
> }
>
> @@ -324,7 +506,7 @@ static int rcar_mipi_dsi_startup(struct rcar_mipi_dsi *dsi,
> {
> struct dsi_setup_info setup_info = {};
> unsigned int timeout;
> - int ret, i;
> + int ret;
> int dsi_format;
> u32 phy_setup;
> u32 clockset2, clockset3;
> @@ -360,10 +542,19 @@ static int rcar_mipi_dsi_startup(struct rcar_mipi_dsi *dsi,
> phy_setup |= PHYSETUP_HSFREQRANGE(setup_info.hsfreqrange);
> rcar_mipi_dsi_write(dsi, PHYSETUP, phy_setup);
>
> - for (i = 0; i < ARRAY_SIZE(phtw); i++) {
> - ret = rcar_mipi_dsi_phtw_test(dsi, phtw[i]);
> + switch (dsi->info->model) {
> + case RCAR_DSI_V3U:
> + default:
> + ret = rcar_mipi_dsi_init_phtw_v3u(dsi);
> if (ret < 0)
> return ret;
> + break;
> +
> + case RCAR_DSI_V4H:
> + ret = rcar_mipi_dsi_init_phtw_v4h(dsi, &setup_info);
> + if (ret < 0)
> + return ret;
> + break;
> }
>
> /* PLL Clock Setting */
> @@ -371,12 +562,13 @@ static int rcar_mipi_dsi_startup(struct rcar_mipi_dsi *dsi,
> rcar_mipi_dsi_set(dsi, CLOCKSET1, CLOCKSET1_SHADOW_CLEAR);
> rcar_mipi_dsi_clr(dsi, CLOCKSET1, CLOCKSET1_SHADOW_CLEAR);
>
> - clockset2 = CLOCKSET2_M(setup_info.m) | CLOCKSET2_N(setup_info.n)
> - | CLOCKSET2_VCO_CNTRL(setup_info.vco_cntrl);
> - clockset3 = CLOCKSET3_PROP_CNTRL(setup_info.prop_cntrl)
> - | CLOCKSET3_INT_CNTRL(0)
> - | CLOCKSET3_CPBIAS_CNTRL(0x10)
> - | CLOCKSET3_GMP_CNTRL(1);
> + clockset2 = CLOCKSET2_M(setup_info.m - dsi->info->clockset2_m_offset)
> + | CLOCKSET2_N(setup_info.n - 1)
> + | CLOCKSET2_VCO_CNTRL(setup_info.clkset->vco_cntrl);
> + clockset3 = CLOCKSET3_PROP_CNTRL(setup_info.clkset->prop_cntrl)
> + | CLOCKSET3_INT_CNTRL(setup_info.clkset->int_cntrl)
> + | CLOCKSET3_CPBIAS_CNTRL(setup_info.clkset->cpbias_cntrl)
> + | CLOCKSET3_GMP_CNTRL(setup_info.clkset->gmp_cntrl);
> rcar_mipi_dsi_write(dsi, CLOCKSET2, clockset2);
> rcar_mipi_dsi_write(dsi, CLOCKSET3, clockset3);
>
> @@ -407,10 +599,19 @@ static int rcar_mipi_dsi_startup(struct rcar_mipi_dsi *dsi,
> return -ETIMEDOUT;
> }
>
> - for (i = 0; i < ARRAY_SIZE(phtw2); i++) {
> - ret = rcar_mipi_dsi_phtw_test(dsi, phtw2[i]);
> + switch (dsi->info->model) {
> + case RCAR_DSI_V3U:
> + default:
> + ret = rcar_mipi_dsi_post_init_phtw_v3u(dsi);
> + if (ret < 0)
> + return ret;
> + break;
> +
> + case RCAR_DSI_V4H:
> + ret = rcar_mipi_dsi_post_init_phtw_v4h(dsi, &setup_info);
> if (ret < 0)
> return ret;
> + break;
> }
>
> /* Enable DOT clock */
> @@ -427,8 +628,19 @@ static int rcar_mipi_dsi_startup(struct rcar_mipi_dsi *dsi,
> dev_warn(dsi->dev, "unsupported format");
> return -EINVAL;
> }
> - vclkset |= VCLKSET_COLOR_RGB | VCLKSET_DIV(setup_info.div)
> - | VCLKSET_LANE(dsi->lanes - 1);
> +
> + vclkset |= VCLKSET_COLOR_RGB | VCLKSET_LANE(dsi->lanes - 1);
> +
> + switch (dsi->info->model) {
> + case RCAR_DSI_V3U:
> + default:
> + vclkset |= VCLKSET_DIV_V3U(__ffs(setup_info.vclk_divider));
> + break;
> +
> + case RCAR_DSI_V4H:
> + vclkset |= VCLKSET_DIV_V4H(__ffs(setup_info.vclk_divider) - 1);
> + break;
> + }
>
> rcar_mipi_dsi_write(dsi, VCLKSET, vclkset);
>
> @@ -841,8 +1053,39 @@ static int rcar_mipi_dsi_remove(struct platform_device *pdev)
> return 0;
> }
>
> +static const struct rcar_mipi_dsi_device_info v3u_data = {
> + .model = RCAR_DSI_V3U,
> + .clk_cfg = dsi_clk_cfg_v3u,
> + .clockset2_m_offset = 2,
> + .n_min = 3,
> + .n_max = 8,
> + .n_mul = 1,
> + .fpfd_min = MHZ(2),
> + .fpfd_max = MHZ(8),
> + .m_min = 64,
> + .m_max = 625,
> + .fout_min = MHZ(320),
> + .fout_max = MHZ(1250),
> +};
> +
> +static const struct rcar_mipi_dsi_device_info v4h_data = {
> + .model = RCAR_DSI_V4H,
> + .clk_cfg = dsi_clk_cfg_v4h,
> + .clockset2_m_offset = 0,
> + .n_min = 1,
> + .n_max = 8,
> + .n_mul = 2,
> + .fpfd_min = MHZ(8),
> + .fpfd_max = MHZ(24),
> + .m_min = 167,
> + .m_max = 1000,
> + .fout_min = MHZ(2000),
> + .fout_max = MHZ(4000),
> +};
> +
> static const struct of_device_id rcar_mipi_dsi_of_table[] = {
> - { .compatible = "renesas,r8a779a0-dsi-csi2-tx" },
> + { .compatible = "renesas,r8a779a0-dsi-csi2-tx", .data = &v3u_data },
> + { .compatible = "renesas,r8a779g0-dsi-csi2-tx", .data = &v4h_data },
> { }
> };
>
> diff --git a/drivers/gpu/drm/rcar-du/rcar_mipi_dsi_regs.h b/drivers/gpu/drm/rcar-du/rcar_mipi_dsi_regs.h
> index 2eaca54636f3..f8114d11f2d1 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_mipi_dsi_regs.h
> +++ b/drivers/gpu/drm/rcar-du/rcar_mipi_dsi_regs.h
> @@ -122,7 +122,8 @@
> #define VCLKSET_CKEN (1 << 16)
> #define VCLKSET_COLOR_RGB (0 << 8)
> #define VCLKSET_COLOR_YCC (1 << 8)
> -#define VCLKSET_DIV(x) (((x) & 0x3) << 4)
> +#define VCLKSET_DIV_V3U(x) (((x) & 0x3) << 4)
> +#define VCLKSET_DIV_V4H(x) (((x) & 0x7) << 4)
> #define VCLKSET_BPP_16 (0 << 2)
> #define VCLKSET_BPP_18 (1 << 2)
> #define VCLKSET_BPP_18L (2 << 2)
> @@ -166,6 +167,9 @@
> #define PHTW_CWEN (1 << 8)
> #define PHTW_TESTDIN_CODE(x) (((x) & 0xff) << 0)
>
> +#define PHTR 0x1038
> +#define PHTR_TEST (1 << 16)
> +
> #define PHTC 0x103c
> #define PHTC_TESTCLR (1 << 0)
>
> --
> 2.34.1
>
On Thu, Dec 1, 2022 at 10:56 AM Tomi Valkeinen
<[email protected]> wrote:
>
> Add DT nodes needed for the mini DP connector. The DP is driven by
> sn65dsi86, which in turn gets the pixel data from the SoC via DSI.
>
> Signed-off-by: Tomi Valkeinen <[email protected]>
> Reviewed-by: Kieran Bingham <[email protected]>
> Reviewed-by: Laurent Pinchart <[email protected]>
(same comments as v2)
Reviewed-by: Geert Uytterhoeven <[email protected]>
i.e. will queue in renesas-devel for v6.3, with the mini-dp-con node
moved up.
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
On 05/12/2022 12:10, Geert Uytterhoeven wrote:
> On Thu, Dec 1, 2022 at 10:56 AM Tomi Valkeinen
> <[email protected]> wrote:
>>
>> Add DT nodes needed for the mini DP connector. The DP is driven by
>> sn65dsi86, which in turn gets the pixel data from the SoC via DSI.
>>
>> Signed-off-by: Tomi Valkeinen <[email protected]>
>> Reviewed-by: Kieran Bingham <[email protected]>
>> Reviewed-by: Laurent Pinchart <[email protected]>
>
> (same comments as v2)
> Reviewed-by: Geert Uytterhoeven <[email protected]>
> i.e. will queue in renesas-devel for v6.3, with the mini-dp-con node
> moved up.
Ah, sorry, I had missed this change. I'll update my branch too.
Tomi
Hi Tomi,
On Tue, Dec 6, 2022 at 2:45 PM Tomi Valkeinen
<[email protected]> wrote:
> On 05/12/2022 12:10, Geert Uytterhoeven wrote:
> > On Thu, Dec 1, 2022 at 10:56 AM Tomi Valkeinen
> > <[email protected]> wrote:
> >>
> >> Add DT nodes needed for the mini DP connector. The DP is driven by
> >> sn65dsi86, which in turn gets the pixel data from the SoC via DSI.
> >>
> >> Signed-off-by: Tomi Valkeinen <[email protected]>
> >> Reviewed-by: Kieran Bingham <[email protected]>
> >> Reviewed-by: Laurent Pinchart <[email protected]>
> >
> > (same comments as v2)
> > Reviewed-by: Geert Uytterhoeven <[email protected]>
> > i.e. will queue in renesas-devel for v6.3, with the mini-dp-con node
> > moved up.
>
> Ah, sorry, I had missed this change. I'll update my branch too.
Np. IIRC, you were sending out v5 while I was reviewing v2/v4.
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds