mirror of
https://git.codelinaro.org/clo/qsdk/oss/boot/u-boot-2016.git
synced 2025-12-10 07:44:53 +01:00
video: ssd2828: Allow using 'pclk' as the PLL clock source
Instead of using the internal 'tx_clk' clock source, it is also
possible to use the pixel clock signal from the parallel LCD
interface ('pclk') as the reference clock for PLL.
The 'tx_clk' clock speed may be different on different boards/devices
(the allowed range is 8MHz - 30MHz). Which is not very convenient,
especially considering the need to know the exact 'tx_clk' clock
speed. This clock speed may be difficult to identify without having
device schematics and/or accurate documentation/sources every time.
Using 'pclk' is free from all these problems.
Signed-off-by: Siarhei Siamashka <siarhei.siamashka@gmail.com>
Acked-by: Anatolij Gustschin <agust@denx.de>
Acked-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
This commit is contained in:
parent
aaa6ac5eab
commit
dddccd6913
3 changed files with 28 additions and 7 deletions
|
|
@ -19,12 +19,14 @@ config VIDEO_LCD_SSD2828
|
||||||
config VIDEO_LCD_SSD2828_TX_CLK
|
config VIDEO_LCD_SSD2828_TX_CLK
|
||||||
int "SSD2828 TX_CLK frequency (in MHz)"
|
int "SSD2828 TX_CLK frequency (in MHz)"
|
||||||
depends on VIDEO_LCD_SSD2828
|
depends on VIDEO_LCD_SSD2828
|
||||||
|
default 0
|
||||||
---help---
|
---help---
|
||||||
The frequency of the crystal, which is clocking SSD2828. It may be
|
The frequency of the crystal, which is clocking SSD2828. It may be
|
||||||
anything in the 8MHz-30MHz range and the exact value should be
|
anything in the 8MHz-30MHz range and the exact value should be
|
||||||
retrieved from the board schematics. Or in the case of Allwinner
|
retrieved from the board schematics. Or in the case of Allwinner
|
||||||
hardware, it can be usually found as 'lcd_xtal_freq' variable in
|
hardware, it can be usually found as 'lcd_xtal_freq' variable in
|
||||||
FEX files.
|
FEX files. It can be also set to 0 for selecting PCLK from the
|
||||||
|
parallel LCD interface instead of TX_CLK as the PLL clock source.
|
||||||
|
|
||||||
config VIDEO_LCD_SSD2828_RESET
|
config VIDEO_LCD_SSD2828_RESET
|
||||||
string "RESET pin of SSD2828"
|
string "RESET pin of SSD2828"
|
||||||
|
|
|
||||||
|
|
@ -340,7 +340,7 @@ static int ssd2828_configure_video_interface(const struct ssd2828_config *cfg,
|
||||||
int ssd2828_init(const struct ssd2828_config *cfg,
|
int ssd2828_init(const struct ssd2828_config *cfg,
|
||||||
const struct ctfb_res_modes *mode)
|
const struct ctfb_res_modes *mode)
|
||||||
{
|
{
|
||||||
u32 lp_div, pll_freq_kbps, pll_config;
|
u32 lp_div, pll_freq_kbps, reference_freq_khz, pll_config;
|
||||||
/* The LP clock speed is limited by 10MHz */
|
/* The LP clock speed is limited by 10MHz */
|
||||||
const u32 mipi_dsi_low_power_clk_khz = 10000;
|
const u32 mipi_dsi_low_power_clk_khz = 10000;
|
||||||
/*
|
/*
|
||||||
|
|
@ -373,6 +373,20 @@ int ssd2828_init(const struct ssd2828_config *cfg,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Pick the reference clock for PLL. If we know the exact 'tx_clk'
|
||||||
|
* clock speed, then everything is good. If not, then we can fallback
|
||||||
|
* to 'pclk' (pixel clock from the parallel LCD interface). In the
|
||||||
|
* case of using this fallback, it is necessary to have parallel LCD
|
||||||
|
* already initialized and running at this point.
|
||||||
|
*/
|
||||||
|
reference_freq_khz = cfg->ssd2828_tx_clk_khz;
|
||||||
|
if (reference_freq_khz == 0) {
|
||||||
|
reference_freq_khz = mode->pixclock_khz;
|
||||||
|
/* Use 'pclk' as the reference clock for PLL */
|
||||||
|
cfgr_reg |= SSD2828_CFGR_CSS;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Setup the parallel LCD timings in the appropriate registers.
|
* Setup the parallel LCD timings in the appropriate registers.
|
||||||
*/
|
*/
|
||||||
|
|
@ -390,10 +404,10 @@ int ssd2828_init(const struct ssd2828_config *cfg,
|
||||||
/* PLL Configuration Register */
|
/* PLL Configuration Register */
|
||||||
pll_config = construct_pll_config(
|
pll_config = construct_pll_config(
|
||||||
cfg->mipi_dsi_bitrate_per_data_lane_mbps * 1000,
|
cfg->mipi_dsi_bitrate_per_data_lane_mbps * 1000,
|
||||||
cfg->ssd2828_tx_clk_khz);
|
reference_freq_khz);
|
||||||
write_hw_register(cfg, SSD2828_PLCR, pll_config);
|
write_hw_register(cfg, SSD2828_PLCR, pll_config);
|
||||||
|
|
||||||
pll_freq_kbps = decode_pll_config(pll_config, cfg->ssd2828_tx_clk_khz);
|
pll_freq_kbps = decode_pll_config(pll_config, reference_freq_khz);
|
||||||
lp_div = DIV_ROUND_UP(pll_freq_kbps, mipi_dsi_low_power_clk_khz * 8);
|
lp_div = DIV_ROUND_UP(pll_freq_kbps, mipi_dsi_low_power_clk_khz * 8);
|
||||||
|
|
||||||
/* VC Control Register */
|
/* VC Control Register */
|
||||||
|
|
|
||||||
|
|
@ -47,8 +47,12 @@ struct ssd2828_config {
|
||||||
* to TX_CLK_XIO/TX_CLK_XIN pins), which is necessary at least for
|
* to TX_CLK_XIO/TX_CLK_XIN pins), which is necessary at least for
|
||||||
* clocking SPI after reset. The exact clock speed is not strictly,
|
* clocking SPI after reset. The exact clock speed is not strictly,
|
||||||
* defined, but the datasheet says that it must be somewhere in the
|
* defined, but the datasheet says that it must be somewhere in the
|
||||||
* 8MHz - 30MHz range (see "TX_CLK Timing" section). It is used as
|
* 8MHz - 30MHz range (see "TX_CLK Timing" section). It can be also
|
||||||
* a reference clock for PLL and must be set correctly.
|
* used as a reference clock for PLL. If the exact clock frequency
|
||||||
|
* is known, then it can be specified here. If it is unknown, or the
|
||||||
|
* information is not trustworthy, then it can be set to 0.
|
||||||
|
*
|
||||||
|
* If unsure, set to 0.
|
||||||
*/
|
*/
|
||||||
int ssd2828_tx_clk_khz;
|
int ssd2828_tx_clk_khz;
|
||||||
|
|
||||||
|
|
@ -115,7 +119,8 @@ struct ssd2828_config {
|
||||||
* The right place to insert this function call is after the parallel LCD
|
* The right place to insert this function call is after the parallel LCD
|
||||||
* interface is initialized and before turning on the backlight. This is
|
* interface is initialized and before turning on the backlight. This is
|
||||||
* advised in the "Example for system sleep in and out" section of the
|
* advised in the "Example for system sleep in and out" section of the
|
||||||
* SSD2828 datasheet.
|
* SSD2828 datasheet. And also SS2828 may use 'pclk' as the clock source
|
||||||
|
* for PLL, which means that the input signal must be already there.
|
||||||
*/
|
*/
|
||||||
int ssd2828_init(const struct ssd2828_config *cfg,
|
int ssd2828_init(const struct ssd2828_config *cfg,
|
||||||
const struct ctfb_res_modes *mode);
|
const struct ctfb_res_modes *mode);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue