Skip to content

Commit

Permalink
drm/msm/dsi: support CPHY mode for 7nm pll/phy
Browse files Browse the repository at this point in the history
Add the required changes to support 7nm pll/phy in CPHY mode.

This adds a "qcom,dsi-phy-cphy-mode" property for the PHY node to enable
the CPHY mode.

Signed-off-by: Jonathan Marek <[email protected]>
Reviewed-by: Dmitry Baryshkov <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Dmitry Baryshkov <[email protected]>
Signed-off-by: Rob Clark <[email protected]>
  • Loading branch information
flto authored and robclark committed Aug 7, 2021
1 parent bb5b94f commit 5ac1783
Show file tree
Hide file tree
Showing 4 changed files with 184 additions and 47 deletions.
34 changes: 30 additions & 4 deletions drivers/gpu/drm/msm/dsi/dsi_host.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include "dsi_cfg.h"
#include "msm_kms.h"
#include "msm_gem.h"
#include "phy/dsi_phy.h"

#define DSI_RESET_TOGGLE_DELAY_MS 20

Expand Down Expand Up @@ -167,6 +168,9 @@ struct msm_dsi_host {
int dlane_swap;
int num_data_lanes;

/* from phy DT */
bool cphy_mode;

u32 dma_cmd_ctrl_restore;

bool registered;
Expand Down Expand Up @@ -510,6 +514,7 @@ int msm_dsi_runtime_resume(struct device *dev)

int dsi_link_clk_set_rate_6g(struct msm_dsi_host *msm_host)
{
u32 byte_intf_rate;
int ret;

DBG("Set clk rates: pclk=%d, byteclk=%d",
Expand All @@ -529,8 +534,13 @@ int dsi_link_clk_set_rate_6g(struct msm_dsi_host *msm_host)
}

if (msm_host->byte_intf_clk) {
ret = clk_set_rate(msm_host->byte_intf_clk,
msm_host->byte_clk_rate / 2);
/* For CPHY, byte_intf_clk is same as byte_clk */
if (msm_host->cphy_mode)
byte_intf_rate = msm_host->byte_clk_rate;
else
byte_intf_rate = msm_host->byte_clk_rate / 2;

ret = clk_set_rate(msm_host->byte_intf_clk, byte_intf_rate);
if (ret) {
pr_err("%s: Failed to set rate byte intf clk, %d\n",
__func__, ret);
Expand Down Expand Up @@ -710,7 +720,11 @@ static void dsi_calc_pclk(struct msm_dsi_host *msm_host, bool is_dual_dsi)
lanes = 1;
}

do_div(pclk_bpp, (8 * lanes));
/* CPHY "byte_clk" is in units of 16 bits */
if (msm_host->cphy_mode)
do_div(pclk_bpp, (16 * lanes));
else
do_div(pclk_bpp, (8 * lanes));

msm_host->pixel_clk_rate = pclk_rate;
msm_host->byte_clk_rate = pclk_bpp;
Expand Down Expand Up @@ -936,6 +950,9 @@ static void dsi_ctrl_config(struct msm_dsi_host *msm_host, bool enable,
data |= DSI_CTRL_ENABLE;

dsi_write(msm_host, REG_DSI_CTRL, data);

if (msm_host->cphy_mode)
dsi_write(msm_host, REG_DSI_CPHY_MODE_CTRL, BIT(0));
}

static void dsi_timing_setup(struct msm_dsi_host *msm_host, bool is_dual_dsi)
Expand Down Expand Up @@ -2226,6 +2243,8 @@ int msm_dsi_host_set_src_pll(struct mipi_dsi_host *host,
struct clk *byte_clk_provider, *pixel_clk_provider;
int ret;

msm_host->cphy_mode = src_phy->cphy_mode;

ret = msm_dsi_phy_get_clk_provider(src_phy,
&byte_clk_provider, &pixel_clk_provider);
if (ret) {
Expand Down Expand Up @@ -2297,7 +2316,14 @@ void msm_dsi_host_get_phy_clk_req(struct mipi_dsi_host *host,
return;
}

clk_req->bitclk_rate = msm_host->byte_clk_rate * 8;
/* CPHY transmits 16 bits over 7 clock cycles
* "byte_clk" is in units of 16-bits (see dsi_calc_pclk),
* so multiply by 7 to get the "bitclk rate"
*/
if (msm_host->cphy_mode)
clk_req->bitclk_rate = msm_host->byte_clk_rate * 7;
else
clk_req->bitclk_rate = msm_host->byte_clk_rate * 8;
clk_req->escclk_rate = msm_host->esc_clk_rate;
}

Expand Down
49 changes: 49 additions & 0 deletions drivers/gpu/drm/msm/dsi/phy/dsi_phy.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

#include <linux/clk-provider.h>
#include <linux/platform_device.h>
#include <dt-bindings/phy/phy.h>

#include "dsi_phy.h"

Expand Down Expand Up @@ -461,6 +462,51 @@ int msm_dsi_dphy_timing_calc_v4(struct msm_dsi_dphy_timing *timing,
return 0;
}

int msm_dsi_cphy_timing_calc_v4(struct msm_dsi_dphy_timing *timing,
struct msm_dsi_phy_clk_request *clk_req)
{
const unsigned long bit_rate = clk_req->bitclk_rate;
const unsigned long esc_rate = clk_req->escclk_rate;
s32 ui, ui_x7;
s32 tmax, tmin;
s32 coeff = 1000; /* Precision, should avoid overflow */
s32 temp;

if (!bit_rate || !esc_rate)
return -EINVAL;

ui = mult_frac(NSEC_PER_MSEC, coeff, bit_rate / 1000);
ui_x7 = ui * 7;

temp = S_DIV_ROUND_UP(38 * coeff, ui_x7);
tmin = max_t(s32, temp, 0);
temp = (95 * coeff) / ui_x7;
tmax = max_t(s32, temp, 0);
timing->clk_prepare = linear_inter(tmax, tmin, 50, 0, false);

tmin = DIV_ROUND_UP(50 * coeff, ui_x7);
tmax = 255;
timing->hs_rqst = linear_inter(tmax, tmin, 1, 0, false);

tmin = DIV_ROUND_UP(100 * coeff, ui_x7) - 1;
tmax = 255;
timing->hs_exit = linear_inter(tmax, tmin, 10, 0, false);

tmin = 1;
tmax = 32;
timing->shared_timings.clk_post = linear_inter(tmax, tmin, 80, 0, false);

tmin = min_t(s32, 64, S_DIV_ROUND_UP(262 * coeff, ui_x7) - 1);
tmax = 64;
timing->shared_timings.clk_pre = linear_inter(tmax, tmin, 20, 0, false);

DBG("%d, %d, %d, %d, %d",
timing->shared_timings.clk_pre, timing->shared_timings.clk_post,
timing->clk_prepare, timing->hs_exit, timing->hs_rqst);

return 0;
}

static int dsi_phy_regulator_init(struct msm_dsi_phy *phy)
{
struct regulator_bulk_data *s = phy->supplies;
Expand Down Expand Up @@ -626,6 +672,7 @@ static int dsi_phy_driver_probe(struct platform_device *pdev)
struct msm_dsi_phy *phy;
struct device *dev = &pdev->dev;
const struct of_device_id *match;
u32 phy_type;
int ret;

phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL);
Expand Down Expand Up @@ -657,6 +704,8 @@ static int dsi_phy_driver_probe(struct platform_device *pdev)

phy->regulator_ldo_mode = of_property_read_bool(dev->of_node,
"qcom,dsi-phy-regulator-ldo-mode");
if (!of_property_read_u32(dev->of_node, "phy-type", &phy_type))
phy->cphy_mode = (phy_type == PHY_TYPE_CPHY);

phy->base = msm_ioremap_size(pdev, "dsi_phy", "DSI_PHY", &phy->base_size);
if (IS_ERR(phy->base)) {
Expand Down
3 changes: 3 additions & 0 deletions drivers/gpu/drm/msm/dsi/phy/dsi_phy.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ struct msm_dsi_phy {

enum msm_dsi_phy_usecase usecase;
bool regulator_ldo_mode;
bool cphy_mode;

struct clk_hw *vco_hw;
bool pll_on;
Expand All @@ -119,5 +120,7 @@ int msm_dsi_dphy_timing_calc_v3(struct msm_dsi_dphy_timing *timing,
struct msm_dsi_phy_clk_request *clk_req);
int msm_dsi_dphy_timing_calc_v4(struct msm_dsi_dphy_timing *timing,
struct msm_dsi_phy_clk_request *clk_req);
int msm_dsi_cphy_timing_calc_v4(struct msm_dsi_dphy_timing *timing,
struct msm_dsi_phy_clk_request *clk_req);

#endif /* __DSI_PHY_H__ */
Loading

0 comments on commit 5ac1783

Please sign in to comment.