[U-Boot] [PATCH 1/2] sunxi: video: Add a hpd_delay parameter to configure hpd delay

In some extreme cases it may be necessary to wait 1.5 seconds or more for a hpd signal to show up (and be able to read edid info), but we do not want to penalize all headless boots with an extra second boot delay, so add a hpd_delay parameter which can be set through the video-mode env. variable.
While at it raise the default from 300ms to 500ms as 300 may very well be too low in many cases.
Signed-off-by: Hans de Goede hdegoede@redhat.com --- doc/README.video | 8 +++++++- drivers/video/sunxi_display.c | 9 +++++---- 2 files changed, 12 insertions(+), 5 deletions(-)
diff --git a/doc/README.video b/doc/README.video index 2c55d6a..d0a3ad6 100644 --- a/doc/README.video +++ b/doc/README.video @@ -53,6 +53,12 @@ The sunxi u-boot driver supports the following video-mode options: 1: Enabled. Fallback to the lcd / vga / none in that order (if available) Defaults to hpd=1.
+- hpd_delay=<int> - How long to wait for the hdmi HPD signal in milliseconds + When the monitor and the board power up at the same time, it may take some + time for the monitor to assert the HPD signal. This configures how long to + wait for the HPD signal before assuming no cable is connected. + Defaults to hpd_delay=500. + - edid=[0|1] - Enable use of DDC + EDID to get monitor info 0: Disabled. 1: Enabled. If valid EDID info was read from the monitor the EDID info will @@ -61,4 +67,4 @@ The sunxi u-boot driver supports the following video-mode options:
For example to always use the hdmi connector, even if no cable is inserted, using edid info when available and otherwise initalizing it at 1024x768@60Hz, -use: video-mode=sunxi:1024x768-24@60,monitor=dvi,hpd=0,edid=1 . +use: "setenv video-mode sunxi:1024x768-24@60,monitor=dvi,hpd=0,edid=1". diff --git a/drivers/video/sunxi_display.c b/drivers/video/sunxi_display.c index 2eafcab..9d17522 100644 --- a/drivers/video/sunxi_display.c +++ b/drivers/video/sunxi_display.c @@ -56,13 +56,13 @@ static int await_completion(u32 *reg, u32 mask, u32 val) return 0; }
-static int sunxi_hdmi_hpd_detect(void) +static int sunxi_hdmi_hpd_detect(int hpd_delay) { struct sunxi_ccm_reg * const ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; struct sunxi_hdmi_reg * const hdmi = (struct sunxi_hdmi_reg *)SUNXI_HDMI_BASE; - unsigned long tmo = timer_get_us() + 300000; + unsigned long tmo = timer_get_us() + hpd_delay * 1000;
/* Set pll3 to 300MHz */ clock_set_pll3(300000000); @@ -854,7 +854,7 @@ void *video_hw_init(void) struct ctfb_res_modes custom; const char *options; #ifdef CONFIG_VIDEO_HDMI - int ret, hpd, edid; + int ret, hpd, hpd_delay, edid; #endif char mon[16]; char *lcd_mode = CONFIG_VIDEO_LCD_MODE; @@ -870,6 +870,7 @@ void *video_hw_init(void) &sunxi_display.depth, &options); #ifdef CONFIG_VIDEO_HDMI hpd = video_get_option_int(options, "hpd", 1); + hpd_delay = video_get_option_int(options, "hpd_delay", 500); edid = video_get_option_int(options, "edid", 1); sunxi_display.monitor = sunxi_monitor_dvi; #elif defined CONFIG_VIDEO_VGA_VIA_LCD @@ -894,7 +895,7 @@ void *video_hw_init(void) if (sunxi_display.monitor == sunxi_monitor_dvi || sunxi_display.monitor == sunxi_monitor_hdmi) { /* Always call hdp_detect, as it also enables clocks, etc. */ - ret = sunxi_hdmi_hpd_detect(); + ret = sunxi_hdmi_hpd_detect(hpd_delay); if (ret) { printf("HDMI connected: "); if (edid && sunxi_hdmi_edid_get_mode(&custom) == 0)

Let clock_set_pll5 pick the optimal m and k values itself based on the requested rate, rather then passing them in as magic constants.
Suggested-by: Siarhei Siamashka siarhei.siamashka@gmail.com Signed-off-by: Hans de Goede hdegoede@redhat.com --- arch/arm/cpu/armv7/sunxi/clock_sun6i.c | 9 ++++++++- arch/arm/cpu/armv7/sunxi/dram_sun6i.c | 2 +- arch/arm/cpu/armv7/sunxi/dram_sun8i.c | 2 +- arch/arm/include/asm/arch-sunxi/clock_sun6i.h | 2 +- 4 files changed, 11 insertions(+), 4 deletions(-)
diff --git a/arch/arm/cpu/armv7/sunxi/clock_sun6i.c b/arch/arm/cpu/armv7/sunxi/clock_sun6i.c index 36e502f..d7a7040 100644 --- a/arch/arm/cpu/armv7/sunxi/clock_sun6i.c +++ b/arch/arm/cpu/armv7/sunxi/clock_sun6i.c @@ -148,15 +148,22 @@ void clock_set_pll3(unsigned int clk) &ccm->pll3_cfg); }
-void clock_set_pll5(unsigned int clk, int k, int m, bool sigma_delta_enable) +void clock_set_pll5(unsigned int clk, bool sigma_delta_enable) { struct sunxi_ccm_reg * const ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; + const int max_n = 32; + int k = 1, m = 2;
if (sigma_delta_enable) writel(CCM_PLL5_PATTERN, &ccm->pll5_pattern_cfg);
/* PLL5 rate = 24000000 * n * k / m */ + if (clk > 24000000 * k * max_n / m) { + m = 1; + if (clk > 24000000 * k * max_n / m) + k = 2; + } writel(CCM_PLL5_CTRL_EN | (sigma_delta_enable ? CCM_PLL5_CTRL_SIGMA_DELTA_EN : 0) | CCM_PLL5_CTRL_UPD | diff --git a/arch/arm/cpu/armv7/sunxi/dram_sun6i.c b/arch/arm/cpu/armv7/sunxi/dram_sun6i.c index 4518b80..5dbbf61 100644 --- a/arch/arm/cpu/armv7/sunxi/dram_sun6i.c +++ b/arch/arm/cpu/armv7/sunxi/dram_sun6i.c @@ -33,7 +33,7 @@ static void mctl_sys_init(void) (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; const int dram_clk_div = 2;
- clock_set_pll5(DRAM_CLK * dram_clk_div, 2, 1, false); + clock_set_pll5(DRAM_CLK * dram_clk_div, false);
clrsetbits_le32(&ccm->dram_clk_cfg, CCM_DRAMCLK_CFG_DIV0_MASK, CCM_DRAMCLK_CFG_DIV0(dram_clk_div) | CCM_DRAMCLK_CFG_RST | diff --git a/arch/arm/cpu/armv7/sunxi/dram_sun8i.c b/arch/arm/cpu/armv7/sunxi/dram_sun8i.c index ebba53b..3d7964d 100644 --- a/arch/arm/cpu/armv7/sunxi/dram_sun8i.c +++ b/arch/arm/cpu/armv7/sunxi/dram_sun8i.c @@ -61,7 +61,7 @@ static void mctl_sys_init(void) (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
/* enable pll5, note the divide by 2 is deliberate! */ - clock_set_pll5(dram_para.clock * 1000000 / 2, 1, 2, + clock_set_pll5(dram_para.clock * 1000000 / 2, dram_para.tpr13 & 0x40000);
/* deassert ahb mctl reset */ diff --git a/arch/arm/include/asm/arch-sunxi/clock_sun6i.h b/arch/arm/include/asm/arch-sunxi/clock_sun6i.h index 0e57abe..653f63c 100644 --- a/arch/arm/include/asm/arch-sunxi/clock_sun6i.h +++ b/arch/arm/include/asm/arch-sunxi/clock_sun6i.h @@ -317,6 +317,6 @@ struct sunxi_ccm_reg { #define CCM_DE_CTRL_PLL10 (5 << 24) #define CCM_DE_CTRL_GATE (1 << 31)
-void clock_set_pll5(unsigned int clk, int k, int m, bool sigma_delta_enable); +void clock_set_pll5(unsigned int clk, bool sigma_delta_enable);
#endif /* _SUNXI_CLOCK_SUN6I_H */

On Sun, 2014-12-28 at 17:08 +0100, Hans de Goede wrote:
Let clock_set_pll5 pick the optimal m and k values itself based on the requested rate, rather then passing them in as magic constants.
Suggested-by: Siarhei Siamashka siarhei.siamashka@gmail.com Signed-off-by: Hans de Goede hdegoede@redhat.com
Acked-by: Ian Campbell ijc@hellion.org.uk
If it's not too disruptive given the original patch adding those params is still in #next you could fold it in, but if that causes rebasing hell I'#m fine with leaving it as an incremental fix.
Ian.

On Sun, 2014-12-28 at 17:08 +0100, Hans de Goede wrote:
In some extreme cases it may be necessary to wait 1.5 seconds or more for a hpd signal to show up (and be able to read edid info), but we do not want to penalize all headless boots with an extra second boot delay, so add a hpd_delay parameter which can be set through the video-mode env. variable.
While at it raise the default from 300ms to 500ms as 300 may very well be too low in many cases.
Signed-off-by: Hans de Goede hdegoede@redhat.com
Acked-by: Ian Campbell ijc@hellion.org.uk
participants (2)
-
Hans de Goede
-
Ian Campbell