Merge "disp: msm: dsi: rework DSI PLL to be configured within PHY" into display-kernel.lnx.5.10
This commit is contained in:

committed by
Gerrit - the friendly Code Review server

commit
6c367a8fed
@@ -109,7 +109,6 @@ msm_drm-$(CONFIG_DRM_MSM_DSI) += dsi/dsi_phy.o \
|
||||
dsi/dsi_phy_timing_v4_0.o \
|
||||
dsi/dsi_pll.o \
|
||||
dsi/dsi_pll_5nm.o \
|
||||
dsi/dsi_pll_10nm.o \
|
||||
dsi/dsi_ctrl_hw_cmn.o \
|
||||
dsi/dsi_ctrl_hw_1_4.o \
|
||||
dsi/dsi_ctrl_hw_2_0.o \
|
||||
|
@@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2015-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2015-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/errno.h>
|
||||
@@ -343,3 +343,26 @@ int dsi_catalog_phy_setup(struct dsi_phy_hw *phy,
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int dsi_catalog_phy_pll_setup(struct dsi_phy_hw *phy, u32 pll_ver)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
if (pll_ver >= DSI_PLL_VERSION_UNKNOWN) {
|
||||
DSI_ERR("Unsupported version: %d\n", pll_ver);
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
switch (pll_ver) {
|
||||
case DSI_PLL_VERSION_5NM:
|
||||
phy->ops.configure = dsi_pll_5nm_configure;
|
||||
phy->ops.pll_toggle = dsi_pll_5nm_toggle;
|
||||
break;
|
||||
default:
|
||||
phy->ops.configure = NULL;
|
||||
phy->ops.pll_toggle = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2015-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2015-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _DSI_CATALOG_H_
|
||||
@@ -284,4 +284,10 @@ void dsi_ctrl_hw_22_configure_cmddma_window(struct dsi_ctrl_hw *ctrl,
|
||||
void dsi_ctrl_hw_22_reset_trigger_controls(struct dsi_ctrl_hw *ctrl,
|
||||
struct dsi_host_common_cfg *cfg);
|
||||
u32 dsi_ctrl_hw_22_log_line_count(struct dsi_ctrl_hw *ctrl, bool cmd_mode);
|
||||
|
||||
/* PLL specific functions */
|
||||
int dsi_catalog_phy_pll_setup(struct dsi_phy_hw *phy, u32 pll_ver);
|
||||
int dsi_pll_5nm_configure(void *pll, bool commit);
|
||||
int dsi_pll_5nm_toggle(void *pll, bool prepare);
|
||||
|
||||
#endif /* _DSI_CATALOG_H_ */
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _DSI_CLK_H_
|
||||
@@ -173,6 +173,25 @@ typedef int (*pre_clockon_cb)(void *priv,
|
||||
enum dsi_clk_state new_state);
|
||||
|
||||
|
||||
/**
|
||||
* typedef *phy_configure_cb() - Callback to configure PHY for PLL clocks
|
||||
* @priv: private data pointer.
|
||||
* @commit: boolean to specify if calculated PHY configuration needs to be
|
||||
* committed. Set to false in case of dynamic clock switch.
|
||||
*
|
||||
* @return: error code.
|
||||
*/
|
||||
typedef int (*phy_configure_cb)(void *priv, bool commit);
|
||||
|
||||
/**
|
||||
* typedef *pll_toggle_cb() - Callback to toggle PHY PLL
|
||||
* @priv: private data pointer.
|
||||
* @prepare: specifies if the PLL needs to be turned on or off.
|
||||
*
|
||||
* @return: error code.
|
||||
*/
|
||||
typedef int (*pll_toggle_cb)(void *priv, bool prepare);
|
||||
|
||||
/**
|
||||
* struct dsi_clk_info - clock information for DSI hardware.
|
||||
* @name: client name.
|
||||
@@ -185,6 +204,8 @@ typedef int (*pre_clockon_cb)(void *priv,
|
||||
* @post_clkoff_cb callback after clock is turned off
|
||||
* @post_clkon_cb callback after clock is turned on
|
||||
* @pre_clkon_cb callback before clock is turned on
|
||||
* @phy_config_cb callback to configure PHY PLL
|
||||
* @phy_pll_toggle_cb callback to toggle PHY PLL state
|
||||
* @priv_data pointer to private data
|
||||
* @master_ndx master DSI controller index
|
||||
* @dsi_ctrl_count number of DSI controllers
|
||||
@@ -199,6 +220,8 @@ struct dsi_clk_info {
|
||||
post_clockoff_cb post_clkoff_cb;
|
||||
post_clockon_cb post_clkon_cb;
|
||||
pre_clockon_cb pre_clkon_cb;
|
||||
phy_configure_cb phy_config_cb;
|
||||
pll_toggle_cb phy_pll_toggle_cb;
|
||||
void *priv_data;
|
||||
u32 master_ndx;
|
||||
u32 dsi_ctrl_count;
|
||||
|
@@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/of.h>
|
||||
@@ -33,6 +33,8 @@ struct dsi_clk_mngr {
|
||||
u32 core_clk_state;
|
||||
u32 link_clk_state;
|
||||
|
||||
phy_configure_cb phy_config_cb;
|
||||
pll_toggle_cb phy_pll_toggle_cb;
|
||||
pre_clockoff_cb pre_clkoff_cb;
|
||||
post_clockoff_cb post_clkoff_cb;
|
||||
post_clockon_cb post_clkon_cb;
|
||||
@@ -498,10 +500,6 @@ error:
|
||||
*/
|
||||
static int dsi_link_hs_clk_stop(struct dsi_link_hs_clk_info *link_hs_clks)
|
||||
{
|
||||
struct dsi_link_clks *l_clks;
|
||||
|
||||
l_clks = container_of(link_hs_clks, struct dsi_link_clks, hs_clks);
|
||||
|
||||
dsi_link_hs_clk_disable(link_hs_clks);
|
||||
dsi_link_hs_clk_unprepare(link_hs_clks);
|
||||
|
||||
@@ -616,6 +614,9 @@ static int dsi_display_link_clk_enable(struct dsi_link_clks *clks,
|
||||
int rc = 0;
|
||||
int i;
|
||||
struct dsi_link_clks *clk, *m_clks;
|
||||
struct dsi_clk_mngr *mngr;
|
||||
|
||||
mngr = container_of(clks, struct dsi_clk_mngr, link_clks[master_ndx]);
|
||||
|
||||
/*
|
||||
* In case of split DSI usecases, the clock for master controller should
|
||||
@@ -635,6 +636,10 @@ static int dsi_display_link_clk_enable(struct dsi_link_clks *clks,
|
||||
}
|
||||
|
||||
if (l_type & DSI_LINK_HS_CLK) {
|
||||
if (!mngr->is_cont_splash_enabled) {
|
||||
mngr->phy_config_cb(mngr->priv_data, true);
|
||||
mngr->phy_pll_toggle_cb(mngr->priv_data, true);
|
||||
}
|
||||
rc = dsi_link_hs_clk_start(&m_clks->hs_clks,
|
||||
DSI_LINK_CLK_START, master_ndx);
|
||||
if (rc) {
|
||||
@@ -724,6 +729,9 @@ static int dsi_display_link_clk_disable(struct dsi_link_clks *clks,
|
||||
int rc = 0;
|
||||
int i;
|
||||
struct dsi_link_clks *clk, *m_clks;
|
||||
struct dsi_clk_mngr *mngr;
|
||||
|
||||
mngr = container_of(clks, struct dsi_clk_mngr, link_clks[master_ndx]);
|
||||
|
||||
/*
|
||||
* In case of split DSI usecases, clock for slave DSI controllers should
|
||||
@@ -767,6 +775,8 @@ static int dsi_display_link_clk_disable(struct dsi_link_clks *clks,
|
||||
if (rc)
|
||||
DSI_ERR("failed to turn off master hs link clocks, rc=%d\n",
|
||||
rc);
|
||||
if (!mngr->is_cont_splash_enabled)
|
||||
mngr->phy_pll_toggle_cb(mngr->priv_data, false);
|
||||
}
|
||||
|
||||
return rc;
|
||||
@@ -1439,6 +1449,8 @@ void *dsi_display_clk_mngr_register(struct dsi_clk_info *info)
|
||||
mngr->post_clkon_cb = info->post_clkon_cb;
|
||||
mngr->pre_clkoff_cb = info->pre_clkoff_cb;
|
||||
mngr->post_clkoff_cb = info->post_clkoff_cb;
|
||||
mngr->phy_config_cb = info->phy_config_cb;
|
||||
mngr->phy_pll_toggle_cb = info->phy_pll_toggle_cb;
|
||||
mngr->priv_data = info->priv_data;
|
||||
memcpy(mngr->name, info->name, MAX_STRING_LEN);
|
||||
|
||||
|
@@ -742,6 +742,23 @@ static inline int dsi_pixel_format_to_bpp(enum dsi_pixel_format fmt)
|
||||
return 24;
|
||||
}
|
||||
|
||||
/* return number of DSI data lanes */
|
||||
static inline int dsi_get_num_of_data_lanes(enum dsi_data_lanes dlanes)
|
||||
{
|
||||
int num_of_lanes = 0;
|
||||
|
||||
if (dlanes & DSI_DATA_LANE_0)
|
||||
num_of_lanes++;
|
||||
if (dlanes & DSI_DATA_LANE_1)
|
||||
num_of_lanes++;
|
||||
if (dlanes & DSI_DATA_LANE_2)
|
||||
num_of_lanes++;
|
||||
if (dlanes & DSI_DATA_LANE_3)
|
||||
num_of_lanes++;
|
||||
|
||||
return num_of_lanes;
|
||||
}
|
||||
|
||||
static inline u64 dsi_h_active_dce(struct dsi_mode_info *mode)
|
||||
{
|
||||
u64 h_active = 0;
|
||||
|
@@ -2608,26 +2608,68 @@ error:
|
||||
return rc;
|
||||
}
|
||||
|
||||
int dsi_display_phy_pll_toggle(void *priv, bool prepare)
|
||||
{
|
||||
int rc = 0;
|
||||
struct dsi_display *display = priv;
|
||||
struct dsi_display_ctrl *m_ctrl;
|
||||
|
||||
if (!display) {
|
||||
DSI_ERR("invalid arguments\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
m_ctrl = &display->ctrl[display->clk_master_idx];
|
||||
if (!m_ctrl->phy) {
|
||||
DSI_ERR("[%s] PHY not found\n", display->name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rc = dsi_phy_pll_toggle(m_ctrl->phy, prepare);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int dsi_display_phy_configure(void *priv, bool commit)
|
||||
{
|
||||
int rc = 0;
|
||||
struct dsi_display *display = priv;
|
||||
struct dsi_display_ctrl *m_ctrl;
|
||||
struct dsi_pll_resource *pll_res;
|
||||
struct dsi_ctrl *ctrl;
|
||||
|
||||
if (!display) {
|
||||
DSI_ERR("invalid arguments\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
m_ctrl = &display->ctrl[display->clk_master_idx];
|
||||
if ((!m_ctrl->phy) || (!m_ctrl->ctrl)) {
|
||||
DSI_ERR("[%s] PHY not found\n", display->name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
pll_res = m_ctrl->phy->pll;
|
||||
if (!pll_res) {
|
||||
DSI_ERR("[%s] PLL res not found\n", display->name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ctrl = m_ctrl->ctrl;
|
||||
pll_res->byteclk_rate = ctrl->clk_freq.byte_clk_rate;
|
||||
pll_res->pclk_rate = ctrl->clk_freq.pix_clk_rate;
|
||||
|
||||
rc = dsi_phy_configure(m_ctrl->phy, commit);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int dsi_display_set_clk_src(struct dsi_display *display)
|
||||
{
|
||||
int rc = 0;
|
||||
int i;
|
||||
struct dsi_display_ctrl *m_ctrl, *ctrl;
|
||||
|
||||
/*
|
||||
* For CPHY mode, the parent of mux_clks need to be set
|
||||
* to Cphy_clks to have correct dividers for byte and
|
||||
* pixel clocks.
|
||||
*/
|
||||
if (display->panel->host_config.phy_type == DSI_PHY_TYPE_CPHY) {
|
||||
rc = dsi_clk_update_parent(&display->clock_info.cphy_clks,
|
||||
&display->clock_info.mux_clks);
|
||||
if (rc) {
|
||||
DSI_ERR("failed update mux parent to shadow\n");
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* In case of split DSI usecases, the clock for master controller should
|
||||
* be enabled before the other controller. Master controller in the
|
||||
@@ -2636,7 +2678,7 @@ static int dsi_display_set_clk_src(struct dsi_display *display)
|
||||
m_ctrl = &display->ctrl[display->clk_master_idx];
|
||||
|
||||
rc = dsi_ctrl_set_clock_source(m_ctrl->ctrl,
|
||||
&display->clock_info.mux_clks);
|
||||
&display->clock_info.pll_clks);
|
||||
if (rc) {
|
||||
DSI_ERR("[%s] failed to set source clocks for master, rc=%d\n",
|
||||
display->name, rc);
|
||||
@@ -2650,7 +2692,7 @@ static int dsi_display_set_clk_src(struct dsi_display *display)
|
||||
continue;
|
||||
|
||||
rc = dsi_ctrl_set_clock_source(ctrl->ctrl,
|
||||
&display->clock_info.mux_clks);
|
||||
&display->clock_info.pll_clks);
|
||||
if (rc) {
|
||||
DSI_ERR("[%s] failed to set source clocks, rc=%d\n",
|
||||
display->name, rc);
|
||||
@@ -3320,46 +3362,6 @@ static int dsi_display_mipi_host_deinit(struct dsi_display *display)
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int dsi_display_clocks_deinit(struct dsi_display *display)
|
||||
{
|
||||
int rc = 0;
|
||||
struct dsi_clk_link_set *src = &display->clock_info.src_clks;
|
||||
struct dsi_clk_link_set *mux = &display->clock_info.mux_clks;
|
||||
struct dsi_clk_link_set *shadow = &display->clock_info.shadow_clks;
|
||||
|
||||
if (src->byte_clk) {
|
||||
devm_clk_put(&display->pdev->dev, src->byte_clk);
|
||||
src->byte_clk = NULL;
|
||||
}
|
||||
|
||||
if (src->pixel_clk) {
|
||||
devm_clk_put(&display->pdev->dev, src->pixel_clk);
|
||||
src->pixel_clk = NULL;
|
||||
}
|
||||
|
||||
if (mux->byte_clk) {
|
||||
devm_clk_put(&display->pdev->dev, mux->byte_clk);
|
||||
mux->byte_clk = NULL;
|
||||
}
|
||||
|
||||
if (mux->pixel_clk) {
|
||||
devm_clk_put(&display->pdev->dev, mux->pixel_clk);
|
||||
mux->pixel_clk = NULL;
|
||||
}
|
||||
|
||||
if (shadow->byte_clk) {
|
||||
devm_clk_put(&display->pdev->dev, shadow->byte_clk);
|
||||
shadow->byte_clk = NULL;
|
||||
}
|
||||
|
||||
if (shadow->pixel_clk) {
|
||||
devm_clk_put(&display->pdev->dev, shadow->pixel_clk);
|
||||
shadow->pixel_clk = NULL;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static bool dsi_display_check_prefix(const char *clk_prefix,
|
||||
const char *clk_name)
|
||||
{
|
||||
@@ -3393,20 +3395,9 @@ static int dsi_display_clocks_init(struct dsi_display *display)
|
||||
{
|
||||
int i, rc = 0, num_clk = 0;
|
||||
const char *clk_name;
|
||||
const char *src_byte = "src_byte", *src_pixel = "src_pixel";
|
||||
const char *mux_byte = "mux_byte", *mux_pixel = "mux_pixel";
|
||||
const char *cphy_byte = "cphy_byte", *cphy_pixel = "cphy_pixel";
|
||||
const char *shadow_byte = "shadow_byte", *shadow_pixel = "shadow_pixel";
|
||||
const char *shadow_cphybyte = "shadow_cphybyte",
|
||||
*shadow_cphypixel = "shadow_cphypixel";
|
||||
const char *pll_byte = "pll_byte", *pll_dsi = "pll_dsi";
|
||||
struct clk *dsi_clk;
|
||||
struct dsi_clk_link_set *src = &display->clock_info.src_clks;
|
||||
struct dsi_clk_link_set *mux = &display->clock_info.mux_clks;
|
||||
struct dsi_clk_link_set *cphy = &display->clock_info.cphy_clks;
|
||||
struct dsi_clk_link_set *shadow = &display->clock_info.shadow_clks;
|
||||
struct dsi_clk_link_set *shadow_cphy =
|
||||
&display->clock_info.shadow_cphy_clks;
|
||||
struct dsi_dyn_clk_caps *dyn_clk_caps = &(display->panel->dyn_clk_caps);
|
||||
struct dsi_clk_link_set *pll = &display->clock_info.pll_clks;
|
||||
char *dsi_clock_name;
|
||||
|
||||
if (!strcmp(display->display_type, "primary"))
|
||||
@@ -3416,8 +3407,6 @@ static int dsi_display_clocks_init(struct dsi_display *display)
|
||||
|
||||
num_clk = dsi_display_get_clocks_count(display, dsi_clock_name);
|
||||
|
||||
DSI_DEBUG("clk count=%d\n", num_clk);
|
||||
|
||||
for (i = 0; i < num_clk; i++) {
|
||||
dsi_display_get_clock_name(display, dsi_clock_name, i,
|
||||
&clk_name);
|
||||
@@ -3430,105 +3419,30 @@ static int dsi_display_clocks_init(struct dsi_display *display)
|
||||
|
||||
DSI_ERR("failed to get %s, rc=%d\n", clk_name, rc);
|
||||
|
||||
if (dsi_display_check_prefix(mux_byte, clk_name)) {
|
||||
mux->byte_clk = NULL;
|
||||
goto error;
|
||||
}
|
||||
if (dsi_display_check_prefix(mux_pixel, clk_name)) {
|
||||
mux->pixel_clk = NULL;
|
||||
if (dsi_display_check_prefix(pll_byte, clk_name)) {
|
||||
pll->byte_clk = NULL;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (dsi_display_check_prefix(cphy_byte, clk_name)) {
|
||||
cphy->byte_clk = NULL;
|
||||
if (dsi_display_check_prefix(pll_dsi, clk_name)) {
|
||||
pll->pixel_clk = NULL;
|
||||
goto error;
|
||||
}
|
||||
if (dsi_display_check_prefix(cphy_pixel, clk_name)) {
|
||||
cphy->pixel_clk = NULL;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (dyn_clk_caps->dyn_clk_support &&
|
||||
(display->panel->panel_mode ==
|
||||
DSI_OP_VIDEO_MODE)) {
|
||||
|
||||
if (dsi_display_check_prefix(src_byte,
|
||||
clk_name))
|
||||
src->byte_clk = NULL;
|
||||
if (dsi_display_check_prefix(src_pixel,
|
||||
clk_name))
|
||||
src->pixel_clk = NULL;
|
||||
if (dsi_display_check_prefix(shadow_byte,
|
||||
clk_name))
|
||||
shadow->byte_clk = NULL;
|
||||
if (dsi_display_check_prefix(shadow_pixel,
|
||||
clk_name))
|
||||
shadow->pixel_clk = NULL;
|
||||
if (dsi_display_check_prefix(shadow_cphybyte,
|
||||
clk_name))
|
||||
shadow_cphy->byte_clk = NULL;
|
||||
if (dsi_display_check_prefix(shadow_cphypixel,
|
||||
clk_name))
|
||||
shadow_cphy->pixel_clk = NULL;
|
||||
|
||||
dyn_clk_caps->dyn_clk_support = false;
|
||||
if (dsi_display_check_prefix(pll_byte, clk_name)) {
|
||||
pll->byte_clk = dsi_clk;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (dsi_display_check_prefix(src_byte, clk_name)) {
|
||||
src->byte_clk = dsi_clk;
|
||||
if (dsi_display_check_prefix(pll_dsi, clk_name)) {
|
||||
pll->pixel_clk = dsi_clk;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (dsi_display_check_prefix(src_pixel, clk_name)) {
|
||||
src->pixel_clk = dsi_clk;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (dsi_display_check_prefix(cphy_byte, clk_name)) {
|
||||
cphy->byte_clk = dsi_clk;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (dsi_display_check_prefix(cphy_pixel, clk_name)) {
|
||||
cphy->pixel_clk = dsi_clk;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (dsi_display_check_prefix(mux_byte, clk_name)) {
|
||||
mux->byte_clk = dsi_clk;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (dsi_display_check_prefix(mux_pixel, clk_name)) {
|
||||
mux->pixel_clk = dsi_clk;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (dsi_display_check_prefix(shadow_byte, clk_name)) {
|
||||
shadow->byte_clk = dsi_clk;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (dsi_display_check_prefix(shadow_pixel, clk_name)) {
|
||||
shadow->pixel_clk = dsi_clk;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (dsi_display_check_prefix(shadow_cphybyte, clk_name)) {
|
||||
shadow_cphy->byte_clk = dsi_clk;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (dsi_display_check_prefix(shadow_cphypixel, clk_name)) {
|
||||
shadow_cphy->pixel_clk = dsi_clk;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
error:
|
||||
(void)dsi_display_clocks_deinit(display);
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -4168,10 +4082,6 @@ static int dsi_display_res_deinit(struct dsi_display *display)
|
||||
int i;
|
||||
struct dsi_display_ctrl *ctrl;
|
||||
|
||||
rc = dsi_display_clocks_deinit(display);
|
||||
if (rc)
|
||||
DSI_ERR("clocks deinit failed, rc=%d\n", rc);
|
||||
|
||||
display_for_each_ctrl(i, display) {
|
||||
ctrl = &display->ctrl[i];
|
||||
dsi_phy_put(ctrl->phy);
|
||||
@@ -4506,28 +4416,17 @@ static int _dsi_display_dyn_update_clks(struct dsi_display *display,
|
||||
u8 ctrl_version;
|
||||
struct dsi_display_ctrl *m_ctrl, *ctrl;
|
||||
struct dsi_dyn_clk_caps *dyn_clk_caps;
|
||||
struct dsi_clk_link_set *parent_clk, *enable_clk;
|
||||
struct dsi_clk_link_set *enable_clk;
|
||||
|
||||
m_ctrl = &display->ctrl[display->clk_master_idx];
|
||||
dyn_clk_caps = &(display->panel->dyn_clk_caps);
|
||||
ctrl_version = m_ctrl->ctrl->version;
|
||||
|
||||
if (dsi_display_is_type_cphy(display)) {
|
||||
enable_clk = &display->clock_info.cphy_clks;
|
||||
parent_clk = &display->clock_info.shadow_cphy_clks;
|
||||
} else {
|
||||
enable_clk = &display->clock_info.src_clks;
|
||||
parent_clk = &display->clock_info.shadow_clks;
|
||||
}
|
||||
enable_clk = &display->clock_info.pll_clks;
|
||||
|
||||
dsi_clk_prepare_enable(enable_clk);
|
||||
|
||||
rc = dsi_clk_update_parent(parent_clk,
|
||||
&display->clock_info.mux_clks);
|
||||
if (rc) {
|
||||
DSI_ERR("failed to update mux parent\n");
|
||||
goto exit;
|
||||
}
|
||||
dsi_display_phy_configure(display, false);
|
||||
|
||||
display_for_each_ctrl(i, display) {
|
||||
ctrl = &display->ctrl[i];
|
||||
@@ -4584,8 +4483,6 @@ static int _dsi_display_dyn_update_clks(struct dsi_display *display,
|
||||
}
|
||||
|
||||
defer_dfps_wait:
|
||||
rc = dsi_clk_update_parent(enable_clk,
|
||||
&display->clock_info.mux_clks);
|
||||
if (rc)
|
||||
DSI_ERR("could not switch back to src clks %d\n", rc);
|
||||
|
||||
@@ -4612,9 +4509,6 @@ recover_byte_clk:
|
||||
bkp_freq->byte_intf_clk_rate, i);
|
||||
}
|
||||
|
||||
exit:
|
||||
dsi_clk_disable_unprepare(&display->clock_info.src_clks);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -5530,6 +5424,8 @@ static int dsi_display_bind(struct device *dev,
|
||||
info.pre_clkon_cb = dsi_pre_clkon_cb;
|
||||
info.post_clkoff_cb = dsi_post_clkoff_cb;
|
||||
info.post_clkon_cb = dsi_post_clkon_cb;
|
||||
info.phy_config_cb = dsi_display_phy_configure;
|
||||
info.phy_pll_toggle_cb = dsi_display_phy_pll_toggle;
|
||||
info.priv_data = display;
|
||||
info.master_ndx = display->clk_master_idx;
|
||||
info.dsi_ctrl_count = display->ctrl_count;
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2015-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2015-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _DSI_DISPLAY_H_
|
||||
@@ -104,17 +104,10 @@ struct dsi_display_boot_param {
|
||||
|
||||
/**
|
||||
* struct dsi_display_clk_info - dsi display clock source information
|
||||
* @src_clks: Source clocks for DSI display.
|
||||
* @mux_clks: Mux clocks used for DFPS.
|
||||
* @shadow_clks: Used for D-phy clock switch.
|
||||
* @shadow_cphy_clks: Used for C-phy clock switch.
|
||||
* @pll_clks: PLL clocks for DSI.
|
||||
*/
|
||||
struct dsi_display_clk_info {
|
||||
struct dsi_clk_link_set src_clks;
|
||||
struct dsi_clk_link_set mux_clks;
|
||||
struct dsi_clk_link_set cphy_clks;
|
||||
struct dsi_clk_link_set shadow_clks;
|
||||
struct dsi_clk_link_set shadow_cphy_clks;
|
||||
struct dsi_clk_link_set pll_clks;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/of_device.h>
|
||||
@@ -461,6 +461,14 @@ static int dsi_phy_driver_probe(struct platform_device *pdev)
|
||||
goto fail_settings;
|
||||
}
|
||||
|
||||
rc = dsi_catalog_phy_pll_setup(&dsi_phy->hw,
|
||||
dsi_phy->pll->pll_revision);
|
||||
if (rc) {
|
||||
DSI_PHY_ERR(dsi_phy, "Catalog does not support PLL version (%d)\n",
|
||||
dsi_phy->pll->pll_revision);
|
||||
goto fail_settings;
|
||||
}
|
||||
|
||||
item->phy = dsi_phy;
|
||||
|
||||
mutex_lock(&dsi_phy_list_lock);
|
||||
@@ -760,6 +768,45 @@ error:
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* dsi_phy_configure() - Configure DSI PHY PLL
|
||||
* @dsi_phy: DSI PHY handle.
|
||||
* @commit: boolean to specify if calculated PHY configuration
|
||||
* needs to be committed. Set to false in case of
|
||||
* dynamic clock switch.
|
||||
*
|
||||
* Return: error code.
|
||||
*/
|
||||
int dsi_phy_configure(struct msm_dsi_phy *phy, bool commit)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
phy->pll->type = phy->cfg.phy_type;
|
||||
phy->pll->bpp = dsi_pixel_format_to_bpp(phy->dst_format);
|
||||
phy->pll->lanes = dsi_get_num_of_data_lanes(phy->data_lanes);
|
||||
if (phy->hw.ops.configure)
|
||||
rc = phy->hw.ops.configure(phy->pll, commit);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* dsi_phy_pll_toggle() - Toggle DSI PHY PLL
|
||||
* @dsi_phy: DSI PHY handle.
|
||||
* @prepare: specifies if PLL needs to be turned on or not.
|
||||
*
|
||||
* Return: error code.
|
||||
*/
|
||||
int dsi_phy_pll_toggle(struct msm_dsi_phy *phy, bool prepare)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
if (phy->hw.ops.pll_toggle)
|
||||
rc = phy->hw.ops.pll_toggle(phy->pll, prepare);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int dsi_phy_enable_ulps(struct msm_dsi_phy *phy,
|
||||
struct dsi_host_config *config, bool clamp_enabled)
|
||||
{
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _DSI_PHY_H_
|
||||
@@ -356,9 +356,9 @@ void dsi_phy_dynamic_refresh_clear(struct msm_dsi_phy *phy);
|
||||
* @dst: Pointer to cache location.
|
||||
* @size: Number of phy lane settings.
|
||||
*/
|
||||
int dsi_phy_dyn_refresh_cache_phy_timings(struct msm_dsi_phy *phy,
|
||||
int dsi_phy_dyn_refresh_cache_phy_timings(struct msm_dsi_phy *phy, u32 *dst,
|
||||
u32 size);
|
||||
|
||||
u32 *dst, u32 size);
|
||||
/**
|
||||
* dsi_phy_set_continuous_clk() - API to set/unset force clock lane HS request.
|
||||
* @phy: DSI PHY Handle.
|
||||
@@ -375,4 +375,31 @@ void dsi_phy_set_continuous_clk(struct msm_dsi_phy *phy, bool enable);
|
||||
*/
|
||||
int dsi_phy_get_io_resources(struct msm_io_res *io_res);
|
||||
|
||||
/**
|
||||
* dsi_phy_configure() - Configure DSI PHY PLL
|
||||
* @dsi_phy: DSI PHY handle.
|
||||
* @commit: boolean to specify if calculated PHY configuration
|
||||
* needs to be committed. Set to false in case of
|
||||
* dynamic clock switch.
|
||||
*
|
||||
* Return: error code.
|
||||
*/
|
||||
int dsi_phy_configure(struct msm_dsi_phy *dsi_phy, bool commit);
|
||||
|
||||
/**
|
||||
* dsi_phy_pll_toggle() - Toggle DSI PHY PLL
|
||||
* @dsi_phy: DSI PHY handle.
|
||||
* @prepare: specifies if PLL needs to be turned on or not.
|
||||
*
|
||||
* Return: error code.
|
||||
*/
|
||||
int dsi_phy_pll_toggle(struct msm_dsi_phy *dsi_phy, bool prepare);
|
||||
|
||||
/**
|
||||
* dsi_phy_dynclk_configure() - Configure DSI PHY PLL during dynamic clock
|
||||
* @dsi_phy: DSI PHY handle.
|
||||
*
|
||||
* Return: error code.
|
||||
*/
|
||||
int dsi_phy_dynclk_configure(struct msm_dsi_phy *phy);
|
||||
#endif /* _DSI_PHY_H_ */
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2015-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2015-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _DSI_PHY_HW_H_
|
||||
@@ -47,6 +47,18 @@ enum dsi_phy_version {
|
||||
DSI_PHY_VERSION_MAX
|
||||
};
|
||||
|
||||
/**
|
||||
* enum dsi_pll_version - DSI PHY PLL version enumeration
|
||||
* @DSI_PLL_VERSION_5NM: 5nm PLL
|
||||
* @DSI_PLL_VERSION_10NM: 10nm PLL
|
||||
* @DSI_PLL_VERSION_UNKNOWN: Unknown PLL version
|
||||
*/
|
||||
enum dsi_pll_version {
|
||||
DSI_PLL_VERSION_5NM,
|
||||
DSI_PLL_VERSION_10NM,
|
||||
DSI_PLL_VERSION_UNKNOWN
|
||||
};
|
||||
|
||||
/**
|
||||
* enum dsi_phy_hw_features - features supported by DSI PHY hardware
|
||||
* @DSI_PHY_DPHY: Supports DPHY
|
||||
@@ -344,6 +356,23 @@ struct dsi_phy_hw_ops {
|
||||
void *timing_ops;
|
||||
struct phy_ulps_config_ops ulps_ops;
|
||||
struct phy_dyn_refresh_ops dyn_refresh_ops;
|
||||
|
||||
/**
|
||||
* configure() - Configure the DSI PHY PLL
|
||||
* @pll: Pointer to DSI PLL.
|
||||
* @commit: boolean to specify if calculated PHY configuration
|
||||
needs to be committed. Set to false in case of
|
||||
dynamic clock switch.
|
||||
*/
|
||||
int (*configure)(void *pll, bool commit);
|
||||
|
||||
/**
|
||||
* pll_toggle() - Toggle the DSI PHY PLL
|
||||
* @pll: Pointer to DSI PLL.
|
||||
* @prepare: specify if PLL needs to be turned on or off.
|
||||
*/
|
||||
int (*pll_toggle)(void *pll, bool prepare);
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
|
@@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) "%s: " fmt, __func__
|
||||
@@ -23,9 +23,6 @@ static int dsi_pll_clock_register(struct platform_device *pdev,
|
||||
case DSI_PLL_5NM:
|
||||
rc = dsi_pll_clock_register_5nm(pdev, pll_res);
|
||||
break;
|
||||
case DSI_PLL_10NM:
|
||||
rc = dsi_pll_clock_register_10nm(pdev, pll_res);
|
||||
break;
|
||||
default:
|
||||
rc = -EINVAL;
|
||||
break;
|
||||
@@ -144,14 +141,12 @@ int dsi_pll_init(struct platform_device *pdev, struct dsi_pll_resource **pll)
|
||||
DSI_PLL_INFO(pll_res, "DSI pll label = %s\n", label);
|
||||
|
||||
/**
|
||||
* Currently, Only supports 5nm and 10nm PLL version. Will add
|
||||
* Currently, Only supports 5nm. Will add
|
||||
* support for other versions as needed.
|
||||
*/
|
||||
|
||||
if (!strcmp(label, "dsi_pll_5nm"))
|
||||
pll_res->pll_revision = DSI_PLL_5NM;
|
||||
else if (!strcmp(label, "dsi_pll_10nm"))
|
||||
pll_res->pll_revision = DSI_PLL_10NM;
|
||||
else
|
||||
return -ENOTSUPP;
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef __DSI_PLL_H
|
||||
@@ -87,20 +87,11 @@ struct dsi_pll_resource {
|
||||
void __iomem *dyn_pll_base;
|
||||
|
||||
s64 vco_current_rate;
|
||||
s64 vco_locking_rate;
|
||||
s64 vco_ref_clk_rate;
|
||||
|
||||
/*
|
||||
* Certain pll's needs to update the same vco rate after resume in
|
||||
* suspend/resume scenario. Cached the vco rate for such plls.
|
||||
*/
|
||||
unsigned long vco_cached_rate;
|
||||
u32 cached_cfg0;
|
||||
u32 cached_cfg1;
|
||||
u32 cached_outdiv;
|
||||
|
||||
u32 cached_postdiv1;
|
||||
u32 cached_postdiv3;
|
||||
s64 vco_min_rate;
|
||||
s64 vco_rate;
|
||||
s64 byteclk_rate;
|
||||
s64 pclk_rate;
|
||||
|
||||
u32 pll_revision;
|
||||
|
||||
@@ -115,24 +106,11 @@ struct dsi_pll_resource {
|
||||
*/
|
||||
bool pll_on;
|
||||
|
||||
/*
|
||||
* handoff_status is true of pll is already enabled by bootloader with
|
||||
* continuous splash enable case. Clock API will call the handoff API
|
||||
* to enable the status. It is disabled if continuous splash
|
||||
* feature is disabled.
|
||||
*/
|
||||
bool handoff_resources;
|
||||
|
||||
/*
|
||||
* caching the pll trim codes in the case of dynamic refresh
|
||||
*/
|
||||
int cache_pll_trim_codes[3];
|
||||
|
||||
/*
|
||||
* for maintaining the status of saving trim codes
|
||||
*/
|
||||
bool reg_upd;
|
||||
|
||||
|
||||
/*
|
||||
* PLL index if multiple index are available. Eg. in case of
|
||||
@@ -147,11 +125,6 @@ struct dsi_pll_resource {
|
||||
|
||||
struct dsi_pll_resource *slave;
|
||||
|
||||
/*
|
||||
* target pll revision information
|
||||
*/
|
||||
int revision;
|
||||
|
||||
void *priv;
|
||||
|
||||
/*
|
||||
@@ -160,24 +133,20 @@ struct dsi_pll_resource {
|
||||
struct dfps_info *dfps;
|
||||
|
||||
/*
|
||||
* for cases where dfps trigger happens before first
|
||||
* suspend/resume and handoff is not finished.
|
||||
* DSI pixel depth and lane information
|
||||
*/
|
||||
bool dfps_trigger;
|
||||
int bpp;
|
||||
int lanes;
|
||||
|
||||
/*
|
||||
* DSI PHY type DPHY/CPHY
|
||||
*/
|
||||
enum dsi_phy_type type;
|
||||
};
|
||||
|
||||
struct dsi_pll_vco_clk {
|
||||
struct dsi_pll_clk {
|
||||
struct clk_hw hw;
|
||||
unsigned long ref_clk_rate;
|
||||
u64 min_rate;
|
||||
u64 max_rate;
|
||||
u32 pll_en_seq_cnt;
|
||||
struct lpfr_cfg *lpfr_lut;
|
||||
u32 lpfr_lut_size;
|
||||
void *priv;
|
||||
|
||||
int (*pll_enable_seqs[MAX_DSI_PLL_EN_SEQS])
|
||||
(struct dsi_pll_resource *pll_res);
|
||||
};
|
||||
|
||||
struct dsi_pll_vco_calc {
|
||||
@@ -191,47 +160,21 @@ struct dsi_pll_vco_calc {
|
||||
s64 pll_plllock_cmp3;
|
||||
};
|
||||
|
||||
static inline bool is_gdsc_disabled(struct dsi_pll_resource *pll_res)
|
||||
{
|
||||
if (!pll_res->gdsc_base) {
|
||||
WARN(1, "gdsc_base register is not defined\n");
|
||||
return true;
|
||||
}
|
||||
return readl_relaxed(pll_res->gdsc_base) & BIT(31) ? false : true;
|
||||
}
|
||||
struct dsi_pll_div_table {
|
||||
u32 min_hz;
|
||||
u32 max_hz;
|
||||
int pll_div;
|
||||
int phy_div;
|
||||
};
|
||||
|
||||
static inline int dsi_pll_div_prepare(struct clk_hw *hw)
|
||||
static inline struct dsi_pll_clk *to_pll_clk_hw(struct clk_hw *hw)
|
||||
{
|
||||
struct clk_hw *parent_hw = clk_hw_get_parent(hw);
|
||||
/* Restore the divider's value */
|
||||
return hw->init->ops->set_rate(hw, clk_hw_get_rate(hw),
|
||||
clk_hw_get_rate(parent_hw));
|
||||
}
|
||||
|
||||
static inline int dsi_set_mux_sel(void *context, unsigned int reg,
|
||||
unsigned int val)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int dsi_get_mux_sel(void *context, unsigned int reg,
|
||||
unsigned int *val)
|
||||
{
|
||||
*val = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline struct dsi_pll_vco_clk *to_vco_clk_hw(struct clk_hw *hw)
|
||||
{
|
||||
return container_of(hw, struct dsi_pll_vco_clk, hw);
|
||||
return container_of(hw, struct dsi_pll_clk, hw);
|
||||
}
|
||||
|
||||
int dsi_pll_clock_register_5nm(struct platform_device *pdev,
|
||||
struct dsi_pll_resource *pll_res);
|
||||
|
||||
int dsi_pll_clock_register_10nm(struct platform_device *pdev,
|
||||
struct dsi_pll_resource *pll_res);
|
||||
|
||||
int dsi_pll_init(struct platform_device *pdev,
|
||||
struct dsi_pll_resource **pll_res);
|
||||
#endif
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
250
msm/dsi/dsi_pll_5nm.h
Normal file
250
msm/dsi/dsi_pll_5nm.h
Normal file
@@ -0,0 +1,250 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include "dsi_pll.h"
|
||||
|
||||
/* Register Offsets from PLL base address */
|
||||
#define PLL_ANALOG_CONTROLS_ONE 0x0000
|
||||
#define PLL_ANALOG_CONTROLS_TWO 0x0004
|
||||
#define PLL_INT_LOOP_SETTINGS 0x0008
|
||||
#define PLL_INT_LOOP_SETTINGS_TWO 0x000C
|
||||
#define PLL_ANALOG_CONTROLS_THREE 0x0010
|
||||
#define PLL_ANALOG_CONTROLS_FOUR 0x0014
|
||||
#define PLL_ANALOG_CONTROLS_FIVE 0x0018
|
||||
#define PLL_INT_LOOP_CONTROLS 0x001C
|
||||
#define PLL_DSM_DIVIDER 0x0020
|
||||
#define PLL_FEEDBACK_DIVIDER 0x0024
|
||||
#define PLL_SYSTEM_MUXES 0x0028
|
||||
#define PLL_FREQ_UPDATE_CONTROL_OVERRIDES 0x002C
|
||||
#define PLL_CMODE 0x0030
|
||||
#define PLL_PSM_CTRL 0x0034
|
||||
#define PLL_RSM_CTRL 0x0038
|
||||
#define PLL_VCO_TUNE_MAP 0x003C
|
||||
#define PLL_PLL_CNTRL 0x0040
|
||||
#define PLL_CALIBRATION_SETTINGS 0x0044
|
||||
#define PLL_BAND_SEL_CAL_TIMER_LOW 0x0048
|
||||
#define PLL_BAND_SEL_CAL_TIMER_HIGH 0x004C
|
||||
#define PLL_BAND_SEL_CAL_SETTINGS 0x0050
|
||||
#define PLL_BAND_SEL_MIN 0x0054
|
||||
#define PLL_BAND_SEL_MAX 0x0058
|
||||
#define PLL_BAND_SEL_PFILT 0x005C
|
||||
#define PLL_BAND_SEL_IFILT 0x0060
|
||||
#define PLL_BAND_SEL_CAL_SETTINGS_TWO 0x0064
|
||||
#define PLL_BAND_SEL_CAL_SETTINGS_THREE 0x0068
|
||||
#define PLL_BAND_SEL_CAL_SETTINGS_FOUR 0x006C
|
||||
#define PLL_BAND_SEL_ICODE_HIGH 0x0070
|
||||
#define PLL_BAND_SEL_ICODE_LOW 0x0074
|
||||
#define PLL_FREQ_DETECT_SETTINGS_ONE 0x0078
|
||||
#define PLL_FREQ_DETECT_THRESH 0x007C
|
||||
#define PLL_FREQ_DET_REFCLK_HIGH 0x0080
|
||||
#define PLL_FREQ_DET_REFCLK_LOW 0x0084
|
||||
#define PLL_FREQ_DET_PLLCLK_HIGH 0x0088
|
||||
#define PLL_FREQ_DET_PLLCLK_LOW 0x008C
|
||||
#define PLL_PFILT 0x0090
|
||||
#define PLL_IFILT 0x0094
|
||||
#define PLL_PLL_GAIN 0x0098
|
||||
#define PLL_ICODE_LOW 0x009C
|
||||
#define PLL_ICODE_HIGH 0x00A0
|
||||
#define PLL_LOCKDET 0x00A4
|
||||
#define PLL_OUTDIV 0x00A8
|
||||
#define PLL_FASTLOCK_CONTROL 0x00AC
|
||||
#define PLL_PASS_OUT_OVERRIDE_ONE 0x00B0
|
||||
#define PLL_PASS_OUT_OVERRIDE_TWO 0x00B4
|
||||
#define PLL_CORE_OVERRIDE 0x00B8
|
||||
#define PLL_CORE_INPUT_OVERRIDE 0x00BC
|
||||
#define PLL_RATE_CHANGE 0x00C0
|
||||
#define PLL_PLL_DIGITAL_TIMERS 0x00C4
|
||||
#define PLL_PLL_DIGITAL_TIMERS_TWO 0x00C8
|
||||
#define PLL_DECIMAL_DIV_START 0x00CC
|
||||
#define PLL_FRAC_DIV_START_LOW 0x00D0
|
||||
#define PLL_FRAC_DIV_START_MID 0x00D4
|
||||
#define PLL_FRAC_DIV_START_HIGH 0x00D8
|
||||
#define PLL_DEC_FRAC_MUXES 0x00DC
|
||||
#define PLL_DECIMAL_DIV_START_1 0x00E0
|
||||
#define PLL_FRAC_DIV_START_LOW_1 0x00E4
|
||||
#define PLL_FRAC_DIV_START_MID_1 0x00E8
|
||||
#define PLL_FRAC_DIV_START_HIGH_1 0x00EC
|
||||
#define PLL_DECIMAL_DIV_START_2 0x00F0
|
||||
#define PLL_FRAC_DIV_START_LOW_2 0x00F4
|
||||
#define PLL_FRAC_DIV_START_MID_2 0x00F8
|
||||
#define PLL_FRAC_DIV_START_HIGH_2 0x00FC
|
||||
#define PLL_MASH_CONTROL 0x0100
|
||||
#define PLL_SSC_STEPSIZE_LOW 0x0104
|
||||
#define PLL_SSC_STEPSIZE_HIGH 0x0108
|
||||
#define PLL_SSC_DIV_PER_LOW 0x010C
|
||||
#define PLL_SSC_DIV_PER_HIGH 0x0110
|
||||
#define PLL_SSC_ADJPER_LOW 0x0114
|
||||
#define PLL_SSC_ADJPER_HIGH 0x0118
|
||||
#define PLL_SSC_MUX_CONTROL 0x011C
|
||||
#define PLL_SSC_STEPSIZE_LOW_1 0x0120
|
||||
#define PLL_SSC_STEPSIZE_HIGH_1 0x0124
|
||||
#define PLL_SSC_DIV_PER_LOW_1 0x0128
|
||||
#define PLL_SSC_DIV_PER_HIGH_1 0x012C
|
||||
#define PLL_SSC_ADJPER_LOW_1 0x0130
|
||||
#define PLL_SSC_ADJPER_HIGH_1 0x0134
|
||||
#define PLL_SSC_STEPSIZE_LOW_2 0x0138
|
||||
#define PLL_SSC_STEPSIZE_HIGH_2 0x013C
|
||||
#define PLL_SSC_DIV_PER_LOW_2 0x0140
|
||||
#define PLL_SSC_DIV_PER_HIGH_2 0x0144
|
||||
#define PLL_SSC_ADJPER_LOW_2 0x0148
|
||||
#define PLL_SSC_ADJPER_HIGH_2 0x014C
|
||||
#define PLL_SSC_CONTROL 0x0150
|
||||
#define PLL_PLL_OUTDIV_RATE 0x0154
|
||||
#define PLL_PLL_LOCKDET_RATE_1 0x0158
|
||||
#define PLL_PLL_LOCKDET_RATE_2 0x015C
|
||||
#define PLL_PLL_PROP_GAIN_RATE_1 0x0160
|
||||
#define PLL_PLL_PROP_GAIN_RATE_2 0x0164
|
||||
#define PLL_PLL_BAND_SEL_RATE_1 0x0168
|
||||
#define PLL_PLL_BAND_SEL_RATE_2 0x016C
|
||||
#define PLL_PLL_INT_GAIN_IFILT_BAND_1 0x0170
|
||||
#define PLL_PLL_INT_GAIN_IFILT_BAND_2 0x0174
|
||||
#define PLL_PLL_FL_INT_GAIN_PFILT_BAND_1 0x0178
|
||||
#define PLL_PLL_FL_INT_GAIN_PFILT_BAND_2 0x017C
|
||||
#define PLL_PLL_FASTLOCK_EN_BAND 0x0180
|
||||
#define PLL_FREQ_TUNE_ACCUM_INIT_MID 0x0184
|
||||
#define PLL_FREQ_TUNE_ACCUM_INIT_HIGH 0x0188
|
||||
#define PLL_FREQ_TUNE_ACCUM_INIT_MUX 0x018C
|
||||
#define PLL_PLL_LOCK_OVERRIDE 0x0190
|
||||
#define PLL_PLL_LOCK_DELAY 0x0194
|
||||
#define PLL_PLL_LOCK_MIN_DELAY 0x0198
|
||||
#define PLL_CLOCK_INVERTERS 0x019C
|
||||
#define PLL_SPARE_AND_JPC_OVERRIDES 0x01A0
|
||||
#define PLL_BIAS_CONTROL_1 0x01A4
|
||||
#define PLL_BIAS_CONTROL_2 0x01A8
|
||||
#define PLL_ALOG_OBSV_BUS_CTRL_1 0x01AC
|
||||
#define PLL_COMMON_STATUS_ONE 0x01B0
|
||||
#define PLL_COMMON_STATUS_TWO 0x01B4
|
||||
#define PLL_BAND_SEL_CAL 0x01B8
|
||||
#define PLL_ICODE_ACCUM_STATUS_LOW 0x01BC
|
||||
#define PLL_ICODE_ACCUM_STATUS_HIGH 0x01C0
|
||||
#define PLL_FD_OUT_LOW 0x01C4
|
||||
#define PLL_FD_OUT_HIGH 0x01C8
|
||||
#define PLL_ALOG_OBSV_BUS_STATUS_1 0x01CC
|
||||
#define PLL_PLL_MISC_CONFIG 0x01D0
|
||||
#define PLL_FLL_CONFIG 0x01D4
|
||||
#define PLL_FLL_FREQ_ACQ_TIME 0x01D8
|
||||
#define PLL_FLL_CODE0 0x01DC
|
||||
#define PLL_FLL_CODE1 0x01E0
|
||||
#define PLL_FLL_GAIN0 0x01E4
|
||||
#define PLL_FLL_GAIN1 0x01E8
|
||||
#define PLL_SW_RESET 0x01EC
|
||||
#define PLL_FAST_PWRUP 0x01F0
|
||||
#define PLL_LOCKTIME0 0x01F4
|
||||
#define PLL_LOCKTIME1 0x01F8
|
||||
#define PLL_DEBUG_BUS_SEL 0x01FC
|
||||
#define PLL_DEBUG_BUS0 0x0200
|
||||
#define PLL_DEBUG_BUS1 0x0204
|
||||
#define PLL_DEBUG_BUS2 0x0208
|
||||
#define PLL_DEBUG_BUS3 0x020C
|
||||
#define PLL_ANALOG_FLL_CONTROL_OVERRIDES 0x0210
|
||||
#define PLL_VCO_CONFIG 0x0214
|
||||
#define PLL_VCO_CAL_CODE1_MODE0_STATUS 0x0218
|
||||
#define PLL_VCO_CAL_CODE1_MODE1_STATUS 0x021C
|
||||
#define PLL_RESET_SM_STATUS 0x0220
|
||||
#define PLL_TDC_OFFSET 0x0224
|
||||
#define PLL_PS3_PWRDOWN_CONTROLS 0x0228
|
||||
#define PLL_PS4_PWRDOWN_CONTROLS 0x022C
|
||||
#define PLL_PLL_RST_CONTROLS 0x0230
|
||||
#define PLL_GEAR_BAND_SELECT_CONTROLS 0x0234
|
||||
#define PLL_PSM_CLK_CONTROLS 0x0238
|
||||
#define PLL_SYSTEM_MUXES_2 0x023C
|
||||
#define PLL_VCO_CONFIG_1 0x0240
|
||||
#define PLL_VCO_CONFIG_2 0x0244
|
||||
#define PLL_CLOCK_INVERTERS_1 0x0248
|
||||
#define PLL_CLOCK_INVERTERS_2 0x024C
|
||||
#define PLL_CMODE_1 0x0250
|
||||
#define PLL_CMODE_2 0x0254
|
||||
#define PLL_ANALOG_CONTROLS_FIVE_1 0x0258
|
||||
#define PLL_ANALOG_CONTROLS_FIVE_2 0x025C
|
||||
#define PLL_PERF_OPTIMIZE 0x0260
|
||||
|
||||
/* Register Offsets from PHY base address */
|
||||
#define PHY_CMN_CLK_CFG0 0x010
|
||||
#define PHY_CMN_CLK_CFG1 0x014
|
||||
#define PHY_CMN_GLBL_CTRL 0x018
|
||||
#define PHY_CMN_RBUF_CTRL 0x01C
|
||||
#define PHY_CMN_CTRL_0 0x024
|
||||
#define PHY_CMN_CTRL_2 0x02C
|
||||
#define PHY_CMN_CTRL_3 0x030
|
||||
#define PHY_CMN_PLL_CNTRL 0x03C
|
||||
#define PHY_CMN_GLBL_DIGTOP_SPARE4 0x128
|
||||
|
||||
/* Bit definition of SSC control registers */
|
||||
#define SSC_CENTER BIT(0)
|
||||
#define SSC_EN BIT(1)
|
||||
#define SSC_FREQ_UPDATE BIT(2)
|
||||
#define SSC_FREQ_UPDATE_MUX BIT(3)
|
||||
#define SSC_UPDATE_SSC BIT(4)
|
||||
#define SSC_UPDATE_SSC_MUX BIT(5)
|
||||
#define SSC_START BIT(6)
|
||||
#define SSC_START_MUX BIT(7)
|
||||
|
||||
/* Dynamic Refresh Control Registers */
|
||||
#define DSI_DYNAMIC_REFRESH_PLL_CTRL0 (0x014)
|
||||
#define DSI_DYNAMIC_REFRESH_PLL_CTRL1 (0x018)
|
||||
#define DSI_DYNAMIC_REFRESH_PLL_CTRL2 (0x01C)
|
||||
#define DSI_DYNAMIC_REFRESH_PLL_CTRL3 (0x020)
|
||||
#define DSI_DYNAMIC_REFRESH_PLL_CTRL4 (0x024)
|
||||
#define DSI_DYNAMIC_REFRESH_PLL_CTRL5 (0x028)
|
||||
#define DSI_DYNAMIC_REFRESH_PLL_CTRL6 (0x02C)
|
||||
#define DSI_DYNAMIC_REFRESH_PLL_CTRL7 (0x030)
|
||||
#define DSI_DYNAMIC_REFRESH_PLL_CTRL8 (0x034)
|
||||
#define DSI_DYNAMIC_REFRESH_PLL_CTRL9 (0x038)
|
||||
#define DSI_DYNAMIC_REFRESH_PLL_CTRL10 (0x03C)
|
||||
#define DSI_DYNAMIC_REFRESH_PLL_CTRL11 (0x040)
|
||||
#define DSI_DYNAMIC_REFRESH_PLL_CTRL12 (0x044)
|
||||
#define DSI_DYNAMIC_REFRESH_PLL_CTRL13 (0x048)
|
||||
#define DSI_DYNAMIC_REFRESH_PLL_CTRL14 (0x04C)
|
||||
#define DSI_DYNAMIC_REFRESH_PLL_CTRL15 (0x050)
|
||||
#define DSI_DYNAMIC_REFRESH_PLL_CTRL16 (0x054)
|
||||
#define DSI_DYNAMIC_REFRESH_PLL_CTRL17 (0x058)
|
||||
#define DSI_DYNAMIC_REFRESH_PLL_CTRL18 (0x05C)
|
||||
#define DSI_DYNAMIC_REFRESH_PLL_CTRL19 (0x060)
|
||||
#define DSI_DYNAMIC_REFRESH_PLL_CTRL20 (0x064)
|
||||
#define DSI_DYNAMIC_REFRESH_PLL_CTRL21 (0x068)
|
||||
#define DSI_DYNAMIC_REFRESH_PLL_CTRL22 (0x06C)
|
||||
#define DSI_DYNAMIC_REFRESH_PLL_CTRL23 (0x070)
|
||||
#define DSI_DYNAMIC_REFRESH_PLL_CTRL24 (0x074)
|
||||
#define DSI_DYNAMIC_REFRESH_PLL_CTRL25 (0x078)
|
||||
#define DSI_DYNAMIC_REFRESH_PLL_CTRL26 (0x07C)
|
||||
#define DSI_DYNAMIC_REFRESH_PLL_CTRL27 (0x080)
|
||||
#define DSI_DYNAMIC_REFRESH_PLL_CTRL28 (0x084)
|
||||
#define DSI_DYNAMIC_REFRESH_PLL_CTRL29 (0x088)
|
||||
#define DSI_DYNAMIC_REFRESH_PLL_CTRL30 (0x08C)
|
||||
#define DSI_DYNAMIC_REFRESH_PLL_CTRL31 (0x090)
|
||||
#define DSI_DYNAMIC_REFRESH_PLL_UPPER_ADDR (0x094)
|
||||
#define DSI_DYNAMIC_REFRESH_PLL_UPPER_ADDR2 (0x098)
|
||||
|
||||
#define DSI_PHY_TO_PLL_OFFSET (0x500)
|
||||
|
||||
enum {
|
||||
DSI_PLL_0,
|
||||
DSI_PLL_1,
|
||||
DSI_PLL_MAX
|
||||
};
|
||||
|
||||
struct dsi_pll_div_table pll_5nm_dphy[] = {
|
||||
{60000000, 86670000, 2, 5},
|
||||
{86670000, 97500000, 1, 9},
|
||||
{97500000, 111430000, 8, 1},
|
||||
{111430000, 130000000, 1, 7},
|
||||
{130000000, 156000000, 2, 3},
|
||||
{150000000, 195000000, 1, 5},
|
||||
{195000000, 260000000, 4, 1},
|
||||
{260000000, 390000000, 1, 3},
|
||||
{390000000, 780000000, 2, 1},
|
||||
{780000000, 3500000000, 1, 1}
|
||||
};
|
||||
|
||||
struct dsi_pll_div_table pll_5nm_cphy[] = {
|
||||
{60000000, 97500000, 2, 5},
|
||||
{97500000, 130000000, 8, 1},
|
||||
{130000000, 156000000, 2, 3},
|
||||
{156000000, 195000000, 1, 5},
|
||||
{195000000, 260000000, 4, 1},
|
||||
{260000000, 390000000, 1, 3},
|
||||
{390000000, 780000000, 2, 1},
|
||||
{780000000, 3500000000, 1, 1}
|
||||
};
|
Reference in New Issue
Block a user