dri-devel.lists.freedesktop.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v4 0/7] drm/vc4: Fix the core clock behaviour
@ 2022-10-20  9:12 maxime
  2022-10-20  9:12 ` [PATCH v4 1/7] firmware: raspberrypi: Introduce rpi_firmware_find_node() maxime
                   ` (6 more replies)
  0 siblings, 7 replies; 17+ messages in thread
From: maxime @ 2022-10-20  9:12 UTC (permalink / raw)
  To: Daniel Vetter, Emma Anholt, Michael Turquette, Stephen Boyd,
	Maxime Ripard, Ray Jui, Florian Fainelli, David Airlie,
	Broadcom internal kernel review list, Scott Branden
  Cc: Stefan Wahren, linux-kernel, dri-devel, Maxime Ripard,
	Dom Cobley, linux-clk, linux-arm-kernel, linux-rpi-kernel

Hi,

Those patches used to be part of a larger clock fixes series:
https://lore.kernel.org/linux-clk/20220715160014.2623107-1-maxime@cerno.tech/

However, that series doesn't seem to be getting anywhere, so I've split out
these patches that fix a regression that has been there since 5.18 and that
prevents the 4k output from working on the RaspberryPi4.

Hopefully, we will be able to merge those patches through the DRM tree to avoid
any further disruption.

Let me know what you think,
Maxime

To: Florian Fainelli <f.fainelli@gmail.com>
To: Broadcom internal kernel review list <bcm-kernel-feedback-list@broadcom.com>
To: Ray Jui <rjui@broadcom.com>
To: Scott Branden <sbranden@broadcom.com>
To: Michael Turquette <mturquette@baylibre.com>
To: Stephen Boyd <sboyd@kernel.org>
To: Emma Anholt <emma@anholt.net>
To: Maxime Ripard <mripard@kernel.org>
To: David Airlie <airlied@linux.ie>
To: Daniel Vetter <daniel@ffwll.ch>
Cc: Stefan Wahren <stefan.wahren@i2se.com>
Cc: linux-rpi-kernel@lists.infradead.org
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-kernel@vger.kernel.org
Cc: linux-clk@vger.kernel.org
Cc: dri-devel@lists.freedesktop.org
Cc: Dom Cobley <popcornmix@gmail.com>
Signed-off-by: Maxime Ripard <maxime@cerno.tech>

---
Changes in v4:
- Move the rpi_firmware_of_match to avoid confusion
- Link to v3: https://lore.kernel.org/r/20220815-rpi-fix-4k-60-v3-0-fc56729d11fe@cerno.tech

Changes in v3:
- Return UINT_MAX when the firmware call fails in the _get_max_rate function
- Link to v2: https://lore.kernel.org/r/20220815-rpi-fix-4k-60-v2-0-983276b83f62@cerno.tech

Changes in v2:
- Dropped the clock patches, made an ad-hoc function in the firmware driver
- Link to v1: https://lore.kernel.org/r/20220815-rpi-fix-4k-60-v1-0-c52bd642f7c6@cerno.tech

---
Dom Cobley (1):
      drm/vc4: hdmi: Add more checks for 4k resolutions

Maxime Ripard (6):
      firmware: raspberrypi: Introduce rpi_firmware_find_node()
      firmware: raspberrypi: Move the clock IDs to the firmware header
      firmware: raspberrypi: Provide a helper to query a clock max rate
      drm/vc4: hdmi: Fix hdmi_enable_4kp60 detection
      drm/vc4: hdmi: Rework hdmi_enable_4kp60 detection code
      drm/vc4: Make sure we don't end up with a core clock too high

 drivers/clk/bcm/clk-raspberrypi.c          | 19 -----------
 drivers/firmware/raspberrypi.c             | 38 ++++++++++++++++++----
 drivers/gpu/drm/vc4/vc4_drv.h              | 16 +++++++++
 drivers/gpu/drm/vc4/vc4_hdmi.c             | 25 +++++++-------
 drivers/gpu/drm/vc4/vc4_hdmi.h             |  8 -----
 drivers/gpu/drm/vc4/vc4_hvs.c              | 26 +++++++++++++++
 drivers/gpu/drm/vc4/vc4_kms.c              | 13 +++++---
 include/soc/bcm2835/raspberrypi-firmware.h | 52 ++++++++++++++++++++++++++++++
 8 files changed, 147 insertions(+), 50 deletions(-)
---
base-commit: 9abf2313adc1ca1b6180c508c25f22f9395cc780
change-id: 20220815-rpi-fix-4k-60-17273650429d

Best regards,
-- 
Maxime Ripard <maxime@cerno.tech>

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH v4 1/7] firmware: raspberrypi: Introduce rpi_firmware_find_node()
  2022-10-20  9:12 [PATCH v4 0/7] drm/vc4: Fix the core clock behaviour maxime
@ 2022-10-20  9:12 ` maxime
  2022-10-24 19:19   ` Florian Fainelli
  2022-10-20  9:12 ` [PATCH v4 2/7] firmware: raspberrypi: Move the clock IDs to the firmware header maxime
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 17+ messages in thread
From: maxime @ 2022-10-20  9:12 UTC (permalink / raw)
  To: Daniel Vetter, Emma Anholt, Michael Turquette, Stephen Boyd,
	Maxime Ripard, Ray Jui, Florian Fainelli, David Airlie,
	Broadcom internal kernel review list, Scott Branden
  Cc: Stefan Wahren, linux-kernel, dri-devel, Maxime Ripard,
	Dom Cobley, linux-clk, linux-arm-kernel, linux-rpi-kernel

A significant number of RaspberryPi drivers using the firmware don't
have a phandle to it, so end up scanning the device tree to find a node
with the firmware compatible.

That code is duplicated everywhere, so let's introduce a helper instead.

Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
 drivers/firmware/raspberrypi.c             | 18 ++++++++++++------
 include/soc/bcm2835/raspberrypi-firmware.h |  7 +++++++
 2 files changed, 19 insertions(+), 6 deletions(-)

diff --git a/drivers/firmware/raspberrypi.c b/drivers/firmware/raspberrypi.c
index 4b8978b254f9..932a8bef22fb 100644
--- a/drivers/firmware/raspberrypi.c
+++ b/drivers/firmware/raspberrypi.c
@@ -311,6 +311,18 @@ static int rpi_firmware_remove(struct platform_device *pdev)
 	return 0;
 }
 
+static const struct of_device_id rpi_firmware_of_match[] = {
+	{ .compatible = "raspberrypi,bcm2835-firmware", },
+	{},
+};
+MODULE_DEVICE_TABLE(of, rpi_firmware_of_match);
+
+struct device_node *rpi_firmware_find_node(void)
+{
+	return of_find_matching_node(NULL, rpi_firmware_of_match);
+}
+EXPORT_SYMBOL_GPL(rpi_firmware_find_node);
+
 /**
  * rpi_firmware_get - Get pointer to rpi_firmware structure.
  * @firmware_node:    Pointer to the firmware Device Tree node.
@@ -366,12 +378,6 @@ struct rpi_firmware *devm_rpi_firmware_get(struct device *dev,
 }
 EXPORT_SYMBOL_GPL(devm_rpi_firmware_get);
 
-static const struct of_device_id rpi_firmware_of_match[] = {
-	{ .compatible = "raspberrypi,bcm2835-firmware", },
-	{},
-};
-MODULE_DEVICE_TABLE(of, rpi_firmware_of_match);
-
 static struct platform_driver rpi_firmware_driver = {
 	.driver = {
 		.name = "raspberrypi-firmware",
diff --git a/include/soc/bcm2835/raspberrypi-firmware.h b/include/soc/bcm2835/raspberrypi-firmware.h
index 811ea668c4a1..63426082bcb9 100644
--- a/include/soc/bcm2835/raspberrypi-firmware.h
+++ b/include/soc/bcm2835/raspberrypi-firmware.h
@@ -142,6 +142,7 @@ int rpi_firmware_property(struct rpi_firmware *fw,
 int rpi_firmware_property_list(struct rpi_firmware *fw,
 			       void *data, size_t tag_size);
 void rpi_firmware_put(struct rpi_firmware *fw);
+struct device_node *rpi_firmware_find_node(void);
 struct rpi_firmware *rpi_firmware_get(struct device_node *firmware_node);
 struct rpi_firmware *devm_rpi_firmware_get(struct device *dev,
 					   struct device_node *firmware_node);
@@ -159,6 +160,12 @@ static inline int rpi_firmware_property_list(struct rpi_firmware *fw,
 }
 
 static inline void rpi_firmware_put(struct rpi_firmware *fw) { }
+
+static inline struct device_node *rpi_firmware_find_node(void)
+{
+	return NULL;
+}
+
 static inline struct rpi_firmware *rpi_firmware_get(struct device_node *firmware_node)
 {
 	return NULL;

-- 
b4 0.10.1

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v4 2/7] firmware: raspberrypi: Move the clock IDs to the firmware header
  2022-10-20  9:12 [PATCH v4 0/7] drm/vc4: Fix the core clock behaviour maxime
  2022-10-20  9:12 ` [PATCH v4 1/7] firmware: raspberrypi: Introduce rpi_firmware_find_node() maxime
@ 2022-10-20  9:12 ` maxime
  2022-10-20  9:12 ` [PATCH v4 3/7] firmware: raspberrypi: Provide a helper to query a clock max rate maxime
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 17+ messages in thread
From: maxime @ 2022-10-20  9:12 UTC (permalink / raw)
  To: Daniel Vetter, Emma Anholt, Michael Turquette, Stephen Boyd,
	Maxime Ripard, Ray Jui, Florian Fainelli, David Airlie,
	Broadcom internal kernel review list, Scott Branden
  Cc: Stefan Wahren, linux-kernel, dri-devel, Maxime Ripard,
	Dom Cobley, linux-clk, linux-arm-kernel, linux-rpi-kernel

We'll need the clock IDs in more drivers than just the clock driver from
now on, so let's move them in the firmware header.

Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Acked-by: Stephen Boyd <sboyd@kernel.org>
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
 drivers/clk/bcm/clk-raspberrypi.c          | 19 -------------------
 include/soc/bcm2835/raspberrypi-firmware.h | 19 +++++++++++++++++++
 2 files changed, 19 insertions(+), 19 deletions(-)

diff --git a/drivers/clk/bcm/clk-raspberrypi.c b/drivers/clk/bcm/clk-raspberrypi.c
index 679f4649a7ef..ce2f93479736 100644
--- a/drivers/clk/bcm/clk-raspberrypi.c
+++ b/drivers/clk/bcm/clk-raspberrypi.c
@@ -18,25 +18,6 @@
 
 #include <soc/bcm2835/raspberrypi-firmware.h>
 
-enum rpi_firmware_clk_id {
-	RPI_FIRMWARE_EMMC_CLK_ID = 1,
-	RPI_FIRMWARE_UART_CLK_ID,
-	RPI_FIRMWARE_ARM_CLK_ID,
-	RPI_FIRMWARE_CORE_CLK_ID,
-	RPI_FIRMWARE_V3D_CLK_ID,
-	RPI_FIRMWARE_H264_CLK_ID,
-	RPI_FIRMWARE_ISP_CLK_ID,
-	RPI_FIRMWARE_SDRAM_CLK_ID,
-	RPI_FIRMWARE_PIXEL_CLK_ID,
-	RPI_FIRMWARE_PWM_CLK_ID,
-	RPI_FIRMWARE_HEVC_CLK_ID,
-	RPI_FIRMWARE_EMMC2_CLK_ID,
-	RPI_FIRMWARE_M2MC_CLK_ID,
-	RPI_FIRMWARE_PIXEL_BVB_CLK_ID,
-	RPI_FIRMWARE_VEC_CLK_ID,
-	RPI_FIRMWARE_NUM_CLK_ID,
-};
-
 static char *rpi_firmware_clk_names[] = {
 	[RPI_FIRMWARE_EMMC_CLK_ID]	= "emmc",
 	[RPI_FIRMWARE_UART_CLK_ID]	= "uart",
diff --git a/include/soc/bcm2835/raspberrypi-firmware.h b/include/soc/bcm2835/raspberrypi-firmware.h
index 63426082bcb9..9b1db12d013f 100644
--- a/include/soc/bcm2835/raspberrypi-firmware.h
+++ b/include/soc/bcm2835/raspberrypi-firmware.h
@@ -136,6 +136,25 @@ enum rpi_firmware_property_tag {
 	RPI_FIRMWARE_GET_DMA_CHANNELS =                       0x00060001,
 };
 
+enum rpi_firmware_clk_id {
+	RPI_FIRMWARE_EMMC_CLK_ID = 1,
+	RPI_FIRMWARE_UART_CLK_ID,
+	RPI_FIRMWARE_ARM_CLK_ID,
+	RPI_FIRMWARE_CORE_CLK_ID,
+	RPI_FIRMWARE_V3D_CLK_ID,
+	RPI_FIRMWARE_H264_CLK_ID,
+	RPI_FIRMWARE_ISP_CLK_ID,
+	RPI_FIRMWARE_SDRAM_CLK_ID,
+	RPI_FIRMWARE_PIXEL_CLK_ID,
+	RPI_FIRMWARE_PWM_CLK_ID,
+	RPI_FIRMWARE_HEVC_CLK_ID,
+	RPI_FIRMWARE_EMMC2_CLK_ID,
+	RPI_FIRMWARE_M2MC_CLK_ID,
+	RPI_FIRMWARE_PIXEL_BVB_CLK_ID,
+	RPI_FIRMWARE_VEC_CLK_ID,
+	RPI_FIRMWARE_NUM_CLK_ID,
+};
+
 #if IS_ENABLED(CONFIG_RASPBERRYPI_FIRMWARE)
 int rpi_firmware_property(struct rpi_firmware *fw,
 			  u32 tag, void *data, size_t len);

-- 
b4 0.10.1

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v4 3/7] firmware: raspberrypi: Provide a helper to query a clock max rate
  2022-10-20  9:12 [PATCH v4 0/7] drm/vc4: Fix the core clock behaviour maxime
  2022-10-20  9:12 ` [PATCH v4 1/7] firmware: raspberrypi: Introduce rpi_firmware_find_node() maxime
  2022-10-20  9:12 ` [PATCH v4 2/7] firmware: raspberrypi: Move the clock IDs to the firmware header maxime
@ 2022-10-20  9:12 ` maxime
  2022-10-20  9:12 ` [PATCH v4 4/7] drm/vc4: hdmi: Fix hdmi_enable_4kp60 detection maxime
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 17+ messages in thread
From: maxime @ 2022-10-20  9:12 UTC (permalink / raw)
  To: Daniel Vetter, Emma Anholt, Michael Turquette, Stephen Boyd,
	Maxime Ripard, Ray Jui, Florian Fainelli, David Airlie,
	Broadcom internal kernel review list, Scott Branden
  Cc: Stefan Wahren, linux-kernel, dri-devel, Maxime Ripard,
	Dom Cobley, linux-clk, linux-arm-kernel, linux-rpi-kernel

The firmware allows to query for its clocks the operating range of a
given clock. We'll need this for some drivers (KMS, in particular) to
infer the state of some configuration options, so let's create a
function to do so.

Acked-by: Stephen Boyd <sboyd@kernel.org>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
 drivers/firmware/raspberrypi.c             | 20 ++++++++++++++++++++
 include/soc/bcm2835/raspberrypi-firmware.h | 26 ++++++++++++++++++++++++++
 2 files changed, 46 insertions(+)

diff --git a/drivers/firmware/raspberrypi.c b/drivers/firmware/raspberrypi.c
index 932a8bef22fb..b15aa6fce0e9 100644
--- a/drivers/firmware/raspberrypi.c
+++ b/drivers/firmware/raspberrypi.c
@@ -228,6 +228,26 @@ static void rpi_register_clk_driver(struct device *dev)
 						-1, NULL, 0);
 }
 
+unsigned int rpi_firmware_clk_get_max_rate(struct rpi_firmware *fw, unsigned int id)
+{
+	struct rpi_firmware_clk_rate_request msg =
+		RPI_FIRMWARE_CLK_RATE_REQUEST(id);
+	int ret;
+
+	ret = rpi_firmware_property(fw, RPI_FIRMWARE_GET_MAX_CLOCK_RATE,
+				    &msg, sizeof(msg));
+	if (ret)
+		/*
+		 * If our firmware doesn't support that operation, or fails, we
+		 * assume the maximum clock rate is absolute maximum we can
+		 * store over our type.
+		 */
+		 return UINT_MAX;
+
+	return le32_to_cpu(msg.rate);
+}
+EXPORT_SYMBOL_GPL(rpi_firmware_clk_get_max_rate);
+
 static void rpi_firmware_delete(struct kref *kref)
 {
 	struct rpi_firmware *fw = container_of(kref, struct rpi_firmware,
diff --git a/include/soc/bcm2835/raspberrypi-firmware.h b/include/soc/bcm2835/raspberrypi-firmware.h
index 9b1db12d013f..ab955591cb72 100644
--- a/include/soc/bcm2835/raspberrypi-firmware.h
+++ b/include/soc/bcm2835/raspberrypi-firmware.h
@@ -155,12 +155,32 @@ enum rpi_firmware_clk_id {
 	RPI_FIRMWARE_NUM_CLK_ID,
 };
 
+/**
+ * struct rpi_firmware_clk_rate_request - Firmware Request for a rate
+ * @id:	ID of the clock being queried
+ * @rate: Rate in Hertz. Set by the firmware.
+ *
+ * Used by @RPI_FIRMWARE_GET_CLOCK_RATE, @RPI_FIRMWARE_GET_CLOCK_MEASURED,
+ * @RPI_FIRMWARE_GET_MAX_CLOCK_RATE and @RPI_FIRMWARE_GET_MIN_CLOCK_RATE.
+ */
+struct rpi_firmware_clk_rate_request {
+	__le32 id;
+	__le32 rate;
+} __packed;
+
+#define RPI_FIRMWARE_CLK_RATE_REQUEST(_id)	\
+	{					\
+		.id = _id,			\
+	}
+
 #if IS_ENABLED(CONFIG_RASPBERRYPI_FIRMWARE)
 int rpi_firmware_property(struct rpi_firmware *fw,
 			  u32 tag, void *data, size_t len);
 int rpi_firmware_property_list(struct rpi_firmware *fw,
 			       void *data, size_t tag_size);
 void rpi_firmware_put(struct rpi_firmware *fw);
+unsigned int rpi_firmware_clk_get_max_rate(struct rpi_firmware *fw,
+					   unsigned int id);
 struct device_node *rpi_firmware_find_node(void);
 struct rpi_firmware *rpi_firmware_get(struct device_node *firmware_node);
 struct rpi_firmware *devm_rpi_firmware_get(struct device *dev,
@@ -180,6 +200,12 @@ static inline int rpi_firmware_property_list(struct rpi_firmware *fw,
 
 static inline void rpi_firmware_put(struct rpi_firmware *fw) { }
 
+static inline unsigned int rpi_firmware_clk_get_max_rate(struct rpi_firmware *fw,
+							 unsigned int id)
+{
+	return UINT_MAX;
+}
+
 static inline struct device_node *rpi_firmware_find_node(void)
 {
 	return NULL;

-- 
b4 0.10.1

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v4 4/7] drm/vc4: hdmi: Fix hdmi_enable_4kp60 detection
  2022-10-20  9:12 [PATCH v4 0/7] drm/vc4: Fix the core clock behaviour maxime
                   ` (2 preceding siblings ...)
  2022-10-20  9:12 ` [PATCH v4 3/7] firmware: raspberrypi: Provide a helper to query a clock max rate maxime
@ 2022-10-20  9:12 ` maxime
  2022-10-26 15:27   ` Dave Stevenson
  2022-10-20  9:12 ` [PATCH v4 5/7] drm/vc4: hdmi: Rework hdmi_enable_4kp60 detection code maxime
                   ` (2 subsequent siblings)
  6 siblings, 1 reply; 17+ messages in thread
From: maxime @ 2022-10-20  9:12 UTC (permalink / raw)
  To: Daniel Vetter, Emma Anholt, Michael Turquette, Stephen Boyd,
	Maxime Ripard, Ray Jui, Florian Fainelli, David Airlie,
	Broadcom internal kernel review list, Scott Branden
  Cc: Stefan Wahren, linux-kernel, dri-devel, Maxime Ripard,
	Dom Cobley, linux-clk, linux-arm-kernel, linux-rpi-kernel

In order to support higher HDMI frequencies, users have to set the
hdmi_enable_4kp60 parameter in their config.txt file.

We were detecting this so far by calling clk_round_rate() on the core
clock with the frequency we're supposed to run at when one of those
modes is enabled. Whether or not the parameter was enabled could then be
inferred by the returned rate since the maximum clock rate reported by
the firmware was one of the side effect of setting that parameter.

However, the recent clock rework we did changed what clk_round_rate()
was returning to always return the minimum allowed, and thus this test
wasn't reliable anymore.

Let's use the new clk_get_max_rate() function to reliably determine the
maximum rate allowed on that clock and fix the 4k@60Hz output.

Fixes: e9d6cea2af1c ("clk: bcm: rpi: Run some clocks at the minimum rate allowed")
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
 drivers/gpu/drm/vc4/vc4_hdmi.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
index 64f9feabf43e..87961d4de5aa 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
@@ -46,6 +46,7 @@
 #include <linux/pm_runtime.h>
 #include <linux/rational.h>
 #include <linux/reset.h>
+#include <soc/bcm2835/raspberrypi-clocks.h>
 #include <sound/dmaengine_pcm.h>
 #include <sound/hdmi-codec.h>
 #include <sound/pcm_drm_eld.h>
@@ -3429,7 +3430,7 @@ static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)
 
 	if (variant->max_pixel_clock == 600000000) {
 		struct vc4_dev *vc4 = to_vc4_dev(drm);
-		long max_rate = clk_round_rate(vc4->hvs->core_clk, 550000000);
+		unsigned long max_rate = rpi_firmware_clk_get_max_rate(vc4->hvs->core_clk);
 
 		if (max_rate < 550000000)
 			vc4_hdmi->disable_4kp60 = true;

-- 
b4 0.10.1

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v4 5/7] drm/vc4: hdmi: Rework hdmi_enable_4kp60 detection code
  2022-10-20  9:12 [PATCH v4 0/7] drm/vc4: Fix the core clock behaviour maxime
                   ` (3 preceding siblings ...)
  2022-10-20  9:12 ` [PATCH v4 4/7] drm/vc4: hdmi: Fix hdmi_enable_4kp60 detection maxime
@ 2022-10-20  9:12 ` maxime
  2022-10-26 16:00   ` Dave Stevenson
  2022-10-20  9:12 ` [PATCH v4 6/7] drm/vc4: hdmi: Add more checks for 4k resolutions maxime
  2022-10-20  9:12 ` [PATCH v4 7/7] drm/vc4: Make sure we don't end up with a core clock too high maxime
  6 siblings, 1 reply; 17+ messages in thread
From: maxime @ 2022-10-20  9:12 UTC (permalink / raw)
  To: Daniel Vetter, Emma Anholt, Michael Turquette, Stephen Boyd,
	Maxime Ripard, Ray Jui, Florian Fainelli, David Airlie,
	Broadcom internal kernel review list, Scott Branden
  Cc: Stefan Wahren, linux-kernel, dri-devel, Maxime Ripard,
	Dom Cobley, linux-clk, linux-arm-kernel, linux-rpi-kernel

In order to support higher HDMI frequencies, users have to set the
hdmi_enable_4kp60 parameter in their config.txt file.

This will have the side-effect of raising the maximum of the core clock,
tied to the HVS, and managed by the HVS driver.

However, we are querying this in the HDMI driver by poking into the HVS
structure to get our struct clk handle.

Let's make this part of the HVS bind implementation to have all the core
clock related setup in the same place.

Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
 drivers/gpu/drm/vc4/vc4_drv.h  | 10 ++++++++++
 drivers/gpu/drm/vc4/vc4_hdmi.c | 15 ++++-----------
 drivers/gpu/drm/vc4/vc4_hdmi.h |  8 --------
 drivers/gpu/drm/vc4/vc4_hvs.c  | 23 +++++++++++++++++++++++
 4 files changed, 37 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
index 418a8242691f..8b2b1af565f9 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.h
+++ b/drivers/gpu/drm/vc4/vc4_drv.h
@@ -326,6 +326,8 @@ struct vc4_hvs {
 
 	struct clk *core_clk;
 
+	unsigned long max_core_rate;
+
 	/* Memory manager for CRTCs to allocate space in the display
 	 * list.  Units are dwords.
 	 */
@@ -337,6 +339,14 @@ struct vc4_hvs {
 	struct drm_mm_node mitchell_netravali_filter;
 
 	struct debugfs_regset32 regset;
+
+	/*
+	 * Even if HDMI0 on the RPi4 can output modes requiring a pixel
+	 * rate higher than 297MHz, it needs some adjustments in the
+	 * config.txt file to be able to do so and thus won't always be
+	 * available.
+	 */
+	bool vc5_hdmi_enable_scrambling;
 };
 
 struct vc4_plane {
diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
index 87961d4de5aa..afe3daa2173e 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
@@ -46,7 +46,6 @@
 #include <linux/pm_runtime.h>
 #include <linux/rational.h>
 #include <linux/reset.h>
-#include <soc/bcm2835/raspberrypi-clocks.h>
 #include <sound/dmaengine_pcm.h>
 #include <sound/hdmi-codec.h>
 #include <sound/pcm_drm_eld.h>
@@ -460,6 +459,7 @@ static int vc4_hdmi_connector_detect_ctx(struct drm_connector *connector,
 static int vc4_hdmi_connector_get_modes(struct drm_connector *connector)
 {
 	struct vc4_hdmi *vc4_hdmi = connector_to_vc4_hdmi(connector);
+	struct vc4_dev *vc4 = to_vc4_dev(connector->dev);
 	int ret = 0;
 	struct edid *edid;
 
@@ -483,7 +483,7 @@ static int vc4_hdmi_connector_get_modes(struct drm_connector *connector)
 	ret = drm_add_edid_modes(connector, edid);
 	kfree(edid);
 
-	if (vc4_hdmi->disable_4kp60) {
+	if (!vc4->hvs->vc5_hdmi_enable_scrambling) {
 		struct drm_device *drm = connector->dev;
 		const struct drm_display_mode *mode;
 
@@ -1757,11 +1757,12 @@ vc4_hdmi_encoder_clock_valid(const struct vc4_hdmi *vc4_hdmi,
 {
 	const struct drm_connector *connector = &vc4_hdmi->connector;
 	const struct drm_display_info *info = &connector->display_info;
+	struct vc4_dev *vc4 = to_vc4_dev(connector->dev);
 
 	if (clock > vc4_hdmi->variant->max_pixel_clock)
 		return MODE_CLOCK_HIGH;
 
-	if (vc4_hdmi->disable_4kp60 && clock > HDMI_14_MAX_TMDS_CLK)
+	if (!vc4->hvs->vc5_hdmi_enable_scrambling && clock > HDMI_14_MAX_TMDS_CLK)
 		return MODE_CLOCK_HIGH;
 
 	if (info->max_tmds_clock && clock > (info->max_tmds_clock * 1000))
@@ -3428,14 +3429,6 @@ static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)
 	vc4_hdmi->disable_wifi_frequencies =
 		of_property_read_bool(dev->of_node, "wifi-2.4ghz-coexistence");
 
-	if (variant->max_pixel_clock == 600000000) {
-		struct vc4_dev *vc4 = to_vc4_dev(drm);
-		unsigned long max_rate = rpi_firmware_clk_get_max_rate(vc4->hvs->core_clk);
-
-		if (max_rate < 550000000)
-			vc4_hdmi->disable_4kp60 = true;
-	}
-
 	ret = devm_pm_runtime_enable(dev);
 	if (ret)
 		return ret;
diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.h b/drivers/gpu/drm/vc4/vc4_hdmi.h
index db823efb2563..e3619836ca17 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.h
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.h
@@ -156,14 +156,6 @@ struct vc4_hdmi {
 	 */
 	bool disable_wifi_frequencies;
 
-	/*
-	 * Even if HDMI0 on the RPi4 can output modes requiring a pixel
-	 * rate higher than 297MHz, it needs some adjustments in the
-	 * config.txt file to be able to do so and thus won't always be
-	 * available.
-	 */
-	bool disable_4kp60;
-
 	struct cec_adapter *cec_adap;
 	struct cec_msg cec_rx_msg;
 	bool cec_tx_ok;
diff --git a/drivers/gpu/drm/vc4/vc4_hvs.c b/drivers/gpu/drm/vc4/vc4_hvs.c
index 4ac9f5a2d5f9..300ac0b57571 100644
--- a/drivers/gpu/drm/vc4/vc4_hvs.c
+++ b/drivers/gpu/drm/vc4/vc4_hvs.c
@@ -28,6 +28,8 @@
 #include <drm/drm_drv.h>
 #include <drm/drm_vblank.h>
 
+#include <soc/bcm2835/raspberrypi-firmware.h>
+
 #include "vc4_drv.h"
 #include "vc4_regs.h"
 
@@ -791,12 +793,33 @@ static int vc4_hvs_bind(struct device *dev, struct device *master, void *data)
 	hvs->regset.nregs = ARRAY_SIZE(hvs_regs);
 
 	if (vc4->is_vc5) {
+		struct rpi_firmware *firmware;
+		struct device_node *node;
+		unsigned long max_rate;
+
+		node = rpi_firmware_find_node();
+		if (!node)
+			return -EINVAL;
+
+		firmware = rpi_firmware_get(node);
+		of_node_put(node);
+		if (!firmware)
+			return -EPROBE_DEFER;
+
 		hvs->core_clk = devm_clk_get(&pdev->dev, NULL);
 		if (IS_ERR(hvs->core_clk)) {
 			dev_err(&pdev->dev, "Couldn't get core clock\n");
 			return PTR_ERR(hvs->core_clk);
 		}
 
+		max_rate = rpi_firmware_clk_get_max_rate(firmware,
+							 RPI_FIRMWARE_CORE_CLK_ID);
+		rpi_firmware_put(firmware);
+		if (max_rate >= 550000000)
+			hvs->vc5_hdmi_enable_scrambling = true;
+
+		hvs->max_core_rate = max_rate;
+
 		ret = clk_prepare_enable(hvs->core_clk);
 		if (ret) {
 			dev_err(&pdev->dev, "Couldn't enable the core clock\n");

-- 
b4 0.10.1

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v4 6/7] drm/vc4: hdmi: Add more checks for 4k resolutions
  2022-10-20  9:12 [PATCH v4 0/7] drm/vc4: Fix the core clock behaviour maxime
                   ` (4 preceding siblings ...)
  2022-10-20  9:12 ` [PATCH v4 5/7] drm/vc4: hdmi: Rework hdmi_enable_4kp60 detection code maxime
@ 2022-10-20  9:12 ` maxime
  2022-10-26 16:06   ` Dave Stevenson
  2022-10-20  9:12 ` [PATCH v4 7/7] drm/vc4: Make sure we don't end up with a core clock too high maxime
  6 siblings, 1 reply; 17+ messages in thread
From: maxime @ 2022-10-20  9:12 UTC (permalink / raw)
  To: Daniel Vetter, Emma Anholt, Michael Turquette, Stephen Boyd,
	Maxime Ripard, Ray Jui, Florian Fainelli, David Airlie,
	Broadcom internal kernel review list, Scott Branden
  Cc: Stefan Wahren, linux-kernel, dri-devel, Maxime Ripard,
	Dom Cobley, linux-clk, linux-arm-kernel, linux-rpi-kernel

From: Dom Cobley <popcornmix@gmail.com>

At least the 4096x2160@60Hz mode requires some overclocking that isn't
available by default, even if hdmi_enable_4kp60 is enabled.

Let's add some logic to detect whether we can satisfy the core clock
requirements for that mode, and prevent it from being used otherwise.

Signed-off-by: Dom Cobley <popcornmix@gmail.com>
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
 drivers/gpu/drm/vc4/vc4_drv.h  |  6 ++++++
 drivers/gpu/drm/vc4/vc4_hdmi.c | 11 +++++++++--
 drivers/gpu/drm/vc4/vc4_hvs.c  |  3 +++
 3 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
index 8b2b1af565f9..72a6b7151d23 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.h
+++ b/drivers/gpu/drm/vc4/vc4_drv.h
@@ -347,6 +347,12 @@ struct vc4_hvs {
 	 * available.
 	 */
 	bool vc5_hdmi_enable_scrambling;
+
+	/*
+	 * 4096x2160@60 requires a core overclock to work, so register
+	 * whether that is sufficient.
+	 */
+	bool vc5_hdmi_enable_4096by2160;
 };
 
 struct vc4_plane {
diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
index afe3daa2173e..fd3730ea976f 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
@@ -1753,6 +1753,7 @@ vc4_hdmi_sink_supports_format_bpc(const struct vc4_hdmi *vc4_hdmi,
 
 static enum drm_mode_status
 vc4_hdmi_encoder_clock_valid(const struct vc4_hdmi *vc4_hdmi,
+			     const struct drm_display_mode *mode,
 			     unsigned long long clock)
 {
 	const struct drm_connector *connector = &vc4_hdmi->connector;
@@ -1765,6 +1766,12 @@ vc4_hdmi_encoder_clock_valid(const struct vc4_hdmi *vc4_hdmi,
 	if (!vc4->hvs->vc5_hdmi_enable_scrambling && clock > HDMI_14_MAX_TMDS_CLK)
 		return MODE_CLOCK_HIGH;
 
+	/* 4096x2160@60 is not reliable without overclocking core */
+	if (!vc4->hvs->vc5_hdmi_enable_4096by2160 &&
+	    mode->hdisplay > 3840 && mode->vdisplay >= 2160 &&
+	    drm_mode_vrefresh(mode) >= 50)
+		return MODE_CLOCK_HIGH;
+
 	if (info->max_tmds_clock && clock > (info->max_tmds_clock * 1000))
 		return MODE_CLOCK_HIGH;
 
@@ -1799,7 +1806,7 @@ vc4_hdmi_encoder_compute_clock(const struct vc4_hdmi *vc4_hdmi,
 	unsigned long long clock;
 
 	clock = vc4_hdmi_encoder_compute_mode_clock(mode, bpc, fmt);
-	if (vc4_hdmi_encoder_clock_valid(vc4_hdmi, clock) != MODE_OK)
+	if (vc4_hdmi_encoder_clock_valid(vc4_hdmi, mode, clock) != MODE_OK)
 		return -EINVAL;
 
 	vc4_state->tmds_char_rate = clock;
@@ -1962,7 +1969,7 @@ vc4_hdmi_encoder_mode_valid(struct drm_encoder *encoder,
 	     (mode->hsync_end % 2) || (mode->htotal % 2)))
 		return MODE_H_ILLEGAL;
 
-	return vc4_hdmi_encoder_clock_valid(vc4_hdmi, mode->clock * 1000);
+	return vc4_hdmi_encoder_clock_valid(vc4_hdmi, mode, mode->clock * 1000);
 }
 
 static const struct drm_encoder_helper_funcs vc4_hdmi_encoder_helper_funcs = {
diff --git a/drivers/gpu/drm/vc4/vc4_hvs.c b/drivers/gpu/drm/vc4/vc4_hvs.c
index 300ac0b57571..a68913f76687 100644
--- a/drivers/gpu/drm/vc4/vc4_hvs.c
+++ b/drivers/gpu/drm/vc4/vc4_hvs.c
@@ -818,6 +818,9 @@ static int vc4_hvs_bind(struct device *dev, struct device *master, void *data)
 		if (max_rate >= 550000000)
 			hvs->vc5_hdmi_enable_scrambling = true;
 
+		if (max_rate >= 600000000)
+			hvs->vc5_hdmi_enable_4096by2160 = true;
+
 		hvs->max_core_rate = max_rate;
 
 		ret = clk_prepare_enable(hvs->core_clk);

-- 
b4 0.10.1

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v4 7/7] drm/vc4: Make sure we don't end up with a core clock too high
  2022-10-20  9:12 [PATCH v4 0/7] drm/vc4: Fix the core clock behaviour maxime
                   ` (5 preceding siblings ...)
  2022-10-20  9:12 ` [PATCH v4 6/7] drm/vc4: hdmi: Add more checks for 4k resolutions maxime
@ 2022-10-20  9:12 ` maxime
  2022-10-26 16:09   ` Dave Stevenson
  6 siblings, 1 reply; 17+ messages in thread
From: maxime @ 2022-10-20  9:12 UTC (permalink / raw)
  To: Daniel Vetter, Emma Anholt, Michael Turquette, Stephen Boyd,
	Maxime Ripard, Ray Jui, Florian Fainelli, David Airlie,
	Broadcom internal kernel review list, Scott Branden
  Cc: Stefan Wahren, linux-kernel, dri-devel, Maxime Ripard,
	Dom Cobley, linux-clk, linux-arm-kernel, linux-rpi-kernel

Following the clock rate range improvements to the clock framework,
trying to set a disjoint range on a clock will now result in an error.

Thus, we can't set a minimum rate higher than the maximum reported by
the firmware, or clk_set_min_rate() will fail.

Thus we need to clamp the rate we are about to ask for to the maximum
rate possible on that clock.

Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
 drivers/gpu/drm/vc4/vc4_kms.c | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_kms.c b/drivers/gpu/drm/vc4/vc4_kms.c
index 4419e810103d..5c97642ed66a 100644
--- a/drivers/gpu/drm/vc4/vc4_kms.c
+++ b/drivers/gpu/drm/vc4/vc4_kms.c
@@ -396,8 +396,8 @@ static void vc4_atomic_commit_tail(struct drm_atomic_state *state)
 	if (vc4->is_vc5) {
 		unsigned long state_rate = max(old_hvs_state->core_clock_rate,
 					       new_hvs_state->core_clock_rate);
-		unsigned long core_rate = max_t(unsigned long,
-						500000000, state_rate);
+		unsigned long core_rate = clamp_t(unsigned long, state_rate,
+						  500000000, hvs->max_core_rate);
 
 		drm_dbg(dev, "Raising the core clock at %lu Hz\n", core_rate);
 
@@ -431,14 +431,17 @@ static void vc4_atomic_commit_tail(struct drm_atomic_state *state)
 	drm_atomic_helper_cleanup_planes(dev, state);
 
 	if (vc4->is_vc5) {
-		drm_dbg(dev, "Running the core clock at %lu Hz\n",
-			new_hvs_state->core_clock_rate);
+		unsigned long core_rate = min_t(unsigned long,
+						hvs->max_core_rate,
+						new_hvs_state->core_clock_rate);
+
+		drm_dbg(dev, "Running the core clock at %lu Hz\n", core_rate);
 
 		/*
 		 * Request a clock rate based on the current HVS
 		 * requirements.
 		 */
-		WARN_ON(clk_set_min_rate(hvs->core_clk, new_hvs_state->core_clock_rate));
+		WARN_ON(clk_set_min_rate(hvs->core_clk, core_rate));
 
 		drm_dbg(dev, "Core clock actual rate: %lu Hz\n",
 			clk_get_rate(hvs->core_clk));

-- 
b4 0.10.1

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* Re: [PATCH v4 1/7] firmware: raspberrypi: Introduce rpi_firmware_find_node()
  2022-10-20  9:12 ` [PATCH v4 1/7] firmware: raspberrypi: Introduce rpi_firmware_find_node() maxime
@ 2022-10-24 19:19   ` Florian Fainelli
  0 siblings, 0 replies; 17+ messages in thread
From: Florian Fainelli @ 2022-10-24 19:19 UTC (permalink / raw)
  To: maxime, Daniel Vetter, Emma Anholt, Michael Turquette,
	Stephen Boyd, Maxime Ripard, Ray Jui, Florian Fainelli,
	David Airlie, Broadcom internal kernel review list,
	Scott Branden
  Cc: Stefan Wahren, linux-kernel, dri-devel, linux-rpi-kernel,
	Dom Cobley, linux-clk, linux-arm-kernel

On 10/20/22 02:12, maxime@cerno.tech wrote:
> A significant number of RaspberryPi drivers using the firmware don't
> have a phandle to it, so end up scanning the device tree to find a node
> with the firmware compatible.
> 
> That code is duplicated everywhere, so let's introduce a helper instead.
> 
> Signed-off-by: Maxime Ripard <maxime@cerno.tech>

Acked-by: Florian Fainelli <f.fainelli@gmail.com>

Thanks for re-ordering the rpi_firmware_of_match array and avoiding a 
forward declaration that I was initially confused about in v3.
-- 
Florian


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v4 4/7] drm/vc4: hdmi: Fix hdmi_enable_4kp60 detection
  2022-10-20  9:12 ` [PATCH v4 4/7] drm/vc4: hdmi: Fix hdmi_enable_4kp60 detection maxime
@ 2022-10-26 15:27   ` Dave Stevenson
  2022-10-26 15:36     ` Dave Stevenson
  0 siblings, 1 reply; 17+ messages in thread
From: Dave Stevenson @ 2022-10-26 15:27 UTC (permalink / raw)
  To: maxime
  Cc: Stefan Wahren, Florian Fainelli, Scott Branden, Emma Anholt,
	Stephen Boyd, Ray Jui, Michael Turquette, linux-kernel,
	David Airlie, Broadcom internal kernel review list, dri-devel,
	Dom Cobley, linux-clk, linux-arm-kernel, linux-rpi-kernel

On Thu, 20 Oct 2022 at 10:14, <maxime@cerno.tech> wrote:
>
> In order to support higher HDMI frequencies, users have to set the
> hdmi_enable_4kp60 parameter in their config.txt file.
>
> We were detecting this so far by calling clk_round_rate() on the core
> clock with the frequency we're supposed to run at when one of those
> modes is enabled. Whether or not the parameter was enabled could then be
> inferred by the returned rate since the maximum clock rate reported by
> the firmware was one of the side effect of setting that parameter.
>
> However, the recent clock rework we did changed what clk_round_rate()
> was returning to always return the minimum allowed, and thus this test
> wasn't reliable anymore.
>
> Let's use the new clk_get_max_rate() function to reliably determine the
> maximum rate allowed on that clock and fix the 4k@60Hz output.
>
> Fixes: e9d6cea2af1c ("clk: bcm: rpi: Run some clocks at the minimum rate allowed")
> Signed-off-by: Maxime Ripard <maxime@cerno.tech>

Reviewed-by: Dave Stevenson <dave.stevenson@raspberrypi.com>

> ---
>  drivers/gpu/drm/vc4/vc4_hdmi.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
> index 64f9feabf43e..87961d4de5aa 100644
> --- a/drivers/gpu/drm/vc4/vc4_hdmi.c
> +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
> @@ -46,6 +46,7 @@
>  #include <linux/pm_runtime.h>
>  #include <linux/rational.h>
>  #include <linux/reset.h>
> +#include <soc/bcm2835/raspberrypi-clocks.h>
>  #include <sound/dmaengine_pcm.h>
>  #include <sound/hdmi-codec.h>
>  #include <sound/pcm_drm_eld.h>
> @@ -3429,7 +3430,7 @@ static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)
>
>         if (variant->max_pixel_clock == 600000000) {
>                 struct vc4_dev *vc4 = to_vc4_dev(drm);
> -               long max_rate = clk_round_rate(vc4->hvs->core_clk, 550000000);
> +               unsigned long max_rate = rpi_firmware_clk_get_max_rate(vc4->hvs->core_clk);
>
>                 if (max_rate < 550000000)
>                         vc4_hdmi->disable_4kp60 = true;
>
> --
> b4 0.10.1

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v4 4/7] drm/vc4: hdmi: Fix hdmi_enable_4kp60 detection
  2022-10-26 15:27   ` Dave Stevenson
@ 2022-10-26 15:36     ` Dave Stevenson
  2022-10-26 16:10       ` maxime
  0 siblings, 1 reply; 17+ messages in thread
From: Dave Stevenson @ 2022-10-26 15:36 UTC (permalink / raw)
  To: maxime
  Cc: Stefan Wahren, Florian Fainelli, Scott Branden, Emma Anholt,
	Stephen Boyd, Ray Jui, Michael Turquette, linux-kernel,
	David Airlie, Broadcom internal kernel review list, dri-devel,
	Dom Cobley, linux-clk, linux-arm-kernel, linux-rpi-kernel

On Wed, 26 Oct 2022 at 16:27, Dave Stevenson
<dave.stevenson@raspberrypi.com> wrote:
>
> On Thu, 20 Oct 2022 at 10:14, <maxime@cerno.tech> wrote:
> >
> > In order to support higher HDMI frequencies, users have to set the
> > hdmi_enable_4kp60 parameter in their config.txt file.
> >
> > We were detecting this so far by calling clk_round_rate() on the core
> > clock with the frequency we're supposed to run at when one of those
> > modes is enabled. Whether or not the parameter was enabled could then be
> > inferred by the returned rate since the maximum clock rate reported by
> > the firmware was one of the side effect of setting that parameter.
> >
> > However, the recent clock rework we did changed what clk_round_rate()
> > was returning to always return the minimum allowed, and thus this test
> > wasn't reliable anymore.
> >
> > Let's use the new clk_get_max_rate() function to reliably determine the
> > maximum rate allowed on that clock and fix the 4k@60Hz output.
> >
> > Fixes: e9d6cea2af1c ("clk: bcm: rpi: Run some clocks at the minimum rate allowed")
> > Signed-off-by: Maxime Ripard <maxime@cerno.tech>
>
> Reviewed-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
>
> > ---
> >  drivers/gpu/drm/vc4/vc4_hdmi.c | 3 ++-
> >  1 file changed, 2 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
> > index 64f9feabf43e..87961d4de5aa 100644
> > --- a/drivers/gpu/drm/vc4/vc4_hdmi.c
> > +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
> > @@ -46,6 +46,7 @@
> >  #include <linux/pm_runtime.h>
> >  #include <linux/rational.h>
> >  #include <linux/reset.h>
> > +#include <soc/bcm2835/raspberrypi-clocks.h>
> >  #include <sound/dmaengine_pcm.h>
> >  #include <sound/hdmi-codec.h>
> >  #include <sound/pcm_drm_eld.h>
> > @@ -3429,7 +3430,7 @@ static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)
> >
> >         if (variant->max_pixel_clock == 600000000) {
> >                 struct vc4_dev *vc4 = to_vc4_dev(drm);
> > -               long max_rate = clk_round_rate(vc4->hvs->core_clk, 550000000);
> > +               unsigned long max_rate = rpi_firmware_clk_get_max_rate(vc4->hvs->core_clk);

Actually minor nit:
rpi_firmware_clk_get_max_rate returns an unsigned int.
AFAICT we don't need the range of unsigned long in any subsequent
code, so I think it could just be unsigned int here.

clk_round_rate returned a long, and therefore previously it did have to be that.

  Dave

> >                 if (max_rate < 550000000)
> >                         vc4_hdmi->disable_4kp60 = true;
> >
> > --
> > b4 0.10.1

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v4 5/7] drm/vc4: hdmi: Rework hdmi_enable_4kp60 detection code
  2022-10-20  9:12 ` [PATCH v4 5/7] drm/vc4: hdmi: Rework hdmi_enable_4kp60 detection code maxime
@ 2022-10-26 16:00   ` Dave Stevenson
  2022-10-26 16:05     ` Dave Stevenson
  2022-10-26 16:14     ` maxime
  0 siblings, 2 replies; 17+ messages in thread
From: Dave Stevenson @ 2022-10-26 16:00 UTC (permalink / raw)
  To: maxime
  Cc: Stefan Wahren, Florian Fainelli, Scott Branden, Emma Anholt,
	Stephen Boyd, Ray Jui, Michael Turquette, linux-kernel,
	David Airlie, Broadcom internal kernel review list, dri-devel,
	Dom Cobley, linux-clk, linux-arm-kernel, linux-rpi-kernel

Hi Maxime

On Thu, 20 Oct 2022 at 10:14, <maxime@cerno.tech> wrote:
>
> In order to support higher HDMI frequencies, users have to set the
> hdmi_enable_4kp60 parameter in their config.txt file.
>
> This will have the side-effect of raising the maximum of the core clock,
> tied to the HVS, and managed by the HVS driver.
>
> However, we are querying this in the HDMI driver by poking into the HVS
> structure to get our struct clk handle.
>
> Let's make this part of the HVS bind implementation to have all the core
> clock related setup in the same place.
>
> Signed-off-by: Maxime Ripard <maxime@cerno.tech>
> ---
>  drivers/gpu/drm/vc4/vc4_drv.h  | 10 ++++++++++
>  drivers/gpu/drm/vc4/vc4_hdmi.c | 15 ++++-----------
>  drivers/gpu/drm/vc4/vc4_hdmi.h |  8 --------
>  drivers/gpu/drm/vc4/vc4_hvs.c  | 23 +++++++++++++++++++++++
>  4 files changed, 37 insertions(+), 19 deletions(-)
>
> diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
> index 418a8242691f..8b2b1af565f9 100644
> --- a/drivers/gpu/drm/vc4/vc4_drv.h
> +++ b/drivers/gpu/drm/vc4/vc4_drv.h
> @@ -326,6 +326,8 @@ struct vc4_hvs {
>
>         struct clk *core_clk;
>
> +       unsigned long max_core_rate;
> +
>         /* Memory manager for CRTCs to allocate space in the display
>          * list.  Units are dwords.
>          */
> @@ -337,6 +339,14 @@ struct vc4_hvs {
>         struct drm_mm_node mitchell_netravali_filter;
>
>         struct debugfs_regset32 regset;
> +
> +       /*
> +        * Even if HDMI0 on the RPi4 can output modes requiring a pixel
> +        * rate higher than 297MHz, it needs some adjustments in the
> +        * config.txt file to be able to do so and thus won't always be
> +        * available.
> +        */
> +       bool vc5_hdmi_enable_scrambling;
>  };
>
>  struct vc4_plane {
> diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
> index 87961d4de5aa..afe3daa2173e 100644
> --- a/drivers/gpu/drm/vc4/vc4_hdmi.c
> +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
> @@ -46,7 +46,6 @@
>  #include <linux/pm_runtime.h>
>  #include <linux/rational.h>
>  #include <linux/reset.h>
> -#include <soc/bcm2835/raspberrypi-clocks.h>
>  #include <sound/dmaengine_pcm.h>
>  #include <sound/hdmi-codec.h>
>  #include <sound/pcm_drm_eld.h>
> @@ -460,6 +459,7 @@ static int vc4_hdmi_connector_detect_ctx(struct drm_connector *connector,
>  static int vc4_hdmi_connector_get_modes(struct drm_connector *connector)
>  {
>         struct vc4_hdmi *vc4_hdmi = connector_to_vc4_hdmi(connector);
> +       struct vc4_dev *vc4 = to_vc4_dev(connector->dev);
>         int ret = 0;
>         struct edid *edid;
>
> @@ -483,7 +483,7 @@ static int vc4_hdmi_connector_get_modes(struct drm_connector *connector)
>         ret = drm_add_edid_modes(connector, edid);
>         kfree(edid);
>
> -       if (vc4_hdmi->disable_4kp60) {
> +       if (!vc4->hvs->vc5_hdmi_enable_scrambling) {
>                 struct drm_device *drm = connector->dev;
>                 const struct drm_display_mode *mode;
>
> @@ -1757,11 +1757,12 @@ vc4_hdmi_encoder_clock_valid(const struct vc4_hdmi *vc4_hdmi,
>  {
>         const struct drm_connector *connector = &vc4_hdmi->connector;
>         const struct drm_display_info *info = &connector->display_info;
> +       struct vc4_dev *vc4 = to_vc4_dev(connector->dev);
>
>         if (clock > vc4_hdmi->variant->max_pixel_clock)
>                 return MODE_CLOCK_HIGH;
>
> -       if (vc4_hdmi->disable_4kp60 && clock > HDMI_14_MAX_TMDS_CLK)
> +       if (!vc4->hvs->vc5_hdmi_enable_scrambling && clock > HDMI_14_MAX_TMDS_CLK)
>                 return MODE_CLOCK_HIGH;
>
>         if (info->max_tmds_clock && clock > (info->max_tmds_clock * 1000))
> @@ -3428,14 +3429,6 @@ static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)
>         vc4_hdmi->disable_wifi_frequencies =
>                 of_property_read_bool(dev->of_node, "wifi-2.4ghz-coexistence");
>
> -       if (variant->max_pixel_clock == 600000000) {
> -               struct vc4_dev *vc4 = to_vc4_dev(drm);
> -               unsigned long max_rate = rpi_firmware_clk_get_max_rate(vc4->hvs->core_clk);
> -
> -               if (max_rate < 550000000)
> -                       vc4_hdmi->disable_4kp60 = true;
> -       }
> -
>         ret = devm_pm_runtime_enable(dev);
>         if (ret)
>                 return ret;
> diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.h b/drivers/gpu/drm/vc4/vc4_hdmi.h
> index db823efb2563..e3619836ca17 100644
> --- a/drivers/gpu/drm/vc4/vc4_hdmi.h
> +++ b/drivers/gpu/drm/vc4/vc4_hdmi.h
> @@ -156,14 +156,6 @@ struct vc4_hdmi {
>          */
>         bool disable_wifi_frequencies;
>
> -       /*
> -        * Even if HDMI0 on the RPi4 can output modes requiring a pixel
> -        * rate higher than 297MHz, it needs some adjustments in the
> -        * config.txt file to be able to do so and thus won't always be
> -        * available.
> -        */
> -       bool disable_4kp60;
> -
>         struct cec_adapter *cec_adap;
>         struct cec_msg cec_rx_msg;
>         bool cec_tx_ok;
> diff --git a/drivers/gpu/drm/vc4/vc4_hvs.c b/drivers/gpu/drm/vc4/vc4_hvs.c
> index 4ac9f5a2d5f9..300ac0b57571 100644
> --- a/drivers/gpu/drm/vc4/vc4_hvs.c
> +++ b/drivers/gpu/drm/vc4/vc4_hvs.c
> @@ -28,6 +28,8 @@
>  #include <drm/drm_drv.h>
>  #include <drm/drm_vblank.h>
>
> +#include <soc/bcm2835/raspberrypi-firmware.h>
> +
>  #include "vc4_drv.h"
>  #include "vc4_regs.h"
>
> @@ -791,12 +793,33 @@ static int vc4_hvs_bind(struct device *dev, struct device *master, void *data)
>         hvs->regset.nregs = ARRAY_SIZE(hvs_regs);
>
>         if (vc4->is_vc5) {
> +               struct rpi_firmware *firmware;
> +               struct device_node *node;
> +               unsigned long max_rate;

As commented on patch 4, the value returned by
rpi_firmware_clk_get_max_rate is only an unsigned int.
I guess in this case it is passed into the clock frame work which
wants unsigned long, but do we need to keep it as an unsigned long?

> +
> +               node = rpi_firmware_find_node();
> +               if (!node)
> +                       return -EINVAL;
> +
> +               firmware = rpi_firmware_get(node);
> +               of_node_put(node);
> +               if (!firmware)
> +                       return -EPROBE_DEFER;
> +
>                 hvs->core_clk = devm_clk_get(&pdev->dev, NULL);
>                 if (IS_ERR(hvs->core_clk)) {
>                         dev_err(&pdev->dev, "Couldn't get core clock\n");
>                         return PTR_ERR(hvs->core_clk);
>                 }
>
> +               max_rate = rpi_firmware_clk_get_max_rate(firmware,
> +                                                        RPI_FIRMWARE_CORE_CLK_ID);
> +               rpi_firmware_put(firmware);
> +               if (max_rate >= 550000000)
> +                       hvs->vc5_hdmi_enable_scrambling = true;
> +
> +               hvs->max_core_rate = max_rate;

I was going to query the reason for storing this value, but it's used
when we get to patch 7/7.
I won't quibble about having it as an unused value for 2 patches.

If you're happy in both cases, then I'll send an R-b.

  Dave

>                 ret = clk_prepare_enable(hvs->core_clk);
>                 if (ret) {
>                         dev_err(&pdev->dev, "Couldn't enable the core clock\n");
>
> --
> b4 0.10.1

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v4 5/7] drm/vc4: hdmi: Rework hdmi_enable_4kp60 detection code
  2022-10-26 16:00   ` Dave Stevenson
@ 2022-10-26 16:05     ` Dave Stevenson
  2022-10-26 16:14     ` maxime
  1 sibling, 0 replies; 17+ messages in thread
From: Dave Stevenson @ 2022-10-26 16:05 UTC (permalink / raw)
  To: maxime
  Cc: Stefan Wahren, Florian Fainelli, Scott Branden, Emma Anholt,
	Stephen Boyd, Ray Jui, Michael Turquette, linux-kernel,
	David Airlie, Broadcom internal kernel review list, dri-devel,
	Dom Cobley, linux-clk, linux-arm-kernel, linux-rpi-kernel

I knew there was something else

On Wed, 26 Oct 2022 at 17:00, Dave Stevenson
<dave.stevenson@raspberrypi.com> wrote:
>
> Hi Maxime
>
> On Thu, 20 Oct 2022 at 10:14, <maxime@cerno.tech> wrote:
> >
> > In order to support higher HDMI frequencies, users have to set the
> > hdmi_enable_4kp60 parameter in their config.txt file.
> >
> > This will have the side-effect of raising the maximum of the core clock,
> > tied to the HVS, and managed by the HVS driver.
> >
> > However, we are querying this in the HDMI driver by poking into the HVS
> > structure to get our struct clk handle.
> >
> > Let's make this part of the HVS bind implementation to have all the core
> > clock related setup in the same place.
> >
> > Signed-off-by: Maxime Ripard <maxime@cerno.tech>
> > ---
> >  drivers/gpu/drm/vc4/vc4_drv.h  | 10 ++++++++++
> >  drivers/gpu/drm/vc4/vc4_hdmi.c | 15 ++++-----------
> >  drivers/gpu/drm/vc4/vc4_hdmi.h |  8 --------
> >  drivers/gpu/drm/vc4/vc4_hvs.c  | 23 +++++++++++++++++++++++
> >  4 files changed, 37 insertions(+), 19 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
> > index 418a8242691f..8b2b1af565f9 100644
> > --- a/drivers/gpu/drm/vc4/vc4_drv.h
> > +++ b/drivers/gpu/drm/vc4/vc4_drv.h
> > @@ -326,6 +326,8 @@ struct vc4_hvs {
> >
> >         struct clk *core_clk;
> >
> > +       unsigned long max_core_rate;
> > +
> >         /* Memory manager for CRTCs to allocate space in the display
> >          * list.  Units are dwords.
> >          */
> > @@ -337,6 +339,14 @@ struct vc4_hvs {
> >         struct drm_mm_node mitchell_netravali_filter;
> >
> >         struct debugfs_regset32 regset;
> > +
> > +       /*
> > +        * Even if HDMI0 on the RPi4 can output modes requiring a pixel
> > +        * rate higher than 297MHz, it needs some adjustments in the
> > +        * config.txt file to be able to do so and thus won't always be
> > +        * available.
> > +        */
> > +       bool vc5_hdmi_enable_scrambling;

Name only. This flag isn't to do with scrambling, it's whether we can
achieve pixel rates greater than those defined by HDMI 1.4.

We do have code related to enabling scrambling, which is part of HDMI
2.0, so this currently could cause confusion.

  Dave

> >  };
> >
> >  struct vc4_plane {
> > diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
> > index 87961d4de5aa..afe3daa2173e 100644
> > --- a/drivers/gpu/drm/vc4/vc4_hdmi.c
> > +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
> > @@ -46,7 +46,6 @@
> >  #include <linux/pm_runtime.h>
> >  #include <linux/rational.h>
> >  #include <linux/reset.h>
> > -#include <soc/bcm2835/raspberrypi-clocks.h>
> >  #include <sound/dmaengine_pcm.h>
> >  #include <sound/hdmi-codec.h>
> >  #include <sound/pcm_drm_eld.h>
> > @@ -460,6 +459,7 @@ static int vc4_hdmi_connector_detect_ctx(struct drm_connector *connector,
> >  static int vc4_hdmi_connector_get_modes(struct drm_connector *connector)
> >  {
> >         struct vc4_hdmi *vc4_hdmi = connector_to_vc4_hdmi(connector);
> > +       struct vc4_dev *vc4 = to_vc4_dev(connector->dev);
> >         int ret = 0;
> >         struct edid *edid;
> >
> > @@ -483,7 +483,7 @@ static int vc4_hdmi_connector_get_modes(struct drm_connector *connector)
> >         ret = drm_add_edid_modes(connector, edid);
> >         kfree(edid);
> >
> > -       if (vc4_hdmi->disable_4kp60) {
> > +       if (!vc4->hvs->vc5_hdmi_enable_scrambling) {
> >                 struct drm_device *drm = connector->dev;
> >                 const struct drm_display_mode *mode;
> >
> > @@ -1757,11 +1757,12 @@ vc4_hdmi_encoder_clock_valid(const struct vc4_hdmi *vc4_hdmi,
> >  {
> >         const struct drm_connector *connector = &vc4_hdmi->connector;
> >         const struct drm_display_info *info = &connector->display_info;
> > +       struct vc4_dev *vc4 = to_vc4_dev(connector->dev);
> >
> >         if (clock > vc4_hdmi->variant->max_pixel_clock)
> >                 return MODE_CLOCK_HIGH;
> >
> > -       if (vc4_hdmi->disable_4kp60 && clock > HDMI_14_MAX_TMDS_CLK)
> > +       if (!vc4->hvs->vc5_hdmi_enable_scrambling && clock > HDMI_14_MAX_TMDS_CLK)
> >                 return MODE_CLOCK_HIGH;
> >
> >         if (info->max_tmds_clock && clock > (info->max_tmds_clock * 1000))
> > @@ -3428,14 +3429,6 @@ static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)
> >         vc4_hdmi->disable_wifi_frequencies =
> >                 of_property_read_bool(dev->of_node, "wifi-2.4ghz-coexistence");
> >
> > -       if (variant->max_pixel_clock == 600000000) {
> > -               struct vc4_dev *vc4 = to_vc4_dev(drm);
> > -               unsigned long max_rate = rpi_firmware_clk_get_max_rate(vc4->hvs->core_clk);
> > -
> > -               if (max_rate < 550000000)
> > -                       vc4_hdmi->disable_4kp60 = true;
> > -       }
> > -
> >         ret = devm_pm_runtime_enable(dev);
> >         if (ret)
> >                 return ret;
> > diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.h b/drivers/gpu/drm/vc4/vc4_hdmi.h
> > index db823efb2563..e3619836ca17 100644
> > --- a/drivers/gpu/drm/vc4/vc4_hdmi.h
> > +++ b/drivers/gpu/drm/vc4/vc4_hdmi.h
> > @@ -156,14 +156,6 @@ struct vc4_hdmi {
> >          */
> >         bool disable_wifi_frequencies;
> >
> > -       /*
> > -        * Even if HDMI0 on the RPi4 can output modes requiring a pixel
> > -        * rate higher than 297MHz, it needs some adjustments in the
> > -        * config.txt file to be able to do so and thus won't always be
> > -        * available.
> > -        */
> > -       bool disable_4kp60;
> > -
> >         struct cec_adapter *cec_adap;
> >         struct cec_msg cec_rx_msg;
> >         bool cec_tx_ok;
> > diff --git a/drivers/gpu/drm/vc4/vc4_hvs.c b/drivers/gpu/drm/vc4/vc4_hvs.c
> > index 4ac9f5a2d5f9..300ac0b57571 100644
> > --- a/drivers/gpu/drm/vc4/vc4_hvs.c
> > +++ b/drivers/gpu/drm/vc4/vc4_hvs.c
> > @@ -28,6 +28,8 @@
> >  #include <drm/drm_drv.h>
> >  #include <drm/drm_vblank.h>
> >
> > +#include <soc/bcm2835/raspberrypi-firmware.h>
> > +
> >  #include "vc4_drv.h"
> >  #include "vc4_regs.h"
> >
> > @@ -791,12 +793,33 @@ static int vc4_hvs_bind(struct device *dev, struct device *master, void *data)
> >         hvs->regset.nregs = ARRAY_SIZE(hvs_regs);
> >
> >         if (vc4->is_vc5) {
> > +               struct rpi_firmware *firmware;
> > +               struct device_node *node;
> > +               unsigned long max_rate;
>
> As commented on patch 4, the value returned by
> rpi_firmware_clk_get_max_rate is only an unsigned int.
> I guess in this case it is passed into the clock frame work which
> wants unsigned long, but do we need to keep it as an unsigned long?
>
> > +
> > +               node = rpi_firmware_find_node();
> > +               if (!node)
> > +                       return -EINVAL;
> > +
> > +               firmware = rpi_firmware_get(node);
> > +               of_node_put(node);
> > +               if (!firmware)
> > +                       return -EPROBE_DEFER;
> > +
> >                 hvs->core_clk = devm_clk_get(&pdev->dev, NULL);
> >                 if (IS_ERR(hvs->core_clk)) {
> >                         dev_err(&pdev->dev, "Couldn't get core clock\n");
> >                         return PTR_ERR(hvs->core_clk);
> >                 }
> >
> > +               max_rate = rpi_firmware_clk_get_max_rate(firmware,
> > +                                                        RPI_FIRMWARE_CORE_CLK_ID);
> > +               rpi_firmware_put(firmware);
> > +               if (max_rate >= 550000000)
> > +                       hvs->vc5_hdmi_enable_scrambling = true;
> > +
> > +               hvs->max_core_rate = max_rate;
>
> I was going to query the reason for storing this value, but it's used
> when we get to patch 7/7.
> I won't quibble about having it as an unused value for 2 patches.
>
> If you're happy in both cases, then I'll send an R-b.
>
>   Dave
>
> >                 ret = clk_prepare_enable(hvs->core_clk);
> >                 if (ret) {
> >                         dev_err(&pdev->dev, "Couldn't enable the core clock\n");
> >
> > --
> > b4 0.10.1

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v4 6/7] drm/vc4: hdmi: Add more checks for 4k resolutions
  2022-10-20  9:12 ` [PATCH v4 6/7] drm/vc4: hdmi: Add more checks for 4k resolutions maxime
@ 2022-10-26 16:06   ` Dave Stevenson
  0 siblings, 0 replies; 17+ messages in thread
From: Dave Stevenson @ 2022-10-26 16:06 UTC (permalink / raw)
  To: maxime
  Cc: Stefan Wahren, Florian Fainelli, Scott Branden, Emma Anholt,
	Stephen Boyd, Ray Jui, Michael Turquette, linux-kernel,
	David Airlie, Broadcom internal kernel review list, dri-devel,
	Dom Cobley, linux-clk, linux-arm-kernel, linux-rpi-kernel

On Thu, 20 Oct 2022 at 10:14, <maxime@cerno.tech> wrote:
>
> From: Dom Cobley <popcornmix@gmail.com>
>
> At least the 4096x2160@60Hz mode requires some overclocking that isn't
> available by default, even if hdmi_enable_4kp60 is enabled.
>
> Let's add some logic to detect whether we can satisfy the core clock
> requirements for that mode, and prevent it from being used otherwise.
>
> Signed-off-by: Dom Cobley <popcornmix@gmail.com>
> Signed-off-by: Maxime Ripard <maxime@cerno.tech>

Reviewed-by: Dave Stevenson <dave.stevenson@raspberrypi.com>

> ---
>  drivers/gpu/drm/vc4/vc4_drv.h  |  6 ++++++
>  drivers/gpu/drm/vc4/vc4_hdmi.c | 11 +++++++++--
>  drivers/gpu/drm/vc4/vc4_hvs.c  |  3 +++
>  3 files changed, 18 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
> index 8b2b1af565f9..72a6b7151d23 100644
> --- a/drivers/gpu/drm/vc4/vc4_drv.h
> +++ b/drivers/gpu/drm/vc4/vc4_drv.h
> @@ -347,6 +347,12 @@ struct vc4_hvs {
>          * available.
>          */
>         bool vc5_hdmi_enable_scrambling;
> +
> +       /*
> +        * 4096x2160@60 requires a core overclock to work, so register
> +        * whether that is sufficient.
> +        */
> +       bool vc5_hdmi_enable_4096by2160;
>  };
>
>  struct vc4_plane {
> diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
> index afe3daa2173e..fd3730ea976f 100644
> --- a/drivers/gpu/drm/vc4/vc4_hdmi.c
> +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
> @@ -1753,6 +1753,7 @@ vc4_hdmi_sink_supports_format_bpc(const struct vc4_hdmi *vc4_hdmi,
>
>  static enum drm_mode_status
>  vc4_hdmi_encoder_clock_valid(const struct vc4_hdmi *vc4_hdmi,
> +                            const struct drm_display_mode *mode,
>                              unsigned long long clock)
>  {
>         const struct drm_connector *connector = &vc4_hdmi->connector;
> @@ -1765,6 +1766,12 @@ vc4_hdmi_encoder_clock_valid(const struct vc4_hdmi *vc4_hdmi,
>         if (!vc4->hvs->vc5_hdmi_enable_scrambling && clock > HDMI_14_MAX_TMDS_CLK)
>                 return MODE_CLOCK_HIGH;
>
> +       /* 4096x2160@60 is not reliable without overclocking core */
> +       if (!vc4->hvs->vc5_hdmi_enable_4096by2160 &&
> +           mode->hdisplay > 3840 && mode->vdisplay >= 2160 &&
> +           drm_mode_vrefresh(mode) >= 50)
> +               return MODE_CLOCK_HIGH;
> +
>         if (info->max_tmds_clock && clock > (info->max_tmds_clock * 1000))
>                 return MODE_CLOCK_HIGH;
>
> @@ -1799,7 +1806,7 @@ vc4_hdmi_encoder_compute_clock(const struct vc4_hdmi *vc4_hdmi,
>         unsigned long long clock;
>
>         clock = vc4_hdmi_encoder_compute_mode_clock(mode, bpc, fmt);
> -       if (vc4_hdmi_encoder_clock_valid(vc4_hdmi, clock) != MODE_OK)
> +       if (vc4_hdmi_encoder_clock_valid(vc4_hdmi, mode, clock) != MODE_OK)
>                 return -EINVAL;
>
>         vc4_state->tmds_char_rate = clock;
> @@ -1962,7 +1969,7 @@ vc4_hdmi_encoder_mode_valid(struct drm_encoder *encoder,
>              (mode->hsync_end % 2) || (mode->htotal % 2)))
>                 return MODE_H_ILLEGAL;
>
> -       return vc4_hdmi_encoder_clock_valid(vc4_hdmi, mode->clock * 1000);
> +       return vc4_hdmi_encoder_clock_valid(vc4_hdmi, mode, mode->clock * 1000);
>  }
>
>  static const struct drm_encoder_helper_funcs vc4_hdmi_encoder_helper_funcs = {
> diff --git a/drivers/gpu/drm/vc4/vc4_hvs.c b/drivers/gpu/drm/vc4/vc4_hvs.c
> index 300ac0b57571..a68913f76687 100644
> --- a/drivers/gpu/drm/vc4/vc4_hvs.c
> +++ b/drivers/gpu/drm/vc4/vc4_hvs.c
> @@ -818,6 +818,9 @@ static int vc4_hvs_bind(struct device *dev, struct device *master, void *data)
>                 if (max_rate >= 550000000)
>                         hvs->vc5_hdmi_enable_scrambling = true;
>
> +               if (max_rate >= 600000000)
> +                       hvs->vc5_hdmi_enable_4096by2160 = true;
> +
>                 hvs->max_core_rate = max_rate;
>
>                 ret = clk_prepare_enable(hvs->core_clk);
>
> --
> b4 0.10.1

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v4 7/7] drm/vc4: Make sure we don't end up with a core clock too high
  2022-10-20  9:12 ` [PATCH v4 7/7] drm/vc4: Make sure we don't end up with a core clock too high maxime
@ 2022-10-26 16:09   ` Dave Stevenson
  0 siblings, 0 replies; 17+ messages in thread
From: Dave Stevenson @ 2022-10-26 16:09 UTC (permalink / raw)
  To: maxime
  Cc: Stefan Wahren, Florian Fainelli, Scott Branden, Emma Anholt,
	Stephen Boyd, Ray Jui, Michael Turquette, linux-kernel,
	David Airlie, Broadcom internal kernel review list, dri-devel,
	Dom Cobley, linux-clk, linux-arm-kernel, linux-rpi-kernel

On Thu, 20 Oct 2022 at 10:14, <maxime@cerno.tech> wrote:
>
> Following the clock rate range improvements to the clock framework,
> trying to set a disjoint range on a clock will now result in an error.
>
> Thus, we can't set a minimum rate higher than the maximum reported by
> the firmware, or clk_set_min_rate() will fail.
>
> Thus we need to clamp the rate we are about to ask for to the maximum
> rate possible on that clock.
>
> Signed-off-by: Maxime Ripard <maxime@cerno.tech>

Thanks Maxime.

Reviewed-by: Dave Stevenson <dave.stevenson@raspberrypi.com>

> ---
>  drivers/gpu/drm/vc4/vc4_kms.c | 13 ++++++++-----
>  1 file changed, 8 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/gpu/drm/vc4/vc4_kms.c b/drivers/gpu/drm/vc4/vc4_kms.c
> index 4419e810103d..5c97642ed66a 100644
> --- a/drivers/gpu/drm/vc4/vc4_kms.c
> +++ b/drivers/gpu/drm/vc4/vc4_kms.c
> @@ -396,8 +396,8 @@ static void vc4_atomic_commit_tail(struct drm_atomic_state *state)
>         if (vc4->is_vc5) {
>                 unsigned long state_rate = max(old_hvs_state->core_clock_rate,
>                                                new_hvs_state->core_clock_rate);
> -               unsigned long core_rate = max_t(unsigned long,
> -                                               500000000, state_rate);
> +               unsigned long core_rate = clamp_t(unsigned long, state_rate,
> +                                                 500000000, hvs->max_core_rate);
>
>                 drm_dbg(dev, "Raising the core clock at %lu Hz\n", core_rate);
>
> @@ -431,14 +431,17 @@ static void vc4_atomic_commit_tail(struct drm_atomic_state *state)
>         drm_atomic_helper_cleanup_planes(dev, state);
>
>         if (vc4->is_vc5) {
> -               drm_dbg(dev, "Running the core clock at %lu Hz\n",
> -                       new_hvs_state->core_clock_rate);
> +               unsigned long core_rate = min_t(unsigned long,
> +                                               hvs->max_core_rate,
> +                                               new_hvs_state->core_clock_rate);
> +
> +               drm_dbg(dev, "Running the core clock at %lu Hz\n", core_rate);
>
>                 /*
>                  * Request a clock rate based on the current HVS
>                  * requirements.
>                  */
> -               WARN_ON(clk_set_min_rate(hvs->core_clk, new_hvs_state->core_clock_rate));
> +               WARN_ON(clk_set_min_rate(hvs->core_clk, core_rate));
>
>                 drm_dbg(dev, "Core clock actual rate: %lu Hz\n",
>                         clk_get_rate(hvs->core_clk));
>
> --
> b4 0.10.1

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v4 4/7] drm/vc4: hdmi: Fix hdmi_enable_4kp60 detection
  2022-10-26 15:36     ` Dave Stevenson
@ 2022-10-26 16:10       ` maxime
  0 siblings, 0 replies; 17+ messages in thread
From: maxime @ 2022-10-26 16:10 UTC (permalink / raw)
  To: Dave Stevenson
  Cc: Stefan Wahren, Florian Fainelli, Scott Branden, Emma Anholt,
	Stephen Boyd, Ray Jui, Michael Turquette, linux-kernel,
	dri-devel, David Airlie, Broadcom internal kernel review list,
	linux-rpi-kernel, Dom Cobley, linux-clk, linux-arm-kernel

Hi Dave,

Thanks for your review

On Wed, Oct 26, 2022 at 04:36:04PM +0100, Dave Stevenson wrote:
> On Wed, 26 Oct 2022 at 16:27, Dave Stevenson
> <dave.stevenson@raspberrypi.com> wrote:
> >
> > On Thu, 20 Oct 2022 at 10:14, <maxime@cerno.tech> wrote:
> > >
> > > In order to support higher HDMI frequencies, users have to set the
> > > hdmi_enable_4kp60 parameter in their config.txt file.
> > >
> > > We were detecting this so far by calling clk_round_rate() on the core
> > > clock with the frequency we're supposed to run at when one of those
> > > modes is enabled. Whether or not the parameter was enabled could then be
> > > inferred by the returned rate since the maximum clock rate reported by
> > > the firmware was one of the side effect of setting that parameter.
> > >
> > > However, the recent clock rework we did changed what clk_round_rate()
> > > was returning to always return the minimum allowed, and thus this test
> > > wasn't reliable anymore.
> > >
> > > Let's use the new clk_get_max_rate() function to reliably determine the
> > > maximum rate allowed on that clock and fix the 4k@60Hz output.
> > >
> > > Fixes: e9d6cea2af1c ("clk: bcm: rpi: Run some clocks at the minimum rate allowed")
> > > Signed-off-by: Maxime Ripard <maxime@cerno.tech>
> >
> > Reviewed-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
> >
> > > ---
> > >  drivers/gpu/drm/vc4/vc4_hdmi.c | 3 ++-
> > >  1 file changed, 2 insertions(+), 1 deletion(-)
> > >
> > > diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
> > > index 64f9feabf43e..87961d4de5aa 100644
> > > --- a/drivers/gpu/drm/vc4/vc4_hdmi.c
> > > +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
> > > @@ -46,6 +46,7 @@
> > >  #include <linux/pm_runtime.h>
> > >  #include <linux/rational.h>
> > >  #include <linux/reset.h>
> > > +#include <soc/bcm2835/raspberrypi-clocks.h>
> > >  #include <sound/dmaengine_pcm.h>
> > >  #include <sound/hdmi-codec.h>
> > >  #include <sound/pcm_drm_eld.h>
> > > @@ -3429,7 +3430,7 @@ static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)
> > >
> > >         if (variant->max_pixel_clock == 600000000) {
> > >                 struct vc4_dev *vc4 = to_vc4_dev(drm);
> > > -               long max_rate = clk_round_rate(vc4->hvs->core_clk, 550000000);
> > > +               unsigned long max_rate = rpi_firmware_clk_get_max_rate(vc4->hvs->core_clk);
> 
> Actually minor nit:
> rpi_firmware_clk_get_max_rate returns an unsigned int.
> AFAICT we don't need the range of unsigned long in any subsequent
> code, so I think it could just be unsigned int here.
> 
> clk_round_rate returned a long, and therefore previously it did have to be that.

Yeah, I was actually two-minded about this.
rpi_firmware_clk_get_max_rate() indeed returns an unsigned long, because
that's what the firmware returns.

But the clock framework uses unsigned long to store all its frequencies,
and in our case here in clk_set_min_rate().

I don't mind changing it to unsigned int here if you prefer to, and if
you're fine with the rest of the patches I can fix it up while applying
the patches.

Maxime

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v4 5/7] drm/vc4: hdmi: Rework hdmi_enable_4kp60 detection code
  2022-10-26 16:00   ` Dave Stevenson
  2022-10-26 16:05     ` Dave Stevenson
@ 2022-10-26 16:14     ` maxime
  1 sibling, 0 replies; 17+ messages in thread
From: maxime @ 2022-10-26 16:14 UTC (permalink / raw)
  To: Dave Stevenson
  Cc: Stefan Wahren, Florian Fainelli, Scott Branden, Emma Anholt,
	Stephen Boyd, Ray Jui, Michael Turquette, linux-kernel,
	dri-devel, David Airlie, Broadcom internal kernel review list,
	linux-rpi-kernel, Dom Cobley, linux-clk, linux-arm-kernel

Hi Dave,

On Wed, Oct 26, 2022 at 05:00:25PM +0100, Dave Stevenson wrote:
> > +
> > +               node = rpi_firmware_find_node();
> > +               if (!node)
> > +                       return -EINVAL;
> > +
> > +               firmware = rpi_firmware_get(node);
> > +               of_node_put(node);
> > +               if (!firmware)
> > +                       return -EPROBE_DEFER;
> > +
> >                 hvs->core_clk = devm_clk_get(&pdev->dev, NULL);
> >                 if (IS_ERR(hvs->core_clk)) {
> >                         dev_err(&pdev->dev, "Couldn't get core clock\n");
> >                         return PTR_ERR(hvs->core_clk);
> >                 }
> >
> > +               max_rate = rpi_firmware_clk_get_max_rate(firmware,
> > +                                                        RPI_FIRMWARE_CORE_CLK_ID);
> > +               rpi_firmware_put(firmware);
> > +               if (max_rate >= 550000000)
> > +                       hvs->vc5_hdmi_enable_scrambling = true;
> > +
> > +               hvs->max_core_rate = max_rate;
> 
> I was going to query the reason for storing this value, but it's used
> when we get to patch 7/7.
> I won't quibble about having it as an unused value for 2 patches.

Yeah, it felt natural to do it in that patch, even though it's indeed
only useful in a couple of patches.

Maxime

^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2022-10-26 16:14 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-10-20  9:12 [PATCH v4 0/7] drm/vc4: Fix the core clock behaviour maxime
2022-10-20  9:12 ` [PATCH v4 1/7] firmware: raspberrypi: Introduce rpi_firmware_find_node() maxime
2022-10-24 19:19   ` Florian Fainelli
2022-10-20  9:12 ` [PATCH v4 2/7] firmware: raspberrypi: Move the clock IDs to the firmware header maxime
2022-10-20  9:12 ` [PATCH v4 3/7] firmware: raspberrypi: Provide a helper to query a clock max rate maxime
2022-10-20  9:12 ` [PATCH v4 4/7] drm/vc4: hdmi: Fix hdmi_enable_4kp60 detection maxime
2022-10-26 15:27   ` Dave Stevenson
2022-10-26 15:36     ` Dave Stevenson
2022-10-26 16:10       ` maxime
2022-10-20  9:12 ` [PATCH v4 5/7] drm/vc4: hdmi: Rework hdmi_enable_4kp60 detection code maxime
2022-10-26 16:00   ` Dave Stevenson
2022-10-26 16:05     ` Dave Stevenson
2022-10-26 16:14     ` maxime
2022-10-20  9:12 ` [PATCH v4 6/7] drm/vc4: hdmi: Add more checks for 4k resolutions maxime
2022-10-26 16:06   ` Dave Stevenson
2022-10-20  9:12 ` [PATCH v4 7/7] drm/vc4: Make sure we don't end up with a core clock too high maxime
2022-10-26 16:09   ` Dave Stevenson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).