Merge "disp: msm: dp: fix disp_cc offsets for pixel clk dividers"

This commit is contained in:
qctecmdr
2021-03-02 13:25:08 -08:00
committed by Gerrit - the friendly Code Review server
8 changed files with 121 additions and 39 deletions

View File

@@ -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)
{

View File

@@ -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_ */

View File

@@ -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 (version >= 0x10040000) {
if (panel->stream_id == DP_STREAM_1)
reg_off = MMSS_DP_PIXEL1_M_V420 - MMSS_DP_PIXEL_M_V420;
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;

View File

@@ -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)) {

View File

@@ -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;

View File

@@ -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 */

View File

@@ -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,27 +828,43 @@ 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 = "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_clks[DP_PLL_NUM_CLKS] = {
{
.hw.init = &(struct clk_init_data) {
.name = "dp_phy_pll_link_clk",
.ops = &pll_link_clk_ops,
},
};
static struct dp_pll_vco_clk dp_phy_pll_vco_div_clk = {
},
{
.hw.init = &(struct clk_init_data) {
.name = "dp_phy_pll_vco_div_clk",
.ops = &pll_vco_div_clk_ops,
},
},
};
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;
}

View File

@@ -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)