Merge "disp: msm: dp: fix disp_cc offsets for pixel clk dividers"
This commit is contained in:

committed by
Gerrit - the friendly Code Review server

commit
1269ba8e88
@@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
|
||||
@@ -123,6 +123,7 @@ struct dp_catalog_private {
|
||||
struct dp_catalog dp_catalog;
|
||||
|
||||
char exe_mode[SZ_4];
|
||||
u32 dp_core_version;
|
||||
};
|
||||
|
||||
static u32 dp_read_sw(struct dp_catalog_private *catalog,
|
||||
@@ -1938,6 +1939,25 @@ static void dp_catalog_ctrl_fec_config(struct dp_catalog_ctrl *ctrl,
|
||||
wmb();
|
||||
}
|
||||
|
||||
u32 dp_catalog_get_dp_core_version(struct dp_catalog *dp_catalog)
|
||||
{
|
||||
struct dp_catalog_private *catalog;
|
||||
struct dp_io_data *io_data;
|
||||
|
||||
if (!dp_catalog) {
|
||||
DP_ERR("invalid input\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
catalog = container_of(dp_catalog, struct dp_catalog_private, dp_catalog);
|
||||
if (catalog->dp_core_version)
|
||||
return catalog->dp_core_version;
|
||||
|
||||
io_data = catalog->io.dp_ahb;
|
||||
|
||||
return dp_read(DP_HW_VERSION);
|
||||
}
|
||||
|
||||
static int dp_catalog_reg_dump(struct dp_catalog *dp_catalog,
|
||||
char *name, u8 **out_buf, u32 *out_buf_len)
|
||||
{
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _DP_CATALOG_H_
|
||||
@@ -336,4 +336,5 @@ struct dp_catalog_sub *dp_catalog_get_v420(struct device *dev,
|
||||
struct dp_catalog_sub *dp_catalog_get_v200(struct device *dev,
|
||||
struct dp_catalog *catalog, struct dp_catalog_io *io);
|
||||
|
||||
u32 dp_catalog_get_dp_core_version(struct dp_catalog *dp_catalog);
|
||||
#endif /* _DP_CATALOG_H_ */
|
||||
|
@@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
|
||||
@@ -8,6 +8,15 @@
|
||||
#include "dp_reg.h"
|
||||
#include "dp_debug.h"
|
||||
|
||||
#define MMSS_DP_PIXEL_BASE_V130 (0x1A8)
|
||||
#define MMSS_DP_PIXEL1_BASE_V130 (0x1C0)
|
||||
|
||||
#define MMSS_DP_PIXEL_BASE_V140 (0x1BC)
|
||||
#define MMSS_DP_PIXEL1_BASE_V140 (0x1D4)
|
||||
|
||||
#define MMSS_DP_M_OFF (0x8)
|
||||
#define MMSS_DP_N_OFF (0xC)
|
||||
|
||||
#define dp_catalog_get_priv_v420(x) ({ \
|
||||
struct dp_catalog *catalog; \
|
||||
catalog = container_of(x, struct dp_catalog, x); \
|
||||
@@ -146,8 +155,10 @@ static void dp_catalog_panel_config_msa_v420(struct dp_catalog_panel *panel,
|
||||
u32 const nvid_fixed = 0x8000;
|
||||
u32 const link_rate_hbr2 = 540000;
|
||||
u32 const link_rate_hbr3 = 810000;
|
||||
struct dp_catalog *dp_catalog;
|
||||
struct dp_catalog_private_v420 *catalog;
|
||||
struct dp_io_data *io_data;
|
||||
u32 version;
|
||||
|
||||
if (!panel || !rate) {
|
||||
DP_ERR("invalid input\n");
|
||||
@@ -159,14 +170,27 @@ static void dp_catalog_panel_config_msa_v420(struct dp_catalog_panel *panel,
|
||||
return;
|
||||
}
|
||||
|
||||
catalog = dp_catalog_get_priv_v420(panel);
|
||||
dp_catalog = container_of(panel, struct dp_catalog, panel);
|
||||
catalog = container_of(dp_catalog->sub, struct dp_catalog_private_v420, sub);
|
||||
|
||||
version = dp_catalog_get_dp_core_version(dp_catalog);
|
||||
io_data = catalog->io->dp_mmss_cc;
|
||||
|
||||
if (panel->stream_id == DP_STREAM_1)
|
||||
reg_off = MMSS_DP_PIXEL1_M_V420 - MMSS_DP_PIXEL_M_V420;
|
||||
if (version >= 0x10040000) {
|
||||
if (panel->stream_id == DP_STREAM_1)
|
||||
reg_off = MMSS_DP_PIXEL1_BASE_V140;
|
||||
else
|
||||
reg_off = MMSS_DP_PIXEL_BASE_V140;
|
||||
} else {
|
||||
if (panel->stream_id == DP_STREAM_1)
|
||||
reg_off = MMSS_DP_PIXEL1_BASE_V130;
|
||||
else
|
||||
reg_off = MMSS_DP_PIXEL_BASE_V130;
|
||||
}
|
||||
|
||||
pixel_m = dp_read(MMSS_DP_PIXEL_M_V420 + reg_off);
|
||||
pixel_n = dp_read(MMSS_DP_PIXEL_N_V420 + reg_off);
|
||||
|
||||
pixel_m = dp_read(reg_off + MMSS_DP_M_OFF);
|
||||
pixel_n = dp_read(reg_off + MMSS_DP_N_OFF);
|
||||
DP_DEBUG("pixel_m=0x%x, pixel_n=0x%x\n", pixel_m, pixel_n);
|
||||
|
||||
mvid = (pixel_m & 0xFFFF) * 5;
|
||||
|
@@ -1950,6 +1950,7 @@ static int dp_init_sub_modules(struct dp_display_private *dp)
|
||||
|
||||
pll_in.aux = dp->aux;
|
||||
pll_in.parser = dp->parser;
|
||||
pll_in.dp_core_revision = dp_catalog_get_dp_core_version(dp->catalog);
|
||||
|
||||
dp->pll = dp_pll_get(&pll_in);
|
||||
if (IS_ERR(dp->pll)) {
|
||||
|
@@ -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/err.h>
|
||||
@@ -74,6 +74,34 @@ static void dp_pll_clock_unregister(struct dp_pll *pll)
|
||||
}
|
||||
}
|
||||
|
||||
int dp_pll_clock_register_helper(struct dp_pll *pll, struct dp_pll_vco_clk *clks, int num_clks)
|
||||
{
|
||||
int rc = 0, i = 0;
|
||||
struct platform_device *pdev;
|
||||
struct clk *clk;
|
||||
|
||||
if (!pll || !clks) {
|
||||
DP_ERR("input not initialized\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
pdev = pll->pdev;
|
||||
|
||||
for (i = 0; i < num_clks; i++) {
|
||||
clks[i].priv = pll;
|
||||
|
||||
clk = clk_register(&pdev->dev, &clks[i].hw);
|
||||
if (IS_ERR(clk)) {
|
||||
DP_ERR("%s registration failed for DP: %d\n",
|
||||
clk_hw_get_name(&clks[i].hw), pll->index);
|
||||
return -EINVAL;
|
||||
}
|
||||
pll->clk_data->clks[i] = clk;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
struct dp_pll *dp_pll_get(struct dp_pll_in *in)
|
||||
{
|
||||
int rc = 0;
|
||||
@@ -93,6 +121,7 @@ struct dp_pll *dp_pll_get(struct dp_pll_in *in)
|
||||
pll->pdev = in->pdev;
|
||||
pll->parser = in->parser;
|
||||
pll->aux = in->aux;
|
||||
pll->dp_core_revision = in->dp_core_revision;
|
||||
parser = pll->parser;
|
||||
pdev = pll->pdev;
|
||||
|
||||
|
@@ -80,6 +80,7 @@ struct dp_pll {
|
||||
struct dp_aux *aux;
|
||||
struct dp_pll_io io;
|
||||
struct clk_onecell_data *clk_data;
|
||||
u32 dp_core_revision;
|
||||
|
||||
int (*pll_cfg)(struct dp_pll *pll, unsigned long rate);
|
||||
int (*pll_prepare)(struct dp_pll *pll);
|
||||
@@ -128,8 +129,10 @@ struct dp_pll_in {
|
||||
struct platform_device *pdev;
|
||||
struct dp_aux *aux;
|
||||
struct dp_parser *parser;
|
||||
u32 dp_core_revision;
|
||||
};
|
||||
|
||||
int dp_pll_clock_register_helper(struct dp_pll *pll, struct dp_pll_vco_clk *clks, int num_clks);
|
||||
struct dp_pll *dp_pll_get(struct dp_pll_in *in);
|
||||
void dp_pll_put(struct dp_pll *pll);
|
||||
#endif /* __DP_PLL_H */
|
||||
|
@@ -121,6 +121,8 @@
|
||||
#define DP_VCO_RATE_9720MHZDIV1000 9720000UL
|
||||
#define DP_VCO_RATE_10800MHZDIV1000 10800000UL
|
||||
|
||||
#define DP_PLL_NUM_CLKS 2
|
||||
|
||||
#define DP_5NM_C_READY BIT(0)
|
||||
#define DP_5NM_FREQ_DONE BIT(0)
|
||||
#define DP_5NM_PLL_LOCKED BIT(1)
|
||||
@@ -826,17 +828,33 @@ static const struct clk_ops pll_vco_div_clk_ops = {
|
||||
.set_rate = dp_pll_vco_div_clk_set_rate,
|
||||
};
|
||||
|
||||
static struct dp_pll_vco_clk dp_phy_pll_link_clk = {
|
||||
static struct dp_pll_vco_clk dp0_phy_pll_clks[DP_PLL_NUM_CLKS] = {
|
||||
{
|
||||
.hw.init = &(struct clk_init_data) {
|
||||
.name = "dp_phy_pll_link_clk",
|
||||
.name = "dp0_phy_pll_link_clk",
|
||||
.ops = &pll_link_clk_ops,
|
||||
},
|
||||
},
|
||||
{
|
||||
.hw.init = &(struct clk_init_data) {
|
||||
.name = "dp0_phy_pll_vco_div_clk",
|
||||
.ops = &pll_vco_div_clk_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct dp_pll_vco_clk dp_phy_pll_vco_div_clk = {
|
||||
static struct dp_pll_vco_clk dp_phy_pll_clks[DP_PLL_NUM_CLKS] = {
|
||||
{
|
||||
.hw.init = &(struct clk_init_data) {
|
||||
.name = "dp_phy_pll_link_clk",
|
||||
.ops = &pll_link_clk_ops,
|
||||
},
|
||||
},
|
||||
{
|
||||
.hw.init = &(struct clk_init_data) {
|
||||
.name = "dp_phy_pll_vco_div_clk",
|
||||
.ops = &pll_vco_div_clk_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -844,9 +862,9 @@ static struct dp_pll_db dp_pdb;
|
||||
|
||||
int dp_pll_clock_register_5nm(struct dp_pll *pll)
|
||||
{
|
||||
int rc = 0, num_clks = 2;
|
||||
int rc = 0;
|
||||
struct platform_device *pdev;
|
||||
struct clk *clk;
|
||||
struct dp_pll_vco_clk *pll_clks;
|
||||
|
||||
if (!pll) {
|
||||
DP_ERR("pll data not initialized\n");
|
||||
@@ -858,46 +876,36 @@ int dp_pll_clock_register_5nm(struct dp_pll *pll)
|
||||
if (!pll->clk_data)
|
||||
return -ENOMEM;
|
||||
|
||||
pll->clk_data->clks = kcalloc(num_clks, sizeof(struct clk *),
|
||||
pll->clk_data->clks = kcalloc(DP_PLL_NUM_CLKS, sizeof(struct clk *),
|
||||
GFP_KERNEL);
|
||||
if (!pll->clk_data->clks) {
|
||||
kfree(pll->clk_data);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
pll->clk_data->clk_num = num_clks;
|
||||
pll->clk_data->clk_num = DP_PLL_NUM_CLKS;
|
||||
pll->priv = &dp_pdb;
|
||||
dp_pdb.pll = pll;
|
||||
|
||||
dp_phy_pll_link_clk.priv = pll;
|
||||
dp_phy_pll_vco_div_clk.priv = pll;
|
||||
|
||||
pll->pll_cfg = dp_pll_configure;
|
||||
pll->pll_prepare = dp_pll_prepare;
|
||||
pll->pll_unprepare = dp_pll_unprepare;
|
||||
|
||||
clk = clk_register(&pdev->dev, &dp_phy_pll_link_clk.hw);
|
||||
if (IS_ERR(clk)) {
|
||||
DP_ERR("%s registration failed for DP: %d\n",
|
||||
clk_hw_get_name(&dp_phy_pll_link_clk.hw), pll->index);
|
||||
rc = -EINVAL;
|
||||
goto clk_reg_fail;
|
||||
}
|
||||
pll->clk_data->clks[0] = clk;
|
||||
if (pll->dp_core_revision >= 0x10040000)
|
||||
pll_clks = dp0_phy_pll_clks;
|
||||
else
|
||||
pll_clks = dp_phy_pll_clks;
|
||||
|
||||
clk = clk_register(&pdev->dev, &dp_phy_pll_vco_div_clk.hw);
|
||||
if (IS_ERR(clk)) {
|
||||
DP_ERR("%s registration failed for DP: %d\n",
|
||||
clk_hw_get_name(&dp_phy_pll_vco_div_clk.hw), pll->index);
|
||||
rc = -EINVAL;
|
||||
rc = dp_pll_clock_register_helper(pll, pll_clks, DP_PLL_NUM_CLKS);
|
||||
if (rc) {
|
||||
DP_ERR("Clock register failed rc=%d\n", rc);
|
||||
goto clk_reg_fail;
|
||||
}
|
||||
pll->clk_data->clks[1] = clk;
|
||||
|
||||
rc = of_clk_add_provider(pdev->dev.of_node,
|
||||
of_clk_src_onecell_get, pll->clk_data);
|
||||
if (rc) {
|
||||
DP_ERR("Clock register failed rc=%d\n", rc);
|
||||
DP_ERR("Clock add provider failed rc=%d\n", rc);
|
||||
goto clk_reg_fail;
|
||||
}
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _DP_REG_H_
|
||||
@@ -398,10 +398,6 @@
|
||||
#define MMSS_DP_PIXEL_N_V200 (0x0134)
|
||||
#define MMSS_DP_PIXEL1_M_V200 (0x0148)
|
||||
#define MMSS_DP_PIXEL1_N_V200 (0x014C)
|
||||
#define MMSS_DP_PIXEL_M_V420 (0x01B0)
|
||||
#define MMSS_DP_PIXEL_N_V420 (0x01B4)
|
||||
#define MMSS_DP_PIXEL1_M_V420 (0x01C8)
|
||||
#define MMSS_DP_PIXEL1_N_V420 (0x01CC)
|
||||
|
||||
/* DP HDCP 1.3 registers */
|
||||
#define DP_HDCP_CTRL (0x0A0)
|
||||
|
Reference in New Issue
Block a user