mirror of https://gitee.com/openkylin/linux.git
drm/msm/dsi: Return more timings from PHY to host
The DSI host is required to configure more timings calculated in PHY. By introducing a shared structure, this change allows more timing information passed from PHY to host. Signed-off-by: Hai Li <hali@codeaurora.org> Signed-off-by: Archit Taneja <architt@codeaurora.org> Signed-off-by: Rob Clark <robdclark@gmail.com>
This commit is contained in:
parent
25c45d8970
commit
dceac34015
|
@ -27,6 +27,8 @@
|
||||||
#define DSI_1 1
|
#define DSI_1 1
|
||||||
#define DSI_MAX 2
|
#define DSI_MAX 2
|
||||||
|
|
||||||
|
struct msm_dsi_phy_shared_timings;
|
||||||
|
|
||||||
enum msm_dsi_phy_type {
|
enum msm_dsi_phy_type {
|
||||||
MSM_DSI_PHY_28NM_HPM,
|
MSM_DSI_PHY_28NM_HPM,
|
||||||
MSM_DSI_PHY_28NM_LP,
|
MSM_DSI_PHY_28NM_LP,
|
||||||
|
@ -86,7 +88,7 @@ struct drm_connector *msm_dsi_manager_connector_init(u8 id);
|
||||||
struct drm_connector *msm_dsi_manager_ext_bridge_init(u8 id);
|
struct drm_connector *msm_dsi_manager_ext_bridge_init(u8 id);
|
||||||
int msm_dsi_manager_phy_enable(int id,
|
int msm_dsi_manager_phy_enable(int id,
|
||||||
const unsigned long bit_rate, const unsigned long esc_rate,
|
const unsigned long bit_rate, const unsigned long esc_rate,
|
||||||
u32 *clk_pre, u32 *clk_post);
|
struct msm_dsi_phy_shared_timings *shared_timing);
|
||||||
void msm_dsi_manager_phy_disable(int id);
|
void msm_dsi_manager_phy_disable(int id);
|
||||||
int msm_dsi_manager_cmd_xfer(int id, const struct mipi_dsi_msg *msg);
|
int msm_dsi_manager_cmd_xfer(int id, const struct mipi_dsi_msg *msg);
|
||||||
bool msm_dsi_manager_cmd_xfer_trigger(int id, u32 dma_base, u32 len);
|
bool msm_dsi_manager_cmd_xfer_trigger(int id, u32 dma_base, u32 len);
|
||||||
|
@ -165,13 +167,18 @@ int msm_dsi_host_init(struct msm_dsi *msm_dsi);
|
||||||
|
|
||||||
/* dsi phy */
|
/* dsi phy */
|
||||||
struct msm_dsi_phy;
|
struct msm_dsi_phy;
|
||||||
|
struct msm_dsi_phy_shared_timings {
|
||||||
|
u32 clk_post;
|
||||||
|
u32 clk_pre;
|
||||||
|
bool clk_pre_inc_by_2;
|
||||||
|
};
|
||||||
void msm_dsi_phy_driver_register(void);
|
void msm_dsi_phy_driver_register(void);
|
||||||
void msm_dsi_phy_driver_unregister(void);
|
void msm_dsi_phy_driver_unregister(void);
|
||||||
int msm_dsi_phy_enable(struct msm_dsi_phy *phy, int src_pll_id,
|
int msm_dsi_phy_enable(struct msm_dsi_phy *phy, int src_pll_id,
|
||||||
const unsigned long bit_rate, const unsigned long esc_rate);
|
const unsigned long bit_rate, const unsigned long esc_rate);
|
||||||
void msm_dsi_phy_disable(struct msm_dsi_phy *phy);
|
void msm_dsi_phy_disable(struct msm_dsi_phy *phy);
|
||||||
void msm_dsi_phy_get_clk_pre_post(struct msm_dsi_phy *phy,
|
void msm_dsi_phy_get_shared_timings(struct msm_dsi_phy *phy,
|
||||||
u32 *clk_pre, u32 *clk_post);
|
struct msm_dsi_phy_shared_timings *shared_timing);
|
||||||
struct msm_dsi_pll *msm_dsi_phy_get_pll(struct msm_dsi_phy *phy);
|
struct msm_dsi_pll *msm_dsi_phy_get_pll(struct msm_dsi_phy *phy);
|
||||||
|
|
||||||
#endif /* __DSI_CONNECTOR_H__ */
|
#endif /* __DSI_CONNECTOR_H__ */
|
||||||
|
|
|
@ -756,7 +756,7 @@ static inline enum dsi_cmd_dst_format dsi_get_cmd_fmt(
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dsi_ctrl_config(struct msm_dsi_host *msm_host, bool enable,
|
static void dsi_ctrl_config(struct msm_dsi_host *msm_host, bool enable,
|
||||||
u32 clk_pre, u32 clk_post)
|
struct msm_dsi_phy_shared_timings *phy_shared_timings)
|
||||||
{
|
{
|
||||||
u32 flags = msm_host->mode_flags;
|
u32 flags = msm_host->mode_flags;
|
||||||
enum mipi_dsi_pixel_format mipi_fmt = msm_host->format;
|
enum mipi_dsi_pixel_format mipi_fmt = msm_host->format;
|
||||||
|
@ -819,10 +819,16 @@ static void dsi_ctrl_config(struct msm_dsi_host *msm_host, bool enable,
|
||||||
data |= DSI_TRIG_CTRL_BLOCK_DMA_WITHIN_FRAME;
|
data |= DSI_TRIG_CTRL_BLOCK_DMA_WITHIN_FRAME;
|
||||||
dsi_write(msm_host, REG_DSI_TRIG_CTRL, data);
|
dsi_write(msm_host, REG_DSI_TRIG_CTRL, data);
|
||||||
|
|
||||||
data = DSI_CLKOUT_TIMING_CTRL_T_CLK_POST(clk_post) |
|
data = DSI_CLKOUT_TIMING_CTRL_T_CLK_POST(phy_shared_timings->clk_post) |
|
||||||
DSI_CLKOUT_TIMING_CTRL_T_CLK_PRE(clk_pre);
|
DSI_CLKOUT_TIMING_CTRL_T_CLK_PRE(phy_shared_timings->clk_pre);
|
||||||
dsi_write(msm_host, REG_DSI_CLKOUT_TIMING_CTRL, data);
|
dsi_write(msm_host, REG_DSI_CLKOUT_TIMING_CTRL, data);
|
||||||
|
|
||||||
|
if ((cfg_hnd->major == MSM_DSI_VER_MAJOR_6G) &&
|
||||||
|
(cfg_hnd->minor > MSM_DSI_6G_VER_MINOR_V1_0) &&
|
||||||
|
phy_shared_timings->clk_pre_inc_by_2)
|
||||||
|
dsi_write(msm_host, REG_DSI_T_CLK_PRE_EXTEND,
|
||||||
|
DSI_T_CLK_PRE_EXTEND_INC_BY_2_BYTECLK);
|
||||||
|
|
||||||
data = 0;
|
data = 0;
|
||||||
if (!(flags & MIPI_DSI_MODE_EOT_PACKET))
|
if (!(flags & MIPI_DSI_MODE_EOT_PACKET))
|
||||||
data |= DSI_EOT_PACKET_CTRL_TX_EOT_APPEND;
|
data |= DSI_EOT_PACKET_CTRL_TX_EOT_APPEND;
|
||||||
|
@ -2170,7 +2176,7 @@ static void msm_dsi_sfpb_config(struct msm_dsi_host *msm_host, bool enable)
|
||||||
int msm_dsi_host_power_on(struct mipi_dsi_host *host)
|
int msm_dsi_host_power_on(struct mipi_dsi_host *host)
|
||||||
{
|
{
|
||||||
struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
|
struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
|
||||||
u32 clk_pre = 0, clk_post = 0;
|
struct msm_dsi_phy_shared_timings phy_shared_timings;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
mutex_lock(&msm_host->dev_mutex);
|
mutex_lock(&msm_host->dev_mutex);
|
||||||
|
@ -2204,7 +2210,7 @@ int msm_dsi_host_power_on(struct mipi_dsi_host *host)
|
||||||
ret = msm_dsi_manager_phy_enable(msm_host->id,
|
ret = msm_dsi_manager_phy_enable(msm_host->id,
|
||||||
msm_host->byte_clk_rate * 8,
|
msm_host->byte_clk_rate * 8,
|
||||||
msm_host->esc_clk_rate,
|
msm_host->esc_clk_rate,
|
||||||
&clk_pre, &clk_post);
|
&phy_shared_timings);
|
||||||
dsi_bus_clk_disable(msm_host);
|
dsi_bus_clk_disable(msm_host);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
pr_err("%s: failed to enable phy, %d\n", __func__, ret);
|
pr_err("%s: failed to enable phy, %d\n", __func__, ret);
|
||||||
|
@ -2226,7 +2232,7 @@ int msm_dsi_host_power_on(struct mipi_dsi_host *host)
|
||||||
|
|
||||||
dsi_timing_setup(msm_host);
|
dsi_timing_setup(msm_host);
|
||||||
dsi_sw_reset(msm_host);
|
dsi_sw_reset(msm_host);
|
||||||
dsi_ctrl_config(msm_host, true, clk_pre, clk_post);
|
dsi_ctrl_config(msm_host, true, &phy_shared_timings);
|
||||||
|
|
||||||
if (msm_host->disp_en_gpio)
|
if (msm_host->disp_en_gpio)
|
||||||
gpiod_set_value(msm_host->disp_en_gpio, 1);
|
gpiod_set_value(msm_host->disp_en_gpio, 1);
|
||||||
|
@ -2255,7 +2261,7 @@ int msm_dsi_host_power_off(struct mipi_dsi_host *host)
|
||||||
goto unlock_ret;
|
goto unlock_ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
dsi_ctrl_config(msm_host, false, 0, 0);
|
dsi_ctrl_config(msm_host, false, NULL);
|
||||||
|
|
||||||
if (msm_host->disp_en_gpio)
|
if (msm_host->disp_en_gpio)
|
||||||
gpiod_set_value(msm_host->disp_en_gpio, 0);
|
gpiod_set_value(msm_host->disp_en_gpio, 0);
|
||||||
|
|
|
@ -660,7 +660,7 @@ void msm_dsi_manager_bridge_destroy(struct drm_bridge *bridge)
|
||||||
|
|
||||||
int msm_dsi_manager_phy_enable(int id,
|
int msm_dsi_manager_phy_enable(int id,
|
||||||
const unsigned long bit_rate, const unsigned long esc_rate,
|
const unsigned long bit_rate, const unsigned long esc_rate,
|
||||||
u32 *clk_pre, u32 *clk_post)
|
struct msm_dsi_phy_shared_timings *shared_timings)
|
||||||
{
|
{
|
||||||
struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
|
struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
|
||||||
struct msm_dsi_phy *phy = msm_dsi->phy;
|
struct msm_dsi_phy *phy = msm_dsi->phy;
|
||||||
|
@ -688,7 +688,7 @@ int msm_dsi_manager_phy_enable(int id,
|
||||||
}
|
}
|
||||||
|
|
||||||
msm_dsi->phy_enabled = true;
|
msm_dsi->phy_enabled = true;
|
||||||
msm_dsi_phy_get_clk_pre_post(phy, clk_pre, clk_post);
|
msm_dsi_phy_get_shared_timings(phy, shared_timings);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -115,8 +115,8 @@ int msm_dsi_dphy_timing_calc(struct msm_dsi_dphy_timing *timing,
|
||||||
temp = ((timing->hs_exit >> 1) + 1) * 2 * ui;
|
temp = ((timing->hs_exit >> 1) + 1) * 2 * ui;
|
||||||
temp = 60 * coeff + 52 * ui - 24 * ui - temp;
|
temp = 60 * coeff + 52 * ui - 24 * ui - temp;
|
||||||
tmin = S_DIV_ROUND_UP(temp, 8 * ui) - 1;
|
tmin = S_DIV_ROUND_UP(temp, 8 * ui) - 1;
|
||||||
timing->clk_post = linear_inter(tmax, tmin, pcnt2, 0, false);
|
timing->shared_timings.clk_post = linear_inter(tmax, tmin, pcnt2, 0,
|
||||||
|
false);
|
||||||
tmax = 63;
|
tmax = 63;
|
||||||
temp = ((timing->clk_prepare >> 1) + 1) * 2 * ui;
|
temp = ((timing->clk_prepare >> 1) + 1) * 2 * ui;
|
||||||
temp += ((timing->clk_zero >> 1) + 1) * 2 * ui;
|
temp += ((timing->clk_zero >> 1) + 1) * 2 * ui;
|
||||||
|
@ -124,17 +124,21 @@ int msm_dsi_dphy_timing_calc(struct msm_dsi_dphy_timing *timing,
|
||||||
tmin = S_DIV_ROUND_UP(temp, 8 * ui) - 1;
|
tmin = S_DIV_ROUND_UP(temp, 8 * ui) - 1;
|
||||||
if (tmin > tmax) {
|
if (tmin > tmax) {
|
||||||
temp = linear_inter(2 * tmax, tmin, pcnt2, 0, false);
|
temp = linear_inter(2 * tmax, tmin, pcnt2, 0, false);
|
||||||
timing->clk_pre = temp >> 1;
|
timing->shared_timings.clk_pre = temp >> 1;
|
||||||
|
timing->shared_timings.clk_pre_inc_by_2 = true;
|
||||||
} else {
|
} else {
|
||||||
timing->clk_pre = linear_inter(tmax, tmin, pcnt2, 0, false);
|
timing->shared_timings.clk_pre =
|
||||||
|
linear_inter(tmax, tmin, pcnt2, 0, false);
|
||||||
|
timing->shared_timings.clk_pre_inc_by_2 = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
timing->ta_go = 3;
|
timing->ta_go = 3;
|
||||||
timing->ta_sure = 0;
|
timing->ta_sure = 0;
|
||||||
timing->ta_get = 4;
|
timing->ta_get = 4;
|
||||||
|
|
||||||
DBG("PHY timings: %d, %d, %d, %d, %d, %d, %d, %d, %d, %d",
|
DBG("PHY timings: %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d",
|
||||||
timing->clk_pre, timing->clk_post, timing->clk_zero,
|
timing->shared_timings.clk_pre, timing->shared_timings.clk_post,
|
||||||
|
timing->shared_timings.clk_pre_inc_by_2, timing->clk_zero,
|
||||||
timing->clk_trail, timing->clk_prepare, timing->hs_exit,
|
timing->clk_trail, timing->clk_prepare, timing->hs_exit,
|
||||||
timing->hs_zero, timing->hs_prepare, timing->hs_trail,
|
timing->hs_zero, timing->hs_prepare, timing->hs_trail,
|
||||||
timing->hs_rqst);
|
timing->hs_rqst);
|
||||||
|
@ -460,16 +464,11 @@ void msm_dsi_phy_disable(struct msm_dsi_phy *phy)
|
||||||
dsi_phy_regulator_disable(phy);
|
dsi_phy_regulator_disable(phy);
|
||||||
}
|
}
|
||||||
|
|
||||||
void msm_dsi_phy_get_clk_pre_post(struct msm_dsi_phy *phy,
|
void msm_dsi_phy_get_shared_timings(struct msm_dsi_phy *phy,
|
||||||
u32 *clk_pre, u32 *clk_post)
|
struct msm_dsi_phy_shared_timings *shared_timings)
|
||||||
{
|
{
|
||||||
if (!phy)
|
memcpy(shared_timings, &phy->timing.shared_timings,
|
||||||
return;
|
sizeof(*shared_timings));
|
||||||
|
|
||||||
if (clk_pre)
|
|
||||||
*clk_pre = phy->timing.clk_pre;
|
|
||||||
if (clk_post)
|
|
||||||
*clk_post = phy->timing.clk_post;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct msm_dsi_pll *msm_dsi_phy_get_pll(struct msm_dsi_phy *phy)
|
struct msm_dsi_pll *msm_dsi_phy_get_pll(struct msm_dsi_phy *phy)
|
||||||
|
|
|
@ -62,6 +62,8 @@ struct msm_dsi_dphy_timing {
|
||||||
u32 ta_go;
|
u32 ta_go;
|
||||||
u32 ta_sure;
|
u32 ta_sure;
|
||||||
u32 ta_get;
|
u32 ta_get;
|
||||||
|
|
||||||
|
struct msm_dsi_phy_shared_timings shared_timings;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct msm_dsi_phy {
|
struct msm_dsi_phy {
|
||||||
|
|
Loading…
Reference in New Issue