Here is next version changes for Allwinner A64 MIPI-DSI support
This series grouped the changes from previous version A64 MIPI-DSI[1]
along with burst mode[2].
Though the series seems to have more patches, but all patches are ordered
in a way that the review process is as smooth as possible.
Overall the series is grouped into four different sets to support three
different panels types that can fit into the DSI controller.
set:1 for 4-lane, burst mode:
- patch 0001: 0009, DSI controller changes that support burst mode.
all the patches fixed the previous comments along with proper commit message.
set:2 for A64 DSI changes:
- patch 0010: 0011, PLL-MIPI changes related to A64
- patch 0012: 0013, VCC-DSI supply change on DSI controller
- patch 0014: 0015: dt-bindings patches for A64 DSI and DPHY documentation
- patch 0016: A64 DSI pipeline patch
- patch 0017: Overlay patch that enable Feiyang FY07024DI26A30-D burst mode
panel on Pine64-LTS to validate set:1 changes
set:3 for 4-lane, non-burst mode:
- patch 0018: msg type MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM support
- patch 0019: Overlay patch that enable Bananapi S070WV20-CT16 ICN6211
panel on Bananapi M64 to validate set:3 changes
set:4 for 2-lane, non-burst mode:
- patch 0020: 0021, DSI hfp and hbp timings fixes
- patch 0022: patch to enable Techstar TS8550B panel on Amarula A64-Relic
to validate set:4 changes.
Changes for v6:
- dropped unneeded changes, patches
- fixed all burst mode patches as per previous version comments
- rebase on master
- update proper commit message
- dropped unneeded comments
- order the patches that make review easy
Changes for v5:
- collect Rob, Acked-by
- droped "Fix VBP size calculation" patch
- updated vblk timing calculation.
- droped techstar, bananapi dsi panel drivers which may require
bridge or other setup. it's under discussion.
Changes for v4:
- droppoed untested CCU_FEATURE_FIXED_POSTDIV check code in
nkm min, max rate patches
- create two patches for "Add Allwinner A64 MIPI DSI support"
one for has_mod_clk quirk and other one for A64 support
- use existing driver code construct for hblk computation
- dropped "Increase hfp packet overhead" patch [2], though BSP added
this but we have no issues as of now.
(no issues on panel side w/o this change)
- create separate function for vblk computation
- enable vcc-dsi regulator in dsi_runtime_resume
- collect Rob, Acked-by
- update MAINTAINERS file for panel drivers
- cleanup commit messages
- fixed checkpatch warnings/errors
[1] https://patchwork.kernel.org/cover/10721509/
[2] https://patchwork.kernel.org/cover/10686655/
Any inputs?
Jagan.
Jagan Teki (22):
drm/sun4i: sun6i_mipi_dsi: Compute burst mode loop N1 instruction
delay
drm/sun4i: sun6i_mipi_dsi: Support instruction loop selection
drm/sun4i: sun6i_mipi_dsi: Setup burst mode timings
drm/sun4i: sun6i_mipi_dsi: Simplify drq to support all modes
drm/sun4i: tcon: Export get tcon0 routine
drm/sun4i: sun6i_mipi_dsi: Probe tcon0 during dsi_bind
drm/sun4i: sun6i_mipi_dsi: Setup burst mode
drm/sun4i: sun6i_mipi_dsi: Enable 2byte trail for 4-lane burst mode
drm/sun4i: sun6i_mipi_dsi: Enable burst mode HBP, HSA_HSE
clk: sunxi-ng: Add check for minimal rate to NKM PLLs
clk: sunxi-ng: a64: Add minimum rate for PLL_MIPI
dt-bindings: sun6i-dsi: Add VCC-DSI supply property
drm/sun4i: sun6i_mipi_dsi: Add support for VCC-DSI voltage regulator
dt-bindings: sun6i-dsi: Add A64 DSI compatible (w/ A31 fallback)
dt-bindings: sun6i-dsi: Add A64 DPHY compatible (w/ A31 fallback)
arm64: dts: allwinner: a64: Add DSI pipeline
[DO NOT MERGE] arm64: allwinner: a64: pine64-lts: Enable Feiyang FY07024DI26A30-D DSI
panel
drm/sun4i: sun6i_mipi_dsi: Add DSI Generic short write 2 param
transfer
[DO NOT MERGE] arm64: dts: allwinner: bananapi-m64: Bananapi S070WV20-CT16 DSI panel
drm/sun4i: sun6i_mipi_dsi: Fix DSI hbp timing value
drm/sun4i: sun6i_mipi_dsi: Fix DSI hfp timing value
arm64: dts: allwinner: a64-amarula-relic: Add Techstar TS8550B
MIPI-DSI panel
.../bindings/display/sunxi/sun6i-dsi.txt | 5 +
.../allwinner/sun50i-a64-amarula-relic.dts | 39 +++++
.../dts/allwinner/sun50i-a64-bananapi-m64.dts | 43 +++++
.../dts/allwinner/sun50i-a64-pine64-lts.dts | 39 +++++
arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 47 +++++
drivers/clk/sunxi-ng/ccu-sun50i-a64.c | 1 +
drivers/clk/sunxi-ng/ccu_nkm.c | 5 +
drivers/clk/sunxi-ng/ccu_nkm.h | 1 +
drivers/gpu/drm/sun4i/sun4i_tcon.c | 3 +-
drivers/gpu/drm/sun4i/sun4i_tcon.h | 1 +
drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c | 165 ++++++++++++++++--
drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h | 4 +
12 files changed, 337 insertions(+), 16 deletions(-)
--
2.18.0.321.gffc6fa0e3
Burst mode display timings are different from conventional
video mode, for burst mode most of the timings hsa, hbp, hfp,
vblk are 0 and hblk is computed as (mode->hdisplay * Bpp)
This patch add burst mode timings and directly goto alloc buffer.
Reference code taken from BSP (from linux-sunxi/
drivers/video/sunxi/disp2/disp/de/lowlevel_sun50iw1/de_dsi.c)
dsi_hsa = 0;
dsi_hbp = 0;
dsi_hact = x*dsi_pixel_bits[format]/8;
dsi_hblk = dsi_hact;
dsi_hfp = 0;
dsi_vblk = 0;
Signed-off-by: Jagan Teki <[email protected]>
---
drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
index 813d5523f1c7..0f02bcc997a5 100644
--- a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
+++ b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
@@ -477,6 +477,12 @@ static void sun6i_dsi_setup_timings(struct sun6i_dsi *dsi,
/* Do all timing calculations up front to allocate buffer space */
+ if (device->mode_flags & MIPI_DSI_MODE_VIDEO_BURST) {
+ hbp = hfp = hsa = vblk = 0;
+ hblk = (mode->hdisplay * Bpp);
+ goto alloc_buf;
+ }
+
/*
* A sync period is composed of a blanking packet (4 bytes +
* payload + 2 bytes) and a sync event packet (4 bytes). Its
@@ -515,6 +521,7 @@ static void sun6i_dsi_setup_timings(struct sun6i_dsi *dsi,
*/
vblk = 0;
+alloc_buf:
/* How many bytes do we need to send all payloads? */
bytes = max_t(size_t, max(max(hfp, hblk), max(hsa, hbp)), vblk);
buffer = kmalloc(bytes, GFP_KERNEL);
--
2.18.0.321.gffc6fa0e3
Setting up burst mode display would require to compute
- Horizontal timing edge values to fill burst drq register
- Line, sync values to fill burst line register
Since there is no direct documentation for these computations
the edge and line formulas are taken from BSP code (from linux-sunxi/
drivers/video/sunxi/disp2/disp/de/lowlevel_sun50iw1/de_dsi.c)
line_num = panel->lcd_ht*dsi_pixel_bits[panel->lcd_dsi_format]/
(8*panel->lcd_dsi_lane);
edge1 = sync_point+(panel->lcd_x+panel->lcd_hbp+20)*
dsi_pixel_bits[panel->lcd_dsi_format] /(8*panel->lcd_dsi_lane);
edge1 = (edge1>line_num)?line_num:edge1;
edge0 = edge1+(panel->lcd_x+40)*tcon_div/8;
edge0 = (edge0>line_num)?(edge0-line_num):1;
Signed-off-by: Jagan Teki <[email protected]>
---
drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c | 70 ++++++++++++++++++++++++--
1 file changed, 67 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
index 2aeaa19a8d1e..46ad142e66e8 100644
--- a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
+++ b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
@@ -355,6 +355,41 @@ static void sun6i_dsi_inst_init(struct sun6i_dsi *dsi,
SUN6I_DSI_INST_JUMP_CFG_NUM(1));
};
+static u32 sun6i_dsi_get_edge1(struct sun6i_dsi *dsi,
+ struct drm_display_mode *mode, u32 sync_point)
+{
+ struct mipi_dsi_device *device = dsi->device;
+ unsigned int bpp = mipi_dsi_pixel_format_to_bpp(device->format);
+ u32 hact_sync_bp;
+
+ /* Horizontal timings duration excluding front porch */
+ hact_sync_bp = (mode->hdisplay + mode->htotal - mode->hsync_start);
+
+ return (sync_point + ((hact_sync_bp + 20) * bpp / (8 * device->lanes)));
+}
+
+static u32 sun6i_dsi_get_edge0(struct sun6i_dsi *dsi,
+ struct drm_display_mode *mode, u32 edge1)
+{
+ struct sun4i_tcon *tcon = dsi->tcon;
+ unsigned long dclk_rate, dclk_parent_rate, tcon0_div;
+
+ dclk_rate = clk_get_rate(tcon->dclk);
+ dclk_parent_rate = clk_get_rate(clk_get_parent(tcon->dclk));
+ tcon0_div = dclk_parent_rate / dclk_rate;
+
+ return (edge1 + (mode->hdisplay + 40) * tcon0_div / 8);
+}
+
+static u32 sun6i_dsi_get_line_num(struct sun6i_dsi *dsi,
+ struct drm_display_mode *mode)
+{
+ struct mipi_dsi_device *device = dsi->device;
+ unsigned int bpp = mipi_dsi_pixel_format_to_bpp(device->format);
+
+ return (mode->htotal * bpp / (8 * device->lanes));
+}
+
static int sun6i_dsi_get_drq(struct sun6i_dsi *dsi,
struct drm_display_mode *mode)
{
@@ -404,8 +439,32 @@ static u16 sun6i_dsi_get_video_start_delay(struct sun6i_dsi *dsi,
static void sun6i_dsi_setup_burst(struct sun6i_dsi *dsi,
struct drm_display_mode *mode)
{
- regmap_write(dsi->regs, SUN6I_DSI_TCON_DRQ_REG,
- sun6i_dsi_get_drq(dsi, mode));
+ struct mipi_dsi_device *device = dsi->device;
+ u32 sync_point = 40;
+ u32 line_num = sun6i_dsi_get_line_num(dsi, mode);
+ u32 edge1 = sun6i_dsi_get_edge1(dsi, mode, sync_point);
+ u32 edge0 = sun6i_dsi_get_edge0(dsi, mode, edge1);
+ u32 val;
+
+ if (edge1 > line_num)
+ edge1 = line_num;
+
+ if (edge0 > line_num)
+ edge0 -= line_num;
+ else
+ edge0 = 1;
+
+ regmap_write(dsi->regs, SUN6I_DSI_BURST_DRQ_REG,
+ SUN6I_DSI_BURST_DRQ_EDGE1(edge1) |
+ SUN6I_DSI_BURST_DRQ_EDGE0(edge0));
+ regmap_write(dsi->regs, SUN6I_DSI_BURST_LINE_REG,
+ SUN6I_DSI_BURST_LINE_NUM(line_num) |
+ SUN6I_DSI_BURST_LINE_SYNC_POINT(sync_point));
+
+ /* enable burst mode */
+ regmap_read(dsi->regs, SUN6I_DSI_BASIC_CTL_REG, &val);
+ val |= SUN6I_DSI_BASIC_CTL_VIDEO_BURST;
+ regmap_write(dsi->regs, SUN6I_DSI_BASIC_CTL_REG, val);
}
static void sun6i_dsi_setup_inst_loop(struct sun6i_dsi *dsi,
@@ -667,7 +726,12 @@ static void sun6i_dsi_encoder_enable(struct drm_encoder *encoder)
SUN6I_DSI_BASIC_CTL1_VIDEO_PRECISION |
SUN6I_DSI_BASIC_CTL1_VIDEO_MODE);
- sun6i_dsi_setup_burst(dsi, mode);
+ regmap_write(dsi->regs, SUN6I_DSI_TCON_DRQ_REG,
+ sun6i_dsi_get_drq(dsi, mode));
+
+ if (device->mode_flags & MIPI_DSI_MODE_VIDEO_BURST)
+ sun6i_dsi_setup_burst(dsi, mode);
+
sun6i_dsi_setup_inst_loop(dsi, mode);
sun6i_dsi_setup_format(dsi, mode);
sun6i_dsi_setup_timings(dsi, mode);
--
2.18.0.321.gffc6fa0e3
For 4-lane, burst mode panels would need to enable 2byte trail_fill
along with filling trail_env in dsi base control register.
Similar reference code avialable in BSP (from linux-sunxi/
drivers/video/sunxi/disp2/disp/de/lowlevel_sun50iw1/de_dsi.c)
if (panel->lcd_dsi_lane == 4)
{
dsi_dev[sel]->dsi_basic_ctl.bits.trail_inv = 0xc;
dsi_dev[sel]->dsi_basic_ctl.bits.trail_fill = 1;
}
Signed-off-by: Jagan Teki <[email protected]>
---
drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
index 46ad142e66e8..a2ad9fa7f8d5 100644
--- a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
+++ b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
@@ -33,6 +33,8 @@
#define SUN6I_DSI_CTL_EN BIT(0)
#define SUN6I_DSI_BASIC_CTL_REG 0x00c
+#define SUN6I_DSI_BASIC_CTL_TRAIL_INV(n) (((n) & 0xf) << 4)
+#define SUN6I_DSI_BASIC_CTL_TRAIL_FILL BIT(3)
#define SUN6I_DSI_BASIC_CTL_HBP_DIS BIT(2)
#define SUN6I_DSI_BASIC_CTL_HSA_HSE_DIS BIT(1)
#define SUN6I_DSI_BASIC_CTL_VIDEO_BURST BIT(0)
@@ -464,6 +466,10 @@ static void sun6i_dsi_setup_burst(struct sun6i_dsi *dsi,
/* enable burst mode */
regmap_read(dsi->regs, SUN6I_DSI_BASIC_CTL_REG, &val);
val |= SUN6I_DSI_BASIC_CTL_VIDEO_BURST;
+ if (device->lanes == 4) {
+ val |= SUN6I_DSI_BASIC_CTL_TRAIL_INV(0xc);
+ val |= SUN6I_DSI_BASIC_CTL_TRAIL_FILL;
+ }
regmap_write(dsi->regs, SUN6I_DSI_BASIC_CTL_REG, val);
}
--
2.18.0.321.gffc6fa0e3
Horizontal back porch, sync active and sync end bits are
needed to disable for burst mode panel operations.
So, disable them via dsi base control register.
Signed-off-by: Jagan Teki <[email protected]>
---
drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
index a2ad9fa7f8d5..3d7c03161954 100644
--- a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
+++ b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
@@ -549,12 +549,17 @@ static void sun6i_dsi_setup_timings(struct sun6i_dsi *dsi,
u16 hbp, hfp, hsa, hblk, vblk;
size_t bytes;
u8 *buffer;
+ u32 val = 0;
/* Do all timing calculations up front to allocate buffer space */
if (device->mode_flags & MIPI_DSI_MODE_VIDEO_BURST) {
hbp = hfp = hsa = vblk = 0;
hblk = (mode->hdisplay * Bpp);
+
+ regmap_read(dsi->regs, SUN6I_DSI_BASIC_CTL_REG, &val);
+ val |= SUN6I_DSI_BASIC_CTL_HBP_DIS;
+ val |= SUN6I_DSI_BASIC_CTL_HSA_HSE_DIS;
goto alloc_buf;
}
@@ -603,7 +608,7 @@ static void sun6i_dsi_setup_timings(struct sun6i_dsi *dsi,
if (WARN_ON(!buffer))
return;
- regmap_write(dsi->regs, SUN6I_DSI_BASIC_CTL_REG, 0);
+ regmap_write(dsi->regs, SUN6I_DSI_BASIC_CTL_REG, val);
regmap_write(dsi->regs, SUN6I_DSI_SYNC_HSS_REG,
sun6i_dsi_build_sync_pkt(MIPI_DSI_H_SYNC_START,
--
2.18.0.321.gffc6fa0e3
Some NKM PLLs doesn't work well when their output clock rate is set below
certain rate.
So, add support for minimal rate for relevant PLLs.
Signed-off-by: Jagan Teki <[email protected]>
Acked-by: Stephen Boyd <[email protected]>
---
drivers/clk/sunxi-ng/ccu_nkm.c | 5 +++++
drivers/clk/sunxi-ng/ccu_nkm.h | 1 +
2 files changed, 6 insertions(+)
diff --git a/drivers/clk/sunxi-ng/ccu_nkm.c b/drivers/clk/sunxi-ng/ccu_nkm.c
index 841840e35e61..096ff4f4839a 100644
--- a/drivers/clk/sunxi-ng/ccu_nkm.c
+++ b/drivers/clk/sunxi-ng/ccu_nkm.c
@@ -125,6 +125,11 @@ static unsigned long ccu_nkm_round_rate(struct ccu_mux_internal *mux,
if (nkm->common.features & CCU_FEATURE_FIXED_POSTDIV)
rate *= nkm->fixed_post_div;
+ if (rate < nkm->min_rate) {
+ rate = nkm->min_rate;
+ return rate;
+ }
+
ccu_nkm_find_best(*parent_rate, rate, &_nkm);
rate = *parent_rate * _nkm.n * _nkm.k / _nkm.m;
diff --git a/drivers/clk/sunxi-ng/ccu_nkm.h b/drivers/clk/sunxi-ng/ccu_nkm.h
index cc6efb70a102..ff5bd00f429f 100644
--- a/drivers/clk/sunxi-ng/ccu_nkm.h
+++ b/drivers/clk/sunxi-ng/ccu_nkm.h
@@ -35,6 +35,7 @@ struct ccu_nkm {
struct ccu_mux_internal mux;
unsigned int fixed_post_div;
+ unsigned int min_rate;
struct ccu_common common;
};
--
2.18.0.321.gffc6fa0e3
Allwinner MIPI DSI drq has enable mode and set bits.
- for burst mode, drq need to set enable mode bit.
- for non-burst video modes, drq need to set enable mode,
set bits for those front proch greater than 20 and for
rest drq is not used.
This patch simplifies existing drq code by grouping into
sun6i_dsi_get_drq and support all video modes.
Signed-off-by: Jagan Teki <[email protected]>
---
drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c | 39 ++++++++++++++++----------
1 file changed, 24 insertions(+), 15 deletions(-)
diff --git a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
index 0f02bcc997a5..16a86d35dc5a 100644
--- a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
+++ b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
@@ -354,6 +354,28 @@ static void sun6i_dsi_inst_init(struct sun6i_dsi *dsi,
SUN6I_DSI_INST_JUMP_CFG_NUM(1));
};
+static int sun6i_dsi_get_drq(struct sun6i_dsi *dsi,
+ struct drm_display_mode *mode)
+{
+ struct mipi_dsi_device *device = dsi->device;
+
+ if (device->mode_flags & MIPI_DSI_MODE_VIDEO_BURST)
+ return SUN6I_DSI_TCON_DRQ_ENABLE_MODE;
+
+ if ((mode->hsync_start - mode->hdisplay) > 20) {
+ /* Maaaaaagic */
+ u16 drq = (mode->hsync_start - mode->hdisplay) - 20;
+
+ drq *= mipi_dsi_pixel_format_to_bpp(device->format);
+ drq /= 32;
+
+ return (SUN6I_DSI_TCON_DRQ_ENABLE_MODE |
+ SUN6I_DSI_TCON_DRQ_SET(drq));
+ }
+
+ return 0;
+}
+
static u16 sun6i_dsi_setup_inst_delay(struct sun6i_dsi *dsi,
struct drm_display_mode *mode)
{
@@ -381,21 +403,8 @@ static u16 sun6i_dsi_get_video_start_delay(struct sun6i_dsi *dsi,
static void sun6i_dsi_setup_burst(struct sun6i_dsi *dsi,
struct drm_display_mode *mode)
{
- struct mipi_dsi_device *device = dsi->device;
- u32 val = 0;
-
- if ((mode->hsync_end - mode->hdisplay) > 20) {
- /* Maaaaaagic */
- u16 drq = (mode->hsync_end - mode->hdisplay) - 20;
-
- drq *= mipi_dsi_pixel_format_to_bpp(device->format);
- drq /= 32;
-
- val = (SUN6I_DSI_TCON_DRQ_ENABLE_MODE |
- SUN6I_DSI_TCON_DRQ_SET(drq));
- }
-
- regmap_write(dsi->regs, SUN6I_DSI_TCON_DRQ_REG, val);
+ regmap_write(dsi->regs, SUN6I_DSI_TCON_DRQ_REG,
+ sun6i_dsi_get_drq(dsi, mode));
}
static void sun6i_dsi_setup_inst_loop(struct sun6i_dsi *dsi,
--
2.18.0.321.gffc6fa0e3
Minimum PLL used for MIPI is 500MHz, as per manual, but
lowering the min rate by 300MHz can result proper working
nkms divider with the help of desired dclock rate from
panel driver.
Signed-off-by: Jagan Teki <[email protected]>
Acked-by: Stephen Boyd <[email protected]>
---
drivers/clk/sunxi-ng/ccu-sun50i-a64.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
index 932836d26e2b..296d489aad6e 100644
--- a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
+++ b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
@@ -183,6 +183,7 @@ static struct ccu_nkm pll_mipi_clk = {
.n = _SUNXI_CCU_MULT(8, 4),
.k = _SUNXI_CCU_MULT_MIN(4, 2, 2),
.m = _SUNXI_CCU_DIV(0, 4),
+ .min_rate = 300000000,
.common = {
.reg = 0x040,
.hw.init = CLK_HW_INIT("pll-mipi", "pll-video0",
--
2.18.0.321.gffc6fa0e3
Sometimes tcon attributes like tcon divider, clock rate etc are needed
in interface drivers like DSI. So for such cases interface driver must
probe the respective tcon and get the attributes.
Since tcon0 probe is already available, via sun4i_get_tcon0 function,
export the same instead of probing tcon explicitly.
Signed-off-by: Jagan Teki <[email protected]>
---
drivers/gpu/drm/sun4i/sun4i_tcon.c | 3 ++-
drivers/gpu/drm/sun4i/sun4i_tcon.h | 1 +
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c b/drivers/gpu/drm/sun4i/sun4i_tcon.c
index 0420f5c978b9..3da75a0c5c5d 100644
--- a/drivers/gpu/drm/sun4i/sun4i_tcon.c
+++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c
@@ -221,7 +221,7 @@ EXPORT_SYMBOL(sun4i_tcon_enable_vblank);
* are located in TCON0. This helper returns a pointer to TCON0's
* sun4i_tcon structure, or NULL if not found.
*/
-static struct sun4i_tcon *sun4i_get_tcon0(struct drm_device *drm)
+struct sun4i_tcon *sun4i_get_tcon0(struct drm_device *drm)
{
struct sun4i_drv *drv = drm->dev_private;
struct sun4i_tcon *tcon;
@@ -235,6 +235,7 @@ static struct sun4i_tcon *sun4i_get_tcon0(struct drm_device *drm)
return NULL;
}
+EXPORT_SYMBOL(sun4i_get_tcon0);
void sun4i_tcon_set_mux(struct sun4i_tcon *tcon, int channel,
const struct drm_encoder *encoder)
diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.h b/drivers/gpu/drm/sun4i/sun4i_tcon.h
index b5214d71610f..a52696db14a5 100644
--- a/drivers/gpu/drm/sun4i/sun4i_tcon.h
+++ b/drivers/gpu/drm/sun4i/sun4i_tcon.h
@@ -274,6 +274,7 @@ struct sun4i_tcon {
struct drm_bridge *sun4i_tcon_find_bridge(struct device_node *node);
struct drm_panel *sun4i_tcon_find_panel(struct device_node *node);
+struct sun4i_tcon *sun4i_get_tcon0(struct drm_device *drm);
void sun4i_tcon_enable_vblank(struct sun4i_tcon *tcon, bool enable);
void sun4i_tcon_mode_set(struct sun4i_tcon *tcon,
const struct drm_encoder *encoder,
--
2.18.0.321.gffc6fa0e3
Some boards have VCC-DSI pin connected to voltage regulator which may
not be turned on by default.
Add support for such boards by adding voltage regulator handling code to
MIPI DSI driver.
Signed-off-by: Jagan Teki <[email protected]>
---
drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c | 14 ++++++++++++++
drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h | 3 +++
2 files changed, 17 insertions(+)
diff --git a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
index 3d7c03161954..9be414131460 100644
--- a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
+++ b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
@@ -1107,6 +1107,12 @@ static int sun6i_dsi_probe(struct platform_device *pdev)
return PTR_ERR(base);
}
+ dsi->regulator = devm_regulator_get(dev, "vcc-dsi");
+ if (IS_ERR(dsi->regulator)) {
+ dev_err(dev, "Couldn't get VCC-DSI supply\n");
+ return PTR_ERR(dsi->regulator);
+ }
+
dsi->regs = devm_regmap_init_mmio_clk(dev, "bus", base,
&sun6i_dsi_regmap_config);
if (IS_ERR(dsi->regs)) {
@@ -1183,6 +1189,13 @@ static int sun6i_dsi_remove(struct platform_device *pdev)
static int __maybe_unused sun6i_dsi_runtime_resume(struct device *dev)
{
struct sun6i_dsi *dsi = dev_get_drvdata(dev);
+ int err;
+
+ err = regulator_enable(dsi->regulator);
+ if (err) {
+ dev_err(dsi->dev, "failed to enable VCC-DSI supply: %d\n", err);
+ return err;
+ }
reset_control_deassert(dsi->reset);
clk_prepare_enable(dsi->mod_clk);
@@ -1215,6 +1228,7 @@ static int __maybe_unused sun6i_dsi_runtime_suspend(struct device *dev)
clk_disable_unprepare(dsi->mod_clk);
reset_control_assert(dsi->reset);
+ regulator_disable(dsi->regulator);
return 0;
}
diff --git a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h
index 257cca660da0..06cce0d0d3ad 100644
--- a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h
+++ b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h
@@ -13,6 +13,8 @@
#include <drm/drm_encoder.h>
#include <drm/drm_mipi_dsi.h>
+#include <linux/regulator/consumer.h>
+
struct sun6i_dphy {
struct clk *bus_clk;
struct clk *mod_clk;
@@ -28,6 +30,7 @@ struct sun6i_dsi {
struct clk *bus_clk;
struct clk *mod_clk;
struct regmap *regs;
+ struct regulator *regulator;
struct reset_control *reset;
struct sun6i_dphy *dphy;
--
2.18.0.321.gffc6fa0e3
The MIPI DSI controller in Allwinner A64 is similar to A33.
But unlike A33, A64 doesn't have DSI_SCLK gating which eventually
set the mod clock rate for the controller.
So, use the DSI_DPHY gating for the similar purpose of mod clock
so-that the controller can operate properly.
Signed-off-by: Jagan Teki <[email protected]>
Reviewed-by: Rob Herring <[email protected]>
---
Documentation/devicetree/bindings/display/sunxi/sun6i-dsi.txt | 1 +
1 file changed, 1 insertion(+)
diff --git a/Documentation/devicetree/bindings/display/sunxi/sun6i-dsi.txt b/Documentation/devicetree/bindings/display/sunxi/sun6i-dsi.txt
index 69e233e8fad1..dbda2e567760 100644
--- a/Documentation/devicetree/bindings/display/sunxi/sun6i-dsi.txt
+++ b/Documentation/devicetree/bindings/display/sunxi/sun6i-dsi.txt
@@ -12,6 +12,7 @@ The DSI Encoder generates the DSI signal from the TCON's.
Required properties:
- compatible: value must be one of:
* allwinner,sun6i-a31-mipi-dsi
+ * "allwinner,sun50i-a64-mipi-dsi", "allwinner,sun6i-a31-mipi-dsi"
- reg: base address and size of memory-mapped region
- interrupts: interrupt associated to this IP
- clocks: phandles to the clocks feeding the DSI encoder
--
2.18.0.321.gffc6fa0e3
The MIPI DSI PHY controller on Allwinner A64 is similar
on the one on A31.
Add A64 compatible and append A31 compatible as fallback.
Signed-off-by: Jagan Teki <[email protected]>
Reviewed-by: Rob Herring <[email protected]>
---
Documentation/devicetree/bindings/display/sunxi/sun6i-dsi.txt | 1 +
1 file changed, 1 insertion(+)
diff --git a/Documentation/devicetree/bindings/display/sunxi/sun6i-dsi.txt b/Documentation/devicetree/bindings/display/sunxi/sun6i-dsi.txt
index dbda2e567760..9c553637c72b 100644
--- a/Documentation/devicetree/bindings/display/sunxi/sun6i-dsi.txt
+++ b/Documentation/devicetree/bindings/display/sunxi/sun6i-dsi.txt
@@ -40,6 +40,7 @@ D-PHY
Required properties:
- compatible: value must be one of:
* allwinner,sun6i-a31-mipi-dphy
+ * "allwinner,sun50i-a64-mipi-dphy", "allwinner,sun6i-a31-mipi-dphy"
- reg: base address and size of memory-mapped region
- clocks: phandles to the clocks feeding the DSI encoder
* bus: the DSI interface clock
--
2.18.0.321.gffc6fa0e3
Loop N1 instruction delay varies between burst and non-burst
video modes. for burst mode panels it is computed based on the
panel clock along with horizontal sync and porch timings and
the rest it is simply (50 - 1)
Reference code is available in BSP (from linux-sunxi
drivers/video/sunxi/disp2/disp/de/lowlevel_sun50iw1/de_dsi.c)
dsi_dev[sel]->dsi_inst_loop_num.bits.loop_n1=
(panel->lcd_ht-panel->lcd_x)*(150)/(panel->lcd_dclk_freq*8) - 50;
=> (((mode->htotal - mode->hdisplay) * 150) /
((mode->clock / 1000) * 8)) - 50;
So, this patch add loop N1 computation for burst mode, for non-burst
which is already available.
Signed-off-by: Jagan Teki <[email protected]>
---
drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c | 20 +++++++++++++++++++-
1 file changed, 19 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
index e3b34a345546..a5fcee750bee 100644
--- a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
+++ b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
@@ -354,6 +354,24 @@ static void sun6i_dsi_inst_init(struct sun6i_dsi *dsi,
SUN6I_DSI_INST_JUMP_CFG_NUM(1));
};
+static u16 sun6i_dsi_setup_inst_delay(struct sun6i_dsi *dsi,
+ struct drm_display_mode *mode)
+{
+ struct mipi_dsi_device *device = dsi->device;
+ u32 hsync_porch, dclk;
+ u16 delay;
+
+ hsync_porch = (mode->htotal - mode->hdisplay);
+ dclk = (mode->clock / 1000);
+
+ if (device->mode_flags & MIPI_DSI_MODE_VIDEO_BURST)
+ delay = ((hsync_porch * 150) / (dclk * 8)) - 50;
+ else
+ delay = 50 - 1;
+
+ return delay;
+}
+
static u16 sun6i_dsi_get_video_start_delay(struct sun6i_dsi *dsi,
struct drm_display_mode *mode)
{
@@ -383,7 +401,7 @@ static void sun6i_dsi_setup_burst(struct sun6i_dsi *dsi,
static void sun6i_dsi_setup_inst_loop(struct sun6i_dsi *dsi,
struct drm_display_mode *mode)
{
- u16 delay = 50 - 1;
+ u16 delay = sun6i_dsi_setup_inst_delay(dsi, mode);
regmap_write(dsi->regs, SUN6I_DSI_INST_LOOP_NUM_REG(0),
SUN6I_DSI_INST_LOOP_NUM_N0(50 - 1) |
--
2.18.0.321.gffc6fa0e3
The A64 has a MIPI-DSI block which is similar to A31.
Add dsi, dphy nodes with A31 fallback compatible and finally
connect the dsi node to tcon0 node to make proper DSI pipeline.
Signed-off-by: Jagan Teki <[email protected]>
---
arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 47 +++++++++++++++++++
1 file changed, 47 insertions(+)
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
index cdc154b14a7e..e18d81aff813 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
@@ -358,6 +358,12 @@
#address-cells = <1>;
#size-cells = <0>;
reg = <1>;
+
+ tcon0_out_dsi: endpoint@1 {
+ reg = <1>;
+ remote-endpoint = <&dsi_in_tcon0>;
+ allwinner,tcon-channel = <1>;
+ };
};
};
};
@@ -935,6 +941,47 @@
status = "disabled";
};
+ dsi: dsi@1ca0000 {
+ compatible = "allwinner,sun50i-a64-mipi-dsi",
+ "allwinner,sun6i-a31-mipi-dsi";
+ reg = <0x01ca0000 0x1000>;
+ interrupts = <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&ccu CLK_BUS_MIPI_DSI>,
+ <&ccu CLK_DSI_DPHY>;
+ clock-names = "bus", "mod";
+ resets = <&ccu RST_BUS_MIPI_DSI>;
+ phys = <&dphy>;
+ phy-names = "dphy";
+ status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+
+ dsi_in_tcon0: endpoint {
+ remote-endpoint = <&tcon0_out_dsi>;
+ };
+ };
+ };
+ };
+
+ dphy: d-phy@1ca1000 {
+ compatible = "allwinner,sun50i-a64-mipi-dphy",
+ "allwinner,sun6i-a31-mipi-dphy";
+ reg = <0x01ca1000 0x1000>;
+ clocks = <&ccu CLK_BUS_MIPI_DSI>,
+ <&ccu CLK_DSI_DPHY>;
+ clock-names = "bus", "mod";
+ resets = <&ccu RST_BUS_MIPI_DSI>;
+ status = "disabled";
+ #phy-cells = <0>;
+ };
+
csi: csi@1cb0000 {
compatible = "allwinner,sun50i-a64-csi";
reg = <0x01cb0000 0x1000>;
--
2.18.0.321.gffc6fa0e3
Instruction loop selection would require before writing
loop number registers, so enable idle, LP11 bits on
loop selection register.
Reference code available in BSP (from linux-sunxi/
drivers/video/sunxi/disp2/disp/de/lowlevel_sun50iw1/de_dsi.c)
(dsi_dev[sel]->dsi_inst_loop_sel.dwval = 2<<(4*DSI_INST_ID_LP11) |
3<<(4*DSI_INST_ID_DLY);
Signed-off-by: Jagan Teki <[email protected]>
---
drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
index a5fcee750bee..813d5523f1c7 100644
--- a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
+++ b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
@@ -403,6 +403,9 @@ static void sun6i_dsi_setup_inst_loop(struct sun6i_dsi *dsi,
{
u16 delay = sun6i_dsi_setup_inst_delay(dsi, mode);
+ regmap_write(dsi->regs, SUN6I_DSI_INST_LOOP_SEL_REG,
+ DSI_INST_ID_HSC << (4 * DSI_INST_ID_LP11) |
+ DSI_INST_ID_HSD << (4 * DSI_INST_ID_DLY));
regmap_write(dsi->regs, SUN6I_DSI_INST_LOOP_NUM_REG(0),
SUN6I_DSI_INST_LOOP_NUM_N0(50 - 1) |
SUN6I_DSI_INST_LOOP_NUM_N1(delay));
--
2.18.0.321.gffc6fa0e3
Feiyang FY07024DI26A30-D MIPI_DSI panel is desiged to attach with
DSI connector on pine64 boards, enable the same for pine64 LTS.
DSI panel connected via board DSI port with,
- DC1SW as AVDD supply
- DLDO2 as DVDD supply
- DLDO1 as VCC-DSI supply
- PD24 gpio for reset pin
- PH10 gpio for backlight enable pin
Signed-off-by: Jagan Teki <[email protected]>
---
.../dts/allwinner/sun50i-a64-pine64-lts.dts | 39 +++++++++++++++++++
1 file changed, 39 insertions(+)
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64-lts.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64-lts.dts
index 72d6961dc312..341b1c035604 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64-lts.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64-lts.dts
@@ -5,9 +5,48 @@
*/
#include "sun50i-a64-sopine-baseboard.dts"
+#include <dt-bindings/pwm/pwm.h>
/ {
model = "Pine64 LTS";
compatible = "pine64,pine64-lts", "allwinner,sun50i-r18",
"allwinner,sun50i-a64";
+
+ backlight: backlight {
+ compatible = "pwm-backlight";
+ pwms = <&r_pwm 0 50000 PWM_POLARITY_INVERTED>;
+ brightness-levels = <1 2 4 8 16 32 64 128 512>;
+ default-brightness-level = <8>;
+ enable-gpios = <&pio 7 10 GPIO_ACTIVE_HIGH>; /* LCD-BL-EN: PH10 */
+ };
+};
+
+&de {
+ status = "okay";
+};
+
+&dphy {
+ status = "okay";
+};
+
+&dsi {
+ vcc-dsi-supply = <®_dldo1>; /* VCC3V3-DSI */
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "okay";
+
+ panel@0 {
+ compatible = "feiyang,fy07024di26a30d";
+ reg = <0>;
+ avdd-supply = <®_dc1sw>; /* VCC-LCD */
+ dvdd-supply = <®_dldo2>; /* VCC-MIPI */
+ reset-gpios = <&pio 3 24 GPIO_ACTIVE_HIGH>; /* LCD-RST: PD24 */
+ backlight = <&backlight>;
+ };
+};
+
+&r_pwm {
+ pinctrl-names = "default";
+ pinctrl-0 = <&r_pwm_pin>;
+ status = "okay";
};
--
2.18.0.321.gffc6fa0e3
Short transfer write support for DCS and Generic transfer types
share similar way to process command sequence in DSI block so
add generic write 2 param transfer type macro so-that the panels
which are requesting similar transfer type may process properly.
Signed-off-by: Jagan Teki <[email protected]>
---
drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
index 9be414131460..58bda0928aef 100644
--- a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
+++ b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
@@ -983,6 +983,7 @@ static ssize_t sun6i_dsi_transfer(struct mipi_dsi_host *host,
switch (msg->type) {
case MIPI_DSI_DCS_SHORT_WRITE:
case MIPI_DSI_DCS_SHORT_WRITE_PARAM:
+ case MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM:
ret = sun6i_dsi_dcs_write_short(dsi, msg);
break;
--
2.18.0.321.gffc6fa0e3
Probe tcon0 during dsi_bind, so-that the tcon attributes like
divider value, clock rate can get whenever it need.
Signed-off-by: Jagan Teki <[email protected]>
---
drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c | 7 +++++++
drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h | 1 +
2 files changed, 8 insertions(+)
diff --git a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
index 16a86d35dc5a..2aeaa19a8d1e 100644
--- a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
+++ b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
@@ -24,6 +24,7 @@
#include <drm/drm_panel.h>
#include "sun4i_drv.h"
+#include "sun4i_tcon.h"
#include "sun6i_mipi_dsi.h"
#include <video/mipi_display.h>
@@ -947,6 +948,7 @@ static int sun6i_dsi_bind(struct device *dev, struct device *master,
struct drm_device *drm = data;
struct sun4i_drv *drv = drm->dev_private;
struct sun6i_dsi *dsi = dev_get_drvdata(dev);
+ struct sun4i_tcon *tcon0 = sun4i_get_tcon0(drm);
int ret;
if (!dsi->panel)
@@ -954,6 +956,11 @@ static int sun6i_dsi_bind(struct device *dev, struct device *master,
dsi->drv = drv;
+ if (!tcon0)
+ return -EINVAL;
+
+ dsi->tcon = tcon0;
+
drm_encoder_helper_add(&dsi->encoder,
&sun6i_dsi_enc_helper_funcs);
ret = drm_encoder_init(drm,
diff --git a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h
index dbbc5b3ecbda..257cca660da0 100644
--- a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h
+++ b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h
@@ -33,6 +33,7 @@ struct sun6i_dsi {
struct device *dev;
struct sun4i_drv *drv;
+ struct sun4i_tcon *tcon;
struct mipi_dsi_device *device;
struct drm_panel *panel;
};
--
2.18.0.321.gffc6fa0e3
Current driver is calculating hfp maximum value by subtracting
htotal with hsync_end which is front back value, but the
hpp refers to front porch.
Front porch value is calculating by subtracting hsync_start with
hdisplay as per drm_mode timings, and BSP code from BPI-M64-bsp
is eventually following the same.
BPI-M64-bsp is computing hfp as (from linux-sunxi/
drivers/video/sunxi/disp2/disp/de/lowlevel_sun50iw1/de_dsi.c)
dsi_hbp = (hbp-hspw)*dsi_pixel_bits[format]/8 - (4+2);
dsi_hact = x * dsi_pixel_bits[format]/8;
dsi_hblk = (ht-hspw)*dsi_pixel_bits[format]/8-(4+4+2);
dsi_hfp = dsi_hblk - (4+dsi_hact+2) - (4+dsi_hbp+2);
Example,
u32 fmt = dsi_pixel_bits[format]/8;
=> ((ht-hspw)*fmt - 10) - (6 + x * fmt) - (6 + (hbp-hspw)*fmt - 6)
=> (ht - hspw - x - (hbp - hspw)) * fmt - 16
=> (ht - x - hbp) * fmt - 16
=> (ht - x - (timmings->hor_total_time - timmings->hor_front_porch - x)
* fmt - 16
=> (timmings->hor_total_time - x - timmings->hor_total_time +
timmings->hor_front_porch + x) * fmt - 16
=> timmings->hor_front_porch * fmt - 16
So, update the DSI hfp timing accordingly.
Tested on 2-lane, 4-lane MIPI-DSI LCD panels.
Signed-off-by: Jagan Teki <[email protected]>
---
drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
index e24719cabba2..9f72eb5f54a6 100644
--- a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
+++ b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
@@ -586,7 +586,8 @@ static void sun6i_dsi_setup_timings(struct sun6i_dsi *dsi,
*/
#define HFP_PACKET_OVERHEAD 6
hfp = max((unsigned int)HFP_PACKET_OVERHEAD,
- (mode->htotal - mode->hsync_end) * Bpp - HFP_PACKET_OVERHEAD);
+ (mode->hsync_start - mode->hdisplay) * Bpp -
+ HFP_PACKET_OVERHEAD);
/*
* hblk seems to be the line + porches length.
--
2.18.0.321.gffc6fa0e3
Amarula A64-Relic board by default bound with Techstar TS8550B
MIPI-DSI panel, add support for it.
DSI panel connected via board DSI port with,
- DLDO2 as VCC supply
- DLDO2 as IOVCC supply
- DLDO1 as VCC-DSI supply
- PD24 gpio for reset pin
- PD23 gpio for backlight enable pin
Signed-off-by: Jagan Teki <[email protected]>
---
.../allwinner/sun50i-a64-amarula-relic.dts | 39 +++++++++++++++++++
1 file changed, 39 insertions(+)
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-amarula-relic.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-amarula-relic.dts
index f180c841ac3c..703055f2a4fb 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-amarula-relic.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-amarula-relic.dts
@@ -9,6 +9,7 @@
#include "sun50i-a64.dtsi"
#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pwm/pwm.h>
/ {
model = "Amarula A64-Relic";
@@ -18,6 +19,14 @@
serial0 = &uart0;
};
+ backlight: backlight {
+ compatible = "pwm-backlight";
+ pwms = <&pwm 0 50000 PWM_POLARITY_INVERTED>;
+ brightness-levels = <1 2 4 8 16 32 64 128 512>;
+ default-brightness-level = <2>;
+ enable-gpios = <&pio 3 23 GPIO_ACTIVE_HIGH>; /* LCD-BL-EN: PD23 */
+ };
+
chosen {
stdout-path = "serial0:115200n8";
};
@@ -83,6 +92,30 @@
};
};
+&de {
+ status = "okay";
+};
+
+&dphy {
+ status = "okay";
+};
+
+&dsi {
+ vcc-dsi-supply = <®_dldo1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "okay";
+
+ panel@0 {
+ compatible = "techstar,ts8550b", "sitronix,st7701";
+ reg = <0>;
+ VCC-supply = <®_dldo2>;
+ IOVCC-supply = <®_dldo2>;
+ reset-gpios = <&pio 3 24 GPIO_ACTIVE_HIGH>; /* LCD-RST: PD24 */
+ backlight = <&backlight>;
+ };
+};
+
&ehci0 {
status = "okay";
};
@@ -160,6 +193,12 @@
status = "okay";
};
+&pwm {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm_pin>;
+ status = "okay";
+};
+
&r_rsb {
status = "okay";
--
2.18.0.321.gffc6fa0e3
Most of the Allwinner MIPI DSI controllers are supply with
VCC-DSI pin. which need to supply for some of the boards to
trigger the power.
So, document the supply property so-that the required board
can eable it via device tree.
Signed-off-by: Jagan Teki <[email protected]>
Reviewed-by: Rob Herring <[email protected]>
---
Documentation/devicetree/bindings/display/sunxi/sun6i-dsi.txt | 3 +++
1 file changed, 3 insertions(+)
diff --git a/Documentation/devicetree/bindings/display/sunxi/sun6i-dsi.txt b/Documentation/devicetree/bindings/display/sunxi/sun6i-dsi.txt
index 6a6cf5de08b0..69e233e8fad1 100644
--- a/Documentation/devicetree/bindings/display/sunxi/sun6i-dsi.txt
+++ b/Documentation/devicetree/bindings/display/sunxi/sun6i-dsi.txt
@@ -27,6 +27,9 @@ Required properties:
first port should be the input endpoint, usually coming from the
associated TCON.
+Optional properties:
+ - vcc-dsi-supply: the VCC-DSI power supply of the DSI encoder
+
Any MIPI-DSI device attached to this should be described according to
the bindings defined in ../mipi-dsi-bus.txt
--
2.18.0.321.gffc6fa0e3
This patch add support for Bananapi S070WV20-CT16 DSI panel to
BPI-M64 board.
DSI panel connected via board DSI port with,
- DLDO1 as VDD supply
- PD6 gpio for reset pin
- PD5 gpio for backlight enable pin
- PD7 gpio for backlight vdd supply
Signed-off-by: Jagan Teki <[email protected]>
---
.../dts/allwinner/sun50i-a64-bananapi-m64.dts | 43 +++++++++++++++++++
1 file changed, 43 insertions(+)
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-bananapi-m64.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-bananapi-m64.dts
index c99f66271287..14ecc57c72cf 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-bananapi-m64.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-bananapi-m64.dts
@@ -45,6 +45,7 @@
#include "sun50i-a64.dtsi"
#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pwm/pwm.h>
/ {
model = "BananaPi-M64";
@@ -56,6 +57,15 @@
serial1 = &uart1;
};
+ backlight: backlight {
+ compatible = "pwm-backlight";
+ pwms = <&r_pwm 0 50000 PWM_POLARITY_INVERTED>;
+ brightness-levels = <1 2 4 8 16 32 64 128 512>;
+ default-brightness-level = <2>;
+ enable-gpios = <&pio 3 5 GPIO_ACTIVE_HIGH>; /* LCD-BL-EN: PD5 */
+ power-supply = <®_vdd_backlight>;
+ };
+
chosen {
stdout-path = "serial0:115200n8";
};
@@ -126,6 +136,15 @@
};
};
+ reg_vdd_backlight: vdd-backlight {
+ compatible = "regulator-fixed";
+ regulator-name = "vdd-backlight";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&pio 3 7 GPIO_ACTIVE_HIGH>; /* LCD-PWR-EN: PD7 */
+ enable-active-high;
+ };
+
wifi_pwrseq: wifi_pwrseq {
compatible = "mmc-pwrseq-simple";
reset-gpios = <&r_pio 0 2 GPIO_ACTIVE_LOW>; /* PL2 */
@@ -169,6 +188,24 @@
status = "okay";
};
+&dphy {
+ status = "okay";
+};
+
+&dsi {
+ status = "okay";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ panel@0 {
+ compatible = "bananapi,s070wv20-ct16-icn6211";
+ reg = <0>;
+ reset-gpios = <&pio 3 6 GPIO_ACTIVE_HIGH>; /* LCD-RST: PD6 */
+ vdd-supply = <®_dldo1>;
+ backlight = <&backlight>;
+ };
+};
+
&ehci0 {
status = "okay";
};
@@ -261,6 +298,12 @@
status = "okay";
};
+&r_pwm {
+ pinctrl-names = "default";
+ pinctrl-0 = <&r_pwm_pin>;
+ status = "okay";
+};
+
&r_rsb {
status = "okay";
--
2.18.0.321.gffc6fa0e3
Current driver is calculating hbp maximum value by subtracting
hsync_start with hdisplay which is front porch value, but the
hbp refers to back porch.
Back porch value is calculating by subtracting htotal with
hsync_end as per drm_mode timings, and BSP code from BPI-M64-bsp
is eventually following the same.
BPI-M64-bsp is computing hbp as
(in drivers/video/sunxi/disp2/disp/de/lowlevel_sun50iw1/de_dsi.c)
dsi_hbp = (hbp-hspw)*dsi_pixel_bits[format]/8 - (4+2);
=> (panel->lcd_hbp - timmings->hor_sync_time)
=> (timmings->hor_back_porch + timmings->hor_sync_time -
timmings->hor_sync_time)
=> timmings->hor_back_porch
=> mode->htotal - mode->hsync_end
So, update the MIPI-DSI hbp value accordingly.
Tested on 2-lane, 4-lane DSI LCD panels.
Signed-off-by: Jagan Teki <[email protected]>
---
drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
index 58bda0928aef..e24719cabba2 100644
--- a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
+++ b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
@@ -578,7 +578,7 @@ static void sun6i_dsi_setup_timings(struct sun6i_dsi *dsi,
*/
#define HBP_PACKET_OVERHEAD 6
hbp = max((unsigned int)HBP_PACKET_OVERHEAD,
- (mode->hsync_start - mode->hdisplay) * Bpp - HBP_PACKET_OVERHEAD);
+ (mode->htotal - mode->hsync_end) * Bpp - HBP_PACKET_OVERHEAD);
/*
* The frontporch is set using a blanking packet (4 bytes +
--
2.18.0.321.gffc6fa0e3
On Fri, Jan 25, 2019 at 01:28:50AM +0530, Jagan Teki wrote:
> Most of the Allwinner MIPI DSI controllers are supply with
> VCC-DSI pin. which need to supply for some of the boards to
> trigger the power.
>
> So, document the supply property so-that the required board
> can eable it via device tree.
>
> Signed-off-by: Jagan Teki <[email protected]>
> Reviewed-by: Rob Herring <[email protected]>
> ---
> Documentation/devicetree/bindings/display/sunxi/sun6i-dsi.txt | 3 +++
> 1 file changed, 3 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/display/sunxi/sun6i-dsi.txt b/Documentation/devicetree/bindings/display/sunxi/sun6i-dsi.txt
> index 6a6cf5de08b0..69e233e8fad1 100644
> --- a/Documentation/devicetree/bindings/display/sunxi/sun6i-dsi.txt
> +++ b/Documentation/devicetree/bindings/display/sunxi/sun6i-dsi.txt
> @@ -27,6 +27,9 @@ Required properties:
> first port should be the input endpoint, usually coming from the
> associated TCON.
>
> +Optional properties:
> + - vcc-dsi-supply: the VCC-DSI power supply of the DSI encoder
> +
It looks like the VCC power rail is found on all the Allwinner SoCs,
so it should be made mandatory.
Maxime
--
Maxime Ripard, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
On Fri, Jan 25, 2019 at 01:28:52AM +0530, Jagan Teki wrote:
> The MIPI DSI controller in Allwinner A64 is similar to A33.
>
> But unlike A33, A64 doesn't have DSI_SCLK gating which eventually
> set the mod clock rate for the controller.
>
> So, use the DSI_DPHY gating for the similar purpose of mod clock
> so-that the controller can operate properly.
>
> Signed-off-by: Jagan Teki <[email protected]>
> Reviewed-by: Rob Herring <[email protected]>
> ---
> Documentation/devicetree/bindings/display/sunxi/sun6i-dsi.txt | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/Documentation/devicetree/bindings/display/sunxi/sun6i-dsi.txt b/Documentation/devicetree/bindings/display/sunxi/sun6i-dsi.txt
> index 69e233e8fad1..dbda2e567760 100644
> --- a/Documentation/devicetree/bindings/display/sunxi/sun6i-dsi.txt
> +++ b/Documentation/devicetree/bindings/display/sunxi/sun6i-dsi.txt
> @@ -12,6 +12,7 @@ The DSI Encoder generates the DSI signal from the TCON's.
> Required properties:
> - compatible: value must be one of:
> * allwinner,sun6i-a31-mipi-dsi
> + * "allwinner,sun50i-a64-mipi-dsi", "allwinner,sun6i-a31-mipi-dsi"
The other line doesn't have quotes, we should be consistent
Maxime
--
Maxime Ripard, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
On Fri, Jan 25, 2019 at 01:28:53AM +0530, Jagan Teki wrote:
> The MIPI DSI PHY controller on Allwinner A64 is similar
> on the one on A31.
>
> Add A64 compatible and append A31 compatible as fallback.
>
> Signed-off-by: Jagan Teki <[email protected]>
> Reviewed-by: Rob Herring <[email protected]>
> ---
> Documentation/devicetree/bindings/display/sunxi/sun6i-dsi.txt | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/Documentation/devicetree/bindings/display/sunxi/sun6i-dsi.txt b/Documentation/devicetree/bindings/display/sunxi/sun6i-dsi.txt
> index dbda2e567760..9c553637c72b 100644
> --- a/Documentation/devicetree/bindings/display/sunxi/sun6i-dsi.txt
> +++ b/Documentation/devicetree/bindings/display/sunxi/sun6i-dsi.txt
> @@ -40,6 +40,7 @@ D-PHY
> Required properties:
> - compatible: value must be one of:
> * allwinner,sun6i-a31-mipi-dphy
> + * "allwinner,sun50i-a64-mipi-dphy", "allwinner,sun6i-a31-mipi-dphy"
Same remark than patch 14
Maxime
--
Maxime Ripard, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
On Fri, Jan 25, 2019 at 01:28:54AM +0530, Jagan Teki wrote:
> The A64 has a MIPI-DSI block which is similar to A31.
>
> Add dsi, dphy nodes with A31 fallback compatible and finally
> connect the dsi node to tcon0 node to make proper DSI pipeline.
>
> Signed-off-by: Jagan Teki <[email protected]>
> ---
> arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 47 +++++++++++++++++++
> 1 file changed, 47 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
> index cdc154b14a7e..e18d81aff813 100644
> --- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
> +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
> @@ -358,6 +358,12 @@
> #address-cells = <1>;
> #size-cells = <0>;
> reg = <1>;
> +
> + tcon0_out_dsi: endpoint@1 {
> + reg = <1>;
> + remote-endpoint = <&dsi_in_tcon0>;
> + allwinner,tcon-channel = <1>;
> + };
> };
> };
> };
> @@ -935,6 +941,47 @@
> status = "disabled";
> };
>
> + dsi: dsi@1ca0000 {
> + compatible = "allwinner,sun50i-a64-mipi-dsi",
> + "allwinner,sun6i-a31-mipi-dsi";
> + reg = <0x01ca0000 0x1000>;
> + interrupts = <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>;
> + clocks = <&ccu CLK_BUS_MIPI_DSI>,
> + <&ccu CLK_DSI_DPHY>;
This one looks weird. There's only a single clock in the A64, and it
seems to be for the D-PHY only.
And the rate is fixed at 148.5 MHz apparently, as opposed to the
current code that is running at twice that speed.
Maxime
--
Maxime Ripard, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
On Fri, Jan 25, 2019 at 01:28:49AM +0530, Jagan Teki wrote:
> Minimum PLL used for MIPI is 500MHz, as per manual, but
> lowering the min rate by 300MHz can result proper working
> nkms divider with the help of desired dclock rate from
> panel driver.
>
> Signed-off-by: Jagan Teki <[email protected]>
> Acked-by: Stephen Boyd <[email protected]>
Going 200MHz below the minimum doesn't seem really reasonable. What
is the issue that you are trying to fix here?
It looks like it's picking bad dividers, but if that's the case, this
isn't the proper fix.
Maxime
--
Maxime Ripard, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
On 25/01/19 9:22 PM, Maxime Ripard wrote:
> On Fri, Jan 25, 2019 at 01:28:52AM +0530, Jagan Teki wrote:
>> The MIPI DSI controller in Allwinner A64 is similar to A33.
>>
>> But unlike A33, A64 doesn't have DSI_SCLK gating which eventually
>> set the mod clock rate for the controller.
>>
>> So, use the DSI_DPHY gating for the similar purpose of mod clock
>> so-that the controller can operate properly.
>>
>> Signed-off-by: Jagan Teki <[email protected]>
>> Reviewed-by: Rob Herring <[email protected]>
>> ---
>> Documentation/devicetree/bindings/display/sunxi/sun6i-dsi.txt | 1 +
>> 1 file changed, 1 insertion(+)
>>
>> diff --git a/Documentation/devicetree/bindings/display/sunxi/sun6i-dsi.txt b/Documentation/devicetree/bindings/display/sunxi/sun6i-dsi.txt
>> index 69e233e8fad1..dbda2e567760 100644
>> --- a/Documentation/devicetree/bindings/display/sunxi/sun6i-dsi.txt
>> +++ b/Documentation/devicetree/bindings/display/sunxi/sun6i-dsi.txt
>> @@ -12,6 +12,7 @@ The DSI Encoder generates the DSI signal from the TCON's.
>> Required properties:
>> - compatible: value must be one of:
>> * allwinner,sun6i-a31-mipi-dsi
>> + * "allwinner,sun50i-a64-mipi-dsi", "allwinner,sun6i-a31-mipi-dsi"
>
> The other line doesn't have quotes, we should be consistent
You mean to say, remove quotes like this
allwinner,sun50i-a64-mipi-dsi, allwinner,sun6i-a31-mipi-dsi
This make confusion with comma with allwinner vs next compatible string
isn't it? (In fact I did follow the similar like TCON in sun4i-drm.txt)
On Sat, Jan 26, 2019 at 2:54 AM Maxime Ripard <[email protected]> wrote:
>
> On Fri, Jan 25, 2019 at 01:28:49AM +0530, Jagan Teki wrote:
> > Minimum PLL used for MIPI is 500MHz, as per manual, but
> > lowering the min rate by 300MHz can result proper working
> > nkms divider with the help of desired dclock rate from
> > panel driver.
> >
> > Signed-off-by: Jagan Teki <[email protected]>
> > Acked-by: Stephen Boyd <[email protected]>
>
> Going 200MHz below the minimum doesn't seem really reasonable. What
> is the issue that you are trying to fix here?
>
> It looks like it's picking bad dividers, but if that's the case, this
> isn't the proper fix.
As I stated in earlier patches, the whole idea is pick the desired
dclk divider based dclk rate. So the dotclock, sun4i_dclk_round_rate
is unable to get the proper dclk divider at the end, so it eventually
picking up wrong divider value and fired vblank timeout.
So, we come-up with optimal and working min_rate 300MHz in pll-mipi to
get the desired clock something like below.
[ 2.415773] [drm] No driver support for vblank timestamp query.
[ 2.424116] sun4i_dclk_round_rate: min_div = 4 max_div = 127, rate = 55000000
[ 2.424172] ideal = 220000000, rounded = 0
[ 2.424176] ideal = 275000000, rounded = 0
[ 2.424194] ccu_nkm_round_rate: rate = 330000000
[ 2.424197] ideal = 330000000, rounded = 330000000
[ 2.424201] sun4i_dclk_round_rate: div = 6 rate = 55000000
[ 2.424205] sun4i_dclk_round_rate: min_div = 4 max_div = 127, rate = 55000000
[ 2.424209] ideal = 220000000, rounded = 0
[ 2.424213] ideal = 275000000, rounded = 0
[ 2.424230] ccu_nkm_round_rate: rate = 330000000
[ 2.424233] ideal = 330000000, rounded = 330000000
[ 2.424236] sun4i_dclk_round_rate: div = 6 rate = 55000000
[ 2.424253] ccu_nkm_round_rate: rate = 330000000
[ 2.424270] ccu_nkm_round_rate: rate = 330000000
[ 2.424278] sun4i_dclk_recalc_rate: val = 1, rate = 330000000
[ 2.424281] sun4i_dclk_recalc_rate: val = 1, rate = 330000000
[ 2.424306] ccu_nkm_set_rate: rate = 330000000, parent_rate = 297000000
[ 2.424309] ccu_nkm_set_rate: _nkm.n = 5
[ 2.424311] ccu_nkm_set_rate: _nkm.k = 2
[ 2.424313] ccu_nkm_set_rate: _nkm.m = 9
[ 2.424661] sun4i_dclk_set_rate div 6
[ 2.424668] sun4i_dclk_recalc_rate: val = 6, rate = 55000000
But look like this wouldn't valid for all other dclock rates, say BPI
panel has 30MHz clock that would failed with this logic.
On the other side Allwinner BSP calculating dclk divider based on the
SoC's. for A33 [1] it is fixed dclk divider of 4 and for A64 is is
calculated based on the bpp/lanes.
Since the above min_rate is not desired for possible panels clock, I
think we can rely on BSP to make a move here. I'm planning to do these
changes in next version.
Let me know if you have any comments here?
[1] https://patchwork.kernel.org/patch/10777519/
On Sat, Jan 26, 2019 at 09:39:00PM +0530, Jagan Teki wrote:
> On 25/01/19 9:22 PM, Maxime Ripard wrote:
> > On Fri, Jan 25, 2019 at 01:28:52AM +0530, Jagan Teki wrote:
> > > The MIPI DSI controller in Allwinner A64 is similar to A33.
> > >
> > > But unlike A33, A64 doesn't have DSI_SCLK gating which eventually
> > > set the mod clock rate for the controller.
> > >
> > > So, use the DSI_DPHY gating for the similar purpose of mod clock
> > > so-that the controller can operate properly.
> > >
> > > Signed-off-by: Jagan Teki <[email protected]>
> > > Reviewed-by: Rob Herring <[email protected]>
> > > ---
> > > Documentation/devicetree/bindings/display/sunxi/sun6i-dsi.txt | 1 +
> > > 1 file changed, 1 insertion(+)
> > >
> > > diff --git a/Documentation/devicetree/bindings/display/sunxi/sun6i-dsi.txt b/Documentation/devicetree/bindings/display/sunxi/sun6i-dsi.txt
> > > index 69e233e8fad1..dbda2e567760 100644
> > > --- a/Documentation/devicetree/bindings/display/sunxi/sun6i-dsi.txt
> > > +++ b/Documentation/devicetree/bindings/display/sunxi/sun6i-dsi.txt
> > > @@ -12,6 +12,7 @@ The DSI Encoder generates the DSI signal from the TCON's.
> > > Required properties:
> > > - compatible: value must be one of:
> > > * allwinner,sun6i-a31-mipi-dsi
> > > + * "allwinner,sun50i-a64-mipi-dsi", "allwinner,sun6i-a31-mipi-dsi"
> >
> > The other line doesn't have quotes, we should be consistent
>
> You mean to say, remove quotes like this
>
> allwinner,sun50i-a64-mipi-dsi, allwinner,sun6i-a31-mipi-dsi
Yep
> This make confusion with comma with allwinner vs next compatible string
> isn't it? (In fact I did follow the similar like TCON in sun4i-drm.txt)
There's no really clear consensus here, andd i don't really have a
strong opinion on the matter either. Since the YAML schemas are going
to have it without double quotes, I guess we should use that
convention as well, but we want to remain consistent at least.
Maxime
--
Maxime Ripard, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
On Mon, Jan 28, 2019 at 03:06:10PM +0530, Jagan Teki wrote:
> On Sat, Jan 26, 2019 at 2:54 AM Maxime Ripard <[email protected]> wrote:
> >
> > On Fri, Jan 25, 2019 at 01:28:49AM +0530, Jagan Teki wrote:
> > > Minimum PLL used for MIPI is 500MHz, as per manual, but
> > > lowering the min rate by 300MHz can result proper working
> > > nkms divider with the help of desired dclock rate from
> > > panel driver.
> > >
> > > Signed-off-by: Jagan Teki <[email protected]>
> > > Acked-by: Stephen Boyd <[email protected]>
> >
> > Going 200MHz below the minimum doesn't seem really reasonable. What
> > is the issue that you are trying to fix here?
> >
> > It looks like it's picking bad dividers, but if that's the case, this
> > isn't the proper fix.
>
> As I stated in earlier patches, the whole idea is pick the desired
> dclk divider based dclk rate. So the dotclock, sun4i_dclk_round_rate
> is unable to get the proper dclk divider at the end, so it eventually
> picking up wrong divider value and fired vblank timeout.
>
> So, we come-up with optimal and working min_rate 300MHz in pll-mipi to
> get the desired clock something like below.
> [ 2.415773] [drm] No driver support for vblank timestamp query.
> [ 2.424116] sun4i_dclk_round_rate: min_div = 4 max_div = 127, rate = 55000000
> [ 2.424172] ideal = 220000000, rounded = 0
> [ 2.424176] ideal = 275000000, rounded = 0
> [ 2.424194] ccu_nkm_round_rate: rate = 330000000
> [ 2.424197] ideal = 330000000, rounded = 330000000
> [ 2.424201] sun4i_dclk_round_rate: div = 6 rate = 55000000
> [ 2.424205] sun4i_dclk_round_rate: min_div = 4 max_div = 127, rate = 55000000
> [ 2.424209] ideal = 220000000, rounded = 0
> [ 2.424213] ideal = 275000000, rounded = 0
> [ 2.424230] ccu_nkm_round_rate: rate = 330000000
> [ 2.424233] ideal = 330000000, rounded = 330000000
> [ 2.424236] sun4i_dclk_round_rate: div = 6 rate = 55000000
> [ 2.424253] ccu_nkm_round_rate: rate = 330000000
> [ 2.424270] ccu_nkm_round_rate: rate = 330000000
> [ 2.424278] sun4i_dclk_recalc_rate: val = 1, rate = 330000000
> [ 2.424281] sun4i_dclk_recalc_rate: val = 1, rate = 330000000
> [ 2.424306] ccu_nkm_set_rate: rate = 330000000, parent_rate = 297000000
> [ 2.424309] ccu_nkm_set_rate: _nkm.n = 5
> [ 2.424311] ccu_nkm_set_rate: _nkm.k = 2
> [ 2.424313] ccu_nkm_set_rate: _nkm.m = 9
> [ 2.424661] sun4i_dclk_set_rate div 6
> [ 2.424668] sun4i_dclk_recalc_rate: val = 6, rate = 55000000
>
> But look like this wouldn't valid for all other dclock rates, say BPI
> panel has 30MHz clock that would failed with this logic.
>
> On the other side Allwinner BSP calculating dclk divider based on the
> SoC's. for A33 [1] it is fixed dclk divider of 4 and for A64 is is
> calculated based on the bpp/lanes.
It looks like the A64 has the same divider of 4:
https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/lowlevel_sun50iw1/de_dsi.c#L12
I think you're confusing it with the ratio between the pixel clock and
the dotclock, called dsi_div:
https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/lowlevel_sun50iw1/disp_al.c#L198
Maxime
--
Maxime Ripard, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
On Tue, Jan 29, 2019 at 8:43 PM Maxime Ripard <[email protected]> wrote:
>
> On Mon, Jan 28, 2019 at 03:06:10PM +0530, Jagan Teki wrote:
> > On Sat, Jan 26, 2019 at 2:54 AM Maxime Ripard <[email protected]> wrote:
> > >
> > > On Fri, Jan 25, 2019 at 01:28:49AM +0530, Jagan Teki wrote:
> > > > Minimum PLL used for MIPI is 500MHz, as per manual, but
> > > > lowering the min rate by 300MHz can result proper working
> > > > nkms divider with the help of desired dclock rate from
> > > > panel driver.
> > > >
> > > > Signed-off-by: Jagan Teki <[email protected]>
> > > > Acked-by: Stephen Boyd <[email protected]>
> > >
> > > Going 200MHz below the minimum doesn't seem really reasonable. What
> > > is the issue that you are trying to fix here?
> > >
> > > It looks like it's picking bad dividers, but if that's the case, this
> > > isn't the proper fix.
> >
> > As I stated in earlier patches, the whole idea is pick the desired
> > dclk divider based dclk rate. So the dotclock, sun4i_dclk_round_rate
> > is unable to get the proper dclk divider at the end, so it eventually
> > picking up wrong divider value and fired vblank timeout.
> >
> > So, we come-up with optimal and working min_rate 300MHz in pll-mipi to
> > get the desired clock something like below.
> > [ 2.415773] [drm] No driver support for vblank timestamp query.
> > [ 2.424116] sun4i_dclk_round_rate: min_div = 4 max_div = 127, rate = 55000000
> > [ 2.424172] ideal = 220000000, rounded = 0
> > [ 2.424176] ideal = 275000000, rounded = 0
> > [ 2.424194] ccu_nkm_round_rate: rate = 330000000
> > [ 2.424197] ideal = 330000000, rounded = 330000000
> > [ 2.424201] sun4i_dclk_round_rate: div = 6 rate = 55000000
> > [ 2.424205] sun4i_dclk_round_rate: min_div = 4 max_div = 127, rate = 55000000
> > [ 2.424209] ideal = 220000000, rounded = 0
> > [ 2.424213] ideal = 275000000, rounded = 0
> > [ 2.424230] ccu_nkm_round_rate: rate = 330000000
> > [ 2.424233] ideal = 330000000, rounded = 330000000
> > [ 2.424236] sun4i_dclk_round_rate: div = 6 rate = 55000000
> > [ 2.424253] ccu_nkm_round_rate: rate = 330000000
> > [ 2.424270] ccu_nkm_round_rate: rate = 330000000
> > [ 2.424278] sun4i_dclk_recalc_rate: val = 1, rate = 330000000
> > [ 2.424281] sun4i_dclk_recalc_rate: val = 1, rate = 330000000
> > [ 2.424306] ccu_nkm_set_rate: rate = 330000000, parent_rate = 297000000
> > [ 2.424309] ccu_nkm_set_rate: _nkm.n = 5
> > [ 2.424311] ccu_nkm_set_rate: _nkm.k = 2
> > [ 2.424313] ccu_nkm_set_rate: _nkm.m = 9
> > [ 2.424661] sun4i_dclk_set_rate div 6
> > [ 2.424668] sun4i_dclk_recalc_rate: val = 6, rate = 55000000
> >
> > But look like this wouldn't valid for all other dclock rates, say BPI
> > panel has 30MHz clock that would failed with this logic.
> >
> > On the other side Allwinner BSP calculating dclk divider based on the
> > SoC's. for A33 [1] it is fixed dclk divider of 4 and for A64 is is
> > calculated based on the bpp/lanes.
>
> It looks like the A64 has the same divider of 4:
> https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/lowlevel_sun50iw1/de_dsi.c#L12
>
> I think you're confusing it with the ratio between the pixel clock and
> the dotclock, called dsi_div:
> https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/lowlevel_sun50iw1/disp_al.c#L198
Ahh.. I thought this initially but as far as DSI clock computation is
concern, the L12 tcon_div is local variable which is used for edge0
computation in burst mode and not for the dsi clock computation. Since
the BSP is unable to get the tcon_div during edge0 computation, they
defined it locally I think.
You can see the lcd_clk_config() code [2], where we can see DSI clock
computation using dsi_div value.
Here is dump after the in Line 792 which is after computation[3]
[ 10.800737] lcd_clk_config: dsi_div = 6, tcon_div = 4, lcd_div = 1
[ 10.800743] lcd_clk_config: lcd_dclk_freq = 55, dclk_rate = 55000000
[ 10.800749] lcd_clk_config: lcd_rate = 330000000, pll_rate = 330000000
The above dump the lcd_rate 330MHz is computed with panel clock, 55MHz
into dsi_div 6. So this can be our actual divider values dclk_min_div,
dclk_max_div in sun4i_dclk_round_rate (from
drivers/gpu/drm/sun4i/sun4i_dotclock.c)
We can even confirm this from Mainline code:
[ 1.866128] sun4i_dclk_round_rate: min_div = 6 max_div = 6, rate = 55000000
[ 1.873112] round_rate, parent = 330000000
[ 1.877351] round_rate, rate = 330000000
[ 1.881338] ideal = 330000000, rounded = 330000000, div = 6
[ 1.887232] sun4i_dclk_round_rate: div = 6 rate = 55000000
[ 1.887239] sun4i_dclk_round_rate: min_div = 6 max_div = 6, rate = 55000000
[ 1.887243] round_rate, parent = 330000000
[ 1.887259] round_rate, rate = 330000000
[ 1.887264] ideal = 330000000, rounded = 330000000, div = 6
[ 1.887267] sun4i_dclk_round_rate: div = 6 rate = 55000000
[ 1.887270] round_rate, parent = 330000000
[ 1.887286] round_rate, rate = 330000000
[ 1.887292] round_rate, parent = 330000000
[ 1.887307] round_rate, rate = 330000000
[ 1.887320] sun4i_dclk_recalc_rate: val = 1, rate = 330000000
[ 1.887324] sun4i_dclk_recalc_rate: val = 1, rate = 330000000
[ 1.887350] rate = 330000000
[ 1.887353] parent_rate = 297000000
[ 1.887355] reg = 0x80c00000
[ 1.887359] _nkm.n = 5, nkm->n.offset = 0x1, nkm->n.shift = 8
[ 1.887362] _nkm.k = 2, nkm->k.offset = 0x1, nkm->k.shift = 4
[ 1.887365] _nkm.m = 9, nkm->m.offset = 0x1, nkm->m.shift = 0
[ 1.887712] sun4i_dclk_set_rate div 6
[ 1.887720] sun4i_dclk_recalc_rate: val = 6, rate = 55000000
So, the dsi_div from AW BSP is our dclk_mini_div(and dclk_max_div) and
that can be computed as format/lanes in A64.
Hope this explaining clears the diff, let me know if I miss anything.
[2] https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L781
[3] https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L792
On Tue, Jan 29, 2019 at 11:01:31PM +0530, Jagan Teki wrote:
> On Tue, Jan 29, 2019 at 8:43 PM Maxime Ripard <[email protected]> wrote:
> >
> > On Mon, Jan 28, 2019 at 03:06:10PM +0530, Jagan Teki wrote:
> > > On Sat, Jan 26, 2019 at 2:54 AM Maxime Ripard <[email protected]> wrote:
> > > >
> > > > On Fri, Jan 25, 2019 at 01:28:49AM +0530, Jagan Teki wrote:
> > > > > Minimum PLL used for MIPI is 500MHz, as per manual, but
> > > > > lowering the min rate by 300MHz can result proper working
> > > > > nkms divider with the help of desired dclock rate from
> > > > > panel driver.
> > > > >
> > > > > Signed-off-by: Jagan Teki <[email protected]>
> > > > > Acked-by: Stephen Boyd <[email protected]>
> > > >
> > > > Going 200MHz below the minimum doesn't seem really reasonable. What
> > > > is the issue that you are trying to fix here?
> > > >
> > > > It looks like it's picking bad dividers, but if that's the case, this
> > > > isn't the proper fix.
> > >
> > > As I stated in earlier patches, the whole idea is pick the desired
> > > dclk divider based dclk rate. So the dotclock, sun4i_dclk_round_rate
> > > is unable to get the proper dclk divider at the end, so it eventually
> > > picking up wrong divider value and fired vblank timeout.
> > >
> > > So, we come-up with optimal and working min_rate 300MHz in pll-mipi to
> > > get the desired clock something like below.
> > > [ 2.415773] [drm] No driver support for vblank timestamp query.
> > > [ 2.424116] sun4i_dclk_round_rate: min_div = 4 max_div = 127, rate = 55000000
> > > [ 2.424172] ideal = 220000000, rounded = 0
> > > [ 2.424176] ideal = 275000000, rounded = 0
> > > [ 2.424194] ccu_nkm_round_rate: rate = 330000000
> > > [ 2.424197] ideal = 330000000, rounded = 330000000
> > > [ 2.424201] sun4i_dclk_round_rate: div = 6 rate = 55000000
> > > [ 2.424205] sun4i_dclk_round_rate: min_div = 4 max_div = 127, rate = 55000000
> > > [ 2.424209] ideal = 220000000, rounded = 0
> > > [ 2.424213] ideal = 275000000, rounded = 0
> > > [ 2.424230] ccu_nkm_round_rate: rate = 330000000
> > > [ 2.424233] ideal = 330000000, rounded = 330000000
> > > [ 2.424236] sun4i_dclk_round_rate: div = 6 rate = 55000000
> > > [ 2.424253] ccu_nkm_round_rate: rate = 330000000
> > > [ 2.424270] ccu_nkm_round_rate: rate = 330000000
> > > [ 2.424278] sun4i_dclk_recalc_rate: val = 1, rate = 330000000
> > > [ 2.424281] sun4i_dclk_recalc_rate: val = 1, rate = 330000000
> > > [ 2.424306] ccu_nkm_set_rate: rate = 330000000, parent_rate = 297000000
> > > [ 2.424309] ccu_nkm_set_rate: _nkm.n = 5
> > > [ 2.424311] ccu_nkm_set_rate: _nkm.k = 2
> > > [ 2.424313] ccu_nkm_set_rate: _nkm.m = 9
> > > [ 2.424661] sun4i_dclk_set_rate div 6
> > > [ 2.424668] sun4i_dclk_recalc_rate: val = 6, rate = 55000000
> > >
> > > But look like this wouldn't valid for all other dclock rates, say BPI
> > > panel has 30MHz clock that would failed with this logic.
> > >
> > > On the other side Allwinner BSP calculating dclk divider based on the
> > > SoC's. for A33 [1] it is fixed dclk divider of 4 and for A64 is is
> > > calculated based on the bpp/lanes.
> >
> > It looks like the A64 has the same divider of 4:
> > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/lowlevel_sun50iw1/de_dsi.c#L12
> >
> > I think you're confusing it with the ratio between the pixel clock and
> > the dotclock, called dsi_div:
> > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/lowlevel_sun50iw1/disp_al.c#L198
>
> Ahh.. I thought this initially but as far as DSI clock computation is
> concern, the L12 tcon_div is local variable which is used for edge0
> computation in burst mode and not for the dsi clock computation. Since
> the BSP is unable to get the tcon_div during edge0 computation, they
> defined it locally I think.
>
> You can see the lcd_clk_config() code [2], where we can see DSI clock
> computation using dsi_div value.
>
> Here is dump after the in Line 792 which is after computation[3]
> [ 10.800737] lcd_clk_config: dsi_div = 6, tcon_div = 4, lcd_div = 1
> [ 10.800743] lcd_clk_config: lcd_dclk_freq = 55, dclk_rate = 55000000
> [ 10.800749] lcd_clk_config: lcd_rate = 330000000, pll_rate = 330000000
>
> The above dump the lcd_rate 330MHz is computed with panel clock, 55MHz
> into dsi_div 6. So this can be our actual divider values dclk_min_div,
> dclk_max_div in sun4i_dclk_round_rate (from
> drivers/gpu/drm/sun4i/sun4i_dotclock.c)
I wish it was in your commit log in the first place, instead of having
to exchange multiple mails over this.
However, I don't think that's quite true, and it might be a bug in
Allwinner's implementation (or rather something quite confusing).
You're right that the lcd_rate and pll_rate seem to be generated from
the pixel clock, and it indeed looks like the ratio between the pixel
clock and the TCON dotclock is defined through the number of bits per
lanes.
However, in this case, dsi_rate is actually the same than lcd_rate,
since pll_rate is going to be divided by dsi_div:
https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L791
Since lcd_div is 1, it also means that in this case, dsi_rate ==
dclk_rate.
The DSI module clock however, is always set to 148.5 MHz. Indeed, if
we look at:
https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L804
We can see that the rate in clk_info is used if it's different than
0. This is filled by disp_al_lcd_get_clk_info, which, in the case of a
DSI panel, will hardcode it to 148.5 MHz:
https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/lowlevel_sun50iw1/disp_al.c#L164
So, the DSI clock is set to this here:
https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L805
The TCON *module* clock (the one in the clock controller) has been set
to lcd_rate (so the pixel clock times the number of bits per lane) here:
https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L800
And the PLL has been set to the same rate here:
https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L794
Let's take a step back now: that function we were looking at,
lcd_clk_config, is called by lcd_clk_enable, which is in turn called
by disp_lcd_enable here:
https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L1328
The next function being called is disp_al_lcd_cfg, and that function
will hardcode the TCON dotclock divider to 4, here:
https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/lowlevel_sun50iw1/disp_al.c#L240
So, in the end, the dotclock divider is always 4, the DSI module clock
is set to 148.5 MHz, and the TCON module clock is set to 330MHz. Since
the TCON module clock doesn't have a divider, the PLL is set at that
same value but this is redundant.
I'll experiment with this and try to see how it works on the A33.
Maxime
--
Maxime Ripard, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
On Fri, Feb 1, 2019 at 8:01 PM Maxime Ripard <[email protected]> wrote:
>
> On Tue, Jan 29, 2019 at 11:01:31PM +0530, Jagan Teki wrote:
> > On Tue, Jan 29, 2019 at 8:43 PM Maxime Ripard <[email protected]> wrote:
> > >
> > > On Mon, Jan 28, 2019 at 03:06:10PM +0530, Jagan Teki wrote:
> > > > On Sat, Jan 26, 2019 at 2:54 AM Maxime Ripard <[email protected]> wrote:
> > > > >
> > > > > On Fri, Jan 25, 2019 at 01:28:49AM +0530, Jagan Teki wrote:
> > > > > > Minimum PLL used for MIPI is 500MHz, as per manual, but
> > > > > > lowering the min rate by 300MHz can result proper working
> > > > > > nkms divider with the help of desired dclock rate from
> > > > > > panel driver.
> > > > > >
> > > > > > Signed-off-by: Jagan Teki <[email protected]>
> > > > > > Acked-by: Stephen Boyd <[email protected]>
> > > > >
> > > > > Going 200MHz below the minimum doesn't seem really reasonable. What
> > > > > is the issue that you are trying to fix here?
> > > > >
> > > > > It looks like it's picking bad dividers, but if that's the case, this
> > > > > isn't the proper fix.
> > > >
> > > > As I stated in earlier patches, the whole idea is pick the desired
> > > > dclk divider based dclk rate. So the dotclock, sun4i_dclk_round_rate
> > > > is unable to get the proper dclk divider at the end, so it eventually
> > > > picking up wrong divider value and fired vblank timeout.
> > > >
> > > > So, we come-up with optimal and working min_rate 300MHz in pll-mipi to
> > > > get the desired clock something like below.
> > > > [ 2.415773] [drm] No driver support for vblank timestamp query.
> > > > [ 2.424116] sun4i_dclk_round_rate: min_div = 4 max_div = 127, rate = 55000000
> > > > [ 2.424172] ideal = 220000000, rounded = 0
> > > > [ 2.424176] ideal = 275000000, rounded = 0
> > > > [ 2.424194] ccu_nkm_round_rate: rate = 330000000
> > > > [ 2.424197] ideal = 330000000, rounded = 330000000
> > > > [ 2.424201] sun4i_dclk_round_rate: div = 6 rate = 55000000
> > > > [ 2.424205] sun4i_dclk_round_rate: min_div = 4 max_div = 127, rate = 55000000
> > > > [ 2.424209] ideal = 220000000, rounded = 0
> > > > [ 2.424213] ideal = 275000000, rounded = 0
> > > > [ 2.424230] ccu_nkm_round_rate: rate = 330000000
> > > > [ 2.424233] ideal = 330000000, rounded = 330000000
> > > > [ 2.424236] sun4i_dclk_round_rate: div = 6 rate = 55000000
> > > > [ 2.424253] ccu_nkm_round_rate: rate = 330000000
> > > > [ 2.424270] ccu_nkm_round_rate: rate = 330000000
> > > > [ 2.424278] sun4i_dclk_recalc_rate: val = 1, rate = 330000000
> > > > [ 2.424281] sun4i_dclk_recalc_rate: val = 1, rate = 330000000
> > > > [ 2.424306] ccu_nkm_set_rate: rate = 330000000, parent_rate = 297000000
> > > > [ 2.424309] ccu_nkm_set_rate: _nkm.n = 5
> > > > [ 2.424311] ccu_nkm_set_rate: _nkm.k = 2
> > > > [ 2.424313] ccu_nkm_set_rate: _nkm.m = 9
> > > > [ 2.424661] sun4i_dclk_set_rate div 6
> > > > [ 2.424668] sun4i_dclk_recalc_rate: val = 6, rate = 55000000
> > > >
> > > > But look like this wouldn't valid for all other dclock rates, say BPI
> > > > panel has 30MHz clock that would failed with this logic.
> > > >
> > > > On the other side Allwinner BSP calculating dclk divider based on the
> > > > SoC's. for A33 [1] it is fixed dclk divider of 4 and for A64 is is
> > > > calculated based on the bpp/lanes.
> > >
> > > It looks like the A64 has the same divider of 4:
> > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/lowlevel_sun50iw1/de_dsi.c#L12
> > >
> > > I think you're confusing it with the ratio between the pixel clock and
> > > the dotclock, called dsi_div:
> > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/lowlevel_sun50iw1/disp_al.c#L198
> >
> > Ahh.. I thought this initially but as far as DSI clock computation is
> > concern, the L12 tcon_div is local variable which is used for edge0
> > computation in burst mode and not for the dsi clock computation. Since
> > the BSP is unable to get the tcon_div during edge0 computation, they
> > defined it locally I think.
> >
> > You can see the lcd_clk_config() code [2], where we can see DSI clock
> > computation using dsi_div value.
> >
> > Here is dump after the in Line 792 which is after computation[3]
> > [ 10.800737] lcd_clk_config: dsi_div = 6, tcon_div = 4, lcd_div = 1
> > [ 10.800743] lcd_clk_config: lcd_dclk_freq = 55, dclk_rate = 55000000
> > [ 10.800749] lcd_clk_config: lcd_rate = 330000000, pll_rate = 330000000
> >
> > The above dump the lcd_rate 330MHz is computed with panel clock, 55MHz
> > into dsi_div 6. So this can be our actual divider values dclk_min_div,
> > dclk_max_div in sun4i_dclk_round_rate (from
> > drivers/gpu/drm/sun4i/sun4i_dotclock.c)
>
> I wish it was in your commit log in the first place, instead of having
> to exchange multiple mails over this.
>
> However, I don't think that's quite true, and it might be a bug in
> Allwinner's implementation (or rather something quite confusing).
>
> You're right that the lcd_rate and pll_rate seem to be generated from
> the pixel clock, and it indeed looks like the ratio between the pixel
> clock and the TCON dotclock is defined through the number of bits per
> lanes.
>
> However, in this case, dsi_rate is actually the same than lcd_rate,
> since pll_rate is going to be divided by dsi_div:
> https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L791
>
> Since lcd_div is 1, it also means that in this case, dsi_rate ==
> dclk_rate.
Yes, but the lcd_rate and dsi_rate are not same, since dsi_rate is
again computed as dsi_div with pll_rate.
lcd_rate = dclk_rate * 6;
pll_rate = lcd_rate * 1;
dsi_rate = pll_rate / 6;
[ 14.719981] tcon_div = 4, lcd_div = 1, dsi_div = 6, dsi_rate = 148500000
[ 14.722666] dsi_div = 6, lcd_div = 1
[ 14.722695] [DISP]disp_module_init finish
[ 14.727699] lcd_rate = 180000000, pll_rate = 180000000
[ 14.730269] dsi_rate = 30000000
> The DSI module clock however, is always set to 148.5 MHz. Indeed, if
> we look at:
> https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L804
>
> We can see that the rate in clk_info is used if it's different than
> 0. This is filled by disp_al_lcd_get_clk_info, which, in the case of a
> DSI panel, will hardcode it to 148.5 MHz:
> https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/lowlevel_sun50iw1/disp_al.c#L164
>
> So, the DSI clock is set to this here:
> https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L805
>
> The TCON *module* clock (the one in the clock controller) has been set
> to lcd_rate (so the pixel clock times the number of bits per lane) here:
> https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L800
>
> And the PLL has been set to the same rate here:
> https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L794
>
> Let's take a step back now: that function we were looking at,
> lcd_clk_config, is called by lcd_clk_enable, which is in turn called
> by disp_lcd_enable here:
> https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L1328
>
> The next function being called is disp_al_lcd_cfg, and that function
> will hardcode the TCON dotclock divider to 4, here:
> https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/lowlevel_sun50iw1/disp_al.c#L240
Haa.. this is reason I have TCON_DCLK register value is 4 in BSP
# devmem 0x01c0c044
0xF0000004
> So, in the end, the dotclock divider is always 4, the DSI module clock
> is set to 148.5 MHz, and the TCON module clock is set to 330MHz. Since
> the TCON module clock doesn't have a divider, the PLL is set at that
> same value but this is redundant.
330 or 180MHz. if we have pixel clock 30MHz with 6 div value it's 180MHz.
>
> I'll experiment with this and try to see how it works on the A33.
OK, thanks. will try digging further on this from my side as well.
Hi Maxime,
On Fri, Feb 1, 2019 at 8:01 PM Maxime Ripard <[email protected]> wrote:
>
> On Tue, Jan 29, 2019 at 11:01:31PM +0530, Jagan Teki wrote:
> > On Tue, Jan 29, 2019 at 8:43 PM Maxime Ripard <[email protected]> wrote:
> > >
> > > On Mon, Jan 28, 2019 at 03:06:10PM +0530, Jagan Teki wrote:
> > > > On Sat, Jan 26, 2019 at 2:54 AM Maxime Ripard <[email protected]> wrote:
> > > > >
> > > > > On Fri, Jan 25, 2019 at 01:28:49AM +0530, Jagan Teki wrote:
> > > > > > Minimum PLL used for MIPI is 500MHz, as per manual, but
> > > > > > lowering the min rate by 300MHz can result proper working
> > > > > > nkms divider with the help of desired dclock rate from
> > > > > > panel driver.
> > > > > >
> > > > > > Signed-off-by: Jagan Teki <[email protected]>
> > > > > > Acked-by: Stephen Boyd <[email protected]>
> > > > >
> > > > > Going 200MHz below the minimum doesn't seem really reasonable. What
> > > > > is the issue that you are trying to fix here?
> > > > >
> > > > > It looks like it's picking bad dividers, but if that's the case, this
> > > > > isn't the proper fix.
> > > >
> > > > As I stated in earlier patches, the whole idea is pick the desired
> > > > dclk divider based dclk rate. So the dotclock, sun4i_dclk_round_rate
> > > > is unable to get the proper dclk divider at the end, so it eventually
> > > > picking up wrong divider value and fired vblank timeout.
> > > >
> > > > So, we come-up with optimal and working min_rate 300MHz in pll-mipi to
> > > > get the desired clock something like below.
> > > > [ 2.415773] [drm] No driver support for vblank timestamp query.
> > > > [ 2.424116] sun4i_dclk_round_rate: min_div = 4 max_div = 127, rate = 55000000
> > > > [ 2.424172] ideal = 220000000, rounded = 0
> > > > [ 2.424176] ideal = 275000000, rounded = 0
> > > > [ 2.424194] ccu_nkm_round_rate: rate = 330000000
> > > > [ 2.424197] ideal = 330000000, rounded = 330000000
> > > > [ 2.424201] sun4i_dclk_round_rate: div = 6 rate = 55000000
> > > > [ 2.424205] sun4i_dclk_round_rate: min_div = 4 max_div = 127, rate = 55000000
> > > > [ 2.424209] ideal = 220000000, rounded = 0
> > > > [ 2.424213] ideal = 275000000, rounded = 0
> > > > [ 2.424230] ccu_nkm_round_rate: rate = 330000000
> > > > [ 2.424233] ideal = 330000000, rounded = 330000000
> > > > [ 2.424236] sun4i_dclk_round_rate: div = 6 rate = 55000000
> > > > [ 2.424253] ccu_nkm_round_rate: rate = 330000000
> > > > [ 2.424270] ccu_nkm_round_rate: rate = 330000000
> > > > [ 2.424278] sun4i_dclk_recalc_rate: val = 1, rate = 330000000
> > > > [ 2.424281] sun4i_dclk_recalc_rate: val = 1, rate = 330000000
> > > > [ 2.424306] ccu_nkm_set_rate: rate = 330000000, parent_rate = 297000000
> > > > [ 2.424309] ccu_nkm_set_rate: _nkm.n = 5
> > > > [ 2.424311] ccu_nkm_set_rate: _nkm.k = 2
> > > > [ 2.424313] ccu_nkm_set_rate: _nkm.m = 9
> > > > [ 2.424661] sun4i_dclk_set_rate div 6
> > > > [ 2.424668] sun4i_dclk_recalc_rate: val = 6, rate = 55000000
> > > >
> > > > But look like this wouldn't valid for all other dclock rates, say BPI
> > > > panel has 30MHz clock that would failed with this logic.
> > > >
> > > > On the other side Allwinner BSP calculating dclk divider based on the
> > > > SoC's. for A33 [1] it is fixed dclk divider of 4 and for A64 is is
> > > > calculated based on the bpp/lanes.
> > >
> > > It looks like the A64 has the same divider of 4:
> > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/lowlevel_sun50iw1/de_dsi.c#L12
> > >
> > > I think you're confusing it with the ratio between the pixel clock and
> > > the dotclock, called dsi_div:
> > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/lowlevel_sun50iw1/disp_al.c#L198
> >
> > Ahh.. I thought this initially but as far as DSI clock computation is
> > concern, the L12 tcon_div is local variable which is used for edge0
> > computation in burst mode and not for the dsi clock computation. Since
> > the BSP is unable to get the tcon_div during edge0 computation, they
> > defined it locally I think.
> >
> > You can see the lcd_clk_config() code [2], where we can see DSI clock
> > computation using dsi_div value.
> >
> > Here is dump after the in Line 792 which is after computation[3]
> > [ 10.800737] lcd_clk_config: dsi_div = 6, tcon_div = 4, lcd_div = 1
> > [ 10.800743] lcd_clk_config: lcd_dclk_freq = 55, dclk_rate = 55000000
> > [ 10.800749] lcd_clk_config: lcd_rate = 330000000, pll_rate = 330000000
> >
> > The above dump the lcd_rate 330MHz is computed with panel clock, 55MHz
> > into dsi_div 6. So this can be our actual divider values dclk_min_div,
> > dclk_max_div in sun4i_dclk_round_rate (from
> > drivers/gpu/drm/sun4i/sun4i_dotclock.c)
>
> I wish it was in your commit log in the first place, instead of having
> to exchange multiple mails over this.
>
> However, I don't think that's quite true, and it might be a bug in
> Allwinner's implementation (or rather something quite confusing).
>
> You're right that the lcd_rate and pll_rate seem to be generated from
> the pixel clock, and it indeed looks like the ratio between the pixel
> clock and the TCON dotclock is defined through the number of bits per
> lanes.
>
> However, in this case, dsi_rate is actually the same than lcd_rate,
> since pll_rate is going to be divided by dsi_div:
> https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L791
>
> Since lcd_div is 1, it also means that in this case, dsi_rate ==
> dclk_rate.
>
> The DSI module clock however, is always set to 148.5 MHz. Indeed, if
> we look at:
> https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L804
>
> We can see that the rate in clk_info is used if it's different than
> 0. This is filled by disp_al_lcd_get_clk_info, which, in the case of a
> DSI panel, will hardcode it to 148.5 MHz:
> https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/lowlevel_sun50iw1/disp_al.c#L164
>
> So, the DSI clock is set to this here:
> https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L805
>
> The TCON *module* clock (the one in the clock controller) has been set
> to lcd_rate (so the pixel clock times the number of bits per lane) here:
> https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L800
>
> And the PLL has been set to the same rate here:
> https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L794
>
> Let's take a step back now: that function we were looking at,
> lcd_clk_config, is called by lcd_clk_enable, which is in turn called
> by disp_lcd_enable here:
> https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L1328
>
> The next function being called is disp_al_lcd_cfg, and that function
> will hardcode the TCON dotclock divider to 4, here:
> https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/lowlevel_sun50iw1/disp_al.c#L240
>
> So, in the end, the dotclock divider is always 4, the DSI module clock
> is set to 148.5 MHz, and the TCON module clock is set to 330MHz. Since
> the TCON module clock doesn't have a divider, the PLL is set at that
> same value but this is redundant.
>
> I'll experiment with this and try to see how it works on the A33.
How is it with A33?
On Mon, Feb 11, 2019 at 07:37:57PM +0530, Jagan Teki wrote:
> Hi Maxime,
>
> On Fri, Feb 1, 2019 at 8:01 PM Maxime Ripard <[email protected]> wrote:
> >
> > On Tue, Jan 29, 2019 at 11:01:31PM +0530, Jagan Teki wrote:
> > > On Tue, Jan 29, 2019 at 8:43 PM Maxime Ripard <[email protected]> wrote:
> > > >
> > > > On Mon, Jan 28, 2019 at 03:06:10PM +0530, Jagan Teki wrote:
> > > > > On Sat, Jan 26, 2019 at 2:54 AM Maxime Ripard <[email protected]> wrote:
> > > > > >
> > > > > > On Fri, Jan 25, 2019 at 01:28:49AM +0530, Jagan Teki wrote:
> > > > > > > Minimum PLL used for MIPI is 500MHz, as per manual, but
> > > > > > > lowering the min rate by 300MHz can result proper working
> > > > > > > nkms divider with the help of desired dclock rate from
> > > > > > > panel driver.
> > > > > > >
> > > > > > > Signed-off-by: Jagan Teki <[email protected]>
> > > > > > > Acked-by: Stephen Boyd <[email protected]>
> > > > > >
> > > > > > Going 200MHz below the minimum doesn't seem really reasonable. What
> > > > > > is the issue that you are trying to fix here?
> > > > > >
> > > > > > It looks like it's picking bad dividers, but if that's the case, this
> > > > > > isn't the proper fix.
> > > > >
> > > > > As I stated in earlier patches, the whole idea is pick the desired
> > > > > dclk divider based dclk rate. So the dotclock, sun4i_dclk_round_rate
> > > > > is unable to get the proper dclk divider at the end, so it eventually
> > > > > picking up wrong divider value and fired vblank timeout.
> > > > >
> > > > > So, we come-up with optimal and working min_rate 300MHz in pll-mipi to
> > > > > get the desired clock something like below.
> > > > > [ 2.415773] [drm] No driver support for vblank timestamp query.
> > > > > [ 2.424116] sun4i_dclk_round_rate: min_div = 4 max_div = 127, rate = 55000000
> > > > > [ 2.424172] ideal = 220000000, rounded = 0
> > > > > [ 2.424176] ideal = 275000000, rounded = 0
> > > > > [ 2.424194] ccu_nkm_round_rate: rate = 330000000
> > > > > [ 2.424197] ideal = 330000000, rounded = 330000000
> > > > > [ 2.424201] sun4i_dclk_round_rate: div = 6 rate = 55000000
> > > > > [ 2.424205] sun4i_dclk_round_rate: min_div = 4 max_div = 127, rate = 55000000
> > > > > [ 2.424209] ideal = 220000000, rounded = 0
> > > > > [ 2.424213] ideal = 275000000, rounded = 0
> > > > > [ 2.424230] ccu_nkm_round_rate: rate = 330000000
> > > > > [ 2.424233] ideal = 330000000, rounded = 330000000
> > > > > [ 2.424236] sun4i_dclk_round_rate: div = 6 rate = 55000000
> > > > > [ 2.424253] ccu_nkm_round_rate: rate = 330000000
> > > > > [ 2.424270] ccu_nkm_round_rate: rate = 330000000
> > > > > [ 2.424278] sun4i_dclk_recalc_rate: val = 1, rate = 330000000
> > > > > [ 2.424281] sun4i_dclk_recalc_rate: val = 1, rate = 330000000
> > > > > [ 2.424306] ccu_nkm_set_rate: rate = 330000000, parent_rate = 297000000
> > > > > [ 2.424309] ccu_nkm_set_rate: _nkm.n = 5
> > > > > [ 2.424311] ccu_nkm_set_rate: _nkm.k = 2
> > > > > [ 2.424313] ccu_nkm_set_rate: _nkm.m = 9
> > > > > [ 2.424661] sun4i_dclk_set_rate div 6
> > > > > [ 2.424668] sun4i_dclk_recalc_rate: val = 6, rate = 55000000
> > > > >
> > > > > But look like this wouldn't valid for all other dclock rates, say BPI
> > > > > panel has 30MHz clock that would failed with this logic.
> > > > >
> > > > > On the other side Allwinner BSP calculating dclk divider based on the
> > > > > SoC's. for A33 [1] it is fixed dclk divider of 4 and for A64 is is
> > > > > calculated based on the bpp/lanes.
> > > >
> > > > It looks like the A64 has the same divider of 4:
> > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/lowlevel_sun50iw1/de_dsi.c#L12
> > > >
> > > > I think you're confusing it with the ratio between the pixel clock and
> > > > the dotclock, called dsi_div:
> > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/lowlevel_sun50iw1/disp_al.c#L198
> > >
> > > Ahh.. I thought this initially but as far as DSI clock computation is
> > > concern, the L12 tcon_div is local variable which is used for edge0
> > > computation in burst mode and not for the dsi clock computation. Since
> > > the BSP is unable to get the tcon_div during edge0 computation, they
> > > defined it locally I think.
> > >
> > > You can see the lcd_clk_config() code [2], where we can see DSI clock
> > > computation using dsi_div value.
> > >
> > > Here is dump after the in Line 792 which is after computation[3]
> > > [ 10.800737] lcd_clk_config: dsi_div = 6, tcon_div = 4, lcd_div = 1
> > > [ 10.800743] lcd_clk_config: lcd_dclk_freq = 55, dclk_rate = 55000000
> > > [ 10.800749] lcd_clk_config: lcd_rate = 330000000, pll_rate = 330000000
> > >
> > > The above dump the lcd_rate 330MHz is computed with panel clock, 55MHz
> > > into dsi_div 6. So this can be our actual divider values dclk_min_div,
> > > dclk_max_div in sun4i_dclk_round_rate (from
> > > drivers/gpu/drm/sun4i/sun4i_dotclock.c)
> >
> > I wish it was in your commit log in the first place, instead of having
> > to exchange multiple mails over this.
> >
> > However, I don't think that's quite true, and it might be a bug in
> > Allwinner's implementation (or rather something quite confusing).
> >
> > You're right that the lcd_rate and pll_rate seem to be generated from
> > the pixel clock, and it indeed looks like the ratio between the pixel
> > clock and the TCON dotclock is defined through the number of bits per
> > lanes.
> >
> > However, in this case, dsi_rate is actually the same than lcd_rate,
> > since pll_rate is going to be divided by dsi_div:
> > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L791
> >
> > Since lcd_div is 1, it also means that in this case, dsi_rate ==
> > dclk_rate.
> >
> > The DSI module clock however, is always set to 148.5 MHz. Indeed, if
> > we look at:
> > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L804
> >
> > We can see that the rate in clk_info is used if it's different than
> > 0. This is filled by disp_al_lcd_get_clk_info, which, in the case of a
> > DSI panel, will hardcode it to 148.5 MHz:
> > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/lowlevel_sun50iw1/disp_al.c#L164
> >
> > So, the DSI clock is set to this here:
> > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L805
> >
> > The TCON *module* clock (the one in the clock controller) has been set
> > to lcd_rate (so the pixel clock times the number of bits per lane) here:
> > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L800
> >
> > And the PLL has been set to the same rate here:
> > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L794
> >
> > Let's take a step back now: that function we were looking at,
> > lcd_clk_config, is called by lcd_clk_enable, which is in turn called
> > by disp_lcd_enable here:
> > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L1328
> >
> > The next function being called is disp_al_lcd_cfg, and that function
> > will hardcode the TCON dotclock divider to 4, here:
> > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/lowlevel_sun50iw1/disp_al.c#L240
> >
> > So, in the end, the dotclock divider is always 4, the DSI module clock
> > is set to 148.5 MHz, and the TCON module clock is set to 330MHz. Since
> > the TCON module clock doesn't have a divider, the PLL is set at that
> > same value but this is redundant.
> >
> > I'll experiment with this and try to see how it works on the A33.
>
> How is it with A33?
The conclusions are the one I sent in my last series
Maxime
--
Maxime Ripard, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
On Tue, Feb 12, 2019 at 3:00 PM Maxime Ripard <[email protected]> wrote:
>
> On Mon, Feb 11, 2019 at 07:37:57PM +0530, Jagan Teki wrote:
> > Hi Maxime,
> >
> > On Fri, Feb 1, 2019 at 8:01 PM Maxime Ripard <[email protected]> wrote:
> > >
> > > On Tue, Jan 29, 2019 at 11:01:31PM +0530, Jagan Teki wrote:
> > > > On Tue, Jan 29, 2019 at 8:43 PM Maxime Ripard <[email protected]> wrote:
> > > > >
> > > > > On Mon, Jan 28, 2019 at 03:06:10PM +0530, Jagan Teki wrote:
> > > > > > On Sat, Jan 26, 2019 at 2:54 AM Maxime Ripard <[email protected]> wrote:
> > > > > > >
> > > > > > > On Fri, Jan 25, 2019 at 01:28:49AM +0530, Jagan Teki wrote:
> > > > > > > > Minimum PLL used for MIPI is 500MHz, as per manual, but
> > > > > > > > lowering the min rate by 300MHz can result proper working
> > > > > > > > nkms divider with the help of desired dclock rate from
> > > > > > > > panel driver.
> > > > > > > >
> > > > > > > > Signed-off-by: Jagan Teki <[email protected]>
> > > > > > > > Acked-by: Stephen Boyd <[email protected]>
> > > > > > >
> > > > > > > Going 200MHz below the minimum doesn't seem really reasonable. What
> > > > > > > is the issue that you are trying to fix here?
> > > > > > >
> > > > > > > It looks like it's picking bad dividers, but if that's the case, this
> > > > > > > isn't the proper fix.
> > > > > >
> > > > > > As I stated in earlier patches, the whole idea is pick the desired
> > > > > > dclk divider based dclk rate. So the dotclock, sun4i_dclk_round_rate
> > > > > > is unable to get the proper dclk divider at the end, so it eventually
> > > > > > picking up wrong divider value and fired vblank timeout.
> > > > > >
> > > > > > So, we come-up with optimal and working min_rate 300MHz in pll-mipi to
> > > > > > get the desired clock something like below.
> > > > > > [ 2.415773] [drm] No driver support for vblank timestamp query.
> > > > > > [ 2.424116] sun4i_dclk_round_rate: min_div = 4 max_div = 127, rate = 55000000
> > > > > > [ 2.424172] ideal = 220000000, rounded = 0
> > > > > > [ 2.424176] ideal = 275000000, rounded = 0
> > > > > > [ 2.424194] ccu_nkm_round_rate: rate = 330000000
> > > > > > [ 2.424197] ideal = 330000000, rounded = 330000000
> > > > > > [ 2.424201] sun4i_dclk_round_rate: div = 6 rate = 55000000
> > > > > > [ 2.424205] sun4i_dclk_round_rate: min_div = 4 max_div = 127, rate = 55000000
> > > > > > [ 2.424209] ideal = 220000000, rounded = 0
> > > > > > [ 2.424213] ideal = 275000000, rounded = 0
> > > > > > [ 2.424230] ccu_nkm_round_rate: rate = 330000000
> > > > > > [ 2.424233] ideal = 330000000, rounded = 330000000
> > > > > > [ 2.424236] sun4i_dclk_round_rate: div = 6 rate = 55000000
> > > > > > [ 2.424253] ccu_nkm_round_rate: rate = 330000000
> > > > > > [ 2.424270] ccu_nkm_round_rate: rate = 330000000
> > > > > > [ 2.424278] sun4i_dclk_recalc_rate: val = 1, rate = 330000000
> > > > > > [ 2.424281] sun4i_dclk_recalc_rate: val = 1, rate = 330000000
> > > > > > [ 2.424306] ccu_nkm_set_rate: rate = 330000000, parent_rate = 297000000
> > > > > > [ 2.424309] ccu_nkm_set_rate: _nkm.n = 5
> > > > > > [ 2.424311] ccu_nkm_set_rate: _nkm.k = 2
> > > > > > [ 2.424313] ccu_nkm_set_rate: _nkm.m = 9
> > > > > > [ 2.424661] sun4i_dclk_set_rate div 6
> > > > > > [ 2.424668] sun4i_dclk_recalc_rate: val = 6, rate = 55000000
> > > > > >
> > > > > > But look like this wouldn't valid for all other dclock rates, say BPI
> > > > > > panel has 30MHz clock that would failed with this logic.
> > > > > >
> > > > > > On the other side Allwinner BSP calculating dclk divider based on the
> > > > > > SoC's. for A33 [1] it is fixed dclk divider of 4 and for A64 is is
> > > > > > calculated based on the bpp/lanes.
> > > > >
> > > > > It looks like the A64 has the same divider of 4:
> > > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/lowlevel_sun50iw1/de_dsi.c#L12
> > > > >
> > > > > I think you're confusing it with the ratio between the pixel clock and
> > > > > the dotclock, called dsi_div:
> > > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/lowlevel_sun50iw1/disp_al.c#L198
> > > >
> > > > Ahh.. I thought this initially but as far as DSI clock computation is
> > > > concern, the L12 tcon_div is local variable which is used for edge0
> > > > computation in burst mode and not for the dsi clock computation. Since
> > > > the BSP is unable to get the tcon_div during edge0 computation, they
> > > > defined it locally I think.
> > > >
> > > > You can see the lcd_clk_config() code [2], where we can see DSI clock
> > > > computation using dsi_div value.
> > > >
> > > > Here is dump after the in Line 792 which is after computation[3]
> > > > [ 10.800737] lcd_clk_config: dsi_div = 6, tcon_div = 4, lcd_div = 1
> > > > [ 10.800743] lcd_clk_config: lcd_dclk_freq = 55, dclk_rate = 55000000
> > > > [ 10.800749] lcd_clk_config: lcd_rate = 330000000, pll_rate = 330000000
> > > >
> > > > The above dump the lcd_rate 330MHz is computed with panel clock, 55MHz
> > > > into dsi_div 6. So this can be our actual divider values dclk_min_div,
> > > > dclk_max_div in sun4i_dclk_round_rate (from
> > > > drivers/gpu/drm/sun4i/sun4i_dotclock.c)
> > >
> > > I wish it was in your commit log in the first place, instead of having
> > > to exchange multiple mails over this.
> > >
> > > However, I don't think that's quite true, and it might be a bug in
> > > Allwinner's implementation (or rather something quite confusing).
> > >
> > > You're right that the lcd_rate and pll_rate seem to be generated from
> > > the pixel clock, and it indeed looks like the ratio between the pixel
> > > clock and the TCON dotclock is defined through the number of bits per
> > > lanes.
> > >
> > > However, in this case, dsi_rate is actually the same than lcd_rate,
> > > since pll_rate is going to be divided by dsi_div:
> > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L791
> > >
> > > Since lcd_div is 1, it also means that in this case, dsi_rate ==
> > > dclk_rate.
> > >
> > > The DSI module clock however, is always set to 148.5 MHz. Indeed, if
> > > we look at:
> > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L804
> > >
> > > We can see that the rate in clk_info is used if it's different than
> > > 0. This is filled by disp_al_lcd_get_clk_info, which, in the case of a
> > > DSI panel, will hardcode it to 148.5 MHz:
> > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/lowlevel_sun50iw1/disp_al.c#L164
> > >
> > > So, the DSI clock is set to this here:
> > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L805
> > >
> > > The TCON *module* clock (the one in the clock controller) has been set
> > > to lcd_rate (so the pixel clock times the number of bits per lane) here:
> > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L800
> > >
> > > And the PLL has been set to the same rate here:
> > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L794
> > >
> > > Let's take a step back now: that function we were looking at,
> > > lcd_clk_config, is called by lcd_clk_enable, which is in turn called
> > > by disp_lcd_enable here:
> > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L1328
> > >
> > > The next function being called is disp_al_lcd_cfg, and that function
> > > will hardcode the TCON dotclock divider to 4, here:
> > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/lowlevel_sun50iw1/disp_al.c#L240
> > >
> > > So, in the end, the dotclock divider is always 4, the DSI module clock
> > > is set to 148.5 MHz, and the TCON module clock is set to 330MHz. Since
> > > the TCON module clock doesn't have a divider, the PLL is set at that
> > > same value but this is redundant.
> > >
> > > I'll experiment with this and try to see how it works on the A33.
> >
> > How is it with A33?
>
> The conclusions are the one I sent in my last series
In this series?
[PATCH v3 0/8] drm/sun4i: dsi: Add burst mode support
On Fri, Feb 1, 2019 at 8:01 PM Maxime Ripard <[email protected]> wrote:
>
> On Tue, Jan 29, 2019 at 11:01:31PM +0530, Jagan Teki wrote:
> > On Tue, Jan 29, 2019 at 8:43 PM Maxime Ripard <[email protected]> wrote:
> > >
> > > On Mon, Jan 28, 2019 at 03:06:10PM +0530, Jagan Teki wrote:
> > > > On Sat, Jan 26, 2019 at 2:54 AM Maxime Ripard <[email protected]> wrote:
> > > > >
> > > > > On Fri, Jan 25, 2019 at 01:28:49AM +0530, Jagan Teki wrote:
> > > > > > Minimum PLL used for MIPI is 500MHz, as per manual, but
> > > > > > lowering the min rate by 300MHz can result proper working
> > > > > > nkms divider with the help of desired dclock rate from
> > > > > > panel driver.
> > > > > >
> > > > > > Signed-off-by: Jagan Teki <[email protected]>
> > > > > > Acked-by: Stephen Boyd <[email protected]>
> > > > >
> > > > > Going 200MHz below the minimum doesn't seem really reasonable. What
> > > > > is the issue that you are trying to fix here?
> > > > >
> > > > > It looks like it's picking bad dividers, but if that's the case, this
> > > > > isn't the proper fix.
> > > >
> > > > As I stated in earlier patches, the whole idea is pick the desired
> > > > dclk divider based dclk rate. So the dotclock, sun4i_dclk_round_rate
> > > > is unable to get the proper dclk divider at the end, so it eventually
> > > > picking up wrong divider value and fired vblank timeout.
> > > >
> > > > So, we come-up with optimal and working min_rate 300MHz in pll-mipi to
> > > > get the desired clock something like below.
> > > > [ 2.415773] [drm] No driver support for vblank timestamp query.
> > > > [ 2.424116] sun4i_dclk_round_rate: min_div = 4 max_div = 127, rate = 55000000
> > > > [ 2.424172] ideal = 220000000, rounded = 0
> > > > [ 2.424176] ideal = 275000000, rounded = 0
> > > > [ 2.424194] ccu_nkm_round_rate: rate = 330000000
> > > > [ 2.424197] ideal = 330000000, rounded = 330000000
> > > > [ 2.424201] sun4i_dclk_round_rate: div = 6 rate = 55000000
> > > > [ 2.424205] sun4i_dclk_round_rate: min_div = 4 max_div = 127, rate = 55000000
> > > > [ 2.424209] ideal = 220000000, rounded = 0
> > > > [ 2.424213] ideal = 275000000, rounded = 0
> > > > [ 2.424230] ccu_nkm_round_rate: rate = 330000000
> > > > [ 2.424233] ideal = 330000000, rounded = 330000000
> > > > [ 2.424236] sun4i_dclk_round_rate: div = 6 rate = 55000000
> > > > [ 2.424253] ccu_nkm_round_rate: rate = 330000000
> > > > [ 2.424270] ccu_nkm_round_rate: rate = 330000000
> > > > [ 2.424278] sun4i_dclk_recalc_rate: val = 1, rate = 330000000
> > > > [ 2.424281] sun4i_dclk_recalc_rate: val = 1, rate = 330000000
> > > > [ 2.424306] ccu_nkm_set_rate: rate = 330000000, parent_rate = 297000000
> > > > [ 2.424309] ccu_nkm_set_rate: _nkm.n = 5
> > > > [ 2.424311] ccu_nkm_set_rate: _nkm.k = 2
> > > > [ 2.424313] ccu_nkm_set_rate: _nkm.m = 9
> > > > [ 2.424661] sun4i_dclk_set_rate div 6
> > > > [ 2.424668] sun4i_dclk_recalc_rate: val = 6, rate = 55000000
> > > >
> > > > But look like this wouldn't valid for all other dclock rates, say BPI
> > > > panel has 30MHz clock that would failed with this logic.
> > > >
> > > > On the other side Allwinner BSP calculating dclk divider based on the
> > > > SoC's. for A33 [1] it is fixed dclk divider of 4 and for A64 is is
> > > > calculated based on the bpp/lanes.
> > >
> > > It looks like the A64 has the same divider of 4:
> > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/lowlevel_sun50iw1/de_dsi.c#L12
> > >
> > > I think you're confusing it with the ratio between the pixel clock and
> > > the dotclock, called dsi_div:
> > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/lowlevel_sun50iw1/disp_al.c#L198
> >
> > Ahh.. I thought this initially but as far as DSI clock computation is
> > concern, the L12 tcon_div is local variable which is used for edge0
> > computation in burst mode and not for the dsi clock computation. Since
> > the BSP is unable to get the tcon_div during edge0 computation, they
> > defined it locally I think.
> >
> > You can see the lcd_clk_config() code [2], where we can see DSI clock
> > computation using dsi_div value.
> >
> > Here is dump after the in Line 792 which is after computation[3]
> > [ 10.800737] lcd_clk_config: dsi_div = 6, tcon_div = 4, lcd_div = 1
> > [ 10.800743] lcd_clk_config: lcd_dclk_freq = 55, dclk_rate = 55000000
> > [ 10.800749] lcd_clk_config: lcd_rate = 330000000, pll_rate = 330000000
> >
> > The above dump the lcd_rate 330MHz is computed with panel clock, 55MHz
> > into dsi_div 6. So this can be our actual divider values dclk_min_div,
> > dclk_max_div in sun4i_dclk_round_rate (from
> > drivers/gpu/drm/sun4i/sun4i_dotclock.c)
>
> I wish it was in your commit log in the first place, instead of having
> to exchange multiple mails over this.
>
> However, I don't think that's quite true, and it might be a bug in
> Allwinner's implementation (or rather something quite confusing).
>
> You're right that the lcd_rate and pll_rate seem to be generated from
> the pixel clock, and it indeed looks like the ratio between the pixel
> clock and the TCON dotclock is defined through the number of bits per
> lanes.
>
> However, in this case, dsi_rate is actually the same than lcd_rate,
> since pll_rate is going to be divided by dsi_div:
> https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L791
>
> Since lcd_div is 1, it also means that in this case, dsi_rate ==
> dclk_rate.
>
> The DSI module clock however, is always set to 148.5 MHz. Indeed, if
> we look at:
> https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L804
>
> We can see that the rate in clk_info is used if it's different than
> 0. This is filled by disp_al_lcd_get_clk_info, which, in the case of a
> DSI panel, will hardcode it to 148.5 MHz:
> https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/lowlevel_sun50iw1/disp_al.c#L164
>
> So, the DSI clock is set to this here:
> https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L805
>
> The TCON *module* clock (the one in the clock controller) has been set
> to lcd_rate (so the pixel clock times the number of bits per lane) here:
> https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L800
>
> And the PLL has been set to the same rate here:
> https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L794
Let me explain, something more.
According to bsp there are clk_info.tcon_div which I will explain below.
clk_info.dsi_div which is dynamic and it depends on bpp/lanes, so it
is 6 for 24bpp and 4 lanes devices.
PLL rate here depends on dsi_div (not tcon_div)
Code here
https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L784
is computing the actual set rate, which depends on dsi_rate.
lcd_rate = dclk_rate * clk_info.dsi_div;
dsi_rate = pll_rate / clk_info.dsi_div;
Say if the dclk_rate 148MHz then the dsi_rate is 888MHz which set rate
for above link you mentioned.
Here are the evidence with some prints.
https://gist.github.com/openedev/9bae2d87d2fcc06b999fe48c998b7043
https://gist.github.com/openedev/700de2e3701b2bf3ad1aa0f0fa862c9a
>
> Let's take a step back now: that function we were looking at,
> lcd_clk_config, is called by lcd_clk_enable, which is in turn called
> by disp_lcd_enable here:
> https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L1328
>
> The next function being called is disp_al_lcd_cfg, and that function
> will hardcode the TCON dotclock divider to 4, here:
> https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/lowlevel_sun50iw1/disp_al.c#L240
tcon_div from BSP point-of-view of there are two variants
00) clk_info.tcon_div which is 4 and same is set the divider position
in SUN4I_TCON0_DCLK_REG (like above link refer)
01) tcon_div which is 4 and used for edge timings computation
https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/lowlevel_sun50iw1/de_dsi.c#L12
The real reason for 01) is again 4 is they set the divider to 4 in 00)
which is technically wrong because the dividers which used during
dotclock in above (dsi_div) should be used here as well. Since there
is no dynamic way of doing this BSP hard-coding these values.
Patches 5,6,7 on this series doing this
https://patchwork.freedesktop.org/series/60847/
Hope this explanation helps?
Hi,
I've reordered the mail a bit to work on chunks
On Fri, May 24, 2019 at 03:37:42PM +0530, Jagan Teki wrote:
> > I wish it was in your commit log in the first place, instead of having
> > to exchange multiple mails over this.
> >
> > However, I don't think that's quite true, and it might be a bug in
> > Allwinner's implementation (or rather something quite confusing).
> >
> > You're right that the lcd_rate and pll_rate seem to be generated from
> > the pixel clock, and it indeed looks like the ratio between the pixel
> > clock and the TCON dotclock is defined through the number of bits per
> > lanes.
> >
> > However, in this case, dsi_rate is actually the same than lcd_rate,
> > since pll_rate is going to be divided by dsi_div:
> > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L791
> >
> > Since lcd_div is 1, it also means that in this case, dsi_rate ==
> > dclk_rate.
> >
> > The DSI module clock however, is always set to 148.5 MHz. Indeed, if
> > we look at:
> > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L804
> >
> > We can see that the rate in clk_info is used if it's different than
> > 0. This is filled by disp_al_lcd_get_clk_info, which, in the case of a
> > DSI panel, will hardcode it to 148.5 MHz:
> > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/lowlevel_sun50iw1/disp_al.c#L164
>
> Let me explain, something more.
>
> According to bsp there are clk_info.tcon_div which I will explain below.
> clk_info.dsi_div which is dynamic and it depends on bpp/lanes, so it
> is 6 for 24bpp and 4 lanes devices.
>
> PLL rate here depends on dsi_div (not tcon_div)
>
> Code here
> https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L784
>
> is computing the actual set rate, which depends on dsi_rate.
>
> lcd_rate = dclk_rate * clk_info.dsi_div;
> dsi_rate = pll_rate / clk_info.dsi_div;
>
> Say if the dclk_rate 148MHz then the dsi_rate is 888MHz which set rate
> for above link you mentioned.
>
> Here are the evidence with some prints.
>
> https://gist.github.com/openedev/9bae2d87d2fcc06b999fe48c998b7043
> https://gist.github.com/openedev/700de2e3701b2bf3ad1aa0f0fa862c9a
Ok, so we agree up to this point, and the prints confirm that the
analysis above is the right one.
> > So, the DSI clock is set to this here:
> > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L805
Your patch doesn't address that, so let's leave that one alone.
> > The TCON *module* clock (the one in the clock controller) has been set
> > to lcd_rate (so the pixel clock times the number of bits per lane) here:
> > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L800
> >
> > And the PLL has been set to the same rate here:
> > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L794
> >
> > Let's take a step back now: that function we were looking at,
> > lcd_clk_config, is called by lcd_clk_enable, which is in turn called
> > by disp_lcd_enable here:
> > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L1328
> >
> > The next function being called is disp_al_lcd_cfg, and that function
> > will hardcode the TCON dotclock divider to 4, here:
> > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/lowlevel_sun50iw1/disp_al.c#L240
>
> tcon_div from BSP point-of-view of there are two variants
> 00) clk_info.tcon_div which is 4 and same is set the divider position
> in SUN4I_TCON0_DCLK_REG (like above link refer)
> 01) tcon_div which is 4 and used for edge timings computation
> https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/lowlevel_sun50iw1/de_dsi.c#L12
>
> The real reason for 01) is again 4 is they set the divider to 4 in 00)
> which is technically wrong because the dividers which used during
> dotclock in above (dsi_div) should be used here as well. Since there
> is no dynamic way of doing this BSP hard-coding these values.
>
> Patches 5,6,7 on this series doing this
> https://patchwork.freedesktop.org/series/60847/
>
> Hope this explanation helps?
It doesn't.
The clock tree is this one:
PLL(s) -> TCON module clock -> TCON dotclock.
The links I mentioned above show that the clock set to lcd_rate is the
TCON module clocks (and it should be the one taking the bpp and lanes
into account), while the TCON dotclock uses a fixed divider of 4.
In your patches, you're using the bpp / lanes divider on the TCON
dotclock, ie, the wrong clock.
Again, I'm not saying that my analysis of the source code is correct
here. But you haven't said anything to prove it's wrong either.
Maxime
--
Maxime Ripard, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
On Wed, Jun 5, 2019 at 12:19 PM Maxime Ripard <[email protected]> wrote:
>
> Hi,
>
> I've reordered the mail a bit to work on chunks
>
> On Fri, May 24, 2019 at 03:37:42PM +0530, Jagan Teki wrote:
> > > I wish it was in your commit log in the first place, instead of having
> > > to exchange multiple mails over this.
> > >
> > > However, I don't think that's quite true, and it might be a bug in
> > > Allwinner's implementation (or rather something quite confusing).
> > >
> > > You're right that the lcd_rate and pll_rate seem to be generated from
> > > the pixel clock, and it indeed looks like the ratio between the pixel
> > > clock and the TCON dotclock is defined through the number of bits per
> > > lanes.
> > >
> > > However, in this case, dsi_rate is actually the same than lcd_rate,
> > > since pll_rate is going to be divided by dsi_div:
> > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L791
> > >
> > > Since lcd_div is 1, it also means that in this case, dsi_rate ==
> > > dclk_rate.
> > >
> > > The DSI module clock however, is always set to 148.5 MHz. Indeed, if
> > > we look at:
> > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L804
> > >
> > > We can see that the rate in clk_info is used if it's different than
> > > 0. This is filled by disp_al_lcd_get_clk_info, which, in the case of a
> > > DSI panel, will hardcode it to 148.5 MHz:
> > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/lowlevel_sun50iw1/disp_al.c#L164
> >
> > Let me explain, something more.
> >
> > According to bsp there are clk_info.tcon_div which I will explain below.
> > clk_info.dsi_div which is dynamic and it depends on bpp/lanes, so it
> > is 6 for 24bpp and 4 lanes devices.
> >
> > PLL rate here depends on dsi_div (not tcon_div)
> >
> > Code here
> > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L784
> >
> > is computing the actual set rate, which depends on dsi_rate.
> >
> > lcd_rate = dclk_rate * clk_info.dsi_div;
> > dsi_rate = pll_rate / clk_info.dsi_div;
> >
> > Say if the dclk_rate 148MHz then the dsi_rate is 888MHz which set rate
> > for above link you mentioned.
> >
> > Here are the evidence with some prints.
> >
> > https://gist.github.com/openedev/9bae2d87d2fcc06b999fe48c998b7043
> > https://gist.github.com/openedev/700de2e3701b2bf3ad1aa0f0fa862c9a
>
> Ok, so we agree up to this point, and the prints confirm that the
> analysis above is the right one.
>
> > > So, the DSI clock is set to this here:
> > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L805
>
> Your patch doesn't address that, so let's leave that one alone.
Basically this is final pll set rate when sun4i_dotclock.c called the
desired rate with ccu_nkm.c so it ended the final rate with parent as
Line 8 of
https://gist.github.com/openedev/700de2e3701b2bf3ad1aa0f0fa862c9a
>
> > > The TCON *module* clock (the one in the clock controller) has been set
> > > to lcd_rate (so the pixel clock times the number of bits per lane) here:
> > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L800
> > >
> > > And the PLL has been set to the same rate here:
> > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L794
> > >
> > > Let's take a step back now: that function we were looking at,
> > > lcd_clk_config, is called by lcd_clk_enable, which is in turn called
> > > by disp_lcd_enable here:
> > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L1328
> > >
> > > The next function being called is disp_al_lcd_cfg, and that function
> > > will hardcode the TCON dotclock divider to 4, here:
> > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/lowlevel_sun50iw1/disp_al.c#L240
> >
> > tcon_div from BSP point-of-view of there are two variants
> > 00) clk_info.tcon_div which is 4 and same is set the divider position
> > in SUN4I_TCON0_DCLK_REG (like above link refer)
> > 01) tcon_div which is 4 and used for edge timings computation
> > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/lowlevel_sun50iw1/de_dsi.c#L12
> >
> > The real reason for 01) is again 4 is they set the divider to 4 in 00)
> > which is technically wrong because the dividers which used during
> > dotclock in above (dsi_div) should be used here as well. Since there
> > is no dynamic way of doing this BSP hard-coding these values.
> >
> > Patches 5,6,7 on this series doing this
> > https://patchwork.freedesktop.org/series/60847/
> >
> > Hope this explanation helps?
>
> It doesn't.
>
> The clock tree is this one:
>
> PLL(s) -> TCON module clock -> TCON dotclock.
>
> The links I mentioned above show that the clock set to lcd_rate is the
> TCON module clocks (and it should be the one taking the bpp and lanes
> into account), while the TCON dotclock uses a fixed divider of 4.
Sorry, I can argue much other-than giving some code snips, according to [1]
00) Line 785, 786 with dclk_rate 148000000
lcd_rate = dclk_rate * clk_info.dsi_div;
pll_rate = lcd_rate * clk_info.lcd_div;
Since dsi_div is 6 (bpp/lanes), lcd_div 1
lcd_rate = 888000000, pll_rate = 888000000
01) Line 801, 804 are final rates computed as per clock driver (say
ccu_nkm in mainline)
lcd_rate_set=891000000
As per your comments if it would be 4 then the desired numbers are
would be 592000000 not 888000000.
This is what I'm trying to say in all mails, and same as verified with
2-lanes devices as well where the dsi_div is 12 so the final rate is
290MHz * 12
>
> In your patches, you're using the bpp / lanes divider on the TCON
> dotclock, ie, the wrong clock.
>
> Again, I'm not saying that my analysis of the source code is correct
> here. But you haven't said anything to prove it's wrong either.
Don't understand what proves are remaining, I have explained each line
from BSP and saying pll rate is depends on dsi_div which is bpp/lanes
not wrt tcon_div on BSP (which is set to default 4) and which indeed
verified in A33, R40. all the code using bpp/lanes.
Please let me know if you need any more information to look?
[1] https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L805
On Wed, Jun 05, 2019 at 01:03:16PM +0530, Jagan Teki wrote:
> On Wed, Jun 5, 2019 at 12:19 PM Maxime Ripard <[email protected]> wrote:
> >
> > Hi,
> >
> > I've reordered the mail a bit to work on chunks
> >
> > On Fri, May 24, 2019 at 03:37:42PM +0530, Jagan Teki wrote:
> > > > I wish it was in your commit log in the first place, instead of having
> > > > to exchange multiple mails over this.
> > > >
> > > > However, I don't think that's quite true, and it might be a bug in
> > > > Allwinner's implementation (or rather something quite confusing).
> > > >
> > > > You're right that the lcd_rate and pll_rate seem to be generated from
> > > > the pixel clock, and it indeed looks like the ratio between the pixel
> > > > clock and the TCON dotclock is defined through the number of bits per
> > > > lanes.
> > > >
> > > > However, in this case, dsi_rate is actually the same than lcd_rate,
> > > > since pll_rate is going to be divided by dsi_div:
> > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L791
> > > >
> > > > Since lcd_div is 1, it also means that in this case, dsi_rate ==
> > > > dclk_rate.
> > > >
> > > > The DSI module clock however, is always set to 148.5 MHz. Indeed, if
> > > > we look at:
> > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L804
> > > >
> > > > We can see that the rate in clk_info is used if it's different than
> > > > 0. This is filled by disp_al_lcd_get_clk_info, which, in the case of a
> > > > DSI panel, will hardcode it to 148.5 MHz:
> > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/lowlevel_sun50iw1/disp_al.c#L164
> > >
> > > Let me explain, something more.
> > >
> > > According to bsp there are clk_info.tcon_div which I will explain below.
> > > clk_info.dsi_div which is dynamic and it depends on bpp/lanes, so it
> > > is 6 for 24bpp and 4 lanes devices.
> > >
> > > PLL rate here depends on dsi_div (not tcon_div)
> > >
> > > Code here
> > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L784
> > >
> > > is computing the actual set rate, which depends on dsi_rate.
> > >
> > > lcd_rate = dclk_rate * clk_info.dsi_div;
> > > dsi_rate = pll_rate / clk_info.dsi_div;
> > >
> > > Say if the dclk_rate 148MHz then the dsi_rate is 888MHz which set rate
> > > for above link you mentioned.
> > >
> > > Here are the evidence with some prints.
> > >
> > > https://gist.github.com/openedev/9bae2d87d2fcc06b999fe48c998b7043
> > > https://gist.github.com/openedev/700de2e3701b2bf3ad1aa0f0fa862c9a
> >
> > Ok, so we agree up to this point, and the prints confirm that the
> > analysis above is the right one.
> >
> > > > So, the DSI clock is set to this here:
> > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L805
> >
> > Your patch doesn't address that, so let's leave that one alone.
>
> Basically this is final pll set rate when sun4i_dotclock.c called the
> desired rate with ccu_nkm.c so it ended the final rate with parent as
> Line 8 of
> https://gist.github.com/openedev/700de2e3701b2bf3ad1aa0f0fa862c9a
If that's important to the driver, it should be set explicitly then,
and not work by accident.
> > > > The TCON *module* clock (the one in the clock controller) has been set
> > > > to lcd_rate (so the pixel clock times the number of bits per lane) here:
> > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L800
> > > >
> > > > And the PLL has been set to the same rate here:
> > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L794
> > > >
> > > > Let's take a step back now: that function we were looking at,
> > > > lcd_clk_config, is called by lcd_clk_enable, which is in turn called
> > > > by disp_lcd_enable here:
> > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L1328
> > > >
> > > > The next function being called is disp_al_lcd_cfg, and that function
> > > > will hardcode the TCON dotclock divider to 4, here:
> > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/lowlevel_sun50iw1/disp_al.c#L240
> > >
> > > tcon_div from BSP point-of-view of there are two variants
> > > 00) clk_info.tcon_div which is 4 and same is set the divider position
> > > in SUN4I_TCON0_DCLK_REG (like above link refer)
> > > 01) tcon_div which is 4 and used for edge timings computation
> > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/lowlevel_sun50iw1/de_dsi.c#L12
> > >
> > > The real reason for 01) is again 4 is they set the divider to 4 in 00)
> > > which is technically wrong because the dividers which used during
> > > dotclock in above (dsi_div) should be used here as well. Since there
> > > is no dynamic way of doing this BSP hard-coding these values.
> > >
> > > Patches 5,6,7 on this series doing this
> > > https://patchwork.freedesktop.org/series/60847/
> > >
> > > Hope this explanation helps?
> >
> > It doesn't.
> >
> > The clock tree is this one:
> >
> > PLL(s) -> TCON module clock -> TCON dotclock.
> >
> > The links I mentioned above show that the clock set to lcd_rate is the
> > TCON module clocks (and it should be the one taking the bpp and lanes
> > into account), while the TCON dotclock uses a fixed divider of 4.
>
> Sorry, I can argue much other-than giving some code snips, according to [1]
>
> 00) Line 785, 786 with dclk_rate 148000000
>
> lcd_rate = dclk_rate * clk_info.dsi_div;
> pll_rate = lcd_rate * clk_info.lcd_div;
>
> Since dsi_div is 6 (bpp/lanes), lcd_div 1
>
> lcd_rate = 888000000, pll_rate = 888000000
>
> 01) Line 801, 804 are final rates computed as per clock driver (say
> ccu_nkm in mainline)
>
> lcd_rate_set=891000000
>
> As per your comments if it would be 4 then the desired numbers are
> would be 592000000 not 888000000.
>
> This is what I'm trying to say in all mails, and same as verified with
> 2-lanes devices as well where the dsi_div is 12 so the final rate is
> 290MHz * 12
In the code you sent, you're forcing a divider on the internal TCON
clock, while that one is fixed in the BSP.
There's indeed the bpp / lanes divider, but it's used in the *parent*
clock of the one you're changing.
And the dsi0_clk clock you pointed out in the code snippet is yet
another clock, the MIPI DSI module clock.
The analysis you have is probably correct, you're just not
implementing it properly in your patch.
Maxime
--
Maxime Ripard, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
On Fri, Jun 14, 2019 at 7:54 PM Maxime Ripard <[email protected]> wrote:
>
> On Wed, Jun 05, 2019 at 01:03:16PM +0530, Jagan Teki wrote:
> > On Wed, Jun 5, 2019 at 12:19 PM Maxime Ripard <[email protected]> wrote:
> > >
> > > Hi,
> > >
> > > I've reordered the mail a bit to work on chunks
> > >
> > > On Fri, May 24, 2019 at 03:37:42PM +0530, Jagan Teki wrote:
> > > > > I wish it was in your commit log in the first place, instead of having
> > > > > to exchange multiple mails over this.
> > > > >
> > > > > However, I don't think that's quite true, and it might be a bug in
> > > > > Allwinner's implementation (or rather something quite confusing).
> > > > >
> > > > > You're right that the lcd_rate and pll_rate seem to be generated from
> > > > > the pixel clock, and it indeed looks like the ratio between the pixel
> > > > > clock and the TCON dotclock is defined through the number of bits per
> > > > > lanes.
> > > > >
> > > > > However, in this case, dsi_rate is actually the same than lcd_rate,
> > > > > since pll_rate is going to be divided by dsi_div:
> > > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L791
> > > > >
> > > > > Since lcd_div is 1, it also means that in this case, dsi_rate ==
> > > > > dclk_rate.
> > > > >
> > > > > The DSI module clock however, is always set to 148.5 MHz. Indeed, if
> > > > > we look at:
> > > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L804
> > > > >
> > > > > We can see that the rate in clk_info is used if it's different than
> > > > > 0. This is filled by disp_al_lcd_get_clk_info, which, in the case of a
> > > > > DSI panel, will hardcode it to 148.5 MHz:
> > > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/lowlevel_sun50iw1/disp_al.c#L164
> > > >
> > > > Let me explain, something more.
> > > >
> > > > According to bsp there are clk_info.tcon_div which I will explain below.
> > > > clk_info.dsi_div which is dynamic and it depends on bpp/lanes, so it
> > > > is 6 for 24bpp and 4 lanes devices.
> > > >
> > > > PLL rate here depends on dsi_div (not tcon_div)
> > > >
> > > > Code here
> > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L784
> > > >
> > > > is computing the actual set rate, which depends on dsi_rate.
> > > >
> > > > lcd_rate = dclk_rate * clk_info.dsi_div;
> > > > dsi_rate = pll_rate / clk_info.dsi_div;
> > > >
> > > > Say if the dclk_rate 148MHz then the dsi_rate is 888MHz which set rate
> > > > for above link you mentioned.
> > > >
> > > > Here are the evidence with some prints.
> > > >
> > > > https://gist.github.com/openedev/9bae2d87d2fcc06b999fe48c998b7043
> > > > https://gist.github.com/openedev/700de2e3701b2bf3ad1aa0f0fa862c9a
> > >
> > > Ok, so we agree up to this point, and the prints confirm that the
> > > analysis above is the right one.
> > >
> > > > > So, the DSI clock is set to this here:
> > > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L805
> > >
> > > Your patch doesn't address that, so let's leave that one alone.
> >
> > Basically this is final pll set rate when sun4i_dotclock.c called the
> > desired rate with ccu_nkm.c so it ended the final rate with parent as
> > Line 8 of
> > https://gist.github.com/openedev/700de2e3701b2bf3ad1aa0f0fa862c9a
>
> If that's important to the driver, it should be set explicitly then,
> and not work by accident.
>
> > > > > The TCON *module* clock (the one in the clock controller) has been set
> > > > > to lcd_rate (so the pixel clock times the number of bits per lane) here:
> > > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L800
> > > > >
> > > > > And the PLL has been set to the same rate here:
> > > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L794
> > > > >
> > > > > Let's take a step back now: that function we were looking at,
> > > > > lcd_clk_config, is called by lcd_clk_enable, which is in turn called
> > > > > by disp_lcd_enable here:
> > > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L1328
> > > > >
> > > > > The next function being called is disp_al_lcd_cfg, and that function
> > > > > will hardcode the TCON dotclock divider to 4, here:
> > > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/lowlevel_sun50iw1/disp_al.c#L240
> > > >
> > > > tcon_div from BSP point-of-view of there are two variants
> > > > 00) clk_info.tcon_div which is 4 and same is set the divider position
> > > > in SUN4I_TCON0_DCLK_REG (like above link refer)
> > > > 01) tcon_div which is 4 and used for edge timings computation
> > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/lowlevel_sun50iw1/de_dsi.c#L12
> > > >
> > > > The real reason for 01) is again 4 is they set the divider to 4 in 00)
> > > > which is technically wrong because the dividers which used during
> > > > dotclock in above (dsi_div) should be used here as well. Since there
> > > > is no dynamic way of doing this BSP hard-coding these values.
> > > >
> > > > Patches 5,6,7 on this series doing this
> > > > https://patchwork.freedesktop.org/series/60847/
> > > >
> > > > Hope this explanation helps?
> > >
> > > It doesn't.
> > >
> > > The clock tree is this one:
> > >
> > > PLL(s) -> TCON module clock -> TCON dotclock.
> > >
> > > The links I mentioned above show that the clock set to lcd_rate is the
> > > TCON module clocks (and it should be the one taking the bpp and lanes
> > > into account), while the TCON dotclock uses a fixed divider of 4.
> >
> > Sorry, I can argue much other-than giving some code snips, according to [1]
> >
> > 00) Line 785, 786 with dclk_rate 148000000
> >
> > lcd_rate = dclk_rate * clk_info.dsi_div;
> > pll_rate = lcd_rate * clk_info.lcd_div;
> >
> > Since dsi_div is 6 (bpp/lanes), lcd_div 1
> >
> > lcd_rate = 888000000, pll_rate = 888000000
> >
> > 01) Line 801, 804 are final rates computed as per clock driver (say
> > ccu_nkm in mainline)
> >
> > lcd_rate_set=891000000
> >
> > As per your comments if it would be 4 then the desired numbers are
> > would be 592000000 not 888000000.
> >
> > This is what I'm trying to say in all mails, and same as verified with
> > 2-lanes devices as well where the dsi_div is 12 so the final rate is
> > 290MHz * 12
>
> In the code you sent, you're forcing a divider on the internal TCON
> clock, while that one is fixed in the BSP.
>
> There's indeed the bpp / lanes divider, but it's used in the *parent*
> clock of the one you're changing.
>
> And the dsi0_clk clock you pointed out in the code snippet is yet
> another clock, the MIPI DSI module clock.
Correct, look like I refereed wrong reference in the above mail. sorry
for the noise.
Actually I'm trying to explain about pll_rate here which indeed
depends on dsi.div
https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L786
lcd_rate = dclk_rate * clk_info.dsi_div;
pll_rate = lcd_rate * clk_info.lcd_div;
Say
1) For 148MHz dclk_rate with dsi_div is 6 (24/4) lcd_div is 1 which
resulting pll_rate is 888MHz.
2) For 30MHz dclk_rate with 4 lane and 24 RGB the resulting pll_rate is 180MHz
3) For 27.5MHz dclk_rate with 2 lane and 24 RGB the resulting pll_rate is 330MHz
Here is the few more logs in code, for case 2)
[ 1.920441] sun4i_dclk_round_rate: min_div = 6 max_div = 6, rate = 30000000
[ 1.920505] ideal = 180000000, rounded = 178200000
[ 1.920509] sun4i_dclk_round_rate: div = 6 rate = 29700000
[ 1.920514] sun4i_dclk_round_rate: min_div = 6 max_div = 6, rate = 30000000
[ 1.920532] ideal = 180000000, rounded = 178200000
[ 1.920535] sun4i_dclk_round_rate: div = 6 rate = 29700000
[ 1.920572] sun4i_dclk_recalc_rate: val = 1, rate = 178200000
[ 1.920576] sun4i_dclk_recalc_rate: val = 1, rate = 178200000
[ 1.920597] rate = 178200000
[ 1.920599] parent_rate = 297000000
[ 1.920602] reg = 0x90c00000
[ 1.920605] _nkm.n = 3, nkm->n.offset = 0x1, nkm->n.shift = 8
[ 1.920609] _nkm.k = 2, nkm->k.offset = 0x1, nkm->k.shift = 4
[ 1.920612] _nkm.m = 10, nkm->m.offset = 0x1, nkm->m.shift = 0
[ 1.920958] sun4i_dclk_set_rate div 6
[ 1.920966] sun4i_dclk_recalc_rate: val = 6, rate = 29700000
and clk_summary:
pll-video0 1 1 1 297000000
0 0 50000
hdmi 0 0 0 297000000
0 0 50000
tcon1 0 0 0 297000000
0 0 50000
pll-mipi 1 1 1 178200000
0 0 50000
tcon0 2 2 1 178200000
0 0 50000
tcon-pixel-clock 1 1 1 29700000
0 0 50000
pll-video0-2x 0 0 0 594000000
0 0 50000
On Thu, Jun 20, 2019 at 11:57:44PM +0530, Jagan Teki wrote:
> On Fri, Jun 14, 2019 at 7:54 PM Maxime Ripard <[email protected]> wrote:
> >
> > On Wed, Jun 05, 2019 at 01:03:16PM +0530, Jagan Teki wrote:
> > > On Wed, Jun 5, 2019 at 12:19 PM Maxime Ripard <[email protected]> wrote:
> > > >
> > > > Hi,
> > > >
> > > > I've reordered the mail a bit to work on chunks
> > > >
> > > > On Fri, May 24, 2019 at 03:37:42PM +0530, Jagan Teki wrote:
> > > > > > I wish it was in your commit log in the first place, instead of having
> > > > > > to exchange multiple mails over this.
> > > > > >
> > > > > > However, I don't think that's quite true, and it might be a bug in
> > > > > > Allwinner's implementation (or rather something quite confusing).
> > > > > >
> > > > > > You're right that the lcd_rate and pll_rate seem to be generated from
> > > > > > the pixel clock, and it indeed looks like the ratio between the pixel
> > > > > > clock and the TCON dotclock is defined through the number of bits per
> > > > > > lanes.
> > > > > >
> > > > > > However, in this case, dsi_rate is actually the same than lcd_rate,
> > > > > > since pll_rate is going to be divided by dsi_div:
> > > > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L791
> > > > > >
> > > > > > Since lcd_div is 1, it also means that in this case, dsi_rate ==
> > > > > > dclk_rate.
> > > > > >
> > > > > > The DSI module clock however, is always set to 148.5 MHz. Indeed, if
> > > > > > we look at:
> > > > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L804
> > > > > >
> > > > > > We can see that the rate in clk_info is used if it's different than
> > > > > > 0. This is filled by disp_al_lcd_get_clk_info, which, in the case of a
> > > > > > DSI panel, will hardcode it to 148.5 MHz:
> > > > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/lowlevel_sun50iw1/disp_al.c#L164
> > > > >
> > > > > Let me explain, something more.
> > > > >
> > > > > According to bsp there are clk_info.tcon_div which I will explain below.
> > > > > clk_info.dsi_div which is dynamic and it depends on bpp/lanes, so it
> > > > > is 6 for 24bpp and 4 lanes devices.
> > > > >
> > > > > PLL rate here depends on dsi_div (not tcon_div)
> > > > >
> > > > > Code here
> > > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L784
> > > > >
> > > > > is computing the actual set rate, which depends on dsi_rate.
> > > > >
> > > > > lcd_rate = dclk_rate * clk_info.dsi_div;
> > > > > dsi_rate = pll_rate / clk_info.dsi_div;
> > > > >
> > > > > Say if the dclk_rate 148MHz then the dsi_rate is 888MHz which set rate
> > > > > for above link you mentioned.
> > > > >
> > > > > Here are the evidence with some prints.
> > > > >
> > > > > https://gist.github.com/openedev/9bae2d87d2fcc06b999fe48c998b7043
> > > > > https://gist.github.com/openedev/700de2e3701b2bf3ad1aa0f0fa862c9a
> > > >
> > > > Ok, so we agree up to this point, and the prints confirm that the
> > > > analysis above is the right one.
> > > >
> > > > > > So, the DSI clock is set to this here:
> > > > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L805
> > > >
> > > > Your patch doesn't address that, so let's leave that one alone.
> > >
> > > Basically this is final pll set rate when sun4i_dotclock.c called the
> > > desired rate with ccu_nkm.c so it ended the final rate with parent as
> > > Line 8 of
> > > https://gist.github.com/openedev/700de2e3701b2bf3ad1aa0f0fa862c9a
> >
> > If that's important to the driver, it should be set explicitly then,
> > and not work by accident.
> >
> > > > > > The TCON *module* clock (the one in the clock controller) has been set
> > > > > > to lcd_rate (so the pixel clock times the number of bits per lane) here:
> > > > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L800
> > > > > >
> > > > > > And the PLL has been set to the same rate here:
> > > > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L794
> > > > > >
> > > > > > Let's take a step back now: that function we were looking at,
> > > > > > lcd_clk_config, is called by lcd_clk_enable, which is in turn called
> > > > > > by disp_lcd_enable here:
> > > > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L1328
> > > > > >
> > > > > > The next function being called is disp_al_lcd_cfg, and that function
> > > > > > will hardcode the TCON dotclock divider to 4, here:
> > > > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/lowlevel_sun50iw1/disp_al.c#L240
> > > > >
> > > > > tcon_div from BSP point-of-view of there are two variants
> > > > > 00) clk_info.tcon_div which is 4 and same is set the divider position
> > > > > in SUN4I_TCON0_DCLK_REG (like above link refer)
> > > > > 01) tcon_div which is 4 and used for edge timings computation
> > > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/lowlevel_sun50iw1/de_dsi.c#L12
> > > > >
> > > > > The real reason for 01) is again 4 is they set the divider to 4 in 00)
> > > > > which is technically wrong because the dividers which used during
> > > > > dotclock in above (dsi_div) should be used here as well. Since there
> > > > > is no dynamic way of doing this BSP hard-coding these values.
> > > > >
> > > > > Patches 5,6,7 on this series doing this
> > > > > https://patchwork.freedesktop.org/series/60847/
> > > > >
> > > > > Hope this explanation helps?
> > > >
> > > > It doesn't.
> > > >
> > > > The clock tree is this one:
> > > >
> > > > PLL(s) -> TCON module clock -> TCON dotclock.
> > > >
> > > > The links I mentioned above show that the clock set to lcd_rate is the
> > > > TCON module clocks (and it should be the one taking the bpp and lanes
> > > > into account), while the TCON dotclock uses a fixed divider of 4.
> > >
> > > Sorry, I can argue much other-than giving some code snips, according to [1]
> > >
> > > 00) Line 785, 786 with dclk_rate 148000000
> > >
> > > lcd_rate = dclk_rate * clk_info.dsi_div;
> > > pll_rate = lcd_rate * clk_info.lcd_div;
> > >
> > > Since dsi_div is 6 (bpp/lanes), lcd_div 1
> > >
> > > lcd_rate = 888000000, pll_rate = 888000000
> > >
> > > 01) Line 801, 804 are final rates computed as per clock driver (say
> > > ccu_nkm in mainline)
> > >
> > > lcd_rate_set=891000000
> > >
> > > As per your comments if it would be 4 then the desired numbers are
> > > would be 592000000 not 888000000.
> > >
> > > This is what I'm trying to say in all mails, and same as verified with
> > > 2-lanes devices as well where the dsi_div is 12 so the final rate is
> > > 290MHz * 12
> >
> > In the code you sent, you're forcing a divider on the internal TCON
> > clock, while that one is fixed in the BSP.
> >
> > There's indeed the bpp / lanes divider, but it's used in the *parent*
> > clock of the one you're changing.
> >
> > And the dsi0_clk clock you pointed out in the code snippet is yet
> > another clock, the MIPI DSI module clock.
>
> Correct, look like I refereed wrong reference in the above mail. sorry
> for the noise.
>
> Actually I'm trying to explain about pll_rate here which indeed
> depends on dsi.div
> https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L786
>
> lcd_rate = dclk_rate * clk_info.dsi_div;
> pll_rate = lcd_rate * clk_info.lcd_div;
>
> Say
>
> 1) For 148MHz dclk_rate with dsi_div is 6 (24/4) lcd_div is 1 which
> resulting pll_rate is 888MHz.
>
> 2) For 30MHz dclk_rate with 4 lane and 24 RGB the resulting pll_rate is 180MHz
>
> 3) For 27.5MHz dclk_rate with 2 lane and 24 RGB the resulting pll_rate is 330MHz
>
> Here is the few more logs in code, for case 2)
>
> [ 1.920441] sun4i_dclk_round_rate: min_div = 6 max_div = 6, rate = 30000000
> [ 1.920505] ideal = 180000000, rounded = 178200000
> [ 1.920509] sun4i_dclk_round_rate: div = 6 rate = 29700000
> [ 1.920514] sun4i_dclk_round_rate: min_div = 6 max_div = 6, rate = 30000000
> [ 1.920532] ideal = 180000000, rounded = 178200000
> [ 1.920535] sun4i_dclk_round_rate: div = 6 rate = 29700000
> [ 1.920572] sun4i_dclk_recalc_rate: val = 1, rate = 178200000
> [ 1.920576] sun4i_dclk_recalc_rate: val = 1, rate = 178200000
> [ 1.920597] rate = 178200000
> [ 1.920599] parent_rate = 297000000
> [ 1.920602] reg = 0x90c00000
> [ 1.920605] _nkm.n = 3, nkm->n.offset = 0x1, nkm->n.shift = 8
> [ 1.920609] _nkm.k = 2, nkm->k.offset = 0x1, nkm->k.shift = 4
> [ 1.920612] _nkm.m = 10, nkm->m.offset = 0x1, nkm->m.shift = 0
> [ 1.920958] sun4i_dclk_set_rate div 6
> [ 1.920966] sun4i_dclk_recalc_rate: val = 6, rate = 29700000
>
> and clk_summary:
>
> pll-video0 1 1 1 297000000
> 0 0 50000
> hdmi 0 0 0 297000000
> 0 0 50000
> tcon1 0 0 0 297000000
> 0 0 50000
> pll-mipi 1 1 1 178200000
> 0 0 50000
> tcon0 2 2 1 178200000
> 0 0 50000
> tcon-pixel-clock 1 1 1 29700000
> 0 0 50000
> pll-video0-2x 0 0 0 594000000
> 0 0 50000
This discussion is going nowhere. I'm telling you that your patch
doesn't apply the divider you want on the proper clock, and you're
replying that indeed, you're applying it on the wrong clock.
It might work by accident in your case, but the board I have here
clearly indicates otherwise, so there's two possible way out here:
- Either you apply that divider to the TCON *module* clock, and not
the dclk
- Or you point to somewhere in the allwinner code where the bpp /
lanes divider is used for the dclk divider.
Maxim
--
Maxime Ripard, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
On Tue, Jun 25, 2019 at 8:19 PM Maxime Ripard <[email protected]> wrote:
>
> On Thu, Jun 20, 2019 at 11:57:44PM +0530, Jagan Teki wrote:
> > On Fri, Jun 14, 2019 at 7:54 PM Maxime Ripard <[email protected]> wrote:
> > >
> > > On Wed, Jun 05, 2019 at 01:03:16PM +0530, Jagan Teki wrote:
> > > > On Wed, Jun 5, 2019 at 12:19 PM Maxime Ripard <[email protected]> wrote:
> > > > >
> > > > > Hi,
> > > > >
> > > > > I've reordered the mail a bit to work on chunks
> > > > >
> > > > > On Fri, May 24, 2019 at 03:37:42PM +0530, Jagan Teki wrote:
> > > > > > > I wish it was in your commit log in the first place, instead of having
> > > > > > > to exchange multiple mails over this.
> > > > > > >
> > > > > > > However, I don't think that's quite true, and it might be a bug in
> > > > > > > Allwinner's implementation (or rather something quite confusing).
> > > > > > >
> > > > > > > You're right that the lcd_rate and pll_rate seem to be generated from
> > > > > > > the pixel clock, and it indeed looks like the ratio between the pixel
> > > > > > > clock and the TCON dotclock is defined through the number of bits per
> > > > > > > lanes.
> > > > > > >
> > > > > > > However, in this case, dsi_rate is actually the same than lcd_rate,
> > > > > > > since pll_rate is going to be divided by dsi_div:
> > > > > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L791
> > > > > > >
> > > > > > > Since lcd_div is 1, it also means that in this case, dsi_rate ==
> > > > > > > dclk_rate.
> > > > > > >
> > > > > > > The DSI module clock however, is always set to 148.5 MHz. Indeed, if
> > > > > > > we look at:
> > > > > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L804
> > > > > > >
> > > > > > > We can see that the rate in clk_info is used if it's different than
> > > > > > > 0. This is filled by disp_al_lcd_get_clk_info, which, in the case of a
> > > > > > > DSI panel, will hardcode it to 148.5 MHz:
> > > > > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/lowlevel_sun50iw1/disp_al.c#L164
> > > > > >
> > > > > > Let me explain, something more.
> > > > > >
> > > > > > According to bsp there are clk_info.tcon_div which I will explain below.
> > > > > > clk_info.dsi_div which is dynamic and it depends on bpp/lanes, so it
> > > > > > is 6 for 24bpp and 4 lanes devices.
> > > > > >
> > > > > > PLL rate here depends on dsi_div (not tcon_div)
> > > > > >
> > > > > > Code here
> > > > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L784
> > > > > >
> > > > > > is computing the actual set rate, which depends on dsi_rate.
> > > > > >
> > > > > > lcd_rate = dclk_rate * clk_info.dsi_div;
> > > > > > dsi_rate = pll_rate / clk_info.dsi_div;
> > > > > >
> > > > > > Say if the dclk_rate 148MHz then the dsi_rate is 888MHz which set rate
> > > > > > for above link you mentioned.
> > > > > >
> > > > > > Here are the evidence with some prints.
> > > > > >
> > > > > > https://gist.github.com/openedev/9bae2d87d2fcc06b999fe48c998b7043
> > > > > > https://gist.github.com/openedev/700de2e3701b2bf3ad1aa0f0fa862c9a
> > > > >
> > > > > Ok, so we agree up to this point, and the prints confirm that the
> > > > > analysis above is the right one.
> > > > >
> > > > > > > So, the DSI clock is set to this here:
> > > > > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L805
> > > > >
> > > > > Your patch doesn't address that, so let's leave that one alone.
> > > >
> > > > Basically this is final pll set rate when sun4i_dotclock.c called the
> > > > desired rate with ccu_nkm.c so it ended the final rate with parent as
> > > > Line 8 of
> > > > https://gist.github.com/openedev/700de2e3701b2bf3ad1aa0f0fa862c9a
> > >
> > > If that's important to the driver, it should be set explicitly then,
> > > and not work by accident.
> > >
> > > > > > > The TCON *module* clock (the one in the clock controller) has been set
> > > > > > > to lcd_rate (so the pixel clock times the number of bits per lane) here:
> > > > > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L800
> > > > > > >
> > > > > > > And the PLL has been set to the same rate here:
> > > > > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L794
> > > > > > >
> > > > > > > Let's take a step back now: that function we were looking at,
> > > > > > > lcd_clk_config, is called by lcd_clk_enable, which is in turn called
> > > > > > > by disp_lcd_enable here:
> > > > > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L1328
> > > > > > >
> > > > > > > The next function being called is disp_al_lcd_cfg, and that function
> > > > > > > will hardcode the TCON dotclock divider to 4, here:
> > > > > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/lowlevel_sun50iw1/disp_al.c#L240
> > > > > >
> > > > > > tcon_div from BSP point-of-view of there are two variants
> > > > > > 00) clk_info.tcon_div which is 4 and same is set the divider position
> > > > > > in SUN4I_TCON0_DCLK_REG (like above link refer)
> > > > > > 01) tcon_div which is 4 and used for edge timings computation
> > > > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/lowlevel_sun50iw1/de_dsi.c#L12
> > > > > >
> > > > > > The real reason for 01) is again 4 is they set the divider to 4 in 00)
> > > > > > which is technically wrong because the dividers which used during
> > > > > > dotclock in above (dsi_div) should be used here as well. Since there
> > > > > > is no dynamic way of doing this BSP hard-coding these values.
> > > > > >
> > > > > > Patches 5,6,7 on this series doing this
> > > > > > https://patchwork.freedesktop.org/series/60847/
> > > > > >
> > > > > > Hope this explanation helps?
> > > > >
> > > > > It doesn't.
> > > > >
> > > > > The clock tree is this one:
> > > > >
> > > > > PLL(s) -> TCON module clock -> TCON dotclock.
> > > > >
> > > > > The links I mentioned above show that the clock set to lcd_rate is the
> > > > > TCON module clocks (and it should be the one taking the bpp and lanes
> > > > > into account), while the TCON dotclock uses a fixed divider of 4.
> > > >
> > > > Sorry, I can argue much other-than giving some code snips, according to [1]
> > > >
> > > > 00) Line 785, 786 with dclk_rate 148000000
> > > >
> > > > lcd_rate = dclk_rate * clk_info.dsi_div;
> > > > pll_rate = lcd_rate * clk_info.lcd_div;
> > > >
> > > > Since dsi_div is 6 (bpp/lanes), lcd_div 1
> > > >
> > > > lcd_rate = 888000000, pll_rate = 888000000
> > > >
> > > > 01) Line 801, 804 are final rates computed as per clock driver (say
> > > > ccu_nkm in mainline)
> > > >
> > > > lcd_rate_set=891000000
> > > >
> > > > As per your comments if it would be 4 then the desired numbers are
> > > > would be 592000000 not 888000000.
> > > >
> > > > This is what I'm trying to say in all mails, and same as verified with
> > > > 2-lanes devices as well where the dsi_div is 12 so the final rate is
> > > > 290MHz * 12
> > >
> > > In the code you sent, you're forcing a divider on the internal TCON
> > > clock, while that one is fixed in the BSP.
> > >
> > > There's indeed the bpp / lanes divider, but it's used in the *parent*
> > > clock of the one you're changing.
> > >
> > > And the dsi0_clk clock you pointed out in the code snippet is yet
> > > another clock, the MIPI DSI module clock.
> >
> > Correct, look like I refereed wrong reference in the above mail. sorry
> > for the noise.
> >
> > Actually I'm trying to explain about pll_rate here which indeed
> > depends on dsi.div
> > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L786
> >
> > lcd_rate = dclk_rate * clk_info.dsi_div;
> > pll_rate = lcd_rate * clk_info.lcd_div;
> >
> > Say
> >
> > 1) For 148MHz dclk_rate with dsi_div is 6 (24/4) lcd_div is 1 which
> > resulting pll_rate is 888MHz.
> >
> > 2) For 30MHz dclk_rate with 4 lane and 24 RGB the resulting pll_rate is 180MHz
> >
> > 3) For 27.5MHz dclk_rate with 2 lane and 24 RGB the resulting pll_rate is 330MHz
> >
> > Here is the few more logs in code, for case 2)
> >
> > [ 1.920441] sun4i_dclk_round_rate: min_div = 6 max_div = 6, rate = 30000000
> > [ 1.920505] ideal = 180000000, rounded = 178200000
> > [ 1.920509] sun4i_dclk_round_rate: div = 6 rate = 29700000
> > [ 1.920514] sun4i_dclk_round_rate: min_div = 6 max_div = 6, rate = 30000000
> > [ 1.920532] ideal = 180000000, rounded = 178200000
> > [ 1.920535] sun4i_dclk_round_rate: div = 6 rate = 29700000
> > [ 1.920572] sun4i_dclk_recalc_rate: val = 1, rate = 178200000
> > [ 1.920576] sun4i_dclk_recalc_rate: val = 1, rate = 178200000
> > [ 1.920597] rate = 178200000
> > [ 1.920599] parent_rate = 297000000
> > [ 1.920602] reg = 0x90c00000
> > [ 1.920605] _nkm.n = 3, nkm->n.offset = 0x1, nkm->n.shift = 8
> > [ 1.920609] _nkm.k = 2, nkm->k.offset = 0x1, nkm->k.shift = 4
> > [ 1.920612] _nkm.m = 10, nkm->m.offset = 0x1, nkm->m.shift = 0
> > [ 1.920958] sun4i_dclk_set_rate div 6
> > [ 1.920966] sun4i_dclk_recalc_rate: val = 6, rate = 29700000
> >
> > and clk_summary:
> >
> > pll-video0 1 1 1 297000000
> > 0 0 50000
> > hdmi 0 0 0 297000000
> > 0 0 50000
> > tcon1 0 0 0 297000000
> > 0 0 50000
> > pll-mipi 1 1 1 178200000
> > 0 0 50000
> > tcon0 2 2 1 178200000
> > 0 0 50000
> > tcon-pixel-clock 1 1 1 29700000
> > 0 0 50000
> > pll-video0-2x 0 0 0 594000000
> > 0 0 50000
>
> This discussion is going nowhere. I'm telling you that your patch
> doesn't apply the divider you want on the proper clock, and you're
> replying that indeed, you're applying it on the wrong clock.
>
> It might work by accident in your case, but the board I have here
> clearly indicates otherwise, so there's two possible way out here:
>
> - Either you apply that divider to the TCON *module* clock, and not
> the dclk
>
> - Or you point to somewhere in the allwinner code where the bpp /
> lanes divider is used for the dclk divider.
I don't know how to proceed further on this, as you say it might work
in accident but I have tested this in A33, A64 and R40 with 4
different DSI panels and one DSI-RGB bridge. All of them do use
PLL_MIPI (pll_rate) and it indeed depends on bpp/lanes
4-lane, 24-bit: Novatek NT35596 panel
4-lane, 24-bit: Feiyang, FY07024di26a30d panel
4-lane, 24-bit: Bananapi-s070wv20 panel
2-lane, 24-bit: Techstar,ts8550b panel
and
4-lane, 24-bit, ICN6211 DSI-to-RGB bridge panel
All above listed panels and bridges are working as per BSP and do
follow bpp/lanes and for DIVIDER 4 no panel is working.
The panels/bridges I have has tested in BSP and as you mentioned in
another mail, your panel is not tested in BSP - this is the only
difference. I did much reverse-engineering on PLL_MIPI clocking in BSP
so I'm afraid what can I do next on this, If you want to look further
on BSP I would suggest to verify on pll_rate side. If you feel
anything I'm missing please let me know.
Jagan.
On Tue, Jun 25, 2019 at 09:00:36PM +0530, Jagan Teki wrote:
> On Tue, Jun 25, 2019 at 8:19 PM Maxime Ripard <[email protected]> wrote:
> >
> > On Thu, Jun 20, 2019 at 11:57:44PM +0530, Jagan Teki wrote:
> > > On Fri, Jun 14, 2019 at 7:54 PM Maxime Ripard <[email protected]> wrote:
> > > >
> > > > On Wed, Jun 05, 2019 at 01:03:16PM +0530, Jagan Teki wrote:
> > > > > On Wed, Jun 5, 2019 at 12:19 PM Maxime Ripard <[email protected]> wrote:
> > > > > >
> > > > > > Hi,
> > > > > >
> > > > > > I've reordered the mail a bit to work on chunks
> > > > > >
> > > > > > On Fri, May 24, 2019 at 03:37:42PM +0530, Jagan Teki wrote:
> > > > > > > > I wish it was in your commit log in the first place, instead of having
> > > > > > > > to exchange multiple mails over this.
> > > > > > > >
> > > > > > > > However, I don't think that's quite true, and it might be a bug in
> > > > > > > > Allwinner's implementation (or rather something quite confusing).
> > > > > > > >
> > > > > > > > You're right that the lcd_rate and pll_rate seem to be generated from
> > > > > > > > the pixel clock, and it indeed looks like the ratio between the pixel
> > > > > > > > clock and the TCON dotclock is defined through the number of bits per
> > > > > > > > lanes.
> > > > > > > >
> > > > > > > > However, in this case, dsi_rate is actually the same than lcd_rate,
> > > > > > > > since pll_rate is going to be divided by dsi_div:
> > > > > > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L791
> > > > > > > >
> > > > > > > > Since lcd_div is 1, it also means that in this case, dsi_rate ==
> > > > > > > > dclk_rate.
> > > > > > > >
> > > > > > > > The DSI module clock however, is always set to 148.5 MHz. Indeed, if
> > > > > > > > we look at:
> > > > > > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L804
> > > > > > > >
> > > > > > > > We can see that the rate in clk_info is used if it's different than
> > > > > > > > 0. This is filled by disp_al_lcd_get_clk_info, which, in the case of a
> > > > > > > > DSI panel, will hardcode it to 148.5 MHz:
> > > > > > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/lowlevel_sun50iw1/disp_al.c#L164
> > > > > > >
> > > > > > > Let me explain, something more.
> > > > > > >
> > > > > > > According to bsp there are clk_info.tcon_div which I will explain below.
> > > > > > > clk_info.dsi_div which is dynamic and it depends on bpp/lanes, so it
> > > > > > > is 6 for 24bpp and 4 lanes devices.
> > > > > > >
> > > > > > > PLL rate here depends on dsi_div (not tcon_div)
> > > > > > >
> > > > > > > Code here
> > > > > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L784
> > > > > > >
> > > > > > > is computing the actual set rate, which depends on dsi_rate.
> > > > > > >
> > > > > > > lcd_rate = dclk_rate * clk_info.dsi_div;
> > > > > > > dsi_rate = pll_rate / clk_info.dsi_div;
> > > > > > >
> > > > > > > Say if the dclk_rate 148MHz then the dsi_rate is 888MHz which set rate
> > > > > > > for above link you mentioned.
> > > > > > >
> > > > > > > Here are the evidence with some prints.
> > > > > > >
> > > > > > > https://gist.github.com/openedev/9bae2d87d2fcc06b999fe48c998b7043
> > > > > > > https://gist.github.com/openedev/700de2e3701b2bf3ad1aa0f0fa862c9a
> > > > > >
> > > > > > Ok, so we agree up to this point, and the prints confirm that the
> > > > > > analysis above is the right one.
> > > > > >
> > > > > > > > So, the DSI clock is set to this here:
> > > > > > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L805
> > > > > >
> > > > > > Your patch doesn't address that, so let's leave that one alone.
> > > > >
> > > > > Basically this is final pll set rate when sun4i_dotclock.c called the
> > > > > desired rate with ccu_nkm.c so it ended the final rate with parent as
> > > > > Line 8 of
> > > > > https://gist.github.com/openedev/700de2e3701b2bf3ad1aa0f0fa862c9a
> > > >
> > > > If that's important to the driver, it should be set explicitly then,
> > > > and not work by accident.
> > > >
> > > > > > > > The TCON *module* clock (the one in the clock controller) has been set
> > > > > > > > to lcd_rate (so the pixel clock times the number of bits per lane) here:
> > > > > > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L800
> > > > > > > >
> > > > > > > > And the PLL has been set to the same rate here:
> > > > > > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L794
> > > > > > > >
> > > > > > > > Let's take a step back now: that function we were looking at,
> > > > > > > > lcd_clk_config, is called by lcd_clk_enable, which is in turn called
> > > > > > > > by disp_lcd_enable here:
> > > > > > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L1328
> > > > > > > >
> > > > > > > > The next function being called is disp_al_lcd_cfg, and that function
> > > > > > > > will hardcode the TCON dotclock divider to 4, here:
> > > > > > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/lowlevel_sun50iw1/disp_al.c#L240
> > > > > > >
> > > > > > > tcon_div from BSP point-of-view of there are two variants
> > > > > > > 00) clk_info.tcon_div which is 4 and same is set the divider position
> > > > > > > in SUN4I_TCON0_DCLK_REG (like above link refer)
> > > > > > > 01) tcon_div which is 4 and used for edge timings computation
> > > > > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/lowlevel_sun50iw1/de_dsi.c#L12
> > > > > > >
> > > > > > > The real reason for 01) is again 4 is they set the divider to 4 in 00)
> > > > > > > which is technically wrong because the dividers which used during
> > > > > > > dotclock in above (dsi_div) should be used here as well. Since there
> > > > > > > is no dynamic way of doing this BSP hard-coding these values.
> > > > > > >
> > > > > > > Patches 5,6,7 on this series doing this
> > > > > > > https://patchwork.freedesktop.org/series/60847/
> > > > > > >
> > > > > > > Hope this explanation helps?
> > > > > >
> > > > > > It doesn't.
> > > > > >
> > > > > > The clock tree is this one:
> > > > > >
> > > > > > PLL(s) -> TCON module clock -> TCON dotclock.
> > > > > >
> > > > > > The links I mentioned above show that the clock set to lcd_rate is the
> > > > > > TCON module clocks (and it should be the one taking the bpp and lanes
> > > > > > into account), while the TCON dotclock uses a fixed divider of 4.
> > > > >
> > > > > Sorry, I can argue much other-than giving some code snips, according to [1]
> > > > >
> > > > > 00) Line 785, 786 with dclk_rate 148000000
> > > > >
> > > > > lcd_rate = dclk_rate * clk_info.dsi_div;
> > > > > pll_rate = lcd_rate * clk_info.lcd_div;
> > > > >
> > > > > Since dsi_div is 6 (bpp/lanes), lcd_div 1
> > > > >
> > > > > lcd_rate = 888000000, pll_rate = 888000000
> > > > >
> > > > > 01) Line 801, 804 are final rates computed as per clock driver (say
> > > > > ccu_nkm in mainline)
> > > > >
> > > > > lcd_rate_set=891000000
> > > > >
> > > > > As per your comments if it would be 4 then the desired numbers are
> > > > > would be 592000000 not 888000000.
> > > > >
> > > > > This is what I'm trying to say in all mails, and same as verified with
> > > > > 2-lanes devices as well where the dsi_div is 12 so the final rate is
> > > > > 290MHz * 12
> > > >
> > > > In the code you sent, you're forcing a divider on the internal TCON
> > > > clock, while that one is fixed in the BSP.
> > > >
> > > > There's indeed the bpp / lanes divider, but it's used in the *parent*
> > > > clock of the one you're changing.
> > > >
> > > > And the dsi0_clk clock you pointed out in the code snippet is yet
> > > > another clock, the MIPI DSI module clock.
> > >
> > > Correct, look like I refereed wrong reference in the above mail. sorry
> > > for the noise.
> > >
> > > Actually I'm trying to explain about pll_rate here which indeed
> > > depends on dsi.div
> > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L786
> > >
> > > lcd_rate = dclk_rate * clk_info.dsi_div;
> > > pll_rate = lcd_rate * clk_info.lcd_div;
> > >
> > > Say
> > >
> > > 1) For 148MHz dclk_rate with dsi_div is 6 (24/4) lcd_div is 1 which
> > > resulting pll_rate is 888MHz.
> > >
> > > 2) For 30MHz dclk_rate with 4 lane and 24 RGB the resulting pll_rate is 180MHz
> > >
> > > 3) For 27.5MHz dclk_rate with 2 lane and 24 RGB the resulting pll_rate is 330MHz
> > >
> > > Here is the few more logs in code, for case 2)
> > >
> > > [ 1.920441] sun4i_dclk_round_rate: min_div = 6 max_div = 6, rate = 30000000
> > > [ 1.920505] ideal = 180000000, rounded = 178200000
> > > [ 1.920509] sun4i_dclk_round_rate: div = 6 rate = 29700000
> > > [ 1.920514] sun4i_dclk_round_rate: min_div = 6 max_div = 6, rate = 30000000
> > > [ 1.920532] ideal = 180000000, rounded = 178200000
> > > [ 1.920535] sun4i_dclk_round_rate: div = 6 rate = 29700000
> > > [ 1.920572] sun4i_dclk_recalc_rate: val = 1, rate = 178200000
> > > [ 1.920576] sun4i_dclk_recalc_rate: val = 1, rate = 178200000
> > > [ 1.920597] rate = 178200000
> > > [ 1.920599] parent_rate = 297000000
> > > [ 1.920602] reg = 0x90c00000
> > > [ 1.920605] _nkm.n = 3, nkm->n.offset = 0x1, nkm->n.shift = 8
> > > [ 1.920609] _nkm.k = 2, nkm->k.offset = 0x1, nkm->k.shift = 4
> > > [ 1.920612] _nkm.m = 10, nkm->m.offset = 0x1, nkm->m.shift = 0
> > > [ 1.920958] sun4i_dclk_set_rate div 6
> > > [ 1.920966] sun4i_dclk_recalc_rate: val = 6, rate = 29700000
> > >
> > > and clk_summary:
> > >
> > > pll-video0 1 1 1 297000000
> > > 0 0 50000
> > > hdmi 0 0 0 297000000
> > > 0 0 50000
> > > tcon1 0 0 0 297000000
> > > 0 0 50000
> > > pll-mipi 1 1 1 178200000
> > > 0 0 50000
> > > tcon0 2 2 1 178200000
> > > 0 0 50000
> > > tcon-pixel-clock 1 1 1 29700000
> > > 0 0 50000
> > > pll-video0-2x 0 0 0 594000000
> > > 0 0 50000
> >
> > This discussion is going nowhere. I'm telling you that your patch
> > doesn't apply the divider you want on the proper clock, and you're
> > replying that indeed, you're applying it on the wrong clock.
> >
> > It might work by accident in your case, but the board I have here
> > clearly indicates otherwise, so there's two possible way out here:
> >
> > - Either you apply that divider to the TCON *module* clock, and not
> > the dclk
> >
> > - Or you point to somewhere in the allwinner code where the bpp /
> > lanes divider is used for the dclk divider.
>
> I don't know how to proceed further on this, as you say it might work
> in accident but I have tested this in A33, A64 and R40 with 4
> different DSI panels and one DSI-RGB bridge. All of them do use
> PLL_MIPI (pll_rate) and it indeed depends on bpp/lanes
>
> 4-lane, 24-bit: Novatek NT35596 panel
> 4-lane, 24-bit: Feiyang, FY07024di26a30d panel
> 4-lane, 24-bit: Bananapi-s070wv20 panel
> 2-lane, 24-bit: Techstar,ts8550b panel
>
> and
>
> 4-lane, 24-bit, ICN6211 DSI-to-RGB bridge panel
>
> All above listed panels and bridges are working as per BSP and do
> follow bpp/lanes and for DIVIDER 4 no panel is working.
Look. I'm not saying that there's no issue, I'm saying that your
patch, applied to the clock you're applying it to, doesn't make sense
and isn't what the BSP does.
You can keep on arguing that your patch is perfect as is, but the fact
that there's regressions proves otherwise.
> The panels/bridges I have has tested in BSP and as you mentioned in
> another mail, your panel is not tested in BSP - this is the only
> difference. I did much reverse-engineering on PLL_MIPI clocking in BSP
> so I'm afraid what can I do next on this, If you want to look further
> on BSP I would suggest to verify on pll_rate side. If you feel
> anything I'm missing please let me know.
I already told you how we can make some progress in the mail you
quoted, but you chose to ignore that.
Until there's been some progress on either points mentionned above,
I'm just going to stop answering on this topic.
Maxime
--
Maxime Ripard, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
Hi Maxime
On Wed, Jul 3, 2019 at 1:49 PM Maxime Ripard <[email protected]> wrote:
>
> On Tue, Jun 25, 2019 at 09:00:36PM +0530, Jagan Teki wrote:
> > On Tue, Jun 25, 2019 at 8:19 PM Maxime Ripard <[email protected]> wrote:
> > >
> > > On Thu, Jun 20, 2019 at 11:57:44PM +0530, Jagan Teki wrote:
> > > > On Fri, Jun 14, 2019 at 7:54 PM Maxime Ripard <[email protected]> wrote:
> > > > >
> > > > > On Wed, Jun 05, 2019 at 01:03:16PM +0530, Jagan Teki wrote:
> > > > > > On Wed, Jun 5, 2019 at 12:19 PM Maxime Ripard <[email protected]> wrote:
> > > > > > >
> > > > > > > Hi,
> > > > > > >
> > > > > > > I've reordered the mail a bit to work on chunks
> > > > > > >
> > > > > > > On Fri, May 24, 2019 at 03:37:42PM +0530, Jagan Teki wrote:
> > > > > > > > > I wish it was in your commit log in the first place, instead of having
> > > > > > > > > to exchange multiple mails over this.
> > > > > > > > >
> > > > > > > > > However, I don't think that's quite true, and it might be a bug in
> > > > > > > > > Allwinner's implementation (or rather something quite confusing).
> > > > > > > > >
> > > > > > > > > You're right that the lcd_rate and pll_rate seem to be generated from
> > > > > > > > > the pixel clock, and it indeed looks like the ratio between the pixel
> > > > > > > > > clock and the TCON dotclock is defined through the number of bits per
> > > > > > > > > lanes.
> > > > > > > > >
> > > > > > > > > However, in this case, dsi_rate is actually the same than lcd_rate,
> > > > > > > > > since pll_rate is going to be divided by dsi_div:
> > > > > > > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L791
> > > > > > > > >
> > > > > > > > > Since lcd_div is 1, it also means that in this case, dsi_rate ==
> > > > > > > > > dclk_rate.
> > > > > > > > >
> > > > > > > > > The DSI module clock however, is always set to 148.5 MHz. Indeed, if
> > > > > > > > > we look at:
> > > > > > > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L804
> > > > > > > > >
> > > > > > > > > We can see that the rate in clk_info is used if it's different than
> > > > > > > > > 0. This is filled by disp_al_lcd_get_clk_info, which, in the case of a
> > > > > > > > > DSI panel, will hardcode it to 148.5 MHz:
> > > > > > > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/lowlevel_sun50iw1/disp_al.c#L164
> > > > > > > >
> > > > > > > > Let me explain, something more.
> > > > > > > >
> > > > > > > > According to bsp there are clk_info.tcon_div which I will explain below.
> > > > > > > > clk_info.dsi_div which is dynamic and it depends on bpp/lanes, so it
> > > > > > > > is 6 for 24bpp and 4 lanes devices.
> > > > > > > >
> > > > > > > > PLL rate here depends on dsi_div (not tcon_div)
> > > > > > > >
> > > > > > > > Code here
> > > > > > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L784
> > > > > > > >
> > > > > > > > is computing the actual set rate, which depends on dsi_rate.
> > > > > > > >
> > > > > > > > lcd_rate = dclk_rate * clk_info.dsi_div;
> > > > > > > > dsi_rate = pll_rate / clk_info.dsi_div;
> > > > > > > >
> > > > > > > > Say if the dclk_rate 148MHz then the dsi_rate is 888MHz which set rate
> > > > > > > > for above link you mentioned.
> > > > > > > >
> > > > > > > > Here are the evidence with some prints.
> > > > > > > >
> > > > > > > > https://gist.github.com/openedev/9bae2d87d2fcc06b999fe48c998b7043
> > > > > > > > https://gist.github.com/openedev/700de2e3701b2bf3ad1aa0f0fa862c9a
> > > > > > >
> > > > > > > Ok, so we agree up to this point, and the prints confirm that the
> > > > > > > analysis above is the right one.
> > > > > > >
> > > > > > > > > So, the DSI clock is set to this here:
> > > > > > > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L805
> > > > > > >
> > > > > > > Your patch doesn't address that, so let's leave that one alone.
> > > > > >
> > > > > > Basically this is final pll set rate when sun4i_dotclock.c called the
> > > > > > desired rate with ccu_nkm.c so it ended the final rate with parent as
> > > > > > Line 8 of
> > > > > > https://gist.github.com/openedev/700de2e3701b2bf3ad1aa0f0fa862c9a
> > > > >
> > > > > If that's important to the driver, it should be set explicitly then,
> > > > > and not work by accident.
> > > > >
> > > > > > > > > The TCON *module* clock (the one in the clock controller) has been set
> > > > > > > > > to lcd_rate (so the pixel clock times the number of bits per lane) here:
> > > > > > > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L800
> > > > > > > > >
> > > > > > > > > And the PLL has been set to the same rate here:
> > > > > > > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L794
> > > > > > > > >
> > > > > > > > > Let's take a step back now: that function we were looking at,
> > > > > > > > > lcd_clk_config, is called by lcd_clk_enable, which is in turn called
> > > > > > > > > by disp_lcd_enable here:
> > > > > > > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L1328
> > > > > > > > >
> > > > > > > > > The next function being called is disp_al_lcd_cfg, and that function
> > > > > > > > > will hardcode the TCON dotclock divider to 4, here:
> > > > > > > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/lowlevel_sun50iw1/disp_al.c#L240
> > > > > > > >
> > > > > > > > tcon_div from BSP point-of-view of there are two variants
> > > > > > > > 00) clk_info.tcon_div which is 4 and same is set the divider position
> > > > > > > > in SUN4I_TCON0_DCLK_REG (like above link refer)
> > > > > > > > 01) tcon_div which is 4 and used for edge timings computation
> > > > > > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/lowlevel_sun50iw1/de_dsi.c#L12
> > > > > > > >
> > > > > > > > The real reason for 01) is again 4 is they set the divider to 4 in 00)
> > > > > > > > which is technically wrong because the dividers which used during
> > > > > > > > dotclock in above (dsi_div) should be used here as well. Since there
> > > > > > > > is no dynamic way of doing this BSP hard-coding these values.
> > > > > > > >
> > > > > > > > Patches 5,6,7 on this series doing this
> > > > > > > > https://patchwork.freedesktop.org/series/60847/
> > > > > > > >
> > > > > > > > Hope this explanation helps?
> > > > > > >
> > > > > > > It doesn't.
> > > > > > >
> > > > > > > The clock tree is this one:
> > > > > > >
> > > > > > > PLL(s) -> TCON module clock -> TCON dotclock.
> > > > > > >
> > > > > > > The links I mentioned above show that the clock set to lcd_rate is the
> > > > > > > TCON module clocks (and it should be the one taking the bpp and lanes
> > > > > > > into account), while the TCON dotclock uses a fixed divider of 4.
> > > > > >
> > > > > > Sorry, I can argue much other-than giving some code snips, according to [1]
> > > > > >
> > > > > > 00) Line 785, 786 with dclk_rate 148000000
> > > > > >
> > > > > > lcd_rate = dclk_rate * clk_info.dsi_div;
> > > > > > pll_rate = lcd_rate * clk_info.lcd_div;
> > > > > >
> > > > > > Since dsi_div is 6 (bpp/lanes), lcd_div 1
> > > > > >
> > > > > > lcd_rate = 888000000, pll_rate = 888000000
> > > > > >
> > > > > > 01) Line 801, 804 are final rates computed as per clock driver (say
> > > > > > ccu_nkm in mainline)
> > > > > >
> > > > > > lcd_rate_set=891000000
> > > > > >
> > > > > > As per your comments if it would be 4 then the desired numbers are
> > > > > > would be 592000000 not 888000000.
> > > > > >
> > > > > > This is what I'm trying to say in all mails, and same as verified with
> > > > > > 2-lanes devices as well where the dsi_div is 12 so the final rate is
> > > > > > 290MHz * 12
> > > > >
> > > > > In the code you sent, you're forcing a divider on the internal TCON
> > > > > clock, while that one is fixed in the BSP.
> > > > >
> > > > > There's indeed the bpp / lanes divider, but it's used in the *parent*
> > > > > clock of the one you're changing.
> > > > >
> > > > > And the dsi0_clk clock you pointed out in the code snippet is yet
> > > > > another clock, the MIPI DSI module clock.
> > > >
> > > > Correct, look like I refereed wrong reference in the above mail. sorry
> > > > for the noise.
> > > >
> > > > Actually I'm trying to explain about pll_rate here which indeed
> > > > depends on dsi.div
> > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L786
> > > >
> > > > lcd_rate = dclk_rate * clk_info.dsi_div;
> > > > pll_rate = lcd_rate * clk_info.lcd_div;
> > > >
> > > > Say
> > > >
> > > > 1) For 148MHz dclk_rate with dsi_div is 6 (24/4) lcd_div is 1 which
> > > > resulting pll_rate is 888MHz.
> > > >
> > > > 2) For 30MHz dclk_rate with 4 lane and 24 RGB the resulting pll_rate is 180MHz
> > > >
> > > > 3) For 27.5MHz dclk_rate with 2 lane and 24 RGB the resulting pll_rate is 330MHz
> > > >
> > > > Here is the few more logs in code, for case 2)
> > > >
> > > > [ 1.920441] sun4i_dclk_round_rate: min_div = 6 max_div = 6, rate = 30000000
> > > > [ 1.920505] ideal = 180000000, rounded = 178200000
> > > > [ 1.920509] sun4i_dclk_round_rate: div = 6 rate = 29700000
> > > > [ 1.920514] sun4i_dclk_round_rate: min_div = 6 max_div = 6, rate = 30000000
> > > > [ 1.920532] ideal = 1800ls and one DSI-RGB bridge. All of them do use
> > PLL_MIPI (pll_rate) and it indeed depends on bpp/lanes
> >00000, rounded = 178200000
> > > > [ 1.920535] sun4i_dclk_round_rate: div = 6 rate = 29700000
> > > > [ 1.920572] sun4i_dclk_recalc_rate: val = 1, rate = 178200000
> > > > [ 1.920576] sun4i_dclk_recalc_rate: val = 1, rate = 178200000
> > > > [ 1.920597] rate = 178200000
> > > > [ 1.920599] parent_rate = 297000000
> > > > [ 1.920602] reg = 0x90c00000
> > > > [ 1.920605] _nkm.n = 3, nkm->n.offset = 0x1, nkm->n.shift = 8
> > > > [ 1.920609] _nkm.k = 2, nkm->k.offset = 0x1, nkm->k.shift = 4
> > > > [ 1.920612] _nkm.m = 10, nkm->m.offset = 0x1, nkm->m.shift = 0
> > > > [ 1.920958] sun4i_dclk_set_rate div 6
> > > > [ 1.920966] sun4i_dclk_recalc_rate: val = 6, rate = 29700000
> > > >
> > > > and clk_summary:
> > > >
> > > > pll-video0 1 1 1 297000000
> > > > 0 0 50000
> > > > hdmi 0 0 0 297000000
> > > > 0 0 50000
> > > > tcon1 0 0 0 297000000
> > > > 0 0 50000
> > > > pll-mipi 1 1 1 178200000
> > > > 0 0 50000
> > > > tcon0 2 2 1 178200000
> > > > 0 0 50000
> > > > tcon-pixel-clock 1 1 1 29700000
> > > > 0 0 50000
> > > > pll-video0-2x 0 0 0 594000000
> > > > 0 0 50000
> > >
> > > This discussion is going nowhere. I'm telling you that your patch
> > > doesn't apply the divider you want on the proper clock, and you're
> > > replying that indeed, you're applying it on the wrong clock.
> > >
> > > It might work by accident in your case, but the board I have here
> > > clearly indicates otherwise, so there's two possible way out here:
> > >
> > > - Either you apply that divider to the TCON *module* clock, and not
> > > the dclk
> > >
> > > - Or you point to somewhere in the allwinner code where the bpp /
> > > lanes divider is used for the dclk divider.
> >
> > I don't know how to proceed further on this, as you say it might work
> > in accident but I have tested this in A33, A64 and R40 with 4
> > different DSI panels and one DSI-RGB bridge. All of them do use
> > PLL_MIPI (pll_rate) and it indeed depends on bpp/lanes
> >
> > 4-lane, 24-bit: Novatek NT35596 panel
> > 4-lane, 24-bit: Feiyang, FY07024di26a30d panel
> > 4-lane, 24-bit: Bananapi-s070wv20 panel
> > 2-lane, 24-bit: Techstar,ts8550b panel
> >
> > and
> >
> > 4-lane, 24-bit, ICN6211 DSI-to-RGB bridge panel
> >
> > All above listed panels and bridges are working as per BSP and do
> > follow bpp/lanes and for DIVIDER 4 no panel is working.
>
> Look. I'm not saying that there's no issue, I'm saying that your
> patch, applied to the clock you're applying it to, doesn't make sense
> and isn't what the BSP does.
tcon-pixel clock is the rate that you want to achive on display side and
if you have 4 lanes 32bit or lanes and different bit number that you need
to have a clock that is able to put outside bits and speed equal to
pixel-clock * bits / lanes. so If you want a pixel-clock of 40 mhz
and you have 32bits and 4 lanes you need to have a clock of
40 * 32 / 4 in no-burst mode. I think that this is done but most of the display.
Now in burst mode I don't know how should work the calculation of the
clock for the
require bandwidth and even I understand your comment I would like to have your
clock tree after you boot on the display side and if it is possible I
want to assemble a kit
like you have.
>
> You can keep on arguing that your patch is perfect as is, but the fact
> that there's regressions proves otherwise.
>
Well when you push your code you said that you have tested on more
then one display.
Can I know where are the others?
> > The panels/bridges I have has tested in BSP and as you mentioned in
> > another mail, your panel is not tested in BSP - this is the only
> > difference. I did much reverse-engineering on PLL_MIPI clocking in BSP
> > so I'm afraid what can I do next on this, If you want to look further
> > on BSP I would suggest to verify on pll_rate side. If you feel
> > anything I'm missing please let me know.
>
> I already told you how we can make some progress in the mail you
> quoted, but you chose to ignore that.
>
Yes, the idea is to make progress. Thank you about your helping
Michael
> Until there's been some progress on either points mentionned above,
> I'm just going to stop answering on this topic.
>
> Maxime
>
> --
> Maxime Ripard, Bootlin
> Embedded Linux and Kernel engineering
> https://bootlin.com
--
| Michael Nazzareno Trimarchi Amarula Solutions BV |
| COO - Founder Cruquiuskade 47 |
| +31(0)851119172 Amsterdam 1018 AM NL |
| [`as] http://www.amarulasolutions.com |
On Fri, Jul 05, 2019 at 07:52:27PM +0200, Michael Nazzareno Trimarchi wrote:
> On Wed, Jul 3, 2019 at 1:49 PM Maxime Ripard <[email protected]> wrote:
> >
> > On Tue, Jun 25, 2019 at 09:00:36PM +0530, Jagan Teki wrote:
> > > On Tue, Jun 25, 2019 at 8:19 PM Maxime Ripard <[email protected]> wrote:
> > > >
> > > > On Thu, Jun 20, 2019 at 11:57:44PM +0530, Jagan Teki wrote:
> > > > > On Fri, Jun 14, 2019 at 7:54 PM Maxime Ripard <[email protected]> wrote:
> > > > > >
> > > > > > On Wed, Jun 05, 2019 at 01:03:16PM +0530, Jagan Teki wrote:
> > > > > > > On Wed, Jun 5, 2019 at 12:19 PM Maxime Ripard <[email protected]> wrote:
> > > > > > > >
> > > > > > > > Hi,
> > > > > > > >
> > > > > > > > I've reordered the mail a bit to work on chunks
> > > > > > > >
> > > > > > > > On Fri, May 24, 2019 at 03:37:42PM +0530, Jagan Teki wrote:
> > > > > > > > > > I wish it was in your commit log in the first place, instead of having
> > > > > > > > > > to exchange multiple mails over this.
> > > > > > > > > >
> > > > > > > > > > However, I don't think that's quite true, and it might be a bug in
> > > > > > > > > > Allwinner's implementation (or rather something quite confusing).
> > > > > > > > > >
> > > > > > > > > > You're right that the lcd_rate and pll_rate seem to be generated from
> > > > > > > > > > the pixel clock, and it indeed looks like the ratio between the pixel
> > > > > > > > > > clock and the TCON dotclock is defined through the number of bits per
> > > > > > > > > > lanes.
> > > > > > > > > >
> > > > > > > > > > However, in this case, dsi_rate is actually the same than lcd_rate,
> > > > > > > > > > since pll_rate is going to be divided by dsi_div:
> > > > > > > > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L791
> > > > > > > > > >
> > > > > > > > > > Since lcd_div is 1, it also means that in this case, dsi_rate ==
> > > > > > > > > > dclk_rate.
> > > > > > > > > >
> > > > > > > > > > The DSI module clock however, is always set to 148.5 MHz. Indeed, if
> > > > > > > > > > we look at:
> > > > > > > > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L804
> > > > > > > > > >
> > > > > > > > > > We can see that the rate in clk_info is used if it's different than
> > > > > > > > > > 0. This is filled by disp_al_lcd_get_clk_info, which, in the case of a
> > > > > > > > > > DSI panel, will hardcode it to 148.5 MHz:
> > > > > > > > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/lowlevel_sun50iw1/disp_al.c#L164
> > > > > > > > >
> > > > > > > > > Let me explain, something more.
> > > > > > > > >
> > > > > > > > > According to bsp there are clk_info.tcon_div which I will explain below.
> > > > > > > > > clk_info.dsi_div which is dynamic and it depends on bpp/lanes, so it
> > > > > > > > > is 6 for 24bpp and 4 lanes devices.
> > > > > > > > >
> > > > > > > > > PLL rate here depends on dsi_div (not tcon_div)
> > > > > > > > >
> > > > > > > > > Code here
> > > > > > > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L784
> > > > > > > > >
> > > > > > > > > is computing the actual set rate, which depends on dsi_rate.
> > > > > > > > >
> > > > > > > > > lcd_rate = dclk_rate * clk_info.dsi_div;
> > > > > > > > > dsi_rate = pll_rate / clk_info.dsi_div;
> > > > > > > > >
> > > > > > > > > Say if the dclk_rate 148MHz then the dsi_rate is 888MHz which set rate
> > > > > > > > > for above link you mentioned.
> > > > > > > > >
> > > > > > > > > Here are the evidence with some prints.
> > > > > > > > >
> > > > > > > > > https://gist.github.com/openedev/9bae2d87d2fcc06b999fe48c998b7043
> > > > > > > > > https://gist.github.com/openedev/700de2e3701b2bf3ad1aa0f0fa862c9a
> > > > > > > >
> > > > > > > > Ok, so we agree up to this point, and the prints confirm that the
> > > > > > > > analysis above is the right one.
> > > > > > > >
> > > > > > > > > > So, the DSI clock is set to this here:
> > > > > > > > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L805
> > > > > > > >
> > > > > > > > Your patch doesn't address that, so let's leave that one alone.
> > > > > > >
> > > > > > > Basically this is final pll set rate when sun4i_dotclock.c called the
> > > > > > > desired rate with ccu_nkm.c so it ended the final rate with parent as
> > > > > > > Line 8 of
> > > > > > > https://gist.github.com/openedev/700de2e3701b2bf3ad1aa0f0fa862c9a
> > > > > >
> > > > > > If that's important to the driver, it should be set explicitly then,
> > > > > > and not work by accident.
> > > > > >
> > > > > > > > > > The TCON *module* clock (the one in the clock controller) has been set
> > > > > > > > > > to lcd_rate (so the pixel clock times the number of bits per lane) here:
> > > > > > > > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L800
> > > > > > > > > >
> > > > > > > > > > And the PLL has been set to the same rate here:
> > > > > > > > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L794
> > > > > > > > > >
> > > > > > > > > > Let's take a step back now: that function we were looking at,
> > > > > > > > > > lcd_clk_config, is called by lcd_clk_enable, which is in turn called
> > > > > > > > > > by disp_lcd_enable here:
> > > > > > > > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L1328
> > > > > > > > > >
> > > > > > > > > > The next function being called is disp_al_lcd_cfg, and that function
> > > > > > > > > > will hardcode the TCON dotclock divider to 4, here:
> > > > > > > > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/lowlevel_sun50iw1/disp_al.c#L240
> > > > > > > > >
> > > > > > > > > tcon_div from BSP point-of-view of there are two variants
> > > > > > > > > 00) clk_info.tcon_div which is 4 and same is set the divider position
> > > > > > > > > in SUN4I_TCON0_DCLK_REG (like above link refer)
> > > > > > > > > 01) tcon_div which is 4 and used for edge timings computation
> > > > > > > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/lowlevel_sun50iw1/de_dsi.c#L12
> > > > > > > > >
> > > > > > > > > The real reason for 01) is again 4 is they set the divider to 4 in 00)
> > > > > > > > > which is technically wrong because the dividers which used during
> > > > > > > > > dotclock in above (dsi_div) should be used here as well. Since there
> > > > > > > > > is no dynamic way of doing this BSP hard-coding these values.
> > > > > > > > >
> > > > > > > > > Patches 5,6,7 on this series doing this
> > > > > > > > > https://patchwork.freedesktop.org/series/60847/
> > > > > > > > >
> > > > > > > > > Hope this explanation helps?
> > > > > > > >
> > > > > > > > It doesn't.
> > > > > > > >
> > > > > > > > The clock tree is this one:
> > > > > > > >
> > > > > > > > PLL(s) -> TCON module clock -> TCON dotclock.
> > > > > > > >
> > > > > > > > The links I mentioned above show that the clock set to lcd_rate is the
> > > > > > > > TCON module clocks (and it should be the one taking the bpp and lanes
> > > > > > > > into account), while the TCON dotclock uses a fixed divider of 4.
> > > > > > >
> > > > > > > Sorry, I can argue much other-than giving some code snips, according to [1]
> > > > > > >
> > > > > > > 00) Line 785, 786 with dclk_rate 148000000
> > > > > > >
> > > > > > > lcd_rate = dclk_rate * clk_info.dsi_div;
> > > > > > > pll_rate = lcd_rate * clk_info.lcd_div;
> > > > > > >
> > > > > > > Since dsi_div is 6 (bpp/lanes), lcd_div 1
> > > > > > >
> > > > > > > lcd_rate = 888000000, pll_rate = 888000000
> > > > > > >
> > > > > > > 01) Line 801, 804 are final rates computed as per clock driver (say
> > > > > > > ccu_nkm in mainline)
> > > > > > >
> > > > > > > lcd_rate_set=891000000
> > > > > > >
> > > > > > > As per your comments if it would be 4 then the desired numbers are
> > > > > > > would be 592000000 not 888000000.
> > > > > > >
> > > > > > > This is what I'm trying to say in all mails, and same as verified with
> > > > > > > 2-lanes devices as well where the dsi_div is 12 so the final rate is
> > > > > > > 290MHz * 12
> > > > > >
> > > > > > In the code you sent, you're forcing a divider on the internal TCON
> > > > > > clock, while that one is fixed in the BSP.
> > > > > >
> > > > > > There's indeed the bpp / lanes divider, but it's used in the *parent*
> > > > > > clock of the one you're changing.
> > > > > >
> > > > > > And the dsi0_clk clock you pointed out in the code snippet is yet
> > > > > > another clock, the MIPI DSI module clock.
> > > > >
> > > > > Correct, look like I refereed wrong reference in the above mail. sorry
> > > > > for the noise.
> > > > >
> > > > > Actually I'm trying to explain about pll_rate here which indeed
> > > > > depends on dsi.div
> > > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L786
> > > > >
> > > > > lcd_rate = dclk_rate * clk_info.dsi_div;
> > > > > pll_rate = lcd_rate * clk_info.lcd_div;
> > > > >
> > > > > Say
> > > > >
> > > > > 1) For 148MHz dclk_rate with dsi_div is 6 (24/4) lcd_div is 1 which
> > > > > resulting pll_rate is 888MHz.
> > > > >
> > > > > 2) For 30MHz dclk_rate with 4 lane and 24 RGB the resulting pll_rate is 180MHz
> > > > >
> > > > > 3) For 27.5MHz dclk_rate with 2 lane and 24 RGB the resulting pll_rate is 330MHz
> > > > >
> > > > > Here is the few more logs in code, for case 2)
> > > > >
> > > > > [ 1.920441] sun4i_dclk_round_rate: min_div = 6 max_div = 6, rate = 30000000
> > > > > [ 1.920505] ideal = 180000000, rounded = 178200000
> > > > > [ 1.920509] sun4i_dclk_round_rate: div = 6 rate = 29700000
> > > > > [ 1.920514] sun4i_dclk_round_rate: min_div = 6 max_div = 6, rate = 30000000
> > > > > [ 1.920532] ideal = 1800ls and one DSI-RGB bridge. All of them do use
> > > PLL_MIPI (pll_rate) and it indeed depends on bpp/lanes
> > >00000, rounded = 178200000
> > > > > [ 1.920535] sun4i_dclk_round_rate: div = 6 rate = 29700000
> > > > > [ 1.920572] sun4i_dclk_recalc_rate: val = 1, rate = 178200000
> > > > > [ 1.920576] sun4i_dclk_recalc_rate: val = 1, rate = 178200000
> > > > > [ 1.920597] rate = 178200000
> > > > > [ 1.920599] parent_rate = 297000000
> > > > > [ 1.920602] reg = 0x90c00000
> > > > > [ 1.920605] _nkm.n = 3, nkm->n.offset = 0x1, nkm->n.shift = 8
> > > > > [ 1.920609] _nkm.k = 2, nkm->k.offset = 0x1, nkm->k.shift = 4
> > > > > [ 1.920612] _nkm.m = 10, nkm->m.offset = 0x1, nkm->m.shift = 0
> > > > > [ 1.920958] sun4i_dclk_set_rate div 6
> > > > > [ 1.920966] sun4i_dclk_recalc_rate: val = 6, rate = 29700000
> > > > >
> > > > > and clk_summary:
> > > > >
> > > > > pll-video0 1 1 1 297000000
> > > > > 0 0 50000
> > > > > hdmi 0 0 0 297000000
> > > > > 0 0 50000
> > > > > tcon1 0 0 0 297000000
> > > > > 0 0 50000
> > > > > pll-mipi 1 1 1 178200000
> > > > > 0 0 50000
> > > > > tcon0 2 2 1 178200000
> > > > > 0 0 50000
> > > > > tcon-pixel-clock 1 1 1 29700000
> > > > > 0 0 50000
> > > > > pll-video0-2x 0 0 0 594000000
> > > > > 0 0 50000
> > > >
> > > > This discussion is going nowhere. I'm telling you that your patch
> > > > doesn't apply the divider you want on the proper clock, and you're
> > > > replying that indeed, you're applying it on the wrong clock.
> > > >
> > > > It might work by accident in your case, but the board I have here
> > > > clearly indicates otherwise, so there's two possible way out here:
> > > >
> > > > - Either you apply that divider to the TCON *module* clock, and not
> > > > the dclk
> > > >
> > > > - Or you point to somewhere in the allwinner code where the bpp /
> > > > lanes divider is used for the dclk divider.
> > >
> > > I don't know how to proceed further on this, as you say it might work
> > > in accident but I have tested this in A33, A64 and R40 with 4
> > > different DSI panels and one DSI-RGB bridge. All of them do use
> > > PLL_MIPI (pll_rate) and it indeed depends on bpp/lanes
> > >
> > > 4-lane, 24-bit: Novatek NT35596 panel
> > > 4-lane, 24-bit: Feiyang, FY07024di26a30d panel
> > > 4-lane, 24-bit: Bananapi-s070wv20 panel
> > > 2-lane, 24-bit: Techstar,ts8550b panel
> > >
> > > and
> > >
> > > 4-lane, 24-bit, ICN6211 DSI-to-RGB bridge panel
> > >
> > > All above listed panels and bridges are working as per BSP and do
> > > follow bpp/lanes and for DIVIDER 4 no panel is working.
> >
> > Look. I'm not saying that there's no issue, I'm saying that your
> > patch, applied to the clock you're applying it to, doesn't make sense
> > and isn't what the BSP does.
>
> tcon-pixel clock is the rate that you want to achive on display side
> and if you have 4 lanes 32bit or lanes and different bit number that
> you need to have a clock that is able to put outside bits and speed
> equal to pixel-clock * bits / lanes. so If you want a pixel-clock of
> 40 mhz and you have 32bits and 4 lanes you need to have a clock of
> 40 * 32 / 4 in no-burst mode. I think that this is done but most of
> the display.
So this is what the issue is then?
This one does make sense, and you should just change the rate in the
call to clk_set_rate in sun4i_tcon0_mode_set_cpu.
I'm still wondering why that hasn't been brought up in either the
discussion or the commit log before though.
> Now in burst mode I don't know how should work the calculation of
> the clock for the require bandwidth and even I understand your
> comment I would like to have your clock tree after you boot on the
> display side and if it is possible I want to assemble a kit like you
> have.
The setup is probably going to be a bit difficult to reproduce, it's a
prototype that I have that can't really be found anywhere. Jagan asked
me on IRC for the reference, and he found the part, but it's unclear
to me if it can be easily adapted to a common board.
However, I'm not even sure we need this. I'll test the next version
and let you know if it works.
Maxime
--
Maxime Ripard, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
Hi Maxime
On Thu, Jul 11, 2019 at 2:23 PM Maxime Ripard <[email protected]> wrote:
>
> On Fri, Jul 05, 2019 at 07:52:27PM +0200, Michael Nazzareno Trimarchi wrote:
> > On Wed, Jul 3, 2019 at 1:49 PM Maxime Ripard <[email protected]> wrote:
> > >
> > > On Tue, Jun 25, 2019 at 09:00:36PM +0530, Jagan Teki wrote:
> > > > On Tue, Jun 25, 2019 at 8:19 PM Maxime Ripard <[email protected]> wrote:
> > > > >
> > > > > On Thu, Jun 20, 2019 at 11:57:44PM +0530, Jagan Teki wrote:
> > > > > > On Fri, Jun 14, 2019 at 7:54 PM Maxime Ripard <[email protected]> wrote:
> > > > > > >
> > > > > > > On Wed, Jun 05, 2019 at 01:03:16PM +0530, Jagan Teki wrote:
> > > > > > > > On Wed, Jun 5, 2019 at 12:19 PM Maxime Ripard <[email protected]> wrote:
> > > > > > > > >
> > > > > > > > > Hi,
> > > > > > > > >
> > > > > > > > > I've reordered the mail a bit to work on chunks
> > > > > > > > >
> > > > > > > > > On Fri, May 24, 2019 at 03:37:42PM +0530, Jagan Teki wrote:
> > > > > > > > > > > I wish it was in your commit log in the first place, instead of having
> > > > > > > > > > > to exchange multiple mails over this.
> > > > > > > > > > >
> > > > > > > > > > > However, I don't think that's quite true, and it might be a bug in
> > > > > > > > > > > Allwinner's implementation (or rather something quite confusing).
> > > > > > > > > > >
> > > > > > > > > > > You're right that the lcd_rate and pll_rate seem to be generated from
> > > > > > > > > > > the pixel clock, and it indeed looks like the ratio between the pixel
> > > > > > > > > > > clock and the TCON dotclock is defined through the number of bits per
> > > > > > > > > > > lanes.
> > > > > > > > > > >
> > > > > > > > > > > However, in this case, dsi_rate is actually the same than lcd_rate,
> > > > > > > > > > > since pll_rate is going to be divided by dsi_div:
> > > > > > > > > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L791
> > > > > > > > > > >
> > > > > > > > > > > Since lcd_div is 1, it also means that in this case, dsi_rate ==
> > > > > > > > > > > dclk_rate.
> > > > > > > > > > >
> > > > > > > > > > > The DSI module clock however, is always set to 148.5 MHz. Indeed, if
> > > > > > > > > > > we look at:
> > > > > > > > > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L804
> > > > > > > > > > >
> > > > > > > > > > > We can see that the rate in clk_info is used if it's different than
> > > > > > > > > > > 0. This is filled by disp_al_lcd_get_clk_info, which, in the case of a
> > > > > > > > > > > DSI panel, will hardcode it to 148.5 MHz:
> > > > > > > > > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/lowlevel_sun50iw1/disp_al.c#L164
> > > > > > > > > >
> > > > > > > > > > Let me explain, something more.
> > > > > > > > > >
> > > > > > > > > > According to bsp there are clk_info.tcon_div which I will explain below.
> > > > > > > > > > clk_info.dsi_div which is dynamic and it depends on bpp/lanes, so it
> > > > > > > > > > is 6 for 24bpp and 4 lanes devices.
> > > > > > > > > >
> > > > > > > > > > PLL rate here depends on dsi_div (not tcon_div)
> > > > > > > > > >
> > > > > > > > > > Code here
> > > > > > > > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L784
> > > > > > > > > >
> > > > > > > > > > is computing the actual set rate, which depends on dsi_rate.
> > > > > > > > > >
> > > > > > > > > > lcd_rate = dclk_rate * clk_info.dsi_div;
> > > > > > > > > > dsi_rate = pll_rate / clk_info.dsi_div;
> > > > > > > > > >
> > > > > > > > > > Say if the dclk_rate 148MHz then the dsi_rate is 888MHz which set rate
> > > > > > > > > > for above link you mentioned.
> > > > > > > > > >
> > > > > > > > > > Here are the evidence with some prints.
> > > > > > > > > >
> > > > > > > > > > https://gist.github.com/openedev/9bae2d87d2fcc06b999fe48c998b7043
> > > > > > > > > > https://gist.github.com/openedev/700de2e3701b2bf3ad1aa0f0fa862c9a
> > > > > > > > >
> > > > > > > > > Ok, so we agree up to this point, and the prints confirm that the
> > > > > > > > > analysis above is the right one.
> > > > > > > > >
> > > > > > > > > > > So, the DSI clock is set to this here:
> > > > > > > > > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L805
> > > > > > > > >
> > > > > > > > > Your patch doesn't address that, so let's leave that one alone.
> > > > > > > >
> > > > > > > > Basically this is final pll set rate when sun4i_dotclock.c called the
> > > > > > > > desired rate with ccu_nkm.c so it ended the final rate with parent as
> > > > > > > > Line 8 of
> > > > > > > > https://gist.github.com/openedev/700de2e3701b2bf3ad1aa0f0fa862c9a
> > > > > > >
> > > > > > > If that's important to the driver, it should be set explicitly then,
> > > > > > > and not work by accident.
> > > > > > >
> > > > > > > > > > > The TCON *module* clock (the one in the clock controller) has been set
> > > > > > > > > > > to lcd_rate (so the pixel clock times the number of bits per lane) here:
> > > > > > > > > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L800
> > > > > > > > > > >
> > > > > > > > > > > And the PLL has been set to the same rate here:
> > > > > > > > > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L794
> > > > > > > > > > >
> > > > > > > > > > > Let's take a step back now: that function we were looking at,
> > > > > > > > > > > lcd_clk_config, is called by lcd_clk_enable, which is in turn called
> > > > > > > > > > > by disp_lcd_enable here:
> > > > > > > > > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L1328
> > > > > > > > > > >
> > > > > > > > > > > The next function being called is disp_al_lcd_cfg, and that function
> > > > > > > > > > > will hardcode the TCON dotclock divider to 4, here:
> > > > > > > > > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/lowlevel_sun50iw1/disp_al.c#L240
> > > > > > > > > >
> > > > > > > > > > tcon_div from BSP point-of-view of there are two variants
> > > > > > > > > > 00) clk_info.tcon_div which is 4 and same is set the divider position
> > > > > > > > > > in SUN4I_TCON0_DCLK_REG (like above link refer)
> > > > > > > > > > 01) tcon_div which is 4 and used for edge timings computation
> > > > > > > > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/lowlevel_sun50iw1/de_dsi.c#L12
> > > > > > > > > >
> > > > > > > > > > The real reason for 01) is again 4 is they set the divider to 4 in 00)
> > > > > > > > > > which is technically wrong because the dividers which used during
> > > > > > > > > > dotclock in above (dsi_div) should be used here as well. Since there
> > > > > > > > > > is no dynamic way of doing this BSP hard-coding these values.
> > > > > > > > > >
> > > > > > > > > > Patches 5,6,7 on this series doing this
> > > > > > > > > > https://patchwork.freedesktop.org/series/60847/
> > > > > > > > > >
> > > > > > > > > > Hope this explanation helps?
> > > > > > > > >
> > > > > > > > > It doesn't.
> > > > > > > > >
> > > > > > > > > The clock tree is this one:
> > > > > > > > >
> > > > > > > > > PLL(s) -> TCON module clock -> TCON dotclock.
> > > > > > > > >
> > > > > > > > > The links I mentioned above show that the clock set to lcd_rate is the
> > > > > > > > > TCON module clocks (and it should be the one taking the bpp and lanes
> > > > > > > > > into account), while the TCON dotclock uses a fixed divider of 4.
> > > > > > > >
> > > > > > > > Sorry, I can argue much other-than giving some code snips, according to [1]
> > > > > > > >
> > > > > > > > 00) Line 785, 786 with dclk_rate 148000000
> > > > > > > >
> > > > > > > > lcd_rate = dclk_rate * clk_info.dsi_div;
> > > > > > > > pll_rate = lcd_rate * clk_info.lcd_div;
> > > > > > > >
> > > > > > > > Since dsi_div is 6 (bpp/lanes), lcd_div 1
> > > > > > > >
> > > > > > > > lcd_rate = 888000000, pll_rate = 888000000
> > > > > > > >
> > > > > > > > 01) Line 801, 804 are final rates computed as per clock driver (say
> > > > > > > > ccu_nkm in mainline)
> > > > > > > >
> > > > > > > > lcd_rate_set=891000000
> > > > > > > >
> > > > > > > > As per your comments if it would be 4 then the desired numbers are
> > > > > > > > would be 592000000 not 888000000.
> > > > > > > >
> > > > > > > > This is what I'm trying to say in all mails, and same as verified with
> > > > > > > > 2-lanes devices as well where the dsi_div is 12 so the final rate is
> > > > > > > > 290MHz * 12
> > > > > > >
> > > > > > > In the code you sent, you're forcing a divider on the internal TCON
> > > > > > > clock, while that one is fixed in the BSP.
> > > > > > >
> > > > > > > There's indeed the bpp / lanes divider, but it's used in the *parent*
> > > > > > > clock of the one you're changing.
> > > > > > >
> > > > > > > And the dsi0_clk clock you pointed out in the code snippet is yet
> > > > > > > another clock, the MIPI DSI module clock.
> > > > > >
> > > > > > Correct, look like I refereed wrong reference in the above mail. sorry
> > > > > > for the noise.
> > > > > >
> > > > > > Actually I'm trying to explain about pll_rate here which indeed
> > > > > > depends on dsi.div
> > > > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L786
> > > > > >
> > > > > > lcd_rate = dclk_rate * clk_info.dsi_div;
> > > > > > pll_rate = lcd_rate * clk_info.lcd_div;
> > > > > >
> > > > > > Say
> > > > > >
> > > > > > 1) For 148MHz dclk_rate with dsi_div is 6 (24/4) lcd_div is 1 which
> > > > > > resulting pll_rate is 888MHz.
> > > > > >
> > > > > > 2) For 30MHz dclk_rate with 4 lane and 24 RGB the resulting pll_rate is 180MHz
> > > > > >
> > > > > > 3) For 27.5MHz dclk_rate with 2 lane and 24 RGB the resulting pll_rate is 330MHz
> > > > > >
> > > > > > Here is the few more logs in code, for case 2)
> > > > > >
> > > > > > [ 1.920441] sun4i_dclk_round_rate: min_div = 6 max_div = 6, rate = 30000000
> > > > > > [ 1.920505] ideal = 180000000, rounded = 178200000
> > > > > > [ 1.920509] sun4i_dclk_round_rate: div = 6 rate = 29700000
> > > > > > [ 1.920514] sun4i_dclk_round_rate: min_div = 6 max_div = 6, rate = 30000000
> > > > > > [ 1.920532] ideal = 1800ls and one DSI-RGB bridge. All of them do use
> > > > PLL_MIPI (pll_rate) and it indeed depends on bpp/lanes
> > > >00000, rounded = 178200000
> > > > > > [ 1.920535] sun4i_dclk_round_rate: div = 6 rate = 29700000
> > > > > > [ 1.920572] sun4i_dclk_recalc_rate: val = 1, rate = 178200000
> > > > > > [ 1.920576] sun4i_dclk_recalc_rate: val = 1, rate = 178200000
> > > > > > [ 1.920597] rate = 178200000
> > > > > > [ 1.920599] parent_rate = 297000000
> > > > > > [ 1.920602] reg = 0x90c00000
> > > > > > [ 1.920605] _nkm.n = 3, nkm->n.offset = 0x1, nkm->n.shift = 8
> > > > > > [ 1.920609] _nkm.k = 2, nkm->k.offset = 0x1, nkm->k.shift = 4
> > > > > > [ 1.920612] _nkm.m = 10, nkm->m.offset = 0x1, nkm->m.shift = 0
> > > > > > [ 1.920958] sun4i_dclk_set_rate div 6
> > > > > > [ 1.920966] sun4i_dclk_recalc_rate: val = 6, rate = 29700000
> > > > > >
> > > > > > and clk_summary:
> > > > > >
> > > > > > pll-video0 1 1 1 297000000
> > > > > > 0 0 50000
> > > > > > hdmi 0 0 0 297000000
> > > > > > 0 0 50000
> > > > > > tcon1 0 0 0 297000000
> > > > > > 0 0 50000
> > > > > > pll-mipi 1 1 1 178200000
> > > > > > 0 0 50000
> > > > > > tcon0 2 2 1 178200000
> > > > > > 0 0 50000
> > > > > > tcon-pixel-clock 1 1 1 29700000
> > > > > > 0 0 50000
> > > > > > pll-video0-2x 0 0 0 594000000
> > > > > > 0 0 50000
> > > > >
> > > > > This discussion is going nowhere. I'm telling you that your patch
> > > > > doesn't apply the divider you want on the proper clock, and you're
> > > > > replying that indeed, you're applying it on the wrong clock.
> > > > >
> > > > > It might work by accident in your case, but the board I have here
> > > > > clearly indicates otherwise, so there's two possible way out here:
> > > > >
> > > > > - Either you apply that divider to the TCON *module* clock, and not
> > > > > the dclk
> > > > >
> > > > > - Or you point to somewhere in the allwinner code where the bpp /
> > > > > lanes divider is used for the dclk divider.
> > > >
> > > > I don't know how to proceed further on this, as you say it might work
> > > > in accident but I have tested this in A33, A64 and R40 with 4
> > > > different DSI panels and one DSI-RGB bridge. All of them do use
> > > > PLL_MIPI (pll_rate) and it indeed depends on bpp/lanes
> > > >
> > > > 4-lane, 24-bit: Novatek NT35596 panel
> > > > 4-lane, 24-bit: Feiyang, FY07024di26a30d panel
> > > > 4-lane, 24-bit: Bananapi-s070wv20 panel
> > > > 2-lane, 24-bit: Techstar,ts8550b panel
> > > >
> > > > and
> > > >
> > > > 4-lane, 24-bit, ICN6211 DSI-to-RGB bridge panel
> > > >
> > > > All above listed panels and bridges are working as per BSP and do
> > > > follow bpp/lanes and for DIVIDER 4 no panel is working.
> > >
> > > Look. I'm not saying that there's no issue, I'm saying that your
> > > patch, applied to the clock you're applying it to, doesn't make sense
> > > and isn't what the BSP does.
> >
> > tcon-pixel clock is the rate that you want to achive on display side
> > and if you have 4 lanes 32bit or lanes and different bit number that
> > you need to have a clock that is able to put outside bits and speed
> > equal to pixel-clock * bits / lanes. so If you want a pixel-clock of
> > 40 mhz and you have 32bits and 4 lanes you need to have a clock of
> > 40 * 32 / 4 in no-burst mode. I think that this is done but most of
> > the display.
>
> So this is what the issue is then?
>
> This one does make sense, and you should just change the rate in the
> call to clk_set_rate in sun4i_tcon0_mode_set_cpu.
>
> I'm still wondering why that hasn't been brought up in either the
> discussion or the commit log before though.
>
Something like this?
drivers/gpu/drm/sun4i/sun4i_tcon.c | 20 +++++++++++---------
drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h | 2 --
2 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c
b/drivers/gpu/drm/sun4i/sun4i_tcon.c
index 64c43ee6bd92..42560d5c327c 100644
--- a/drivers/gpu/drm/sun4i/sun4i_tcon.c
+++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c
@@ -263,10 +263,11 @@ static int sun4i_tcon_get_clk_delay(const struct
drm_display_mode *mode,
}
static void sun4i_tcon0_mode_set_common(struct sun4i_tcon *tcon,
- const struct drm_display_mode *mode)
+ const struct drm_display_mode *mode,
+ u32 tcon_mul)
{
/* Configure the dot clock */
- clk_set_rate(tcon->dclk, mode->crtc_clock * 1000);
+ clk_set_rate(tcon->dclk, mode->crtc_clock * tcon_mul * 1000);
/* Set the resolution */
regmap_write(tcon->regs, SUN4I_TCON0_BASIC0_REG,
@@ -335,12 +336,13 @@ static void sun4i_tcon0_mode_set_cpu(struct
sun4i_tcon *tcon,
u8 bpp = mipi_dsi_pixel_format_to_bpp(device->format);
u8 lanes = device->lanes;
u32 block_space, start_delay;
- u32 tcon_div;
+ u32 tcon_div, tcon_mul;
- tcon->dclk_min_div = SUN6I_DSI_TCON_DIV;
- tcon->dclk_max_div = SUN6I_DSI_TCON_DIV;
+ tcon->dclk_min_div = 4;
+ tcon->dclk_max_div = 127;
- sun4i_tcon0_mode_set_common(tcon, mode);
+ tcon_mul = bpp / lanes;
+ sun4i_tcon0_mode_set_common(tcon, mode, tcon_mul);
/* Set dithering if needed */
sun4i_tcon0_mode_set_dithering(tcon, sun4i_tcon_get_connector(encoder));
@@ -366,7 +368,7 @@ static void sun4i_tcon0_mode_set_cpu(struct
sun4i_tcon *tcon,
*/
regmap_read(tcon->regs, SUN4I_TCON0_DCLK_REG, &tcon_div);
tcon_div &= GENMASK(6, 0);
- block_space = mode->htotal * bpp / (tcon_div * lanes);
+ block_space = mode->htotal * tcon_div * tcon_mul;
block_space -= mode->hdisplay + 40;
regmap_write(tcon->regs, SUN4I_TCON0_CPU_TRI0_REG,
@@ -408,7 +410,7 @@ static void sun4i_tcon0_mode_set_lvds(struct
sun4i_tcon *tcon,
tcon->dclk_min_div = 7;
tcon->dclk_max_div = 7;
- sun4i_tcon0_mode_set_common(tcon, mode);
+ sun4i_tcon0_mode_set_common(tcon, mode, 1);
/* Set dithering if needed */
sun4i_tcon0_mode_set_dithering(tcon, sun4i_tcon_get_connector(encoder));
@@ -487,7 +489,7 @@ static void sun4i_tcon0_mode_set_rgb(struct
sun4i_tcon *tcon,
tcon->dclk_min_div = 6;
tcon->dclk_max_div = 127;
- sun4i_tcon0_mode_set_common(tcon, mode);
+ sun4i_tcon0_mode_set_common(tcon, mode, 1);
/* Set dithering if needed */
sun4i_tcon0_mode_set_dithering(tcon, connector);
diff --git a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h
b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h
index 5c3ad5be0690..a07090579f84 100644
--- a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h
+++ b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h
@@ -13,8 +13,6 @@
#include <drm/drm_encoder.h>
#include <drm/drm_mipi_dsi.h>
-#define SUN6I_DSI_TCON_DIV 4
-
struct sun6i_dsi {
struct drm_connector connector;
struct drm_encoder encoder;
> > Now in burst mode I don't know how should work the calculation of
> > the clock for the require bandwidth and even I understand your
> > comment I would like to have your clock tree after you boot on the
> > display side and if it is possible I want to assemble a kit like you
> > have.
>
> The setup is probably going to be a bit difficult to reproduce, it's a
> prototype that I have that can't really be found anywhere. Jagan asked
> me on IRC for the reference, and he found the part, but it's unclear
> to me if it can be easily adapted to a common board.
>
> However, I'm not even sure we need this. I'll test the next version
> and let you know if it works.
>
> Maxime
>
> --
> Maxime Ripard, Bootlin
> Embedded Linux and Kernel engineering
> https://bootlin.com
--
| Michael Nazzareno Trimarchi Amarula Solutions BV |
| COO - Founder Cruquiuskade 47 |
| +31(0)851119172 Amsterdam 1018 AM NL |
| [`as] http://www.amarulasolutions.com |
Hi
On Thu, Jul 11, 2019 at 7:43 PM Michael Nazzareno Trimarchi
<[email protected]> wrote:
>
> Hi Maxime
>
> On Thu, Jul 11, 2019 at 2:23 PM Maxime Ripard <[email protected]> wrote:
> >
> > On Fri, Jul 05, 2019 at 07:52:27PM +0200, Michael Nazzareno Trimarchi wrote:
> > > On Wed, Jul 3, 2019 at 1:49 PM Maxime Ripard <[email protected]> wrote:
> > > >
> > > > On Tue, Jun 25, 2019 at 09:00:36PM +0530, Jagan Teki wrote:
> > > > > On Tue, Jun 25, 2019 at 8:19 PM Maxime Ripard <[email protected]> wrote:
> > > > > >
> > > > > > On Thu, Jun 20, 2019 at 11:57:44PM +0530, Jagan Teki wrote:
> > > > > > > On Fri, Jun 14, 2019 at 7:54 PM Maxime Ripard <[email protected]> wrote:
> > > > > > > >
> > > > > > > > On Wed, Jun 05, 2019 at 01:03:16PM +0530, Jagan Teki wrote:
> > > > > > > > > On Wed, Jun 5, 2019 at 12:19 PM Maxime Ripard <[email protected]> wrote:
> > > > > > > > > >
> > > > > > > > > > Hi,
> > > > > > > > > >
> > > > > > > > > > I've reordered the mail a bit to work on chunks
> > > > > > > > > >
> > > > > > > > > > On Fri, May 24, 2019 at 03:37:42PM +0530, Jagan Teki wrote:
> > > > > > > > > > > > I wish it was in your commit log in the first place, instead of having
> > > > > > > > > > > > to exchange multiple mails over this.
> > > > > > > > > > > >
> > > > > > > > > > > > However, I don't think that's quite true, and it might be a bug in
> > > > > > > > > > > > Allwinner's implementation (or rather something quite confusing).
> > > > > > > > > > > >
> > > > > > > > > > > > You're right that the lcd_rate and pll_rate seem to be generated from
> > > > > > > > > > > > the pixel clock, and it indeed looks like the ratio between the pixel
> > > > > > > > > > > > clock and the TCON dotclock is defined through the number of bits per
> > > > > > > > > > > > lanes.
> > > > > > > > > > > >
> > > > > > > > > > > > However, in this case, dsi_rate is actually the same than lcd_rate,
> > > > > > > > > > > > since pll_rate is going to be divided by dsi_div:
> > > > > > > > > > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L791
> > > > > > > > > > > >
> > > > > > > > > > > > Since lcd_div is 1, it also means that in this case, dsi_rate ==
> > > > > > > > > > > > dclk_rate.
> > > > > > > > > > > >
> > > > > > > > > > > > The DSI module clock however, is always set to 148.5 MHz. Indeed, if
> > > > > > > > > > > > we look at:
> > > > > > > > > > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L804
> > > > > > > > > > > >
> > > > > > > > > > > > We can see that the rate in clk_info is used if it's different than
> > > > > > > > > > > > 0. This is filled by disp_al_lcd_get_clk_info, which, in the case of a
> > > > > > > > > > > > DSI panel, will hardcode it to 148.5 MHz:
> > > > > > > > > > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/lowlevel_sun50iw1/disp_al.c#L164
> > > > > > > > > > >
> > > > > > > > > > > Let me explain, something more.
> > > > > > > > > > >
> > > > > > > > > > > According to bsp there are clk_info.tcon_div which I will explain below.
> > > > > > > > > > > clk_info.dsi_div which is dynamic and it depends on bpp/lanes, so it
> > > > > > > > > > > is 6 for 24bpp and 4 lanes devices.
> > > > > > > > > > >
> > > > > > > > > > > PLL rate here depends on dsi_div (not tcon_div)
> > > > > > > > > > >
> > > > > > > > > > > Code here
> > > > > > > > > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L784
> > > > > > > > > > >
> > > > > > > > > > > is computing the actual set rate, which depends on dsi_rate.
> > > > > > > > > > >
> > > > > > > > > > > lcd_rate = dclk_rate * clk_info.dsi_div;
> > > > > > > > > > > dsi_rate = pll_rate / clk_info.dsi_div;
> > > > > > > > > > >
> > > > > > > > > > > Say if the dclk_rate 148MHz then the dsi_rate is 888MHz which set rate
> > > > > > > > > > > for above link you mentioned.
> > > > > > > > > > >
> > > > > > > > > > > Here are the evidence with some prints.
> > > > > > > > > > >
> > > > > > > > > > > https://gist.github.com/openedev/9bae2d87d2fcc06b999fe48c998b7043
> > > > > > > > > > > https://gist.github.com/openedev/700de2e3701b2bf3ad1aa0f0fa862c9a
> > > > > > > > > >
> > > > > > > > > > Ok, so we agree up to this point, and the prints confirm that the
> > > > > > > > > > analysis above is the right one.
> > > > > > > > > >
> > > > > > > > > > > > So, the DSI clock is set to this here:
> > > > > > > > > > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L805
> > > > > > > > > >
> > > > > > > > > > Your patch doesn't address that, so let's leave that one alone.
> > > > > > > > >
> > > > > > > > > Basically this is final pll set rate when sun4i_dotclock.c called the
> > > > > > > > > desired rate with ccu_nkm.c so it ended the final rate with parent as
> > > > > > > > > Line 8 of
> > > > > > > > > https://gist.github.com/openedev/700de2e3701b2bf3ad1aa0f0fa862c9a
> > > > > > > >
> > > > > > > > If that's important to the driver, it should be set explicitly then,
> > > > > > > > and not work by accident.
> > > > > > > >
> > > > > > > > > > > > The TCON *module* clock (the one in the clock controller) has been set
> > > > > > > > > > > > to lcd_rate (so the pixel clock times the number of bits per lane) here:
> > > > > > > > > > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L800
> > > > > > > > > > > >
> > > > > > > > > > > > And the PLL has been set to the same rate here:
> > > > > > > > > > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L794
> > > > > > > > > > > >
> > > > > > > > > > > > Let's take a step back now: that function we were looking at,
> > > > > > > > > > > > lcd_clk_config, is called by lcd_clk_enable, which is in turn called
> > > > > > > > > > > > by disp_lcd_enable here:
> > > > > > > > > > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L1328
> > > > > > > > > > > >
> > > > > > > > > > > > The next function being called is disp_al_lcd_cfg, and that function
> > > > > > > > > > > > will hardcode the TCON dotclock divider to 4, here:
> > > > > > > > > > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/lowlevel_sun50iw1/disp_al.c#L240
> > > > > > > > > > >
> > > > > > > > > > > tcon_div from BSP point-of-view of there are two variants
> > > > > > > > > > > 00) clk_info.tcon_div which is 4 and same is set the divider position
> > > > > > > > > > > in SUN4I_TCON0_DCLK_REG (like above link refer)
> > > > > > > > > > > 01) tcon_div which is 4 and used for edge timings computation
> > > > > > > > > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/lowlevel_sun50iw1/de_dsi.c#L12
> > > > > > > > > > >
> > > > > > > > > > > The real reason for 01) is again 4 is they set the divider to 4 in 00)
> > > > > > > > > > > which is technically wrong because the dividers which used during
> > > > > > > > > > > dotclock in above (dsi_div) should be used here as well. Since there
> > > > > > > > > > > is no dynamic way of doing this BSP hard-coding these values.
> > > > > > > > > > >
> > > > > > > > > > > Patches 5,6,7 on this series doing this
> > > > > > > > > > > https://patchwork.freedesktop.org/series/60847/
> > > > > > > > > > >
> > > > > > > > > > > Hope this explanation helps?
> > > > > > > > > >
> > > > > > > > > > It doesn't.
> > > > > > > > > >
> > > > > > > > > > The clock tree is this one:
> > > > > > > > > >
> > > > > > > > > > PLL(s) -> TCON module clock -> TCON dotclock.
> > > > > > > > > >
> > > > > > > > > > The links I mentioned above show that the clock set to lcd_rate is the
> > > > > > > > > > TCON module clocks (and it should be the one taking the bpp and lanes
> > > > > > > > > > into account), while the TCON dotclock uses a fixed divider of 4.
> > > > > > > > >
> > > > > > > > > Sorry, I can argue much other-than giving some code snips, according to [1]
> > > > > > > > >
> > > > > > > > > 00) Line 785, 786 with dclk_rate 148000000
> > > > > > > > >
> > > > > > > > > lcd_rate = dclk_rate * clk_info.dsi_div;
> > > > > > > > > pll_rate = lcd_rate * clk_info.lcd_div;
> > > > > > > > >
> > > > > > > > > Since dsi_div is 6 (bpp/lanes), lcd_div 1
> > > > > > > > >
> > > > > > > > > lcd_rate = 888000000, pll_rate = 888000000
> > > > > > > > >
> > > > > > > > > 01) Line 801, 804 are final rates computed as per clock driver (say
> > > > > > > > > ccu_nkm in mainline)
> > > > > > > > >
> > > > > > > > > lcd_rate_set=891000000
> > > > > > > > >
> > > > > > > > > As per your comments if it would be 4 then the desired numbers are
> > > > > > > > > would be 592000000 not 888000000.
> > > > > > > > >
> > > > > > > > > This is what I'm trying to say in all mails, and same as verified with
> > > > > > > > > 2-lanes devices as well where the dsi_div is 12 so the final rate is
> > > > > > > > > 290MHz * 12
> > > > > > > >
> > > > > > > > In the code you sent, you're forcing a divider on the internal TCON
> > > > > > > > clock, while that one is fixed in the BSP.
> > > > > > > >
> > > > > > > > There's indeed the bpp / lanes divider, but it's used in the *parent*
> > > > > > > > clock of the one you're changing.
> > > > > > > >
> > > > > > > > And the dsi0_clk clock you pointed out in the code snippet is yet
> > > > > > > > another clock, the MIPI DSI module clock.
> > > > > > >
> > > > > > > Correct, look like I refereed wrong reference in the above mail. sorry
> > > > > > > for the noise.
> > > > > > >
> > > > > > > Actually I'm trying to explain about pll_rate here which indeed
> > > > > > > depends on dsi.div
> > > > > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L786
> > > > > > >
> > > > > > > lcd_rate = dclk_rate * clk_info.dsi_div;
> > > > > > > pll_rate = lcd_rate * clk_info.lcd_div;
> > > > > > >
> > > > > > > Say
> > > > > > >
> > > > > > > 1) For 148MHz dclk_rate with dsi_div is 6 (24/4) lcd_div is 1 which
> > > > > > > resulting pll_rate is 888MHz.
> > > > > > >
> > > > > > > 2) For 30MHz dclk_rate with 4 lane and 24 RGB the resulting pll_rate is 180MHz
> > > > > > >
> > > > > > > 3) For 27.5MHz dclk_rate with 2 lane and 24 RGB the resulting pll_rate is 330MHz
> > > > > > >
> > > > > > > Here is the few more logs in code, for case 2)
> > > > > > >
> > > > > > > [ 1.920441] sun4i_dclk_round_rate: min_div = 6 max_div = 6, rate = 30000000
> > > > > > > [ 1.920505] ideal = 180000000, rounded = 178200000
> > > > > > > [ 1.920509] sun4i_dclk_round_rate: div = 6 rate = 29700000
> > > > > > > [ 1.920514] sun4i_dclk_round_rate: min_div = 6 max_div = 6, rate = 30000000
> > > > > > > [ 1.920532] ideal = 1800ls and one DSI-RGB bridge. All of them do use
> > > > > PLL_MIPI (pll_rate) and it indeed depends on bpp/lanes
> > > > >00000, rounded = 178200000
> > > > > > > [ 1.920535] sun4i_dclk_round_rate: div = 6 rate = 29700000
> > > > > > > [ 1.920572] sun4i_dclk_recalc_rate: val = 1, rate = 178200000
> > > > > > > [ 1.920576] sun4i_dclk_recalc_rate: val = 1, rate = 178200000
> > > > > > > [ 1.920597] rate = 178200000
> > > > > > > [ 1.920599] parent_rate = 297000000
> > > > > > > [ 1.920602] reg = 0x90c00000
> > > > > > > [ 1.920605] _nkm.n = 3, nkm->n.offset = 0x1, nkm->n.shift = 8
> > > > > > > [ 1.920609] _nkm.k = 2, nkm->k.offset = 0x1, nkm->k.shift = 4
> > > > > > > [ 1.920612] _nkm.m = 10, nkm->m.offset = 0x1, nkm->m.shift = 0
> > > > > > > [ 1.920958] sun4i_dclk_set_rate div 6
> > > > > > > [ 1.920966] sun4i_dclk_recalc_rate: val = 6, rate = 29700000
> > > > > > >
> > > > > > > and clk_summary:
> > > > > > >
> > > > > > > pll-video0 1 1 1 297000000
> > > > > > > 0 0 50000
> > > > > > > hdmi 0 0 0 297000000
> > > > > > > 0 0 50000
> > > > > > > tcon1 0 0 0 297000000
> > > > > > > 0 0 50000
> > > > > > > pll-mipi 1 1 1 178200000
> > > > > > > 0 0 50000
> > > > > > > tcon0 2 2 1 178200000
> > > > > > > 0 0 50000
> > > > > > > tcon-pixel-clock 1 1 1 29700000
> > > > > > > 0 0 50000
> > > > > > > pll-video0-2x 0 0 0 594000000
> > > > > > > 0 0 50000
> > > > > >
> > > > > > This discussion is going nowhere. I'm telling you that your patch
> > > > > > doesn't apply the divider you want on the proper clock, and you're
> > > > > > replying that indeed, you're applying it on the wrong clock.
> > > > > >
> > > > > > It might work by accident in your case, but the board I have here
> > > > > > clearly indicates otherwise, so there's two possible way out here:
> > > > > >
> > > > > > - Either you apply that divider to the TCON *module* clock, and not
> > > > > > the dclk
> > > > > >
> > > > > > - Or you point to somewhere in the allwinner code where the bpp /
> > > > > > lanes divider is used for the dclk divider.
> > > > >
> > > > > I don't know how to proceed further on this, as you say it might work
> > > > > in accident but I have tested this in A33, A64 and R40 with 4
> > > > > different DSI panels and one DSI-RGB bridge. All of them do use
> > > > > PLL_MIPI (pll_rate) and it indeed depends on bpp/lanes
> > > > >
> > > > > 4-lane, 24-bit: Novatek NT35596 panel
> > > > > 4-lane, 24-bit: Feiyang, FY07024di26a30d panel
> > > > > 4-lane, 24-bit: Bananapi-s070wv20 panel
> > > > > 2-lane, 24-bit: Techstar,ts8550b panel
> > > > >
> > > > > and
> > > > >
> > > > > 4-lane, 24-bit, ICN6211 DSI-to-RGB bridge panel
> > > > >
> > > > > All above listed panels and bridges are working as per BSP and do
> > > > > follow bpp/lanes and for DIVIDER 4 no panel is working.
> > > >
> > > > Look. I'm not saying that there's no issue, I'm saying that your
> > > > patch, applied to the clock you're applying it to, doesn't make sense
> > > > and isn't what the BSP does.
> > >
> > > tcon-pixel clock is the rate that you want to achive on display side
> > > and if you have 4 lanes 32bit or lanes and different bit number that
> > > you need to have a clock that is able to put outside bits and speed
> > > equal to pixel-clock * bits / lanes. so If you want a pixel-clock of
> > > 40 mhz and you have 32bits and 4 lanes you need to have a clock of
> > > 40 * 32 / 4 in no-burst mode. I think that this is done but most of
> > > the display.
> >
> > So this is what the issue is then?
> >
> > This one does make sense, and you should just change the rate in the
> > call to clk_set_rate in sun4i_tcon0_mode_set_cpu.
> >
> > I'm still wondering why that hasn't been brought up in either the
> > discussion or the commit log before though.
> >
> Something like this?
>
> drivers/gpu/drm/sun4i/sun4i_tcon.c | 20 +++++++++++---------
> drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h | 2 --
> 2 files changed, 11 insertions(+), 11 deletions(-)
>
> diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c
> b/drivers/gpu/drm/sun4i/sun4i_tcon.c
> index 64c43ee6bd92..42560d5c327c 100644
> --- a/drivers/gpu/drm/sun4i/sun4i_tcon.c
> +++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c
> @@ -263,10 +263,11 @@ static int sun4i_tcon_get_clk_delay(const struct
> drm_display_mode *mode,
> }
>
> static void sun4i_tcon0_mode_set_common(struct sun4i_tcon *tcon,
> - const struct drm_display_mode *mode)
> + const struct drm_display_mode *mode,
> + u32 tcon_mul)
> {
> /* Configure the dot clock */
> - clk_set_rate(tcon->dclk, mode->crtc_clock * 1000);
> + clk_set_rate(tcon->dclk, mode->crtc_clock * tcon_mul * 1000);
>
> /* Set the resolution */
> regmap_write(tcon->regs, SUN4I_TCON0_BASIC0_REG,
> @@ -335,12 +336,13 @@ static void sun4i_tcon0_mode_set_cpu(struct
> sun4i_tcon *tcon,
> u8 bpp = mipi_dsi_pixel_format_to_bpp(device->format);
> u8 lanes = device->lanes;
> u32 block_space, start_delay;
> - u32 tcon_div;
> + u32 tcon_div, tcon_mul;
>
> - tcon->dclk_min_div = SUN6I_DSI_TCON_DIV;
> - tcon->dclk_max_div = SUN6I_DSI_TCON_DIV;
> + tcon->dclk_min_div = 4;
> + tcon->dclk_max_div = 127;
>
> - sun4i_tcon0_mode_set_common(tcon, mode);
> + tcon_mul = bpp / lanes;
> + sun4i_tcon0_mode_set_common(tcon, mode, tcon_mul);
>
Maybe wrong clock ;) but is this your idea?
Michael
> /* Set dithering if needed */
> sun4i_tcon0_mode_set_dithering(tcon, sun4i_tcon_get_connector(encoder));
> @@ -366,7 +368,7 @@ static void sun4i_tcon0_mode_set_cpu(struct
> sun4i_tcon *tcon,
> */
> regmap_read(tcon->regs, SUN4I_TCON0_DCLK_REG, &tcon_div);
> tcon_div &= GENMASK(6, 0);
> - block_space = mode->htotal * bpp / (tcon_div * lanes);
> + block_space = mode->htotal * tcon_div * tcon_mul;
> block_space -= mode->hdisplay + 40;
>
> regmap_write(tcon->regs, SUN4I_TCON0_CPU_TRI0_REG,
> @@ -408,7 +410,7 @@ static void sun4i_tcon0_mode_set_lvds(struct
> sun4i_tcon *tcon,
>
> tcon->dclk_min_div = 7;
> tcon->dclk_max_div = 7;
> - sun4i_tcon0_mode_set_common(tcon, mode);
> + sun4i_tcon0_mode_set_common(tcon, mode, 1);
>
> /* Set dithering if needed */
> sun4i_tcon0_mode_set_dithering(tcon, sun4i_tcon_get_connector(encoder));
> @@ -487,7 +489,7 @@ static void sun4i_tcon0_mode_set_rgb(struct
> sun4i_tcon *tcon,
>
> tcon->dclk_min_div = 6;
> tcon->dclk_max_div = 127;
> - sun4i_tcon0_mode_set_common(tcon, mode);
> + sun4i_tcon0_mode_set_common(tcon, mode, 1);
>
> /* Set dithering if needed */
> sun4i_tcon0_mode_set_dithering(tcon, connector);
> diff --git a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h
> b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h
> index 5c3ad5be0690..a07090579f84 100644
> --- a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h
> +++ b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h
> @@ -13,8 +13,6 @@
> #include <drm/drm_encoder.h>
> #include <drm/drm_mipi_dsi.h>
>
> -#define SUN6I_DSI_TCON_DIV 4
> -
> struct sun6i_dsi {
> struct drm_connector connector;
> struct drm_encoder encoder;
>
>
> > > Now in burst mode I don't know how should work the calculation of
> > > the clock for the require bandwidth and even I understand your
> > > comment I would like to have your clock tree after you boot on the
> > > display side and if it is possible I want to assemble a kit like you
> > > have.
> >
> > The setup is probably going to be a bit difficult to reproduce, it's a
> > prototype that I have that can't really be found anywhere. Jagan asked
> > me on IRC for the reference, and he found the part, but it's unclear
> > to me if it can be easily adapted to a common board.
> >
> > However, I'm not even sure we need this. I'll test the next version
> > and let you know if it works.
> >
> > Maxime
> >
> > --
> > Maxime Ripard, Bootlin
> > Embedded Linux and Kernel engineering
> > https://bootlin.com
>
>
>
> --
> | Michael Nazzareno Trimarchi Amarula Solutions BV |
> | COO - Founder Cruquiuskade 47 |
> | +31(0)851119172 Amsterdam 1018 AM NL |
> | [`as] http://www.amarulasolutions.com |
--
| Michael Nazzareno Trimarchi Amarula Solutions BV |
| COO - Founder Cruquiuskade 47 |
| +31(0)851119172 Amsterdam 1018 AM NL |
| [`as] http://www.amarulasolutions.com |
On Thu, Jul 11, 2019 at 07:43:16PM +0200, Michael Nazzareno Trimarchi wrote:
> > > tcon-pixel clock is the rate that you want to achive on display side
> > > and if you have 4 lanes 32bit or lanes and different bit number that
> > > you need to have a clock that is able to put outside bits and speed
> > > equal to pixel-clock * bits / lanes. so If you want a pixel-clock of
> > > 40 mhz and you have 32bits and 4 lanes you need to have a clock of
> > > 40 * 32 / 4 in no-burst mode. I think that this is done but most of
> > > the display.
> >
> > So this is what the issue is then?
> >
> > This one does make sense, and you should just change the rate in the
> > call to clk_set_rate in sun4i_tcon0_mode_set_cpu.
> >
> > I'm still wondering why that hasn't been brought up in either the
> > discussion or the commit log before though.
> >
> Something like this?
>
> drivers/gpu/drm/sun4i/sun4i_tcon.c | 20 +++++++++++---------
> drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h | 2 --
> 2 files changed, 11 insertions(+), 11 deletions(-)
>
> diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c
> b/drivers/gpu/drm/sun4i/sun4i_tcon.c
> index 64c43ee6bd92..42560d5c327c 100644
> --- a/drivers/gpu/drm/sun4i/sun4i_tcon.c
> +++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c
> @@ -263,10 +263,11 @@ static int sun4i_tcon_get_clk_delay(const struct
> drm_display_mode *mode,
> }
>
> static void sun4i_tcon0_mode_set_common(struct sun4i_tcon *tcon,
> - const struct drm_display_mode *mode)
> + const struct drm_display_mode *mode,
> + u32 tcon_mul)
> {
> /* Configure the dot clock */
> - clk_set_rate(tcon->dclk, mode->crtc_clock * 1000);
> + clk_set_rate(tcon->dclk, mode->crtc_clock * tcon_mul * 1000);
>
> /* Set the resolution */
> regmap_write(tcon->regs, SUN4I_TCON0_BASIC0_REG,
> @@ -335,12 +336,13 @@ static void sun4i_tcon0_mode_set_cpu(struct
> sun4i_tcon *tcon,
> u8 bpp = mipi_dsi_pixel_format_to_bpp(device->format);
> u8 lanes = device->lanes;
> u32 block_space, start_delay;
> - u32 tcon_div;
> + u32 tcon_div, tcon_mul;
>
> - tcon->dclk_min_div = SUN6I_DSI_TCON_DIV;
> - tcon->dclk_max_div = SUN6I_DSI_TCON_DIV;
> + tcon->dclk_min_div = 4;
> + tcon->dclk_max_div = 127;
>
> - sun4i_tcon0_mode_set_common(tcon, mode);
> + tcon_mul = bpp / lanes;
> + sun4i_tcon0_mode_set_common(tcon, mode, tcon_mul);
>
> /* Set dithering if needed */
> sun4i_tcon0_mode_set_dithering(tcon, sun4i_tcon_get_connector(encoder));
> @@ -366,7 +368,7 @@ static void sun4i_tcon0_mode_set_cpu(struct
> sun4i_tcon *tcon,
> */
> regmap_read(tcon->regs, SUN4I_TCON0_DCLK_REG, &tcon_div);
> tcon_div &= GENMASK(6, 0);
> - block_space = mode->htotal * bpp / (tcon_div * lanes);
> + block_space = mode->htotal * tcon_div * tcon_mul;
> block_space -= mode->hdisplay + 40;
>
> regmap_write(tcon->regs, SUN4I_TCON0_CPU_TRI0_REG,
> @@ -408,7 +410,7 @@ static void sun4i_tcon0_mode_set_lvds(struct
> sun4i_tcon *tcon,
>
> tcon->dclk_min_div = 7;
> tcon->dclk_max_div = 7;
> - sun4i_tcon0_mode_set_common(tcon, mode);
> + sun4i_tcon0_mode_set_common(tcon, mode, 1);
>
> /* Set dithering if needed */
> sun4i_tcon0_mode_set_dithering(tcon, sun4i_tcon_get_connector(encoder));
> @@ -487,7 +489,7 @@ static void sun4i_tcon0_mode_set_rgb(struct
> sun4i_tcon *tcon,
>
> tcon->dclk_min_div = 6;
> tcon->dclk_max_div = 127;
> - sun4i_tcon0_mode_set_common(tcon, mode);
> + sun4i_tcon0_mode_set_common(tcon, mode, 1);
>
> /* Set dithering if needed */
> sun4i_tcon0_mode_set_dithering(tcon, connector);
> diff --git a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h
> b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h
> index 5c3ad5be0690..a07090579f84 100644
> --- a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h
> +++ b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h
> @@ -13,8 +13,6 @@
> #include <drm/drm_encoder.h>
> #include <drm/drm_mipi_dsi.h>
>
> -#define SUN6I_DSI_TCON_DIV 4
> -
> struct sun6i_dsi {
> struct drm_connector connector;
> struct drm_encoder encoder;
I had more something like this in mind:
http://code.bulix.org/nlp5a4-803511
You really don't need to change the divider range (or this is another
issue that the one you mentionned).
Maxime
--
Maxime Ripard, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
On Sat, Jul 20, 2019 at 12:28 PM Maxime Ripard
<[email protected]> wrote:
>
> On Thu, Jul 11, 2019 at 07:43:16PM +0200, Michael Nazzareno Trimarchi wrote:
> > > > tcon-pixel clock is the rate that you want to achive on display side
> > > > and if you have 4 lanes 32bit or lanes and different bit number that
> > > > you need to have a clock that is able to put outside bits and speed
> > > > equal to pixel-clock * bits / lanes. so If you want a pixel-clock of
> > > > 40 mhz and you have 32bits and 4 lanes you need to have a clock of
> > > > 40 * 32 / 4 in no-burst mode. I think that this is done but most of
> > > > the display.
> > >
> > > So this is what the issue is then?
> > >
> > > This one does make sense, and you should just change the rate in the
> > > call to clk_set_rate in sun4i_tcon0_mode_set_cpu.
> > >
> > > I'm still wondering why that hasn't been brought up in either the
> > > discussion or the commit log before though.
> > >
> > Something like this?
> >
> > drivers/gpu/drm/sun4i/sun4i_tcon.c | 20 +++++++++++---------
> > drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h | 2 --
> > 2 files changed, 11 insertions(+), 11 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c
> > b/drivers/gpu/drm/sun4i/sun4i_tcon.c
> > index 64c43ee6bd92..42560d5c327c 100644
> > --- a/drivers/gpu/drm/sun4i/sun4i_tcon.c
> > +++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c
> > @@ -263,10 +263,11 @@ static int sun4i_tcon_get_clk_delay(const struct
> > drm_display_mode *mode,
> > }
> >
> > static void sun4i_tcon0_mode_set_common(struct sun4i_tcon *tcon,
> > - const struct drm_display_mode *mode)
> > + const struct drm_display_mode *mode,
> > + u32 tcon_mul)
> > {
> > /* Configure the dot clock */
> > - clk_set_rate(tcon->dclk, mode->crtc_clock * 1000);
> > + clk_set_rate(tcon->dclk, mode->crtc_clock * tcon_mul * 1000);
> >
> > /* Set the resolution */
> > regmap_write(tcon->regs, SUN4I_TCON0_BASIC0_REG,
> > @@ -335,12 +336,13 @@ static void sun4i_tcon0_mode_set_cpu(struct
> > sun4i_tcon *tcon,
> > u8 bpp = mipi_dsi_pixel_format_to_bpp(device->format);
> > u8 lanes = device->lanes;
> > u32 block_space, start_delay;
> > - u32 tcon_div;
> > + u32 tcon_div, tcon_mul;
> >
> > - tcon->dclk_min_div = SUN6I_DSI_TCON_DIV;
> > - tcon->dclk_max_div = SUN6I_DSI_TCON_DIV;
> > + tcon->dclk_min_div = 4;
> > + tcon->dclk_max_div = 127;
> >
> > - sun4i_tcon0_mode_set_common(tcon, mode);
> > + tcon_mul = bpp / lanes;
> > + sun4i_tcon0_mode_set_common(tcon, mode, tcon_mul);
> >
> > /* Set dithering if needed */
> > sun4i_tcon0_mode_set_dithering(tcon, sun4i_tcon_get_connector(encoder));
> > @@ -366,7 +368,7 @@ static void sun4i_tcon0_mode_set_cpu(struct
> > sun4i_tcon *tcon,
> > */
> > regmap_read(tcon->regs, SUN4I_TCON0_DCLK_REG, &tcon_div);
> > tcon_div &= GENMASK(6, 0);
> > - block_space = mode->htotal * bpp / (tcon_div * lanes);
> > + block_space = mode->htotal * tcon_div * tcon_mul;
> > block_space -= mode->hdisplay + 40;
> >
> > regmap_write(tcon->regs, SUN4I_TCON0_CPU_TRI0_REG,
> > @@ -408,7 +410,7 @@ static void sun4i_tcon0_mode_set_lvds(struct
> > sun4i_tcon *tcon,
> >
> > tcon->dclk_min_div = 7;
> > tcon->dclk_max_div = 7;
> > - sun4i_tcon0_mode_set_common(tcon, mode);
> > + sun4i_tcon0_mode_set_common(tcon, mode, 1);
> >
> > /* Set dithering if needed */
> > sun4i_tcon0_mode_set_dithering(tcon, sun4i_tcon_get_connector(encoder));
> > @@ -487,7 +489,7 @@ static void sun4i_tcon0_mode_set_rgb(struct
> > sun4i_tcon *tcon,
> >
> > tcon->dclk_min_div = 6;
> > tcon->dclk_max_div = 127;
> > - sun4i_tcon0_mode_set_common(tcon, mode);
> > + sun4i_tcon0_mode_set_common(tcon, mode, 1);
> >
> > /* Set dithering if needed */
> > sun4i_tcon0_mode_set_dithering(tcon, connector);
> > diff --git a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h
> > b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h
> > index 5c3ad5be0690..a07090579f84 100644
> > --- a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h
> > +++ b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h
> > @@ -13,8 +13,6 @@
> > #include <drm/drm_encoder.h>
> > #include <drm/drm_mipi_dsi.h>
> >
> > -#define SUN6I_DSI_TCON_DIV 4
> > -
> > struct sun6i_dsi {
> > struct drm_connector connector;
> > struct drm_encoder encoder;
>
> I had more something like this in mind:
> http://code.bulix.org/nlp5a4-803511
Worth to look at it. was it working on your panel? meanwhile I will check it.
We have updated with below change [1], seems working on but is
actually checking the each divider as before start with 4... till 127.
This new approach, is start looking the best divider from 4.. based on
the idea vs rounded it will ended up best divider like [2]
https://gist.github.com/openedev/7e2c33248b372d29be9979e06d483673
https://gist.github.com/openedev/c72dfffc0ca59e7ec1edcd7ad360cdd1
Jagan.
On Sat, Jul 20, 2019 at 12:46 PM Jagan Teki <[email protected]> wrote:
>
> On Sat, Jul 20, 2019 at 12:28 PM Maxime Ripard
> <[email protected]> wrote:
> >
> > On Thu, Jul 11, 2019 at 07:43:16PM +0200, Michael Nazzareno Trimarchi wrote:
> > > > > tcon-pixel clock is the rate that you want to achive on display side
> > > > > and if you have 4 lanes 32bit or lanes and different bit number that
> > > > > you need to have a clock that is able to put outside bits and speed
> > > > > equal to pixel-clock * bits / lanes. so If you want a pixel-clock of
> > > > > 40 mhz and you have 32bits and 4 lanes you need to have a clock of
> > > > > 40 * 32 / 4 in no-burst mode. I think that this is done but most of
> > > > > the display.
> > > >
> > > > So this is what the issue is then?
> > > >
> > > > This one does make sense, and you should just change the rate in the
> > > > call to clk_set_rate in sun4i_tcon0_mode_set_cpu.
> > > >
> > > > I'm still wondering why that hasn't been brought up in either the
> > > > discussion or the commit log before though.
> > > >
> > > Something like this?
> > >
> > > drivers/gpu/drm/sun4i/sun4i_tcon.c | 20 +++++++++++---------
> > > drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h | 2 --
> > > 2 files changed, 11 insertions(+), 11 deletions(-)
> > >
> > > diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c
> > > b/drivers/gpu/drm/sun4i/sun4i_tcon.c
> > > index 64c43ee6bd92..42560d5c327c 100644
> > > --- a/drivers/gpu/drm/sun4i/sun4i_tcon.c
> > > +++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c
> > > @@ -263,10 +263,11 @@ static int sun4i_tcon_get_clk_delay(const struct
> > > drm_display_mode *mode,
> > > }
> > >
> > > static void sun4i_tcon0_mode_set_common(struct sun4i_tcon *tcon,
> > > - const struct drm_display_mode *mode)
> > > + const struct drm_display_mode *mode,
> > > + u32 tcon_mul)
> > > {
> > > /* Configure the dot clock */
> > > - clk_set_rate(tcon->dclk, mode->crtc_clock * 1000);
> > > + clk_set_rate(tcon->dclk, mode->crtc_clock * tcon_mul * 1000);
> > >
> > > /* Set the resolution */
> > > regmap_write(tcon->regs, SUN4I_TCON0_BASIC0_REG,
> > > @@ -335,12 +336,13 @@ static void sun4i_tcon0_mode_set_cpu(struct
> > > sun4i_tcon *tcon,
> > > u8 bpp = mipi_dsi_pixel_format_to_bpp(device->format);
> > > u8 lanes = device->lanes;
> > > u32 block_space, start_delay;
> > > - u32 tcon_div;
> > > + u32 tcon_div, tcon_mul;
> > >
> > > - tcon->dclk_min_div = SUN6I_DSI_TCON_DIV;
> > > - tcon->dclk_max_div = SUN6I_DSI_TCON_DIV;
> > > + tcon->dclk_min_div = 4;
> > > + tcon->dclk_max_div = 127;
> > >
> > > - sun4i_tcon0_mode_set_common(tcon, mode);
> > > + tcon_mul = bpp / lanes;
> > > + sun4i_tcon0_mode_set_common(tcon, mode, tcon_mul);
> > >
> > > /* Set dithering if needed */
> > > sun4i_tcon0_mode_set_dithering(tcon, sun4i_tcon_get_connector(encoder));
> > > @@ -366,7 +368,7 @@ static void sun4i_tcon0_mode_set_cpu(struct
> > > sun4i_tcon *tcon,
> > > */
> > > regmap_read(tcon->regs, SUN4I_TCON0_DCLK_REG, &tcon_div);
> > > tcon_div &= GENMASK(6, 0);
> > > - block_space = mode->htotal * bpp / (tcon_div * lanes);
> > > + block_space = mode->htotal * tcon_div * tcon_mul;
> > > block_space -= mode->hdisplay + 40;
> > >
> > > regmap_write(tcon->regs, SUN4I_TCON0_CPU_TRI0_REG,
> > > @@ -408,7 +410,7 @@ static void sun4i_tcon0_mode_set_lvds(struct
> > > sun4i_tcon *tcon,
> > >
> > > tcon->dclk_min_div = 7;
> > > tcon->dclk_max_div = 7;
> > > - sun4i_tcon0_mode_set_common(tcon, mode);
> > > + sun4i_tcon0_mode_set_common(tcon, mode, 1);
> > >
> > > /* Set dithering if needed */
> > > sun4i_tcon0_mode_set_dithering(tcon, sun4i_tcon_get_connector(encoder));
> > > @@ -487,7 +489,7 @@ static void sun4i_tcon0_mode_set_rgb(struct
> > > sun4i_tcon *tcon,
> > >
> > > tcon->dclk_min_div = 6;
> > > tcon->dclk_max_div = 127;
> > > - sun4i_tcon0_mode_set_common(tcon, mode);
> > > + sun4i_tcon0_mode_set_common(tcon, mode, 1);
> > >
> > > /* Set dithering if needed */
> > > sun4i_tcon0_mode_set_dithering(tcon, connector);
> > > diff --git a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h
> > > b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h
> > > index 5c3ad5be0690..a07090579f84 100644
> > > --- a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h
> > > +++ b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h
> > > @@ -13,8 +13,6 @@
> > > #include <drm/drm_encoder.h>
> > > #include <drm/drm_mipi_dsi.h>
> > >
> > > -#define SUN6I_DSI_TCON_DIV 4
> > > -
> > > struct sun6i_dsi {
> > > struct drm_connector connector;
> > > struct drm_encoder encoder;
> >
> > I had more something like this in mind:
> > http://code.bulix.org/nlp5a4-803511
>
> Worth to look at it. was it working on your panel? meanwhile I will check it.
>
> We have updated with below change [1], seems working on but is
> actually checking the each divider as before start with 4... till 127.
>
> This new approach, is start looking the best divider from 4.. based on
> the idea vs rounded it will ended up best divider like [2]
>
> https://gist.github.com/openedev/7e2c33248b372d29be9979e06d483673
> https://gist.github.com/openedev/c72dfffc0ca59e7ec1edcd7ad360cdd1
I made quick check on two possibilities.
1) with Maxime change
https://gist.github.com/openedev/3b0b3d35ced6d89f5be0831f1cc9d840
https://gist.github.com/openedev/dd6a9e528cde80ef0508cb54723f505d
2) with Maxime change along with min 4, max 127 divider values.
The outcome similar like 1)
This look it will depends on divider, need to check further on this page.
Jagan.
On Sat, Jul 20, 2019 at 12:46:27PM +0530, Jagan Teki wrote:
> On Sat, Jul 20, 2019 at 12:28 PM Maxime Ripard
> <[email protected]> wrote:
> >
> > On Thu, Jul 11, 2019 at 07:43:16PM +0200, Michael Nazzareno Trimarchi wrote:
> > > > > tcon-pixel clock is the rate that you want to achive on display side
> > > > > and if you have 4 lanes 32bit or lanes and different bit number that
> > > > > you need to have a clock that is able to put outside bits and speed
> > > > > equal to pixel-clock * bits / lanes. so If you want a pixel-clock of
> > > > > 40 mhz and you have 32bits and 4 lanes you need to have a clock of
> > > > > 40 * 32 / 4 in no-burst mode. I think that this is done but most of
> > > > > the display.
> > > >
> > > > So this is what the issue is then?
> > > >
> > > > This one does make sense, and you should just change the rate in the
> > > > call to clk_set_rate in sun4i_tcon0_mode_set_cpu.
> > > >
> > > > I'm still wondering why that hasn't been brought up in either the
> > > > discussion or the commit log before though.
> > > >
> > > Something like this?
> > >
> > > drivers/gpu/drm/sun4i/sun4i_tcon.c | 20 +++++++++++---------
> > > drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h | 2 --
> > > 2 files changed, 11 insertions(+), 11 deletions(-)
> > >
> > > diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c
> > > b/drivers/gpu/drm/sun4i/sun4i_tcon.c
> > > index 64c43ee6bd92..42560d5c327c 100644
> > > --- a/drivers/gpu/drm/sun4i/sun4i_tcon.c
> > > +++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c
> > > @@ -263,10 +263,11 @@ static int sun4i_tcon_get_clk_delay(const struct
> > > drm_display_mode *mode,
> > > }
> > >
> > > static void sun4i_tcon0_mode_set_common(struct sun4i_tcon *tcon,
> > > - const struct drm_display_mode *mode)
> > > + const struct drm_display_mode *mode,
> > > + u32 tcon_mul)
> > > {
> > > /* Configure the dot clock */
> > > - clk_set_rate(tcon->dclk, mode->crtc_clock * 1000);
> > > + clk_set_rate(tcon->dclk, mode->crtc_clock * tcon_mul * 1000);
> > >
> > > /* Set the resolution */
> > > regmap_write(tcon->regs, SUN4I_TCON0_BASIC0_REG,
> > > @@ -335,12 +336,13 @@ static void sun4i_tcon0_mode_set_cpu(struct
> > > sun4i_tcon *tcon,
> > > u8 bpp = mipi_dsi_pixel_format_to_bpp(device->format);
> > > u8 lanes = device->lanes;
> > > u32 block_space, start_delay;
> > > - u32 tcon_div;
> > > + u32 tcon_div, tcon_mul;
> > >
> > > - tcon->dclk_min_div = SUN6I_DSI_TCON_DIV;
> > > - tcon->dclk_max_div = SUN6I_DSI_TCON_DIV;
> > > + tcon->dclk_min_div = 4;
> > > + tcon->dclk_max_div = 127;
> > >
> > > - sun4i_tcon0_mode_set_common(tcon, mode);
> > > + tcon_mul = bpp / lanes;
> > > + sun4i_tcon0_mode_set_common(tcon, mode, tcon_mul);
> > >
> > > /* Set dithering if needed */
> > > sun4i_tcon0_mode_set_dithering(tcon, sun4i_tcon_get_connector(encoder));
> > > @@ -366,7 +368,7 @@ static void sun4i_tcon0_mode_set_cpu(struct
> > > sun4i_tcon *tcon,
> > > */
> > > regmap_read(tcon->regs, SUN4I_TCON0_DCLK_REG, &tcon_div);
> > > tcon_div &= GENMASK(6, 0);
> > > - block_space = mode->htotal * bpp / (tcon_div * lanes);
> > > + block_space = mode->htotal * tcon_div * tcon_mul;
> > > block_space -= mode->hdisplay + 40;
> > >
> > > regmap_write(tcon->regs, SUN4I_TCON0_CPU_TRI0_REG,
> > > @@ -408,7 +410,7 @@ static void sun4i_tcon0_mode_set_lvds(struct
> > > sun4i_tcon *tcon,
> > >
> > > tcon->dclk_min_div = 7;
> > > tcon->dclk_max_div = 7;
> > > - sun4i_tcon0_mode_set_common(tcon, mode);
> > > + sun4i_tcon0_mode_set_common(tcon, mode, 1);
> > >
> > > /* Set dithering if needed */
> > > sun4i_tcon0_mode_set_dithering(tcon, sun4i_tcon_get_connector(encoder));
> > > @@ -487,7 +489,7 @@ static void sun4i_tcon0_mode_set_rgb(struct
> > > sun4i_tcon *tcon,
> > >
> > > tcon->dclk_min_div = 6;
> > > tcon->dclk_max_div = 127;
> > > - sun4i_tcon0_mode_set_common(tcon, mode);
> > > + sun4i_tcon0_mode_set_common(tcon, mode, 1);
> > >
> > > /* Set dithering if needed */
> > > sun4i_tcon0_mode_set_dithering(tcon, connector);
> > > diff --git a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h
> > > b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h
> > > index 5c3ad5be0690..a07090579f84 100644
> > > --- a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h
> > > +++ b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h
> > > @@ -13,8 +13,6 @@
> > > #include <drm/drm_encoder.h>
> > > #include <drm/drm_mipi_dsi.h>
> > >
> > > -#define SUN6I_DSI_TCON_DIV 4
> > > -
> > > struct sun6i_dsi {
> > > struct drm_connector connector;
> > > struct drm_encoder encoder;
> >
> > I had more something like this in mind:
> > http://code.bulix.org/nlp5a4-803511
>
> Worth to look at it. was it working on your panel? meanwhile I will check it.
I haven't tested it.
> We have updated with below change [1], seems working on but is
> actually checking the each divider as before start with 4... till 127.
>
> This new approach, is start looking the best divider from 4.. based on
> the idea vs rounded it will ended up best divider like [2]
But why?
I mean, it's not like it's the first time I'm asking this...
If the issue is what Micheal described, then the divider has nothing
to do with it. We've had that discussion over and over again.
So you need to come with some argument and proof that the divider of
that clock need to change. Otherwise, stop trying to make that happen:
it won't.
Maxime
--
Maxime Ripard, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
Hi
On Sat, Jul 20, 2019 at 11:32 AM Maxime Ripard
<[email protected]> wrote:
>
> On Sat, Jul 20, 2019 at 12:46:27PM +0530, Jagan Teki wrote:
> > On Sat, Jul 20, 2019 at 12:28 PM Maxime Ripard
> > <[email protected]> wrote:
> > >
> > > On Thu, Jul 11, 2019 at 07:43:16PM +0200, Michael Nazzareno Trimarchi wrote:
> > > > > > tcon-pixel clock is the rate that you want to achive on display side
> > > > > > and if you have 4 lanes 32bit or lanes and different bit number that
> > > > > > you need to have a clock that is able to put outside bits and speed
> > > > > > equal to pixel-clock * bits / lanes. so If you want a pixel-clock of
> > > > > > 40 mhz and you have 32bits and 4 lanes you need to have a clock of
> > > > > > 40 * 32 / 4 in no-burst mode. I think that this is done but most of
> > > > > > the display.
> > > > >
> > > > > So this is what the issue is then?
> > > > >
> > > > > This one does make sense, and you should just change the rate in the
> > > > > call to clk_set_rate in sun4i_tcon0_mode_set_cpu.
> > > > >
> > > > > I'm still wondering why that hasn't been brought up in either the
> > > > > discussion or the commit log before though.
> > > > >
> > > > Something like this?
> > > >
> > > > drivers/gpu/drm/sun4i/sun4i_tcon.c | 20 +++++++++++---------
> > > > drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h | 2 --
> > > > 2 files changed, 11 insertions(+), 11 deletions(-)
> > > >
> > > > diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c
> > > > b/drivers/gpu/drm/sun4i/sun4i_tcon.c
> > > > index 64c43ee6bd92..42560d5c327c 100644
> > > > --- a/drivers/gpu/drm/sun4i/sun4i_tcon.c
> > > > +++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c
> > > > @@ -263,10 +263,11 @@ static int sun4i_tcon_get_clk_delay(const struct
> > > > drm_display_mode *mode,
> > > > }
> > > >
> > > > static void sun4i_tcon0_mode_set_common(struct sun4i_tcon *tcon,
> > > > - const struct drm_display_mode *mode)
> > > > + const struct drm_display_mode *mode,
> > > > + u32 tcon_mul)
> > > > {
> > > > /* Configure the dot clock */
> > > > - clk_set_rate(tcon->dclk, mode->crtc_clock * 1000);
> > > > + clk_set_rate(tcon->dclk, mode->crtc_clock * tcon_mul * 1000);
> > > >
> > > > /* Set the resolution */
> > > > regmap_write(tcon->regs, SUN4I_TCON0_BASIC0_REG,
> > > > @@ -335,12 +336,13 @@ static void sun4i_tcon0_mode_set_cpu(struct
> > > > sun4i_tcon *tcon,
> > > > u8 bpp = mipi_dsi_pixel_format_to_bpp(device->format);
> > > > u8 lanes = device->lanes;
> > > > u32 block_space, start_delay;
> > > > - u32 tcon_div;
> > > > + u32 tcon_div, tcon_mul;
> > > >
> > > > - tcon->dclk_min_div = SUN6I_DSI_TCON_DIV;
> > > > - tcon->dclk_max_div = SUN6I_DSI_TCON_DIV;
> > > > + tcon->dclk_min_div = 4;
> > > > + tcon->dclk_max_div = 127;
> > > >
> > > > - sun4i_tcon0_mode_set_common(tcon, mode);
> > > > + tcon_mul = bpp / lanes;
> > > > + sun4i_tcon0_mode_set_common(tcon, mode, tcon_mul);
> > > >
> > > > /* Set dithering if needed */
> > > > sun4i_tcon0_mode_set_dithering(tcon, sun4i_tcon_get_connector(encoder));
> > > > @@ -366,7 +368,7 @@ static void sun4i_tcon0_mode_set_cpu(struct
> > > > sun4i_tcon *tcon,
> > > > */
> > > > regmap_read(tcon->regs, SUN4I_TCON0_DCLK_REG, &tcon_div);
> > > > tcon_div &= GENMASK(6, 0);
> > > > - block_space = mode->htotal * bpp / (tcon_div * lanes);
> > > > + block_space = mode->htotal * tcon_div * tcon_mul;
> > > > block_space -= mode->hdisplay + 40;
> > > >
> > > > regmap_write(tcon->regs, SUN4I_TCON0_CPU_TRI0_REG,
> > > > @@ -408,7 +410,7 @@ static void sun4i_tcon0_mode_set_lvds(struct
> > > > sun4i_tcon *tcon,
> > > >
> > > > tcon->dclk_min_div = 7;
> > > > tcon->dclk_max_div = 7;
> > > > - sun4i_tcon0_mode_set_common(tcon, mode);
> > > > + sun4i_tcon0_mode_set_common(tcon, mode, 1);
> > > >
> > > > /* Set dithering if needed */
> > > > sun4i_tcon0_mode_set_dithering(tcon, sun4i_tcon_get_connector(encoder));
> > > > @@ -487,7 +489,7 @@ static void sun4i_tcon0_mode_set_rgb(struct
> > > > sun4i_tcon *tcon,
> > > >
> > > > tcon->dclk_min_div = 6;
> > > > tcon->dclk_max_div = 127;
> > > > - sun4i_tcon0_mode_set_common(tcon, mode);
> > > > + sun4i_tcon0_mode_set_common(tcon, mode, 1);
> > > >
> > > > /* Set dithering if needed */
> > > > sun4i_tcon0_mode_set_dithering(tcon, connector);
> > > > diff --git a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h
> > > > b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h
> > > > index 5c3ad5be0690..a07090579f84 100644
> > > > --- a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h
> > > > +++ b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h
> > > > @@ -13,8 +13,6 @@
> > > > #include <drm/drm_encoder.h>
> > > > #include <drm/drm_mipi_dsi.h>
> > > >
> > > > -#define SUN6I_DSI_TCON_DIV 4
> > > > -
> > > > struct sun6i_dsi {
> > > > struct drm_connector connector;
> > > > struct drm_encoder encoder;
> > >
> > > I had more something like this in mind:
> > > http://code.bulix.org/nlp5a4-803511
> >
> > Worth to look at it. was it working on your panel? meanwhile I will check it.
>
> I haven't tested it.
>
> > We have updated with below change [1], seems working on but is
> > actually checking the each divider as before start with 4... till 127.
> >
> > This new approach, is start looking the best divider from 4.. based on
> > the idea vs rounded it will ended up best divider like [2]
>
> But why?
>
> I mean, it's not like it's the first time I'm asking this...
>
> If the issue is what Micheal described, then the divider has nothing
> to do with it. We've had that discussion over and over again.
>
Sorry to quick copy and paste but my idea is somenthing like:
---
drivers/gpu/drm/sun4i/sun4i_dotclock.c | 5 ++++-
drivers/gpu/drm/sun4i/sun4i_tcon.c | 9 ++++++---
drivers/gpu/drm/sun4i/sun4i_tcon.h | 1 +
drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h | 2 --
4 files changed, 11 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/drm/sun4i/sun4i_dotclock.c
b/drivers/gpu/drm/sun4i/sun4i_dotclock.c
index 417ade3d2565..b8be67cbb037 100644
--- a/drivers/gpu/drm/sun4i/sun4i_dotclock.c
+++ b/drivers/gpu/drm/sun4i/sun4i_dotclock.c
@@ -74,12 +74,15 @@ static long sun4i_dclk_round_rate(struct clk_hw
*hw, unsigned long rate,
struct sun4i_tcon *tcon = dclk->tcon;
unsigned long best_parent = 0;
u8 best_div = 1;
+ u64 ideal = (u64)rate * tcon->dclk_mul;
int i;
for (i = tcon->dclk_min_div; i <= tcon->dclk_max_div; i++) {
- u64 ideal = (u64)rate * i;
unsigned long rounded;
+ if (!tcon->dclk_mul)
+ ideal = (u64)rate * i;
+
/*
* ideal has overflowed the max value that can be stored in an
* unsigned long, and every clk operation we might do on a
diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c
b/drivers/gpu/drm/sun4i/sun4i_tcon.c
index 64c43ee6bd92..3301952bcf32 100644
--- a/drivers/gpu/drm/sun4i/sun4i_tcon.c
+++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c
@@ -337,8 +337,9 @@ static void sun4i_tcon0_mode_set_cpu(struct
sun4i_tcon *tcon,
u32 block_space, start_delay;
u32 tcon_div;
- tcon->dclk_min_div = SUN6I_DSI_TCON_DIV;
- tcon->dclk_max_div = SUN6I_DSI_TCON_DIV;
+ tcon->dclk_min_div = 4;
+ tcon->dclk_max_div = 127;
+ tcon->dclk_mul = bpp / lanes;
sun4i_tcon0_mode_set_common(tcon, mode);
@@ -366,7 +367,7 @@ static void sun4i_tcon0_mode_set_cpu(struct
sun4i_tcon *tcon,
*/
regmap_read(tcon->regs, SUN4I_TCON0_DCLK_REG, &tcon_div);
tcon_div &= GENMASK(6, 0);
- block_space = mode->htotal * bpp / (tcon_div * lanes);
+ block_space = mode->htotal * tcon_div * tcon->dclk_mul;
block_space -= mode->hdisplay + 40;
regmap_write(tcon->regs, SUN4I_TCON0_CPU_TRI0_REG,
@@ -408,6 +409,7 @@ static void sun4i_tcon0_mode_set_lvds(struct
sun4i_tcon *tcon,
tcon->dclk_min_div = 7;
tcon->dclk_max_div = 7;
+ tcon->dclk_mul = 0;
sun4i_tcon0_mode_set_common(tcon, mode);
/* Set dithering if needed */
@@ -487,6 +489,7 @@ static void sun4i_tcon0_mode_set_rgb(struct
sun4i_tcon *tcon,
tcon->dclk_min_div = 6;
tcon->dclk_max_div = 127;
+ tcon->dclk_mul = 0;
sun4i_tcon0_mode_set_common(tcon, mode);
/* Set dithering if needed */
diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.h
b/drivers/gpu/drm/sun4i/sun4i_tcon.h
index f9f1fe80b206..44b69533778e 100644
--- a/drivers/gpu/drm/sun4i/sun4i_tcon.h
+++ b/drivers/gpu/drm/sun4i/sun4i_tcon.h
@@ -248,6 +248,7 @@ struct sun4i_tcon {
struct clk *dclk;
u8 dclk_max_div;
u8 dclk_min_div;
+ u8 dclk_mul;
/* Reset control */
struct reset_control *lcd_rst;
diff --git a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h
b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h
index 5c3ad5be0690..a07090579f84 100644
--- a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h
+++ b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h
@@ -13,8 +13,6 @@
#include <drm/drm_encoder.h>
#include <drm/drm_mipi_dsi.h>
-#define SUN6I_DSI_TCON_DIV 4
-
struct sun6i_dsi {
struct drm_connector connector;
struct drm_encoder encoder;
--
2.17.1
Michael
> So you need to come with some argument and proof that the divider of
> that clock need to change. Otherwise, stop trying to make that happen:
> it won't.
>
> Maxime
>
> --
> Maxime Ripard, Bootlin
> Embedded Linux and Kernel engineering
> https://bootlin.com
--
| Michael Nazzareno Trimarchi Amarula Solutions BV |
| COO - Founder Cruquiuskade 47 |
| +31(0)851119172 Amsterdam 1018 AM NL |
| [`as] http://www.amarulasolutions.com |
Hi Maxime,
On Sat, Jul 20, 2019 at 3:02 PM Maxime Ripard <[email protected]> wrote:
>
> On Sat, Jul 20, 2019 at 12:46:27PM +0530, Jagan Teki wrote:
> > On Sat, Jul 20, 2019 at 12:28 PM Maxime Ripard
> > <[email protected]> wrote:
> > >
> > > On Thu, Jul 11, 2019 at 07:43:16PM +0200, Michael Nazzareno Trimarchi wrote:
> > > > > > tcon-pixel clock is the rate that you want to achive on display side
> > > > > > and if you have 4 lanes 32bit or lanes and different bit number that
> > > > > > you need to have a clock that is able to put outside bits and speed
> > > > > > equal to pixel-clock * bits / lanes. so If you want a pixel-clock of
> > > > > > 40 mhz and you have 32bits and 4 lanes you need to have a clock of
> > > > > > 40 * 32 / 4 in no-burst mode. I think that this is done but most of
> > > > > > the display.
> > > > >
> > > > > So this is what the issue is then?
> > > > >
> > > > > This one does make sense, and you should just change the rate in the
> > > > > call to clk_set_rate in sun4i_tcon0_mode_set_cpu.
> > > > >
> > > > > I'm still wondering why that hasn't been brought up in either the
> > > > > discussion or the commit log before though.
> > > > >
> > > > Something like this?
> > > >
> > > > drivers/gpu/drm/sun4i/sun4i_tcon.c | 20 +++++++++++---------
> > > > drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h | 2 --
> > > > 2 files changed, 11 insertions(+), 11 deletions(-)
> > > >
> > > > diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c
> > > > b/drivers/gpu/drm/sun4i/sun4i_tcon.c
> > > > index 64c43ee6bd92..42560d5c327c 100644
> > > > --- a/drivers/gpu/drm/sun4i/sun4i_tcon.c
> > > > +++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c
> > > > @@ -263,10 +263,11 @@ static int sun4i_tcon_get_clk_delay(const struct
> > > > drm_display_mode *mode,
> > > > }
> > > >
> > > > static void sun4i_tcon0_mode_set_common(struct sun4i_tcon *tcon,
> > > > - const struct drm_display_mode *mode)
> > > > + const struct drm_display_mode *mode,
> > > > + u32 tcon_mul)
> > > > {
> > > > /* Configure the dot clock */
> > > > - clk_set_rate(tcon->dclk, mode->crtc_clock * 1000);
> > > > + clk_set_rate(tcon->dclk, mode->crtc_clock * tcon_mul * 1000);
> > > >
> > > > /* Set the resolution */
> > > > regmap_write(tcon->regs, SUN4I_TCON0_BASIC0_REG,
> > > > @@ -335,12 +336,13 @@ static void sun4i_tcon0_mode_set_cpu(struct
> > > > sun4i_tcon *tcon,
> > > > u8 bpp = mipi_dsi_pixel_format_to_bpp(device->format);
> > > > u8 lanes = device->lanes;
> > > > u32 block_space, start_delay;
> > > > - u32 tcon_div;
> > > > + u32 tcon_div, tcon_mul;
> > > >
> > > > - tcon->dclk_min_div = SUN6I_DSI_TCON_DIV;
> > > > - tcon->dclk_max_div = SUN6I_DSI_TCON_DIV;
> > > > + tcon->dclk_min_div = 4;
> > > > + tcon->dclk_max_div = 127;
> > > >
> > > > - sun4i_tcon0_mode_set_common(tcon, mode);
> > > > + tcon_mul = bpp / lanes;
> > > > + sun4i_tcon0_mode_set_common(tcon, mode, tcon_mul);
> > > >
> > > > /* Set dithering if needed */
> > > > sun4i_tcon0_mode_set_dithering(tcon, sun4i_tcon_get_connector(encoder));
> > > > @@ -366,7 +368,7 @@ static void sun4i_tcon0_mode_set_cpu(struct
> > > > sun4i_tcon *tcon,
> > > > */
> > > > regmap_read(tcon->regs, SUN4I_TCON0_DCLK_REG, &tcon_div);
> > > > tcon_div &= GENMASK(6, 0);
> > > > - block_space = mode->htotal * bpp / (tcon_div * lanes);
> > > > + block_space = mode->htotal * tcon_div * tcon_mul;
> > > > block_space -= mode->hdisplay + 40;
> > > >
> > > > regmap_write(tcon->regs, SUN4I_TCON0_CPU_TRI0_REG,
> > > > @@ -408,7 +410,7 @@ static void sun4i_tcon0_mode_set_lvds(struct
> > > > sun4i_tcon *tcon,
> > > >
> > > > tcon->dclk_min_div = 7;
> > > > tcon->dclk_max_div = 7;
> > > > - sun4i_tcon0_mode_set_common(tcon, mode);
> > > > + sun4i_tcon0_mode_set_common(tcon, mode, 1);
> > > >
> > > > /* Set dithering if needed */
> > > > sun4i_tcon0_mode_set_dithering(tcon, sun4i_tcon_get_connector(encoder));
> > > > @@ -487,7 +489,7 @@ static void sun4i_tcon0_mode_set_rgb(struct
> > > > sun4i_tcon *tcon,
> > > >
> > > > tcon->dclk_min_div = 6;
> > > > tcon->dclk_max_div = 127;
> > > > - sun4i_tcon0_mode_set_common(tcon, mode);
> > > > + sun4i_tcon0_mode_set_common(tcon, mode, 1);
> > > >
> > > > /* Set dithering if needed */
> > > > sun4i_tcon0_mode_set_dithering(tcon, connector);
> > > > diff --git a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h
> > > > b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h
> > > > index 5c3ad5be0690..a07090579f84 100644
> > > > --- a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h
> > > > +++ b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h
> > > > @@ -13,8 +13,6 @@
> > > > #include <drm/drm_encoder.h>
> > > > #include <drm/drm_mipi_dsi.h>
> > > >
> > > > -#define SUN6I_DSI_TCON_DIV 4
> > > > -
> > > > struct sun6i_dsi {
> > > > struct drm_connector connector;
> > > > struct drm_encoder encoder;
> > >
> > > I had more something like this in mind:
> > > http://code.bulix.org/nlp5a4-803511
> >
> > Worth to look at it. was it working on your panel? meanwhile I will check it.
>
> I haven't tested it.
>
> > We have updated with below change [1], seems working on but is
> > actually checking the each divider as before start with 4... till 127.
> >
> > This new approach, is start looking the best divider from 4.. based on
> > the idea vs rounded it will ended up best divider like [2]
>
> But why?
>
> I mean, it's not like it's the first time I'm asking this...
>
> If the issue is what Micheal described, then the divider has nothing
> to do with it. We've had that discussion over and over again.
This is what Michael is mentioned in above mail
"tcon-pixel clock is the rate that you want to achive on display side and
if you have 4 lanes 32bit or lanes and different bit number that you need
to have a clock that is able to put outside bits and speed equal to
pixel-clock * bits / lanes. so If you want a pixel-clock of 40 mhz
and you have 32bits and 4 lanes you need to have a clock of
40 * 32 / 4 in no-burst mode. "
He is trying to manage the bpp/lanes into dclk_mul (in last mail) and
it can multiply with pixel clock which is rate argument in
sun4i_dclk_round_rate.
The solution I have mentioned in dclk_min, max is bpp/lanes also
multiple rate in dotclock sun4i_dclk_round_rate.
In both cases the overall pll_rate depends on dividers, the one that I
have on this patch is based on BSP and the Michael one is more generic
way so-that it can not to touch other functionalities and looping
dividers to find the best one.
If dclk_min/max is bpp/lanes then dotclock directly using divider 6
(assuming 24-bit and 4 lanes) and return the pll_rate and divider 6
associated.
if dclk_mul is bpp/lanes, on Michael new change, the dividers start
with 4 and end with 127 but the constant ideal rate which rate *
bpp/lanes but the loop from sun4i_dclk_round_rate computed the divider
as 6 only, ie what I'm mentioned on the above mail.
Jagan.
Hi Jagan
On Mon, Jul 22, 2019 at 12:21 PM Jagan Teki <[email protected]> wrote:
>
> Hi Maxime,
>
> On Sat, Jul 20, 2019 at 3:02 PM Maxime Ripard <[email protected]> wrote:
> >
> > On Sat, Jul 20, 2019 at 12:46:27PM +0530, Jagan Teki wrote:
> > > On Sat, Jul 20, 2019 at 12:28 PM Maxime Ripard
> > > <[email protected]> wrote:
> > > >
> > > > On Thu, Jul 11, 2019 at 07:43:16PM +0200, Michael Nazzareno Trimarchi wrote:
> > > > > > > tcon-pixel clock is the rate that you want to achive on display side
> > > > > > > and if you have 4 lanes 32bit or lanes and different bit number that
> > > > > > > you need to have a clock that is able to put outside bits and speed
> > > > > > > equal to pixel-clock * bits / lanes. so If you want a pixel-clock of
> > > > > > > 40 mhz and you have 32bits and 4 lanes you need to have a clock of
> > > > > > > 40 * 32 / 4 in no-burst mode. I think that this is done but most of
> > > > > > > the display.
> > > > > >
> > > > > > So this is what the issue is then?
> > > > > >
> > > > > > This one does make sense, and you should just change the rate in the
> > > > > > call to clk_set_rate in sun4i_tcon0_mode_set_cpu.
> > > > > >
> > > > > > I'm still wondering why that hasn't been brought up in either the
> > > > > > discussion or the commit log before though.
> > > > > >
> > > > > Something like this?
> > > > >
> > > > > drivers/gpu/drm/sun4i/sun4i_tcon.c | 20 +++++++++++---------
> > > > > drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h | 2 --
> > > > > 2 files changed, 11 insertions(+), 11 deletions(-)
> > > > >
> > > > > diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c
> > > > > b/drivers/gpu/drm/sun4i/sun4i_tcon.c
> > > > > index 64c43ee6bd92..42560d5c327c 100644
> > > > > --- a/drivers/gpu/drm/sun4i/sun4i_tcon.c
> > > > > +++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c
> > > > > @@ -263,10 +263,11 @@ static int sun4i_tcon_get_clk_delay(const struct
> > > > > drm_display_mode *mode,
> > > > > }
> > > > >
> > > > > static void sun4i_tcon0_mode_set_common(struct sun4i_tcon *tcon,
> > > > > - const struct drm_display_mode *mode)
> > > > > + const struct drm_display_mode *mode,
> > > > > + u32 tcon_mul)
> > > > > {
> > > > > /* Configure the dot clock */
> > > > > - clk_set_rate(tcon->dclk, mode->crtc_clock * 1000);
> > > > > + clk_set_rate(tcon->dclk, mode->crtc_clock * tcon_mul * 1000);
> > > > >
> > > > > /* Set the resolution */
> > > > > regmap_write(tcon->regs, SUN4I_TCON0_BASIC0_REG,
> > > > > @@ -335,12 +336,13 @@ static void sun4i_tcon0_mode_set_cpu(struct
> > > > > sun4i_tcon *tcon,
> > > > > u8 bpp = mipi_dsi_pixel_format_to_bpp(device->format);
> > > > > u8 lanes = device->lanes;
> > > > > u32 block_space, start_delay;
> > > > > - u32 tcon_div;
> > > > > + u32 tcon_div, tcon_mul;
> > > > >
> > > > > - tcon->dclk_min_div = SUN6I_DSI_TCON_DIV;
> > > > > - tcon->dclk_max_div = SUN6I_DSI_TCON_DIV;
> > > > > + tcon->dclk_min_div = 4;
> > > > > + tcon->dclk_max_div = 127;
> > > > >
> > > > > - sun4i_tcon0_mode_set_common(tcon, mode);
> > > > > + tcon_mul = bpp / lanes;
> > > > > + sun4i_tcon0_mode_set_common(tcon, mode, tcon_mul);
> > > > >
> > > > > /* Set dithering if needed */
> > > > > sun4i_tcon0_mode_set_dithering(tcon, sun4i_tcon_get_connector(encoder));
> > > > > @@ -366,7 +368,7 @@ static void sun4i_tcon0_mode_set_cpu(struct
> > > > > sun4i_tcon *tcon,
> > > > > */
> > > > > regmap_read(tcon->regs, SUN4I_TCON0_DCLK_REG, &tcon_div);
> > > > > tcon_div &= GENMASK(6, 0);
> > > > > - block_space = mode->htotal * bpp / (tcon_div * lanes);
> > > > > + block_space = mode->htotal * tcon_div * tcon_mul;
> > > > > block_space -= mode->hdisplay + 40;
> > > > >
> > > > > regmap_write(tcon->regs, SUN4I_TCON0_CPU_TRI0_REG,
> > > > > @@ -408,7 +410,7 @@ static void sun4i_tcon0_mode_set_lvds(struct
> > > > > sun4i_tcon *tcon,
> > > > >
> > > > > tcon->dclk_min_div = 7;
> > > > > tcon->dclk_max_div = 7;
> > > > > - sun4i_tcon0_mode_set_common(tcon, mode);
> > > > > + sun4i_tcon0_mode_set_common(tcon, mode, 1);
> > > > >
> > > > > /* Set dithering if needed */
> > > > > sun4i_tcon0_mode_set_dithering(tcon, sun4i_tcon_get_connector(encoder));
> > > > > @@ -487,7 +489,7 @@ static void sun4i_tcon0_mode_set_rgb(struct
> > > > > sun4i_tcon *tcon,
> > > > >
> > > > > tcon->dclk_min_div = 6;
> > > > > tcon->dclk_max_div = 127;
> > > > > - sun4i_tcon0_mode_set_common(tcon, mode);
> > > > > + sun4i_tcon0_mode_set_common(tcon, mode, 1);
> > > > >
> > > > > /* Set dithering if needed */
> > > > > sun4i_tcon0_mode_set_dithering(tcon, connector);
> > > > > diff --git a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h
> > > > > b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h
> > > > > index 5c3ad5be0690..a07090579f84 100644
> > > > > --- a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h
> > > > > +++ b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h
> > > > > @@ -13,8 +13,6 @@
> > > > > #include <drm/drm_encoder.h>
> > > > > #include <drm/drm_mipi_dsi.h>
> > > > >
> > > > > -#define SUN6I_DSI_TCON_DIV 4
> > > > > -
> > > > > struct sun6i_dsi {
> > > > > struct drm_connector connector;
> > > > > struct drm_encoder encoder;
> > > >
> > > > I had more something like this in mind:
> > > > http://code.bulix.org/nlp5a4-803511
> > >
> > > Worth to look at it. was it working on your panel? meanwhile I will check it.
> >
> > I haven't tested it.
> >
> > > We have updated with below change [1], seems working on but is
> > > actually checking the each divider as before start with 4... till 127.
> > >
> > > This new approach, is start looking the best divider from 4.. based on
> > > the idea vs rounded it will ended up best divider like [2]
> >
> > But why?
> >
> > I mean, it's not like it's the first time I'm asking this...
> >
> > If the issue is what Micheal described, then the divider has nothing
> > to do with it. We've had that discussion over and over again.
>
> This is what Michael is mentioned in above mail
> "tcon-pixel clock is the rate that you want to achive on display side and
> if you have 4 lanes 32bit or lanes and different bit number that you need
> to have a clock that is able to put outside bits and speed equal to
> pixel-clock * bits / lanes. so If you want a pixel-clock of 40 mhz
> and you have 32bits and 4 lanes you need to have a clock of
> 40 * 32 / 4 in no-burst mode. "
>
> He is trying to manage the bpp/lanes into dclk_mul (in last mail) and
> it can multiply with pixel clock which is rate argument in
> sun4i_dclk_round_rate.
>
> The solution I have mentioned in dclk_min, max is bpp/lanes also
> multiple rate in dotclock sun4i_dclk_round_rate.
>
> In both cases the overall pll_rate depends on dividers, the one that I
> have on this patch is based on BSP and the Michael one is more generic
> way so-that it can not to touch other functionalities and looping
> dividers to find the best one.
>
> If dclk_min/max is bpp/lanes then dotclock directly using divider 6
> (assuming 24-bit and 4 lanes) and return the pll_rate and divider 6
> associated.
>
> if dclk_mul is bpp/lanes, on Michael new change, the dividers start
> with 4 and end with 127 but the constant ideal rate which rate *
> bpp/lanes but the loop from sun4i_dclk_round_rate computed the divider
> as 6 only, ie what I'm mentioned on the above mail.
>
tcon-pixel clock and tcon are mutual connected. The code is done in a way
that optimal clock need to be search. Now the patch that I propose is more
connected to the description I gave.
I need some comment from Maxime, what he prefers or we need to search for
a different one. I don't had time to check Maxime proposal because I'm working
on other projects.
Michael
> Jagan.
--
| Michael Nazzareno Trimarchi Amarula Solutions BV |
| COO - Founder Cruquiuskade 47 |
| +31(0)851119172 Amsterdam 1018 AM NL |
| [`as] http://www.amarulasolutions.com |
On Mon, Jul 22, 2019 at 3:55 PM Michael Nazzareno Trimarchi
<[email protected]> wrote:
>
> Hi Jagan
>
> On Mon, Jul 22, 2019 at 12:21 PM Jagan Teki <[email protected]> wrote:
> >
> > Hi Maxime,
> >
> > On Sat, Jul 20, 2019 at 3:02 PM Maxime Ripard <[email protected]> wrote:
> > >
> > > On Sat, Jul 20, 2019 at 12:46:27PM +0530, Jagan Teki wrote:
> > > > On Sat, Jul 20, 2019 at 12:28 PM Maxime Ripard
> > > > <[email protected]> wrote:
> > > > >
> > > > > On Thu, Jul 11, 2019 at 07:43:16PM +0200, Michael Nazzareno Trimarchi wrote:
> > > > > > > > tcon-pixel clock is the rate that you want to achive on display side
> > > > > > > > and if you have 4 lanes 32bit or lanes and different bit number that
> > > > > > > > you need to have a clock that is able to put outside bits and speed
> > > > > > > > equal to pixel-clock * bits / lanes. so If you want a pixel-clock of
> > > > > > > > 40 mhz and you have 32bits and 4 lanes you need to have a clock of
> > > > > > > > 40 * 32 / 4 in no-burst mode. I think that this is done but most of
> > > > > > > > the display.
> > > > > > >
> > > > > > > So this is what the issue is then?
> > > > > > >
> > > > > > > This one does make sense, and you should just change the rate in the
> > > > > > > call to clk_set_rate in sun4i_tcon0_mode_set_cpu.
> > > > > > >
> > > > > > > I'm still wondering why that hasn't been brought up in either the
> > > > > > > discussion or the commit log before though.
> > > > > > >
> > > > > > Something like this?
> > > > > >
> > > > > > drivers/gpu/drm/sun4i/sun4i_tcon.c | 20 +++++++++++---------
> > > > > > drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h | 2 --
> > > > > > 2 files changed, 11 insertions(+), 11 deletions(-)
> > > > > >
> > > > > > diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c
> > > > > > b/drivers/gpu/drm/sun4i/sun4i_tcon.c
> > > > > > index 64c43ee6bd92..42560d5c327c 100644
> > > > > > --- a/drivers/gpu/drm/sun4i/sun4i_tcon.c
> > > > > > +++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c
> > > > > > @@ -263,10 +263,11 @@ static int sun4i_tcon_get_clk_delay(const struct
> > > > > > drm_display_mode *mode,
> > > > > > }
> > > > > >
> > > > > > static void sun4i_tcon0_mode_set_common(struct sun4i_tcon *tcon,
> > > > > > - const struct drm_display_mode *mode)
> > > > > > + const struct drm_display_mode *mode,
> > > > > > + u32 tcon_mul)
> > > > > > {
> > > > > > /* Configure the dot clock */
> > > > > > - clk_set_rate(tcon->dclk, mode->crtc_clock * 1000);
> > > > > > + clk_set_rate(tcon->dclk, mode->crtc_clock * tcon_mul * 1000);
> > > > > >
> > > > > > /* Set the resolution */
> > > > > > regmap_write(tcon->regs, SUN4I_TCON0_BASIC0_REG,
> > > > > > @@ -335,12 +336,13 @@ static void sun4i_tcon0_mode_set_cpu(struct
> > > > > > sun4i_tcon *tcon,
> > > > > > u8 bpp = mipi_dsi_pixel_format_to_bpp(device->format);
> > > > > > u8 lanes = device->lanes;
> > > > > > u32 block_space, start_delay;
> > > > > > - u32 tcon_div;
> > > > > > + u32 tcon_div, tcon_mul;
> > > > > >
> > > > > > - tcon->dclk_min_div = SUN6I_DSI_TCON_DIV;
> > > > > > - tcon->dclk_max_div = SUN6I_DSI_TCON_DIV;
> > > > > > + tcon->dclk_min_div = 4;
> > > > > > + tcon->dclk_max_div = 127;
> > > > > >
> > > > > > - sun4i_tcon0_mode_set_common(tcon, mode);
> > > > > > + tcon_mul = bpp / lanes;
> > > > > > + sun4i_tcon0_mode_set_common(tcon, mode, tcon_mul);
> > > > > >
> > > > > > /* Set dithering if needed */
> > > > > > sun4i_tcon0_mode_set_dithering(tcon, sun4i_tcon_get_connector(encoder));
> > > > > > @@ -366,7 +368,7 @@ static void sun4i_tcon0_mode_set_cpu(struct
> > > > > > sun4i_tcon *tcon,
> > > > > > */
> > > > > > regmap_read(tcon->regs, SUN4I_TCON0_DCLK_REG, &tcon_div);
> > > > > > tcon_div &= GENMASK(6, 0);
> > > > > > - block_space = mode->htotal * bpp / (tcon_div * lanes);
> > > > > > + block_space = mode->htotal * tcon_div * tcon_mul;
> > > > > > block_space -= mode->hdisplay + 40;
> > > > > >
> > > > > > regmap_write(tcon->regs, SUN4I_TCON0_CPU_TRI0_REG,
> > > > > > @@ -408,7 +410,7 @@ static void sun4i_tcon0_mode_set_lvds(struct
> > > > > > sun4i_tcon *tcon,
> > > > > >
> > > > > > tcon->dclk_min_div = 7;
> > > > > > tcon->dclk_max_div = 7;
> > > > > > - sun4i_tcon0_mode_set_common(tcon, mode);
> > > > > > + sun4i_tcon0_mode_set_common(tcon, mode, 1);
> > > > > >
> > > > > > /* Set dithering if needed */
> > > > > > sun4i_tcon0_mode_set_dithering(tcon, sun4i_tcon_get_connector(encoder));
> > > > > > @@ -487,7 +489,7 @@ static void sun4i_tcon0_mode_set_rgb(struct
> > > > > > sun4i_tcon *tcon,
> > > > > >
> > > > > > tcon->dclk_min_div = 6;
> > > > > > tcon->dclk_max_div = 127;
> > > > > > - sun4i_tcon0_mode_set_common(tcon, mode);
> > > > > > + sun4i_tcon0_mode_set_common(tcon, mode, 1);
> > > > > >
> > > > > > /* Set dithering if needed */
> > > > > > sun4i_tcon0_mode_set_dithering(tcon, connector);
> > > > > > diff --git a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h
> > > > > > b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h
> > > > > > index 5c3ad5be0690..a07090579f84 100644
> > > > > > --- a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h
> > > > > > +++ b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h
> > > > > > @@ -13,8 +13,6 @@
> > > > > > #include <drm/drm_encoder.h>
> > > > > > #include <drm/drm_mipi_dsi.h>
> > > > > >
> > > > > > -#define SUN6I_DSI_TCON_DIV 4
> > > > > > -
> > > > > > struct sun6i_dsi {
> > > > > > struct drm_connector connector;
> > > > > > struct drm_encoder encoder;
> > > > >
> > > > > I had more something like this in mind:
> > > > > http://code.bulix.org/nlp5a4-803511
> > > >
> > > > Worth to look at it. was it working on your panel? meanwhile I will check it.
> > >
> > > I haven't tested it.
> > >
> > > > We have updated with below change [1], seems working on but is
> > > > actually checking the each divider as before start with 4... till 127.
> > > >
> > > > This new approach, is start looking the best divider from 4.. based on
> > > > the idea vs rounded it will ended up best divider like [2]
> > >
> > > But why?
> > >
> > > I mean, it's not like it's the first time I'm asking this...
> > >
> > > If the issue is what Micheal described, then the divider has nothing
> > > to do with it. We've had that discussion over and over again.
> >
> > This is what Michael is mentioned in above mail
> > "tcon-pixel clock is the rate that you want to achive on display side and
> > if you have 4 lanes 32bit or lanes and different bit number that you need
> > to have a clock that is able to put outside bits and speed equal to
> > pixel-clock * bits / lanes. so If you want a pixel-clock of 40 mhz
> > and you have 32bits and 4 lanes you need to have a clock of
> > 40 * 32 / 4 in no-burst mode. "
> >
> > He is trying to manage the bpp/lanes into dclk_mul (in last mail) and
> > it can multiply with pixel clock which is rate argument in
> > sun4i_dclk_round_rate.
> >
> > The solution I have mentioned in dclk_min, max is bpp/lanes also
> > multiple rate in dotclock sun4i_dclk_round_rate.
> >
> > In both cases the overall pll_rate depends on dividers, the one that I
> > have on this patch is based on BSP and the Michael one is more generic
> > way so-that it can not to touch other functionalities and looping
> > dividers to find the best one.
> >
> > If dclk_min/max is bpp/lanes then dotclock directly using divider 6
> > (assuming 24-bit and 4 lanes) and return the pll_rate and divider 6
> > associated.
> >
> > if dclk_mul is bpp/lanes, on Michael new change, the dividers start
> > with 4 and end with 127 but the constant ideal rate which rate *
> > bpp/lanes but the loop from sun4i_dclk_round_rate computed the divider
> > as 6 only, ie what I'm mentioned on the above mail.
> >
>
> tcon-pixel clock and tcon are mutual connected. The code is done in a way
> that optimal clock need to be search. Now the patch that I propose is more
> connected to the description I gave.
True, ie what I'm trying to say in above mail. My idea on the above
mail is to give more information on the both the solutions (one on the
this patch and another you mentioned on above mail) are depends on
divider value for computing desired pll_rate.
>
> I need some comment from Maxime, what he prefers or we need to search for
> a different one. I don't had time to check Maxime proposal because I'm working
> on other projects.
I already provide my logs on Maxime change.if you want you can have a look.
On Mon, Jul 22, 2019 at 03:51:04PM +0530, Jagan Teki wrote:
> Hi Maxime,
>
> On Sat, Jul 20, 2019 at 3:02 PM Maxime Ripard <[email protected]> wrote:
> >
> > On Sat, Jul 20, 2019 at 12:46:27PM +0530, Jagan Teki wrote:
> > > On Sat, Jul 20, 2019 at 12:28 PM Maxime Ripard
> > > <[email protected]> wrote:
> > > >
> > > > On Thu, Jul 11, 2019 at 07:43:16PM +0200, Michael Nazzareno Trimarchi wrote:
> > > > > > > tcon-pixel clock is the rate that you want to achive on display side
> > > > > > > and if you have 4 lanes 32bit or lanes and different bit number that
> > > > > > > you need to have a clock that is able to put outside bits and speed
> > > > > > > equal to pixel-clock * bits / lanes. so If you want a pixel-clock of
> > > > > > > 40 mhz and you have 32bits and 4 lanes you need to have a clock of
> > > > > > > 40 * 32 / 4 in no-burst mode. I think that this is done but most of
> > > > > > > the display.
> > > > > >
> > > > > > So this is what the issue is then?
> > > > > >
> > > > > > This one does make sense, and you should just change the rate in the
> > > > > > call to clk_set_rate in sun4i_tcon0_mode_set_cpu.
> > > > > >
> > > > > > I'm still wondering why that hasn't been brought up in either the
> > > > > > discussion or the commit log before though.
> > > > > >
> > > > > Something like this?
> > > > >
> > > > > drivers/gpu/drm/sun4i/sun4i_tcon.c | 20 +++++++++++---------
> > > > > drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h | 2 --
> > > > > 2 files changed, 11 insertions(+), 11 deletions(-)
> > > > >
> > > > > diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c
> > > > > b/drivers/gpu/drm/sun4i/sun4i_tcon.c
> > > > > index 64c43ee6bd92..42560d5c327c 100644
> > > > > --- a/drivers/gpu/drm/sun4i/sun4i_tcon.c
> > > > > +++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c
> > > > > @@ -263,10 +263,11 @@ static int sun4i_tcon_get_clk_delay(const struct
> > > > > drm_display_mode *mode,
> > > > > }
> > > > >
> > > > > static void sun4i_tcon0_mode_set_common(struct sun4i_tcon *tcon,
> > > > > - const struct drm_display_mode *mode)
> > > > > + const struct drm_display_mode *mode,
> > > > > + u32 tcon_mul)
> > > > > {
> > > > > /* Configure the dot clock */
> > > > > - clk_set_rate(tcon->dclk, mode->crtc_clock * 1000);
> > > > > + clk_set_rate(tcon->dclk, mode->crtc_clock * tcon_mul * 1000);
> > > > >
> > > > > /* Set the resolution */
> > > > > regmap_write(tcon->regs, SUN4I_TCON0_BASIC0_REG,
> > > > > @@ -335,12 +336,13 @@ static void sun4i_tcon0_mode_set_cpu(struct
> > > > > sun4i_tcon *tcon,
> > > > > u8 bpp = mipi_dsi_pixel_format_to_bpp(device->format);
> > > > > u8 lanes = device->lanes;
> > > > > u32 block_space, start_delay;
> > > > > - u32 tcon_div;
> > > > > + u32 tcon_div, tcon_mul;
> > > > >
> > > > > - tcon->dclk_min_div = SUN6I_DSI_TCON_DIV;
> > > > > - tcon->dclk_max_div = SUN6I_DSI_TCON_DIV;
> > > > > + tcon->dclk_min_div = 4;
> > > > > + tcon->dclk_max_div = 127;
> > > > >
> > > > > - sun4i_tcon0_mode_set_common(tcon, mode);
> > > > > + tcon_mul = bpp / lanes;
> > > > > + sun4i_tcon0_mode_set_common(tcon, mode, tcon_mul);
> > > > >
> > > > > /* Set dithering if needed */
> > > > > sun4i_tcon0_mode_set_dithering(tcon, sun4i_tcon_get_connector(encoder));
> > > > > @@ -366,7 +368,7 @@ static void sun4i_tcon0_mode_set_cpu(struct
> > > > > sun4i_tcon *tcon,
> > > > > */
> > > > > regmap_read(tcon->regs, SUN4I_TCON0_DCLK_REG, &tcon_div);
> > > > > tcon_div &= GENMASK(6, 0);
> > > > > - block_space = mode->htotal * bpp / (tcon_div * lanes);
> > > > > + block_space = mode->htotal * tcon_div * tcon_mul;
> > > > > block_space -= mode->hdisplay + 40;
> > > > >
> > > > > regmap_write(tcon->regs, SUN4I_TCON0_CPU_TRI0_REG,
> > > > > @@ -408,7 +410,7 @@ static void sun4i_tcon0_mode_set_lvds(struct
> > > > > sun4i_tcon *tcon,
> > > > >
> > > > > tcon->dclk_min_div = 7;
> > > > > tcon->dclk_max_div = 7;
> > > > > - sun4i_tcon0_mode_set_common(tcon, mode);
> > > > > + sun4i_tcon0_mode_set_common(tcon, mode, 1);
> > > > >
> > > > > /* Set dithering if needed */
> > > > > sun4i_tcon0_mode_set_dithering(tcon, sun4i_tcon_get_connector(encoder));
> > > > > @@ -487,7 +489,7 @@ static void sun4i_tcon0_mode_set_rgb(struct
> > > > > sun4i_tcon *tcon,
> > > > >
> > > > > tcon->dclk_min_div = 6;
> > > > > tcon->dclk_max_div = 127;
> > > > > - sun4i_tcon0_mode_set_common(tcon, mode);
> > > > > + sun4i_tcon0_mode_set_common(tcon, mode, 1);
> > > > >
> > > > > /* Set dithering if needed */
> > > > > sun4i_tcon0_mode_set_dithering(tcon, connector);
> > > > > diff --git a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h
> > > > > b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h
> > > > > index 5c3ad5be0690..a07090579f84 100644
> > > > > --- a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h
> > > > > +++ b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h
> > > > > @@ -13,8 +13,6 @@
> > > > > #include <drm/drm_encoder.h>
> > > > > #include <drm/drm_mipi_dsi.h>
> > > > >
> > > > > -#define SUN6I_DSI_TCON_DIV 4
> > > > > -
> > > > > struct sun6i_dsi {
> > > > > struct drm_connector connector;
> > > > > struct drm_encoder encoder;
> > > >
> > > > I had more something like this in mind:
> > > > http://code.bulix.org/nlp5a4-803511
> > >
> > > Worth to look at it. was it working on your panel? meanwhile I will check it.
> >
> > I haven't tested it.
> >
> > > We have updated with below change [1], seems working on but is
> > > actually checking the each divider as before start with 4... till 127.
> > >
> > > This new approach, is start looking the best divider from 4.. based on
> > > the idea vs rounded it will ended up best divider like [2]
> >
> > But why?
> >
> > I mean, it's not like it's the first time I'm asking this...
> >
> > If the issue is what Micheal described, then the divider has nothing
> > to do with it. We've had that discussion over and over again.
>
> This is what Michael is mentioned in above mail "tcon-pixel clock is
> the rate that you want to achive on display side and if you have 4
> lanes 32bit or lanes and different bit number that you need to have
> a clock that is able to put outside bits and speed equal to
> pixel-clock * bits / lanes. so If you want a pixel-clock of 40 mhz
> and you have 32bits and 4 lanes you need to have a clock of 40 * 32
> / 4 in no-burst mode. "
Yeah, so we need to change the clock rate.
> He is trying to manage the bpp/lanes into dclk_mul (in last mail)
> and it can multiply with pixel clock which is rate argument in
> sun4i_dclk_round_rate.
>
> The solution I have mentioned in dclk_min, max is bpp/lanes also
> multiple rate in dotclock sun4i_dclk_round_rate.
>
> In both cases the overall pll_rate depends on dividers, the one that I
> have on this patch is based on BSP and the Michael one is more generic
> way so-that it can not to touch other functionalities and looping
> dividers to find the best one.
>
> If dclk_min/max is bpp/lanes then dotclock directly using divider 6
> (assuming 24-bit and 4 lanes) and return the pll_rate and divider 6
> associated.
>
> if dclk_mul is bpp/lanes, on Michael new change, the dividers start
> with 4 and end with 127 but the constant ideal rate which rate *
> bpp/lanes but the loop from sun4i_dclk_round_rate computed the divider
> as 6 only, ie what I'm mentioned on the above mail.
We've been over this a couple of times already.
The clock is generated like this:
PLL -> TCON Module Clock -> TCON DCLK
You want the TCON DCLK to be at the pixel clock rate * bpp /
lanes. Fine, that makes sense.
Except that the patch you've sent, instead of changing the rate
itself, changes the ratio between the module clock and DCLK.
And this is where the issue lies. First, from a logical viewpoint, it
doesn't make sense. If you want to change the clock rate, then just do
it. Don't hack around the multipliers trying to fall back to something
that works for you.
Then, the ratio itself needs to be set to 4. This is the part that
we've discussed way too many times already, but in the Allwinner BSP,
that ratio is hardcoded to 4, and we've had panels that need it at
that value.
So, what you want to do is to have:
TCON DCLK = pixel clock * bpp / lanes
TCON Module Clock = DCLK * 4
PLL = Module Clock * Module Clock Divider (which I believe is 1 in most cases)
So you want to increase the PLL. Fortunately for use, this is exactly
what a call to clk_set_rate will end up doing.
Maxime
--
Maxime Ripard, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
Hi
On Wed, Jul 24, 2019 at 11:05 AM Maxime Ripard
<[email protected]> wrote:
>
> On Mon, Jul 22, 2019 at 03:51:04PM +0530, Jagan Teki wrote:
> > Hi Maxime,
> >
> > On Sat, Jul 20, 2019 at 3:02 PM Maxime Ripard <[email protected]> wrote:
> > >
> > > On Sat, Jul 20, 2019 at 12:46:27PM +0530, Jagan Teki wrote:
> > > > On Sat, Jul 20, 2019 at 12:28 PM Maxime Ripard
> > > > <[email protected]> wrote:
> > > > >
> > > > > On Thu, Jul 11, 2019 at 07:43:16PM +0200, Michael Nazzareno Trimarchi wrote:
> > > > > > > > tcon-pixel clock is the rate that you want to achive on display side
> > > > > > > > and if you have 4 lanes 32bit or lanes and different bit number that
> > > > > > > > you need to have a clock that is able to put outside bits and speed
> > > > > > > > equal to pixel-clock * bits / lanes. so If you want a pixel-clock of
> > > > > > > > 40 mhz and you have 32bits and 4 lanes you need to have a clock of
> > > > > > > > 40 * 32 / 4 in no-burst mode. I think that this is done but most of
> > > > > > > > the display.
> > > > > > >
> > > > > > > So this is what the issue is then?
> > > > > > >
> > > > > > > This one does make sense, and you should just change the rate in the
> > > > > > > call to clk_set_rate in sun4i_tcon0_mode_set_cpu.
> > > > > > >
> > > > > > > I'm still wondering why that hasn't been brought up in either the
> > > > > > > discussion or the commit log before though.
> > > > > > >
> > > > > > Something like this?
> > > > > >
> > > > > > drivers/gpu/drm/sun4i/sun4i_tcon.c | 20 +++++++++++---------
> > > > > > drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h | 2 --
> > > > > > 2 files changed, 11 insertions(+), 11 deletions(-)
> > > > > >
> > > > > > diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c
> > > > > > b/drivers/gpu/drm/sun4i/sun4i_tcon.c
> > > > > > index 64c43ee6bd92..42560d5c327c 100644
> > > > > > --- a/drivers/gpu/drm/sun4i/sun4i_tcon.c
> > > > > > +++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c
> > > > > > @@ -263,10 +263,11 @@ static int sun4i_tcon_get_clk_delay(const struct
> > > > > > drm_display_mode *mode,
> > > > > > }
> > > > > >
> > > > > > static void sun4i_tcon0_mode_set_common(struct sun4i_tcon *tcon,
> > > > > > - const struct drm_display_mode *mode)
> > > > > > + const struct drm_display_mode *mode,
> > > > > > + u32 tcon_mul)
> > > > > > {
> > > > > > /* Configure the dot clock */
> > > > > > - clk_set_rate(tcon->dclk, mode->crtc_clock * 1000);
> > > > > > + clk_set_rate(tcon->dclk, mode->crtc_clock * tcon_mul * 1000);
> > > > > >
> > > > > > /* Set the resolution */
> > > > > > regmap_write(tcon->regs, SUN4I_TCON0_BASIC0_REG,
> > > > > > @@ -335,12 +336,13 @@ static void sun4i_tcon0_mode_set_cpu(struct
> > > > > > sun4i_tcon *tcon,
> > > > > > u8 bpp = mipi_dsi_pixel_format_to_bpp(device->format);
> > > > > > u8 lanes = device->lanes;
> > > > > > u32 block_space, start_delay;
> > > > > > - u32 tcon_div;
> > > > > > + u32 tcon_div, tcon_mul;
> > > > > >
> > > > > > - tcon->dclk_min_div = SUN6I_DSI_TCON_DIV;
> > > > > > - tcon->dclk_max_div = SUN6I_DSI_TCON_DIV;
> > > > > > + tcon->dclk_min_div = 4;
> > > > > > + tcon->dclk_max_div = 127;
> > > > > >
> > > > > > - sun4i_tcon0_mode_set_common(tcon, mode);
> > > > > > + tcon_mul = bpp / lanes;
> > > > > > + sun4i_tcon0_mode_set_common(tcon, mode, tcon_mul);
> > > > > >
> > > > > > /* Set dithering if needed */
> > > > > > sun4i_tcon0_mode_set_dithering(tcon, sun4i_tcon_get_connector(encoder));
> > > > > > @@ -366,7 +368,7 @@ static void sun4i_tcon0_mode_set_cpu(struct
> > > > > > sun4i_tcon *tcon,
> > > > > > */
> > > > > > regmap_read(tcon->regs, SUN4I_TCON0_DCLK_REG, &tcon_div);
> > > > > > tcon_div &= GENMASK(6, 0);
> > > > > > - block_space = mode->htotal * bpp / (tcon_div * lanes);
> > > > > > + block_space = mode->htotal * tcon_div * tcon_mul;
> > > > > > block_space -= mode->hdisplay + 40;
> > > > > >
> > > > > > regmap_write(tcon->regs, SUN4I_TCON0_CPU_TRI0_REG,
> > > > > > @@ -408,7 +410,7 @@ static void sun4i_tcon0_mode_set_lvds(struct
> > > > > > sun4i_tcon *tcon,
> > > > > >
> > > > > > tcon->dclk_min_div = 7;
> > > > > > tcon->dclk_max_div = 7;
> > > > > > - sun4i_tcon0_mode_set_common(tcon, mode);
> > > > > > + sun4i_tcon0_mode_set_common(tcon, mode, 1);
> > > > > >
> > > > > > /* Set dithering if needed */
> > > > > > sun4i_tcon0_mode_set_dithering(tcon, sun4i_tcon_get_connector(encoder));
> > > > > > @@ -487,7 +489,7 @@ static void sun4i_tcon0_mode_set_rgb(struct
> > > > > > sun4i_tcon *tcon,
> > > > > >
> > > > > > tcon->dclk_min_div = 6;
> > > > > > tcon->dclk_max_div = 127;
> > > > > > - sun4i_tcon0_mode_set_common(tcon, mode);
> > > > > > + sun4i_tcon0_mode_set_common(tcon, mode, 1);
> > > > > >
> > > > > > /* Set dithering if needed */
> > > > > > sun4i_tcon0_mode_set_dithering(tcon, connector);
> > > > > > diff --git a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h
> > > > > > b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h
> > > > > > index 5c3ad5be0690..a07090579f84 100644
> > > > > > --- a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h
> > > > > > +++ b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h
> > > > > > @@ -13,8 +13,6 @@
> > > > > > #include <drm/drm_encoder.h>
> > > > > > #include <drm/drm_mipi_dsi.h>
> > > > > >
> > > > > > -#define SUN6I_DSI_TCON_DIV 4
> > > > > > -
> > > > > > struct sun6i_dsi {
> > > > > > struct drm_connector connector;
> > > > > > struct drm_encoder encoder;
> > > > >
> > > > > I had more something like this in mind:
> > > > > http://code.bulix.org/nlp5a4-803511
> > > >
> > > > Worth to look at it. was it working on your panel? meanwhile I will check it.
> > >
> > > I haven't tested it.
> > >
> > > > We have updated with below change [1], seems working on but is
> > > > actually checking the each divider as before start with 4... till 127.
> > > >
> > > > This new approach, is start looking the best divider from 4.. based on
> > > > the idea vs rounded it will ended up best divider like [2]
> > >
> > > But why?
> > >
> > > I mean, it's not like it's the first time I'm asking this...
> > >
> > > If the issue is what Micheal described, then the divider has nothing
> > > to do with it. We've had that discussion over and over again.
> >
> > This is what Michael is mentioned in above mail "tcon-pixel clock is
> > the rate that you want to achive on display side and if you have 4
> > lanes 32bit or lanes and different bit number that you need to have
> > a clock that is able to put outside bits and speed equal to
> > pixel-clock * bits / lanes. so If you want a pixel-clock of 40 mhz
> > and you have 32bits and 4 lanes you need to have a clock of 40 * 32
> > / 4 in no-burst mode. "
>
> Yeah, so we need to change the clock rate.
>
> > He is trying to manage the bpp/lanes into dclk_mul (in last mail)
> > and it can multiply with pixel clock which is rate argument in
> > sun4i_dclk_round_rate.
> >
> > The solution I have mentioned in dclk_min, max is bpp/lanes also
> > multiple rate in dotclock sun4i_dclk_round_rate.
> >
> > In both cases the overall pll_rate depends on dividers, the one that I
> > have on this patch is based on BSP and the Michael one is more generic
> > way so-that it can not to touch other functionalities and looping
> > dividers to find the best one.
> >
> > If dclk_min/max is bpp/lanes then dotclock directly using divider 6
> > (assuming 24-bit and 4 lanes) and return the pll_rate and divider 6
> > associated.
> >
> > if dclk_mul is bpp/lanes, on Michael new change, the dividers start
> > with 4 and end with 127 but the constant ideal rate which rate *
> > bpp/lanes but the loop from sun4i_dclk_round_rate computed the divider
> > as 6 only, ie what I'm mentioned on the above mail.
>
> We've been over this a couple of times already.
>
> The clock is generated like this:
>
> PLL -> TCON Module Clock -> TCON DCLK
>
> You want the TCON DCLK to be at the pixel clock rate * bpp /
> lanes. Fine, that makes sense.
>
> Except that the patch you've sent, instead of changing the rate
> itself, changes the ratio between the module clock and DCLK.
>
> And this is where the issue lies. First, from a logical viewpoint, it
> doesn't make sense. If you want to change the clock rate, then just do
> it. Don't hack around the multipliers trying to fall back to something
> that works for you.
>
> Then, the ratio itself needs to be set to 4. This is the part that
> we've discussed way too many times already, but in the Allwinner BSP,
> that ratio is hardcoded to 4, and we've had panels that need it at
> that value.
>
> So, what you want to do is to have:
>
> TCON DCLK = pixel clock * bpp / lanes
> TCON Module Clock = DCLK * 4
> PLL = Module Clock * Module Clock Divider (which I believe is 1 in most cases)
pll-mipi 1 1 1 178200000
0 0 50000
tcon0 2 2 1 178200000
0 0 50000
tcon-pixel-clock 1 1 1 29700000
0 0 50000
This is an english problem from my side:
tcon-pixel-clock is DCLK
tcon0 must be tcon-pixel-clock * bpp / lanes because the logic need to
put a bit every cycle.
One solution can be:
- set_rate_exclusive to tcon0 and calculate as display pixel clock *
bpp / lanes
- calculate the tcon-pixel-clock using all divider
Problem is that the function that calculate tcon-pixel-clock does not
have any constrain on the ideal value. What you are
suggesting is not correct in my opinion or I'm not following your
suggesstion. What I know is that if we have a pixel-clock
of dvi display of 50Mhz and we have 4 lanes 32bit we need a clock in
the logic of 400Mhz (this is the ideal throughtput).
So tcon-pixel-clock is 50mhz and tcon0 is 400Mhz.
Michael
>
> So you want to increase the PLL. Fortunately for use, this is exactly
> what a call to clk_set_rate will end up doing.
>
> Maxime
>
> --
> Maxime Ripard, Bootlin
> Embedded Linux and Kernel engineering
> https://bootlin.com
--
| Michael Nazzareno Trimarchi Amarula Solutions BV |
| COO - Founder Cruquiuskade 47 |
| +31(0)851119172 Amsterdam 1018 AM NL |
| [`as] http://www.amarulasolutions.com |
Hi Maxime
On Mon, Jul 29, 2019 at 8:59 AM Michael Nazzareno Trimarchi
<[email protected]> wrote:
>
> Hi
>
> On Wed, Jul 24, 2019 at 11:05 AM Maxime Ripard
> <[email protected]> wrote:
> >
> > On Mon, Jul 22, 2019 at 03:51:04PM +0530, Jagan Teki wrote:
> > > Hi Maxime,
> > >
> > > On Sat, Jul 20, 2019 at 3:02 PM Maxime Ripard <[email protected]> wrote:
> > > >
> > > > On Sat, Jul 20, 2019 at 12:46:27PM +0530, Jagan Teki wrote:
> > > > > On Sat, Jul 20, 2019 at 12:28 PM Maxime Ripard
> > > > > <[email protected]> wrote:
> > > > > >
> > > > > > On Thu, Jul 11, 2019 at 07:43:16PM +0200, Michael Nazzareno Trimarchi wrote:
> > > > > > > > > tcon-pixel clock is the rate that you want to achive on display side
> > > > > > > > > and if you have 4 lanes 32bit or lanes and different bit number that
> > > > > > > > > you need to have a clock that is able to put outside bits and speed
> > > > > > > > > equal to pixel-clock * bits / lanes. so If you want a pixel-clock of
> > > > > > > > > 40 mhz and you have 32bits and 4 lanes you need to have a clock of
> > > > > > > > > 40 * 32 / 4 in no-burst mode. I think that this is done but most of
> > > > > > > > > the display.
> > > > > > > >
> > > > > > > > So this is what the issue is then?
> > > > > > > >
> > > > > > > > This one does make sense, and you should just change the rate in the
> > > > > > > > call to clk_set_rate in sun4i_tcon0_mode_set_cpu.
> > > > > > > >
> > > > > > > > I'm still wondering why that hasn't been brought up in either the
> > > > > > > > discussion or the commit log before though.
> > > > > > > >
> > > > > > > Something like this?
> > > > > > >
> > > > > > > drivers/gpu/drm/sun4i/sun4i_tcon.c | 20 +++++++++++---------
> > > > > > > drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h | 2 --
> > > > > > > 2 files changed, 11 insertions(+), 11 deletions(-)
> > > > > > >
> > > > > > > diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c
> > > > > > > b/drivers/gpu/drm/sun4i/sun4i_tcon.c
> > > > > > > index 64c43ee6bd92..42560d5c327c 100644
> > > > > > > --- a/drivers/gpu/drm/sun4i/sun4i_tcon.c
> > > > > > > +++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c
> > > > > > > @@ -263,10 +263,11 @@ static int sun4i_tcon_get_clk_delay(const struct
> > > > > > > drm_display_mode *mode,
> > > > > > > }
> > > > > > >
> > > > > > > static void sun4i_tcon0_mode_set_common(struct sun4i_tcon *tcon,
> > > > > > > - const struct drm_display_mode *mode)
> > > > > > > + const struct drm_display_mode *mode,
> > > > > > > + u32 tcon_mul)
> > > > > > > {
> > > > > > > /* Configure the dot clock */
> > > > > > > - clk_set_rate(tcon->dclk, mode->crtc_clock * 1000);
> > > > > > > + clk_set_rate(tcon->dclk, mode->crtc_clock * tcon_mul * 1000);
> > > > > > >
> > > > > > > /* Set the resolution */
> > > > > > > regmap_write(tcon->regs, SUN4I_TCON0_BASIC0_REG,
> > > > > > > @@ -335,12 +336,13 @@ static void sun4i_tcon0_mode_set_cpu(struct
> > > > > > > sun4i_tcon *tcon,
> > > > > > > u8 bpp = mipi_dsi_pixel_format_to_bpp(device->format);
> > > > > > > u8 lanes = device->lanes;
> > > > > > > u32 block_space, start_delay;
> > > > > > > - u32 tcon_div;
> > > > > > > + u32 tcon_div, tcon_mul;
> > > > > > >
> > > > > > > - tcon->dclk_min_div = SUN6I_DSI_TCON_DIV;
> > > > > > > - tcon->dclk_max_div = SUN6I_DSI_TCON_DIV;
> > > > > > > + tcon->dclk_min_div = 4;
> > > > > > > + tcon->dclk_max_div = 127;
> > > > > > >
> > > > > > > - sun4i_tcon0_mode_set_common(tcon, mode);
> > > > > > > + tcon_mul = bpp / lanes;
> > > > > > > + sun4i_tcon0_mode_set_common(tcon, mode, tcon_mul);
> > > > > > >
> > > > > > > /* Set dithering if needed */
> > > > > > > sun4i_tcon0_mode_set_dithering(tcon, sun4i_tcon_get_connector(encoder));
> > > > > > > @@ -366,7 +368,7 @@ static void sun4i_tcon0_mode_set_cpu(struct
> > > > > > > sun4i_tcon *tcon,
> > > > > > > */
> > > > > > > regmap_read(tcon->regs, SUN4I_TCON0_DCLK_REG, &tcon_div);
> > > > > > > tcon_div &= GENMASK(6, 0);
> > > > > > > - block_space = mode->htotal * bpp / (tcon_div * lanes);
> > > > > > > + block_space = mode->htotal * tcon_div * tcon_mul;
> > > > > > > block_space -= mode->hdisplay + 40;
> > > > > > >
> > > > > > > regmap_write(tcon->regs, SUN4I_TCON0_CPU_TRI0_REG,
> > > > > > > @@ -408,7 +410,7 @@ static void sun4i_tcon0_mode_set_lvds(struct
> > > > > > > sun4i_tcon *tcon,
> > > > > > >
> > > > > > > tcon->dclk_min_div = 7;
> > > > > > > tcon->dclk_max_div = 7;
> > > > > > > - sun4i_tcon0_mode_set_common(tcon, mode);
> > > > > > > + sun4i_tcon0_mode_set_common(tcon, mode, 1);
> > > > > > >
> > > > > > > /* Set dithering if needed */
> > > > > > > sun4i_tcon0_mode_set_dithering(tcon, sun4i_tcon_get_connector(encoder));
> > > > > > > @@ -487,7 +489,7 @@ static void sun4i_tcon0_mode_set_rgb(struct
> > > > > > > sun4i_tcon *tcon,
> > > > > > >
> > > > > > > tcon->dclk_min_div = 6;
> > > > > > > tcon->dclk_max_div = 127;
> > > > > > > - sun4i_tcon0_mode_set_common(tcon, mode);
> > > > > > > + sun4i_tcon0_mode_set_common(tcon, mode, 1);
> > > > > > >
> > > > > > > /* Set dithering if needed */
> > > > > > > sun4i_tcon0_mode_set_dithering(tcon, connector);
> > > > > > > diff --git a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h
> > > > > > > b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h
> > > > > > > index 5c3ad5be0690..a07090579f84 100644
> > > > > > > --- a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h
> > > > > > > +++ b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h
> > > > > > > @@ -13,8 +13,6 @@
> > > > > > > #include <drm/drm_encoder.h>
> > > > > > > #include <drm/drm_mipi_dsi.h>
> > > > > > >
> > > > > > > -#define SUN6I_DSI_TCON_DIV 4
> > > > > > > -
> > > > > > > struct sun6i_dsi {
> > > > > > > struct drm_connector connector;
> > > > > > > struct drm_encoder encoder;
> > > > > >
> > > > > > I had more something like this in mind:
> > > > > > http://code.bulix.org/nlp5a4-803511
> > > > >
> > > > > Worth to look at it. was it working on your panel? meanwhile I will check it.
> > > >
> > > > I haven't tested it.
> > > >
> > > > > We have updated with below change [1], seems working on but is
> > > > > actually checking the each divider as before start with 4... till 127.
> > > > >
> > > > > This new approach, is start looking the best divider from 4.. based on
> > > > > the idea vs rounded it will ended up best divider like [2]
> > > >
> > > > But why?
> > > >
> > > > I mean, it's not like it's the first time I'm asking this...
> > > >
> > > > If the issue is what Micheal described, then the divider has nothing
> > > > to do with it. We've had that discussion over and over again.
> > >
> > > This is what Michael is mentioned in above mail "tcon-pixel clock is
> > > the rate that you want to achive on display side and if you have 4
> > > lanes 32bit or lanes and different bit number that you need to have
> > > a clock that is able to put outside bits and speed equal to
> > > pixel-clock * bits / lanes. so If you want a pixel-clock of 40 mhz
> > > and you have 32bits and 4 lanes you need to have a clock of 40 * 32
> > > / 4 in no-burst mode. "
> >
> > Yeah, so we need to change the clock rate.
> >
> > > He is trying to manage the bpp/lanes into dclk_mul (in last mail)
> > > and it can multiply with pixel clock which is rate argument in
> > > sun4i_dclk_round_rate.
> > >
> > > The solution I have mentioned in dclk_min, max is bpp/lanes also
> > > multiple rate in dotclock sun4i_dclk_round_rate.
> > >
> > > In both cases the overall pll_rate depends on dividers, the one that I
> > > have on this patch is based on BSP and the Michael one is more generic
> > > way so-that it can not to touch other functionalities and looping
> > > dividers to find the best one.
> > >
> > > If dclk_min/max is bpp/lanes then dotclock directly using divider 6
> > > (assuming 24-bit and 4 lanes) and return the pll_rate and divider 6
> > > associated.
> > >
> > > if dclk_mul is bpp/lanes, on Michael new change, the dividers start
> > > with 4 and end with 127 but the constant ideal rate which rate *
> > > bpp/lanes but the loop from sun4i_dclk_round_rate computed the divider
> > > as 6 only, ie what I'm mentioned on the above mail.
> >
> > We've been over this a couple of times already.
> >
> > The clock is generated like this:
> >
> > PLL -> TCON Module Clock -> TCON DCLK
> >
> > You want the TCON DCLK to be at the pixel clock rate * bpp /
> > lanes. Fine, that makes sense.
> >
> > Except that the patch you've sent, instead of changing the rate
> > itself, changes the ratio between the module clock and DCLK.
> >
> > And this is where the issue lies. First, from a logical viewpoint, it
> > doesn't make sense. If you want to change the clock rate, then just do
> > it. Don't hack around the multipliers trying to fall back to something
> > that works for you.
> >
> > Then, the ratio itself needs to be set to 4. This is the part that
> > we've discussed way too many times already, but in the Allwinner BSP,
> > that ratio is hardcoded to 4, and we've had panels that need it at
> > that value.
> >
> > So, what you want to do is to have:
> >
> > TCON DCLK = pixel clock * bpp / lanes
> > TCON Module Clock = DCLK * 4
> > PLL = Module Clock * Module Clock Divider (which I believe is 1 in most cases)
>
> pll-mipi 1 1 1 178200000
> 0 0 50000
> tcon0 2 2 1 178200000
> 0 0 50000
> tcon-pixel-clock 1 1 1 29700000
> 0 0 50000
>
> This is an english problem from my side:
> tcon-pixel-clock is DCLK
> tcon0 must be tcon-pixel-clock * bpp / lanes because the logic need to
> put a bit every cycle.
>
> One solution can be:
> - set_rate_exclusive to tcon0 and calculate as display pixel clock *
> bpp / lanes
> - calculate the tcon-pixel-clock using all divider
>
> Problem is that the function that calculate tcon-pixel-clock does not
> have any constrain on the ideal value. What you are
> suggesting is not correct in my opinion or I'm not following your
> suggesstion. What I know is that if we have a pixel-clock
> of dvi display of 50Mhz and we have 4 lanes 32bit we need a clock in
> the logic of 400Mhz (this is the ideal throughtput).
> So tcon-pixel-clock is 50mhz and tcon0 is 400Mhz.
>
diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c
b/drivers/gpu/drm/sun4i/sun4i_tcon.c
index 94f24c5e2dc5..ffb7906054e5 100644
--- a/drivers/gpu/drm/sun4i/sun4i_tcon.c
+++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c
@@ -338,8 +338,9 @@ static void sun4i_tcon0_mode_set_cpu(struct
sun4i_tcon *tcon,
u32 block_space, start_delay;
u32 tcon_div;
- tcon->dclk_min_div = bpp/lanes;
- tcon->dclk_max_div = bpp/lanes;
+ tcon->dclk_min_div = 4;
+ tcon->dclk_max_div = 127;
+ clk_set_rate_exclusive(tcon->sclk0, mode->crtc_clock * 1000 * bpp / lanes);
sun4i_tcon0_mode_set_common(tcon, mode);
Something like this on top of jagan proposal
Michael
> Michael
>
>
> >
> > So you want to increase the PLL. Fortunately for use, this is exactly
> > what a call to clk_set_rate will end up doing.
> >
> > Maxime
> >
> > --
> > Maxime Ripard, Bootlin
> > Embedded Linux and Kernel engineering
> > https://bootlin.com
>
>
>
> --
> | Michael Nazzareno Trimarchi Amarula Solutions BV |
> | COO - Founder Cruquiuskade 47 |
> | +31(0)851119172 Amsterdam 1018 AM NL |
> | [`as] http://www.amarulasolutions.com |
--
| Michael Nazzareno Trimarchi Amarula Solutions BV |
| COO - Founder Cruquiuskade 47 |
| +31(0)851119172 Amsterdam 1018 AM NL |
| [`as] http://www.amarulasolutions.com |
On Mon, Jul 29, 2019 at 08:59:04AM +0200, Michael Nazzareno Trimarchi wrote:
> Hi
>
> On Wed, Jul 24, 2019 at 11:05 AM Maxime Ripard
> <[email protected]> wrote:
> >
> > On Mon, Jul 22, 2019 at 03:51:04PM +0530, Jagan Teki wrote:
> > > Hi Maxime,
> > >
> > > On Sat, Jul 20, 2019 at 3:02 PM Maxime Ripard <[email protected]> wrote:
> > > >
> > > > On Sat, Jul 20, 2019 at 12:46:27PM +0530, Jagan Teki wrote:
> > > > > On Sat, Jul 20, 2019 at 12:28 PM Maxime Ripard
> > > > > <[email protected]> wrote:
> > > > > >
> > > > > > On Thu, Jul 11, 2019 at 07:43:16PM +0200, Michael Nazzareno Trimarchi wrote:
> > > > > > > > > tcon-pixel clock is the rate that you want to achive on display side
> > > > > > > > > and if you have 4 lanes 32bit or lanes and different bit number that
> > > > > > > > > you need to have a clock that is able to put outside bits and speed
> > > > > > > > > equal to pixel-clock * bits / lanes. so If you want a pixel-clock of
> > > > > > > > > 40 mhz and you have 32bits and 4 lanes you need to have a clock of
> > > > > > > > > 40 * 32 / 4 in no-burst mode. I think that this is done but most of
> > > > > > > > > the display.
> > > > > > > >
> > > > > > > > So this is what the issue is then?
> > > > > > > >
> > > > > > > > This one does make sense, and you should just change the rate in the
> > > > > > > > call to clk_set_rate in sun4i_tcon0_mode_set_cpu.
> > > > > > > >
> > > > > > > > I'm still wondering why that hasn't been brought up in either the
> > > > > > > > discussion or the commit log before though.
> > > > > > > >
> > > > > > > Something like this?
> > > > > > >
> > > > > > > drivers/gpu/drm/sun4i/sun4i_tcon.c | 20 +++++++++++---------
> > > > > > > drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h | 2 --
> > > > > > > 2 files changed, 11 insertions(+), 11 deletions(-)
> > > > > > >
> > > > > > > diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c
> > > > > > > b/drivers/gpu/drm/sun4i/sun4i_tcon.c
> > > > > > > index 64c43ee6bd92..42560d5c327c 100644
> > > > > > > --- a/drivers/gpu/drm/sun4i/sun4i_tcon.c
> > > > > > > +++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c
> > > > > > > @@ -263,10 +263,11 @@ static int sun4i_tcon_get_clk_delay(const struct
> > > > > > > drm_display_mode *mode,
> > > > > > > }
> > > > > > >
> > > > > > > static void sun4i_tcon0_mode_set_common(struct sun4i_tcon *tcon,
> > > > > > > - const struct drm_display_mode *mode)
> > > > > > > + const struct drm_display_mode *mode,
> > > > > > > + u32 tcon_mul)
> > > > > > > {
> > > > > > > /* Configure the dot clock */
> > > > > > > - clk_set_rate(tcon->dclk, mode->crtc_clock * 1000);
> > > > > > > + clk_set_rate(tcon->dclk, mode->crtc_clock * tcon_mul * 1000);
> > > > > > >
> > > > > > > /* Set the resolution */
> > > > > > > regmap_write(tcon->regs, SUN4I_TCON0_BASIC0_REG,
> > > > > > > @@ -335,12 +336,13 @@ static void sun4i_tcon0_mode_set_cpu(struct
> > > > > > > sun4i_tcon *tcon,
> > > > > > > u8 bpp = mipi_dsi_pixel_format_to_bpp(device->format);
> > > > > > > u8 lanes = device->lanes;
> > > > > > > u32 block_space, start_delay;
> > > > > > > - u32 tcon_div;
> > > > > > > + u32 tcon_div, tcon_mul;
> > > > > > >
> > > > > > > - tcon->dclk_min_div = SUN6I_DSI_TCON_DIV;
> > > > > > > - tcon->dclk_max_div = SUN6I_DSI_TCON_DIV;
> > > > > > > + tcon->dclk_min_div = 4;
> > > > > > > + tcon->dclk_max_div = 127;
> > > > > > >
> > > > > > > - sun4i_tcon0_mode_set_common(tcon, mode);
> > > > > > > + tcon_mul = bpp / lanes;
> > > > > > > + sun4i_tcon0_mode_set_common(tcon, mode, tcon_mul);
> > > > > > >
> > > > > > > /* Set dithering if needed */
> > > > > > > sun4i_tcon0_mode_set_dithering(tcon, sun4i_tcon_get_connector(encoder));
> > > > > > > @@ -366,7 +368,7 @@ static void sun4i_tcon0_mode_set_cpu(struct
> > > > > > > sun4i_tcon *tcon,
> > > > > > > */
> > > > > > > regmap_read(tcon->regs, SUN4I_TCON0_DCLK_REG, &tcon_div);
> > > > > > > tcon_div &= GENMASK(6, 0);
> > > > > > > - block_space = mode->htotal * bpp / (tcon_div * lanes);
> > > > > > > + block_space = mode->htotal * tcon_div * tcon_mul;
> > > > > > > block_space -= mode->hdisplay + 40;
> > > > > > >
> > > > > > > regmap_write(tcon->regs, SUN4I_TCON0_CPU_TRI0_REG,
> > > > > > > @@ -408,7 +410,7 @@ static void sun4i_tcon0_mode_set_lvds(struct
> > > > > > > sun4i_tcon *tcon,
> > > > > > >
> > > > > > > tcon->dclk_min_div = 7;
> > > > > > > tcon->dclk_max_div = 7;
> > > > > > > - sun4i_tcon0_mode_set_common(tcon, mode);
> > > > > > > + sun4i_tcon0_mode_set_common(tcon, mode, 1);
> > > > > > >
> > > > > > > /* Set dithering if needed */
> > > > > > > sun4i_tcon0_mode_set_dithering(tcon, sun4i_tcon_get_connector(encoder));
> > > > > > > @@ -487,7 +489,7 @@ static void sun4i_tcon0_mode_set_rgb(struct
> > > > > > > sun4i_tcon *tcon,
> > > > > > >
> > > > > > > tcon->dclk_min_div = 6;
> > > > > > > tcon->dclk_max_div = 127;
> > > > > > > - sun4i_tcon0_mode_set_common(tcon, mode);
> > > > > > > + sun4i_tcon0_mode_set_common(tcon, mode, 1);
> > > > > > >
> > > > > > > /* Set dithering if needed */
> > > > > > > sun4i_tcon0_mode_set_dithering(tcon, connector);
> > > > > > > diff --git a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h
> > > > > > > b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h
> > > > > > > index 5c3ad5be0690..a07090579f84 100644
> > > > > > > --- a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h
> > > > > > > +++ b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h
> > > > > > > @@ -13,8 +13,6 @@
> > > > > > > #include <drm/drm_encoder.h>
> > > > > > > #include <drm/drm_mipi_dsi.h>
> > > > > > >
> > > > > > > -#define SUN6I_DSI_TCON_DIV 4
> > > > > > > -
> > > > > > > struct sun6i_dsi {
> > > > > > > struct drm_connector connector;
> > > > > > > struct drm_encoder encoder;
> > > > > >
> > > > > > I had more something like this in mind:
> > > > > > http://code.bulix.org/nlp5a4-803511
> > > > >
> > > > > Worth to look at it. was it working on your panel? meanwhile I will check it.
> > > >
> > > > I haven't tested it.
> > > >
> > > > > We have updated with below change [1], seems working on but is
> > > > > actually checking the each divider as before start with 4... till 127.
> > > > >
> > > > > This new approach, is start looking the best divider from 4.. based on
> > > > > the idea vs rounded it will ended up best divider like [2]
> > > >
> > > > But why?
> > > >
> > > > I mean, it's not like it's the first time I'm asking this...
> > > >
> > > > If the issue is what Micheal described, then the divider has nothing
> > > > to do with it. We've had that discussion over and over again.
> > >
> > > This is what Michael is mentioned in above mail "tcon-pixel clock is
> > > the rate that you want to achive on display side and if you have 4
> > > lanes 32bit or lanes and different bit number that you need to have
> > > a clock that is able to put outside bits and speed equal to
> > > pixel-clock * bits / lanes. so If you want a pixel-clock of 40 mhz
> > > and you have 32bits and 4 lanes you need to have a clock of 40 * 32
> > > / 4 in no-burst mode. "
> >
> > Yeah, so we need to change the clock rate.
> >
> > > He is trying to manage the bpp/lanes into dclk_mul (in last mail)
> > > and it can multiply with pixel clock which is rate argument in
> > > sun4i_dclk_round_rate.
> > >
> > > The solution I have mentioned in dclk_min, max is bpp/lanes also
> > > multiple rate in dotclock sun4i_dclk_round_rate.
> > >
> > > In both cases the overall pll_rate depends on dividers, the one that I
> > > have on this patch is based on BSP and the Michael one is more generic
> > > way so-that it can not to touch other functionalities and looping
> > > dividers to find the best one.
> > >
> > > If dclk_min/max is bpp/lanes then dotclock directly using divider 6
> > > (assuming 24-bit and 4 lanes) and return the pll_rate and divider 6
> > > associated.
> > >
> > > if dclk_mul is bpp/lanes, on Michael new change, the dividers start
> > > with 4 and end with 127 but the constant ideal rate which rate *
> > > bpp/lanes but the loop from sun4i_dclk_round_rate computed the divider
> > > as 6 only, ie what I'm mentioned on the above mail.
> >
> > We've been over this a couple of times already.
> >
> > The clock is generated like this:
> >
> > PLL -> TCON Module Clock -> TCON DCLK
> >
> > You want the TCON DCLK to be at the pixel clock rate * bpp /
> > lanes. Fine, that makes sense.
> >
> > Except that the patch you've sent, instead of changing the rate
> > itself, changes the ratio between the module clock and DCLK.
> >
> > And this is where the issue lies. First, from a logical viewpoint, it
> > doesn't make sense. If you want to change the clock rate, then just do
> > it. Don't hack around the multipliers trying to fall back to something
> > that works for you.
> >
> > Then, the ratio itself needs to be set to 4. This is the part that
> > we've discussed way too many times already, but in the Allwinner BSP,
> > that ratio is hardcoded to 4, and we've had panels that need it at
> > that value.
> >
> > So, what you want to do is to have:
> >
> > TCON DCLK = pixel clock * bpp / lanes
> > TCON Module Clock = DCLK * 4
> > PLL = Module Clock * Module Clock Divider (which I believe is 1 in most cases)
>
> pll-mipi 1 1 1 178200000
> 0 0 50000
> tcon0 2 2 1 178200000
> 0 0 50000
> tcon-pixel-clock 1 1 1 29700000
> 0 0 50000
Is this before or after your patches?
> This is an english problem from my side:
> tcon-pixel-clock is DCLK
> tcon0 must be tcon-pixel-clock * bpp / lanes, because the logic need to
> put a bit every cycle.
Again, I'm not saying this is wrong, but each time I've looked at it
the BSP was using a 4 divider between the tcon module clock and the
dotclock.
So, please prove me wrong here.
> One solution can be:
> - set_rate_exclusive to tcon0 and calculate as display pixel clock *
> bpp / lanes
I'm not sure what set_rate_exclusive has to do with it. I mean, it's a
good idea to use it, but it shouldn't really change anything to the
discussion.
> - calculate the tcon-pixel-clock using all divider
I'm not sure what you mean by that.
> Problem is that the function that calculate tcon-pixel-clock does not
> have any constrain on the ideal value.
It does have constraints, but you're right that it will not try to
find an exact match and bail out if it can't do it, but will find the
closest match.
> What you are suggesting is not correct in my opinion or I'm not
> following your suggesstion.
Then prove me wrong.
> What I know is that if we have a pixel-clock of dvi display of 50Mhz
> and we have 4 lanes 32bit we need a clock in the logic of 400Mhz
> (this is the ideal throughtput).
> So tcon-pixel-clock is 50mhz and tcon0 is 400Mhz.
There's one thing to keep in mind though. The TCON dotclock in the
MIPI-DSI case isn't directly tied to the Bit Clock, it's simply an
internal clock in the pipeline to feed the FIFO of the MIPI-DSI
controller. The MIPI-DSI controller itself will generate that clock,
and only that one will have those constraints.
Maxime
--
Maxime Ripard, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
Hi Maxime
On Tue, Aug 13, 2019 at 8:05 AM Maxime Ripard <[email protected]> wrote:
>
> On Mon, Jul 29, 2019 at 08:59:04AM +0200, Michael Nazzareno Trimarchi wrote:
> > Hi
> >
> > On Wed, Jul 24, 2019 at 11:05 AM Maxime Ripard
> > <[email protected]> wrote:
> > >
> > > On Mon, Jul 22, 2019 at 03:51:04PM +0530, Jagan Teki wrote:
> > > > Hi Maxime,
> > > >
> > > > On Sat, Jul 20, 2019 at 3:02 PM Maxime Ripard <[email protected]> wrote:
> > > > >
> > > > > On Sat, Jul 20, 2019 at 12:46:27PM +0530, Jagan Teki wrote:
> > > > > > On Sat, Jul 20, 2019 at 12:28 PM Maxime Ripard
> > > > > > <[email protected]> wrote:
> > > > > > >
> > > > > > > On Thu, Jul 11, 2019 at 07:43:16PM +0200, Michael Nazzareno Trimarchi wrote:
> > > > > > > > > > tcon-pixel clock is the rate that you want to achive on display side
> > > > > > > > > > and if you have 4 lanes 32bit or lanes and different bit number that
> > > > > > > > > > you need to have a clock that is able to put outside bits and speed
> > > > > > > > > > equal to pixel-clock * bits / lanes. so If you want a pixel-clock of
> > > > > > > > > > 40 mhz and you have 32bits and 4 lanes you need to have a clock of
> > > > > > > > > > 40 * 32 / 4 in no-burst mode. I think that this is done but most of
> > > > > > > > > > the display.
> > > > > > > > >
> > > > > > > > > So this is what the issue is then?
> > > > > > > > >
> > > > > > > > > This one does make sense, and you should just change the rate in the
> > > > > > > > > call to clk_set_rate in sun4i_tcon0_mode_set_cpu.
> > > > > > > > >
> > > > > > > > > I'm still wondering why that hasn't been brought up in either the
> > > > > > > > > discussion or the commit log before though.
> > > > > > > > >
> > > > > > > > Something like this?
> > > > > > > >
> > > > > > > > drivers/gpu/drm/sun4i/sun4i_tcon.c | 20 +++++++++++---------
> > > > > > > > drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h | 2 --
> > > > > > > > 2 files changed, 11 insertions(+), 11 deletions(-)
> > > > > > > >
> > > > > > > > diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c
> > > > > > > > b/drivers/gpu/drm/sun4i/sun4i_tcon.c
> > > > > > > > index 64c43ee6bd92..42560d5c327c 100644
> > > > > > > > --- a/drivers/gpu/drm/sun4i/sun4i_tcon.c
> > > > > > > > +++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c
> > > > > > > > @@ -263,10 +263,11 @@ static int sun4i_tcon_get_clk_delay(const struct
> > > > > > > > drm_display_mode *mode,
> > > > > > > > }
> > > > > > > >
> > > > > > > > static void sun4i_tcon0_mode_set_common(struct sun4i_tcon *tcon,
> > > > > > > > - const struct drm_display_mode *mode)
> > > > > > > > + const struct drm_display_mode *mode,
> > > > > > > > + u32 tcon_mul)
> > > > > > > > {
> > > > > > > > /* Configure the dot clock */
> > > > > > > > - clk_set_rate(tcon->dclk, mode->crtc_clock * 1000);
> > > > > > > > + clk_set_rate(tcon->dclk, mode->crtc_clock * tcon_mul * 1000);
> > > > > > > >
> > > > > > > > /* Set the resolution */
> > > > > > > > regmap_write(tcon->regs, SUN4I_TCON0_BASIC0_REG,
> > > > > > > > @@ -335,12 +336,13 @@ static void sun4i_tcon0_mode_set_cpu(struct
> > > > > > > > sun4i_tcon *tcon,
> > > > > > > > u8 bpp = mipi_dsi_pixel_format_to_bpp(device->format);
> > > > > > > > u8 lanes = device->lanes;
> > > > > > > > u32 block_space, start_delay;
> > > > > > > > - u32 tcon_div;
> > > > > > > > + u32 tcon_div, tcon_mul;
> > > > > > > >
> > > > > > > > - tcon->dclk_min_div = SUN6I_DSI_TCON_DIV;
> > > > > > > > - tcon->dclk_max_div = SUN6I_DSI_TCON_DIV;
> > > > > > > > + tcon->dclk_min_div = 4;
> > > > > > > > + tcon->dclk_max_div = 127;
> > > > > > > >
> > > > > > > > - sun4i_tcon0_mode_set_common(tcon, mode);
> > > > > > > > + tcon_mul = bpp / lanes;
> > > > > > > > + sun4i_tcon0_mode_set_common(tcon, mode, tcon_mul);
> > > > > > > >
> > > > > > > > /* Set dithering if needed */
> > > > > > > > sun4i_tcon0_mode_set_dithering(tcon, sun4i_tcon_get_connector(encoder));
> > > > > > > > @@ -366,7 +368,7 @@ static void sun4i_tcon0_mode_set_cpu(struct
> > > > > > > > sun4i_tcon *tcon,
> > > > > > > > */
> > > > > > > > regmap_read(tcon->regs, SUN4I_TCON0_DCLK_REG, &tcon_div);
> > > > > > > > tcon_div &= GENMASK(6, 0);
> > > > > > > > - block_space = mode->htotal * bpp / (tcon_div * lanes);
> > > > > > > > + block_space = mode->htotal * tcon_div * tcon_mul;
> > > > > > > > block_space -= mode->hdisplay + 40;
> > > > > > > >
> > > > > > > > regmap_write(tcon->regs, SUN4I_TCON0_CPU_TRI0_REG,
> > > > > > > > @@ -408,7 +410,7 @@ static void sun4i_tcon0_mode_set_lvds(struct
> > > > > > > > sun4i_tcon *tcon,
> > > > > > > >
> > > > > > > > tcon->dclk_min_div = 7;
> > > > > > > > tcon->dclk_max_div = 7;
> > > > > > > > - sun4i_tcon0_mode_set_common(tcon, mode);
> > > > > > > > + sun4i_tcon0_mode_set_common(tcon, mode, 1);
> > > > > > > >
> > > > > > > > /* Set dithering if needed */
> > > > > > > > sun4i_tcon0_mode_set_dithering(tcon, sun4i_tcon_get_connector(encoder));
> > > > > > > > @@ -487,7 +489,7 @@ static void sun4i_tcon0_mode_set_rgb(struct
> > > > > > > > sun4i_tcon *tcon,
> > > > > > > >
> > > > > > > > tcon->dclk_min_div = 6;
> > > > > > > > tcon->dclk_max_div = 127;
> > > > > > > > - sun4i_tcon0_mode_set_common(tcon, mode);
> > > > > > > > + sun4i_tcon0_mode_set_common(tcon, mode, 1);
> > > > > > > >
> > > > > > > > /* Set dithering if needed */
> > > > > > > > sun4i_tcon0_mode_set_dithering(tcon, connector);
> > > > > > > > diff --git a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h
> > > > > > > > b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h
> > > > > > > > index 5c3ad5be0690..a07090579f84 100644
> > > > > > > > --- a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h
> > > > > > > > +++ b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h
> > > > > > > > @@ -13,8 +13,6 @@
> > > > > > > > #include <drm/drm_encoder.h>
> > > > > > > > #include <drm/drm_mipi_dsi.h>
> > > > > > > >
> > > > > > > > -#define SUN6I_DSI_TCON_DIV 4
> > > > > > > > -
> > > > > > > > struct sun6i_dsi {
> > > > > > > > struct drm_connector connector;
> > > > > > > > struct drm_encoder encoder;
> > > > > > >
> > > > > > > I had more something like this in mind:
> > > > > > > http://code.bulix.org/nlp5a4-803511
> > > > > >
> > > > > > Worth to look at it. was it working on your panel? meanwhile I will check it.
> > > > >
> > > > > I haven't tested it.
> > > > >
> > > > > > We have updated with below change [1], seems working on but is
> > > > > > actually checking the each divider as before start with 4... till 127.
> > > > > >
> > > > > > This new approach, is start looking the best divider from 4.. based on
> > > > > > the idea vs rounded it will ended up best divider like [2]
> > > > >
> > > > > But why?
> > > > >
> > > > > I mean, it's not like it's the first time I'm asking this...
> > > > >
> > > > > If the issue is what Micheal described, then the divider has nothing
> > > > > to do with it. We've had that discussion over and over again.
> > > >
> > > > This is what Michael is mentioned in above mail "tcon-pixel clock is
> > > > the rate that you want to achive on display side and if you have 4
> > > > lanes 32bit or lanes and different bit number that you need to have
> > > > a clock that is able to put outside bits and speed equal to
> > > > pixel-clock * bits / lanes. so If you want a pixel-clock of 40 mhz
> > > > and you have 32bits and 4 lanes you need to have a clock of 40 * 32
> > > > / 4 in no-burst mode. "
> > >
> > > Yeah, so we need to change the clock rate.
> > >
> > > > He is trying to manage the bpp/lanes into dclk_mul (in last mail)
> > > > and it can multiply with pixel clock which is rate argument in
> > > > sun4i_dclk_round_rate.
> > > >
> > > > The solution I have mentioned in dclk_min, max is bpp/lanes also
> > > > multiple rate in dotclock sun4i_dclk_round_rate.
> > > >
> > > > In both cases the overall pll_rate depends on dividers, the one that I
> > > > have on this patch is based on BSP and the Michael one is more generic
> > > > way so-that it can not to touch other functionalities and looping
> > > > dividers to find the best one.
> > > >
> > > > If dclk_min/max is bpp/lanes then dotclock directly using divider 6
> > > > (assuming 24-bit and 4 lanes) and return the pll_rate and divider 6
> > > > associated.
> > > >
> > > > if dclk_mul is bpp/lanes, on Michael new change, the dividers start
> > > > with 4 and end with 127 but the constant ideal rate which rate *
> > > > bpp/lanes but the loop from sun4i_dclk_round_rate computed the divider
> > > > as 6 only, ie what I'm mentioned on the above mail.
> > >
> > > We've been over this a couple of times already.
> > >
> > > The clock is generated like this:
> > >
> > > PLL -> TCON Module Clock -> TCON DCLK
> > >
> > > You want the TCON DCLK to be at the pixel clock rate * bpp /
> > > lanes. Fine, that makes sense.
> > >
> > > Except that the patch you've sent, instead of changing the rate
> > > itself, changes the ratio between the module clock and DCLK.
> > >
> > > And this is where the issue lies. First, from a logical viewpoint, it
> > > doesn't make sense. If you want to change the clock rate, then just do
> > > it. Don't hack around the multipliers trying to fall back to something
> > > that works for you.
> > >
> > > Then, the ratio itself needs to be set to 4. This is the part that
> > > we've discussed way too many times already, but in the Allwinner BSP,
> > > that ratio is hardcoded to 4, and we've had panels that need it at
> > > that value.
> > >
> > > So, what you want to do is to have:
> > >
> > > TCON DCLK = pixel clock * bpp / lanes
> > > TCON Module Clock = DCLK * 4
> > > PLL = Module Clock * Module Clock Divider (which I believe is 1 in most cases)
> >
> > pll-mipi 1 1 1 178200000
> > 0 0 50000
> > tcon0 2 2 1 178200000
> > 0 0 50000
> > tcon-pixel-clock 1 1 1 29700000
> > 0 0 50000
>
> Is this before or after your patches?
>
This is just an example of clock tree to be clear to everyone how they
are connected
> > This is an english problem from my side:
> > tcon-pixel-clock is DCLK
> > tcon0 must be tcon-pixel-clock * bpp / lanes, because the logic need to
> > put a bit every cycle.
>
> Again, I'm not saying this is wrong, but each time I've looked at it
> the BSP was using a 4 divider between the tcon module clock and the
> dotclock.
>
We have tested on 4-5 displays. Well I don't care on bsp but I care
about if it works
and if other SoC has similar approach on clock calculation.
> So, please prove me wrong here.
>
Having only 10 pages of documentation is a bit difficult.
> > One solution can be:
> > - set_rate_exclusive to tcon0 and calculate as display pixel clock *
> > bpp / lanes
>
> I'm not sure what set_rate_exclusive has to do with it. I mean, it's a
> good idea to use it, but it shouldn't really change anything to the
> discussion.
Well, this will just do a minimal change on source code and put the constrains
to the tcon0
>
> > - calculate the tcon-pixel-clock using all divider
>
> I'm not sure what you mean by that.
>
> > Problem is that the function that calculate tcon-pixel-clock does not
> > have any constrain on the ideal value.
>
> It does have constraints, but you're right that it will not try to
> find an exact match and bail out if it can't do it, but will find the
> closest match.
>
We need to find the closest divider that match the pixel clock and be close
to the ideal tcon0 rate.
> > What you are suggesting is not correct in my opinion or I'm not
> > following your suggesstion.
>
> Then prove me wrong.
>
> > What I know is that if we have a pixel-clock of dvi display of 50Mhz
> > and we have 4 lanes 32bit we need a clock in the logic of 400Mhz
> > (this is the ideal throughtput).
> > So tcon-pixel-clock is 50mhz and tcon0 is 400Mhz.
>
> There's one thing to keep in mind though. The TCON dotclock in the
> MIPI-DSI case isn't directly tied to the Bit Clock, it's simply an
> internal clock in the pipeline to feed the FIFO of the MIPI-DSI
> controller. The MIPI-DSI controller itself will generate that clock,
> and only that one will have those constraints.
>
I have done the same thinking but because it works for us seems that
somehow is used
to internal logic too
Michael
> Maxime
>
> --
> Maxime Ripard, Bootlin
> Embedded Linux and Kernel engineering
> https://bootlin.com
--
| Michael Nazzareno Trimarchi Amarula Solutions BV |
| COO - Founder Cruquiuskade 47 |
| +31(0)851119172 Amsterdam 1018 AM NL |
| [`as] http://www.amarulasolutions.com |
Hi,
On Thu, Aug 15, 2019 at 02:25:57PM +0200, Michael Nazzareno Trimarchi wrote:
> On Tue, Aug 13, 2019 at 8:05 AM Maxime Ripard <[email protected]> wrote:
> > On Mon, Jul 29, 2019 at 08:59:04AM +0200, Michael Nazzareno Trimarchi wrote:
> > > Hi
> > >
> > > On Wed, Jul 24, 2019 at 11:05 AM Maxime Ripard
> > > <[email protected]> wrote:
> > > >
> > > > On Mon, Jul 22, 2019 at 03:51:04PM +0530, Jagan Teki wrote:
> > > > > Hi Maxime,
> > > > >
> > > > > On Sat, Jul 20, 2019 at 3:02 PM Maxime Ripard <[email protected]> wrote:
> > > > > >
> > > > > > On Sat, Jul 20, 2019 at 12:46:27PM +0530, Jagan Teki wrote:
> > > > > > > On Sat, Jul 20, 2019 at 12:28 PM Maxime Ripard
> > > > > > > <[email protected]> wrote:
> > > > > > > >
> > > > > > > > On Thu, Jul 11, 2019 at 07:43:16PM +0200, Michael Nazzareno Trimarchi wrote:
> > > > > > > > > > > tcon-pixel clock is the rate that you want to achive on display side
> > > > > > > > > > > and if you have 4 lanes 32bit or lanes and different bit number that
> > > > > > > > > > > you need to have a clock that is able to put outside bits and speed
> > > > > > > > > > > equal to pixel-clock * bits / lanes. so If you want a pixel-clock of
> > > > > > > > > > > 40 mhz and you have 32bits and 4 lanes you need to have a clock of
> > > > > > > > > > > 40 * 32 / 4 in no-burst mode. I think that this is done but most of
> > > > > > > > > > > the display.
> > > > > > > > > >
> > > > > > > > > > So this is what the issue is then?
> > > > > > > > > >
> > > > > > > > > > This one does make sense, and you should just change the rate in the
> > > > > > > > > > call to clk_set_rate in sun4i_tcon0_mode_set_cpu.
> > > > > > > > > >
> > > > > > > > > > I'm still wondering why that hasn't been brought up in either the
> > > > > > > > > > discussion or the commit log before though.
> > > > > > > > > >
> > > > > > > > > Something like this?
> > > > > > > > >
> > > > > > > > > drivers/gpu/drm/sun4i/sun4i_tcon.c | 20 +++++++++++---------
> > > > > > > > > drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h | 2 --
> > > > > > > > > 2 files changed, 11 insertions(+), 11 deletions(-)
> > > > > > > > >
> > > > > > > > > diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c
> > > > > > > > > b/drivers/gpu/drm/sun4i/sun4i_tcon.c
> > > > > > > > > index 64c43ee6bd92..42560d5c327c 100644
> > > > > > > > > --- a/drivers/gpu/drm/sun4i/sun4i_tcon.c
> > > > > > > > > +++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c
> > > > > > > > > @@ -263,10 +263,11 @@ static int sun4i_tcon_get_clk_delay(const struct
> > > > > > > > > drm_display_mode *mode,
> > > > > > > > > }
> > > > > > > > >
> > > > > > > > > static void sun4i_tcon0_mode_set_common(struct sun4i_tcon *tcon,
> > > > > > > > > - const struct drm_display_mode *mode)
> > > > > > > > > + const struct drm_display_mode *mode,
> > > > > > > > > + u32 tcon_mul)
> > > > > > > > > {
> > > > > > > > > /* Configure the dot clock */
> > > > > > > > > - clk_set_rate(tcon->dclk, mode->crtc_clock * 1000);
> > > > > > > > > + clk_set_rate(tcon->dclk, mode->crtc_clock * tcon_mul * 1000);
> > > > > > > > >
> > > > > > > > > /* Set the resolution */
> > > > > > > > > regmap_write(tcon->regs, SUN4I_TCON0_BASIC0_REG,
> > > > > > > > > @@ -335,12 +336,13 @@ static void sun4i_tcon0_mode_set_cpu(struct
> > > > > > > > > sun4i_tcon *tcon,
> > > > > > > > > u8 bpp = mipi_dsi_pixel_format_to_bpp(device->format);
> > > > > > > > > u8 lanes = device->lanes;
> > > > > > > > > u32 block_space, start_delay;
> > > > > > > > > - u32 tcon_div;
> > > > > > > > > + u32 tcon_div, tcon_mul;
> > > > > > > > >
> > > > > > > > > - tcon->dclk_min_div = SUN6I_DSI_TCON_DIV;
> > > > > > > > > - tcon->dclk_max_div = SUN6I_DSI_TCON_DIV;
> > > > > > > > > + tcon->dclk_min_div = 4;
> > > > > > > > > + tcon->dclk_max_div = 127;
> > > > > > > > >
> > > > > > > > > - sun4i_tcon0_mode_set_common(tcon, mode);
> > > > > > > > > + tcon_mul = bpp / lanes;
> > > > > > > > > + sun4i_tcon0_mode_set_common(tcon, mode, tcon_mul);
> > > > > > > > >
> > > > > > > > > /* Set dithering if needed */
> > > > > > > > > sun4i_tcon0_mode_set_dithering(tcon, sun4i_tcon_get_connector(encoder));
> > > > > > > > > @@ -366,7 +368,7 @@ static void sun4i_tcon0_mode_set_cpu(struct
> > > > > > > > > sun4i_tcon *tcon,
> > > > > > > > > */
> > > > > > > > > regmap_read(tcon->regs, SUN4I_TCON0_DCLK_REG, &tcon_div);
> > > > > > > > > tcon_div &= GENMASK(6, 0);
> > > > > > > > > - block_space = mode->htotal * bpp / (tcon_div * lanes);
> > > > > > > > > + block_space = mode->htotal * tcon_div * tcon_mul;
> > > > > > > > > block_space -= mode->hdisplay + 40;
> > > > > > > > >
> > > > > > > > > regmap_write(tcon->regs, SUN4I_TCON0_CPU_TRI0_REG,
> > > > > > > > > @@ -408,7 +410,7 @@ static void sun4i_tcon0_mode_set_lvds(struct
> > > > > > > > > sun4i_tcon *tcon,
> > > > > > > > >
> > > > > > > > > tcon->dclk_min_div = 7;
> > > > > > > > > tcon->dclk_max_div = 7;
> > > > > > > > > - sun4i_tcon0_mode_set_common(tcon, mode);
> > > > > > > > > + sun4i_tcon0_mode_set_common(tcon, mode, 1);
> > > > > > > > >
> > > > > > > > > /* Set dithering if needed */
> > > > > > > > > sun4i_tcon0_mode_set_dithering(tcon, sun4i_tcon_get_connector(encoder));
> > > > > > > > > @@ -487,7 +489,7 @@ static void sun4i_tcon0_mode_set_rgb(struct
> > > > > > > > > sun4i_tcon *tcon,
> > > > > > > > >
> > > > > > > > > tcon->dclk_min_div = 6;
> > > > > > > > > tcon->dclk_max_div = 127;
> > > > > > > > > - sun4i_tcon0_mode_set_common(tcon, mode);
> > > > > > > > > + sun4i_tcon0_mode_set_common(tcon, mode, 1);
> > > > > > > > >
> > > > > > > > > /* Set dithering if needed */
> > > > > > > > > sun4i_tcon0_mode_set_dithering(tcon, connector);
> > > > > > > > > diff --git a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h
> > > > > > > > > b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h
> > > > > > > > > index 5c3ad5be0690..a07090579f84 100644
> > > > > > > > > --- a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h
> > > > > > > > > +++ b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h
> > > > > > > > > @@ -13,8 +13,6 @@
> > > > > > > > > #include <drm/drm_encoder.h>
> > > > > > > > > #include <drm/drm_mipi_dsi.h>
> > > > > > > > >
> > > > > > > > > -#define SUN6I_DSI_TCON_DIV 4
> > > > > > > > > -
> > > > > > > > > struct sun6i_dsi {
> > > > > > > > > struct drm_connector connector;
> > > > > > > > > struct drm_encoder encoder;
> > > > > > > >
> > > > > > > > I had more something like this in mind:
> > > > > > > > http://code.bulix.org/nlp5a4-803511
> > > > > > >
> > > > > > > Worth to look at it. was it working on your panel? meanwhile I will check it.
> > > > > >
> > > > > > I haven't tested it.
> > > > > >
> > > > > > > We have updated with below change [1], seems working on but is
> > > > > > > actually checking the each divider as before start with 4... till 127.
> > > > > > >
> > > > > > > This new approach, is start looking the best divider from 4.. based on
> > > > > > > the idea vs rounded it will ended up best divider like [2]
> > > > > >
> > > > > > But why?
> > > > > >
> > > > > > I mean, it's not like it's the first time I'm asking this...
> > > > > >
> > > > > > If the issue is what Micheal described, then the divider has nothing
> > > > > > to do with it. We've had that discussion over and over again.
> > > > >
> > > > > This is what Michael is mentioned in above mail "tcon-pixel clock is
> > > > > the rate that you want to achive on display side and if you have 4
> > > > > lanes 32bit or lanes and different bit number that you need to have
> > > > > a clock that is able to put outside bits and speed equal to
> > > > > pixel-clock * bits / lanes. so If you want a pixel-clock of 40 mhz
> > > > > and you have 32bits and 4 lanes you need to have a clock of 40 * 32
> > > > > / 4 in no-burst mode. "
> > > >
> > > > Yeah, so we need to change the clock rate.
> > > >
> > > > > He is trying to manage the bpp/lanes into dclk_mul (in last mail)
> > > > > and it can multiply with pixel clock which is rate argument in
> > > > > sun4i_dclk_round_rate.
> > > > >
> > > > > The solution I have mentioned in dclk_min, max is bpp/lanes also
> > > > > multiple rate in dotclock sun4i_dclk_round_rate.
> > > > >
> > > > > In both cases the overall pll_rate depends on dividers, the one that I
> > > > > have on this patch is based on BSP and the Michael one is more generic
> > > > > way so-that it can not to touch other functionalities and looping
> > > > > dividers to find the best one.
> > > > >
> > > > > If dclk_min/max is bpp/lanes then dotclock directly using divider 6
> > > > > (assuming 24-bit and 4 lanes) and return the pll_rate and divider 6
> > > > > associated.
> > > > >
> > > > > if dclk_mul is bpp/lanes, on Michael new change, the dividers start
> > > > > with 4 and end with 127 but the constant ideal rate which rate *
> > > > > bpp/lanes but the loop from sun4i_dclk_round_rate computed the divider
> > > > > as 6 only, ie what I'm mentioned on the above mail.
> > > >
> > > > We've been over this a couple of times already.
> > > >
> > > > The clock is generated like this:
> > > >
> > > > PLL -> TCON Module Clock -> TCON DCLK
> > > >
> > > > You want the TCON DCLK to be at the pixel clock rate * bpp /
> > > > lanes. Fine, that makes sense.
> > > >
> > > > Except that the patch you've sent, instead of changing the rate
> > > > itself, changes the ratio between the module clock and DCLK.
> > > >
> > > > And this is where the issue lies. First, from a logical viewpoint, it
> > > > doesn't make sense. If you want to change the clock rate, then just do
> > > > it. Don't hack around the multipliers trying to fall back to something
> > > > that works for you.
> > > >
> > > > Then, the ratio itself needs to be set to 4. This is the part that
> > > > we've discussed way too many times already, but in the Allwinner BSP,
> > > > that ratio is hardcoded to 4, and we've had panels that need it at
> > > > that value.
> > > >
> > > > So, what you want to do is to have:
> > > >
> > > > TCON DCLK = pixel clock * bpp / lanes
> > > > TCON Module Clock = DCLK * 4
> > > > PLL = Module Clock * Module Clock Divider (which I believe is 1 in most cases)
> > >
> > > pll-mipi 1 1 1 178200000
> > > 0 0 50000
> > > tcon0 2 2 1 178200000
> > > 0 0 50000
> > > tcon-pixel-clock 1 1 1 29700000
> > > 0 0 50000
> >
> > Is this before or after your patches?
> >
>
> This is just an example of clock tree to be clear to everyone how they
> are connected
>
> > > This is an english problem from my side:
> > > tcon-pixel-clock is DCLK
> > > tcon0 must be tcon-pixel-clock * bpp / lanes, because the logic need to
> > > put a bit every cycle.
> >
> > Again, I'm not saying this is wrong, but each time I've looked at it
> > the BSP was using a 4 divider between the tcon module clock and the
> > dotclock.
>
> We have tested on 4-5 displays. Well I don't care on bsp but I care
> about if it works and if other SoC has similar approach on clock
> calculation.
Well, it's also breaking another panel.
> > So, please prove me wrong here.
>
> Having only 10 pages of documentation is a bit difficult.
The BSP source code will be a fine example too.
> > > One solution can be:
> > > - set_rate_exclusive to tcon0 and calculate as display pixel clock *
> > > bpp / lanes
> >
> > I'm not sure what set_rate_exclusive has to do with it. I mean, it's a
> > good idea to use it, but it shouldn't really change anything to the
> > discussion.
>
> Well, this will just do a minimal change on source code and put the constrains
> to the tcon0
I agree, but again, this has nothing to do with the current discussion.
Maxime
--
Maxime Ripard, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
Hi Maxime
On Wed, Aug 28, 2019 at 3:03 PM Maxime Ripard <[email protected]> wrote:
>
> Hi,
>
> On Thu, Aug 15, 2019 at 02:25:57PM +0200, Michael Nazzareno Trimarchi wrote:
> > On Tue, Aug 13, 2019 at 8:05 AM Maxime Ripard <[email protected]> wrote:
> > > On Mon, Jul 29, 2019 at 08:59:04AM +0200, Michael Nazzareno Trimarchi wrote:
> > > > Hi
> > > >
> > > > On Wed, Jul 24, 2019 at 11:05 AM Maxime Ripard
> > > > <[email protected]> wrote:
> > > > >
> > > > > On Mon, Jul 22, 2019 at 03:51:04PM +0530, Jagan Teki wrote:
> > > > > > Hi Maxime,
> > > > > >
> > > > > > On Sat, Jul 20, 2019 at 3:02 PM Maxime Ripard <[email protected]> wrote:
> > > > > > >
> > > > > > > On Sat, Jul 20, 2019 at 12:46:27PM +0530, Jagan Teki wrote:
> > > > > > > > On Sat, Jul 20, 2019 at 12:28 PM Maxime Ripard
> > > > > > > > <[email protected]> wrote:
> > > > > > > > >
> > > > > > > > > On Thu, Jul 11, 2019 at 07:43:16PM +0200, Michael Nazzareno Trimarchi wrote:
> > > > > > > > > > > > tcon-pixel clock is the rate that you want to achive on display side
> > > > > > > > > > > > and if you have 4 lanes 32bit or lanes and different bit number that
> > > > > > > > > > > > you need to have a clock that is able to put outside bits and speed
> > > > > > > > > > > > equal to pixel-clock * bits / lanes. so If you want a pixel-clock of
> > > > > > > > > > > > 40 mhz and you have 32bits and 4 lanes you need to have a clock of
> > > > > > > > > > > > 40 * 32 / 4 in no-burst mode. I think that this is done but most of
> > > > > > > > > > > > the display.
> > > > > > > > > > >
> > > > > > > > > > > So this is what the issue is then?
> > > > > > > > > > >
> > > > > > > > > > > This one does make sense, and you should just change the rate in the
> > > > > > > > > > > call to clk_set_rate in sun4i_tcon0_mode_set_cpu.
> > > > > > > > > > >
> > > > > > > > > > > I'm still wondering why that hasn't been brought up in either the
> > > > > > > > > > > discussion or the commit log before though.
> > > > > > > > > > >
> > > > > > > > > > Something like this?
> > > > > > > > > >
> > > > > > > > > > drivers/gpu/drm/sun4i/sun4i_tcon.c | 20 +++++++++++---------
> > > > > > > > > > drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h | 2 --
> > > > > > > > > > 2 files changed, 11 insertions(+), 11 deletions(-)
> > > > > > > > > >
> > > > > > > > > > diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c
> > > > > > > > > > b/drivers/gpu/drm/sun4i/sun4i_tcon.c
> > > > > > > > > > index 64c43ee6bd92..42560d5c327c 100644
> > > > > > > > > > --- a/drivers/gpu/drm/sun4i/sun4i_tcon.c
> > > > > > > > > > +++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c
> > > > > > > > > > @@ -263,10 +263,11 @@ static int sun4i_tcon_get_clk_delay(const struct
> > > > > > > > > > drm_display_mode *mode,
> > > > > > > > > > }
> > > > > > > > > >
> > > > > > > > > > static void sun4i_tcon0_mode_set_common(struct sun4i_tcon *tcon,
> > > > > > > > > > - const struct drm_display_mode *mode)
> > > > > > > > > > + const struct drm_display_mode *mode,
> > > > > > > > > > + u32 tcon_mul)
> > > > > > > > > > {
> > > > > > > > > > /* Configure the dot clock */
> > > > > > > > > > - clk_set_rate(tcon->dclk, mode->crtc_clock * 1000);
> > > > > > > > > > + clk_set_rate(tcon->dclk, mode->crtc_clock * tcon_mul * 1000);
> > > > > > > > > >
> > > > > > > > > > /* Set the resolution */
> > > > > > > > > > regmap_write(tcon->regs, SUN4I_TCON0_BASIC0_REG,
> > > > > > > > > > @@ -335,12 +336,13 @@ static void sun4i_tcon0_mode_set_cpu(struct
> > > > > > > > > > sun4i_tcon *tcon,
> > > > > > > > > > u8 bpp = mipi_dsi_pixel_format_to_bpp(device->format);
> > > > > > > > > > u8 lanes = device->lanes;
> > > > > > > > > > u32 block_space, start_delay;
> > > > > > > > > > - u32 tcon_div;
> > > > > > > > > > + u32 tcon_div, tcon_mul;
> > > > > > > > > >
> > > > > > > > > > - tcon->dclk_min_div = SUN6I_DSI_TCON_DIV;
> > > > > > > > > > - tcon->dclk_max_div = SUN6I_DSI_TCON_DIV;
> > > > > > > > > > + tcon->dclk_min_div = 4;
> > > > > > > > > > + tcon->dclk_max_div = 127;
> > > > > > > > > >
> > > > > > > > > > - sun4i_tcon0_mode_set_common(tcon, mode);
> > > > > > > > > > + tcon_mul = bpp / lanes;
> > > > > > > > > > + sun4i_tcon0_mode_set_common(tcon, mode, tcon_mul);
> > > > > > > > > >
> > > > > > > > > > /* Set dithering if needed */
> > > > > > > > > > sun4i_tcon0_mode_set_dithering(tcon, sun4i_tcon_get_connector(encoder));
> > > > > > > > > > @@ -366,7 +368,7 @@ static void sun4i_tcon0_mode_set_cpu(struct
> > > > > > > > > > sun4i_tcon *tcon,
> > > > > > > > > > */
> > > > > > > > > > regmap_read(tcon->regs, SUN4I_TCON0_DCLK_REG, &tcon_div);
> > > > > > > > > > tcon_div &= GENMASK(6, 0);
> > > > > > > > > > - block_space = mode->htotal * bpp / (tcon_div * lanes);
> > > > > > > > > > + block_space = mode->htotal * tcon_div * tcon_mul;
> > > > > > > > > > block_space -= mode->hdisplay + 40;
> > > > > > > > > >
> > > > > > > > > > regmap_write(tcon->regs, SUN4I_TCON0_CPU_TRI0_REG,
> > > > > > > > > > @@ -408,7 +410,7 @@ static void sun4i_tcon0_mode_set_lvds(struct
> > > > > > > > > > sun4i_tcon *tcon,
> > > > > > > > > >
> > > > > > > > > > tcon->dclk_min_div = 7;
> > > > > > > > > > tcon->dclk_max_div = 7;
> > > > > > > > > > - sun4i_tcon0_mode_set_common(tcon, mode);
> > > > > > > > > > + sun4i_tcon0_mode_set_common(tcon, mode, 1);
> > > > > > > > > >
> > > > > > > > > > /* Set dithering if needed */
> > > > > > > > > > sun4i_tcon0_mode_set_dithering(tcon, sun4i_tcon_get_connector(encoder));
> > > > > > > > > > @@ -487,7 +489,7 @@ static void sun4i_tcon0_mode_set_rgb(struct
> > > > > > > > > > sun4i_tcon *tcon,
> > > > > > > > > >
> > > > > > > > > > tcon->dclk_min_div = 6;
> > > > > > > > > > tcon->dclk_max_div = 127;
> > > > > > > > > > - sun4i_tcon0_mode_set_common(tcon, mode);
> > > > > > > > > > + sun4i_tcon0_mode_set_common(tcon, mode, 1);
> > > > > > > > > >
> > > > > > > > > > /* Set dithering if needed */
> > > > > > > > > > sun4i_tcon0_mode_set_dithering(tcon, connector);
> > > > > > > > > > diff --git a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h
> > > > > > > > > > b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h
> > > > > > > > > > index 5c3ad5be0690..a07090579f84 100644
> > > > > > > > > > --- a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h
> > > > > > > > > > +++ b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h
> > > > > > > > > > @@ -13,8 +13,6 @@
> > > > > > > > > > #include <drm/drm_encoder.h>
> > > > > > > > > > #include <drm/drm_mipi_dsi.h>
> > > > > > > > > >
> > > > > > > > > > -#define SUN6I_DSI_TCON_DIV 4
> > > > > > > > > > -
> > > > > > > > > > struct sun6i_dsi {
> > > > > > > > > > struct drm_connector connector;
> > > > > > > > > > struct drm_encoder encoder;
> > > > > > > > >
> > > > > > > > > I had more something like this in mind:
> > > > > > > > > http://code.bulix.org/nlp5a4-803511
> > > > > > > >
> > > > > > > > Worth to look at it. was it working on your panel? meanwhile I will check it.
> > > > > > >
> > > > > > > I haven't tested it.
> > > > > > >
> > > > > > > > We have updated with below change [1], seems working on but is
> > > > > > > > actually checking the each divider as before start with 4... till 127.
> > > > > > > >
> > > > > > > > This new approach, is start looking the best divider from 4.. based on
> > > > > > > > the idea vs rounded it will ended up best divider like [2]
> > > > > > >
> > > > > > > But why?
> > > > > > >
> > > > > > > I mean, it's not like it's the first time I'm asking this...
> > > > > > >
> > > > > > > If the issue is what Micheal described, then the divider has nothing
> > > > > > > to do with it. We've had that discussion over and over again.
> > > > > >
> > > > > > This is what Michael is mentioned in above mail "tcon-pixel clock is
> > > > > > the rate that you want to achive on display side and if you have 4
> > > > > > lanes 32bit or lanes and different bit number that you need to have
> > > > > > a clock that is able to put outside bits and speed equal to
> > > > > > pixel-clock * bits / lanes. so If you want a pixel-clock of 40 mhz
> > > > > > and you have 32bits and 4 lanes you need to have a clock of 40 * 32
> > > > > > / 4 in no-burst mode. "
> > > > >
> > > > > Yeah, so we need to change the clock rate.
> > > > >
> > > > > > He is trying to manage the bpp/lanes into dclk_mul (in last mail)
> > > > > > and it can multiply with pixel clock which is rate argument in
> > > > > > sun4i_dclk_round_rate.
> > > > > >
> > > > > > The solution I have mentioned in dclk_min, max is bpp/lanes also
> > > > > > multiple rate in dotclock sun4i_dclk_round_rate.
> > > > > >
> > > > > > In both cases the overall pll_rate depends on dividers, the one that I
> > > > > > have on this patch is based on BSP and the Michael one is more generic
> > > > > > way so-that it can not to touch other functionalities and looping
> > > > > > dividers to find the best one.
> > > > > >
> > > > > > If dclk_min/max is bpp/lanes then dotclock directly using divider 6
> > > > > > (assuming 24-bit and 4 lanes) and return the pll_rate and divider 6
> > > > > > associated.
> > > > > >
> > > > > > if dclk_mul is bpp/lanes, on Michael new change, the dividers start
> > > > > > with 4 and end with 127 but the constant ideal rate which rate *
> > > > > > bpp/lanes but the loop from sun4i_dclk_round_rate computed the divider
> > > > > > as 6 only, ie what I'm mentioned on the above mail.
> > > > >
> > > > > We've been over this a couple of times already.
> > > > >
> > > > > The clock is generated like this:
> > > > >
> > > > > PLL -> TCON Module Clock -> TCON DCLK
> > > > >
> > > > > You want the TCON DCLK to be at the pixel clock rate * bpp /
> > > > > lanes. Fine, that makes sense.
> > > > >
> > > > > Except that the patch you've sent, instead of changing the rate
> > > > > itself, changes the ratio between the module clock and DCLK.
> > > > >
> > > > > And this is where the issue lies. First, from a logical viewpoint, it
> > > > > doesn't make sense. If you want to change the clock rate, then just do
> > > > > it. Don't hack around the multipliers trying to fall back to something
> > > > > that works for you.
> > > > >
> > > > > Then, the ratio itself needs to be set to 4. This is the part that
> > > > > we've discussed way too many times already, but in the Allwinner BSP,
> > > > > that ratio is hardcoded to 4, and we've had panels that need it at
> > > > > that value.
> > > > >
> > > > > So, what you want to do is to have:
> > > > >
> > > > > TCON DCLK = pixel clock * bpp / lanes
> > > > > TCON Module Clock = DCLK * 4
> > > > > PLL = Module Clock * Module Clock Divider (which I believe is 1 in most cases)
> > > >
> > > > pll-mipi 1 1 1 178200000
> > > > 0 0 50000
> > > > tcon0 2 2 1 178200000
> > > > 0 0 50000
> > > > tcon-pixel-clock 1 1 1 29700000
> > > > 0 0 50000
> > >
> > > Is this before or after your patches?
> > >
> >
> > This is just an example of clock tree to be clear to everyone how they
> > are connected
> >
> > > > This is an english problem from my side:
> > > > tcon-pixel-clock is DCLK
> > > > tcon0 must be tcon-pixel-clock * bpp / lanes, because the logic need to
> > > > put a bit every cycle.
> > >
> > > Again, I'm not saying this is wrong, but each time I've looked at it
> > > the BSP was using a 4 divider between the tcon module clock and the
> > > dotclock.
> >
> > We have tested on 4-5 displays. Well I don't care on bsp but I care
> > about if it works and if other SoC has similar approach on clock
> > calculation.
>
> Well, it's also breaking another panel.
>
Agree but I need to have the panel. Do you know if we have users of this panel?
I don't want to break the users off course. Can I have your clk_tree
dbg of your devices
the panel datasheet?
> > > So, please prove me wrong here.
> >
> > Having only 10 pages of documentation is a bit difficult.
>
> The BSP source code will be a fine example too.
>
Do you have any contact in allwinner?
Let's be this last email, I don't want to bother the people more.
After I get the panel
info and datasheet I will come back if I found a solution that does not break it
Michael
> > > > One solution can be:
> > > > - set_rate_exclusive to tcon0 and calculate as display pixel clock *
> > > > bpp / lanes
> > >
> > > I'm not sure what set_rate_exclusive has to do with it. I mean, it's a
> > > good idea to use it, but it shouldn't really change anything to the
> > > discussion.
> >
> > Well, this will just do a minimal change on source code and put the constrains
> > to the tcon0
>
> I agree, but again, this has nothing to do with the current discussion.
>
> Maxime
>
> --
> Maxime Ripard, Bootlin
> Embedded Linux and Kernel engineering
> https://bootlin.com
--
| Michael Nazzareno Trimarchi Amarula Solutions BV |
| COO - Founder Cruquiuskade 47 |
| +31(0)851119172 Amsterdam 1018 AM NL |
| [`as] http://www.amarulasolutions.com |