| b.liu | e958203 | 2025-04-17 19:18:16 +0800 | [diff] [blame] | 1 | From 32e84f4f525e2a0d7dc021b5795df34407096b0e Mon Sep 17 00:00:00 2001 | 
 | 2 | From: Dom Cobley <popcornmix@gmail.com> | 
 | 3 | Date: Thu, 7 May 2020 18:16:08 +0100 | 
 | 4 | Subject: [PATCH] vc4_hdmi: Adjust CEC ref clock based on its input | 
 | 5 |  clock | 
 | 6 |  | 
 | 7 | 2711 uses a fixed 27MHz input, earlier models use the HSM clock | 
 | 8 |  | 
 | 9 | Signed-off-by: Dom Cobley <popcornmix@gmail.com> | 
 | 10 | --- | 
 | 11 |  drivers/gpu/drm/vc4/vc4_hdmi.c | 11 ++++++++--- | 
 | 12 |  drivers/gpu/drm/vc4/vc4_hdmi.h |  3 +++ | 
 | 13 |  2 files changed, 11 insertions(+), 3 deletions(-) | 
 | 14 |  | 
 | 15 | --- a/drivers/gpu/drm/vc4/vc4_hdmi.c | 
 | 16 | +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c | 
 | 17 | @@ -79,6 +79,7 @@ | 
 | 18 |  # define VC4_HD_M_ENABLE			BIT(0) | 
 | 19 |   | 
 | 20 |  #define CEC_CLOCK_FREQ 40000 | 
 | 21 | +#define VC4_HSM_CLOCK 163682864 | 
 | 22 |   | 
 | 23 |  static int vc4_hdmi_debugfs_regs(struct seq_file *m, void *unused) | 
 | 24 |  { | 
 | 25 | @@ -755,8 +756,7 @@ static u32 vc4_hdmi_calc_hsm_clock(struc | 
 | 26 |  	 * needs to be a bit higher than the pixel clock rate | 
 | 27 |  	 * (generally 148.5Mhz). | 
 | 28 |  	 */ | 
 | 29 | - | 
 | 30 | -	return 163682864; | 
 | 31 | +	return VC4_HSM_CLOCK; | 
 | 32 |  } | 
 | 33 |   | 
 | 34 |  static u32 vc5_hdmi_calc_hsm_clock(struct vc4_hdmi *vc4_hdmi, unsigned long pixel_rate) | 
 | 35 | @@ -1400,6 +1400,7 @@ static int vc4_hdmi_cec_init(struct vc4_ | 
 | 36 |  	struct cec_connector_info conn_info; | 
 | 37 |  	struct platform_device *pdev = vc4_hdmi->pdev; | 
 | 38 |  	u32 value; | 
 | 39 | +	u32 clk_cnt; | 
 | 40 |  	int ret; | 
 | 41 |   | 
 | 42 |  	if (!vc4_hdmi->variant->cec_available) | 
 | 43 | @@ -1424,8 +1425,9 @@ static int vc4_hdmi_cec_init(struct vc4_ | 
 | 44 |  	 * divider: the hsm_clock rate and this divider setting will | 
 | 45 |  	 * give a 40 kHz CEC clock. | 
 | 46 |  	 */ | 
 | 47 | +	clk_cnt = vc4_hdmi->variant->cec_input_clock / CEC_CLOCK_FREQ; | 
 | 48 |  	value |= VC4_HDMI_CEC_ADDR_MASK | | 
 | 49 | -		 (4091 << VC4_HDMI_CEC_DIV_CLK_CNT_SHIFT); | 
 | 50 | +		 ((clk_cnt-1) << VC4_HDMI_CEC_DIV_CLK_CNT_SHIFT); | 
 | 51 |  	HDMI_WRITE(HDMI_CEC_CNTRL_1, value); | 
 | 52 |  	ret = devm_request_threaded_irq(&pdev->dev, platform_get_irq(pdev, 0), | 
 | 53 |  					vc4_cec_irq_handler, | 
 | 54 | @@ -1770,6 +1772,7 @@ static int vc4_hdmi_dev_remove(struct pl | 
 | 55 |   | 
 | 56 |  static const struct vc4_hdmi_variant bcm2835_variant = { | 
 | 57 |  	.max_pixel_clock	= 162000000, | 
 | 58 | +	.cec_input_clock	= VC4_HSM_CLOCK, | 
 | 59 |  	.audio_available	= true, | 
 | 60 |  	.cec_available		= true, | 
 | 61 |  	.registers		= vc4_hdmi_fields, | 
 | 62 | @@ -1794,6 +1797,7 @@ static const struct vc4_hdmi_variant bcm | 
 | 63 |  	.id			= 0, | 
 | 64 |  	.audio_available	= true, | 
 | 65 |  	.max_pixel_clock	= 297000000, | 
 | 66 | +	.cec_input_clock	= 27000000, | 
 | 67 |  	.registers		= vc5_hdmi_hdmi0_fields, | 
 | 68 |  	.num_registers		= ARRAY_SIZE(vc5_hdmi_hdmi0_fields), | 
 | 69 |  	.phy_lane_mapping	= { | 
 | 70 | @@ -1821,6 +1825,7 @@ static const struct vc4_hdmi_variant bcm | 
 | 71 |  	.id			= 1, | 
 | 72 |  	.audio_available	= true, | 
 | 73 |  	.max_pixel_clock	= 297000000, | 
 | 74 | +	.cec_input_clock	= 27000000, | 
 | 75 |  	.registers		= vc5_hdmi_hdmi1_fields, | 
 | 76 |  	.num_registers		= ARRAY_SIZE(vc5_hdmi_hdmi1_fields), | 
 | 77 |  	.phy_lane_mapping	= { | 
 | 78 | --- a/drivers/gpu/drm/vc4/vc4_hdmi.h | 
 | 79 | +++ b/drivers/gpu/drm/vc4/vc4_hdmi.h | 
 | 80 | @@ -48,6 +48,9 @@ struct vc4_hdmi_variant { | 
 | 81 |  	/* Maximum pixel clock supported by the controller (in Hz) */ | 
 | 82 |  	unsigned long long max_pixel_clock; | 
 | 83 |   | 
 | 84 | +	/* Input clock frequency of CEC block (in Hz) */ | 
 | 85 | +	unsigned long cec_input_clock; | 
 | 86 | + | 
 | 87 |  	/* List of the registers available on that variant */ | 
 | 88 |  	const struct vc4_hdmi_register *registers; | 
 | 89 |   |