2023-12-22 17:42:34

by Alex Bee

[permalink] [raw]
Subject: [PATCH v4 00/29] Add HDMI support for RK3128

This is version 4 of my series that aims to add support for the display
controller (VOP) and the HDMI controller block of RK3128 (which is very
similar to the one found in RK3036). The original intention of this series
was to add support for this slightly different integration but is by now,
driven by maintainer's feedback, exploded to be a rework of inno-hdmi
driver in large parts. It is, however, a change for the better.

The VOP part is very simple - everything we need for HDMI support is
already there. I only needed to split the output selection registers from
RK3036. The VOP has an IOMMU attached, but it has a serious silicon bug:
Registers can only be written, but not be read. As it's not possible to use
it with the IOMMU driver in it's current state I'm not adding it here and
we have to live with CMA for now - which works fine also. I got response
from the vendor, that there is no possibility to read the registers and an
workaround must be implemented in software in order to use it.

The inno-hdmi driver currently gets a lot of attention [0-2] and I'm
hooking in now also. As requested I incorporated some of Maxime's series
[0] (and tested them).
I have intentionally not removed any code dealing with output format
conversion in this series. In contrast to the input format, which is always
RGB on this platform and certainly can be dropped, that can be implemented
later. And secondly I need the conversion for RGB full range to RGB limited
range for this series.

I did also some smaller driver cleanups from my side and implemented a
custom connector state which now holds the data that belongs there and it
is not longer in the device structure and, of course, addressed the
feedback from v1 [3] and v2 [4].
There hasn't been any feedback to v3[5] so far, but I fixed an issue with
the new custom connector reset hook: If there is a connector state already
it needs to be destroyed in there as well.

Please see individual patches for detailed changelog.

Note: Patches are based and tested on next-20231213.

[0] https://lore.kernel.org/all/[email protected]
[1] https://lore.kernel.org/all/[email protected]
[2] https://lore.kernel.org/all/[email protected]
[3] https://lore.kernel.org/all/[email protected]/
[4] https://lore.kernel.org/all/[email protected]/
[5] https://lore.kernel.org/all/[email protected]/

Alex Bee (17):
dt-bindings: display: rockchip,inno-hdmi: Document RK3128 compatible
drm/rockchip: vop: Add output selection registers for RK312x
drm/rockchip: inno_hdmi: Fix video timing
drm/rockchip: inno_hdmi: Remove YUV-based csc coefficents
drm/rockchip: inno_hdmi: Drop irq struct member
drm/rockchip: inno_hdmi: Remove useless include
drm/rockchip: inno_hdmi: Subclass connector state
drm/rockchip: inno_hdmi: Correctly setup HDMI quantization range
drm/rockchip: inno_hdmi: Don't power up the phy after resetting
drm/rockchip: inno_hdmi: Split power mode setting
drm/rockchip: inno_hdmi: Add variant support
drm/rockchip: inno_hdmi: Add RK3128 support
drm/rockchip: inno_hdmi: Add basic mode validation
drm/rockchip: inno_hdmi: Drop custom fill_modes hook
ARM: dts: rockchip: Add display subsystem for RK3128
ARM: dts: rockchip: Add HDMI node for RK3128
ARM: dts: rockchip: Enable HDMI output for XPI-3128

Maxime Ripard (12):
drm/rockchip: inno_hdmi: Remove useless mode_fixup
drm/rockchip: inno_hdmi: Remove useless copy of drm_display_mode
drm/rockchip: inno_hdmi: Switch encoder hooks to atomic
drm/rockchip: inno_hdmi: Get rid of mode_set
drm/rockchip: inno_hdmi: no need to store vic
drm/rockchip: inno_hdmi: Remove unneeded has audio flag
drm/rockchip: inno_hdmi: Remove useless input format
drm/rockchip: inno_hdmi: Remove tmds rate from structure
drm/rockchip: inno_hdmi: Drop HDMI Vendor Infoframe support
drm/rockchip: inno_hdmi: Move infoframe disable to separate function
drm/rockchip: inno_hdmi: Switch to infoframe type
drm/rockchip: inno_hdmi: Remove unused drm device pointer

.../display/rockchip/rockchip,inno-hdmi.yaml | 40 +-
.../arm/boot/dts/rockchip/rk3128-xpi-3128.dts | 29 +
arch/arm/boot/dts/rockchip/rk3128.dtsi | 60 ++
drivers/gpu/drm/rockchip/inno_hdmi.c | 549 +++++++++++-------
drivers/gpu/drm/rockchip/inno_hdmi.h | 5 -
drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 13 +-
drivers/gpu/drm/rockchip/rockchip_vop_reg.h | 3 +
7 files changed, 484 insertions(+), 215 deletions(-)


base-commit: 48e8992e33abf054bcc0bb2e77b2d43bb899212e
--
2.43.0



2023-12-22 17:42:48

by Alex Bee

[permalink] [raw]
Subject: [PATCH v4 01/29] dt-bindings: display: rockchip,inno-hdmi: Document RK3128 compatible

The integration for this SoC is different from the currently existing: It
needs it's PHY's reference clock rate to calculate the DDC bus frequency
correctly. The controller is also part of a powerdomain, so this gets added
as an mandatory property for this variant.

Signed-off-by: Alex Bee <[email protected]>
Reviewed-by: Conor Dooley <[email protected]>
---
changes in v2:
- clarify that the controller itself is part of the powerdomain
- simplify clock-names
- made power-domains property only allowed (and required) for new variant

changes in v3:
- collect RB

changes in v4:
- none

.../display/rockchip/rockchip,inno-hdmi.yaml | 40 ++++++++++++++++++-
1 file changed, 38 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/display/rockchip/rockchip,inno-hdmi.yaml b/Documentation/devicetree/bindings/display/rockchip/rockchip,inno-hdmi.yaml
index 96889c86849a..be78dcfa1c76 100644
--- a/Documentation/devicetree/bindings/display/rockchip/rockchip,inno-hdmi.yaml
+++ b/Documentation/devicetree/bindings/display/rockchip/rockchip,inno-hdmi.yaml
@@ -14,6 +14,7 @@ properties:
compatible:
enum:
- rockchip,rk3036-inno-hdmi
+ - rockchip,rk3128-inno-hdmi

reg:
maxItems: 1
@@ -22,10 +23,19 @@ properties:
maxItems: 1

clocks:
- maxItems: 1
+ minItems: 1
+ items:
+ - description: The HDMI controller main clock
+ - description: The HDMI PHY reference clock

clock-names:
- const: pclk
+ minItems: 1
+ items:
+ - const: pclk
+ - const: ref
+
+ power-domains:
+ maxItems: 1

ports:
$ref: /schemas/graph.yaml#/properties/ports
@@ -55,6 +65,32 @@ required:
- pinctrl-names
- ports

+allOf:
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: rockchip,rk3036-inno-hdmi
+
+ then:
+ properties:
+ power-domains: false
+
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: rockchip,rk3128-inno-hdmi
+
+ then:
+ properties:
+ clocks:
+ minItems: 2
+ clock-names:
+ minItems: 2
+ required:
+ - power-domains
+
additionalProperties: false

examples:
--
2.43.0


2023-12-22 17:43:08

by Alex Bee

[permalink] [raw]
Subject: [PATCH v4 02/29] drm/rockchip: vop: Add output selection registers for RK312x

In contrast to RK3036, RK312x SoCs have multiple output channels such as
RGB (i.e. LVDS TTL), LVDS, DSI and HDMI.

In order to support that, this splits output from RK3036 and defines an
separate one for RK3126 with the registers required to enable the
appropriate output and setup the correct polarity.

Signed-off-by: Alex Bee <[email protected]>
---
changes in v2:
- rephrase commit message

changes in v3:
- none

changes in v4:
- none

drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 13 ++++++++++++-
drivers/gpu/drm/rockchip/rockchip_vop_reg.h | 3 +++
2 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
index c51ca82320cb..b9ee02061d5b 100644
--- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
+++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
@@ -227,11 +227,22 @@ static const struct vop_win_data rk3126_vop_win_data[] = {
.type = DRM_PLANE_TYPE_CURSOR },
};

+static const struct vop_output rk3126_output = {
+ .pin_pol = VOP_REG(RK3036_DSP_CTRL0, 0xf, 4),
+ .hdmi_pin_pol = VOP_REG(RK3126_INT_SCALER, 0x7, 4),
+ .hdmi_en = VOP_REG(RK3036_AXI_BUS_CTRL, 0x1, 22),
+ .hdmi_dclk_pol = VOP_REG(RK3036_AXI_BUS_CTRL, 0x1, 23),
+ .rgb_en = VOP_REG(RK3036_AXI_BUS_CTRL, 0x1, 24),
+ .rgb_dclk_pol = VOP_REG(RK3036_AXI_BUS_CTRL, 0x1, 25),
+ .mipi_en = VOP_REG(RK3036_AXI_BUS_CTRL, 0x1, 28),
+ .mipi_dclk_pol = VOP_REG(RK3036_AXI_BUS_CTRL, 0x1, 29),
+};
+
static const struct vop_data rk3126_vop = {
.intr = &rk3036_intr,
.common = &rk3036_common,
.modeset = &rk3036_modeset,
- .output = &rk3036_output,
+ .output = &rk3126_output,
.win = rk3126_vop_win_data,
.win_size = ARRAY_SIZE(rk3126_vop_win_data),
.max_output = { 1920, 1080 },
diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.h b/drivers/gpu/drm/rockchip/rockchip_vop_reg.h
index 406e981c75bd..fbf1bcc68625 100644
--- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.h
+++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.h
@@ -872,6 +872,9 @@
/* rk3036 register definition end */

/* rk3126 register definition */
+#define RK3126_INT_SCALER 0x0c
+
+/* win1 register */
#define RK3126_WIN1_MST 0x4c
#define RK3126_WIN1_DSP_INFO 0x50
#define RK3126_WIN1_DSP_ST 0x54
--
2.43.0


2023-12-22 17:43:19

by Alex Bee

[permalink] [raw]
Subject: [PATCH v4 03/29] drm/rockchip: inno_hdmi: Fix video timing

The controller wants the difference between *total and *sync_start in the
HDMI_VIDEO_EXT_*DELAY registers. Otherwise the signal is very unstable for
certain non-VIC modes. See downstream commit [0].

[0] https://github.com/rockchip-linux/kernel/commit/8eb559f2502c

Fixes: 412d4ae6b7a5 ("drm/rockchip: hdmi: add Innosilicon HDMI support")
Co-developed-by: Zheng Yang <[email protected]>
Signed-off-by: Zheng Yang <[email protected]>
Signed-off-by: Alex Bee <[email protected]>
---
changes in v2:
- none

changes in v3:
- none

changes in v4:
- none

drivers/gpu/drm/rockchip/inno_hdmi.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/inno_hdmi.c b/drivers/gpu/drm/rockchip/inno_hdmi.c
index 6e5b922a121e..345253e033c5 100644
--- a/drivers/gpu/drm/rockchip/inno_hdmi.c
+++ b/drivers/gpu/drm/rockchip/inno_hdmi.c
@@ -412,7 +412,7 @@ static int inno_hdmi_config_video_timing(struct inno_hdmi *hdmi,
hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HBLANK_L, value & 0xFF);
hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HBLANK_H, (value >> 8) & 0xFF);

- value = mode->hsync_start - mode->hdisplay;
+ value = mode->htotal - mode->hsync_start;
hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HDELAY_L, value & 0xFF);
hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HDELAY_H, (value >> 8) & 0xFF);

@@ -427,7 +427,7 @@ static int inno_hdmi_config_video_timing(struct inno_hdmi *hdmi,
value = mode->vtotal - mode->vdisplay;
hdmi_writeb(hdmi, HDMI_VIDEO_EXT_VBLANK, value & 0xFF);

- value = mode->vsync_start - mode->vdisplay;
+ value = mode->vtotal - mode->vsync_start;
hdmi_writeb(hdmi, HDMI_VIDEO_EXT_VDELAY, value & 0xFF);

value = mode->vsync_end - mode->vsync_start;
--
2.43.0


2023-12-22 17:43:33

by Alex Bee

[permalink] [raw]
Subject: [PATCH v4 04/29] drm/rockchip: inno_hdmi: Remove useless mode_fixup

From: Maxime Ripard <[email protected]>

The mode_fixup implementation doesn't do anything, so we can simply
remove it.

Signed-off-by: Maxime Ripard <[email protected]>
Tested-by: Alex Bee <[email protected]>
Signed-off-by: Alex Bee <[email protected]>
---
changes in v2:
- imported patch

changes in v3:
- added my SoB

changes in v4:
- none

drivers/gpu/drm/rockchip/inno_hdmi.c | 8 --------
1 file changed, 8 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/inno_hdmi.c b/drivers/gpu/drm/rockchip/inno_hdmi.c
index 345253e033c5..0b1740b38c7b 100644
--- a/drivers/gpu/drm/rockchip/inno_hdmi.c
+++ b/drivers/gpu/drm/rockchip/inno_hdmi.c
@@ -517,13 +517,6 @@ static void inno_hdmi_encoder_disable(struct drm_encoder *encoder)
inno_hdmi_set_pwr_mode(hdmi, LOWER_PWR);
}

-static bool inno_hdmi_encoder_mode_fixup(struct drm_encoder *encoder,
- const struct drm_display_mode *mode,
- struct drm_display_mode *adj_mode)
-{
- return true;
-}
-
static int
inno_hdmi_encoder_atomic_check(struct drm_encoder *encoder,
struct drm_crtc_state *crtc_state,
@@ -540,7 +533,6 @@ inno_hdmi_encoder_atomic_check(struct drm_encoder *encoder,
static struct drm_encoder_helper_funcs inno_hdmi_encoder_helper_funcs = {
.enable = inno_hdmi_encoder_enable,
.disable = inno_hdmi_encoder_disable,
- .mode_fixup = inno_hdmi_encoder_mode_fixup,
.mode_set = inno_hdmi_encoder_mode_set,
.atomic_check = inno_hdmi_encoder_atomic_check,
};
--
2.43.0


2023-12-22 17:44:16

by Alex Bee

[permalink] [raw]
Subject: [PATCH v4 07/29] drm/rockchip: inno_hdmi: Get rid of mode_set

From: Maxime Ripard <[email protected]>

We're not doing anything special in atomic_mode_set so we can simply
merge it into atomic_enable.

Signed-off-by: Maxime Ripard <[email protected]>
Tested-by: Alex Bee <[email protected]>
Signed-off-by: Alex Bee <[email protected]>
---
changes in v2:
- imported patch

changes in v3:
- added my SoB

changes in v4:
- none

drivers/gpu/drm/rockchip/inno_hdmi.c | 22 +++++++++++-----------
1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/inno_hdmi.c b/drivers/gpu/drm/rockchip/inno_hdmi.c
index 48c4f010b260..299770e481b7 100644
--- a/drivers/gpu/drm/rockchip/inno_hdmi.c
+++ b/drivers/gpu/drm/rockchip/inno_hdmi.c
@@ -490,21 +490,22 @@ static int inno_hdmi_setup(struct inno_hdmi *hdmi,
return 0;
}

-static void inno_hdmi_encoder_mode_set(struct drm_encoder *encoder,
- struct drm_crtc_state *crtc_state,
- struct drm_connector_state *conn_state)
-{
- struct drm_display_mode *adj_mode = &crtc_state->adjusted_mode;
- struct inno_hdmi *hdmi = encoder_to_inno_hdmi(encoder);
-
- inno_hdmi_setup(hdmi, adj_mode);
-}
-
static void inno_hdmi_encoder_enable(struct drm_encoder *encoder,
struct drm_atomic_state *state)
{
struct inno_hdmi *hdmi = encoder_to_inno_hdmi(encoder);
+ struct drm_connector_state *conn_state;
+ struct drm_crtc_state *crtc_state;
+
+ conn_state = drm_atomic_get_new_connector_state(state, &hdmi->connector);
+ if (WARN_ON(!conn_state))
+ return;
+
+ crtc_state = drm_atomic_get_new_crtc_state(state, conn_state->crtc);
+ if (WARN_ON(!crtc_state))
+ return;

+ inno_hdmi_setup(hdmi, &crtc_state->adjusted_mode);
inno_hdmi_set_pwr_mode(hdmi, NORMAL);
}

@@ -533,7 +534,6 @@ static struct drm_encoder_helper_funcs inno_hdmi_encoder_helper_funcs = {
.atomic_check = inno_hdmi_encoder_atomic_check,
.atomic_enable = inno_hdmi_encoder_enable,
.atomic_disable = inno_hdmi_encoder_disable,
- .atomic_mode_set = inno_hdmi_encoder_mode_set,
};

static enum drm_connector_status
--
2.43.0


2023-12-22 17:44:20

by Alex Bee

[permalink] [raw]
Subject: [PATCH v4 06/29] drm/rockchip: inno_hdmi: Switch encoder hooks to atomic

From: Maxime Ripard <[email protected]>

The inno_hdmi encoder still uses the !atomic variants of enable, disable
and modeset. Convert to their atomic equivalents.

Signed-off-by: Maxime Ripard <[email protected]>
Tested-by: Alex Bee <[email protected]>
Signed-off-by: Alex Bee <[email protected]>
---
changes in v2:
- imported patch

changes in v3:
- added my SoB

changes in v4:
- none

drivers/gpu/drm/rockchip/inno_hdmi.c | 19 +++++++++++--------
1 file changed, 11 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/inno_hdmi.c b/drivers/gpu/drm/rockchip/inno_hdmi.c
index 14d2ba92a606..48c4f010b260 100644
--- a/drivers/gpu/drm/rockchip/inno_hdmi.c
+++ b/drivers/gpu/drm/rockchip/inno_hdmi.c
@@ -491,22 +491,25 @@ static int inno_hdmi_setup(struct inno_hdmi *hdmi,
}

static void inno_hdmi_encoder_mode_set(struct drm_encoder *encoder,
- struct drm_display_mode *mode,
- struct drm_display_mode *adj_mode)
+ struct drm_crtc_state *crtc_state,
+ struct drm_connector_state *conn_state)
{
+ struct drm_display_mode *adj_mode = &crtc_state->adjusted_mode;
struct inno_hdmi *hdmi = encoder_to_inno_hdmi(encoder);

inno_hdmi_setup(hdmi, adj_mode);
}

-static void inno_hdmi_encoder_enable(struct drm_encoder *encoder)
+static void inno_hdmi_encoder_enable(struct drm_encoder *encoder,
+ struct drm_atomic_state *state)
{
struct inno_hdmi *hdmi = encoder_to_inno_hdmi(encoder);

inno_hdmi_set_pwr_mode(hdmi, NORMAL);
}

-static void inno_hdmi_encoder_disable(struct drm_encoder *encoder)
+static void inno_hdmi_encoder_disable(struct drm_encoder *encoder,
+ struct drm_atomic_state *state)
{
struct inno_hdmi *hdmi = encoder_to_inno_hdmi(encoder);

@@ -527,10 +530,10 @@ inno_hdmi_encoder_atomic_check(struct drm_encoder *encoder,
}

static struct drm_encoder_helper_funcs inno_hdmi_encoder_helper_funcs = {
- .enable = inno_hdmi_encoder_enable,
- .disable = inno_hdmi_encoder_disable,
- .mode_set = inno_hdmi_encoder_mode_set,
- .atomic_check = inno_hdmi_encoder_atomic_check,
+ .atomic_check = inno_hdmi_encoder_atomic_check,
+ .atomic_enable = inno_hdmi_encoder_enable,
+ .atomic_disable = inno_hdmi_encoder_disable,
+ .atomic_mode_set = inno_hdmi_encoder_mode_set,
};

static enum drm_connector_status
--
2.43.0


2023-12-22 17:45:05

by Alex Bee

[permalink] [raw]
Subject: [PATCH v4 10/29] drm/rockchip: inno_hdmi: Remove useless input format

From: Maxime Ripard <[email protected]>

The driver has a lot of logic to deal with multiple input formats, but
hardcodes it to RGB. This means that most of that code has been dead
code, so let's get rid of it.

Signed-off-by: Maxime Ripard <[email protected]>
Tested-by: Alex Bee <[email protected]>
[made checkpatch happy]
Signed-off-by: Alex Bee <[email protected]>
---
changes in v2:
- imported patch

changes in v3:
- none

changes in v4:
- none

drivers/gpu/drm/rockchip/inno_hdmi.c | 41 ++++++++--------------------
1 file changed, 11 insertions(+), 30 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/inno_hdmi.c b/drivers/gpu/drm/rockchip/inno_hdmi.c
index 58aff7a9c09a..7c75feedacad 100644
--- a/drivers/gpu/drm/rockchip/inno_hdmi.c
+++ b/drivers/gpu/drm/rockchip/inno_hdmi.c
@@ -28,7 +28,6 @@
#include "inno_hdmi.h"

struct hdmi_data_info {
- unsigned int enc_in_format;
unsigned int enc_out_format;
unsigned int colorimetry;
};
@@ -328,47 +327,30 @@ static int inno_hdmi_config_video_csc(struct inno_hdmi *hdmi)
v_VIDEO_INPUT_CSP(0);
hdmi_writeb(hdmi, HDMI_VIDEO_CONTRL2, value);

- if (data->enc_in_format == data->enc_out_format) {
- if ((data->enc_in_format == HDMI_COLORSPACE_RGB) ||
- (data->enc_in_format >= HDMI_COLORSPACE_YUV444)) {
- value = v_SOF_DISABLE | v_COLOR_DEPTH_NOT_INDICATED(1);
- hdmi_writeb(hdmi, HDMI_VIDEO_CONTRL3, value);
-
- hdmi_modb(hdmi, HDMI_VIDEO_CONTRL,
- m_VIDEO_AUTO_CSC | m_VIDEO_C0_C2_SWAP,
- v_VIDEO_AUTO_CSC(AUTO_CSC_DISABLE) |
- v_VIDEO_C0_C2_SWAP(C0_C2_CHANGE_DISABLE));
- return 0;
- }
+ if (data->enc_out_format == HDMI_COLORSPACE_RGB) {
+ value = v_SOF_DISABLE | v_COLOR_DEPTH_NOT_INDICATED(1);
+ hdmi_writeb(hdmi, HDMI_VIDEO_CONTRL3, value);
+
+ hdmi_modb(hdmi, HDMI_VIDEO_CONTRL,
+ m_VIDEO_AUTO_CSC | m_VIDEO_C0_C2_SWAP,
+ v_VIDEO_AUTO_CSC(AUTO_CSC_DISABLE) |
+ v_VIDEO_C0_C2_SWAP(C0_C2_CHANGE_DISABLE));
+ return 0;
}

if (data->colorimetry == HDMI_COLORIMETRY_ITU_601) {
- if ((data->enc_in_format == HDMI_COLORSPACE_RGB) &&
- (data->enc_out_format == HDMI_COLORSPACE_YUV444)) {
+ if (data->enc_out_format == HDMI_COLORSPACE_YUV444) {
csc_mode = CSC_RGB_0_255_TO_ITU601_16_235_8BIT;
auto_csc = AUTO_CSC_DISABLE;
c0_c2_change = C0_C2_CHANGE_DISABLE;
csc_enable = v_CSC_ENABLE;
- } else if ((data->enc_in_format == HDMI_COLORSPACE_YUV444) &&
- (data->enc_out_format == HDMI_COLORSPACE_RGB)) {
- csc_mode = CSC_ITU601_16_235_TO_RGB_0_255_8BIT;
- auto_csc = AUTO_CSC_ENABLE;
- c0_c2_change = C0_C2_CHANGE_DISABLE;
- csc_enable = v_CSC_DISABLE;
}
} else {
- if ((data->enc_in_format == HDMI_COLORSPACE_RGB) &&
- (data->enc_out_format == HDMI_COLORSPACE_YUV444)) {
+ if (data->enc_out_format == HDMI_COLORSPACE_YUV444) {
csc_mode = CSC_RGB_0_255_TO_ITU709_16_235_8BIT;
auto_csc = AUTO_CSC_DISABLE;
c0_c2_change = C0_C2_CHANGE_DISABLE;
csc_enable = v_CSC_ENABLE;
- } else if ((data->enc_in_format == HDMI_COLORSPACE_YUV444) &&
- (data->enc_out_format == HDMI_COLORSPACE_RGB)) {
- csc_mode = CSC_ITU709_16_235_TO_RGB_0_255_8BIT;
- auto_csc = AUTO_CSC_ENABLE;
- c0_c2_change = C0_C2_CHANGE_DISABLE;
- csc_enable = v_CSC_DISABLE;
}
}

@@ -443,7 +425,6 @@ static int inno_hdmi_setup(struct inno_hdmi *hdmi,
struct drm_display_info *display = &hdmi->connector.display_info;
u8 vic = drm_match_cea_mode(mode);

- hdmi->hdmi_data.enc_in_format = HDMI_COLORSPACE_RGB;
hdmi->hdmi_data.enc_out_format = HDMI_COLORSPACE_RGB;

if (vic == 6 || vic == 7 ||
--
2.43.0


2023-12-22 17:45:21

by Alex Bee

[permalink] [raw]
Subject: [PATCH v4 11/29] drm/rockchip: inno_hdmi: Remove YUV-based csc coefficents

Now that the unneeded support for YUV based input formats is gone, the csc
coefficients for those formats can be dropped as well.

Signed-off-by: Alex Bee <[email protected]>
---
changes in v2:
- new patch

changes in v3:
- none

changes in v4:
- none

drivers/gpu/drm/rockchip/inno_hdmi.c | 37 ----------------------------
1 file changed, 37 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/inno_hdmi.c b/drivers/gpu/drm/rockchip/inno_hdmi.c
index 7c75feedacad..04344ee1265d 100644
--- a/drivers/gpu/drm/rockchip/inno_hdmi.c
+++ b/drivers/gpu/drm/rockchip/inno_hdmi.c
@@ -74,49 +74,12 @@ static struct inno_hdmi *connector_to_inno_hdmi(struct drm_connector *connector)
}

enum {
- CSC_ITU601_16_235_TO_RGB_0_255_8BIT,
- CSC_ITU601_0_255_TO_RGB_0_255_8BIT,
- CSC_ITU709_16_235_TO_RGB_0_255_8BIT,
CSC_RGB_0_255_TO_ITU601_16_235_8BIT,
CSC_RGB_0_255_TO_ITU709_16_235_8BIT,
CSC_RGB_0_255_TO_RGB_16_235_8BIT,
};

static const char coeff_csc[][24] = {
- /*
- * YUV2RGB:601 SD mode(Y[16:235], UV[16:240], RGB[0:255]):
- * R = 1.164*Y + 1.596*V - 204
- * G = 1.164*Y - 0.391*U - 0.813*V + 154
- * B = 1.164*Y + 2.018*U - 258
- */
- {
- 0x04, 0xa7, 0x00, 0x00, 0x06, 0x62, 0x02, 0xcc,
- 0x04, 0xa7, 0x11, 0x90, 0x13, 0x40, 0x00, 0x9a,
- 0x04, 0xa7, 0x08, 0x12, 0x00, 0x00, 0x03, 0x02
- },
- /*
- * YUV2RGB:601 SD mode(YUV[0:255],RGB[0:255]):
- * R = Y + 1.402*V - 248
- * G = Y - 0.344*U - 0.714*V + 135
- * B = Y + 1.772*U - 227
- */
- {
- 0x04, 0x00, 0x00, 0x00, 0x05, 0x9b, 0x02, 0xf8,
- 0x04, 0x00, 0x11, 0x60, 0x12, 0xdb, 0x00, 0x87,
- 0x04, 0x00, 0x07, 0x16, 0x00, 0x00, 0x02, 0xe3
- },
- /*
- * YUV2RGB:709 HD mode(Y[16:235],UV[16:240],RGB[0:255]):
- * R = 1.164*Y + 1.793*V - 248
- * G = 1.164*Y - 0.213*U - 0.534*V + 77
- * B = 1.164*Y + 2.115*U - 289
- */
- {
- 0x04, 0xa7, 0x00, 0x00, 0x07, 0x2c, 0x02, 0xf8,
- 0x04, 0xa7, 0x10, 0xda, 0x12, 0x22, 0x00, 0x4d,
- 0x04, 0xa7, 0x08, 0x74, 0x00, 0x00, 0x03, 0x21
- },
-
/*
* RGB2YUV:601 SD mode:
* Cb = -0.291G - 0.148R + 0.439B + 128
--
2.43.0


2023-12-22 17:45:44

by Alex Bee

[permalink] [raw]
Subject: [PATCH v4 13/29] drm/rockchip: inno_hdmi: Drop HDMI Vendor Infoframe support

From: Maxime Ripard <[email protected]>

The HDMI vendor infoframe is only meant to be sent with 4k60 modes and
higher, but the controller doesn't support them. Let's drop them from
the kernel.

Suggested-by: Johan Jonker <[email protected]>
Signed-off-by: Maxime Ripard <[email protected]>
Tested-by: Alex Bee <[email protected]>
Signed-off-by: Alex Bee <[email protected]>
---
changes in v2:
- imported patch

changes in v3:
- added my SoB

changes in v4:
- none

drivers/gpu/drm/rockchip/inno_hdmi.c | 35 ++++++++--------------------
1 file changed, 10 insertions(+), 25 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/inno_hdmi.c b/drivers/gpu/drm/rockchip/inno_hdmi.c
index 102195837206..5c9f1325441f 100644
--- a/drivers/gpu/drm/rockchip/inno_hdmi.c
+++ b/drivers/gpu/drm/rockchip/inno_hdmi.c
@@ -206,11 +206,15 @@ static void inno_hdmi_reset(struct inno_hdmi *hdmi)
}

static int inno_hdmi_upload_frame(struct inno_hdmi *hdmi, int setup_rc,
- union hdmi_infoframe *frame, u32 frame_index,
- u32 mask, u32 disable, u32 enable)
+ union hdmi_infoframe *frame, u32 frame_index)
{
- if (mask)
- hdmi_modb(hdmi, HDMI_PACKET_SEND_AUTO, mask, disable);
+ struct drm_connector *connector = &hdmi->connector;
+
+ if (frame_index != INFOFRAME_AVI) {
+ drm_err(connector->dev,
+ "Unsupported infoframe type: %u\n", frame_index);
+ return 0;
+ }

hdmi_writeb(hdmi, HDMI_CONTROL_PACKET_BUF_INDEX, frame_index);

@@ -226,28 +230,11 @@ static int inno_hdmi_upload_frame(struct inno_hdmi *hdmi, int setup_rc,
for (i = 0; i < rc; i++)
hdmi_writeb(hdmi, HDMI_CONTROL_PACKET_ADDR + i,
packed_frame[i]);
-
- if (mask)
- hdmi_modb(hdmi, HDMI_PACKET_SEND_AUTO, mask, enable);
}

return setup_rc;
}

-static int inno_hdmi_config_video_vsi(struct inno_hdmi *hdmi,
- struct drm_display_mode *mode)
-{
- union hdmi_infoframe frame;
- int rc;
-
- rc = drm_hdmi_vendor_infoframe_from_display_mode(&frame.vendor.hdmi,
- &hdmi->connector,
- mode);
-
- return inno_hdmi_upload_frame(hdmi, rc, &frame, INFOFRAME_VSI,
- m_PACKET_VSI_EN, v_PACKET_VSI_EN(0), v_PACKET_VSI_EN(1));
-}
-
static int inno_hdmi_config_video_avi(struct inno_hdmi *hdmi,
struct drm_display_mode *mode)
{
@@ -265,7 +252,7 @@ static int inno_hdmi_config_video_avi(struct inno_hdmi *hdmi,
else
frame.avi.colorspace = HDMI_COLORSPACE_RGB;

- return inno_hdmi_upload_frame(hdmi, rc, &frame, INFOFRAME_AVI, 0, 0, 0);
+ return inno_hdmi_upload_frame(hdmi, rc, &frame, INFOFRAME_AVI);
}

static int inno_hdmi_config_video_csc(struct inno_hdmi *hdmi)
@@ -408,10 +395,8 @@ static int inno_hdmi_setup(struct inno_hdmi *hdmi,

inno_hdmi_config_video_csc(hdmi);

- if (display->is_hdmi) {
+ if (display->is_hdmi)
inno_hdmi_config_video_avi(hdmi, mode);
- inno_hdmi_config_video_vsi(hdmi, mode);
- }

/*
* When IP controller have configured to an accurate video
--
2.43.0


2023-12-22 17:46:00

by Alex Bee

[permalink] [raw]
Subject: [PATCH v4 14/29] drm/rockchip: inno_hdmi: Move infoframe disable to separate function

From: Maxime Ripard <[email protected]>

The code to upload infoframes to the controller uses a weird construct
which, based on the previous function call return code, will either
disable or enable that infoframe.

In order to get rid of that argument, let's split the function to
disable the infoframe into a separate function and make it obvious what
we are doing in the error path.

Signed-off-by: Maxime Ripard <[email protected]>
Tested-by: Alex Bee <[email protected]>
Signed-off-by: Alex Bee <[email protected]>
---
changes in v2:
- imported patch

changes in v3:
- added my SoB

changes in v4:
- none

drivers/gpu/drm/rockchip/inno_hdmi.c | 46 ++++++++++++++++++----------
1 file changed, 30 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/inno_hdmi.c b/drivers/gpu/drm/rockchip/inno_hdmi.c
index 5c9f1325441f..10466c2aa520 100644
--- a/drivers/gpu/drm/rockchip/inno_hdmi.c
+++ b/drivers/gpu/drm/rockchip/inno_hdmi.c
@@ -205,34 +205,44 @@ static void inno_hdmi_reset(struct inno_hdmi *hdmi)
inno_hdmi_set_pwr_mode(hdmi, NORMAL);
}

-static int inno_hdmi_upload_frame(struct inno_hdmi *hdmi, int setup_rc,
- union hdmi_infoframe *frame, u32 frame_index)
+static void inno_hdmi_disable_frame(struct inno_hdmi *hdmi, u32 frame_index)
{
struct drm_connector *connector = &hdmi->connector;

if (frame_index != INFOFRAME_AVI) {
drm_err(connector->dev,
"Unsupported infoframe type: %u\n", frame_index);
- return 0;
+ return;
}

hdmi_writeb(hdmi, HDMI_CONTROL_PACKET_BUF_INDEX, frame_index);
+}

- if (setup_rc >= 0) {
- u8 packed_frame[HDMI_MAXIMUM_INFO_FRAME_SIZE];
- ssize_t rc, i;
-
- rc = hdmi_infoframe_pack(frame, packed_frame,
- sizeof(packed_frame));
- if (rc < 0)
- return rc;
+static int inno_hdmi_upload_frame(struct inno_hdmi *hdmi,
+ union hdmi_infoframe *frame, u32 frame_index)
+{
+ struct drm_connector *connector = &hdmi->connector;
+ u8 packed_frame[HDMI_MAXIMUM_INFO_FRAME_SIZE];
+ ssize_t rc, i;

- for (i = 0; i < rc; i++)
- hdmi_writeb(hdmi, HDMI_CONTROL_PACKET_ADDR + i,
- packed_frame[i]);
+ if (frame_index != INFOFRAME_AVI) {
+ drm_err(connector->dev,
+ "Unsupported infoframe type: %u\n", frame_index);
+ return 0;
}

- return setup_rc;
+ inno_hdmi_disable_frame(hdmi, frame_index);
+
+ rc = hdmi_infoframe_pack(frame, packed_frame,
+ sizeof(packed_frame));
+ if (rc < 0)
+ return rc;
+
+ for (i = 0; i < rc; i++)
+ hdmi_writeb(hdmi, HDMI_CONTROL_PACKET_ADDR + i,
+ packed_frame[i]);
+
+ return 0;
}

static int inno_hdmi_config_video_avi(struct inno_hdmi *hdmi,
@@ -244,6 +254,10 @@ static int inno_hdmi_config_video_avi(struct inno_hdmi *hdmi,
rc = drm_hdmi_avi_infoframe_from_display_mode(&frame.avi,
&hdmi->connector,
mode);
+ if (rc) {
+ inno_hdmi_disable_frame(hdmi, INFOFRAME_AVI);
+ return rc;
+ }

if (hdmi->hdmi_data.enc_out_format == HDMI_COLORSPACE_YUV444)
frame.avi.colorspace = HDMI_COLORSPACE_YUV444;
@@ -252,7 +266,7 @@ static int inno_hdmi_config_video_avi(struct inno_hdmi *hdmi,
else
frame.avi.colorspace = HDMI_COLORSPACE_RGB;

- return inno_hdmi_upload_frame(hdmi, rc, &frame, INFOFRAME_AVI);
+ return inno_hdmi_upload_frame(hdmi, &frame, INFOFRAME_AVI);
}

static int inno_hdmi_config_video_csc(struct inno_hdmi *hdmi)
--
2.43.0


2023-12-22 17:46:05

by Alex Bee

[permalink] [raw]
Subject: [PATCH v4 15/29] drm/rockchip: inno_hdmi: Switch to infoframe type

From: Maxime Ripard <[email protected]>

The inno_hdmi driver relies on its own internal infoframe type matching
the hardware.

This works fine, but in order to make further reworks easier, let's
switch to the HDMI spec definition of those types.

Signed-off-by: Maxime Ripard <[email protected]>
Tested-by: Alex Bee <[email protected]>
Signed-off-by: Alex Bee <[email protected]>
---
changes in v2:
- imported patch

changes in v3:
- added my SoB

changes in v4:
- none

drivers/gpu/drm/rockchip/inno_hdmi.c | 21 +++++++++++----------
1 file changed, 11 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/inno_hdmi.c b/drivers/gpu/drm/rockchip/inno_hdmi.c
index 10466c2aa520..49367ca24125 100644
--- a/drivers/gpu/drm/rockchip/inno_hdmi.c
+++ b/drivers/gpu/drm/rockchip/inno_hdmi.c
@@ -205,33 +205,34 @@ static void inno_hdmi_reset(struct inno_hdmi *hdmi)
inno_hdmi_set_pwr_mode(hdmi, NORMAL);
}

-static void inno_hdmi_disable_frame(struct inno_hdmi *hdmi, u32 frame_index)
+static void inno_hdmi_disable_frame(struct inno_hdmi *hdmi,
+ enum hdmi_infoframe_type type)
{
struct drm_connector *connector = &hdmi->connector;

- if (frame_index != INFOFRAME_AVI) {
+ if (type != HDMI_INFOFRAME_TYPE_AVI) {
drm_err(connector->dev,
- "Unsupported infoframe type: %u\n", frame_index);
+ "Unsupported infoframe type: %u\n", type);
return;
}

- hdmi_writeb(hdmi, HDMI_CONTROL_PACKET_BUF_INDEX, frame_index);
+ hdmi_writeb(hdmi, HDMI_CONTROL_PACKET_BUF_INDEX, INFOFRAME_AVI);
}

static int inno_hdmi_upload_frame(struct inno_hdmi *hdmi,
- union hdmi_infoframe *frame, u32 frame_index)
+ union hdmi_infoframe *frame, enum hdmi_infoframe_type type)
{
struct drm_connector *connector = &hdmi->connector;
u8 packed_frame[HDMI_MAXIMUM_INFO_FRAME_SIZE];
ssize_t rc, i;

- if (frame_index != INFOFRAME_AVI) {
+ if (type != HDMI_INFOFRAME_TYPE_AVI) {
drm_err(connector->dev,
- "Unsupported infoframe type: %u\n", frame_index);
+ "Unsupported infoframe type: %u\n", type);
return 0;
}

- inno_hdmi_disable_frame(hdmi, frame_index);
+ inno_hdmi_disable_frame(hdmi, type);

rc = hdmi_infoframe_pack(frame, packed_frame,
sizeof(packed_frame));
@@ -255,7 +256,7 @@ static int inno_hdmi_config_video_avi(struct inno_hdmi *hdmi,
&hdmi->connector,
mode);
if (rc) {
- inno_hdmi_disable_frame(hdmi, INFOFRAME_AVI);
+ inno_hdmi_disable_frame(hdmi, HDMI_INFOFRAME_TYPE_AVI);
return rc;
}

@@ -266,7 +267,7 @@ static int inno_hdmi_config_video_avi(struct inno_hdmi *hdmi,
else
frame.avi.colorspace = HDMI_COLORSPACE_RGB;

- return inno_hdmi_upload_frame(hdmi, &frame, INFOFRAME_AVI);
+ return inno_hdmi_upload_frame(hdmi, &frame, HDMI_INFOFRAME_TYPE_AVI);
}

static int inno_hdmi_config_video_csc(struct inno_hdmi *hdmi)
--
2.43.0


2023-12-22 17:46:27

by Alex Bee

[permalink] [raw]
Subject: [PATCH v4 12/29] drm/rockchip: inno_hdmi: Remove tmds rate from structure

From: Maxime Ripard <[email protected]>

The tmds_rate field in the inno_hdmi structure is used mostly to
configure the internal i2c controller divider through a call to the
inno_hdmi_i2c_init() function.

We can simply make that rate an argument to that function, which also
removes a workaround to initialize the divider at probe time when we
don't have a mode yet.

Signed-off-by: Maxime Ripard <[email protected]>
Tested-by: Alex Bee <[email protected]>
Signed-off-by: Alex Bee <[email protected]>
---
changes in v3:
- imported patch

changes in v4:
- none

drivers/gpu/drm/rockchip/inno_hdmi.c | 14 +++++---------
1 file changed, 5 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/inno_hdmi.c b/drivers/gpu/drm/rockchip/inno_hdmi.c
index 04344ee1265d..102195837206 100644
--- a/drivers/gpu/drm/rockchip/inno_hdmi.c
+++ b/drivers/gpu/drm/rockchip/inno_hdmi.c
@@ -56,8 +56,6 @@ struct inno_hdmi {
struct inno_hdmi_i2c *i2c;
struct i2c_adapter *ddc;

- unsigned int tmds_rate;
-
struct hdmi_data_info hdmi_data;
};

@@ -134,11 +132,11 @@ static inline void hdmi_modb(struct inno_hdmi *hdmi, u16 offset,
hdmi_writeb(hdmi, offset, temp);
}

-static void inno_hdmi_i2c_init(struct inno_hdmi *hdmi)
+static void inno_hdmi_i2c_init(struct inno_hdmi *hdmi, unsigned long long rate)
{
- int ddc_bus_freq;
+ unsigned long long ddc_bus_freq = rate >> 2;

- ddc_bus_freq = (hdmi->tmds_rate >> 2) / HDMI_SCL_RATE;
+ do_div(ddc_bus_freq, HDMI_SCL_RATE);

hdmi_writeb(hdmi, DDC_BUS_FREQ_L, ddc_bus_freq & 0xFF);
hdmi_writeb(hdmi, DDC_BUS_FREQ_H, (ddc_bus_freq >> 8) & 0xFF);
@@ -421,8 +419,7 @@ static int inno_hdmi_setup(struct inno_hdmi *hdmi,
* DCLK_LCDC, so we need to init the TMDS rate to mode pixel
* clock rate, and reconfigure the DDC clock.
*/
- hdmi->tmds_rate = mode->clock * 1000;
- inno_hdmi_i2c_init(hdmi);
+ inno_hdmi_i2c_init(hdmi, mode->clock * 1000);

/* Unmute video and audio output */
hdmi_modb(hdmi, HDMI_AV_MUTE, m_AUDIO_MUTE | m_VIDEO_BLACK,
@@ -800,8 +797,7 @@ static int inno_hdmi_bind(struct device *dev, struct device *master,
* PCLK_HDMI, so we need to init the TMDS rate to PCLK rate,
* and reconfigure the DDC clock.
*/
- hdmi->tmds_rate = clk_get_rate(hdmi->pclk);
- inno_hdmi_i2c_init(hdmi);
+ inno_hdmi_i2c_init(hdmi, clk_get_rate(hdmi->pclk));

ret = inno_hdmi_register(drm, hdmi);
if (ret)
--
2.43.0


2023-12-22 17:46:51

by Alex Bee

[permalink] [raw]
Subject: [PATCH v4 18/29] drm/rockchip: inno_hdmi: Remove useless include

The inclusion syscon.h isn't used anywhere. Remove it.

Signed-off-by: Alex Bee <[email protected]>
Reviewed-by: Maxime Ripard <[email protected]>
---
changes in v2:
- new patch

changes in v3:
- collect RB

changes in v4:
- none

drivers/gpu/drm/rockchip/inno_hdmi.c | 1 -
1 file changed, 1 deletion(-)

diff --git a/drivers/gpu/drm/rockchip/inno_hdmi.c b/drivers/gpu/drm/rockchip/inno_hdmi.c
index 138cd4287dea..c306db90832a 100644
--- a/drivers/gpu/drm/rockchip/inno_hdmi.c
+++ b/drivers/gpu/drm/rockchip/inno_hdmi.c
@@ -10,7 +10,6 @@
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/hdmi.h>
-#include <linux/mfd/syscon.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/mutex.h>
--
2.43.0


2023-12-22 17:47:22

by Alex Bee

[permalink] [raw]
Subject: [PATCH v4 20/29] drm/rockchip: inno_hdmi: Correctly setup HDMI quantization range

The display controller will always give full range RGB regardless of the
mode set, but HDMI requires certain modes to be transmitted in limited
range RGB. This is especially required for HDMI sinks which do not support
non-standard quantization ranges.

This enables color space conversion for those modes and sets the
quantization range accordingly in the AVI infoframe.

Signed-off-by: Alex Bee <[email protected]>
---
changes in v2:
- made rgb_limited_range part of the new custom connector state

changes in v3:
- moved assignment of rgb_limited_range to atomic check

changes in v4:
- none

drivers/gpu/drm/rockchip/inno_hdmi.c | 60 +++++++++++++++++++---------
1 file changed, 42 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/inno_hdmi.c b/drivers/gpu/drm/rockchip/inno_hdmi.c
index e43fce968310..f3b90b479ab9 100644
--- a/drivers/gpu/drm/rockchip/inno_hdmi.c
+++ b/drivers/gpu/drm/rockchip/inno_hdmi.c
@@ -53,6 +53,7 @@ struct inno_hdmi_connector_state {
struct drm_connector_state base;
unsigned int enc_out_format;
unsigned int colorimetry;
+ bool rgb_limited_range;
};

static struct inno_hdmi *encoder_to_inno_hdmi(struct drm_encoder *encoder)
@@ -270,6 +271,18 @@ static int inno_hdmi_config_video_avi(struct inno_hdmi *hdmi,
else
frame.avi.colorspace = HDMI_COLORSPACE_RGB;

+ if (inno_conn_state->enc_out_format == HDMI_COLORSPACE_RGB) {
+ drm_hdmi_avi_infoframe_quant_range(&frame.avi,
+ connector, mode,
+ inno_conn_state->rgb_limited_range ?
+ HDMI_QUANTIZATION_RANGE_LIMITED :
+ HDMI_QUANTIZATION_RANGE_FULL);
+ } else {
+ frame.avi.quantization_range = HDMI_QUANTIZATION_RANGE_DEFAULT;
+ frame.avi.ycc_quantization_range =
+ HDMI_YCC_QUANTIZATION_RANGE_LIMITED;
+ }
+
return inno_hdmi_upload_frame(hdmi, &frame, HDMI_INFOFRAME_TYPE_AVI);
}

@@ -297,29 +310,37 @@ static int inno_hdmi_config_video_csc(struct inno_hdmi *hdmi)
hdmi_writeb(hdmi, HDMI_VIDEO_CONTRL2, value);

if (inno_conn_state->enc_out_format == HDMI_COLORSPACE_RGB) {
- value = v_SOF_DISABLE | v_COLOR_DEPTH_NOT_INDICATED(1);
- hdmi_writeb(hdmi, HDMI_VIDEO_CONTRL3, value);
-
- hdmi_modb(hdmi, HDMI_VIDEO_CONTRL,
- m_VIDEO_AUTO_CSC | m_VIDEO_C0_C2_SWAP,
- v_VIDEO_AUTO_CSC(AUTO_CSC_DISABLE) |
- v_VIDEO_C0_C2_SWAP(C0_C2_CHANGE_DISABLE));
- return 0;
- }
-
- if (inno_conn_state->colorimetry == HDMI_COLORIMETRY_ITU_601) {
- if (inno_conn_state->enc_out_format == HDMI_COLORSPACE_YUV444) {
- csc_mode = CSC_RGB_0_255_TO_ITU601_16_235_8BIT;
+ if (inno_conn_state->rgb_limited_range) {
+ csc_mode = CSC_RGB_0_255_TO_RGB_16_235_8BIT;
auto_csc = AUTO_CSC_DISABLE;
c0_c2_change = C0_C2_CHANGE_DISABLE;
csc_enable = v_CSC_ENABLE;
+
+ } else {
+ value = v_SOF_DISABLE | v_COLOR_DEPTH_NOT_INDICATED(1);
+ hdmi_writeb(hdmi, HDMI_VIDEO_CONTRL3, value);
+
+ hdmi_modb(hdmi, HDMI_VIDEO_CONTRL,
+ m_VIDEO_AUTO_CSC | m_VIDEO_C0_C2_SWAP,
+ v_VIDEO_AUTO_CSC(AUTO_CSC_DISABLE) |
+ v_VIDEO_C0_C2_SWAP(C0_C2_CHANGE_DISABLE));
+ return 0;
}
} else {
- if (inno_conn_state->enc_out_format == HDMI_COLORSPACE_YUV444) {
- csc_mode = CSC_RGB_0_255_TO_ITU709_16_235_8BIT;
- auto_csc = AUTO_CSC_DISABLE;
- c0_c2_change = C0_C2_CHANGE_DISABLE;
- csc_enable = v_CSC_ENABLE;
+ if (inno_conn_state->colorimetry == HDMI_COLORIMETRY_ITU_601) {
+ if (inno_conn_state->enc_out_format == HDMI_COLORSPACE_YUV444) {
+ csc_mode = CSC_RGB_0_255_TO_ITU601_16_235_8BIT;
+ auto_csc = AUTO_CSC_DISABLE;
+ c0_c2_change = C0_C2_CHANGE_DISABLE;
+ csc_enable = v_CSC_ENABLE;
+ }
+ } else {
+ if (inno_conn_state->enc_out_format == HDMI_COLORSPACE_YUV444) {
+ csc_mode = CSC_RGB_0_255_TO_ITU709_16_235_8BIT;
+ auto_csc = AUTO_CSC_DISABLE;
+ c0_c2_change = C0_C2_CHANGE_DISABLE;
+ csc_enable = v_CSC_ENABLE;
+ }
}
}

@@ -473,6 +494,8 @@ inno_hdmi_encoder_atomic_check(struct drm_encoder *encoder,
inno_conn_state->colorimetry = HDMI_COLORIMETRY_ITU_709;

inno_conn_state->enc_out_format = HDMI_COLORSPACE_RGB;
+ inno_conn_state->rgb_limited_range =
+ drm_default_rgb_quant_range(mode) == HDMI_QUANTIZATION_RANGE_LIMITED;

return 0;
}
@@ -559,6 +582,7 @@ static void inno_hdmi_connector_reset(struct drm_connector *connector)

inno_conn_state->colorimetry = HDMI_COLORIMETRY_ITU_709;
inno_conn_state->enc_out_format = HDMI_COLORSPACE_RGB;
+ inno_conn_state->rgb_limited_range = false;
}

static struct drm_connector_state *
--
2.43.0


2023-12-22 17:47:24

by Alex Bee

[permalink] [raw]
Subject: [PATCH v4 17/29] drm/rockchip: inno_hdmi: Drop irq struct member

The struct member irq isn't used anywhere. Drop it.

Signed-off-by: Alex Bee <[email protected]>
Reviewed-by: Maxime Ripard <[email protected]>
---
changes in v2:
- new patch

changes in v3:
- collect RB

changes in v4:
- none

drivers/gpu/drm/rockchip/inno_hdmi.c | 1 -
1 file changed, 1 deletion(-)

diff --git a/drivers/gpu/drm/rockchip/inno_hdmi.c b/drivers/gpu/drm/rockchip/inno_hdmi.c
index 51c1a69dfcc0..138cd4287dea 100644
--- a/drivers/gpu/drm/rockchip/inno_hdmi.c
+++ b/drivers/gpu/drm/rockchip/inno_hdmi.c
@@ -45,7 +45,6 @@ struct inno_hdmi_i2c {
struct inno_hdmi {
struct device *dev;

- int irq;
struct clk *pclk;
void __iomem *regs;

--
2.43.0


2023-12-22 17:47:35

by Alex Bee

[permalink] [raw]
Subject: [PATCH v4 21/29] drm/rockchip: inno_hdmi: Don't power up the phy after resetting

inno_hdmi_reset is only ever called when initializing the controller. At
this point it’s completely uneccessary to power up the PHY, since all
what has to work at this point is the DDC bus. The phy will be powered up
correctly when a mode is set in inno_hdmi_encoder_enable and disabled in
inno_hdmi_encoder_disable.
Set it to LOWER_PWR after resetting the controller.

Signed-off-by: Alex Bee <[email protected]>
---
changes in v3:
- new patch

changes in v4:
- none

drivers/gpu/drm/rockchip/inno_hdmi.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/rockchip/inno_hdmi.c b/drivers/gpu/drm/rockchip/inno_hdmi.c
index f3b90b479ab9..52b49f44a4f4 100644
--- a/drivers/gpu/drm/rockchip/inno_hdmi.c
+++ b/drivers/gpu/drm/rockchip/inno_hdmi.c
@@ -202,7 +202,7 @@ static void inno_hdmi_reset(struct inno_hdmi *hdmi)
val = v_REG_CLK_INV | v_REG_CLK_SOURCE_SYS | v_PWR_ON | v_INT_POL_HIGH;
hdmi_modb(hdmi, HDMI_SYS_CTRL, msk, val);

- inno_hdmi_set_pwr_mode(hdmi, NORMAL);
+ inno_hdmi_set_pwr_mode(hdmi, LOWER_PWR);
}

static void inno_hdmi_disable_frame(struct inno_hdmi *hdmi,
--
2.43.0


2023-12-22 17:47:50

by Alex Bee

[permalink] [raw]
Subject: [PATCH v4 22/29] drm/rockchip: inno_hdmi: Split power mode setting

This splits setting the power mode of the controller / phy in two
functions. It's done in preparation of setting up the phy based on the
pixelclock.

No functional changes intended.

Signed-off-by: Alex Bee <[email protected]>
---
changes in v3:
- new patch

changes in v4:
- none

drivers/gpu/drm/rockchip/inno_hdmi.c | 54 +++++++++++++---------------
drivers/gpu/drm/rockchip/inno_hdmi.h | 5 ---
2 files changed, 24 insertions(+), 35 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/inno_hdmi.c b/drivers/gpu/drm/rockchip/inno_hdmi.c
index 52b49f44a4f4..44c311e7e2d3 100644
--- a/drivers/gpu/drm/rockchip/inno_hdmi.c
+++ b/drivers/gpu/drm/rockchip/inno_hdmi.c
@@ -154,38 +154,31 @@ static void inno_hdmi_sys_power(struct inno_hdmi *hdmi, bool enable)
hdmi_modb(hdmi, HDMI_SYS_CTRL, m_POWER, v_PWR_OFF);
}

-static void inno_hdmi_set_pwr_mode(struct inno_hdmi *hdmi, int mode)
+static void inno_hdmi_standby(struct inno_hdmi *hdmi)
{
- switch (mode) {
- case NORMAL:
- inno_hdmi_sys_power(hdmi, false);
+ inno_hdmi_sys_power(hdmi, false);

- hdmi_writeb(hdmi, HDMI_PHY_PRE_EMPHASIS, 0x6f);
- hdmi_writeb(hdmi, HDMI_PHY_DRIVER, 0xbb);
-
- hdmi_writeb(hdmi, HDMI_PHY_SYS_CTL, 0x15);
- hdmi_writeb(hdmi, HDMI_PHY_SYS_CTL, 0x14);
- hdmi_writeb(hdmi, HDMI_PHY_SYS_CTL, 0x10);
- hdmi_writeb(hdmi, HDMI_PHY_CHG_PWR, 0x0f);
- hdmi_writeb(hdmi, HDMI_PHY_SYNC, 0x00);
- hdmi_writeb(hdmi, HDMI_PHY_SYNC, 0x01);
-
- inno_hdmi_sys_power(hdmi, true);
- break;
+ hdmi_writeb(hdmi, HDMI_PHY_DRIVER, 0x00);
+ hdmi_writeb(hdmi, HDMI_PHY_PRE_EMPHASIS, 0x00);
+ hdmi_writeb(hdmi, HDMI_PHY_CHG_PWR, 0x00);
+ hdmi_writeb(hdmi, HDMI_PHY_SYS_CTL, 0x15);
+};

- case LOWER_PWR:
- inno_hdmi_sys_power(hdmi, false);
- hdmi_writeb(hdmi, HDMI_PHY_DRIVER, 0x00);
- hdmi_writeb(hdmi, HDMI_PHY_PRE_EMPHASIS, 0x00);
- hdmi_writeb(hdmi, HDMI_PHY_CHG_PWR, 0x00);
- hdmi_writeb(hdmi, HDMI_PHY_SYS_CTL, 0x15);
+static void inno_hdmi_power_up(struct inno_hdmi *hdmi)
+{
+ inno_hdmi_sys_power(hdmi, false);

- break;
+ hdmi_writeb(hdmi, HDMI_PHY_PRE_EMPHASIS, 0x6f);
+ hdmi_writeb(hdmi, HDMI_PHY_DRIVER, 0xbb);
+ hdmi_writeb(hdmi, HDMI_PHY_SYS_CTL, 0x15);
+ hdmi_writeb(hdmi, HDMI_PHY_SYS_CTL, 0x14);
+ hdmi_writeb(hdmi, HDMI_PHY_SYS_CTL, 0x10);
+ hdmi_writeb(hdmi, HDMI_PHY_CHG_PWR, 0x0f);
+ hdmi_writeb(hdmi, HDMI_PHY_SYNC, 0x00);
+ hdmi_writeb(hdmi, HDMI_PHY_SYNC, 0x01);

- default:
- DRM_DEV_ERROR(hdmi->dev, "Unknown power mode %d\n", mode);
- }
-}
+ inno_hdmi_sys_power(hdmi, true);
+};

static void inno_hdmi_reset(struct inno_hdmi *hdmi)
{
@@ -202,7 +195,7 @@ static void inno_hdmi_reset(struct inno_hdmi *hdmi)
val = v_REG_CLK_INV | v_REG_CLK_SOURCE_SYS | v_PWR_ON | v_INT_POL_HIGH;
hdmi_modb(hdmi, HDMI_SYS_CTRL, msk, val);

- inno_hdmi_set_pwr_mode(hdmi, LOWER_PWR);
+ inno_hdmi_standby(hdmi);
}

static void inno_hdmi_disable_frame(struct inno_hdmi *hdmi,
@@ -441,6 +434,8 @@ static int inno_hdmi_setup(struct inno_hdmi *hdmi,
hdmi_modb(hdmi, HDMI_AV_MUTE, m_AUDIO_MUTE | m_VIDEO_BLACK,
v_AUDIO_MUTE(0) | v_VIDEO_MUTE(0));

+ inno_hdmi_power_up(hdmi);
+
return 0;
}

@@ -460,7 +455,6 @@ static void inno_hdmi_encoder_enable(struct drm_encoder *encoder,
return;

inno_hdmi_setup(hdmi, &crtc_state->adjusted_mode);
- inno_hdmi_set_pwr_mode(hdmi, NORMAL);
}

static void inno_hdmi_encoder_disable(struct drm_encoder *encoder,
@@ -468,7 +462,7 @@ static void inno_hdmi_encoder_disable(struct drm_encoder *encoder,
{
struct inno_hdmi *hdmi = encoder_to_inno_hdmi(encoder);

- inno_hdmi_set_pwr_mode(hdmi, LOWER_PWR);
+ inno_hdmi_standby(hdmi);
}

static int
diff --git a/drivers/gpu/drm/rockchip/inno_hdmi.h b/drivers/gpu/drm/rockchip/inno_hdmi.h
index 93245b55f967..a7edf3559e60 100644
--- a/drivers/gpu/drm/rockchip/inno_hdmi.h
+++ b/drivers/gpu/drm/rockchip/inno_hdmi.h
@@ -10,11 +10,6 @@

#define DDC_SEGMENT_ADDR 0x30

-enum PWR_MODE {
- NORMAL,
- LOWER_PWR,
-};
-
#define HDMI_SCL_RATE (100*1000)
#define DDC_BUS_FREQ_L 0x4b
#define DDC_BUS_FREQ_H 0x4c
--
2.43.0


2023-12-22 17:48:00

by Alex Bee

[permalink] [raw]
Subject: [PATCH v4 19/29] drm/rockchip: inno_hdmi: Subclass connector state

The data which is currently hold in hdmi_data should not be part of device
itself but of the connector state.
Introduce a connector state subclass and move the data from hdmi_data in
there.

Suggested-by: Maxime Ripard <[email protected]>
Signed-off-by: Alex Bee <[email protected]>
---
changes in v2:
- new patch

changes in v3:
- added missing customizations of reset and atomic_destroy_state connector hooks
- moved inno_conn_state member assignments to atomic_check

changes in v4:
- added missing state destroy in reset hook

drivers/gpu/drm/rockchip/inno_hdmi.c | 117 ++++++++++++++++++++-------
1 file changed, 90 insertions(+), 27 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/inno_hdmi.c b/drivers/gpu/drm/rockchip/inno_hdmi.c
index c306db90832a..e43fce968310 100644
--- a/drivers/gpu/drm/rockchip/inno_hdmi.c
+++ b/drivers/gpu/drm/rockchip/inno_hdmi.c
@@ -26,11 +26,6 @@

#include "inno_hdmi.h"

-struct hdmi_data_info {
- unsigned int enc_out_format;
- unsigned int colorimetry;
-};
-
struct inno_hdmi_i2c {
struct i2c_adapter adap;

@@ -52,8 +47,12 @@ struct inno_hdmi {

struct inno_hdmi_i2c *i2c;
struct i2c_adapter *ddc;
+};

- struct hdmi_data_info hdmi_data;
+struct inno_hdmi_connector_state {
+ struct drm_connector_state base;
+ unsigned int enc_out_format;
+ unsigned int colorimetry;
};

static struct inno_hdmi *encoder_to_inno_hdmi(struct drm_encoder *encoder)
@@ -68,6 +67,9 @@ static struct inno_hdmi *connector_to_inno_hdmi(struct drm_connector *connector)
return container_of(connector, struct inno_hdmi, connector);
}

+#define to_inno_hdmi_conn_state(conn_state) \
+ container_of_const(conn_state, struct inno_hdmi_connector_state, base)
+
enum {
CSC_RGB_0_255_TO_ITU601_16_235_8BIT,
CSC_RGB_0_255_TO_ITU709_16_235_8BIT,
@@ -246,6 +248,10 @@ static int inno_hdmi_upload_frame(struct inno_hdmi *hdmi,
static int inno_hdmi_config_video_avi(struct inno_hdmi *hdmi,
struct drm_display_mode *mode)
{
+ struct drm_connector *connector = &hdmi->connector;
+ struct drm_connector_state *conn_state = connector->state;
+ struct inno_hdmi_connector_state *inno_conn_state =
+ to_inno_hdmi_conn_state(conn_state);
union hdmi_infoframe frame;
int rc;

@@ -257,9 +263,9 @@ static int inno_hdmi_config_video_avi(struct inno_hdmi *hdmi,
return rc;
}

- if (hdmi->hdmi_data.enc_out_format == HDMI_COLORSPACE_YUV444)
+ if (inno_conn_state->enc_out_format == HDMI_COLORSPACE_YUV444)
frame.avi.colorspace = HDMI_COLORSPACE_YUV444;
- else if (hdmi->hdmi_data.enc_out_format == HDMI_COLORSPACE_YUV422)
+ else if (inno_conn_state->enc_out_format == HDMI_COLORSPACE_YUV422)
frame.avi.colorspace = HDMI_COLORSPACE_YUV422;
else
frame.avi.colorspace = HDMI_COLORSPACE_RGB;
@@ -269,7 +275,10 @@ static int inno_hdmi_config_video_avi(struct inno_hdmi *hdmi,

static int inno_hdmi_config_video_csc(struct inno_hdmi *hdmi)
{
- struct hdmi_data_info *data = &hdmi->hdmi_data;
+ struct drm_connector *connector = &hdmi->connector;
+ struct drm_connector_state *conn_state = connector->state;
+ struct inno_hdmi_connector_state *inno_conn_state =
+ to_inno_hdmi_conn_state(conn_state);
int c0_c2_change = 0;
int csc_enable = 0;
int csc_mode = 0;
@@ -287,7 +296,7 @@ static int inno_hdmi_config_video_csc(struct inno_hdmi *hdmi)
v_VIDEO_INPUT_CSP(0);
hdmi_writeb(hdmi, HDMI_VIDEO_CONTRL2, value);

- if (data->enc_out_format == HDMI_COLORSPACE_RGB) {
+ if (inno_conn_state->enc_out_format == HDMI_COLORSPACE_RGB) {
value = v_SOF_DISABLE | v_COLOR_DEPTH_NOT_INDICATED(1);
hdmi_writeb(hdmi, HDMI_VIDEO_CONTRL3, value);

@@ -298,15 +307,15 @@ static int inno_hdmi_config_video_csc(struct inno_hdmi *hdmi)
return 0;
}

- if (data->colorimetry == HDMI_COLORIMETRY_ITU_601) {
- if (data->enc_out_format == HDMI_COLORSPACE_YUV444) {
+ if (inno_conn_state->colorimetry == HDMI_COLORIMETRY_ITU_601) {
+ if (inno_conn_state->enc_out_format == HDMI_COLORSPACE_YUV444) {
csc_mode = CSC_RGB_0_255_TO_ITU601_16_235_8BIT;
auto_csc = AUTO_CSC_DISABLE;
c0_c2_change = C0_C2_CHANGE_DISABLE;
csc_enable = v_CSC_ENABLE;
}
} else {
- if (data->enc_out_format == HDMI_COLORSPACE_YUV444) {
+ if (inno_conn_state->enc_out_format == HDMI_COLORSPACE_YUV444) {
csc_mode = CSC_RGB_0_255_TO_ITU709_16_235_8BIT;
auto_csc = AUTO_CSC_DISABLE;
c0_c2_change = C0_C2_CHANGE_DISABLE;
@@ -383,17 +392,6 @@ static int inno_hdmi_setup(struct inno_hdmi *hdmi,
struct drm_display_mode *mode)
{
struct drm_display_info *display = &hdmi->connector.display_info;
- u8 vic = drm_match_cea_mode(mode);
-
- hdmi->hdmi_data.enc_out_format = HDMI_COLORSPACE_RGB;
-
- if (vic == 6 || vic == 7 ||
- vic == 21 || vic == 22 ||
- vic == 2 || vic == 3 ||
- vic == 17 || vic == 18)
- hdmi->hdmi_data.colorimetry = HDMI_COLORIMETRY_ITU_601;
- else
- hdmi->hdmi_data.colorimetry = HDMI_COLORIMETRY_ITU_709;

/* Mute video and audio output */
hdmi_modb(hdmi, HDMI_AV_MUTE, m_AUDIO_MUTE | m_VIDEO_BLACK,
@@ -458,10 +456,24 @@ inno_hdmi_encoder_atomic_check(struct drm_encoder *encoder,
struct drm_connector_state *conn_state)
{
struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc_state);
+ struct drm_display_mode *mode = &crtc_state->adjusted_mode;
+ u8 vic = drm_match_cea_mode(mode);
+ struct inno_hdmi_connector_state *inno_conn_state =
+ to_inno_hdmi_conn_state(conn_state);

s->output_mode = ROCKCHIP_OUT_MODE_P888;
s->output_type = DRM_MODE_CONNECTOR_HDMIA;

+ if (vic == 6 || vic == 7 ||
+ vic == 21 || vic == 22 ||
+ vic == 2 || vic == 3 ||
+ vic == 17 || vic == 18)
+ inno_conn_state->colorimetry = HDMI_COLORIMETRY_ITU_601;
+ else
+ inno_conn_state->colorimetry = HDMI_COLORIMETRY_ITU_709;
+
+ inno_conn_state->enc_out_format = HDMI_COLORSPACE_RGB;
+
return 0;
}

@@ -519,13 +531,63 @@ static void inno_hdmi_connector_destroy(struct drm_connector *connector)
drm_connector_cleanup(connector);
}

+static void
+inno_hdmi_connector_destroy_state(struct drm_connector *connector,
+ struct drm_connector_state *state)
+{
+ struct inno_hdmi_connector_state *inno_conn_state =
+ to_inno_hdmi_conn_state(state);
+
+ __drm_atomic_helper_connector_destroy_state(&inno_conn_state->base);
+ kfree(inno_conn_state);
+}
+
+static void inno_hdmi_connector_reset(struct drm_connector *connector)
+{
+ struct inno_hdmi_connector_state *inno_conn_state;
+
+ if (connector->state) {
+ inno_hdmi_connector_destroy_state(connector, connector->state);
+ connector->state = NULL;
+ }
+
+ inno_conn_state = kzalloc(sizeof(*inno_conn_state), GFP_KERNEL);
+ if (!inno_conn_state)
+ return;
+
+ __drm_atomic_helper_connector_reset(connector, &inno_conn_state->base);
+
+ inno_conn_state->colorimetry = HDMI_COLORIMETRY_ITU_709;
+ inno_conn_state->enc_out_format = HDMI_COLORSPACE_RGB;
+}
+
+static struct drm_connector_state *
+inno_hdmi_connector_duplicate_state(struct drm_connector *connector)
+{
+ struct inno_hdmi_connector_state *inno_conn_state;
+
+ if (WARN_ON(!connector->state))
+ return NULL;
+
+ inno_conn_state = kmemdup(to_inno_hdmi_conn_state(connector->state),
+ sizeof(*inno_conn_state), GFP_KERNEL);
+
+ if (!inno_conn_state)
+ return NULL;
+
+ __drm_atomic_helper_connector_duplicate_state(connector,
+ &inno_conn_state->base);
+
+ return &inno_conn_state->base;
+}
+
static const struct drm_connector_funcs inno_hdmi_connector_funcs = {
.fill_modes = inno_hdmi_probe_single_connector_modes,
.detect = inno_hdmi_connector_detect,
.destroy = inno_hdmi_connector_destroy,
- .reset = drm_atomic_helper_connector_reset,
- .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
- .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
+ .reset = inno_hdmi_connector_reset,
+ .atomic_duplicate_state = inno_hdmi_connector_duplicate_state,
+ .atomic_destroy_state = inno_hdmi_connector_destroy_state,
};

static struct drm_connector_helper_funcs inno_hdmi_connector_helper_funcs = {
--
2.43.0


2023-12-22 17:48:28

by Alex Bee

[permalink] [raw]
Subject: [PATCH v4 24/29] drm/rockchip: inno_hdmi: Add RK3128 support

This variant requires the phy reference clock to be enabled before the DDC
block can work and the (initial) DDC bus frequency is calculated based on
the rate of this clock. Besides the only difference is phy configuration
required to make the driver working for this variant as well.

Signed-off-by: Alex Bee <[email protected]>
---
changes in v2:
- no changes

changes in v3:
- no changes

changes in v4:
- none

drivers/gpu/drm/rockchip/inno_hdmi.c | 46 +++++++++++++++++++++++++---
1 file changed, 41 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/inno_hdmi.c b/drivers/gpu/drm/rockchip/inno_hdmi.c
index 34f0358e8d7b..3b76929deefe 100644
--- a/drivers/gpu/drm/rockchip/inno_hdmi.c
+++ b/drivers/gpu/drm/rockchip/inno_hdmi.c
@@ -51,6 +51,7 @@ struct inno_hdmi {
struct device *dev;

struct clk *pclk;
+ struct clk *refclk;
void __iomem *regs;

struct drm_connector connector;
@@ -132,6 +133,12 @@ static struct inno_hdmi_phy_config rk3036_hdmi_phy_configs[] = {
{ ~0UL, 0x00, 0x00 }
};

+static struct inno_hdmi_phy_config rk3128_hdmi_phy_configs[] = {
+ { 74250000, 0x3f, 0xaa },
+ { 165000000, 0x5f, 0xaa },
+ { ~0UL, 0x00, 0x00 }
+};
+
static int inno_hdmi_find_phy_config(struct inno_hdmi *hdmi,
unsigned long pixelclk)
{
@@ -911,6 +918,20 @@ static int inno_hdmi_bind(struct device *dev, struct device *master,
return ret;
}

+ hdmi->refclk = devm_clk_get_optional(hdmi->dev, "ref");
+ if (IS_ERR(hdmi->refclk)) {
+ DRM_DEV_ERROR(hdmi->dev, "Unable to get HDMI reference clock\n");
+ ret = PTR_ERR(hdmi->refclk);
+ goto err_disable_pclk;
+ }
+
+ ret = clk_prepare_enable(hdmi->refclk);
+ if (ret) {
+ DRM_DEV_ERROR(hdmi->dev,
+ "Cannot enable HDMI reference clock: %d\n", ret);
+ goto err_disable_pclk;
+ }
+
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
ret = irq;
@@ -927,12 +948,16 @@ static int inno_hdmi_bind(struct device *dev, struct device *master,
}

/*
- * When IP controller haven't configured to an accurate video
- * timing, then the TMDS clock source would be switched to
- * PCLK_HDMI, so we need to init the TMDS rate to PCLK rate,
- * and reconfigure the DDC clock.
+ * When the controller isn't configured to an accurate
+ * video timing and there is no reference clock available,
+ * then the TMDS clock source would be switched to PCLK_HDMI,
+ * so we need to init the TMDS rate to PCLK rate, and
+ * reconfigure the DDC clock.
*/
- inno_hdmi_i2c_init(hdmi, clk_get_rate(hdmi->pclk));
+ if (hdmi->refclk)
+ inno_hdmi_i2c_init(hdmi, clk_get_rate(hdmi->refclk));
+ else
+ inno_hdmi_i2c_init(hdmi, clk_get_rate(hdmi->pclk));

ret = inno_hdmi_register(drm, hdmi);
if (ret)
@@ -956,6 +981,8 @@ static int inno_hdmi_bind(struct device *dev, struct device *master,
err_put_adapter:
i2c_put_adapter(hdmi->ddc);
err_disable_clk:
+ clk_disable_unprepare(hdmi->refclk);
+err_disable_pclk:
clk_disable_unprepare(hdmi->pclk);
return ret;
}
@@ -969,6 +996,7 @@ static void inno_hdmi_unbind(struct device *dev, struct device *master,
hdmi->encoder.encoder.funcs->destroy(&hdmi->encoder.encoder);

i2c_put_adapter(hdmi->ddc);
+ clk_disable_unprepare(hdmi->refclk);
clk_disable_unprepare(hdmi->pclk);
}

@@ -992,10 +1020,18 @@ static const struct inno_hdmi_variant rk3036_inno_hdmi_variant = {
.default_phy_config = &rk3036_hdmi_phy_configs[1],
};

+static const struct inno_hdmi_variant rk3128_inno_hdmi_variant = {
+ .phy_configs = rk3128_hdmi_phy_configs,
+ .default_phy_config = &rk3128_hdmi_phy_configs[1],
+};
+
static const struct of_device_id inno_hdmi_dt_ids[] = {
{ .compatible = "rockchip,rk3036-inno-hdmi",
.data = &rk3036_inno_hdmi_variant,
},
+ { .compatible = "rockchip,rk3128-inno-hdmi",
+ .data = &rk3128_inno_hdmi_variant,
+ },
{},
};
MODULE_DEVICE_TABLE(of, inno_hdmi_dt_ids);
--
2.43.0


2023-12-22 17:48:47

by Alex Bee

[permalink] [raw]
Subject: [PATCH v4 23/29] drm/rockchip: inno_hdmi: Add variant support

In preparation to support RK3128's integration of the controller, this
patch adds a simple variant implementation. They mainly differ in the phy
configuration required, so those are part of the match_data. The values
have been taken from downstream. The pixelclocks in there are meant to be
max-inclusive.

Signed-off-by: Alex Bee <[email protected]>
---
changes in v2:
- no changes

changes in v3:
- adapt to the newly introduced inno_hdmi_power_up / inno_hdmi_standby functions

changes in v4:
- none

drivers/gpu/drm/rockchip/inno_hdmi.c | 74 ++++++++++++++++++++++++++--
1 file changed, 69 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/inno_hdmi.c b/drivers/gpu/drm/rockchip/inno_hdmi.c
index 44c311e7e2d3..34f0358e8d7b 100644
--- a/drivers/gpu/drm/rockchip/inno_hdmi.c
+++ b/drivers/gpu/drm/rockchip/inno_hdmi.c
@@ -26,6 +26,17 @@

#include "inno_hdmi.h"

+struct inno_hdmi_phy_config {
+ unsigned long pixelclock;
+ u8 pre_emphasis;
+ u8 voltage_level_control;
+};
+
+struct inno_hdmi_variant {
+ struct inno_hdmi_phy_config *phy_configs;
+ struct inno_hdmi_phy_config *default_phy_config;
+};
+
struct inno_hdmi_i2c {
struct i2c_adapter adap;

@@ -47,6 +58,8 @@ struct inno_hdmi {

struct inno_hdmi_i2c *i2c;
struct i2c_adapter *ddc;
+
+ const struct inno_hdmi_variant *variant;
};

struct inno_hdmi_connector_state {
@@ -113,6 +126,30 @@ static const char coeff_csc[][24] = {
},
};

+static struct inno_hdmi_phy_config rk3036_hdmi_phy_configs[] = {
+ { 74250000, 0x3f, 0xbb },
+ { 165000000, 0x6f, 0xbb },
+ { ~0UL, 0x00, 0x00 }
+};
+
+static int inno_hdmi_find_phy_config(struct inno_hdmi *hdmi,
+ unsigned long pixelclk)
+{
+ const struct inno_hdmi_phy_config *phy_configs =
+ hdmi->variant->phy_configs;
+ int i;
+
+ for (i = 0; phy_configs[i].pixelclock != ~0UL; i++) {
+ if (pixelclk <= phy_configs[i].pixelclock)
+ return i;
+ }
+
+ DRM_DEV_DEBUG(hdmi->dev, "No phy configuration for pixelclock %lu\n",
+ pixelclk);
+
+ return -EINVAL;
+}
+
static inline u8 hdmi_readb(struct inno_hdmi *hdmi, u16 offset)
{
return readl_relaxed(hdmi->regs + (offset) * 0x04);
@@ -164,12 +201,25 @@ static void inno_hdmi_standby(struct inno_hdmi *hdmi)
hdmi_writeb(hdmi, HDMI_PHY_SYS_CTL, 0x15);
};

-static void inno_hdmi_power_up(struct inno_hdmi *hdmi)
+static void inno_hdmi_power_up(struct inno_hdmi *hdmi,
+ unsigned long mpixelclock)
{
+ struct inno_hdmi_phy_config *phy_config;
+ int ret = inno_hdmi_find_phy_config(hdmi, mpixelclock);
+
+ if (ret < 0) {
+ phy_config = hdmi->variant->default_phy_config;
+ DRM_DEV_ERROR(hdmi->dev,
+ "Using default phy configuration for TMDS rate %lu",
+ mpixelclock);
+ } else {
+ phy_config = &hdmi->variant->phy_configs[ret];
+ }
+
inno_hdmi_sys_power(hdmi, false);

- hdmi_writeb(hdmi, HDMI_PHY_PRE_EMPHASIS, 0x6f);
- hdmi_writeb(hdmi, HDMI_PHY_DRIVER, 0xbb);
+ hdmi_writeb(hdmi, HDMI_PHY_PRE_EMPHASIS, phy_config->pre_emphasis);
+ hdmi_writeb(hdmi, HDMI_PHY_DRIVER, phy_config->voltage_level_control);
hdmi_writeb(hdmi, HDMI_PHY_SYS_CTL, 0x15);
hdmi_writeb(hdmi, HDMI_PHY_SYS_CTL, 0x14);
hdmi_writeb(hdmi, HDMI_PHY_SYS_CTL, 0x10);
@@ -406,6 +456,7 @@ static int inno_hdmi_setup(struct inno_hdmi *hdmi,
struct drm_display_mode *mode)
{
struct drm_display_info *display = &hdmi->connector.display_info;
+ unsigned long mpixelclock = mode->clock * 1000;

/* Mute video and audio output */
hdmi_modb(hdmi, HDMI_AV_MUTE, m_AUDIO_MUTE | m_VIDEO_BLACK,
@@ -428,13 +479,13 @@ static int inno_hdmi_setup(struct inno_hdmi *hdmi,
* DCLK_LCDC, so we need to init the TMDS rate to mode pixel
* clock rate, and reconfigure the DDC clock.
*/
- inno_hdmi_i2c_init(hdmi, mode->clock * 1000);
+ inno_hdmi_i2c_init(hdmi, mpixelclock);

/* Unmute video and audio output */
hdmi_modb(hdmi, HDMI_AV_MUTE, m_AUDIO_MUTE | m_VIDEO_BLACK,
v_AUDIO_MUTE(0) | v_VIDEO_MUTE(0));

- inno_hdmi_power_up(hdmi);
+ inno_hdmi_power_up(hdmi, mpixelclock);

return 0;
}
@@ -827,6 +878,7 @@ static int inno_hdmi_bind(struct device *dev, struct device *master,
struct platform_device *pdev = to_platform_device(dev);
struct drm_device *drm = data;
struct inno_hdmi *hdmi;
+ const struct inno_hdmi_variant *variant;
int irq;
int ret;

@@ -836,6 +888,12 @@ static int inno_hdmi_bind(struct device *dev, struct device *master,

hdmi->dev = dev;

+ variant = of_device_get_match_data(hdmi->dev);
+ if (!variant)
+ return -EINVAL;
+
+ hdmi->variant = variant;
+
hdmi->regs = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(hdmi->regs))
return PTR_ERR(hdmi->regs);
@@ -929,8 +987,14 @@ static void inno_hdmi_remove(struct platform_device *pdev)
component_del(&pdev->dev, &inno_hdmi_ops);
}

+static const struct inno_hdmi_variant rk3036_inno_hdmi_variant = {
+ .phy_configs = rk3036_hdmi_phy_configs,
+ .default_phy_config = &rk3036_hdmi_phy_configs[1],
+};
+
static const struct of_device_id inno_hdmi_dt_ids[] = {
{ .compatible = "rockchip,rk3036-inno-hdmi",
+ .data = &rk3036_inno_hdmi_variant,
},
{},
};
--
2.43.0


2023-12-22 17:48:52

by Alex Bee

[permalink] [raw]
Subject: [PATCH v4 26/29] drm/rockchip: inno_hdmi: Drop custom fill_modes hook

Now that we have proper pixelclock-based mode validation we can drop the
custom fill_modes hook.
CRTC size validation for the display controller has been added with
Commit 8e140cb60270 ("drm/rockchip: vop: limit maximum resolution to
hardware capabilities")

Signed-off-by: Alex Bee <[email protected]>
Reviewed-by: Maxime Ripard <[email protected]>
---
changes in v2:
- no changes

changes in v3:
- collect RB

changes in v4:
- none

drivers/gpu/drm/rockchip/inno_hdmi.c | 9 +--------
1 file changed, 1 insertion(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/inno_hdmi.c b/drivers/gpu/drm/rockchip/inno_hdmi.c
index a074451a0c49..d7453c36d37a 100644
--- a/drivers/gpu/drm/rockchip/inno_hdmi.c
+++ b/drivers/gpu/drm/rockchip/inno_hdmi.c
@@ -630,13 +630,6 @@ inno_hdmi_connector_mode_valid(struct drm_connector *connector,
return inno_hdmi_display_mode_valid(hdmi, mode);
}

-static int
-inno_hdmi_probe_single_connector_modes(struct drm_connector *connector,
- uint32_t maxX, uint32_t maxY)
-{
- return drm_helper_probe_single_connector_modes(connector, 1920, 1080);
-}
-
static void inno_hdmi_connector_destroy(struct drm_connector *connector)
{
drm_connector_unregister(connector);
@@ -695,7 +688,7 @@ inno_hdmi_connector_duplicate_state(struct drm_connector *connector)
}

static const struct drm_connector_funcs inno_hdmi_connector_funcs = {
- .fill_modes = inno_hdmi_probe_single_connector_modes,
+ .fill_modes = drm_helper_probe_single_connector_modes,
.detect = inno_hdmi_connector_detect,
.destroy = inno_hdmi_connector_destroy,
.reset = inno_hdmi_connector_reset,
--
2.43.0


2023-12-22 17:49:11

by Alex Bee

[permalink] [raw]
Subject: [PATCH v4 25/29] drm/rockchip: inno_hdmi: Add basic mode validation

As per TRM this controller supports pixelclocks starting from 25 MHz. The
maximum supported pixelclocks are defined by the phy configurations we
have. Also it can't support modes that require doubled clocks. If the
variant has a phy reference clock we can additionally validate against VESA
DMT'srecommendations.

Signed-off-by: Alex Bee <[email protected]>
Reviewed-by: Maxime Ripard <[email protected]>
---
changes in v2:
- rename inno_mode_valid -> inno_hdmi_display_mode_valid
- fixed max_tolerance calculation
- use abs_diff() instead of abs()
- call in inno_hdmi_display_mode_valid in atomic_check

changes in v3:
- collect RB

changes in v4:
- none

drivers/gpu/drm/rockchip/inno_hdmi.c | 42 ++++++++++++++++++++++++++--
1 file changed, 40 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/inno_hdmi.c b/drivers/gpu/drm/rockchip/inno_hdmi.c
index 3b76929deefe..a074451a0c49 100644
--- a/drivers/gpu/drm/rockchip/inno_hdmi.c
+++ b/drivers/gpu/drm/rockchip/inno_hdmi.c
@@ -26,6 +26,8 @@

#include "inno_hdmi.h"

+#define INNO_HDMI_MIN_TMDS_CLOCK 25000000U
+
struct inno_hdmi_phy_config {
unsigned long pixelclock;
u8 pre_emphasis;
@@ -497,6 +499,38 @@ static int inno_hdmi_setup(struct inno_hdmi *hdmi,
return 0;
}

+static enum drm_mode_status inno_hdmi_display_mode_valid(struct inno_hdmi *hdmi,
+ struct drm_display_mode *mode)
+{
+ unsigned long mpixelclk, max_tolerance;
+ long rounded_refclk;
+
+ /* No support for double-clock modes */
+ if (mode->flags & DRM_MODE_FLAG_DBLCLK)
+ return MODE_BAD;
+
+ mpixelclk = mode->clock * 1000;
+
+ if (mpixelclk < INNO_HDMI_MIN_TMDS_CLOCK)
+ return MODE_CLOCK_LOW;
+
+ if (inno_hdmi_find_phy_config(hdmi, mpixelclk) < 0)
+ return MODE_CLOCK_HIGH;
+
+ if (hdmi->refclk) {
+ rounded_refclk = clk_round_rate(hdmi->refclk, mpixelclk);
+ if (rounded_refclk < 0)
+ return MODE_BAD;
+
+ /* Vesa DMT standard mentions +/- 0.5% max tolerance */
+ max_tolerance = mpixelclk / 200;
+ if (abs_diff((unsigned long)rounded_refclk, mpixelclk) > max_tolerance)
+ return MODE_NOCLOCK;
+ }
+
+ return MODE_OK;
+}
+
static void inno_hdmi_encoder_enable(struct drm_encoder *encoder,
struct drm_atomic_state *state)
{
@@ -529,6 +563,7 @@ inno_hdmi_encoder_atomic_check(struct drm_encoder *encoder,
struct drm_connector_state *conn_state)
{
struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc_state);
+ struct inno_hdmi *hdmi = encoder_to_inno_hdmi(encoder);
struct drm_display_mode *mode = &crtc_state->adjusted_mode;
u8 vic = drm_match_cea_mode(mode);
struct inno_hdmi_connector_state *inno_conn_state =
@@ -549,7 +584,8 @@ inno_hdmi_encoder_atomic_check(struct drm_encoder *encoder,
inno_conn_state->rgb_limited_range =
drm_default_rgb_quant_range(mode) == HDMI_QUANTIZATION_RANGE_LIMITED;

- return 0;
+ return inno_hdmi_display_mode_valid(hdmi,
+ &crtc_state->adjusted_mode) == MODE_OK ? 0 : -EINVAL;
}

static struct drm_encoder_helper_funcs inno_hdmi_encoder_helper_funcs = {
@@ -590,7 +626,9 @@ static enum drm_mode_status
inno_hdmi_connector_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode)
{
- return MODE_OK;
+ struct inno_hdmi *hdmi = connector_to_inno_hdmi(connector);
+
+ return inno_hdmi_display_mode_valid(hdmi, mode);
}

static int
--
2.43.0


2023-12-22 17:49:33

by Alex Bee

[permalink] [raw]
Subject: [PATCH v4 27/29] ARM: dts: rockchip: Add display subsystem for RK3128

Add vop and display-subsystem nodes to RK3128's device tree.

Signed-off-by: Alex Bee <[email protected]>
---
changes in v2:
- no changes

changes in v3:
- no changes

changes in v4:
- none

arch/arm/boot/dts/rockchip/rk3128.dtsi | 27 ++++++++++++++++++++++++++
1 file changed, 27 insertions(+)

diff --git a/arch/arm/boot/dts/rockchip/rk3128.dtsi b/arch/arm/boot/dts/rockchip/rk3128.dtsi
index e2264c40b924..1a3bc8b2bc6e 100644
--- a/arch/arm/boot/dts/rockchip/rk3128.dtsi
+++ b/arch/arm/boot/dts/rockchip/rk3128.dtsi
@@ -115,6 +115,12 @@ opp-1200000000 {
};
};

+ display_subsystem: display-subsystem {
+ compatible = "rockchip,display-subsystem";
+ ports = <&vop_out>;
+ status = "disabled";
+ };
+
gpu_opp_table: opp-table-1 {
compatible = "operating-points-v2";

@@ -246,6 +252,27 @@ power-domain@RK3128_PD_GPU {
};
};

+ vop: vop@1010e000 {
+ compatible = "rockchip,rk3126-vop";
+ reg = <0x1010e000 0x300>;
+ interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru ACLK_LCDC0>, <&cru DCLK_VOP>,
+ <&cru HCLK_LCDC0>;
+ clock-names = "aclk_vop", "dclk_vop",
+ "hclk_vop";
+ resets = <&cru SRST_VOP_A>, <&cru SRST_VOP_H>,
+ <&cru SRST_VOP_D>;
+ reset-names = "axi", "ahb",
+ "dclk";
+ power-domains = <&power RK3128_PD_VIO>;
+ status = "disabled";
+
+ vop_out: port {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+
qos_gpu: qos@1012d000 {
compatible = "rockchip,rk3128-qos", "syscon";
reg = <0x1012d000 0x20>;
--
2.43.0


2023-12-22 17:49:39

by Alex Bee

[permalink] [raw]
Subject: [PATCH v4 29/29] ARM: dts: rockchip: Enable HDMI output for XPI-3128

Add an hdmi-connector node and enable the hdmi, display-subsystem and vop
nodes.

Signed-off-by: Alex Bee <[email protected]>
---
changes in v2:
- no changes

changes in v3:
- no changes

changes in v4:
- none

.../arm/boot/dts/rockchip/rk3128-xpi-3128.dts | 29 +++++++++++++++++++
1 file changed, 29 insertions(+)

diff --git a/arch/arm/boot/dts/rockchip/rk3128-xpi-3128.dts b/arch/arm/boot/dts/rockchip/rk3128-xpi-3128.dts
index 03a97881519a..21c1678f4e91 100644
--- a/arch/arm/boot/dts/rockchip/rk3128-xpi-3128.dts
+++ b/arch/arm/boot/dts/rockchip/rk3128-xpi-3128.dts
@@ -47,6 +47,17 @@ dc_5v: dc-5v-regulator {
regulator-boot-on;
};

+ hdmi-connnector {
+ compatible = "hdmi-connector";
+ type = "a";
+
+ port {
+ hdmi_connector_in: endpoint {
+ remote-endpoint = <&hdmi_connector_out>;
+ };
+ };
+ };
+
/*
* This is a vbus-supply, which also supplies the GL852G usb hub,
* thus has to be always-on
@@ -239,6 +250,10 @@ &cpu0 {
cpu-supply = <&vdd_arm>;
};

+&display_subsystem {
+ status = "okay";
+};
+
&emmc {
bus-width = <8>;
vmmc-supply = <&vcc_io>;
@@ -328,6 +343,16 @@ &gpu {
status = "okay";
};

+&hdmi {
+ status = "okay";
+};
+
+&hdmi_out {
+ hdmi_connector_out: endpoint {
+ remote-endpoint = <&hdmi_connector_in>;
+ };
+};
+
&mdio {
phy0: ethernet-phy@1 {
compatible = "ethernet-phy-ieee802.3-c22";
@@ -423,3 +448,7 @@ &usb2phy_host {
&usb2phy_otg {
status = "okay";
};
+
+&vop {
+ status = "okay";
+};
--
2.43.0


2023-12-22 17:59:58

by Alex Bee

[permalink] [raw]
Subject: [PATCH v4 28/29] ARM: dts: rockchip: Add HDMI node for RK3128

RK3128 has Innosilicon based HDMI TX controller similar to the one found in
RK3036.
Add it and the respective port nodes to the SoC device tree.

Signed-off-by: Alex Bee <[email protected]>
---
changes in v2:
- no changes

changes in v3:
- no changes

changes in v4:
- none

arch/arm/boot/dts/rockchip/rk3128.dtsi | 33 ++++++++++++++++++++++++++
1 file changed, 33 insertions(+)

diff --git a/arch/arm/boot/dts/rockchip/rk3128.dtsi b/arch/arm/boot/dts/rockchip/rk3128.dtsi
index 1a3bc8b2bc6e..fb98873fd94e 100644
--- a/arch/arm/boot/dts/rockchip/rk3128.dtsi
+++ b/arch/arm/boot/dts/rockchip/rk3128.dtsi
@@ -270,6 +270,11 @@ vop: vop@1010e000 {
vop_out: port {
#address-cells = <1>;
#size-cells = <0>;
+
+ vop_out_hdmi: endpoint@0 {
+ reg = <0>;
+ remote-endpoint = <&hdmi_in_vop>;
+ };
};
};

@@ -463,6 +468,34 @@ usb2phy_otg: otg-port {
};
};

+ hdmi: hdmi@20034000 {
+ compatible = "rockchip,rk3128-inno-hdmi";
+ reg = <0x20034000 0x4000>;
+ interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru PCLK_HDMI>, <&cru DCLK_VOP>;
+ clock-names = "pclk", "ref";
+ pinctrl-names = "default";
+ pinctrl-0 = <&hdmii2c_xfer &hdmi_hpd &hdmi_cec>;
+ power-domains = <&power RK3128_PD_VIO>;
+ status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ hdmi_in: port@0 {
+ reg = <0>;
+ hdmi_in_vop: endpoint {
+ remote-endpoint = <&vop_out_hdmi>;
+ };
+ };
+
+ hdmi_out: port@1 {
+ reg = <1>;
+ };
+ };
+ };
+
timer0: timer@20044000 {
compatible = "rockchip,rk3128-timer", "rockchip,rk3288-timer";
reg = <0x20044000 0x20>;
--
2.43.0


2023-12-29 23:26:54

by Heiko Stübner

[permalink] [raw]
Subject: Re: [PATCH v4 01/29] dt-bindings: display: rockchip,inno-hdmi: Document RK3128 compatible

Am Freitag, 22. Dezember 2023, 18:41:52 CET schrieb Alex Bee:
> The integration for this SoC is different from the currently existing: It
> needs it's PHY's reference clock rate to calculate the DDC bus frequency
> correctly. The controller is also part of a powerdomain, so this gets added
> as an mandatory property for this variant.
>
> Signed-off-by: Alex Bee <[email protected]>
> Reviewed-by: Conor Dooley <[email protected]>

this is just a note to myself:

The binding conversion to yaml was picked by Rob in [0], so will most
likely be part of 6.8-rc1, so this will need to wait until 6.8-rc1 gets into
drm-misc-next .


Heiko


[0] https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git/commit/?h=for-next&id=7048708fec3a401f9a70e4a74e2e12aa7f88c132

> ---
> changes in v2:
> - clarify that the controller itself is part of the powerdomain
> - simplify clock-names
> - made power-domains property only allowed (and required) for new variant
>
> changes in v3:
> - collect RB
>
> changes in v4:
> - none
>
> .../display/rockchip/rockchip,inno-hdmi.yaml | 40 ++++++++++++++++++-
> 1 file changed, 38 insertions(+), 2 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/display/rockchip/rockchip,inno-hdmi.yaml b/Documentation/devicetree/bindings/display/rockchip/rockchip,inno-hdmi.yaml
> index 96889c86849a..be78dcfa1c76 100644
> --- a/Documentation/devicetree/bindings/display/rockchip/rockchip,inno-hdmi.yaml
> +++ b/Documentation/devicetree/bindings/display/rockchip/rockchip,inno-hdmi.yaml
> @@ -14,6 +14,7 @@ properties:
> compatible:
> enum:
> - rockchip,rk3036-inno-hdmi
> + - rockchip,rk3128-inno-hdmi
>
> reg:
> maxItems: 1
> @@ -22,10 +23,19 @@ properties:
> maxItems: 1
>
> clocks:
> - maxItems: 1
> + minItems: 1
> + items:
> + - description: The HDMI controller main clock
> + - description: The HDMI PHY reference clock
>
> clock-names:
> - const: pclk
> + minItems: 1
> + items:
> + - const: pclk
> + - const: ref
> +
> + power-domains:
> + maxItems: 1
>
> ports:
> $ref: /schemas/graph.yaml#/properties/ports
> @@ -55,6 +65,32 @@ required:
> - pinctrl-names
> - ports
>
> +allOf:
> + - if:
> + properties:
> + compatible:
> + contains:
> + const: rockchip,rk3036-inno-hdmi
> +
> + then:
> + properties:
> + power-domains: false
> +
> + - if:
> + properties:
> + compatible:
> + contains:
> + const: rockchip,rk3128-inno-hdmi
> +
> + then:
> + properties:
> + clocks:
> + minItems: 2
> + clock-names:
> + minItems: 2
> + required:
> + - power-domains
> +
> additionalProperties: false
>
> examples:
>





2023-12-29 23:37:21

by Heiko Stübner

[permalink] [raw]
Subject: Re: (subset) [PATCH v4 00/29] Add HDMI support for RK3128

On Fri, 22 Dec 2023 18:41:51 +0100, Alex Bee wrote:
> This is version 4 of my series that aims to add support for the display
> controller (VOP) and the HDMI controller block of RK3128 (which is very
> similar to the one found in RK3036). The original intention of this series
> was to add support for this slightly different integration but is by now,
> driven by maintainer's feedback, exploded to be a rework of inno-hdmi
> driver in large parts. It is, however, a change for the better.
>
> [...]

Applied, thanks!

[02/29] drm/rockchip: vop: Add output selection registers for RK312x
commit: 407eaa4aa64a8429094fa75fac00fff5e471138d
[03/29] drm/rockchip: inno_hdmi: Fix video timing
commit: 47a145c03484d33e65d773169d5ca1b9fe2a492e
[04/29] drm/rockchip: inno_hdmi: Remove useless mode_fixup
commit: 099be7b6718685ebafb417e74bb637abf992474a
[05/29] drm/rockchip: inno_hdmi: Remove useless copy of drm_display_mode
commit: 8f0df2012b8a94aed0cc450016f7592c24e92cfb
[06/29] drm/rockchip: inno_hdmi: Switch encoder hooks to atomic
commit: ff4d4fa76fcc19f7d5d261f717121f0a88ec4e30
[07/29] drm/rockchip: inno_hdmi: Get rid of mode_set
commit: d3e040f450ec8e46ff42fa495a433b976ab47686
[08/29] drm/rockchip: inno_hdmi: no need to store vic
commit: d7ba3d711cf537ef0ece14cd85d2113ca338a00b
[09/29] drm/rockchip: inno_hdmi: Remove unneeded has audio flag
commit: f8723484e045ff2d176124484907ec0199c55a0c
[10/29] drm/rockchip: inno_hdmi: Remove useless input format
commit: c1ceee3248742149d1a602fd913bd88857da1d52
[11/29] drm/rockchip: inno_hdmi: Remove YUV-based csc coefficents
commit: 139771b8239c43ad1bd6c2976aa12788096a5483
[12/29] drm/rockchip: inno_hdmi: Remove tmds rate from structure
commit: 5f92474844a4fcb7997da20dd1de2031aed1d794

Best regards,
--
Heiko Stuebner <[email protected]>

2023-12-29 23:42:33

by Heiko Stübner

[permalink] [raw]
Subject: Re: (subset) [PATCH v4 00/29] Add HDMI support for RK3128

On Fri, 22 Dec 2023 18:41:51 +0100, Alex Bee wrote:
> This is version 4 of my series that aims to add support for the display
> controller (VOP) and the HDMI controller block of RK3128 (which is very
> similar to the one found in RK3036). The original intention of this series
> was to add support for this slightly different integration but is by now,
> driven by maintainer's feedback, exploded to be a rework of inno-hdmi
> driver in large parts. It is, however, a change for the better.
>
> [...]

Applied, thanks!

[13/29] drm/rockchip: inno_hdmi: Drop HDMI Vendor Infoframe support
commit: aa4f96e2de82f5e0dfc0102d08f66918c5e3637f
[14/29] drm/rockchip: inno_hdmi: Move infoframe disable to separate function
commit: cc9ec38cb2cd32518fe02615d004e96ce2fd0348
[15/29] drm/rockchip: inno_hdmi: Switch to infoframe type
commit: 4278ff62b73936a9138b60cc0610381003132b77
[16/29] drm/rockchip: inno_hdmi: Remove unused drm device pointer
commit: 153fe8dbd866869846af3a359ecf82d5ad9fe247
[17/29] drm/rockchip: inno_hdmi: Drop irq struct member
commit: 073aa696f8cbc170a2c3502c2165aeb835be0156
[18/29] drm/rockchip: inno_hdmi: Remove useless include
commit: f68a68fe9d9197ea6aa9cb461270685f370b165e
[19/29] drm/rockchip: inno_hdmi: Subclass connector state
commit: ceeb0f0104a62c867656c2730a51df47e7350b8f
[20/29] drm/rockchip: inno_hdmi: Correctly setup HDMI quantization range
commit: 164abbd2b7ef62aae6fc80450a2d085acdc3da3e
[21/29] drm/rockchip: inno_hdmi: Don't power up the phy after resetting
commit: 71892cee6ceb3e1b88e0bb44b05c8397d8261a85
[22/29] drm/rockchip: inno_hdmi: Split power mode setting
commit: f01e33cb586b5fd354cba73052f82c3b4246109d

Best regards,
--
Heiko Stuebner <[email protected]>

2024-01-02 18:55:01

by Rob Herring

[permalink] [raw]
Subject: Re: [PATCH v4 01/29] dt-bindings: display: rockchip,inno-hdmi: Document RK3128 compatible


On Fri, 22 Dec 2023 18:41:52 +0100, Alex Bee wrote:
> The integration for this SoC is different from the currently existing: It
> needs it's PHY's reference clock rate to calculate the DDC bus frequency
> correctly. The controller is also part of a powerdomain, so this gets added
> as an mandatory property for this variant.
>
> Signed-off-by: Alex Bee <[email protected]>
> Reviewed-by: Conor Dooley <[email protected]>
> ---
> changes in v2:
> - clarify that the controller itself is part of the powerdomain
> - simplify clock-names
> - made power-domains property only allowed (and required) for new variant
>
> changes in v3:
> - collect RB
>
> changes in v4:
> - none
>
> .../display/rockchip/rockchip,inno-hdmi.yaml | 40 ++++++++++++++++++-
> 1 file changed, 38 insertions(+), 2 deletions(-)
>

Since I applied the conversion I applied this one, thanks!


2024-01-04 08:15:24

by Heiko Stübner

[permalink] [raw]
Subject: Re: (subset) [PATCH v4 00/29] Add HDMI support for RK3128

On Fri, 22 Dec 2023 18:41:51 +0100, Alex Bee wrote:
> This is version 4 of my series that aims to add support for the display
> controller (VOP) and the HDMI controller block of RK3128 (which is very
> similar to the one found in RK3036). The original intention of this series
> was to add support for this slightly different integration but is by now,
> driven by maintainer's feedback, exploded to be a rework of inno-hdmi
> driver in large parts. It is, however, a change for the better.
>
> [...]

Applied, thanks!

[23/29] drm/rockchip: inno_hdmi: Add variant support
commit: 5f2e93e6719701a91307090f8f7696fd6b3bffdf
[24/29] drm/rockchip: inno_hdmi: Add RK3128 support
commit: aa54f334c291effe321aa4b9ac0e67a895fd7b58
[25/29] drm/rockchip: inno_hdmi: Add basic mode validation
commit: 701029621d4141d0c9f8b81a88a37b95ec84ce65
[26/29] drm/rockchip: inno_hdmi: Drop custom fill_modes hook
commit: 50a3c772bd927dd409c484832ddd9f6bf00b7389


For reference, Rob has applied the rk3128 compatible in
https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git/commit/?id=21960bda59852ca961fcd27fba9f92750caccd06


Best regards,
--
Heiko Stuebner <[email protected]>

2024-01-05 16:47:36

by Alex Bee

[permalink] [raw]
Subject: Re: (subset) [PATCH v4 00/29] Add HDMI support for RK3128

Hi Heiko,


Am 04.01.24 um 09:14 schrieb Heiko Stuebner:
> On Fri, 22 Dec 2023 18:41:51 +0100, Alex Bee wrote:
>> This is version 4 of my series that aims to add support for the display
>> controller (VOP) and the HDMI controller block of RK3128 (which is very
>> similar to the one found in RK3036). The original intention of this series
>> was to add support for this slightly different integration but is by now,
>> driven by maintainer's feedback, exploded to be a rework of inno-hdmi
>> driver in large parts. It is, however, a change for the better.
>>
>> [...]
> Applied, thanks!
>
> [23/29] drm/rockchip: inno_hdmi: Add variant support
> commit: 5f2e93e6719701a91307090f8f7696fd6b3bffdf
> [24/29] drm/rockchip: inno_hdmi: Add RK3128 support
> commit: aa54f334c291effe321aa4b9ac0e67a895fd7b58
> [25/29] drm/rockchip: inno_hdmi: Add basic mode validation
> commit: 701029621d4141d0c9f8b81a88a37b95ec84ce65
> [26/29] drm/rockchip: inno_hdmi: Drop custom fill_modes hook
> commit: 50a3c772bd927dd409c484832ddd9f6bf00b7389
>
>
> For reference, Rob has applied the rk3128 compatible in
> https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git/commit/?id=21960bda59852ca961fcd27fba9f92750caccd06
thanks for keeping track on this.

Is there any reason the DT paches aren't merged yet? From what I can see
they should be fine to be merged in your v6.8-armsoc/dts32 branch which is
6.7-rc1 based. There was only a txt-binding at this point and it's very
likely that both the rockchip,inno-hdmi.yaml-conversion and the rk3128
additon will both land in 6.8 (they are both in linux-next). Linus' 6.8
merge-window will open earliest next week.
I'm really not pressuring here and I'm fine if they land in 6.9 - it's just
for my understanding for further submissions.

Alex

>
> Best regards,

2024-01-05 17:02:49

by Heiko Stübner

[permalink] [raw]
Subject: Re: (subset) [PATCH v4 00/29] Add HDMI support for RK3128

Am Freitag, 5. Januar 2024, 17:47:21 CET schrieb Alex Bee:
> Hi Heiko,
>
>
> Am 04.01.24 um 09:14 schrieb Heiko Stuebner:
> > On Fri, 22 Dec 2023 18:41:51 +0100, Alex Bee wrote:
> >> This is version 4 of my series that aims to add support for the display
> >> controller (VOP) and the HDMI controller block of RK3128 (which is very
> >> similar to the one found in RK3036). The original intention of this series
> >> was to add support for this slightly different integration but is by now,
> >> driven by maintainer's feedback, exploded to be a rework of inno-hdmi
> >> driver in large parts. It is, however, a change for the better.
> >>
> >> [...]
> > Applied, thanks!
> >
> > [23/29] drm/rockchip: inno_hdmi: Add variant support
> > commit: 5f2e93e6719701a91307090f8f7696fd6b3bffdf
> > [24/29] drm/rockchip: inno_hdmi: Add RK3128 support
> > commit: aa54f334c291effe321aa4b9ac0e67a895fd7b58
> > [25/29] drm/rockchip: inno_hdmi: Add basic mode validation
> > commit: 701029621d4141d0c9f8b81a88a37b95ec84ce65
> > [26/29] drm/rockchip: inno_hdmi: Drop custom fill_modes hook
> > commit: 50a3c772bd927dd409c484832ddd9f6bf00b7389
> >
> >
> > For reference, Rob has applied the rk3128 compatible in
> > https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git/commit/?id=21960bda59852ca961fcd27fba9f92750caccd06
> thanks for keeping track on this.
>
> Is there any reason the DT paches aren't merged yet? From what I can see
> they should be fine to be merged in your v6.8-armsoc/dts32 branch which is
> 6.7-rc1 based. There was only a txt-binding at this point and it's very
> likely that both the rockchip,inno-hdmi.yaml-conversion and the rk3128
> additon will both land in 6.8 (they are both in linux-next). Linus' 6.8
> merge-window will open earliest next week.

Exactly ... and the arm subarchitectures (Rockchip, etc) feed into the
more generic soc-tree[0] and from there in a set of pull requests.

Normally everything needs to go to the soc tree before -rc7 .
With the whole xmas stuff, I sent some stragglers in a second pull
request on monday, but that was already before Rob applied the
binding on tuesday.

So 6.8 devicetree stuff is essentially done and the dts patches
from this series will go in to 6.9 .


Hope that explains things a bit :-)
Heiko

[0] https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git/

> I'm really not pressuring here and I'm fine if they land in 6.9 - it's just
> for my understanding for further submissions.
>
> Alex
>
> >
> > Best regards,
>





2024-01-05 17:33:55

by Alex Bee

[permalink] [raw]
Subject: Re: (subset) [PATCH v4 00/29] Add HDMI support for RK3128


Am 05.01.24 um 18:02 schrieb Heiko Stübner:
> Am Freitag, 5. Januar 2024, 17:47:21 CET schrieb Alex Bee:
>> Hi Heiko,
>>
>>
>> Am 04.01.24 um 09:14 schrieb Heiko Stuebner:
>>> On Fri, 22 Dec 2023 18:41:51 +0100, Alex Bee wrote:
>>>> This is version 4 of my series that aims to add support for the display
>>>> controller (VOP) and the HDMI controller block of RK3128 (which is very
>>>> similar to the one found in RK3036). The original intention of this series
>>>> was to add support for this slightly different integration but is by now,
>>>> driven by maintainer's feedback, exploded to be a rework of inno-hdmi
>>>> driver in large parts. It is, however, a change for the better.
>>>>
>>>> [...]
>>> Applied, thanks!
>>>
>>> [23/29] drm/rockchip: inno_hdmi: Add variant support
>>> commit: 5f2e93e6719701a91307090f8f7696fd6b3bffdf
>>> [24/29] drm/rockchip: inno_hdmi: Add RK3128 support
>>> commit: aa54f334c291effe321aa4b9ac0e67a895fd7b58
>>> [25/29] drm/rockchip: inno_hdmi: Add basic mode validation
>>> commit: 701029621d4141d0c9f8b81a88a37b95ec84ce65
>>> [26/29] drm/rockchip: inno_hdmi: Drop custom fill_modes hook
>>> commit: 50a3c772bd927dd409c484832ddd9f6bf00b7389
>>>
>>>
>>> For reference, Rob has applied the rk3128 compatible in
>>> https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git/commit/?id=21960bda59852ca961fcd27fba9f92750caccd06
>> thanks for keeping track on this.
>>
>> Is there any reason the DT paches aren't merged yet? From what I can see
>> they should be fine to be merged in your v6.8-armsoc/dts32 branch which is
>> 6.7-rc1 based. There was only a txt-binding at this point and it's very
>> likely that both the rockchip,inno-hdmi.yaml-conversion and the rk3128
>> additon will both land in 6.8 (they are both in linux-next). Linus' 6.8
>> merge-window will open earliest next week.
> Exactly ... and the arm subarchitectures (Rockchip, etc) feed into the
> more generic soc-tree[0] and from there in a set of pull requests.
>
> Normally everything needs to go to the soc tree before -rc7 .
> With the whole xmas stuff, I sent some stragglers in a second pull
> request on monday, but that was already before Rob applied the
> binding on tuesday.
>
> So 6.8 devicetree stuff is essentially done and the dts patches
> from this series will go in to 6.9 .
>
>
> Hope that explains things a bit :-)
I assumed (for some reason) that sub-architecture maintainers are allowed
to send PRs to the respective upper tree until the merge window opens and
"all the rest" is done within this  ~2 weeks.
Thanks for explaining.

Alex
> Heiko
>
> [0] https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git/
>
>> I'm really not pressuring here and I'm fine if they land in 6.9 - it's just
>> for my understanding for further submissions.
>>
>> Alex
>>
>>> Best regards,
>
>
>

2024-01-05 17:51:29

by Heiko Stübner

[permalink] [raw]
Subject: Re: (subset) [PATCH v4 00/29] Add HDMI support for RK3128

Am Freitag, 5. Januar 2024, 18:33:34 CET schrieb Alex Bee:
>
> Am 05.01.24 um 18:02 schrieb Heiko St?bner:
> > Am Freitag, 5. Januar 2024, 17:47:21 CET schrieb Alex Bee:
> >> Hi Heiko,
> >>
> >>
> >> Am 04.01.24 um 09:14 schrieb Heiko Stuebner:
> >>> On Fri, 22 Dec 2023 18:41:51 +0100, Alex Bee wrote:
> >>>> This is version 4 of my series that aims to add support for the display
> >>>> controller (VOP) and the HDMI controller block of RK3128 (which is very
> >>>> similar to the one found in RK3036). The original intention of this series
> >>>> was to add support for this slightly different integration but is by now,
> >>>> driven by maintainer's feedback, exploded to be a rework of inno-hdmi
> >>>> driver in large parts. It is, however, a change for the better.
> >>>>
> >>>> [...]
> >>> Applied, thanks!
> >>>
> >>> [23/29] drm/rockchip: inno_hdmi: Add variant support
> >>> commit: 5f2e93e6719701a91307090f8f7696fd6b3bffdf
> >>> [24/29] drm/rockchip: inno_hdmi: Add RK3128 support
> >>> commit: aa54f334c291effe321aa4b9ac0e67a895fd7b58
> >>> [25/29] drm/rockchip: inno_hdmi: Add basic mode validation
> >>> commit: 701029621d4141d0c9f8b81a88a37b95ec84ce65
> >>> [26/29] drm/rockchip: inno_hdmi: Drop custom fill_modes hook
> >>> commit: 50a3c772bd927dd409c484832ddd9f6bf00b7389
> >>>
> >>>
> >>> For reference, Rob has applied the rk3128 compatible in
> >>> https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git/commit/?id=21960bda59852ca961fcd27fba9f92750caccd06
> >> thanks for keeping track on this.
> >>
> >> Is there any reason the DT paches aren't merged yet? From what I can see
> >> they should be fine to be merged in your v6.8-armsoc/dts32 branch which is
> >> 6.7-rc1 based. There was only a txt-binding at this point and it's very
> >> likely that both the rockchip,inno-hdmi.yaml-conversion and the rk3128
> >> additon will both land in 6.8 (they are both in linux-next). Linus' 6.8
> >> merge-window will open earliest next week.
> > Exactly ... and the arm subarchitectures (Rockchip, etc) feed into the
> > more generic soc-tree[0] and from there in a set of pull requests.
> >
> > Normally everything needs to go to the soc tree before -rc7 .
> > With the whole xmas stuff, I sent some stragglers in a second pull
> > request on monday, but that was already before Rob applied the
> > binding on tuesday.
> >
> > So 6.8 devicetree stuff is essentially done and the dts patches
> > from this series will go in to 6.9 .
> >
> >
> > Hope that explains things a bit :-)
> I assumed (for some reason) that sub-architecture maintainers are allowed
> to send PRs to the respective upper tree until the merge window opens and
> "all the rest" is done within this ~2 weeks.
> Thanks for explaining.

No worries :-) .

The general rule of thumb is that everything should be done and ready
before the merge-window opens. Linus often writes very positively about
people sending him pull-requests even before the merge window opens ;-)
[meaning their tree is settled early and all test-robots have run]

And there are different rules in every tree.

For the soc tree the general rule of thumb of =< -rc7 - earlier with larger
changesets. On the other side drm-misc stays open all the time, but makes
a cut at -rc6. So everything targetted at v6.8 needs to be in before
v6.7-rc6.


Heiko



2024-01-25 21:14:01

by Heiko Stübner

[permalink] [raw]
Subject: Re: (subset) [PATCH v4 00/29] Add HDMI support for RK3128

On Fri, 22 Dec 2023 18:41:51 +0100, Alex Bee wrote:
> This is version 4 of my series that aims to add support for the display
> controller (VOP) and the HDMI controller block of RK3128 (which is very
> similar to the one found in RK3036). The original intention of this series
> was to add support for this slightly different integration but is by now,
> driven by maintainer's feedback, exploded to be a rework of inno-hdmi
> driver in large parts. It is, however, a change for the better.
>
> [...]

Applied, thanks!

[27/29] ARM: dts: rockchip: Add display subsystem for RK3128
commit: 695b9b57443d88a1c8e0567c88a79d1a4532c75e
[28/29] ARM: dts: rockchip: Add HDMI node for RK3128
commit: 3fd6e33f8fde16869d4cd9cef71ca964b2b0789b
[29/29] ARM: dts: rockchip: Enable HDMI output for XPI-3128
commit: 5aab66e319df2a6fc4ab06bcb4bd974c1ac4927e

Best regards,
--
Heiko Stuebner <[email protected]>