Commit 89691775 authored by Adam Ford's avatar Adam Ford Committed by Neil Armstrong

drm: bridge: samsung-dsim: Dynamically configure DPHY timing

The DPHY timings are currently hard coded. Since the input
clock can be variable, the phy timings need to be variable
too.  To facilitate this, we need to cache the hs_clock
based on what is generated from the PLL.

The phy_mipi_dphy_get_default_config_for_hsclk function
configures the DPHY timings in pico-seconds, and a small macro
converts those timings into clock cycles based on the hs_clk.
Signed-off-by: default avatarAdam Ford <aford173@gmail.com>
Signed-off-by: default avatarLucas Stach <l.stach@pengutronix.de>
Tested-by: default avatarChen-Yu Tsai <wenst@chromium.org>
Tested-by: default avatarFrieder Schrempf <frieder.schrempf@kontron.de>
Reviewed-by: default avatarFrieder Schrempf <frieder.schrempf@kontron.de>
Tested-by: default avatarMichael Walle <michael@walle.cc>
Tested-by: default avatarMarek Szyprowski <m.szyprowski@samsung.com>
Reviewed-by: default avatarJagan Teki <jagan@amarulasolutions.com>
Tested-by: Jagan Teki <jagan@amarulasolutions.com> # imx8mm-icore
Signed-off-by: default avatarNeil Armstrong <neil.armstrong@linaro.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20230526030559.326566-6-aford173@gmail.com
parent 171b3b1e
......@@ -220,6 +220,8 @@
#define OLD_SCLK_MIPI_CLK_NAME "pll_clk"
#define PS_TO_CYCLE(ps, hz) DIV64_U64_ROUND_CLOSEST(((ps) * (hz)), 1000000000000ULL)
static const char *const clk_names[5] = {
"bus_clk",
"sclk_mipi",
......@@ -658,6 +660,8 @@ static unsigned long samsung_dsim_set_pll(struct samsung_dsim *dsi,
reg = samsung_dsim_read(dsi, DSIM_STATUS_REG);
} while ((reg & DSIM_PLL_STABLE) == 0);
dsi->hs_clock = fout;
return fout;
}
......@@ -705,13 +709,47 @@ static void samsung_dsim_set_phy_ctrl(struct samsung_dsim *dsi)
const struct samsung_dsim_driver_data *driver_data = dsi->driver_data;
const unsigned int *reg_values = driver_data->reg_values;
u32 reg;
struct phy_configure_opts_mipi_dphy cfg;
int clk_prepare, lpx, clk_zero, clk_post, clk_trail;
int hs_exit, hs_prepare, hs_zero, hs_trail;
unsigned long long byte_clock = dsi->hs_clock / 8;
if (driver_data->has_freqband)
return;
phy_mipi_dphy_get_default_config_for_hsclk(dsi->hs_clock,
dsi->lanes, &cfg);
/*
* TODO:
* The tech Applications Processor manuals for i.MX8M Mini, Nano,
* and Plus don't state what the definition of the PHYTIMING
* bits are beyond their address and bit position.
* After reviewing NXP's downstream code, it appears
* that the various PHYTIMING registers take the number
* of cycles and use various dividers on them. This
* calculation does not result in an exact match to the
* downstream code, but it is very close to the values
* generated by their lookup table, and it appears
* to sync at a variety of resolutions. If someone
* can get a more accurate mathematical equation needed
* for these registers, this should be updated.
*/
lpx = PS_TO_CYCLE(cfg.lpx, byte_clock);
hs_exit = PS_TO_CYCLE(cfg.hs_exit, byte_clock);
clk_prepare = PS_TO_CYCLE(cfg.clk_prepare, byte_clock);
clk_zero = PS_TO_CYCLE(cfg.clk_zero, byte_clock);
clk_post = PS_TO_CYCLE(cfg.clk_post, byte_clock);
clk_trail = PS_TO_CYCLE(cfg.clk_trail, byte_clock);
hs_prepare = PS_TO_CYCLE(cfg.hs_prepare, byte_clock);
hs_zero = PS_TO_CYCLE(cfg.hs_zero, byte_clock);
hs_trail = PS_TO_CYCLE(cfg.hs_trail, byte_clock);
/* B D-PHY: D-PHY Master & Slave Analog Block control */
reg = reg_values[PHYCTRL_ULPS_EXIT] | reg_values[PHYCTRL_VREG_LP] |
reg_values[PHYCTRL_SLEW_UP];
samsung_dsim_write(dsi, DSIM_PHYCTRL_REG, reg);
/*
......@@ -719,7 +757,9 @@ static void samsung_dsim_set_phy_ctrl(struct samsung_dsim *dsi)
* T HS-EXIT: Time that the transmitter drives LP-11 following a HS
* burst
*/
reg = reg_values[PHYTIMING_LPX] | reg_values[PHYTIMING_HS_EXIT];
reg = DSIM_PHYTIMING_LPX(lpx) | DSIM_PHYTIMING_HS_EXIT(hs_exit);
samsung_dsim_write(dsi, DSIM_PHYTIMING_REG, reg);
/*
......@@ -735,10 +775,11 @@ static void samsung_dsim_set_phy_ctrl(struct samsung_dsim *dsi)
* T CLK-TRAIL: Time that the transmitter drives the HS-0 state after
* the last payload clock bit of a HS transmission burst
*/
reg = reg_values[PHYTIMING_CLK_PREPARE] |
reg_values[PHYTIMING_CLK_ZERO] |
reg_values[PHYTIMING_CLK_POST] |
reg_values[PHYTIMING_CLK_TRAIL];
reg = DSIM_PHYTIMING1_CLK_PREPARE(clk_prepare) |
DSIM_PHYTIMING1_CLK_ZERO(clk_zero) |
DSIM_PHYTIMING1_CLK_POST(clk_post) |
DSIM_PHYTIMING1_CLK_TRAIL(clk_trail);
samsung_dsim_write(dsi, DSIM_PHYTIMING1_REG, reg);
......@@ -751,8 +792,11 @@ static void samsung_dsim_set_phy_ctrl(struct samsung_dsim *dsi)
* T HS-TRAIL: Time that the transmitter drives the flipped differential
* state after last payload data bit of a HS transmission burst
*/
reg = reg_values[PHYTIMING_HS_PREPARE] | reg_values[PHYTIMING_HS_ZERO] |
reg_values[PHYTIMING_HS_TRAIL];
reg = DSIM_PHYTIMING2_HS_PREPARE(hs_prepare) |
DSIM_PHYTIMING2_HS_ZERO(hs_zero) |
DSIM_PHYTIMING2_HS_TRAIL(hs_trail);
samsung_dsim_write(dsi, DSIM_PHYTIMING2_REG, reg);
}
......
......@@ -93,6 +93,7 @@ struct samsung_dsim {
u32 pll_clk_rate;
u32 burst_clk_rate;
u32 hs_clock;
u32 esc_clk_rate;
u32 lanes;
u32 mode_flags;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment