disp: msm: dsi: rework DSI PLL to be configured within PHY
Change avoids clock framework APIs to configure the DSI PHY PLL. It follows HW recommendation to set the byte and pclk dividers. Change-Id: I8c110f3997e4ec4c2eaa28778b70091855725ab8 Signed-off-by: Satya Rama Aditya Pinapala <psraditya30@codeaurora.org>
This commit is contained in:
@@ -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);
|
||||
|
||||
|
@@ -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_DEFS_H_
|
||||
@@ -739,6 +739,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;
|
||||
|
@@ -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/list.h>
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -5526,6 +5420,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 soppresso perché troppo grande
Carica Diff
File diff soppresso perché troppo grande
Carica 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}
|
||||
};
|
Fai riferimento in un nuovo problema
Block a user