#include "vc4_hdmi_regs.h"
#include "vc4_regs.h"
-#define HSM_CLOCK_FREQ 163682864
#define CEC_CLOCK_FREQ 40000
static int vc4_hdmi_debugfs_regs(struct seq_file *m, void *unused)
HDMI_WRITE(HDMI_VID_CTL,
HDMI_READ(HDMI_VID_CTL) & ~VC4_HD_VID_CTL_ENABLE);
+ clk_disable_unprepare(vc4_hdmi->hsm_clock);
clk_disable_unprepare(vc4_hdmi->pixel_clock);
ret = pm_runtime_put(&vc4_hdmi->pdev->dev);
struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
struct vc4_hdmi_encoder *vc4_encoder = to_vc4_hdmi_encoder(encoder);
bool debug_dump_regs = false;
+ unsigned long pixel_rate, hsm_rate;
int ret;
ret = pm_runtime_get_sync(&vc4_hdmi->pdev->dev);
return;
}
- ret = clk_set_rate(vc4_hdmi->pixel_clock,
- mode->clock * 1000 *
- ((mode->flags & DRM_MODE_FLAG_DBLCLK) ? 2 : 1));
+ pixel_rate = mode->clock * 1000 * ((mode->flags & DRM_MODE_FLAG_DBLCLK) ? 2 : 1);
+ ret = clk_set_rate(vc4_hdmi->pixel_clock, pixel_rate);
if (ret) {
DRM_ERROR("Failed to set pixel clock rate: %d\n", ret);
return;
return;
}
+ /*
+ * The HSM rate needs to be at 108% of the pixel clock, with a
+ * minimum of 108MHz.
+ */
+ hsm_rate = max_t(unsigned long, 108000000, (pixel_rate / 100) * 108);
+ ret = clk_set_rate(vc4_hdmi->hsm_clock, hsm_rate);
+ if (ret) {
+ DRM_ERROR("Failed to set HSM clock rate: %d\n", ret);
+ return;
+ }
+
+ ret = clk_prepare_enable(vc4_hdmi->hsm_clock);
+ if (ret) {
+ DRM_ERROR("Failed to turn on HSM clock: %d\n", ret);
+ clk_disable_unprepare(vc4_hdmi->pixel_clock);
+ return;
+ }
+
if (vc4_hdmi->variant->reset)
vc4_hdmi->variant->reset(vc4_hdmi);
* Additionally, the AXI clock needs to be at least 25% of
* pixel clock, but HSM ends up being the limiting factor.
*/
- if (mode->clock > HSM_CLOCK_FREQ / (1000 * 101 / 100))
+ struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
+
+ if ((mode->clock * 1000) > vc4_hdmi->variant->max_pixel_clock)
return MODE_CLOCK_HIGH;
return MODE_OK;
return -EPROBE_DEFER;
}
- /* This is the rate that is set by the firmware. The number
- * needs to be a bit higher than the pixel clock rate
- * (generally 148.5Mhz).
- */
- ret = clk_set_rate(vc4_hdmi->hsm_clock, HSM_CLOCK_FREQ);
- if (ret) {
- DRM_ERROR("Failed to set HSM clock rate: %d\n", ret);
- goto err_put_i2c;
- }
-
- ret = clk_prepare_enable(vc4_hdmi->hsm_clock);
- if (ret) {
- DRM_ERROR("Failed to turn on HDMI state machine clock: %d\n",
- ret);
- goto err_put_i2c;
- }
-
/* Only use the GPIO HPD pin if present in the DT, otherwise
* we'll use the HDMI core's register.
*/
err_destroy_encoder:
vc4_hdmi_encoder_destroy(encoder);
err_unprepare_hsm:
- clk_disable_unprepare(vc4_hdmi->hsm_clock);
pm_runtime_disable(dev);
-err_put_i2c:
put_device(&vc4_hdmi->ddc->dev);
return ret;
vc4_hdmi_connector_destroy(&vc4_hdmi->connector);
vc4_hdmi_encoder_destroy(&vc4_hdmi->encoder.base.base);
- clk_disable_unprepare(vc4_hdmi->hsm_clock);
pm_runtime_disable(dev);
put_device(&vc4_hdmi->ddc->dev);
}
static const struct vc4_hdmi_variant bcm2835_variant = {
+ .max_pixel_clock = 148500000,
.audio_available = true,
.cec_available = true,
.registers = vc4_hdmi_fields,