From 5694bc2eee1cef7eb21d039ad3a00c03d6d891a4 Mon Sep 17 00:00:00 2001 From: Satya Rama Aditya Pinapala Date: Mon, 18 Nov 2019 15:35:41 -0800 Subject: [PATCH] disp: msm: dsi: move dsi pll as subnode to dsi PHY DSI PLL is tightly coupled with DSI PHY. This change removes separate DSI pll driver and makes DSI pll as a subnode to DSI PHY which is an accurate way of representation. In addition, this change adds support for 5nm DSI ctrl and PHY revisions and adds DSI pll support for 5nm. Remove support for older DSI pll revisions such as 7nm, 10nm, 14nm, 20nm, 28nm. Change-Id: Ic8b886a9fe24b906e4ec5130720600efa1e59b68 Signed-off-by: Satya Rama Aditya Pinapala --- Makefile | 1 - msm/Makefile | 3 + msm/dsi/dsi_catalog.c | 5 +- msm/dsi/dsi_ctrl.c | 30 +- msm/dsi/dsi_ctrl_hw.h | 4 +- msm/dsi/dsi_phy.c | 20 +- msm/dsi/dsi_phy.h | 6 +- msm/dsi/dsi_phy_hw.h | 4 +- msm/dsi/dsi_phy_hw_v4_0.c | 13 +- msm/dsi/dsi_phy_timing_calc.c | 3 +- msm/dsi/dsi_pll.c | 148 ++ pll/pll_drv.h => msm/dsi/dsi_pll.h | 144 +- pll/dsi_pll_7nm.c => msm/dsi/dsi_pll_5nm.c | 953 +++---- pll/Makefile | 18 - pll/dp_pll.h | 50 - pll/dp_pll_10nm.c | 287 --- pll/dp_pll_10nm.h | 51 - pll/dp_pll_10nm_util.c | 757 ------ pll/dp_pll_14nm.c | 820 ------ pll/dp_pll_14nm.h | 188 -- pll/dp_pll_7nm.c | 341 --- pll/dp_pll_7nm.h | 52 - pll/dp_pll_7nm_util.c | 739 ------ pll/dsi_20nm_pll_util.c | 1004 -------- pll/dsi_pll.h | 52 - pll/dsi_pll_10nm.c | 2168 ---------------- pll/dsi_pll_14nm.c | 592 ----- pll/dsi_pll_14nm.h | 220 -- pll/dsi_pll_14nm_util.c | 1149 --------- pll/dsi_pll_20nm.c | 590 ----- pll/dsi_pll_28hpm.c | 317 --- pll/dsi_pll_28lpm.c | 545 ---- pll/dsi_pll_28nm.h | 64 - pll/dsi_pll_28nm_util.c | 652 ----- pll/dsi_pll_8996.c | 548 ---- pll/dsi_pll_8996.h | 214 -- pll/dsi_pll_8996_util.c | 1130 --------- pll/dsi_pll_util.c | 580 ----- pll/edp_pll_28hpm.c | 580 ----- pll/hdmi_pll.h | 57 - pll/hdmi_pll_20nm.c | 970 ------- pll/hdmi_pll_28hpm.c | 1091 -------- pll/hdmi_pll_28lpm.c | 790 ------ pll/hdmi_pll_8996.c | 2675 -------------------- pll/hdmi_pll_8998.c | 827 ------ pll/pll_drv.c | 424 ---- pll/pll_trace.h | 109 - pll/pll_util.c | 380 --- 48 files changed, 681 insertions(+), 21684 deletions(-) create mode 100644 msm/dsi/dsi_pll.c rename pll/pll_drv.h => msm/dsi/dsi_pll.h (58%) rename pll/dsi_pll_7nm.c => msm/dsi/dsi_pll_5nm.c (67%) delete mode 100644 pll/Makefile delete mode 100644 pll/dp_pll.h delete mode 100644 pll/dp_pll_10nm.c delete mode 100644 pll/dp_pll_10nm.h delete mode 100644 pll/dp_pll_10nm_util.c delete mode 100644 pll/dp_pll_14nm.c delete mode 100644 pll/dp_pll_14nm.h delete mode 100644 pll/dp_pll_7nm.c delete mode 100644 pll/dp_pll_7nm.h delete mode 100644 pll/dp_pll_7nm_util.c delete mode 100644 pll/dsi_20nm_pll_util.c delete mode 100644 pll/dsi_pll.h delete mode 100644 pll/dsi_pll_10nm.c delete mode 100644 pll/dsi_pll_14nm.c delete mode 100644 pll/dsi_pll_14nm.h delete mode 100644 pll/dsi_pll_14nm_util.c delete mode 100644 pll/dsi_pll_20nm.c delete mode 100644 pll/dsi_pll_28hpm.c delete mode 100644 pll/dsi_pll_28lpm.c delete mode 100644 pll/dsi_pll_28nm.h delete mode 100644 pll/dsi_pll_28nm_util.c delete mode 100644 pll/dsi_pll_8996.c delete mode 100644 pll/dsi_pll_8996.h delete mode 100644 pll/dsi_pll_8996_util.c delete mode 100644 pll/dsi_pll_util.c delete mode 100644 pll/edp_pll_28hpm.c delete mode 100644 pll/hdmi_pll.h delete mode 100644 pll/hdmi_pll_20nm.c delete mode 100644 pll/hdmi_pll_28hpm.c delete mode 100644 pll/hdmi_pll_28lpm.c delete mode 100644 pll/hdmi_pll_8996.c delete mode 100644 pll/hdmi_pll_8998.c delete mode 100644 pll/pll_drv.c delete mode 100644 pll/pll_trace.h delete mode 100644 pll/pll_util.c diff --git a/Makefile b/Makefile index b2829628ff13..f874aa3cb7a9 100644 --- a/Makefile +++ b/Makefile @@ -27,4 +27,3 @@ endif obj-$(CONFIG_DRM_MSM) += msm/ obj-$(CONFIG_MSM_SDE_ROTATOR) += rotator/ -obj-$(CONFIG_QCOM_MDSS_PLL) += pll/ diff --git a/msm/Makefile b/msm/Makefile index 3b4d2259454e..f3ba4a70403d 100644 --- a/msm/Makefile +++ b/msm/Makefile @@ -2,6 +2,7 @@ ccflags-y := -I$(srctree)/include/drm -I$(srctree)/techpack/display/msm -I$(srctree)/techpack/display/msm/dsi -I$(srctree)/techpack/display/msm/dp ccflags-y += -I$(srctree)/techpack/display/msm/sde ccflags-y += -I$(srctree)/techpack/display/rotator +ccflags-y += -I$(srctree)/drivers/clk/qcom/ msm_drm-$(CONFIG_DRM_MSM_DP) += dp/dp_usbpd.o \ dp/dp_parser.o \ @@ -88,6 +89,8 @@ msm_drm-$(CONFIG_DRM_MSM_DSI) += dsi/dsi_phy.o \ dsi/dsi_phy_timing_v2_0.o \ dsi/dsi_phy_timing_v3_0.o \ dsi/dsi_phy_timing_v4_0.o \ + dsi/dsi_pll.o \ + dsi/dsi_pll_5nm.o \ dsi/dsi_ctrl_hw_cmn.o \ dsi/dsi_ctrl_hw_1_4.o \ dsi/dsi_ctrl_hw_2_0.o \ diff --git a/msm/dsi/dsi_catalog.c b/msm/dsi/dsi_catalog.c index 1bc14666da80..7d0434365d18 100644 --- a/msm/dsi/dsi_catalog.c +++ b/msm/dsi/dsi_catalog.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2020, The Linux Foundation. All rights reserved. */ #include @@ -100,6 +100,7 @@ static void dsi_catalog_cmn_init(struct dsi_ctrl_hw *ctrl, case DSI_CTRL_VERSION_2_2: case DSI_CTRL_VERSION_2_3: case DSI_CTRL_VERSION_2_4: + case DSI_CTRL_VERSION_2_5: ctrl->ops.phy_reset_config = dsi_ctrl_hw_22_phy_reset_config; ctrl->ops.config_clk_gating = dsi_ctrl_hw_22_config_clk_gating; ctrl->ops.setup_lane_map = dsi_ctrl_hw_20_setup_lane_map; @@ -163,6 +164,7 @@ int dsi_catalog_ctrl_setup(struct dsi_ctrl_hw *ctrl, case DSI_CTRL_VERSION_2_2: case DSI_CTRL_VERSION_2_3: case DSI_CTRL_VERSION_2_4: + case DSI_CTRL_VERSION_2_5: ctrl->phy_isolation_enabled = phy_isolation_enabled; dsi_catalog_cmn_init(ctrl, version); break; @@ -302,6 +304,7 @@ int dsi_catalog_phy_setup(struct dsi_phy_hw *phy, break; case DSI_PHY_VERSION_4_0: case DSI_PHY_VERSION_4_1: + case DSI_PHY_VERSION_4_2: dsi_catalog_phy_4_0_init(phy); break; case DSI_PHY_VERSION_0_0_HPM: diff --git a/msm/dsi/dsi_ctrl.c b/msm/dsi/dsi_ctrl.c index c3935d60a08f..8de634cc1e94 100644 --- a/msm/dsi/dsi_ctrl.c +++ b/msm/dsi/dsi_ctrl.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. */ #include @@ -53,6 +53,7 @@ static const enum dsi_ctrl_version dsi_ctrl_v2_0 = DSI_CTRL_VERSION_2_0; static const enum dsi_ctrl_version dsi_ctrl_v2_2 = DSI_CTRL_VERSION_2_2; static const enum dsi_ctrl_version dsi_ctrl_v2_3 = DSI_CTRL_VERSION_2_3; static const enum dsi_ctrl_version dsi_ctrl_v2_4 = DSI_CTRL_VERSION_2_4; +static const enum dsi_ctrl_version dsi_ctrl_v2_5 = DSI_CTRL_VERSION_2_5; static const struct of_device_id msm_dsi_of_match[] = { { @@ -75,6 +76,10 @@ static const struct of_device_id msm_dsi_of_match[] = { .compatible = "qcom,dsi-ctrl-hw-v2.4", .data = &dsi_ctrl_v2_4, }, + { + .compatible = "qcom,dsi-ctrl-hw-v2.5", + .data = &dsi_ctrl_v2_5, + }, {} }; @@ -559,6 +564,7 @@ static int dsi_ctrl_init_regmap(struct platform_device *pdev, case DSI_CTRL_VERSION_2_2: case DSI_CTRL_VERSION_2_3: case DSI_CTRL_VERSION_2_4: + case DSI_CTRL_VERSION_2_5: ptr = msm_ioremap(pdev, "disp_cc_base", ctrl->name); if (IS_ERR(ptr)) { DSI_CTRL_ERR(ctrl, "disp_cc base address not found for\n"); @@ -1867,18 +1873,18 @@ static int dsi_ctrl_dev_probe(struct platform_device *pdev) goto fail; } - rc = dsi_ctrl_clocks_init(pdev, dsi_ctrl); - if (rc) { - DSI_CTRL_ERR(dsi_ctrl, "Failed to parse clock information, rc = %d\n", - rc); - goto fail; - } - rc = dsi_ctrl_supplies_init(pdev, dsi_ctrl); if (rc) { DSI_CTRL_ERR(dsi_ctrl, "Failed to parse voltage supplies, rc = %d\n", rc); - goto fail_clks; + goto fail; + } + + rc = dsi_ctrl_clocks_init(pdev, dsi_ctrl); + if (rc) { + DSI_CTRL_ERR(dsi_ctrl, "Failed to parse clock information, rc = %d\n", + rc); + goto fail_supplies; } rc = dsi_catalog_ctrl_setup(&dsi_ctrl->hw, dsi_ctrl->version, @@ -1887,7 +1893,7 @@ static int dsi_ctrl_dev_probe(struct platform_device *pdev) if (rc) { DSI_CTRL_ERR(dsi_ctrl, "Catalog does not support version (%d)\n", dsi_ctrl->version); - goto fail_supplies; + goto fail_clks; } item->ctrl = dsi_ctrl; @@ -1905,10 +1911,10 @@ static int dsi_ctrl_dev_probe(struct platform_device *pdev) return 0; -fail_supplies: - (void)dsi_ctrl_supplies_deinit(dsi_ctrl); fail_clks: (void)dsi_ctrl_clocks_deinit(dsi_ctrl); +fail_supplies: + (void)dsi_ctrl_supplies_deinit(dsi_ctrl); fail: return rc; } diff --git a/msm/dsi/dsi_ctrl_hw.h b/msm/dsi/dsi_ctrl_hw.h index 2f5519229ca2..39ccc73a53a9 100644 --- a/msm/dsi/dsi_ctrl_hw.h +++ b/msm/dsi/dsi_ctrl_hw.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2020, The Linux Foundation. All rights reserved. */ #ifndef _DSI_CTRL_HW_H_ @@ -36,6 +36,7 @@ * @DSI_CTRL_VERSION_2_2: DSI host v2.2 controller * @DSI_CTRL_VERSION_2_3: DSI host v2.3 controller * @DSI_CTRL_VERSION_2_4: DSI host v2.4 controller + * @DSI_CTRL_VERSION_2_5: DSI host v2.5 controller * @DSI_CTRL_VERSION_MAX: max version */ enum dsi_ctrl_version { @@ -45,6 +46,7 @@ enum dsi_ctrl_version { DSI_CTRL_VERSION_2_2, DSI_CTRL_VERSION_2_3, DSI_CTRL_VERSION_2_4, + DSI_CTRL_VERSION_2_5, DSI_CTRL_VERSION_MAX }; diff --git a/msm/dsi/dsi_phy.c b/msm/dsi/dsi_phy.c index abe770101c6b..830016e94f5f 100644 --- a/msm/dsi/dsi_phy.c +++ b/msm/dsi/dsi_phy.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. */ #include @@ -83,6 +83,14 @@ static const struct dsi_ver_spec_info dsi_phy_v4_1 = { .timing_cfg_count = 14, }; +static const struct dsi_ver_spec_info dsi_phy_v4_2 = { + .version = DSI_PHY_VERSION_4_2, + .lane_cfg_count = 4, + .strength_cfg_count = 2, + .regulator_cfg_count = 0, + .timing_cfg_count = 14, +}; + static const struct of_device_id msm_dsi_phy_of_match[] = { { .compatible = "qcom,dsi-phy-v0.0-hpm", .data = &dsi_phy_v0_0_hpm,}, @@ -98,6 +106,8 @@ static const struct of_device_id msm_dsi_phy_of_match[] = { .data = &dsi_phy_v4_0,}, { .compatible = "qcom,dsi-phy-v4.1", .data = &dsi_phy_v4_1,}, + { .compatible = "qcom,dsi-phy-v4.2", + .data = &dsi_phy_v4_2,}, {} }; @@ -422,6 +432,12 @@ static int dsi_phy_driver_probe(struct platform_device *pdev) goto fail_supplies; } + rc = dsi_pll_init(pdev, &dsi_phy->pll); + if (rc) { + DSI_PHY_ERR(dsi_phy, "Failed to initialize DSI PLL, rc=%d\n", rc); + goto fail_settings; + } + item->phy = dsi_phy; mutex_lock(&dsi_phy_list_lock); @@ -435,6 +451,8 @@ static int dsi_phy_driver_probe(struct platform_device *pdev) DSI_PHY_INFO(dsi_phy, "Probe successful\n"); return 0; +fail_settings: + (void)dsi_phy_settings_deinit(dsi_phy); fail_supplies: (void)dsi_phy_supplies_deinit(dsi_phy); fail_regmap: diff --git a/msm/dsi/dsi_phy.h b/msm/dsi/dsi_phy.h index e2e5efd97d3f..10683046121c 100644 --- a/msm/dsi/dsi_phy.h +++ b/msm/dsi/dsi_phy.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. */ #ifndef _DSI_PHY_H_ @@ -10,6 +10,7 @@ #include "dsi_clk.h" #include "dsi_pwr.h" #include "dsi_phy_hw.h" +#include "dsi_pll.h" struct dsi_ver_spec_info { enum dsi_phy_version version; @@ -70,6 +71,7 @@ enum phy_ulps_return_type { * @mode: Current mode. * @data_lanes: Number of data lanes used. * @dst_format: Destination format. + * @pll: Pointer to PLL resource. * @allow_phy_power_off: True if PHY is allowed to power off when idle * @regulator_min_datarate_bps: Minimum per lane data rate to turn on regulator * @regulator_required: True if phy regulator is required @@ -95,6 +97,8 @@ struct msm_dsi_phy { enum dsi_data_lanes data_lanes; enum dsi_pixel_format dst_format; + struct dsi_pll_resource *pll; + bool allow_phy_power_off; u32 regulator_min_datarate_bps; bool regulator_required; diff --git a/msm/dsi/dsi_phy_hw.h b/msm/dsi/dsi_phy_hw.h index 2f5f23920ef7..7700520c24dd 100644 --- a/msm/dsi/dsi_phy_hw.h +++ b/msm/dsi/dsi_phy_hw.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2020, The Linux Foundation. All rights reserved. */ #ifndef _DSI_PHY_HW_H_ @@ -31,6 +31,7 @@ * @DSI_PHY_VERSION_3_0: 10nm * @DSI_PHY_VERSION_4_0: 7nm * @DSI_PHY_VERSION_4_1: 7nm + * @DSI_PHY_VERSION_4_2: 5nm * @DSI_PHY_VERSION_MAX: */ enum dsi_phy_version { @@ -42,6 +43,7 @@ enum dsi_phy_version { DSI_PHY_VERSION_3_0, /* 10nm */ DSI_PHY_VERSION_4_0, /* 7nm */ DSI_PHY_VERSION_4_1, /* 7nm */ + DSI_PHY_VERSION_4_2, /* 5nm */ DSI_PHY_VERSION_MAX }; diff --git a/msm/dsi/dsi_phy_hw_v4_0.c b/msm/dsi/dsi_phy_hw_v4_0.c index ac5e7b0e6eeb..442a9b459908 100644 --- a/msm/dsi/dsi_phy_hw_v4_0.c +++ b/msm/dsi/dsi_phy_hw_v4_0.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. */ #include @@ -156,7 +156,8 @@ static void dsi_phy_hw_v4_0_lane_settings(struct dsi_phy_hw *phy, u8 tx_dctrl_v4_1[] = {0x40, 0x40, 0x40, 0x46, 0x41}; u8 *tx_dctrl; - if (phy->version == DSI_PHY_VERSION_4_1) + if ((phy->version == DSI_PHY_VERSION_4_1) || + (phy->version == DSI_PHY_VERSION_4_2)) tx_dctrl = &tx_dctrl_v4_1[0]; else tx_dctrl = &tx_dctrl_v4[0]; @@ -241,7 +242,13 @@ void dsi_phy_hw_v4_0_enable(struct dsi_phy_hw *phy, if (cfg->bit_clk_rate_hz <= 1500000000) less_than_1500_mhz = true; - if (phy->version == DSI_PHY_VERSION_4_1) { + if (phy->version == DSI_PHY_VERSION_4_2) { + vreg_ctrl_0 = 0x58; + glbl_rescode_top_ctrl = 0x03; + glbl_rescode_bot_ctrl = 0x3c; + glbl_str_swi_cal_sel_ctrl = 0x00; + glbl_hstx_str_ctrl_0 = 0x88; + } else if (phy->version == DSI_PHY_VERSION_4_1) { vreg_ctrl_0 = less_than_1500_mhz ? 0x53 : 0x52; glbl_rescode_top_ctrl = less_than_1500_mhz ? 0x3d : 0x00; glbl_rescode_bot_ctrl = less_than_1500_mhz ? 0x39 : 0x3c; diff --git a/msm/dsi/dsi_phy_timing_calc.c b/msm/dsi/dsi_phy_timing_calc.c index 948e2038de29..c10d986de5ab 100644 --- a/msm/dsi/dsi_phy_timing_calc.c +++ b/msm/dsi/dsi_phy_timing_calc.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. */ #include "dsi_phy_timing_calc.h" @@ -788,6 +788,7 @@ int dsi_phy_timing_calc_init(struct dsi_phy_hw *phy, break; case DSI_PHY_VERSION_4_0: case DSI_PHY_VERSION_4_1: + case DSI_PHY_VERSION_4_2: ops->get_default_phy_params = dsi_phy_hw_v4_0_get_default_phy_params; ops->calc_clk_zero = diff --git a/msm/dsi/dsi_pll.c b/msm/dsi/dsi_pll.c new file mode 100644 index 000000000000..c323bd050f02 --- /dev/null +++ b/msm/dsi/dsi_pll.c @@ -0,0 +1,148 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + */ + +#define pr_fmt(fmt) "%s: " fmt, __func__ + +#include +#include +#include +#include +#include +#include +#include "dsi_pll.h" + +static int dsi_pll_clock_register(struct platform_device *pdev, + struct dsi_pll_resource *pll_res) +{ + int rc; + + switch (pll_res->pll_revision) { + case DSI_PLL_5NM: + rc = dsi_pll_clock_register_5nm(pdev, pll_res); + break; + default: + rc = -EINVAL; + break; + } + + if (rc) + DSI_PLL_ERR(pll_res, "clock register failed rc=%d\n", rc); + + return rc; +} + +static inline int dsi_pll_get_ioresources(struct platform_device *pdev, + void __iomem **regmap, char *resource_name) +{ + int rc = 0; + struct resource *rsc = platform_get_resource_byname(pdev, + IORESOURCE_MEM, resource_name); + if (rsc) { + if (!regmap) + return -ENOMEM; + + *regmap = devm_ioremap(&pdev->dev, + rsc->start, resource_size(rsc)); + if (!*regmap) + return -ENOMEM; + } + return rc; +} + +int dsi_pll_init(struct platform_device *pdev, struct dsi_pll_resource **pll) +{ + int rc = 0; + const char *label; + struct dsi_pll_resource *pll_res = NULL; + + if (!pdev->dev.of_node) { + pr_err("Invalid DSI PHY node\n"); + return -ENOTSUPP; + } + + pll_res = devm_kzalloc(&pdev->dev, sizeof(struct dsi_pll_resource), + GFP_KERNEL); + if (!pll_res) + return -ENOMEM; + + *pll = pll_res; + + label = of_get_property(pdev->dev.of_node, "pll-label", NULL); + if (!label) + DSI_PLL_INFO(pll_res, "DSI pll label not specified\n"); + else + DSI_PLL_INFO(pll_res, "DSI pll label = %s\n", label); + + /** + * Currently, Only supports 5nm PLL version. Will add + * support for other versions as needed. + */ + + if (!strcmp(label, "dsi_pll_5nm")) + pll_res->pll_revision = DSI_PLL_5NM; + else + return -ENOTSUPP; + + rc = of_property_read_u32(pdev->dev.of_node, "cell-index", + &pll_res->index); + if (rc) { + DSI_PLL_ERR(pll_res, "Unable to get the cell-index rc=%d\n", rc); + pll_res->index = 0; + } + + pll_res->ssc_en = of_property_read_bool(pdev->dev.of_node, + "qcom,dsi-pll-ssc-en"); + + if (pll_res->ssc_en) { + DSI_PLL_INFO(pll_res, "PLL SSC enabled\n"); + + rc = of_property_read_u32(pdev->dev.of_node, + "qcom,ssc-frequency-hz", &pll_res->ssc_freq); + + rc = of_property_read_u32(pdev->dev.of_node, + "qcom,ssc-ppm", &pll_res->ssc_ppm); + + pll_res->ssc_center = false; + + label = of_get_property(pdev->dev.of_node, + "qcom,dsi-pll-ssc-mode", NULL); + + if (label && !strcmp(label, "center-spread")) + pll_res->ssc_center = true; + } + + + if (dsi_pll_get_ioresources(pdev, &pll_res->pll_base, "pll_base")) { + DSI_PLL_ERR(pll_res, "Unable to remap pll base resources\n"); + return -ENOMEM; + } + + pr_info("PLL base=%p\n", pll_res->pll_base); + + if (dsi_pll_get_ioresources(pdev, &pll_res->phy_base, "dsi_phy")) { + DSI_PLL_ERR(pll_res, "Unable to remap pll phy base resources\n"); + return -ENOMEM; + } + + if (dsi_pll_get_ioresources(pdev, &pll_res->dyn_pll_base, + "dyn_refresh_base")) { + DSI_PLL_ERR(pll_res, "Unable to remap dynamic pll base resources\n"); + return -ENOMEM; + } + + if (dsi_pll_get_ioresources(pdev, &pll_res->gdsc_base, "gdsc_base")) { + DSI_PLL_ERR(pll_res, "Unable to remap gdsc base resources\n"); + return -ENOMEM; + } + + rc = dsi_pll_clock_register(pdev, pll_res); + if (rc) { + DSI_PLL_ERR(pll_res, "clock register failed rc=%d\n", rc); + return -EINVAL; + } + + return rc; + +} diff --git a/pll/pll_drv.h b/msm/dsi/dsi_pll.h similarity index 58% rename from pll/pll_drv.h rename to msm/dsi/dsi_pll.h index 2f03d860ec72..ba1abbce1b6a 100644 --- a/pll/pll_drv.h +++ b/msm/dsi/dsi_pll.h @@ -1,10 +1,10 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2013-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2020, The Linux Foundation. All rights reserved. */ -#ifndef __MDSS_PLL_H -#define __MDSS_PLL_H +#ifndef __DSI_PLL_H +#define __DSI_PLL_H #include #include @@ -14,47 +14,48 @@ #include "clk-regmap.h" #include "clk-regmap-divider.h" #include "clk-regmap-mux.h" +#include "dsi_defs.h" -#if defined(CONFIG_DRM) -#include -#else -#include -#endif +#define DSI_PLL_DBG(p, fmt, ...) DRM_DEV_DEBUG(NULL, "[msm-dsi-debug]: DSI_PLL_%d: "\ + fmt, p ? p->index : -1, ##__VA_ARGS__) +#define DSI_PLL_ERR(p, fmt, ...) DRM_DEV_ERROR(NULL, "[msm-dsi-error]: DSI_PLL_%d: "\ + fmt, p ? p->index : -1, ##__VA_ARGS__) +#define DSI_PLL_INFO(p, fmt, ...) DRM_DEV_INFO(NULL, "[msm-dsi-info]: DSI_PLL_%d: "\ + fmt, p ? p->index : -1, ##__VA_ARGS__) +#define DSI_PLL_WARN(p, fmt, ...) DRM_WARN("[msm-dsi-warn]: DSI_PLL_%d: "\ + fmt, p ? p->index : -1, ##__VA_ARGS__) -#define MDSS_PLL_REG_W(base, offset, data) \ +#define DSI_PLL_REG_W(base, offset, data) \ writel_relaxed((data), (base) + (offset)) -#define MDSS_PLL_REG_R(base, offset) readl_relaxed((base) + (offset)) +#define DSI_PLL_REG_R(base, offset) readl_relaxed((base) + (offset)) #define PLL_CALC_DATA(addr0, addr1, data0, data1) \ (((data1) << 24) | ((((addr1) / 4) & 0xFF) << 16) | \ ((data0) << 8) | (((addr0) / 4) & 0xFF)) -#define MDSS_DYN_PLL_REG_W(base, offset, addr0, addr1, data0, data1) \ +#define DSI_DYN_PLL_REG_W(base, offset, addr0, addr1, data0, data1) \ writel_relaxed(PLL_CALC_DATA(addr0, addr1, data0, data1), \ (base) + (offset)) #define upper_8_bit(x) ((((x) >> 2) & 0x100) >> 8) -enum { - MDSS_DSI_PLL_10NM, - MDSS_DP_PLL_10NM, - MDSS_DSI_PLL_7NM, - MDSS_DSI_PLL_7NM_V2, - MDSS_DSI_PLL_7NM_V4_1, - MDSS_DP_PLL_7NM, - MDSS_DP_PLL_7NM_V2, - MDSS_DSI_PLL_28LPM, - MDSS_DSI_PLL_14NM, - MDSS_DP_PLL_14NM, - MDSS_HDMI_PLL_28LPM, - MDSS_UNKNOWN_PLL, -}; - -enum { - MDSS_PLL_TARGET_8996, -}; - #define DFPS_MAX_NUM_OF_FRAME_RATES 16 +#define MAX_DSI_PLL_EN_SEQS 10 + +/* Register offsets for 5nm PHY PLL */ +#define MMSS_DSI_PHY_PLL_PLL_CNTRL (0x0014) +#define MMSS_DSI_PHY_PLL_PLL_BKG_KVCO_CAL_EN (0x002C) +#define MMSS_DSI_PHY_PLL_PLLLOCK_CMP_EN (0x009C) + +struct lpfr_cfg { + unsigned long vco_rate; + u32 r; +}; + +enum { + DSI_PLL_5NM, + DSI_UNKNOWN_PLL, +}; struct dfps_pll_codes { uint32_t pll_codes_1; @@ -73,27 +74,17 @@ struct dfps_info { struct dfps_codes_info codes_dfps[DFPS_MAX_NUM_OF_FRAME_RATES]; }; -struct mdss_pll_resources { - - /* Pll specific resources like GPIO, power supply, clocks, etc*/ - struct dss_module_power mp; +struct dsi_pll_resource { /* - * dsi/edp/hmdi plls' base register, phy, gdsc and dynamic refresh + * dsi base register, phy, gdsc and dynamic refresh * register mapping */ void __iomem *pll_base; void __iomem *phy_base; - void __iomem *ln_tx0_base; - void __iomem *ln_tx0_tran_base; - void __iomem *ln_tx0_vmode_base; - void __iomem *ln_tx1_base; - void __iomem *ln_tx1_tran_base; - void __iomem *ln_tx1_vmode_base; void __iomem *gdsc_base; void __iomem *dyn_pll_base; - bool is_init_locked; s64 vco_current_rate; s64 vco_locking_rate; s64 vco_ref_clk_rate; @@ -109,28 +100,13 @@ struct mdss_pll_resources { u32 cached_postdiv1; u32 cached_postdiv3; - u32 cached_vreg_cfg; - /* dsi/edp/hmdi pll interface type */ - u32 pll_interface_type; + u32 pll_revision; - /* - * Target ID. Used in pll_register API for valid target check before - * registering the PLL clocks. - */ - u32 target_id; /* HW recommended delay during configuration of vco clock rate */ u32 vco_delay; - /* Ref-count of the PLL resources */ - u32 resource_ref_cnt; - - /* - * Keep track to resource status to avoid updating same status for the - * pll from different paths - */ - bool resource_enable; /* * Certain plls' do not allow vco rate update if it is on. Keep track of @@ -156,15 +132,6 @@ struct mdss_pll_resources { */ bool reg_upd; - /* - * Notifier callback for MDSS gdsc regulator events - */ - struct notifier_block gdsc_cb; - - /* - * Worker function to call PLL off event - */ - struct work_struct pll_off; /* * PLL index if multiple index are available. Eg. in case of @@ -177,7 +144,7 @@ struct mdss_pll_resources { u32 ssc_freq; u32 ssc_ppm; - struct mdss_pll_resources *slave; + struct dsi_pll_resource *slave; /* * target pll revision information @@ -198,7 +165,21 @@ struct mdss_pll_resources { bool dfps_trigger; }; -struct mdss_pll_vco_calc { +struct dsi_pll_vco_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 { s32 div_frac_start1; s32 div_frac_start2; s32 div_frac_start3; @@ -209,7 +190,7 @@ struct mdss_pll_vco_calc { s64 pll_plllock_cmp3; }; -static inline bool is_gdsc_disabled(struct mdss_pll_resources *pll_res) +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"); @@ -218,7 +199,7 @@ static inline bool is_gdsc_disabled(struct mdss_pll_resources *pll_res) return readl_relaxed(pll_res->gdsc_base) & BIT(31) ? false : true; } -static inline int mdss_pll_div_prepare(struct clk_hw *hw) +static inline int dsi_pll_div_prepare(struct clk_hw *hw) { struct clk_hw *parent_hw = clk_hw_get_parent(hw); /* Restore the divider's value */ @@ -226,24 +207,27 @@ static inline int mdss_pll_div_prepare(struct clk_hw *hw) clk_hw_get_rate(parent_hw)); } -static inline int mdss_set_mux_sel(void *context, unsigned int reg, +static inline int dsi_set_mux_sel(void *context, unsigned int reg, unsigned int val) { return 0; } -static inline int mdss_get_mux_sel(void *context, unsigned int reg, +static inline int dsi_get_mux_sel(void *context, unsigned int reg, unsigned int *val) { *val = 0; return 0; } -int mdss_pll_resource_enable(struct mdss_pll_resources *pll_res, bool enable); -int mdss_pll_util_resource_enable(struct mdss_pll_resources *pll_res, - bool enable); -int mdss_pll_util_resource_parse(struct platform_device *pdev, - struct mdss_pll_resources *pll_res); -struct dss_vreg *mdss_pll_get_mp_by_reg_name(struct mdss_pll_resources *pll_res - , char *name); +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); +} + +int dsi_pll_clock_register_5nm(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 diff --git a/pll/dsi_pll_7nm.c b/msm/dsi/dsi_pll_5nm.c similarity index 67% rename from pll/dsi_pll_7nm.c rename to msm/dsi/dsi_pll_5nm.c index 6eaa7f383b38..271eb76ef732 100644 --- a/pll/dsi_pll_7nm.c +++ b/msm/dsi/dsi_pll_5nm.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. */ #define pr_fmt(fmt) "%s: " fmt, __func__ @@ -9,9 +9,10 @@ #include #include #include +#include +#include #include "dsi_pll.h" -#include "pll_drv.h" -#include +#include #define VCO_DELAY_USEC 1 @@ -275,28 +276,16 @@ struct dsi_pll_config { u32 refclk_cycles; }; -struct dsi_pll_7nm { - struct mdss_pll_resources *rsc; +struct dsi_pll_5nm { + struct dsi_pll_resource *rsc; struct dsi_pll_config pll_configuration; struct dsi_pll_regs reg_setup; }; -static inline bool dsi_pll_7nm_is_hw_revision_v1( - struct mdss_pll_resources *rsc) +static inline bool dsi_pll_5nm_is_hw_revision( + struct dsi_pll_resource *rsc) { - return (rsc->pll_interface_type == MDSS_DSI_PLL_7NM) ? true : false; -} - -static inline bool dsi_pll_7nm_is_hw_revision_v2( - struct mdss_pll_resources *rsc) -{ - return (rsc->pll_interface_type == MDSS_DSI_PLL_7NM_V2) ? true : false; -} - -static inline bool dsi_pll_7nm_is_hw_revision_v4_1( - struct mdss_pll_resources *rsc) -{ - return (rsc->pll_interface_type == MDSS_DSI_PLL_7NM_V4_1) ? + return (rsc->pll_revision == DSI_PLL_5NM) ? true : false; } @@ -305,28 +294,15 @@ static inline int pll_reg_read(void *context, unsigned int reg, { int rc = 0; u32 data; - struct mdss_pll_resources *rsc = context; + struct dsi_pll_resource *rsc = context; - rc = mdss_pll_resource_enable(rsc, true); - if (rc) { - pr_err("Failed to enable dsi pll resources, rc=%d\n", rc); - return rc; - } - - /* - * DSI PHY/PLL should be both powered on when reading PLL - * registers. Since PHY power has been enabled in DSI PHY - * driver, only PLL power is needed to enable here. - */ - data = MDSS_PLL_REG_R(rsc->phy_base, PHY_CMN_CTRL_0); - MDSS_PLL_REG_W(rsc->phy_base, PHY_CMN_CTRL_0, data | BIT(5)); + data = DSI_PLL_REG_R(rsc->phy_base, PHY_CMN_CTRL_0); + DSI_PLL_REG_W(rsc->phy_base, PHY_CMN_CTRL_0, data | BIT(5)); ndelay(250); - *val = MDSS_PLL_REG_R(rsc->pll_base, reg); + *val = DSI_PLL_REG_R(rsc->pll_base, reg); - MDSS_PLL_REG_W(rsc->phy_base, PHY_CMN_CTRL_0, data); - - (void)mdss_pll_resource_enable(rsc, false); + DSI_PLL_REG_W(rsc->phy_base, PHY_CMN_CTRL_0, data); return rc; } @@ -335,16 +311,9 @@ static inline int pll_reg_write(void *context, unsigned int reg, unsigned int val) { int rc = 0; - struct mdss_pll_resources *rsc = context; + struct dsi_pll_resource *rsc = context; - rc = mdss_pll_resource_enable(rsc, true); - if (rc) { - pr_err("Failed to enable dsi pll resources, rc=%d\n", rc); - return rc; - } - - MDSS_PLL_REG_W(rsc->pll_base, reg, val); - (void)mdss_pll_resource_enable(rsc, false); + DSI_PLL_REG_W(rsc->pll_base, reg, val); return rc; } @@ -353,16 +322,9 @@ static inline int phy_reg_read(void *context, unsigned int reg, unsigned int *val) { int rc = 0; - struct mdss_pll_resources *rsc = context; + struct dsi_pll_resource *rsc = context; - rc = mdss_pll_resource_enable(rsc, true); - if (rc) { - pr_err("Failed to enable dsi pll resources, rc=%d\n", rc); - return rc; - } - - *val = MDSS_PLL_REG_R(rsc->phy_base, reg); - (void)mdss_pll_resource_enable(rsc, false); + *val = DSI_PLL_REG_R(rsc->phy_base, reg); return rc; } @@ -371,29 +333,22 @@ static inline int phy_reg_write(void *context, unsigned int reg, unsigned int val) { int rc = 0; - struct mdss_pll_resources *rsc = context; + struct dsi_pll_resource *rsc = context; - rc = mdss_pll_resource_enable(rsc, true); - if (rc) { - pr_err("Failed to enable dsi pll resources, rc=%d\n", rc); - return rc; - } - - MDSS_PLL_REG_W(rsc->phy_base, reg, val); - (void)mdss_pll_resource_enable(rsc, false); + DSI_PLL_REG_W(rsc->phy_base, reg, val); return rc; } -static inline int phy_reg_update_bits_sub(struct mdss_pll_resources *rsc, +static inline int phy_reg_update_bits_sub(struct dsi_pll_resource *rsc, unsigned int reg, unsigned int mask, unsigned int val) { u32 reg_val; - reg_val = MDSS_PLL_REG_R(rsc->phy_base, reg); + reg_val = DSI_PLL_REG_R(rsc->phy_base, reg); reg_val &= ~mask; reg_val |= (val & mask); - MDSS_PLL_REG_W(rsc->phy_base, reg, reg_val); + DSI_PLL_REG_W(rsc->phy_base, reg, reg_val); return 0; } @@ -402,18 +357,11 @@ static inline int phy_reg_update_bits(void *context, unsigned int reg, unsigned int mask, unsigned int val) { int rc = 0; - struct mdss_pll_resources *rsc = context; - - rc = mdss_pll_resource_enable(rsc, true); - if (rc) { - pr_err("Failed to enable dsi pll resources, rc=%d\n", rc); - return rc; - } + struct dsi_pll_resource *rsc = context; rc = phy_reg_update_bits_sub(rsc, reg, mask, val); if (!rc && rsc->slave) rc = phy_reg_update_bits_sub(rsc->slave, reg, mask, val); - (void)mdss_pll_resource_enable(rsc, false); return rc; } @@ -422,29 +370,24 @@ static inline int pclk_mux_read_sel(void *context, unsigned int reg, unsigned int *val) { int rc = 0; - struct mdss_pll_resources *rsc = context; + struct dsi_pll_resource *rsc = context; - rc = mdss_pll_resource_enable(rsc, true); - if (rc) - pr_err("Failed to enable dsi pll resources, rc=%d\n", rc); - else - *val = (MDSS_PLL_REG_R(rsc->phy_base, reg) & 0x3); + *val = (DSI_PLL_REG_R(rsc->phy_base, reg) & 0x3); - (void)mdss_pll_resource_enable(rsc, false); return rc; } -static inline int pclk_mux_write_sel_sub(struct mdss_pll_resources *rsc, +static inline int pclk_mux_write_sel_sub(struct dsi_pll_resource *rsc, unsigned int reg, unsigned int val) { u32 reg_val; - reg_val = MDSS_PLL_REG_R(rsc->phy_base, reg); + reg_val = DSI_PLL_REG_R(rsc->phy_base, reg); reg_val &= ~0x03; reg_val |= val; - MDSS_PLL_REG_W(rsc->phy_base, reg, reg_val); + DSI_PLL_REG_W(rsc->phy_base, reg, reg_val); return 0; } @@ -453,19 +396,12 @@ static inline int pclk_mux_write_sel(void *context, unsigned int reg, unsigned int val) { int rc = 0; - struct mdss_pll_resources *rsc = context; - - rc = mdss_pll_resource_enable(rsc, true); - if (rc) { - pr_err("Failed to enable dsi pll resources, rc=%d\n", rc); - return rc; - } + struct dsi_pll_resource *rsc = context; rc = pclk_mux_write_sel_sub(rsc, reg, val); if (!rc && rsc->slave) rc = pclk_mux_write_sel_sub(rsc->slave, reg, val); - (void)mdss_pll_resource_enable(rsc, false); /* * cache the current parent index for cases where parent @@ -478,13 +414,25 @@ static inline int pclk_mux_write_sel(void *context, unsigned int reg, return rc; } -static struct mdss_pll_resources *pll_rsc_db[DSI_PLL_MAX]; -static struct dsi_pll_7nm plls[DSI_PLL_MAX]; +static int dsi_pll_5nm_get_gdsc_status(struct dsi_pll_resource *rsc) +{ + u32 reg = 0; + bool status; -static void dsi_pll_config_slave(struct mdss_pll_resources *rsc) + reg = DSI_PLL_REG_R(rsc->gdsc_base, 0x0); + status = reg & BIT(31); + pr_err("reg:0x%x status:%d\n", reg, status); + + return status; +} + +static struct dsi_pll_resource *pll_rsc_db[DSI_PLL_MAX]; +static struct dsi_pll_5nm plls[DSI_PLL_MAX]; + +static void dsi_pll_config_slave(struct dsi_pll_resource *rsc) { u32 reg; - struct mdss_pll_resources *orsc = pll_rsc_db[DSI_PLL_1]; + struct dsi_pll_resource *orsc = pll_rsc_db[DSI_PLL_1]; if (!rsc) return; @@ -502,7 +450,7 @@ static void dsi_pll_config_slave(struct mdss_pll_resources *rsc) } /* check to see if the source of DSI1 PLL bitclk is set to external */ - reg = MDSS_PLL_REG_R(orsc->phy_base, PHY_CMN_CLK_CFG1); + reg = DSI_PLL_REG_R(orsc->phy_base, PHY_CMN_CLK_CFG1); reg &= (BIT(2) | BIT(3)); if (reg == 0x04) rsc->slave = pll_rsc_db[DSI_PLL_1]; /* external source */ @@ -510,8 +458,8 @@ static void dsi_pll_config_slave(struct mdss_pll_resources *rsc) pr_debug("Slave PLL %s\n", rsc->slave ? "configured" : "absent"); } -static void dsi_pll_setup_config(struct dsi_pll_7nm *pll, - struct mdss_pll_resources *rsc) +static void dsi_pll_setup_config(struct dsi_pll_5nm *pll, + struct dsi_pll_resource *rsc) { struct dsi_pll_config *config = &pll->pll_configuration; @@ -542,8 +490,8 @@ static void dsi_pll_setup_config(struct dsi_pll_7nm *pll, dsi_pll_config_slave(rsc); } -static void dsi_pll_calc_dec_frac(struct dsi_pll_7nm *pll, - struct mdss_pll_resources *rsc) +static void dsi_pll_calc_dec_frac(struct dsi_pll_5nm *pll, + struct dsi_pll_resource *rsc) { struct dsi_pll_config *config = &pll->pll_configuration; struct dsi_pll_regs *regs = &pll->reg_setup; @@ -567,20 +515,14 @@ static void dsi_pll_calc_dec_frac(struct dsi_pll_7nm *pll, dec = div_u64(dec_multiple, multiplier); - switch (rsc->pll_interface_type) { - case MDSS_DSI_PLL_7NM: - regs->pll_clock_inverters = 0x0; - break; - case MDSS_DSI_PLL_7NM_V2: - regs->pll_clock_inverters = 0x28; - break; - case MDSS_DSI_PLL_7NM_V4_1: + switch (rsc->pll_revision) { + case DSI_PLL_5NM: default: - if (pll_freq <= 1000000000ULL) + if (pll_freq <= 1000000000) regs->pll_clock_inverters = 0xA0; - else if (pll_freq <= 2500000000ULL) + else if (pll_freq <= 2500000000) regs->pll_clock_inverters = 0x20; - else if (pll_freq <= 3020000000ULL) + else if (pll_freq <= 3500000000) regs->pll_clock_inverters = 0x00; else regs->pll_clock_inverters = 0x40; @@ -595,8 +537,8 @@ static void dsi_pll_calc_dec_frac(struct dsi_pll_7nm *pll, regs->pll_prop_gain_rate = 10; } -static void dsi_pll_calc_ssc(struct dsi_pll_7nm *pll, - struct mdss_pll_resources *rsc) +static void dsi_pll_calc_ssc(struct dsi_pll_5nm *pll, + struct dsi_pll_resource *rsc) { struct dsi_pll_config *config = &pll->pll_configuration; struct dsi_pll_regs *regs = &pll->reg_setup; @@ -640,8 +582,8 @@ static void dsi_pll_calc_ssc(struct dsi_pll_7nm *pll, ssc_per, (u32)ssc_step_size, config->ssc_adj_per); } -static void dsi_pll_ssc_commit(struct dsi_pll_7nm *pll, - struct mdss_pll_resources *rsc) +static void dsi_pll_ssc_commit(struct dsi_pll_5nm *pll, + struct dsi_pll_resource *rsc) { void __iomem *pll_base = rsc->pll_base; struct dsi_pll_regs *regs = &pll->reg_setup; @@ -649,269 +591,249 @@ static void dsi_pll_ssc_commit(struct dsi_pll_7nm *pll, if (pll->pll_configuration.enable_ssc) { pr_debug("SSC is enabled\n"); - MDSS_PLL_REG_W(pll_base, PLL_SSC_STEPSIZE_LOW_1, + DSI_PLL_REG_W(pll_base, PLL_SSC_STEPSIZE_LOW_1, regs->ssc_stepsize_low); - MDSS_PLL_REG_W(pll_base, PLL_SSC_STEPSIZE_HIGH_1, + DSI_PLL_REG_W(pll_base, PLL_SSC_STEPSIZE_HIGH_1, regs->ssc_stepsize_high); - MDSS_PLL_REG_W(pll_base, PLL_SSC_DIV_PER_LOW_1, + DSI_PLL_REG_W(pll_base, PLL_SSC_DIV_PER_LOW_1, regs->ssc_div_per_low); - MDSS_PLL_REG_W(pll_base, PLL_SSC_DIV_PER_HIGH_1, + DSI_PLL_REG_W(pll_base, PLL_SSC_DIV_PER_HIGH_1, regs->ssc_div_per_high); - MDSS_PLL_REG_W(pll_base, PLL_SSC_ADJPER_LOW_1, + DSI_PLL_REG_W(pll_base, PLL_SSC_ADJPER_LOW_1, regs->ssc_adjper_low); - MDSS_PLL_REG_W(pll_base, PLL_SSC_ADJPER_HIGH_1, + DSI_PLL_REG_W(pll_base, PLL_SSC_ADJPER_HIGH_1, regs->ssc_adjper_high); - MDSS_PLL_REG_W(pll_base, PLL_SSC_CONTROL, + DSI_PLL_REG_W(pll_base, PLL_SSC_CONTROL, SSC_EN | regs->ssc_control); } } -static void dsi_pll_config_hzindep_reg(struct dsi_pll_7nm *pll, - struct mdss_pll_resources *rsc) +static void dsi_pll_config_hzindep_reg(struct dsi_pll_5nm *pll, + struct dsi_pll_resource *rsc) { void __iomem *pll_base = rsc->pll_base; u64 vco_rate = rsc->vco_current_rate; - switch (rsc->pll_interface_type) { - case MDSS_DSI_PLL_7NM: - case MDSS_DSI_PLL_7NM_V2: - MDSS_PLL_REG_W(pll_base, PLL_ANALOG_CONTROLS_FIVE_1, 0x01); - MDSS_PLL_REG_W(pll_base, PLL_VCO_CONFIG_1, 0x00); - break; - case MDSS_DSI_PLL_7NM_V4_1: + switch (rsc->pll_revision) { + case DSI_PLL_5NM: default: - if (vco_rate < 3100000000ULL) - MDSS_PLL_REG_W(pll_base, + if (vco_rate < 3100000000) + DSI_PLL_REG_W(pll_base, PLL_ANALOG_CONTROLS_FIVE_1, 0x01); else - MDSS_PLL_REG_W(pll_base, + DSI_PLL_REG_W(pll_base, PLL_ANALOG_CONTROLS_FIVE_1, 0x03); - if (vco_rate < 1520000000ULL) - MDSS_PLL_REG_W(pll_base, PLL_VCO_CONFIG_1, 0x08); - else if (vco_rate < 2990000000ULL) - MDSS_PLL_REG_W(pll_base, PLL_VCO_CONFIG_1, 0x01); + if (vco_rate < 1520000000) + DSI_PLL_REG_W(pll_base, PLL_VCO_CONFIG_1, 0x08); + else if (vco_rate < 2990000000) + DSI_PLL_REG_W(pll_base, PLL_VCO_CONFIG_1, 0x00); else - MDSS_PLL_REG_W(pll_base, PLL_VCO_CONFIG_1, 0x00); + DSI_PLL_REG_W(pll_base, PLL_VCO_CONFIG_1, 0x01); break; } - if (dsi_pll_7nm_is_hw_revision_v1(rsc)) - MDSS_PLL_REG_W(pll_base, PLL_GEAR_BAND_SELECT_CONTROLS, 0x21); + DSI_PLL_REG_W(pll_base, PLL_ANALOG_CONTROLS_FIVE, 0x01); + DSI_PLL_REG_W(pll_base, PLL_ANALOG_CONTROLS_TWO, 0x03); + DSI_PLL_REG_W(pll_base, PLL_ANALOG_CONTROLS_THREE, 0x00); + DSI_PLL_REG_W(pll_base, PLL_DSM_DIVIDER, 0x00); + DSI_PLL_REG_W(pll_base, PLL_FEEDBACK_DIVIDER, 0x4e); + DSI_PLL_REG_W(pll_base, PLL_CALIBRATION_SETTINGS, 0x40); + DSI_PLL_REG_W(pll_base, PLL_BAND_SEL_CAL_SETTINGS_THREE, 0xba); + DSI_PLL_REG_W(pll_base, PLL_FREQ_DETECT_SETTINGS_ONE, 0x0c); + DSI_PLL_REG_W(pll_base, PLL_OUTDIV, 0x00); + DSI_PLL_REG_W(pll_base, PLL_CORE_OVERRIDE, 0x00); + DSI_PLL_REG_W(pll_base, PLL_PLL_DIGITAL_TIMERS_TWO, 0x08); + DSI_PLL_REG_W(pll_base, PLL_PLL_PROP_GAIN_RATE_1, 0x0a); + DSI_PLL_REG_W(pll_base, PLL_PLL_BAND_SEL_RATE_1, 0xc0); + DSI_PLL_REG_W(pll_base, PLL_PLL_INT_GAIN_IFILT_BAND_1, 0x84); + DSI_PLL_REG_W(pll_base, PLL_PLL_INT_GAIN_IFILT_BAND_1, 0x82); + DSI_PLL_REG_W(pll_base, PLL_PLL_FL_INT_GAIN_PFILT_BAND_1, 0x4c); + DSI_PLL_REG_W(pll_base, PLL_PLL_LOCK_OVERRIDE, 0x80); + DSI_PLL_REG_W(pll_base, PLL_PFILT, 0x29); + DSI_PLL_REG_W(pll_base, PLL_PFILT, 0x2f); + DSI_PLL_REG_W(pll_base, PLL_IFILT, 0x2a); - MDSS_PLL_REG_W(pll_base, PLL_ANALOG_CONTROLS_FIVE, 0x01); - MDSS_PLL_REG_W(pll_base, PLL_ANALOG_CONTROLS_TWO, 0x03); - MDSS_PLL_REG_W(pll_base, PLL_ANALOG_CONTROLS_THREE, 0x00); - MDSS_PLL_REG_W(pll_base, PLL_DSM_DIVIDER, 0x00); - MDSS_PLL_REG_W(pll_base, PLL_FEEDBACK_DIVIDER, 0x4e); - MDSS_PLL_REG_W(pll_base, PLL_CALIBRATION_SETTINGS, 0x40); - MDSS_PLL_REG_W(pll_base, PLL_BAND_SEL_CAL_SETTINGS_THREE, 0xba); - MDSS_PLL_REG_W(pll_base, PLL_FREQ_DETECT_SETTINGS_ONE, 0x0c); - MDSS_PLL_REG_W(pll_base, PLL_OUTDIV, 0x00); - MDSS_PLL_REG_W(pll_base, PLL_CORE_OVERRIDE, 0x00); - MDSS_PLL_REG_W(pll_base, PLL_PLL_DIGITAL_TIMERS_TWO, 0x08); - MDSS_PLL_REG_W(pll_base, PLL_PLL_PROP_GAIN_RATE_1, 0x0a); - MDSS_PLL_REG_W(pll_base, PLL_PLL_BAND_SEL_RATE_1, 0xc0); - MDSS_PLL_REG_W(pll_base, PLL_PLL_INT_GAIN_IFILT_BAND_1, 0x84); - MDSS_PLL_REG_W(pll_base, PLL_PLL_INT_GAIN_IFILT_BAND_1, 0x82); - MDSS_PLL_REG_W(pll_base, PLL_PLL_FL_INT_GAIN_PFILT_BAND_1, 0x4c); - MDSS_PLL_REG_W(pll_base, PLL_PLL_LOCK_OVERRIDE, 0x80); - MDSS_PLL_REG_W(pll_base, PLL_PFILT, 0x29); - MDSS_PLL_REG_W(pll_base, PLL_PFILT, 0x2f); - MDSS_PLL_REG_W(pll_base, PLL_IFILT, 0x2a); - - switch (rsc->pll_interface_type) { - case MDSS_DSI_PLL_7NM: - MDSS_PLL_REG_W(pll_base, PLL_IFILT, 0x30); - break; - case MDSS_DSI_PLL_7NM_V2: - MDSS_PLL_REG_W(pll_base, PLL_IFILT, 0x22); - break; - case MDSS_DSI_PLL_7NM_V4_1: + switch (rsc->pll_revision) { + case DSI_PLL_5NM: default: - MDSS_PLL_REG_W(pll_base, PLL_IFILT, 0x3F); + DSI_PLL_REG_W(pll_base, PLL_IFILT, 0x3F); break; } - if (dsi_pll_7nm_is_hw_revision_v4_1(rsc)) { - MDSS_PLL_REG_W(pll_base, PLL_PERF_OPTIMIZE, 0x22); - if (rsc->slave) - MDSS_PLL_REG_W(rsc->slave->pll_base, PLL_PERF_OPTIMIZE, 0x22); - } + DSI_PLL_REG_W(pll_base, PLL_PERF_OPTIMIZE, 0x22); + if (rsc->slave) + DSI_PLL_REG_W(rsc->slave->pll_base, PLL_PERF_OPTIMIZE, 0x22); } -static void dsi_pll_init_val(struct mdss_pll_resources *rsc) +static void dsi_pll_init_val(struct dsi_pll_resource *rsc) { void __iomem *pll_base = rsc->pll_base; - MDSS_PLL_REG_W(pll_base, PLL_ANALOG_CONTROLS_ONE, 0x00000000); - MDSS_PLL_REG_W(pll_base, PLL_INT_LOOP_SETTINGS, 0x0000003F); - MDSS_PLL_REG_W(pll_base, PLL_INT_LOOP_SETTINGS_TWO, 0x00000000); - MDSS_PLL_REG_W(pll_base, PLL_ANALOG_CONTROLS_FOUR, 0x00000000); - MDSS_PLL_REG_W(pll_base, PLL_INT_LOOP_CONTROLS, 0x00000080); - MDSS_PLL_REG_W(pll_base, PLL_SYSTEM_MUXES, 0x00000000); - MDSS_PLL_REG_W(pll_base, PLL_FREQ_UPDATE_CONTROL_OVERRIDES, 0x00000000); - MDSS_PLL_REG_W(pll_base, PLL_CMODE, 0x00000010); - MDSS_PLL_REG_W(pll_base, PLL_PSM_CTRL, 0x00000020); - MDSS_PLL_REG_W(pll_base, PLL_RSM_CTRL, 0x00000010); - MDSS_PLL_REG_W(pll_base, PLL_VCO_TUNE_MAP, 0x00000002); - MDSS_PLL_REG_W(pll_base, PLL_PLL_CNTRL, 0x0000001C); - MDSS_PLL_REG_W(pll_base, PLL_BAND_SEL_CAL_TIMER_LOW, 0x00000000); - MDSS_PLL_REG_W(pll_base, PLL_BAND_SEL_CAL_TIMER_HIGH, 0x00000002); - MDSS_PLL_REG_W(pll_base, PLL_BAND_SEL_CAL_SETTINGS, 0x00000020); - MDSS_PLL_REG_W(pll_base, PLL_BAND_SEL_MIN, 0x00000000); - MDSS_PLL_REG_W(pll_base, PLL_BAND_SEL_MAX, 0x000000FF); - MDSS_PLL_REG_W(pll_base, PLL_BAND_SEL_PFILT, 0x00000000); - MDSS_PLL_REG_W(pll_base, PLL_BAND_SEL_IFILT, 0x0000000A); - MDSS_PLL_REG_W(pll_base, PLL_BAND_SEL_CAL_SETTINGS_TWO, 0x00000025); - MDSS_PLL_REG_W(pll_base, PLL_BAND_SEL_CAL_SETTINGS_THREE, 0x000000BA); - MDSS_PLL_REG_W(pll_base, PLL_BAND_SEL_CAL_SETTINGS_FOUR, 0x0000004F); - MDSS_PLL_REG_W(pll_base, PLL_BAND_SEL_ICODE_HIGH, 0x0000000A); - MDSS_PLL_REG_W(pll_base, PLL_BAND_SEL_ICODE_LOW, 0x00000000); - MDSS_PLL_REG_W(pll_base, PLL_FREQ_DETECT_SETTINGS_ONE, 0x0000000C); - MDSS_PLL_REG_W(pll_base, PLL_FREQ_DETECT_THRESH, 0x00000020); - MDSS_PLL_REG_W(pll_base, PLL_FREQ_DET_REFCLK_HIGH, 0x00000000); - MDSS_PLL_REG_W(pll_base, PLL_FREQ_DET_REFCLK_LOW, 0x000000FF); - MDSS_PLL_REG_W(pll_base, PLL_FREQ_DET_PLLCLK_HIGH, 0x00000010); - MDSS_PLL_REG_W(pll_base, PLL_FREQ_DET_PLLCLK_LOW, 0x00000046); - MDSS_PLL_REG_W(pll_base, PLL_PLL_GAIN, 0x00000054); - MDSS_PLL_REG_W(pll_base, PLL_ICODE_LOW, 0x00000000); - MDSS_PLL_REG_W(pll_base, PLL_ICODE_HIGH, 0x00000000); - MDSS_PLL_REG_W(pll_base, PLL_LOCKDET, 0x00000040); - MDSS_PLL_REG_W(pll_base, PLL_FASTLOCK_CONTROL, 0x00000004); - MDSS_PLL_REG_W(pll_base, PLL_PASS_OUT_OVERRIDE_ONE, 0x00000000); - MDSS_PLL_REG_W(pll_base, PLL_PASS_OUT_OVERRIDE_TWO, 0x00000000); - MDSS_PLL_REG_W(pll_base, PLL_CORE_OVERRIDE, 0x00000000); - MDSS_PLL_REG_W(pll_base, PLL_CORE_INPUT_OVERRIDE, 0x00000010); - MDSS_PLL_REG_W(pll_base, PLL_RATE_CHANGE, 0x00000000); - MDSS_PLL_REG_W(pll_base, PLL_PLL_DIGITAL_TIMERS, 0x00000008); - MDSS_PLL_REG_W(pll_base, PLL_PLL_DIGITAL_TIMERS_TWO, 0x00000008); - MDSS_PLL_REG_W(pll_base, PLL_DEC_FRAC_MUXES, 0x00000000); - MDSS_PLL_REG_W(pll_base, PLL_MASH_CONTROL, 0x00000003); - MDSS_PLL_REG_W(pll_base, PLL_SSC_STEPSIZE_LOW, 0x00000000); - MDSS_PLL_REG_W(pll_base, PLL_SSC_STEPSIZE_HIGH, 0x00000000); - MDSS_PLL_REG_W(pll_base, PLL_SSC_DIV_PER_LOW, 0x00000000); - MDSS_PLL_REG_W(pll_base, PLL_SSC_DIV_PER_HIGH, 0x00000000); - MDSS_PLL_REG_W(pll_base, PLL_SSC_ADJPER_LOW, 0x00000000); - MDSS_PLL_REG_W(pll_base, PLL_SSC_ADJPER_HIGH, 0x00000000); - MDSS_PLL_REG_W(pll_base, PLL_SSC_MUX_CONTROL, 0x00000000); - MDSS_PLL_REG_W(pll_base, PLL_SSC_STEPSIZE_LOW_1, 0x00000000); - MDSS_PLL_REG_W(pll_base, PLL_SSC_STEPSIZE_HIGH_1, 0x00000000); - MDSS_PLL_REG_W(pll_base, PLL_SSC_DIV_PER_LOW_1, 0x00000000); - MDSS_PLL_REG_W(pll_base, PLL_SSC_DIV_PER_HIGH_1, 0x00000000); - MDSS_PLL_REG_W(pll_base, PLL_SSC_ADJPER_LOW_1, 0x00000000); - MDSS_PLL_REG_W(pll_base, PLL_SSC_ADJPER_HIGH_1, 0x00000000); - MDSS_PLL_REG_W(pll_base, PLL_SSC_STEPSIZE_LOW_2, 0x00000000); - MDSS_PLL_REG_W(pll_base, PLL_SSC_STEPSIZE_HIGH_2, 0x00000000); - MDSS_PLL_REG_W(pll_base, PLL_SSC_DIV_PER_LOW_2, 0x00000000); - MDSS_PLL_REG_W(pll_base, PLL_SSC_DIV_PER_HIGH_2, 0x00000000); - MDSS_PLL_REG_W(pll_base, PLL_SSC_ADJPER_LOW_2, 0x00000000); - MDSS_PLL_REG_W(pll_base, PLL_SSC_ADJPER_HIGH_2, 0x00000000); - MDSS_PLL_REG_W(pll_base, PLL_SSC_CONTROL, 0x00000000); - MDSS_PLL_REG_W(pll_base, PLL_PLL_OUTDIV_RATE, 0x00000000); - MDSS_PLL_REG_W(pll_base, PLL_PLL_LOCKDET_RATE_1, 0x00000040); - MDSS_PLL_REG_W(pll_base, PLL_PLL_LOCKDET_RATE_2, 0x00000040); - MDSS_PLL_REG_W(pll_base, PLL_PLL_PROP_GAIN_RATE_1, 0x0000000C); - MDSS_PLL_REG_W(pll_base, PLL_PLL_PROP_GAIN_RATE_2, 0x0000000A); - MDSS_PLL_REG_W(pll_base, PLL_PLL_BAND_SEL_RATE_1, 0x000000C0); - MDSS_PLL_REG_W(pll_base, PLL_PLL_BAND_SEL_RATE_2, 0x00000000); - MDSS_PLL_REG_W(pll_base, PLL_PLL_INT_GAIN_IFILT_BAND_1, 0x00000054); - MDSS_PLL_REG_W(pll_base, PLL_PLL_INT_GAIN_IFILT_BAND_2, 0x00000054); - MDSS_PLL_REG_W(pll_base, PLL_PLL_FL_INT_GAIN_PFILT_BAND_1, 0x0000004C); - MDSS_PLL_REG_W(pll_base, PLL_PLL_FL_INT_GAIN_PFILT_BAND_2, 0x0000004C); - MDSS_PLL_REG_W(pll_base, PLL_PLL_FASTLOCK_EN_BAND, 0x00000003); - MDSS_PLL_REG_W(pll_base, PLL_FREQ_TUNE_ACCUM_INIT_MID, 0x00000000); - MDSS_PLL_REG_W(pll_base, PLL_FREQ_TUNE_ACCUM_INIT_HIGH, 0x00000000); - MDSS_PLL_REG_W(pll_base, PLL_FREQ_TUNE_ACCUM_INIT_MUX, 0x00000000); - MDSS_PLL_REG_W(pll_base, PLL_PLL_LOCK_OVERRIDE, 0x00000080); - MDSS_PLL_REG_W(pll_base, PLL_PLL_LOCK_DELAY, 0x00000006); - MDSS_PLL_REG_W(pll_base, PLL_PLL_LOCK_MIN_DELAY, 0x00000019); - MDSS_PLL_REG_W(pll_base, PLL_CLOCK_INVERTERS, 0x00000000); - MDSS_PLL_REG_W(pll_base, PLL_SPARE_AND_JPC_OVERRIDES, 0x00000000); + DSI_PLL_REG_W(pll_base, PLL_ANALOG_CONTROLS_ONE, 0x00000000); + DSI_PLL_REG_W(pll_base, PLL_INT_LOOP_SETTINGS, 0x0000003F); + DSI_PLL_REG_W(pll_base, PLL_INT_LOOP_SETTINGS_TWO, 0x00000000); + DSI_PLL_REG_W(pll_base, PLL_ANALOG_CONTROLS_FOUR, 0x00000000); + DSI_PLL_REG_W(pll_base, PLL_INT_LOOP_CONTROLS, 0x00000080); + DSI_PLL_REG_W(pll_base, PLL_SYSTEM_MUXES, 0x00000000); + DSI_PLL_REG_W(pll_base, PLL_FREQ_UPDATE_CONTROL_OVERRIDES, 0x00000000); + DSI_PLL_REG_W(pll_base, PLL_CMODE, 0x00000010); + DSI_PLL_REG_W(pll_base, PLL_PSM_CTRL, 0x00000020); + DSI_PLL_REG_W(pll_base, PLL_RSM_CTRL, 0x00000010); + DSI_PLL_REG_W(pll_base, PLL_VCO_TUNE_MAP, 0x00000002); + DSI_PLL_REG_W(pll_base, PLL_PLL_CNTRL, 0x0000001C); + DSI_PLL_REG_W(pll_base, PLL_BAND_SEL_CAL_TIMER_LOW, 0x00000000); + DSI_PLL_REG_W(pll_base, PLL_BAND_SEL_CAL_TIMER_HIGH, 0x00000002); + DSI_PLL_REG_W(pll_base, PLL_BAND_SEL_CAL_SETTINGS, 0x00000020); + DSI_PLL_REG_W(pll_base, PLL_BAND_SEL_MIN, 0x00000000); + DSI_PLL_REG_W(pll_base, PLL_BAND_SEL_MAX, 0x000000FF); + DSI_PLL_REG_W(pll_base, PLL_BAND_SEL_PFILT, 0x00000000); + DSI_PLL_REG_W(pll_base, PLL_BAND_SEL_IFILT, 0x0000000A); + DSI_PLL_REG_W(pll_base, PLL_BAND_SEL_CAL_SETTINGS_TWO, 0x00000025); + DSI_PLL_REG_W(pll_base, PLL_BAND_SEL_CAL_SETTINGS_THREE, 0x000000BA); + DSI_PLL_REG_W(pll_base, PLL_BAND_SEL_CAL_SETTINGS_FOUR, 0x0000004F); + DSI_PLL_REG_W(pll_base, PLL_BAND_SEL_ICODE_HIGH, 0x0000000A); + DSI_PLL_REG_W(pll_base, PLL_BAND_SEL_ICODE_LOW, 0x00000000); + DSI_PLL_REG_W(pll_base, PLL_FREQ_DETECT_SETTINGS_ONE, 0x0000000C); + DSI_PLL_REG_W(pll_base, PLL_FREQ_DETECT_THRESH, 0x00000020); + DSI_PLL_REG_W(pll_base, PLL_FREQ_DET_REFCLK_HIGH, 0x00000000); + DSI_PLL_REG_W(pll_base, PLL_FREQ_DET_REFCLK_LOW, 0x000000FF); + DSI_PLL_REG_W(pll_base, PLL_FREQ_DET_PLLCLK_HIGH, 0x00000010); + DSI_PLL_REG_W(pll_base, PLL_FREQ_DET_PLLCLK_LOW, 0x00000046); + DSI_PLL_REG_W(pll_base, PLL_PLL_GAIN, 0x00000054); + DSI_PLL_REG_W(pll_base, PLL_ICODE_LOW, 0x00000000); + DSI_PLL_REG_W(pll_base, PLL_ICODE_HIGH, 0x00000000); + DSI_PLL_REG_W(pll_base, PLL_LOCKDET, 0x00000040); + DSI_PLL_REG_W(pll_base, PLL_FASTLOCK_CONTROL, 0x00000004); + DSI_PLL_REG_W(pll_base, PLL_PASS_OUT_OVERRIDE_ONE, 0x00000000); + DSI_PLL_REG_W(pll_base, PLL_PASS_OUT_OVERRIDE_TWO, 0x00000000); + DSI_PLL_REG_W(pll_base, PLL_CORE_OVERRIDE, 0x00000000); + DSI_PLL_REG_W(pll_base, PLL_CORE_INPUT_OVERRIDE, 0x00000010); + DSI_PLL_REG_W(pll_base, PLL_RATE_CHANGE, 0x00000000); + DSI_PLL_REG_W(pll_base, PLL_PLL_DIGITAL_TIMERS, 0x00000008); + DSI_PLL_REG_W(pll_base, PLL_PLL_DIGITAL_TIMERS_TWO, 0x00000008); + DSI_PLL_REG_W(pll_base, PLL_DEC_FRAC_MUXES, 0x00000000); + DSI_PLL_REG_W(pll_base, PLL_MASH_CONTROL, 0x00000003); + DSI_PLL_REG_W(pll_base, PLL_SSC_STEPSIZE_LOW, 0x00000000); + DSI_PLL_REG_W(pll_base, PLL_SSC_STEPSIZE_HIGH, 0x00000000); + DSI_PLL_REG_W(pll_base, PLL_SSC_DIV_PER_LOW, 0x00000000); + DSI_PLL_REG_W(pll_base, PLL_SSC_DIV_PER_HIGH, 0x00000000); + DSI_PLL_REG_W(pll_base, PLL_SSC_ADJPER_LOW, 0x00000000); + DSI_PLL_REG_W(pll_base, PLL_SSC_ADJPER_HIGH, 0x00000000); + DSI_PLL_REG_W(pll_base, PLL_SSC_MUX_CONTROL, 0x00000000); + DSI_PLL_REG_W(pll_base, PLL_SSC_STEPSIZE_LOW_1, 0x00000000); + DSI_PLL_REG_W(pll_base, PLL_SSC_STEPSIZE_HIGH_1, 0x00000000); + DSI_PLL_REG_W(pll_base, PLL_SSC_DIV_PER_LOW_1, 0x00000000); + DSI_PLL_REG_W(pll_base, PLL_SSC_DIV_PER_HIGH_1, 0x00000000); + DSI_PLL_REG_W(pll_base, PLL_SSC_ADJPER_LOW_1, 0x00000000); + DSI_PLL_REG_W(pll_base, PLL_SSC_ADJPER_HIGH_1, 0x00000000); + DSI_PLL_REG_W(pll_base, PLL_SSC_STEPSIZE_LOW_2, 0x00000000); + DSI_PLL_REG_W(pll_base, PLL_SSC_STEPSIZE_HIGH_2, 0x00000000); + DSI_PLL_REG_W(pll_base, PLL_SSC_DIV_PER_LOW_2, 0x00000000); + DSI_PLL_REG_W(pll_base, PLL_SSC_DIV_PER_HIGH_2, 0x00000000); + DSI_PLL_REG_W(pll_base, PLL_SSC_ADJPER_LOW_2, 0x00000000); + DSI_PLL_REG_W(pll_base, PLL_SSC_ADJPER_HIGH_2, 0x00000000); + DSI_PLL_REG_W(pll_base, PLL_SSC_CONTROL, 0x00000000); + DSI_PLL_REG_W(pll_base, PLL_PLL_OUTDIV_RATE, 0x00000000); + DSI_PLL_REG_W(pll_base, PLL_PLL_LOCKDET_RATE_1, 0x00000040); + DSI_PLL_REG_W(pll_base, PLL_PLL_LOCKDET_RATE_2, 0x00000040); + DSI_PLL_REG_W(pll_base, PLL_PLL_PROP_GAIN_RATE_1, 0x0000000C); + DSI_PLL_REG_W(pll_base, PLL_PLL_PROP_GAIN_RATE_2, 0x0000000A); + DSI_PLL_REG_W(pll_base, PLL_PLL_BAND_SEL_RATE_1, 0x000000C0); + DSI_PLL_REG_W(pll_base, PLL_PLL_BAND_SEL_RATE_2, 0x00000000); + DSI_PLL_REG_W(pll_base, PLL_PLL_INT_GAIN_IFILT_BAND_1, 0x00000054); + DSI_PLL_REG_W(pll_base, PLL_PLL_INT_GAIN_IFILT_BAND_2, 0x00000054); + DSI_PLL_REG_W(pll_base, PLL_PLL_FL_INT_GAIN_PFILT_BAND_1, 0x0000004C); + DSI_PLL_REG_W(pll_base, PLL_PLL_FL_INT_GAIN_PFILT_BAND_2, 0x0000004C); + DSI_PLL_REG_W(pll_base, PLL_PLL_FASTLOCK_EN_BAND, 0x00000003); + DSI_PLL_REG_W(pll_base, PLL_FREQ_TUNE_ACCUM_INIT_MID, 0x00000000); + DSI_PLL_REG_W(pll_base, PLL_FREQ_TUNE_ACCUM_INIT_HIGH, 0x00000000); + DSI_PLL_REG_W(pll_base, PLL_FREQ_TUNE_ACCUM_INIT_MUX, 0x00000000); + DSI_PLL_REG_W(pll_base, PLL_PLL_LOCK_OVERRIDE, 0x00000080); + DSI_PLL_REG_W(pll_base, PLL_PLL_LOCK_DELAY, 0x00000006); + DSI_PLL_REG_W(pll_base, PLL_PLL_LOCK_MIN_DELAY, 0x00000019); + DSI_PLL_REG_W(pll_base, PLL_CLOCK_INVERTERS, 0x00000000); + DSI_PLL_REG_W(pll_base, PLL_SPARE_AND_JPC_OVERRIDES, 0x00000000); - if (dsi_pll_7nm_is_hw_revision_v1(rsc)) - MDSS_PLL_REG_W(pll_base, PLL_BIAS_CONTROL_1, 0x00000066); - else - MDSS_PLL_REG_W(pll_base, PLL_BIAS_CONTROL_1, 0x00000040); + DSI_PLL_REG_W(pll_base, PLL_BIAS_CONTROL_1, 0x00000040); - MDSS_PLL_REG_W(pll_base, PLL_BIAS_CONTROL_2, 0x00000020); - MDSS_PLL_REG_W(pll_base, PLL_ALOG_OBSV_BUS_CTRL_1, 0x00000000); - MDSS_PLL_REG_W(pll_base, PLL_COMMON_STATUS_ONE, 0x00000000); - MDSS_PLL_REG_W(pll_base, PLL_COMMON_STATUS_TWO, 0x00000000); - MDSS_PLL_REG_W(pll_base, PLL_BAND_SEL_CAL, 0x00000000); - MDSS_PLL_REG_W(pll_base, PLL_ICODE_ACCUM_STATUS_LOW, 0x00000000); - MDSS_PLL_REG_W(pll_base, PLL_ICODE_ACCUM_STATUS_HIGH, 0x00000000); - MDSS_PLL_REG_W(pll_base, PLL_FD_OUT_LOW, 0x00000000); - MDSS_PLL_REG_W(pll_base, PLL_FD_OUT_HIGH, 0x00000000); - MDSS_PLL_REG_W(pll_base, PLL_ALOG_OBSV_BUS_STATUS_1, 0x00000000); - MDSS_PLL_REG_W(pll_base, PLL_PLL_MISC_CONFIG, 0x00000000); - MDSS_PLL_REG_W(pll_base, PLL_FLL_CONFIG, 0x00000002); - MDSS_PLL_REG_W(pll_base, PLL_FLL_FREQ_ACQ_TIME, 0x00000011); - MDSS_PLL_REG_W(pll_base, PLL_FLL_CODE0, 0x00000000); - MDSS_PLL_REG_W(pll_base, PLL_FLL_CODE1, 0x00000000); - MDSS_PLL_REG_W(pll_base, PLL_FLL_GAIN0, 0x00000080); - MDSS_PLL_REG_W(pll_base, PLL_FLL_GAIN1, 0x00000000); - MDSS_PLL_REG_W(pll_base, PLL_SW_RESET, 0x00000000); - MDSS_PLL_REG_W(pll_base, PLL_FAST_PWRUP, 0x00000000); - MDSS_PLL_REG_W(pll_base, PLL_LOCKTIME0, 0x00000000); - MDSS_PLL_REG_W(pll_base, PLL_LOCKTIME1, 0x00000000); - MDSS_PLL_REG_W(pll_base, PLL_DEBUG_BUS_SEL, 0x00000000); - MDSS_PLL_REG_W(pll_base, PLL_DEBUG_BUS0, 0x00000000); - MDSS_PLL_REG_W(pll_base, PLL_DEBUG_BUS1, 0x00000000); - MDSS_PLL_REG_W(pll_base, PLL_DEBUG_BUS2, 0x00000000); - MDSS_PLL_REG_W(pll_base, PLL_DEBUG_BUS3, 0x00000000); - MDSS_PLL_REG_W(pll_base, PLL_ANALOG_FLL_CONTROL_OVERRIDES, 0x00000000); - MDSS_PLL_REG_W(pll_base, PLL_VCO_CONFIG, 0x00000000); - MDSS_PLL_REG_W(pll_base, PLL_VCO_CAL_CODE1_MODE0_STATUS, 0x00000000); - MDSS_PLL_REG_W(pll_base, PLL_VCO_CAL_CODE1_MODE1_STATUS, 0x00000000); - MDSS_PLL_REG_W(pll_base, PLL_RESET_SM_STATUS, 0x00000000); - MDSS_PLL_REG_W(pll_base, PLL_TDC_OFFSET, 0x00000000); - MDSS_PLL_REG_W(pll_base, PLL_PS3_PWRDOWN_CONTROLS, 0x0000001D); - MDSS_PLL_REG_W(pll_base, PLL_PS4_PWRDOWN_CONTROLS, 0x0000001C); - MDSS_PLL_REG_W(pll_base, PLL_PLL_RST_CONTROLS, 0x000000FF); - MDSS_PLL_REG_W(pll_base, PLL_GEAR_BAND_SELECT_CONTROLS, 0x00000022); - MDSS_PLL_REG_W(pll_base, PLL_PSM_CLK_CONTROLS, 0x00000009); - MDSS_PLL_REG_W(pll_base, PLL_SYSTEM_MUXES_2, 0x00000000); - MDSS_PLL_REG_W(pll_base, PLL_VCO_CONFIG_1, 0x00000000); - MDSS_PLL_REG_W(pll_base, PLL_VCO_CONFIG_2, 0x00000000); - MDSS_PLL_REG_W(pll_base, PLL_CLOCK_INVERTERS_1, 0x00000040); - MDSS_PLL_REG_W(pll_base, PLL_CLOCK_INVERTERS_2, 0x00000000); - MDSS_PLL_REG_W(pll_base, PLL_CMODE_1, 0x00000010); - MDSS_PLL_REG_W(pll_base, PLL_CMODE_2, 0x00000010); - MDSS_PLL_REG_W(pll_base, PLL_ANALOG_CONTROLS_FIVE_2, 0x00000003); + DSI_PLL_REG_W(pll_base, PLL_BIAS_CONTROL_2, 0x00000020); + DSI_PLL_REG_W(pll_base, PLL_ALOG_OBSV_BUS_CTRL_1, 0x00000000); + DSI_PLL_REG_W(pll_base, PLL_COMMON_STATUS_ONE, 0x00000000); + DSI_PLL_REG_W(pll_base, PLL_COMMON_STATUS_TWO, 0x00000000); + DSI_PLL_REG_W(pll_base, PLL_BAND_SEL_CAL, 0x00000000); + DSI_PLL_REG_W(pll_base, PLL_ICODE_ACCUM_STATUS_LOW, 0x00000000); + DSI_PLL_REG_W(pll_base, PLL_ICODE_ACCUM_STATUS_HIGH, 0x00000000); + DSI_PLL_REG_W(pll_base, PLL_FD_OUT_LOW, 0x00000000); + DSI_PLL_REG_W(pll_base, PLL_FD_OUT_HIGH, 0x00000000); + DSI_PLL_REG_W(pll_base, PLL_ALOG_OBSV_BUS_STATUS_1, 0x00000000); + DSI_PLL_REG_W(pll_base, PLL_PLL_MISC_CONFIG, 0x00000000); + DSI_PLL_REG_W(pll_base, PLL_FLL_CONFIG, 0x00000002); + DSI_PLL_REG_W(pll_base, PLL_FLL_FREQ_ACQ_TIME, 0x00000011); + DSI_PLL_REG_W(pll_base, PLL_FLL_CODE0, 0x00000000); + DSI_PLL_REG_W(pll_base, PLL_FLL_CODE1, 0x00000000); + DSI_PLL_REG_W(pll_base, PLL_FLL_GAIN0, 0x00000080); + DSI_PLL_REG_W(pll_base, PLL_FLL_GAIN1, 0x00000000); + DSI_PLL_REG_W(pll_base, PLL_SW_RESET, 0x00000000); + DSI_PLL_REG_W(pll_base, PLL_FAST_PWRUP, 0x00000000); + DSI_PLL_REG_W(pll_base, PLL_LOCKTIME0, 0x00000000); + DSI_PLL_REG_W(pll_base, PLL_LOCKTIME1, 0x00000000); + DSI_PLL_REG_W(pll_base, PLL_DEBUG_BUS_SEL, 0x00000000); + DSI_PLL_REG_W(pll_base, PLL_DEBUG_BUS0, 0x00000000); + DSI_PLL_REG_W(pll_base, PLL_DEBUG_BUS1, 0x00000000); + DSI_PLL_REG_W(pll_base, PLL_DEBUG_BUS2, 0x00000000); + DSI_PLL_REG_W(pll_base, PLL_DEBUG_BUS3, 0x00000000); + DSI_PLL_REG_W(pll_base, PLL_ANALOG_FLL_CONTROL_OVERRIDES, 0x00000000); + DSI_PLL_REG_W(pll_base, PLL_VCO_CONFIG, 0x00000000); + DSI_PLL_REG_W(pll_base, PLL_VCO_CAL_CODE1_MODE0_STATUS, 0x00000000); + DSI_PLL_REG_W(pll_base, PLL_VCO_CAL_CODE1_MODE1_STATUS, 0x00000000); + DSI_PLL_REG_W(pll_base, PLL_RESET_SM_STATUS, 0x00000000); + DSI_PLL_REG_W(pll_base, PLL_TDC_OFFSET, 0x00000000); + DSI_PLL_REG_W(pll_base, PLL_PS3_PWRDOWN_CONTROLS, 0x0000001D); + DSI_PLL_REG_W(pll_base, PLL_PS4_PWRDOWN_CONTROLS, 0x0000001C); + DSI_PLL_REG_W(pll_base, PLL_PLL_RST_CONTROLS, 0x000000FF); + DSI_PLL_REG_W(pll_base, PLL_GEAR_BAND_SELECT_CONTROLS, 0x00000022); + DSI_PLL_REG_W(pll_base, PLL_PSM_CLK_CONTROLS, 0x00000009); + DSI_PLL_REG_W(pll_base, PLL_SYSTEM_MUXES_2, 0x00000000); + DSI_PLL_REG_W(pll_base, PLL_VCO_CONFIG_1, 0x00000000); + DSI_PLL_REG_W(pll_base, PLL_VCO_CONFIG_2, 0x00000000); + DSI_PLL_REG_W(pll_base, PLL_CLOCK_INVERTERS_1, 0x00000040); + DSI_PLL_REG_W(pll_base, PLL_CLOCK_INVERTERS_2, 0x00000000); + DSI_PLL_REG_W(pll_base, PLL_CMODE_1, 0x00000010); + DSI_PLL_REG_W(pll_base, PLL_CMODE_2, 0x00000010); + DSI_PLL_REG_W(pll_base, PLL_ANALOG_CONTROLS_FIVE_2, 0x00000003); } -static void dsi_pll_commit(struct dsi_pll_7nm *pll, - struct mdss_pll_resources *rsc) +static void dsi_pll_commit(struct dsi_pll_5nm *pll, + struct dsi_pll_resource *rsc) { void __iomem *pll_base = rsc->pll_base; struct dsi_pll_regs *reg = &pll->reg_setup; - MDSS_PLL_REG_W(pll_base, PLL_CORE_INPUT_OVERRIDE, 0x12); - MDSS_PLL_REG_W(pll_base, PLL_DECIMAL_DIV_START_1, + DSI_PLL_REG_W(pll_base, PLL_CORE_INPUT_OVERRIDE, 0x12); + DSI_PLL_REG_W(pll_base, PLL_DECIMAL_DIV_START_1, reg->decimal_div_start); - MDSS_PLL_REG_W(pll_base, PLL_FRAC_DIV_START_LOW_1, + DSI_PLL_REG_W(pll_base, PLL_FRAC_DIV_START_LOW_1, reg->frac_div_start_low); - MDSS_PLL_REG_W(pll_base, PLL_FRAC_DIV_START_MID_1, + DSI_PLL_REG_W(pll_base, PLL_FRAC_DIV_START_MID_1, reg->frac_div_start_mid); - MDSS_PLL_REG_W(pll_base, PLL_FRAC_DIV_START_HIGH_1, + DSI_PLL_REG_W(pll_base, PLL_FRAC_DIV_START_HIGH_1, reg->frac_div_start_high); - MDSS_PLL_REG_W(pll_base, PLL_PLL_LOCKDET_RATE_1, 0x40); - MDSS_PLL_REG_W(pll_base, PLL_PLL_LOCK_DELAY, 0x06); - MDSS_PLL_REG_W(pll_base, PLL_CMODE_1, 0x10); - MDSS_PLL_REG_W(pll_base, PLL_CLOCK_INVERTERS_1, + DSI_PLL_REG_W(pll_base, PLL_PLL_LOCKDET_RATE_1, 0x40); + DSI_PLL_REG_W(pll_base, PLL_PLL_LOCK_DELAY, 0x06); + DSI_PLL_REG_W(pll_base, PLL_CMODE_1, 0x10); + DSI_PLL_REG_W(pll_base, PLL_CLOCK_INVERTERS_1, reg->pll_clock_inverters); } -static int vco_7nm_set_rate(struct clk_hw *hw, unsigned long rate, +static int vco_5nm_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate) { - int rc; struct dsi_pll_vco_clk *vco = to_vco_clk_hw(hw); - struct mdss_pll_resources *rsc = vco->priv; - struct dsi_pll_7nm *pll; + struct dsi_pll_resource *rsc = vco->priv; + struct dsi_pll_5nm *pll; if (!rsc) { pr_err("pll resource not found\n"); @@ -933,13 +855,6 @@ static int vco_7nm_set_rate(struct clk_hw *hw, unsigned long rate, rsc->vco_ref_clk_rate = vco->ref_clk_rate; rsc->dfps_trigger = false; - rc = mdss_pll_resource_enable(rsc, true); - if (rc) { - pr_err("failed to enable mdss dsi pll(%d), rc=%d\n", - rsc->index, rc); - return rc; - } - dsi_pll_init_val(rsc); dsi_pll_setup_config(pll, rsc); @@ -957,12 +872,10 @@ static int vco_7nm_set_rate(struct clk_hw *hw, unsigned long rate, /* flush, ensure all register writes are done*/ wmb(); - mdss_pll_resource_enable(rsc, false); - return 0; } -static int dsi_pll_read_stored_trim_codes(struct mdss_pll_resources *pll_res, +static int dsi_pll_read_stored_trim_codes(struct dsi_pll_resource *pll_res, unsigned long vco_clk_rate) { int i; @@ -1006,8 +919,8 @@ static int dsi_pll_read_stored_trim_codes(struct mdss_pll_resources *pll_res, return 0; } -static void shadow_dsi_pll_dynamic_refresh_7nm(struct dsi_pll_7nm *pll, - struct mdss_pll_resources *rsc) +static void shadow_dsi_pll_dynamic_refresh_5nm(struct dsi_pll_5nm *pll, + struct dsi_pll_resource *rsc) { u32 data; u32 offset = DSI_PHY_TO_PLL_OFFSET; @@ -1015,43 +928,43 @@ static void shadow_dsi_pll_dynamic_refresh_7nm(struct dsi_pll_7nm *pll, u32 upper_addr2 = 0; struct dsi_pll_regs *reg = &pll->reg_setup; - data = MDSS_PLL_REG_R(rsc->phy_base, PHY_CMN_CLK_CFG1); + data = DSI_PLL_REG_R(rsc->phy_base, PHY_CMN_CLK_CFG1); data &= ~BIT(5); - MDSS_DYN_PLL_REG_W(rsc->dyn_pll_base, DSI_DYNAMIC_REFRESH_PLL_CTRL0, + DSI_DYN_PLL_REG_W(rsc->dyn_pll_base, DSI_DYNAMIC_REFRESH_PLL_CTRL0, PHY_CMN_CLK_CFG1, PHY_CMN_PLL_CNTRL, data, 0); upper_addr |= (upper_8_bit(PHY_CMN_CLK_CFG1) << 0); upper_addr |= (upper_8_bit(PHY_CMN_PLL_CNTRL) << 1); - MDSS_DYN_PLL_REG_W(rsc->dyn_pll_base, DSI_DYNAMIC_REFRESH_PLL_CTRL1, + DSI_DYN_PLL_REG_W(rsc->dyn_pll_base, DSI_DYNAMIC_REFRESH_PLL_CTRL1, PHY_CMN_RBUF_CTRL, (PLL_CORE_INPUT_OVERRIDE + offset), 0, 0x12); upper_addr |= (upper_8_bit(PHY_CMN_RBUF_CTRL) << 2); upper_addr |= (upper_8_bit(PLL_CORE_INPUT_OVERRIDE + offset) << 3); - MDSS_DYN_PLL_REG_W(rsc->dyn_pll_base, DSI_DYNAMIC_REFRESH_PLL_CTRL2, + DSI_DYN_PLL_REG_W(rsc->dyn_pll_base, DSI_DYNAMIC_REFRESH_PLL_CTRL2, (PLL_DECIMAL_DIV_START_1 + offset), (PLL_FRAC_DIV_START_LOW_1 + offset), reg->decimal_div_start, reg->frac_div_start_low); upper_addr |= (upper_8_bit(PLL_DECIMAL_DIV_START_1 + offset) << 4); upper_addr |= (upper_8_bit(PLL_FRAC_DIV_START_LOW_1 + offset) << 5); - MDSS_DYN_PLL_REG_W(rsc->dyn_pll_base, DSI_DYNAMIC_REFRESH_PLL_CTRL3, + DSI_DYN_PLL_REG_W(rsc->dyn_pll_base, DSI_DYNAMIC_REFRESH_PLL_CTRL3, (PLL_FRAC_DIV_START_MID_1 + offset), (PLL_FRAC_DIV_START_HIGH_1 + offset), reg->frac_div_start_mid, reg->frac_div_start_high); upper_addr |= (upper_8_bit(PLL_FRAC_DIV_START_MID_1 + offset) << 6); upper_addr |= (upper_8_bit(PLL_FRAC_DIV_START_HIGH_1 + offset) << 7); - MDSS_DYN_PLL_REG_W(rsc->dyn_pll_base, DSI_DYNAMIC_REFRESH_PLL_CTRL4, + DSI_DYN_PLL_REG_W(rsc->dyn_pll_base, DSI_DYNAMIC_REFRESH_PLL_CTRL4, (PLL_SYSTEM_MUXES + offset), (PLL_PLL_LOCKDET_RATE_1 + offset), 0xc0, 0x10); upper_addr |= (upper_8_bit(PLL_SYSTEM_MUXES + offset) << 8); upper_addr |= (upper_8_bit(PLL_PLL_LOCKDET_RATE_1 + offset) << 9); - data = MDSS_PLL_REG_R(rsc->pll_base, PLL_PLL_OUTDIV_RATE) & 0x03; - MDSS_DYN_PLL_REG_W(rsc->dyn_pll_base, DSI_DYNAMIC_REFRESH_PLL_CTRL5, + data = DSI_PLL_REG_R(rsc->pll_base, PLL_PLL_OUTDIV_RATE) & 0x03; + DSI_DYN_PLL_REG_W(rsc->dyn_pll_base, DSI_DYNAMIC_REFRESH_PLL_CTRL5, (PLL_PLL_OUTDIV_RATE + offset), (PLL_PLL_LOCK_DELAY + offset), data, 0x06); @@ -1059,7 +972,7 @@ static void shadow_dsi_pll_dynamic_refresh_7nm(struct dsi_pll_7nm *pll, upper_addr |= (upper_8_bit(PLL_PLL_OUTDIV_RATE + offset) << 10); upper_addr |= (upper_8_bit(PLL_PLL_LOCK_DELAY + offset) << 11); - MDSS_DYN_PLL_REG_W(rsc->dyn_pll_base, DSI_DYNAMIC_REFRESH_PLL_CTRL6, + DSI_DYN_PLL_REG_W(rsc->dyn_pll_base, DSI_DYNAMIC_REFRESH_PLL_CTRL6, (PLL_CMODE_1 + offset), (PLL_CLOCK_INVERTERS_1 + offset), 0x10, reg->pll_clock_inverters); @@ -1067,34 +980,34 @@ static void shadow_dsi_pll_dynamic_refresh_7nm(struct dsi_pll_7nm *pll, (upper_8_bit(PLL_CMODE_1 + offset) << 12); upper_addr |= (upper_8_bit(PLL_CLOCK_INVERTERS_1 + offset) << 13); - data = MDSS_PLL_REG_R(rsc->pll_base, PLL_VCO_CONFIG_1); - MDSS_DYN_PLL_REG_W(rsc->dyn_pll_base, DSI_DYNAMIC_REFRESH_PLL_CTRL7, + data = DSI_PLL_REG_R(rsc->pll_base, PLL_VCO_CONFIG_1); + DSI_DYN_PLL_REG_W(rsc->dyn_pll_base, DSI_DYNAMIC_REFRESH_PLL_CTRL7, (PLL_ANALOG_CONTROLS_FIVE_1 + offset), (PLL_VCO_CONFIG_1 + offset), 0x01, data); upper_addr |= (upper_8_bit(PLL_ANALOG_CONTROLS_FIVE_1 + offset) << 14); upper_addr |= (upper_8_bit(PLL_VCO_CONFIG_1 + offset) << 15); - MDSS_DYN_PLL_REG_W(rsc->dyn_pll_base, DSI_DYNAMIC_REFRESH_PLL_CTRL8, + DSI_DYN_PLL_REG_W(rsc->dyn_pll_base, DSI_DYNAMIC_REFRESH_PLL_CTRL8, (PLL_ANALOG_CONTROLS_FIVE + offset), (PLL_ANALOG_CONTROLS_TWO + offset), 0x01, 0x03); upper_addr |= (upper_8_bit(PLL_ANALOG_CONTROLS_FIVE + offset) << 16); upper_addr |= (upper_8_bit(PLL_ANALOG_CONTROLS_TWO + offset) << 17); - MDSS_DYN_PLL_REG_W(rsc->dyn_pll_base, DSI_DYNAMIC_REFRESH_PLL_CTRL9, + DSI_DYN_PLL_REG_W(rsc->dyn_pll_base, DSI_DYNAMIC_REFRESH_PLL_CTRL9, (PLL_ANALOG_CONTROLS_THREE + offset), (PLL_DSM_DIVIDER + offset), rsc->cache_pll_trim_codes[2], 0x00); upper_addr |= (upper_8_bit(PLL_ANALOG_CONTROLS_THREE + offset) << 18); upper_addr |= (upper_8_bit(PLL_DSM_DIVIDER + offset) << 19); - MDSS_DYN_PLL_REG_W(rsc->dyn_pll_base, DSI_DYNAMIC_REFRESH_PLL_CTRL10, + DSI_DYN_PLL_REG_W(rsc->dyn_pll_base, DSI_DYNAMIC_REFRESH_PLL_CTRL10, (PLL_FEEDBACK_DIVIDER + offset), (PLL_CALIBRATION_SETTINGS + offset), 0x4E, 0x40); upper_addr |= (upper_8_bit(PLL_FEEDBACK_DIVIDER + offset) << 20); upper_addr |= (upper_8_bit(PLL_CALIBRATION_SETTINGS + offset) << 21); - MDSS_DYN_PLL_REG_W(rsc->dyn_pll_base, DSI_DYNAMIC_REFRESH_PLL_CTRL11, + DSI_DYN_PLL_REG_W(rsc->dyn_pll_base, DSI_DYNAMIC_REFRESH_PLL_CTRL11, (PLL_BAND_SEL_CAL_SETTINGS_THREE + offset), (PLL_FREQ_DETECT_SETTINGS_ONE + offset), 0xBA, 0x0C); upper_addr |= (upper_8_bit(PLL_BAND_SEL_CAL_SETTINGS_THREE + offset) @@ -1102,20 +1015,20 @@ static void shadow_dsi_pll_dynamic_refresh_7nm(struct dsi_pll_7nm *pll, upper_addr |= (upper_8_bit(PLL_FREQ_DETECT_SETTINGS_ONE + offset) << 23); - MDSS_DYN_PLL_REG_W(rsc->dyn_pll_base, DSI_DYNAMIC_REFRESH_PLL_CTRL12, + DSI_DYN_PLL_REG_W(rsc->dyn_pll_base, DSI_DYNAMIC_REFRESH_PLL_CTRL12, (PLL_OUTDIV + offset), (PLL_CORE_OVERRIDE + offset), 0, 0); upper_addr |= (upper_8_bit(PLL_OUTDIV + offset) << 24); upper_addr |= (upper_8_bit(PLL_CORE_OVERRIDE + offset) << 25); - MDSS_DYN_PLL_REG_W(rsc->dyn_pll_base, DSI_DYNAMIC_REFRESH_PLL_CTRL13, + DSI_DYN_PLL_REG_W(rsc->dyn_pll_base, DSI_DYNAMIC_REFRESH_PLL_CTRL13, (PLL_PLL_DIGITAL_TIMERS_TWO + offset), (PLL_PLL_PROP_GAIN_RATE_1 + offset), 0x08, reg->pll_prop_gain_rate); upper_addr |= (upper_8_bit(PLL_PLL_DIGITAL_TIMERS_TWO + offset) << 26); upper_addr |= (upper_8_bit(PLL_PLL_PROP_GAIN_RATE_1 + offset) << 27); - MDSS_DYN_PLL_REG_W(rsc->dyn_pll_base, DSI_DYNAMIC_REFRESH_PLL_CTRL14, + DSI_DYN_PLL_REG_W(rsc->dyn_pll_base, DSI_DYNAMIC_REFRESH_PLL_CTRL14, (PLL_PLL_BAND_SEL_RATE_1 + offset), (PLL_PLL_INT_GAIN_IFILT_BAND_1 + offset), 0xC0, 0x82); @@ -1123,7 +1036,7 @@ static void shadow_dsi_pll_dynamic_refresh_7nm(struct dsi_pll_7nm *pll, upper_addr |= (upper_8_bit(PLL_PLL_INT_GAIN_IFILT_BAND_1 + offset) << 29); - MDSS_DYN_PLL_REG_W(rsc->dyn_pll_base, DSI_DYNAMIC_REFRESH_PLL_CTRL15, + DSI_DYN_PLL_REG_W(rsc->dyn_pll_base, DSI_DYNAMIC_REFRESH_PLL_CTRL15, (PLL_PLL_FL_INT_GAIN_PFILT_BAND_1 + offset), (PLL_PLL_LOCK_OVERRIDE + offset), 0x4c, 0x80); @@ -1131,71 +1044,71 @@ static void shadow_dsi_pll_dynamic_refresh_7nm(struct dsi_pll_7nm *pll, << 30); upper_addr |= (upper_8_bit(PLL_PLL_LOCK_OVERRIDE + offset) << 31); - MDSS_DYN_PLL_REG_W(rsc->dyn_pll_base, DSI_DYNAMIC_REFRESH_PLL_CTRL16, + DSI_DYN_PLL_REG_W(rsc->dyn_pll_base, DSI_DYNAMIC_REFRESH_PLL_CTRL16, (PLL_PFILT + offset), (PLL_IFILT + offset), 0x29, 0x3f); upper_addr2 |= (upper_8_bit(PLL_PFILT + offset) << 0); upper_addr2 |= (upper_8_bit(PLL_IFILT + offset) << 1); - MDSS_DYN_PLL_REG_W(rsc->dyn_pll_base, DSI_DYNAMIC_REFRESH_PLL_CTRL17, + DSI_DYN_PLL_REG_W(rsc->dyn_pll_base, DSI_DYNAMIC_REFRESH_PLL_CTRL17, (PLL_SYSTEM_MUXES + offset), (PLL_CALIBRATION_SETTINGS + offset), 0xe0, 0x44); upper_addr2 |= (upper_8_bit(PLL_BAND_SEL_CAL + offset) << 2); upper_addr2 |= (upper_8_bit(PLL_CALIBRATION_SETTINGS + offset) << 3); - data = MDSS_PLL_REG_R(rsc->phy_base, PHY_CMN_CLK_CFG0); - MDSS_DYN_PLL_REG_W(rsc->dyn_pll_base, DSI_DYNAMIC_REFRESH_PLL_CTRL18, + data = DSI_PLL_REG_R(rsc->phy_base, PHY_CMN_CLK_CFG0); + DSI_DYN_PLL_REG_W(rsc->dyn_pll_base, DSI_DYNAMIC_REFRESH_PLL_CTRL18, PHY_CMN_CTRL_2, PHY_CMN_CLK_CFG0, 0x40, data); if (rsc->slave) - MDSS_DYN_PLL_REG_W(rsc->slave->dyn_pll_base, + DSI_DYN_PLL_REG_W(rsc->slave->dyn_pll_base, DSI_DYNAMIC_REFRESH_PLL_CTRL10, PHY_CMN_CLK_CFG0, PHY_CMN_CTRL_0, data, 0x7f); - MDSS_DYN_PLL_REG_W(rsc->dyn_pll_base, DSI_DYNAMIC_REFRESH_PLL_CTRL27, + DSI_DYN_PLL_REG_W(rsc->dyn_pll_base, DSI_DYNAMIC_REFRESH_PLL_CTRL27, PHY_CMN_PLL_CNTRL, PHY_CMN_PLL_CNTRL, 0x01, 0x01); - MDSS_DYN_PLL_REG_W(rsc->dyn_pll_base, DSI_DYNAMIC_REFRESH_PLL_CTRL28, + DSI_DYN_PLL_REG_W(rsc->dyn_pll_base, DSI_DYNAMIC_REFRESH_PLL_CTRL28, PHY_CMN_PLL_CNTRL, PHY_CMN_PLL_CNTRL, 0x01, 0x01); - MDSS_DYN_PLL_REG_W(rsc->dyn_pll_base, DSI_DYNAMIC_REFRESH_PLL_CTRL29, + DSI_DYN_PLL_REG_W(rsc->dyn_pll_base, DSI_DYNAMIC_REFRESH_PLL_CTRL29, PHY_CMN_PLL_CNTRL, PHY_CMN_PLL_CNTRL, 0x01, 0x01); - data = MDSS_PLL_REG_R(rsc->phy_base, PHY_CMN_CLK_CFG1) | BIT(5); - MDSS_DYN_PLL_REG_W(rsc->dyn_pll_base, DSI_DYNAMIC_REFRESH_PLL_CTRL30, + data = DSI_PLL_REG_R(rsc->phy_base, PHY_CMN_CLK_CFG1) | BIT(5); + DSI_DYN_PLL_REG_W(rsc->dyn_pll_base, DSI_DYNAMIC_REFRESH_PLL_CTRL30, PHY_CMN_CLK_CFG1, PHY_CMN_RBUF_CTRL, data, 0x01); - MDSS_DYN_PLL_REG_W(rsc->dyn_pll_base, DSI_DYNAMIC_REFRESH_PLL_CTRL31, + DSI_DYN_PLL_REG_W(rsc->dyn_pll_base, DSI_DYNAMIC_REFRESH_PLL_CTRL31, PHY_CMN_CLK_CFG1, PHY_CMN_CLK_CFG1, data, data); if (rsc->slave) { - data = MDSS_PLL_REG_R(rsc->slave->phy_base, PHY_CMN_CLK_CFG1) | + data = DSI_PLL_REG_R(rsc->slave->phy_base, PHY_CMN_CLK_CFG1) | BIT(5); - MDSS_DYN_PLL_REG_W(rsc->slave->dyn_pll_base, + DSI_DYN_PLL_REG_W(rsc->slave->dyn_pll_base, DSI_DYNAMIC_REFRESH_PLL_CTRL30, PHY_CMN_CLK_CFG1, PHY_CMN_RBUF_CTRL, data, 0x01); - MDSS_DYN_PLL_REG_W(rsc->slave->dyn_pll_base, + DSI_DYN_PLL_REG_W(rsc->slave->dyn_pll_base, DSI_DYNAMIC_REFRESH_PLL_CTRL31, PHY_CMN_CLK_CFG1, PHY_CMN_CLK_CFG1, data, data); } - MDSS_PLL_REG_W(rsc->dyn_pll_base, + DSI_PLL_REG_W(rsc->dyn_pll_base, DSI_DYNAMIC_REFRESH_PLL_UPPER_ADDR, upper_addr); - MDSS_PLL_REG_W(rsc->dyn_pll_base, + DSI_PLL_REG_W(rsc->dyn_pll_base, DSI_DYNAMIC_REFRESH_PLL_UPPER_ADDR2, upper_addr2); wmb(); /* commit register writes */ } -static int shadow_vco_7nm_set_rate(struct clk_hw *hw, unsigned long rate, +static int shadow_vco_5nm_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate) { int rc; - struct dsi_pll_7nm *pll; + struct dsi_pll_5nm *pll; struct dsi_pll_vco_clk *vco = to_vco_clk_hw(hw); - struct mdss_pll_resources *rsc = vco->priv; + struct dsi_pll_resource *rsc = vco->priv; if (!rsc) { pr_err("pll resource not found\n"); @@ -1215,12 +1128,6 @@ static int shadow_vco_7nm_set_rate(struct clk_hw *hw, unsigned long rate, } pr_debug("ndx=%d, rate=%lu\n", rsc->index, rate); - rc = mdss_pll_resource_enable(rsc, true); - if (rc) { - pr_err("failed to enable mdss dsi pll(%d), rc=%d\n", - rsc->index, rc); - return rc; - } rsc->vco_current_rate = rate; rsc->vco_ref_clk_rate = vco->ref_clk_rate; @@ -1230,18 +1137,16 @@ static int shadow_vco_7nm_set_rate(struct clk_hw *hw, unsigned long rate, dsi_pll_calc_dec_frac(pll, rsc); /* program dynamic refresh control registers */ - shadow_dsi_pll_dynamic_refresh_7nm(pll, rsc); + shadow_dsi_pll_dynamic_refresh_5nm(pll, rsc); /* update cached vco rate */ rsc->vco_cached_rate = rate; rsc->dfps_trigger = true; - mdss_pll_resource_enable(rsc, false); - return 0; } -static int dsi_pll_7nm_lock_status(struct mdss_pll_resources *pll) +static int dsi_pll_5nm_lock_status(struct dsi_pll_resource *pll) { int rc; u32 status; @@ -1260,62 +1165,62 @@ static int dsi_pll_7nm_lock_status(struct mdss_pll_resources *pll) return rc; } -static void dsi_pll_disable_pll_bias(struct mdss_pll_resources *rsc) +static void dsi_pll_disable_pll_bias(struct dsi_pll_resource *rsc) { - u32 data = MDSS_PLL_REG_R(rsc->phy_base, PHY_CMN_CTRL_0); + u32 data = DSI_PLL_REG_R(rsc->phy_base, PHY_CMN_CTRL_0); - MDSS_PLL_REG_W(rsc->pll_base, PLL_SYSTEM_MUXES, 0); - MDSS_PLL_REG_W(rsc->phy_base, PHY_CMN_CTRL_0, data & ~BIT(5)); + DSI_PLL_REG_W(rsc->pll_base, PLL_SYSTEM_MUXES, 0); + DSI_PLL_REG_W(rsc->phy_base, PHY_CMN_CTRL_0, data & ~BIT(5)); ndelay(250); } -static void dsi_pll_enable_pll_bias(struct mdss_pll_resources *rsc) +static void dsi_pll_enable_pll_bias(struct dsi_pll_resource *rsc) { - u32 data = MDSS_PLL_REG_R(rsc->phy_base, PHY_CMN_CTRL_0); + u32 data = DSI_PLL_REG_R(rsc->phy_base, PHY_CMN_CTRL_0); - MDSS_PLL_REG_W(rsc->phy_base, PHY_CMN_CTRL_0, data | BIT(5)); - MDSS_PLL_REG_W(rsc->pll_base, PLL_SYSTEM_MUXES, 0xc0); + DSI_PLL_REG_W(rsc->phy_base, PHY_CMN_CTRL_0, data | BIT(5)); + DSI_PLL_REG_W(rsc->pll_base, PLL_SYSTEM_MUXES, 0xc0); ndelay(250); } -static void dsi_pll_disable_global_clk(struct mdss_pll_resources *rsc) +static void dsi_pll_disable_global_clk(struct dsi_pll_resource *rsc) { u32 data; - data = MDSS_PLL_REG_R(rsc->phy_base, PHY_CMN_CLK_CFG1); - MDSS_PLL_REG_W(rsc->phy_base, PHY_CMN_CLK_CFG1, (data & ~BIT(5))); + data = DSI_PLL_REG_R(rsc->phy_base, PHY_CMN_CLK_CFG1); + DSI_PLL_REG_W(rsc->phy_base, PHY_CMN_CLK_CFG1, (data & ~BIT(5))); } -static void dsi_pll_enable_global_clk(struct mdss_pll_resources *rsc) +static void dsi_pll_enable_global_clk(struct dsi_pll_resource *rsc) { u32 data; - MDSS_PLL_REG_W(rsc->phy_base, PHY_CMN_CTRL_3, 0x04); + DSI_PLL_REG_W(rsc->phy_base, PHY_CMN_CTRL_3, 0x04); - data = MDSS_PLL_REG_R(rsc->phy_base, PHY_CMN_CLK_CFG1); + data = DSI_PLL_REG_R(rsc->phy_base, PHY_CMN_CLK_CFG1); /* Turn on clk_en_sel bit prior to resync toggle fifo */ - MDSS_PLL_REG_W(rsc->phy_base, PHY_CMN_CLK_CFG1, (data | BIT(5) | + DSI_PLL_REG_W(rsc->phy_base, PHY_CMN_CLK_CFG1, (data | BIT(5) | BIT(4))); } -static void dsi_pll_phy_dig_reset(struct mdss_pll_resources *rsc) +static void dsi_pll_phy_dig_reset(struct dsi_pll_resource *rsc) { /* * Reset the PHY digital domain. This would be needed when * coming out of a CX or analog rail power collapse while * ensuring that the pads maintain LP00 or LP11 state */ - MDSS_PLL_REG_W(rsc->phy_base, PHY_CMN_GLBL_DIGTOP_SPARE4, BIT(0)); + DSI_PLL_REG_W(rsc->phy_base, PHY_CMN_GLBL_DIGTOP_SPARE4, BIT(0)); wmb(); /* Ensure that the reset is asserted */ - MDSS_PLL_REG_W(rsc->phy_base, PHY_CMN_GLBL_DIGTOP_SPARE4, 0x0); + DSI_PLL_REG_W(rsc->phy_base, PHY_CMN_GLBL_DIGTOP_SPARE4, 0x0); wmb(); /* Ensure that the reset is deasserted */ } static int dsi_pll_enable(struct dsi_pll_vco_clk *vco) { int rc; - struct mdss_pll_resources *rsc = vco->priv; + struct dsi_pll_resource *rsc = vco->priv; dsi_pll_enable_pll_bias(rsc); if (rsc->slave) @@ -1328,7 +1233,7 @@ static int dsi_pll_enable(struct dsi_pll_vco_clk *vco) wmb(); /* ensure dsiclk_sel is always programmed before pll start */ /* Start PLL */ - MDSS_PLL_REG_W(rsc->phy_base, PHY_CMN_PLL_CNTRL, 0x01); + DSI_PLL_REG_W(rsc->phy_base, PHY_CMN_PLL_CNTRL, 0x01); /* * ensure all PLL configurations are written prior to checking @@ -1337,7 +1242,7 @@ static int dsi_pll_enable(struct dsi_pll_vco_clk *vco) wmb(); /* Check for PLL lock */ - rc = dsi_pll_7nm_lock_status(rsc); + rc = dsi_pll_5nm_lock_status(rsc); if (rc) { pr_err("PLL(%d) lock failed\n", rsc->index); goto error; @@ -1362,18 +1267,17 @@ error: return rc; } -static void dsi_pll_disable_sub(struct mdss_pll_resources *rsc) +static void dsi_pll_disable_sub(struct dsi_pll_resource *rsc) { - MDSS_PLL_REG_W(rsc->phy_base, PHY_CMN_RBUF_CTRL, 0); + DSI_PLL_REG_W(rsc->phy_base, PHY_CMN_RBUF_CTRL, 0); dsi_pll_disable_pll_bias(rsc); } static void dsi_pll_disable(struct dsi_pll_vco_clk *vco) { - struct mdss_pll_resources *rsc = vco->priv; + struct dsi_pll_resource *rsc = vco->priv; - if (!rsc->pll_on && - mdss_pll_resource_enable(rsc, true)) { + if (!rsc->pll_on) { pr_err("failed to enable pll (%d) resources\n", rsc->index); return; } @@ -1391,7 +1295,7 @@ static void dsi_pll_disable(struct dsi_pll_vco_clk *vco) * down the PLL */ dsi_pll_disable_global_clk(rsc); - MDSS_PLL_REG_W(rsc->phy_base, PHY_CMN_PLL_CNTRL, 0); + DSI_PLL_REG_W(rsc->phy_base, PHY_CMN_PLL_CNTRL, 0); dsi_pll_disable_sub(rsc); if (rsc->slave) { dsi_pll_disable_global_clk(rsc->slave); @@ -1402,7 +1306,7 @@ static void dsi_pll_disable(struct dsi_pll_vco_clk *vco) rsc->pll_on = false; } -long vco_7nm_round_rate(struct clk_hw *hw, unsigned long rate, +long vco_5nm_round_rate(struct clk_hw *hw, unsigned long rate, unsigned long *parent_rate) { unsigned long rrate = rate; @@ -1418,10 +1322,10 @@ long vco_7nm_round_rate(struct clk_hw *hw, unsigned long rate, return rrate; } -static void vco_7nm_unprepare(struct clk_hw *hw) +static void vco_5nm_unprepare(struct clk_hw *hw) { struct dsi_pll_vco_clk *vco = to_vco_clk_hw(hw); - struct mdss_pll_resources *pll = vco->priv; + struct dsi_pll_resource *pll = vco->priv; if (!pll) { pr_err("dsi pll resources not available\n"); @@ -1439,9 +1343,9 @@ static void vco_7nm_unprepare(struct clk_hw *hw) * is triggered. */ if (!pll->handoff_resources || pll->dfps_trigger) { - pll->cached_cfg0 = MDSS_PLL_REG_R(pll->phy_base, + pll->cached_cfg0 = DSI_PLL_REG_R(pll->phy_base, PHY_CMN_CLK_CFG0); - pll->cached_outdiv = MDSS_PLL_REG_R(pll->pll_base, + pll->cached_outdiv = DSI_PLL_REG_R(pll->pll_base, PLL_PLL_OUTDIV_RATE); pr_debug("cfg0=%d,cfg1=%d, outdiv=%d\n", pll->cached_cfg0, pll->cached_cfg1, pll->cached_outdiv); @@ -1457,23 +1361,22 @@ static void vco_7nm_unprepare(struct clk_hw *hw) * value is programmed prior to PLL being locked */ if (pll->handoff_resources) { - pll->cached_cfg1 = MDSS_PLL_REG_R(pll->phy_base, + pll->cached_cfg1 = DSI_PLL_REG_R(pll->phy_base, PHY_CMN_CLK_CFG1); if (pll->slave) pll->slave->cached_cfg1 = - MDSS_PLL_REG_R(pll->slave->phy_base, + DSI_PLL_REG_R(pll->slave->phy_base, PHY_CMN_CLK_CFG1); } dsi_pll_disable(vco); - mdss_pll_resource_enable(pll, false); } -static int vco_7nm_prepare(struct clk_hw *hw) +static int vco_5nm_prepare(struct clk_hw *hw) { int rc = 0; struct dsi_pll_vco_clk *vco = to_vco_clk_hw(hw); - struct mdss_pll_resources *pll = vco->priv; + struct dsi_pll_resource *pll = vco->priv; if (!pll) { pr_err("dsi pll resources are not available\n"); @@ -1481,14 +1384,9 @@ static int vco_7nm_prepare(struct clk_hw *hw) } /* Skip vco recalculation for continuous splash use case */ - if (pll->handoff_resources) + if (pll->handoff_resources) { + pll->pll_on = true; return 0; - - rc = mdss_pll_resource_enable(pll, true); - if (rc) { - pr_err("failed to enable pll (%d) resource, rc=%d\n", - pll->index, rc); - return rc; } if ((pll->vco_cached_rate != 0) && @@ -1498,36 +1396,30 @@ static int vco_7nm_prepare(struct clk_hw *hw) if (rc) { pr_err("pll(%d) set_rate failed, rc=%d\n", pll->index, rc); - mdss_pll_resource_enable(pll, false); return rc; } pr_debug("cfg0=%d, cfg1=%d\n", pll->cached_cfg0, pll->cached_cfg1); - MDSS_PLL_REG_W(pll->phy_base, PHY_CMN_CLK_CFG0, + DSI_PLL_REG_W(pll->phy_base, PHY_CMN_CLK_CFG0, pll->cached_cfg0); if (pll->slave) - MDSS_PLL_REG_W(pll->slave->phy_base, PHY_CMN_CLK_CFG0, + DSI_PLL_REG_W(pll->slave->phy_base, PHY_CMN_CLK_CFG0, pll->cached_cfg0); - MDSS_PLL_REG_W(pll->pll_base, PLL_PLL_OUTDIV_RATE, + DSI_PLL_REG_W(pll->pll_base, PLL_PLL_OUTDIV_RATE, pll->cached_outdiv); } rc = dsi_pll_enable(vco); - if (rc) { - mdss_pll_resource_enable(pll, false); - pr_err("pll(%d) enable failed, rc=%d\n", pll->index, rc); - return rc; - } return rc; } -static unsigned long vco_7nm_recalc_rate(struct clk_hw *hw, +static unsigned long vco_5nm_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) { + int rc = 0; struct dsi_pll_vco_clk *vco = to_vco_clk_hw(hw); - struct mdss_pll_resources *pll = vco->priv; - int rc; + struct dsi_pll_resource *pll = vco->priv; if (!vco->priv) { pr_err("vco priv is null\n"); @@ -1545,51 +1437,43 @@ static unsigned long vco_7nm_recalc_rate(struct clk_hw *hw, return pll->vco_current_rate; } - rc = mdss_pll_resource_enable(pll, true); - if (rc) { - pr_err("failed to enable pll(%d) resource, rc=%d\n", - pll->index, rc); + pll->handoff_resources = true; + + + if (!dsi_pll_5nm_get_gdsc_status(pll)) { + pll->handoff_resources = false; + pr_err("Hand_off_resources not needed since gdsc is off\n"); return 0; } - pll->handoff_resources = true; - if (dsi_pll_7nm_lock_status(pll)) { - pr_debug("PLL not enabled\n"); + if (dsi_pll_5nm_lock_status(pll)) { + pr_err("PLL not enabled\n"); pll->handoff_resources = false; } + pr_err("handoff_resources %s\n", pll->handoff_resources ? "true" : "false"); - (void)mdss_pll_resource_enable(pll, false); return rc; } static int pixel_clk_get_div(void *context, unsigned int reg, unsigned int *div) { - int rc; - struct mdss_pll_resources *pll = context; + struct dsi_pll_resource *pll = context; u32 reg_val; - rc = mdss_pll_resource_enable(pll, true); - if (rc) { - pr_err("Failed to enable dsi pll resources, rc=%d\n", rc); - return rc; - } - - reg_val = MDSS_PLL_REG_R(pll->phy_base, PHY_CMN_CLK_CFG0); + reg_val = DSI_PLL_REG_R(pll->phy_base, PHY_CMN_CLK_CFG0); *div = (reg_val & 0xF0) >> 4; - (void)mdss_pll_resource_enable(pll, false); - - return rc; + return 0; } -static void pixel_clk_set_div_sub(struct mdss_pll_resources *pll, int div) +static void pixel_clk_set_div_sub(struct dsi_pll_resource *pll, int div) { u32 reg_val; - reg_val = MDSS_PLL_REG_R(pll->phy_base, PHY_CMN_CLK_CFG0); + reg_val = DSI_PLL_REG_R(pll->phy_base, PHY_CMN_CLK_CFG0); reg_val &= ~0xF0; reg_val |= (div << 4); - MDSS_PLL_REG_W(pll->phy_base, PHY_CMN_CLK_CFG0, reg_val); + DSI_PLL_REG_W(pll->phy_base, PHY_CMN_CLK_CFG0, reg_val); /* * cache the current parent index for cases where parent @@ -1602,87 +1486,54 @@ static void pixel_clk_set_div_sub(struct mdss_pll_resources *pll, int div) static int pixel_clk_set_div(void *context, unsigned int reg, unsigned int div) { - int rc; - struct mdss_pll_resources *pll = context; - - rc = mdss_pll_resource_enable(pll, true); - if (rc) { - pr_err("Failed to enable dsi pll resources, rc=%d\n", rc); - return rc; - } + struct dsi_pll_resource *pll = context; pixel_clk_set_div_sub(pll, div); if (pll->slave) pixel_clk_set_div_sub(pll->slave, div); - (void)mdss_pll_resource_enable(pll, false); return 0; } static int bit_clk_get_div(void *context, unsigned int reg, unsigned int *div) { - int rc; - struct mdss_pll_resources *pll = context; + struct dsi_pll_resource *pll = context; u32 reg_val; - rc = mdss_pll_resource_enable(pll, true); - if (rc) { - pr_err("Failed to enable dsi pll resources, rc=%d\n", rc); - return rc; - } - - reg_val = MDSS_PLL_REG_R(pll->phy_base, PHY_CMN_CLK_CFG0); + reg_val = DSI_PLL_REG_R(pll->phy_base, PHY_CMN_CLK_CFG0); *div = (reg_val & 0x0F); - (void)mdss_pll_resource_enable(pll, false); - - return rc; + return 0; } -static void bit_clk_set_div_sub(struct mdss_pll_resources *rsc, int div) +static void bit_clk_set_div_sub(struct dsi_pll_resource *rsc, int div) { u32 reg_val; - reg_val = MDSS_PLL_REG_R(rsc->phy_base, PHY_CMN_CLK_CFG0); + reg_val = DSI_PLL_REG_R(rsc->phy_base, PHY_CMN_CLK_CFG0); reg_val &= ~0x0F; reg_val |= div; - MDSS_PLL_REG_W(rsc->phy_base, PHY_CMN_CLK_CFG0, reg_val); + DSI_PLL_REG_W(rsc->phy_base, PHY_CMN_CLK_CFG0, reg_val); } static int bit_clk_set_div(void *context, unsigned int reg, unsigned int div) { - int rc; - struct mdss_pll_resources *rsc = context; - struct dsi_pll_8998 *pll; + struct dsi_pll_resource *rsc = context; if (!rsc) { pr_err("pll resource not found\n"); return -EINVAL; } - pll = rsc->priv; - if (!pll) { - pr_err("pll configuration not found\n"); - return -EINVAL; - } - - rc = mdss_pll_resource_enable(rsc, true); - if (rc) { - pr_err("Failed to enable dsi pll resources, rc=%d\n", rc); - return rc; - } - bit_clk_set_div_sub(rsc, div); /* For slave PLL, this divider always should be set to 1 */ if (rsc->slave) bit_clk_set_div_sub(rsc->slave, 1); - (void)mdss_pll_resource_enable(rsc, false); - - return rc; + return 0; } -static struct regmap_config dsi_pll_7nm_config = { +static struct regmap_config dsi_pll_5nm_config = { .reg_bits = 32, .reg_stride = 4, .val_bits = 32, @@ -1709,23 +1560,23 @@ static struct regmap_bus bitclk_src_regmap_bus = { .reg_read = bit_clk_get_div, }; -static const struct clk_ops clk_ops_vco_7nm = { - .recalc_rate = vco_7nm_recalc_rate, - .set_rate = vco_7nm_set_rate, - .round_rate = vco_7nm_round_rate, - .prepare = vco_7nm_prepare, - .unprepare = vco_7nm_unprepare, +static const struct clk_ops clk_ops_vco_5nm = { + .recalc_rate = vco_5nm_recalc_rate, + .set_rate = vco_5nm_set_rate, + .round_rate = vco_5nm_round_rate, + .prepare = vco_5nm_prepare, + .unprepare = vco_5nm_unprepare, }; -static const struct clk_ops clk_ops_shadow_vco_7nm = { - .recalc_rate = vco_7nm_recalc_rate, - .set_rate = shadow_vco_7nm_set_rate, - .round_rate = vco_7nm_round_rate, +static const struct clk_ops clk_ops_shadow_vco_5nm = { + .recalc_rate = vco_5nm_recalc_rate, + .set_rate = shadow_vco_5nm_set_rate, + .round_rate = vco_5nm_round_rate, }; -static struct regmap_bus mdss_mux_regmap_bus = { - .reg_write = mdss_set_mux_sel, - .reg_read = mdss_get_mux_sel, +static struct regmap_bus dsi_mux_regmap_bus = { + .reg_write = dsi_set_mux_sel, + .reg_read = dsi_get_mux_sel, }; /* @@ -1792,7 +1643,7 @@ static struct dsi_pll_vco_clk dsi0pll_vco_clk = { .name = "dsi0pll_vco_clk", .parent_names = (const char *[]){"bi_tcxo"}, .num_parents = 1, - .ops = &clk_ops_vco_7nm, + .ops = &clk_ops_vco_5nm, }, }; @@ -1804,7 +1655,7 @@ static struct dsi_pll_vco_clk dsi0pll_shadow_vco_clk = { .name = "dsi0pll_shadow_vco_clk", .parent_names = (const char *[]){"bi_tcxo"}, .num_parents = 1, - .ops = &clk_ops_shadow_vco_7nm, + .ops = &clk_ops_shadow_vco_5nm, }, }; @@ -1816,7 +1667,7 @@ static struct dsi_pll_vco_clk dsi1pll_vco_clk = { .name = "dsi1pll_vco_clk", .parent_names = (const char *[]){"bi_tcxo"}, .num_parents = 1, - .ops = &clk_ops_vco_7nm, + .ops = &clk_ops_vco_5nm, }, }; @@ -1828,7 +1679,7 @@ static struct dsi_pll_vco_clk dsi1pll_shadow_vco_clk = { .name = "dsi1pll_shadow_vco_clk", .parent_names = (const char *[]){"bi_tcxo"}, .num_parents = 1, - .ops = &clk_ops_shadow_vco_7nm, + .ops = &clk_ops_shadow_vco_5nm, }, }; @@ -2286,7 +2137,7 @@ static struct clk_regmap_mux dsi1pll_pclk_mux = { }, }; -static struct clk_hw *mdss_dsi_pllcc_7nm[] = { +static struct clk_hw *dsi_pllcc_5nm[] = { [VCO_CLK_0] = &dsi0pll_vco_clk.hw, [PLL_OUT_DIV_0_CLK] = &dsi0pll_pll_out_div.clkr.hw, [BITCLK_SRC_0_CLK] = &dsi0pll_bitclk_src.clkr.hw, @@ -2325,13 +2176,13 @@ static struct clk_hw *mdss_dsi_pllcc_7nm[] = { [SHADOW_PCLK_SRC_1_CLK] = &dsi1pll_shadow_pclk_src.clkr.hw, }; -int dsi_pll_clock_register_7nm(struct platform_device *pdev, - struct mdss_pll_resources *pll_res) +int dsi_pll_clock_register_5nm(struct platform_device *pdev, + struct dsi_pll_resource *pll_res) { int rc = 0, ndx, i; struct clk *clk; struct clk_onecell_data *clk_data; - int num_clks = ARRAY_SIZE(mdss_dsi_pllcc_7nm); + int num_clks = ARRAY_SIZE(dsi_pllcc_5nm); struct regmap *rmap; if (!pdev || !pdev->dev.of_node || @@ -2367,37 +2218,37 @@ int dsi_pll_clock_register_7nm(struct platform_device *pdev, /* Establish client data */ if (ndx == 0) { rmap = devm_regmap_init(&pdev->dev, &pll_regmap_bus, - pll_res, &dsi_pll_7nm_config); + pll_res, &dsi_pll_5nm_config); dsi0pll_pll_out_div.clkr.regmap = rmap; dsi0pll_shadow_pll_out_div.clkr.regmap = rmap; rmap = devm_regmap_init(&pdev->dev, &bitclk_src_regmap_bus, - pll_res, &dsi_pll_7nm_config); + pll_res, &dsi_pll_5nm_config); dsi0pll_bitclk_src.clkr.regmap = rmap; dsi0pll_shadow_bitclk_src.clkr.regmap = rmap; rmap = devm_regmap_init(&pdev->dev, &pclk_src_regmap_bus, - pll_res, &dsi_pll_7nm_config); + pll_res, &dsi_pll_5nm_config); dsi0pll_pclk_src.clkr.regmap = rmap; dsi0pll_shadow_pclk_src.clkr.regmap = rmap; - rmap = devm_regmap_init(&pdev->dev, &mdss_mux_regmap_bus, - pll_res, &dsi_pll_7nm_config); + rmap = devm_regmap_init(&pdev->dev, &dsi_mux_regmap_bus, + pll_res, &dsi_pll_5nm_config); dsi0pll_pclk_mux.clkr.regmap = rmap; rmap = devm_regmap_init(&pdev->dev, &pclk_src_mux_regmap_bus, - pll_res, &dsi_pll_7nm_config); + pll_res, &dsi_pll_5nm_config); dsi0pll_pclk_src_mux.clkr.regmap = rmap; dsi0pll_shadow_pclk_src_mux.clkr.regmap = rmap; - rmap = devm_regmap_init(&pdev->dev, &mdss_mux_regmap_bus, - pll_res, &dsi_pll_7nm_config); + rmap = devm_regmap_init(&pdev->dev, &dsi_mux_regmap_bus, + pll_res, &dsi_pll_5nm_config); dsi0pll_byteclk_mux.clkr.regmap = rmap; dsi0pll_vco_clk.priv = pll_res; dsi0pll_shadow_vco_clk.priv = pll_res; - if (dsi_pll_7nm_is_hw_revision_v4_1(pll_res)) { + if (dsi_pll_5nm_is_hw_revision(pll_res)) { dsi0pll_vco_clk.min_rate = 600000000; dsi0pll_vco_clk.max_rate = 5000000000; dsi0pll_shadow_vco_clk.min_rate = 600000000; @@ -2406,7 +2257,7 @@ int dsi_pll_clock_register_7nm(struct platform_device *pdev, for (i = VCO_CLK_0; i <= SHADOW_PCLK_SRC_0_CLK; i++) { clk = devm_clk_register(&pdev->dev, - mdss_dsi_pllcc_7nm[i]); + dsi_pllcc_5nm[i]); if (IS_ERR(clk)) { pr_err("clk registration failed for DSI clock:%d\n", pll_res->index); @@ -2421,37 +2272,37 @@ int dsi_pll_clock_register_7nm(struct platform_device *pdev, of_clk_src_onecell_get, clk_data); } else { rmap = devm_regmap_init(&pdev->dev, &pll_regmap_bus, - pll_res, &dsi_pll_7nm_config); + pll_res, &dsi_pll_5nm_config); dsi1pll_pll_out_div.clkr.regmap = rmap; dsi1pll_shadow_pll_out_div.clkr.regmap = rmap; rmap = devm_regmap_init(&pdev->dev, &bitclk_src_regmap_bus, - pll_res, &dsi_pll_7nm_config); + pll_res, &dsi_pll_5nm_config); dsi1pll_bitclk_src.clkr.regmap = rmap; dsi1pll_shadow_bitclk_src.clkr.regmap = rmap; rmap = devm_regmap_init(&pdev->dev, &pclk_src_regmap_bus, - pll_res, &dsi_pll_7nm_config); + pll_res, &dsi_pll_5nm_config); dsi1pll_pclk_src.clkr.regmap = rmap; dsi1pll_shadow_pclk_src.clkr.regmap = rmap; - rmap = devm_regmap_init(&pdev->dev, &mdss_mux_regmap_bus, - pll_res, &dsi_pll_7nm_config); + rmap = devm_regmap_init(&pdev->dev, &dsi_mux_regmap_bus, + pll_res, &dsi_pll_5nm_config); dsi1pll_pclk_mux.clkr.regmap = rmap; rmap = devm_regmap_init(&pdev->dev, &pclk_src_mux_regmap_bus, - pll_res, &dsi_pll_7nm_config); + pll_res, &dsi_pll_5nm_config); dsi1pll_pclk_src_mux.clkr.regmap = rmap; dsi1pll_shadow_pclk_src_mux.clkr.regmap = rmap; - rmap = devm_regmap_init(&pdev->dev, &mdss_mux_regmap_bus, - pll_res, &dsi_pll_7nm_config); + rmap = devm_regmap_init(&pdev->dev, &dsi_mux_regmap_bus, + pll_res, &dsi_pll_5nm_config); dsi1pll_byteclk_mux.clkr.regmap = rmap; dsi1pll_vco_clk.priv = pll_res; dsi1pll_shadow_vco_clk.priv = pll_res; - if (dsi_pll_7nm_is_hw_revision_v4_1(pll_res)) { + if (dsi_pll_5nm_is_hw_revision(pll_res)) { dsi1pll_vco_clk.min_rate = 600000000; dsi1pll_vco_clk.max_rate = 5000000000; dsi1pll_shadow_vco_clk.min_rate = 600000000; @@ -2460,7 +2311,7 @@ int dsi_pll_clock_register_7nm(struct platform_device *pdev, for (i = VCO_CLK_1; i <= SHADOW_PCLK_SRC_1_CLK; i++) { clk = devm_clk_register(&pdev->dev, - mdss_dsi_pllcc_7nm[i]); + dsi_pllcc_5nm[i]); if (IS_ERR(clk)) { pr_err("clk registration failed for DSI clock:%d\n", pll_res->index); diff --git a/pll/Makefile b/pll/Makefile deleted file mode 100644 index 0b29a90caf87..000000000000 --- a/pll/Makefile +++ /dev/null @@ -1,18 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only - -ccflags-y := -I$(srctree)/drivers/clk/qcom/ - -obj-$(CONFIG_QCOM_MDSS_PLL) += pll_util.o -obj-$(CONFIG_QCOM_MDSS_PLL) += pll_drv.o -obj-$(CONFIG_QCOM_MDSS_PLL) += dsi_pll_10nm.o -obj-$(CONFIG_QCOM_MDSS_PLL) += dsi_pll_7nm.o -obj-$(CONFIG_QCOM_MDSS_PLL) += dsi_pll_28lpm.o -obj-$(CONFIG_QCOM_MDSS_PLL) += dsi_pll_28nm_util.o -obj-$(CONFIG_QCOM_MDSS_PLL) += dsi_pll_14nm.o -obj-$(CONFIG_QCOM_MDSS_PLL) += dsi_pll_14nm_util.o -obj-$(CONFIG_QCOM_MDSS_PLL) += hdmi_pll_28lpm.o -obj-$(CONFIG_QCOM_MDSS_DP_PLL) += dp_pll_7nm.o \ - dp_pll_7nm_util.o \ - dp_pll_10nm.o \ - dp_pll_10nm_util.o \ - dp_pll_14nm.o \ diff --git a/pll/dp_pll.h b/pll/dp_pll.h deleted file mode 100644 index 2ef735833002..000000000000 --- a/pll/dp_pll.h +++ /dev/null @@ -1,50 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. - */ - -#ifndef __MDSS_DP_PLL_H -#define __MDSS_DP_PLL_H - -struct dp_pll_vco_clk { - struct clk_hw hw; - unsigned long rate; /* current vco rate */ - u64 min_rate; /* min vco rate */ - u64 max_rate; /* max vco rate */ - void *priv; -}; - -static inline struct dp_pll_vco_clk *to_dp_vco_hw(struct clk_hw *hw) -{ - return container_of(hw, struct dp_pll_vco_clk, hw); -} - -#ifdef CONFIG_QCOM_MDSS_DP_PLL -int dp_pll_clock_register_14nm(struct platform_device *pdev, - struct mdss_pll_resources *pll_res); - -int dp_pll_clock_register_10nm(struct platform_device *pdev, - struct mdss_pll_resources *pll_res); - -int dp_pll_clock_register_7nm(struct platform_device *pdev, - struct mdss_pll_resources *pll_res); -#else -static inline int dp_pll_clock_register_14nm(struct platform_device *pdev, - struct mdss_pll_resources *pll_res) -{ - return 0; -} - -static inline int dp_pll_clock_register_10nm(struct platform_device *pdev, - struct mdss_pll_resources *pll_res) -{ - return 0; -} - -static inline int dp_pll_clock_register_7nm(struct platform_device *pdev, - struct mdss_pll_resources *pll_res) -{ - return 0; -} -#endif -#endif /* __MDSS_DP_PLL_H */ diff --git a/pll/dp_pll_10nm.c b/pll/dp_pll_10nm.c deleted file mode 100644 index 9c4db5ba3f24..000000000000 --- a/pll/dp_pll_10nm.c +++ /dev/null @@ -1,287 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. - */ - -/* - * Display Port PLL driver block diagram for branch clocks - * - * +------------------------------+ - * | DP_VCO_CLK | - * | | - * | +-------------------+ | - * | | (DP PLL/VCO) | | - * | +---------+---------+ | - * | v | - * | +----------+-----------+ | - * | | hsclk_divsel_clk_src | | - * | +----------+-----------+ | - * +------------------------------+ - * | - * +------------<---------v------------>----------+ - * | | - * +-----v------------+ | - * | dp_link_clk_src | | - * | divsel_ten | | - * +---------+--------+ | - * | | - * | | - * v v - * Input to DISPCC block | - * for link clk, crypto clk | - * and interface clock | - * | - * | - * +--------<------------+-----------------+---<---+ - * | | | - * +-------v------+ +--------v-----+ +--------v------+ - * | vco_divided | | vco_divided | | vco_divided | - * | _clk_src | | _clk_src | | _clk_src | - * | | | | | | - * |divsel_six | | divsel_two | | divsel_four | - * +-------+------+ +-----+--------+ +--------+------+ - * | | | - * v------->----------v-------------<------v - * | - * +----------+---------+ - * | vco_divided_clk | - * | _src_mux | - * +---------+----------+ - * | - * v - * Input to DISPCC block - * for DP pixel clock - * - */ - -#define pr_fmt(fmt) "%s: " fmt, __func__ - -#include -#include -#include -#include - -#include "pll_drv.h" -#include "dp_pll.h" -#include "dp_pll_10nm.h" - -static struct dp_pll_db dp_pdb; -static struct clk_ops mux_clk_ops; - -static struct regmap_config dp_pll_10nm_cfg = { - .reg_bits = 32, - .reg_stride = 4, - .val_bits = 32, - .max_register = 0x910, -}; - -static struct regmap_bus dp_pixel_mux_regmap_ops = { - .reg_write = dp_mux_set_parent_10nm, - .reg_read = dp_mux_get_parent_10nm, -}; - -/* Op structures */ -static const struct clk_ops dp_10nm_vco_clk_ops = { - .recalc_rate = dp_vco_recalc_rate_10nm, - .set_rate = dp_vco_set_rate_10nm, - .round_rate = dp_vco_round_rate_10nm, - .prepare = dp_vco_prepare_10nm, - .unprepare = dp_vco_unprepare_10nm, -}; - -static struct dp_pll_vco_clk dp_vco_clk = { - .min_rate = DP_VCO_HSCLK_RATE_1620MHZDIV1000, - .max_rate = DP_VCO_HSCLK_RATE_8100MHZDIV1000, - .hw.init = &(struct clk_init_data){ - .name = "dp_vco_clk", - .parent_names = (const char *[]){ "xo_board" }, - .num_parents = 1, - .ops = &dp_10nm_vco_clk_ops, - }, -}; - -static struct clk_fixed_factor dp_link_clk_divsel_ten = { - .div = 10, - .mult = 1, - - .hw.init = &(struct clk_init_data){ - .name = "dp_link_clk_divsel_ten", - .parent_names = - (const char *[]){ "dp_vco_clk" }, - .num_parents = 1, - .flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT), - .ops = &clk_fixed_factor_ops, - }, -}; - -static struct clk_fixed_factor dp_vco_divsel_two_clk_src = { - .div = 2, - .mult = 1, - - .hw.init = &(struct clk_init_data){ - .name = "dp_vco_divsel_two_clk_src", - .parent_names = - (const char *[]){ "dp_vco_clk" }, - .num_parents = 1, - .flags = (CLK_GET_RATE_NOCACHE), - .ops = &clk_fixed_factor_ops, - }, -}; - -static struct clk_fixed_factor dp_vco_divsel_four_clk_src = { - .div = 4, - .mult = 1, - - .hw.init = &(struct clk_init_data){ - .name = "dp_vco_divsel_four_clk_src", - .parent_names = - (const char *[]){ "dp_vco_clk" }, - .num_parents = 1, - .flags = (CLK_GET_RATE_NOCACHE), - .ops = &clk_fixed_factor_ops, - }, -}; - -static struct clk_fixed_factor dp_vco_divsel_six_clk_src = { - .div = 6, - .mult = 1, - - .hw.init = &(struct clk_init_data){ - .name = "dp_vco_divsel_six_clk_src", - .parent_names = - (const char *[]){ "dp_vco_clk" }, - .num_parents = 1, - .flags = (CLK_GET_RATE_NOCACHE), - .ops = &clk_fixed_factor_ops, - }, -}; - - -static int clk_mux_determine_rate(struct clk_hw *hw, - struct clk_rate_request *req) -{ - int ret = 0; - - ret = __clk_mux_determine_rate_closest(hw, req); - if (ret) - return ret; - - /* Set the new parent of mux if there is a new valid parent */ - if (hw->clk && req->best_parent_hw->clk) - clk_set_parent(hw->clk, req->best_parent_hw->clk); - - return 0; -} - -static unsigned long mux_recalc_rate(struct clk_hw *hw, - unsigned long parent_rate) -{ - struct clk *div_clk = NULL, *vco_clk = NULL; - struct dp_pll_vco_clk *vco = NULL; - - div_clk = clk_get_parent(hw->clk); - if (!div_clk) - return 0; - - vco_clk = clk_get_parent(div_clk); - if (!vco_clk) - return 0; - - vco = to_dp_vco_hw(__clk_get_hw(vco_clk)); - if (!vco) - return 0; - - if (vco->rate == DP_VCO_HSCLK_RATE_8100MHZDIV1000) - return (vco->rate / 6); - else if (vco->rate == DP_VCO_HSCLK_RATE_5400MHZDIV1000) - return (vco->rate / 4); - else - return (vco->rate / 2); -} - -static struct clk_regmap_mux dp_vco_divided_clk_src_mux = { - .reg = 0x64, - .shift = 0, - .width = 2, - - .clkr = { - .hw.init = &(struct clk_init_data){ - .name = "dp_vco_divided_clk_src_mux", - .parent_names = - (const char *[]){"dp_vco_divsel_two_clk_src", - "dp_vco_divsel_four_clk_src", - "dp_vco_divsel_six_clk_src"}, - .num_parents = 3, - .ops = &mux_clk_ops, - .flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT), - }, - }, -}; - -static struct clk_hw *mdss_dp_pllcc_10nm[] = { - [DP_VCO_CLK] = &dp_vco_clk.hw, - [DP_LINK_CLK_DIVSEL_TEN] = &dp_link_clk_divsel_ten.hw, - [DP_VCO_DIVIDED_TWO_CLK_SRC] = &dp_vco_divsel_two_clk_src.hw, - [DP_VCO_DIVIDED_FOUR_CLK_SRC] = &dp_vco_divsel_four_clk_src.hw, - [DP_VCO_DIVIDED_SIX_CLK_SRC] = &dp_vco_divsel_six_clk_src.hw, - [DP_VCO_DIVIDED_CLK_SRC_MUX] = &dp_vco_divided_clk_src_mux.clkr.hw, -}; - -int dp_pll_clock_register_10nm(struct platform_device *pdev, - struct mdss_pll_resources *pll_res) -{ - int rc = -ENOTSUPP, i = 0; - struct clk_onecell_data *clk_data; - struct clk *clk; - struct regmap *regmap; - int num_clks = ARRAY_SIZE(mdss_dp_pllcc_10nm); - - clk_data = devm_kzalloc(&pdev->dev, sizeof(*clk_data), GFP_KERNEL); - if (!clk_data) - return -ENOMEM; - - clk_data->clks = devm_kcalloc(&pdev->dev, num_clks, - sizeof(struct clk *), GFP_KERNEL); - if (!clk_data->clks) - return -ENOMEM; - - clk_data->clk_num = num_clks; - - pll_res->priv = &dp_pdb; - dp_pdb.pll = pll_res; - - /* Set client data for vco, mux and div clocks */ - regmap = devm_regmap_init(&pdev->dev, &dp_pixel_mux_regmap_ops, - pll_res, &dp_pll_10nm_cfg); - dp_vco_divided_clk_src_mux.clkr.regmap = regmap; - mux_clk_ops = clk_regmap_mux_closest_ops; - mux_clk_ops.determine_rate = clk_mux_determine_rate; - mux_clk_ops.recalc_rate = mux_recalc_rate; - - dp_vco_clk.priv = pll_res; - - for (i = DP_VCO_CLK; i <= DP_VCO_DIVIDED_CLK_SRC_MUX; i++) { - pr_debug("reg clk: %d index: %d\n", i, pll_res->index); - clk = devm_clk_register(&pdev->dev, - mdss_dp_pllcc_10nm[i]); - if (IS_ERR(clk)) { - pr_err("clk registration failed for DP: %d\n", - pll_res->index); - rc = -EINVAL; - goto clk_reg_fail; - } - clk_data->clks[i] = clk; - } - - rc = of_clk_add_provider(pdev->dev.of_node, - of_clk_src_onecell_get, clk_data); - if (rc) { - pr_err("%s: Clock register failed rc=%d\n", __func__, rc); - rc = -EPROBE_DEFER; - } else { - pr_debug("%s SUCCESS\n", __func__); - } - return 0; -clk_reg_fail: - return rc; -} diff --git a/pll/dp_pll_10nm.h b/pll/dp_pll_10nm.h deleted file mode 100644 index 2adbdf3e66cb..000000000000 --- a/pll/dp_pll_10nm.h +++ /dev/null @@ -1,51 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. - */ - -#ifndef __MDSS_DP_PLL_10NM_H -#define __MDSS_DP_PLL_10NM_H - -#define DP_VCO_HSCLK_RATE_1620MHZDIV1000 1620000UL -#define DP_VCO_HSCLK_RATE_2700MHZDIV1000 2700000UL -#define DP_VCO_HSCLK_RATE_5400MHZDIV1000 5400000UL -#define DP_VCO_HSCLK_RATE_8100MHZDIV1000 8100000UL - -struct dp_pll_db { - struct mdss_pll_resources *pll; - - /* lane and orientation settings */ - u8 lane_cnt; - u8 orientation; - - /* COM PHY settings */ - u32 hsclk_sel; - u32 dec_start_mode0; - u32 div_frac_start1_mode0; - u32 div_frac_start2_mode0; - u32 div_frac_start3_mode0; - u32 integloop_gain0_mode0; - u32 integloop_gain1_mode0; - u32 vco_tune_map; - u32 lock_cmp1_mode0; - u32 lock_cmp2_mode0; - u32 lock_cmp3_mode0; - u32 lock_cmp_en; - - /* PHY vco divider */ - u32 phy_vco_div; -}; - -int dp_vco_set_rate_10nm(struct clk_hw *hw, unsigned long rate, - unsigned long parent_rate); -unsigned long dp_vco_recalc_rate_10nm(struct clk_hw *hw, - unsigned long parent_rate); -long dp_vco_round_rate_10nm(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate); -int dp_vco_prepare_10nm(struct clk_hw *hw); -void dp_vco_unprepare_10nm(struct clk_hw *hw); -int dp_mux_set_parent_10nm(void *context, - unsigned int reg, unsigned int val); -int dp_mux_get_parent_10nm(void *context, - unsigned int reg, unsigned int *val); -#endif /* __MDSS_DP_PLL_10NM_H */ diff --git a/pll/dp_pll_10nm_util.c b/pll/dp_pll_10nm_util.c deleted file mode 100644 index 4eb859c31922..000000000000 --- a/pll/dp_pll_10nm_util.c +++ /dev/null @@ -1,757 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. - */ - -#define pr_fmt(fmt) "%s: " fmt, __func__ - -#include -#include -#include -#include -#include - -#include "pll_drv.h" -#include "dp_pll.h" -#include "dp_pll_10nm.h" - -#define DP_PHY_REVISION_ID0 0x0000 -#define DP_PHY_REVISION_ID1 0x0004 -#define DP_PHY_REVISION_ID2 0x0008 -#define DP_PHY_REVISION_ID3 0x000C - -#define DP_PHY_CFG 0x0010 -#define DP_PHY_PD_CTL 0x0018 -#define DP_PHY_MODE 0x001C - -#define DP_PHY_AUX_CFG0 0x0020 -#define DP_PHY_AUX_CFG1 0x0024 -#define DP_PHY_AUX_CFG2 0x0028 -#define DP_PHY_AUX_CFG3 0x002C -#define DP_PHY_AUX_CFG4 0x0030 -#define DP_PHY_AUX_CFG5 0x0034 -#define DP_PHY_AUX_CFG6 0x0038 -#define DP_PHY_AUX_CFG7 0x003C -#define DP_PHY_AUX_CFG8 0x0040 -#define DP_PHY_AUX_CFG9 0x0044 -#define DP_PHY_AUX_INTERRUPT_MASK 0x0048 -#define DP_PHY_AUX_INTERRUPT_CLEAR 0x004C -#define DP_PHY_AUX_BIST_CFG 0x0050 - -#define DP_PHY_VCO_DIV 0x0064 -#define DP_PHY_TX0_TX1_LANE_CTL 0x006C -#define DP_PHY_TX2_TX3_LANE_CTL 0x0088 - -#define DP_PHY_SPARE0 0x00AC -#define DP_PHY_STATUS 0x00C0 - -/* Tx registers */ -#define TXn_BIST_MODE_LANENO 0x0000 -#define TXn_CLKBUF_ENABLE 0x0008 -#define TXn_TX_EMP_POST1_LVL 0x000C - -#define TXn_TX_DRV_LVL 0x001C - -#define TXn_RESET_TSYNC_EN 0x0024 -#define TXn_PRE_STALL_LDO_BOOST_EN 0x0028 -#define TXn_TX_BAND 0x002C -#define TXn_SLEW_CNTL 0x0030 -#define TXn_INTERFACE_SELECT 0x0034 - -#define TXn_RES_CODE_LANE_TX 0x003C -#define TXn_RES_CODE_LANE_RX 0x0040 -#define TXn_RES_CODE_LANE_OFFSET_TX 0x0044 -#define TXn_RES_CODE_LANE_OFFSET_RX 0x0048 - -#define TXn_DEBUG_BUS_SEL 0x0058 -#define TXn_TRANSCEIVER_BIAS_EN 0x005C -#define TXn_HIGHZ_DRVR_EN 0x0060 -#define TXn_TX_POL_INV 0x0064 -#define TXn_PARRATE_REC_DETECT_IDLE_EN 0x0068 - -#define TXn_LANE_MODE_1 0x008C - -#define TXn_TRAN_DRVR_EMP_EN 0x00C0 -#define TXn_TX_INTERFACE_MODE 0x00C4 - -#define TXn_VMODE_CTRL1 0x00F0 - -/* PLL register offset */ -#define QSERDES_COM_ATB_SEL1 0x0000 -#define QSERDES_COM_ATB_SEL2 0x0004 -#define QSERDES_COM_FREQ_UPDATE 0x0008 -#define QSERDES_COM_BG_TIMER 0x000C -#define QSERDES_COM_SSC_EN_CENTER 0x0010 -#define QSERDES_COM_SSC_ADJ_PER1 0x0014 -#define QSERDES_COM_SSC_ADJ_PER2 0x0018 -#define QSERDES_COM_SSC_PER1 0x001C -#define QSERDES_COM_SSC_PER2 0x0020 -#define QSERDES_COM_SSC_STEP_SIZE1 0x0024 -#define QSERDES_COM_SSC_STEP_SIZE2 0x0028 -#define QSERDES_COM_POST_DIV 0x002C -#define QSERDES_COM_POST_DIV_MUX 0x0030 -#define QSERDES_COM_BIAS_EN_CLKBUFLR_EN 0x0034 -#define QSERDES_COM_CLK_ENABLE1 0x0038 -#define QSERDES_COM_SYS_CLK_CTRL 0x003C -#define QSERDES_COM_SYSCLK_BUF_ENABLE 0x0040 -#define QSERDES_COM_PLL_EN 0x0044 -#define QSERDES_COM_PLL_IVCO 0x0048 -#define QSERDES_COM_CMN_IETRIM 0x004C -#define QSERDES_COM_CMN_IPTRIM 0x0050 - -#define QSERDES_COM_CP_CTRL_MODE0 0x0060 -#define QSERDES_COM_CP_CTRL_MODE1 0x0064 -#define QSERDES_COM_PLL_RCTRL_MODE0 0x0068 -#define QSERDES_COM_PLL_RCTRL_MODE1 0x006C -#define QSERDES_COM_PLL_CCTRL_MODE0 0x0070 -#define QSERDES_COM_PLL_CCTRL_MODE1 0x0074 -#define QSERDES_COM_PLL_CNTRL 0x0078 -#define QSERDES_COM_BIAS_EN_CTRL_BY_PSM 0x007C -#define QSERDES_COM_SYSCLK_EN_SEL 0x0080 -#define QSERDES_COM_CML_SYSCLK_SEL 0x0084 -#define QSERDES_COM_RESETSM_CNTRL 0x0088 -#define QSERDES_COM_RESETSM_CNTRL2 0x008C -#define QSERDES_COM_LOCK_CMP_EN 0x0090 -#define QSERDES_COM_LOCK_CMP_CFG 0x0094 -#define QSERDES_COM_LOCK_CMP1_MODE0 0x0098 -#define QSERDES_COM_LOCK_CMP2_MODE0 0x009C -#define QSERDES_COM_LOCK_CMP3_MODE0 0x00A0 - -#define QSERDES_COM_DEC_START_MODE0 0x00B0 -#define QSERDES_COM_DEC_START_MODE1 0x00B4 -#define QSERDES_COM_DIV_FRAC_START1_MODE0 0x00B8 -#define QSERDES_COM_DIV_FRAC_START2_MODE0 0x00BC -#define QSERDES_COM_DIV_FRAC_START3_MODE0 0x00C0 -#define QSERDES_COM_DIV_FRAC_START1_MODE1 0x00C4 -#define QSERDES_COM_DIV_FRAC_START2_MODE1 0x00C8 -#define QSERDES_COM_DIV_FRAC_START3_MODE1 0x00CC -#define QSERDES_COM_INTEGLOOP_INITVAL 0x00D0 -#define QSERDES_COM_INTEGLOOP_EN 0x00D4 -#define QSERDES_COM_INTEGLOOP_GAIN0_MODE0 0x00D8 -#define QSERDES_COM_INTEGLOOP_GAIN1_MODE0 0x00DC -#define QSERDES_COM_INTEGLOOP_GAIN0_MODE1 0x00E0 -#define QSERDES_COM_INTEGLOOP_GAIN1_MODE1 0x00E4 -#define QSERDES_COM_VCOCAL_DEADMAN_CTRL 0x00E8 -#define QSERDES_COM_VCO_TUNE_CTRL 0x00EC -#define QSERDES_COM_VCO_TUNE_MAP 0x00F0 - -#define QSERDES_COM_CMN_STATUS 0x0124 -#define QSERDES_COM_RESET_SM_STATUS 0x0128 - -#define QSERDES_COM_CLK_SEL 0x0138 -#define QSERDES_COM_HSCLK_SEL 0x013C - -#define QSERDES_COM_CORECLK_DIV_MODE0 0x0148 - -#define QSERDES_COM_SW_RESET 0x0150 -#define QSERDES_COM_CORE_CLK_EN 0x0154 -#define QSERDES_COM_C_READY_STATUS 0x0158 -#define QSERDES_COM_CMN_CONFIG 0x015C - -#define QSERDES_COM_SVS_MODE_CLK_SEL 0x0164 - -#define DP_PHY_PLL_POLL_SLEEP_US 500 -#define DP_PHY_PLL_POLL_TIMEOUT_US 10000 - -#define DP_VCO_RATE_8100MHZDIV1000 8100000UL -#define DP_VCO_RATE_9720MHZDIV1000 9720000UL -#define DP_VCO_RATE_10800MHZDIV1000 10800000UL - -int dp_mux_set_parent_10nm(void *context, unsigned int reg, unsigned int val) -{ - struct mdss_pll_resources *dp_res = context; - int rc; - u32 auxclk_div; - - rc = mdss_pll_resource_enable(dp_res, true); - if (rc) { - pr_err("Failed to enable mdss DP PLL resources\n"); - return rc; - } - - auxclk_div = MDSS_PLL_REG_R(dp_res->phy_base, DP_PHY_VCO_DIV); - auxclk_div &= ~0x03; /* bits 0 to 1 */ - - if (val == 0) /* mux parent index = 0 */ - auxclk_div |= 1; - else if (val == 1) /* mux parent index = 1 */ - auxclk_div |= 2; - else if (val == 2) /* mux parent index = 2 */ - auxclk_div |= 0; - - MDSS_PLL_REG_W(dp_res->phy_base, - DP_PHY_VCO_DIV, auxclk_div); - /* Make sure the PHY registers writes are done */ - wmb(); - pr_debug("%s: mux=%d auxclk_div=%x\n", __func__, val, auxclk_div); - - mdss_pll_resource_enable(dp_res, false); - - return 0; -} - -int dp_mux_get_parent_10nm(void *context, unsigned int reg, unsigned int *val) -{ - int rc; - u32 auxclk_div = 0; - struct mdss_pll_resources *dp_res = context; - - rc = mdss_pll_resource_enable(dp_res, true); - if (rc) { - pr_err("Failed to enable dp_res resources\n"); - return rc; - } - - auxclk_div = MDSS_PLL_REG_R(dp_res->phy_base, DP_PHY_VCO_DIV); - auxclk_div &= 0x03; - - if (auxclk_div == 1) /* Default divider */ - *val = 0; - else if (auxclk_div == 2) - *val = 1; - else if (auxclk_div == 0) - *val = 2; - - mdss_pll_resource_enable(dp_res, false); - - pr_debug("%s: auxclk_div=%d, val=%d\n", __func__, auxclk_div, *val); - - return 0; -} - -static int dp_vco_pll_init_db_10nm(struct dp_pll_db *pdb, - unsigned long rate) -{ - struct mdss_pll_resources *dp_res = pdb->pll; - u32 spare_value = 0; - - spare_value = MDSS_PLL_REG_R(dp_res->phy_base, DP_PHY_SPARE0); - pdb->lane_cnt = spare_value & 0x0F; - pdb->orientation = (spare_value & 0xF0) >> 4; - - pr_debug("%s: spare_value=0x%x, ln_cnt=0x%x, orientation=0x%x\n", - __func__, spare_value, pdb->lane_cnt, pdb->orientation); - - switch (rate) { - case DP_VCO_HSCLK_RATE_1620MHZDIV1000: - pr_debug("%s: VCO rate: %ld\n", __func__, - DP_VCO_RATE_9720MHZDIV1000); - pdb->hsclk_sel = 0x0c; - pdb->dec_start_mode0 = 0x69; - pdb->div_frac_start1_mode0 = 0x00; - pdb->div_frac_start2_mode0 = 0x80; - pdb->div_frac_start3_mode0 = 0x07; - pdb->integloop_gain0_mode0 = 0x3f; - pdb->integloop_gain1_mode0 = 0x00; - pdb->vco_tune_map = 0x00; - pdb->lock_cmp1_mode0 = 0x6f; - pdb->lock_cmp2_mode0 = 0x08; - pdb->lock_cmp3_mode0 = 0x00; - pdb->phy_vco_div = 0x1; - pdb->lock_cmp_en = 0x00; - break; - case DP_VCO_HSCLK_RATE_2700MHZDIV1000: - pr_debug("%s: VCO rate: %ld\n", __func__, - DP_VCO_RATE_10800MHZDIV1000); - pdb->hsclk_sel = 0x04; - pdb->dec_start_mode0 = 0x69; - pdb->div_frac_start1_mode0 = 0x00; - pdb->div_frac_start2_mode0 = 0x80; - pdb->div_frac_start3_mode0 = 0x07; - pdb->integloop_gain0_mode0 = 0x3f; - pdb->integloop_gain1_mode0 = 0x00; - pdb->vco_tune_map = 0x00; - pdb->lock_cmp1_mode0 = 0x0f; - pdb->lock_cmp2_mode0 = 0x0e; - pdb->lock_cmp3_mode0 = 0x00; - pdb->phy_vco_div = 0x1; - pdb->lock_cmp_en = 0x00; - break; - case DP_VCO_HSCLK_RATE_5400MHZDIV1000: - pr_debug("%s: VCO rate: %ld\n", __func__, - DP_VCO_RATE_10800MHZDIV1000); - pdb->hsclk_sel = 0x00; - pdb->dec_start_mode0 = 0x8c; - pdb->div_frac_start1_mode0 = 0x00; - pdb->div_frac_start2_mode0 = 0x00; - pdb->div_frac_start3_mode0 = 0x0a; - pdb->integloop_gain0_mode0 = 0x3f; - pdb->integloop_gain1_mode0 = 0x00; - pdb->vco_tune_map = 0x00; - pdb->lock_cmp1_mode0 = 0x1f; - pdb->lock_cmp2_mode0 = 0x1c; - pdb->lock_cmp3_mode0 = 0x00; - pdb->phy_vco_div = 0x2; - pdb->lock_cmp_en = 0x00; - break; - case DP_VCO_HSCLK_RATE_8100MHZDIV1000: - pr_debug("%s: VCO rate: %ld\n", __func__, - DP_VCO_RATE_8100MHZDIV1000); - pdb->hsclk_sel = 0x03; - pdb->dec_start_mode0 = 0x69; - pdb->div_frac_start1_mode0 = 0x00; - pdb->div_frac_start2_mode0 = 0x80; - pdb->div_frac_start3_mode0 = 0x07; - pdb->integloop_gain0_mode0 = 0x3f; - pdb->integloop_gain1_mode0 = 0x00; - pdb->vco_tune_map = 0x00; - pdb->lock_cmp1_mode0 = 0x2f; - pdb->lock_cmp2_mode0 = 0x2a; - pdb->lock_cmp3_mode0 = 0x00; - pdb->phy_vco_div = 0x0; - pdb->lock_cmp_en = 0x08; - break; - default: - return -EINVAL; - } - return 0; -} - -static int dp_config_vco_rate_10nm(struct dp_pll_vco_clk *vco, - unsigned long rate) -{ - u32 res = 0; - struct mdss_pll_resources *dp_res = vco->priv; - struct dp_pll_db *pdb = (struct dp_pll_db *)dp_res->priv; - - res = dp_vco_pll_init_db_10nm(pdb, rate); - if (res) { - pr_err("VCO Init DB failed\n"); - return res; - } - - if (pdb->lane_cnt != 4) { - if (pdb->orientation == ORIENTATION_CC2) - MDSS_PLL_REG_W(dp_res->phy_base, DP_PHY_PD_CTL, 0x6d); - else - MDSS_PLL_REG_W(dp_res->phy_base, DP_PHY_PD_CTL, 0x75); - } else { - MDSS_PLL_REG_W(dp_res->phy_base, DP_PHY_PD_CTL, 0x7d); - } - - /* Make sure the PHY register writes are done */ - wmb(); - - MDSS_PLL_REG_W(dp_res->pll_base, QSERDES_COM_SVS_MODE_CLK_SEL, 0x01); - MDSS_PLL_REG_W(dp_res->pll_base, QSERDES_COM_SYSCLK_EN_SEL, 0x37); - MDSS_PLL_REG_W(dp_res->pll_base, QSERDES_COM_SYS_CLK_CTRL, 0x02); - MDSS_PLL_REG_W(dp_res->pll_base, QSERDES_COM_CLK_ENABLE1, 0x0e); - MDSS_PLL_REG_W(dp_res->pll_base, QSERDES_COM_SYSCLK_BUF_ENABLE, 0x06); - MDSS_PLL_REG_W(dp_res->pll_base, QSERDES_COM_CLK_SEL, 0x30); - MDSS_PLL_REG_W(dp_res->pll_base, QSERDES_COM_CMN_CONFIG, 0x02); - - /* Different for each clock rates */ - MDSS_PLL_REG_W(dp_res->pll_base, - QSERDES_COM_HSCLK_SEL, pdb->hsclk_sel); - MDSS_PLL_REG_W(dp_res->pll_base, - QSERDES_COM_DEC_START_MODE0, pdb->dec_start_mode0); - MDSS_PLL_REG_W(dp_res->pll_base, - QSERDES_COM_DIV_FRAC_START1_MODE0, pdb->div_frac_start1_mode0); - MDSS_PLL_REG_W(dp_res->pll_base, - QSERDES_COM_DIV_FRAC_START2_MODE0, pdb->div_frac_start2_mode0); - MDSS_PLL_REG_W(dp_res->pll_base, - QSERDES_COM_DIV_FRAC_START3_MODE0, pdb->div_frac_start3_mode0); - MDSS_PLL_REG_W(dp_res->pll_base, - QSERDES_COM_INTEGLOOP_GAIN0_MODE0, pdb->integloop_gain0_mode0); - MDSS_PLL_REG_W(dp_res->pll_base, - QSERDES_COM_INTEGLOOP_GAIN1_MODE0, pdb->integloop_gain1_mode0); - MDSS_PLL_REG_W(dp_res->pll_base, - QSERDES_COM_VCO_TUNE_MAP, pdb->vco_tune_map); - MDSS_PLL_REG_W(dp_res->pll_base, - QSERDES_COM_LOCK_CMP1_MODE0, pdb->lock_cmp1_mode0); - MDSS_PLL_REG_W(dp_res->pll_base, - QSERDES_COM_LOCK_CMP2_MODE0, pdb->lock_cmp2_mode0); - MDSS_PLL_REG_W(dp_res->pll_base, - QSERDES_COM_LOCK_CMP3_MODE0, pdb->lock_cmp3_mode0); - /* Make sure the PLL register writes are done */ - wmb(); - - MDSS_PLL_REG_W(dp_res->pll_base, QSERDES_COM_BG_TIMER, 0x0a); - MDSS_PLL_REG_W(dp_res->pll_base, QSERDES_COM_CORECLK_DIV_MODE0, 0x0a); - MDSS_PLL_REG_W(dp_res->pll_base, QSERDES_COM_VCO_TUNE_CTRL, 0x00); - MDSS_PLL_REG_W(dp_res->pll_base, QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x3f); - MDSS_PLL_REG_W(dp_res->pll_base, QSERDES_COM_CORE_CLK_EN, 0x1f); - MDSS_PLL_REG_W(dp_res->pll_base, QSERDES_COM_PLL_IVCO, 0x07); - MDSS_PLL_REG_W(dp_res->pll_base, - QSERDES_COM_LOCK_CMP_EN, pdb->lock_cmp_en); - MDSS_PLL_REG_W(dp_res->pll_base, QSERDES_COM_PLL_CCTRL_MODE0, 0x36); - MDSS_PLL_REG_W(dp_res->pll_base, QSERDES_COM_PLL_RCTRL_MODE0, 0x16); - MDSS_PLL_REG_W(dp_res->pll_base, QSERDES_COM_CP_CTRL_MODE0, 0x06); - /* Make sure the PHY register writes are done */ - wmb(); - - if (pdb->orientation == ORIENTATION_CC2) - MDSS_PLL_REG_W(dp_res->phy_base, DP_PHY_MODE, 0x4c); - else - MDSS_PLL_REG_W(dp_res->phy_base, DP_PHY_MODE, 0x5c); - /* Make sure the PLL register writes are done */ - wmb(); - - /* TX Lane configuration */ - MDSS_PLL_REG_W(dp_res->phy_base, - DP_PHY_TX0_TX1_LANE_CTL, 0x05); - MDSS_PLL_REG_W(dp_res->phy_base, - DP_PHY_TX2_TX3_LANE_CTL, 0x05); - - /* TX-0 register configuration */ - MDSS_PLL_REG_W(dp_res->ln_tx0_base, TXn_TRANSCEIVER_BIAS_EN, 0x1a); - MDSS_PLL_REG_W(dp_res->ln_tx0_base, TXn_VMODE_CTRL1, 0x40); - MDSS_PLL_REG_W(dp_res->ln_tx0_base, TXn_PRE_STALL_LDO_BOOST_EN, 0x30); - MDSS_PLL_REG_W(dp_res->ln_tx0_base, TXn_INTERFACE_SELECT, 0x3d); - MDSS_PLL_REG_W(dp_res->ln_tx0_base, TXn_CLKBUF_ENABLE, 0x0f); - MDSS_PLL_REG_W(dp_res->ln_tx0_base, TXn_RESET_TSYNC_EN, 0x03); - MDSS_PLL_REG_W(dp_res->ln_tx0_base, TXn_TRAN_DRVR_EMP_EN, 0x03); - MDSS_PLL_REG_W(dp_res->ln_tx0_base, - TXn_PARRATE_REC_DETECT_IDLE_EN, 0x00); - MDSS_PLL_REG_W(dp_res->ln_tx0_base, TXn_TX_INTERFACE_MODE, 0x00); - MDSS_PLL_REG_W(dp_res->ln_tx0_base, TXn_TX_BAND, 0x4); - - /* TX-1 register configuration */ - MDSS_PLL_REG_W(dp_res->ln_tx1_base, TXn_TRANSCEIVER_BIAS_EN, 0x1a); - MDSS_PLL_REG_W(dp_res->ln_tx1_base, TXn_VMODE_CTRL1, 0x40); - MDSS_PLL_REG_W(dp_res->ln_tx1_base, TXn_PRE_STALL_LDO_BOOST_EN, 0x30); - MDSS_PLL_REG_W(dp_res->ln_tx1_base, TXn_INTERFACE_SELECT, 0x3d); - MDSS_PLL_REG_W(dp_res->ln_tx1_base, TXn_CLKBUF_ENABLE, 0x0f); - MDSS_PLL_REG_W(dp_res->ln_tx1_base, TXn_RESET_TSYNC_EN, 0x03); - MDSS_PLL_REG_W(dp_res->ln_tx1_base, TXn_TRAN_DRVR_EMP_EN, 0x03); - MDSS_PLL_REG_W(dp_res->ln_tx1_base, - TXn_PARRATE_REC_DETECT_IDLE_EN, 0x00); - MDSS_PLL_REG_W(dp_res->ln_tx1_base, TXn_TX_INTERFACE_MODE, 0x00); - MDSS_PLL_REG_W(dp_res->ln_tx1_base, TXn_TX_BAND, 0x4); - /* Make sure the PHY register writes are done */ - wmb(); - - /* dependent on the vco frequency */ - MDSS_PLL_REG_W(dp_res->phy_base, DP_PHY_VCO_DIV, pdb->phy_vco_div); - - return res; -} - -static bool dp_10nm_pll_lock_status(struct mdss_pll_resources *dp_res) -{ - u32 status; - bool pll_locked; - - /* poll for PLL lock status */ - if (readl_poll_timeout_atomic((dp_res->pll_base + - QSERDES_COM_C_READY_STATUS), - status, - ((status & BIT(0)) > 0), - DP_PHY_PLL_POLL_SLEEP_US, - DP_PHY_PLL_POLL_TIMEOUT_US)) { - pr_err("%s: C_READY status is not high. Status=%x\n", - __func__, status); - pll_locked = false; - } else { - pll_locked = true; - } - - return pll_locked; -} - -static bool dp_10nm_phy_rdy_status(struct mdss_pll_resources *dp_res) -{ - u32 status; - bool phy_ready = true; - - /* poll for PHY ready status */ - if (readl_poll_timeout_atomic((dp_res->phy_base + - DP_PHY_STATUS), - status, - ((status & (BIT(1))) > 0), - DP_PHY_PLL_POLL_SLEEP_US, - DP_PHY_PLL_POLL_TIMEOUT_US)) { - pr_err("%s: Phy_ready is not high. Status=%x\n", - __func__, status); - phy_ready = false; - } - - return phy_ready; -} - -static int dp_pll_enable_10nm(struct clk_hw *hw) -{ - int rc = 0; - struct dp_pll_vco_clk *vco = to_dp_vco_hw(hw); - struct mdss_pll_resources *dp_res = vco->priv; - struct dp_pll_db *pdb = (struct dp_pll_db *)dp_res->priv; - u32 bias_en, drvr_en; - - MDSS_PLL_REG_W(dp_res->phy_base, DP_PHY_AUX_CFG2, 0x04); - MDSS_PLL_REG_W(dp_res->phy_base, DP_PHY_CFG, 0x01); - MDSS_PLL_REG_W(dp_res->phy_base, DP_PHY_CFG, 0x05); - MDSS_PLL_REG_W(dp_res->phy_base, DP_PHY_CFG, 0x01); - MDSS_PLL_REG_W(dp_res->phy_base, DP_PHY_CFG, 0x09); - wmb(); /* Make sure the PHY register writes are done */ - - MDSS_PLL_REG_W(dp_res->pll_base, QSERDES_COM_RESETSM_CNTRL, 0x20); - wmb(); /* Make sure the PLL register writes are done */ - - if (!dp_10nm_pll_lock_status(dp_res)) { - rc = -EINVAL; - goto lock_err; - } - - MDSS_PLL_REG_W(dp_res->phy_base, DP_PHY_CFG, 0x19); - /* Make sure the PHY register writes are done */ - wmb(); - /* poll for PHY ready status */ - if (!dp_10nm_phy_rdy_status(dp_res)) { - rc = -EINVAL; - goto lock_err; - } - - pr_debug("%s: PLL is locked\n", __func__); - - if (pdb->lane_cnt == 1) { - bias_en = 0x3e; - drvr_en = 0x13; - } else { - bias_en = 0x3f; - drvr_en = 0x10; - } - - if (pdb->lane_cnt != 4) { - if (pdb->orientation == ORIENTATION_CC1) { - MDSS_PLL_REG_W(dp_res->ln_tx1_base, - TXn_HIGHZ_DRVR_EN, drvr_en); - MDSS_PLL_REG_W(dp_res->ln_tx1_base, - TXn_TRANSCEIVER_BIAS_EN, bias_en); - } else { - MDSS_PLL_REG_W(dp_res->ln_tx0_base, - TXn_HIGHZ_DRVR_EN, drvr_en); - MDSS_PLL_REG_W(dp_res->ln_tx0_base, - TXn_TRANSCEIVER_BIAS_EN, bias_en); - } - } else { - MDSS_PLL_REG_W(dp_res->ln_tx0_base, TXn_HIGHZ_DRVR_EN, drvr_en); - MDSS_PLL_REG_W(dp_res->ln_tx0_base, - TXn_TRANSCEIVER_BIAS_EN, bias_en); - MDSS_PLL_REG_W(dp_res->ln_tx1_base, TXn_HIGHZ_DRVR_EN, drvr_en); - MDSS_PLL_REG_W(dp_res->ln_tx1_base, - TXn_TRANSCEIVER_BIAS_EN, bias_en); - } - - MDSS_PLL_REG_W(dp_res->ln_tx0_base, TXn_TX_POL_INV, 0x0a); - MDSS_PLL_REG_W(dp_res->ln_tx1_base, TXn_TX_POL_INV, 0x0a); - MDSS_PLL_REG_W(dp_res->phy_base, DP_PHY_CFG, 0x18); - udelay(2000); - - MDSS_PLL_REG_W(dp_res->phy_base, DP_PHY_CFG, 0x19); - - /* - * Make sure all the register writes are completed before - * doing any other operation - */ - wmb(); - - /* poll for PHY ready status */ - if (!dp_10nm_phy_rdy_status(dp_res)) { - rc = -EINVAL; - goto lock_err; - } - - MDSS_PLL_REG_W(dp_res->ln_tx0_base, TXn_TX_DRV_LVL, 0x38); - MDSS_PLL_REG_W(dp_res->ln_tx1_base, TXn_TX_DRV_LVL, 0x38); - MDSS_PLL_REG_W(dp_res->ln_tx0_base, TXn_TX_EMP_POST1_LVL, 0x20); - MDSS_PLL_REG_W(dp_res->ln_tx1_base, TXn_TX_EMP_POST1_LVL, 0x20); - MDSS_PLL_REG_W(dp_res->ln_tx0_base, TXn_RES_CODE_LANE_OFFSET_TX, 0x06); - MDSS_PLL_REG_W(dp_res->ln_tx1_base, TXn_RES_CODE_LANE_OFFSET_TX, 0x06); - MDSS_PLL_REG_W(dp_res->ln_tx0_base, TXn_RES_CODE_LANE_OFFSET_RX, 0x07); - MDSS_PLL_REG_W(dp_res->ln_tx1_base, TXn_RES_CODE_LANE_OFFSET_RX, 0x07); - /* Make sure the PHY register writes are done */ - wmb(); - -lock_err: - return rc; -} - -static int dp_pll_disable_10nm(struct clk_hw *hw) -{ - struct dp_pll_vco_clk *vco = to_dp_vco_hw(hw); - struct mdss_pll_resources *dp_res = vco->priv; - - /* Assert DP PHY power down */ - MDSS_PLL_REG_W(dp_res->phy_base, DP_PHY_PD_CTL, 0x2); - /* - * Make sure all the register writes to disable PLL are - * completed before doing any other operation - */ - wmb(); - - return 0; -} - - -int dp_vco_prepare_10nm(struct clk_hw *hw) -{ - int rc = 0; - struct dp_pll_vco_clk *vco = to_dp_vco_hw(hw); - struct mdss_pll_resources *dp_res = vco->priv; - - pr_debug("rate=%ld\n", vco->rate); - rc = mdss_pll_resource_enable(dp_res, true); - if (rc) { - pr_err("Failed to enable mdss DP pll resources\n"); - goto error; - } - - if ((dp_res->vco_cached_rate != 0) - && (dp_res->vco_cached_rate == vco->rate)) { - rc = vco->hw.init->ops->set_rate(hw, - dp_res->vco_cached_rate, dp_res->vco_cached_rate); - if (rc) { - pr_err("index=%d vco_set_rate failed. rc=%d\n", - rc, dp_res->index); - mdss_pll_resource_enable(dp_res, false); - goto error; - } - } - - rc = dp_pll_enable_10nm(hw); - if (rc) { - mdss_pll_resource_enable(dp_res, false); - pr_err("ndx=%d failed to enable dp pll\n", - dp_res->index); - goto error; - } - - mdss_pll_resource_enable(dp_res, false); -error: - return rc; -} - -void dp_vco_unprepare_10nm(struct clk_hw *hw) -{ - struct dp_pll_vco_clk *vco = to_dp_vco_hw(hw); - struct mdss_pll_resources *dp_res = vco->priv; - - if (!dp_res) { - pr_err("Invalid input parameter\n"); - return; - } - - if (!dp_res->pll_on && - mdss_pll_resource_enable(dp_res, true)) { - pr_err("pll resource can't be enabled\n"); - return; - } - dp_res->vco_cached_rate = vco->rate; - dp_pll_disable_10nm(hw); - - dp_res->handoff_resources = false; - mdss_pll_resource_enable(dp_res, false); - dp_res->pll_on = false; -} - -int dp_vco_set_rate_10nm(struct clk_hw *hw, unsigned long rate, - unsigned long parent_rate) -{ - struct dp_pll_vco_clk *vco = to_dp_vco_hw(hw); - struct mdss_pll_resources *dp_res = vco->priv; - int rc; - - rc = mdss_pll_resource_enable(dp_res, true); - if (rc) { - pr_err("pll resource can't be enabled\n"); - return rc; - } - - pr_debug("DP lane CLK rate=%ld\n", rate); - - rc = dp_config_vco_rate_10nm(vco, rate); - if (rc) - pr_err("%s: Failed to set clk rate\n", __func__); - - mdss_pll_resource_enable(dp_res, false); - - vco->rate = rate; - - return 0; -} - -unsigned long dp_vco_recalc_rate_10nm(struct clk_hw *hw, - unsigned long parent_rate) -{ - struct dp_pll_vco_clk *vco = to_dp_vco_hw(hw); - int rc; - u32 div, hsclk_div, link_clk_div = 0; - u64 vco_rate; - struct mdss_pll_resources *dp_res = vco->priv; - - rc = mdss_pll_resource_enable(dp_res, true); - if (rc) { - pr_err("Failed to enable mdss DP pll=%d\n", dp_res->index); - return rc; - } - - div = MDSS_PLL_REG_R(dp_res->pll_base, QSERDES_COM_HSCLK_SEL); - div &= 0x0f; - - if (div == 12) - hsclk_div = 6; /* Default */ - else if (div == 4) - hsclk_div = 4; - else if (div == 0) - hsclk_div = 2; - else if (div == 3) - hsclk_div = 1; - else { - pr_debug("unknown divider. forcing to default\n"); - hsclk_div = 5; - } - - div = MDSS_PLL_REG_R(dp_res->phy_base, DP_PHY_AUX_CFG2); - div >>= 2; - - if ((div & 0x3) == 0) - link_clk_div = 5; - else if ((div & 0x3) == 1) - link_clk_div = 10; - else if ((div & 0x3) == 2) - link_clk_div = 20; - else - pr_err("%s: unsupported div. Phy_mode: %d\n", __func__, div); - - if (link_clk_div == 20) { - vco_rate = DP_VCO_HSCLK_RATE_2700MHZDIV1000; - } else { - if (hsclk_div == 6) - vco_rate = DP_VCO_HSCLK_RATE_1620MHZDIV1000; - else if (hsclk_div == 4) - vco_rate = DP_VCO_HSCLK_RATE_2700MHZDIV1000; - else if (hsclk_div == 2) - vco_rate = DP_VCO_HSCLK_RATE_5400MHZDIV1000; - else - vco_rate = DP_VCO_HSCLK_RATE_8100MHZDIV1000; - } - - pr_debug("returning vco rate = %lu\n", (unsigned long)vco_rate); - - mdss_pll_resource_enable(dp_res, false); - - dp_res->vco_cached_rate = vco->rate = vco_rate; - return (unsigned long)vco_rate; -} - -long dp_vco_round_rate_10nm(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) -{ - unsigned long rrate = rate; - struct dp_pll_vco_clk *vco = to_dp_vco_hw(hw); - - if (rate <= vco->min_rate) - rrate = vco->min_rate; - else if (rate <= DP_VCO_HSCLK_RATE_2700MHZDIV1000) - rrate = DP_VCO_HSCLK_RATE_2700MHZDIV1000; - else if (rate <= DP_VCO_HSCLK_RATE_5400MHZDIV1000) - rrate = DP_VCO_HSCLK_RATE_5400MHZDIV1000; - else - rrate = vco->max_rate; - - pr_debug("%s: rrate=%ld\n", __func__, rrate); - - *parent_rate = rrate; - return rrate; -} - diff --git a/pll/dp_pll_14nm.c b/pll/dp_pll_14nm.c deleted file mode 100644 index 05641bb8432c..000000000000 --- a/pll/dp_pll_14nm.c +++ /dev/null @@ -1,820 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. - */ - -/* - *************************************************************************** - ******** Display Port PLL driver block diagram for branch clocks ********** - *************************************************************************** - - +--------------------------+ - | DP_VCO_CLK | - | | - | +-------------------+ | - | | (DP PLL/VCO) | | - | +---------+---------+ | - | v | - | +----------+-----------+ | - | | hsclk_divsel_clk_src | | - | +----------+-----------+ | - +--------------------------+ - | - v - +------------<------------|------------>-------------+ - | | | -+----------v----------+ +----------v----------+ +----------v----------+ -| dp_link_2x_clk | | vco_divided_clk_src | | vco_divided_clk_src | -| divsel_five | | | | | -v----------+----------v | divsel_two | | divsel_four | - | +----------+----------+ +----------+----------+ - | | | - v v v - | +---------------------+ | - Input to MMSSCC block | | (aux_clk_ops) | | - for link clk, crypto clk +--> vco_divided_clk <-+ - and interface clock | _src_mux | - +----------+----------+ - | - v - Input to MMSSCC block - for DP pixel clock - - ****************************************************************************** - */ - -#define pr_fmt(fmt) "%s: " fmt, __func__ - -#include -#include -#include -#include -#include - -#include - -#include "pll_drv.h" -#include "dp_pll.h" -#include "dp_pll_14nm.h" - -static struct dp_pll_db dp_pdb; -static struct clk_ops mux_clk_ops; - -static struct regmap_config dp_pll_14nm_cfg = { - .reg_bits = 32, - .reg_stride = 4, - .val_bits = 32, - .max_register = 0x910, -}; - -static struct regmap_bus dp_pixel_mux_regmap_ops = { - .reg_write = dp_mux_set_parent_14nm, - .reg_read = dp_mux_get_parent_14nm, -}; - -/* Op structures */ -static const struct clk_ops dp_14nm_vco_clk_ops = { - .recalc_rate = dp_vco_recalc_rate_14nm, - .set_rate = dp_vco_set_rate_14nm, - .round_rate = dp_vco_round_rate_14nm, - .prepare = dp_vco_prepare_14nm, - .unprepare = dp_vco_unprepare_14nm, -}; - -static struct dp_pll_vco_clk dp_vco_clk = { - .min_rate = DP_VCO_HSCLK_RATE_1620MHZDIV1000, - .max_rate = DP_VCO_HSCLK_RATE_5400MHZDIV1000, - .hw.init = &(struct clk_init_data){ - .name = "dp_vco_clk", - .parent_names = (const char *[]){ "xo_board" }, - .num_parents = 1, - .ops = &dp_14nm_vco_clk_ops, - }, -}; - -static struct clk_fixed_factor dp_phy_pll_link_clk = { - .div = 10, - .mult = 1, - - .hw.init = &(struct clk_init_data){ - .name = "dp_phy_pll_link_clk", - .parent_names = - (const char *[]){ "dp_vco_clk" }, - .num_parents = 1, - .flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT), - .ops = &clk_fixed_factor_ops, - }, -}; - -static struct clk_fixed_factor dp_vco_divsel_two_clk_src = { - .div = 2, - .mult = 1, - - .hw.init = &(struct clk_init_data){ - .name = "dp_vco_divsel_two_clk_src", - .parent_names = - (const char *[]){ "dp_vco_clk" }, - .num_parents = 1, - .flags = (CLK_GET_RATE_NOCACHE), - .ops = &clk_fixed_factor_ops, - }, -}; - -static struct clk_fixed_factor dp_vco_divsel_four_clk_src = { - .div = 4, - .mult = 1, - - .hw.init = &(struct clk_init_data){ - .name = "dp_vco_divsel_four_clk_src", - .parent_names = - (const char *[]){ "dp_vco_clk" }, - .num_parents = 1, - .flags = (CLK_GET_RATE_NOCACHE), - .ops = &clk_fixed_factor_ops, - }, -}; - -static int clk_mux_determine_rate(struct clk_hw *hw, - struct clk_rate_request *req) -{ - int ret = 0; - - ret = __clk_mux_determine_rate_closest(hw, req); - if (ret) - return ret; - - /* Set the new parent of mux if there is a new valid parent */ - if (hw->clk && req->best_parent_hw->clk) - clk_set_parent(hw->clk, req->best_parent_hw->clk); - - return 0; -} - - -static unsigned long mux_recalc_rate(struct clk_hw *hw, - unsigned long parent_rate) -{ - struct clk *div_clk = NULL, *vco_clk = NULL; - struct dp_pll_vco_clk *vco = NULL; - - div_clk = clk_get_parent(hw->clk); - if (!div_clk) - return 0; - - vco_clk = clk_get_parent(div_clk); - if (!vco_clk) - return 0; - - vco = to_dp_vco_hw(__clk_get_hw(vco_clk)); - if (!vco) - return 0; - - if (vco->rate == DP_VCO_HSCLK_RATE_5400MHZDIV1000) - return (vco->rate / 4); - else - return (vco->rate / 2); -} - -static struct clk_regmap_mux dp_phy_pll_vco_div_clk = { - .reg = 0x64, - .shift = 0, - .width = 1, - - .clkr = { - .hw.init = &(struct clk_init_data){ - .name = "dp_phy_pll_vco_div_clk", - .parent_names = - (const char *[]){"dp_vco_divsel_two_clk_src", - "dp_vco_divsel_four_clk_src"}, - .num_parents = 2, - .ops = &mux_clk_ops, - .flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT), - }, - }, -}; - -static struct clk_hw *mdss_dp_pllcc_14nm[] = { - [DP_VCO_CLK] = &dp_vco_clk.hw, - [DP_PHY_PLL_LINK_CLK] = &dp_phy_pll_link_clk.hw, - [DP_VCO_DIVSEL_FOUR_CLK_SRC] = &dp_vco_divsel_four_clk_src.hw, - [DP_VCO_DIVSEL_TWO_CLK_SRC] = &dp_vco_divsel_two_clk_src.hw, - [DP_PHY_PLL_VCO_DIV_CLK] = &dp_phy_pll_vco_div_clk.clkr.hw, -}; - - -int dp_mux_set_parent_14nm(void *context, unsigned int reg, unsigned int val) -{ - struct mdss_pll_resources *dp_res = context; - int rc; - u32 auxclk_div; - - rc = mdss_pll_resource_enable(dp_res, true); - if (rc) { - pr_err("Failed to enable mdss DP PLL resources\n"); - return rc; - } - - auxclk_div = MDSS_PLL_REG_R(dp_res->phy_base, DP_PHY_VCO_DIV); - auxclk_div &= ~0x03; /* bits 0 to 1 */ - - if (val == 0) /* mux parent index = 0 */ - auxclk_div |= 1; - else if (val == 1) /* mux parent index = 1 */ - auxclk_div |= 2; - - MDSS_PLL_REG_W(dp_res->phy_base, - DP_PHY_VCO_DIV, auxclk_div); - /* Make sure the PHY registers writes are done */ - wmb(); - pr_debug("mux=%d auxclk_div=%x\n", val, auxclk_div); - - mdss_pll_resource_enable(dp_res, false); - - return 0; -} - -int dp_mux_get_parent_14nm(void *context, unsigned int reg, unsigned int *val) -{ - int rc; - u32 auxclk_div = 0; - struct mdss_pll_resources *dp_res = context; - - rc = mdss_pll_resource_enable(dp_res, true); - if (rc) { - pr_err("Failed to enable dp_res resources\n"); - return rc; - } - - auxclk_div = MDSS_PLL_REG_R(dp_res->phy_base, DP_PHY_VCO_DIV); - auxclk_div &= 0x03; - - if (auxclk_div == 1) /* Default divider */ - *val = 0; - else if (auxclk_div == 2) - *val = 1; - - mdss_pll_resource_enable(dp_res, false); - - pr_debug("auxclk_div=%d, val=%d\n", auxclk_div, *val); - - return 0; -} - -static int dp_vco_pll_init_db_14nm(struct dp_pll_db *pdb, - unsigned long rate) -{ - struct mdss_pll_resources *dp_res = pdb->pll; - u32 spare_value = 0; - - spare_value = MDSS_PLL_REG_R(dp_res->phy_base, DP_PHY_SPARE0); - pdb->lane_cnt = spare_value & 0x0F; - pdb->orientation = (spare_value & 0xF0) >> 4; - - pr_debug("spare_value=0x%x, ln_cnt=0x%x, orientation=0x%x\n", - spare_value, pdb->lane_cnt, pdb->orientation); - - switch (rate) { - case DP_VCO_HSCLK_RATE_1620MHZDIV1000: - pdb->hsclk_sel = 0x2c; - pdb->dec_start_mode0 = 0x69; - pdb->div_frac_start1_mode0 = 0x00; - pdb->div_frac_start2_mode0 = 0x80; - pdb->div_frac_start3_mode0 = 0x07; - pdb->lock_cmp1_mode0 = 0xbf; - pdb->lock_cmp2_mode0 = 0x21; - pdb->lock_cmp3_mode0 = 0x00; - pdb->phy_vco_div = 0x1; - pdb->lane_mode_1 = 0xc6; - break; - case DP_VCO_HSCLK_RATE_2700MHZDIV1000: - pdb->hsclk_sel = 0x24; - pdb->dec_start_mode0 = 0x69; - pdb->div_frac_start1_mode0 = 0x00; - pdb->div_frac_start2_mode0 = 0x80; - pdb->div_frac_start3_mode0 = 0x07; - pdb->lock_cmp1_mode0 = 0x3f; - pdb->lock_cmp2_mode0 = 0x38; - pdb->lock_cmp3_mode0 = 0x00; - pdb->phy_vco_div = 0x1; - pdb->lane_mode_1 = 0xc4; - break; - case DP_VCO_HSCLK_RATE_5400MHZDIV1000: - pdb->hsclk_sel = 0x20; - pdb->dec_start_mode0 = 0x8c; - pdb->div_frac_start1_mode0 = 0x00; - pdb->div_frac_start2_mode0 = 0x00; - pdb->div_frac_start3_mode0 = 0x0a; - pdb->lock_cmp1_mode0 = 0x7f; - pdb->lock_cmp2_mode0 = 0x70; - pdb->lock_cmp3_mode0 = 0x00; - pdb->phy_vco_div = 0x2; - pdb->lane_mode_1 = 0xc4; - break; - default: - return -EINVAL; - } - return 0; -} - -int dp_config_vco_rate_14nm(struct dp_pll_vco_clk *vco, - unsigned long rate) -{ - u32 res = 0; - struct mdss_pll_resources *dp_res = vco->priv; - struct dp_pll_db *pdb = (struct dp_pll_db *)dp_res->priv; - - res = dp_vco_pll_init_db_14nm(pdb, rate); - if (res) { - pr_err("VCO Init DB failed\n"); - return res; - } - - MDSS_PLL_REG_W(dp_res->phy_base, DP_PHY_PD_CTL, 0x3d); - - /* Make sure the PHY register writes are done */ - wmb(); - - MDSS_PLL_REG_W(dp_res->pll_base, - QSERDES_COM_SVS_MODE_CLK_SEL, 0x01); - MDSS_PLL_REG_W(dp_res->pll_base, - QSERDES_COM_SYSCLK_EN_SEL, 0x37); - MDSS_PLL_REG_W(dp_res->pll_base, - QSERDES_COM_CLK_SELECT, 0x00); - MDSS_PLL_REG_W(dp_res->pll_base, - QSERDES_COM_SYS_CLK_CTRL, 0x06); - MDSS_PLL_REG_W(dp_res->pll_base, - QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x3f); - MDSS_PLL_REG_W(dp_res->pll_base, - QSERDES_COM_CLK_ENABLE1, 0x0e); - MDSS_PLL_REG_W(dp_res->pll_base, - QSERDES_COM_BG_CTRL, 0x0f); - MDSS_PLL_REG_W(dp_res->pll_base, - QSERDES_COM_SYSCLK_BUF_ENABLE, 0x06); - MDSS_PLL_REG_W(dp_res->pll_base, - QSERDES_COM_CLK_SELECT, 0x30); - MDSS_PLL_REG_W(dp_res->pll_base, - QSERDES_COM_PLL_IVCO, 0x0f); - MDSS_PLL_REG_W(dp_res->pll_base, - QSERDES_COM_PLL_CCTRL_MODE0, 0x28); - MDSS_PLL_REG_W(dp_res->pll_base, - QSERDES_COM_PLL_RCTRL_MODE0, 0x16); - MDSS_PLL_REG_W(dp_res->pll_base, - QSERDES_COM_CP_CTRL_MODE0, 0x0b); - - /* Parameters dependent on vco clock frequency */ - MDSS_PLL_REG_W(dp_res->pll_base, - QSERDES_COM_HSCLK_SEL, pdb->hsclk_sel); - MDSS_PLL_REG_W(dp_res->pll_base, - QSERDES_COM_DEC_START_MODE0, pdb->dec_start_mode0); - MDSS_PLL_REG_W(dp_res->pll_base, - QSERDES_COM_DIV_FRAC_START1_MODE0, pdb->div_frac_start1_mode0); - MDSS_PLL_REG_W(dp_res->pll_base, - QSERDES_COM_DIV_FRAC_START2_MODE0, pdb->div_frac_start2_mode0); - MDSS_PLL_REG_W(dp_res->pll_base, - QSERDES_COM_DIV_FRAC_START3_MODE0, pdb->div_frac_start3_mode0); - MDSS_PLL_REG_W(dp_res->pll_base, - QSERDES_COM_LOCK_CMP1_MODE0, pdb->lock_cmp1_mode0); - MDSS_PLL_REG_W(dp_res->pll_base, - QSERDES_COM_LOCK_CMP2_MODE0, pdb->lock_cmp2_mode0); - MDSS_PLL_REG_W(dp_res->pll_base, - QSERDES_COM_LOCK_CMP3_MODE0, pdb->lock_cmp3_mode0); - - MDSS_PLL_REG_W(dp_res->pll_base, - QSERDES_COM_INTEGLOOP_GAIN0_MODE0, 0x40); - MDSS_PLL_REG_W(dp_res->pll_base, - QSERDES_COM_INTEGLOOP_GAIN1_MODE0, 0x00); - MDSS_PLL_REG_W(dp_res->pll_base, - QSERDES_COM_VCO_TUNE_MAP, 0x00); - MDSS_PLL_REG_W(dp_res->pll_base, - QSERDES_COM_BG_TIMER, 0x08); - MDSS_PLL_REG_W(dp_res->pll_base, - QSERDES_COM_CORECLK_DIV, 0x05); - MDSS_PLL_REG_W(dp_res->pll_base, - QSERDES_COM_VCO_TUNE_CTRL, 0x00); - MDSS_PLL_REG_W(dp_res->pll_base, - QSERDES_COM_VCO_TUNE1_MODE0, 0x00); - MDSS_PLL_REG_W(dp_res->pll_base, - QSERDES_COM_VCO_TUNE2_MODE0, 0x00); - MDSS_PLL_REG_W(dp_res->pll_base, - QSERDES_COM_VCO_TUNE_CTRL, 0x00); - wmb(); /* make sure write happens */ - - MDSS_PLL_REG_W(dp_res->pll_base, - QSERDES_COM_CORE_CLK_EN, 0x0f); - wmb(); /* make sure write happens */ - - if (pdb->orientation == ORIENTATION_CC2) - MDSS_PLL_REG_W(dp_res->phy_base, DP_PHY_MODE, 0xc9); - else - MDSS_PLL_REG_W(dp_res->phy_base, DP_PHY_MODE, 0xd9); - wmb(); /* make sure write happens */ - - /* TX Lane configuration */ - MDSS_PLL_REG_W(dp_res->phy_base, - DP_PHY_TX0_TX1_LANE_CTL, 0x05); - MDSS_PLL_REG_W(dp_res->phy_base, - DP_PHY_TX2_TX3_LANE_CTL, 0x05); - - /* TX-0 register configuration */ - MDSS_PLL_REG_W(dp_res->phy_base, - QSERDES_TX0_OFFSET + TXn_TRANSCEIVER_BIAS_EN, 0x1a); - MDSS_PLL_REG_W(dp_res->phy_base, - QSERDES_TX0_OFFSET + TXn_VMODE_CTRL1, 0x40); - MDSS_PLL_REG_W(dp_res->phy_base, - QSERDES_TX0_OFFSET + TXn_PRE_STALL_LDO_BOOST_EN, 0x30); - MDSS_PLL_REG_W(dp_res->phy_base, - QSERDES_TX0_OFFSET + TXn_INTERFACE_SELECT, 0x3d); - MDSS_PLL_REG_W(dp_res->phy_base, - QSERDES_TX0_OFFSET + TXn_CLKBUF_ENABLE, 0x0f); - MDSS_PLL_REG_W(dp_res->phy_base, - QSERDES_TX0_OFFSET + TXn_RESET_TSYNC_EN, 0x03); - MDSS_PLL_REG_W(dp_res->phy_base, - QSERDES_TX0_OFFSET + TXn_TRAN_DRVR_EMP_EN, 0x03); - MDSS_PLL_REG_W(dp_res->phy_base, - QSERDES_TX0_OFFSET + TXn_PARRATE_REC_DETECT_IDLE_EN, 0x00); - MDSS_PLL_REG_W(dp_res->phy_base, - QSERDES_TX0_OFFSET + TXn_TX_INTERFACE_MODE, 0x00); - MDSS_PLL_REG_W(dp_res->phy_base, - QSERDES_TX0_OFFSET + TXn_TX_EMP_POST1_LVL, 0x2b); - MDSS_PLL_REG_W(dp_res->phy_base, - QSERDES_TX0_OFFSET + TXn_TX_DRV_LVL, 0x2f); - MDSS_PLL_REG_W(dp_res->phy_base, - QSERDES_TX0_OFFSET + TXn_TX_BAND, 0x4); - MDSS_PLL_REG_W(dp_res->phy_base, - QSERDES_TX0_OFFSET + TXn_RES_CODE_LANE_OFFSET_TX, 0x12); - MDSS_PLL_REG_W(dp_res->phy_base, - QSERDES_TX0_OFFSET + TXn_RES_CODE_LANE_OFFSET_RX, 0x12); - - /* TX-1 register configuration */ - MDSS_PLL_REG_W(dp_res->phy_base, - QSERDES_TX1_OFFSET + TXn_TRANSCEIVER_BIAS_EN, 0x1a); - MDSS_PLL_REG_W(dp_res->phy_base, - QSERDES_TX1_OFFSET + TXn_VMODE_CTRL1, 0x40); - MDSS_PLL_REG_W(dp_res->phy_base, - QSERDES_TX1_OFFSET + TXn_PRE_STALL_LDO_BOOST_EN, 0x30); - MDSS_PLL_REG_W(dp_res->phy_base, - QSERDES_TX1_OFFSET + TXn_INTERFACE_SELECT, 0x3d); - MDSS_PLL_REG_W(dp_res->phy_base, - QSERDES_TX1_OFFSET + TXn_CLKBUF_ENABLE, 0x0f); - MDSS_PLL_REG_W(dp_res->phy_base, - QSERDES_TX1_OFFSET + TXn_RESET_TSYNC_EN, 0x03); - MDSS_PLL_REG_W(dp_res->phy_base, - QSERDES_TX1_OFFSET + TXn_TRAN_DRVR_EMP_EN, 0x03); - MDSS_PLL_REG_W(dp_res->phy_base, - QSERDES_TX1_OFFSET + TXn_PARRATE_REC_DETECT_IDLE_EN, 0x00); - MDSS_PLL_REG_W(dp_res->phy_base, - QSERDES_TX1_OFFSET + TXn_TX_INTERFACE_MODE, 0x00); - MDSS_PLL_REG_W(dp_res->phy_base, - QSERDES_TX1_OFFSET + TXn_TX_EMP_POST1_LVL, 0x2b); - MDSS_PLL_REG_W(dp_res->phy_base, - QSERDES_TX1_OFFSET + TXn_TX_DRV_LVL, 0x2f); - MDSS_PLL_REG_W(dp_res->phy_base, - QSERDES_TX1_OFFSET + TXn_TX_BAND, 0x4); - MDSS_PLL_REG_W(dp_res->phy_base, - QSERDES_TX1_OFFSET + TXn_RES_CODE_LANE_OFFSET_TX, 0x12); - MDSS_PLL_REG_W(dp_res->phy_base, - QSERDES_TX1_OFFSET + TXn_RES_CODE_LANE_OFFSET_RX, 0x12); - wmb(); /* make sure write happens */ - - /* PHY VCO divider programming */ - MDSS_PLL_REG_W(dp_res->phy_base, - DP_PHY_VCO_DIV, pdb->phy_vco_div); - wmb(); /* make sure write happens */ - - MDSS_PLL_REG_W(dp_res->pll_base, - QSERDES_COM_CMN_CONFIG, 0x02); - wmb(); /* make sure write happens */ - - return res; -} - -static bool dp_14nm_pll_lock_status(struct mdss_pll_resources *dp_res) -{ - u32 status; - bool pll_locked; - - /* poll for PLL lock status */ - if (readl_poll_timeout_atomic((dp_res->pll_base + - QSERDES_COM_C_READY_STATUS), - status, - ((status & BIT(0)) > 0), - DP_PLL_POLL_SLEEP_US, - DP_PLL_POLL_TIMEOUT_US)) { - pr_err("C_READY status is not high. Status=%x\n", status); - pll_locked = false; - } else { - pll_locked = true; - } - - return pll_locked; -} - -static bool dp_14nm_phy_rdy_status(struct mdss_pll_resources *dp_res) -{ - u32 status; - bool phy_ready = true; - - /* poll for PHY ready status */ - if (readl_poll_timeout_atomic((dp_res->phy_base + - DP_PHY_STATUS), - status, - ((status & (BIT(1) | BIT(0))) > 0), - DP_PHY_POLL_SLEEP_US, - DP_PHY_POLL_TIMEOUT_US)) { - pr_err("Phy_ready is not high. Status=%x\n", status); - phy_ready = false; - } - - return phy_ready; -} - -static int dp_pll_enable_14nm(struct clk_hw *hw) -{ - int rc = 0; - struct dp_pll_vco_clk *vco = to_dp_vco_hw(hw); - struct mdss_pll_resources *dp_res = vco->priv; - - MDSS_PLL_REG_W(dp_res->phy_base, DP_PHY_CFG, 0x01); - MDSS_PLL_REG_W(dp_res->phy_base, DP_PHY_CFG, 0x05); - MDSS_PLL_REG_W(dp_res->phy_base, DP_PHY_CFG, 0x01); - MDSS_PLL_REG_W(dp_res->phy_base, DP_PHY_CFG, 0x09); - wmb(); /* Make sure the PHY register writes are done */ - - MDSS_PLL_REG_W(dp_res->pll_base, - QSERDES_COM_RESETSM_CNTRL, 0x20); - wmb(); /* Make sure the PLL register writes are done */ - - udelay(900); /* hw recommended delay for full PU */ - - if (!dp_14nm_pll_lock_status(dp_res)) { - rc = -EINVAL; - goto lock_err; - } - - MDSS_PLL_REG_W(dp_res->phy_base, DP_PHY_CFG, 0x19); - wmb(); /* Make sure the PHY register writes are done */ - - udelay(10); /* hw recommended delay */ - - if (!dp_14nm_phy_rdy_status(dp_res)) { - rc = -EINVAL; - goto lock_err; - } - - pr_debug("PLL is locked\n"); - - MDSS_PLL_REG_W(dp_res->phy_base, - QSERDES_TX0_OFFSET + TXn_TRANSCEIVER_BIAS_EN, 0x3f); - MDSS_PLL_REG_W(dp_res->phy_base, - QSERDES_TX0_OFFSET + TXn_HIGHZ_DRVR_EN, 0x10); - MDSS_PLL_REG_W(dp_res->phy_base, - QSERDES_TX1_OFFSET + TXn_TRANSCEIVER_BIAS_EN, 0x3f); - MDSS_PLL_REG_W(dp_res->phy_base, - QSERDES_TX1_OFFSET + TXn_HIGHZ_DRVR_EN, 0x10); - - MDSS_PLL_REG_W(dp_res->phy_base, - QSERDES_TX0_OFFSET + TXn_TX_POL_INV, 0x0a); - MDSS_PLL_REG_W(dp_res->phy_base, - QSERDES_TX1_OFFSET + TXn_TX_POL_INV, 0x0a); - - /* - * Switch DP Mainlink clock (cc_dpphy_link_clk) from DP - * controller side with final frequency - */ - MDSS_PLL_REG_W(dp_res->phy_base, DP_PHY_CFG, 0x18); - wmb(); /* Make sure the PHY register writes are done */ - MDSS_PLL_REG_W(dp_res->phy_base, DP_PHY_CFG, 0x19); - wmb(); /* Make sure the PHY register writes are done */ - -lock_err: - return rc; -} - -static int dp_pll_disable_14nm(struct clk_hw *hw) -{ - struct dp_pll_vco_clk *vco = to_dp_vco_hw(hw); - struct mdss_pll_resources *dp_res = vco->priv; - - /* Assert DP PHY power down */ - MDSS_PLL_REG_W(dp_res->phy_base, DP_PHY_PD_CTL, 0x2); - /* - * Make sure all the register writes to disable PLL are - * completed before doing any other operation - */ - wmb(); - - return 0; -} - - -int dp_vco_prepare_14nm(struct clk_hw *hw) -{ - int rc = 0; - struct dp_pll_vco_clk *vco = to_dp_vco_hw(hw); - struct mdss_pll_resources *dp_res = vco->priv; - - pr_debug("rate=%ld\n", vco->rate); - rc = mdss_pll_resource_enable(dp_res, true); - if (rc) { - pr_err("Failed to enable mdss DP pll resources\n"); - goto error; - } - - if ((dp_res->vco_cached_rate != 0) - && (dp_res->vco_cached_rate == vco->rate)) { - rc = vco->hw.init->ops->set_rate(hw, - dp_res->vco_cached_rate, dp_res->vco_cached_rate); - if (rc) { - pr_err("index=%d vco_set_rate failed. rc=%d\n", - rc, dp_res->index); - mdss_pll_resource_enable(dp_res, false); - goto error; - } - } - - rc = dp_pll_enable_14nm(hw); - if (rc) { - mdss_pll_resource_enable(dp_res, false); - pr_err("ndx=%d failed to enable dp pll\n", - dp_res->index); - goto error; - } - - mdss_pll_resource_enable(dp_res, false); -error: - return rc; -} - -void dp_vco_unprepare_14nm(struct clk_hw *hw) -{ - struct dp_pll_vco_clk *vco = to_dp_vco_hw(hw); - struct mdss_pll_resources *dp_res = vco->priv; - - if (!dp_res) { - pr_err("Invalid input parameter\n"); - return; - } - - if (!dp_res->pll_on && - mdss_pll_resource_enable(dp_res, true)) { - pr_err("pll resource can't be enabled\n"); - return; - } - dp_res->vco_cached_rate = vco->rate; - dp_pll_disable_14nm(hw); - - dp_res->handoff_resources = false; - mdss_pll_resource_enable(dp_res, false); - dp_res->pll_on = false; -} - -int dp_vco_set_rate_14nm(struct clk_hw *hw, unsigned long rate, - unsigned long parent_rate) -{ - struct dp_pll_vco_clk *vco = to_dp_vco_hw(hw); - struct mdss_pll_resources *dp_res = vco->priv; - int rc; - - rc = mdss_pll_resource_enable(dp_res, true); - if (rc) { - pr_err("pll resource can't be enabled\n"); - return rc; - } - - pr_debug("DP lane CLK rate=%ld\n", rate); - - rc = dp_config_vco_rate_14nm(vco, rate); - if (rc) - pr_err("Failed to set clk rate\n"); - - mdss_pll_resource_enable(dp_res, false); - - vco->rate = rate; - - return 0; -} - -unsigned long dp_vco_recalc_rate_14nm(struct clk_hw *hw, - unsigned long parent_rate) -{ - struct dp_pll_vco_clk *vco = to_dp_vco_hw(hw); - int rc; - u32 div, hsclk_div; - u64 vco_rate; - struct mdss_pll_resources *dp_res = vco->priv; - - if (is_gdsc_disabled(dp_res)) - return 0; - - rc = mdss_pll_resource_enable(dp_res, true); - if (rc) { - pr_err("Failed to enable mdss DP pll=%d\n", dp_res->index); - return rc; - } - - div = MDSS_PLL_REG_R(dp_res->pll_base, QSERDES_COM_HSCLK_SEL); - div &= 0x0f; - - if (div == 12) - hsclk_div = 5; /* Default */ - else if (div == 4) - hsclk_div = 3; - else if (div == 0) - hsclk_div = 2; - else { - pr_debug("unknown divider. forcing to default\n"); - hsclk_div = 5; - } - - if (hsclk_div == 5) - vco_rate = DP_VCO_HSCLK_RATE_1620MHZDIV1000; - else if (hsclk_div == 3) - vco_rate = DP_VCO_HSCLK_RATE_2700MHZDIV1000; - else - vco_rate = DP_VCO_HSCLK_RATE_5400MHZDIV1000; - - pr_debug("returning vco rate = %lu\n", (unsigned long)vco_rate); - - mdss_pll_resource_enable(dp_res, false); - - dp_res->vco_cached_rate = vco->rate = vco_rate; - return (unsigned long)vco_rate; -} - -long dp_vco_round_rate_14nm(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) -{ - unsigned long rrate = rate; - struct dp_pll_vco_clk *vco = to_dp_vco_hw(hw); - - if (rate <= vco->min_rate) - rrate = vco->min_rate; - else if (rate <= DP_VCO_HSCLK_RATE_2700MHZDIV1000) - rrate = DP_VCO_HSCLK_RATE_2700MHZDIV1000; - else - rrate = vco->max_rate; - - pr_debug("rrate=%ld\n", rrate); - - *parent_rate = rrate; - return rrate; -} - -int dp_pll_clock_register_14nm(struct platform_device *pdev, - struct mdss_pll_resources *pll_res) -{ - int rc = -ENOTSUPP, i = 0; - struct clk_onecell_data *clk_data; - struct clk *clk; - struct regmap *regmap; - int num_clks = ARRAY_SIZE(mdss_dp_pllcc_14nm); - - clk_data = devm_kzalloc(&pdev->dev, sizeof(*clk_data), GFP_KERNEL); - if (!clk_data) - return -ENOMEM; - - clk_data->clks = devm_kcalloc(&pdev->dev, num_clks, - sizeof(struct clk *), GFP_KERNEL); - if (!clk_data->clks) - return -ENOMEM; - - clk_data->clk_num = num_clks; - - pll_res->priv = &dp_pdb; - dp_pdb.pll = pll_res; - - /* Set client data for vco, mux and div clocks */ - regmap = devm_regmap_init(&pdev->dev, &dp_pixel_mux_regmap_ops, - pll_res, &dp_pll_14nm_cfg); - dp_phy_pll_vco_div_clk.clkr.regmap = regmap; - mux_clk_ops = clk_regmap_mux_closest_ops; - mux_clk_ops.determine_rate = clk_mux_determine_rate; - mux_clk_ops.recalc_rate = mux_recalc_rate; - - dp_vco_clk.priv = pll_res; - - for (i = DP_VCO_CLK; i <= DP_PHY_PLL_VCO_DIV_CLK; i++) { - pr_debug("reg clk: %d index: %d\n", i, pll_res->index); - clk = devm_clk_register(&pdev->dev, - mdss_dp_pllcc_14nm[i]); - if (IS_ERR(clk)) { - pr_err("clk registration failed for DP: %d\n", - pll_res->index); - rc = -EINVAL; - goto clk_reg_fail; - } - clk_data->clks[i] = clk; - } - - rc = of_clk_add_provider(pdev->dev.of_node, - of_clk_src_onecell_get, clk_data); - if (rc) { - pr_err("Clock register failed rc=%d\n", rc); - rc = -EPROBE_DEFER; - } else { - pr_debug("SUCCESS\n"); - } - return 0; -clk_reg_fail: - return rc; -} diff --git a/pll/dp_pll_14nm.h b/pll/dp_pll_14nm.h deleted file mode 100644 index f8c9c3043bdf..000000000000 --- a/pll/dp_pll_14nm.h +++ /dev/null @@ -1,188 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. - */ - -#ifndef __MDSS_DP_PLL_14NM_H -#define __MDSS_DP_PLL_14NM_H - -#define DP_PHY_REVISION_ID0 0x0000 -#define DP_PHY_REVISION_ID1 0x0004 -#define DP_PHY_REVISION_ID2 0x0008 -#define DP_PHY_REVISION_ID3 0x000C - -#define DP_PHY_CFG 0x0010 -#define DP_PHY_CFG_1 0x0014 -#define DP_PHY_PD_CTL 0x0018 -#define DP_PHY_MODE 0x001C - -#define DP_PHY_AUX_CFG0 0x0020 -#define DP_PHY_AUX_CFG1 0x0024 -#define DP_PHY_AUX_CFG2 0x0028 -#define DP_PHY_AUX_CFG3 0x002C -#define DP_PHY_AUX_CFG4 0x0030 -#define DP_PHY_AUX_CFG5 0x0034 -#define DP_PHY_AUX_CFG6 0x0038 -#define DP_PHY_AUX_CFG7 0x003C -#define DP_PHY_AUX_CFG8 0x0040 -#define DP_PHY_AUX_CFG9 0x0044 -#define DP_PHY_AUX_INTERRUPT_MASK 0x0048 -#define DP_PHY_AUX_INTERRUPT_CLEAR 0x004C -#define DP_PHY_AUX_BIST_CFG 0x0050 - -#define DP_PHY_VCO_DIV 0x0068 -#define DP_PHY_TX0_TX1_LANE_CTL 0x006C - -#define DP_PHY_TX2_TX3_LANE_CTL 0x0088 -#define DP_PHY_SPARE0 0x00AC -#define DP_PHY_STATUS 0x00C0 - -/* Tx registers */ -#define QSERDES_TX0_OFFSET 0x0400 -#define QSERDES_TX1_OFFSET 0x0800 - -#define TXn_BIST_MODE_LANENO 0x0000 -#define TXn_CLKBUF_ENABLE 0x0008 -#define TXn_TX_EMP_POST1_LVL 0x000C - -#define TXn_TX_DRV_LVL 0x001C - -#define TXn_RESET_TSYNC_EN 0x0024 -#define TXn_PRE_STALL_LDO_BOOST_EN 0x0028 -#define TXn_TX_BAND 0x002C -#define TXn_SLEW_CNTL 0x0030 -#define TXn_INTERFACE_SELECT 0x0034 - -#define TXn_RES_CODE_LANE_TX 0x003C -#define TXn_RES_CODE_LANE_RX 0x0040 -#define TXn_RES_CODE_LANE_OFFSET_TX 0x0044 -#define TXn_RES_CODE_LANE_OFFSET_RX 0x0048 - -#define TXn_DEBUG_BUS_SEL 0x0058 -#define TXn_TRANSCEIVER_BIAS_EN 0x005C -#define TXn_HIGHZ_DRVR_EN 0x0060 -#define TXn_TX_POL_INV 0x0064 -#define TXn_PARRATE_REC_DETECT_IDLE_EN 0x0068 - -#define TXn_LANE_MODE_1 0x008C - -#define TXn_TRAN_DRVR_EMP_EN 0x00C0 -#define TXn_TX_INTERFACE_MODE 0x00C4 - -#define TXn_VMODE_CTRL1 0x00F0 - - -/* PLL register offset */ -#define QSERDES_COM_ATB_SEL1 0x0000 -#define QSERDES_COM_ATB_SEL2 0x0004 -#define QSERDES_COM_FREQ_UPDATE 0x0008 -#define QSERDES_COM_BG_TIMER 0x000C -#define QSERDES_COM_SSC_EN_CENTER 0x0010 -#define QSERDES_COM_SSC_ADJ_PER1 0x0014 -#define QSERDES_COM_SSC_ADJ_PER2 0x0018 -#define QSERDES_COM_SSC_PER1 0x001C -#define QSERDES_COM_SSC_PER2 0x0020 -#define QSERDES_COM_SSC_STEP_SIZE1 0x0024 -#define QSERDES_COM_SSC_STEP_SIZE2 0x0028 -#define QSERDES_COM_POST_DIV 0x002C -#define QSERDES_COM_POST_DIV_MUX 0x0030 -#define QSERDES_COM_BIAS_EN_CLKBUFLR_EN 0x0034 -#define QSERDES_COM_CLK_ENABLE1 0x0038 -#define QSERDES_COM_SYS_CLK_CTRL 0x003C -#define QSERDES_COM_SYSCLK_BUF_ENABLE 0x0040 -#define QSERDES_COM_PLL_EN 0x0044 -#define QSERDES_COM_PLL_IVCO 0x0048 -#define QSERDES_COM_LOCK_CMP1_MODE0 0x004C -#define QSERDES_COM_LOCK_CMP2_MODE0 0x0050 -#define QSERDES_COM_LOCK_CMP3_MODE0 0x0054 - -#define QSERDES_COM_CP_CTRL_MODE0 0x0078 -#define QSERDES_COM_CP_CTRL_MODE1 0x007C -#define QSERDES_COM_PLL_RCTRL_MODE0 0x0084 -#define QSERDES_COM_PLL_CCTRL_MODE0 0x0090 -#define QSERDES_COM_PLL_CNTRL 0x009C - -#define QSERDES_COM_SYSCLK_EN_SEL 0x00AC -#define QSERDES_COM_CML_SYSCLK_SEL 0x00B0 -#define QSERDES_COM_RESETSM_CNTRL 0x00B4 -#define QSERDES_COM_RESETSM_CNTRL2 0x00B8 -#define QSERDES_COM_LOCK_CMP_EN 0x00C8 -#define QSERDES_COM_LOCK_CMP_CFG 0x00CC - - -#define QSERDES_COM_DEC_START_MODE0 0x00D0 -#define QSERDES_COM_DEC_START_MODE1 0x00D4 -#define QSERDES_COM_DIV_FRAC_START1_MODE0 0x00DC -#define QSERDES_COM_DIV_FRAC_START2_MODE0 0x00E0 -#define QSERDES_COM_DIV_FRAC_START3_MODE0 0x00E4 - -#define QSERDES_COM_INTEGLOOP_GAIN0_MODE0 0x0108 -#define QSERDES_COM_INTEGLOOP_GAIN1_MODE0 0x010C -#define QSERDES_COM_VCO_TUNE_CTRL 0x0124 -#define QSERDES_COM_VCO_TUNE_MAP 0x0128 -#define QSERDES_COM_VCO_TUNE1_MODE0 0x012C -#define QSERDES_COM_VCO_TUNE2_MODE0 0x0130 - -#define QSERDES_COM_CMN_STATUS 0x015C -#define QSERDES_COM_RESET_SM_STATUS 0x0160 - -#define QSERDES_COM_BG_CTRL 0x0170 -#define QSERDES_COM_CLK_SELECT 0x0174 -#define QSERDES_COM_HSCLK_SEL 0x0178 -#define QSERDES_COM_CORECLK_DIV 0x0184 -#define QSERDES_COM_SW_RESET 0x0188 -#define QSERDES_COM_CORE_CLK_EN 0x018C -#define QSERDES_COM_C_READY_STATUS 0x0190 -#define QSERDES_COM_CMN_CONFIG 0x0194 -#define QSERDES_COM_SVS_MODE_CLK_SEL 0x019C - -#define DP_PLL_POLL_SLEEP_US 500 -#define DP_PLL_POLL_TIMEOUT_US 10000 - -#define DP_PHY_POLL_SLEEP_US 500 -#define DP_PHY_POLL_TIMEOUT_US 10000 - -#define DP_VCO_RATE_8100MHZDIV1000 8100000UL -#define DP_VCO_RATE_10800MHZDIV1000 10800000UL - -#define DP_VCO_HSCLK_RATE_1620MHZDIV1000 1620000UL -#define DP_VCO_HSCLK_RATE_2700MHZDIV1000 2700000UL -#define DP_VCO_HSCLK_RATE_5400MHZDIV1000 5400000UL - -struct dp_pll_db { - struct mdss_pll_resources *pll; - - /* lane and orientation settings */ - u8 lane_cnt; - u8 orientation; - - /* COM PHY settings */ - u32 hsclk_sel; - u32 dec_start_mode0; - u32 div_frac_start1_mode0; - u32 div_frac_start2_mode0; - u32 div_frac_start3_mode0; - u32 lock_cmp1_mode0; - u32 lock_cmp2_mode0; - u32 lock_cmp3_mode0; - - /* PHY vco divider */ - u32 phy_vco_div; - - /* TX settings */ - u32 lane_mode_1; -}; - -int dp_vco_set_rate_14nm(struct clk_hw *hw, unsigned long rate, - unsigned long parent_rate); -unsigned long dp_vco_recalc_rate_14nm(struct clk_hw *hw, - unsigned long parent_rate); -long dp_vco_round_rate_14nm(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate); -int dp_vco_prepare_14nm(struct clk_hw *hw); -void dp_vco_unprepare_14nm(struct clk_hw *hw); -int dp_mux_set_parent_14nm(void *context, - unsigned int reg, unsigned int val); -int dp_mux_get_parent_14nm(void *context, - unsigned int reg, unsigned int *val); -#endif /* __MDSS_DP_PLL_14NM_H */ diff --git a/pll/dp_pll_7nm.c b/pll/dp_pll_7nm.c deleted file mode 100644 index 480c00fda658..000000000000 --- a/pll/dp_pll_7nm.c +++ /dev/null @@ -1,341 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. - */ - -/* - * Display Port PLL driver block diagram for branch clocks - * - * +------------------------------+ - * | DP_VCO_CLK | - * | | - * | +-------------------+ | - * | | (DP PLL/VCO) | | - * | +---------+---------+ | - * | v | - * | +----------+-----------+ | - * | | hsclk_divsel_clk_src | | - * | +----------+-----------+ | - * +------------------------------+ - * | - * +------------<---------v------------>----------+ - * | | - * +-----v------------+ | - * | dp_link_clk_src | | - * | divsel_ten | | - * +---------+--------+ | - * | | - * | | - * v v - * Input to DISPCC block | - * for link clk, crypto clk | - * and interface clock | - * | - * | - * +--------<------------+-----------------+---<---+ - * | | | - * +-------v------+ +--------v-----+ +--------v------+ - * | vco_divided | | vco_divided | | vco_divided | - * | _clk_src | | _clk_src | | _clk_src | - * | | | | | | - * |divsel_six | | divsel_two | | divsel_four | - * +-------+------+ +-----+--------+ +--------+------+ - * | | | - * v------->----------v-------------<------v - * | - * +----------+---------+ - * | vco_divided_clk | - * | _src_mux | - * +---------+----------+ - * | - * v - * Input to DISPCC block - * for DP pixel clock - * - */ - -#define pr_fmt(fmt) "%s: " fmt, __func__ - -#include -#include -#include -#include - -#include "pll_drv.h" -#include "dp_pll.h" -#include "dp_pll_7nm.h" - -static struct dp_pll_db_7nm dp_pdb_7nm; -static struct clk_ops mux_clk_ops; - -static struct regmap_config dp_pll_7nm_cfg = { - .reg_bits = 32, - .reg_stride = 4, - .val_bits = 32, - .max_register = 0x910, -}; - -static struct regmap_bus dp_pixel_mux_regmap_ops = { - .reg_write = dp_mux_set_parent_7nm, - .reg_read = dp_mux_get_parent_7nm, -}; - -/* Op structures */ -static const struct clk_ops dp_7nm_vco_clk_ops = { - .recalc_rate = dp_vco_recalc_rate_7nm, - .set_rate = dp_vco_set_rate_7nm, - .round_rate = dp_vco_round_rate_7nm, - .prepare = dp_vco_prepare_7nm, - .unprepare = dp_vco_unprepare_7nm, -}; - -static struct dp_pll_vco_clk dp_vco_clk = { - .min_rate = DP_VCO_HSCLK_RATE_1620MHZDIV1000, - .max_rate = DP_VCO_HSCLK_RATE_8100MHZDIV1000, - .hw.init = &(struct clk_init_data){ - .name = "dp_vco_clk", - .parent_names = (const char *[]){ "xo_board" }, - .num_parents = 1, - .ops = &dp_7nm_vco_clk_ops, - }, -}; - -static struct clk_fixed_factor dp_phy_pll_link_clk = { - .div = 10, - .mult = 1, - - .hw.init = &(struct clk_init_data){ - .name = "dp_phy_pll_link_clk", - .parent_names = - (const char *[]){ "dp_vco_clk" }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - .ops = &clk_fixed_factor_ops, - }, -}; - -static struct clk_fixed_factor dp_link_clk_divsel_ten = { - .div = 10, - .mult = 1, - - .hw.init = &(struct clk_init_data){ - .name = "dp_link_clk_divsel_ten", - .parent_names = - (const char *[]){ "dp_vco_clk" }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - .ops = &clk_fixed_factor_ops, - }, -}; - -static struct clk_fixed_factor dp_vco_divsel_two_clk_src = { - .div = 2, - .mult = 1, - - .hw.init = &(struct clk_init_data){ - .name = "dp_vco_divsel_two_clk_src", - .parent_names = - (const char *[]){ "dp_vco_clk" }, - .num_parents = 1, - .ops = &clk_fixed_factor_ops, - }, -}; - -static struct clk_fixed_factor dp_vco_divsel_four_clk_src = { - .div = 4, - .mult = 1, - - .hw.init = &(struct clk_init_data){ - .name = "dp_vco_divsel_four_clk_src", - .parent_names = - (const char *[]){ "dp_vco_clk" }, - .num_parents = 1, - .ops = &clk_fixed_factor_ops, - }, -}; - -static struct clk_fixed_factor dp_vco_divsel_six_clk_src = { - .div = 6, - .mult = 1, - - .hw.init = &(struct clk_init_data){ - .name = "dp_vco_divsel_six_clk_src", - .parent_names = - (const char *[]){ "dp_vco_clk" }, - .num_parents = 1, - .ops = &clk_fixed_factor_ops, - }, -}; - - -static int clk_mux_determine_rate(struct clk_hw *hw, - struct clk_rate_request *req) -{ - int ret = 0; - - if (!hw || !req) { - pr_err("Invalid input parameters\n"); - return -EINVAL; - } - - ret = __clk_mux_determine_rate_closest(hw, req); - if (ret) - return ret; - - /* Set the new parent of mux if there is a new valid parent */ - if (hw->clk && req->best_parent_hw->clk) - clk_set_parent(hw->clk, req->best_parent_hw->clk); - - return 0; -} - -static unsigned long mux_recalc_rate(struct clk_hw *hw, - unsigned long parent_rate) -{ - struct clk *div_clk = NULL, *vco_clk = NULL; - struct dp_pll_vco_clk *vco = NULL; - - if (!hw) { - pr_err("Invalid input parameter\n"); - return 0; - } - - div_clk = clk_get_parent(hw->clk); - if (!div_clk) - return 0; - - vco_clk = clk_get_parent(div_clk); - if (!vco_clk) - return 0; - - vco = to_dp_vco_hw(__clk_get_hw(vco_clk)); - if (!vco) - return 0; - - if (vco->rate == DP_VCO_HSCLK_RATE_8100MHZDIV1000) - return (vco->rate / 6); - else if (vco->rate == DP_VCO_HSCLK_RATE_5400MHZDIV1000) - return (vco->rate / 4); - else - return (vco->rate / 2); -} - -static struct clk_regmap_mux dp_phy_pll_vco_div_clk = { - .reg = 0x64, - .shift = 0, - .width = 2, - - .clkr = { - .hw.init = &(struct clk_init_data){ - .name = "dp_phy_pll_vco_div_clk", - .parent_names = - (const char *[]){"dp_vco_divsel_two_clk_src", - "dp_vco_divsel_four_clk_src", - "dp_vco_divsel_six_clk_src"}, - .num_parents = 3, - .ops = &mux_clk_ops, - .flags = CLK_SET_RATE_PARENT, - }, - }, -}; - -static struct clk_regmap_mux dp_vco_divided_clk_src_mux = { - .reg = 0x64, - .shift = 0, - .width = 2, - - .clkr = { - .hw.init = &(struct clk_init_data){ - .name = "dp_vco_divided_clk_src_mux", - .parent_names = - (const char *[]){"dp_vco_divsel_two_clk_src", - "dp_vco_divsel_four_clk_src", - "dp_vco_divsel_six_clk_src"}, - .num_parents = 3, - .ops = &mux_clk_ops, - .flags = CLK_SET_RATE_PARENT, - }, - }, -}; - -static struct clk_hw *mdss_dp_pllcc_7nm[] = { - [DP_VCO_CLK] = &dp_vco_clk.hw, - [DP_LINK_CLK_DIVSEL_TEN] = &dp_link_clk_divsel_ten.hw, - [DP_VCO_DIVIDED_TWO_CLK_SRC] = &dp_vco_divsel_two_clk_src.hw, - [DP_VCO_DIVIDED_FOUR_CLK_SRC] = &dp_vco_divsel_four_clk_src.hw, - [DP_VCO_DIVIDED_SIX_CLK_SRC] = &dp_vco_divsel_six_clk_src.hw, - [DP_VCO_DIVIDED_CLK_SRC_MUX] = &dp_vco_divided_clk_src_mux.clkr.hw, -}; - -int dp_pll_clock_register_7nm(struct platform_device *pdev, - struct mdss_pll_resources *pll_res) -{ - int rc = -ENOTSUPP, i = 0; - struct clk_onecell_data *clk_data; - struct clk *clk; - struct regmap *regmap; - int num_clks = ARRAY_SIZE(mdss_dp_pllcc_7nm); - - clk_data = devm_kzalloc(&pdev->dev, sizeof(*clk_data), GFP_KERNEL); - if (!clk_data) - return -ENOMEM; - - clk_data->clks = devm_kcalloc(&pdev->dev, num_clks, - sizeof(struct clk *), GFP_KERNEL); - if (!clk_data->clks) - return -ENOMEM; - - clk_data->clk_num = num_clks; - - pll_res->priv = &dp_pdb_7nm; - dp_pdb_7nm.pll = pll_res; - - /* Set client data for vco, mux and div clocks */ - regmap = devm_regmap_init(&pdev->dev, &dp_pixel_mux_regmap_ops, - pll_res, &dp_pll_7nm_cfg); - mux_clk_ops = clk_regmap_mux_closest_ops; - mux_clk_ops.determine_rate = clk_mux_determine_rate; - mux_clk_ops.recalc_rate = mux_recalc_rate; - - dp_vco_clk.priv = pll_res; - - /* - * Consumer for the pll clock expects, the DP_LINK_CLK_DIVSEL_TEN and - * DP_VCO_DIVIDED_CLK_SRC_MUX clock names to be "dp_phy_pll_link_clk" - * and "dp_phy_pll_vco_div_clk" respectively for a V2 pll interface - * target. - */ - if (pll_res->pll_interface_type == MDSS_DP_PLL_7NM_V2) { - mdss_dp_pllcc_7nm[DP_LINK_CLK_DIVSEL_TEN] = - &dp_phy_pll_link_clk.hw; - mdss_dp_pllcc_7nm[DP_VCO_DIVIDED_CLK_SRC_MUX] = - &dp_phy_pll_vco_div_clk.clkr.hw; - dp_phy_pll_vco_div_clk.clkr.regmap = regmap; - } else - dp_vco_divided_clk_src_mux.clkr.regmap = regmap; - - for (i = DP_VCO_CLK; i <= DP_VCO_DIVIDED_CLK_SRC_MUX; i++) { - pr_debug("reg clk: %d index: %d\n", i, pll_res->index); - clk = devm_clk_register(&pdev->dev, mdss_dp_pllcc_7nm[i]); - if (IS_ERR(clk)) { - pr_err("clk registration failed for DP: %d\n", - pll_res->index); - rc = -EINVAL; - goto clk_reg_fail; - } - clk_data->clks[i] = clk; - } - - rc = of_clk_add_provider(pdev->dev.of_node, - of_clk_src_onecell_get, clk_data); - if (rc) { - pr_err("Clock register failed rc=%d\n", rc); - rc = -EPROBE_DEFER; - goto clk_reg_fail; - } else { - pr_debug("SUCCESS\n"); - } - return rc; -clk_reg_fail: - return rc; -} diff --git a/pll/dp_pll_7nm.h b/pll/dp_pll_7nm.h deleted file mode 100644 index 87037f9c60fa..000000000000 --- a/pll/dp_pll_7nm.h +++ /dev/null @@ -1,52 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. - */ - -#ifndef __MDSS_DP_PLL_7NM_H -#define __MDSS_DP_PLL_7NM_H - -#define DP_VCO_HSCLK_RATE_1620MHZDIV1000 1620000UL -#define DP_VCO_HSCLK_RATE_2700MHZDIV1000 2700000UL -#define DP_VCO_HSCLK_RATE_5400MHZDIV1000 5400000UL -#define DP_VCO_HSCLK_RATE_8100MHZDIV1000 8100000UL - -struct dp_pll_db_7nm { - struct mdss_pll_resources *pll; - - /* lane and orientation settings */ - u8 lane_cnt; - u8 orientation; - - /* COM PHY settings */ - u32 hsclk_sel; - u32 dec_start_mode0; - u32 div_frac_start1_mode0; - u32 div_frac_start2_mode0; - u32 div_frac_start3_mode0; - u32 integloop_gain0_mode0; - u32 integloop_gain1_mode0; - u32 vco_tune_map; - u32 lock_cmp1_mode0; - u32 lock_cmp2_mode0; - u32 lock_cmp_en; - u32 cmn_config; - u32 txn_tran_drv_emp_en; - - /* PHY vco divider */ - u32 phy_vco_div; -}; - -int dp_vco_set_rate_7nm(struct clk_hw *hw, unsigned long rate, - unsigned long parent_rate); -unsigned long dp_vco_recalc_rate_7nm(struct clk_hw *hw, - unsigned long parent_rate); -long dp_vco_round_rate_7nm(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate); -int dp_vco_prepare_7nm(struct clk_hw *hw); -void dp_vco_unprepare_7nm(struct clk_hw *hw); -int dp_mux_set_parent_7nm(void *context, - unsigned int reg, unsigned int val); -int dp_mux_get_parent_7nm(void *context, - unsigned int reg, unsigned int *val); -#endif /* __MDSS_DP_PLL_7NM_H */ diff --git a/pll/dp_pll_7nm_util.c b/pll/dp_pll_7nm_util.c deleted file mode 100644 index 4ce47a7f5497..000000000000 --- a/pll/dp_pll_7nm_util.c +++ /dev/null @@ -1,739 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. - */ - -#define pr_fmt(fmt) "[dp-pll] %s: " fmt, __func__ - -#include -#include -#include -#include -#include - -#include "pll_drv.h" -#include "dp_pll.h" -#include "dp_pll_7nm.h" - -#define DP_PHY_CFG 0x0010 -#define DP_PHY_CFG_1 0x0014 -#define DP_PHY_PD_CTL 0x0018 -#define DP_PHY_MODE 0x001C - -#define DP_PHY_AUX_CFG1 0x0024 -#define DP_PHY_AUX_CFG2 0x0028 - -#define DP_PHY_VCO_DIV 0x0070 -#define DP_PHY_TX0_TX1_LANE_CTL 0x0078 -#define DP_PHY_TX2_TX3_LANE_CTL 0x009C - -#define DP_PHY_SPARE0 0x00C8 -#define DP_PHY_STATUS 0x00DC - -/* Tx registers */ -#define TXn_CLKBUF_ENABLE 0x0008 -#define TXn_TX_EMP_POST1_LVL 0x000C - -#define TXn_TX_DRV_LVL 0x0014 - -#define TXn_RESET_TSYNC_EN 0x001C -#define TXn_PRE_STALL_LDO_BOOST_EN 0x0020 -#define TXn_TX_BAND 0x0024 -#define TXn_INTERFACE_SELECT 0x002C - -#define TXn_RES_CODE_LANE_OFFSET_TX 0x003C -#define TXn_RES_CODE_LANE_OFFSET_RX 0x0040 - -#define TXn_TRANSCEIVER_BIAS_EN 0x0054 -#define TXn_HIGHZ_DRVR_EN 0x0058 -#define TXn_TX_POL_INV 0x005C -#define TXn_PARRATE_REC_DETECT_IDLE_EN 0x0060 - -/* PLL register offset */ -#define QSERDES_COM_BG_TIMER 0x000C -#define QSERDES_COM_BIAS_EN_CLKBUFLR_EN 0x0044 -#define QSERDES_COM_CLK_ENABLE1 0x0048 -#define QSERDES_COM_SYS_CLK_CTRL 0x004C -#define QSERDES_COM_SYSCLK_BUF_ENABLE 0x0050 -#define QSERDES_COM_PLL_IVCO 0x0058 - -#define QSERDES_COM_CP_CTRL_MODE0 0x0074 -#define QSERDES_COM_PLL_RCTRL_MODE0 0x007C -#define QSERDES_COM_PLL_CCTRL_MODE0 0x0084 -#define QSERDES_COM_SYSCLK_EN_SEL 0x0094 -#define QSERDES_COM_RESETSM_CNTRL 0x009C -#define QSERDES_COM_LOCK_CMP_EN 0x00A4 -#define QSERDES_COM_LOCK_CMP1_MODE0 0x00AC -#define QSERDES_COM_LOCK_CMP2_MODE0 0x00B0 - -#define QSERDES_COM_DEC_START_MODE0 0x00BC -#define QSERDES_COM_DIV_FRAC_START1_MODE0 0x00CC -#define QSERDES_COM_DIV_FRAC_START2_MODE0 0x00D0 -#define QSERDES_COM_DIV_FRAC_START3_MODE0 0x00D4 -#define QSERDES_COM_INTEGLOOP_GAIN0_MODE0 0x00EC -#define QSERDES_COM_INTEGLOOP_GAIN1_MODE0 0x00F0 -#define QSERDES_COM_VCO_TUNE_CTRL 0x0108 -#define QSERDES_COM_VCO_TUNE_MAP 0x010C - -#define QSERDES_COM_CMN_STATUS 0x0140 -#define QSERDES_COM_CLK_SEL 0x0154 -#define QSERDES_COM_HSCLK_SEL 0x0158 - -#define QSERDES_COM_CORECLK_DIV_MODE0 0x0168 - -#define QSERDES_COM_CORE_CLK_EN 0x0174 -#define QSERDES_COM_C_READY_STATUS 0x0178 -#define QSERDES_COM_CMN_CONFIG 0x017C - -#define QSERDES_COM_SVS_MODE_CLK_SEL 0x0184 - -/* Tx tran offsets */ -#define DP_TRAN_DRVR_EMP_EN 0x0000 -#define DP_TX_INTERFACE_MODE 0x0004 - -/* Tx VMODE offsets */ -#define DP_VMODE_CTRL1 0x0000 - -#define DP_PHY_PLL_POLL_SLEEP_US 500 -#define DP_PHY_PLL_POLL_TIMEOUT_US 10000 - -#define DP_VCO_RATE_8100MHZDIV1000 8100000UL -#define DP_VCO_RATE_9720MHZDIV1000 9720000UL -#define DP_VCO_RATE_10800MHZDIV1000 10800000UL - -#define DP_7NM_C_READY BIT(0) -#define DP_7NM_FREQ_DONE BIT(0) -#define DP_7NM_PLL_LOCKED BIT(1) -#define DP_7NM_PHY_READY BIT(1) -#define DP_7NM_TSYNC_DONE BIT(0) - -int dp_mux_set_parent_7nm(void *context, unsigned int reg, unsigned int val) -{ - struct mdss_pll_resources *dp_res = context; - int rc; - u32 auxclk_div; - - if (!context) { - pr_err("invalid input parameters\n"); - return -EINVAL; - } - - rc = mdss_pll_resource_enable(dp_res, true); - if (rc) { - pr_err("Failed to enable mdss DP PLL resources\n"); - return rc; - } - - auxclk_div = MDSS_PLL_REG_R(dp_res->phy_base, DP_PHY_VCO_DIV); - auxclk_div &= ~0x03; - - if (val == 0) - auxclk_div |= 1; - else if (val == 1) - auxclk_div |= 2; - else if (val == 2) - auxclk_div |= 0; - - MDSS_PLL_REG_W(dp_res->phy_base, DP_PHY_VCO_DIV, auxclk_div); - /* Make sure the PHY registers writes are done */ - wmb(); - pr_debug("mux=%d auxclk_div=%x\n", val, auxclk_div); - - mdss_pll_resource_enable(dp_res, false); - - return 0; -} - -int dp_mux_get_parent_7nm(void *context, unsigned int reg, unsigned int *val) -{ - int rc; - u32 auxclk_div = 0; - struct mdss_pll_resources *dp_res = context; - - if (!context || !val) { - pr_err("invalid input parameters\n"); - return -EINVAL; - } - - if (is_gdsc_disabled(dp_res)) - return 0; - - rc = mdss_pll_resource_enable(dp_res, true); - if (rc) { - pr_err("Failed to enable dp_res resources\n"); - return rc; - } - - auxclk_div = MDSS_PLL_REG_R(dp_res->phy_base, DP_PHY_VCO_DIV); - auxclk_div &= 0x03; - - if (auxclk_div == 1) /* Default divider */ - *val = 0; - else if (auxclk_div == 2) - *val = 1; - else if (auxclk_div == 0) - *val = 2; - - mdss_pll_resource_enable(dp_res, false); - - pr_debug("auxclk_div=%d, val=%d\n", auxclk_div, *val); - - return 0; -} - -static int dp_vco_pll_init_db_7nm(struct dp_pll_db_7nm *pdb, - unsigned long rate) -{ - struct mdss_pll_resources *dp_res = pdb->pll; - u32 spare_value = 0; - - spare_value = MDSS_PLL_REG_R(dp_res->phy_base, DP_PHY_SPARE0); - pdb->lane_cnt = spare_value & 0x0F; - pdb->orientation = (spare_value & 0xF0) >> 4; - - pr_debug("spare_value=0x%x, ln_cnt=0x%x, orientation=0x%x\n", - spare_value, pdb->lane_cnt, pdb->orientation); - - pdb->div_frac_start1_mode0 = 0x00; - pdb->integloop_gain0_mode0 = 0x3f; - pdb->integloop_gain1_mode0 = 0x00; - pdb->vco_tune_map = 0x00; - pdb->cmn_config = 0x02; - - switch (rate) { - case DP_VCO_HSCLK_RATE_1620MHZDIV1000: - pr_debug("VCO rate: %ld\n", DP_VCO_RATE_9720MHZDIV1000); - pdb->hsclk_sel = 0x05; - pdb->dec_start_mode0 = 0x69; - pdb->div_frac_start2_mode0 = 0x80; - pdb->div_frac_start3_mode0 = 0x07; - pdb->lock_cmp1_mode0 = 0x6f; - pdb->lock_cmp2_mode0 = 0x08; - pdb->phy_vco_div = 0x1; - pdb->lock_cmp_en = 0x04; - break; - case DP_VCO_HSCLK_RATE_2700MHZDIV1000: - pr_debug("VCO rate: %ld\n", DP_VCO_RATE_10800MHZDIV1000); - pdb->hsclk_sel = 0x03; - pdb->dec_start_mode0 = 0x69; - pdb->div_frac_start2_mode0 = 0x80; - pdb->div_frac_start3_mode0 = 0x07; - pdb->lock_cmp1_mode0 = 0x0f; - pdb->lock_cmp2_mode0 = 0x0e; - pdb->phy_vco_div = 0x1; - pdb->lock_cmp_en = 0x08; - break; - case DP_VCO_HSCLK_RATE_5400MHZDIV1000: - pr_debug("VCO rate: %ld\n", DP_VCO_RATE_10800MHZDIV1000); - pdb->hsclk_sel = 0x01; - pdb->dec_start_mode0 = 0x8c; - pdb->div_frac_start2_mode0 = 0x00; - pdb->div_frac_start3_mode0 = 0x0a; - pdb->lock_cmp1_mode0 = 0x1f; - pdb->lock_cmp2_mode0 = 0x1c; - pdb->phy_vco_div = 0x2; - pdb->lock_cmp_en = 0x08; - break; - case DP_VCO_HSCLK_RATE_8100MHZDIV1000: - pr_debug("VCO rate: %ld\n", DP_VCO_RATE_8100MHZDIV1000); - pdb->hsclk_sel = 0x00; - pdb->dec_start_mode0 = 0x69; - pdb->div_frac_start2_mode0 = 0x80; - pdb->div_frac_start3_mode0 = 0x07; - pdb->lock_cmp1_mode0 = 0x2f; - pdb->lock_cmp2_mode0 = 0x2a; - pdb->phy_vco_div = 0x0; - pdb->lock_cmp_en = 0x08; - break; - default: - pr_err("unsupported rate %ld\n", rate); - return -EINVAL; - } - return 0; -} - -static int dp_config_vco_rate_7nm(struct dp_pll_vco_clk *vco, - unsigned long rate) -{ - u32 res = 0; - struct mdss_pll_resources *dp_res = vco->priv; - struct dp_pll_db_7nm *pdb = (struct dp_pll_db_7nm *)dp_res->priv; - - res = dp_vco_pll_init_db_7nm(pdb, rate); - if (res) { - pr_err("VCO Init DB failed\n"); - return res; - } - - MDSS_PLL_REG_W(dp_res->phy_base, DP_PHY_CFG_1, 0x0F); - - if (pdb->lane_cnt != 4) { - if (pdb->orientation == ORIENTATION_CC2) - MDSS_PLL_REG_W(dp_res->phy_base, DP_PHY_PD_CTL, 0x6d); - else - MDSS_PLL_REG_W(dp_res->phy_base, DP_PHY_PD_CTL, 0x75); - } else { - MDSS_PLL_REG_W(dp_res->phy_base, DP_PHY_PD_CTL, 0x7d); - } - - /* Make sure the PHY register writes are done */ - wmb(); - - MDSS_PLL_REG_W(dp_res->pll_base, QSERDES_COM_SVS_MODE_CLK_SEL, 0x05); - MDSS_PLL_REG_W(dp_res->pll_base, QSERDES_COM_SYSCLK_EN_SEL, 0x3b); - MDSS_PLL_REG_W(dp_res->pll_base, QSERDES_COM_SYS_CLK_CTRL, 0x02); - MDSS_PLL_REG_W(dp_res->pll_base, QSERDES_COM_CLK_ENABLE1, 0x0c); - MDSS_PLL_REG_W(dp_res->pll_base, QSERDES_COM_SYSCLK_BUF_ENABLE, 0x06); - MDSS_PLL_REG_W(dp_res->pll_base, QSERDES_COM_CLK_SEL, 0x30); - /* Make sure the PHY register writes are done */ - wmb(); - - /* PLL Optimization */ - MDSS_PLL_REG_W(dp_res->pll_base, QSERDES_COM_PLL_IVCO, 0x0f); - MDSS_PLL_REG_W(dp_res->pll_base, QSERDES_COM_PLL_CCTRL_MODE0, 0x36); - MDSS_PLL_REG_W(dp_res->pll_base, QSERDES_COM_PLL_RCTRL_MODE0, 0x16); - MDSS_PLL_REG_W(dp_res->pll_base, QSERDES_COM_CP_CTRL_MODE0, 0x06); - /* Make sure the PHY register writes are done */ - wmb(); - - /* link rate dependent params */ - MDSS_PLL_REG_W(dp_res->pll_base, - QSERDES_COM_HSCLK_SEL, pdb->hsclk_sel); - MDSS_PLL_REG_W(dp_res->pll_base, - QSERDES_COM_DEC_START_MODE0, pdb->dec_start_mode0); - MDSS_PLL_REG_W(dp_res->pll_base, - QSERDES_COM_DIV_FRAC_START1_MODE0, pdb->div_frac_start1_mode0); - MDSS_PLL_REG_W(dp_res->pll_base, - QSERDES_COM_DIV_FRAC_START2_MODE0, pdb->div_frac_start2_mode0); - MDSS_PLL_REG_W(dp_res->pll_base, - QSERDES_COM_DIV_FRAC_START3_MODE0, pdb->div_frac_start3_mode0); - MDSS_PLL_REG_W(dp_res->pll_base, - QSERDES_COM_LOCK_CMP1_MODE0, pdb->lock_cmp1_mode0); - MDSS_PLL_REG_W(dp_res->pll_base, - QSERDES_COM_LOCK_CMP2_MODE0, pdb->lock_cmp2_mode0); - MDSS_PLL_REG_W(dp_res->pll_base, QSERDES_COM_LOCK_CMP_EN, - pdb->lock_cmp_en); - MDSS_PLL_REG_W(dp_res->phy_base, DP_PHY_VCO_DIV, pdb->phy_vco_div); - /* Make sure the PLL register writes are done */ - wmb(); - - MDSS_PLL_REG_W(dp_res->pll_base, QSERDES_COM_CMN_CONFIG, 0x02); - MDSS_PLL_REG_W(dp_res->pll_base, - QSERDES_COM_INTEGLOOP_GAIN0_MODE0, 0x3f); - MDSS_PLL_REG_W(dp_res->pll_base, - QSERDES_COM_INTEGLOOP_GAIN1_MODE0, 0x00); - MDSS_PLL_REG_W(dp_res->pll_base, QSERDES_COM_VCO_TUNE_MAP, 0x00); - /* Make sure the PHY register writes are done */ - wmb(); - - MDSS_PLL_REG_W(dp_res->pll_base, QSERDES_COM_BG_TIMER, 0x0a); - MDSS_PLL_REG_W(dp_res->pll_base, QSERDES_COM_CORECLK_DIV_MODE0, 0x0a); - MDSS_PLL_REG_W(dp_res->pll_base, QSERDES_COM_VCO_TUNE_CTRL, 0x00); - MDSS_PLL_REG_W(dp_res->pll_base, QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x17); - MDSS_PLL_REG_W(dp_res->pll_base, QSERDES_COM_CORE_CLK_EN, 0x1f); - /* Make sure the PHY register writes are done */ - wmb(); - - if (pdb->orientation == ORIENTATION_CC2) - MDSS_PLL_REG_W(dp_res->phy_base, DP_PHY_MODE, 0x4c); - else - MDSS_PLL_REG_W(dp_res->phy_base, DP_PHY_MODE, 0x5c); - - MDSS_PLL_REG_W(dp_res->phy_base, DP_PHY_AUX_CFG1, 0x13); - MDSS_PLL_REG_W(dp_res->phy_base, DP_PHY_AUX_CFG2, 0xA4); - /* Make sure the PLL register writes are done */ - wmb(); - - /* TX-0 register configuration */ - MDSS_PLL_REG_W(dp_res->phy_base, DP_PHY_TX0_TX1_LANE_CTL, 0x05); - MDSS_PLL_REG_W(dp_res->ln_tx0_vmode_base, DP_VMODE_CTRL1, 0x40); - MDSS_PLL_REG_W(dp_res->ln_tx0_base, TXn_PRE_STALL_LDO_BOOST_EN, 0x30); - MDSS_PLL_REG_W(dp_res->ln_tx0_base, TXn_INTERFACE_SELECT, 0x3b); - MDSS_PLL_REG_W(dp_res->ln_tx0_base, TXn_CLKBUF_ENABLE, 0x0f); - MDSS_PLL_REG_W(dp_res->ln_tx0_base, TXn_RESET_TSYNC_EN, 0x03); - MDSS_PLL_REG_W(dp_res->ln_tx0_tran_base, DP_TRAN_DRVR_EMP_EN, 0xf); - MDSS_PLL_REG_W(dp_res->ln_tx0_base, - TXn_PARRATE_REC_DETECT_IDLE_EN, 0x00); - MDSS_PLL_REG_W(dp_res->ln_tx0_tran_base, DP_TX_INTERFACE_MODE, 0x00); - MDSS_PLL_REG_W(dp_res->ln_tx0_base, TXn_RES_CODE_LANE_OFFSET_TX, 0x11); - MDSS_PLL_REG_W(dp_res->ln_tx0_base, TXn_RES_CODE_LANE_OFFSET_RX, 0x11); - MDSS_PLL_REG_W(dp_res->ln_tx0_base, TXn_TX_BAND, 0x04); - - /* TX-1 register configuration */ - MDSS_PLL_REG_W(dp_res->phy_base, DP_PHY_TX2_TX3_LANE_CTL, 0x05); - MDSS_PLL_REG_W(dp_res->ln_tx1_vmode_base, DP_VMODE_CTRL1, 0x40); - MDSS_PLL_REG_W(dp_res->ln_tx1_base, TXn_PRE_STALL_LDO_BOOST_EN, 0x30); - MDSS_PLL_REG_W(dp_res->ln_tx1_base, TXn_INTERFACE_SELECT, 0x3b); - MDSS_PLL_REG_W(dp_res->ln_tx1_base, TXn_CLKBUF_ENABLE, 0x0f); - MDSS_PLL_REG_W(dp_res->ln_tx1_base, TXn_RESET_TSYNC_EN, 0x03); - MDSS_PLL_REG_W(dp_res->ln_tx1_tran_base, DP_TRAN_DRVR_EMP_EN, 0xf); - MDSS_PLL_REG_W(dp_res->ln_tx1_base, - TXn_PARRATE_REC_DETECT_IDLE_EN, 0x00); - MDSS_PLL_REG_W(dp_res->ln_tx1_tran_base, DP_TX_INTERFACE_MODE, 0x00); - MDSS_PLL_REG_W(dp_res->ln_tx1_base, TXn_RES_CODE_LANE_OFFSET_TX, 0x11); - MDSS_PLL_REG_W(dp_res->ln_tx1_base, TXn_RES_CODE_LANE_OFFSET_RX, 0x11); - MDSS_PLL_REG_W(dp_res->ln_tx1_base, TXn_TX_BAND, 0x04); - /* Make sure the PHY register writes are done */ - wmb(); - - return res; -} - -enum dp_7nm_pll_status { - C_READY, - FREQ_DONE, - PLL_LOCKED, - PHY_READY, - TSYNC_DONE, -}; - -char *dp_7nm_pll_get_status_name(enum dp_7nm_pll_status status) -{ - switch (status) { - case C_READY: - return "C_READY"; - case FREQ_DONE: - return "FREQ_DONE"; - case PLL_LOCKED: - return "PLL_LOCKED"; - case PHY_READY: - return "PHY_READY"; - case TSYNC_DONE: - return "TSYNC_DONE"; - default: - return "unknown"; - } - - -} - -static bool dp_7nm_pll_get_status(struct mdss_pll_resources *dp_res, - enum dp_7nm_pll_status status) -{ - u32 reg, state, bit; - void __iomem *base; - bool success = true; - - switch (status) { - case C_READY: - base = dp_res->pll_base; - reg = QSERDES_COM_C_READY_STATUS; - bit = DP_7NM_C_READY; - break; - case FREQ_DONE: - base = dp_res->pll_base; - reg = QSERDES_COM_CMN_STATUS; - bit = DP_7NM_FREQ_DONE; - break; - case PLL_LOCKED: - base = dp_res->pll_base; - reg = QSERDES_COM_CMN_STATUS; - bit = DP_7NM_PLL_LOCKED; - break; - case PHY_READY: - base = dp_res->phy_base; - reg = DP_PHY_STATUS; - bit = DP_7NM_PHY_READY; - break; - case TSYNC_DONE: - base = dp_res->phy_base; - reg = DP_PHY_STATUS; - bit = DP_7NM_TSYNC_DONE; - break; - default: - return false; - } - - if (readl_poll_timeout_atomic((base + reg), state, - ((state & bit) > 0), - DP_PHY_PLL_POLL_SLEEP_US, - DP_PHY_PLL_POLL_TIMEOUT_US)) { - pr_err("%s failed, status=%x\n", - dp_7nm_pll_get_status_name(status), state); - - success = false; - } - - return success; -} - -static int dp_pll_enable_7nm(struct clk_hw *hw) -{ - int rc = 0; - struct dp_pll_vco_clk *vco = to_dp_vco_hw(hw); - struct mdss_pll_resources *dp_res = vco->priv; - - MDSS_PLL_REG_W(dp_res->phy_base, DP_PHY_CFG, 0x01); - MDSS_PLL_REG_W(dp_res->phy_base, DP_PHY_CFG, 0x05); - MDSS_PLL_REG_W(dp_res->phy_base, DP_PHY_CFG, 0x01); - MDSS_PLL_REG_W(dp_res->phy_base, DP_PHY_CFG, 0x09); - MDSS_PLL_REG_W(dp_res->pll_base, QSERDES_COM_RESETSM_CNTRL, 0x20); - wmb(); /* Make sure the PLL register writes are done */ - - if (!dp_7nm_pll_get_status(dp_res, C_READY)) { - rc = -EINVAL; - goto lock_err; - } - - if (!dp_7nm_pll_get_status(dp_res, FREQ_DONE)) { - rc = -EINVAL; - goto lock_err; - } - - if (!dp_7nm_pll_get_status(dp_res, PLL_LOCKED)) { - rc = -EINVAL; - goto lock_err; - } - - MDSS_PLL_REG_W(dp_res->phy_base, DP_PHY_CFG, 0x19); - /* Make sure the PHY register writes are done */ - wmb(); - - if (!dp_7nm_pll_get_status(dp_res, TSYNC_DONE)) { - rc = -EINVAL; - goto lock_err; - } - - if (!dp_7nm_pll_get_status(dp_res, PHY_READY)) { - rc = -EINVAL; - goto lock_err; - } - - pr_debug("PLL is locked\n"); -lock_err: - return rc; -} - -static int dp_pll_disable_7nm(struct clk_hw *hw) -{ - struct dp_pll_vco_clk *vco = to_dp_vco_hw(hw); - struct mdss_pll_resources *dp_res = vco->priv; - - /* Assert DP PHY power down */ - MDSS_PLL_REG_W(dp_res->phy_base, DP_PHY_PD_CTL, 0x2); - /* - * Make sure all the register writes to disable PLL are - * completed before doing any other operation - */ - wmb(); - - return 0; -} - -int dp_vco_prepare_7nm(struct clk_hw *hw) -{ - int rc = 0; - struct dp_pll_vco_clk *vco; - struct mdss_pll_resources *dp_res; - - if (!hw) { - pr_err("invalid input parameters\n"); - return -EINVAL; - } - - vco = to_dp_vco_hw(hw); - dp_res = vco->priv; - - pr_debug("rate=%ld\n", vco->rate); - rc = mdss_pll_resource_enable(dp_res, true); - if (rc) { - pr_err("Failed to enable mdss DP pll resources\n"); - goto error; - } - - if ((dp_res->vco_cached_rate != 0) - && (dp_res->vco_cached_rate == vco->rate)) { - rc = vco->hw.init->ops->set_rate(hw, - dp_res->vco_cached_rate, dp_res->vco_cached_rate); - if (rc) { - pr_err("index=%d vco_set_rate failed. rc=%d\n", - rc, dp_res->index); - mdss_pll_resource_enable(dp_res, false); - goto error; - } - } - - rc = dp_pll_enable_7nm(hw); - if (rc) { - mdss_pll_resource_enable(dp_res, false); - pr_err("ndx=%d failed to enable dp pll\n", dp_res->index); - goto error; - } - - mdss_pll_resource_enable(dp_res, false); -error: - return rc; -} - -void dp_vco_unprepare_7nm(struct clk_hw *hw) -{ - struct dp_pll_vco_clk *vco; - struct mdss_pll_resources *dp_res; - - if (!hw) { - pr_err("invalid input parameters\n"); - return; - } - - vco = to_dp_vco_hw(hw); - dp_res = vco->priv; - - if (!dp_res) { - pr_err("invalid input parameter\n"); - return; - } - - if (!dp_res->pll_on && - mdss_pll_resource_enable(dp_res, true)) { - pr_err("pll resource can't be enabled\n"); - return; - } - dp_res->vco_cached_rate = vco->rate; - dp_pll_disable_7nm(hw); - - dp_res->handoff_resources = false; - mdss_pll_resource_enable(dp_res, false); - dp_res->pll_on = false; -} - -int dp_vco_set_rate_7nm(struct clk_hw *hw, unsigned long rate, - unsigned long parent_rate) -{ - struct dp_pll_vco_clk *vco; - struct mdss_pll_resources *dp_res; - int rc; - - if (!hw) { - pr_err("invalid input parameters\n"); - return -EINVAL; - } - - vco = to_dp_vco_hw(hw); - dp_res = vco->priv; - - rc = mdss_pll_resource_enable(dp_res, true); - if (rc) { - pr_err("pll resource can't be enabled\n"); - return rc; - } - - pr_debug("DP lane CLK rate=%ld\n", rate); - - rc = dp_config_vco_rate_7nm(vco, rate); - if (rc) - pr_err("Failed to set clk rate\n"); - - mdss_pll_resource_enable(dp_res, false); - - vco->rate = rate; - - return 0; -} - -unsigned long dp_vco_recalc_rate_7nm(struct clk_hw *hw, - unsigned long parent_rate) -{ - struct dp_pll_vco_clk *vco; - int rc; - u32 hsclk_sel, link_clk_divsel, hsclk_div, link_clk_div = 0; - unsigned long vco_rate; - struct mdss_pll_resources *dp_res; - - if (!hw) { - pr_err("invalid input parameters\n"); - return 0; - } - - vco = to_dp_vco_hw(hw); - dp_res = vco->priv; - - if (is_gdsc_disabled(dp_res)) - return 0; - - rc = mdss_pll_resource_enable(dp_res, true); - if (rc) { - pr_err("Failed to enable mdss DP pll=%d\n", dp_res->index); - return 0; - } - - pr_debug("input rates: parent=%lu, vco=%lu\n", parent_rate, vco->rate); - - hsclk_sel = MDSS_PLL_REG_R(dp_res->pll_base, QSERDES_COM_HSCLK_SEL); - hsclk_sel &= 0x0f; - - if (hsclk_sel == 5) - hsclk_div = 5; - else if (hsclk_sel == 3) - hsclk_div = 3; - else if (hsclk_sel == 1) - hsclk_div = 2; - else if (hsclk_sel == 0) - hsclk_div = 1; - else { - pr_debug("unknown divider. forcing to default\n"); - hsclk_div = 5; - } - - link_clk_divsel = MDSS_PLL_REG_R(dp_res->phy_base, DP_PHY_AUX_CFG2); - link_clk_divsel >>= 2; - link_clk_divsel &= 0x3; - - if (link_clk_divsel == 0) - link_clk_div = 5; - else if (link_clk_divsel == 1) - link_clk_div = 10; - else if (link_clk_divsel == 2) - link_clk_div = 20; - else - pr_err("unsupported div. Phy_mode: %d\n", link_clk_divsel); - - if (link_clk_div == 20) { - vco_rate = DP_VCO_HSCLK_RATE_2700MHZDIV1000; - } else { - if (hsclk_div == 5) - vco_rate = DP_VCO_HSCLK_RATE_1620MHZDIV1000; - else if (hsclk_div == 3) - vco_rate = DP_VCO_HSCLK_RATE_2700MHZDIV1000; - else if (hsclk_div == 2) - vco_rate = DP_VCO_HSCLK_RATE_5400MHZDIV1000; - else - vco_rate = DP_VCO_HSCLK_RATE_8100MHZDIV1000; - } - - pr_debug("hsclk: sel=0x%x, div=0x%x; lclk: sel=%u, div=%u, rate=%lu\n", - hsclk_sel, hsclk_div, link_clk_divsel, link_clk_div, vco_rate); - - mdss_pll_resource_enable(dp_res, false); - - dp_res->vco_cached_rate = vco->rate = vco_rate; - return vco_rate; -} - -long dp_vco_round_rate_7nm(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) -{ - unsigned long rrate = rate; - struct dp_pll_vco_clk *vco; - - if (!hw) { - pr_err("invalid input parameters\n"); - return 0; - } - - vco = to_dp_vco_hw(hw); - if (rate <= vco->min_rate) - rrate = vco->min_rate; - else if (rate <= DP_VCO_HSCLK_RATE_2700MHZDIV1000) - rrate = DP_VCO_HSCLK_RATE_2700MHZDIV1000; - else if (rate <= DP_VCO_HSCLK_RATE_5400MHZDIV1000) - rrate = DP_VCO_HSCLK_RATE_5400MHZDIV1000; - else - rrate = vco->max_rate; - - pr_debug("rrate=%ld\n", rrate); - - if (parent_rate) - *parent_rate = rrate; - return rrate; -} - diff --git a/pll/dsi_20nm_pll_util.c b/pll/dsi_20nm_pll_util.c deleted file mode 100644 index 2a0ab26e7011..000000000000 --- a/pll/dsi_20nm_pll_util.c +++ /dev/null @@ -1,1004 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (c) 2014-2019, The Linux Foundation. All rights reserved. - */ - -#define pr_fmt(fmt) "%s: " fmt, __func__ - -#include -#include -#include -#include -#include - -#include "pll_drv.h" -#include "dsi_pll.h" - -#define MMSS_DSI_PHY_PLL_SYS_CLK_CTRL 0x0000 -#define MMSS_DSI_PHY_PLL_PLL_VCOTAIL_EN 0x0004 -#define MMSS_DSI_PHY_PLL_CMN_MODE 0x0008 -#define MMSS_DSI_PHY_PLL_IE_TRIM 0x000C -#define MMSS_DSI_PHY_PLL_IP_TRIM 0x0010 - -#define MMSS_DSI_PHY_PLL_PLL_PHSEL_CONTROL 0x0018 -#define MMSS_DSI_PHY_PLL_IPTAT_TRIM_VCCA_TX_SEL 0x001C -#define MMSS_DSI_PHY_PLL_PLL_PHSEL_DC 0x0020 -#define MMSS_DSI_PHY_PLL_PLL_IP_SETI 0x0024 -#define MMSS_DSI_PHY_PLL_CORE_CLK_IN_SYNC_SEL 0x0028 - -#define MMSS_DSI_PHY_PLL_BIAS_EN_CLKBUFLR_EN 0x0030 -#define MMSS_DSI_PHY_PLL_PLL_CP_SETI 0x0034 -#define MMSS_DSI_PHY_PLL_PLL_IP_SETP 0x0038 -#define MMSS_DSI_PHY_PLL_PLL_CP_SETP 0x003C -#define MMSS_DSI_PHY_PLL_ATB_SEL1 0x0040 -#define MMSS_DSI_PHY_PLL_ATB_SEL2 0x0044 -#define MMSS_DSI_PHY_PLL_SYSCLK_EN_SEL_TXBAND 0x0048 -#define MMSS_DSI_PHY_PLL_RESETSM_CNTRL 0x004C -#define MMSS_DSI_PHY_PLL_RESETSM_CNTRL2 0x0050 -#define MMSS_DSI_PHY_PLL_RESETSM_CNTRL3 0x0054 -#define MMSS_DSI_PHY_PLL_RESETSM_PLL_CAL_COUNT1 0x0058 -#define MMSS_DSI_PHY_PLL_RESETSM_PLL_CAL_COUNT2 0x005C -#define MMSS_DSI_PHY_PLL_DIV_REF1 0x0060 -#define MMSS_DSI_PHY_PLL_DIV_REF2 0x0064 -#define MMSS_DSI_PHY_PLL_KVCO_COUNT1 0x0068 -#define MMSS_DSI_PHY_PLL_KVCO_COUNT2 0x006C -#define MMSS_DSI_PHY_PLL_KVCO_CAL_CNTRL 0x0070 -#define MMSS_DSI_PHY_PLL_KVCO_CODE 0x0074 -#define MMSS_DSI_PHY_PLL_VREF_CFG1 0x0078 -#define MMSS_DSI_PHY_PLL_VREF_CFG2 0x007C -#define MMSS_DSI_PHY_PLL_VREF_CFG3 0x0080 -#define MMSS_DSI_PHY_PLL_VREF_CFG4 0x0084 -#define MMSS_DSI_PHY_PLL_VREF_CFG5 0x0088 -#define MMSS_DSI_PHY_PLL_VREF_CFG6 0x008C -#define MMSS_DSI_PHY_PLL_PLLLOCK_CMP1 0x0090 -#define MMSS_DSI_PHY_PLL_PLLLOCK_CMP2 0x0094 -#define MMSS_DSI_PHY_PLL_PLLLOCK_CMP3 0x0098 - -#define MMSS_DSI_PHY_PLL_BGTC 0x00A0 -#define MMSS_DSI_PHY_PLL_PLL_TEST_UPDN 0x00A4 -#define MMSS_DSI_PHY_PLL_PLL_VCO_TUNE 0x00A8 -#define MMSS_DSI_PHY_PLL_DEC_START1 0x00AC -#define MMSS_DSI_PHY_PLL_PLL_AMP_OS 0x00B0 -#define MMSS_DSI_PHY_PLL_SSC_EN_CENTER 0x00B4 -#define MMSS_DSI_PHY_PLL_SSC_ADJ_PER1 0x00B8 -#define MMSS_DSI_PHY_PLL_SSC_ADJ_PER2 0x00BC -#define MMSS_DSI_PHY_PLL_SSC_PER1 0x00C0 -#define MMSS_DSI_PHY_PLL_SSC_PER2 0x00C4 -#define MMSS_DSI_PHY_PLL_SSC_STEP_SIZE1 0x00C8 -#define MMSS_DSI_PHY_PLL_SSC_STEP_SIZE2 0x00CC -#define MMSS_DSI_PHY_PLL_RES_CODE_UP 0x00D0 -#define MMSS_DSI_PHY_PLL_RES_CODE_DN 0x00D4 -#define MMSS_DSI_PHY_PLL_RES_CODE_UP_OFFSET 0x00D8 -#define MMSS_DSI_PHY_PLL_RES_CODE_DN_OFFSET 0x00DC -#define MMSS_DSI_PHY_PLL_RES_CODE_START_SEG1 0x00E0 -#define MMSS_DSI_PHY_PLL_RES_CODE_START_SEG2 0x00E4 -#define MMSS_DSI_PHY_PLL_RES_CODE_CAL_CSR 0x00E8 -#define MMSS_DSI_PHY_PLL_RES_CODE 0x00EC -#define MMSS_DSI_PHY_PLL_RES_TRIM_CONTROL 0x00F0 -#define MMSS_DSI_PHY_PLL_RES_TRIM_CONTROL2 0x00F4 -#define MMSS_DSI_PHY_PLL_RES_TRIM_EN_VCOCALDONE 0x00F8 -#define MMSS_DSI_PHY_PLL_FAUX_EN 0x00FC - -#define MMSS_DSI_PHY_PLL_DIV_FRAC_START1 0x0100 -#define MMSS_DSI_PHY_PLL_DIV_FRAC_START2 0x0104 -#define MMSS_DSI_PHY_PLL_DIV_FRAC_START3 0x0108 -#define MMSS_DSI_PHY_PLL_DEC_START2 0x010C -#define MMSS_DSI_PHY_PLL_PLL_RXTXEPCLK_EN 0x0110 -#define MMSS_DSI_PHY_PLL_PLL_CRCTRL 0x0114 -#define MMSS_DSI_PHY_PLL_LOW_POWER_RO_CONTROL 0x013C -#define MMSS_DSI_PHY_PLL_POST_DIVIDER_CONTROL 0x0140 -#define MMSS_DSI_PHY_PLL_HR_OCLK2_DIVIDER 0x0144 -#define MMSS_DSI_PHY_PLL_HR_OCLK3_DIVIDER 0x0148 -#define MMSS_DSI_PHY_PLL_PLL_VCO_HIGH 0x014C -#define MMSS_DSI_PHY_PLL_RESET_SM 0x0150 -#define MMSS_DSI_PHY_PLL_MUXVAL 0x0154 -#define MMSS_DSI_PHY_PLL_CORE_RES_CODE_DN 0x0158 -#define MMSS_DSI_PHY_PLL_CORE_RES_CODE_UP 0x015C -#define MMSS_DSI_PHY_PLL_CORE_VCO_TUNE 0x0160 -#define MMSS_DSI_PHY_PLL_CORE_VCO_TAIL 0x0164 -#define MMSS_DSI_PHY_PLL_CORE_KVCO_CODE 0x0168 - -#define MMSS_DSI_DYNAMIC_REFRESH_PLL_CTRL0 0x014 -#define MMSS_DSI_DYNAMIC_REFRESH_PLL_CTRL1 0x018 -#define MMSS_DSI_DYNAMIC_REFRESH_PLL_CTRL2 0x01C -#define MMSS_DSI_DYNAMIC_REFRESH_PLL_CTRL3 0x020 -#define MMSS_DSI_DYNAMIC_REFRESH_PLL_CTRL4 0x024 -#define MMSS_DSI_DYNAMIC_REFRESH_PLL_CTRL5 0x028 -#define MMSS_DSI_DYNAMIC_REFRESH_PLL_CTRL6 0x02C -#define MMSS_DSI_DYNAMIC_REFRESH_PLL_CTRL7 0x030 -#define MMSS_DSI_DYNAMIC_REFRESH_PLL_CTRL8 0x034 -#define MMSS_DSI_DYNAMIC_REFRESH_PLL_CTRL9 0x038 -#define MMSS_DSI_DYNAMIC_REFRESH_PLL_CTRL10 0x03C -#define MMSS_DSI_DYNAMIC_REFRESH_PLL_CTRL11 0x040 -#define MMSS_DSI_DYNAMIC_REFRESH_PLL_CTRL12 0x044 -#define MMSS_DSI_DYNAMIC_REFRESH_PLL_CTRL13 0x048 -#define MMSS_DSI_DYNAMIC_REFRESH_PLL_CTRL14 0x04C -#define MMSS_DSI_DYNAMIC_REFRESH_PLL_CTRL15 0x050 -#define MMSS_DSI_DYNAMIC_REFRESH_PLL_CTRL16 0x054 -#define MMSS_DSI_DYNAMIC_REFRESH_PLL_CTRL17 0x058 - -#define DSI_PLL_POLL_DELAY_US 1000 -#define DSI_PLL_POLL_TIMEOUT_US 15000 - -int set_mdss_byte_mux_sel(struct mux_clk *clk, int sel) -{ - return 0; -} - -int get_mdss_byte_mux_sel(struct mux_clk *clk) -{ - return 0; -} - -int set_mdss_pixel_mux_sel(struct mux_clk *clk, int sel) -{ - return 0; -} - -int get_mdss_pixel_mux_sel(struct mux_clk *clk) -{ - return 0; -} - -static void pll_20nm_cache_trim_codes(struct mdss_pll_resources *dsi_pll_res) -{ - int rc; - - if (dsi_pll_res->reg_upd) - return; - - rc = mdss_pll_resource_enable(dsi_pll_res, true); - if (rc) { - pr_err("Failed to enable mdss dsi pll resources\n"); - return; - } - - dsi_pll_res->cache_pll_trim_codes[0] = - MDSS_PLL_REG_R(dsi_pll_res->pll_base, - MMSS_DSI_PHY_PLL_CORE_KVCO_CODE); - dsi_pll_res->cache_pll_trim_codes[1] = - MDSS_PLL_REG_R(dsi_pll_res->pll_base, - MMSS_DSI_PHY_PLL_CORE_VCO_TUNE); - - pr_debug("core_kvco_code=0x%x core_vco_turn=0x%x\n", - dsi_pll_res->cache_pll_trim_codes[0], - dsi_pll_res->cache_pll_trim_codes[1]); - - mdss_pll_resource_enable(dsi_pll_res, false); - - dsi_pll_res->reg_upd = true; -} - -static void pll_20nm_override_trim_codes(struct mdss_pll_resources *dsi_pll_res) -{ - u32 reg_data; - void __iomem *pll_base = dsi_pll_res->pll_base; - - /* - * Override mux config for all cached trim codes from - * saved config except for VCO Tune - */ - reg_data = (dsi_pll_res->cache_pll_trim_codes[0] & 0x3f) | BIT(5); - MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_KVCO_CODE, reg_data); - - reg_data = (dsi_pll_res->cache_pll_trim_codes[1] & 0x7f) | BIT(7); - MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_PLL_VCO_TUNE, reg_data); -} - - -int set_bypass_lp_div_mux_sel(struct mux_clk *clk, int sel) -{ - struct mdss_pll_resources *dsi_pll_res = clk->priv; - int reg_data; - - pr_debug("bypass_lp_div mux set to %s mode\n", - sel ? "indirect" : "direct"); - - pr_debug("POST_DIVIDER_CONTROL = 0x%x\n", - MDSS_PLL_REG_R(dsi_pll_res->pll_base, - MMSS_DSI_PHY_PLL_POST_DIVIDER_CONTROL)); - - reg_data = MDSS_PLL_REG_R(dsi_pll_res->pll_base, - MMSS_DSI_PHY_PLL_POST_DIVIDER_CONTROL); - reg_data |= BIT(7); - MDSS_PLL_REG_W(dsi_pll_res->pll_base, - MMSS_DSI_PHY_PLL_POST_DIVIDER_CONTROL, - reg_data | (sel << 5)); - pr_debug("POST_DIVIDER_CONTROL = 0x%x\n", - MDSS_PLL_REG_R(dsi_pll_res->pll_base, - MMSS_DSI_PHY_PLL_POST_DIVIDER_CONTROL)); - - return 0; -} - -int set_shadow_bypass_lp_div_mux_sel(struct mux_clk *clk, int sel) -{ - struct mdss_pll_resources *dsi_pll_res = clk->priv; - int reg_data, rem; - - if (!dsi_pll_res->resource_enable) { - pr_err("PLL resources disabled. Dynamic fps invalid\n"); - return -EINVAL; - } - - reg_data = MDSS_PLL_REG_R(dsi_pll_res->pll_base, - MMSS_DSI_PHY_PLL_POST_DIVIDER_CONTROL); - reg_data |= BIT(7); - - pr_debug("%d: reg_data = %x\n", __LINE__, reg_data); - - /* Repeat POST DIVIDER 2 times (4 writes)*/ - for (rem = 0; rem < 2; rem++) - MDSS_DYN_PLL_REG_W(dsi_pll_res->dyn_pll_base, - MMSS_DSI_DYNAMIC_REFRESH_PLL_CTRL16 + (4 * rem), - MMSS_DSI_PHY_PLL_POST_DIVIDER_CONTROL, - MMSS_DSI_PHY_PLL_POST_DIVIDER_CONTROL, - (reg_data | (sel << 5)), (reg_data | (sel << 5))); - - return 0; -} - -int get_bypass_lp_div_mux_sel(struct mux_clk *clk) -{ - int mux_mode, rc; - struct mdss_pll_resources *dsi_pll_res = clk->priv; - - if (is_gdsc_disabled(dsi_pll_res)) - return 0; - - rc = mdss_pll_resource_enable(dsi_pll_res, true); - if (rc) { - pr_err("Failed to enable mdss dsi pll resources\n"); - return rc; - } - - mux_mode = MDSS_PLL_REG_R(dsi_pll_res->pll_base, - MMSS_DSI_PHY_PLL_POST_DIVIDER_CONTROL) & BIT(5); - - pr_debug("bypass_lp_div mux mode = %s\n", - mux_mode ? "indirect" : "direct"); - mdss_pll_resource_enable(dsi_pll_res, false); - - return !!mux_mode; -} - -int ndiv_set_div(struct div_clk *clk, int div) -{ - int rc, reg_data; - struct mdss_pll_resources *dsi_pll_res = clk->priv; - - rc = mdss_pll_resource_enable(dsi_pll_res, true); - if (rc) { - pr_err("Failed to enable mdss dsi pll resources\n"); - return rc; - } - - reg_data = MDSS_PLL_REG_R(dsi_pll_res->pll_base, - MMSS_DSI_PHY_PLL_POST_DIVIDER_CONTROL); - MDSS_PLL_REG_W(dsi_pll_res->pll_base, - MMSS_DSI_PHY_PLL_POST_DIVIDER_CONTROL, - reg_data | div); - - pr_debug("POST_DIVIDER_CONTROL = 0x%x\n", - MDSS_PLL_REG_R(dsi_pll_res->pll_base, - MMSS_DSI_PHY_PLL_POST_DIVIDER_CONTROL)); - - mdss_pll_resource_enable(dsi_pll_res, false); - return rc; -} - -int shadow_ndiv_set_div(struct div_clk *clk, int div) -{ - struct mdss_pll_resources *dsi_pll_res = clk->priv; - - if (!dsi_pll_res->resource_enable) { - pr_err("PLL resources disabled. Dynamic fps invalid\n"); - return -EINVAL; - } - - pr_debug("%d div=%i\n", __LINE__, div); - - MDSS_DYN_PLL_REG_W(dsi_pll_res->dyn_pll_base, - MMSS_DSI_DYNAMIC_REFRESH_PLL_CTRL14, - MMSS_DSI_PHY_PLL_RESETSM_CNTRL3, - MMSS_DSI_PHY_PLL_POST_DIVIDER_CONTROL, - 0x07, (0xB | div)); - - return 0; -} - -int ndiv_get_div(struct div_clk *clk) -{ - int div = 0, rc; - struct mdss_pll_resources *dsi_pll_res = clk->priv; - - if (is_gdsc_disabled(dsi_pll_res)) - return 0; - - rc = mdss_pll_resource_enable(clk->priv, true); - if (rc) { - pr_err("Failed to enable mdss dsi pll resources\n"); - return rc; - } - - div = MDSS_PLL_REG_R(dsi_pll_res->pll_base, - MMSS_DSI_PHY_PLL_POST_DIVIDER_CONTROL) & 0x0F; - - mdss_pll_resource_enable(dsi_pll_res, false); - - return div; -} - -int fixed_hr_oclk2_set_div(struct div_clk *clk, int div) -{ - int rc; - struct mdss_pll_resources *dsi_pll_res = clk->priv; - - rc = mdss_pll_resource_enable(dsi_pll_res, true); - if (rc) { - pr_err("Failed to enable mdss dsi pll resources\n"); - return rc; - } - - MDSS_PLL_REG_W(dsi_pll_res->pll_base, - MMSS_DSI_PHY_PLL_HR_OCLK2_DIVIDER, - (div - 1)); - - mdss_pll_resource_enable(dsi_pll_res, false); - return rc; -} - -int shadow_fixed_hr_oclk2_set_div(struct div_clk *clk, int div) -{ - struct mdss_pll_resources *dsi_pll_res = clk->priv; - - if (!dsi_pll_res->resource_enable) { - pr_err("PLL resources disabled. Dynamic fps invalid\n"); - return -EINVAL; - } - pr_debug("%d div = %d\n", __LINE__, div); - - MDSS_DYN_PLL_REG_W(dsi_pll_res->dyn_pll_base, - MMSS_DSI_DYNAMIC_REFRESH_PLL_CTRL5, - MMSS_DSI_PHY_PLL_HR_OCLK2_DIVIDER, - MMSS_DSI_PHY_PLL_HR_OCLK2_DIVIDER, - (div - 1), (div - 1)); - - return 0; -} - -int fixed_hr_oclk2_get_div(struct div_clk *clk) -{ - int div = 0, rc; - struct mdss_pll_resources *dsi_pll_res = clk->priv; - - if (is_gdsc_disabled(dsi_pll_res)) - return 0; - - rc = mdss_pll_resource_enable(dsi_pll_res, true); - if (rc) { - pr_err("Failed to enable mdss dsi pll resources\n"); - return rc; - } - - div = MDSS_PLL_REG_R(dsi_pll_res->pll_base, - MMSS_DSI_PHY_PLL_HR_OCLK2_DIVIDER); - - mdss_pll_resource_enable(dsi_pll_res, false); - return div + 1; -} - -int hr_oclk3_set_div(struct div_clk *clk, int div) -{ - int rc; - struct mdss_pll_resources *dsi_pll_res = clk->priv; - - rc = mdss_pll_resource_enable(dsi_pll_res, true); - if (rc) { - pr_err("Failed to enable mdss dsi pll resources\n"); - return rc; - } - - pr_debug("%d div = %d\n", __LINE__, div); - MDSS_PLL_REG_W(dsi_pll_res->pll_base, - MMSS_DSI_PHY_PLL_HR_OCLK3_DIVIDER, - (div - 1)); - pr_debug("%s: HR_OCLK3_DIVIDER = 0x%x\n", __func__, - MDSS_PLL_REG_R(dsi_pll_res->pll_base, - MMSS_DSI_PHY_PLL_HR_OCLK3_DIVIDER)); - - mdss_pll_resource_enable(dsi_pll_res, false); - return rc; -} - -int shadow_hr_oclk3_set_div(struct div_clk *clk, int div) -{ - struct mdss_pll_resources *dsi_pll_res = clk->priv; - - if (!dsi_pll_res->resource_enable) { - pr_err("PLL resources disabled. Dynamic fps invalid\n"); - return -EINVAL; - } - - pr_debug("%d div = %d\n", __LINE__, div); - - MDSS_DYN_PLL_REG_W(dsi_pll_res->dyn_pll_base, - MMSS_DSI_DYNAMIC_REFRESH_PLL_CTRL6, - MMSS_DSI_PHY_PLL_HR_OCLK3_DIVIDER, - MMSS_DSI_PHY_PLL_HR_OCLK3_DIVIDER, - (div - 1), (div - 1)); - - return 0; -} - -int hr_oclk3_get_div(struct div_clk *clk) -{ - int div = 0, rc; - struct mdss_pll_resources *dsi_pll_res = clk->priv; - - if (is_gdsc_disabled(dsi_pll_res)) - return 0; - - rc = mdss_pll_resource_enable(dsi_pll_res, true); - if (rc) { - pr_err("Failed to enable mdss dsi pll resources\n"); - return rc; - } - - div = MDSS_PLL_REG_R(dsi_pll_res->pll_base, - MMSS_DSI_PHY_PLL_HR_OCLK3_DIVIDER); - - mdss_pll_resource_enable(dsi_pll_res, false); - return div + 1; -} - -static bool pll_20nm_is_pll_locked(struct mdss_pll_resources *dsi_pll_res) -{ - u32 status; - bool pll_locked; - - /* poll for PLL ready status */ - if (readl_poll_timeout_atomic((dsi_pll_res->pll_base + - MMSS_DSI_PHY_PLL_RESET_SM), - status, - ((status & BIT(5)) > 0), - DSI_PLL_POLL_DELAY_US, - DSI_PLL_POLL_TIMEOUT_US)) { - pr_debug("DSI PLL status=%x failed to Lock\n", status); - pll_locked = false; - } else if (readl_poll_timeout_atomic((dsi_pll_res->pll_base + - MMSS_DSI_PHY_PLL_RESET_SM), - status, - ((status & BIT(6)) > 0), - DSI_PLL_POLL_DELAY_US, - DSI_PLL_POLL_TIMEOUT_US)) { - pr_debug("DSI PLL status=%x PLl not ready\n", status); - pll_locked = false; - } else { - pll_locked = true; - } - - return pll_locked; -} - -void __dsi_pll_disable(void __iomem *pll_base) -{ - if (!pll_base) { - pr_err("Invalid pll base\n"); - return; - } - pr_debug("Disabling PHY PLL for PLL_BASE=%p\n", pll_base); - - MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_PLL_VCOTAIL_EN, 0x02); - MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_RESETSM_CNTRL3, 0x06); -} - -static void pll_20nm_config_powerdown(void __iomem *pll_base) -{ - if (!pll_base) { - pr_err("Invalid pll base.\n"); - return; - } - - MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_SYS_CLK_CTRL, 0x00); - MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_CMN_MODE, 0x01); - MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_PLL_VCOTAIL_EN, 0x82); - MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_BIAS_EN_CLKBUFLR_EN, 0x02); -} - -static int dsi_pll_enable(struct clk *c) -{ - int i, rc; - struct dsi_pll_vco_clk *vco = to_vco_clk(c); - struct mdss_pll_resources *dsi_pll_res = vco->priv; - - rc = mdss_pll_resource_enable(dsi_pll_res, true); - if (rc) { - pr_err("Failed to enable mdss dsi pll resources\n"); - return rc; - } - - /* Try all enable sequences until one succeeds */ - for (i = 0; i < vco->pll_en_seq_cnt; i++) { - rc = vco->pll_enable_seqs[i](dsi_pll_res); - pr_debug("DSI PLL %s after sequence #%d\n", - rc ? "unlocked" : "locked", i + 1); - if (!rc) - break; - } - /* Disable PLL1 to avoid current leakage while toggling MDSS GDSC */ - if (dsi_pll_res->pll_1_base) - pll_20nm_config_powerdown(dsi_pll_res->pll_1_base); - - if (rc) { - mdss_pll_resource_enable(dsi_pll_res, false); - pr_err("DSI PLL failed to lock\n"); - } - dsi_pll_res->pll_on = true; - - return rc; -} - -static void dsi_pll_disable(struct clk *c) -{ - struct dsi_pll_vco_clk *vco = to_vco_clk(c); - struct mdss_pll_resources *dsi_pll_res = vco->priv; - - if (!dsi_pll_res->pll_on && - mdss_pll_resource_enable(dsi_pll_res, true)) { - pr_err("Failed to enable mdss dsi pll resources\n"); - return; - } - - dsi_pll_res->handoff_resources = false; - - __dsi_pll_disable(dsi_pll_res->pll_base); - - /* Disable PLL1 to avoid current leakage while toggling MDSS GDSC */ - if (dsi_pll_res->pll_1_base) - pll_20nm_config_powerdown(dsi_pll_res->pll_1_base); - - pll_20nm_config_powerdown(dsi_pll_res->pll_base); - - mdss_pll_resource_enable(dsi_pll_res, false); - - dsi_pll_res->pll_on = false; - - pr_debug("DSI PLL Disabled\n"); -} - -static void pll_20nm_config_common_block_1(void __iomem *pll_base) -{ - MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_PLL_VCOTAIL_EN, 0x82); - MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_BIAS_EN_CLKBUFLR_EN, 0x2a); - MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_BIAS_EN_CLKBUFLR_EN, 0x2b); - MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_RESETSM_CNTRL3, 0x02); -} - -static void pll_20nm_config_common_block_2(void __iomem *pll_base) -{ - MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_SYS_CLK_CTRL, 0x40); - MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_IE_TRIM, 0x0F); - MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_IP_TRIM, 0x0F); - MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_PLL_PHSEL_CONTROL, 0x08); - MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_IPTAT_TRIM_VCCA_TX_SEL, 0x0E); - MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_PLL_BKG_KVCO_CAL_EN, 0x08); - MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_SYSCLK_EN_SEL_TXBAND, 0x4A); - MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_DIV_REF1, 0x00); - MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_DIV_REF2, 0x01); - MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_PLL_CNTRL, 0x07); - MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_KVCO_CAL_CNTRL, 0x1f); - MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_KVCO_COUNT1, 0x8A); - MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_VREF_CFG3, 0x10); - MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_SSC_EN_CENTER, 0x00); - MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_FAUX_EN, 0x0C); - MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_PLL_RXTXEPCLK_EN, 0x0a); - MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_LOW_POWER_RO_CONTROL, 0x0f); - MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_CMN_MODE, 0x00); -} - -static void pll_20nm_config_loop_bw(void __iomem *pll_base) -{ - MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_PLL_IP_SETI, 0x03); - MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_PLL_CP_SETI, 0x3F); - MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_PLL_IP_SETP, 0x03); - MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_PLL_CP_SETP, 0x1F); - MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_PLL_CRCTRL, 0x77); -} - -static void pll_20nm_vco_rate_calc(struct mdss_pll_vco_calc *vco_calc, - s64 vco_clk_rate, s64 ref_clk_rate) -{ - s64 multiplier = (1 << 20); - s64 duration = 1024, pll_comp_val; - s64 dec_start_multiple, dec_start; - s32 div_frac_start; - s64 dec_start1, dec_start2; - s32 div_frac_start1, div_frac_start2, div_frac_start3; - s64 pll_plllock_cmp1, pll_plllock_cmp2, pll_plllock_cmp3; - - memset(vco_calc, 0, sizeof(*vco_calc)); - pr_debug("vco_clk_rate=%lld ref_clk_rate=%lld\n", vco_clk_rate, - ref_clk_rate); - - dec_start_multiple = div_s64(vco_clk_rate * multiplier, - 2 * ref_clk_rate); - div_s64_rem(dec_start_multiple, - multiplier, &div_frac_start); - - dec_start = div_s64(dec_start_multiple, multiplier); - dec_start1 = (dec_start & 0x7f) | BIT(7); - dec_start2 = ((dec_start & 0x80) >> 7) | BIT(1); - div_frac_start1 = (div_frac_start & 0x7f) | BIT(7); - div_frac_start2 = ((div_frac_start >> 7) & 0x7f) | BIT(7); - div_frac_start3 = ((div_frac_start >> 14) & 0x3f) | BIT(6); - pll_comp_val = (div_s64(dec_start_multiple * 2 * duration, - 10 * multiplier)) - 1; - pll_plllock_cmp1 = pll_comp_val & 0xff; - pll_plllock_cmp2 = (pll_comp_val >> 8) & 0xff; - pll_plllock_cmp3 = (pll_comp_val >> 16) & 0xff; - - pr_debug("dec_start_multiple = 0x%llx\n", dec_start_multiple); - pr_debug("dec_start = 0x%llx, div_frac_start = 0x%x\n", - dec_start, div_frac_start); - pr_debug("dec_start1 = 0x%llx, dec_start2 = 0x%llx\n", - dec_start1, dec_start2); - pr_debug("div_frac_start1 = 0x%x, div_frac_start2 = 0x%x\n", - div_frac_start1, div_frac_start2); - pr_debug("div_frac_start3 = 0x%x\n", div_frac_start3); - pr_debug("pll_comp_val = 0x%llx\n", pll_comp_val); - pr_debug("pll_plllock_cmp1 = 0x%llx, pll_plllock_cmp2 =%llx\n", - pll_plllock_cmp1, pll_plllock_cmp2); - pr_debug("pll_plllock_cmp3 = 0x%llx\n", pll_plllock_cmp3); - - /* Assign to vco struct */ - vco_calc->div_frac_start1 = div_frac_start1; - vco_calc->div_frac_start2 = div_frac_start2; - vco_calc->div_frac_start3 = div_frac_start3; - vco_calc->dec_start1 = dec_start1; - vco_calc->dec_start2 = dec_start2; - vco_calc->pll_plllock_cmp1 = pll_plllock_cmp1; - vco_calc->pll_plllock_cmp2 = pll_plllock_cmp2; - vco_calc->pll_plllock_cmp3 = pll_plllock_cmp3; -} - -static void pll_20nm_config_vco_rate(void __iomem *pll_base, - struct mdss_pll_vco_calc *vco_calc) -{ - MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_DIV_FRAC_START1, - vco_calc->div_frac_start1); - MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_DIV_FRAC_START2, - vco_calc->div_frac_start2); - MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_DIV_FRAC_START3, - vco_calc->div_frac_start3); - MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_DEC_START1, - vco_calc->dec_start1); - MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_DEC_START2, - vco_calc->dec_start2); - MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_PLLLOCK_CMP1, - vco_calc->pll_plllock_cmp1); - MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_PLLLOCK_CMP2, - vco_calc->pll_plllock_cmp2); - MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_PLLLOCK_CMP3, - vco_calc->pll_plllock_cmp3); - MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_PLLLOCK_CMP_EN, 0x01); -} - -int pll_20nm_vco_set_rate(struct dsi_pll_vco_clk *vco, unsigned long rate) -{ - struct mdss_pll_resources *dsi_pll_res = vco->priv; - - dsi_pll_res->vco_current_rate = rate; - dsi_pll_res->vco_ref_clk_rate = vco->ref_clk_rate; - - return 0; -} - -int shadow_pll_20nm_vco_set_rate(struct dsi_pll_vco_clk *vco, - unsigned long rate) -{ - struct mdss_pll_resources *dsi_pll_res = vco->priv; - struct mdss_pll_vco_calc vco_calc; - s64 vco_clk_rate = rate; - u32 rem; - - if (!dsi_pll_res->resource_enable) { - pr_err("PLL resources disabled. Dynamic fps invalid\n"); - return -EINVAL; - } - - pr_debug("req vco set rate: %lld\n", vco_clk_rate); - - pll_20nm_override_trim_codes(dsi_pll_res); - - /* div fraction, start and comp calculations */ - pll_20nm_vco_rate_calc(&vco_calc, vco_clk_rate, - dsi_pll_res->vco_ref_clk_rate); - - MDSS_DYN_PLL_REG_W(dsi_pll_res->dyn_pll_base, - MMSS_DSI_DYNAMIC_REFRESH_PLL_CTRL0, - MMSS_DSI_PHY_PLL_POST_DIVIDER_CONTROL, - MMSS_DSI_PHY_PLL_PLLLOCK_CMP_EN, - 0xB1, 0); - MDSS_DYN_PLL_REG_W(dsi_pll_res->dyn_pll_base, - MMSS_DSI_DYNAMIC_REFRESH_PLL_CTRL1, - MMSS_DSI_PHY_PLL_PLLLOCK_CMP1, - MMSS_DSI_PHY_PLL_PLLLOCK_CMP2, - vco_calc.pll_plllock_cmp1, vco_calc.pll_plllock_cmp2); - MDSS_DYN_PLL_REG_W(dsi_pll_res->dyn_pll_base, - MMSS_DSI_DYNAMIC_REFRESH_PLL_CTRL2, - MMSS_DSI_PHY_PLL_PLLLOCK_CMP3, - MMSS_DSI_PHY_PLL_DEC_START1, - vco_calc.pll_plllock_cmp3, vco_calc.dec_start1); - MDSS_DYN_PLL_REG_W(dsi_pll_res->dyn_pll_base, - MMSS_DSI_DYNAMIC_REFRESH_PLL_CTRL3, - MMSS_DSI_PHY_PLL_DEC_START2, - MMSS_DSI_PHY_PLL_DIV_FRAC_START1, - vco_calc.dec_start2, vco_calc.div_frac_start1); - MDSS_DYN_PLL_REG_W(dsi_pll_res->dyn_pll_base, - MMSS_DSI_DYNAMIC_REFRESH_PLL_CTRL4, - MMSS_DSI_PHY_PLL_DIV_FRAC_START2, - MMSS_DSI_PHY_PLL_DIV_FRAC_START3, - vco_calc.div_frac_start2, vco_calc.div_frac_start3); - /* Method 2 - Auto PLL calibration */ - MDSS_DYN_PLL_REG_W(dsi_pll_res->dyn_pll_base, - MMSS_DSI_DYNAMIC_REFRESH_PLL_CTRL7, - MMSS_DSI_PHY_PLL_PLL_VCO_TUNE, - MMSS_DSI_PHY_PLL_PLLLOCK_CMP_EN, - 0, 0x0D); - MDSS_DYN_PLL_REG_W(dsi_pll_res->dyn_pll_base, - MMSS_DSI_DYNAMIC_REFRESH_PLL_CTRL8, - MMSS_DSI_PHY_PLL_POST_DIVIDER_CONTROL, - MMSS_DSI_PHY_PLL_RESETSM_CNTRL3, - 0xF0, 0x07); - - /* - * RESETSM_CTRL3 has to be set for 12 times (6 reg writes), - * Each register setting write 2 times, running in loop for 5 - * times (5 reg writes) and other two iterations are taken - * care (one above and other in shadow_bypass - */ - for (rem = 0; rem < 5; rem++) { - MDSS_DYN_PLL_REG_W(dsi_pll_res->dyn_pll_base, - MMSS_DSI_DYNAMIC_REFRESH_PLL_CTRL9 + (4 * rem), - MMSS_DSI_PHY_PLL_RESETSM_CNTRL3, - MMSS_DSI_PHY_PLL_RESETSM_CNTRL3, - 0x07, 0x07); - } - - MDSS_DYN_PLL_REG_W(dsi_pll_res->dyn_pll_base, - MMSS_DSI_DYNAMIC_REFRESH_PLL_CTRL15, - MMSS_DSI_PHY_PLL_RESETSM_CNTRL3, - MMSS_DSI_PHY_PLL_RESETSM_CNTRL3, - 0x03, 0x03); - - /* memory barrier */ - wmb(); - return 0; -} - -unsigned long pll_20nm_vco_get_rate(struct clk *c) -{ - u64 vco_rate, multiplier = (1 << 20); - s32 div_frac_start; - u32 dec_start; - struct dsi_pll_vco_clk *vco = to_vco_clk(c); - u64 ref_clk = vco->ref_clk_rate; - int rc; - struct mdss_pll_resources *dsi_pll_res = vco->priv; - - if (is_gdsc_disabled(dsi_pll_res)) - return 0; - - rc = mdss_pll_resource_enable(dsi_pll_res, true); - if (rc) { - pr_err("Failed to enable mdss dsi pll resources\n"); - return rc; - } - - dec_start = (MDSS_PLL_REG_R(dsi_pll_res->pll_base, - MMSS_DSI_PHY_PLL_DEC_START2) & BIT(0)) << 7; - dec_start |= (MDSS_PLL_REG_R(dsi_pll_res->pll_base, - MMSS_DSI_PHY_PLL_DEC_START1) & 0x7f); - pr_debug("dec_start = 0x%x\n", dec_start); - - div_frac_start = (MDSS_PLL_REG_R(dsi_pll_res->pll_base, - MMSS_DSI_PHY_PLL_DIV_FRAC_START3) & 0x3f) << 14; - div_frac_start |= (MDSS_PLL_REG_R(dsi_pll_res->pll_base, - MMSS_DSI_PHY_PLL_DIV_FRAC_START2) & 0x7f) << 7; - div_frac_start |= MDSS_PLL_REG_R(dsi_pll_res->pll_base, - MMSS_DSI_PHY_PLL_DIV_FRAC_START1) & 0x7f; - pr_debug("div_frac_start = 0x%x\n", div_frac_start); - - vco_rate = ref_clk * 2 * dec_start; - vco_rate += ((ref_clk * 2 * div_frac_start) / multiplier); - pr_debug("returning vco rate = %lu\n", (unsigned long)vco_rate); - - mdss_pll_resource_enable(dsi_pll_res, false); - - return (unsigned long)vco_rate; -} -long pll_20nm_vco_round_rate(struct clk *c, unsigned long rate) -{ - unsigned long rrate = rate; - struct dsi_pll_vco_clk *vco = to_vco_clk(c); - - if (rate < vco->min_rate) - rrate = vco->min_rate; - if (rate > vco->max_rate) - rrate = vco->max_rate; - - return rrate; -} - -enum handoff pll_20nm_vco_handoff(struct clk *c) -{ - int rc; - enum handoff ret = HANDOFF_DISABLED_CLK; - struct dsi_pll_vco_clk *vco = to_vco_clk(c); - struct mdss_pll_resources *dsi_pll_res = vco->priv; - - if (is_gdsc_disabled(dsi_pll_res)) - return HANDOFF_DISABLED_CLK; - - rc = mdss_pll_resource_enable(dsi_pll_res, true); - if (rc) { - pr_err("Failed to enable mdss dsi pll resources\n"); - return ret; - } - - if (pll_20nm_is_pll_locked(dsi_pll_res)) { - dsi_pll_res->handoff_resources = true; - dsi_pll_res->pll_on = true; - c->rate = pll_20nm_vco_get_rate(c); - ret = HANDOFF_ENABLED_CLK; - dsi_pll_res->vco_locking_rate = c->rate; - dsi_pll_res->is_init_locked = true; - pll_20nm_cache_trim_codes(dsi_pll_res); - pr_debug("handoff vco_locking_rate=%llu\n", - dsi_pll_res->vco_locking_rate); - } else { - mdss_pll_resource_enable(dsi_pll_res, false); - dsi_pll_res->vco_locking_rate = 0; - dsi_pll_res->is_init_locked = false; - } - - return ret; -} - -int pll_20nm_vco_prepare(struct clk *c) -{ - int rc = 0; - struct dsi_pll_vco_clk *vco = to_vco_clk(c); - struct mdss_pll_resources *dsi_pll_res = vco->priv; - - if (!dsi_pll_res) { - pr_err("Dsi pll resources are not available\n"); - return -EINVAL; - } - - if ((dsi_pll_res->vco_cached_rate != 0) - && (dsi_pll_res->vco_cached_rate == c->rate)) { - rc = c->ops->set_rate(c, dsi_pll_res->vco_cached_rate); - if (rc) { - pr_err("vco_set_rate failed. rc=%d\n", rc); - goto error; - } - } - - rc = dsi_pll_enable(c); - -error: - return rc; -} - -void pll_20nm_vco_unprepare(struct clk *c) -{ - struct dsi_pll_vco_clk *vco = to_vco_clk(c); - struct mdss_pll_resources *dsi_pll_res = vco->priv; - - if (!dsi_pll_res) { - pr_err("Dsi pll resources are not available\n"); - return; - } - - dsi_pll_res->vco_cached_rate = c->rate; - dsi_pll_disable(c); -} - -static void pll_20nm_config_resetsm(void __iomem *pll_base) -{ - MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_RESETSM_CNTRL, 0x24); - MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_RESETSM_CNTRL2, 0x07); -} - -static void pll_20nm_config_vco_start(void __iomem *pll_base) -{ - - MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_PLL_VCOTAIL_EN, 0x03); - MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_RESETSM_CNTRL3, 0x02); - udelay(10); - MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_RESETSM_CNTRL3, 0x03); -} - -static void pll_20nm_config_bypass_cal(void __iomem *pll_base) -{ - MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_RESETSM_CNTRL, 0xac); - MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_PLL_BKG_KVCO_CAL_EN, 0x28); -} - -static int pll_20nm_vco_relock(struct mdss_pll_resources *dsi_pll_res) -{ - int rc = 0; - - pll_20nm_override_trim_codes(dsi_pll_res); - pll_20nm_config_bypass_cal(dsi_pll_res->pll_base); - pll_20nm_config_vco_start(dsi_pll_res->pll_base); - - if (!pll_20nm_is_pll_locked(dsi_pll_res)) { - pr_err("DSI PLL re-lock failed\n"); - rc = -EINVAL; - } - - return rc; -} - -static int pll_20nm_vco_init_lock(struct mdss_pll_resources *dsi_pll_res) -{ - int rc = 0; - - pll_20nm_config_resetsm(dsi_pll_res->pll_base); - pll_20nm_config_vco_start(dsi_pll_res->pll_base); - - if (!pll_20nm_is_pll_locked(dsi_pll_res)) { - pr_err("DSI PLL init lock failed\n"); - rc = -EINVAL; - goto init_lock_err; - } - - pll_20nm_cache_trim_codes(dsi_pll_res); - -init_lock_err: - return rc; -} - -int pll_20nm_vco_enable_seq(struct mdss_pll_resources *dsi_pll_res) -{ - int rc = 0; - struct mdss_pll_vco_calc vco_calc; - - if (!dsi_pll_res) { - pr_err("Invalid PLL resources\n"); - return -EINVAL; - } - - pll_20nm_config_common_block_1(dsi_pll_res->pll_1_base); - pll_20nm_config_common_block_1(dsi_pll_res->pll_base); - pll_20nm_config_common_block_2(dsi_pll_res->pll_base); - pll_20nm_config_loop_bw(dsi_pll_res->pll_base); - - pll_20nm_vco_rate_calc(&vco_calc, dsi_pll_res->vco_current_rate, - dsi_pll_res->vco_ref_clk_rate); - pll_20nm_config_vco_rate(dsi_pll_res->pll_base, &vco_calc); - - pr_debug("init lock=%d prev vco_rate=%llu, new vco_rate=%llu\n", - dsi_pll_res->is_init_locked, dsi_pll_res->vco_locking_rate, - dsi_pll_res->vco_current_rate); - /* - * Run auto-lock sequence if it is either bootup initial - * locking or when the vco rate is changed. Otherwise, just - * use stored codes and bypass caliberation. - */ - if (!dsi_pll_res->is_init_locked || (dsi_pll_res->vco_locking_rate != - dsi_pll_res->vco_current_rate)) { - rc = pll_20nm_vco_init_lock(dsi_pll_res); - dsi_pll_res->is_init_locked = (rc) ? false : true; - } else { - rc = pll_20nm_vco_relock(dsi_pll_res); - } - - dsi_pll_res->vco_locking_rate = (rc) ? 0 : - dsi_pll_res->vco_current_rate; - - return rc; -} diff --git a/pll/dsi_pll.h b/pll/dsi_pll.h deleted file mode 100644 index 35aa81494120..000000000000 --- a/pll/dsi_pll.h +++ /dev/null @@ -1,52 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. - */ - -#ifndef __MDSS_DSI_PLL_H -#define __MDSS_DSI_PLL_H - -#include -#include "pll_drv.h" -#define MAX_DSI_PLL_EN_SEQS 10 - -/* Register offsets for 20nm PHY PLL */ -#define MMSS_DSI_PHY_PLL_PLL_CNTRL (0x0014) -#define MMSS_DSI_PHY_PLL_PLL_BKG_KVCO_CAL_EN (0x002C) -#define MMSS_DSI_PHY_PLL_PLLLOCK_CMP_EN (0x009C) - -struct lpfr_cfg { - unsigned long vco_rate; - u32 r; -}; - -struct dsi_pll_vco_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 mdss_pll_resources *dsi_pll_Res); -}; - -int dsi_pll_clock_register_10nm(struct platform_device *pdev, - struct mdss_pll_resources *pll_res); - -int dsi_pll_clock_register_7nm(struct platform_device *pdev, - struct mdss_pll_resources *pll_res); -int dsi_pll_clock_register_28lpm(struct platform_device *pdev, - struct mdss_pll_resources *pll_res); - -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); -} - -int dsi_pll_clock_register_14nm(struct platform_device *pdev, - struct mdss_pll_resources *pll_res); -#endif diff --git a/pll/dsi_pll_10nm.c b/pll/dsi_pll_10nm.c deleted file mode 100644 index 5f4140dccc3b..000000000000 --- a/pll/dsi_pll_10nm.c +++ /dev/null @@ -1,2168 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. - */ - -#define pr_fmt(fmt) "%s: " fmt, __func__ - -#include -#include -#include -#include -#include "dsi_pll.h" -#include "pll_drv.h" -#include -#define CREATE_TRACE_POINTS -#include "pll_trace.h" - -#define VCO_DELAY_USEC 1 - -#define MHZ_250 250000000UL -#define MHZ_500 500000000UL -#define MHZ_1000 1000000000UL -#define MHZ_1100 1100000000UL -#define MHZ_1900 1900000000UL -#define MHZ_3000 3000000000UL - -/* Register Offsets from PLL base address */ -#define PLL_ANALOG_CONTROLS_ONE 0x000 -#define PLL_ANALOG_CONTROLS_TWO 0x004 -#define PLL_INT_LOOP_SETTINGS 0x008 -#define PLL_INT_LOOP_SETTINGS_TWO 0x00c -#define PLL_ANALOG_CONTROLS_THREE 0x010 -#define PLL_ANALOG_CONTROLS_FOUR 0x014 -#define PLL_INT_LOOP_CONTROLS 0x018 -#define PLL_DSM_DIVIDER 0x01c -#define PLL_FEEDBACK_DIVIDER 0x020 -#define PLL_SYSTEM_MUXES 0x024 -#define PLL_FREQ_UPDATE_CONTROL_OVERRIDES 0x028 -#define PLL_CMODE 0x02c -#define PLL_CALIBRATION_SETTINGS 0x030 -#define PLL_BAND_SEL_CAL_TIMER_LOW 0x034 -#define PLL_BAND_SEL_CAL_TIMER_HIGH 0x038 -#define PLL_BAND_SEL_CAL_SETTINGS 0x03c -#define PLL_BAND_SEL_MIN 0x040 -#define PLL_BAND_SEL_MAX 0x044 -#define PLL_BAND_SEL_PFILT 0x048 -#define PLL_BAND_SEL_IFILT 0x04c -#define PLL_BAND_SEL_CAL_SETTINGS_TWO 0x050 -#define PLL_BAND_SEL_CAL_SETTINGS_THREE 0x054 -#define PLL_BAND_SEL_CAL_SETTINGS_FOUR 0x058 -#define PLL_BAND_SEL_ICODE_HIGH 0x05c -#define PLL_BAND_SEL_ICODE_LOW 0x060 -#define PLL_FREQ_DETECT_SETTINGS_ONE 0x064 -#define PLL_PFILT 0x07c -#define PLL_IFILT 0x080 -#define PLL_GAIN 0x084 -#define PLL_ICODE_LOW 0x088 -#define PLL_ICODE_HIGH 0x08c -#define PLL_LOCKDET 0x090 -#define PLL_OUTDIV 0x094 -#define PLL_FASTLOCK_CONTROL 0x098 -#define PLL_PASS_OUT_OVERRIDE_ONE 0x09c -#define PLL_PASS_OUT_OVERRIDE_TWO 0x0a0 -#define PLL_CORE_OVERRIDE 0x0a4 -#define PLL_CORE_INPUT_OVERRIDE 0x0a8 -#define PLL_RATE_CHANGE 0x0ac -#define PLL_PLL_DIGITAL_TIMERS 0x0b0 -#define PLL_PLL_DIGITAL_TIMERS_TWO 0x0b4 -#define PLL_DEC_FRAC_MUXES 0x0c8 -#define PLL_DECIMAL_DIV_START_1 0x0cc -#define PLL_FRAC_DIV_START_LOW_1 0x0d0 -#define PLL_FRAC_DIV_START_MID_1 0x0d4 -#define PLL_FRAC_DIV_START_HIGH_1 0x0d8 -#define PLL_MASH_CONTROL 0x0ec -#define PLL_SSC_MUX_CONTROL 0x108 -#define PLL_SSC_STEPSIZE_LOW_1 0x10c -#define PLL_SSC_STEPSIZE_HIGH_1 0x110 -#define PLL_SSC_DIV_PER_LOW_1 0x114 -#define PLL_SSC_DIV_PER_HIGH_1 0x118 -#define PLL_SSC_DIV_ADJPER_LOW_1 0x11c -#define PLL_SSC_DIV_ADJPER_HIGH_1 0x120 -#define PLL_SSC_CONTROL 0x13c -#define PLL_PLL_OUTDIV_RATE 0x140 -#define PLL_PLL_LOCKDET_RATE_1 0x144 -#define PLL_PLL_PROP_GAIN_RATE_1 0x14c -#define PLL_PLL_BAND_SET_RATE_1 0x154 -#define PLL_PLL_INT_GAIN_IFILT_BAND_1 0x15c -#define PLL_PLL_FL_INT_GAIN_PFILT_BAND_1 0x164 -#define PLL_FASTLOCK_EN_BAND 0x16c -#define PLL_FREQ_TUNE_ACCUM_INIT_LOW 0x170 -#define PLL_FREQ_TUNE_ACCUM_INIT_MID 0x174 -#define PLL_FREQ_TUNE_ACCUM_INIT_HIGH 0x178 -#define PLL_FREQ_TUNE_ACCUM_INIT_MUX 0x17c -#define PLL_PLL_LOCK_OVERRIDE 0x180 -#define PLL_PLL_LOCK_DELAY 0x184 -#define PLL_PLL_LOCK_MIN_DELAY 0x188 -#define PLL_CLOCK_INVERTERS 0x18c -#define PLL_SPARE_AND_JPC_OVERRIDES 0x190 -#define PLL_BIAS_CONTROL_1 0x194 -#define PLL_BIAS_CONTROL_2 0x198 -#define PLL_ALOG_OBSV_BUS_CTRL_1 0x19c -#define PLL_COMMON_STATUS_ONE 0x1a0 - -/* Register Offsets from PHY base address */ -#define PHY_CMN_CLK_CFG0 0x010 -#define PHY_CMN_CLK_CFG1 0x014 -#define PHY_CMN_RBUF_CTRL 0x01c -#define PHY_CMN_PLL_CNTRL 0x038 -#define PHY_CMN_CTRL_0 0x024 -#define PHY_CMN_CTRL_2 0x02c - -/* 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 (0x600) -enum { - DSI_PLL_0, - DSI_PLL_1, - DSI_PLL_MAX -}; - -struct dsi_pll_regs { - u32 pll_prop_gain_rate; - u32 pll_lockdet_rate; - u32 decimal_div_start; - u32 frac_div_start_low; - u32 frac_div_start_mid; - u32 frac_div_start_high; - u32 pll_clock_inverters; - u32 ssc_stepsize_low; - u32 ssc_stepsize_high; - u32 ssc_div_per_low; - u32 ssc_div_per_high; - u32 ssc_adjper_low; - u32 ssc_adjper_high; - u32 ssc_control; -}; - -struct dsi_pll_config { - u32 ref_freq; - bool div_override; - u32 output_div; - bool ignore_frac; - bool disable_prescaler; - bool enable_ssc; - bool ssc_center; - u32 dec_bits; - u32 frac_bits; - u32 lock_timer; - u32 ssc_freq; - u32 ssc_offset; - u32 ssc_adj_per; - u32 thresh_cycles; - u32 refclk_cycles; -}; - -struct dsi_pll_10nm { - struct mdss_pll_resources *rsc; - struct dsi_pll_config pll_configuration; - struct dsi_pll_regs reg_setup; -}; - -static inline int pll_reg_read(void *context, unsigned int reg, - unsigned int *val) -{ - int rc = 0; - struct mdss_pll_resources *rsc = context; - - rc = mdss_pll_resource_enable(rsc, true); - if (rc) { - pr_err("Failed to enable dsi pll resources, rc=%d\n", rc); - return rc; - } - - *val = MDSS_PLL_REG_R(rsc->pll_base, reg); - (void)mdss_pll_resource_enable(rsc, false); - - return rc; -} - -static inline int pll_reg_write(void *context, unsigned int reg, - unsigned int val) -{ - int rc = 0; - struct mdss_pll_resources *rsc = context; - - rc = mdss_pll_resource_enable(rsc, true); - if (rc) { - pr_err("Failed to enable dsi pll resources, rc=%d\n", rc); - return rc; - } - - MDSS_PLL_REG_W(rsc->pll_base, reg, val); - (void)mdss_pll_resource_enable(rsc, false); - - return rc; -} - -static inline int phy_reg_read(void *context, unsigned int reg, - unsigned int *val) -{ - int rc = 0; - struct mdss_pll_resources *rsc = context; - - rc = mdss_pll_resource_enable(rsc, true); - if (rc) { - pr_err("Failed to enable dsi pll resources, rc=%d\n", rc); - return rc; - } - - *val = MDSS_PLL_REG_R(rsc->phy_base, reg); - (void)mdss_pll_resource_enable(rsc, false); - - return rc; -} - -static inline int phy_reg_write(void *context, unsigned int reg, - unsigned int val) -{ - int rc = 0; - struct mdss_pll_resources *rsc = context; - - rc = mdss_pll_resource_enable(rsc, true); - if (rc) { - pr_err("Failed to enable dsi pll resources, rc=%d\n", rc); - return rc; - } - - MDSS_PLL_REG_W(rsc->phy_base, reg, val); - (void)mdss_pll_resource_enable(rsc, false); - - return rc; -} - -static inline int phy_reg_update_bits_sub(struct mdss_pll_resources *rsc, - unsigned int reg, unsigned int mask, unsigned int val) -{ - u32 reg_val; - - reg_val = MDSS_PLL_REG_R(rsc->phy_base, reg); - reg_val &= ~mask; - reg_val |= (val & mask); - MDSS_PLL_REG_W(rsc->phy_base, reg, reg_val); - - return 0; -} - -static inline int phy_reg_update_bits(void *context, unsigned int reg, - unsigned int mask, unsigned int val) -{ - int rc = 0; - struct mdss_pll_resources *rsc = context; - - rc = mdss_pll_resource_enable(rsc, true); - if (rc) { - pr_err("Failed to enable dsi pll resources, rc=%d\n", rc); - return rc; - } - - rc = phy_reg_update_bits_sub(rsc, reg, mask, val); - if (!rc && rsc->slave) - rc = phy_reg_update_bits_sub(rsc->slave, reg, mask, val); - (void)mdss_pll_resource_enable(rsc, false); - - return rc; -} - -static inline int pclk_mux_read_sel(void *context, unsigned int reg, - unsigned int *val) -{ - int rc = 0; - struct mdss_pll_resources *rsc = context; - - rc = mdss_pll_resource_enable(rsc, true); - if (rc) - pr_err("Failed to enable dsi pll resources, rc=%d\n", rc); - else - *val = (MDSS_PLL_REG_R(rsc->phy_base, reg) & 0x3); - - (void)mdss_pll_resource_enable(rsc, false); - return rc; -} - - -static inline int pclk_mux_write_sel_sub(struct mdss_pll_resources *rsc, - unsigned int reg, unsigned int val) -{ - u32 reg_val; - - reg_val = MDSS_PLL_REG_R(rsc->phy_base, reg); - reg_val &= ~0x03; - reg_val |= val; - - MDSS_PLL_REG_W(rsc->phy_base, reg, reg_val); - - return 0; -} - -static inline int pclk_mux_write_sel(void *context, unsigned int reg, - unsigned int val) -{ - int rc = 0; - struct mdss_pll_resources *rsc = context; - - rc = mdss_pll_resource_enable(rsc, true); - if (rc) { - pr_err("Failed to enable dsi pll resources, rc=%d\n", rc); - return rc; - } - - rc = pclk_mux_write_sel_sub(rsc, reg, val); - if (!rc && rsc->slave) - rc = pclk_mux_write_sel_sub(rsc->slave, reg, val); - - (void)mdss_pll_resource_enable(rsc, false); - - /* - * cache the current parent index for cases where parent - * is not changing but rate is changing. In that case - * clock framework won't call parent_set and hence dsiclk_sel - * bit won't be programmed. e.g. dfps update use case. - */ - rsc->cached_cfg1 = val; - - return rc; -} - -static struct mdss_pll_resources *pll_rsc_db[DSI_PLL_MAX]; -static struct dsi_pll_10nm plls[DSI_PLL_MAX]; - -static void dsi_pll_config_slave(struct mdss_pll_resources *rsc) -{ - u32 reg; - struct mdss_pll_resources *orsc = pll_rsc_db[DSI_PLL_1]; - - if (!rsc) - return; - - /* Only DSI PLL0 can act as a master */ - if (rsc->index != DSI_PLL_0) - return; - - /* default configuration: source is either internal or ref clock */ - rsc->slave = NULL; - - if (!orsc) { - pr_warn("slave PLL unavilable, assuming standalone config\n"); - return; - } - - /* check to see if the source of DSI1 PLL bitclk is set to external */ - reg = MDSS_PLL_REG_R(orsc->phy_base, PHY_CMN_CLK_CFG1); - reg &= (BIT(2) | BIT(3)); - if (reg == 0x04) - rsc->slave = pll_rsc_db[DSI_PLL_1]; /* external source */ - - pr_debug("Slave PLL %s\n", rsc->slave ? "configured" : "absent"); -} - -static void dsi_pll_setup_config(struct dsi_pll_10nm *pll, - struct mdss_pll_resources *rsc) -{ - struct dsi_pll_config *config = &pll->pll_configuration; - - config->ref_freq = 19200000; - config->output_div = 1; - config->dec_bits = 8; - config->frac_bits = 18; - config->lock_timer = 64; - config->ssc_freq = 31500; - config->ssc_offset = 5000; - config->ssc_adj_per = 2; - config->thresh_cycles = 32; - config->refclk_cycles = 256; - - config->div_override = false; - config->ignore_frac = false; - config->disable_prescaler = false; - config->enable_ssc = rsc->ssc_en; - config->ssc_center = rsc->ssc_center; - - if (config->enable_ssc) { - if (rsc->ssc_freq) - config->ssc_freq = rsc->ssc_freq; - if (rsc->ssc_ppm) - config->ssc_offset = rsc->ssc_ppm; - } - - dsi_pll_config_slave(rsc); -} - -static void dsi_pll_calc_dec_frac(struct dsi_pll_10nm *pll, - struct mdss_pll_resources *rsc) -{ - struct dsi_pll_config *config = &pll->pll_configuration; - struct dsi_pll_regs *regs = &pll->reg_setup; - u64 fref = rsc->vco_ref_clk_rate; - u64 pll_freq; - u64 divider; - u64 dec, dec_multiple; - u32 frac; - u64 multiplier; - - pll_freq = rsc->vco_current_rate; - - if (config->disable_prescaler) - divider = fref; - else - divider = fref * 2; - - multiplier = 1 << config->frac_bits; - dec_multiple = div_u64(pll_freq * multiplier, divider); - div_u64_rem(dec_multiple, multiplier, &frac); - - dec = div_u64(dec_multiple, multiplier); - - if (pll_freq <= MHZ_1900) - regs->pll_prop_gain_rate = 8; - else if (pll_freq <= MHZ_3000) - regs->pll_prop_gain_rate = 10; - else - regs->pll_prop_gain_rate = 12; - if (pll_freq < MHZ_1100) - regs->pll_clock_inverters = 8; - else - regs->pll_clock_inverters = 0; - - regs->pll_lockdet_rate = config->lock_timer; - regs->decimal_div_start = dec; - regs->frac_div_start_low = (frac & 0xff); - regs->frac_div_start_mid = (frac & 0xff00) >> 8; - regs->frac_div_start_high = (frac & 0x30000) >> 16; -} - -static void dsi_pll_calc_ssc(struct dsi_pll_10nm *pll, - struct mdss_pll_resources *rsc) -{ - struct dsi_pll_config *config = &pll->pll_configuration; - struct dsi_pll_regs *regs = &pll->reg_setup; - u32 ssc_per; - u32 ssc_mod; - u64 ssc_step_size; - u64 frac; - - if (!config->enable_ssc) { - pr_debug("SSC not enabled\n"); - return; - } - - ssc_per = DIV_ROUND_CLOSEST(config->ref_freq, config->ssc_freq) / 2 - 1; - ssc_mod = (ssc_per + 1) % (config->ssc_adj_per + 1); - ssc_per -= ssc_mod; - - frac = regs->frac_div_start_low | - (regs->frac_div_start_mid << 8) | - (regs->frac_div_start_high << 16); - ssc_step_size = regs->decimal_div_start; - ssc_step_size *= (1 << config->frac_bits); - ssc_step_size += frac; - ssc_step_size *= config->ssc_offset; - ssc_step_size *= (config->ssc_adj_per + 1); - ssc_step_size = div_u64(ssc_step_size, (ssc_per + 1)); - ssc_step_size = DIV_ROUND_CLOSEST_ULL(ssc_step_size, 1000000); - - regs->ssc_div_per_low = ssc_per & 0xFF; - regs->ssc_div_per_high = (ssc_per & 0xFF00) >> 8; - regs->ssc_stepsize_low = (u32)(ssc_step_size & 0xFF); - regs->ssc_stepsize_high = (u32)((ssc_step_size & 0xFF00) >> 8); - regs->ssc_adjper_low = config->ssc_adj_per & 0xFF; - regs->ssc_adjper_high = (config->ssc_adj_per & 0xFF00) >> 8; - - regs->ssc_control = config->ssc_center ? SSC_CENTER : 0; - - pr_debug("SCC: Dec:%d, frac:%llu, frac_bits:%d\n", - regs->decimal_div_start, frac, config->frac_bits); - pr_debug("SSC: div_per:0x%X, stepsize:0x%X, adjper:0x%X\n", - ssc_per, (u32)ssc_step_size, config->ssc_adj_per); -} - -static void dsi_pll_ssc_commit(struct dsi_pll_10nm *pll, - struct mdss_pll_resources *rsc) -{ - void __iomem *pll_base = rsc->pll_base; - struct dsi_pll_regs *regs = &pll->reg_setup; - - if (pll->pll_configuration.enable_ssc) { - pr_debug("SSC is enabled\n"); - - MDSS_PLL_REG_W(pll_base, PLL_SSC_STEPSIZE_LOW_1, - regs->ssc_stepsize_low); - MDSS_PLL_REG_W(pll_base, PLL_SSC_STEPSIZE_HIGH_1, - regs->ssc_stepsize_high); - MDSS_PLL_REG_W(pll_base, PLL_SSC_DIV_PER_LOW_1, - regs->ssc_div_per_low); - MDSS_PLL_REG_W(pll_base, PLL_SSC_DIV_PER_HIGH_1, - regs->ssc_div_per_high); - MDSS_PLL_REG_W(pll_base, PLL_SSC_DIV_ADJPER_LOW_1, - regs->ssc_adjper_low); - MDSS_PLL_REG_W(pll_base, PLL_SSC_DIV_ADJPER_HIGH_1, - regs->ssc_adjper_high); - MDSS_PLL_REG_W(pll_base, PLL_SSC_CONTROL, - SSC_EN | regs->ssc_control); - } -} - -static void dsi_pll_config_hzindep_reg(struct dsi_pll_10nm *pll, - struct mdss_pll_resources *rsc) -{ - void __iomem *pll_base = rsc->pll_base; - - MDSS_PLL_REG_W(pll_base, PLL_ANALOG_CONTROLS_ONE, 0x80); - MDSS_PLL_REG_W(pll_base, PLL_ANALOG_CONTROLS_TWO, 0x03); - MDSS_PLL_REG_W(pll_base, PLL_ANALOG_CONTROLS_THREE, 0x00); - MDSS_PLL_REG_W(pll_base, PLL_DSM_DIVIDER, 0x00); - MDSS_PLL_REG_W(pll_base, PLL_FEEDBACK_DIVIDER, 0x4e); - MDSS_PLL_REG_W(pll_base, PLL_CALIBRATION_SETTINGS, 0x40); - MDSS_PLL_REG_W(pll_base, PLL_BAND_SEL_CAL_SETTINGS_THREE, 0xba); - MDSS_PLL_REG_W(pll_base, PLL_FREQ_DETECT_SETTINGS_ONE, 0x0c); - MDSS_PLL_REG_W(pll_base, PLL_OUTDIV, 0x00); - MDSS_PLL_REG_W(pll_base, PLL_CORE_OVERRIDE, 0x00); - MDSS_PLL_REG_W(pll_base, PLL_PLL_DIGITAL_TIMERS_TWO, 0x08); - MDSS_PLL_REG_W(pll_base, PLL_PLL_PROP_GAIN_RATE_1, 0x08); - MDSS_PLL_REG_W(pll_base, PLL_PLL_BAND_SET_RATE_1, 0xc0); - MDSS_PLL_REG_W(pll_base, PLL_PLL_INT_GAIN_IFILT_BAND_1, 0xfa); - MDSS_PLL_REG_W(pll_base, PLL_PLL_FL_INT_GAIN_PFILT_BAND_1, 0x4c); - MDSS_PLL_REG_W(pll_base, PLL_PLL_LOCK_OVERRIDE, 0x80); - MDSS_PLL_REG_W(pll_base, PLL_PFILT, 0x29); - MDSS_PLL_REG_W(pll_base, PLL_IFILT, 0x3f); -} - -static void dsi_pll_init_val(struct mdss_pll_resources *rsc) -{ - void __iomem *pll_base = rsc->pll_base; - - MDSS_PLL_REG_W(pll_base, PLL_CORE_INPUT_OVERRIDE, 0x10); - MDSS_PLL_REG_W(pll_base, PLL_INT_LOOP_SETTINGS, 0x3f); - MDSS_PLL_REG_W(pll_base, PLL_INT_LOOP_SETTINGS_TWO, 0x0); - MDSS_PLL_REG_W(pll_base, PLL_ANALOG_CONTROLS_FOUR, 0x0); - MDSS_PLL_REG_W(pll_base, PLL_INT_LOOP_CONTROLS, 0x80); - MDSS_PLL_REG_W(pll_base, PLL_FREQ_UPDATE_CONTROL_OVERRIDES, 0x0); - MDSS_PLL_REG_W(pll_base, PLL_BAND_SEL_CAL_TIMER_LOW, 0x0); - MDSS_PLL_REG_W(pll_base, PLL_BAND_SEL_CAL_TIMER_HIGH, 0x02); - MDSS_PLL_REG_W(pll_base, PLL_BAND_SEL_CAL_SETTINGS, 0x82); - MDSS_PLL_REG_W(pll_base, PLL_BAND_SEL_MIN, 0x00); - MDSS_PLL_REG_W(pll_base, PLL_BAND_SEL_MAX, 0xff); - MDSS_PLL_REG_W(pll_base, PLL_BAND_SEL_PFILT, 0x00); - MDSS_PLL_REG_W(pll_base, PLL_BAND_SEL_IFILT, 0x00); - MDSS_PLL_REG_W(pll_base, PLL_BAND_SEL_CAL_SETTINGS_TWO, 0x25); - MDSS_PLL_REG_W(pll_base, PLL_BAND_SEL_CAL_SETTINGS_FOUR, 0x4f); - MDSS_PLL_REG_W(pll_base, PLL_BAND_SEL_ICODE_HIGH, 0x0a); - MDSS_PLL_REG_W(pll_base, PLL_BAND_SEL_ICODE_LOW, 0x0); - MDSS_PLL_REG_W(pll_base, PLL_GAIN, 0x42); - MDSS_PLL_REG_W(pll_base, PLL_ICODE_LOW, 0x00); - MDSS_PLL_REG_W(pll_base, PLL_ICODE_HIGH, 0x00); - MDSS_PLL_REG_W(pll_base, PLL_LOCKDET, 0x30); - MDSS_PLL_REG_W(pll_base, PLL_FASTLOCK_CONTROL, 0x04); - MDSS_PLL_REG_W(pll_base, PLL_PASS_OUT_OVERRIDE_ONE, 0x00); - MDSS_PLL_REG_W(pll_base, PLL_PASS_OUT_OVERRIDE_TWO, 0x00); - MDSS_PLL_REG_W(pll_base, PLL_RATE_CHANGE, 0x01); - MDSS_PLL_REG_W(pll_base, PLL_PLL_DIGITAL_TIMERS, 0x08); - MDSS_PLL_REG_W(pll_base, PLL_DEC_FRAC_MUXES, 0x00); - MDSS_PLL_REG_W(pll_base, PLL_MASH_CONTROL, 0x03); - MDSS_PLL_REG_W(pll_base, PLL_SSC_MUX_CONTROL, 0x0); - MDSS_PLL_REG_W(pll_base, PLL_SSC_CONTROL, 0x0); - MDSS_PLL_REG_W(pll_base, PLL_FASTLOCK_EN_BAND, 0x03); - MDSS_PLL_REG_W(pll_base, PLL_FREQ_TUNE_ACCUM_INIT_MUX, 0x0); - MDSS_PLL_REG_W(pll_base, PLL_PLL_LOCK_MIN_DELAY, 0x19); - MDSS_PLL_REG_W(pll_base, PLL_SPARE_AND_JPC_OVERRIDES, 0x0); - MDSS_PLL_REG_W(pll_base, PLL_BIAS_CONTROL_1, 0x40); - MDSS_PLL_REG_W(pll_base, PLL_BIAS_CONTROL_2, 0x20); - MDSS_PLL_REG_W(pll_base, PLL_ALOG_OBSV_BUS_CTRL_1, 0x0); -} - -static void dsi_pll_commit(struct dsi_pll_10nm *pll, - struct mdss_pll_resources *rsc) -{ - void __iomem *pll_base = rsc->pll_base; - struct dsi_pll_regs *reg = &pll->reg_setup; - - MDSS_PLL_REG_W(pll_base, PLL_CORE_INPUT_OVERRIDE, 0x12); - MDSS_PLL_REG_W(pll_base, PLL_DECIMAL_DIV_START_1, - reg->decimal_div_start); - MDSS_PLL_REG_W(pll_base, PLL_FRAC_DIV_START_LOW_1, - reg->frac_div_start_low); - MDSS_PLL_REG_W(pll_base, PLL_FRAC_DIV_START_MID_1, - reg->frac_div_start_mid); - MDSS_PLL_REG_W(pll_base, PLL_FRAC_DIV_START_HIGH_1, - reg->frac_div_start_high); - MDSS_PLL_REG_W(pll_base, PLL_PLL_LOCKDET_RATE_1, 0x40); - MDSS_PLL_REG_W(pll_base, PLL_PLL_LOCK_DELAY, 0x06); - MDSS_PLL_REG_W(pll_base, PLL_CMODE, 0x10); - MDSS_PLL_REG_W(pll_base, PLL_CLOCK_INVERTERS, reg->pll_clock_inverters); - -} - -static int vco_10nm_set_rate(struct clk_hw *hw, unsigned long rate, - unsigned long parent_rate) -{ - int rc; - struct dsi_pll_vco_clk *vco = to_vco_clk_hw(hw); - struct mdss_pll_resources *rsc = vco->priv; - struct dsi_pll_10nm *pll; - - if (!rsc) { - pr_err("pll resource not found\n"); - return -EINVAL; - } - - if (rsc->pll_on) - return 0; - - pll = rsc->priv; - if (!pll) { - pr_err("pll configuration not found\n"); - return -EINVAL; - } - - pr_debug("ndx=%d, rate=%lu\n", rsc->index, rate); - - rsc->vco_current_rate = rate; - rsc->vco_ref_clk_rate = vco->ref_clk_rate; - rsc->dfps_trigger = false; - - rc = mdss_pll_resource_enable(rsc, true); - if (rc) { - pr_err("failed to enable mdss dsi pll(%d), rc=%d\n", - rsc->index, rc); - return rc; - } - - dsi_pll_init_val(rsc); - - dsi_pll_setup_config(pll, rsc); - - dsi_pll_calc_dec_frac(pll, rsc); - - dsi_pll_calc_ssc(pll, rsc); - - dsi_pll_commit(pll, rsc); - - dsi_pll_config_hzindep_reg(pll, rsc); - - dsi_pll_ssc_commit(pll, rsc); - - /* flush, ensure all register writes are done*/ - wmb(); - - mdss_pll_resource_enable(rsc, false); - - return 0; -} - -static int dsi_pll_read_stored_trim_codes(struct mdss_pll_resources *pll_res, - unsigned long vco_clk_rate) -{ - int i; - bool found = false; - - if (!pll_res->dfps) - return -EINVAL; - - for (i = 0; i < pll_res->dfps->vco_rate_cnt; i++) { - struct dfps_codes_info *codes_info = - &pll_res->dfps->codes_dfps[i]; - - pr_debug("valid=%d vco_rate=%d, code %d %d %d\n", - codes_info->is_valid, codes_info->clk_rate, - codes_info->pll_codes.pll_codes_1, - codes_info->pll_codes.pll_codes_2, - codes_info->pll_codes.pll_codes_3); - - if (vco_clk_rate != codes_info->clk_rate && - codes_info->is_valid) - continue; - - pll_res->cache_pll_trim_codes[0] = - codes_info->pll_codes.pll_codes_1; - pll_res->cache_pll_trim_codes[1] = - codes_info->pll_codes.pll_codes_2; - pll_res->cache_pll_trim_codes[2] = - codes_info->pll_codes.pll_codes_3; - found = true; - break; - } - - if (!found) - return -EINVAL; - - pr_debug("trim_code_0=0x%x trim_code_1=0x%x trim_code_2=0x%x\n", - pll_res->cache_pll_trim_codes[0], - pll_res->cache_pll_trim_codes[1], - pll_res->cache_pll_trim_codes[2]); - - return 0; -} - -static void shadow_dsi_pll_dynamic_refresh_10nm(struct dsi_pll_10nm *pll, - struct mdss_pll_resources *rsc) -{ - u32 data; - u32 offset = DSI_PHY_TO_PLL_OFFSET; - u32 upper_addr = 0; - struct dsi_pll_regs *reg = &pll->reg_setup; - - data = MDSS_PLL_REG_R(rsc->phy_base, PHY_CMN_CLK_CFG1); - data &= ~BIT(5); - MDSS_DYN_PLL_REG_W(rsc->dyn_pll_base, DSI_DYNAMIC_REFRESH_PLL_CTRL0, - PHY_CMN_CLK_CFG1, PHY_CMN_PLL_CNTRL, data, 0); - upper_addr |= (upper_8_bit(PHY_CMN_CLK_CFG1) << 0); - upper_addr |= (upper_8_bit(PHY_CMN_PLL_CNTRL) << 1); - - MDSS_DYN_PLL_REG_W(rsc->dyn_pll_base, DSI_DYNAMIC_REFRESH_PLL_CTRL1, - PHY_CMN_RBUF_CTRL, - (PLL_DECIMAL_DIV_START_1 + offset), - 0, reg->decimal_div_start); - upper_addr |= (upper_8_bit(PHY_CMN_RBUF_CTRL) << 2); - upper_addr |= (upper_8_bit(PLL_DECIMAL_DIV_START_1 + offset) << 3); - - MDSS_DYN_PLL_REG_W(rsc->dyn_pll_base, DSI_DYNAMIC_REFRESH_PLL_CTRL2, - (PLL_FRAC_DIV_START_LOW_1 + offset), - (PLL_FRAC_DIV_START_MID_1 + offset), - reg->frac_div_start_low, reg->frac_div_start_mid); - upper_addr |= (upper_8_bit(PLL_FRAC_DIV_START_LOW_1 + offset) << 4); - upper_addr |= (upper_8_bit(PLL_FRAC_DIV_START_MID_1 + offset) << 5); - - MDSS_DYN_PLL_REG_W(rsc->dyn_pll_base, DSI_DYNAMIC_REFRESH_PLL_CTRL3, - (PLL_FRAC_DIV_START_HIGH_1 + offset), - (PLL_PLL_PROP_GAIN_RATE_1 + offset), - reg->frac_div_start_high, reg->pll_prop_gain_rate); - upper_addr |= (upper_8_bit(PLL_FRAC_DIV_START_HIGH_1 + offset) << 6); - upper_addr |= (upper_8_bit(PLL_PLL_PROP_GAIN_RATE_1 + offset) << 7); - - data = MDSS_PLL_REG_R(rsc->pll_base, PLL_PLL_OUTDIV_RATE) & 0x03; - MDSS_DYN_PLL_REG_W(rsc->dyn_pll_base, DSI_DYNAMIC_REFRESH_PLL_CTRL4, - (PLL_PLL_OUTDIV_RATE + offset), - (PLL_FREQ_TUNE_ACCUM_INIT_LOW + offset), - data, 0); - upper_addr |= (upper_8_bit(PLL_PLL_OUTDIV_RATE + offset) << 8); - upper_addr |= (upper_8_bit(PLL_FREQ_TUNE_ACCUM_INIT_LOW + offset) << 9); - - MDSS_DYN_PLL_REG_W(rsc->dyn_pll_base, DSI_DYNAMIC_REFRESH_PLL_CTRL5, - (PLL_FREQ_TUNE_ACCUM_INIT_MID + offset), - (PLL_FREQ_TUNE_ACCUM_INIT_HIGH + offset), - rsc->cache_pll_trim_codes[1], - rsc->cache_pll_trim_codes[0]); - upper_addr |= - (upper_8_bit(PLL_FREQ_TUNE_ACCUM_INIT_MID + offset) << 10); - upper_addr |= - (upper_8_bit(PLL_FREQ_TUNE_ACCUM_INIT_HIGH + offset) << 11); - - MDSS_DYN_PLL_REG_W(rsc->dyn_pll_base, DSI_DYNAMIC_REFRESH_PLL_CTRL6, - (PLL_FREQ_TUNE_ACCUM_INIT_MUX + offset), - (PLL_PLL_BAND_SET_RATE_1 + offset), - 0x07, rsc->cache_pll_trim_codes[2]); - upper_addr |= - (upper_8_bit(PLL_FREQ_TUNE_ACCUM_INIT_MUX + offset) << 12); - upper_addr |= (upper_8_bit(PLL_PLL_BAND_SET_RATE_1 + offset) << 13); - - MDSS_DYN_PLL_REG_W(rsc->dyn_pll_base, DSI_DYNAMIC_REFRESH_PLL_CTRL7, - (PLL_CALIBRATION_SETTINGS + offset), - (PLL_BAND_SEL_CAL_SETTINGS + offset), 0x44, 0x3a); - upper_addr |= (upper_8_bit(PLL_CALIBRATION_SETTINGS + offset) << 14); - upper_addr |= (upper_8_bit(PLL_BAND_SEL_CAL_SETTINGS + offset) << 15); - - MDSS_DYN_PLL_REG_W(rsc->dyn_pll_base, DSI_DYNAMIC_REFRESH_PLL_CTRL8, - (PLL_PLL_LOCKDET_RATE_1 + offset), - (PLL_PLL_LOCK_DELAY + offset), 0x10, 0x06); - upper_addr |= (upper_8_bit(PLL_PLL_LOCKDET_RATE_1 + offset) << 16); - upper_addr |= (upper_8_bit(PLL_PLL_LOCK_DELAY + offset) << 17); - - data = MDSS_PLL_REG_R(rsc->phy_base, PHY_CMN_CLK_CFG0); - MDSS_DYN_PLL_REG_W(rsc->dyn_pll_base, DSI_DYNAMIC_REFRESH_PLL_CTRL17, - PHY_CMN_CTRL_2, PHY_CMN_CLK_CFG0, 0x40, data); - if (rsc->slave) - MDSS_DYN_PLL_REG_W(rsc->slave->dyn_pll_base, - DSI_DYNAMIC_REFRESH_PLL_CTRL10, - PHY_CMN_CLK_CFG0, PHY_CMN_CTRL_0, - data, 0x7f); - - MDSS_DYN_PLL_REG_W(rsc->dyn_pll_base, DSI_DYNAMIC_REFRESH_PLL_CTRL18, - PHY_CMN_PLL_CNTRL, PHY_CMN_PLL_CNTRL, 0x01, 0x01); - /* Dummy register writes */ - MDSS_DYN_PLL_REG_W(rsc->dyn_pll_base, DSI_DYNAMIC_REFRESH_PLL_CTRL19, - PHY_CMN_PLL_CNTRL, PHY_CMN_PLL_CNTRL, 0x01, 0x01); - MDSS_DYN_PLL_REG_W(rsc->dyn_pll_base, DSI_DYNAMIC_REFRESH_PLL_CTRL20, - PHY_CMN_PLL_CNTRL, PHY_CMN_PLL_CNTRL, 0x01, 0x01); - MDSS_DYN_PLL_REG_W(rsc->dyn_pll_base, DSI_DYNAMIC_REFRESH_PLL_CTRL21, - PHY_CMN_PLL_CNTRL, PHY_CMN_PLL_CNTRL, 0x01, 0x01); - MDSS_DYN_PLL_REG_W(rsc->dyn_pll_base, DSI_DYNAMIC_REFRESH_PLL_CTRL22, - PHY_CMN_PLL_CNTRL, PHY_CMN_PLL_CNTRL, 0x01, 0x01); - MDSS_DYN_PLL_REG_W(rsc->dyn_pll_base, DSI_DYNAMIC_REFRESH_PLL_CTRL23, - PHY_CMN_PLL_CNTRL, PHY_CMN_PLL_CNTRL, 0x01, 0x01); - MDSS_DYN_PLL_REG_W(rsc->dyn_pll_base, DSI_DYNAMIC_REFRESH_PLL_CTRL24, - PHY_CMN_PLL_CNTRL, PHY_CMN_PLL_CNTRL, 0x01, 0x01); - MDSS_DYN_PLL_REG_W(rsc->dyn_pll_base, DSI_DYNAMIC_REFRESH_PLL_CTRL25, - PHY_CMN_PLL_CNTRL, PHY_CMN_PLL_CNTRL, 0x01, 0x01); - MDSS_DYN_PLL_REG_W(rsc->dyn_pll_base, DSI_DYNAMIC_REFRESH_PLL_CTRL26, - PHY_CMN_PLL_CNTRL, PHY_CMN_PLL_CNTRL, 0x01, 0x01); - MDSS_DYN_PLL_REG_W(rsc->dyn_pll_base, DSI_DYNAMIC_REFRESH_PLL_CTRL27, - PHY_CMN_PLL_CNTRL, PHY_CMN_PLL_CNTRL, 0x01, 0x01); - MDSS_DYN_PLL_REG_W(rsc->dyn_pll_base, DSI_DYNAMIC_REFRESH_PLL_CTRL28, - PHY_CMN_PLL_CNTRL, PHY_CMN_PLL_CNTRL, 0x01, 0x01); - MDSS_DYN_PLL_REG_W(rsc->dyn_pll_base, DSI_DYNAMIC_REFRESH_PLL_CTRL29, - PHY_CMN_PLL_CNTRL, PHY_CMN_PLL_CNTRL, 0x01, 0x01); - - /* Registers to configure after PLL enable delay */ - data = MDSS_PLL_REG_R(rsc->phy_base, PHY_CMN_CLK_CFG1) | BIT(5); - MDSS_DYN_PLL_REG_W(rsc->dyn_pll_base, DSI_DYNAMIC_REFRESH_PLL_CTRL30, - PHY_CMN_CLK_CFG1, PHY_CMN_RBUF_CTRL, data, 0x01); - MDSS_DYN_PLL_REG_W(rsc->dyn_pll_base, DSI_DYNAMIC_REFRESH_PLL_CTRL31, - PHY_CMN_CLK_CFG1, PHY_CMN_CLK_CFG1, data, data); - if (rsc->slave) { - data = MDSS_PLL_REG_R(rsc->slave->phy_base, PHY_CMN_CLK_CFG1) | - BIT(5); - MDSS_DYN_PLL_REG_W(rsc->slave->dyn_pll_base, - DSI_DYNAMIC_REFRESH_PLL_CTRL30, - PHY_CMN_CLK_CFG1, PHY_CMN_RBUF_CTRL, - data, 0x01); - MDSS_DYN_PLL_REG_W(rsc->slave->dyn_pll_base, - DSI_DYNAMIC_REFRESH_PLL_CTRL31, - PHY_CMN_CLK_CFG1, PHY_CMN_CLK_CFG1, - data, data); - } - - MDSS_PLL_REG_W(rsc->dyn_pll_base, - DSI_DYNAMIC_REFRESH_PLL_UPPER_ADDR, upper_addr); - MDSS_PLL_REG_W(rsc->dyn_pll_base, - DSI_DYNAMIC_REFRESH_PLL_UPPER_ADDR2, 0); - wmb(); /* commit register writes */ -} - -static int shadow_vco_10nm_set_rate(struct clk_hw *hw, unsigned long rate, - unsigned long parent_rate) -{ - int rc; - struct dsi_pll_10nm *pll; - struct dsi_pll_vco_clk *vco = to_vco_clk_hw(hw); - struct mdss_pll_resources *rsc = vco->priv; - - if (!rsc) { - pr_err("pll resource not found\n"); - return -EINVAL; - } - - pll = rsc->priv; - if (!pll) { - pr_err("pll configuration not found\n"); - return -EINVAL; - } - - rc = dsi_pll_read_stored_trim_codes(rsc, rate); - if (rc) { - pr_err("cannot find pll codes rate=%ld\n", rate); - return -EINVAL; - } - pr_debug("ndx=%d, rate=%lu\n", rsc->index, rate); - - rsc->vco_current_rate = rate; - rsc->vco_ref_clk_rate = vco->ref_clk_rate; - - rc = mdss_pll_resource_enable(rsc, true); - if (rc) { - pr_err("failed to enable mdss dsi pll(%d), rc=%d\n", - rsc->index, rc); - return rc; - } - - dsi_pll_setup_config(pll, rsc); - - dsi_pll_calc_dec_frac(pll, rsc); - - /* program dynamic refresh control registers */ - shadow_dsi_pll_dynamic_refresh_10nm(pll, rsc); - - /* update cached vco rate */ - rsc->vco_cached_rate = rate; - rsc->dfps_trigger = true; - - mdss_pll_resource_enable(rsc, false); - - return 0; -} - -static int dsi_pll_10nm_lock_status(struct mdss_pll_resources *pll) -{ - int rc; - u32 status; - u32 const delay_us = 100; - u32 const timeout_us = 5000; - - rc = readl_poll_timeout_atomic(pll->pll_base + PLL_COMMON_STATUS_ONE, - status, - ((status & BIT(0)) > 0), - delay_us, - timeout_us); - if (rc) - pr_err("DSI PLL(%d) lock failed, status=0x%08x\n", - pll->index, status); - - return rc; -} - -static void dsi_pll_disable_pll_bias(struct mdss_pll_resources *rsc) -{ - u32 data = MDSS_PLL_REG_R(rsc->phy_base, PHY_CMN_CTRL_0); - - MDSS_PLL_REG_W(rsc->pll_base, PLL_SYSTEM_MUXES, 0); - MDSS_PLL_REG_W(rsc->phy_base, PHY_CMN_CTRL_0, data & ~BIT(5)); - ndelay(250); -} - -static void dsi_pll_enable_pll_bias(struct mdss_pll_resources *rsc) -{ - u32 data = MDSS_PLL_REG_R(rsc->phy_base, PHY_CMN_CTRL_0); - - MDSS_PLL_REG_W(rsc->phy_base, PHY_CMN_CTRL_0, data | BIT(5)); - MDSS_PLL_REG_W(rsc->pll_base, PLL_SYSTEM_MUXES, 0xc0); - ndelay(250); -} - -static void dsi_pll_disable_global_clk(struct mdss_pll_resources *rsc) -{ - u32 data; - - data = MDSS_PLL_REG_R(rsc->phy_base, PHY_CMN_CLK_CFG1); - MDSS_PLL_REG_W(rsc->phy_base, PHY_CMN_CLK_CFG1, (data & ~BIT(5))); -} - -static void dsi_pll_enable_global_clk(struct mdss_pll_resources *rsc) -{ - u32 data; - - data = MDSS_PLL_REG_R(rsc->phy_base, PHY_CMN_CLK_CFG1); - MDSS_PLL_REG_W(rsc->phy_base, PHY_CMN_CLK_CFG1, (data | BIT(5))); -} - -static int dsi_pll_enable(struct dsi_pll_vco_clk *vco) -{ - int rc; - struct mdss_pll_resources *rsc = vco->priv; - - dsi_pll_enable_pll_bias(rsc); - if (rsc->slave) - dsi_pll_enable_pll_bias(rsc->slave); - - phy_reg_update_bits_sub(rsc, PHY_CMN_CLK_CFG1, 0x03, rsc->cached_cfg1); - if (rsc->slave) - phy_reg_update_bits_sub(rsc->slave, PHY_CMN_CLK_CFG1, - 0x03, rsc->slave->cached_cfg1); - wmb(); /* ensure dsiclk_sel is always programmed before pll start */ - - /* Start PLL */ - MDSS_PLL_REG_W(rsc->phy_base, PHY_CMN_PLL_CNTRL, 0x01); - - /* - * ensure all PLL configurations are written prior to checking - * for PLL lock. - */ - wmb(); - - /* Check for PLL lock */ - rc = dsi_pll_10nm_lock_status(rsc); - if (rc) { - pr_err("PLL(%d) lock failed\n", rsc->index); - goto error; - } - - rsc->pll_on = true; - - dsi_pll_enable_global_clk(rsc); - if (rsc->slave) - dsi_pll_enable_global_clk(rsc->slave); - - MDSS_PLL_REG_W(rsc->phy_base, PHY_CMN_RBUF_CTRL, 0x01); - if (rsc->slave) - MDSS_PLL_REG_W(rsc->slave->phy_base, PHY_CMN_RBUF_CTRL, 0x01); - -error: - return rc; -} - -static void dsi_pll_disable_sub(struct mdss_pll_resources *rsc) -{ - MDSS_PLL_REG_W(rsc->phy_base, PHY_CMN_RBUF_CTRL, 0); - dsi_pll_disable_pll_bias(rsc); -} - -static void dsi_pll_disable(struct dsi_pll_vco_clk *vco) -{ - struct mdss_pll_resources *rsc = vco->priv; - - if (!rsc->pll_on && - mdss_pll_resource_enable(rsc, true)) { - pr_err("failed to enable pll (%d) resources\n", rsc->index); - return; - } - - rsc->handoff_resources = false; - rsc->dfps_trigger = false; - - pr_debug("stop PLL (%d)\n", rsc->index); - - /* - * To avoid any stray glitches while - * abruptly powering down the PLL - * make sure to gate the clock using - * the clock enable bit before powering - * down the PLL - */ - dsi_pll_disable_global_clk(rsc); - MDSS_PLL_REG_W(rsc->phy_base, PHY_CMN_PLL_CNTRL, 0); - dsi_pll_disable_sub(rsc); - if (rsc->slave) { - dsi_pll_disable_global_clk(rsc->slave); - dsi_pll_disable_sub(rsc->slave); - } - /* flush, ensure all register writes are done*/ - wmb(); - rsc->pll_on = false; -} - -long vco_10nm_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) -{ - unsigned long rrate = rate; - struct dsi_pll_vco_clk *vco = to_vco_clk_hw(hw); - - if (rate < vco->min_rate) - rrate = vco->min_rate; - if (rate > vco->max_rate) - rrate = vco->max_rate; - - *parent_rate = rrate; - - return rrate; -} - -static void vco_10nm_unprepare(struct clk_hw *hw) -{ - struct dsi_pll_vco_clk *vco = to_vco_clk_hw(hw); - struct mdss_pll_resources *pll = vco->priv; - - if (!pll) { - pr_err("dsi pll resources not available\n"); - return; - } - - /* - * During unprepare in continuous splash use case we want driver - * to pick all dividers instead of retaining bootloader configurations. - * Also handle use cases where dynamic refresh triggered before - * first suspend/resume. - */ - if (!pll->handoff_resources || pll->dfps_trigger) { - pll->cached_cfg0 = MDSS_PLL_REG_R(pll->phy_base, - PHY_CMN_CLK_CFG0); - pll->cached_outdiv = MDSS_PLL_REG_R(pll->pll_base, - PLL_PLL_OUTDIV_RATE); - pr_debug("cfg0=%d,cfg1=%d, outdiv=%d\n", pll->cached_cfg0, - pll->cached_cfg1, pll->cached_outdiv); - - pll->vco_cached_rate = clk_get_rate(hw->clk); - } - - /* - * When continuous splash screen feature is enabled, we need to cache - * the mux configuration for the pixel_clk_src mux clock. The clock - * framework does not call back to re-configure the mux value if it is - * does not change.For such usecases, we need to ensure that the cached - * value is programmed prior to PLL being locked - */ - if (pll->handoff_resources) { - pll->cached_cfg1 = MDSS_PLL_REG_R(pll->phy_base, - PHY_CMN_CLK_CFG1); - if (pll->slave) - pll->slave->cached_cfg1 = - MDSS_PLL_REG_R(pll->slave->phy_base, - PHY_CMN_CLK_CFG1); - } - - dsi_pll_disable(vco); - mdss_pll_resource_enable(pll, false); -} - -static int vco_10nm_prepare(struct clk_hw *hw) -{ - int rc = 0; - struct dsi_pll_vco_clk *vco = to_vco_clk_hw(hw); - struct mdss_pll_resources *pll = vco->priv; - - if (!pll) { - pr_err("dsi pll resources are not available\n"); - return -EINVAL; - } - - /* Skip vco recalculation for continuous splash use case */ - if (pll->handoff_resources) - return 0; - - rc = mdss_pll_resource_enable(pll, true); - if (rc) { - pr_err("failed to enable pll (%d) resource, rc=%d\n", - pll->index, rc); - return rc; - } - - if ((pll->vco_cached_rate != 0) && - (pll->vco_cached_rate == clk_get_rate(hw->clk))) { - rc = hw->init->ops->set_rate(hw, pll->vco_cached_rate, - pll->vco_cached_rate); - if (rc) { - pr_err("pll(%d) set_rate failed, rc=%d\n", - pll->index, rc); - mdss_pll_resource_enable(pll, false); - return rc; - } - pr_debug("cfg0=%d, cfg1=%d\n", pll->cached_cfg0, - pll->cached_cfg1); - MDSS_PLL_REG_W(pll->phy_base, PHY_CMN_CLK_CFG0, - pll->cached_cfg0); - if (pll->slave) - MDSS_PLL_REG_W(pll->slave->phy_base, PHY_CMN_CLK_CFG0, - pll->cached_cfg0); - MDSS_PLL_REG_W(pll->pll_base, PLL_PLL_OUTDIV_RATE, - pll->cached_outdiv); - } - MDSS_PLL_ATRACE_BEGIN("pll_lock"); - trace_mdss_pll_lock_start((u64)pll->vco_cached_rate, - pll->vco_current_rate, - pll->cached_cfg0, pll->cached_cfg1, - pll->cached_outdiv, pll->resource_ref_cnt); - rc = dsi_pll_enable(vco); - MDSS_PLL_ATRACE_END("pll_lock"); - if (rc) { - mdss_pll_resource_enable(pll, false); - pr_err("pll(%d) enable failed, rc=%d\n", pll->index, rc); - return rc; - } - - return rc; -} - -static unsigned long vco_10nm_recalc_rate(struct clk_hw *hw, - unsigned long parent_rate) -{ - struct dsi_pll_vco_clk *vco = to_vco_clk_hw(hw); - struct mdss_pll_resources *pll = vco->priv; - int rc; - - if (!vco->priv) - pr_err("vco priv is null\n"); - - if (!pll) { - pr_err("pll is null\n"); - return 0; - } - - /* - * In the case when vco arte is set, the recalculation function should - * return the current rate as to avoid trying to set the vco rate - * again. However durng handoff, recalculation should set the flag - * according to the status of PLL. - */ - if (pll->vco_current_rate != 0) { - pr_debug("returning vco rate = %lld\n", pll->vco_current_rate); - return pll->vco_current_rate; - } - - rc = mdss_pll_resource_enable(pll, true); - if (rc) { - pr_err("failed to enable pll(%d) resource, rc=%d\n", - pll->index, rc); - return 0; - } - - if (!dsi_pll_10nm_lock_status(pll)) - pll->handoff_resources = true; - - - (void)mdss_pll_resource_enable(pll, false); - - return rc; -} - -static int pixel_clk_get_div(void *context, unsigned int reg, unsigned int *div) -{ - int rc; - struct mdss_pll_resources *pll = context; - u32 reg_val; - - rc = mdss_pll_resource_enable(pll, true); - if (rc) { - pr_err("Failed to enable dsi pll resources, rc=%d\n", rc); - return rc; - } - - reg_val = MDSS_PLL_REG_R(pll->phy_base, PHY_CMN_CLK_CFG0); - *div = (reg_val & 0xF0) >> 4; - - /** - * Common clock framework the divider value is interpreted as one less - * hence we return one less for all dividers except when zero - */ - if (*div != 0) - *div -= 1; - - (void)mdss_pll_resource_enable(pll, false); - - return rc; -} - -static void pixel_clk_set_div_sub(struct mdss_pll_resources *pll, int div) -{ - u32 reg_val; - - reg_val = MDSS_PLL_REG_R(pll->phy_base, PHY_CMN_CLK_CFG0); - reg_val &= ~0xF0; - reg_val |= (div << 4); - MDSS_PLL_REG_W(pll->phy_base, PHY_CMN_CLK_CFG0, reg_val); - - /* - * cache the current parent index for cases where parent - * is not changing but rate is changing. In that case - * clock framework won't call parent_set and hence dsiclk_sel - * bit won't be programmed. e.g. dfps update use case. - */ - pll->cached_cfg0 = reg_val; -} - -static int pixel_clk_set_div(void *context, unsigned int reg, unsigned int div) -{ - int rc; - struct mdss_pll_resources *pll = context; - - rc = mdss_pll_resource_enable(pll, true); - if (rc) { - pr_err("Failed to enable dsi pll resources, rc=%d\n", rc); - return rc; - } - /** - * In common clock framework the divider value provided is one less and - * and hence adjusting the divider value by one prior to writing it to - * hardware - */ - div++; - pixel_clk_set_div_sub(pll, div); - if (pll->slave) - pixel_clk_set_div_sub(pll->slave, div); - (void)mdss_pll_resource_enable(pll, false); - - return 0; -} - -static int bit_clk_get_div(void *context, unsigned int reg, unsigned int *div) -{ - int rc; - struct mdss_pll_resources *pll = context; - u32 reg_val; - - rc = mdss_pll_resource_enable(pll, true); - if (rc) { - pr_err("Failed to enable dsi pll resources, rc=%d\n", rc); - return rc; - } - - reg_val = MDSS_PLL_REG_R(pll->phy_base, PHY_CMN_CLK_CFG0); - *div = (reg_val & 0x0F); - - /** - *Common clock framework the divider value is interpreted as one less - * hence we return one less for all dividers except when zero - */ - if (*div != 0) - *div -= 1; - (void)mdss_pll_resource_enable(pll, false); - - return rc; -} - -static void bit_clk_set_div_sub(struct mdss_pll_resources *rsc, int div) -{ - u32 reg_val; - - reg_val = MDSS_PLL_REG_R(rsc->phy_base, PHY_CMN_CLK_CFG0); - reg_val &= ~0x0F; - reg_val |= div; - MDSS_PLL_REG_W(rsc->phy_base, PHY_CMN_CLK_CFG0, reg_val); -} - -static int bit_clk_set_div(void *context, unsigned int reg, unsigned int div) -{ - int rc; - struct mdss_pll_resources *rsc = context; - struct dsi_pll_8998 *pll; - - if (!rsc) { - pr_err("pll resource not found\n"); - return -EINVAL; - } - - pll = rsc->priv; - if (!pll) { - pr_err("pll configuration not found\n"); - return -EINVAL; - } - - rc = mdss_pll_resource_enable(rsc, true); - if (rc) { - pr_err("Failed to enable dsi pll resources, rc=%d\n", rc); - return rc; - } - - /** - * In common clock framework the divider value provided is one less and - * and hence adjusting the divider value by one prior to writing it to - * hardware - */ - div++; - - bit_clk_set_div_sub(rsc, div); - /* For slave PLL, this divider always should be set to 1 */ - if (rsc->slave) - bit_clk_set_div_sub(rsc->slave, 1); - - (void)mdss_pll_resource_enable(rsc, false); - - return rc; -} - -static struct regmap_config dsi_pll_10nm_config = { - .reg_bits = 32, - .reg_stride = 4, - .val_bits = 32, - .max_register = 0x7c0, -}; - -static struct regmap_bus pll_regmap_bus = { - .reg_write = pll_reg_write, - .reg_read = pll_reg_read, -}; - -static struct regmap_bus pclk_src_mux_regmap_bus = { - .reg_read = pclk_mux_read_sel, - .reg_write = pclk_mux_write_sel, -}; - -static struct regmap_bus pclk_src_regmap_bus = { - .reg_write = pixel_clk_set_div, - .reg_read = pixel_clk_get_div, -}; - -static struct regmap_bus bitclk_src_regmap_bus = { - .reg_write = bit_clk_set_div, - .reg_read = bit_clk_get_div, -}; - -static const struct clk_ops clk_ops_vco_10nm = { - .recalc_rate = vco_10nm_recalc_rate, - .set_rate = vco_10nm_set_rate, - .round_rate = vco_10nm_round_rate, - .prepare = vco_10nm_prepare, - .unprepare = vco_10nm_unprepare, -}; - -static const struct clk_ops clk_ops_shadow_vco_10nm = { - .recalc_rate = vco_10nm_recalc_rate, - .set_rate = shadow_vco_10nm_set_rate, - .round_rate = vco_10nm_round_rate, -}; - -static struct regmap_bus mdss_mux_regmap_bus = { - .reg_write = mdss_set_mux_sel, - .reg_read = mdss_get_mux_sel, -}; - -/* - * Clock tree for generating DSI byte and pixel clocks. - * - * - * +---------------+ - * | vco_clk | - * +-------+-------+ - * | - * | - * +---------------+ - * | pll_out_div | - * | DIV(1,2,4,8) | - * +-------+-------+ - * | - * +-----------------------------+--------+ - * | | | - * +-------v-------+ | | - * | bitclk_src | | | - * | DIV(1..15) | | | - * +-------+-------+ | | - * | | | - * +----------+---------+ | | - * Shadow Path | | | | | - * + +-------v-------+ | +------v------+ | +------v-------+ - * | | byteclk_src | | |post_bit_div | | |post_vco_div | - * | | DIV(8) | | |DIV (2) | | |DIV(4) | - * | +-------+-------+ | +------+------+ | +------+-------+ - * | | | | | | | - * | | | +------+ | | - * | | +-------------+ | | +----+ - * | +--------+ | | | | - * | | +-v--v-v---v------+ - * +-v---------v----+ \ pclk_src_mux / - * \ byteclk_mux / \ / - * \ / +-----+-----+ - * +----+-----+ | Shadow Path - * | | + - * v +-----v------+ | - * dsi_byte_clk | pclk_src | | - * | DIV(1..15) | | - * +-----+------+ | - * | | - * | | - * +--------+ | - * | | - * +---v----v----+ - * \ pclk_mux / - * \ / - * +---+---+ - * | - * | - * v - * dsi_pclk - * - */ - -static struct dsi_pll_vco_clk dsi0pll_vco_clk = { - .ref_clk_rate = 19200000UL, - .min_rate = 1000000000UL, - .max_rate = 3500000000UL, - .hw.init = &(struct clk_init_data){ - .name = "dsi0pll_vco_clk", - .parent_names = (const char *[]){"bi_tcxo"}, - .num_parents = 1, - .ops = &clk_ops_vco_10nm, - .flags = CLK_GET_RATE_NOCACHE, - }, -}; - -static struct dsi_pll_vco_clk dsi0pll_shadow_vco_clk = { - .ref_clk_rate = 19200000UL, - .min_rate = 1000000000UL, - .max_rate = 3500000000UL, - .hw.init = &(struct clk_init_data){ - .name = "dsi0pll_shadow_vco_clk", - .parent_names = (const char *[]){"bi_tcxo"}, - .num_parents = 1, - .ops = &clk_ops_shadow_vco_10nm, - .flags = CLK_GET_RATE_NOCACHE, - }, -}; - -static struct dsi_pll_vco_clk dsi1pll_vco_clk = { - .ref_clk_rate = 19200000UL, - .min_rate = 1000000000UL, - .max_rate = 3500000000UL, - .hw.init = &(struct clk_init_data){ - .name = "dsi1pll_vco_clk", - .parent_names = (const char *[]){"bi_tcxo"}, - .num_parents = 1, - .ops = &clk_ops_vco_10nm, - .flags = CLK_GET_RATE_NOCACHE, - }, -}; - -static struct dsi_pll_vco_clk dsi1pll_shadow_vco_clk = { - .ref_clk_rate = 19200000UL, - .min_rate = 1000000000UL, - .max_rate = 3500000000UL, - .hw.init = &(struct clk_init_data){ - .name = "dsi1pll_shadow_vco_clk", - .parent_names = (const char *[]){"bi_tcxo"}, - .num_parents = 1, - .ops = &clk_ops_shadow_vco_10nm, - .flags = CLK_GET_RATE_NOCACHE, - }, -}; - -static struct clk_regmap_div dsi0pll_pll_out_div = { - .reg = PLL_PLL_OUTDIV_RATE, - .shift = 0, - .width = 2, - .flags = CLK_DIVIDER_POWER_OF_TWO, - .clkr = { - .hw.init = &(struct clk_init_data){ - .name = "dsi0pll_pll_out_div", - .parent_names = (const char *[]){"dsi0pll_vco_clk"}, - .num_parents = 1, - .flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT), - .ops = &clk_regmap_div_ops, - }, - }, -}; - -static struct clk_regmap_div dsi0pll_shadow_pll_out_div = { - .reg = PLL_PLL_OUTDIV_RATE, - .shift = 0, - .width = 2, - .flags = CLK_DIVIDER_POWER_OF_TWO, - .clkr = { - .hw.init = &(struct clk_init_data){ - .name = "dsi0pll_shadow_pll_out_div", - .parent_names = (const char *[]){ - "dsi0pll_shadow_vco_clk"}, - .num_parents = 1, - .flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT), - .ops = &clk_regmap_div_ops, - }, - }, -}; - -static struct clk_regmap_div dsi1pll_pll_out_div = { - .reg = PLL_PLL_OUTDIV_RATE, - .shift = 0, - .width = 2, - .flags = CLK_DIVIDER_POWER_OF_TWO, - .clkr = { - .hw.init = &(struct clk_init_data){ - .name = "dsi1pll_pll_out_div", - .parent_names = (const char *[]){"dsi1pll_vco_clk"}, - .num_parents = 1, - .flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT), - .ops = &clk_regmap_div_ops, - }, - }, -}; - -static struct clk_regmap_div dsi1pll_shadow_pll_out_div = { - .reg = PLL_PLL_OUTDIV_RATE, - .shift = 0, - .width = 2, - .flags = CLK_DIVIDER_POWER_OF_TWO, - .clkr = { - .hw.init = &(struct clk_init_data){ - .name = "dsi1pll_shadow_pll_out_div", - .parent_names = (const char *[]){ - "dsi1pll_shadow_vco_clk"}, - .num_parents = 1, - .flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT), - .ops = &clk_regmap_div_ops, - }, - }, -}; - -static struct clk_regmap_div dsi0pll_bitclk_src = { - .shift = 0, - .width = 4, - .clkr = { - .hw.init = &(struct clk_init_data){ - .name = "dsi0pll_bitclk_src", - .parent_names = (const char *[]){"dsi0pll_pll_out_div"}, - .num_parents = 1, - .flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT), - .ops = &clk_regmap_div_ops, - }, - }, -}; - -static struct clk_regmap_div dsi0pll_shadow_bitclk_src = { - .shift = 0, - .width = 4, - .clkr = { - .hw.init = &(struct clk_init_data){ - .name = "dsi0pll_shadow_bitclk_src", - .parent_names = (const char *[]){ - "dsi0pll_shadow_pll_out_div"}, - .num_parents = 1, - .flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT), - .ops = &clk_regmap_div_ops, - }, - }, -}; - -static struct clk_regmap_div dsi1pll_bitclk_src = { - .shift = 0, - .width = 4, - .clkr = { - .hw.init = &(struct clk_init_data){ - .name = "dsi1pll_bitclk_src", - .parent_names = (const char *[]){"dsi1pll_pll_out_div"}, - .num_parents = 1, - .flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT), - .ops = &clk_regmap_div_ops, - }, - }, -}; - -static struct clk_regmap_div dsi1pll_shadow_bitclk_src = { - .shift = 0, - .width = 4, - .clkr = { - .hw.init = &(struct clk_init_data){ - .name = "dsi1pll_shadow_bitclk_src", - .parent_names = (const char *[]){ - "dsi1pll_shadow_pll_out_div"}, - .num_parents = 1, - .flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT), - .ops = &clk_regmap_div_ops, - }, - }, -}; - -static struct clk_fixed_factor dsi0pll_post_vco_div = { - .div = 4, - .mult = 1, - .hw.init = &(struct clk_init_data){ - .name = "dsi0pll_post_vco_div", - .parent_names = (const char *[]){"dsi0pll_pll_out_div"}, - .num_parents = 1, - .flags = CLK_GET_RATE_NOCACHE, - .ops = &clk_fixed_factor_ops, - }, -}; - -static struct clk_fixed_factor dsi0pll_shadow_post_vco_div = { - .div = 4, - .mult = 1, - .hw.init = &(struct clk_init_data){ - .name = "dsi0pll_shadow_post_vco_div", - .parent_names = (const char *[]){"dsi0pll_shadow_pll_out_div"}, - .num_parents = 1, - .flags = CLK_GET_RATE_NOCACHE, - .ops = &clk_fixed_factor_ops, - }, -}; - -static struct clk_fixed_factor dsi1pll_post_vco_div = { - .div = 4, - .mult = 1, - .hw.init = &(struct clk_init_data){ - .name = "dsi1pll_post_vco_div", - .parent_names = (const char *[]){"dsi1pll_pll_out_div"}, - .num_parents = 1, - .flags = CLK_GET_RATE_NOCACHE, - .ops = &clk_fixed_factor_ops, - }, -}; - -static struct clk_fixed_factor dsi1pll_shadow_post_vco_div = { - .div = 4, - .mult = 1, - .hw.init = &(struct clk_init_data){ - .name = "dsi1pll_shadow_post_vco_div", - .parent_names = (const char *[]){"dsi1pll_shadow_pll_out_div"}, - .num_parents = 1, - .flags = CLK_GET_RATE_NOCACHE, - .ops = &clk_fixed_factor_ops, - }, -}; - -static struct clk_fixed_factor dsi0pll_byteclk_src = { - .div = 8, - .mult = 1, - .hw.init = &(struct clk_init_data){ - .name = "dsi0pll_byteclk_src", - .parent_names = (const char *[]){"dsi0pll_bitclk_src"}, - .num_parents = 1, - .flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT), - .ops = &clk_fixed_factor_ops, - }, -}; - -static struct clk_fixed_factor dsi0pll_shadow_byteclk_src = { - .div = 8, - .mult = 1, - .hw.init = &(struct clk_init_data){ - .name = "dsi0pll_shadow_byteclk_src", - .parent_names = (const char *[]){"dsi0pll_shadow_bitclk_src"}, - .num_parents = 1, - .flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT), - .ops = &clk_fixed_factor_ops, - }, -}; - -static struct clk_fixed_factor dsi1pll_byteclk_src = { - .div = 8, - .mult = 1, - .hw.init = &(struct clk_init_data){ - .name = "dsi1pll_byteclk_src", - .parent_names = (const char *[]){"dsi1pll_bitclk_src"}, - .num_parents = 1, - .flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT), - .ops = &clk_fixed_factor_ops, - }, -}; - -static struct clk_fixed_factor dsi1pll_shadow_byteclk_src = { - .div = 8, - .mult = 1, - .hw.init = &(struct clk_init_data){ - .name = "dsi1pll_shadow_byteclk_src", - .parent_names = (const char *[]){"dsi1pll_shadow_bitclk_src"}, - .num_parents = 1, - .flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT), - .ops = &clk_fixed_factor_ops, - }, -}; - -static struct clk_fixed_factor dsi0pll_post_bit_div = { - .div = 2, - .mult = 1, - .hw.init = &(struct clk_init_data){ - .name = "dsi0pll_post_bit_div", - .parent_names = (const char *[]){"dsi0pll_bitclk_src"}, - .num_parents = 1, - .flags = CLK_GET_RATE_NOCACHE, - .ops = &clk_fixed_factor_ops, - }, -}; - -static struct clk_fixed_factor dsi0pll_shadow_post_bit_div = { - .div = 2, - .mult = 1, - .hw.init = &(struct clk_init_data){ - .name = "dsi0pll_shadow_post_bit_div", - .parent_names = (const char *[]){"dsi0pll_shadow_bitclk_src"}, - .num_parents = 1, - .flags = CLK_GET_RATE_NOCACHE, - .ops = &clk_fixed_factor_ops, - }, -}; - -static struct clk_fixed_factor dsi1pll_post_bit_div = { - .div = 2, - .mult = 1, - .hw.init = &(struct clk_init_data){ - .name = "dsi1pll_post_bit_div", - .parent_names = (const char *[]){"dsi1pll_bitclk_src"}, - .num_parents = 1, - .flags = CLK_GET_RATE_NOCACHE, - .ops = &clk_fixed_factor_ops, - }, -}; - -static struct clk_fixed_factor dsi1pll_shadow_post_bit_div = { - .div = 2, - .mult = 1, - .hw.init = &(struct clk_init_data){ - .name = "dsi1pll_shadow_post_bit_div", - .parent_names = (const char *[]){"dsi1pll_shadow_bitclk_src"}, - .num_parents = 1, - .flags = CLK_GET_RATE_NOCACHE, - .ops = &clk_fixed_factor_ops, - }, -}; - -static struct clk_regmap_mux dsi0pll_byteclk_mux = { - .shift = 0, - .width = 1, - .clkr = { - .hw.init = &(struct clk_init_data){ - .name = "dsi0_phy_pll_out_byteclk", - .parent_names = (const char *[]){"dsi0pll_byteclk_src", - "dsi0pll_shadow_byteclk_src"}, - .num_parents = 2, - .flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT | - CLK_SET_RATE_NO_REPARENT), - .ops = &clk_regmap_mux_closest_ops, - }, - }, -}; - -static struct clk_regmap_mux dsi1pll_byteclk_mux = { - .shift = 0, - .width = 1, - .clkr = { - .hw.init = &(struct clk_init_data){ - .name = "dsi1_phy_pll_out_byteclk", - .parent_names = (const char *[]){"dsi1pll_byteclk_src", - "dsi1pll_shadow_byteclk_src"}, - .num_parents = 2, - .flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT | - CLK_SET_RATE_NO_REPARENT), - .ops = &clk_regmap_mux_closest_ops, - }, - }, -}; - -static struct clk_regmap_mux dsi0pll_pclk_src_mux = { - .reg = PHY_CMN_CLK_CFG1, - .shift = 0, - .width = 2, - .clkr = { - .hw.init = &(struct clk_init_data){ - .name = "dsi0pll_pclk_src_mux", - .parent_names = (const char *[]){"dsi0pll_bitclk_src", - "dsi0pll_post_bit_div", - "dsi0pll_pll_out_div", - "dsi0pll_post_vco_div"}, - .num_parents = 4, - .flags = CLK_GET_RATE_NOCACHE, - .ops = &clk_regmap_mux_closest_ops, - }, - }, -}; - -static struct clk_regmap_mux dsi0pll_shadow_pclk_src_mux = { - .reg = PHY_CMN_CLK_CFG1, - .shift = 0, - .width = 2, - .clkr = { - .hw.init = &(struct clk_init_data){ - .name = "dsi0pll_shadow_pclk_src_mux", - .parent_names = (const char *[]){ - "dsi0pll_shadow_bitclk_src", - "dsi0pll_shadow_post_bit_div", - "dsi0pll_shadow_pll_out_div", - "dsi0pll_shadow_post_vco_div"}, - .num_parents = 4, - .flags = CLK_GET_RATE_NOCACHE, - .ops = &clk_regmap_mux_closest_ops, - }, - }, -}; - -static struct clk_regmap_mux dsi1pll_pclk_src_mux = { - .reg = PHY_CMN_CLK_CFG1, - .shift = 0, - .width = 2, - .clkr = { - .hw.init = &(struct clk_init_data){ - .name = "dsi1pll_pclk_src_mux", - .parent_names = (const char *[]){"dsi1pll_bitclk_src", - "dsi1pll_post_bit_div", - "dsi1pll_pll_out_div", - "dsi1pll_post_vco_div"}, - .num_parents = 4, - .flags = CLK_GET_RATE_NOCACHE, - .ops = &clk_regmap_mux_closest_ops, - }, - }, -}; - -static struct clk_regmap_mux dsi1pll_shadow_pclk_src_mux = { - .reg = PHY_CMN_CLK_CFG1, - .shift = 0, - .width = 2, - .clkr = { - .hw.init = &(struct clk_init_data){ - .name = "dsi1pll_shadow_pclk_src_mux", - .parent_names = (const char *[]){ - "dsi1pll_shadow_bitclk_src", - "dsi1pll_shadow_post_bit_div", - "dsi1pll_shadow_pll_out_div", - "dsi1pll_shadow_post_vco_div"}, - .num_parents = 4, - .flags = CLK_GET_RATE_NOCACHE, - .ops = &clk_regmap_mux_closest_ops, - }, - }, -}; - -static struct clk_regmap_div dsi0pll_pclk_src = { - .shift = 0, - .width = 4, - .clkr = { - .hw.init = &(struct clk_init_data){ - .name = "dsi0pll_pclk_src", - .parent_names = (const char *[]){ - "dsi0pll_pclk_src_mux"}, - .num_parents = 1, - .flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT), - .ops = &clk_regmap_div_ops, - }, - }, -}; - -static struct clk_regmap_div dsi0pll_shadow_pclk_src = { - .shift = 0, - .width = 4, - .clkr = { - .hw.init = &(struct clk_init_data){ - .name = "dsi0pll_shadow_pclk_src", - .parent_names = (const char *[]){ - "dsi0pll_shadow_pclk_src_mux"}, - .num_parents = 1, - .flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT), - .ops = &clk_regmap_div_ops, - }, - }, -}; - -static struct clk_regmap_div dsi1pll_pclk_src = { - .shift = 0, - .width = 4, - .clkr = { - .hw.init = &(struct clk_init_data){ - .name = "dsi1pll_pclk_src", - .parent_names = (const char *[]){ - "dsi1pll_pclk_src_mux"}, - .num_parents = 1, - .flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT), - .ops = &clk_regmap_div_ops, - }, - }, -}; - -static struct clk_regmap_div dsi1pll_shadow_pclk_src = { - .shift = 0, - .width = 4, - .clkr = { - .hw.init = &(struct clk_init_data){ - .name = "dsi1pll_shadow_pclk_src", - .parent_names = (const char *[]){ - "dsi1pll_shadow_pclk_src_mux"}, - .num_parents = 1, - .flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT), - .ops = &clk_regmap_div_ops, - }, - }, -}; - -static struct clk_regmap_mux dsi0pll_pclk_mux = { - .shift = 0, - .width = 1, - .clkr = { - .hw.init = &(struct clk_init_data){ - .name = "dsi0_phy_pll_out_dsiclk", - .parent_names = (const char *[]){"dsi0pll_pclk_src", - "dsi0pll_shadow_pclk_src"}, - .num_parents = 2, - .flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT | - CLK_SET_RATE_NO_REPARENT), - .ops = &clk_regmap_mux_closest_ops, - }, - }, -}; - -static struct clk_regmap_mux dsi1pll_pclk_mux = { - .shift = 0, - .width = 1, - .clkr = { - .hw.init = &(struct clk_init_data){ - .name = "dsi1_phy_pll_out_dsiclk", - .parent_names = (const char *[]){"dsi1pll_pclk_src", - "dsi1pll_shadow_pclk_src"}, - .num_parents = 2, - .flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT | - CLK_SET_RATE_NO_REPARENT), - .ops = &clk_regmap_mux_closest_ops, - }, - }, -}; - -static struct clk_hw *mdss_dsi_pllcc_10nm[] = { - [VCO_CLK_0] = &dsi0pll_vco_clk.hw, - [PLL_OUT_DIV_0_CLK] = &dsi0pll_pll_out_div.clkr.hw, - [BITCLK_SRC_0_CLK] = &dsi0pll_bitclk_src.clkr.hw, - [BYTECLK_SRC_0_CLK] = &dsi0pll_byteclk_src.hw, - [POST_BIT_DIV_0_CLK] = &dsi0pll_post_bit_div.hw, - [POST_VCO_DIV_0_CLK] = &dsi0pll_post_vco_div.hw, - [BYTECLK_MUX_0_CLK] = &dsi0pll_byteclk_mux.clkr.hw, - [PCLK_SRC_MUX_0_CLK] = &dsi0pll_pclk_src_mux.clkr.hw, - [PCLK_SRC_0_CLK] = &dsi0pll_pclk_src.clkr.hw, - [PCLK_MUX_0_CLK] = &dsi0pll_pclk_mux.clkr.hw, - [SHADOW_VCO_CLK_0] = &dsi0pll_shadow_vco_clk.hw, - [SHADOW_PLL_OUT_DIV_0_CLK] = &dsi0pll_shadow_pll_out_div.clkr.hw, - [SHADOW_BITCLK_SRC_0_CLK] = &dsi0pll_shadow_bitclk_src.clkr.hw, - [SHADOW_BYTECLK_SRC_0_CLK] = &dsi0pll_shadow_byteclk_src.hw, - [SHADOW_POST_BIT_DIV_0_CLK] = &dsi0pll_shadow_post_bit_div.hw, - [SHADOW_POST_VCO_DIV_0_CLK] = &dsi0pll_shadow_post_vco_div.hw, - [SHADOW_PCLK_SRC_MUX_0_CLK] = &dsi0pll_shadow_pclk_src_mux.clkr.hw, - [SHADOW_PCLK_SRC_0_CLK] = &dsi0pll_shadow_pclk_src.clkr.hw, - [VCO_CLK_1] = &dsi1pll_vco_clk.hw, - [PLL_OUT_DIV_1_CLK] = &dsi1pll_pll_out_div.clkr.hw, - [BITCLK_SRC_1_CLK] = &dsi1pll_bitclk_src.clkr.hw, - [BYTECLK_SRC_1_CLK] = &dsi1pll_byteclk_src.hw, - [POST_BIT_DIV_1_CLK] = &dsi1pll_post_bit_div.hw, - [POST_VCO_DIV_1_CLK] = &dsi1pll_post_vco_div.hw, - [BYTECLK_MUX_1_CLK] = &dsi1pll_byteclk_mux.clkr.hw, - [PCLK_SRC_MUX_1_CLK] = &dsi1pll_pclk_src_mux.clkr.hw, - [PCLK_SRC_1_CLK] = &dsi1pll_pclk_src.clkr.hw, - [PCLK_MUX_1_CLK] = &dsi1pll_pclk_mux.clkr.hw, - [SHADOW_VCO_CLK_1] = &dsi1pll_shadow_vco_clk.hw, - [SHADOW_PLL_OUT_DIV_1_CLK] = &dsi1pll_shadow_pll_out_div.clkr.hw, - [SHADOW_BITCLK_SRC_1_CLK] = &dsi1pll_shadow_bitclk_src.clkr.hw, - [SHADOW_BYTECLK_SRC_1_CLK] = &dsi1pll_shadow_byteclk_src.hw, - [SHADOW_POST_BIT_DIV_1_CLK] = &dsi1pll_shadow_post_bit_div.hw, - [SHADOW_POST_VCO_DIV_1_CLK] = &dsi1pll_shadow_post_vco_div.hw, - [SHADOW_PCLK_SRC_MUX_1_CLK] = &dsi1pll_shadow_pclk_src_mux.clkr.hw, - [SHADOW_PCLK_SRC_1_CLK] = &dsi1pll_shadow_pclk_src.clkr.hw, -}; - -int dsi_pll_clock_register_10nm(struct platform_device *pdev, - struct mdss_pll_resources *pll_res) -{ - int rc = 0, ndx, i; - struct clk *clk; - struct clk_onecell_data *clk_data; - int num_clks = ARRAY_SIZE(mdss_dsi_pllcc_10nm); - struct regmap *rmap; - - ndx = pll_res->index; - - if (ndx >= DSI_PLL_MAX) { - pr_err("pll index(%d) NOT supported\n", ndx); - return -EINVAL; - } - - pll_rsc_db[ndx] = pll_res; - plls[ndx].rsc = pll_res; - pll_res->priv = &plls[ndx]; - pll_res->vco_delay = VCO_DELAY_USEC; - - clk_data = devm_kzalloc(&pdev->dev, sizeof(*clk_data), GFP_KERNEL); - if (!clk_data) - return -ENOMEM; - - clk_data->clks = devm_kcalloc(&pdev->dev, num_clks, - sizeof(struct clk *), GFP_KERNEL); - if (!clk_data->clks) - return -ENOMEM; - - clk_data->clk_num = num_clks; - - /* Establish client data */ - if (ndx == 0) { - rmap = devm_regmap_init(&pdev->dev, &pll_regmap_bus, - pll_res, &dsi_pll_10nm_config); - dsi0pll_pll_out_div.clkr.regmap = rmap; - dsi0pll_shadow_pll_out_div.clkr.regmap = rmap; - - rmap = devm_regmap_init(&pdev->dev, &bitclk_src_regmap_bus, - pll_res, &dsi_pll_10nm_config); - dsi0pll_bitclk_src.clkr.regmap = rmap; - dsi0pll_shadow_bitclk_src.clkr.regmap = rmap; - - rmap = devm_regmap_init(&pdev->dev, &pclk_src_regmap_bus, - pll_res, &dsi_pll_10nm_config); - dsi0pll_pclk_src.clkr.regmap = rmap; - dsi0pll_shadow_pclk_src.clkr.regmap = rmap; - - rmap = devm_regmap_init(&pdev->dev, &mdss_mux_regmap_bus, - pll_res, &dsi_pll_10nm_config); - dsi0pll_pclk_mux.clkr.regmap = rmap; - - rmap = devm_regmap_init(&pdev->dev, &pclk_src_mux_regmap_bus, - pll_res, &dsi_pll_10nm_config); - dsi0pll_pclk_src_mux.clkr.regmap = rmap; - dsi0pll_shadow_pclk_src_mux.clkr.regmap = rmap; - - rmap = devm_regmap_init(&pdev->dev, &mdss_mux_regmap_bus, - pll_res, &dsi_pll_10nm_config); - dsi0pll_byteclk_mux.clkr.regmap = rmap; - - dsi0pll_vco_clk.priv = pll_res; - dsi0pll_shadow_vco_clk.priv = pll_res; - - for (i = VCO_CLK_0; i <= SHADOW_PCLK_SRC_0_CLK; i++) { - clk = devm_clk_register(&pdev->dev, - mdss_dsi_pllcc_10nm[i]); - if (IS_ERR(clk)) { - pr_err("clk registration failed for DSI clock:%d\n", - pll_res->index); - rc = -EINVAL; - goto clk_register_fail; - } - clk_data->clks[i] = clk; - - } - - rc = of_clk_add_provider(pdev->dev.of_node, - of_clk_src_onecell_get, clk_data); - } else { - rmap = devm_regmap_init(&pdev->dev, &pll_regmap_bus, - pll_res, &dsi_pll_10nm_config); - dsi1pll_pll_out_div.clkr.regmap = rmap; - dsi1pll_shadow_pll_out_div.clkr.regmap = rmap; - - rmap = devm_regmap_init(&pdev->dev, &bitclk_src_regmap_bus, - pll_res, &dsi_pll_10nm_config); - dsi1pll_bitclk_src.clkr.regmap = rmap; - dsi1pll_shadow_bitclk_src.clkr.regmap = rmap; - - rmap = devm_regmap_init(&pdev->dev, &pclk_src_regmap_bus, - pll_res, &dsi_pll_10nm_config); - dsi1pll_pclk_src.clkr.regmap = rmap; - dsi1pll_shadow_pclk_src.clkr.regmap = rmap; - - rmap = devm_regmap_init(&pdev->dev, &mdss_mux_regmap_bus, - pll_res, &dsi_pll_10nm_config); - dsi1pll_pclk_mux.clkr.regmap = rmap; - - rmap = devm_regmap_init(&pdev->dev, &pclk_src_mux_regmap_bus, - pll_res, &dsi_pll_10nm_config); - dsi1pll_pclk_src_mux.clkr.regmap = rmap; - dsi1pll_shadow_pclk_src_mux.clkr.regmap = rmap; - - rmap = devm_regmap_init(&pdev->dev, &mdss_mux_regmap_bus, - pll_res, &dsi_pll_10nm_config); - dsi1pll_byteclk_mux.clkr.regmap = rmap; - - dsi1pll_vco_clk.priv = pll_res; - dsi1pll_shadow_vco_clk.priv = pll_res; - - for (i = VCO_CLK_1; i <= SHADOW_PCLK_SRC_1_CLK; i++) { - clk = devm_clk_register(&pdev->dev, - mdss_dsi_pllcc_10nm[i]); - if (IS_ERR(clk)) { - pr_err("clk registration failed for DSI clock:%d\n", - pll_res->index); - rc = -EINVAL; - goto clk_register_fail; - } - clk_data->clks[i] = clk; - - } - - rc = of_clk_add_provider(pdev->dev.of_node, - of_clk_src_onecell_get, clk_data); - } - if (!rc) { - pr_info("Registered DSI PLL ndx=%d, clocks successfully\n", - ndx); - - return rc; - } -clk_register_fail: - return rc; -} diff --git a/pll/dsi_pll_14nm.c b/pll/dsi_pll_14nm.c deleted file mode 100644 index 5ec50bf8d6e5..000000000000 --- a/pll/dsi_pll_14nm.c +++ /dev/null @@ -1,592 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. - */ - -#define pr_fmt(fmt) "%s: " fmt, __func__ - -#include -#include -#include -#include - -#include "pll_drv.h" -#include "dsi_pll.h" -#include "dsi_pll_14nm.h" -#include - -#define VCO_DELAY_USEC 1 - -static struct dsi_pll_db pll_db[DSI_PLL_NUM]; - -static struct regmap_config dsi_pll_14nm_config = { - .reg_bits = 32, - .reg_stride = 4, - .val_bits = 32, - .max_register = 0x588, -}; - -static struct regmap_bus post_n1_div_regmap_bus = { - .reg_write = post_n1_div_set_div, - .reg_read = post_n1_div_get_div, -}; - -static struct regmap_bus n2_div_regmap_bus = { - .reg_write = n2_div_set_div, - .reg_read = n2_div_get_div, -}; - -static struct regmap_bus shadow_n2_div_regmap_bus = { - .reg_write = shadow_n2_div_set_div, - .reg_read = n2_div_get_div, -}; - -static struct regmap_bus dsi_mux_regmap_bus = { - .reg_write = dsi_mux_set_parent_14nm, - .reg_read = dsi_mux_get_parent_14nm, -}; - -/* Op structures */ -static const struct clk_ops clk_ops_dsi_vco = { - .recalc_rate = pll_vco_recalc_rate_14nm, - .set_rate = pll_vco_set_rate_14nm, - .round_rate = pll_vco_round_rate_14nm, - .prepare = pll_vco_prepare_14nm, - .unprepare = pll_vco_unprepare_14nm, -}; - -/* Shadow ops for dynamic refresh */ -static const struct clk_ops clk_ops_shadow_dsi_vco = { - .recalc_rate = pll_vco_recalc_rate_14nm, - .set_rate = shadow_pll_vco_set_rate_14nm, - .round_rate = pll_vco_round_rate_14nm, -}; - -static struct dsi_pll_vco_clk dsi0pll_vco_clk = { - .ref_clk_rate = 19200000UL, - .min_rate = 1300000000UL, - .max_rate = 2600000000UL, - .pll_en_seq_cnt = 1, - .pll_enable_seqs[0] = dsi_pll_enable_seq_14nm, - .hw.init = &(struct clk_init_data){ - .name = "dsi0pll_vco_clk_14nm", - .parent_names = (const char *[]){ "bi_tcxo" }, - .num_parents = 1, - .ops = &clk_ops_dsi_vco, - }, -}; - -static struct dsi_pll_vco_clk dsi0pll_shadow_vco_clk = { - .ref_clk_rate = 19200000u, - .min_rate = 1300000000u, - .max_rate = 2600000000u, - .hw.init = &(struct clk_init_data){ - .name = "dsi0pll_shadow_vco_clk_14nm", - .parent_names = (const char *[]){ "bi_tcxo" }, - .num_parents = 1, - .ops = &clk_ops_shadow_dsi_vco, - }, -}; - -static struct dsi_pll_vco_clk dsi1pll_vco_clk = { - .ref_clk_rate = 19200000UL, - .min_rate = 1300000000UL, - .max_rate = 2600000000UL, - .pll_en_seq_cnt = 1, - .pll_enable_seqs[0] = dsi_pll_enable_seq_14nm, - .hw.init = &(struct clk_init_data){ - .name = "dsi1pll_vco_clk_14nm", - .parent_names = (const char *[]){ "bi_tcxo" }, - .num_parents = 1, - .ops = &clk_ops_dsi_vco, - }, -}; - -static struct dsi_pll_vco_clk dsi1pll_shadow_vco_clk = { - .ref_clk_rate = 19200000u, - .min_rate = 1300000000u, - .max_rate = 2600000000u, - .pll_en_seq_cnt = 1, - .pll_enable_seqs[0] = dsi_pll_enable_seq_14nm, - .hw.init = &(struct clk_init_data){ - .name = "dsi1pll_shadow_vco_clk_14nm", - .parent_names = (const char *[]){ "bi_tcxo" }, - .num_parents = 1, - .ops = &clk_ops_shadow_dsi_vco, - }, -}; - -static struct clk_regmap_div dsi0pll_post_n1_div_clk = { - .reg = 0x48, - .shift = 0, - .width = 4, - - .clkr = { - .hw.init = &(struct clk_init_data){ - .name = "dsi0pll_post_n1_div_clk", - .parent_names = - (const char *[]){ "dsi0pll_vco_clk_14nm" }, - .num_parents = 1, - .flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT), - .ops = &clk_regmap_div_ops, - }, - }, -}; - -static struct clk_regmap_div dsi0pll_shadow_post_n1_div_clk = { - .reg = 0x48, - .shift = 0, - .width = 4, - - .clkr = { - .hw.init = &(struct clk_init_data){ - .name = "dsi0pll_shadow_post_n1_div_clk", - .parent_names = - (const char *[]){"dsi0pll_shadow_vco_clk_14nm"}, - .num_parents = 1, - .flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT), - .ops = &clk_regmap_div_ops, - }, - }, -}; - -static struct clk_regmap_div dsi1pll_post_n1_div_clk = { - .reg = 0x48, - .shift = 0, - .width = 4, - - .clkr = { - .hw.init = &(struct clk_init_data){ - .name = "dsi1pll_post_n1_div_clk", - .parent_names = - (const char *[]){ "dsi1pll_vco_clk_14nm" }, - .num_parents = 1, - .flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT), - .ops = &clk_regmap_div_ops, - }, - }, -}; - -static struct clk_regmap_div dsi1pll_shadow_post_n1_div_clk = { - .reg = 0x48, - .shift = 0, - .width = 4, - - .clkr = { - .hw.init = &(struct clk_init_data){ - .name = "dsi1pll_shadow_post_n1_div_clk", - .parent_names = - (const char *[]){"dsi1pll_shadow_vco_clk_14nm"}, - .num_parents = 1, - .flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT), - .ops = &clk_regmap_div_ops, - }, - }, -}; - -static struct clk_regmap_div dsi0pll_n2_div_clk = { - .reg = 0x48, - .shift = 0, - .width = 4, - - .clkr = { - .hw.init = &(struct clk_init_data){ - .name = "dsi0pll_n2_div_clk", - .parent_names = - (const char *[]){ "dsi0pll_post_n1_div_clk" }, - .num_parents = 1, - .flags = CLK_GET_RATE_NOCACHE, - .ops = &clk_regmap_div_ops, - }, - }, -}; - -static struct clk_regmap_div dsi0pll_shadow_n2_div_clk = { - .reg = 0x48, - .shift = 0, - .width = 4, - - .clkr = { - .hw.init = &(struct clk_init_data){ - .name = "dsi0pll_shadow_n2_div_clk", - .parent_names = - (const char *[]){ "dsi0pll_shadow_post_n1_div_clk" }, - .num_parents = 1, - .flags = CLK_GET_RATE_NOCACHE, - .ops = &clk_regmap_div_ops, - }, - }, -}; - -static struct clk_regmap_div dsi1pll_n2_div_clk = { - .reg = 0x48, - .shift = 0, - .width = 4, - - .clkr = { - .hw.init = &(struct clk_init_data){ - .name = "dsi1pll_n2_div_clk", - .parent_names = - (const char *[]){ "dsi1pll_post_n1_div_clk" }, - .num_parents = 1, - .flags = CLK_GET_RATE_NOCACHE, - .ops = &clk_regmap_div_ops, - }, - }, -}; - -static struct clk_regmap_div dsi1pll_shadow_n2_div_clk = { - .reg = 0x48, - .shift = 0, - .width = 4, - - .clkr = { - .hw.init = &(struct clk_init_data){ - .name = "dsi1pll_shadow_n2_div_clk", - .parent_names = - (const char *[]){ "dsi1pll_shadow_post_n1_div_clk" }, - .num_parents = 1, - .flags = CLK_GET_RATE_NOCACHE, - .ops = &clk_regmap_div_ops, - }, - }, -}; - -static struct clk_fixed_factor dsi0pll_pixel_clk_src = { - .div = 2, - .mult = 1, - - .hw.init = &(struct clk_init_data){ - .name = "dsi0pll_pixel_clk_src", - .parent_names = (const char *[]){ "dsi0pll_n2_div_clk" }, - .num_parents = 1, - .flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT), - .ops = &clk_fixed_factor_ops, - }, -}; - -static struct clk_fixed_factor dsi0pll_shadow_pixel_clk_src = { - .div = 2, - .mult = 1, - - .hw.init = &(struct clk_init_data){ - .name = "dsi0pll_shadow_pixel_clk_src", - .parent_names = (const char *[]){ "dsi0pll_shadow_n2_div_clk" }, - .num_parents = 1, - .flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT), - .ops = &clk_fixed_factor_ops, - }, -}; - -static struct clk_fixed_factor dsi1pll_pixel_clk_src = { - .div = 2, - .mult = 1, - - .hw.init = &(struct clk_init_data){ - .name = "dsi1pll_pixel_clk_src", - .parent_names = (const char *[]){ "dsi1pll_n2_div_clk" }, - .num_parents = 1, - .flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT), - .ops = &clk_fixed_factor_ops, - }, -}; - -static struct clk_fixed_factor dsi1pll_shadow_pixel_clk_src = { - .div = 2, - .mult = 1, - - .hw.init = &(struct clk_init_data){ - .name = "dsi1pll_shadow_pixel_clk_src", - .parent_names = (const char *[]){ "dsi1pll_shadow_n2_div_clk" }, - .num_parents = 1, - .flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT), - .ops = &clk_fixed_factor_ops, - }, -}; - -static struct clk_regmap_mux dsi0pll_pixel_clk_mux = { - .reg = 0x48, - .shift = 0, - .width = 1, - - .clkr = { - .hw.init = &(struct clk_init_data){ - .name = "dsi0_phy_pll_out_dsiclk", - .parent_names = - (const char *[]){ "dsi0pll_pixel_clk_src", - "dsi0pll_shadow_pixel_clk_src"}, - .num_parents = 2, - .flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT), - .ops = &clk_regmap_mux_closest_ops, - }, - }, -}; - -static struct clk_regmap_mux dsi1pll_pixel_clk_mux = { - .reg = 0x48, - .shift = 0, - .width = 1, - - .clkr = { - .hw.init = &(struct clk_init_data){ - .name = "dsi1pll_pixel_clk_mux", - .parent_names = - (const char *[]){ "dsi1pll_pixel_clk_src", - "dsi1pll_shadow_pixel_clk_src"}, - .num_parents = 2, - .flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT), - .ops = &clk_regmap_mux_closest_ops, - }, - }, -}; - -static struct clk_fixed_factor dsi0pll_byte_clk_src = { - .div = 8, - .mult = 1, - - .hw.init = &(struct clk_init_data){ - .name = "dsi0pll_byte_clk_src", - .parent_names = (const char *[]){ "dsi0pll_post_n1_div_clk" }, - .num_parents = 1, - .flags = (CLK_SET_RATE_PARENT), - .ops = &clk_fixed_factor_ops, - }, -}; - -static struct clk_fixed_factor dsi0pll_shadow_byte_clk_src = { - .div = 8, - .mult = 1, - - .hw.init = &(struct clk_init_data){ - .name = "dsi0pll_shadow_byte_clk_src", - .parent_names = - (const char *[]){ "dsi0pll_shadow_post_n1_div_clk" }, - .num_parents = 1, - .flags = (CLK_SET_RATE_PARENT), - .ops = &clk_fixed_factor_ops, - }, -}; - -static struct clk_fixed_factor dsi1pll_byte_clk_src = { - .div = 8, - .mult = 1, - - .hw.init = &(struct clk_init_data){ - .name = "dsi1pll_byte_clk_src", - .parent_names = (const char *[]){ "dsi1pll_post_n1_div_clk" }, - .num_parents = 1, - .flags = (CLK_SET_RATE_PARENT), - .ops = &clk_fixed_factor_ops, - }, -}; - -static struct clk_fixed_factor dsi1pll_shadow_byte_clk_src = { - .div = 8, - .mult = 1, - - .hw.init = &(struct clk_init_data){ - .name = "dsi1pll_shadow_byte_clk_src", - .parent_names = - (const char *[]){ "dsi1pll_shadow_post_n1_div_clk" }, - .num_parents = 1, - .flags = (CLK_SET_RATE_PARENT), - .ops = &clk_fixed_factor_ops, - }, -}; - -static struct clk_regmap_mux dsi0pll_byte_clk_mux = { - .reg = 0x48, - .shift = 0, - .width = 1, - - .clkr = { - .hw.init = &(struct clk_init_data){ - .name = "dsi0_phy_pll_out_byteclk", - .parent_names = - (const char *[]){"dsi0pll_byte_clk_src", - "dsi0pll_shadow_byte_clk_src"}, - .num_parents = 2, - .ops = &clk_regmap_mux_closest_ops, - .flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT), - }, - }, -}; - -static struct clk_regmap_mux dsi1pll_byte_clk_mux = { - .reg = 0x48, - .shift = 0, - .width = 1, - - .clkr = { - .hw.init = &(struct clk_init_data){ - .name = "dsi1pll_byte_clk_mux", - .parent_names = - (const char *[]){"dsi1pll_byte_clk_src", - "dsi1pll_shadow_byte_clk_src"}, - .num_parents = 2, - .ops = &clk_regmap_mux_closest_ops, - .flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT), - }, - }, -}; - -static struct clk_hw *mdss_dsi_pllcc_14nm[] = { - [BYTE0_MUX_CLK] = &dsi0pll_byte_clk_mux.clkr.hw, - [BYTE0_SRC_CLK] = &dsi0pll_byte_clk_src.hw, - [PIX0_MUX_CLK] = &dsi0pll_pixel_clk_mux.clkr.hw, - [PIX0_SRC_CLK] = &dsi0pll_pixel_clk_src.hw, - [N2_DIV_0_CLK] = &dsi0pll_n2_div_clk.clkr.hw, - [POST_N1_DIV_0_CLK] = &dsi0pll_post_n1_div_clk.clkr.hw, - [VCO_CLK_0_CLK] = &dsi0pll_vco_clk.hw, - [SHADOW_BYTE0_SRC_CLK] = &dsi0pll_shadow_byte_clk_src.hw, - [SHADOW_PIX0_SRC_CLK] = &dsi0pll_shadow_pixel_clk_src.hw, - [SHADOW_N2_DIV_0_CLK] = &dsi0pll_shadow_n2_div_clk.clkr.hw, - [SHADOW_POST_N1_DIV_0_CLK] = &dsi0pll_shadow_post_n1_div_clk.clkr.hw, - [SHADOW_VCO_CLK_0_CLK] = &dsi0pll_shadow_vco_clk.hw, - [BYTE1_MUX_CLK] = &dsi1pll_byte_clk_mux.clkr.hw, - [BYTE1_SRC_CLK] = &dsi1pll_byte_clk_src.hw, - [PIX1_MUX_CLK] = &dsi1pll_pixel_clk_mux.clkr.hw, - [PIX1_SRC_CLK] = &dsi1pll_pixel_clk_src.hw, - [N2_DIV_1_CLK] = &dsi1pll_n2_div_clk.clkr.hw, - [POST_N1_DIV_1_CLK] = &dsi1pll_post_n1_div_clk.clkr.hw, - [VCO_CLK_1_CLK] = &dsi1pll_vco_clk.hw, - [SHADOW_BYTE1_SRC_CLK] = &dsi1pll_shadow_byte_clk_src.hw, - [SHADOW_PIX1_SRC_CLK] = &dsi1pll_shadow_pixel_clk_src.hw, - [SHADOW_N2_DIV_1_CLK] = &dsi1pll_shadow_n2_div_clk.clkr.hw, - [SHADOW_POST_N1_DIV_1_CLK] = &dsi1pll_shadow_post_n1_div_clk.clkr.hw, - [SHADOW_VCO_CLK_1_CLK] = &dsi1pll_shadow_vco_clk.hw, -}; - -int dsi_pll_clock_register_14nm(struct platform_device *pdev, - struct mdss_pll_resources *pll_res) -{ - int rc = 0, ndx, i; - int const ssc_freq_default = 31500; /* default h/w recommended value */ - int const ssc_ppm_default = 5000; /* default h/w recommended value */ - struct dsi_pll_db *pdb; - struct clk_onecell_data *clk_data; - struct clk *clk; - struct regmap *regmap; - int num_clks = ARRAY_SIZE(mdss_dsi_pllcc_14nm); - - if (pll_res->index >= DSI_PLL_NUM) { - pr_err("pll ndx=%d is NOT supported\n", pll_res->index); - return -EINVAL; - } - - ndx = pll_res->index; - pdb = &pll_db[ndx]; - pll_res->priv = pdb; - pdb->pll = pll_res; - ndx++; - ndx %= DSI_PLL_NUM; - pdb->next = &pll_db[ndx]; - - if (pll_res->ssc_en) { - if (!pll_res->ssc_freq) - pll_res->ssc_freq = ssc_freq_default; - if (!pll_res->ssc_ppm) - pll_res->ssc_ppm = ssc_ppm_default; - } - - clk_data = devm_kzalloc(&pdev->dev, sizeof(*clk_data), GFP_KERNEL); - if (!clk_data) - return -ENOMEM; - - clk_data->clks = devm_kcalloc(&pdev->dev, num_clks, - sizeof(struct clk *), GFP_KERNEL); - if (!clk_data->clks) - return -ENOMEM; - - clk_data->clk_num = num_clks; - - /* Set client data to mux, div and vco clocks. */ - if (pll_res->index == DSI_PLL_1) { - regmap = devm_regmap_init(&pdev->dev, &post_n1_div_regmap_bus, - pll_res, &dsi_pll_14nm_config); - dsi1pll_post_n1_div_clk.clkr.regmap = regmap; - dsi1pll_shadow_post_n1_div_clk.clkr.regmap = regmap; - - regmap = devm_regmap_init(&pdev->dev, &n2_div_regmap_bus, - pll_res, &dsi_pll_14nm_config); - dsi1pll_n2_div_clk.clkr.regmap = regmap; - - regmap = devm_regmap_init(&pdev->dev, &shadow_n2_div_regmap_bus, - pll_res, &dsi_pll_14nm_config); - dsi1pll_shadow_n2_div_clk.clkr.regmap = regmap; - - regmap = devm_regmap_init(&pdev->dev, &dsi_mux_regmap_bus, - pll_res, &dsi_pll_14nm_config); - dsi1pll_byte_clk_mux.clkr.regmap = regmap; - dsi1pll_pixel_clk_mux.clkr.regmap = regmap; - - dsi1pll_vco_clk.priv = pll_res; - dsi1pll_shadow_vco_clk.priv = pll_res; - - pll_res->vco_delay = VCO_DELAY_USEC; - - for (i = BYTE1_MUX_CLK; i <= SHADOW_VCO_CLK_1_CLK; i++) { - pr_debug("register clk: %d index: %d\n", - i, pll_res->index); - clk = devm_clk_register(&pdev->dev, - mdss_dsi_pllcc_14nm[i]); - if (IS_ERR(clk)) { - pr_err("clk registration failed for DSI: %d\n", - pll_res->index); - rc = -EINVAL; - goto clk_reg_fail; - } - clk_data->clks[i] = clk; - } - - rc = of_clk_add_provider(pdev->dev.of_node, - of_clk_src_onecell_get, clk_data); - } else { - regmap = devm_regmap_init(&pdev->dev, &post_n1_div_regmap_bus, - pll_res, &dsi_pll_14nm_config); - dsi0pll_post_n1_div_clk.clkr.regmap = regmap; - dsi0pll_shadow_post_n1_div_clk.clkr.regmap = regmap; - - regmap = devm_regmap_init(&pdev->dev, &n2_div_regmap_bus, - pll_res, &dsi_pll_14nm_config); - dsi0pll_n2_div_clk.clkr.regmap = regmap; - - regmap = devm_regmap_init(&pdev->dev, &shadow_n2_div_regmap_bus, - pll_res, &dsi_pll_14nm_config); - dsi0pll_shadow_n2_div_clk.clkr.regmap = regmap; - - regmap = devm_regmap_init(&pdev->dev, &dsi_mux_regmap_bus, - pll_res, &dsi_pll_14nm_config); - dsi0pll_byte_clk_mux.clkr.regmap = regmap; - dsi0pll_pixel_clk_mux.clkr.regmap = regmap; - - dsi0pll_vco_clk.priv = pll_res; - dsi0pll_shadow_vco_clk.priv = pll_res; - pll_res->vco_delay = VCO_DELAY_USEC; - - for (i = BYTE0_MUX_CLK; i <= SHADOW_VCO_CLK_0_CLK; i++) { - pr_debug("reg clk: %d index: %d\n", i, pll_res->index); - clk = devm_clk_register(&pdev->dev, - mdss_dsi_pllcc_14nm[i]); - if (IS_ERR(clk)) { - pr_err("clk registration failed for DSI: %d\n", - pll_res->index); - rc = -EINVAL; - goto clk_reg_fail; - } - clk_data->clks[i] = clk; - } - - rc = of_clk_add_provider(pdev->dev.of_node, - of_clk_src_onecell_get, clk_data); - } - - if (!rc) { - pr_info("Registered DSI PLL ndx=%d clocks successfully\n", - pll_res->index); - return rc; - } - -clk_reg_fail: - return rc; -} diff --git a/pll/dsi_pll_14nm.h b/pll/dsi_pll_14nm.h deleted file mode 100644 index abc08f639a57..000000000000 --- a/pll/dsi_pll_14nm.h +++ /dev/null @@ -1,220 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. - */ - -#ifndef MDSS_DSI_PLL_14NM_H -#define MDSS_DSI_PLL_14NM_H - -#define DSIPHY_CMN_CLK_CFG0 0x0010 -#define DSIPHY_CMN_CLK_CFG1 0x0014 -#define DSIPHY_CMN_GLBL_TEST_CTRL 0x0018 - -#define DSIPHY_CMN_PLL_CNTRL 0x0048 -#define DSIPHY_CMN_CTRL_0 0x001c -#define DSIPHY_CMN_CTRL_1 0x0020 - -#define DSIPHY_CMN_LDO_CNTRL 0x004c - -#define DSIPHY_PLL_IE_TRIM 0x0400 -#define DSIPHY_PLL_IP_TRIM 0x0404 - -#define DSIPHY_PLL_IPTAT_TRIM 0x0410 - -#define DSIPHY_PLL_CLKBUFLR_EN 0x041c - -#define DSIPHY_PLL_SYSCLK_EN_RESET 0x0428 -#define DSIPHY_PLL_RESETSM_CNTRL 0x042c -#define DSIPHY_PLL_RESETSM_CNTRL2 0x0430 -#define DSIPHY_PLL_RESETSM_CNTRL3 0x0434 -#define DSIPHY_PLL_RESETSM_CNTRL4 0x0438 -#define DSIPHY_PLL_RESETSM_CNTRL5 0x043c -#define DSIPHY_PLL_KVCO_DIV_REF1 0x0440 -#define DSIPHY_PLL_KVCO_DIV_REF2 0x0444 -#define DSIPHY_PLL_KVCO_COUNT1 0x0448 -#define DSIPHY_PLL_KVCO_COUNT2 0x044c -#define DSIPHY_PLL_VREF_CFG1 0x045c - -#define DSIPHY_PLL_KVCO_CODE 0x0458 - -#define DSIPHY_PLL_VCO_DIV_REF1 0x046c -#define DSIPHY_PLL_VCO_DIV_REF2 0x0470 -#define DSIPHY_PLL_VCO_COUNT1 0x0474 -#define DSIPHY_PLL_VCO_COUNT2 0x0478 -#define DSIPHY_PLL_PLLLOCK_CMP1 0x047c -#define DSIPHY_PLL_PLLLOCK_CMP2 0x0480 -#define DSIPHY_PLL_PLLLOCK_CMP3 0x0484 -#define DSIPHY_PLL_PLLLOCK_CMP_EN 0x0488 -#define DSIPHY_PLL_PLL_VCO_TUNE 0x048C -#define DSIPHY_PLL_DEC_START 0x0490 -#define DSIPHY_PLL_SSC_EN_CENTER 0x0494 -#define DSIPHY_PLL_SSC_ADJ_PER1 0x0498 -#define DSIPHY_PLL_SSC_ADJ_PER2 0x049c -#define DSIPHY_PLL_SSC_PER1 0x04a0 -#define DSIPHY_PLL_SSC_PER2 0x04a4 -#define DSIPHY_PLL_SSC_STEP_SIZE1 0x04a8 -#define DSIPHY_PLL_SSC_STEP_SIZE2 0x04ac -#define DSIPHY_PLL_DIV_FRAC_START1 0x04b4 -#define DSIPHY_PLL_DIV_FRAC_START2 0x04b8 -#define DSIPHY_PLL_DIV_FRAC_START3 0x04bc -#define DSIPHY_PLL_TXCLK_EN 0x04c0 -#define DSIPHY_PLL_PLL_CRCTRL 0x04c4 - -#define DSIPHY_PLL_RESET_SM_READY_STATUS 0x04cc - -#define DSIPHY_PLL_PLL_MISC1 0x04e8 - -#define DSIPHY_PLL_CP_SET_CUR 0x04f0 -#define DSIPHY_PLL_PLL_ICPMSET 0x04f4 -#define DSIPHY_PLL_PLL_ICPCSET 0x04f8 -#define DSIPHY_PLL_PLL_ICP_SET 0x04fc -#define DSIPHY_PLL_PLL_LPF1 0x0500 -#define DSIPHY_PLL_PLL_LPF2_POSTDIV 0x0504 -#define DSIPHY_PLL_PLL_BANDGAP 0x0508 - -#define DSI_DYNAMIC_REFRESH_PLL_CTRL15 0x050 -#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_UPPER_ADDR 0x094 -#define DSI_DYNAMIC_REFRESH_PLL_UPPER_ADDR2 0x098 - -struct dsi_pll_input { - u32 fref; /* 19.2 Mhz, reference clk */ - u32 fdata; /* bit clock rate */ - u32 dsiclk_sel; /* 1, reg: 0x0014 */ - u32 n2div; /* 1, reg: 0x0010, bit 4-7 */ - u32 ssc_en; /* 1, reg: 0x0494, bit 0 */ - u32 ldo_en; /* 0, reg: 0x004c, bit 0 */ - - /* fixed */ - u32 refclk_dbler_en; /* 0, reg: 0x04c0, bit 1 */ - u32 vco_measure_time; /* 5, unknown */ - u32 kvco_measure_time; /* 5, unknown */ - u32 bandgap_timer; /* 4, reg: 0x0430, bit 3 - 5 */ - u32 pll_wakeup_timer; /* 5, reg: 0x043c, bit 0 - 2 */ - u32 plllock_cnt; /* 1, reg: 0x0488, bit 1 - 2 */ - u32 plllock_rng; /* 1, reg: 0x0488, bit 3 - 4 */ - u32 ssc_center; /* 0, reg: 0x0494, bit 1 */ - u32 ssc_adj_period; /* 37, reg: 0x498, bit 0 - 9 */ - u32 ssc_spread; /* 0.005 */ - u32 ssc_freq; /* unknown */ - u32 pll_ie_trim; /* 4, reg: 0x0400 */ - u32 pll_ip_trim; /* 4, reg: 0x0404 */ - u32 pll_iptat_trim; /* reg: 0x0410 */ - u32 pll_cpcset_cur; /* 1, reg: 0x04f0, bit 0 - 2 */ - u32 pll_cpmset_cur; /* 1, reg: 0x04f0, bit 3 - 5 */ - - u32 pll_icpmset; /* 4, reg: 0x04fc, bit 3 - 5 */ - u32 pll_icpcset; /* 4, reg: 0x04fc, bit 0 - 2 */ - - u32 pll_icpmset_p; /* 0, reg: 0x04f4, bit 0 - 2 */ - u32 pll_icpmset_m; /* 0, reg: 0x04f4, bit 3 - 5 */ - - u32 pll_icpcset_p; /* 0, reg: 0x04f8, bit 0 - 2 */ - u32 pll_icpcset_m; /* 0, reg: 0x04f8, bit 3 - 5 */ - - u32 pll_lpf_res1; /* 3, reg: 0x0504, bit 0 - 3 */ - u32 pll_lpf_cap1; /* 11, reg: 0x0500, bit 0 - 3 */ - u32 pll_lpf_cap2; /* 1, reg: 0x0500, bit 4 - 7 */ - u32 pll_c3ctrl; /* 2, reg: 0x04c4 */ - u32 pll_r3ctrl; /* 1, reg: 0x04c4 */ -}; - -struct dsi_pll_output { - u32 pll_txclk_en; /* reg: 0x04c0 */ - u32 dec_start; /* reg: 0x0490 */ - u32 div_frac_start; /* reg: 0x04b4, 0x4b8, 0x04bc */ - u32 ssc_period; /* reg: 0x04a0, 0x04a4 */ - u32 ssc_step_size; /* reg: 0x04a8, 0x04ac */ - u32 plllock_cmp; /* reg: 0x047c, 0x0480, 0x0484 */ - u32 pll_vco_div_ref; /* reg: 0x046c, 0x0470 */ - u32 pll_vco_count; /* reg: 0x0474, 0x0478 */ - u32 pll_kvco_div_ref; /* reg: 0x0440, 0x0444 */ - u32 pll_kvco_count; /* reg: 0x0448, 0x044c */ - u32 pll_misc1; /* reg: 0x04e8 */ - u32 pll_lpf2_postdiv; /* reg: 0x0504 */ - u32 pll_resetsm_cntrl; /* reg: 0x042c */ - u32 pll_resetsm_cntrl2; /* reg: 0x0430 */ - u32 pll_resetsm_cntrl5; /* reg: 0x043c */ - u32 pll_kvco_code; /* reg: 0x0458 */ - - u32 cmn_clk_cfg0; /* reg: 0x0010 */ - u32 cmn_clk_cfg1; /* reg: 0x0014 */ - u32 cmn_ldo_cntrl; /* reg: 0x004c */ - - u32 pll_postdiv; /* vco */ - u32 pll_n1div; /* vco */ - u32 pll_n2div; /* hr_oclk3, pixel */ - u32 fcvo; -}; - -enum { - DSI_PLL_0, - DSI_PLL_1, - DSI_PLL_NUM -}; - -struct dsi_pll_db { - struct dsi_pll_db *next; - struct mdss_pll_resources *pll; - struct dsi_pll_input in; - struct dsi_pll_output out; - int source_setup_done; -}; - -enum { - PLL_OUTPUT_NONE, - PLL_OUTPUT_RIGHT, - PLL_OUTPUT_LEFT, - PLL_OUTPUT_BOTH -}; - -enum { - PLL_SOURCE_FROM_LEFT, - PLL_SOURCE_FROM_RIGHT -}; - -enum { - PLL_UNKNOWN, - PLL_STANDALONE, - PLL_SLAVE, - PLL_MASTER -}; - -int pll_vco_set_rate_14nm(struct clk_hw *hw, unsigned long rate, - unsigned long parent_rate); -int shadow_pll_vco_set_rate_14nm(struct clk_hw *hw, unsigned long rate, - unsigned long parent_rate); -long pll_vco_round_rate_14nm(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate); -unsigned long pll_vco_recalc_rate_14nm(struct clk_hw *hw, - unsigned long parent_rate); - -int pll_vco_prepare_14nm(struct clk_hw *hw); -void pll_vco_unprepare_14nm(struct clk_hw *hw); - -int shadow_post_n1_div_set_div(void *context, - unsigned int reg, unsigned int div); -int shadow_post_n1_div_get_div(void *context, - unsigned int reg, unsigned int *div); -int shadow_n2_div_set_div(void *context, unsigned int reg, unsigned int div); -int shadow_n2_div_get_div(void *context, unsigned int reg, unsigned int *div); - -int post_n1_div_set_div(void *context, unsigned int reg, unsigned int div); -int post_n1_div_get_div(void *context, unsigned int reg, unsigned int *div); -int n2_div_set_div(void *context, unsigned int reg, unsigned int div); -int n2_div_get_div(void *context, unsigned int reg, unsigned int *div); -int dsi_pll_enable_seq_14nm(struct mdss_pll_resources *pll); -int dsi_mux_set_parent_14nm(void *context, unsigned int reg, unsigned int val); -int dsi_mux_get_parent_14nm(void *context, unsigned int reg, unsigned int *val); - -#endif /* MDSS_DSI_PLL_14NM_H */ diff --git a/pll/dsi_pll_14nm_util.c b/pll/dsi_pll_14nm_util.c deleted file mode 100644 index 5cd7869cf77f..000000000000 --- a/pll/dsi_pll_14nm_util.c +++ /dev/null @@ -1,1149 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. - */ - -#define pr_fmt(fmt) "%s: " fmt, __func__ - -#include -#include -#include -#include - -#include "pll_drv.h" -#include "dsi_pll.h" -#include "dsi_pll_14nm.h" - -#define DSI_PLL_POLL_MAX_READS 15 -#define DSI_PLL_POLL_TIMEOUT_US 1000 -#define MSM8996_DSI_PLL_REVISION_2 2 - -#define VCO_REF_CLK_RATE 19200000 - -#define CEIL(x, y) (((x) + ((y)-1)) / (y)) - -static int mdss_pll_read_stored_trim_codes( - struct mdss_pll_resources *dsi_pll_res, s64 vco_clk_rate) -{ - int i; - int rc = 0; - bool found = false; - - if (!dsi_pll_res->dfps) { - rc = -EINVAL; - goto end_read; - } - - for (i = 0; i < dsi_pll_res->dfps->vco_rate_cnt; i++) { - struct dfps_codes_info *codes_info = - &dsi_pll_res->dfps->codes_dfps[i]; - - pr_debug("valid=%d frame_rate=%d, code %d %d\n", - codes_info->is_valid, - codes_info->clk_rate, codes_info->pll_codes.pll_codes_1, - codes_info->pll_codes.pll_codes_2); - - if (vco_clk_rate != codes_info->clk_rate && - codes_info->is_valid) - continue; - - dsi_pll_res->cache_pll_trim_codes[0] = - codes_info->pll_codes.pll_codes_1; - dsi_pll_res->cache_pll_trim_codes[1] = - codes_info->pll_codes.pll_codes_2; - found = true; - break; - } - - if (!found) { - rc = -EINVAL; - goto end_read; - } - - pr_debug("core_kvco_code=0x%x core_vco_tune=0x%x\n", - dsi_pll_res->cache_pll_trim_codes[0], - dsi_pll_res->cache_pll_trim_codes[1]); - -end_read: - return rc; -} - -int post_n1_div_set_div(void *context, unsigned int reg, unsigned int div) -{ - struct mdss_pll_resources *pll = context; - struct dsi_pll_db *pdb; - struct dsi_pll_output *pout; - int rc; - u32 n1div = 0; - - rc = mdss_pll_resource_enable(pll, true); - if (rc) { - pr_err("Failed to enable mdss dsi pll resources\n"); - return rc; - } - - /* in common clock framework the divider value provided is one less */ - div++; - - pdb = (struct dsi_pll_db *)pll->priv; - pout = &pdb->out; - - /* - * vco rate = bit_clk * postdiv * n1div - * vco range from 1300 to 2600 Mhz - * postdiv = 1 - * n1div = 1 to 15 - * n1div = roundup(1300Mhz / bit_clk) - * support bit_clk above 86.67Mhz - */ - - pout->pll_n1div = div; - - n1div = MDSS_PLL_REG_R(pll->pll_base, DSIPHY_CMN_CLK_CFG0); - n1div &= ~0xf; - n1div |= (div & 0xf); - MDSS_PLL_REG_W(pll->pll_base, DSIPHY_CMN_CLK_CFG0, n1div); - /* ensure n1 divider is programed */ - wmb(); - pr_debug("ndx=%d div=%d postdiv=%x n1div=%x\n", - pll->index, div, pout->pll_postdiv, pout->pll_n1div); - - mdss_pll_resource_enable(pll, false); - - return 0; -} - -int post_n1_div_get_div(void *context, unsigned int reg, unsigned int *div) -{ - int rc; - struct mdss_pll_resources *pll = context; - struct dsi_pll_db *pdb; - struct dsi_pll_output *pout; - - pdb = (struct dsi_pll_db *)pll->priv; - pout = &pdb->out; - - if (is_gdsc_disabled(pll)) - return 0; - - rc = mdss_pll_resource_enable(pll, true); - if (rc) { - pr_err("Failed to enable mdss dsi pll resources\n"); - return rc; - } - - /* - * postdiv = 1/2/4/8 - * n1div = 1 - 15 - * fot the time being, assume postdiv = 1 - */ - - *div = MDSS_PLL_REG_R(pll->pll_base, DSIPHY_CMN_CLK_CFG0); - *div &= 0xF; - - /* - * initialize n1div here, it will get updated when - * corresponding set_div is called. - */ - pout->pll_n1div = *div; - - /* common clock framework will add one to the divider value sent */ - if (*div == 0) - *div = 1; /* value of zero means div is 2 as per SWI */ - else - *div -= 1; - - pr_debug("post n1 get div = %d\n", *div); - - mdss_pll_resource_enable(pll, false); - - return rc; -} - -int n2_div_set_div(void *context, unsigned int reg, unsigned int div) -{ - int rc; - u32 n2div; - struct mdss_pll_resources *pll = context; - struct dsi_pll_db *pdb; - struct dsi_pll_output *pout; - struct mdss_pll_resources *slave; - - rc = mdss_pll_resource_enable(pll, true); - if (rc) { - pr_err("Failed to enable mdss dsi pll resources\n"); - return rc; - } - - /* - * in common clock framework the actual divider value - * provided is one less. - */ - div++; - - pdb = (struct dsi_pll_db *)pll->priv; - pout = &pdb->out; - - /* this is for pixel clock */ - n2div = MDSS_PLL_REG_R(pll->pll_base, DSIPHY_CMN_CLK_CFG0); - n2div &= ~0xf0; /* bits 4 to 7 */ - n2div |= (div << 4); - MDSS_PLL_REG_W(pll->pll_base, DSIPHY_CMN_CLK_CFG0, n2div); - - /* commit slave if split display is enabled */ - slave = pll->slave; - if (slave) - MDSS_PLL_REG_W(slave->pll_base, DSIPHY_CMN_CLK_CFG0, n2div); - - pout->pll_n2div = div; - - /* set dsiclk_sel=1 so that n2div *= 2 */ - MDSS_PLL_REG_W(pll->pll_base, DSIPHY_CMN_CLK_CFG1, 1); - pr_debug("ndx=%d div=%d n2div=%x\n", pll->index, div, n2div); - - mdss_pll_resource_enable(pll, false); - - return rc; -} - -int shadow_n2_div_set_div(void *context, unsigned int reg, unsigned int div) -{ - struct mdss_pll_resources *pll = context; - struct dsi_pll_db *pdb; - struct dsi_pll_output *pout; - u32 data; - - pdb = pll->priv; - pout = &pdb->out; - - /* - * in common clock framework the actual divider value - * provided is one less. - */ - div++; - - pout->pll_n2div = div; - - data = (pout->pll_n1div | (pout->pll_n2div << 4)); - MDSS_DYN_PLL_REG_W(pll->dyn_pll_base, - DSI_DYNAMIC_REFRESH_PLL_CTRL19, - DSIPHY_CMN_CLK_CFG0, DSIPHY_CMN_CLK_CFG1, - data, 1); - return 0; -} - -int n2_div_get_div(void *context, unsigned int reg, unsigned int *div) -{ - int rc; - u32 n2div; - struct mdss_pll_resources *pll = context; - struct dsi_pll_db *pdb; - struct dsi_pll_output *pout; - - if (is_gdsc_disabled(pll)) - return 0; - - pdb = (struct dsi_pll_db *)pll->priv; - pout = &pdb->out; - - rc = mdss_pll_resource_enable(pll, true); - if (rc) { - pr_err("Failed to enable mdss dsi pll=%d resources\n", - pll->index); - return rc; - } - - n2div = MDSS_PLL_REG_R(pll->pll_base, DSIPHY_CMN_CLK_CFG0); - n2div >>= 4; - n2div &= 0x0f; - /* - * initialize n2div here, it will get updated when - * corresponding set_div is called. - */ - pout->pll_n2div = n2div; - mdss_pll_resource_enable(pll, false); - - *div = n2div; - - /* common clock framework will add one to the divider value sent */ - if (*div == 0) - *div = 1; /* value of zero means div is 2 as per SWI */ - else - *div -= 1; - - pr_debug("ndx=%d div=%d\n", pll->index, *div); - - return rc; -} - -static bool pll_is_pll_locked_14nm(struct mdss_pll_resources *pll) -{ - u32 status; - bool pll_locked; - - /* poll for PLL ready status */ - if (readl_poll_timeout_atomic((pll->pll_base + - DSIPHY_PLL_RESET_SM_READY_STATUS), - status, - ((status & BIT(5)) > 0), - DSI_PLL_POLL_MAX_READS, - DSI_PLL_POLL_TIMEOUT_US)) { - pr_err("DSI PLL ndx=%d status=%x failed to Lock\n", - pll->index, status); - pll_locked = false; - } else if (readl_poll_timeout_atomic((pll->pll_base + - DSIPHY_PLL_RESET_SM_READY_STATUS), - status, - ((status & BIT(0)) > 0), - DSI_PLL_POLL_MAX_READS, - DSI_PLL_POLL_TIMEOUT_US)) { - pr_err("DSI PLL ndx=%d status=%x PLl not ready\n", - pll->index, status); - pll_locked = false; - } else { - pll_locked = true; - } - - return pll_locked; -} - -static void dsi_pll_start_14nm(void __iomem *pll_base) -{ - pr_debug("start PLL at base=%pK\n", pll_base); - - MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_VREF_CFG1, 0x10); - MDSS_PLL_REG_W(pll_base, DSIPHY_CMN_PLL_CNTRL, 1); -} - -static void dsi_pll_stop_14nm(void __iomem *pll_base) -{ - pr_debug("stop PLL at base=%pK\n", pll_base); - - MDSS_PLL_REG_W(pll_base, DSIPHY_CMN_PLL_CNTRL, 0); -} - -int dsi_pll_enable_seq_14nm(struct mdss_pll_resources *pll) -{ - int rc = 0; - - if (!pll) { - pr_err("Invalid PLL resources\n"); - return -EINVAL; - } - - dsi_pll_start_14nm(pll->pll_base); - - /* - * both DSIPHY_PLL_CLKBUFLR_EN and DSIPHY_CMN_GLBL_TEST_CTRL - * enabled at mdss_dsi_14nm_phy_config() - */ - - if (!pll_is_pll_locked_14nm(pll)) { - pr_err("DSI PLL ndx=%d lock failed\n", pll->index); - rc = -EINVAL; - goto init_lock_err; - } - - pr_debug("DSI PLL ndx=%d Lock success\n", pll->index); - -init_lock_err: - return rc; -} - -static int dsi_pll_enable(struct clk_hw *hw) -{ - int i, rc = 0; - struct dsi_pll_vco_clk *vco = to_vco_clk_hw(hw); - struct mdss_pll_resources *pll = vco->priv; - - /* Try all enable sequences until one succeeds */ - for (i = 0; i < vco->pll_en_seq_cnt; i++) { - rc = vco->pll_enable_seqs[i](pll); - pr_debug("DSI PLL %s after sequence #%d\n", - rc ? "unlocked" : "locked", i + 1); - if (!rc) - break; - } - - if (rc) - pr_err("ndx=%d DSI PLL failed to lock\n", pll->index); - else - pll->pll_on = true; - - return rc; -} - -static void dsi_pll_disable(struct clk_hw *hw) -{ - struct dsi_pll_vco_clk *vco = to_vco_clk_hw(hw); - struct mdss_pll_resources *pll = vco->priv; - struct mdss_pll_resources *slave; - - if (!pll->pll_on && - mdss_pll_resource_enable(pll, true)) { - pr_err("Failed to enable mdss dsi pll=%d\n", pll->index); - return; - } - - pll->handoff_resources = false; - slave = pll->slave; - - dsi_pll_stop_14nm(pll->pll_base); - - mdss_pll_resource_enable(pll, false); - - pll->pll_on = false; - - pr_debug("DSI PLL ndx=%d Disabled\n", pll->index); -} - -static void mdss_dsi_pll_14nm_input_init(struct mdss_pll_resources *pll, - struct dsi_pll_db *pdb) -{ - pdb->in.fref = 19200000; /* 19.2 Mhz*/ - pdb->in.fdata = 0; /* bit clock rate */ - pdb->in.dsiclk_sel = 1; /* 1, reg: 0x0014 */ - pdb->in.ssc_en = pll->ssc_en; /* 1, reg: 0x0494, bit 0 */ - pdb->in.ldo_en = 0; /* 0, reg: 0x004c, bit 0 */ - - /* fixed input */ - pdb->in.refclk_dbler_en = 0; /* 0, reg: 0x04c0, bit 1 */ - pdb->in.vco_measure_time = 5; /* 5, unknown */ - pdb->in.kvco_measure_time = 5; /* 5, unknown */ - pdb->in.bandgap_timer = 4; /* 4, reg: 0x0430, bit 3 - 5 */ - pdb->in.pll_wakeup_timer = 5; /* 5, reg: 0x043c, bit 0 - 2 */ - pdb->in.plllock_cnt = 1; /* 1, reg: 0x0488, bit 1 - 2 */ - pdb->in.plllock_rng = 0; /* 0, reg: 0x0488, bit 3 - 4 */ - pdb->in.ssc_center = pll->ssc_center;/* 0, reg: 0x0494, bit 1 */ - pdb->in.ssc_adj_period = 37; /* 37, reg: 0x498, bit 0 - 9 */ - pdb->in.ssc_spread = pll->ssc_ppm / 1000; - pdb->in.ssc_freq = pll->ssc_freq; - - pdb->in.pll_ie_trim = 4; /* 4, reg: 0x0400 */ - pdb->in.pll_ip_trim = 4; /* 4, reg: 0x0404 */ - pdb->in.pll_cpcset_cur = 1; /* 1, reg: 0x04f0, bit 0 - 2 */ - pdb->in.pll_cpmset_cur = 1; /* 1, reg: 0x04f0, bit 3 - 5 */ - pdb->in.pll_icpmset = 4; /* 4, reg: 0x04fc, bit 3 - 5 */ - pdb->in.pll_icpcset = 4; /* 4, reg: 0x04fc, bit 0 - 2 */ - pdb->in.pll_icpmset_p = 0; /* 0, reg: 0x04f4, bit 0 - 2 */ - pdb->in.pll_icpmset_m = 0; /* 0, reg: 0x04f4, bit 3 - 5 */ - pdb->in.pll_icpcset_p = 0; /* 0, reg: 0x04f8, bit 0 - 2 */ - pdb->in.pll_icpcset_m = 0; /* 0, reg: 0x04f8, bit 3 - 5 */ - pdb->in.pll_lpf_res1 = 3; /* 3, reg: 0x0504, bit 0 - 3 */ - pdb->in.pll_lpf_cap1 = 11; /* 11, reg: 0x0500, bit 0 - 3 */ - pdb->in.pll_lpf_cap2 = 1; /* 1, reg: 0x0500, bit 4 - 7 */ - pdb->in.pll_iptat_trim = 7; - pdb->in.pll_c3ctrl = 2; /* 2 */ - pdb->in.pll_r3ctrl = 1; /* 1 */ - pdb->out.pll_postdiv = 1; -} - -static void pll_14nm_ssc_calc(struct mdss_pll_resources *pll, - struct dsi_pll_db *pdb) -{ - u32 period, ssc_period; - u32 ref, rem; - s64 step_size; - - pr_debug("%s: vco=%lld ref=%lld\n", __func__, - pll->vco_current_rate, pll->vco_ref_clk_rate); - - ssc_period = pdb->in.ssc_freq / 500; - period = (unsigned long)pll->vco_ref_clk_rate / 1000; - ssc_period = CEIL(period, ssc_period); - ssc_period -= 1; - pdb->out.ssc_period = ssc_period; - - pr_debug("%s: ssc, freq=%d spread=%d period=%d\n", __func__, - pdb->in.ssc_freq, pdb->in.ssc_spread, pdb->out.ssc_period); - - step_size = (u32)pll->vco_current_rate; - ref = pll->vco_ref_clk_rate; - ref /= 1000; - step_size = div_s64(step_size, ref); - step_size <<= 20; - step_size = div_s64(step_size, 1000); - step_size *= pdb->in.ssc_spread; - step_size = div_s64(step_size, 1000); - step_size *= (pdb->in.ssc_adj_period + 1); - - rem = 0; - step_size = div_s64_rem(step_size, ssc_period + 1, &rem); - if (rem) - step_size++; - - pr_debug("%s: step_size=%lld\n", __func__, step_size); - - step_size &= 0x0ffff; /* take lower 16 bits */ - - pdb->out.ssc_step_size = step_size; -} - -static void pll_14nm_dec_frac_calc(struct mdss_pll_resources *pll, - struct dsi_pll_db *pdb) -{ - struct dsi_pll_input *pin = &pdb->in; - struct dsi_pll_output *pout = &pdb->out; - u64 multiplier = BIT(20); - u64 dec_start_multiple, dec_start, pll_comp_val; - s32 duration, div_frac_start; - s64 vco_clk_rate = pll->vco_current_rate; - s64 fref = pll->vco_ref_clk_rate; - - pr_debug("vco_clk_rate=%lld ref_clk_rate=%lld\n", - vco_clk_rate, fref); - - dec_start_multiple = div_s64(vco_clk_rate * multiplier, fref); - div_s64_rem(dec_start_multiple, multiplier, &div_frac_start); - - dec_start = div_s64(dec_start_multiple, multiplier); - - pout->dec_start = (u32)dec_start; - pout->div_frac_start = div_frac_start; - - if (pin->plllock_cnt == 0) - duration = 1024; - else if (pin->plllock_cnt == 1) - duration = 256; - else if (pin->plllock_cnt == 2) - duration = 128; - else - duration = 32; - - pll_comp_val = duration * dec_start_multiple; - pll_comp_val = div_u64(pll_comp_val, multiplier); - do_div(pll_comp_val, 10); - - pout->plllock_cmp = (u32)pll_comp_val; - - pout->pll_txclk_en = 1; - if (pll->revision == MSM8996_DSI_PLL_REVISION_2) - pout->cmn_ldo_cntrl = 0x3c; - else - pout->cmn_ldo_cntrl = 0x1c; -} - -static u32 pll_14nm_kvco_slop(u32 vrate) -{ - u32 slop = 0; - - if (vrate > 1300000000UL && vrate <= 1800000000UL) - slop = 600; - else if (vrate > 1800000000UL && vrate < 2300000000UL) - slop = 400; - else if (vrate > 2300000000UL && vrate < 2600000000UL) - slop = 280; - - return slop; -} - -static void pll_14nm_calc_vco_count(struct dsi_pll_db *pdb, - s64 vco_clk_rate, s64 fref) -{ - struct dsi_pll_input *pin = &pdb->in; - struct dsi_pll_output *pout = &pdb->out; - u64 data; - u32 cnt; - - data = fref * pin->vco_measure_time; - do_div(data, 1000000); - data &= 0x03ff; /* 10 bits */ - data -= 2; - pout->pll_vco_div_ref = data; - - data = (unsigned long)vco_clk_rate / 1000000; /* unit is Mhz */ - data *= pin->vco_measure_time; - do_div(data, 10); - pout->pll_vco_count = data; /* reg: 0x0474, 0x0478 */ - - data = fref * pin->kvco_measure_time; - do_div(data, 1000000); - data &= 0x03ff; /* 10 bits */ - data -= 1; - pout->pll_kvco_div_ref = data; - - cnt = pll_14nm_kvco_slop(vco_clk_rate); - cnt *= 2; - cnt /= 100; - cnt *= pin->kvco_measure_time; - pout->pll_kvco_count = cnt; - - pout->pll_misc1 = 16; - pout->pll_resetsm_cntrl = 48; - pout->pll_resetsm_cntrl2 = pin->bandgap_timer << 3; - pout->pll_resetsm_cntrl5 = pin->pll_wakeup_timer; - pout->pll_kvco_code = 0; -} - -static void pll_db_commit_ssc(struct mdss_pll_resources *pll, - struct dsi_pll_db *pdb) -{ - void __iomem *pll_base = pll->pll_base; - struct dsi_pll_input *pin = &pdb->in; - struct dsi_pll_output *pout = &pdb->out; - char data; - - data = pin->ssc_adj_period; - data &= 0x0ff; - MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_SSC_ADJ_PER1, data); - data = (pin->ssc_adj_period >> 8); - data &= 0x03; - MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_SSC_ADJ_PER2, data); - - data = pout->ssc_period; - data &= 0x0ff; - MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_SSC_PER1, data); - data = (pout->ssc_period >> 8); - data &= 0x0ff; - MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_SSC_PER2, data); - - data = pout->ssc_step_size; - data &= 0x0ff; - MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_SSC_STEP_SIZE1, data); - data = (pout->ssc_step_size >> 8); - data &= 0x0ff; - MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_SSC_STEP_SIZE2, data); - - data = (pin->ssc_center & 0x01); - data <<= 1; - data |= 0x01; /* enable */ - MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_SSC_EN_CENTER, data); - - wmb(); /* make sure register committed */ -} - -static void pll_db_commit_common(struct mdss_pll_resources *pll, - struct dsi_pll_db *pdb) -{ - void __iomem *pll_base = pll->pll_base; - struct dsi_pll_input *pin = &pdb->in; - struct dsi_pll_output *pout = &pdb->out; - char data; - - /* confgiure the non frequency dependent pll registers */ - data = 0; - MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_SYSCLK_EN_RESET, data); - - /* DSIPHY_PLL_CLKBUFLR_EN updated at dsi phy */ - - data = pout->pll_txclk_en; - MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_TXCLK_EN, data); - - data = pout->pll_resetsm_cntrl; - MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_RESETSM_CNTRL, data); - data = pout->pll_resetsm_cntrl2; - MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_RESETSM_CNTRL2, data); - data = pout->pll_resetsm_cntrl5; - MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_RESETSM_CNTRL5, data); - - data = pout->pll_vco_div_ref; - data &= 0x0ff; - MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_VCO_DIV_REF1, data); - data = (pout->pll_vco_div_ref >> 8); - data &= 0x03; - MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_VCO_DIV_REF2, data); - - data = pout->pll_kvco_div_ref; - data &= 0x0ff; - MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_KVCO_DIV_REF1, data); - data = (pout->pll_kvco_div_ref >> 8); - data &= 0x03; - MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_KVCO_DIV_REF2, data); - - data = pout->pll_misc1; - MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_PLL_MISC1, data); - - data = pin->pll_ie_trim; - MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_IE_TRIM, data); - - data = pin->pll_ip_trim; - MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_IP_TRIM, data); - - data = ((pin->pll_cpmset_cur << 3) | pin->pll_cpcset_cur); - MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_CP_SET_CUR, data); - - data = ((pin->pll_icpcset_p << 3) | pin->pll_icpcset_m); - MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_PLL_ICPCSET, data); - - data = ((pin->pll_icpmset_p << 3) | pin->pll_icpcset_m); - MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_PLL_ICPMSET, data); - - data = ((pin->pll_icpmset << 3) | pin->pll_icpcset); - MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_PLL_ICP_SET, data); - - data = ((pdb->in.pll_lpf_cap2 << 4) | pdb->in.pll_lpf_cap1); - MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_PLL_LPF1, data); - - data = pin->pll_iptat_trim; - MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_IPTAT_TRIM, data); - - data = (pdb->in.pll_c3ctrl | (pdb->in.pll_r3ctrl << 4)); - MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_PLL_CRCTRL, data); -} - -static void pll_db_commit_14nm(struct mdss_pll_resources *pll, - struct dsi_pll_db *pdb) -{ - void __iomem *pll_base = pll->pll_base; - struct dsi_pll_input *pin = &pdb->in; - struct dsi_pll_output *pout = &pdb->out; - char data; - - data = pout->cmn_ldo_cntrl; - MDSS_PLL_REG_W(pll_base, DSIPHY_CMN_LDO_CNTRL, data); - - pll_db_commit_common(pll, pdb); - - /* de assert pll start and apply pll sw reset */ - /* stop pll */ - MDSS_PLL_REG_W(pll_base, DSIPHY_CMN_PLL_CNTRL, 0); - - /* pll sw reset */ - MDSS_PLL_REG_W(pll_base, DSIPHY_CMN_CTRL_1, 0x20); - wmb(); /* make sure register committed */ - udelay(10); - - MDSS_PLL_REG_W(pll_base, DSIPHY_CMN_CTRL_1, 0); - wmb(); /* make sure register committed */ - - data = pdb->in.dsiclk_sel; /* set dsiclk_sel = 1 */ - MDSS_PLL_REG_W(pll_base, DSIPHY_CMN_CLK_CFG1, data); - - data = 0xff; /* data, clk, pll normal operation */ - MDSS_PLL_REG_W(pll_base, DSIPHY_CMN_CTRL_0, data); - - /* confgiure the frequency dependent pll registers */ - data = pout->dec_start; - MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_DEC_START, data); - - data = pout->div_frac_start; - data &= 0x0ff; - MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_DIV_FRAC_START1, data); - data = (pout->div_frac_start >> 8); - data &= 0x0ff; - MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_DIV_FRAC_START2, data); - data = (pout->div_frac_start >> 16); - data &= 0x0f; - MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_DIV_FRAC_START3, data); - - data = pout->plllock_cmp; - data &= 0x0ff; - MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_PLLLOCK_CMP1, data); - data = (pout->plllock_cmp >> 8); - data &= 0x0ff; - MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_PLLLOCK_CMP2, data); - data = (pout->plllock_cmp >> 16); - data &= 0x03; - MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_PLLLOCK_CMP3, data); - - data = ((pin->plllock_cnt << 1) | (pin->plllock_rng << 3)); - MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_PLLLOCK_CMP_EN, data); - - data = pout->pll_vco_count; - data &= 0x0ff; - MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_VCO_COUNT1, data); - data = (pout->pll_vco_count >> 8); - data &= 0x0ff; - MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_VCO_COUNT2, data); - - data = pout->pll_kvco_count; - data &= 0x0ff; - MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_KVCO_COUNT1, data); - data = (pout->pll_kvco_count >> 8); - data &= 0x03; - MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_KVCO_COUNT2, data); - - /* - * tx_band = pll_postdiv - * 0: divided by 1 <== for now - * 1: divided by 2 - * 2: divided by 4 - * 3: divided by 8 - */ - data = (((pout->pll_postdiv - 1) << 4) | pdb->in.pll_lpf_res1); - MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_PLL_LPF2_POSTDIV, data); - - data = (pout->pll_n1div | (pout->pll_n2div << 4)); - MDSS_PLL_REG_W(pll_base, DSIPHY_CMN_CLK_CFG0, data); - - if (pll->ssc_en) - pll_db_commit_ssc(pll, pdb); - - wmb(); /* make sure register committed */ -} - -/* - * pll_source_finding: - * Both GLBL_TEST_CTRL and CLKBUFLR_EN are configured - * at mdss_dsi_14nm_phy_config() - */ -static int pll_source_finding(struct mdss_pll_resources *pll) -{ - u32 clk_buf_en; - u32 glbl_test_ctrl; - - glbl_test_ctrl = MDSS_PLL_REG_R(pll->pll_base, - DSIPHY_CMN_GLBL_TEST_CTRL); - clk_buf_en = MDSS_PLL_REG_R(pll->pll_base, - DSIPHY_PLL_CLKBUFLR_EN); - - glbl_test_ctrl &= BIT(2); - glbl_test_ctrl >>= 2; - - pr_debug("%s: pll=%d clk_buf_en=%x glbl_test_ctrl=%x\n", - __func__, pll->index, clk_buf_en, glbl_test_ctrl); - - clk_buf_en &= (PLL_OUTPUT_RIGHT | PLL_OUTPUT_LEFT); - - if ((glbl_test_ctrl == PLL_SOURCE_FROM_LEFT) && - (clk_buf_en == PLL_OUTPUT_BOTH)) - return PLL_MASTER; - - if ((glbl_test_ctrl == PLL_SOURCE_FROM_RIGHT) && - (clk_buf_en == PLL_OUTPUT_NONE)) - return PLL_SLAVE; - - if ((glbl_test_ctrl == PLL_SOURCE_FROM_LEFT) && - (clk_buf_en == PLL_OUTPUT_RIGHT)) - return PLL_STANDALONE; - - pr_debug("%s: Error pll setup, clk_buf_en=%x glbl_test_ctrl=%x\n", - __func__, clk_buf_en, glbl_test_ctrl); - - return PLL_UNKNOWN; -} - -static void pll_source_setup(struct mdss_pll_resources *pll) -{ - int status; - struct dsi_pll_db *pdb = (struct dsi_pll_db *)pll->priv; - struct mdss_pll_resources *other; - - if (pdb->source_setup_done) - return; - - pdb->source_setup_done++; - - status = pll_source_finding(pll); - - if (status == PLL_STANDALONE || status == PLL_UNKNOWN) - return; - - other = pdb->next->pll; - if (!other) - return; - - pr_debug("%s: status=%d pll=%d other=%d\n", __func__, - status, pll->index, other->index); - - if (status == PLL_MASTER) - pll->slave = other; - else - other->slave = pll; -} - -unsigned long pll_vco_recalc_rate_14nm(struct clk_hw *hw, - unsigned long parent_rate) -{ - struct dsi_pll_vco_clk *vco = to_vco_clk_hw(hw); - struct mdss_pll_resources *pll = vco->priv; - u64 vco_rate, multiplier = BIT(20); - s32 div_frac_start; - u32 dec_start; - u64 ref_clk = vco->ref_clk_rate; - int rc; - - if (pll->vco_current_rate) - return (unsigned long)pll->vco_current_rate; - - if (is_gdsc_disabled(pll)) - return 0; - - rc = mdss_pll_resource_enable(pll, true); - if (rc) { - pr_err("Failed to enable mdss dsi pll=%d\n", pll->index); - return rc; - } - - dec_start = MDSS_PLL_REG_R(pll->pll_base, - DSIPHY_PLL_DEC_START); - dec_start &= 0x0ff; - pr_debug("dec_start = 0x%x\n", dec_start); - - div_frac_start = (MDSS_PLL_REG_R(pll->pll_base, - DSIPHY_PLL_DIV_FRAC_START3) & 0x0f) << 16; - div_frac_start |= (MDSS_PLL_REG_R(pll->pll_base, - DSIPHY_PLL_DIV_FRAC_START2) & 0x0ff) << 8; - div_frac_start |= MDSS_PLL_REG_R(pll->pll_base, - DSIPHY_PLL_DIV_FRAC_START1) & 0x0ff; - pr_debug("div_frac_start = 0x%x\n", div_frac_start); - - vco_rate = ref_clk * dec_start; - vco_rate += ((ref_clk * div_frac_start) / multiplier); - - pr_debug("returning vco rate = %lu\n", (unsigned long)vco_rate); - - mdss_pll_resource_enable(pll, false); - - pr_debug("%s: returning vco rate as %lu\n", - __func__, (unsigned long)vco_rate); - return (unsigned long)vco_rate; -} - -int pll_vco_set_rate_14nm(struct clk_hw *hw, unsigned long rate, - unsigned long parent_rate) -{ - int rc; - struct dsi_pll_vco_clk *vco = to_vco_clk_hw(hw); - struct mdss_pll_resources *pll = vco->priv; - struct mdss_pll_resources *slave; - struct dsi_pll_db *pdb; - - pdb = (struct dsi_pll_db *)pll->priv; - if (!pdb) { - pr_err("No prov found\n"); - return -EINVAL; - } - - rc = mdss_pll_resource_enable(pll, true); - if (rc) { - pr_err("Failed to enable mdss dsi plla=%d\n", pll->index); - return rc; - } - - pll_source_setup(pll); - - pr_debug("%s: ndx=%d base=%pK rate=%lu slave=%pK\n", __func__, - pll->index, pll->pll_base, rate, pll->slave); - - pll->vco_current_rate = rate; - pll->vco_ref_clk_rate = vco->ref_clk_rate; - - mdss_dsi_pll_14nm_input_init(pll, pdb); - - pll_14nm_dec_frac_calc(pll, pdb); - - if (pll->ssc_en) - pll_14nm_ssc_calc(pll, pdb); - - pll_14nm_calc_vco_count(pdb, pll->vco_current_rate, - pll->vco_ref_clk_rate); - - /* commit slave if split display is enabled */ - slave = pll->slave; - if (slave) - pll_db_commit_14nm(slave, pdb); - - /* commit master itself */ - pll_db_commit_14nm(pll, pdb); - - mdss_pll_resource_enable(pll, false); - - return rc; -} - -static void shadow_pll_dynamic_refresh_14nm(struct mdss_pll_resources *pll, - struct dsi_pll_db *pdb) -{ - struct dsi_pll_output *pout = &pdb->out; - - MDSS_DYN_PLL_REG_W(pll->dyn_pll_base, - DSI_DYNAMIC_REFRESH_PLL_CTRL20, - DSIPHY_CMN_CTRL_0, DSIPHY_PLL_SYSCLK_EN_RESET, - 0xFF, 0x0); - MDSS_DYN_PLL_REG_W(pll->dyn_pll_base, - DSI_DYNAMIC_REFRESH_PLL_CTRL21, - DSIPHY_PLL_DEC_START, DSIPHY_PLL_DIV_FRAC_START1, - pout->dec_start, (pout->div_frac_start & 0x0FF)); - MDSS_DYN_PLL_REG_W(pll->dyn_pll_base, - DSI_DYNAMIC_REFRESH_PLL_CTRL22, - DSIPHY_PLL_DIV_FRAC_START2, DSIPHY_PLL_DIV_FRAC_START3, - ((pout->div_frac_start >> 8) & 0x0FF), - ((pout->div_frac_start >> 16) & 0x0F)); - MDSS_DYN_PLL_REG_W(pll->dyn_pll_base, - DSI_DYNAMIC_REFRESH_PLL_CTRL23, - DSIPHY_PLL_PLLLOCK_CMP1, DSIPHY_PLL_PLLLOCK_CMP2, - (pout->plllock_cmp & 0x0FF), - ((pout->plllock_cmp >> 8) & 0x0FF)); - MDSS_DYN_PLL_REG_W(pll->dyn_pll_base, - DSI_DYNAMIC_REFRESH_PLL_CTRL24, - DSIPHY_PLL_PLLLOCK_CMP3, DSIPHY_PLL_PLL_VCO_TUNE, - ((pout->plllock_cmp >> 16) & 0x03), - (pll->cache_pll_trim_codes[1] | BIT(7))); /* VCO tune*/ - MDSS_DYN_PLL_REG_W(pll->dyn_pll_base, - DSI_DYNAMIC_REFRESH_PLL_CTRL25, - DSIPHY_PLL_KVCO_CODE, DSIPHY_PLL_RESETSM_CNTRL, - (pll->cache_pll_trim_codes[0] | BIT(5)), 0x38); - MDSS_DYN_PLL_REG_W(pll->dyn_pll_base, - DSI_DYNAMIC_REFRESH_PLL_CTRL26, - DSIPHY_PLL_PLL_LPF2_POSTDIV, DSIPHY_CMN_PLL_CNTRL, - (((pout->pll_postdiv - 1) << 4) | pdb->in.pll_lpf_res1), 0x01); - MDSS_DYN_PLL_REG_W(pll->dyn_pll_base, - DSI_DYNAMIC_REFRESH_PLL_CTRL27, - DSIPHY_CMN_PLL_CNTRL, DSIPHY_CMN_PLL_CNTRL, - 0x01, 0x01); - MDSS_DYN_PLL_REG_W(pll->dyn_pll_base, - DSI_DYNAMIC_REFRESH_PLL_CTRL28, - DSIPHY_CMN_PLL_CNTRL, DSIPHY_CMN_PLL_CNTRL, - 0x01, 0x01); - MDSS_DYN_PLL_REG_W(pll->dyn_pll_base, - DSI_DYNAMIC_REFRESH_PLL_CTRL29, - DSIPHY_CMN_PLL_CNTRL, DSIPHY_CMN_PLL_CNTRL, - 0x01, 0x01); - MDSS_PLL_REG_W(pll->dyn_pll_base, - DSI_DYNAMIC_REFRESH_PLL_UPPER_ADDR, 0x0000001E); - MDSS_PLL_REG_W(pll->dyn_pll_base, - DSI_DYNAMIC_REFRESH_PLL_UPPER_ADDR2, 0x001FFE00); - - /* - * Ensure all the dynamic refresh registers are written before - * dynamic refresh to change the fps is triggered - */ - wmb(); -} - -int shadow_pll_vco_set_rate_14nm(struct clk_hw *hw, unsigned long rate, - unsigned long parent_rate) -{ - int rc; - struct dsi_pll_vco_clk *vco = to_vco_clk_hw(hw); - struct mdss_pll_resources *pll = vco->priv; - struct dsi_pll_db *pdb; - s64 vco_clk_rate = (s64)rate; - - if (!pll) { - pr_err("PLL data not found\n"); - return -EINVAL; - } - - pdb = pll->priv; - if (!pdb) { - pr_err("No priv data found\n"); - return -EINVAL; - } - - rc = mdss_pll_read_stored_trim_codes(pll, vco_clk_rate); - if (rc) { - pr_err("cannot find pll codes rate=%lld\n", vco_clk_rate); - return -EINVAL; - } - - rc = mdss_pll_resource_enable(pll, true); - if (rc) { - pr_err("Failed to enable mdss dsi plla=%d\n", pll->index); - return rc; - } - - pr_debug("%s: ndx=%d base=%pK rate=%lu\n", __func__, - pll->index, pll->pll_base, rate); - - pll->vco_current_rate = rate; - pll->vco_ref_clk_rate = vco->ref_clk_rate; - - mdss_dsi_pll_14nm_input_init(pll, pdb); - - pll_14nm_dec_frac_calc(pll, pdb); - - pll_14nm_calc_vco_count(pdb, pll->vco_current_rate, - pll->vco_ref_clk_rate); - - shadow_pll_dynamic_refresh_14nm(pll, pdb); - - rc = mdss_pll_resource_enable(pll, false); - if (rc) { - pr_err("Failed to enable mdss dsi plla=%d\n", pll->index); - return rc; - } - - return rc; -} - -long pll_vco_round_rate_14nm(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) -{ - unsigned long rrate = rate; - u64 div; - struct dsi_pll_vco_clk *vco = to_vco_clk_hw(hw); - - div = vco->min_rate; - do_div(div, rate); - if (div > 15) { - /* rate < 86.67 Mhz */ - pr_err("rate=%lu NOT supportted\n", rate); - return -EINVAL; - } - - if (rate < vco->min_rate) - rrate = vco->min_rate; - if (rate > vco->max_rate) - rrate = vco->max_rate; - - *parent_rate = rrate; - return rrate; -} - -int pll_vco_prepare_14nm(struct clk_hw *hw) -{ - int rc = 0; - struct dsi_pll_vco_clk *vco = to_vco_clk_hw(hw); - struct mdss_pll_resources *pll = vco->priv; - - if (!pll) { - pr_err("Dsi pll resources are not available\n"); - return -EINVAL; - } - - rc = mdss_pll_resource_enable(pll, true); - if (rc) { - pr_err("ndx=%d Failed to enable mdss dsi pll resources\n", - pll->index); - return rc; - } - - if ((pll->vco_cached_rate != 0) - && (pll->vco_cached_rate == clk_hw_get_rate(hw))) { - rc = hw->init->ops->set_rate(hw, pll->vco_cached_rate, - pll->vco_cached_rate); - if (rc) { - pr_err("index=%d vco_set_rate failed. rc=%d\n", - rc, pll->index); - mdss_pll_resource_enable(pll, false); - goto error; - } - } - - rc = dsi_pll_enable(hw); - - if (rc) { - mdss_pll_resource_enable(pll, false); - pr_err("ndx=%d failed to enable dsi pll\n", pll->index); - } - -error: - return rc; -} - -void pll_vco_unprepare_14nm(struct clk_hw *hw) -{ - struct dsi_pll_vco_clk *vco = to_vco_clk_hw(hw); - struct mdss_pll_resources *pll = vco->priv; - - if (!pll) { - pr_err("Dsi pll resources are not available\n"); - return; - } - - pll->vco_cached_rate = clk_hw_get_rate(hw); - dsi_pll_disable(hw); -} - -int dsi_mux_set_parent_14nm(void *context, unsigned int reg, unsigned int val) -{ - return 0; -} - -int dsi_mux_get_parent_14nm(void *context, unsigned int reg, unsigned int *val) -{ - *val = 0; - return 0; -} diff --git a/pll/dsi_pll_20nm.c b/pll/dsi_pll_20nm.c deleted file mode 100644 index f9e22c6abe25..000000000000 --- a/pll/dsi_pll_20nm.c +++ /dev/null @@ -1,590 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (c) 2014-2019, The Linux Foundation. All rights reserved. - */ - -#define pr_fmt(fmt) "%s: " fmt, __func__ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "pll_drv.h" -#include "dsi_pll.h" - -#define VCO_DELAY_USEC 1 - -static const struct clk_ops bypass_lp_div_mux_clk_ops; -static const struct clk_ops pixel_clk_src_ops; -static const struct clk_ops byte_clk_src_ops; -static const struct clk_ops ndiv_clk_ops; - -static const struct clk_ops shadow_pixel_clk_src_ops; -static const struct clk_ops shadow_byte_clk_src_ops; -static const struct clk_ops clk_ops_gen_mux_dsi; - -static int vco_set_rate_20nm(struct clk *c, unsigned long rate) -{ - int rc; - struct dsi_pll_vco_clk *vco = to_vco_clk(c); - struct mdss_pll_resources *dsi_pll_res = vco->priv; - - rc = mdss_pll_resource_enable(dsi_pll_res, true); - if (rc) { - pr_err("Failed to enable mdss dsi pll resources\n"); - return rc; - } - - pr_debug("Cancel pending pll off work\n"); - cancel_work_sync(&dsi_pll_res->pll_off); - rc = pll_20nm_vco_set_rate(vco, rate); - - mdss_pll_resource_enable(dsi_pll_res, false); - return rc; -} - -static int pll1_vco_set_rate_20nm(struct clk *c, unsigned long rate) -{ - struct dsi_pll_vco_clk *vco = to_vco_clk(c); - struct mdss_pll_resources *pll_res = vco->priv; - - mdss_pll_resource_enable(pll_res, true); - __dsi_pll_disable(pll_res->pll_base); - mdss_pll_resource_enable(pll_res, false); - - pr_debug("Configuring PLL1 registers.\n"); - - return 0; -} - -static int shadow_vco_set_rate_20nm(struct clk *c, unsigned long rate) -{ - int rc; - struct dsi_pll_vco_clk *vco = to_vco_clk(c); - struct mdss_pll_resources *dsi_pll_res = vco->priv; - - if (!dsi_pll_res->resource_enable) { - pr_err("PLL resources disabled. Dynamic fps invalid\n"); - return -EINVAL; - } - - rc = shadow_pll_20nm_vco_set_rate(vco, rate); - - return rc; -} - -/* Op structures */ - -static const struct clk_ops pll1_clk_ops_dsi_vco = { - .set_rate = pll1_vco_set_rate_20nm, -}; - -static const struct clk_ops clk_ops_dsi_vco = { - .set_rate = vco_set_rate_20nm, - .round_rate = pll_20nm_vco_round_rate, - .handoff = pll_20nm_vco_handoff, - .prepare = pll_20nm_vco_prepare, - .unprepare = pll_20nm_vco_unprepare, -}; - -static struct clk_div_ops fixed_hr_oclk2_div_ops = { - .set_div = fixed_hr_oclk2_set_div, - .get_div = fixed_hr_oclk2_get_div, -}; - -static struct clk_div_ops ndiv_ops = { - .set_div = ndiv_set_div, - .get_div = ndiv_get_div, -}; - -static struct clk_div_ops hr_oclk3_div_ops = { - .set_div = hr_oclk3_set_div, - .get_div = hr_oclk3_get_div, -}; - -static struct clk_mux_ops bypass_lp_div_mux_ops = { - .set_mux_sel = set_bypass_lp_div_mux_sel, - .get_mux_sel = get_bypass_lp_div_mux_sel, -}; - -static const struct clk_ops shadow_clk_ops_dsi_vco = { - .set_rate = shadow_vco_set_rate_20nm, - .round_rate = pll_20nm_vco_round_rate, - .handoff = pll_20nm_vco_handoff, -}; - -static struct clk_div_ops shadow_fixed_hr_oclk2_div_ops = { - .set_div = shadow_fixed_hr_oclk2_set_div, - .get_div = fixed_hr_oclk2_get_div, -}; - -static struct clk_div_ops shadow_ndiv_ops = { - .set_div = shadow_ndiv_set_div, - .get_div = ndiv_get_div, -}; - -static struct clk_div_ops shadow_hr_oclk3_div_ops = { - .set_div = shadow_hr_oclk3_set_div, - .get_div = hr_oclk3_get_div, -}; - -static struct clk_mux_ops shadow_bypass_lp_div_mux_ops = { - .set_mux_sel = set_shadow_bypass_lp_div_mux_sel, - .get_mux_sel = get_bypass_lp_div_mux_sel, -}; - -static struct clk_mux_ops mdss_byte_mux_ops = { - .set_mux_sel = set_mdss_byte_mux_sel, - .get_mux_sel = get_mdss_byte_mux_sel, -}; - -static struct clk_mux_ops mdss_pixel_mux_ops = { - .set_mux_sel = set_mdss_pixel_mux_sel, - .get_mux_sel = get_mdss_pixel_mux_sel, -}; - -static struct dsi_pll_vco_clk mdss_dsi1_vco_clk_src = { - .c = { - .dbg_name = "mdss_dsi1_vco_clk_src", - .ops = &pll1_clk_ops_dsi_vco, - .flags = CLKFLAG_NO_RATE_CACHE, - CLK_INIT(mdss_dsi1_vco_clk_src.c), - }, -}; - -static struct dsi_pll_vco_clk dsi_vco_clk_8994 = { - .ref_clk_rate = 19200000, - .min_rate = 300000000, - .max_rate = 1500000000, - .pll_en_seq_cnt = 1, - .pll_enable_seqs[0] = pll_20nm_vco_enable_seq, - .c = { - .dbg_name = "dsi_vco_clk_8994", - .ops = &clk_ops_dsi_vco, - CLK_INIT(dsi_vco_clk_8994.c), - }, -}; - -static struct dsi_pll_vco_clk shadow_dsi_vco_clk_8994 = { - .ref_clk_rate = 19200000, - .min_rate = 300000000, - .max_rate = 1500000000, - .c = { - .dbg_name = "shadow_dsi_vco_clk_8994", - .ops = &shadow_clk_ops_dsi_vco, - CLK_INIT(shadow_dsi_vco_clk_8994.c), - }, -}; - -static struct div_clk ndiv_clk_8994 = { - .data = { - .max_div = 15, - .min_div = 1, - }, - .ops = &ndiv_ops, - .c = { - .parent = &dsi_vco_clk_8994.c, - .dbg_name = "ndiv_clk_8994", - .ops = &ndiv_clk_ops, - .flags = CLKFLAG_NO_RATE_CACHE, - CLK_INIT(ndiv_clk_8994.c), - }, -}; - -static struct div_clk shadow_ndiv_clk_8994 = { - .data = { - .max_div = 15, - .min_div = 1, - }, - .ops = &shadow_ndiv_ops, - .c = { - .parent = &shadow_dsi_vco_clk_8994.c, - .dbg_name = "shadow_ndiv_clk_8994", - .ops = &clk_ops_div, - .flags = CLKFLAG_NO_RATE_CACHE, - CLK_INIT(shadow_ndiv_clk_8994.c), - }, -}; - -static struct div_clk indirect_path_div2_clk_8994 = { - .data = { - .div = 2, - .min_div = 2, - .max_div = 2, - }, - .c = { - .parent = &ndiv_clk_8994.c, - .dbg_name = "indirect_path_div2_clk_8994", - .ops = &clk_ops_div, - .flags = CLKFLAG_NO_RATE_CACHE, - CLK_INIT(indirect_path_div2_clk_8994.c), - }, -}; - -static struct div_clk shadow_indirect_path_div2_clk_8994 = { - .data = { - .div = 2, - .min_div = 2, - .max_div = 2, - }, - .c = { - .parent = &shadow_ndiv_clk_8994.c, - .dbg_name = "shadow_indirect_path_div2_clk_8994", - .ops = &clk_ops_div, - .flags = CLKFLAG_NO_RATE_CACHE, - CLK_INIT(shadow_indirect_path_div2_clk_8994.c), - }, -}; - -static struct div_clk hr_oclk3_div_clk_8994 = { - .data = { - .max_div = 255, - .min_div = 1, - }, - .ops = &hr_oclk3_div_ops, - .c = { - .parent = &dsi_vco_clk_8994.c, - .dbg_name = "hr_oclk3_div_clk_8994", - .ops = &pixel_clk_src_ops, - .flags = CLKFLAG_NO_RATE_CACHE, - CLK_INIT(hr_oclk3_div_clk_8994.c), - }, -}; - -static struct div_clk shadow_hr_oclk3_div_clk_8994 = { - .data = { - .max_div = 255, - .min_div = 1, - }, - .ops = &shadow_hr_oclk3_div_ops, - .c = { - .parent = &shadow_dsi_vco_clk_8994.c, - .dbg_name = "shadow_hr_oclk3_div_clk_8994", - .ops = &shadow_pixel_clk_src_ops, - .flags = CLKFLAG_NO_RATE_CACHE, - CLK_INIT(shadow_hr_oclk3_div_clk_8994.c), - }, -}; - -static struct div_clk pixel_clk_src = { - .data = { - .div = 2, - .min_div = 2, - .max_div = 2, - }, - .c = { - .parent = &hr_oclk3_div_clk_8994.c, - .dbg_name = "pixel_clk_src", - .ops = &clk_ops_div, - .flags = CLKFLAG_NO_RATE_CACHE, - CLK_INIT(pixel_clk_src.c), - }, -}; - -static struct div_clk shadow_pixel_clk_src = { - .data = { - .div = 2, - .min_div = 2, - .max_div = 2, - }, - .c = { - .parent = &shadow_hr_oclk3_div_clk_8994.c, - .dbg_name = "shadow_pixel_clk_src", - .ops = &clk_ops_div, - .flags = CLKFLAG_NO_RATE_CACHE, - CLK_INIT(shadow_pixel_clk_src.c), - }, -}; - -static struct mux_clk bypass_lp_div_mux_8994 = { - .num_parents = 2, - .parents = (struct clk_src[]){ - {&dsi_vco_clk_8994.c, 0}, - {&indirect_path_div2_clk_8994.c, 1}, - }, - .ops = &bypass_lp_div_mux_ops, - .c = { - .parent = &dsi_vco_clk_8994.c, - .dbg_name = "bypass_lp_div_mux_8994", - .ops = &bypass_lp_div_mux_clk_ops, - CLK_INIT(bypass_lp_div_mux_8994.c), - }, -}; - -static struct mux_clk shadow_bypass_lp_div_mux_8994 = { - .num_parents = 2, - .parents = (struct clk_src[]){ - {&shadow_dsi_vco_clk_8994.c, 0}, - {&shadow_indirect_path_div2_clk_8994.c, 1}, - }, - .ops = &shadow_bypass_lp_div_mux_ops, - .c = { - .parent = &shadow_dsi_vco_clk_8994.c, - .dbg_name = "shadow_bypass_lp_div_mux_8994", - .ops = &clk_ops_gen_mux, - CLK_INIT(shadow_bypass_lp_div_mux_8994.c), - }, -}; - -static struct div_clk fixed_hr_oclk2_div_clk_8994 = { - .ops = &fixed_hr_oclk2_div_ops, - .data = { - .min_div = 4, - .max_div = 4, - }, - .c = { - .parent = &bypass_lp_div_mux_8994.c, - .dbg_name = "fixed_hr_oclk2_div_clk_8994", - .ops = &byte_clk_src_ops, - CLK_INIT(fixed_hr_oclk2_div_clk_8994.c), - }, -}; - -static struct div_clk shadow_fixed_hr_oclk2_div_clk_8994 = { - .ops = &shadow_fixed_hr_oclk2_div_ops, - .data = { - .min_div = 4, - .max_div = 4, - }, - .c = { - .parent = &shadow_bypass_lp_div_mux_8994.c, - .dbg_name = "shadow_fixed_hr_oclk2_div_clk_8994", - .ops = &shadow_byte_clk_src_ops, - CLK_INIT(shadow_fixed_hr_oclk2_div_clk_8994.c), - }, -}; - -static struct div_clk byte_clk_src = { - .data = { - .div = 2, - .min_div = 2, - .max_div = 2, - }, - .c = { - .parent = &fixed_hr_oclk2_div_clk_8994.c, - .dbg_name = "byte_clk_src", - .ops = &clk_ops_div, - CLK_INIT(byte_clk_src.c), - }, -}; - -static struct div_clk shadow_byte_clk_src = { - .data = { - .div = 2, - .min_div = 2, - .max_div = 2, - }, - .c = { - .parent = &shadow_fixed_hr_oclk2_div_clk_8994.c, - .dbg_name = "shadow_byte_clk_src", - .ops = &clk_ops_div, - CLK_INIT(shadow_byte_clk_src.c), - }, -}; - -static struct mux_clk mdss_pixel_clk_mux = { - .num_parents = 2, - .parents = (struct clk_src[]) { - {&pixel_clk_src.c, 0}, - {&shadow_pixel_clk_src.c, 1}, - }, - .ops = &mdss_pixel_mux_ops, - .c = { - .parent = &pixel_clk_src.c, - .dbg_name = "mdss_pixel_clk_mux", - .ops = &clk_ops_gen_mux, - CLK_INIT(mdss_pixel_clk_mux.c), - } -}; - -static struct mux_clk mdss_byte_clk_mux = { - .num_parents = 2, - .parents = (struct clk_src[]) { - {&byte_clk_src.c, 0}, - {&shadow_byte_clk_src.c, 1}, - }, - .ops = &mdss_byte_mux_ops, - .c = { - .parent = &byte_clk_src.c, - .dbg_name = "mdss_byte_clk_mux", - .ops = &clk_ops_gen_mux_dsi, - CLK_INIT(mdss_byte_clk_mux.c), - } -}; - -static struct clk_lookup mdss_dsi_pll_1_cc_8994[] = { - CLK_LIST(mdss_dsi1_vco_clk_src), -}; - -static struct clk_lookup mdss_dsi_pllcc_8994[] = { - CLK_LIST(mdss_pixel_clk_mux), - CLK_LIST(mdss_byte_clk_mux), - CLK_LIST(pixel_clk_src), - CLK_LIST(byte_clk_src), - CLK_LIST(fixed_hr_oclk2_div_clk_8994), - CLK_LIST(bypass_lp_div_mux_8994), - CLK_LIST(hr_oclk3_div_clk_8994), - CLK_LIST(indirect_path_div2_clk_8994), - CLK_LIST(ndiv_clk_8994), - CLK_LIST(dsi_vco_clk_8994), - CLK_LIST(shadow_pixel_clk_src), - CLK_LIST(shadow_byte_clk_src), - CLK_LIST(shadow_fixed_hr_oclk2_div_clk_8994), - CLK_LIST(shadow_bypass_lp_div_mux_8994), - CLK_LIST(shadow_hr_oclk3_div_clk_8994), - CLK_LIST(shadow_indirect_path_div2_clk_8994), - CLK_LIST(shadow_ndiv_clk_8994), - CLK_LIST(shadow_dsi_vco_clk_8994), -}; - -static void dsi_pll_off_work(struct work_struct *work) -{ - struct mdss_pll_resources *pll_res; - - if (!work) { - pr_err("pll_resource is invalid\n"); - return; - } - - pr_debug("Starting PLL off Worker%s\n", __func__); - - pll_res = container_of(work, struct - mdss_pll_resources, pll_off); - - mdss_pll_resource_enable(pll_res, true); - __dsi_pll_disable(pll_res->pll_base); - if (pll_res->pll_1_base) - __dsi_pll_disable(pll_res->pll_1_base); - mdss_pll_resource_enable(pll_res, false); -} - -static int dsi_pll_regulator_notifier_call(struct notifier_block *self, - unsigned long event, void *data) -{ - - struct mdss_pll_resources *pll_res; - - if (!self) { - pr_err("pll_resource is invalid\n"); - goto error; - } - - pll_res = container_of(self, struct - mdss_pll_resources, gdsc_cb); - - if (event & REGULATOR_EVENT_ENABLE) { - pr_debug("Regulator ON event. Scheduling pll off worker\n"); - schedule_work(&pll_res->pll_off); - } - - if (event & REGULATOR_EVENT_DISABLE) - pr_debug("Regulator OFF event.\n"); - -error: - return NOTIFY_OK; -} - -int dsi_pll_clock_register_20nm(struct platform_device *pdev, - struct mdss_pll_resources *pll_res) -{ - int rc; - struct dss_vreg *pll_reg; - - /* - * Set client data to mux, div and vco clocks. - * This needs to be done only for PLL0 since, that is the one in - * use. - **/ - if (!pll_res->index) { - byte_clk_src.priv = pll_res; - pixel_clk_src.priv = pll_res; - bypass_lp_div_mux_8994.priv = pll_res; - indirect_path_div2_clk_8994.priv = pll_res; - ndiv_clk_8994.priv = pll_res; - fixed_hr_oclk2_div_clk_8994.priv = pll_res; - hr_oclk3_div_clk_8994.priv = pll_res; - dsi_vco_clk_8994.priv = pll_res; - - shadow_byte_clk_src.priv = pll_res; - shadow_pixel_clk_src.priv = pll_res; - shadow_bypass_lp_div_mux_8994.priv = pll_res; - shadow_indirect_path_div2_clk_8994.priv = pll_res; - shadow_ndiv_clk_8994.priv = pll_res; - shadow_fixed_hr_oclk2_div_clk_8994.priv = pll_res; - shadow_hr_oclk3_div_clk_8994.priv = pll_res; - shadow_dsi_vco_clk_8994.priv = pll_res; - - pll_res->vco_delay = VCO_DELAY_USEC; - - /* Set clock source operations */ - pixel_clk_src_ops = clk_ops_slave_div; - pixel_clk_src_ops.prepare = dsi_pll_div_prepare; - - ndiv_clk_ops = clk_ops_div; - ndiv_clk_ops.prepare = dsi_pll_div_prepare; - - byte_clk_src_ops = clk_ops_div; - byte_clk_src_ops.prepare = dsi_pll_div_prepare; - - bypass_lp_div_mux_clk_ops = clk_ops_gen_mux; - bypass_lp_div_mux_clk_ops.prepare = dsi_pll_mux_prepare; - - clk_ops_gen_mux_dsi = clk_ops_gen_mux; - clk_ops_gen_mux_dsi.round_rate = parent_round_rate; - clk_ops_gen_mux_dsi.set_rate = parent_set_rate; - - shadow_pixel_clk_src_ops = clk_ops_slave_div; - shadow_pixel_clk_src_ops.prepare = dsi_pll_div_prepare; - - shadow_byte_clk_src_ops = clk_ops_div; - shadow_byte_clk_src_ops.prepare = dsi_pll_div_prepare; - } else { - mdss_dsi1_vco_clk_src.priv = pll_res; - } - - if ((pll_res->target_id == MDSS_PLL_TARGET_8994) || - (pll_res->target_id == MDSS_PLL_TARGET_8992)) { - if (pll_res->index) { - rc = of_msm_clock_register(pdev->dev.of_node, - mdss_dsi_pll_1_cc_8994, - ARRAY_SIZE(mdss_dsi_pll_1_cc_8994)); - if (rc) { - pr_err("Clock register failed\n"); - rc = -EPROBE_DEFER; - } - } else { - rc = of_msm_clock_register(pdev->dev.of_node, - mdss_dsi_pllcc_8994, - ARRAY_SIZE(mdss_dsi_pllcc_8994)); - if (rc) { - pr_err("Clock register failed\n"); - rc = -EPROBE_DEFER; - } - pll_res->gdsc_cb.notifier_call = - dsi_pll_regulator_notifier_call; - INIT_WORK(&pll_res->pll_off, dsi_pll_off_work); - - pll_reg = mdss_pll_get_mp_by_reg_name(pll_res, "gdsc"); - if (pll_reg) { - pr_debug("Registering for gdsc regulator events\n"); - if (regulator_register_notifier(pll_reg->vreg, - &(pll_res->gdsc_cb))) - pr_err("Regulator notification registration failed!\n"); - } - } - - } else { - pr_err("Invalid target ID\n"); - rc = -EINVAL; - } - - if (!rc) - pr_info("Registered DSI PLL clocks successfully\n"); - - return rc; -} diff --git a/pll/dsi_pll_28hpm.c b/pll/dsi_pll_28hpm.c deleted file mode 100644 index ba9052342d2a..000000000000 --- a/pll/dsi_pll_28hpm.c +++ /dev/null @@ -1,317 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. - */ - -#define pr_fmt(fmt) "%s: " fmt, __func__ - -#include -#include -#include -#include -#include -#include -#include - -#include "pll_drv.h" -#include "dsi_pll.h" - -#define VCO_DELAY_USEC 1 - -static struct clk_div_ops fixed_2div_ops; -static const struct clk_ops byte_mux_clk_ops; -static const struct clk_ops pixel_clk_src_ops; -static const struct clk_ops byte_clk_src_ops; -static const struct clk_ops analog_postdiv_clk_ops; -static struct lpfr_cfg lpfr_lut_struct[] = { - {479500000, 8}, - {480000000, 11}, - {575500000, 8}, - {576000000, 12}, - {610500000, 8}, - {659500000, 9}, - {671500000, 10}, - {672000000, 14}, - {708500000, 10}, - {750000000, 11}, -}; - -static void dsi_pll_software_reset(struct mdss_pll_resources *dsi_pll_res) -{ - /* - * Add HW recommended delays after toggling the software - * reset bit off and back on. - */ - MDSS_PLL_REG_W(dsi_pll_res->pll_base, - DSI_PHY_PLL_UNIPHY_PLL_TEST_CFG, 0x01); - udelay(1); - MDSS_PLL_REG_W(dsi_pll_res->pll_base, - DSI_PHY_PLL_UNIPHY_PLL_TEST_CFG, 0x00); - udelay(1); -} - -static int vco_set_rate_hpm(struct clk *c, unsigned long rate) -{ - int rc; - struct dsi_pll_vco_clk *vco = to_vco_clk(c); - struct mdss_pll_resources *dsi_pll_res = vco->priv; - - rc = mdss_pll_resource_enable(dsi_pll_res, true); - if (rc) { - pr_err("Failed to enable mdss dsi pll resources\n"); - return rc; - } - - rc = vco_set_rate(vco, rate); - - mdss_pll_resource_enable(dsi_pll_res, false); - return rc; -} - -static int dsi_pll_enable_seq_8974(struct mdss_pll_resources *dsi_pll_res) -{ - int i, rc = 0; - int pll_locked; - - dsi_pll_software_reset(dsi_pll_res); - - /* - * PLL power up sequence. - * Add necessary delays recommeded by hardware. - */ - MDSS_PLL_REG_W(dsi_pll_res->pll_base, - DSI_PHY_PLL_UNIPHY_PLL_GLB_CFG, 0x01); - udelay(1); - MDSS_PLL_REG_W(dsi_pll_res->pll_base, - DSI_PHY_PLL_UNIPHY_PLL_GLB_CFG, 0x05); - udelay(200); - MDSS_PLL_REG_W(dsi_pll_res->pll_base, - DSI_PHY_PLL_UNIPHY_PLL_GLB_CFG, 0x07); - udelay(500); - MDSS_PLL_REG_W(dsi_pll_res->pll_base, - DSI_PHY_PLL_UNIPHY_PLL_GLB_CFG, 0x0f); - udelay(500); - - for (i = 0; i < 2; i++) { - udelay(100); - /* DSI Uniphy lock detect setting */ - MDSS_PLL_REG_W(dsi_pll_res->pll_base, - DSI_PHY_PLL_UNIPHY_PLL_LKDET_CFG2, 0x0c); - udelay(100); - MDSS_PLL_REG_W(dsi_pll_res->pll_base, - DSI_PHY_PLL_UNIPHY_PLL_LKDET_CFG2, 0x0d); - - pll_locked = dsi_pll_lock_status(dsi_pll_res); - if (pll_locked) - break; - - dsi_pll_software_reset(dsi_pll_res); - /* - * PLL power up sequence. - * Add necessary delays recommeded by hardware. - */ - MDSS_PLL_REG_W(dsi_pll_res->pll_base, - DSI_PHY_PLL_UNIPHY_PLL_GLB_CFG, 0x1); - udelay(1); - MDSS_PLL_REG_W(dsi_pll_res->pll_base, - DSI_PHY_PLL_UNIPHY_PLL_GLB_CFG, 0x5); - udelay(200); - MDSS_PLL_REG_W(dsi_pll_res->pll_base, - DSI_PHY_PLL_UNIPHY_PLL_GLB_CFG, 0x7); - udelay(250); - MDSS_PLL_REG_W(dsi_pll_res->pll_base, - DSI_PHY_PLL_UNIPHY_PLL_GLB_CFG, 0x5); - udelay(200); - MDSS_PLL_REG_W(dsi_pll_res->pll_base, - DSI_PHY_PLL_UNIPHY_PLL_GLB_CFG, 0x7); - udelay(500); - MDSS_PLL_REG_W(dsi_pll_res->pll_base, - DSI_PHY_PLL_UNIPHY_PLL_GLB_CFG, 0xf); - udelay(500); - - } - - if (!pll_locked) { - pr_err("DSI PLL lock failed\n"); - rc = -EINVAL; - } else { - pr_debug("DSI PLL Lock success\n"); - } - - return rc; -} - -/* Op structures */ - -static const struct clk_ops clk_ops_dsi_vco = { - .set_rate = vco_set_rate_hpm, - .round_rate = vco_round_rate, - .handoff = vco_handoff, - .prepare = vco_prepare, - .unprepare = vco_unprepare, -}; - - -static struct clk_div_ops fixed_4div_ops = { - .set_div = fixed_4div_set_div, - .get_div = fixed_4div_get_div, -}; - -static struct clk_div_ops analog_postdiv_ops = { - .set_div = analog_set_div, - .get_div = analog_get_div, -}; - -static struct clk_div_ops digital_postdiv_ops = { - .set_div = digital_set_div, - .get_div = digital_get_div, -}; - -static struct clk_mux_ops byte_mux_ops = { - .set_mux_sel = set_byte_mux_sel, - .get_mux_sel = get_byte_mux_sel, -}; - -static struct dsi_pll_vco_clk dsi_vco_clk_8974 = { - .ref_clk_rate = 19200000, - .min_rate = 350000000, - .max_rate = 750000000, - .pll_en_seq_cnt = 3, - .pll_enable_seqs[0] = dsi_pll_enable_seq_8974, - .pll_enable_seqs[1] = dsi_pll_enable_seq_8974, - .pll_enable_seqs[2] = dsi_pll_enable_seq_8974, - .lpfr_lut_size = 10, - .lpfr_lut = lpfr_lut_struct, - .c = { - .dbg_name = "dsi_vco_clk_8974", - .ops = &clk_ops_dsi_vco, - CLK_INIT(dsi_vco_clk_8974.c), - }, -}; - -static struct div_clk analog_postdiv_clk_8974 = { - .data = { - .max_div = 255, - .min_div = 1, - }, - .ops = &analog_postdiv_ops, - .c = { - .parent = &dsi_vco_clk_8974.c, - .dbg_name = "analog_postdiv_clk", - .ops = &analog_postdiv_clk_ops, - .flags = CLKFLAG_NO_RATE_CACHE, - CLK_INIT(analog_postdiv_clk_8974.c), - }, -}; - -static struct div_clk indirect_path_div2_clk_8974 = { - .ops = &fixed_2div_ops, - .data = { - .div = 2, - .min_div = 2, - .max_div = 2, - }, - .c = { - .parent = &analog_postdiv_clk_8974.c, - .dbg_name = "indirect_path_div2_clk", - .ops = &clk_ops_div, - .flags = CLKFLAG_NO_RATE_CACHE, - CLK_INIT(indirect_path_div2_clk_8974.c), - }, -}; - -static struct div_clk pixel_clk_src_8974 = { - .data = { - .max_div = 255, - .min_div = 1, - }, - .ops = &digital_postdiv_ops, - .c = { - .parent = &dsi_vco_clk_8974.c, - .dbg_name = "pixel_clk_src_8974", - .ops = &pixel_clk_src_ops, - .flags = CLKFLAG_NO_RATE_CACHE, - CLK_INIT(pixel_clk_src_8974.c), - }, -}; - -static struct mux_clk byte_mux_8974 = { - .num_parents = 2, - .parents = (struct clk_src[]){ - {&dsi_vco_clk_8974.c, 0}, - {&indirect_path_div2_clk_8974.c, 1}, - }, - .ops = &byte_mux_ops, - .c = { - .parent = &dsi_vco_clk_8974.c, - .dbg_name = "byte_mux_8974", - .ops = &byte_mux_clk_ops, - CLK_INIT(byte_mux_8974.c), - }, -}; - -static struct div_clk byte_clk_src_8974 = { - .ops = &fixed_4div_ops, - .data = { - .min_div = 4, - .max_div = 4, - }, - .c = { - .parent = &byte_mux_8974.c, - .dbg_name = "byte_clk_src_8974", - .ops = &byte_clk_src_ops, - CLK_INIT(byte_clk_src_8974.c), - }, -}; - -static struct clk_lookup mdss_dsi_pllcc_8974[] = { - CLK_LOOKUP_OF("pixel_src", pixel_clk_src_8974, - "fd8c0000.qcom,mmsscc-mdss"), - CLK_LOOKUP_OF("byte_src", byte_clk_src_8974, - "fd8c0000.qcom,mmsscc-mdss"), -}; - -int dsi_pll_clock_register_hpm(struct platform_device *pdev, - struct mdss_pll_resources *pll_res) -{ - int rc; - - /* Set client data to mux, div and vco clocks */ - byte_clk_src_8974.priv = pll_res; - pixel_clk_src_8974.priv = pll_res; - byte_mux_8974.priv = pll_res; - indirect_path_div2_clk_8974.priv = pll_res; - analog_postdiv_clk_8974.priv = pll_res; - dsi_vco_clk_8974.priv = pll_res; - pll_res->vco_delay = VCO_DELAY_USEC; - - /* Set clock source operations */ - pixel_clk_src_ops = clk_ops_slave_div; - pixel_clk_src_ops.prepare = dsi_pll_div_prepare; - - analog_postdiv_clk_ops = clk_ops_div; - analog_postdiv_clk_ops.prepare = dsi_pll_div_prepare; - - byte_clk_src_ops = clk_ops_div; - byte_clk_src_ops.prepare = dsi_pll_div_prepare; - - byte_mux_clk_ops = clk_ops_gen_mux; - byte_mux_clk_ops.prepare = dsi_pll_mux_prepare; - - if (pll_res->target_id == MDSS_PLL_TARGET_8974) { - rc = of_msm_clock_register(pdev->dev.of_node, - mdss_dsi_pllcc_8974, ARRAY_SIZE(mdss_dsi_pllcc_8974)); - if (rc) { - pr_err("Clock register failed\n"); - rc = -EPROBE_DEFER; - } - } else { - pr_err("Invalid target ID\n"); - rc = -EINVAL; - } - - if (!rc) - pr_info("Registered DSI PLL clocks successfully\n"); - - return rc; -} diff --git a/pll/dsi_pll_28lpm.c b/pll/dsi_pll_28lpm.c deleted file mode 100644 index 16c2eff92e6b..000000000000 --- a/pll/dsi_pll_28lpm.c +++ /dev/null @@ -1,545 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. - */ - -#define pr_fmt(fmt) "%s: " fmt, __func__ - -#include -#include -#include -#include - -#include "pll_drv.h" -#include "dsi_pll.h" -#include "dsi_pll_28nm.h" - -#define VCO_DELAY_USEC 1000 - -enum { - DSI_PLL_0, - DSI_PLL_1, - DSI_PLL_MAX -}; - -static struct lpfr_cfg lpfr_lut_struct[] = { - {479500000, 8}, - {480000000, 11}, - {575500000, 8}, - {576000000, 12}, - {610500000, 8}, - {659500000, 9}, - {671500000, 10}, - {672000000, 14}, - {708500000, 10}, - {750000000, 11}, -}; - -static void dsi_pll_sw_reset(struct mdss_pll_resources *rsc) -{ - /* - * DSI PLL software reset. Add HW recommended delays after toggling - * the software reset bit off and back on. - */ - MDSS_PLL_REG_W(rsc->pll_base, - DSI_PHY_PLL_UNIPHY_PLL_TEST_CFG, 0x01); - ndelay(500); - MDSS_PLL_REG_W(rsc->pll_base, - DSI_PHY_PLL_UNIPHY_PLL_TEST_CFG, 0x00); -} - -static void dsi_pll_toggle_lock_detect( - struct mdss_pll_resources *rsc) -{ - /* DSI PLL toggle lock detect setting */ - MDSS_PLL_REG_W(rsc->pll_base, - DSI_PHY_PLL_UNIPHY_PLL_LKDET_CFG2, 0x04); - ndelay(500); - MDSS_PLL_REG_W(rsc->pll_base, - DSI_PHY_PLL_UNIPHY_PLL_LKDET_CFG2, 0x05); - udelay(512); -} - -static int dsi_pll_check_lock_status( - struct mdss_pll_resources *rsc) -{ - int rc = 0; - - rc = dsi_pll_lock_status(rsc); - if (rc) - pr_debug("PLL Locked\n"); - else - pr_err("PLL failed to lock\n"); - - return rc; -} - - -static int dsi_pll_enable_seq_gf2(struct mdss_pll_resources *rsc) -{ - int pll_locked = 0; - - dsi_pll_sw_reset(rsc); - - /* - * GF PART 2 PLL power up sequence. - * Add necessary delays recommended by hardware. - */ - MDSS_PLL_REG_W(rsc->pll_base, - DSI_PHY_PLL_UNIPHY_PLL_CAL_CFG1, 0x04); - MDSS_PLL_REG_W(rsc->pll_base, - DSI_PHY_PLL_UNIPHY_PLL_GLB_CFG, 0x01); - MDSS_PLL_REG_W(rsc->pll_base, - DSI_PHY_PLL_UNIPHY_PLL_GLB_CFG, 0x05); - udelay(3); - MDSS_PLL_REG_W(rsc->pll_base, - DSI_PHY_PLL_UNIPHY_PLL_GLB_CFG, 0x0f); - udelay(500); - - dsi_pll_toggle_lock_detect(rsc); - - pll_locked = dsi_pll_check_lock_status(rsc); - return pll_locked ? 0 : -EINVAL; -} - -static int dsi_pll_enable_seq_gf1(struct mdss_pll_resources *rsc) -{ - int pll_locked = 0; - - dsi_pll_sw_reset(rsc); - /* - * GF PART 1 PLL power up sequence. - * Add necessary delays recommended by hardware. - */ - - MDSS_PLL_REG_W(rsc->pll_base, - DSI_PHY_PLL_UNIPHY_PLL_CAL_CFG1, 0x14); - MDSS_PLL_REG_W(rsc->pll_base, - DSI_PHY_PLL_UNIPHY_PLL_GLB_CFG, 0x01); - MDSS_PLL_REG_W(rsc->pll_base, - DSI_PHY_PLL_UNIPHY_PLL_GLB_CFG, 0x05); - udelay(3); - MDSS_PLL_REG_W(rsc->pll_base, - DSI_PHY_PLL_UNIPHY_PLL_GLB_CFG, 0x0f); - udelay(500); - - dsi_pll_toggle_lock_detect(rsc); - - pll_locked = dsi_pll_check_lock_status(rsc); - return pll_locked ? 0 : -EINVAL; -} - -static int dsi_pll_enable_seq_tsmc(struct mdss_pll_resources *rsc) -{ - int pll_locked = 0; - - dsi_pll_sw_reset(rsc); - /* - * TSMC PLL power up sequence. - * Add necessary delays recommended by hardware. - */ - MDSS_PLL_REG_W(rsc->pll_base, - DSI_PHY_PLL_UNIPHY_PLL_CAL_CFG1, 0x34); - MDSS_PLL_REG_W(rsc->pll_base, - DSI_PHY_PLL_UNIPHY_PLL_GLB_CFG, 0x01); - MDSS_PLL_REG_W(rsc->pll_base, - DSI_PHY_PLL_UNIPHY_PLL_GLB_CFG, 0x05); - MDSS_PLL_REG_W(rsc->pll_base, - DSI_PHY_PLL_UNIPHY_PLL_GLB_CFG, 0x0f); - udelay(500); - - dsi_pll_toggle_lock_detect(rsc); - - pll_locked = dsi_pll_check_lock_status(rsc); - return pll_locked ? 0 : -EINVAL; -} - -static struct regmap_config dsi_pll_28lpm_config = { - .reg_bits = 32, - .reg_stride = 4, - .val_bits = 32, - .max_register = 0xF4, -}; - -static struct regmap_bus analog_postdiv_regmap_bus = { - .reg_write = analog_postdiv_reg_write, - .reg_read = analog_postdiv_reg_read, -}; - -static struct regmap_bus byteclk_src_mux_regmap_bus = { - .reg_write = byteclk_mux_write_sel, - .reg_read = byteclk_mux_read_sel, -}; - -static struct regmap_bus pclk_src_regmap_bus = { - .reg_write = pixel_clk_set_div, - .reg_read = pixel_clk_get_div, -}; - -static const struct clk_ops clk_ops_vco_28lpm = { - .recalc_rate = vco_28nm_recalc_rate, - .set_rate = vco_28nm_set_rate, - .round_rate = vco_28nm_round_rate, - .prepare = vco_28nm_prepare, - .unprepare = vco_28nm_unprepare, -}; - -static struct dsi_pll_vco_clk dsi0pll_vco_clk = { - .ref_clk_rate = 19200000UL, - .min_rate = 350000000UL, - .max_rate = 750000000UL, - .pll_en_seq_cnt = 9, - .pll_enable_seqs[0] = dsi_pll_enable_seq_tsmc, - .pll_enable_seqs[1] = dsi_pll_enable_seq_tsmc, - .pll_enable_seqs[2] = dsi_pll_enable_seq_tsmc, - .pll_enable_seqs[3] = dsi_pll_enable_seq_gf1, - .pll_enable_seqs[4] = dsi_pll_enable_seq_gf1, - .pll_enable_seqs[5] = dsi_pll_enable_seq_gf1, - .pll_enable_seqs[6] = dsi_pll_enable_seq_gf2, - .pll_enable_seqs[7] = dsi_pll_enable_seq_gf2, - .pll_enable_seqs[8] = dsi_pll_enable_seq_gf2, - .lpfr_lut_size = 10, - .lpfr_lut = lpfr_lut_struct, - .hw.init = &(struct clk_init_data){ - .name = "dsi0pll_vco_clk", - .parent_names = (const char *[]){"cxo"}, - .num_parents = 1, - .ops = &clk_ops_vco_28lpm, - .flags = CLK_GET_RATE_NOCACHE, - }, -}; - -static struct dsi_pll_vco_clk dsi1pll_vco_clk = { - .ref_clk_rate = 19200000UL, - .min_rate = 350000000UL, - .max_rate = 750000000UL, - .pll_en_seq_cnt = 9, - .pll_enable_seqs[0] = dsi_pll_enable_seq_tsmc, - .pll_enable_seqs[1] = dsi_pll_enable_seq_tsmc, - .pll_enable_seqs[2] = dsi_pll_enable_seq_tsmc, - .pll_enable_seqs[3] = dsi_pll_enable_seq_gf1, - .pll_enable_seqs[4] = dsi_pll_enable_seq_gf1, - .pll_enable_seqs[5] = dsi_pll_enable_seq_gf1, - .pll_enable_seqs[6] = dsi_pll_enable_seq_gf2, - .pll_enable_seqs[7] = dsi_pll_enable_seq_gf2, - .pll_enable_seqs[8] = dsi_pll_enable_seq_gf2, - .lpfr_lut_size = 10, - .lpfr_lut = lpfr_lut_struct, - .hw.init = &(struct clk_init_data){ - .name = "dsi1pll_vco_clk", - .parent_names = (const char *[]){"cxo"}, - .num_parents = 1, - .ops = &clk_ops_vco_28lpm, - .flags = CLK_GET_RATE_NOCACHE, - }, -}; - -static struct clk_regmap_div dsi0pll_analog_postdiv = { - .reg = DSI_PHY_PLL_UNIPHY_PLL_POSTDIV1_CFG, - .shift = 0, - .width = 4, - .clkr = { - .hw.init = &(struct clk_init_data){ - .name = "dsi0pll_analog_postdiv", - .parent_names = (const char *[]){"dsi0pll_vco_clk"}, - .num_parents = 1, - .flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT), - .ops = &clk_regmap_div_ops, - }, - }, -}; - -static struct clk_regmap_div dsi1pll_analog_postdiv = { - .reg = DSI_PHY_PLL_UNIPHY_PLL_POSTDIV1_CFG, - .shift = 0, - .width = 4, - .clkr = { - .hw.init = &(struct clk_init_data){ - .name = "dsi1pll_analog_postdiv", - .parent_names = (const char *[]){"dsi1pll_vco_clk"}, - .num_parents = 1, - .flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT), - .ops = &clk_regmap_div_ops, - }, - }, -}; - -static struct clk_fixed_factor dsi0pll_indirect_path_src = { - .div = 2, - .mult = 1, - .hw.init = &(struct clk_init_data){ - .name = "dsi0pll_indirect_path_src", - .parent_names = (const char *[]){"dsi0pll_analog_postdiv"}, - .num_parents = 1, - .flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT), - .ops = &clk_fixed_factor_ops, - }, -}; - -static struct clk_fixed_factor dsi1pll_indirect_path_src = { - .div = 2, - .mult = 1, - .hw.init = &(struct clk_init_data){ - .name = "dsi1pll_indirect_path_src", - .parent_names = (const char *[]){"dsi1pll_analog_postdiv"}, - .num_parents = 1, - .flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT), - .ops = &clk_fixed_factor_ops, - }, -}; - -static struct clk_regmap_mux dsi0pll_byteclk_src_mux = { - .reg = DSI_PHY_PLL_UNIPHY_PLL_VREG_CFG, - .shift = 1, - .width = 1, - .clkr = { - .hw.init = &(struct clk_init_data){ - .name = "dsi0pll_byteclk_src_mux", - .parent_names = (const char *[]){ - "dsi0pll_vco_clk", - "dsi0pll_indirect_path_src"}, - .num_parents = 2, - .flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT), - .ops = &clk_regmap_mux_closest_ops, - }, - }, -}; - -static struct clk_regmap_mux dsi1pll_byteclk_src_mux = { - .reg = DSI_PHY_PLL_UNIPHY_PLL_VREG_CFG, - .shift = 1, - .width = 1, - .clkr = { - .hw.init = &(struct clk_init_data){ - .name = "dsi1pll_byteclk_src_mux", - .parent_names = (const char *[]){ - "dsi1pll_vco_clk", - "dsi1pll_indirect_path_src"}, - .num_parents = 2, - .flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT), - .ops = &clk_regmap_mux_closest_ops, - }, - }, -}; - -static struct clk_fixed_factor dsi0pll_byteclk_src = { - .div = 4, - .mult = 1, - .hw.init = &(struct clk_init_data){ - .name = "dsi0pll_byteclk_src", - .parent_names = (const char *[]){ - "dsi0pll_byteclk_src_mux"}, - .num_parents = 1, - .flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT), - .ops = &clk_fixed_factor_ops, - }, -}; - -static struct clk_fixed_factor dsi1pll_byteclk_src = { - .div = 4, - .mult = 1, - .hw.init = &(struct clk_init_data){ - .name = "dsi1pll_byteclk_src", - .parent_names = (const char *[]){ - "dsi1pll_byteclk_src_mux"}, - .num_parents = 1, - .flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT), - .ops = &clk_fixed_factor_ops, - }, -}; - -static struct clk_regmap_div dsi0pll_pclk_src = { - .reg = DSI_PHY_PLL_UNIPHY_PLL_POSTDIV3_CFG, - .shift = 0, - .width = 8, - .clkr = { - .hw.init = &(struct clk_init_data){ - .name = "dsi0pll_pclk_src", - .parent_names = (const char *[]){"dsi0pll_vco_clk"}, - .num_parents = 1, - .flags = CLK_GET_RATE_NOCACHE, - .ops = &clk_regmap_div_ops, - }, - }, -}; - -static struct clk_regmap_div dsi1pll_pclk_src = { - .reg = DSI_PHY_PLL_UNIPHY_PLL_POSTDIV3_CFG, - .shift = 0, - .width = 8, - .clkr = { - .hw.init = &(struct clk_init_data){ - .name = "dsi1pll_pclk_src", - .parent_names = (const char *[]){"dsi1pll_vco_clk"}, - .num_parents = 1, - .flags = CLK_GET_RATE_NOCACHE, - .ops = &clk_regmap_div_ops, - }, - }, -}; - -static struct clk_hw *mdss_dsi_pllcc_28lpm[] = { - [VCO_CLK_0] = &dsi0pll_vco_clk.hw, - [ANALOG_POSTDIV_0_CLK] = &dsi0pll_analog_postdiv.clkr.hw, - [INDIRECT_PATH_SRC_0_CLK] = &dsi0pll_indirect_path_src.hw, - [BYTECLK_SRC_MUX_0_CLK] = &dsi0pll_byteclk_src_mux.clkr.hw, - [BYTECLK_SRC_0_CLK] = &dsi0pll_byteclk_src.hw, - [PCLK_SRC_0_CLK] = &dsi0pll_pclk_src.clkr.hw, - [VCO_CLK_1] = &dsi1pll_vco_clk.hw, - [ANALOG_POSTDIV_1_CLK] = &dsi1pll_analog_postdiv.clkr.hw, - [INDIRECT_PATH_SRC_1_CLK] = &dsi1pll_indirect_path_src.hw, - [BYTECLK_SRC_MUX_1_CLK] = &dsi1pll_byteclk_src_mux.clkr.hw, - [BYTECLK_SRC_1_CLK] = &dsi1pll_byteclk_src.hw, - [PCLK_SRC_1_CLK] = &dsi1pll_pclk_src.clkr.hw, -}; - -int dsi_pll_clock_register_28lpm(struct platform_device *pdev, - struct mdss_pll_resources *pll_res) -{ - int rc = 0, ndx, i; - struct clk *clk; - struct clk_onecell_data *clk_data; - int num_clks = ARRAY_SIZE(mdss_dsi_pllcc_28lpm); - struct regmap *rmap; - - int const ssc_freq_min = 30000; /* min. recommended freq. value */ - int const ssc_freq_max = 33000; /* max. recommended freq. value */ - int const ssc_ppm_max = 5000; /* max. recommended ppm */ - - ndx = pll_res->index; - - if (ndx >= DSI_PLL_MAX) { - pr_err("pll index(%d) NOT supported\n", ndx); - return -EINVAL; - } - - pll_res->vco_delay = VCO_DELAY_USEC; - - if (pll_res->ssc_en) { - if (!pll_res->ssc_freq || (pll_res->ssc_freq < ssc_freq_min) || - (pll_res->ssc_freq > ssc_freq_max)) { - pll_res->ssc_freq = ssc_freq_min; - pr_debug("SSC frequency out of recommended range. Set to default=%d\n", - pll_res->ssc_freq); - } - - if (!pll_res->ssc_ppm || (pll_res->ssc_ppm > ssc_ppm_max)) { - pll_res->ssc_ppm = ssc_ppm_max; - pr_debug("SSC PPM out of recommended range. Set to default=%d\n", - pll_res->ssc_ppm); - } - } - - clk_data = devm_kzalloc(&pdev->dev, sizeof(*clk_data), - GFP_KERNEL); - if (!clk_data) - return -ENOMEM; - - clk_data->clks = devm_kcalloc(&pdev->dev, num_clks, - sizeof(struct clk *), GFP_KERNEL); - if (!clk_data->clks) - return -ENOMEM; - - clk_data->clk_num = num_clks; - - /* Establish client data */ - if (ndx == 0) { - rmap = devm_regmap_init(&pdev->dev, &byteclk_src_mux_regmap_bus, - pll_res, &dsi_pll_28lpm_config); - if (IS_ERR(rmap)) { - pr_err("regmap init failed for DSI clock:%d\n", - pll_res->index); - return -EINVAL; - } - dsi0pll_byteclk_src_mux.clkr.regmap = rmap; - - rmap = devm_regmap_init(&pdev->dev, &analog_postdiv_regmap_bus, - pll_res, &dsi_pll_28lpm_config); - if (IS_ERR(rmap)) { - pr_err("regmap init failed for DSI clock:%d\n", - pll_res->index); - return -EINVAL; - } - dsi0pll_analog_postdiv.clkr.regmap = rmap; - - rmap = devm_regmap_init(&pdev->dev, &pclk_src_regmap_bus, - pll_res, &dsi_pll_28lpm_config); - if (IS_ERR(rmap)) { - pr_err("regmap init failed for DSI clock:%d\n", - pll_res->index); - return -EINVAL; - } - dsi0pll_pclk_src.clkr.regmap = rmap; - - dsi0pll_vco_clk.priv = pll_res; - for (i = VCO_CLK_0; i <= PCLK_SRC_0_CLK; i++) { - clk = devm_clk_register(&pdev->dev, - mdss_dsi_pllcc_28lpm[i]); - if (IS_ERR(clk)) { - pr_err("clk registration failed for DSI clock:%d\n", - pll_res->index); - rc = -EINVAL; - goto clk_register_fail; - } - clk_data->clks[i] = clk; - - } - - rc = of_clk_add_provider(pdev->dev.of_node, - of_clk_src_onecell_get, clk_data); - - } else { - rmap = devm_regmap_init(&pdev->dev, &byteclk_src_mux_regmap_bus, - pll_res, &dsi_pll_28lpm_config); - if (IS_ERR(rmap)) { - pr_err("regmap init failed for DSI clock:%d\n", - pll_res->index); - return -EINVAL; - } - dsi1pll_byteclk_src_mux.clkr.regmap = rmap; - - rmap = devm_regmap_init(&pdev->dev, &analog_postdiv_regmap_bus, - pll_res, &dsi_pll_28lpm_config); - if (IS_ERR(rmap)) { - pr_err("regmap init failed for DSI clock:%d\n", - pll_res->index); - return -EINVAL; - } - dsi1pll_analog_postdiv.clkr.regmap = rmap; - - rmap = devm_regmap_init(&pdev->dev, &pclk_src_regmap_bus, - pll_res, &dsi_pll_28lpm_config); - if (IS_ERR(rmap)) { - pr_err("regmap init failed for DSI clock:%d\n", - pll_res->index); - return -EINVAL; - } - dsi1pll_pclk_src.clkr.regmap = rmap; - - dsi1pll_vco_clk.priv = pll_res; - for (i = VCO_CLK_1; i <= PCLK_SRC_1_CLK; i++) { - clk = devm_clk_register(&pdev->dev, - mdss_dsi_pllcc_28lpm[i]); - if (IS_ERR(clk)) { - pr_err("clk registration failed for DSI clock:%d\n", - pll_res->index); - rc = -EINVAL; - goto clk_register_fail; - } - clk_data->clks[i] = clk; - - } - - rc = of_clk_add_provider(pdev->dev.of_node, - of_clk_src_onecell_get, clk_data); - } - if (!rc) { - pr_info("Registered DSI PLL ndx=%d, clocks successfully\n", - ndx); - - return rc; - } - -clk_register_fail: - return rc; -} diff --git a/pll/dsi_pll_28nm.h b/pll/dsi_pll_28nm.h deleted file mode 100644 index 2c59a6477f65..000000000000 --- a/pll/dsi_pll_28nm.h +++ /dev/null @@ -1,64 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. - */ - -#ifndef __MDSS_DSI_PLL_28NM_H -#define __MDSS_DSI_PLL_28NM_H - -#define DSI_PHY_PLL_UNIPHY_PLL_GLB_CFG (0x0020) -#define DSI_PHY_PLL_UNIPHY_PLL_LKDET_CFG2 (0x0064) -#define DSI_PHY_PLL_UNIPHY_PLL_TEST_CFG (0x0068) -#define DSI_PHY_PLL_UNIPHY_PLL_CAL_CFG1 (0x0070) - -#define DSI_PHY_PLL_UNIPHY_PLL_POSTDIV1_CFG (0x0004) -#define DSI_PHY_PLL_UNIPHY_PLL_POSTDIV3_CFG (0x0028) -#define DSI_PHY_PLL_UNIPHY_PLL_VREG_CFG (0x0010) - -struct ssc_params { - s32 kdiv; - s64 triang_inc_7_0; - s64 triang_inc_9_8; - s64 triang_steps; - s64 dc_offset; - s64 freq_seed_7_0; - s64 freq_seed_15_8; -}; - -struct mdss_dsi_vco_calc { - s64 sdm_cfg0; - s64 sdm_cfg1; - s64 sdm_cfg2; - s64 sdm_cfg3; - s64 cal_cfg10; - s64 cal_cfg11; - s64 refclk_cfg; - s64 gen_vco_clk; - u32 lpfr_lut_res; - struct ssc_params ssc; -}; - -unsigned long vco_28nm_recalc_rate(struct clk_hw *hw, - unsigned long parent_rate); -int vco_28nm_set_rate(struct clk_hw *hw, unsigned long rate, - unsigned long parent_rate); -long vco_28nm_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate); -int vco_28nm_prepare(struct clk_hw *hw); -void vco_28nm_unprepare(struct clk_hw *hw); - -int analog_postdiv_reg_write(void *context, - unsigned int reg, unsigned int div); -int analog_postdiv_reg_read(void *context, - unsigned int reg, unsigned int *div); -int byteclk_mux_write_sel(void *context, - unsigned int reg, unsigned int val); -int byteclk_mux_read_sel(void *context, - unsigned int reg, unsigned int *val); -int pixel_clk_set_div(void *context, - unsigned int reg, unsigned int div); -int pixel_clk_get_div(void *context, - unsigned int reg, unsigned int *div); - -int dsi_pll_lock_status(struct mdss_pll_resources *rsc); -#endif /* __MDSS_DSI_PLL_28NM_H */ diff --git a/pll/dsi_pll_28nm_util.c b/pll/dsi_pll_28nm_util.c deleted file mode 100644 index 6ec5a70b8322..000000000000 --- a/pll/dsi_pll_28nm_util.c +++ /dev/null @@ -1,652 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. - */ - -#define pr_fmt(fmt) "%s: " fmt, __func__ - -#include -#include -#include -#include - -#include "pll_drv.h" -#include "dsi_pll.h" -#include "dsi_pll_28nm.h" - -#define DSI_PHY_PLL_UNIPHY_PLL_REFCLK_CFG (0x0) -#define DSI_PHY_PLL_UNIPHY_PLL_CHGPUMP_CFG (0x0008) -#define DSI_PHY_PLL_UNIPHY_PLL_VCOLPF_CFG (0x000C) -#define DSI_PHY_PLL_UNIPHY_PLL_PWRGEN_CFG (0x0014) -#define DSI_PHY_PLL_UNIPHY_PLL_POSTDIV2_CFG (0x0024) -#define DSI_PHY_PLL_UNIPHY_PLL_LPFR_CFG (0x002C) -#define DSI_PHY_PLL_UNIPHY_PLL_LPFC1_CFG (0x0030) -#define DSI_PHY_PLL_UNIPHY_PLL_LPFC2_CFG (0x0034) -#define DSI_PHY_PLL_UNIPHY_PLL_SDM_CFG0 (0x0038) -#define DSI_PHY_PLL_UNIPHY_PLL_SDM_CFG1 (0x003C) -#define DSI_PHY_PLL_UNIPHY_PLL_SDM_CFG2 (0x0040) -#define DSI_PHY_PLL_UNIPHY_PLL_SDM_CFG3 (0x0044) -#define DSI_PHY_PLL_UNIPHY_PLL_SDM_CFG4 (0x0048) -#define DSI_PHY_PLL_UNIPHY_PLL_SSC_CFG0 (0x004C) -#define DSI_PHY_PLL_UNIPHY_PLL_SSC_CFG1 (0x0050) -#define DSI_PHY_PLL_UNIPHY_PLL_SSC_CFG2 (0x0054) -#define DSI_PHY_PLL_UNIPHY_PLL_SSC_CFG3 (0x0058) -#define DSI_PHY_PLL_UNIPHY_PLL_CAL_CFG0 (0x006C) -#define DSI_PHY_PLL_UNIPHY_PLL_CAL_CFG2 (0x0074) -#define DSI_PHY_PLL_UNIPHY_PLL_CAL_CFG3 (0x0078) -#define DSI_PHY_PLL_UNIPHY_PLL_CAL_CFG4 (0x007C) -#define DSI_PHY_PLL_UNIPHY_PLL_CAL_CFG5 (0x0080) -#define DSI_PHY_PLL_UNIPHY_PLL_CAL_CFG6 (0x0084) -#define DSI_PHY_PLL_UNIPHY_PLL_CAL_CFG7 (0x0088) -#define DSI_PHY_PLL_UNIPHY_PLL_CAL_CFG8 (0x008C) -#define DSI_PHY_PLL_UNIPHY_PLL_CAL_CFG9 (0x0090) -#define DSI_PHY_PLL_UNIPHY_PLL_CAL_CFG10 (0x0094) -#define DSI_PHY_PLL_UNIPHY_PLL_CAL_CFG11 (0x0098) -#define DSI_PHY_PLL_UNIPHY_PLL_EFUSE_CFG (0x009C) -#define DSI_PHY_PLL_UNIPHY_PLL_STATUS (0x00C0) - -#define DSI_PLL_POLL_DELAY_US 50 -#define DSI_PLL_POLL_TIMEOUT_US 500 - -int analog_postdiv_reg_read(void *context, unsigned int reg, - unsigned int *div) -{ - int rc = 0; - struct mdss_pll_resources *rsc = context; - - rc = mdss_pll_resource_enable(rsc, true); - if (rc) { - pr_err("Failed to enable dsi pll resources, rc=%d\n", rc); - return rc; - } - - *div = MDSS_PLL_REG_R(rsc->pll_base, reg); - - pr_debug("analog_postdiv div = %d\n", *div); - - (void)mdss_pll_resource_enable(rsc, false); - return rc; -} - -int analog_postdiv_reg_write(void *context, unsigned int reg, - unsigned int div) -{ - int rc = 0; - struct mdss_pll_resources *rsc = context; - - rc = mdss_pll_resource_enable(rsc, true); - if (rc) { - pr_err("Failed to enable dsi pll resources, rc=%d\n", rc); - return rc; - } - - pr_debug("analog_postdiv div = %d\n", div); - - MDSS_PLL_REG_W(rsc->pll_base, reg, div); - - (void)mdss_pll_resource_enable(rsc, false); - return rc; -} - -int byteclk_mux_read_sel(void *context, unsigned int reg, - unsigned int *val) -{ - int rc = 0; - struct mdss_pll_resources *rsc = context; - - rc = mdss_pll_resource_enable(rsc, true); - if (rc) { - pr_err("Failed to enable dsi pll resources, rc=%d\n", rc); - return rc; - } - - *val = (MDSS_PLL_REG_R(rsc->pll_base, reg) & BIT(1)); - pr_debug("byteclk mux mode = %s\n", *val ? "indirect" : "direct"); - - (void)mdss_pll_resource_enable(rsc, false); - return rc; -} - -int byteclk_mux_write_sel(void *context, unsigned int reg, - unsigned int val) -{ - int rc = 0; - u32 reg_val = 0; - struct mdss_pll_resources *rsc = context; - - rc = mdss_pll_resource_enable(rsc, true); - if (rc) { - pr_err("Failed to enable dsi pll resources, rc=%d\n", rc); - return rc; - } - - pr_debug("byteclk mux set to %s mode\n", val ? "indirect" : "direct"); - - reg_val = MDSS_PLL_REG_R(rsc->pll_base, reg); - reg_val &= ~0x02; - reg_val |= val; - - MDSS_PLL_REG_W(rsc->pll_base, reg, reg_val); - - (void)mdss_pll_resource_enable(rsc, false); - - return rc; -} - -int pixel_clk_get_div(void *context, unsigned int reg, - unsigned int *div) -{ - int rc = 0; - struct mdss_pll_resources *rsc = context; - - rc = mdss_pll_resource_enable(rsc, true); - if (rc) { - pr_err("Failed to enable dsi pll resources, rc=%d\n", rc); - return rc; - } - - *div = MDSS_PLL_REG_R(rsc->pll_base, reg); - - pr_debug("pclk_src div = %d\n", *div); - - (void)mdss_pll_resource_enable(rsc, false); - return rc; -} - -int pixel_clk_set_div(void *context, unsigned int reg, - unsigned int div) -{ - int rc = 0; - struct mdss_pll_resources *rsc = context; - - rc = mdss_pll_resource_enable(rsc, true); - if (rc) { - pr_err("Failed to enable dsi pll resources, rc=%d\n", rc); - return rc; - } - - pr_debug("pclk_src div = %d\n", div); - - MDSS_PLL_REG_W(rsc->pll_base, reg, div); - - (void)mdss_pll_resource_enable(rsc, false); - return rc; -} - -int dsi_pll_lock_status(struct mdss_pll_resources *rsc) -{ - u32 status; - int pll_locked; - - /* poll for PLL ready status */ - if (readl_poll_timeout_atomic((rsc->pll_base + - DSI_PHY_PLL_UNIPHY_PLL_STATUS), - status, - ((status & BIT(0)) == 1), - DSI_PLL_POLL_DELAY_US, - DSI_PLL_POLL_TIMEOUT_US)) { - pr_debug("DSI PLL status=%x failed to Lock\n", status); - pll_locked = 0; - } else { - pll_locked = 1; - } - - return pll_locked; -} - -static int pll_28nm_vco_rate_calc(struct dsi_pll_vco_clk *vco, - struct mdss_dsi_vco_calc *vco_calc, unsigned long vco_clk_rate) -{ - s32 rem; - s64 frac_n_mode, ref_doubler_en_b; - s64 ref_clk_to_pll, div_fb, frac_n_value; - int i; - - /* Configure the Loop filter resistance */ - for (i = 0; i < vco->lpfr_lut_size; i++) - if (vco_clk_rate <= vco->lpfr_lut[i].vco_rate) - break; - if (i == vco->lpfr_lut_size) { - pr_err("unable to get loop filter resistance. vco=%ld\n", - vco_clk_rate); - return -EINVAL; - } - vco_calc->lpfr_lut_res = vco->lpfr_lut[i].r; - - div_s64_rem(vco_clk_rate, vco->ref_clk_rate, &rem); - if (rem) { - vco_calc->refclk_cfg = 0x1; - frac_n_mode = 1; - ref_doubler_en_b = 0; - } else { - vco_calc->refclk_cfg = 0x0; - frac_n_mode = 0; - ref_doubler_en_b = 1; - } - - pr_debug("refclk_cfg = %lld\n", vco_calc->refclk_cfg); - - ref_clk_to_pll = ((vco->ref_clk_rate * 2 * (vco_calc->refclk_cfg)) - + (ref_doubler_en_b * vco->ref_clk_rate)); - - div_fb = div_s64_rem(vco_clk_rate, ref_clk_to_pll, &rem); - frac_n_value = div_s64(((s64)rem * (1 << 16)), ref_clk_to_pll); - vco_calc->gen_vco_clk = vco_clk_rate; - - pr_debug("ref_clk_to_pll = %lld\n", ref_clk_to_pll); - pr_debug("div_fb = %lld\n", div_fb); - pr_debug("frac_n_value = %lld\n", frac_n_value); - - pr_debug("Generated VCO Clock: %lld\n", vco_calc->gen_vco_clk); - rem = 0; - if (frac_n_mode) { - vco_calc->sdm_cfg0 = 0; - vco_calc->sdm_cfg1 = (div_fb & 0x3f) - 1; - vco_calc->sdm_cfg3 = div_s64_rem(frac_n_value, 256, &rem); - vco_calc->sdm_cfg2 = rem; - } else { - vco_calc->sdm_cfg0 = (0x1 << 5); - vco_calc->sdm_cfg0 |= (div_fb & 0x3f) - 1; - vco_calc->sdm_cfg1 = 0; - vco_calc->sdm_cfg2 = 0; - vco_calc->sdm_cfg3 = 0; - } - - pr_debug("sdm_cfg0=%lld\n", vco_calc->sdm_cfg0); - pr_debug("sdm_cfg1=%lld\n", vco_calc->sdm_cfg1); - pr_debug("sdm_cfg2=%lld\n", vco_calc->sdm_cfg2); - pr_debug("sdm_cfg3=%lld\n", vco_calc->sdm_cfg3); - - vco_calc->cal_cfg11 = div_s64_rem(vco_calc->gen_vco_clk, - 256 * 1000000, &rem); - vco_calc->cal_cfg10 = rem / 1000000; - pr_debug("cal_cfg10=%lld, cal_cfg11=%lld\n", - vco_calc->cal_cfg10, vco_calc->cal_cfg11); - - return 0; -} - -static void pll_28nm_ssc_param_calc(struct dsi_pll_vco_clk *vco, - struct mdss_dsi_vco_calc *vco_calc) -{ - struct mdss_pll_resources *rsc = vco->priv; - s64 ppm_freq, incr, spread_freq, div_rf, frac_n_value; - s32 rem; - - if (!rsc->ssc_en) { - pr_debug("DSI PLL SSC not enabled\n"); - return; - } - - vco_calc->ssc.kdiv = DIV_ROUND_CLOSEST(vco->ref_clk_rate, - 1000000) - 1; - vco_calc->ssc.triang_steps = DIV_ROUND_CLOSEST(vco->ref_clk_rate, - rsc->ssc_freq * (vco_calc->ssc.kdiv + 1)); - ppm_freq = div_s64(vco_calc->gen_vco_clk * rsc->ssc_ppm, - 1000000); - incr = div64_s64(ppm_freq * 65536, vco->ref_clk_rate * 2 * - vco_calc->ssc.triang_steps); - - vco_calc->ssc.triang_inc_7_0 = incr & 0xff; - vco_calc->ssc.triang_inc_9_8 = (incr >> 8) & 0x3; - - if (!rsc->ssc_center) - spread_freq = vco_calc->gen_vco_clk - ppm_freq; - else - spread_freq = vco_calc->gen_vco_clk - (ppm_freq / 2); - - div_rf = div_s64(spread_freq, 2 * vco->ref_clk_rate); - vco_calc->ssc.dc_offset = (div_rf - 1); - - div_s64_rem(spread_freq, 2 * vco->ref_clk_rate, &rem); - frac_n_value = div_s64((s64)rem * 65536, 2 * vco->ref_clk_rate); - - vco_calc->ssc.freq_seed_7_0 = frac_n_value & 0xff; - vco_calc->ssc.freq_seed_15_8 = (frac_n_value >> 8) & 0xff; -} - -static void pll_28nm_vco_config(struct dsi_pll_vco_clk *vco, - struct mdss_dsi_vco_calc *vco_calc) -{ - struct mdss_pll_resources *rsc = vco->priv; - void __iomem *pll_base = rsc->pll_base; - u32 vco_delay_us = rsc->vco_delay; - bool ssc_en = rsc->ssc_en; - - MDSS_PLL_REG_W(pll_base, DSI_PHY_PLL_UNIPHY_PLL_LPFR_CFG, - vco_calc->lpfr_lut_res); - - /* Loop filter capacitance values : c1 and c2 */ - MDSS_PLL_REG_W(pll_base, DSI_PHY_PLL_UNIPHY_PLL_LPFC1_CFG, 0x70); - MDSS_PLL_REG_W(pll_base, DSI_PHY_PLL_UNIPHY_PLL_LPFC2_CFG, 0x15); - - MDSS_PLL_REG_W(pll_base, DSI_PHY_PLL_UNIPHY_PLL_CHGPUMP_CFG, 0x02); - MDSS_PLL_REG_W(pll_base, DSI_PHY_PLL_UNIPHY_PLL_CAL_CFG3, 0x2b); - MDSS_PLL_REG_W(pll_base, DSI_PHY_PLL_UNIPHY_PLL_CAL_CFG4, 0x66); - MDSS_PLL_REG_W(pll_base, DSI_PHY_PLL_UNIPHY_PLL_LKDET_CFG2, 0x0d); - - if (!ssc_en) { - MDSS_PLL_REG_W(pll_base, DSI_PHY_PLL_UNIPHY_PLL_SDM_CFG1, - (u32)(vco_calc->sdm_cfg1 & 0xff)); - MDSS_PLL_REG_W(pll_base, DSI_PHY_PLL_UNIPHY_PLL_SDM_CFG2, - (u32)(vco_calc->sdm_cfg2 & 0xff)); - MDSS_PLL_REG_W(pll_base, DSI_PHY_PLL_UNIPHY_PLL_SDM_CFG3, - (u32)(vco_calc->sdm_cfg3 & 0xff)); - } else { - MDSS_PLL_REG_W(pll_base, DSI_PHY_PLL_UNIPHY_PLL_SDM_CFG1, - (u32)vco_calc->ssc.dc_offset); - MDSS_PLL_REG_W(pll_base, DSI_PHY_PLL_UNIPHY_PLL_SDM_CFG2, - (u32)vco_calc->ssc.freq_seed_7_0); - MDSS_PLL_REG_W(pll_base, DSI_PHY_PLL_UNIPHY_PLL_SDM_CFG3, - (u32)vco_calc->ssc.freq_seed_15_8); - MDSS_PLL_REG_W(pll_base, DSI_PHY_PLL_UNIPHY_PLL_SSC_CFG0, - (u32)vco_calc->ssc.kdiv); - MDSS_PLL_REG_W(pll_base, DSI_PHY_PLL_UNIPHY_PLL_SSC_CFG1, - (u32)vco_calc->ssc.triang_inc_7_0); - MDSS_PLL_REG_W(pll_base, DSI_PHY_PLL_UNIPHY_PLL_SSC_CFG2, - (u32)vco_calc->ssc.triang_inc_9_8); - MDSS_PLL_REG_W(pll_base, DSI_PHY_PLL_UNIPHY_PLL_SSC_CFG3, - (u32)vco_calc->ssc.triang_steps); - } - MDSS_PLL_REG_W(pll_base, DSI_PHY_PLL_UNIPHY_PLL_SDM_CFG4, 0x00); - - /* Add hardware recommended delay for correct PLL configuration */ - if (vco_delay_us) - udelay(vco_delay_us); - - MDSS_PLL_REG_W(pll_base, DSI_PHY_PLL_UNIPHY_PLL_REFCLK_CFG, - (u32)vco_calc->refclk_cfg); - MDSS_PLL_REG_W(pll_base, DSI_PHY_PLL_UNIPHY_PLL_PWRGEN_CFG, 0x00); - MDSS_PLL_REG_W(pll_base, DSI_PHY_PLL_UNIPHY_PLL_VCOLPF_CFG, 0x71); - MDSS_PLL_REG_W(pll_base, DSI_PHY_PLL_UNIPHY_PLL_SDM_CFG0, - (u32)vco_calc->sdm_cfg0); - MDSS_PLL_REG_W(pll_base, DSI_PHY_PLL_UNIPHY_PLL_CAL_CFG0, 0x12); - MDSS_PLL_REG_W(pll_base, DSI_PHY_PLL_UNIPHY_PLL_CAL_CFG6, 0x30); - MDSS_PLL_REG_W(pll_base, DSI_PHY_PLL_UNIPHY_PLL_CAL_CFG7, 0x00); - MDSS_PLL_REG_W(pll_base, DSI_PHY_PLL_UNIPHY_PLL_CAL_CFG8, 0x60); - MDSS_PLL_REG_W(pll_base, DSI_PHY_PLL_UNIPHY_PLL_CAL_CFG9, 0x00); - MDSS_PLL_REG_W(pll_base, DSI_PHY_PLL_UNIPHY_PLL_CAL_CFG10, - (u32)(vco_calc->cal_cfg10 & 0xff)); - MDSS_PLL_REG_W(pll_base, DSI_PHY_PLL_UNIPHY_PLL_CAL_CFG11, - (u32)(vco_calc->cal_cfg11 & 0xff)); - MDSS_PLL_REG_W(pll_base, DSI_PHY_PLL_UNIPHY_PLL_EFUSE_CFG, 0x20); - MDSS_PLL_REG_W(pll_base, - DSI_PHY_PLL_UNIPHY_PLL_POSTDIV2_CFG, 0x3); /* Fixed div-4 */ -} - -static int vco_set_rate(struct dsi_pll_vco_clk *vco, unsigned long rate) -{ - struct mdss_dsi_vco_calc vco_calc = {0}; - int rc = 0; - - rc = pll_28nm_vco_rate_calc(vco, &vco_calc, rate); - if (rc) { - pr_err("vco rate calculation failed\n"); - return rc; - } - - pll_28nm_ssc_param_calc(vco, &vco_calc); - pll_28nm_vco_config(vco, &vco_calc); - - return 0; -} - -static unsigned long vco_get_rate(struct dsi_pll_vco_clk *vco) -{ - struct mdss_pll_resources *rsc = vco->priv; - int rc; - u32 sdm0, doubler, sdm_byp_div; - u64 vco_rate; - u32 sdm_dc_off, sdm_freq_seed, sdm2, sdm3; - u64 ref_clk = vco->ref_clk_rate; - - rc = mdss_pll_resource_enable(rsc, true); - if (rc) { - pr_err("Failed to enable mdss dsi pll resources\n"); - return rc; - } - - /* Check to see if the ref clk doubler is enabled */ - doubler = MDSS_PLL_REG_R(rsc->pll_base, - DSI_PHY_PLL_UNIPHY_PLL_REFCLK_CFG) & BIT(0); - ref_clk += (doubler * vco->ref_clk_rate); - - /* see if it is integer mode or sdm mode */ - sdm0 = MDSS_PLL_REG_R(rsc->pll_base, - DSI_PHY_PLL_UNIPHY_PLL_SDM_CFG0); - if (sdm0 & BIT(6)) { - /* integer mode */ - sdm_byp_div = (MDSS_PLL_REG_R(rsc->pll_base, - DSI_PHY_PLL_UNIPHY_PLL_SDM_CFG0) & 0x3f) + 1; - vco_rate = ref_clk * sdm_byp_div; - } else { - /* sdm mode */ - sdm_dc_off = MDSS_PLL_REG_R(rsc->pll_base, - DSI_PHY_PLL_UNIPHY_PLL_SDM_CFG1) & 0xFF; - pr_debug("sdm_dc_off = %d\n", sdm_dc_off); - sdm2 = MDSS_PLL_REG_R(rsc->pll_base, - DSI_PHY_PLL_UNIPHY_PLL_SDM_CFG2) & 0xFF; - sdm3 = MDSS_PLL_REG_R(rsc->pll_base, - DSI_PHY_PLL_UNIPHY_PLL_SDM_CFG3) & 0xFF; - sdm_freq_seed = (sdm3 << 8) | sdm2; - pr_debug("sdm_freq_seed = %d\n", sdm_freq_seed); - - vco_rate = (ref_clk * (sdm_dc_off + 1)) + - mult_frac(ref_clk, sdm_freq_seed, BIT(16)); - pr_debug("vco rate = %lld\n", vco_rate); - } - - pr_debug("returning vco rate = %lu\n", (unsigned long)vco_rate); - - mdss_pll_resource_enable(rsc, false); - - return (unsigned long)vco_rate; -} - -static int dsi_pll_enable(struct dsi_pll_vco_clk *vco) -{ - int i, rc; - struct mdss_pll_resources *rsc = vco->priv; - - rc = mdss_pll_resource_enable(rsc, true); - if (rc) { - pr_err("failed to enable dsi pll(%d) resources\n", - rsc->index); - return rc; - } - - /* Try all enable sequences until one succeeds */ - for (i = 0; i < vco->pll_en_seq_cnt; i++) { - rc = vco->pll_enable_seqs[i](rsc); - pr_debug("DSI PLL %s after sequence #%d\n", - rc ? "unlocked" : "locked", i + 1); - if (!rc) - break; - } - - if (rc) { - mdss_pll_resource_enable(rsc, false); - pr_err("DSI PLL failed to lock\n"); - } - rsc->pll_on = true; - - return rc; -} - -static void dsi_pll_disable(struct dsi_pll_vco_clk *vco) -{ - struct mdss_pll_resources *rsc = vco->priv; - - if (!rsc->pll_on && - mdss_pll_resource_enable(rsc, true)) { - pr_err("failed to enable dsi pll(%d) resources\n", - rsc->index); - return; - } - - rsc->handoff_resources = false; - - MDSS_PLL_REG_W(rsc->pll_base, - DSI_PHY_PLL_UNIPHY_PLL_GLB_CFG, 0x00); - - mdss_pll_resource_enable(rsc, false); - rsc->pll_on = false; - - pr_debug("DSI PLL Disabled\n"); -} - -int vco_28nm_set_rate(struct clk_hw *hw, unsigned long rate, - unsigned long parent_rate) -{ - struct dsi_pll_vco_clk *vco = to_vco_clk_hw(hw); - struct mdss_pll_resources *rsc = vco->priv; - int rc; - - if (!rsc) { - pr_err("pll resource not found\n"); - return -EINVAL; - } - - if (rsc->pll_on) - return 0; - - pr_debug("ndx=%d, rate=%lu\n", rsc->index, rate); - - rc = mdss_pll_resource_enable(rsc, true); - if (rc) { - pr_err("failed to enable mdss dsi pll(%d), rc=%d\n", - rsc->index, rc); - return rc; - } - - /* - * DSI PLL software reset. Add HW recommended delays after toggling - * the software reset bit off and back on. - */ - MDSS_PLL_REG_W(rsc->pll_base, - DSI_PHY_PLL_UNIPHY_PLL_TEST_CFG, 0x01); - udelay(1000); - MDSS_PLL_REG_W(rsc->pll_base, - DSI_PHY_PLL_UNIPHY_PLL_TEST_CFG, 0x00); - udelay(1000); - - rc = vco_set_rate(vco, rate); - rsc->vco_current_rate = rate; - - mdss_pll_resource_enable(rsc, false); - - return 0; -} - -long vco_28nm_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) -{ - unsigned long rrate = rate; - struct dsi_pll_vco_clk *vco = to_vco_clk_hw(hw); - - if (rate < vco->min_rate) - rrate = vco->min_rate; - if (rate > vco->max_rate) - rrate = vco->max_rate; - - *parent_rate = rrate; - - return rrate; -} - -unsigned long vco_28nm_recalc_rate(struct clk_hw *hw, - unsigned long parent_rate) -{ - struct dsi_pll_vco_clk *vco = to_vco_clk_hw(hw); - struct mdss_pll_resources *rsc = vco->priv; - int rc; - u64 vco_rate = 0; - - if (!rsc) { - pr_err("dsi pll resources not available\n"); - return 0; - } - - if (rsc->vco_current_rate) - return (unsigned long)rsc->vco_current_rate; - - if (is_gdsc_disabled(rsc)) - return 0; - - rc = mdss_pll_resource_enable(rsc, true); - if (rc) { - pr_err("failed to enable dsi pll(%d) resources\n", - rsc->index); - return 0; - } - - if (dsi_pll_lock_status(rsc)) { - rsc->handoff_resources = true; - rsc->pll_on = true; - vco_rate = vco_get_rate(vco); - } else { - mdss_pll_resource_enable(rsc, false); - } - - return (unsigned long)vco_rate; -} - -int vco_28nm_prepare(struct clk_hw *hw) -{ - int rc = 0; - struct dsi_pll_vco_clk *vco = to_vco_clk_hw(hw); - struct mdss_pll_resources *rsc = vco->priv; - - if (!rsc) { - pr_err("dsi pll resources not available\n"); - return -EINVAL; - } - - if ((rsc->vco_cached_rate != 0) - && (rsc->vco_cached_rate == clk_hw_get_rate(hw))) { - rc = hw->init->ops->set_rate(hw, rsc->vco_cached_rate, - rsc->vco_cached_rate); - if (rc) { - pr_err("pll(%d ) set_rate failed. rc=%d\n", - rsc->index, rc); - goto error; - } - - MDSS_PLL_REG_W(rsc->pll_base, - DSI_PHY_PLL_UNIPHY_PLL_POSTDIV1_CFG, - rsc->cached_postdiv1); - MDSS_PLL_REG_W(rsc->pll_base, - DSI_PHY_PLL_UNIPHY_PLL_POSTDIV3_CFG, - rsc->cached_postdiv3); - MDSS_PLL_REG_W(rsc->pll_base, - DSI_PHY_PLL_UNIPHY_PLL_VREG_CFG, - rsc->cached_vreg_cfg); - } - - rc = dsi_pll_enable(vco); - -error: - return rc; -} - -void vco_28nm_unprepare(struct clk_hw *hw) -{ - struct dsi_pll_vco_clk *vco = to_vco_clk_hw(hw); - struct mdss_pll_resources *rsc = vco->priv; - - if (!rsc) { - pr_err("dsi pll resources not available\n"); - return; - } - - rsc->cached_postdiv1 = MDSS_PLL_REG_R(rsc->pll_base, - DSI_PHY_PLL_UNIPHY_PLL_POSTDIV1_CFG); - rsc->cached_postdiv3 = MDSS_PLL_REG_R(rsc->pll_base, - DSI_PHY_PLL_UNIPHY_PLL_POSTDIV3_CFG); - rsc->cached_vreg_cfg = MDSS_PLL_REG_R(rsc->pll_base, - DSI_PHY_PLL_UNIPHY_PLL_VREG_CFG); - - rsc->vco_cached_rate = clk_hw_get_rate(hw); - - dsi_pll_disable(vco); -} diff --git a/pll/dsi_pll_8996.c b/pll/dsi_pll_8996.c deleted file mode 100644 index 963c56c06fb2..000000000000 --- a/pll/dsi_pll_8996.c +++ /dev/null @@ -1,548 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. - */ - -#define pr_fmt(fmt) "%s: " fmt, __func__ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "pll_drv.h" -#include "dsi_pll.h" -#include "dsi_pll_8996.h" - -#define VCO_DELAY_USEC 1 - -static struct dsi_pll_db pll_db[DSI_PLL_NUM]; - -static const struct clk_ops n2_clk_src_ops; -static const struct clk_ops shadow_n2_clk_src_ops; -static const struct clk_ops byte_clk_src_ops; -static const struct clk_ops post_n1_div_clk_src_ops; -static const struct clk_ops shadow_post_n1_div_clk_src_ops; - -static const struct clk_ops clk_ops_gen_mux_dsi; - -/* Op structures */ -static const struct clk_ops clk_ops_dsi_vco = { - .set_rate = pll_vco_set_rate_8996, - .round_rate = pll_vco_round_rate_8996, - .handoff = pll_vco_handoff_8996, - .prepare = pll_vco_prepare_8996, - .unprepare = pll_vco_unprepare_8996, -}; - -static struct clk_div_ops post_n1_div_ops = { - .set_div = post_n1_div_set_div, - .get_div = post_n1_div_get_div, -}; - -static struct clk_div_ops n2_div_ops = { /* hr_oclk3 */ - .set_div = n2_div_set_div, - .get_div = n2_div_get_div, -}; - -static struct clk_mux_ops mdss_byte_mux_ops = { - .set_mux_sel = set_mdss_byte_mux_sel_8996, - .get_mux_sel = get_mdss_byte_mux_sel_8996, -}; - -static struct clk_mux_ops mdss_pixel_mux_ops = { - .set_mux_sel = set_mdss_pixel_mux_sel_8996, - .get_mux_sel = get_mdss_pixel_mux_sel_8996, -}; - -/* Shadow ops for dynamic refresh */ -static const struct clk_ops clk_ops_shadow_dsi_vco = { - .set_rate = shadow_pll_vco_set_rate_8996, - .round_rate = pll_vco_round_rate_8996, - .handoff = shadow_pll_vco_handoff_8996, -}; - -static struct clk_div_ops shadow_post_n1_div_ops = { - .set_div = post_n1_div_set_div, -}; - -static struct clk_div_ops shadow_n2_div_ops = { - .set_div = shadow_n2_div_set_div, -}; - -static struct dsi_pll_vco_clk dsi0pll_vco_clk = { - .ref_clk_rate = 19200000UL, - .min_rate = 1300000000UL, - .max_rate = 2600000000UL, - .pll_en_seq_cnt = 1, - .pll_enable_seqs[0] = dsi_pll_enable_seq_8996, - .c = { - .dbg_name = "dsi0pll_vco_clk_8996", - .ops = &clk_ops_dsi_vco, - CLK_INIT(dsi0pll_vco_clk.c), - }, -}; - -static struct dsi_pll_vco_clk dsi0pll_shadow_vco_clk = { - .ref_clk_rate = 19200000u, - .min_rate = 1300000000u, - .max_rate = 2600000000u, - .c = { - .dbg_name = "dsi0pll_shadow_vco_clk", - .ops = &clk_ops_shadow_dsi_vco, - CLK_INIT(dsi0pll_shadow_vco_clk.c), - }, -}; - -static struct dsi_pll_vco_clk dsi1pll_vco_clk = { - .ref_clk_rate = 19200000UL, - .min_rate = 1300000000UL, - .max_rate = 2600000000UL, - .pll_en_seq_cnt = 1, - .pll_enable_seqs[0] = dsi_pll_enable_seq_8996, - .c = { - .dbg_name = "dsi1pll_vco_clk_8996", - .ops = &clk_ops_dsi_vco, - CLK_INIT(dsi1pll_vco_clk.c), - }, -}; - -static struct dsi_pll_vco_clk dsi1pll_shadow_vco_clk = { - .ref_clk_rate = 19200000u, - .min_rate = 1300000000u, - .max_rate = 2600000000u, - .pll_en_seq_cnt = 1, - .pll_enable_seqs[0] = dsi_pll_enable_seq_8996, - .c = { - .dbg_name = "dsi1pll_shadow_vco_clk", - .ops = &clk_ops_shadow_dsi_vco, - CLK_INIT(dsi1pll_shadow_vco_clk.c), - }, -}; - -static struct div_clk dsi0pll_post_n1_div_clk = { - .data = { - .max_div = 15, - .min_div = 1, - }, - .ops = &post_n1_div_ops, - .c = { - .parent = &dsi0pll_vco_clk.c, - .dbg_name = "dsi0pll_post_n1_div_clk", - .ops = &post_n1_div_clk_src_ops, - .flags = CLKFLAG_NO_RATE_CACHE, - CLK_INIT(dsi0pll_post_n1_div_clk.c), - }, -}; - -static struct div_clk dsi0pll_shadow_post_n1_div_clk = { - .data = { - .max_div = 15, - .min_div = 1, - }, - .ops = &shadow_post_n1_div_ops, - .c = { - .parent = &dsi0pll_shadow_vco_clk.c, - .dbg_name = "dsi0pll_shadow_post_n1_div_clk", - .ops = &shadow_post_n1_div_clk_src_ops, - .flags = CLKFLAG_NO_RATE_CACHE, - CLK_INIT(dsi0pll_shadow_post_n1_div_clk.c), - }, -}; - -static struct div_clk dsi1pll_post_n1_div_clk = { - .data = { - .max_div = 15, - .min_div = 1, - }, - .ops = &post_n1_div_ops, - .c = { - .parent = &dsi1pll_vco_clk.c, - .dbg_name = "dsi1pll_post_n1_div_clk", - .ops = &post_n1_div_clk_src_ops, - .flags = CLKFLAG_NO_RATE_CACHE, - CLK_INIT(dsi1pll_post_n1_div_clk.c), - }, -}; - -static struct div_clk dsi1pll_shadow_post_n1_div_clk = { - .data = { - .max_div = 15, - .min_div = 1, - }, - .ops = &shadow_post_n1_div_ops, - .c = { - .parent = &dsi1pll_shadow_vco_clk.c, - .dbg_name = "dsi1pll_shadow_post_n1_div_clk", - .ops = &shadow_post_n1_div_clk_src_ops, - .flags = CLKFLAG_NO_RATE_CACHE, - CLK_INIT(dsi1pll_shadow_post_n1_div_clk.c), - }, -}; - -static struct div_clk dsi0pll_n2_div_clk = { - .data = { - .max_div = 15, - .min_div = 1, - }, - .ops = &n2_div_ops, - .c = { - .parent = &dsi0pll_post_n1_div_clk.c, - .dbg_name = "dsi0pll_n2_div_clk", - .ops = &n2_clk_src_ops, - .flags = CLKFLAG_NO_RATE_CACHE, - CLK_INIT(dsi0pll_n2_div_clk.c), - }, -}; - -static struct div_clk dsi0pll_shadow_n2_div_clk = { - .data = { - .max_div = 15, - .min_div = 1, - }, - .ops = &shadow_n2_div_ops, - .c = { - .parent = &dsi0pll_shadow_post_n1_div_clk.c, - .dbg_name = "dsi0pll_shadow_n2_div_clk", - .ops = &shadow_n2_clk_src_ops, - .flags = CLKFLAG_NO_RATE_CACHE, - CLK_INIT(dsi0pll_shadow_n2_div_clk.c), - }, -}; - -static struct div_clk dsi1pll_n2_div_clk = { - .data = { - .max_div = 15, - .min_div = 1, - }, - .ops = &n2_div_ops, - .c = { - .parent = &dsi1pll_post_n1_div_clk.c, - .dbg_name = "dsi1pll_n2_div_clk", - .ops = &n2_clk_src_ops, - .flags = CLKFLAG_NO_RATE_CACHE, - CLK_INIT(dsi1pll_n2_div_clk.c), - }, -}; - -static struct div_clk dsi1pll_shadow_n2_div_clk = { - .data = { - .max_div = 15, - .min_div = 1, - }, - .ops = &shadow_n2_div_ops, - .c = { - .parent = &dsi1pll_shadow_post_n1_div_clk.c, - .dbg_name = "dsi1pll_shadow_n2_div_clk", - .ops = &shadow_n2_clk_src_ops, - .flags = CLKFLAG_NO_RATE_CACHE, - CLK_INIT(dsi1pll_shadow_n2_div_clk.c), - }, -}; - -static struct div_clk dsi0pll_pixel_clk_src = { - .data = { - .div = 2, - .min_div = 2, - .max_div = 2, - }, - .c = { - .parent = &dsi0pll_n2_div_clk.c, - .dbg_name = "dsi0pll_pixel_clk_src", - .ops = &clk_ops_div, - .flags = CLKFLAG_NO_RATE_CACHE, - CLK_INIT(dsi0pll_pixel_clk_src.c), - }, -}; - -static struct div_clk dsi0pll_shadow_pixel_clk_src = { - .data = { - .div = 2, - .min_div = 2, - .max_div = 2, - }, - .c = { - .parent = &dsi0pll_shadow_n2_div_clk.c, - .dbg_name = "dsi0pll_shadow_pixel_clk_src", - .ops = &clk_ops_div, - .flags = CLKFLAG_NO_RATE_CACHE, - CLK_INIT(dsi0pll_shadow_pixel_clk_src.c), - }, -}; - -static struct div_clk dsi1pll_pixel_clk_src = { - .data = { - .div = 2, - .min_div = 2, - .max_div = 2, - }, - .c = { - .parent = &dsi1pll_n2_div_clk.c, - .dbg_name = "dsi1pll_pixel_clk_src", - .ops = &clk_ops_div, - .flags = CLKFLAG_NO_RATE_CACHE, - CLK_INIT(dsi1pll_pixel_clk_src.c), - }, -}; - -static struct div_clk dsi1pll_shadow_pixel_clk_src = { - .data = { - .div = 2, - .min_div = 2, - .max_div = 2, - }, - .c = { - .parent = &dsi1pll_shadow_n2_div_clk.c, - .dbg_name = "dsi1pll_shadow_pixel_clk_src", - .ops = &clk_ops_div, - .flags = CLKFLAG_NO_RATE_CACHE, - CLK_INIT(dsi1pll_shadow_pixel_clk_src.c), - }, -}; - -static struct mux_clk dsi0pll_pixel_clk_mux = { - .num_parents = 2, - .parents = (struct clk_src[]) { - {&dsi0pll_pixel_clk_src.c, 0}, - {&dsi0pll_shadow_pixel_clk_src.c, 1}, - }, - .ops = &mdss_pixel_mux_ops, - .c = { - .parent = &dsi0pll_pixel_clk_src.c, - .dbg_name = "dsi0pll_pixel_clk_mux", - .ops = &clk_ops_gen_mux_dsi, - .flags = CLKFLAG_NO_RATE_CACHE, - CLK_INIT(dsi0pll_pixel_clk_mux.c), - } -}; - -static struct mux_clk dsi1pll_pixel_clk_mux = { - .num_parents = 2, - .parents = (struct clk_src[]) { - {&dsi1pll_pixel_clk_src.c, 0}, - {&dsi1pll_shadow_pixel_clk_src.c, 1}, - }, - .ops = &mdss_pixel_mux_ops, - .c = { - .parent = &dsi1pll_pixel_clk_src.c, - .dbg_name = "dsi1pll_pixel_clk_mux", - .ops = &clk_ops_gen_mux_dsi, - .flags = CLKFLAG_NO_RATE_CACHE, - CLK_INIT(dsi1pll_pixel_clk_mux.c), - } -}; - -static struct div_clk dsi0pll_byte_clk_src = { - .data = { - .div = 8, - .min_div = 8, - .max_div = 8, - }, - .c = { - .parent = &dsi0pll_post_n1_div_clk.c, - .dbg_name = "dsi0pll_byte_clk_src", - .ops = &clk_ops_div, - CLK_INIT(dsi0pll_byte_clk_src.c), - }, -}; - -static struct div_clk dsi0pll_shadow_byte_clk_src = { - .data = { - .div = 8, - .min_div = 8, - .max_div = 8, - }, - .c = { - .parent = &dsi0pll_shadow_post_n1_div_clk.c, - .dbg_name = "dsi0pll_shadow_byte_clk_src", - .ops = &clk_ops_div, - CLK_INIT(dsi0pll_shadow_byte_clk_src.c), - }, -}; - -static struct div_clk dsi1pll_byte_clk_src = { - .data = { - .div = 8, - .min_div = 8, - .max_div = 8, - }, - .c = { - .parent = &dsi1pll_post_n1_div_clk.c, - .dbg_name = "dsi1pll_byte_clk_src", - .ops = &clk_ops_div, - CLK_INIT(dsi1pll_byte_clk_src.c), - }, -}; - -static struct div_clk dsi1pll_shadow_byte_clk_src = { - .data = { - .div = 8, - .min_div = 8, - .max_div = 8, - }, - .c = { - .parent = &dsi1pll_shadow_post_n1_div_clk.c, - .dbg_name = "dsi1pll_shadow_byte_clk_src", - .ops = &clk_ops_div, - CLK_INIT(dsi1pll_shadow_byte_clk_src.c), - }, -}; - -static struct mux_clk dsi0pll_byte_clk_mux = { - .num_parents = 2, - .parents = (struct clk_src[]) { - {&dsi0pll_byte_clk_src.c, 0}, - {&dsi0pll_shadow_byte_clk_src.c, 1}, - }, - .ops = &mdss_byte_mux_ops, - .c = { - .parent = &dsi0pll_byte_clk_src.c, - .dbg_name = "dsi0pll_byte_clk_mux", - .ops = &clk_ops_gen_mux_dsi, - .flags = CLKFLAG_NO_RATE_CACHE, - CLK_INIT(dsi0pll_byte_clk_mux.c), - } -}; -static struct mux_clk dsi1pll_byte_clk_mux = { - .num_parents = 2, - .parents = (struct clk_src[]) { - {&dsi1pll_byte_clk_src.c, 0}, - {&dsi1pll_shadow_byte_clk_src.c, 1}, - }, - .ops = &mdss_byte_mux_ops, - .c = { - .parent = &dsi1pll_byte_clk_src.c, - .dbg_name = "dsi1pll_byte_clk_mux", - .ops = &clk_ops_gen_mux_dsi, - .flags = CLKFLAG_NO_RATE_CACHE, - CLK_INIT(dsi1pll_byte_clk_mux.c), - } -}; - -static struct clk_lookup mdss_dsi_pllcc_8996[] = { - CLK_LIST(dsi0pll_byte_clk_mux), - CLK_LIST(dsi0pll_byte_clk_src), - CLK_LIST(dsi0pll_pixel_clk_mux), - CLK_LIST(dsi0pll_pixel_clk_src), - CLK_LIST(dsi0pll_n2_div_clk), - CLK_LIST(dsi0pll_post_n1_div_clk), - CLK_LIST(dsi0pll_vco_clk), - CLK_LIST(dsi0pll_shadow_byte_clk_src), - CLK_LIST(dsi0pll_shadow_pixel_clk_src), - CLK_LIST(dsi0pll_shadow_n2_div_clk), - CLK_LIST(dsi0pll_shadow_post_n1_div_clk), - CLK_LIST(dsi0pll_shadow_vco_clk), -}; - -static struct clk_lookup mdss_dsi_pllcc_8996_1[] = { - CLK_LIST(dsi1pll_byte_clk_mux), - CLK_LIST(dsi1pll_byte_clk_src), - CLK_LIST(dsi1pll_pixel_clk_mux), - CLK_LIST(dsi1pll_pixel_clk_src), - CLK_LIST(dsi1pll_n2_div_clk), - CLK_LIST(dsi1pll_post_n1_div_clk), - CLK_LIST(dsi1pll_vco_clk), - CLK_LIST(dsi1pll_shadow_byte_clk_src), - CLK_LIST(dsi1pll_shadow_pixel_clk_src), - CLK_LIST(dsi1pll_shadow_n2_div_clk), - CLK_LIST(dsi1pll_shadow_post_n1_div_clk), - CLK_LIST(dsi1pll_shadow_vco_clk), -}; - -int dsi_pll_clock_register_8996(struct platform_device *pdev, - struct mdss_pll_resources *pll_res) -{ - int rc = 0, ndx; - int const ssc_freq_default = 31500; /* default h/w recommended value */ - int const ssc_ppm_default = 5000; /* default h/w recommended value */ - struct dsi_pll_db *pdb; - - if (pll_res->index >= DSI_PLL_NUM) { - pr_err("pll ndx=%d is NOT supported\n", pll_res->index); - return -EINVAL; - } - - ndx = pll_res->index; - pdb = &pll_db[ndx]; - pll_res->priv = pdb; - pdb->pll = pll_res; - ndx++; - ndx %= DSI_PLL_NUM; - pdb->next = &pll_db[ndx]; - - /* Set clock source operations */ - - /* hr_oclk3, pixel */ - n2_clk_src_ops = clk_ops_slave_div; - n2_clk_src_ops.prepare = mdss_pll_div_prepare; - - shadow_n2_clk_src_ops = clk_ops_slave_div; - - /* hr_ockl2, byte, vco pll */ - post_n1_div_clk_src_ops = clk_ops_div; - post_n1_div_clk_src_ops.prepare = mdss_pll_div_prepare; - - shadow_post_n1_div_clk_src_ops = clk_ops_div; - - byte_clk_src_ops = clk_ops_div; - byte_clk_src_ops.prepare = mdss_pll_div_prepare; - - clk_ops_gen_mux_dsi = clk_ops_gen_mux; - clk_ops_gen_mux_dsi.round_rate = parent_round_rate; - clk_ops_gen_mux_dsi.set_rate = parent_set_rate; - - if (pll_res->ssc_en) { - if (!pll_res->ssc_freq) - pll_res->ssc_freq = ssc_freq_default; - if (!pll_res->ssc_ppm) - pll_res->ssc_ppm = ssc_ppm_default; - } - - /* Set client data to mux, div and vco clocks. */ - if (pll_res->index == DSI_PLL_1) { - dsi1pll_byte_clk_src.priv = pll_res; - dsi1pll_pixel_clk_src.priv = pll_res; - dsi1pll_post_n1_div_clk.priv = pll_res; - dsi1pll_n2_div_clk.priv = pll_res; - dsi1pll_vco_clk.priv = pll_res; - - dsi1pll_shadow_byte_clk_src.priv = pll_res; - dsi1pll_shadow_pixel_clk_src.priv = pll_res; - dsi1pll_shadow_post_n1_div_clk.priv = pll_res; - dsi1pll_shadow_n2_div_clk.priv = pll_res; - dsi1pll_shadow_vco_clk.priv = pll_res; - - pll_res->vco_delay = VCO_DELAY_USEC; - rc = of_msm_clock_register(pdev->dev.of_node, - mdss_dsi_pllcc_8996_1, - ARRAY_SIZE(mdss_dsi_pllcc_8996_1)); - } else { - dsi0pll_byte_clk_src.priv = pll_res; - dsi0pll_pixel_clk_src.priv = pll_res; - dsi0pll_post_n1_div_clk.priv = pll_res; - dsi0pll_n2_div_clk.priv = pll_res; - dsi0pll_vco_clk.priv = pll_res; - - dsi0pll_shadow_byte_clk_src.priv = pll_res; - dsi0pll_shadow_pixel_clk_src.priv = pll_res; - dsi0pll_shadow_post_n1_div_clk.priv = pll_res; - dsi0pll_shadow_n2_div_clk.priv = pll_res; - dsi0pll_shadow_vco_clk.priv = pll_res; - - pll_res->vco_delay = VCO_DELAY_USEC; - rc = of_msm_clock_register(pdev->dev.of_node, - mdss_dsi_pllcc_8996, - ARRAY_SIZE(mdss_dsi_pllcc_8996)); - } - - if (!rc) { - pr_info("Registered DSI PLL ndx=%d clocks successfully\n", - pll_res->index); - } - - return rc; -} diff --git a/pll/dsi_pll_8996.h b/pll/dsi_pll_8996.h deleted file mode 100644 index 94e16d86fd23..000000000000 --- a/pll/dsi_pll_8996.h +++ /dev/null @@ -1,214 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. - */ - -#ifndef MDSS_DSI_PLL_8996_H -#define MDSS_DSI_PLL_8996_H - -#define DSIPHY_CMN_CLK_CFG0 0x0010 -#define DSIPHY_CMN_CLK_CFG1 0x0014 -#define DSIPHY_CMN_GLBL_TEST_CTRL 0x0018 - -#define DSIPHY_CMN_PLL_CNTRL 0x0048 -#define DSIPHY_CMN_CTRL_0 0x001c -#define DSIPHY_CMN_CTRL_1 0x0020 - -#define DSIPHY_CMN_LDO_CNTRL 0x004c - -#define DSIPHY_PLL_IE_TRIM 0x0400 -#define DSIPHY_PLL_IP_TRIM 0x0404 - -#define DSIPHY_PLL_IPTAT_TRIM 0x0410 - -#define DSIPHY_PLL_CLKBUFLR_EN 0x041c - -#define DSIPHY_PLL_SYSCLK_EN_RESET 0x0428 -#define DSIPHY_PLL_RESETSM_CNTRL 0x042c -#define DSIPHY_PLL_RESETSM_CNTRL2 0x0430 -#define DSIPHY_PLL_RESETSM_CNTRL3 0x0434 -#define DSIPHY_PLL_RESETSM_CNTRL4 0x0438 -#define DSIPHY_PLL_RESETSM_CNTRL5 0x043c -#define DSIPHY_PLL_KVCO_DIV_REF1 0x0440 -#define DSIPHY_PLL_KVCO_DIV_REF2 0x0444 -#define DSIPHY_PLL_KVCO_COUNT1 0x0448 -#define DSIPHY_PLL_KVCO_COUNT2 0x044c -#define DSIPHY_PLL_VREF_CFG1 0x045c - -#define DSIPHY_PLL_KVCO_CODE 0x0458 - -#define DSIPHY_PLL_VCO_DIV_REF1 0x046c -#define DSIPHY_PLL_VCO_DIV_REF2 0x0470 -#define DSIPHY_PLL_VCO_COUNT1 0x0474 -#define DSIPHY_PLL_VCO_COUNT2 0x0478 -#define DSIPHY_PLL_PLLLOCK_CMP1 0x047c -#define DSIPHY_PLL_PLLLOCK_CMP2 0x0480 -#define DSIPHY_PLL_PLLLOCK_CMP3 0x0484 -#define DSIPHY_PLL_PLLLOCK_CMP_EN 0x0488 -#define DSIPHY_PLL_PLL_VCO_TUNE 0x048C -#define DSIPHY_PLL_DEC_START 0x0490 -#define DSIPHY_PLL_SSC_EN_CENTER 0x0494 -#define DSIPHY_PLL_SSC_ADJ_PER1 0x0498 -#define DSIPHY_PLL_SSC_ADJ_PER2 0x049c -#define DSIPHY_PLL_SSC_PER1 0x04a0 -#define DSIPHY_PLL_SSC_PER2 0x04a4 -#define DSIPHY_PLL_SSC_STEP_SIZE1 0x04a8 -#define DSIPHY_PLL_SSC_STEP_SIZE2 0x04ac -#define DSIPHY_PLL_DIV_FRAC_START1 0x04b4 -#define DSIPHY_PLL_DIV_FRAC_START2 0x04b8 -#define DSIPHY_PLL_DIV_FRAC_START3 0x04bc -#define DSIPHY_PLL_TXCLK_EN 0x04c0 -#define DSIPHY_PLL_PLL_CRCTRL 0x04c4 - -#define DSIPHY_PLL_RESET_SM_READY_STATUS 0x04cc - -#define DSIPHY_PLL_PLL_MISC1 0x04e8 - -#define DSIPHY_PLL_CP_SET_CUR 0x04f0 -#define DSIPHY_PLL_PLL_ICPMSET 0x04f4 -#define DSIPHY_PLL_PLL_ICPCSET 0x04f8 -#define DSIPHY_PLL_PLL_ICP_SET 0x04fc -#define DSIPHY_PLL_PLL_LPF1 0x0500 -#define DSIPHY_PLL_PLL_LPF2_POSTDIV 0x0504 -#define DSIPHY_PLL_PLL_BANDGAP 0x0508 - -#define DSI_DYNAMIC_REFRESH_PLL_CTRL15 0x050 -#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_UPPER_ADDR 0x094 -#define DSI_DYNAMIC_REFRESH_PLL_UPPER_ADDR2 0x098 - -struct dsi_pll_input { - u32 fref; /* 19.2 Mhz, reference clk */ - u32 fdata; /* bit clock rate */ - u32 dsiclk_sel; /* 1, reg: 0x0014 */ - u32 n2div; /* 1, reg: 0x0010, bit 4-7 */ - u32 ssc_en; /* 1, reg: 0x0494, bit 0 */ - u32 ldo_en; /* 0, reg: 0x004c, bit 0 */ - - /* fixed */ - u32 refclk_dbler_en; /* 0, reg: 0x04c0, bit 1 */ - u32 vco_measure_time; /* 5, unknown */ - u32 kvco_measure_time; /* 5, unknown */ - u32 bandgap_timer; /* 4, reg: 0x0430, bit 3 - 5 */ - u32 pll_wakeup_timer; /* 5, reg: 0x043c, bit 0 - 2 */ - u32 plllock_cnt; /* 1, reg: 0x0488, bit 1 - 2 */ - u32 plllock_rng; /* 1, reg: 0x0488, bit 3 - 4 */ - u32 ssc_center; /* 0, reg: 0x0494, bit 1 */ - u32 ssc_adj_period; /* 37, reg: 0x498, bit 0 - 9 */ - u32 ssc_spread; /* 0.005 */ - u32 ssc_freq; /* unknown */ - u32 pll_ie_trim; /* 4, reg: 0x0400 */ - u32 pll_ip_trim; /* 4, reg: 0x0404 */ - u32 pll_iptat_trim; /* reg: 0x0410 */ - u32 pll_cpcset_cur; /* 1, reg: 0x04f0, bit 0 - 2 */ - u32 pll_cpmset_cur; /* 1, reg: 0x04f0, bit 3 - 5 */ - - u32 pll_icpmset; /* 4, reg: 0x04fc, bit 3 - 5 */ - u32 pll_icpcset; /* 4, reg: 0x04fc, bit 0 - 2 */ - - u32 pll_icpmset_p; /* 0, reg: 0x04f4, bit 0 - 2 */ - u32 pll_icpmset_m; /* 0, reg: 0x04f4, bit 3 - 5 */ - - u32 pll_icpcset_p; /* 0, reg: 0x04f8, bit 0 - 2 */ - u32 pll_icpcset_m; /* 0, reg: 0x04f8, bit 3 - 5 */ - - u32 pll_lpf_res1; /* 3, reg: 0x0504, bit 0 - 3 */ - u32 pll_lpf_cap1; /* 11, reg: 0x0500, bit 0 - 3 */ - u32 pll_lpf_cap2; /* 1, reg: 0x0500, bit 4 - 7 */ - u32 pll_c3ctrl; /* 2, reg: 0x04c4 */ - u32 pll_r3ctrl; /* 1, reg: 0x04c4 */ -}; - -struct dsi_pll_output { - u32 pll_txclk_en; /* reg: 0x04c0 */ - u32 dec_start; /* reg: 0x0490 */ - u32 div_frac_start; /* reg: 0x04b4, 0x4b8, 0x04bc */ - u32 ssc_period; /* reg: 0x04a0, 0x04a4 */ - u32 ssc_step_size; /* reg: 0x04a8, 0x04ac */ - u32 plllock_cmp; /* reg: 0x047c, 0x0480, 0x0484 */ - u32 pll_vco_div_ref; /* reg: 0x046c, 0x0470 */ - u32 pll_vco_count; /* reg: 0x0474, 0x0478 */ - u32 pll_kvco_div_ref; /* reg: 0x0440, 0x0444 */ - u32 pll_kvco_count; /* reg: 0x0448, 0x044c */ - u32 pll_misc1; /* reg: 0x04e8 */ - u32 pll_lpf2_postdiv; /* reg: 0x0504 */ - u32 pll_resetsm_cntrl; /* reg: 0x042c */ - u32 pll_resetsm_cntrl2; /* reg: 0x0430 */ - u32 pll_resetsm_cntrl5; /* reg: 0x043c */ - u32 pll_kvco_code; /* reg: 0x0458 */ - - u32 cmn_clk_cfg0; /* reg: 0x0010 */ - u32 cmn_clk_cfg1; /* reg: 0x0014 */ - u32 cmn_ldo_cntrl; /* reg: 0x004c */ - - u32 pll_postdiv; /* vco */ - u32 pll_n1div; /* vco */ - u32 pll_n2div; /* hr_oclk3, pixel */ - u32 fcvo; -}; - -enum { - DSI_PLL_0, - DSI_PLL_1, - DSI_PLL_NUM -}; - -struct dsi_pll_db { - struct dsi_pll_db *next; - struct mdss_pll_resources *pll; - struct dsi_pll_input in; - struct dsi_pll_output out; - int source_setup_done; -}; - -enum { - PLL_OUTPUT_NONE, - PLL_OUTPUT_RIGHT, - PLL_OUTPUT_LEFT, - PLL_OUTPUT_BOTH -}; - -enum { - PLL_SOURCE_FROM_LEFT, - PLL_SOURCE_FROM_RIGHT -}; - -enum { - PLL_UNKNOWN, - PLL_STANDALONE, - PLL_SLAVE, - PLL_MASTER -}; - -int pll_vco_set_rate_8996(struct clk *c, unsigned long rate); -long pll_vco_round_rate_8996(struct clk *c, unsigned long rate); -enum handoff pll_vco_handoff_8996(struct clk *c); -enum handoff shadow_pll_vco_handoff_8996(struct clk *c); -int shadow_post_n1_div_set_div(struct div_clk *clk, int div); -int shadow_post_n1_div_get_div(struct div_clk *clk); -int shadow_n2_div_set_div(struct div_clk *clk, int div); -int shadow_n2_div_get_div(struct div_clk *clk); -int shadow_pll_vco_set_rate_8996(struct clk *c, unsigned long rate); -int pll_vco_prepare_8996(struct clk *c); -void pll_vco_unprepare_8996(struct clk *c); -int set_mdss_byte_mux_sel_8996(struct mux_clk *clk, int sel); -int get_mdss_byte_mux_sel_8996(struct mux_clk *clk); -int set_mdss_pixel_mux_sel_8996(struct mux_clk *clk, int sel); -int get_mdss_pixel_mux_sel_8996(struct mux_clk *clk); -int post_n1_div_set_div(struct div_clk *clk, int div); -int post_n1_div_get_div(struct div_clk *clk); -int n2_div_set_div(struct div_clk *clk, int div); -int n2_div_get_div(struct div_clk *clk); -int dsi_pll_enable_seq_8996(struct mdss_pll_resources *pll); - -#endif /* MDSS_DSI_PLL_8996_H */ diff --git a/pll/dsi_pll_8996_util.c b/pll/dsi_pll_8996_util.c deleted file mode 100644 index 543548eaa51a..000000000000 --- a/pll/dsi_pll_8996_util.c +++ /dev/null @@ -1,1130 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. - */ - -#define pr_fmt(fmt) "%s: " fmt, __func__ - -#include -#include -#include -#include -#include - -#include "pll_drv.h" -#include "dsi_pll.h" -#include "dsi_pll_8996.h" - -#define DSI_PLL_POLL_MAX_READS 15 -#define DSI_PLL_POLL_TIMEOUT_US 1000 -#define MSM8996_DSI_PLL_REVISION_2 2 - -#define CEIL(x, y) (((x) + ((y)-1)) / (y)) - -int set_mdss_byte_mux_sel_8996(struct mux_clk *clk, int sel) -{ - return 0; -} - -int get_mdss_byte_mux_sel_8996(struct mux_clk *clk) -{ - return 0; -} - -int set_mdss_pixel_mux_sel_8996(struct mux_clk *clk, int sel) -{ - return 0; -} - -int get_mdss_pixel_mux_sel_8996(struct mux_clk *clk) -{ - return 0; -} - -static int mdss_pll_read_stored_trim_codes( - struct mdss_pll_resources *dsi_pll_res, s64 vco_clk_rate) -{ - int i; - int rc = 0; - bool found = false; - - if (!dsi_pll_res->dfps) { - rc = -EINVAL; - goto end_read; - } - - for (i = 0; i < dsi_pll_res->dfps->panel_dfps.frame_rate_cnt; i++) { - struct dfps_codes_info *codes_info = - &dsi_pll_res->dfps->codes_dfps[i]; - - pr_debug("valid=%d frame_rate=%d, vco_rate=%d, code %d %d\n", - codes_info->is_valid, codes_info->frame_rate, - codes_info->clk_rate, codes_info->pll_codes.pll_codes_1, - codes_info->pll_codes.pll_codes_2); - - if (vco_clk_rate != codes_info->clk_rate && - codes_info->is_valid) - continue; - - dsi_pll_res->cache_pll_trim_codes[0] = - codes_info->pll_codes.pll_codes_1; - dsi_pll_res->cache_pll_trim_codes[1] = - codes_info->pll_codes.pll_codes_2; - found = true; - break; - } - - if (!found) { - rc = -EINVAL; - goto end_read; - } - - pr_debug("core_kvco_code=0x%x core_vco_tune=0x%x\n", - dsi_pll_res->cache_pll_trim_codes[0], - dsi_pll_res->cache_pll_trim_codes[1]); - -end_read: - return rc; -} - -int post_n1_div_set_div(struct div_clk *clk, int div) -{ - struct mdss_pll_resources *pll = clk->priv; - struct dsi_pll_db *pdb; - struct dsi_pll_output *pout; - int rc; - u32 n1div = 0; - - rc = mdss_pll_resource_enable(pll, true); - if (rc) { - pr_err("Failed to enable mdss dsi pll resources\n"); - return rc; - } - - pdb = (struct dsi_pll_db *)pll->priv; - pout = &pdb->out; - - /* - * vco rate = bit_clk * postdiv * n1div - * vco range from 1300 to 2600 Mhz - * postdiv = 1 - * n1div = 1 to 15 - * n1div = roundup(1300Mhz / bit_clk) - * support bit_clk above 86.67Mhz - */ - - /* this is for vco/bit clock */ - pout->pll_postdiv = 1; /* fixed, divided by 1 */ - pout->pll_n1div = div; - - n1div = MDSS_PLL_REG_R(pll->pll_base, DSIPHY_CMN_CLK_CFG0); - n1div &= ~0xf; - n1div |= (div & 0xf); - MDSS_PLL_REG_W(pll->pll_base, DSIPHY_CMN_CLK_CFG0, n1div); - /* ensure n1 divider is programed */ - wmb(); - pr_debug("ndx=%d div=%d postdiv=%x n1div=%x\n", - pll->index, div, pout->pll_postdiv, pout->pll_n1div); - - mdss_pll_resource_enable(pll, false); - - return 0; -} - -int post_n1_div_get_div(struct div_clk *clk) -{ - u32 div; - int rc; - struct mdss_pll_resources *pll = clk->priv; - - if (is_gdsc_disabled(pll)) - return 0; - - rc = mdss_pll_resource_enable(pll, true); - if (rc) { - pr_err("Failed to enable mdss dsi pll resources\n"); - return rc; - } - - /* - * postdiv = 1/2/4/8 - * n1div = 1 - 15 - * fot the time being, assume postdiv = 1 - */ - - div = MDSS_PLL_REG_R(pll->pll_base, DSIPHY_CMN_CLK_CFG0); - div &= 0xF; - pr_debug("n1 div = %d\n", div); - - mdss_pll_resource_enable(pll, false); - - return div; -} - -int n2_div_set_div(struct div_clk *clk, int div) -{ - int rc; - u32 n2div; - struct mdss_pll_resources *pll = clk->priv; - struct dsi_pll_db *pdb; - struct dsi_pll_output *pout; - struct mdss_pll_resources *slave; - - rc = mdss_pll_resource_enable(pll, true); - if (rc) { - pr_err("Failed to enable mdss dsi pll resources\n"); - return rc; - } - - pdb = (struct dsi_pll_db *)pll->priv; - pout = &pdb->out; - - /* this is for pixel clock */ - n2div = MDSS_PLL_REG_R(pll->pll_base, DSIPHY_CMN_CLK_CFG0); - n2div &= ~0xf0; /* bits 4 to 7 */ - n2div |= (div << 4); - MDSS_PLL_REG_W(pll->pll_base, DSIPHY_CMN_CLK_CFG0, n2div); - - /* commit slave if split display is enabled */ - slave = pll->slave; - if (slave) - MDSS_PLL_REG_W(slave->pll_base, DSIPHY_CMN_CLK_CFG0, n2div); - - pout->pll_n2div = div; - - /* set dsiclk_sel=1 so that n2div *= 2 */ - MDSS_PLL_REG_W(pll->pll_base, DSIPHY_CMN_CLK_CFG1, 1); - pr_debug("ndx=%d div=%d n2div=%x\n", pll->index, div, n2div); - - mdss_pll_resource_enable(pll, false); - - return rc; -} - -int shadow_n2_div_set_div(struct div_clk *clk, int div) -{ - struct mdss_pll_resources *pll = clk->priv; - struct dsi_pll_db *pdb; - struct dsi_pll_output *pout; - u32 data; - - pdb = pll->priv; - pout = &pdb->out; - - pout->pll_n2div = div; - - data = (pout->pll_n1div | (pout->pll_n2div << 4)); - MDSS_DYN_PLL_REG_W(pll->dyn_pll_base, - DSI_DYNAMIC_REFRESH_PLL_CTRL19, - DSIPHY_CMN_CLK_CFG0, DSIPHY_CMN_CLK_CFG1, - data, 1); - return 0; -} - -int n2_div_get_div(struct div_clk *clk) -{ - int rc; - u32 n2div; - struct mdss_pll_resources *pll = clk->priv; - - if (is_gdsc_disabled(pll)) - return 0; - - rc = mdss_pll_resource_enable(pll, true); - if (rc) { - pr_err("Failed to enable mdss dsi pll=%d resources\n", - pll->index); - return rc; - } - - n2div = MDSS_PLL_REG_R(pll->pll_base, DSIPHY_CMN_CLK_CFG0); - n2div >>= 4; - n2div &= 0x0f; - - mdss_pll_resource_enable(pll, false); - - pr_debug("ndx=%d div=%d\n", pll->index, n2div); - - return n2div; -} - -static bool pll_is_pll_locked_8996(struct mdss_pll_resources *pll) -{ - u32 status; - bool pll_locked; - - /* poll for PLL ready status */ - if (readl_poll_timeout_atomic((pll->pll_base + - DSIPHY_PLL_RESET_SM_READY_STATUS), - status, - ((status & BIT(5)) > 0), - DSI_PLL_POLL_MAX_READS, - DSI_PLL_POLL_TIMEOUT_US)) { - pr_err("DSI PLL ndx=%d status=%x failed to Lock\n", - pll->index, status); - pll_locked = false; - } else if (readl_poll_timeout_atomic((pll->pll_base + - DSIPHY_PLL_RESET_SM_READY_STATUS), - status, - ((status & BIT(0)) > 0), - DSI_PLL_POLL_MAX_READS, - DSI_PLL_POLL_TIMEOUT_US)) { - pr_err("DSI PLL ndx=%d status=%x PLl not ready\n", - pll->index, status); - pll_locked = false; - } else { - pll_locked = true; - } - - return pll_locked; -} - -static void dsi_pll_start_8996(void __iomem *pll_base) -{ - pr_debug("start PLL at base=%p\n", pll_base); - - MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_VREF_CFG1, 0x10); - MDSS_PLL_REG_W(pll_base, DSIPHY_CMN_PLL_CNTRL, 1); -} - -static void dsi_pll_stop_8996(void __iomem *pll_base) -{ - pr_debug("stop PLL at base=%p\n", pll_base); - - MDSS_PLL_REG_W(pll_base, DSIPHY_CMN_PLL_CNTRL, 0); -} - -int dsi_pll_enable_seq_8996(struct mdss_pll_resources *pll) -{ - int rc = 0; - - if (!pll) { - pr_err("Invalid PLL resources\n"); - return -EINVAL; - } - - dsi_pll_start_8996(pll->pll_base); - - /* - * both DSIPHY_PLL_CLKBUFLR_EN and DSIPHY_CMN_GLBL_TEST_CTRL - * enabled at mdss_dsi_8996_phy_config() - */ - - if (!pll_is_pll_locked_8996(pll)) { - pr_err("DSI PLL ndx=%d lock failed\n", pll->index); - rc = -EINVAL; - goto init_lock_err; - } - - pr_debug("DSI PLL ndx=%d Lock success\n", pll->index); - -init_lock_err: - return rc; -} - -static int dsi_pll_enable(struct clk *c) -{ - int i, rc = 0; - struct dsi_pll_vco_clk *vco = to_vco_clk(c); - struct mdss_pll_resources *pll = vco->priv; - - /* Try all enable sequences until one succeeds */ - for (i = 0; i < vco->pll_en_seq_cnt; i++) { - rc = vco->pll_enable_seqs[i](pll); - pr_debug("DSI PLL %s after sequence #%d\n", - rc ? "unlocked" : "locked", i + 1); - if (!rc) - break; - } - - if (rc) - pr_err("ndx=%d DSI PLL failed to lock\n", pll->index); - else - pll->pll_on = true; - - return rc; -} - -static void dsi_pll_disable(struct clk *c) -{ - struct dsi_pll_vco_clk *vco = to_vco_clk(c); - struct mdss_pll_resources *pll = vco->priv; - struct mdss_pll_resources *slave; - - if (!pll->pll_on && - mdss_pll_resource_enable(pll, true)) { - pr_err("Failed to enable mdss dsi pll=%d\n", pll->index); - return; - } - - pll->handoff_resources = false; - slave = pll->slave; - - dsi_pll_stop_8996(pll->pll_base); - - mdss_pll_resource_enable(pll, false); - - pll->pll_on = false; - - pr_debug("DSI PLL ndx=%d Disabled\n", pll->index); -} - -static void mdss_dsi_pll_8996_input_init(struct mdss_pll_resources *pll, - struct dsi_pll_db *pdb) -{ - pdb->in.fref = 19200000; /* 19.2 Mhz*/ - pdb->in.fdata = 0; /* bit clock rate */ - pdb->in.dsiclk_sel = 1; /* 1, reg: 0x0014 */ - pdb->in.ssc_en = pll->ssc_en; /* 1, reg: 0x0494, bit 0 */ - pdb->in.ldo_en = 0; /* 0, reg: 0x004c, bit 0 */ - - /* fixed input */ - pdb->in.refclk_dbler_en = 0; /* 0, reg: 0x04c0, bit 1 */ - pdb->in.vco_measure_time = 5; /* 5, unknown */ - pdb->in.kvco_measure_time = 5; /* 5, unknown */ - pdb->in.bandgap_timer = 4; /* 4, reg: 0x0430, bit 3 - 5 */ - pdb->in.pll_wakeup_timer = 5; /* 5, reg: 0x043c, bit 0 - 2 */ - pdb->in.plllock_cnt = 1; /* 1, reg: 0x0488, bit 1 - 2 */ - pdb->in.plllock_rng = 0; /* 0, reg: 0x0488, bit 3 - 4 */ - pdb->in.ssc_center = pll->ssc_center;/* 0, reg: 0x0494, bit 1 */ - pdb->in.ssc_adj_period = 37; /* 37, reg: 0x498, bit 0 - 9 */ - pdb->in.ssc_spread = pll->ssc_ppm / 1000; - pdb->in.ssc_freq = pll->ssc_freq; - - pdb->in.pll_ie_trim = 4; /* 4, reg: 0x0400 */ - pdb->in.pll_ip_trim = 4; /* 4, reg: 0x0404 */ - pdb->in.pll_cpcset_cur = 1; /* 1, reg: 0x04f0, bit 0 - 2 */ - pdb->in.pll_cpmset_cur = 1; /* 1, reg: 0x04f0, bit 3 - 5 */ - pdb->in.pll_icpmset = 4; /* 4, reg: 0x04fc, bit 3 - 5 */ - pdb->in.pll_icpcset = 4; /* 4, reg: 0x04fc, bit 0 - 2 */ - pdb->in.pll_icpmset_p = 0; /* 0, reg: 0x04f4, bit 0 - 2 */ - pdb->in.pll_icpmset_m = 0; /* 0, reg: 0x04f4, bit 3 - 5 */ - pdb->in.pll_icpcset_p = 0; /* 0, reg: 0x04f8, bit 0 - 2 */ - pdb->in.pll_icpcset_m = 0; /* 0, reg: 0x04f8, bit 3 - 5 */ - pdb->in.pll_lpf_res1 = 3; /* 3, reg: 0x0504, bit 0 - 3 */ - pdb->in.pll_lpf_cap1 = 11; /* 11, reg: 0x0500, bit 0 - 3 */ - pdb->in.pll_lpf_cap2 = 1; /* 1, reg: 0x0500, bit 4 - 7 */ - pdb->in.pll_iptat_trim = 7; - pdb->in.pll_c3ctrl = 2; /* 2 */ - pdb->in.pll_r3ctrl = 1; /* 1 */ -} - -static void pll_8996_ssc_calc(struct mdss_pll_resources *pll, - struct dsi_pll_db *pdb) -{ - u32 period, ssc_period; - u32 ref, rem; - s64 step_size; - - pr_debug("%s: vco=%lld ref=%lld\n", __func__, - pll->vco_current_rate, pll->vco_ref_clk_rate); - - ssc_period = pdb->in.ssc_freq / 500; - period = (unsigned long)pll->vco_ref_clk_rate / 1000; - ssc_period = CEIL(period, ssc_period); - ssc_period -= 1; - pdb->out.ssc_period = ssc_period; - - pr_debug("%s: ssc, freq=%d spread=%d period=%d\n", __func__, - pdb->in.ssc_freq, pdb->in.ssc_spread, pdb->out.ssc_period); - - step_size = (u32)pll->vco_current_rate; - ref = pll->vco_ref_clk_rate; - ref /= 1000; - step_size = div_s64(step_size, ref); - step_size <<= 20; - step_size = div_s64(step_size, 1000); - step_size *= pdb->in.ssc_spread; - step_size = div_s64(step_size, 1000); - step_size *= (pdb->in.ssc_adj_period + 1); - - rem = 0; - step_size = div_s64_rem(step_size, ssc_period + 1, &rem); - if (rem) - step_size++; - - pr_debug("%s: step_size=%lld\n", __func__, step_size); - - step_size &= 0x0ffff; /* take lower 16 bits */ - - pdb->out.ssc_step_size = step_size; -} - -static void pll_8996_dec_frac_calc(struct mdss_pll_resources *pll, - struct dsi_pll_db *pdb) -{ - struct dsi_pll_input *pin = &pdb->in; - struct dsi_pll_output *pout = &pdb->out; - s64 multiplier = BIT(20); - s64 dec_start_multiple, dec_start, pll_comp_val; - s32 duration, div_frac_start; - s64 vco_clk_rate = pll->vco_current_rate; - s64 fref = pll->vco_ref_clk_rate; - - pr_debug("vco_clk_rate=%lld ref_clk_rate=%lld\n", - vco_clk_rate, fref); - - dec_start_multiple = div_s64(vco_clk_rate * multiplier, fref); - div_s64_rem(dec_start_multiple, multiplier, &div_frac_start); - - dec_start = div_s64(dec_start_multiple, multiplier); - - pout->dec_start = (u32)dec_start; - pout->div_frac_start = div_frac_start; - - if (pin->plllock_cnt == 0) - duration = 1024; - else if (pin->plllock_cnt == 1) - duration = 256; - else if (pin->plllock_cnt == 2) - duration = 128; - else - duration = 32; - - pll_comp_val = duration * dec_start_multiple; - pll_comp_val = div_s64(pll_comp_val, multiplier); - do_div(pll_comp_val, 10); - - pout->plllock_cmp = (u32)pll_comp_val; - - pout->pll_txclk_en = 1; - if (pll->revision == MSM8996_DSI_PLL_REVISION_2) - pout->cmn_ldo_cntrl = 0x3c; - else - pout->cmn_ldo_cntrl = 0x1c; -} - -static u32 pll_8996_kvco_slop(u32 vrate) -{ - u32 slop = 0; - - if (vrate > 1300000000UL && vrate <= 1800000000UL) - slop = 600; - else if (vrate > 1800000000UL && vrate < 2300000000UL) - slop = 400; - else if (vrate > 2300000000UL && vrate < 2600000000UL) - slop = 280; - - return slop; -} - -static void pll_8996_calc_vco_count(struct dsi_pll_db *pdb, - s64 vco_clk_rate, s64 fref) -{ - struct dsi_pll_input *pin = &pdb->in; - struct dsi_pll_output *pout = &pdb->out; - s64 data; - u32 cnt; - - data = fref * pin->vco_measure_time; - do_div(data, 1000000); - data &= 0x03ff; /* 10 bits */ - data -= 2; - pout->pll_vco_div_ref = data; - - data = (unsigned long)vco_clk_rate / 1000000; /* unit is Mhz */ - data *= pin->vco_measure_time; - do_div(data, 10); - pout->pll_vco_count = data; /* reg: 0x0474, 0x0478 */ - - data = fref * pin->kvco_measure_time; - do_div(data, 1000000); - data &= 0x03ff; /* 10 bits */ - data -= 1; - pout->pll_kvco_div_ref = data; - - cnt = pll_8996_kvco_slop(vco_clk_rate); - cnt *= 2; - do_div(cnt, 100); - cnt *= pin->kvco_measure_time; - pout->pll_kvco_count = cnt; - - pout->pll_misc1 = 16; - pout->pll_resetsm_cntrl = 48; - pout->pll_resetsm_cntrl2 = pin->bandgap_timer << 3; - pout->pll_resetsm_cntrl5 = pin->pll_wakeup_timer; - pout->pll_kvco_code = 0; -} - -static void pll_db_commit_ssc(struct mdss_pll_resources *pll, - struct dsi_pll_db *pdb) -{ - void __iomem *pll_base = pll->pll_base; - struct dsi_pll_input *pin = &pdb->in; - struct dsi_pll_output *pout = &pdb->out; - char data; - - data = pin->ssc_adj_period; - data &= 0x0ff; - MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_SSC_ADJ_PER1, data); - data = (pin->ssc_adj_period >> 8); - data &= 0x03; - MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_SSC_ADJ_PER2, data); - - data = pout->ssc_period; - data &= 0x0ff; - MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_SSC_PER1, data); - data = (pout->ssc_period >> 8); - data &= 0x0ff; - MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_SSC_PER2, data); - - data = pout->ssc_step_size; - data &= 0x0ff; - MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_SSC_STEP_SIZE1, data); - data = (pout->ssc_step_size >> 8); - data &= 0x0ff; - MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_SSC_STEP_SIZE2, data); - - data = (pin->ssc_center & 0x01); - data <<= 1; - data |= 0x01; /* enable */ - MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_SSC_EN_CENTER, data); - - wmb(); /* make sure register committed */ -} - -static void pll_db_commit_common(struct mdss_pll_resources *pll, - struct dsi_pll_db *pdb) -{ - void __iomem *pll_base = pll->pll_base; - struct dsi_pll_input *pin = &pdb->in; - struct dsi_pll_output *pout = &pdb->out; - char data; - - /* confgiure the non frequency dependent pll registers */ - data = 0; - MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_SYSCLK_EN_RESET, data); - - /* DSIPHY_PLL_CLKBUFLR_EN updated at dsi phy */ - - data = pout->pll_txclk_en; - MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_TXCLK_EN, data); - - data = pout->pll_resetsm_cntrl; - MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_RESETSM_CNTRL, data); - data = pout->pll_resetsm_cntrl2; - MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_RESETSM_CNTRL2, data); - data = pout->pll_resetsm_cntrl5; - MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_RESETSM_CNTRL5, data); - - data = pout->pll_vco_div_ref; - data &= 0x0ff; - MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_VCO_DIV_REF1, data); - data = (pout->pll_vco_div_ref >> 8); - data &= 0x03; - MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_VCO_DIV_REF2, data); - - data = pout->pll_kvco_div_ref; - data &= 0x0ff; - MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_KVCO_DIV_REF1, data); - data = (pout->pll_kvco_div_ref >> 8); - data &= 0x03; - MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_KVCO_DIV_REF2, data); - - data = pout->pll_misc1; - MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_PLL_MISC1, data); - - data = pin->pll_ie_trim; - MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_IE_TRIM, data); - - data = pin->pll_ip_trim; - MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_IP_TRIM, data); - - data = ((pin->pll_cpmset_cur << 3) | pin->pll_cpcset_cur); - MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_CP_SET_CUR, data); - - data = ((pin->pll_icpcset_p << 3) | pin->pll_icpcset_m); - MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_PLL_ICPCSET, data); - - data = ((pin->pll_icpmset_p << 3) | pin->pll_icpcset_m); - MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_PLL_ICPMSET, data); - - data = ((pin->pll_icpmset << 3) | pin->pll_icpcset); - MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_PLL_ICP_SET, data); - - data = ((pdb->in.pll_lpf_cap2 << 4) | pdb->in.pll_lpf_cap1); - MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_PLL_LPF1, data); - - data = pin->pll_iptat_trim; - MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_IPTAT_TRIM, data); - - data = (pdb->in.pll_c3ctrl | (pdb->in.pll_r3ctrl << 4)); - MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_PLL_CRCTRL, data); -} - -static void pll_db_commit_8996(struct mdss_pll_resources *pll, - struct dsi_pll_db *pdb) -{ - void __iomem *pll_base = pll->pll_base; - struct dsi_pll_input *pin = &pdb->in; - struct dsi_pll_output *pout = &pdb->out; - char data; - - data = pout->cmn_ldo_cntrl; - MDSS_PLL_REG_W(pll_base, DSIPHY_CMN_LDO_CNTRL, data); - - pll_db_commit_common(pll, pdb); - - /* de assert pll start and apply pll sw reset */ - /* stop pll */ - MDSS_PLL_REG_W(pll_base, DSIPHY_CMN_PLL_CNTRL, 0); - - /* pll sw reset */ - MDSS_PLL_REG_W(pll_base, DSIPHY_CMN_CTRL_1, 0x20); - wmb(); /* make sure register committed */ - udelay(10); - - MDSS_PLL_REG_W(pll_base, DSIPHY_CMN_CTRL_1, 0); - wmb(); /* make sure register committed */ - - data = pdb->in.dsiclk_sel; /* set dsiclk_sel = 1 */ - MDSS_PLL_REG_W(pll_base, DSIPHY_CMN_CLK_CFG1, data); - - data = 0xff; /* data, clk, pll normal operation */ - MDSS_PLL_REG_W(pll_base, DSIPHY_CMN_CTRL_0, data); - - /* confgiure the frequency dependent pll registers */ - data = pout->dec_start; - MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_DEC_START, data); - - data = pout->div_frac_start; - data &= 0x0ff; - MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_DIV_FRAC_START1, data); - data = (pout->div_frac_start >> 8); - data &= 0x0ff; - MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_DIV_FRAC_START2, data); - data = (pout->div_frac_start >> 16); - data &= 0x0f; - MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_DIV_FRAC_START3, data); - - data = pout->plllock_cmp; - data &= 0x0ff; - MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_PLLLOCK_CMP1, data); - data = (pout->plllock_cmp >> 8); - data &= 0x0ff; - MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_PLLLOCK_CMP2, data); - data = (pout->plllock_cmp >> 16); - data &= 0x03; - MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_PLLLOCK_CMP3, data); - - data = ((pin->plllock_cnt << 1) | (pin->plllock_rng << 3)); - MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_PLLLOCK_CMP_EN, data); - - data = pout->pll_vco_count; - data &= 0x0ff; - MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_VCO_COUNT1, data); - data = (pout->pll_vco_count >> 8); - data &= 0x0ff; - MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_VCO_COUNT2, data); - - data = pout->pll_kvco_count; - data &= 0x0ff; - MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_KVCO_COUNT1, data); - data = (pout->pll_kvco_count >> 8); - data &= 0x03; - MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_KVCO_COUNT2, data); - - /* - * tx_band = pll_postdiv - * 0: divided by 1 <== for now - * 1: divided by 2 - * 2: divided by 4 - * 3: divided by 8 - */ - data = (((pout->pll_postdiv - 1) << 4) | pdb->in.pll_lpf_res1); - MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_PLL_LPF2_POSTDIV, data); - - data = (pout->pll_n1div | (pout->pll_n2div << 4)); - MDSS_PLL_REG_W(pll_base, DSIPHY_CMN_CLK_CFG0, data); - - if (pll->ssc_en) - pll_db_commit_ssc(pll, pdb); - - wmb(); /* make sure register committed */ -} - -/* - * pll_source_finding: - * Both GLBL_TEST_CTRL and CLKBUFLR_EN are configured - * at mdss_dsi_8996_phy_config() - */ -static int pll_source_finding(struct mdss_pll_resources *pll) -{ - u32 clk_buf_en; - u32 glbl_test_ctrl; - - glbl_test_ctrl = MDSS_PLL_REG_R(pll->pll_base, - DSIPHY_CMN_GLBL_TEST_CTRL); - clk_buf_en = MDSS_PLL_REG_R(pll->pll_base, - DSIPHY_PLL_CLKBUFLR_EN); - - glbl_test_ctrl &= BIT(2); - glbl_test_ctrl >>= 2; - - pr_debug("%s: pll=%d clk_buf_en=%x glbl_test_ctrl=%x\n", - __func__, pll->index, clk_buf_en, glbl_test_ctrl); - - clk_buf_en &= (PLL_OUTPUT_RIGHT | PLL_OUTPUT_LEFT); - - if ((glbl_test_ctrl == PLL_SOURCE_FROM_LEFT) && - (clk_buf_en == PLL_OUTPUT_BOTH)) - return PLL_MASTER; - - if ((glbl_test_ctrl == PLL_SOURCE_FROM_RIGHT) && - (clk_buf_en == PLL_OUTPUT_NONE)) - return PLL_SLAVE; - - if ((glbl_test_ctrl == PLL_SOURCE_FROM_LEFT) && - (clk_buf_en == PLL_OUTPUT_RIGHT)) - return PLL_STANDALONE; - - pr_debug("%s: Error pll setup, clk_buf_en=%x glbl_test_ctrl=%x\n", - __func__, clk_buf_en, glbl_test_ctrl); - - return PLL_UNKNOWN; -} - -static void pll_source_setup(struct mdss_pll_resources *pll) -{ - int status; - struct dsi_pll_db *pdb = (struct dsi_pll_db *)pll->priv; - struct mdss_pll_resources *other; - - if (pdb->source_setup_done) - return; - - pdb->source_setup_done++; - - status = pll_source_finding(pll); - - if (status == PLL_STANDALONE || status == PLL_UNKNOWN) - return; - - other = pdb->next->pll; - if (!other) - return; - - pr_debug("%s: status=%d pll=%d other=%d\n", __func__, - status, pll->index, other->index); - - if (status == PLL_MASTER) - pll->slave = other; - else - other->slave = pll; -} - -int pll_vco_set_rate_8996(struct clk *c, unsigned long rate) -{ - int rc; - struct dsi_pll_vco_clk *vco = to_vco_clk(c); - struct mdss_pll_resources *pll = vco->priv; - struct mdss_pll_resources *slave; - struct dsi_pll_db *pdb; - - pdb = (struct dsi_pll_db *)pll->priv; - if (!pdb) { - pr_err("No prov found\n"); - return -EINVAL; - } - - rc = mdss_pll_resource_enable(pll, true); - if (rc) { - pr_err("Failed to enable mdss dsi plla=%d\n", pll->index); - return rc; - } - - pll_source_setup(pll); - - pr_debug("%s: ndx=%d base=%p rate=%lu slave=%p\n", __func__, - pll->index, pll->pll_base, rate, pll->slave); - - pll->vco_current_rate = rate; - pll->vco_ref_clk_rate = vco->ref_clk_rate; - - mdss_dsi_pll_8996_input_init(pll, pdb); - - pll_8996_dec_frac_calc(pll, pdb); - - if (pll->ssc_en) - pll_8996_ssc_calc(pll, pdb); - - pll_8996_calc_vco_count(pdb, pll->vco_current_rate, - pll->vco_ref_clk_rate); - - /* commit slave if split display is enabled */ - slave = pll->slave; - if (slave) - pll_db_commit_8996(slave, pdb); - - /* commit master itself */ - pll_db_commit_8996(pll, pdb); - - mdss_pll_resource_enable(pll, false); - - return rc; -} - -static void shadow_pll_dynamic_refresh_8996(struct mdss_pll_resources *pll, - struct dsi_pll_db *pdb) -{ - struct dsi_pll_output *pout = &pdb->out; - - MDSS_DYN_PLL_REG_W(pll->dyn_pll_base, - DSI_DYNAMIC_REFRESH_PLL_CTRL20, - DSIPHY_CMN_CTRL_0, DSIPHY_PLL_SYSCLK_EN_RESET, - 0xFF, 0x0); - MDSS_DYN_PLL_REG_W(pll->dyn_pll_base, - DSI_DYNAMIC_REFRESH_PLL_CTRL21, - DSIPHY_PLL_DEC_START, DSIPHY_PLL_DIV_FRAC_START1, - pout->dec_start, (pout->div_frac_start & 0x0FF)); - MDSS_DYN_PLL_REG_W(pll->dyn_pll_base, - DSI_DYNAMIC_REFRESH_PLL_CTRL22, - DSIPHY_PLL_DIV_FRAC_START2, DSIPHY_PLL_DIV_FRAC_START3, - ((pout->div_frac_start >> 8) & 0x0FF), - ((pout->div_frac_start >> 16) & 0x0F)); - MDSS_DYN_PLL_REG_W(pll->dyn_pll_base, - DSI_DYNAMIC_REFRESH_PLL_CTRL23, - DSIPHY_PLL_PLLLOCK_CMP1, DSIPHY_PLL_PLLLOCK_CMP2, - (pout->plllock_cmp & 0x0FF), - ((pout->plllock_cmp >> 8) & 0x0FF)); - MDSS_DYN_PLL_REG_W(pll->dyn_pll_base, - DSI_DYNAMIC_REFRESH_PLL_CTRL24, - DSIPHY_PLL_PLLLOCK_CMP3, DSIPHY_PLL_PLL_VCO_TUNE, - ((pout->plllock_cmp >> 16) & 0x03), - (pll->cache_pll_trim_codes[1] | BIT(7))); /* VCO tune*/ - MDSS_DYN_PLL_REG_W(pll->dyn_pll_base, - DSI_DYNAMIC_REFRESH_PLL_CTRL25, - DSIPHY_PLL_KVCO_CODE, DSIPHY_PLL_RESETSM_CNTRL, - (pll->cache_pll_trim_codes[0] | BIT(5)), 0x38); - MDSS_DYN_PLL_REG_W(pll->dyn_pll_base, - DSI_DYNAMIC_REFRESH_PLL_CTRL26, - DSIPHY_PLL_PLL_LPF2_POSTDIV, DSIPHY_CMN_PLL_CNTRL, - (((pout->pll_postdiv - 1) << 4) | pdb->in.pll_lpf_res1), 0x01); - MDSS_DYN_PLL_REG_W(pll->dyn_pll_base, - DSI_DYNAMIC_REFRESH_PLL_CTRL27, - DSIPHY_CMN_PLL_CNTRL, DSIPHY_CMN_PLL_CNTRL, - 0x01, 0x01); - MDSS_DYN_PLL_REG_W(pll->dyn_pll_base, - DSI_DYNAMIC_REFRESH_PLL_CTRL28, - DSIPHY_CMN_PLL_CNTRL, DSIPHY_CMN_PLL_CNTRL, - 0x01, 0x01); - MDSS_DYN_PLL_REG_W(pll->dyn_pll_base, - DSI_DYNAMIC_REFRESH_PLL_CTRL29, - DSIPHY_CMN_PLL_CNTRL, DSIPHY_CMN_PLL_CNTRL, - 0x01, 0x01); - MDSS_PLL_REG_W(pll->dyn_pll_base, - DSI_DYNAMIC_REFRESH_PLL_UPPER_ADDR, 0x0000001E); - MDSS_PLL_REG_W(pll->dyn_pll_base, - DSI_DYNAMIC_REFRESH_PLL_UPPER_ADDR2, 0x001FFE00); - - /* - * Ensure all the dynamic refresh registers are written before - * dynamic refresh to change the fps is triggered - */ - wmb(); -} - -int shadow_pll_vco_set_rate_8996(struct clk *c, unsigned long rate) -{ - int rc; - struct dsi_pll_vco_clk *vco = to_vco_clk(c); - struct mdss_pll_resources *pll = vco->priv; - struct dsi_pll_db *pdb; - s64 vco_clk_rate = (s64)rate; - - if (!pll) { - pr_err("PLL data not found\n"); - return -EINVAL; - } - - pdb = pll->priv; - if (!pdb) { - pr_err("No priv data found\n"); - return -EINVAL; - } - - rc = mdss_pll_read_stored_trim_codes(pll, vco_clk_rate); - if (rc) { - pr_err("cannot find pll codes rate=%lld\n", vco_clk_rate); - return -EINVAL; - } - - rc = mdss_pll_resource_enable(pll, true); - if (rc) { - pr_err("Failed to enable mdss dsi plla=%d\n", pll->index); - return rc; - } - - pr_debug("%s: ndx=%d base=%p rate=%lu\n", __func__, - pll->index, pll->pll_base, rate); - - pll->vco_current_rate = rate; - pll->vco_ref_clk_rate = vco->ref_clk_rate; - - mdss_dsi_pll_8996_input_init(pll, pdb); - - pll_8996_dec_frac_calc(pll, pdb); - - pll_8996_calc_vco_count(pdb, pll->vco_current_rate, - pll->vco_ref_clk_rate); - - shadow_pll_dynamic_refresh_8996(pll, pdb); - - rc = mdss_pll_resource_enable(pll, false); - if (rc) { - pr_err("Failed to enable mdss dsi plla=%d\n", pll->index); - return rc; - } - - return rc; -} - -unsigned long pll_vco_get_rate_8996(struct clk *c) -{ - u64 vco_rate, multiplier = BIT(20); - s32 div_frac_start; - u32 dec_start; - struct dsi_pll_vco_clk *vco = to_vco_clk(c); - u64 ref_clk = vco->ref_clk_rate; - int rc; - struct mdss_pll_resources *pll = vco->priv; - - if (is_gdsc_disabled(pll)) - return 0; - - rc = mdss_pll_resource_enable(pll, true); - if (rc) { - pr_err("Failed to enable mdss dsi pll=%d\n", pll->index); - return rc; - } - - dec_start = MDSS_PLL_REG_R(pll->pll_base, - DSIPHY_PLL_DEC_START); - dec_start &= 0x0ff; - pr_debug("dec_start = 0x%x\n", dec_start); - - div_frac_start = (MDSS_PLL_REG_R(pll->pll_base, - DSIPHY_PLL_DIV_FRAC_START3) & 0x0f) << 16; - div_frac_start |= (MDSS_PLL_REG_R(pll->pll_base, - DSIPHY_PLL_DIV_FRAC_START2) & 0x0ff) << 8; - div_frac_start |= MDSS_PLL_REG_R(pll->pll_base, - DSIPHY_PLL_DIV_FRAC_START1) & 0x0ff; - pr_debug("div_frac_start = 0x%x\n", div_frac_start); - - vco_rate = ref_clk * dec_start; - vco_rate += ((ref_clk * div_frac_start) / multiplier); - - pr_debug("returning vco rate = %lu\n", (unsigned long)vco_rate); - - mdss_pll_resource_enable(pll, false); - - return (unsigned long)vco_rate; -} - -long pll_vco_round_rate_8996(struct clk *c, unsigned long rate) -{ - unsigned long rrate = rate; - u32 div; - struct dsi_pll_vco_clk *vco = to_vco_clk(c); - - div = vco->min_rate / rate; - if (div > 15) { - /* rate < 86.67 Mhz */ - pr_err("rate=%lu NOT supportted\n", rate); - return -EINVAL; - } - - if (rate < vco->min_rate) - rrate = vco->min_rate; - if (rate > vco->max_rate) - rrate = vco->max_rate; - - return rrate; -} - -enum handoff pll_vco_handoff_8996(struct clk *c) -{ - int rc; - enum handoff ret = HANDOFF_DISABLED_CLK; - struct dsi_pll_vco_clk *vco = to_vco_clk(c); - struct mdss_pll_resources *pll = vco->priv; - - if (is_gdsc_disabled(pll)) - return HANDOFF_DISABLED_CLK; - - rc = mdss_pll_resource_enable(pll, true); - if (rc) { - pr_err("Failed to enable mdss dsi pll=%d\n", pll->index); - return ret; - } - - if (pll_is_pll_locked_8996(pll)) { - pll->handoff_resources = true; - pll->pll_on = true; - c->rate = pll_vco_get_rate_8996(c); - ret = HANDOFF_ENABLED_CLK; - } else { - mdss_pll_resource_enable(pll, false); - } - - return ret; -} - -enum handoff shadow_pll_vco_handoff_8996(struct clk *c) -{ - return HANDOFF_DISABLED_CLK; -} - -int pll_vco_prepare_8996(struct clk *c) -{ - int rc = 0; - struct dsi_pll_vco_clk *vco = to_vco_clk(c); - struct mdss_pll_resources *pll = vco->priv; - - if (!pll) { - pr_err("Dsi pll resources are not available\n"); - return -EINVAL; - } - - rc = mdss_pll_resource_enable(pll, true); - if (rc) { - pr_err("ndx=%d Failed to enable mdss dsi pll resources\n", - pll->index); - return rc; - } - - if ((pll->vco_cached_rate != 0) - && (pll->vco_cached_rate == c->rate)) { - rc = c->ops->set_rate(c, pll->vco_cached_rate); - if (rc) { - pr_err("index=%d vco_set_rate failed. rc=%d\n", - rc, pll->index); - mdss_pll_resource_enable(pll, false); - goto error; - } - } - - rc = dsi_pll_enable(c); - - if (rc) { - mdss_pll_resource_enable(pll, false); - pr_err("ndx=%d failed to enable dsi pll\n", pll->index); - } - -error: - return rc; -} - -void pll_vco_unprepare_8996(struct clk *c) -{ - struct dsi_pll_vco_clk *vco = to_vco_clk(c); - struct mdss_pll_resources *pll = vco->priv; - - if (!pll) { - pr_err("Dsi pll resources are not available\n"); - return; - } - - pll->vco_cached_rate = c->rate; - dsi_pll_disable(c); -} diff --git a/pll/dsi_pll_util.c b/pll/dsi_pll_util.c deleted file mode 100644 index 0769bf3061cb..000000000000 --- a/pll/dsi_pll_util.c +++ /dev/null @@ -1,580 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. - */ - -#define pr_fmt(fmt) "%s: " fmt, __func__ - -#include -#include -#include -#include -#include - -#include "pll_drv.h" -#include "dsi_pll.h" - -#define DSI_PHY_PLL_UNIPHY_PLL_REFCLK_CFG (0x0) -#define DSI_PHY_PLL_UNIPHY_PLL_POSTDIV1_CFG (0x0004) -#define DSI_PHY_PLL_UNIPHY_PLL_CHGPUMP_CFG (0x0008) -#define DSI_PHY_PLL_UNIPHY_PLL_VCOLPF_CFG (0x000C) -#define DSI_PHY_PLL_UNIPHY_PLL_VREG_CFG (0x0010) -#define DSI_PHY_PLL_UNIPHY_PLL_PWRGEN_CFG (0x0014) -#define DSI_PHY_PLL_UNIPHY_PLL_POSTDIV2_CFG (0x0024) -#define DSI_PHY_PLL_UNIPHY_PLL_POSTDIV3_CFG (0x0028) -#define DSI_PHY_PLL_UNIPHY_PLL_LPFR_CFG (0x002C) -#define DSI_PHY_PLL_UNIPHY_PLL_LPFC1_CFG (0x0030) -#define DSI_PHY_PLL_UNIPHY_PLL_LPFC2_CFG (0x0034) -#define DSI_PHY_PLL_UNIPHY_PLL_SDM_CFG0 (0x0038) -#define DSI_PHY_PLL_UNIPHY_PLL_SDM_CFG1 (0x003C) -#define DSI_PHY_PLL_UNIPHY_PLL_SDM_CFG2 (0x0040) -#define DSI_PHY_PLL_UNIPHY_PLL_SDM_CFG3 (0x0044) -#define DSI_PHY_PLL_UNIPHY_PLL_SDM_CFG4 (0x0048) -#define DSI_PHY_PLL_UNIPHY_PLL_CAL_CFG0 (0x006C) -#define DSI_PHY_PLL_UNIPHY_PLL_CAL_CFG2 (0x0074) -#define DSI_PHY_PLL_UNIPHY_PLL_CAL_CFG3 (0x0078) -#define DSI_PHY_PLL_UNIPHY_PLL_CAL_CFG4 (0x007C) -#define DSI_PHY_PLL_UNIPHY_PLL_CAL_CFG5 (0x0080) -#define DSI_PHY_PLL_UNIPHY_PLL_CAL_CFG6 (0x0084) -#define DSI_PHY_PLL_UNIPHY_PLL_CAL_CFG7 (0x0088) -#define DSI_PHY_PLL_UNIPHY_PLL_CAL_CFG8 (0x008C) -#define DSI_PHY_PLL_UNIPHY_PLL_CAL_CFG9 (0x0090) -#define DSI_PHY_PLL_UNIPHY_PLL_CAL_CFG10 (0x0094) -#define DSI_PHY_PLL_UNIPHY_PLL_CAL_CFG11 (0x0098) -#define DSI_PHY_PLL_UNIPHY_PLL_EFUSE_CFG (0x009C) -#define DSI_PHY_PLL_UNIPHY_PLL_STATUS (0x00C0) - -#define DSI_PLL_POLL_DELAY_US 50 -#define DSI_PLL_POLL_TIMEOUT_US 500 - -int set_byte_mux_sel(struct mux_clk *clk, int sel) -{ - struct mdss_pll_resources *dsi_pll_res = clk->priv; - - pr_debug("byte mux set to %s mode\n", sel ? "indirect" : "direct"); - MDSS_PLL_REG_W(dsi_pll_res->pll_base, - DSI_PHY_PLL_UNIPHY_PLL_VREG_CFG, (sel << 1)); - - return 0; -} - -int get_byte_mux_sel(struct mux_clk *clk) -{ - int mux_mode, rc; - struct mdss_pll_resources *dsi_pll_res = clk->priv; - - if (is_gdsc_disabled(dsi_pll_res)) - return 0; - - rc = mdss_pll_resource_enable(dsi_pll_res, true); - if (rc) { - pr_err("Failed to enable mdss dsi pll resources\n"); - return rc; - } - - mux_mode = MDSS_PLL_REG_R(dsi_pll_res->pll_base, - DSI_PHY_PLL_UNIPHY_PLL_VREG_CFG) & BIT(1); - - pr_debug("byte mux mode = %s\n", mux_mode ? "indirect" : "direct"); - mdss_pll_resource_enable(dsi_pll_res, false); - - return !!mux_mode; -} - -int dsi_pll_div_prepare(struct clk *c) -{ - struct div_clk *div = to_div_clk(c); - /* Restore the divider's value */ - return div->ops->set_div(div, div->data.div); -} - -int dsi_pll_mux_prepare(struct clk *c) -{ - struct mux_clk *mux = to_mux_clk(c); - int i, rc, sel = 0; - struct mdss_pll_resources *dsi_pll_res = mux->priv; - - rc = mdss_pll_resource_enable(dsi_pll_res, true); - if (rc) { - pr_err("Failed to enable mdss dsi pll resources\n"); - return rc; - } - - for (i = 0; i < mux->num_parents; i++) - if (mux->parents[i].src == c->parent) { - sel = mux->parents[i].sel; - break; - } - - if (i == mux->num_parents) { - pr_err("Failed to select the parent clock\n"); - rc = -EINVAL; - goto error; - } - - /* Restore the mux source select value */ - rc = mux->ops->set_mux_sel(mux, sel); - -error: - mdss_pll_resource_enable(dsi_pll_res, false); - return rc; -} - -int fixed_4div_set_div(struct div_clk *clk, int div) -{ - int rc; - struct mdss_pll_resources *dsi_pll_res = clk->priv; - - rc = mdss_pll_resource_enable(dsi_pll_res, true); - if (rc) { - pr_err("Failed to enable mdss dsi pll resources\n"); - return rc; - } - - MDSS_PLL_REG_W(dsi_pll_res->pll_base, - DSI_PHY_PLL_UNIPHY_PLL_POSTDIV2_CFG, (div - 1)); - - mdss_pll_resource_enable(dsi_pll_res, false); - return rc; -} - -int fixed_4div_get_div(struct div_clk *clk) -{ - int div = 0, rc; - struct mdss_pll_resources *dsi_pll_res = clk->priv; - - if (is_gdsc_disabled(dsi_pll_res)) - return 0; - - rc = mdss_pll_resource_enable(dsi_pll_res, true); - if (rc) { - pr_err("Failed to enable mdss dsi pll resources\n"); - return rc; - } - - div = MDSS_PLL_REG_R(dsi_pll_res->pll_base, - DSI_PHY_PLL_UNIPHY_PLL_POSTDIV2_CFG); - - mdss_pll_resource_enable(dsi_pll_res, false); - return div + 1; -} - -int digital_set_div(struct div_clk *clk, int div) -{ - int rc; - struct mdss_pll_resources *dsi_pll_res = clk->priv; - - rc = mdss_pll_resource_enable(dsi_pll_res, true); - if (rc) { - pr_err("Failed to enable mdss dsi pll resources\n"); - return rc; - } - - MDSS_PLL_REG_W(dsi_pll_res->pll_base, - DSI_PHY_PLL_UNIPHY_PLL_POSTDIV3_CFG, (div - 1)); - - mdss_pll_resource_enable(dsi_pll_res, false); - return rc; -} - -int digital_get_div(struct div_clk *clk) -{ - int div = 0, rc; - struct mdss_pll_resources *dsi_pll_res = clk->priv; - - if (is_gdsc_disabled(dsi_pll_res)) - return 0; - - rc = mdss_pll_resource_enable(dsi_pll_res, true); - if (rc) { - pr_err("Failed to enable mdss dsi pll resources\n"); - return rc; - } - - div = MDSS_PLL_REG_R(dsi_pll_res->pll_base, - DSI_PHY_PLL_UNIPHY_PLL_POSTDIV3_CFG); - - mdss_pll_resource_enable(dsi_pll_res, false); - return div + 1; -} - -int analog_set_div(struct div_clk *clk, int div) -{ - int rc; - struct mdss_pll_resources *dsi_pll_res = clk->priv; - - rc = mdss_pll_resource_enable(dsi_pll_res, true); - if (rc) { - pr_err("Failed to enable mdss dsi pll resources\n"); - return rc; - } - - MDSS_PLL_REG_W(dsi_pll_res->pll_base, - DSI_PHY_PLL_UNIPHY_PLL_POSTDIV1_CFG, div - 1); - - mdss_pll_resource_enable(dsi_pll_res, false); - return rc; -} - -int analog_get_div(struct div_clk *clk) -{ - int div = 0, rc; - struct mdss_pll_resources *dsi_pll_res = clk->priv; - - if (is_gdsc_disabled(dsi_pll_res)) - return 0; - - rc = mdss_pll_resource_enable(clk->priv, true); - if (rc) { - pr_err("Failed to enable mdss dsi pll resources\n"); - return rc; - } - - div = MDSS_PLL_REG_R(dsi_pll_res->pll_base, - DSI_PHY_PLL_UNIPHY_PLL_POSTDIV1_CFG) + 1; - - mdss_pll_resource_enable(dsi_pll_res, false); - - return div; -} - -int dsi_pll_lock_status(struct mdss_pll_resources *dsi_pll_res) -{ - u32 status; - int pll_locked; - - /* poll for PLL ready status */ - if (readl_poll_timeout_atomic((dsi_pll_res->pll_base + - DSI_PHY_PLL_UNIPHY_PLL_STATUS), - status, - ((status & BIT(0)) == 1), - DSI_PLL_POLL_DELAY_US, - DSI_PLL_POLL_TIMEOUT_US)) { - pr_debug("DSI PLL status=%x failed to Lock\n", status); - pll_locked = 0; - } else { - pll_locked = 1; - } - - return pll_locked; -} - -int vco_set_rate(struct dsi_pll_vco_clk *vco, unsigned long rate) -{ - s64 vco_clk_rate = rate; - s32 rem; - s64 refclk_cfg, frac_n_mode, ref_doubler_en_b; - s64 ref_clk_to_pll, div_fbx1000, frac_n_value; - s64 sdm_cfg0, sdm_cfg1, sdm_cfg2, sdm_cfg3; - s64 gen_vco_clk, cal_cfg10, cal_cfg11; - u32 res; - int i; - struct mdss_pll_resources *dsi_pll_res = vco->priv; - - /* Configure the Loop filter resistance */ - for (i = 0; i < vco->lpfr_lut_size; i++) - if (vco_clk_rate <= vco->lpfr_lut[i].vco_rate) - break; - if (i == vco->lpfr_lut_size) { - pr_err("unable to get loop filter resistance. vco=%ld\n", rate); - return -EINVAL; - } - res = vco->lpfr_lut[i].r; - MDSS_PLL_REG_W(dsi_pll_res->pll_base, - DSI_PHY_PLL_UNIPHY_PLL_LPFR_CFG, res); - - /* Loop filter capacitance values : c1 and c2 */ - MDSS_PLL_REG_W(dsi_pll_res->pll_base, - DSI_PHY_PLL_UNIPHY_PLL_LPFC1_CFG, 0x70); - MDSS_PLL_REG_W(dsi_pll_res->pll_base, - DSI_PHY_PLL_UNIPHY_PLL_LPFC2_CFG, 0x15); - - div_s64_rem(vco_clk_rate, vco->ref_clk_rate, &rem); - if (rem) { - refclk_cfg = 0x1; - frac_n_mode = 1; - ref_doubler_en_b = 0; - } else { - refclk_cfg = 0x0; - frac_n_mode = 0; - ref_doubler_en_b = 1; - } - - pr_debug("refclk_cfg = %lld\n", refclk_cfg); - - ref_clk_to_pll = ((vco->ref_clk_rate * 2 * (refclk_cfg)) - + (ref_doubler_en_b * vco->ref_clk_rate)); - div_fbx1000 = div_s64((vco_clk_rate * 1000), ref_clk_to_pll); - - div_s64_rem(div_fbx1000, 1000, &rem); - frac_n_value = div_s64((rem * (1 << 16)), 1000); - gen_vco_clk = div_s64(div_fbx1000 * ref_clk_to_pll, 1000); - - pr_debug("ref_clk_to_pll = %lld\n", ref_clk_to_pll); - pr_debug("div_fb = %lld\n", div_fbx1000); - pr_debug("frac_n_value = %lld\n", frac_n_value); - - pr_debug("Generated VCO Clock: %lld\n", gen_vco_clk); - rem = 0; - if (frac_n_mode) { - sdm_cfg0 = (0x0 << 5); - sdm_cfg0 |= (0x0 & 0x3f); - sdm_cfg1 = (div_s64(div_fbx1000, 1000) & 0x3f) - 1; - sdm_cfg3 = div_s64_rem(frac_n_value, 256, &rem); - sdm_cfg2 = rem; - } else { - sdm_cfg0 = (0x1 << 5); - sdm_cfg0 |= (div_s64(div_fbx1000, 1000) & 0x3f) - 1; - sdm_cfg1 = (0x0 & 0x3f); - sdm_cfg2 = 0; - sdm_cfg3 = 0; - } - - pr_debug("sdm_cfg0=%lld\n", sdm_cfg0); - pr_debug("sdm_cfg1=%lld\n", sdm_cfg1); - pr_debug("sdm_cfg2=%lld\n", sdm_cfg2); - pr_debug("sdm_cfg3=%lld\n", sdm_cfg3); - - cal_cfg11 = div_s64_rem(gen_vco_clk, 256 * 1000000, &rem); - cal_cfg10 = rem / 1000000; - pr_debug("cal_cfg10=%lld, cal_cfg11=%lld\n", cal_cfg10, cal_cfg11); - - MDSS_PLL_REG_W(dsi_pll_res->pll_base, - DSI_PHY_PLL_UNIPHY_PLL_CHGPUMP_CFG, 0x02); - MDSS_PLL_REG_W(dsi_pll_res->pll_base, - DSI_PHY_PLL_UNIPHY_PLL_CAL_CFG3, 0x2b); - MDSS_PLL_REG_W(dsi_pll_res->pll_base, - DSI_PHY_PLL_UNIPHY_PLL_CAL_CFG4, 0x66); - MDSS_PLL_REG_W(dsi_pll_res->pll_base, - DSI_PHY_PLL_UNIPHY_PLL_LKDET_CFG2, 0x0d); - - MDSS_PLL_REG_W(dsi_pll_res->pll_base, - DSI_PHY_PLL_UNIPHY_PLL_SDM_CFG1, (u32)(sdm_cfg1 & 0xff)); - MDSS_PLL_REG_W(dsi_pll_res->pll_base, - DSI_PHY_PLL_UNIPHY_PLL_SDM_CFG2, (u32)(sdm_cfg2 & 0xff)); - MDSS_PLL_REG_W(dsi_pll_res->pll_base, - DSI_PHY_PLL_UNIPHY_PLL_SDM_CFG3, (u32)(sdm_cfg3 & 0xff)); - MDSS_PLL_REG_W(dsi_pll_res->pll_base, - DSI_PHY_PLL_UNIPHY_PLL_SDM_CFG4, 0x00); - - /* Add hardware recommended delay for correct PLL configuration */ - if (dsi_pll_res->vco_delay) - udelay(dsi_pll_res->vco_delay); - - MDSS_PLL_REG_W(dsi_pll_res->pll_base, - DSI_PHY_PLL_UNIPHY_PLL_REFCLK_CFG, (u32)refclk_cfg); - MDSS_PLL_REG_W(dsi_pll_res->pll_base, - DSI_PHY_PLL_UNIPHY_PLL_PWRGEN_CFG, 0x00); - MDSS_PLL_REG_W(dsi_pll_res->pll_base, - DSI_PHY_PLL_UNIPHY_PLL_VCOLPF_CFG, 0x71); - MDSS_PLL_REG_W(dsi_pll_res->pll_base, - DSI_PHY_PLL_UNIPHY_PLL_SDM_CFG0, (u32)sdm_cfg0); - MDSS_PLL_REG_W(dsi_pll_res->pll_base, - DSI_PHY_PLL_UNIPHY_PLL_CAL_CFG0, 0x12); - MDSS_PLL_REG_W(dsi_pll_res->pll_base, - DSI_PHY_PLL_UNIPHY_PLL_CAL_CFG6, 0x30); - MDSS_PLL_REG_W(dsi_pll_res->pll_base, - DSI_PHY_PLL_UNIPHY_PLL_CAL_CFG7, 0x00); - MDSS_PLL_REG_W(dsi_pll_res->pll_base, - DSI_PHY_PLL_UNIPHY_PLL_CAL_CFG8, 0x60); - MDSS_PLL_REG_W(dsi_pll_res->pll_base, - DSI_PHY_PLL_UNIPHY_PLL_CAL_CFG9, 0x00); - MDSS_PLL_REG_W(dsi_pll_res->pll_base, - DSI_PHY_PLL_UNIPHY_PLL_CAL_CFG10, (u32)(cal_cfg10 & 0xff)); - MDSS_PLL_REG_W(dsi_pll_res->pll_base, - DSI_PHY_PLL_UNIPHY_PLL_CAL_CFG11, (u32)(cal_cfg11 & 0xff)); - MDSS_PLL_REG_W(dsi_pll_res->pll_base, - DSI_PHY_PLL_UNIPHY_PLL_EFUSE_CFG, 0x20); - - return 0; -} - -unsigned long vco_get_rate(struct clk *c) -{ - u32 sdm0, doubler, sdm_byp_div; - u64 vco_rate; - u32 sdm_dc_off, sdm_freq_seed, sdm2, sdm3; - struct dsi_pll_vco_clk *vco = to_vco_clk(c); - u64 ref_clk = vco->ref_clk_rate; - int rc; - struct mdss_pll_resources *dsi_pll_res = vco->priv; - - if (is_gdsc_disabled(dsi_pll_res)) - return 0; - - rc = mdss_pll_resource_enable(dsi_pll_res, true); - if (rc) { - pr_err("Failed to enable mdss dsi pll resources\n"); - return rc; - } - - /* Check to see if the ref clk doubler is enabled */ - doubler = MDSS_PLL_REG_R(dsi_pll_res->pll_base, - DSI_PHY_PLL_UNIPHY_PLL_REFCLK_CFG) & BIT(0); - ref_clk += (doubler * vco->ref_clk_rate); - - /* see if it is integer mode or sdm mode */ - sdm0 = MDSS_PLL_REG_R(dsi_pll_res->pll_base, - DSI_PHY_PLL_UNIPHY_PLL_SDM_CFG0); - if (sdm0 & BIT(6)) { - /* integer mode */ - sdm_byp_div = (MDSS_PLL_REG_R(dsi_pll_res->pll_base, - DSI_PHY_PLL_UNIPHY_PLL_SDM_CFG0) & 0x3f) + 1; - vco_rate = ref_clk * sdm_byp_div; - } else { - /* sdm mode */ - sdm_dc_off = MDSS_PLL_REG_R(dsi_pll_res->pll_base, - DSI_PHY_PLL_UNIPHY_PLL_SDM_CFG1) & 0xFF; - pr_debug("sdm_dc_off = %d\n", sdm_dc_off); - sdm2 = MDSS_PLL_REG_R(dsi_pll_res->pll_base, - DSI_PHY_PLL_UNIPHY_PLL_SDM_CFG2) & 0xFF; - sdm3 = MDSS_PLL_REG_R(dsi_pll_res->pll_base, - DSI_PHY_PLL_UNIPHY_PLL_SDM_CFG3) & 0xFF; - sdm_freq_seed = (sdm3 << 8) | sdm2; - pr_debug("sdm_freq_seed = %d\n", sdm_freq_seed); - - vco_rate = (ref_clk * (sdm_dc_off + 1)) + - mult_frac(ref_clk, sdm_freq_seed, BIT(16)); - pr_debug("vco rate = %lld\n", vco_rate); - } - - pr_debug("returning vco rate = %lu\n", (unsigned long)vco_rate); - - mdss_pll_resource_enable(dsi_pll_res, false); - - return (unsigned long)vco_rate; -} - -static int dsi_pll_enable(struct clk *c) -{ - int i, rc; - struct dsi_pll_vco_clk *vco = to_vco_clk(c); - struct mdss_pll_resources *dsi_pll_res = vco->priv; - - rc = mdss_pll_resource_enable(dsi_pll_res, true); - if (rc) { - pr_err("Failed to enable mdss dsi pll resources\n"); - return rc; - } - - /* Try all enable sequences until one succeeds */ - for (i = 0; i < vco->pll_en_seq_cnt; i++) { - rc = vco->pll_enable_seqs[i](dsi_pll_res); - pr_debug("DSI PLL %s after sequence #%d\n", - rc ? "unlocked" : "locked", i + 1); - if (!rc) - break; - } - - if (rc) { - mdss_pll_resource_enable(dsi_pll_res, false); - pr_err("DSI PLL failed to lock\n"); - } - dsi_pll_res->pll_on = true; - - return rc; -} - -static void dsi_pll_disable(struct clk *c) -{ - struct dsi_pll_vco_clk *vco = to_vco_clk(c); - struct mdss_pll_resources *dsi_pll_res = vco->priv; - - if (!dsi_pll_res->pll_on && - mdss_pll_resource_enable(dsi_pll_res, true)) { - pr_err("Failed to enable mdss dsi pll resources\n"); - return; - } - - dsi_pll_res->handoff_resources = false; - - MDSS_PLL_REG_W(dsi_pll_res->pll_base, - DSI_PHY_PLL_UNIPHY_PLL_GLB_CFG, 0x00); - - mdss_pll_resource_enable(dsi_pll_res, false); - dsi_pll_res->pll_on = false; - - pr_debug("DSI PLL Disabled\n"); -} - -long vco_round_rate(struct clk *c, unsigned long rate) -{ - unsigned long rrate = rate; - struct dsi_pll_vco_clk *vco = to_vco_clk(c); - - if (rate < vco->min_rate) - rrate = vco->min_rate; - if (rate > vco->max_rate) - rrate = vco->max_rate; - - return rrate; -} - -enum handoff vco_handoff(struct clk *c) -{ - int rc; - enum handoff ret = HANDOFF_DISABLED_CLK; - struct dsi_pll_vco_clk *vco = to_vco_clk(c); - struct mdss_pll_resources *dsi_pll_res = vco->priv; - - if (is_gdsc_disabled(dsi_pll_res)) - return HANDOFF_DISABLED_CLK; - - rc = mdss_pll_resource_enable(dsi_pll_res, true); - if (rc) { - pr_err("Failed to enable mdss dsi pll resources\n"); - return ret; - } - - if (dsi_pll_lock_status(dsi_pll_res)) { - dsi_pll_res->handoff_resources = true; - dsi_pll_res->pll_on = true; - c->rate = vco_get_rate(c); - ret = HANDOFF_ENABLED_CLK; - } else { - mdss_pll_resource_enable(dsi_pll_res, false); - } - - return ret; -} - -int vco_prepare(struct clk *c) -{ - int rc = 0; - struct dsi_pll_vco_clk *vco = to_vco_clk(c); - struct mdss_pll_resources *dsi_pll_res = vco->priv; - - if (!dsi_pll_res) { - pr_err("Dsi pll resources are not available\n"); - return -EINVAL; - } - - if ((dsi_pll_res->vco_cached_rate != 0) - && (dsi_pll_res->vco_cached_rate == c->rate)) { - rc = c->ops->set_rate(c, dsi_pll_res->vco_cached_rate); - if (rc) { - pr_err("vco_set_rate failed. rc=%d\n", rc); - goto error; - } - } - - rc = dsi_pll_enable(c); - -error: - return rc; -} - -void vco_unprepare(struct clk *c) -{ - struct dsi_pll_vco_clk *vco = to_vco_clk(c); - struct mdss_pll_resources *dsi_pll_res = vco->priv; - - if (!dsi_pll_res) { - pr_err("Dsi pll resources are not available\n"); - return; - } - - dsi_pll_res->vco_cached_rate = c->rate; - dsi_pll_disable(c); -} - diff --git a/pll/edp_pll_28hpm.c b/pll/edp_pll_28hpm.c deleted file mode 100644 index b2053ec891f8..000000000000 --- a/pll/edp_pll_28hpm.c +++ /dev/null @@ -1,580 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. - */ - -#define pr_fmt(fmt) "%s: " fmt, __func__ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "pll_drv.h" -#include "edp_pll.h" - -#define EDP_PHY_PLL_UNIPHY_PLL_REFCLK_CFG (0x0) -#define EDP_PHY_PLL_UNIPHY_PLL_POSTDIV1_CFG (0x0004) -#define EDP_PHY_PLL_UNIPHY_PLL_VCOLPF_CFG (0x000C) -#define EDP_PHY_PLL_UNIPHY_PLL_GLB_CFG (0x0020) -#define EDP_PHY_PLL_UNIPHY_PLL_POSTDIV2_CFG (0x0024) -#define EDP_PHY_PLL_UNIPHY_PLL_POSTDIV3_CFG (0x0028) -#define EDP_PHY_PLL_UNIPHY_PLL_SDM_CFG0 (0x0038) -#define EDP_PHY_PLL_UNIPHY_PLL_SDM_CFG1 (0x003C) -#define EDP_PHY_PLL_UNIPHY_PLL_SDM_CFG2 (0x0040) -#define EDP_PHY_PLL_UNIPHY_PLL_SDM_CFG3 (0x0044) -#define EDP_PHY_PLL_UNIPHY_PLL_SDM_CFG4 (0x0048) -#define EDP_PHY_PLL_UNIPHY_PLL_SSC_CFG0 (0x004C) -#define EDP_PHY_PLL_UNIPHY_PLL_SSC_CFG1 (0x0050) -#define EDP_PHY_PLL_UNIPHY_PLL_SSC_CFG2 (0x0054) -#define EDP_PHY_PLL_UNIPHY_PLL_SSC_CFG3 (0x0058) -#define EDP_PHY_PLL_UNIPHY_PLL_LKDET_CFG2 (0x0064) -#define EDP_PHY_PLL_UNIPHY_PLL_CAL_CFG0 (0x006C) -#define EDP_PHY_PLL_UNIPHY_PLL_CAL_CFG2 (0x0074) -#define EDP_PHY_PLL_UNIPHY_PLL_CAL_CFG6 (0x0084) -#define EDP_PHY_PLL_UNIPHY_PLL_CAL_CFG7 (0x0088) -#define EDP_PHY_PLL_UNIPHY_PLL_CAL_CFG8 (0x008C) -#define EDP_PHY_PLL_UNIPHY_PLL_CAL_CFG9 (0x0090) -#define EDP_PHY_PLL_UNIPHY_PLL_CAL_CFG10 (0x0094) -#define EDP_PHY_PLL_UNIPHY_PLL_CAL_CFG11 (0x0098) -#define EDP_PHY_PLL_UNIPHY_PLL_LKDET_CFG0 (0x005C) -#define EDP_PHY_PLL_UNIPHY_PLL_LKDET_CFG1 (0x0060) - -#define EDP_PLL_POLL_DELAY_US 50 -#define EDP_PLL_POLL_TIMEOUT_US 500 - -static const struct clk_ops edp_mainlink_clk_src_ops; -static struct clk_div_ops fixed_5div_ops; /* null ops */ -static const struct clk_ops edp_pixel_clk_ops; - -static inline struct edp_pll_vco_clk *to_edp_vco_clk(struct clk *clk) -{ - return container_of(clk, struct edp_pll_vco_clk, c); -} - -int edp_div_prepare(struct clk *c) -{ - struct div_clk *div = to_div_clk(c); - /* Restore the divider's value */ - return div->ops->set_div(div, div->data.div); -} - -static int edp_vco_set_rate(struct clk *c, unsigned long vco_rate) -{ - struct edp_pll_vco_clk *vco = to_edp_vco_clk(c); - struct mdss_pll_resources *edp_pll_res = vco->priv; - int rc; - - pr_debug("vco_rate=%d\n", (int)vco_rate); - - rc = mdss_pll_resource_enable(edp_pll_res, true); - if (rc) { - pr_err("failed to enable edp pll res rc=%d\n", rc); - rc = -EINVAL; - } - - if (vco_rate == 810000000) { - MDSS_PLL_REG_W(edp_pll_res->pll_base, - EDP_PHY_PLL_UNIPHY_PLL_VCOLPF_CFG, 0x18); - MDSS_PLL_REG_W(edp_pll_res->pll_base, - EDP_PHY_PLL_UNIPHY_PLL_LKDET_CFG2, 0x0d); - MDSS_PLL_REG_W(edp_pll_res->pll_base, - EDP_PHY_PLL_UNIPHY_PLL_REFCLK_CFG, 0x00); - MDSS_PLL_REG_W(edp_pll_res->pll_base, - EDP_PHY_PLL_UNIPHY_PLL_SDM_CFG0, 0x36); - MDSS_PLL_REG_W(edp_pll_res->pll_base, - EDP_PHY_PLL_UNIPHY_PLL_SDM_CFG1, 0x69); - MDSS_PLL_REG_W(edp_pll_res->pll_base, - EDP_PHY_PLL_UNIPHY_PLL_SDM_CFG2, 0xff); - MDSS_PLL_REG_W(edp_pll_res->pll_base, - EDP_PHY_PLL_UNIPHY_PLL_SDM_CFG3, 0x2f); - MDSS_PLL_REG_W(edp_pll_res->pll_base, - EDP_PHY_PLL_UNIPHY_PLL_SDM_CFG4, 0x00); - MDSS_PLL_REG_W(edp_pll_res->pll_base, - EDP_PHY_PLL_UNIPHY_PLL_SSC_CFG0, 0x80); - MDSS_PLL_REG_W(edp_pll_res->pll_base, - EDP_PHY_PLL_UNIPHY_PLL_SSC_CFG1, 0x00); - MDSS_PLL_REG_W(edp_pll_res->pll_base, - EDP_PHY_PLL_UNIPHY_PLL_SSC_CFG2, 0x00); - MDSS_PLL_REG_W(edp_pll_res->pll_base, - EDP_PHY_PLL_UNIPHY_PLL_SSC_CFG3, 0x00); - MDSS_PLL_REG_W(edp_pll_res->pll_base, - EDP_PHY_PLL_UNIPHY_PLL_CAL_CFG0, 0x12); - MDSS_PLL_REG_W(edp_pll_res->pll_base, - EDP_PHY_PLL_UNIPHY_PLL_CAL_CFG2, 0x01); - MDSS_PLL_REG_W(edp_pll_res->pll_base, - EDP_PHY_PLL_UNIPHY_PLL_CAL_CFG6, 0x5a); - MDSS_PLL_REG_W(edp_pll_res->pll_base, - EDP_PHY_PLL_UNIPHY_PLL_CAL_CFG7, 0x0); - MDSS_PLL_REG_W(edp_pll_res->pll_base, - EDP_PHY_PLL_UNIPHY_PLL_CAL_CFG8, 0x60); - MDSS_PLL_REG_W(edp_pll_res->pll_base, - EDP_PHY_PLL_UNIPHY_PLL_CAL_CFG9, 0x0); - MDSS_PLL_REG_W(edp_pll_res->pll_base, - EDP_PHY_PLL_UNIPHY_PLL_CAL_CFG10, 0x2a); - MDSS_PLL_REG_W(edp_pll_res->pll_base, - EDP_PHY_PLL_UNIPHY_PLL_CAL_CFG11, 0x3); - MDSS_PLL_REG_W(edp_pll_res->pll_base, - EDP_PHY_PLL_UNIPHY_PLL_LKDET_CFG0, 0x10); - MDSS_PLL_REG_W(edp_pll_res->pll_base, - EDP_PHY_PLL_UNIPHY_PLL_LKDET_CFG1, 0x1a); - MDSS_PLL_REG_W(edp_pll_res->pll_base, - EDP_PHY_PLL_UNIPHY_PLL_POSTDIV1_CFG, 0x00); - MDSS_PLL_REG_W(edp_pll_res->pll_base, - EDP_PHY_PLL_UNIPHY_PLL_POSTDIV3_CFG, 0x00); - } else if (vco_rate == 1350000000) { - MDSS_PLL_REG_W(edp_pll_res->pll_base, - EDP_PHY_PLL_UNIPHY_PLL_LKDET_CFG2, 0x0d); - MDSS_PLL_REG_W(edp_pll_res->pll_base, - EDP_PHY_PLL_UNIPHY_PLL_REFCLK_CFG, 0x01); - MDSS_PLL_REG_W(edp_pll_res->pll_base, - EDP_PHY_PLL_UNIPHY_PLL_SDM_CFG0, 0x36); - MDSS_PLL_REG_W(edp_pll_res->pll_base, - EDP_PHY_PLL_UNIPHY_PLL_SDM_CFG1, 0x62); - MDSS_PLL_REG_W(edp_pll_res->pll_base, - EDP_PHY_PLL_UNIPHY_PLL_SDM_CFG2, 0x00); - MDSS_PLL_REG_W(edp_pll_res->pll_base, - EDP_PHY_PLL_UNIPHY_PLL_SDM_CFG3, 0x28); - MDSS_PLL_REG_W(edp_pll_res->pll_base, - EDP_PHY_PLL_UNIPHY_PLL_SDM_CFG4, 0x00); - MDSS_PLL_REG_W(edp_pll_res->pll_base, - EDP_PHY_PLL_UNIPHY_PLL_SSC_CFG0, 0x80); - MDSS_PLL_REG_W(edp_pll_res->pll_base, - EDP_PHY_PLL_UNIPHY_PLL_SSC_CFG1, 0x00); - MDSS_PLL_REG_W(edp_pll_res->pll_base, - EDP_PHY_PLL_UNIPHY_PLL_SSC_CFG2, 0x00); - MDSS_PLL_REG_W(edp_pll_res->pll_base, - EDP_PHY_PLL_UNIPHY_PLL_SSC_CFG3, 0x00); - MDSS_PLL_REG_W(edp_pll_res->pll_base, - EDP_PHY_PLL_UNIPHY_PLL_CAL_CFG0, 0x12); - MDSS_PLL_REG_W(edp_pll_res->pll_base, - EDP_PHY_PLL_UNIPHY_PLL_CAL_CFG2, 0x01); - MDSS_PLL_REG_W(edp_pll_res->pll_base, - EDP_PHY_PLL_UNIPHY_PLL_CAL_CFG6, 0x5a); - MDSS_PLL_REG_W(edp_pll_res->pll_base, - EDP_PHY_PLL_UNIPHY_PLL_CAL_CFG7, 0x0); - MDSS_PLL_REG_W(edp_pll_res->pll_base, - EDP_PHY_PLL_UNIPHY_PLL_CAL_CFG8, 0x60); - MDSS_PLL_REG_W(edp_pll_res->pll_base, - EDP_PHY_PLL_UNIPHY_PLL_CAL_CFG9, 0x0); - MDSS_PLL_REG_W(edp_pll_res->pll_base, - EDP_PHY_PLL_UNIPHY_PLL_CAL_CFG10, 0x46); - MDSS_PLL_REG_W(edp_pll_res->pll_base, - EDP_PHY_PLL_UNIPHY_PLL_CAL_CFG11, 0x5); - MDSS_PLL_REG_W(edp_pll_res->pll_base, - EDP_PHY_PLL_UNIPHY_PLL_LKDET_CFG0, 0x10); - MDSS_PLL_REG_W(edp_pll_res->pll_base, - EDP_PHY_PLL_UNIPHY_PLL_LKDET_CFG1, 0x1a); - MDSS_PLL_REG_W(edp_pll_res->pll_base, - EDP_PHY_PLL_UNIPHY_PLL_POSTDIV1_CFG, 0x00); - MDSS_PLL_REG_W(edp_pll_res->pll_base, - EDP_PHY_PLL_UNIPHY_PLL_POSTDIV3_CFG, 0x00); - } else { - pr_err("rate=%d is NOT supported\n", (int)vco_rate); - vco_rate = 0; - rc = -EINVAL; - } - - MDSS_PLL_REG_W(edp_pll_res->pll_base, - EDP_PHY_PLL_UNIPHY_PLL_GLB_CFG, 0x01); - udelay(100); - MDSS_PLL_REG_W(edp_pll_res->pll_base, - EDP_PHY_PLL_UNIPHY_PLL_GLB_CFG, 0x05); - udelay(100); - MDSS_PLL_REG_W(edp_pll_res->pll_base, - EDP_PHY_PLL_UNIPHY_PLL_GLB_CFG, 0x07); - udelay(100); - MDSS_PLL_REG_W(edp_pll_res->pll_base, - EDP_PHY_PLL_UNIPHY_PLL_GLB_CFG, 0x0f); - udelay(100); - mdss_pll_resource_enable(edp_pll_res, false); - - vco->rate = vco_rate; - - return rc; -} - -static int edp_pll_ready_poll(struct mdss_pll_resources *edp_pll_res) -{ - int cnt; - u32 status; - - cnt = 100; - while (cnt--) { - udelay(100); - status = MDSS_PLL_REG_R(edp_pll_res->pll_base, 0xc0); - status &= 0x01; - if (status) - break; - } - pr_debug("cnt=%d status=%d\n", cnt, (int)status); - - if (status) - return 1; - - return 0; -} - -static int edp_vco_enable(struct clk *c) -{ - int i, ready; - int rc; - struct edp_pll_vco_clk *vco = to_edp_vco_clk(c); - struct mdss_pll_resources *edp_pll_res = vco->priv; - - rc = mdss_pll_resource_enable(edp_pll_res, true); - if (rc) { - pr_err("edp pll resources not available\n"); - return rc; - } - - for (i = 0; i < 3; i++) { - ready = edp_pll_ready_poll(edp_pll_res); - if (ready) - break; - MDSS_PLL_REG_W(edp_pll_res->pll_base, - EDP_PHY_PLL_UNIPHY_PLL_GLB_CFG, 0x01); - udelay(100); - MDSS_PLL_REG_W(edp_pll_res->pll_base, - EDP_PHY_PLL_UNIPHY_PLL_GLB_CFG, 0x05); - udelay(100); - MDSS_PLL_REG_W(edp_pll_res->pll_base, - EDP_PHY_PLL_UNIPHY_PLL_GLB_CFG, 0x07); - udelay(100); - MDSS_PLL_REG_W(edp_pll_res->pll_base, - EDP_PHY_PLL_UNIPHY_PLL_GLB_CFG, 0x0f); - udelay(100); - } - - if (ready) { - pr_debug("EDP PLL lock success\n"); - edp_pll_res->pll_on = true; - rc = 0; - } else { - pr_err("EDP PLL failed to lock\n"); - mdss_pll_resource_enable(edp_pll_res, false); - rc = -EINVAL; - } - - return rc; -} - -static void edp_vco_disable(struct clk *c) -{ - struct edp_pll_vco_clk *vco = to_edp_vco_clk(c); - struct mdss_pll_resources *edp_pll_res = vco->priv; - - if (!edp_pll_res) { - pr_err("Invalid input parameter\n"); - return; - } - - if (!edp_pll_res->pll_on && - mdss_pll_resource_enable(edp_pll_res, true)) { - pr_err("edp pll resources not available\n"); - return; - } - - MDSS_PLL_REG_W(edp_pll_res->pll_base, 0x20, 0x00); - - edp_pll_res->handoff_resources = false; - edp_pll_res->pll_on = false; - - mdss_pll_resource_enable(edp_pll_res, false); - - pr_debug("EDP PLL Disabled\n"); -} - -static unsigned long edp_vco_get_rate(struct clk *c) -{ - struct edp_pll_vco_clk *vco = to_edp_vco_clk(c); - struct mdss_pll_resources *edp_pll_res = vco->priv; - u32 pll_status, div2; - int rc; - - if (is_gdsc_disabled(edp_pll_res)) - return 0; - - rc = mdss_pll_resource_enable(edp_pll_res, true); - if (rc) { - pr_err("edp pll resources not available\n"); - return rc; - } - - if (vco->rate == 0) { - pll_status = MDSS_PLL_REG_R(edp_pll_res->pll_base, 0xc0); - if (pll_status & 0x01) { - div2 = MDSS_PLL_REG_R(edp_pll_res->pll_base, 0x24); - if (div2 & 0x01) - vco->rate = 1350000000; - else - vco->rate = 810000000; - } - } - mdss_pll_resource_enable(edp_pll_res, false); - - pr_debug("rate=%d\n", (int)vco->rate); - - return vco->rate; -} - -static long edp_vco_round_rate(struct clk *c, unsigned long rate) -{ - struct edp_pll_vco_clk *vco = to_edp_vco_clk(c); - unsigned long rrate = -ENOENT; - unsigned long *lp; - - lp = vco->rate_list; - while (*lp) { - rrate = *lp; - if (rate <= rrate) - break; - lp++; - } - - pr_debug("rrate=%d\n", (int)rrate); - - return rrate; -} - -static int edp_vco_prepare(struct clk *c) -{ - struct edp_pll_vco_clk *vco = to_edp_vco_clk(c); - - pr_debug("rate=%d\n", (int)vco->rate); - - return edp_vco_set_rate(c, vco->rate); -} - -static void edp_vco_unprepare(struct clk *c) -{ - struct edp_pll_vco_clk *vco = to_edp_vco_clk(c); - - pr_debug("rate=%d\n", (int)vco->rate); - - edp_vco_disable(c); -} - -static int edp_pll_lock_status(struct mdss_pll_resources *edp_pll_res) -{ - u32 status; - int pll_locked = 0; - int rc; - - rc = mdss_pll_resource_enable(edp_pll_res, true); - if (rc) { - pr_err("edp pll resources not available\n"); - return rc; - } - - /* poll for PLL ready status */ - if (readl_poll_timeout_atomic((edp_pll_res->pll_base + 0xc0), - status, ((status & BIT(0)) == 1), - EDP_PLL_POLL_DELAY_US, - EDP_PLL_POLL_TIMEOUT_US)) { - pr_debug("EDP PLL status=%x failed to Lock\n", status); - pll_locked = 0; - } else { - pll_locked = 1; - } - mdss_pll_resource_enable(edp_pll_res, false); - - return pll_locked; -} - -static enum handoff edp_vco_handoff(struct clk *c) -{ - enum handoff ret = HANDOFF_DISABLED_CLK; - struct edp_pll_vco_clk *vco = to_edp_vco_clk(c); - struct mdss_pll_resources *edp_pll_res = vco->priv; - - if (is_gdsc_disabled(edp_pll_res)) - return HANDOFF_DISABLED_CLK; - - if (mdss_pll_resource_enable(edp_pll_res, true)) { - pr_err("edp pll resources not available\n"); - return ret; - } - - edp_pll_res->handoff_resources = true; - - if (edp_pll_lock_status(edp_pll_res)) { - c->rate = edp_vco_get_rate(c); - edp_pll_res->pll_on = true; - ret = HANDOFF_ENABLED_CLK; - } else { - edp_pll_res->handoff_resources = false; - mdss_pll_resource_enable(edp_pll_res, false); - } - - pr_debug("done, ret=%d\n", ret); - return ret; -} - -static unsigned long edp_vco_rate_list[] = { - 810000000, 1350000000, 0}; - -struct const clk_ops edp_vco_clk_ops = { - .enable = edp_vco_enable, - .set_rate = edp_vco_set_rate, - .get_rate = edp_vco_get_rate, - .round_rate = edp_vco_round_rate, - .prepare = edp_vco_prepare, - .unprepare = edp_vco_unprepare, - .handoff = edp_vco_handoff, -}; - -struct edp_pll_vco_clk edp_vco_clk = { - .ref_clk_rate = 19200000, - .rate = 0, - .rate_list = edp_vco_rate_list, - .c = { - .dbg_name = "edp_vco_clk", - .ops = &edp_vco_clk_ops, - CLK_INIT(edp_vco_clk.c), - }, -}; - -static unsigned long edp_mainlink_get_rate(struct clk *c) -{ - struct div_clk *mclk = to_div_clk(c); - struct clk *pclk; - unsigned long rate = 0; - - pclk = clk_get_parent(c); - - if (pclk && pclk->ops->get_rate) { - rate = pclk->ops->get_rate(pclk); - rate /= mclk->data.div; - } - - pr_debug("rate=%d div=%d\n", (int)rate, mclk->data.div); - - return rate; -} - - -struct div_clk edp_mainlink_clk_src = { - .ops = &fixed_5div_ops, - .data = { - .div = 5, - .min_div = 5, - .max_div = 5, - }, - .c = { - .parent = &edp_vco_clk.c, - .dbg_name = "edp_mainlink_clk_src", - .ops = &edp_mainlink_clk_src_ops, - .flags = CLKFLAG_NO_RATE_CACHE, - CLK_INIT(edp_mainlink_clk_src.c), - } -}; - -/* - * this rate is from pll to clock controller - * output from pll to CC has two possibilities - * 1: if mainlink rate is 270M, then 675M - * 2: if mainlink rate is 162M, then 810M - */ -static int edp_pixel_set_div(struct div_clk *clk, int div) -{ - int rc; - struct mdss_pll_resources *edp_pll_res = clk->priv; - - rc = mdss_pll_resource_enable(edp_pll_res, true); - if (rc) { - pr_err("edp pll resources not available\n"); - return rc; - } - - pr_debug("div=%d\n", div); - MDSS_PLL_REG_W(edp_pll_res->pll_base, - EDP_PHY_PLL_UNIPHY_PLL_POSTDIV2_CFG, (div - 1)); - mdss_pll_resource_enable(edp_pll_res, false); - - return 0; -} - -static int edp_pixel_get_div(struct div_clk *clk) -{ - int div = 0; - int rc; - struct mdss_pll_resources *edp_pll_res = clk->priv; - - if (is_gdsc_disabled(edp_pll_res)) - return 0; - - rc = mdss_pll_resource_enable(edp_pll_res, true); - if (rc) { - pr_err("edp pll resources not available\n"); - return rc; - } - - div = MDSS_PLL_REG_R(edp_pll_res->pll_base, - EDP_PHY_PLL_UNIPHY_PLL_POSTDIV2_CFG); - mdss_pll_resource_enable(edp_pll_res, false); - div &= 0x01; - pr_debug("div=%d\n", div); - return div + 1; -} - -static struct clk_div_ops edp_pixel_ops = { - .set_div = edp_pixel_set_div, - .get_div = edp_pixel_get_div, -}; - -struct div_clk edp_pixel_clk_src = { - .data = { - .max_div = 2, - .min_div = 1, - }, - .ops = &edp_pixel_ops, - .c = { - .parent = &edp_vco_clk.c, - .dbg_name = "edp_pixel_clk_src", - .ops = &edp_pixel_clk_ops, - .flags = CLKFLAG_NO_RATE_CACHE, - CLK_INIT(edp_pixel_clk_src.c), - }, -}; - -static struct clk_lookup mdss_edp_pllcc_8974[] = { - CLK_LOOKUP("edp_pixel_src", edp_pixel_clk_src.c, - "fd8c0000.qcom,mmsscc-mdss"), - CLK_LOOKUP("edp_mainlink_src", edp_mainlink_clk_src.c, - "fd8c0000.qcom,mmsscc-mdss"), -}; - -int edp_pll_clock_register(struct platform_device *pdev, - struct mdss_pll_resources *pll_res) -{ - int rc = -ENOTSUPP; - - /* Set client data to div and vco clocks */ - edp_pixel_clk_src.priv = pll_res; - edp_mainlink_clk_src.priv = pll_res; - edp_vco_clk.priv = pll_res; - - /* Set clock operation for mainlink and pixel clock */ - edp_mainlink_clk_src_ops = clk_ops_div; - edp_mainlink_clk_src_ops.get_parent = clk_get_parent; - edp_mainlink_clk_src_ops.get_rate = edp_mainlink_get_rate; - - edp_pixel_clk_ops = clk_ops_slave_div; - edp_pixel_clk_ops.prepare = edp_div_prepare; - - rc = of_msm_clock_register(pdev->dev.of_node, mdss_edp_pllcc_8974, - ARRAY_SIZE(mdss_edp_pllcc_8974)); - if (rc) { - pr_err("Clock register failed rc=%d\n", rc); - rc = -EPROBE_DEFER; - } - - return rc; -} diff --git a/pll/hdmi_pll.h b/pll/hdmi_pll.h deleted file mode 100644 index 03f6fa20ea80..000000000000 --- a/pll/hdmi_pll.h +++ /dev/null @@ -1,57 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. - */ - -#ifndef __MDSS_HDMI_PLL_H -#define __MDSS_HDMI_PLL_H - -struct hdmi_pll_cfg { - unsigned long vco_rate; - u32 reg; -}; - -struct hdmi_pll_vco_clk { - struct clk_hw hw; - unsigned long rate; /* current vco rate */ - unsigned long min_rate; /* min vco rate */ - unsigned long max_rate; /* max vco rate */ - bool rate_set; - struct hdmi_pll_cfg *ip_seti; - struct hdmi_pll_cfg *cp_seti; - struct hdmi_pll_cfg *ip_setp; - struct hdmi_pll_cfg *cp_setp; - struct hdmi_pll_cfg *crctrl; - void *priv; - -}; - -static inline struct hdmi_pll_vco_clk *to_hdmi_vco_clk_hw(struct clk_hw *hw) -{ - return container_of(hw, struct hdmi_pll_vco_clk, hw); -} - -int hdmi_pll_clock_register_28lpm(struct platform_device *pdev, - struct mdss_pll_resources *pll_res); - -int hdmi_pll_clock_register(struct platform_device *pdev, - struct mdss_pll_resources *pll_res); - -int hdmi_20nm_pll_clock_register(struct platform_device *pdev, - struct mdss_pll_resources *pll_res); - -int hdmi_8996_v1_pll_clock_register(struct platform_device *pdev, - struct mdss_pll_resources *pll_res); - -int hdmi_8996_v2_pll_clock_register(struct platform_device *pdev, - struct mdss_pll_resources *pll_res); - -int hdmi_8996_v3_pll_clock_register(struct platform_device *pdev, - struct mdss_pll_resources *pll_res); - -int hdmi_8996_v3_1p8_pll_clock_register(struct platform_device *pdev, - struct mdss_pll_resources *pll_res); - -int hdmi_8998_pll_clock_register(struct platform_device *pdev, - struct mdss_pll_resources *pll_res); -#endif diff --git a/pll/hdmi_pll_20nm.c b/pll/hdmi_pll_20nm.c deleted file mode 100644 index 847ddf261a8b..000000000000 --- a/pll/hdmi_pll_20nm.c +++ /dev/null @@ -1,970 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "pll_drv.h" -#include "hdmi_pll.h" - -/* hdmi phy registers */ - -#define HDMI_PHY_CMD_SIZE 68 -#define HDMI_PHY_CLK_SIZE 97 - -/* Set to 1 for auto KVCO cal; set to 0 for fixed value */ -#define HDMI_PHY_AUTO_KVCO_CAL 1 - -/* PLL REGISTERS */ -#define QSERDES_COM_SYS_CLK_CTRL (0x000) -#define QSERDES_COM_PLL_VCOTAIL_EN (0x004) -#define QSERDES_COM_CMN_MODE (0x008) -#define QSERDES_COM_IE_TRIM (0x00C) -#define QSERDES_COM_IP_TRIM (0x010) -#define QSERDES_COM_PLL_CNTRL (0x014) -#define QSERDES_COM_PLL_PHSEL_CONTROL (0x018) -#define QSERDES_COM_IPTAT_TRIM_VCCA_TX_SEL (0x01C) -#define QSERDES_COM_PLL_PHSEL_DC (0x020) -#define QSERDES_COM_PLL_IP_SETI (0x024) -#define QSERDES_COM_CORE_CLK_IN_SYNC_SEL (0x028) -#define QSERDES_COM_PLL_BKG_KVCO_CAL_EN (0x02C) -#define QSERDES_COM_BIAS_EN_CLKBUFLR_EN (0x030) -#define QSERDES_COM_PLL_CP_SETI (0x034) -#define QSERDES_COM_PLL_IP_SETP (0x038) -#define QSERDES_COM_PLL_CP_SETP (0x03C) -#define QSERDES_COM_ATB_SEL1 (0x040) -#define QSERDES_COM_ATB_SEL2 (0x044) -#define QSERDES_COM_SYSCLK_EN_SEL_TXBAND (0x048) -#define QSERDES_COM_RESETSM_CNTRL (0x04C) -#define QSERDES_COM_RESETSM_CNTRL2 (0x050) -#define QSERDES_COM_RESETSM_CNTRL3 (0x054) -#define QSERDES_COM_RESETSM_PLL_CAL_COUNT1 (0x058) -#define QSERDES_COM_RESETSM_PLL_CAL_COUNT2 (0x05C) -#define QSERDES_COM_DIV_REF1 (0x060) -#define QSERDES_COM_DIV_REF2 (0x064) -#define QSERDES_COM_KVCO_COUNT1 (0x068) -#define QSERDES_COM_KVCO_COUNT2 (0x06C) -#define QSERDES_COM_KVCO_CAL_CNTRL (0x070) -#define QSERDES_COM_KVCO_CODE (0x074) -#define QSERDES_COM_VREF_CFG1 (0x078) -#define QSERDES_COM_VREF_CFG2 (0x07C) -#define QSERDES_COM_VREF_CFG3 (0x080) -#define QSERDES_COM_VREF_CFG4 (0x084) -#define QSERDES_COM_VREF_CFG5 (0x088) -#define QSERDES_COM_VREF_CFG6 (0x08C) -#define QSERDES_COM_PLLLOCK_CMP1 (0x090) -#define QSERDES_COM_PLLLOCK_CMP2 (0x094) -#define QSERDES_COM_PLLLOCK_CMP3 (0x098) -#define QSERDES_COM_PLLLOCK_CMP_EN (0x09C) -#define QSERDES_COM_BGTC (0x0A0) -#define QSERDES_COM_PLL_TEST_UPDN (0x0A4) -#define QSERDES_COM_PLL_VCO_TUNE (0x0A8) -#define QSERDES_COM_DEC_START1 (0x0AC) -#define QSERDES_COM_PLL_AMP_OS (0x0B0) -#define QSERDES_COM_SSC_EN_CENTER (0x0B4) -#define QSERDES_COM_SSC_ADJ_PER1 (0x0B8) -#define QSERDES_COM_SSC_ADJ_PER2 (0x0BC) -#define QSERDES_COM_SSC_PER1 (0x0C0) -#define QSERDES_COM_SSC_PER2 (0x0C4) -#define QSERDES_COM_SSC_STEP_SIZE1 (0x0C8) -#define QSERDES_COM_SSC_STEP_SIZE2 (0x0CC) -#define QSERDES_COM_RES_CODE_UP (0x0D0) -#define QSERDES_COM_RES_CODE_DN (0x0D4) -#define QSERDES_COM_RES_CODE_UP_OFFSET (0x0D8) -#define QSERDES_COM_RES_CODE_DN_OFFSET (0x0DC) -#define QSERDES_COM_RES_CODE_START_SEG1 (0x0E0) -#define QSERDES_COM_RES_CODE_START_SEG2 (0x0E4) -#define QSERDES_COM_RES_CODE_CAL_CSR (0x0E8) -#define QSERDES_COM_RES_CODE (0x0EC) -#define QSERDES_COM_RES_TRIM_CONTROL (0x0F0) -#define QSERDES_COM_RES_TRIM_CONTROL2 (0x0F4) -#define QSERDES_COM_RES_TRIM_EN_VCOCALDONE (0x0F8) -#define QSERDES_COM_FAUX_EN (0x0FC) -#define QSERDES_COM_DIV_FRAC_START1 (0x100) -#define QSERDES_COM_DIV_FRAC_START2 (0x104) -#define QSERDES_COM_DIV_FRAC_START3 (0x108) -#define QSERDES_COM_DEC_START2 (0x10C) -#define QSERDES_COM_PLL_RXTXEPCLK_EN (0x110) -#define QSERDES_COM_PLL_CRCTRL (0x114) -#define QSERDES_COM_PLL_CLKEPDIV (0x118) -#define QSERDES_COM_PLL_FREQUPDATE (0x11C) -#define QSERDES_COM_PLL_BKGCAL_TRIM_UP (0x120) -#define QSERDES_COM_PLL_BKGCAL_TRIM_DN (0x124) -#define QSERDES_COM_PLL_BKGCAL_TRIM_MUX (0x128) -#define QSERDES_COM_PLL_BKGCAL_VREF_CFG (0x12C) -#define QSERDES_COM_PLL_BKGCAL_DIV_REF1 (0x130) -#define QSERDES_COM_PLL_BKGCAL_DIV_REF2 (0x134) -#define QSERDES_COM_MUXADDR (0x138) -#define QSERDES_COM_LOW_POWER_RO_CONTROL (0x13C) -#define QSERDES_COM_POST_DIVIDER_CONTROL (0x140) -#define QSERDES_COM_HR_OCLK2_DIVIDER (0x144) -#define QSERDES_COM_HR_OCLK3_DIVIDER (0x148) -#define QSERDES_COM_PLL_VCO_HIGH (0x14C) -#define QSERDES_COM_RESET_SM (0x150) -#define QSERDES_COM_MUXVAL (0x154) -#define QSERDES_COM_CORE_RES_CODE_DN (0x158) -#define QSERDES_COM_CORE_RES_CODE_UP (0x15C) -#define QSERDES_COM_CORE_VCO_TUNE (0x160) -#define QSERDES_COM_CORE_VCO_TAIL (0x164) -#define QSERDES_COM_CORE_KVCO_CODE (0x168) - -/* Tx Channel 0 REGISTERS */ -#define QSERDES_TX_L0_BIST_MODE_LANENO (0x00) -#define QSERDES_TX_L0_CLKBUF_ENABLE (0x04) -#define QSERDES_TX_L0_TX_EMP_POST1_LVL (0x08) -#define QSERDES_TX_L0_TX_DRV_LVL (0x0C) -#define QSERDES_TX_L0_RESET_TSYNC_EN (0x10) -#define QSERDES_TX_L0_LPB_EN (0x14) -#define QSERDES_TX_L0_RES_CODE_UP (0x18) -#define QSERDES_TX_L0_RES_CODE_DN (0x1C) -#define QSERDES_TX_L0_PERL_LENGTH1 (0x20) -#define QSERDES_TX_L0_PERL_LENGTH2 (0x24) -#define QSERDES_TX_L0_SERDES_BYP_EN_OUT (0x28) -#define QSERDES_TX_L0_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN (0x2C) -#define QSERDES_TX_L0_PARRATE_REC_DETECT_IDLE_EN (0x30) -#define QSERDES_TX_L0_BIST_PATTERN1 (0x34) -#define QSERDES_TX_L0_BIST_PATTERN2 (0x38) -#define QSERDES_TX_L0_BIST_PATTERN3 (0x3C) -#define QSERDES_TX_L0_BIST_PATTERN4 (0x40) -#define QSERDES_TX_L0_BIST_PATTERN5 (0x44) -#define QSERDES_TX_L0_BIST_PATTERN6 (0x48) -#define QSERDES_TX_L0_BIST_PATTERN7 (0x4C) -#define QSERDES_TX_L0_BIST_PATTERN8 (0x50) -#define QSERDES_TX_L0_LANE_MODE (0x54) -#define QSERDES_TX_L0_IDAC_CAL_LANE_MODE (0x58) -#define QSERDES_TX_L0_IDAC_CAL_LANE_MODE_CONFIGURATION (0x5C) -#define QSERDES_TX_L0_ATB_SEL1 (0x60) -#define QSERDES_TX_L0_ATB_SEL2 (0x64) -#define QSERDES_TX_L0_RCV_DETECT_LVL (0x68) -#define QSERDES_TX_L0_PRBS_SEED1 (0x6C) -#define QSERDES_TX_L0_PRBS_SEED2 (0x70) -#define QSERDES_TX_L0_PRBS_SEED3 (0x74) -#define QSERDES_TX_L0_PRBS_SEED4 (0x78) -#define QSERDES_TX_L0_RESET_GEN (0x7C) -#define QSERDES_TX_L0_TRAN_DRVR_EMP_EN (0x80) -#define QSERDES_TX_L0_TX_INTERFACE_MODE (0x84) -#define QSERDES_TX_L0_PWM_CTRL (0x88) -#define QSERDES_TX_L0_PWM_DATA (0x8C) -#define QSERDES_TX_L0_PWM_ENC_DIV_CTRL (0x90) -#define QSERDES_TX_L0_VMODE_CTRL1 (0x94) -#define QSERDES_TX_L0_VMODE_CTRL2 (0x98) -#define QSERDES_TX_L0_VMODE_CTRL3 (0x9C) -#define QSERDES_TX_L0_VMODE_CTRL4 (0xA0) -#define QSERDES_TX_L0_VMODE_CTRL5 (0xA4) -#define QSERDES_TX_L0_VMODE_CTRL6 (0xA8) -#define QSERDES_TX_L0_VMODE_CTRL7 (0xAC) -#define QSERDES_TX_L0_TX_ALOG_INTF_OBSV_CNTL (0xB0) -#define QSERDES_TX_L0_BIST_STATUS (0xB4) -#define QSERDES_TX_L0_BIST_ERROR_COUNT1 (0xB8) -#define QSERDES_TX_L0_BIST_ERROR_COUNT2 (0xBC) -#define QSERDES_TX_L0_TX_ALOG_INTF_OBSV (0xC0) -#define QSERDES_TX_L0_PWM_DEC_STATUS (0xC4) - -/* Tx Channel 1 REGISTERS */ -#define QSERDES_TX_L1_BIST_MODE_LANENO (0x00) -#define QSERDES_TX_L1_CLKBUF_ENABLE (0x04) -#define QSERDES_TX_L1_TX_EMP_POST1_LVL (0x08) -#define QSERDES_TX_L1_TX_DRV_LVL (0x0C) -#define QSERDES_TX_L1_RESET_TSYNC_EN (0x10) -#define QSERDES_TX_L1_LPB_EN (0x14) -#define QSERDES_TX_L1_RES_CODE_UP (0x18) -#define QSERDES_TX_L1_RES_CODE_DN (0x1C) -#define QSERDES_TX_L1_PERL_LENGTH1 (0x20) -#define QSERDES_TX_L1_PERL_LENGTH2 (0x24) -#define QSERDES_TX_L1_SERDES_BYP_EN_OUT (0x28) -#define QSERDES_TX_L1_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN (0x2C) -#define QSERDES_TX_L1_PARRATE_REC_DETECT_IDLE_EN (0x30) -#define QSERDES_TX_L1_BIST_PATTERN1 (0x34) -#define QSERDES_TX_L1_BIST_PATTERN2 (0x38) -#define QSERDES_TX_L1_BIST_PATTERN3 (0x3C) -#define QSERDES_TX_L1_BIST_PATTERN4 (0x40) -#define QSERDES_TX_L1_BIST_PATTERN5 (0x44) -#define QSERDES_TX_L1_BIST_PATTERN6 (0x48) -#define QSERDES_TX_L1_BIST_PATTERN7 (0x4C) -#define QSERDES_TX_L1_BIST_PATTERN8 (0x50) -#define QSERDES_TX_L1_LANE_MODE (0x54) -#define QSERDES_TX_L1_IDAC_CAL_LANE_MODE (0x58) -#define QSERDES_TX_L1_IDAC_CAL_LANE_MODE_CONFIGURATION (0x5C) -#define QSERDES_TX_L1_ATB_SEL1 (0x60) -#define QSERDES_TX_L1_ATB_SEL2 (0x64) -#define QSERDES_TX_L1_RCV_DETECT_LVL (0x68) -#define QSERDES_TX_L1_PRBS_SEED1 (0x6C) -#define QSERDES_TX_L1_PRBS_SEED2 (0x70) -#define QSERDES_TX_L1_PRBS_SEED3 (0x74) -#define QSERDES_TX_L1_PRBS_SEED4 (0x78) -#define QSERDES_TX_L1_RESET_GEN (0x7C) -#define QSERDES_TX_L1_TRAN_DRVR_EMP_EN (0x80) -#define QSERDES_TX_L1_TX_INTERFACE_MODE (0x84) -#define QSERDES_TX_L1_PWM_CTRL (0x88) -#define QSERDES_TX_L1_PWM_DATA (0x8C) -#define QSERDES_TX_L1_PWM_ENC_DIV_CTRL (0x90) -#define QSERDES_TX_L1_VMODE_CTRL1 (0x94) -#define QSERDES_TX_L1_VMODE_CTRL2 (0x98) -#define QSERDES_TX_L1_VMODE_CTRL3 (0x9C) -#define QSERDES_TX_L1_VMODE_CTRL4 (0xA0) -#define QSERDES_TX_L1_VMODE_CTRL5 (0xA4) -#define QSERDES_TX_L1_VMODE_CTRL6 (0xA8) -#define QSERDES_TX_L1_VMODE_CTRL7 (0xAC) -#define QSERDES_TX_L1_TX_ALOG_INTF_OBSV_CNTL (0xB0) -#define QSERDES_TX_L1_BIST_STATUS (0xB4) -#define QSERDES_TX_L1_BIST_ERROR_COUNT1 (0xB8) -#define QSERDES_TX_L1_BIST_ERROR_COUNT2 (0xBC) -#define QSERDES_TX_L1_TX_ALOG_INTF_OBSV (0xC0) -#define QSERDES_TX_L1_PWM_DEC_STATUS (0xC4) - -/* Tx Channel 2 REGISERS */ -#define QSERDES_TX_L2_BIST_MODE_LANENO (0x00) -#define QSERDES_TX_L2_CLKBUF_ENABLE (0x04) -#define QSERDES_TX_L2_TX_EMP_POST1_LVL (0x08) -#define QSERDES_TX_L2_TX_DRV_LVL (0x0C) -#define QSERDES_TX_L2_RESET_TSYNC_EN (0x10) -#define QSERDES_TX_L2_LPB_EN (0x14) -#define QSERDES_TX_L2_RES_CODE_UP (0x18) -#define QSERDES_TX_L2_RES_CODE_DN (0x1C) -#define QSERDES_TX_L2_PERL_LENGTH1 (0x20) -#define QSERDES_TX_L2_PERL_LENGTH2 (0x24) -#define QSERDES_TX_L2_SERDES_BYP_EN_OUT (0x28) -#define QSERDES_TX_L2_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN (0x2C) -#define QSERDES_TX_L2_PARRATE_REC_DETECT_IDLE_EN (0x30) -#define QSERDES_TX_L2_BIST_PATTERN1 (0x34) -#define QSERDES_TX_L2_BIST_PATTERN2 (0x38) -#define QSERDES_TX_L2_BIST_PATTERN3 (0x3C) -#define QSERDES_TX_L2_BIST_PATTERN4 (0x40) -#define QSERDES_TX_L2_BIST_PATTERN5 (0x44) -#define QSERDES_TX_L2_BIST_PATTERN6 (0x48) -#define QSERDES_TX_L2_BIST_PATTERN7 (0x4C) -#define QSERDES_TX_L2_BIST_PATTERN8 (0x50) -#define QSERDES_TX_L2_LANE_MODE (0x54) -#define QSERDES_TX_L2_IDAC_CAL_LANE_MODE (0x58) -#define QSERDES_TX_L2_IDAC_CAL_LANE_MODE_CONFIGURATION (0x5C) -#define QSERDES_TX_L2_ATB_SEL1 (0x60) -#define QSERDES_TX_L2_ATB_SEL2 (0x64) -#define QSERDES_TX_L2_RCV_DETECT_LVL (0x68) -#define QSERDES_TX_L2_PRBS_SEED1 (0x6C) -#define QSERDES_TX_L2_PRBS_SEED2 (0x70) -#define QSERDES_TX_L2_PRBS_SEED3 (0x74) -#define QSERDES_TX_L2_PRBS_SEED4 (0x78) -#define QSERDES_TX_L2_RESET_GEN (0x7C) -#define QSERDES_TX_L2_TRAN_DRVR_EMP_EN (0x80) -#define QSERDES_TX_L2_TX_INTERFACE_MODE (0x84) -#define QSERDES_TX_L2_PWM_CTRL (0x88) -#define QSERDES_TX_L2_PWM_DATA (0x8C) -#define QSERDES_TX_L2_PWM_ENC_DIV_CTRL (0x90) -#define QSERDES_TX_L2_VMODE_CTRL1 (0x94) -#define QSERDES_TX_L2_VMODE_CTRL2 (0x98) -#define QSERDES_TX_L2_VMODE_CTRL3 (0x9C) -#define QSERDES_TX_L2_VMODE_CTRL4 (0xA0) -#define QSERDES_TX_L2_VMODE_CTRL5 (0xA4) -#define QSERDES_TX_L2_VMODE_CTRL6 (0xA8) -#define QSERDES_TX_L2_VMODE_CTRL7 (0xAC) -#define QSERDES_TX_L2_TX_ALOG_INTF_OBSV_CNTL (0xB0) -#define QSERDES_TX_L2_BIST_STATUS (0xB4) -#define QSERDES_TX_L2_BIST_ERROR_COUNT1 (0xB8) -#define QSERDES_TX_L2_BIST_ERROR_COUNT2 (0xBC) -#define QSERDES_TX_L2_TX_ALOG_INTF_OBSV (0xC0) -#define QSERDES_TX_L2_PWM_DEC_STATUS (0xC4) - -/* Tx Channel 3 REGISERS */ -#define QSERDES_TX_L3_BIST_MODE_LANENO (0x00) -#define QSERDES_TX_L3_CLKBUF_ENABLE (0x04) -#define QSERDES_TX_L3_TX_EMP_POST1_LVL (0x08) -#define QSERDES_TX_L3_TX_DRV_LVL (0x0C) -#define QSERDES_TX_L3_RESET_TSYNC_EN (0x10) -#define QSERDES_TX_L3_LPB_EN (0x14) -#define QSERDES_TX_L3_RES_CODE_UP (0x18) -#define QSERDES_TX_L3_RES_CODE_DN (0x1C) -#define QSERDES_TX_L3_PERL_LENGTH1 (0x20) -#define QSERDES_TX_L3_PERL_LENGTH2 (0x24) -#define QSERDES_TX_L3_SERDES_BYP_EN_OUT (0x28) -#define QSERDES_TX_L3_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN (0x2C) -#define QSERDES_TX_L3_PARRATE_REC_DETECT_IDLE_EN (0x30) -#define QSERDES_TX_L3_BIST_PATTERN1 (0x34) -#define QSERDES_TX_L3_BIST_PATTERN2 (0x38) -#define QSERDES_TX_L3_BIST_PATTERN3 (0x3C) -#define QSERDES_TX_L3_BIST_PATTERN4 (0x40) -#define QSERDES_TX_L3_BIST_PATTERN5 (0x44) -#define QSERDES_TX_L3_BIST_PATTERN6 (0x48) -#define QSERDES_TX_L3_BIST_PATTERN7 (0x4C) -#define QSERDES_TX_L3_BIST_PATTERN8 (0x50) -#define QSERDES_TX_L3_LANE_MODE (0x54) -#define QSERDES_TX_L3_IDAC_CAL_LANE_MODE (0x58) -#define QSERDES_TX_L3_IDAC_CAL_LANE_MODE_CONFIGURATION (0x5C) -#define QSERDES_TX_L3_ATB_SEL1 (0x60) -#define QSERDES_TX_L3_ATB_SEL2 (0x64) -#define QSERDES_TX_L3_RCV_DETECT_LVL (0x68) -#define QSERDES_TX_L3_PRBS_SEED1 (0x6C) -#define QSERDES_TX_L3_PRBS_SEED2 (0x70) -#define QSERDES_TX_L3_PRBS_SEED3 (0x74) -#define QSERDES_TX_L3_PRBS_SEED4 (0x78) -#define QSERDES_TX_L3_RESET_GEN (0x7C) -#define QSERDES_TX_L3_TRAN_DRVR_EMP_EN (0x80) -#define QSERDES_TX_L3_TX_INTERFACE_MODE (0x84) -#define QSERDES_TX_L3_PWM_CTRL (0x88) -#define QSERDES_TX_L3_PWM_DATA (0x8C) -#define QSERDES_TX_L3_PWM_ENC_DIV_CTRL (0x90) -#define QSERDES_TX_L3_VMODE_CTRL1 (0x94) -#define QSERDES_TX_L3_VMODE_CTRL2 (0x98) -#define QSERDES_TX_L3_VMODE_CTRL3 (0x9C) -#define QSERDES_TX_L3_VMODE_CTRL4 (0xA0) -#define QSERDES_TX_L3_VMODE_CTRL5 (0xA4) -#define QSERDES_TX_L3_VMODE_CTRL6 (0xA8) -#define QSERDES_TX_L3_VMODE_CTRL7 (0xAC) -#define QSERDES_TX_L3_TX_ALOG_INTF_OBSV_CNTL (0xB0) -#define QSERDES_TX_L3_BIST_STATUS (0xB4) -#define QSERDES_TX_L3_BIST_ERROR_COUNT1 (0xB8) -#define QSERDES_TX_L3_BIST_ERROR_COUNT2 (0xBC) -#define QSERDES_TX_L3_TX_ALOG_INTF_OBSV (0xC0) -#define QSERDES_TX_L3_PWM_DEC_STATUS (0xC4) - -/* HDMI PHY REGISTERS */ -#define HDMI_PHY_CFG (0x00) -#define HDMI_PHY_PD_CTL (0x04) -#define HDMI_PHY_MODE (0x08) -#define HDMI_PHY_MISR_CLEAR (0x0C) -#define HDMI_PHY_TX0_TX1_BIST_CFG0 (0x10) -#define HDMI_PHY_TX0_TX1_BIST_CFG1 (0x14) -#define HDMI_PHY_TX0_TX1_PRBS_SEED_BYTE0 (0x18) -#define HDMI_PHY_TX0_TX1_PRBS_SEED_BYTE1 (0x1C) -#define HDMI_PHY_TX0_TX1_PRBS_SEED_BYTE2 (0x20) -#define HDMI_PHY_TX0_TX1_PRBS_SEED_BYTE3 (0x24) -#define HDMI_PHY_TX0_TX1_PRBS_POLY_BYTE0 (0x28) -#define HDMI_PHY_TX0_TX1_PRBS_POLY_BYTE1 (0x2C) -#define HDMI_PHY_TX0_TX1_PRBS_POLY_BYTE2 (0x30) -#define HDMI_PHY_TX0_TX1_PRBS_POLY_BYTE3 (0x34) -#define HDMI_PHY_TX2_TX3_BIST_CFG0 (0x38) -#define HDMI_PHY_TX2_TX3_BIST_CFG1 (0x3C) -#define HDMI_PHY_TX2_TX3_PRBS_SEED_BYTE0 (0x40) -#define HDMI_PHY_TX2_TX3_PRBS_SEED_BYTE1 (0x44) -#define HDMI_PHY_TX2_TX3_PRBS_SEED_BYTE2 (0x48) -#define HDMI_PHY_TX2_TX3_PRBS_SEED_BYTE3 (0x4C) -#define HDMI_PHY_TX2_TX3_PRBS_POLY_BYTE0 (0x50) -#define HDMI_PHY_TX2_TX3_PRBS_POLY_BYTE1 (0x54) -#define HDMI_PHY_TX2_TX3_PRBS_POLY_BYTE2 (0x58) -#define HDMI_PHY_TX2_TX3_PRBS_POLY_BYTE3 (0x5C) -#define HDMI_PHY_DEBUG_BUS_SEL (0x60) -#define HDMI_PHY_TXCAL_CFG0 (0x64) -#define HDMI_PHY_TXCAL_CFG1 (0x68) -#define HDMI_PHY_TX0_TX1_BIST_STATUS0 (0x6C) -#define HDMI_PHY_TX0_TX1_BIST_STATUS1 (0x70) -#define HDMI_PHY_TX0_TX1_BIST_STATUS2 (0x74) -#define HDMI_PHY_TX2_TX3_BIST_STATUS0 (0x78) -#define HDMI_PHY_TX2_TX3_BIST_STATUS1 (0x7C) -#define HDMI_PHY_TX2_TX3_BIST_STATUS2 (0x80) -#define HDMI_PHY_PRE_MISR_STATUS0 (0x84) -#define HDMI_PHY_PRE_MISR_STATUS1 (0x88) -#define HDMI_PHY_PRE_MISR_STATUS2 (0x8C) -#define HDMI_PHY_PRE_MISR_STATUS3 (0x90) -#define HDMI_PHY_POST_MISR_STATUS0 (0x94) -#define HDMI_PHY_POST_MISR_STATUS1 (0x98) -#define HDMI_PHY_POST_MISR_STATUS2 (0x9C) -#define HDMI_PHY_POST_MISR_STATUS3 (0xA0) -#define HDMI_PHY_STATUS (0xA4) -#define HDMI_PHY_MISC3_STATUS (0xA8) -#define HDMI_PHY_DEBUG_BUS0 (0xAC) -#define HDMI_PHY_DEBUG_BUS1 (0xB0) -#define HDMI_PHY_DEBUG_BUS2 (0xB4) -#define HDMI_PHY_DEBUG_BUS3 (0xB8) -#define HDMI_PHY_REVISION_ID0 (0xBC) -#define HDMI_PHY_REVISION_ID1 (0xC0) -#define HDMI_PHY_REVISION_ID2 (0xC4) -#define HDMI_PHY_REVISION_ID3 (0xC8) - -#define HDMI_PLL_POLL_DELAY_US 50 -#define HDMI_PLL_POLL_TIMEOUT_US 125000 -#define HDMI_PLL_REF_CLK_RATE 192ULL -#define HDMI_PLL_DIVISOR 10000000000ULL -#define HDMI_PLL_DIVISOR_32 100000U -#define HDMI_PLL_MIN_VCO_CLK 160000000ULL -#define HDMI_PLL_TMDS_MAX 800000000U - - -static int hdmi_20nm_pll_lock_status(struct mdss_pll_resources *io) -{ - u32 status; - int pll_locked = 0; - int phy_ready = 0; - int rc; - - rc = mdss_pll_resource_enable(io, true); - if (rc) { - pr_err("pll resource can't be enabled\n"); - return rc; - } - - /* Poll for C_READY and PHY READY */ - pr_debug("%s: Waiting for PHY Ready\n", __func__); - - /* poll for PLL ready status */ - if (!readl_poll_timeout_atomic( - (io->pll_base + QSERDES_COM_RESET_SM), - status, ((status & BIT(6)) == 1), - HDMI_PLL_POLL_DELAY_US, - HDMI_PLL_POLL_TIMEOUT_US)) { - pr_debug("%s: C READY\n", __func__); - pll_locked = 1; - } else { - pr_debug("%s: C READY TIMEOUT\n", __func__); - pll_locked = 0; - } - - /* poll for PHY ready status */ - if (pll_locked && !readl_poll_timeout_atomic( - (io->phy_base + HDMI_PHY_STATUS), - status, ((status & BIT(0)) == 1), - HDMI_PLL_POLL_DELAY_US, - HDMI_PLL_POLL_TIMEOUT_US)) { - pr_debug("%s: PHY READY\n", __func__); - phy_ready = 1; - } else { - pr_debug("%s: PHY READY TIMEOUT\n", __func__); - phy_ready = 0; - } - mdss_pll_resource_enable(io, false); - - return phy_ready; -} - -static inline struct hdmi_pll_vco_clk *to_hdmi_20nm_vco_clk(struct clk *clk) -{ - return container_of(clk, struct hdmi_pll_vco_clk, c); -} - -static inline u32 hdmi_20nm_phy_pll_vco_reg_val(struct hdmi_pll_cfg *pll_cfg, - u32 tmds_clk) -{ - u32 index = 0; - - while (pll_cfg[index].vco_rate < HDMI_PLL_TMDS_MAX && - pll_cfg[index].vco_rate < tmds_clk) - index++; - return pll_cfg[index].reg; -} - -static void hdmi_20nm_phy_pll_calc_settings(struct mdss_pll_resources *io, - struct hdmi_pll_vco_clk *vco, u32 vco_clk, u32 tmds_clk) -{ - u32 val = 0; - u64 dec_start_val, frac_start_val, pll_lock_cmp; - - /* Calculate decimal and fractional values */ - dec_start_val = 1000000UL * vco_clk; - do_div(dec_start_val, HDMI_PLL_REF_CLK_RATE); - do_div(dec_start_val, 2U); - frac_start_val = dec_start_val; - do_div(frac_start_val, HDMI_PLL_DIVISOR_32); - do_div(frac_start_val, HDMI_PLL_DIVISOR_32); - frac_start_val *= HDMI_PLL_DIVISOR; - frac_start_val = dec_start_val - frac_start_val; - frac_start_val *= (u64)(2 << 19); - do_div(frac_start_val, HDMI_PLL_DIVISOR_32); - do_div(frac_start_val, HDMI_PLL_DIVISOR_32); - pll_lock_cmp = dec_start_val; - do_div(pll_lock_cmp, 10U); - pll_lock_cmp *= 0x800; - do_div(pll_lock_cmp, HDMI_PLL_DIVISOR_32); - do_div(pll_lock_cmp, HDMI_PLL_DIVISOR_32); - pll_lock_cmp -= 1U; - do_div(dec_start_val, HDMI_PLL_DIVISOR_32); - do_div(dec_start_val, HDMI_PLL_DIVISOR_32); - - /* PLL loop bandwidth */ - val = hdmi_20nm_phy_pll_vco_reg_val(vco->ip_seti, tmds_clk); - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_PLL_IP_SETI, val); - val = hdmi_20nm_phy_pll_vco_reg_val(vco->cp_seti, tmds_clk); - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_PLL_CP_SETI, val); - val = hdmi_20nm_phy_pll_vco_reg_val(vco->cp_setp, tmds_clk); - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_PLL_CP_SETP, val); - val = hdmi_20nm_phy_pll_vco_reg_val(vco->ip_setp, tmds_clk); - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_PLL_IP_SETP, val); - val = hdmi_20nm_phy_pll_vco_reg_val(vco->crctrl, tmds_clk); - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_PLL_CRCTRL, val); - - /* PLL calibration */ - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_DIV_FRAC_START1, - 0x80 | (frac_start_val & 0x7F)); - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_DIV_FRAC_START2, - 0x80 | ((frac_start_val >> 7) & 0x7F)); - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_DIV_FRAC_START3, - 0x40 | ((frac_start_val >> 14) & 0x3F)); - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_DEC_START1, - 0x80 | (dec_start_val & 0x7F)); - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_DEC_START2, - 0x02 | (0x01 & (dec_start_val >> 7))); - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_PLLLOCK_CMP1, - pll_lock_cmp & 0xFF); - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_PLLLOCK_CMP2, - (pll_lock_cmp >> 8) & 0xFF); - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_PLLLOCK_CMP3, - (pll_lock_cmp >> 16) & 0xFF); -} - -static u32 hdmi_20nm_phy_pll_set_clk_rate(struct clk *c, u32 tmds_clk) -{ - u32 tx_band = 0; - - struct hdmi_pll_vco_clk *vco = to_hdmi_20nm_vco_clk(c); - struct mdss_pll_resources *io = vco->priv; - u64 vco_clk = tmds_clk; - - while (vco_clk > 0 && vco_clk < HDMI_PLL_MIN_VCO_CLK) { - tx_band++; - vco_clk *= 2; - } - - /* Initially shut down PHY */ - pr_debug("%s: Disabling PHY\n", __func__); - MDSS_PLL_REG_W(io->phy_base, HDMI_PHY_PD_CTL, 0x0); - udelay(1000); - /* memory barrier */ - mb(); - - /* power-up and recommended common block settings */ - MDSS_PLL_REG_W(io->phy_base, HDMI_PHY_PD_CTL, 0x1F); - MDSS_PLL_REG_W(io->phy_base, HDMI_PHY_CFG, 0x01); - udelay(1000); - /* memory barrier */ - mb(); - - MDSS_PLL_REG_W(io->phy_base, HDMI_PHY_CFG, 0x07); - udelay(1000); - /* memory barrier */ - mb(); - - MDSS_PLL_REG_W(io->phy_base, HDMI_PHY_CFG, 0x05); - udelay(1000); - /* memory barrier */ - mb(); - - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_SYS_CLK_CTRL, 0x42); - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_PLL_VCOTAIL_EN, 0x03); - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_CMN_MODE, 0x00); - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_IE_TRIM, 0x00); - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_IP_TRIM, 0x00); - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_PLL_CNTRL, 0x07); - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_PLL_PHSEL_CONTROL, 0x04); - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_IPTAT_TRIM_VCCA_TX_SEL, 0xA0); - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_PLL_PHSEL_DC, 0x00); - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_CORE_CLK_IN_SYNC_SEL, 0x00); - - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_PLL_BKG_KVCO_CAL_EN, 0x00); - - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x0F); - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_ATB_SEL1, 0x01); - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_ATB_SEL2, 0x01); - - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_SYSCLK_EN_SEL_TXBAND, - 0x4A + (0x10 * tx_band)); - - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_VREF_CFG1, 0x00); - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_VREF_CFG2, 0x00); - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_BGTC, 0xFF); - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_PLL_TEST_UPDN, 0x00); - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_PLL_VCO_TUNE, 0x00); - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_PLL_AMP_OS, 0x00); - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_SSC_EN_CENTER, 0x00); - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_RES_CODE_UP, 0x00); - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_RES_CODE_DN, 0x00); - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_KVCO_CODE, - tmds_clk > 300000000 ? 0x3F : 0x00); - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_KVCO_COUNT1, - tmds_clk > 300000000 ? 0x00 : 0x8A); - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_DIV_REF1, 0x00); - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_DIV_REF2, - tmds_clk > 300000000 ? 0x00 : 0x01); - - - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_KVCO_CAL_CNTRL, - tmds_clk > 300000000 ? 0x00 : 0x1F); - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_VREF_CFG3, - tmds_clk > 300000000 ? 0x00 : 0x40); - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_VREF_CFG4, 0x00); - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_VREF_CFG5, 0x10); - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_RESETSM_CNTRL, - tmds_clk > 300000000 ? 0x80 : 0x00); - - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_RES_CODE_CAL_CSR, 0x77); - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_RES_TRIM_EN_VCOCALDONE, 0x00); - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_PLL_RXTXEPCLK_EN, 0x0C); - - hdmi_20nm_phy_pll_calc_settings(io, vco, vco_clk, tmds_clk); - - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_PLLLOCK_CMP_EN, 0x11); - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_PLL_CNTRL, 0x07); - - /* Resistor calibration linear search */ - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_RES_CODE_START_SEG1, 0x60); - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_RES_CODE_START_SEG2, 0x60); - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_RES_TRIM_CONTROL, 0x01); - - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_RESETSM_CNTRL2, 0x07); - - udelay(1000); - /* memory barrier */ - mb(); - - MDSS_PLL_REG_W(io->phy_base, HDMI_PHY_MODE, tx_band); - - /* TX lanes (transceivers) power-up sequence */ - MDSS_PLL_REG_W(io->pll_base + 0x400, QSERDES_TX_L0_CLKBUF_ENABLE, 0x03); - MDSS_PLL_REG_W(io->pll_base + 0x600, QSERDES_TX_L1_CLKBUF_ENABLE, 0x03); - MDSS_PLL_REG_W(io->pll_base + 0x800, QSERDES_TX_L2_CLKBUF_ENABLE, 0x03); - MDSS_PLL_REG_W(io->pll_base + 0xA00, QSERDES_TX_L3_CLKBUF_ENABLE, 0x03); - - MDSS_PLL_REG_W(io->pll_base + 0x400, - QSERDES_TX_L0_TRAN_DRVR_EMP_EN, 0x03); - MDSS_PLL_REG_W(io->pll_base + 0x600, - QSERDES_TX_L1_TRAN_DRVR_EMP_EN, 0x03); - MDSS_PLL_REG_W(io->pll_base + 0x800, - QSERDES_TX_L2_TRAN_DRVR_EMP_EN, 0x03); - MDSS_PLL_REG_W(io->pll_base + 0xA00, - QSERDES_TX_L3_TRAN_DRVR_EMP_EN, 0x03); - - MDSS_PLL_REG_W(io->pll_base + 0x400, - QSERDES_TX_L0_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN, 0x6F); - MDSS_PLL_REG_W(io->pll_base + 0x600, - QSERDES_TX_L1_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN, 0x6F); - MDSS_PLL_REG_W(io->pll_base + 0x800, - QSERDES_TX_L2_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN, 0x6F); - MDSS_PLL_REG_W(io->pll_base + 0xA00, - QSERDES_TX_L3_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN, 0x6F); - - MDSS_PLL_REG_W(io->pll_base + 0x400, - QSERDES_TX_L0_TX_EMP_POST1_LVL, 0x0000002F); - MDSS_PLL_REG_W(io->phy_base, HDMI_PHY_TXCAL_CFG0, 0x000000AF); - - MDSS_PLL_REG_W(io->pll_base + 0x400, QSERDES_TX_L0_VMODE_CTRL1, 0x08); - MDSS_PLL_REG_W(io->pll_base + 0x800, QSERDES_TX_L2_VMODE_CTRL1, 0x09); - MDSS_PLL_REG_W(io->pll_base + 0x400, QSERDES_TX_L0_VMODE_CTRL5, 0xA0); - MDSS_PLL_REG_W(io->pll_base + 0x400, QSERDES_TX_L0_VMODE_CTRL6, 0x01); - MDSS_PLL_REG_W(io->pll_base + 0x800, QSERDES_TX_L2_VMODE_CTRL5, 0xA0); - MDSS_PLL_REG_W(io->pll_base + 0x800, QSERDES_TX_L2_VMODE_CTRL6, 0x01); - - MDSS_PLL_REG_W(io->pll_base + 0x400, - QSERDES_TX_L0_PARRATE_REC_DETECT_IDLE_EN, 0x40); - MDSS_PLL_REG_W(io->pll_base + 0x400, - QSERDES_TX_L0_TX_INTERFACE_MODE, 0x00); - MDSS_PLL_REG_W(io->pll_base + 0x600, - QSERDES_TX_L1_PARRATE_REC_DETECT_IDLE_EN, 0x40); - MDSS_PLL_REG_W(io->pll_base + 0x600, - QSERDES_TX_L1_TX_INTERFACE_MODE, 0x00); - MDSS_PLL_REG_W(io->pll_base + 0x800, - QSERDES_TX_L2_PARRATE_REC_DETECT_IDLE_EN, 0x40); - MDSS_PLL_REG_W(io->pll_base + 0x800, - QSERDES_TX_L2_TX_INTERFACE_MODE, 0x00); - MDSS_PLL_REG_W(io->pll_base + 0xA00, - QSERDES_TX_L3_PARRATE_REC_DETECT_IDLE_EN, 0x40); - MDSS_PLL_REG_W(io->pll_base + 0xA00, - QSERDES_TX_L3_TX_INTERFACE_MODE, 0x00); - - return 0; -} - -static int hdmi_20nm_vco_enable(struct clk *c) -{ - u32 ready_poll; - u32 time_out_loop; - /* Hardware recommended timeout iterator */ - u32 time_out_max = 50000; - - struct hdmi_pll_vco_clk *vco = to_hdmi_20nm_vco_clk(c); - struct mdss_pll_resources *io = vco->priv; - - MDSS_PLL_REG_W(io->phy_base, HDMI_PHY_CFG, 0x00000000); - udelay(100); - /* memory barrier */ - mb(); - MDSS_PLL_REG_W(io->phy_base, HDMI_PHY_CFG, 0x00000003); - udelay(100); - /* memory barrier */ - mb(); - MDSS_PLL_REG_W(io->phy_base, HDMI_PHY_CFG, 0x00000009); - udelay(100); - /* memory barrier */ - mb(); - - /* Poll for C_READY and PHY READY */ - pr_debug("%s: Waiting for PHY Ready\n", __func__); - time_out_loop = 0; - do { - ready_poll = MDSS_PLL_REG_R(io->pll_base, QSERDES_COM_RESET_SM); - time_out_loop++; - udelay(10); - } while (((ready_poll & (1 << 6)) == 0) && - (time_out_loop < time_out_max)); - if (time_out_loop >= time_out_max) - pr_err("%s: ERROR: TIMED OUT BEFORE C READY\n", __func__); - else - pr_debug("%s: C READY\n", __func__); - - /* Poll for PHY READY */ - pr_debug("%s: Waiting for PHY Ready\n", __func__); - time_out_loop = 0; - do { - ready_poll = MDSS_PLL_REG_R(io->phy_base, HDMI_PHY_STATUS); - time_out_loop++; - udelay(1); - } while (((ready_poll & 0x1) == 0) && (time_out_loop < time_out_max)); - - if (time_out_loop >= time_out_max) - pr_err("%s: TIMED OUT BEFORE PHY READY\n", __func__); - else - pr_debug("%s: HDMI PHY READY\n", __func__); - - io->pll_on = true; - - return 0; -} - - -static int hdmi_20nm_vco_set_rate(struct clk *c, unsigned long rate) -{ - struct hdmi_pll_vco_clk *vco = to_hdmi_20nm_vco_clk(c); - struct mdss_pll_resources *io = vco->priv; - void __iomem *pll_base; - void __iomem *phy_base; - unsigned int set_power_dwn = 0; - int rc; - - rc = mdss_pll_resource_enable(io, true); - if (rc) { - pr_err("pll resource can't be enabled\n"); - return rc; - } - - if (io->pll_on) - set_power_dwn = 1; - - pll_base = io->pll_base; - phy_base = io->phy_base; - - pr_debug("rate=%ld\n", rate); - - hdmi_20nm_phy_pll_set_clk_rate(c, rate); - - mdss_pll_resource_enable(io, false); - - if (set_power_dwn) - hdmi_20nm_vco_enable(c); - - vco->rate = rate; - vco->rate_set = true; - - return 0; -} - -static unsigned long hdmi_20nm_vco_get_rate(struct clk *c) -{ - unsigned long freq = 0; - int rc; - struct hdmi_pll_vco_clk *vco = to_hdmi_20nm_vco_clk(c); - struct mdss_pll_resources *io = vco->priv; - - if (is_gdsc_disabled(io)) - return 0; - - rc = mdss_pll_resource_enable(io, true); - if (rc) { - pr_err("pll resource can't be enabled\n"); - return rc; - } - - mdss_pll_resource_enable(io, false); - - return freq; -} - -static long hdmi_20nm_vco_round_rate(struct clk *c, unsigned long rate) -{ - unsigned long rrate = rate; - - pr_debug("rrate=%ld\n", rrate); - - return rrate; -} - -static int hdmi_20nm_vco_prepare(struct clk *c) -{ - struct hdmi_pll_vco_clk *vco = to_hdmi_20nm_vco_clk(c); - struct mdss_pll_resources *io = vco->priv; - int ret = 0; - - pr_debug("rate=%ld\n", vco->rate); - - if (!vco->rate_set && vco->rate) - ret = hdmi_20nm_vco_set_rate(c, vco->rate); - - if (!ret) { - ret = mdss_pll_resource_enable(io, true); - if (ret) - pr_err("pll resource can't be enabled\n"); - } - - return ret; -} - -static void hdmi_20nm_vco_unprepare(struct clk *c) -{ - struct hdmi_pll_vco_clk *vco = to_hdmi_20nm_vco_clk(c); - struct mdss_pll_resources *io = vco->priv; - - vco->rate_set = false; - - if (!io) { - pr_err("Invalid input parameter\n"); - return; - } - - if (!io->pll_on && - mdss_pll_resource_enable(io, true)) { - pr_err("pll resource can't be enabled\n"); - return; - } - - io->handoff_resources = false; - mdss_pll_resource_enable(io, false); - io->pll_on = false; -} - -static enum handoff hdmi_20nm_vco_handoff(struct clk *c) -{ - enum handoff ret = HANDOFF_DISABLED_CLK; - struct hdmi_pll_vco_clk *vco = to_hdmi_20nm_vco_clk(c); - struct mdss_pll_resources *io = vco->priv; - - if (is_gdsc_disabled(io)) - return HANDOFF_DISABLED_CLK; - - if (mdss_pll_resource_enable(io, true)) { - pr_err("pll resource can't be enabled\n"); - return ret; - } - - io->handoff_resources = true; - - if (hdmi_20nm_pll_lock_status(io)) { - io->pll_on = true; - c->rate = hdmi_20nm_vco_get_rate(c); - ret = HANDOFF_ENABLED_CLK; - } else { - io->handoff_resources = false; - mdss_pll_resource_enable(io, false); - } - - pr_debug("done, ret=%d\n", ret); - return ret; -} - -static const struct clk_ops hdmi_20nm_vco_clk_ops = { - .enable = hdmi_20nm_vco_enable, - .set_rate = hdmi_20nm_vco_set_rate, - .get_rate = hdmi_20nm_vco_get_rate, - .round_rate = hdmi_20nm_vco_round_rate, - .prepare = hdmi_20nm_vco_prepare, - .unprepare = hdmi_20nm_vco_unprepare, - .handoff = hdmi_20nm_vco_handoff, -}; - -static struct hdmi_pll_vco_clk hdmi_20nm_vco_clk = { - .ip_seti = (struct hdmi_pll_cfg[]){ - {550890000, 0x03}, - {589240000, 0x07}, - {689290000, 0x03}, - {727600000, 0x07}, - {HDMI_PLL_TMDS_MAX, 0x03}, - }, - .cp_seti = (struct hdmi_pll_cfg[]){ - {34440000, 0x3F}, - {36830000, 0x2F}, - {68870000, 0x3F}, - {73660000, 0x2F}, - {137730000, 0x3F}, - {147310000, 0x2F}, - {275450000, 0x3F}, - {294620000, 0x2F}, - {344650000, 0x3F}, - {363800000, 0x2F}, - {477960000, 0x3F}, - {512530000, 0x2F}, - {550890000, 0x1F}, - {589240000, 0x2F}, - {630900000, 0x3F}, - {650590000, 0x2F}, - {689290000, 0x1F}, - {727600000, 0x2F}, - {HDMI_PLL_TMDS_MAX, 0x3F}, - }, - .ip_setp = (struct hdmi_pll_cfg[]){ - {497340000, 0x03}, - {512530000, 0x07}, - {535680000, 0x03}, - {550890000, 0x07}, - {574060000, 0x03}, - {727600000, 0x07}, - {HDMI_PLL_TMDS_MAX, 0x03}, - }, - .cp_setp = (struct hdmi_pll_cfg[]){ - {36830000, 0x1F}, - {40010000, 0x17}, - {73660000, 0x1F}, - {80000000, 0x17}, - {147310000, 0x1F}, - {160010000, 0x17}, - {294620000, 0x1F}, - {363800000, 0x17}, - {497340000, 0x0F}, - {512530000, 0x1F}, - {535680000, 0x0F}, - {550890000, 0x1F}, - {574060000, 0x0F}, - {589240000, 0x1F}, - {727600000, 0x17}, - {HDMI_PLL_TMDS_MAX, 0x07}, - }, - .crctrl = (struct hdmi_pll_cfg[]){ - {40010000, 0xBB}, - {40030000, 0x77}, - {80000000, 0xBB}, - {80060000, 0x77}, - {160010000, 0xBB}, - {160120000, 0x77}, - {772930000, 0xBB}, - {HDMI_PLL_TMDS_MAX, 0xFF}, - }, - .c = { - .dbg_name = "hdmi_20nm_vco_clk", - .ops = &hdmi_20nm_vco_clk_ops, - CLK_INIT(hdmi_20nm_vco_clk.c), - }, -}; - -static struct clk_lookup hdmipllcc_8994[] = { - CLK_LIST(hdmi_20nm_vco_clk), -}; - -int hdmi_20nm_pll_clock_register(struct platform_device *pdev, - struct mdss_pll_resources *pll_res) -{ - int rc = -ENOTSUPP; - - /* Set client data for vco, mux and div clocks */ - hdmi_20nm_vco_clk.priv = pll_res; - - rc = of_msm_clock_register(pdev->dev.of_node, hdmipllcc_8994, - ARRAY_SIZE(hdmipllcc_8994)); - if (rc) { - pr_err("Clock register failed rc=%d\n", rc); - rc = -EPROBE_DEFER; - } else { - pr_debug("%s: SUCCESS\n", __func__); - } - - return rc; -} diff --git a/pll/hdmi_pll_28hpm.c b/pll/hdmi_pll_28hpm.c deleted file mode 100644 index 962a4cec4984..000000000000 --- a/pll/hdmi_pll_28hpm.c +++ /dev/null @@ -1,1091 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. - */ - -#define pr_fmt(fmt) "%s: " fmt, __func__ - -#include -#include -#include -#include -#include -#include -#include - -#include "pll_drv.h" -#include "hdmi_pll.h" - -/* hdmi phy registers */ -#define HDMI_PHY_ANA_CFG0 (0x0000) -#define HDMI_PHY_ANA_CFG1 (0x0004) -#define HDMI_PHY_ANA_CFG2 (0x0008) -#define HDMI_PHY_ANA_CFG3 (0x000C) -#define HDMI_PHY_PD_CTRL0 (0x0010) -#define HDMI_PHY_PD_CTRL1 (0x0014) -#define HDMI_PHY_GLB_CFG (0x0018) -#define HDMI_PHY_DCC_CFG0 (0x001C) -#define HDMI_PHY_DCC_CFG1 (0x0020) -#define HDMI_PHY_TXCAL_CFG0 (0x0024) -#define HDMI_PHY_TXCAL_CFG1 (0x0028) -#define HDMI_PHY_TXCAL_CFG2 (0x002C) -#define HDMI_PHY_TXCAL_CFG3 (0x0030) -#define HDMI_PHY_BIST_CFG0 (0x0034) -#define HDMI_PHY_BIST_CFG1 (0x0038) -#define HDMI_PHY_BIST_PATN0 (0x003C) -#define HDMI_PHY_BIST_PATN1 (0x0040) -#define HDMI_PHY_BIST_PATN2 (0x0044) -#define HDMI_PHY_BIST_PATN3 (0x0048) -#define HDMI_PHY_STATUS (0x005C) - -/* hdmi phy unified pll registers */ -#define HDMI_UNI_PLL_REFCLK_CFG (0x0000) -#define HDMI_UNI_PLL_POSTDIV1_CFG (0x0004) -#define HDMI_UNI_PLL_CHFPUMP_CFG (0x0008) -#define HDMI_UNI_PLL_VCOLPF_CFG (0x000C) -#define HDMI_UNI_PLL_VREG_CFG (0x0010) -#define HDMI_UNI_PLL_PWRGEN_CFG (0x0014) -#define HDMI_UNI_PLL_GLB_CFG (0x0020) -#define HDMI_UNI_PLL_POSTDIV2_CFG (0x0024) -#define HDMI_UNI_PLL_POSTDIV3_CFG (0x0028) -#define HDMI_UNI_PLL_LPFR_CFG (0x002C) -#define HDMI_UNI_PLL_LPFC1_CFG (0x0030) -#define HDMI_UNI_PLL_LPFC2_CFG (0x0034) -#define HDMI_UNI_PLL_SDM_CFG0 (0x0038) -#define HDMI_UNI_PLL_SDM_CFG1 (0x003C) -#define HDMI_UNI_PLL_SDM_CFG2 (0x0040) -#define HDMI_UNI_PLL_SDM_CFG3 (0x0044) -#define HDMI_UNI_PLL_SDM_CFG4 (0x0048) -#define HDMI_UNI_PLL_SSC_CFG0 (0x004C) -#define HDMI_UNI_PLL_SSC_CFG1 (0x0050) -#define HDMI_UNI_PLL_SSC_CFG2 (0x0054) -#define HDMI_UNI_PLL_SSC_CFG3 (0x0058) -#define HDMI_UNI_PLL_LKDET_CFG0 (0x005C) -#define HDMI_UNI_PLL_LKDET_CFG1 (0x0060) -#define HDMI_UNI_PLL_LKDET_CFG2 (0x0064) -#define HDMI_UNI_PLL_CAL_CFG0 (0x006C) -#define HDMI_UNI_PLL_CAL_CFG1 (0x0070) -#define HDMI_UNI_PLL_CAL_CFG2 (0x0074) -#define HDMI_UNI_PLL_CAL_CFG3 (0x0078) -#define HDMI_UNI_PLL_CAL_CFG4 (0x007C) -#define HDMI_UNI_PLL_CAL_CFG5 (0x0080) -#define HDMI_UNI_PLL_CAL_CFG6 (0x0084) -#define HDMI_UNI_PLL_CAL_CFG7 (0x0088) -#define HDMI_UNI_PLL_CAL_CFG8 (0x008C) -#define HDMI_UNI_PLL_CAL_CFG9 (0x0090) -#define HDMI_UNI_PLL_CAL_CFG10 (0x0094) -#define HDMI_UNI_PLL_CAL_CFG11 (0x0098) -#define HDMI_UNI_PLL_STATUS (0x00C0) - -#define HDMI_PLL_POLL_DELAY_US 50 -#define HDMI_PLL_POLL_TIMEOUT_US 500 - -static inline struct hdmi_pll_vco_clk *to_hdmi_vco_clk(struct clk *clk) -{ - return container_of(clk, struct hdmi_pll_vco_clk, c); -} - -static void hdmi_vco_disable(struct clk *c) -{ - struct hdmi_pll_vco_clk *vco = to_hdmi_vco_clk(c); - struct mdss_pll_resources *hdmi_pll_res = vco->priv; - - if (!hdmi_pll_res) { - pr_err("Invalid input parameter\n"); - return; - } - - if (!hdmi_pll_res->pll_on && - mdss_pll_resource_enable(hdmi_pll_res, true)) { - pr_err("pll resource can't be enabled\n"); - return; - } - - MDSS_PLL_REG_W(hdmi_pll_res->pll_base, HDMI_UNI_PLL_GLB_CFG, 0x0); - udelay(5); - MDSS_PLL_REG_W(hdmi_pll_res->phy_base, HDMI_PHY_GLB_CFG, 0x0); - - hdmi_pll_res->handoff_resources = false; - mdss_pll_resource_enable(hdmi_pll_res, false); - hdmi_pll_res->pll_on = false; -} /* hdmi_vco_disable */ - -static int hdmi_vco_enable(struct clk *c) -{ - u32 status; - u32 delay_us, timeout_us; - int rc; - struct hdmi_pll_vco_clk *vco = to_hdmi_vco_clk(c); - struct mdss_pll_resources *hdmi_pll_res = vco->priv; - - rc = mdss_pll_resource_enable(hdmi_pll_res, true); - if (rc) { - pr_err("pll resource can't be enabled\n"); - return rc; - } - - /* Global Enable */ - MDSS_PLL_REG_W(hdmi_pll_res->phy_base, HDMI_PHY_GLB_CFG, 0x81); - /* Power up power gen */ - MDSS_PLL_REG_W(hdmi_pll_res->phy_base, HDMI_PHY_PD_CTRL0, 0x00); - udelay(350); - - /* PLL Power-Up */ - MDSS_PLL_REG_W(hdmi_pll_res->pll_base, HDMI_UNI_PLL_GLB_CFG, 0x01); - udelay(5); - /* Power up PLL LDO */ - MDSS_PLL_REG_W(hdmi_pll_res->pll_base, HDMI_UNI_PLL_GLB_CFG, 0x03); - udelay(350); - - /* PLL Power-Up */ - MDSS_PLL_REG_W(hdmi_pll_res->pll_base, HDMI_UNI_PLL_GLB_CFG, 0x0F); - udelay(350); - - /* poll for PLL ready status */ - delay_us = 100; - timeout_us = 2000; - if (readl_poll_timeout_atomic( - (hdmi_pll_res->pll_base + HDMI_UNI_PLL_STATUS), - status, ((status & BIT(0)) == 1), delay_us, timeout_us)) { - pr_err("hdmi phy pll status=%x failed to Lock\n", status); - hdmi_vco_disable(c); - mdss_pll_resource_enable(hdmi_pll_res, false); - return -EINVAL; - } - pr_debug("hdmi phy pll is locked\n"); - - udelay(350); - /* poll for PHY ready status */ - delay_us = 100; - timeout_us = 2000; - if (readl_poll_timeout_atomic( - (hdmi_pll_res->phy_base + HDMI_PHY_STATUS), - status, ((status & BIT(0)) == 1), delay_us, timeout_us)) { - pr_err("hdmi phy status=%x failed to Lock\n", status); - hdmi_vco_disable(c); - mdss_pll_resource_enable(hdmi_pll_res, false); - return -EINVAL; - } - hdmi_pll_res->pll_on = true; - pr_debug("hdmi phy is locked\n"); - - return 0; -} /* hdmi_vco_enable */ - - -static void hdmi_phy_pll_calculator(u32 vco_freq, - struct mdss_pll_resources *hdmi_pll_res) -{ - u32 ref_clk = 19200000; - u32 sdm_mode = 1; - u32 ref_clk_multiplier = sdm_mode == 1 ? 2 : 1; - u32 int_ref_clk_freq = ref_clk * ref_clk_multiplier; - u32 fbclk_pre_div = 1; - u32 ssc_mode = 0; - u32 kvco = 270; - u32 vdd = 95; - u32 ten_power_six = 1000000; - u32 ssc_ds_ppm = ssc_mode ? 5000 : 0; - u32 sdm_res = 16; - u32 ssc_tri_step = 32; - u32 ssc_freq = 2; - u64 ssc_ds = vco_freq * ssc_ds_ppm; - u32 div_in_freq = vco_freq / fbclk_pre_div; - u64 dc_offset = (div_in_freq / int_ref_clk_freq - 1) * - ten_power_six * 10; - u32 ssc_kdiv = (int_ref_clk_freq / ssc_freq) - - ten_power_six; - u64 sdm_freq_seed; - u32 ssc_tri_inc; - u64 fb_div_n; - void __iomem *pll_base = hdmi_pll_res->pll_base; - u32 val; - - pr_debug("vco_freq = %u\n", vco_freq); - - do_div(ssc_ds, (u64)ten_power_six); - - fb_div_n = (u64)div_in_freq * (u64)ten_power_six * 10; - do_div(fb_div_n, int_ref_clk_freq); - - sdm_freq_seed = ((fb_div_n - dc_offset - ten_power_six * 10) * - (1 << sdm_res) * 10) + 5; - do_div(sdm_freq_seed, ((u64)ten_power_six * 100)); - - ssc_tri_inc = (u32)ssc_ds; - ssc_tri_inc = (ssc_tri_inc / int_ref_clk_freq) * (1 << 16) / - ssc_tri_step; - - val = (ref_clk_multiplier == 2 ? 1 : 0) + - ((fbclk_pre_div == 2 ? 1 : 0) * 16); - pr_debug("HDMI_UNI_PLL_REFCLK_CFG = 0x%x\n", val); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_REFCLK_CFG, val); - - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_CHFPUMP_CFG, 0x02); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_VCOLPF_CFG, 0x19); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_VREG_CFG, 0x04); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_PWRGEN_CFG, 0x00); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_POSTDIV2_CFG, 0x00); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_POSTDIV3_CFG, 0x00); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_LPFR_CFG, 0x0E); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_LPFC1_CFG, 0x20); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_LPFC2_CFG, 0x0D); - - do_div(dc_offset, (u64)ten_power_six * 10); - val = sdm_mode == 0 ? 64 + dc_offset : 0; - pr_debug("HDMI_UNI_PLL_SDM_CFG0 = 0x%x\n", val); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_SDM_CFG0, val); - - val = 64 + dc_offset; - pr_debug("HDMI_UNI_PLL_SDM_CFG1 = 0x%x\n", val); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_SDM_CFG1, val); - - val = sdm_freq_seed & 0xFF; - pr_debug("HDMI_UNI_PLL_SDM_CFG2 = 0x%x\n", val); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_SDM_CFG2, val); - - val = (sdm_freq_seed >> 8) & 0xFF; - pr_debug("HDMI_UNI_PLL_SDM_CFG3 = 0x%x\n", val); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_SDM_CFG3, val); - - val = (sdm_freq_seed >> 16) & 0xFF; - pr_debug("HDMI_UNI_PLL_SDM_CFG4 = 0x%x\n", val); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_SDM_CFG4, val); - - val = (ssc_mode == 0 ? 128 : 0) + (ssc_kdiv / ten_power_six); - pr_debug("HDMI_UNI_PLL_SSC_CFG0 = 0x%x\n", val); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_SSC_CFG0, val); - - val = ssc_tri_inc & 0xFF; - pr_debug("HDMI_UNI_PLL_SSC_CFG1 = 0x%x\n", val); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_SSC_CFG1, val); - - val = (ssc_tri_inc >> 8) & 0xFF; - pr_debug("HDMI_UNI_PLL_SSC_CFG2 = 0x%x\n", val); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_SSC_CFG2, val); - - pr_debug("HDMI_UNI_PLL_SSC_CFG3 = 0x%x\n", ssc_tri_step); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_SSC_CFG3, ssc_tri_step); - - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_LKDET_CFG0, 0x10); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_LKDET_CFG1, 0x1A); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_LKDET_CFG2, 0x05); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_CAL_CFG0, 0x0A); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_CAL_CFG1, 0x04); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_CAL_CFG2, 0x01); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_CAL_CFG3, 0x00); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_CAL_CFG4, 0x00); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_CAL_CFG5, 0x00); - - val = (kvco * vdd * 10000) / 6; - val += 500000; - val /= ten_power_six; - pr_debug("HDMI_UNI_PLL_CAL_CFG6 = 0x%x\n", val); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_CAL_CFG6, val & 0xFF); - - val = (kvco * vdd * 10000) / 6; - val -= ten_power_six; - val /= ten_power_six; - val = (val >> 8) & 0xFF; - pr_debug("HDMI_UNI_PLL_CAL_CFG7 = 0x%x\n", val); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_CAL_CFG7, val); - - val = (ref_clk * 5) / ten_power_six; - pr_debug("HDMI_UNI_PLL_CAL_CFG8 = 0x%x\n", val); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_CAL_CFG8, val); - - val = ((ref_clk * 5) / ten_power_six) >> 8; - pr_debug("HDMI_UNI_PLL_CAL_CFG9 = 0x%x\n", val); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_CAL_CFG9, val); - - vco_freq /= ten_power_six; - val = vco_freq & 0xFF; - pr_debug("HDMI_UNI_PLL_CAL_CFG10 = 0x%x\n", val); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_CAL_CFG10, val); - - val = vco_freq >> 8; - pr_debug("HDMI_UNI_PLL_CAL_CFG11 = 0x%x\n", val); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_CAL_CFG11, val); -} /* hdmi_phy_pll_calculator */ - -static int hdmi_vco_set_rate(struct clk *c, unsigned long rate) -{ - struct hdmi_pll_vco_clk *vco = to_hdmi_vco_clk(c); - struct mdss_pll_resources *hdmi_pll_res = vco->priv; - void __iomem *pll_base; - void __iomem *phy_base; - unsigned int set_power_dwn = 0; - int rc; - - rc = mdss_pll_resource_enable(hdmi_pll_res, true); - if (rc) { - pr_err("pll resource can't be enabled\n"); - return rc; - } - - if (hdmi_pll_res->pll_on) { - hdmi_vco_disable(c); - set_power_dwn = 1; - } - - pll_base = hdmi_pll_res->pll_base; - phy_base = hdmi_pll_res->phy_base; - - pr_debug("rate=%ld\n", rate); - - switch (rate) { - case 0: - break; - - case 756000000: - /* 640x480p60 */ - MDSS_PLL_REG_W(phy_base, HDMI_PHY_GLB_CFG, 0x81); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_GLB_CFG, 0x01); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_REFCLK_CFG, 0x01); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_VCOLPF_CFG, 0x19); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_LPFR_CFG, 0x0E); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_LPFC1_CFG, 0x20); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_LPFC2_CFG, 0x0D); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_SDM_CFG0, 0x00); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_SDM_CFG1, 0x52); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_SDM_CFG2, 0x00); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_SDM_CFG3, 0xB0); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_SDM_CFG4, 0x00); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_LKDET_CFG0, 0x10); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_LKDET_CFG1, 0x1A); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_LKDET_CFG2, 0x05); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_POSTDIV2_CFG, 0x00); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_POSTDIV3_CFG, 0x00); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_CAL_CFG2, 0x01); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_CAL_CFG8, 0x60); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_CAL_CFG9, 0x00); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_CAL_CFG10, 0xF4); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_CAL_CFG11, 0x02); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_PD_CTRL0, 0x1F); - udelay(50); - - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_GLB_CFG, 0x0F); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_PD_CTRL1, 0x00); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_ANA_CFG2, 0x10); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_ANA_CFG0, 0xDB); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_ANA_CFG1, 0x43); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_ANA_CFG2, 0x02); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_ANA_CFG3, 0x00); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_VREG_CFG, 0x04); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_DCC_CFG0, 0xD0); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_DCC_CFG1, 0x1A); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_TXCAL_CFG0, 0x00); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_TXCAL_CFG1, 0x00); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_TXCAL_CFG2, 0x02); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_TXCAL_CFG3, 0x05); - udelay(200); - break; - - case 810000000: - /* 576p50/576i50 case */ - MDSS_PLL_REG_W(phy_base, HDMI_PHY_GLB_CFG, 0x81); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_GLB_CFG, 0x01); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_REFCLK_CFG, 0x01); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_VCOLPF_CFG, 0x19); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_LPFR_CFG, 0x0E); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_LPFC1_CFG, 0x20); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_LPFC2_CFG, 0x0D); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_SDM_CFG0, 0x00); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_SDM_CFG1, 0x54); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_SDM_CFG2, 0x00); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_SDM_CFG3, 0x18); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_SDM_CFG4, 0x00); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_LKDET_CFG0, 0x10); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_LKDET_CFG1, 0x1A); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_LKDET_CFG2, 0x05); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_POSTDIV2_CFG, 0x00); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_POSTDIV3_CFG, 0x00); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_CAL_CFG2, 0x01); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_CAL_CFG8, 0x60); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_CAL_CFG9, 0x00); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_CAL_CFG10, 0x2A); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_CAL_CFG11, 0x03); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_PD_CTRL0, 0x1F); - udelay(50); - - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_GLB_CFG, 0x0F); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_PD_CTRL1, 0x00); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_ANA_CFG2, 0x10); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_ANA_CFG0, 0xDB); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_ANA_CFG1, 0x43); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_ANA_CFG2, 0x02); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_ANA_CFG3, 0x00); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_VREG_CFG, 0x04); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_DCC_CFG0, 0xD0); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_DCC_CFG1, 0x1A); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_TXCAL_CFG0, 0x00); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_TXCAL_CFG1, 0x00); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_TXCAL_CFG2, 0x02); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_TXCAL_CFG3, 0x05); - udelay(200); - break; - - case 810900000: - /* 480p60/480i60 case */ - MDSS_PLL_REG_W(phy_base, HDMI_PHY_GLB_CFG, 0x81); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_GLB_CFG, 0x01); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_REFCLK_CFG, 0x01); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_VCOLPF_CFG, 0x19); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_LPFR_CFG, 0x0E); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_LPFC1_CFG, 0x20); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_LPFC2_CFG, 0x0D); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_SDM_CFG0, 0x00); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_SDM_CFG1, 0x54); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_SDM_CFG2, 0x66); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_SDM_CFG3, 0x1D); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_SDM_CFG4, 0x00); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_LKDET_CFG0, 0x10); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_LKDET_CFG1, 0x1A); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_LKDET_CFG2, 0x05); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_POSTDIV2_CFG, 0x00); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_POSTDIV3_CFG, 0x00); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_CAL_CFG2, 0x01); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_CAL_CFG8, 0x60); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_CAL_CFG9, 0x00); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_CAL_CFG10, 0x2A); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_CAL_CFG11, 0x03); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_PD_CTRL0, 0x1F); - udelay(50); - - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_GLB_CFG, 0x0F); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_PD_CTRL1, 0x00); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_ANA_CFG2, 0x10); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_ANA_CFG0, 0xDB); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_ANA_CFG1, 0x43); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_ANA_CFG2, 0x02); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_ANA_CFG3, 0x00); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_VREG_CFG, 0x04); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_DCC_CFG0, 0xD0); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_DCC_CFG1, 0x1A); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_TXCAL_CFG0, 0x00); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_TXCAL_CFG1, 0x00); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_TXCAL_CFG2, 0x02); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_TXCAL_CFG3, 0x05); - udelay(200); - break; - - case 650000000: - MDSS_PLL_REG_W(phy_base, HDMI_PHY_GLB_CFG, 0x81); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_GLB_CFG, 0x01); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_REFCLK_CFG, 0x01); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_VCOLPF_CFG, 0x19); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_LPFR_CFG, 0x0E); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_LPFC1_CFG, 0x20); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_LPFC2_CFG, 0x0D); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_SDM_CFG0, 0x00); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_SDM_CFG1, 0x4F); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_SDM_CFG2, 0x55); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_SDM_CFG3, 0xED); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_SDM_CFG4, 0x00); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_LKDET_CFG0, 0x10); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_LKDET_CFG1, 0x1A); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_LKDET_CFG2, 0x05); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_POSTDIV2_CFG, 0x00); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_POSTDIV3_CFG, 0x00); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_CAL_CFG2, 0x01); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_CAL_CFG8, 0x60); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_CAL_CFG9, 0x00); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_CAL_CFG10, 0x8A); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_CAL_CFG11, 0x02); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_PD_CTRL0, 0x1F); - udelay(50); - - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_GLB_CFG, 0x0F); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_PD_CTRL1, 0x00); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_ANA_CFG2, 0x10); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_ANA_CFG0, 0xDB); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_ANA_CFG1, 0x43); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_ANA_CFG2, 0x02); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_ANA_CFG3, 0x00); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_VREG_CFG, 0x04); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_DCC_CFG0, 0xD0); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_DCC_CFG1, 0x1A); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_TXCAL_CFG0, 0x00); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_TXCAL_CFG1, 0x00); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_TXCAL_CFG2, 0x02); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_TXCAL_CFG3, 0x05); - udelay(200); - break; - - case 742500000: - /* - * 720p60/720p50/1080i60/1080i50 - * 1080p24/1080p30/1080p25 case - */ - MDSS_PLL_REG_W(phy_base, HDMI_PHY_GLB_CFG, 0x81); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_GLB_CFG, 0x01); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_REFCLK_CFG, 0x01); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_VCOLPF_CFG, 0x19); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_LPFR_CFG, 0x0E); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_LPFC1_CFG, 0x20); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_LPFC2_CFG, 0x0D); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_SDM_CFG0, 0x00); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_SDM_CFG1, 0x52); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_SDM_CFG2, 0x00); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_SDM_CFG3, 0x56); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_SDM_CFG4, 0x00); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_LKDET_CFG0, 0x10); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_LKDET_CFG1, 0x1A); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_LKDET_CFG2, 0x05); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_POSTDIV2_CFG, 0x00); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_POSTDIV3_CFG, 0x00); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_CAL_CFG2, 0x01); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_CAL_CFG8, 0x60); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_CAL_CFG9, 0x00); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_CAL_CFG10, 0xE6); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_CAL_CFG11, 0x02); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_PD_CTRL0, 0x1F); - udelay(50); - - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_GLB_CFG, 0x0F); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_PD_CTRL1, 0x00); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_ANA_CFG2, 0x10); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_ANA_CFG0, 0xDB); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_ANA_CFG1, 0x43); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_ANA_CFG2, 0x02); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_ANA_CFG3, 0x00); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_VREG_CFG, 0x04); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_DCC_CFG0, 0xD0); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_DCC_CFG1, 0x1A); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_TXCAL_CFG0, 0x00); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_TXCAL_CFG1, 0x00); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_TXCAL_CFG2, 0x02); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_TXCAL_CFG3, 0x05); - udelay(200); - break; - - case 1080000000: - MDSS_PLL_REG_W(phy_base, HDMI_PHY_GLB_CFG, 0x81); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_GLB_CFG, 0x01); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_REFCLK_CFG, 0x01); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_VCOLPF_CFG, 0x19); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_LPFR_CFG, 0x0E); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_LPFC1_CFG, 0x20); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_LPFC2_CFG, 0x0D); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_SDM_CFG0, 0x00); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_SDM_CFG1, 0x5B); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_SDM_CFG2, 0x00); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_SDM_CFG3, 0x20); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_SDM_CFG4, 0x00); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_LKDET_CFG0, 0x10); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_LKDET_CFG1, 0x1A); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_LKDET_CFG2, 0x05); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_POSTDIV2_CFG, 0x00); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_POSTDIV3_CFG, 0x00); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_CAL_CFG2, 0x01); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_CAL_CFG8, 0x60); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_CAL_CFG9, 0x00); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_CAL_CFG10, 0x38); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_CAL_CFG11, 0x04); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_PD_CTRL0, 0x1F); - udelay(50); - - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_GLB_CFG, 0x0F); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_PD_CTRL1, 0x00); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_ANA_CFG2, 0x10); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_ANA_CFG0, 0xDB); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_ANA_CFG1, 0x43); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_ANA_CFG2, 0x02); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_ANA_CFG3, 0x00); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_VREG_CFG, 0x04); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_DCC_CFG0, 0xD0); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_DCC_CFG1, 0x1A); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_TXCAL_CFG0, 0x00); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_TXCAL_CFG1, 0x00); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_TXCAL_CFG2, 0x02); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_TXCAL_CFG3, 0x05); - udelay(200); - break; - - case 1342500000: - MDSS_PLL_REG_W(phy_base, HDMI_PHY_GLB_CFG, 0x81); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_GLB_CFG, 0x01); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_REFCLK_CFG, 0x01); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_VCOLPF_CFG, 0x19); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_LPFR_CFG, 0x0E); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_LPFC1_CFG, 0x20); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_LPFC2_CFG, 0x0D); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_SDM_CFG0, 0x36); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_SDM_CFG1, 0x61); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_SDM_CFG2, 0x01); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_SDM_CFG3, 0xF6); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_SDM_CFG4, 0x00); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_LKDET_CFG0, 0x10); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_LKDET_CFG1, 0x1A); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_LKDET_CFG2, 0x05); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_POSTDIV2_CFG, 0x00); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_POSTDIV3_CFG, 0x00); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_CAL_CFG2, 0x01); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_CAL_CFG8, 0x60); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_CAL_CFG9, 0x00); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_CAL_CFG10, 0x3E); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_CAL_CFG11, 0x05); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_PD_CTRL0, 0x1F); - udelay(50); - - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_GLB_CFG, 0x0F); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_PD_CTRL1, 0x00); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_ANA_CFG2, 0x10); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_ANA_CFG0, 0xDB); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_ANA_CFG1, 0x43); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_ANA_CFG2, 0x05); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_ANA_CFG3, 0x00); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_VREG_CFG, 0x04); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_DCC_CFG0, 0xD0); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_DCC_CFG1, 0x1A); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_TXCAL_CFG0, 0x00); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_TXCAL_CFG1, 0x00); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_TXCAL_CFG2, 0x11); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_TXCAL_CFG3, 0x05); - udelay(200); - break; - - case 1485000000: - MDSS_PLL_REG_W(phy_base, HDMI_PHY_GLB_CFG, 0x81); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_GLB_CFG, 0x01); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_REFCLK_CFG, 0x01); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_VCOLPF_CFG, 0x19); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_LPFR_CFG, 0x0E); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_LPFC1_CFG, 0x20); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_LPFC2_CFG, 0x0D); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_SDM_CFG0, 0x00); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_SDM_CFG1, 0x65); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_SDM_CFG2, 0x00); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_SDM_CFG3, 0xAC); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_SDM_CFG4, 0x00); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_LKDET_CFG0, 0x10); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_LKDET_CFG1, 0x1A); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_LKDET_CFG2, 0x05); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_POSTDIV2_CFG, 0x00); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_POSTDIV3_CFG, 0x00); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_CAL_CFG2, 0x01); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_CAL_CFG8, 0x60); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_CAL_CFG9, 0x00); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_CAL_CFG10, 0xCD); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_CAL_CFG11, 0x05); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_PD_CTRL0, 0x1F); - udelay(50); - - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_GLB_CFG, 0x0F); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_PD_CTRL1, 0x00); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_ANA_CFG2, 0x10); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_ANA_CFG0, 0xDB); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_ANA_CFG1, 0x43); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_ANA_CFG2, 0x06); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_ANA_CFG3, 0x03); - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_VREG_CFG, 0x04); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_DCC_CFG0, 0xD0); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_DCC_CFG1, 0x1A); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_TXCAL_CFG0, 0x00); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_TXCAL_CFG1, 0x00); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_TXCAL_CFG2, 0x02); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_TXCAL_CFG3, 0x05); - udelay(200); - break; - - default: - pr_debug("Use pll settings calculator for rate=%ld\n", rate); - - MDSS_PLL_REG_W(phy_base, HDMI_PHY_GLB_CFG, 0x81); - hdmi_phy_pll_calculator(rate, hdmi_pll_res); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_PD_CTRL0, 0x1F); - udelay(50); - - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_GLB_CFG, 0x0F); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_PD_CTRL1, 0x00); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_ANA_CFG2, 0x10); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_ANA_CFG0, 0xDB); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_ANA_CFG1, 0x43); - - if (rate < 825000000) { - MDSS_PLL_REG_W(phy_base, HDMI_PHY_ANA_CFG2, 0x01); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_ANA_CFG3, 0x00); - } else if (rate >= 825000000 && rate < 1342500000) { - MDSS_PLL_REG_W(phy_base, HDMI_PHY_ANA_CFG2, 0x05); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_ANA_CFG3, 0x03); - } else { - MDSS_PLL_REG_W(phy_base, HDMI_PHY_ANA_CFG2, 0x06); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_ANA_CFG3, 0x03); - } - - MDSS_PLL_REG_W(pll_base, HDMI_UNI_PLL_VREG_CFG, 0x04); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_DCC_CFG0, 0xD0); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_DCC_CFG1, 0x1A); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_TXCAL_CFG0, 0x00); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_TXCAL_CFG1, 0x00); - - if (rate < 825000000) - MDSS_PLL_REG_W(phy_base, HDMI_PHY_TXCAL_CFG2, 0x01); - else - MDSS_PLL_REG_W(phy_base, HDMI_PHY_TXCAL_CFG2, 0x00); - - MDSS_PLL_REG_W(phy_base, HDMI_PHY_TXCAL_CFG3, 0x05); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_BIST_PATN0, 0x62); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_BIST_PATN1, 0x03); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_BIST_PATN2, 0x69); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_BIST_PATN3, 0x02); - - udelay(200); - - MDSS_PLL_REG_W(phy_base, HDMI_PHY_BIST_CFG1, 0x00); - MDSS_PLL_REG_W(phy_base, HDMI_PHY_BIST_CFG0, 0x00); - } - - /* Make sure writes complete before disabling iface clock */ - mb(); - - mdss_pll_resource_enable(hdmi_pll_res, false); - - if (set_power_dwn) - hdmi_vco_enable(c); - - vco->rate = rate; - vco->rate_set = true; - - return 0; -} /* hdmi_pll_set_rate */ - -/* HDMI PLL DIV CLK */ - -static unsigned long hdmi_vco_get_rate(struct clk *c) -{ - unsigned long freq = 0; - int rc; - struct hdmi_pll_vco_clk *vco = to_hdmi_vco_clk(c); - struct mdss_pll_resources *hdmi_pll_res = vco->priv; - - if (is_gdsc_disabled(hdmi_pll_res)) - return 0; - - rc = mdss_pll_resource_enable(hdmi_pll_res, true); - if (rc) { - pr_err("pll resource can't be enabled\n"); - return rc; - } - - freq = MDSS_PLL_REG_R(hdmi_pll_res->pll_base, - HDMI_UNI_PLL_CAL_CFG11) << 8 | - MDSS_PLL_REG_R(hdmi_pll_res->pll_base, HDMI_UNI_PLL_CAL_CFG10); - - switch (freq) { - case 742: - freq = 742500000; - break; - case 810: - if (MDSS_PLL_REG_R(hdmi_pll_res->pll_base, - HDMI_UNI_PLL_SDM_CFG3) == 0x18) - freq = 810000000; - else - freq = 810900000; - break; - case 1342: - freq = 1342500000; - break; - default: - freq *= 1000000; - } - mdss_pll_resource_enable(hdmi_pll_res, false); - - return freq; -} - -static long hdmi_vco_round_rate(struct clk *c, unsigned long rate) -{ - unsigned long rrate = rate; - struct hdmi_pll_vco_clk *vco = to_hdmi_vco_clk(c); - - if (rate < vco->min_rate) - rrate = vco->min_rate; - if (rate > vco->max_rate) - rrate = vco->max_rate; - - pr_debug("rrate=%ld\n", rrate); - - return rrate; -} - -static int hdmi_vco_prepare(struct clk *c) -{ - struct hdmi_pll_vco_clk *vco = to_hdmi_vco_clk(c); - int ret = 0; - - pr_debug("rate=%ld\n", vco->rate); - - if (!vco->rate_set && vco->rate) - ret = hdmi_vco_set_rate(c, vco->rate); - - return ret; -} - -static void hdmi_vco_unprepare(struct clk *c) -{ - struct hdmi_pll_vco_clk *vco = to_hdmi_vco_clk(c); - - vco->rate_set = false; -} - -static int hdmi_pll_lock_status(struct mdss_pll_resources *hdmi_pll_res) -{ - u32 status; - int pll_locked = 0; - int rc; - - rc = mdss_pll_resource_enable(hdmi_pll_res, true); - if (rc) { - pr_err("pll resource can't be enabled\n"); - return rc; - } - - /* poll for PLL ready status */ - if (readl_poll_timeout_atomic( - (hdmi_pll_res->phy_base + HDMI_PHY_STATUS), - status, ((status & BIT(0)) == 1), - HDMI_PLL_POLL_DELAY_US, - HDMI_PLL_POLL_TIMEOUT_US)) { - pr_debug("HDMI PLL status=%x failed to Lock\n", status); - pll_locked = 0; - } else { - pll_locked = 1; - } - mdss_pll_resource_enable(hdmi_pll_res, false); - - return pll_locked; -} - -static enum handoff hdmi_vco_handoff(struct clk *c) -{ - enum handoff ret = HANDOFF_DISABLED_CLK; - struct hdmi_pll_vco_clk *vco = to_hdmi_vco_clk(c); - struct mdss_pll_resources *hdmi_pll_res = vco->priv; - - if (is_gdsc_disabled(hdmi_pll_res)) - return HANDOFF_DISABLED_CLK; - - if (mdss_pll_resource_enable(hdmi_pll_res, true)) { - pr_err("pll resource can't be enabled\n"); - return ret; - } - - hdmi_pll_res->handoff_resources = true; - - if (hdmi_pll_lock_status(hdmi_pll_res)) { - hdmi_pll_res->pll_on = true; - c->rate = hdmi_vco_get_rate(c); - ret = HANDOFF_ENABLED_CLK; - } else { - hdmi_pll_res->handoff_resources = false; - mdss_pll_resource_enable(hdmi_pll_res, false); - } - - pr_debug("done, ret=%d\n", ret); - return ret; -} - -static const struct clk_ops hdmi_vco_clk_ops = { - .enable = hdmi_vco_enable, - .set_rate = hdmi_vco_set_rate, - .get_rate = hdmi_vco_get_rate, - .round_rate = hdmi_vco_round_rate, - .prepare = hdmi_vco_prepare, - .unprepare = hdmi_vco_unprepare, - .disable = hdmi_vco_disable, - .handoff = hdmi_vco_handoff, -}; - -static struct hdmi_pll_vco_clk hdmi_vco_clk = { - .min_rate = 600000000, - .max_rate = 1800000000, - .c = { - .dbg_name = "hdmi_vco_clk", - .ops = &hdmi_vco_clk_ops, - CLK_INIT(hdmi_vco_clk.c), - }, -}; - -struct div_clk hdmipll_div1_clk = { - .data = { - .div = 1, - .min_div = 1, - .max_div = 1, - }, - .c = { - .parent = &hdmi_vco_clk.c, - .dbg_name = "hdmipll_div1_clk", - .ops = &clk_ops_div, - .flags = CLKFLAG_NO_RATE_CACHE, - CLK_INIT(hdmipll_div1_clk.c), - }, -}; - -struct div_clk hdmipll_div2_clk = { - .data = { - .div = 2, - .min_div = 2, - .max_div = 2, - }, - .c = { - .parent = &hdmi_vco_clk.c, - .dbg_name = "hdmipll_div2_clk", - .ops = &clk_ops_div, - .flags = CLKFLAG_NO_RATE_CACHE, - CLK_INIT(hdmipll_div2_clk.c), - }, -}; - -struct div_clk hdmipll_div4_clk = { - .data = { - .div = 4, - .min_div = 4, - .max_div = 4, - }, - .c = { - .parent = &hdmi_vco_clk.c, - .dbg_name = "hdmipll_div4_clk", - .ops = &clk_ops_div, - .flags = CLKFLAG_NO_RATE_CACHE, - CLK_INIT(hdmipll_div4_clk.c), - }, -}; - -struct div_clk hdmipll_div6_clk = { - .data = { - .div = 6, - .min_div = 6, - .max_div = 6, - }, - .c = { - .parent = &hdmi_vco_clk.c, - .dbg_name = "hdmipll_div6_clk", - .ops = &clk_ops_div, - .flags = CLKFLAG_NO_RATE_CACHE, - CLK_INIT(hdmipll_div6_clk.c), - }, -}; - -static int hdmipll_set_mux_sel(struct mux_clk *clk, int mux_sel) -{ - struct mdss_pll_resources *hdmi_pll_res = clk->priv; - int rc; - - rc = mdss_pll_resource_enable(hdmi_pll_res, true); - if (rc) { - pr_err("pll resource can't be enabled\n"); - return rc; - } - - pr_debug("mux_sel=%d\n", mux_sel); - MDSS_PLL_REG_W(hdmi_pll_res->pll_base, - HDMI_UNI_PLL_POSTDIV1_CFG, mux_sel); - mdss_pll_resource_enable(hdmi_pll_res, false); - - return 0; -} - -static int hdmipll_get_mux_sel(struct mux_clk *clk) -{ - int rc; - int mux_sel = 0; - struct mdss_pll_resources *hdmi_pll_res = clk->priv; - - if (is_gdsc_disabled(hdmi_pll_res)) - return 0; - - rc = mdss_pll_resource_enable(hdmi_pll_res, true); - if (rc) { - pr_err("pll resource can't be enabled\n"); - return rc; - } - - mux_sel = MDSS_PLL_REG_R(hdmi_pll_res->pll_base, - HDMI_UNI_PLL_POSTDIV1_CFG); - mdss_pll_resource_enable(hdmi_pll_res, false); - mux_sel &= 0x03; - pr_debug("mux_sel=%d\n", mux_sel); - - return mux_sel; -} - -static struct clk_mux_ops hdmipll_mux_ops = { - .set_mux_sel = hdmipll_set_mux_sel, - .get_mux_sel = hdmipll_get_mux_sel, -}; - -static const struct clk_ops hdmi_mux_ops; - -static int hdmi_mux_prepare(struct clk *c) -{ - int ret = 0; - - if (c && c->ops && c->ops->set_rate) - ret = c->ops->set_rate(c, c->rate); - - return ret; -} - -struct mux_clk hdmipll_mux_clk = { - MUX_SRC_LIST( - { &hdmipll_div1_clk.c, 0 }, - { &hdmipll_div2_clk.c, 1 }, - { &hdmipll_div4_clk.c, 2 }, - { &hdmipll_div6_clk.c, 3 }, - ), - .ops = &hdmipll_mux_ops, - .c = { - .parent = &hdmipll_div1_clk.c, - .dbg_name = "hdmipll_mux_clk", - .ops = &hdmi_mux_ops, - CLK_INIT(hdmipll_mux_clk.c), - }, -}; - -struct div_clk hdmipll_clk_src = { - .data = { - .div = 5, - .min_div = 5, - .max_div = 5, - }, - .c = { - .parent = &hdmipll_mux_clk.c, - .dbg_name = "hdmipll_clk_src", - .ops = &clk_ops_div, - CLK_INIT(hdmipll_clk_src.c), - }, -}; - -static struct clk_lookup hdmipllcc_8974[] = { - CLK_LOOKUP("extp_clk_src", hdmipll_clk_src.c, - "fd8c0000.qcom,mmsscc-mdss"), -}; - -int hdmi_pll_clock_register(struct platform_device *pdev, - struct mdss_pll_resources *pll_res) -{ - int rc = -ENOTSUPP; - - /* Set client data for vco, mux and div clocks */ - hdmipll_clk_src.priv = pll_res; - hdmipll_mux_clk.priv = pll_res; - hdmipll_div1_clk.priv = pll_res; - hdmipll_div2_clk.priv = pll_res; - hdmipll_div4_clk.priv = pll_res; - hdmipll_div6_clk.priv = pll_res; - hdmi_vco_clk.priv = pll_res; - - /* Set hdmi mux clock operation */ - hdmi_mux_ops = clk_ops_gen_mux; - hdmi_mux_ops.prepare = hdmi_mux_prepare; - - rc = of_msm_clock_register(pdev->dev.of_node, hdmipllcc_8974, - ARRAY_SIZE(hdmipllcc_8974)); - if (rc) { - pr_err("Clock register failed rc=%d\n", rc); - rc = -EPROBE_DEFER; - } - - return rc; -} diff --git a/pll/hdmi_pll_28lpm.c b/pll/hdmi_pll_28lpm.c deleted file mode 100644 index a0fba39c2c23..000000000000 --- a/pll/hdmi_pll_28lpm.c +++ /dev/null @@ -1,790 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. - */ - - -#define pr_fmt(fmt) "%s: " fmt, __func__ - -#include -#include -#include -#include -#include -#include "pll_drv.h" -#include "hdmi_pll.h" - -/* HDMI PLL macros */ -#define HDMI_PHY_PLL_REFCLK_CFG (0x0400) -#define HDMI_PHY_PLL_CHRG_PUMP_CFG (0x0404) -#define HDMI_PHY_PLL_LOOP_FLT_CFG0 (0x0408) -#define HDMI_PHY_PLL_LOOP_FLT_CFG1 (0x040c) -#define HDMI_PHY_PLL_IDAC_ADJ_CFG (0x0410) -#define HDMI_PHY_PLL_I_VI_KVCO_CFG (0x0414) -#define HDMI_PHY_PLL_PWRDN_B (0x0418) -#define HDMI_PHY_PLL_SDM_CFG0 (0x041c) -#define HDMI_PHY_PLL_SDM_CFG1 (0x0420) -#define HDMI_PHY_PLL_SDM_CFG2 (0x0424) -#define HDMI_PHY_PLL_SDM_CFG3 (0x0428) -#define HDMI_PHY_PLL_SDM_CFG4 (0x042c) -#define HDMI_PHY_PLL_SSC_CFG0 (0x0430) -#define HDMI_PHY_PLL_SSC_CFG1 (0x0434) -#define HDMI_PHY_PLL_SSC_CFG2 (0x0438) -#define HDMI_PHY_PLL_SSC_CFG3 (0x043c) -#define HDMI_PHY_PLL_LOCKDET_CFG0 (0x0440) -#define HDMI_PHY_PLL_LOCKDET_CFG1 (0x0444) -#define HDMI_PHY_PLL_LOCKDET_CFG2 (0x0448) -#define HDMI_PHY_PLL_VCOCAL_CFG0 (0x044c) -#define HDMI_PHY_PLL_VCOCAL_CFG1 (0x0450) -#define HDMI_PHY_PLL_VCOCAL_CFG2 (0x0454) -#define HDMI_PHY_PLL_VCOCAL_CFG3 (0x0458) -#define HDMI_PHY_PLL_VCOCAL_CFG4 (0x045c) -#define HDMI_PHY_PLL_VCOCAL_CFG5 (0x0460) -#define HDMI_PHY_PLL_VCOCAL_CFG6 (0x0464) -#define HDMI_PHY_PLL_VCOCAL_CFG7 (0x0468) -#define HDMI_PHY_PLL_DEBUG_SEL (0x046c) -#define HDMI_PHY_PLL_MISC0 (0x0470) -#define HDMI_PHY_PLL_MISC1 (0x0474) -#define HDMI_PHY_PLL_MISC2 (0x0478) -#define HDMI_PHY_PLL_MISC3 (0x047c) -#define HDMI_PHY_PLL_MISC4 (0x0480) -#define HDMI_PHY_PLL_MISC5 (0x0484) -#define HDMI_PHY_PLL_MISC6 (0x0488) -#define HDMI_PHY_PLL_DEBUG_BUS0 (0x048c) -#define HDMI_PHY_PLL_DEBUG_BUS1 (0x0490) -#define HDMI_PHY_PLL_DEBUG_BUS2 (0x0494) -#define HDMI_PHY_PLL_STATUS0 (0x0498) -#define HDMI_PHY_PLL_STATUS1 (0x049c) - -#define HDMI_PHY_REG_0 (0x0000) -#define HDMI_PHY_REG_1 (0x0004) -#define HDMI_PHY_REG_2 (0x0008) -#define HDMI_PHY_REG_3 (0x000c) -#define HDMI_PHY_REG_4 (0x0010) -#define HDMI_PHY_REG_5 (0x0014) -#define HDMI_PHY_REG_6 (0x0018) -#define HDMI_PHY_REG_7 (0x001c) -#define HDMI_PHY_REG_8 (0x0020) -#define HDMI_PHY_REG_9 (0x0024) -#define HDMI_PHY_REG_10 (0x0028) -#define HDMI_PHY_REG_11 (0x002c) -#define HDMI_PHY_REG_12 (0x0030) -#define HDMI_PHY_REG_BIST_CFG (0x0034) -#define HDMI_PHY_DEBUG_BUS_SEL (0x0038) -#define HDMI_PHY_REG_MISC0 (0x003c) -#define HDMI_PHY_REG_13 (0x0040) -#define HDMI_PHY_REG_14 (0x0044) -#define HDMI_PHY_REG_15 (0x0048) - -/* HDMI PHY/PLL bit field macros */ -#define SW_RESET BIT(2) -#define SW_RESET_PLL BIT(0) -#define PWRDN_B BIT(7) - -#define PLL_PWRDN_B BIT(3) -#define REG_VTEST_EN BIT(2) -#define PD_PLL BIT(1) -#define PD_PLL_REG BIT(0) - - -#define HDMI_PLL_POLL_DELAY_US 50 -#define HDMI_PLL_POLL_TIMEOUT_US 500 - -static int hdmi_pll_lock_status(struct mdss_pll_resources *hdmi_pll_res) -{ - u32 status; - int pll_locked = 0; - int rc; - - rc = mdss_pll_resource_enable(hdmi_pll_res, true); - if (rc) { - pr_err("pll resource can't be enabled\n"); - return rc; - } - - /* poll for PLL ready status */ - if (readl_poll_timeout_atomic( - (hdmi_pll_res->pll_base + HDMI_PHY_PLL_STATUS0), - status, ((status & BIT(0)) == 1), - HDMI_PLL_POLL_DELAY_US, - HDMI_PLL_POLL_TIMEOUT_US)) { - pr_debug("HDMI PLL status=%x failed to Lock\n", status); - pll_locked = 0; - } else { - pr_debug("HDMI PLL locked\n"); - pll_locked = 1; - } - mdss_pll_resource_enable(hdmi_pll_res, false); - - return pll_locked; -} - -static void hdmi_pll_disable_28lpm(struct clk_hw *hw) -{ - struct hdmi_pll_vco_clk *vco = to_hdmi_vco_clk_hw(hw); - struct mdss_pll_resources *hdmi_pll_res = vco->priv; - u32 val; - - if (!hdmi_pll_res) { - pr_err("Invalid input parameter\n"); - return; - } - - val = MDSS_PLL_REG_R(hdmi_pll_res->pll_base, HDMI_PHY_REG_12); - val &= (~PWRDN_B); - MDSS_PLL_REG_W(hdmi_pll_res->pll_base, HDMI_PHY_REG_12, val); - - val = MDSS_PLL_REG_R(hdmi_pll_res->pll_base, HDMI_PHY_PLL_PWRDN_B); - val |= PD_PLL; - val &= (~PLL_PWRDN_B); - MDSS_PLL_REG_W(hdmi_pll_res->pll_base, HDMI_PHY_PLL_PWRDN_B, val); - - /* Make sure HDMI PHY/PLL are powered down */ - wmb(); - -} /* hdmi_pll_disable_28lpm */ - -static int hdmi_pll_enable_28lpm(struct clk_hw *hw) -{ - struct hdmi_pll_vco_clk *vco = to_hdmi_vco_clk_hw(hw); - struct mdss_pll_resources *hdmi_pll_res = vco->priv; - void __iomem *pll_base; - u32 val; - int pll_lock_retry = 10; - - pll_base = hdmi_pll_res->pll_base; - - /* Assert PLL S/W reset */ - MDSS_PLL_REG_W(pll_base, HDMI_PHY_PLL_LOCKDET_CFG2, 0x8d); - MDSS_PLL_REG_W(pll_base, HDMI_PHY_PLL_LOCKDET_CFG0, 0x10); - MDSS_PLL_REG_W(pll_base, HDMI_PHY_PLL_LOCKDET_CFG1, 0x1a); - udelay(10); - /* De-assert PLL S/W reset */ - MDSS_PLL_REG_W(pll_base, HDMI_PHY_PLL_LOCKDET_CFG2, 0x0d); - - MDSS_PLL_REG_W(pll_base, HDMI_PHY_REG_1, 0xf2); - - udelay(10); - - MDSS_PLL_REG_W(pll_base, HDMI_PHY_REG_2, 0x1f); - - val = MDSS_PLL_REG_R(pll_base, HDMI_PHY_REG_12); - val |= BIT(5); - /* Assert PHY S/W reset */ - MDSS_PLL_REG_W(pll_base, HDMI_PHY_REG_12, val); - val &= ~BIT(5); - udelay(10); - /* De-assert PHY S/W reset */ - MDSS_PLL_REG_W(pll_base, HDMI_PHY_REG_12, val); - - val = MDSS_PLL_REG_R(pll_base, HDMI_PHY_REG_12); - val |= PWRDN_B; - MDSS_PLL_REG_W(pll_base, HDMI_PHY_REG_12, val); - - /* Wait 10 us for enabling global power for PHY */ - wmb(); - udelay(10); - - MDSS_PLL_REG_W(pll_base, HDMI_PHY_REG_3, 0x20); - MDSS_PLL_REG_W(pll_base, HDMI_PHY_REG_4, 0x10); - - val = MDSS_PLL_REG_R(pll_base, HDMI_PHY_PLL_PWRDN_B); - val |= PLL_PWRDN_B; - val |= REG_VTEST_EN; - val &= ~PD_PLL; - val |= PD_PLL_REG; - MDSS_PLL_REG_W(pll_base, HDMI_PHY_PLL_PWRDN_B, val); - - MDSS_PLL_REG_W(pll_base, HDMI_PHY_REG_2, 0x81); - - do { - if (!hdmi_pll_lock_status(hdmi_pll_res)) { - /* PLL has still not locked. - * Do a software reset and try again - * Assert PLL S/W reset first - */ - MDSS_PLL_REG_W(pll_base, - HDMI_PHY_PLL_LOCKDET_CFG2, 0x8d); - - /* Wait for a short time before de-asserting - * to allow the hardware to complete its job. - * This much of delay should be fine for hardware - * to assert and de-assert. - */ - udelay(10); - MDSS_PLL_REG_W(pll_base, - HDMI_PHY_PLL_LOCKDET_CFG2, 0xd); - - /* Wait for a short duration for the PLL calibration - * before checking if the PLL gets locked - */ - udelay(350); - } else { - pr_debug("HDMI PLL locked\n"); - break; - } - - } while (--pll_lock_retry); - - if (!pll_lock_retry) { - pr_err("HDMI PLL not locked\n"); - hdmi_pll_disable_28lpm(hw); - return -EAGAIN; - } - - return 0; -} /* hdmi_pll_enable_28lpm */ - -static void hdmi_phy_pll_calculator_28lpm(unsigned long vco_rate, - struct mdss_pll_resources *hdmi_pll_res) -{ - u32 ref_clk = 19200000; - u32 integer_mode = 0; - u32 ref_clk_multiplier = integer_mode == 0 ? 2 : 1; - u32 int_ref_clk_freq = ref_clk * ref_clk_multiplier; - u32 refclk_cfg = 0; - u32 ten_power_six = 1000000; - u64 multiplier_q = 0; - u64 multiplier_r = 0; - u32 lf_cfg0 = 0; - u32 lf_cfg1 = 0; - u64 vco_cfg0 = 0; - u64 vco_cfg4 = 0; - u64 sdm_cfg0 = 0; - u64 sdm_cfg1 = 0; - u64 sdm_cfg2 = 0; - u32 val1 = 0; - u32 val2 = 0; - u32 val3 = 0; - void __iomem *pll_base = hdmi_pll_res->pll_base; - - multiplier_q = vco_rate; - multiplier_r = do_div(multiplier_q, int_ref_clk_freq); - - lf_cfg0 = multiplier_q > 30 ? 0 : (multiplier_q > 16 ? 16 : 32); - lf_cfg0 += integer_mode; - - lf_cfg1 = multiplier_q > 30 ? 0xc3 : (multiplier_q > 16 ? 0xbb : 0xf9); - - vco_cfg0 = vco_rate / ten_power_six; - vco_cfg4 = ((ref_clk * 5) / ten_power_six) - 1; - - sdm_cfg0 = (integer_mode * 64) + multiplier_q - 1; - sdm_cfg1 = 64 + multiplier_q - 1; - - sdm_cfg2 = (multiplier_r) * 65536; - do_div(sdm_cfg2, int_ref_clk_freq); - - pr_debug("lf_cfg0 = 0x%x lf_cfg1 = 0x%x\n", lf_cfg0, lf_cfg1); - pr_debug("vco_cfg0 = 0x%llx vco_cfg4 = 0x%llx\n", vco_cfg0, vco_cfg4); - pr_debug("sdm_cfg0 = 0x%llx sdm_cfg1 = 0x%llx sdm_cfg2 = 0x%llx\n", - sdm_cfg0, sdm_cfg1, sdm_cfg2); - - refclk_cfg = MDSS_PLL_REG_R(pll_base, HDMI_PHY_PLL_REFCLK_CFG); - refclk_cfg &= ~0xf; - refclk_cfg |= (ref_clk_multiplier == 2) ? 0x8 - : (ref_clk_multiplier == 1) ? 0 : 0x2; - - MDSS_PLL_REG_W(pll_base, HDMI_PHY_PLL_REFCLK_CFG, refclk_cfg); - MDSS_PLL_REG_W(pll_base, HDMI_PHY_PLL_CHRG_PUMP_CFG, 0x02); - MDSS_PLL_REG_W(pll_base, HDMI_PHY_PLL_LOOP_FLT_CFG0, lf_cfg0); - MDSS_PLL_REG_W(pll_base, HDMI_PHY_PLL_LOOP_FLT_CFG1, lf_cfg1); - MDSS_PLL_REG_W(pll_base, HDMI_PHY_PLL_IDAC_ADJ_CFG, 0x2c); - MDSS_PLL_REG_W(pll_base, HDMI_PHY_PLL_I_VI_KVCO_CFG, 0x06); - MDSS_PLL_REG_W(pll_base, HDMI_PHY_PLL_PWRDN_B, 0x0a); - - MDSS_PLL_REG_W(pll_base, HDMI_PHY_PLL_SDM_CFG0, sdm_cfg0); - MDSS_PLL_REG_W(pll_base, HDMI_PHY_PLL_SDM_CFG1, sdm_cfg1); - - val1 = sdm_cfg2 & 0xff; - val2 = (sdm_cfg2 >> 8) & 0xff; - val3 = (sdm_cfg2 >> 16) & 0xff; - MDSS_PLL_REG_W(pll_base, HDMI_PHY_PLL_SDM_CFG2, val1); - MDSS_PLL_REG_W(pll_base, HDMI_PHY_PLL_SDM_CFG3, val2); - MDSS_PLL_REG_W(pll_base, HDMI_PHY_PLL_SDM_CFG4, val3); - - MDSS_PLL_REG_W(pll_base, HDMI_PHY_PLL_SSC_CFG0, 0x9a); - MDSS_PLL_REG_W(pll_base, HDMI_PHY_PLL_SSC_CFG1, 0x00); - MDSS_PLL_REG_W(pll_base, HDMI_PHY_PLL_SSC_CFG2, 0x00); - MDSS_PLL_REG_W(pll_base, HDMI_PHY_PLL_SSC_CFG3, 0x00); - MDSS_PLL_REG_W(pll_base, HDMI_PHY_PLL_LOCKDET_CFG0, 0x10); - MDSS_PLL_REG_W(pll_base, HDMI_PHY_PLL_LOCKDET_CFG1, 0x1a); - MDSS_PLL_REG_W(pll_base, HDMI_PHY_PLL_LOCKDET_CFG2, 0x0d); - - val1 = vco_cfg0 & 0xff; - val2 = (vco_cfg0 >> 8) & 0xff; - MDSS_PLL_REG_W(pll_base, HDMI_PHY_PLL_VCOCAL_CFG0, val1); - MDSS_PLL_REG_W(pll_base, HDMI_PHY_PLL_VCOCAL_CFG1, val2); - - MDSS_PLL_REG_W(pll_base, HDMI_PHY_PLL_VCOCAL_CFG2, 0x3b); - MDSS_PLL_REG_W(pll_base, HDMI_PHY_PLL_VCOCAL_CFG3, 0x00); - - val1 = vco_cfg4 & 0xff; - val2 = (vco_cfg4 >> 8) & 0xff; - MDSS_PLL_REG_W(pll_base, HDMI_PHY_PLL_VCOCAL_CFG4, val1); - MDSS_PLL_REG_W(pll_base, HDMI_PHY_PLL_VCOCAL_CFG5, val2); - - MDSS_PLL_REG_W(pll_base, HDMI_PHY_PLL_VCOCAL_CFG6, 0x33); - MDSS_PLL_REG_W(pll_base, HDMI_PHY_PLL_VCOCAL_CFG7, 0x03); - -} - -int hdmi_vco_set_rate_28lpm(struct clk_hw *hw, unsigned long rate, - unsigned long parent_rate) -{ - struct hdmi_pll_vco_clk *vco = to_hdmi_vco_clk_hw(hw); - struct mdss_pll_resources *hdmi_pll_res = vco->priv; - void __iomem *pll_base; - int rc; - - rc = mdss_pll_resource_enable(hdmi_pll_res, true); - if (rc) { - pr_err("pll resource can't be enabled\n"); - return rc; - } - - if (hdmi_pll_res->pll_on) - return 0; - - pll_base = hdmi_pll_res->pll_base; - - pr_debug("rate=%ld\n", rate); - - hdmi_phy_pll_calculator_28lpm(rate, hdmi_pll_res); - - /* Make sure writes complete before disabling iface clock */ - wmb(); - - vco->rate = rate; - hdmi_pll_res->vco_current_rate = rate; - - mdss_pll_resource_enable(hdmi_pll_res, false); - - - return 0; -} /* hdmi_pll_set_rate */ - -static unsigned long hdmi_vco_get_rate(struct hdmi_pll_vco_clk *vco) -{ - unsigned long freq = 0; - int rc = 0; - struct mdss_pll_resources *hdmi_pll_res = vco->priv; - - rc = mdss_pll_resource_enable(hdmi_pll_res, true); - if (rc) { - pr_err("Failed to enable hdmi pll resources\n"); - return 0; - } - - freq = MDSS_PLL_REG_R(hdmi_pll_res->pll_base, - HDMI_PHY_PLL_VCOCAL_CFG1) << 8 | - MDSS_PLL_REG_R(hdmi_pll_res->pll_base, - HDMI_PHY_PLL_VCOCAL_CFG0); - - switch (freq) { - case 742: - freq = 742500000; - break; - case 810: - if (MDSS_PLL_REG_R(hdmi_pll_res->pll_base, - HDMI_PHY_PLL_SDM_CFG3) == 0x18) - freq = 810000000; - else - freq = 810900000; - break; - case 1342: - freq = 1342500000; - break; - default: - freq *= 1000000; - } - mdss_pll_resource_enable(hdmi_pll_res, false); - - return freq; -} - -long hdmi_vco_round_rate_28lpm(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) -{ - unsigned long rrate = rate; - struct hdmi_pll_vco_clk *vco = to_hdmi_vco_clk_hw(hw); - - if (rate < vco->min_rate) - rrate = vco->min_rate; - if (rate > vco->max_rate) - rrate = vco->max_rate; - - *parent_rate = rrate; - pr_debug("rrate=%ld\n", rrate); - - return rrate; -} - -int hdmi_vco_prepare_28lpm(struct clk_hw *hw) -{ - int rc = 0; - struct hdmi_pll_vco_clk *vco = to_hdmi_vco_clk_hw(hw); - struct mdss_pll_resources *hdmi_res = vco->priv; - - pr_debug("rate=%ld\n", clk_hw_get_rate(hw)); - rc = mdss_pll_resource_enable(hdmi_res, true); - if (rc) { - pr_err("Failed to enable mdss HDMI pll resources\n"); - goto error; - } - - if ((hdmi_res->vco_cached_rate != 0) - && (hdmi_res->vco_cached_rate == clk_hw_get_rate(hw))) { - rc = vco->hw.init->ops->set_rate(hw, - hdmi_res->vco_cached_rate, hdmi_res->vco_cached_rate); - if (rc) { - pr_err("index=%d vco_set_rate failed. rc=%d\n", - rc, hdmi_res->index); - mdss_pll_resource_enable(hdmi_res, false); - goto error; - } - } - - rc = hdmi_pll_enable_28lpm(hw); - if (rc) { - mdss_pll_resource_enable(hdmi_res, false); - pr_err("ndx=%d failed to enable hdmi pll\n", - hdmi_res->index); - goto error; - } - - mdss_pll_resource_enable(hdmi_res, false); - pr_debug("HDMI PLL enabled\n"); -error: - return rc; -} - -void hdmi_vco_unprepare_28lpm(struct clk_hw *hw) -{ - struct hdmi_pll_vco_clk *vco = to_hdmi_vco_clk_hw(hw); - struct mdss_pll_resources *hdmi_res = vco->priv; - - if (!hdmi_res) { - pr_err("Invalid input parameter\n"); - return; - } - - if (!hdmi_res->pll_on && - mdss_pll_resource_enable(hdmi_res, true)) { - pr_err("pll resource can't be enabled\n"); - return; - } - - hdmi_res->vco_cached_rate = clk_hw_get_rate(hw); - hdmi_pll_disable_28lpm(hw); - - hdmi_res->handoff_resources = false; - mdss_pll_resource_enable(hdmi_res, false); - hdmi_res->pll_on = false; - - pr_debug("HDMI PLL disabled\n"); -} - - -unsigned long hdmi_vco_recalc_rate_28lpm(struct clk_hw *hw, - unsigned long parent_rate) -{ - struct hdmi_pll_vco_clk *vco = to_hdmi_vco_clk_hw(hw); - struct mdss_pll_resources *hdmi_pll_res = vco->priv; - u64 vco_rate = 0; - - if (!hdmi_pll_res) { - pr_err("dsi pll resources not available\n"); - return 0; - } - - if (hdmi_pll_res->vco_current_rate) { - vco_rate = (unsigned long)hdmi_pll_res->vco_current_rate; - pr_debug("vco_rate=%lld\n", vco_rate); - return vco_rate; - } - - if (is_gdsc_disabled(hdmi_pll_res)) - return 0; - - if (mdss_pll_resource_enable(hdmi_pll_res, true)) { - pr_err("Failed to enable hdmi pll resources\n"); - return 0; - } - - if (hdmi_pll_lock_status(hdmi_pll_res)) { - hdmi_pll_res->handoff_resources = true; - hdmi_pll_res->pll_on = true; - vco_rate = hdmi_vco_get_rate(vco); - } else { - hdmi_pll_res->handoff_resources = false; - mdss_pll_resource_enable(hdmi_pll_res, false); - } - - pr_debug("vco_rate = %lld\n", vco_rate); - - return (unsigned long)vco_rate; -} - -static int hdmi_mux_set_parent(void *context, unsigned int reg, - unsigned int mux_sel) -{ - struct mdss_pll_resources *hdmi_pll_res = context; - int rc = 0; - u32 reg_val = 0; - const u32 div_4 = 0x20; - const u32 div_6 = 0x30; - - rc = mdss_pll_resource_enable(hdmi_pll_res, true); - if (rc) { - pr_err("Failed to enable hdmi pll resources\n"); - return rc; - } - - /* - * divsel_six is preferred over divsel_four to keep - * vco range within goal limits to maintain margin. - * To achieve this, its precedence order is toggled - * at mux level. So reverse toggle the mux_sel value - * here. - */ - switch (mux_sel) { - case 0x20: /* intended divider is divsel_six */ - mux_sel = div_6; - break; - case 0x30: /* intended divider is divsel_four */ - mux_sel = div_4; - break; - } - pr_debug("mux_sel = %d\n", mux_sel); - - reg_val = MDSS_PLL_REG_R(hdmi_pll_res->pll_base, - HDMI_PHY_PLL_REFCLK_CFG); - reg_val &= ~0x70; - reg_val |= (mux_sel & 0x70); - pr_debug("pll_refclk_cfg = 0x%x\n", reg_val); - MDSS_PLL_REG_W(hdmi_pll_res->pll_base, - HDMI_PHY_PLL_REFCLK_CFG, reg_val); - - (void)mdss_pll_resource_enable(hdmi_pll_res, false); - - return 0; -} - -static int hdmi_mux_get_parent(void *context, unsigned int reg, - unsigned int *val) -{ - int rc = 0; - int mux_sel = 0; - struct mdss_pll_resources *hdmi_pll_res = context; - - rc = mdss_pll_resource_enable(hdmi_pll_res, true); - if (rc) { - *val = 0; - pr_err("Failed to enable hdmi pll resources\n"); - } else { - mux_sel = MDSS_PLL_REG_R(hdmi_pll_res->pll_base, - HDMI_PHY_PLL_REFCLK_CFG); - mux_sel &= 0x70; - *val = mux_sel; - pr_debug("mux_sel = %d\n", *val); - } - - (void)mdss_pll_resource_enable(hdmi_pll_res, false); - - return rc; -} - -static struct regmap_config hdmi_pll_28lpm_cfg = { - .reg_bits = 32, - .reg_stride = 4, - .val_bits = 32, - .max_register = 0x49c, -}; - -static struct regmap_bus hdmi_pclk_src_mux_regmap_ops = { - .reg_write = hdmi_mux_set_parent, - .reg_read = hdmi_mux_get_parent, -}; - -/* Op structures */ -static const struct clk_ops hdmi_28lpm_vco_clk_ops = { - .recalc_rate = hdmi_vco_recalc_rate_28lpm, - .set_rate = hdmi_vco_set_rate_28lpm, - .round_rate = hdmi_vco_round_rate_28lpm, - .prepare = hdmi_vco_prepare_28lpm, - .unprepare = hdmi_vco_unprepare_28lpm, -}; - -static struct hdmi_pll_vco_clk hdmi_vco_clk = { - .min_rate = 540000000, - .max_rate = 1125000000, - .hw.init = &(struct clk_init_data){ - .name = "hdmi_vco_clk", - .parent_names = (const char *[]){ "cxo" }, - .num_parents = 1, - .ops = &hdmi_28lpm_vco_clk_ops, - }, -}; - -static struct clk_fixed_factor hdmi_vco_divsel_one_clk_src = { - .div = 1, - .mult = 1, - - .hw.init = &(struct clk_init_data){ - .name = "hdmi_vco_divsel_one_clk_src", - .parent_names = - (const char *[]){ "hdmi_vco_clk" }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - .ops = &clk_fixed_factor_ops, - }, -}; - -static struct clk_fixed_factor hdmi_vco_divsel_two_clk_src = { - .div = 2, - .mult = 1, - - .hw.init = &(struct clk_init_data){ - .name = "hdmi_vco_divsel_two_clk_src", - .parent_names = - (const char *[]){ "hdmi_vco_clk" }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - .ops = &clk_fixed_factor_ops, - }, -}; - -static struct clk_fixed_factor hdmi_vco_divsel_four_clk_src = { - .div = 4, - .mult = 1, - - .hw.init = &(struct clk_init_data){ - .name = "hdmi_vco_divsel_four_clk_src", - .parent_names = - (const char *[]){ "hdmi_vco_clk" }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - .ops = &clk_fixed_factor_ops, - }, -}; - -static struct clk_fixed_factor hdmi_vco_divsel_six_clk_src = { - .div = 6, - .mult = 1, - - .hw.init = &(struct clk_init_data){ - .name = "hdmi_vco_divsel_six_clk_src", - .parent_names = - (const char *[]){ "hdmi_vco_clk" }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - .ops = &clk_fixed_factor_ops, - }, -}; - -static struct clk_regmap_mux hdmi_pclk_src_mux = { - .reg = HDMI_PHY_PLL_REFCLK_CFG, - .shift = 4, - .width = 2, - - .clkr = { - .hw.init = &(struct clk_init_data){ - .name = "hdmi_pclk_src_mux", - .parent_names = - (const char *[]){"hdmi_vco_divsel_one_clk_src", - "hdmi_vco_divsel_two_clk_src", - "hdmi_vco_divsel_six_clk_src", - "hdmi_vco_divsel_four_clk_src"}, - .num_parents = 4, - .ops = &clk_regmap_mux_closest_ops, - .flags = CLK_SET_RATE_PARENT, - }, - }, -}; - -static struct clk_fixed_factor hdmi_pclk_src = { - .div = 5, - .mult = 1, - - .hw.init = &(struct clk_init_data){ - .name = "hdmi_phy_pll_clk", - .parent_names = - (const char *[]){ "hdmi_pclk_src_mux" }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - .ops = &clk_fixed_factor_ops, - }, -}; - -static struct clk_hw *mdss_hdmi_pllcc_28lpm[] = { - [HDMI_VCO_CLK] = &hdmi_vco_clk.hw, - [HDMI_VCO_DIVIDED_1_CLK_SRC] = &hdmi_vco_divsel_one_clk_src.hw, - [HDMI_VCO_DIVIDED_TWO_CLK_SRC] = &hdmi_vco_divsel_two_clk_src.hw, - [HDMI_VCO_DIVIDED_FOUR_CLK_SRC] = &hdmi_vco_divsel_four_clk_src.hw, - [HDMI_VCO_DIVIDED_SIX_CLK_SRC] = &hdmi_vco_divsel_six_clk_src.hw, - [HDMI_PCLK_SRC_MUX] = &hdmi_pclk_src_mux.clkr.hw, - [HDMI_PCLK_SRC] = &hdmi_pclk_src.hw, -}; - -int hdmi_pll_clock_register_28lpm(struct platform_device *pdev, - struct mdss_pll_resources *pll_res) -{ - int rc = -ENOTSUPP, i; - struct clk *clk; - struct clk_onecell_data *clk_data; - int num_clks = ARRAY_SIZE(mdss_hdmi_pllcc_28lpm); - struct regmap *regmap; - - if (!pdev || !pdev->dev.of_node || - !pll_res || !pll_res->pll_base) { - pr_err("Invalid input parameters\n"); - return -EPROBE_DEFER; - } - - clk_data = devm_kzalloc(&pdev->dev, sizeof(struct clk_onecell_data), - GFP_KERNEL); - if (!clk_data) - return -ENOMEM; - - clk_data->clks = devm_kzalloc(&pdev->dev, (num_clks * - sizeof(struct clk *)), GFP_KERNEL); - if (!clk_data->clks) { - devm_kfree(&pdev->dev, clk_data); - return -ENOMEM; - } - clk_data->clk_num = num_clks; - - /* Set client data for vco, mux and div clocks */ - regmap = devm_regmap_init(&pdev->dev, &hdmi_pclk_src_mux_regmap_ops, - pll_res, &hdmi_pll_28lpm_cfg); - hdmi_pclk_src_mux.clkr.regmap = regmap; - - hdmi_vco_clk.priv = pll_res; - - for (i = HDMI_VCO_CLK; i <= HDMI_PCLK_SRC; i++) { - pr_debug("reg clk: %d index: %d\n", i, pll_res->index); - clk = devm_clk_register(&pdev->dev, - mdss_hdmi_pllcc_28lpm[i]); - if (IS_ERR(clk)) { - pr_err("clk registration failed for HDMI: %d\n", - pll_res->index); - rc = -EINVAL; - goto clk_reg_fail; - } - clk_data->clks[i] = clk; - } - - rc = of_clk_add_provider(pdev->dev.of_node, - of_clk_src_onecell_get, clk_data); - if (rc) { - pr_err("%s: Clock register failed rc=%d\n", __func__, rc); - rc = -EPROBE_DEFER; - } else { - pr_debug("%s SUCCESS\n", __func__); - rc = 0; - } - return rc; -clk_reg_fail: - return rc; -} diff --git a/pll/hdmi_pll_8996.c b/pll/hdmi_pll_8996.c deleted file mode 100644 index 04e93fd95042..000000000000 --- a/pll/hdmi_pll_8996.c +++ /dev/null @@ -1,2675 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (c) 2014-2019, The Linux Foundation. All rights reserved. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "pll_drv.h" -#include "hdmi_pll.h" - -/* CONSTANTS */ -#define HDMI_BIT_CLK_TO_PIX_CLK_RATIO 10 -#define HDMI_HIGH_FREQ_BIT_CLK_THRESHOLD 3400000000UL -#define HDMI_DIG_FREQ_BIT_CLK_THRESHOLD 1500000000UL -#define HDMI_MID_FREQ_BIT_CLK_THRESHOLD 750000000 -#define HDMI_CLKS_PLL_DIVSEL 0 -#define HDMI_CORECLK_DIV 5 -#define HDMI_REF_CLOCK 19200000 -#define HDMI_64B_ERR_VAL 0xFFFFFFFFFFFFFFFF -#define HDMI_VERSION_8996_V1 1 -#define HDMI_VERSION_8996_V2 2 -#define HDMI_VERSION_8996_V3 3 -#define HDMI_VERSION_8996_V3_1_8 4 - -#define HDMI_VCO_MAX_FREQ 12000000000 -#define HDMI_VCO_MIN_FREQ 8000000000 -#define HDMI_2400MHZ_BIT_CLK_HZ 2400000000UL -#define HDMI_2250MHZ_BIT_CLK_HZ 2250000000UL -#define HDMI_2000MHZ_BIT_CLK_HZ 2000000000UL -#define HDMI_1700MHZ_BIT_CLK_HZ 1700000000UL -#define HDMI_1200MHZ_BIT_CLK_HZ 1200000000UL -#define HDMI_1334MHZ_BIT_CLK_HZ 1334000000UL -#define HDMI_1000MHZ_BIT_CLK_HZ 1000000000UL -#define HDMI_850MHZ_BIT_CLK_HZ 850000000 -#define HDMI_667MHZ_BIT_CLK_HZ 667000000 -#define HDMI_600MHZ_BIT_CLK_HZ 600000000 -#define HDMI_500MHZ_BIT_CLK_HZ 500000000 -#define HDMI_450MHZ_BIT_CLK_HZ 450000000 -#define HDMI_334MHZ_BIT_CLK_HZ 334000000 -#define HDMI_300MHZ_BIT_CLK_HZ 300000000 -#define HDMI_282MHZ_BIT_CLK_HZ 282000000 -#define HDMI_250MHZ_BIT_CLK_HZ 250000000 -#define HDMI_KHZ_TO_HZ 1000 - -/* PLL REGISTERS */ -#define QSERDES_COM_ATB_SEL1 (0x000) -#define QSERDES_COM_ATB_SEL2 (0x004) -#define QSERDES_COM_FREQ_UPDATE (0x008) -#define QSERDES_COM_BG_TIMER (0x00C) -#define QSERDES_COM_SSC_EN_CENTER (0x010) -#define QSERDES_COM_SSC_ADJ_PER1 (0x014) -#define QSERDES_COM_SSC_ADJ_PER2 (0x018) -#define QSERDES_COM_SSC_PER1 (0x01C) -#define QSERDES_COM_SSC_PER2 (0x020) -#define QSERDES_COM_SSC_STEP_SIZE1 (0x024) -#define QSERDES_COM_SSC_STEP_SIZE2 (0x028) -#define QSERDES_COM_POST_DIV (0x02C) -#define QSERDES_COM_POST_DIV_MUX (0x030) -#define QSERDES_COM_BIAS_EN_CLKBUFLR_EN (0x034) -#define QSERDES_COM_CLK_ENABLE1 (0x038) -#define QSERDES_COM_SYS_CLK_CTRL (0x03C) -#define QSERDES_COM_SYSCLK_BUF_ENABLE (0x040) -#define QSERDES_COM_PLL_EN (0x044) -#define QSERDES_COM_PLL_IVCO (0x048) -#define QSERDES_COM_LOCK_CMP1_MODE0 (0x04C) -#define QSERDES_COM_LOCK_CMP2_MODE0 (0x050) -#define QSERDES_COM_LOCK_CMP3_MODE0 (0x054) -#define QSERDES_COM_LOCK_CMP1_MODE1 (0x058) -#define QSERDES_COM_LOCK_CMP2_MODE1 (0x05C) -#define QSERDES_COM_LOCK_CMP3_MODE1 (0x060) -#define QSERDES_COM_LOCK_CMP1_MODE2 (0x064) -#define QSERDES_COM_CMN_RSVD0 (0x064) -#define QSERDES_COM_LOCK_CMP2_MODE2 (0x068) -#define QSERDES_COM_EP_CLOCK_DETECT_CTRL (0x068) -#define QSERDES_COM_LOCK_CMP3_MODE2 (0x06C) -#define QSERDES_COM_SYSCLK_DET_COMP_STATUS (0x06C) -#define QSERDES_COM_BG_TRIM (0x070) -#define QSERDES_COM_CLK_EP_DIV (0x074) -#define QSERDES_COM_CP_CTRL_MODE0 (0x078) -#define QSERDES_COM_CP_CTRL_MODE1 (0x07C) -#define QSERDES_COM_CP_CTRL_MODE2 (0x080) -#define QSERDES_COM_CMN_RSVD1 (0x080) -#define QSERDES_COM_PLL_RCTRL_MODE0 (0x084) -#define QSERDES_COM_PLL_RCTRL_MODE1 (0x088) -#define QSERDES_COM_PLL_RCTRL_MODE2 (0x08C) -#define QSERDES_COM_CMN_RSVD2 (0x08C) -#define QSERDES_COM_PLL_CCTRL_MODE0 (0x090) -#define QSERDES_COM_PLL_CCTRL_MODE1 (0x094) -#define QSERDES_COM_PLL_CCTRL_MODE2 (0x098) -#define QSERDES_COM_CMN_RSVD3 (0x098) -#define QSERDES_COM_PLL_CNTRL (0x09C) -#define QSERDES_COM_PHASE_SEL_CTRL (0x0A0) -#define QSERDES_COM_PHASE_SEL_DC (0x0A4) -#define QSERDES_COM_CORE_CLK_IN_SYNC_SEL (0x0A8) -#define QSERDES_COM_BIAS_EN_CTRL_BY_PSM (0x0A8) -#define QSERDES_COM_SYSCLK_EN_SEL (0x0AC) -#define QSERDES_COM_CML_SYSCLK_SEL (0x0B0) -#define QSERDES_COM_RESETSM_CNTRL (0x0B4) -#define QSERDES_COM_RESETSM_CNTRL2 (0x0B8) -#define QSERDES_COM_RESTRIM_CTRL (0x0BC) -#define QSERDES_COM_RESTRIM_CTRL2 (0x0C0) -#define QSERDES_COM_RESCODE_DIV_NUM (0x0C4) -#define QSERDES_COM_LOCK_CMP_EN (0x0C8) -#define QSERDES_COM_LOCK_CMP_CFG (0x0CC) -#define QSERDES_COM_DEC_START_MODE0 (0x0D0) -#define QSERDES_COM_DEC_START_MODE1 (0x0D4) -#define QSERDES_COM_DEC_START_MODE2 (0x0D8) -#define QSERDES_COM_VCOCAL_DEADMAN_CTRL (0x0D8) -#define QSERDES_COM_DIV_FRAC_START1_MODE0 (0x0DC) -#define QSERDES_COM_DIV_FRAC_START2_MODE0 (0x0E0) -#define QSERDES_COM_DIV_FRAC_START3_MODE0 (0x0E4) -#define QSERDES_COM_DIV_FRAC_START1_MODE1 (0x0E8) -#define QSERDES_COM_DIV_FRAC_START2_MODE1 (0x0EC) -#define QSERDES_COM_DIV_FRAC_START3_MODE1 (0x0F0) -#define QSERDES_COM_DIV_FRAC_START1_MODE2 (0x0F4) -#define QSERDES_COM_VCO_TUNE_MINVAL1 (0x0F4) -#define QSERDES_COM_DIV_FRAC_START2_MODE2 (0x0F8) -#define QSERDES_COM_VCO_TUNE_MINVAL2 (0x0F8) -#define QSERDES_COM_DIV_FRAC_START3_MODE2 (0x0FC) -#define QSERDES_COM_CMN_RSVD4 (0x0FC) -#define QSERDES_COM_INTEGLOOP_INITVAL (0x100) -#define QSERDES_COM_INTEGLOOP_EN (0x104) -#define QSERDES_COM_INTEGLOOP_GAIN0_MODE0 (0x108) -#define QSERDES_COM_INTEGLOOP_GAIN1_MODE0 (0x10C) -#define QSERDES_COM_INTEGLOOP_GAIN0_MODE1 (0x110) -#define QSERDES_COM_INTEGLOOP_GAIN1_MODE1 (0x114) -#define QSERDES_COM_INTEGLOOP_GAIN0_MODE2 (0x118) -#define QSERDES_COM_VCO_TUNE_MAXVAL1 (0x118) -#define QSERDES_COM_INTEGLOOP_GAIN1_MODE2 (0x11C) -#define QSERDES_COM_VCO_TUNE_MAXVAL2 (0x11C) -#define QSERDES_COM_RES_TRIM_CONTROL2 (0x120) -#define QSERDES_COM_VCO_TUNE_CTRL (0x124) -#define QSERDES_COM_VCO_TUNE_MAP (0x128) -#define QSERDES_COM_VCO_TUNE1_MODE0 (0x12C) -#define QSERDES_COM_VCO_TUNE2_MODE0 (0x130) -#define QSERDES_COM_VCO_TUNE1_MODE1 (0x134) -#define QSERDES_COM_VCO_TUNE2_MODE1 (0x138) -#define QSERDES_COM_VCO_TUNE1_MODE2 (0x13C) -#define QSERDES_COM_VCO_TUNE_INITVAL1 (0x13C) -#define QSERDES_COM_VCO_TUNE2_MODE2 (0x140) -#define QSERDES_COM_VCO_TUNE_INITVAL2 (0x140) -#define QSERDES_COM_VCO_TUNE_TIMER1 (0x144) -#define QSERDES_COM_VCO_TUNE_TIMER2 (0x148) -#define QSERDES_COM_SAR (0x14C) -#define QSERDES_COM_SAR_CLK (0x150) -#define QSERDES_COM_SAR_CODE_OUT_STATUS (0x154) -#define QSERDES_COM_SAR_CODE_READY_STATUS (0x158) -#define QSERDES_COM_CMN_STATUS (0x15C) -#define QSERDES_COM_RESET_SM_STATUS (0x160) -#define QSERDES_COM_RESTRIM_CODE_STATUS (0x164) -#define QSERDES_COM_PLLCAL_CODE1_STATUS (0x168) -#define QSERDES_COM_PLLCAL_CODE2_STATUS (0x16C) -#define QSERDES_COM_BG_CTRL (0x170) -#define QSERDES_COM_CLK_SELECT (0x174) -#define QSERDES_COM_HSCLK_SEL (0x178) -#define QSERDES_COM_INTEGLOOP_BINCODE_STATUS (0x17C) -#define QSERDES_COM_PLL_ANALOG (0x180) -#define QSERDES_COM_CORECLK_DIV (0x184) -#define QSERDES_COM_SW_RESET (0x188) -#define QSERDES_COM_CORE_CLK_EN (0x18C) -#define QSERDES_COM_C_READY_STATUS (0x190) -#define QSERDES_COM_CMN_CONFIG (0x194) -#define QSERDES_COM_CMN_RATE_OVERRIDE (0x198) -#define QSERDES_COM_SVS_MODE_CLK_SEL (0x19C) -#define QSERDES_COM_DEBUG_BUS0 (0x1A0) -#define QSERDES_COM_DEBUG_BUS1 (0x1A4) -#define QSERDES_COM_DEBUG_BUS2 (0x1A8) -#define QSERDES_COM_DEBUG_BUS3 (0x1AC) -#define QSERDES_COM_DEBUG_BUS_SEL (0x1B0) -#define QSERDES_COM_CMN_MISC1 (0x1B4) -#define QSERDES_COM_CMN_MISC2 (0x1B8) -#define QSERDES_COM_CORECLK_DIV_MODE1 (0x1BC) -#define QSERDES_COM_CORECLK_DIV_MODE2 (0x1C0) -#define QSERDES_COM_CMN_RSVD5 (0x1C0) - -/* Tx Channel base addresses */ -#define HDMI_TX_L0_BASE_OFFSET (0x400) -#define HDMI_TX_L1_BASE_OFFSET (0x600) -#define HDMI_TX_L2_BASE_OFFSET (0x800) -#define HDMI_TX_L3_BASE_OFFSET (0xA00) - -/* Tx Channel PHY registers */ -#define QSERDES_TX_L0_BIST_MODE_LANENO (0x000) -#define QSERDES_TX_L0_BIST_INVERT (0x004) -#define QSERDES_TX_L0_CLKBUF_ENABLE (0x008) -#define QSERDES_TX_L0_CMN_CONTROL_ONE (0x00C) -#define QSERDES_TX_L0_CMN_CONTROL_TWO (0x010) -#define QSERDES_TX_L0_CMN_CONTROL_THREE (0x014) -#define QSERDES_TX_L0_TX_EMP_POST1_LVL (0x018) -#define QSERDES_TX_L0_TX_POST2_EMPH (0x01C) -#define QSERDES_TX_L0_TX_BOOST_LVL_UP_DN (0x020) -#define QSERDES_TX_L0_HP_PD_ENABLES (0x024) -#define QSERDES_TX_L0_TX_IDLE_LVL_LARGE_AMP (0x028) -#define QSERDES_TX_L0_TX_DRV_LVL (0x02C) -#define QSERDES_TX_L0_TX_DRV_LVL_OFFSET (0x030) -#define QSERDES_TX_L0_RESET_TSYNC_EN (0x034) -#define QSERDES_TX_L0_PRE_STALL_LDO_BOOST_EN (0x038) -#define QSERDES_TX_L0_TX_BAND (0x03C) -#define QSERDES_TX_L0_SLEW_CNTL (0x040) -#define QSERDES_TX_L0_INTERFACE_SELECT (0x044) -#define QSERDES_TX_L0_LPB_EN (0x048) -#define QSERDES_TX_L0_RES_CODE_LANE_TX (0x04C) -#define QSERDES_TX_L0_RES_CODE_LANE_RX (0x050) -#define QSERDES_TX_L0_RES_CODE_LANE_OFFSET (0x054) -#define QSERDES_TX_L0_PERL_LENGTH1 (0x058) -#define QSERDES_TX_L0_PERL_LENGTH2 (0x05C) -#define QSERDES_TX_L0_SERDES_BYP_EN_OUT (0x060) -#define QSERDES_TX_L0_DEBUG_BUS_SEL (0x064) -#define QSERDES_TX_L0_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN (0x068) -#define QSERDES_TX_L0_TX_POL_INV (0x06C) -#define QSERDES_TX_L0_PARRATE_REC_DETECT_IDLE_EN (0x070) -#define QSERDES_TX_L0_BIST_PATTERN1 (0x074) -#define QSERDES_TX_L0_BIST_PATTERN2 (0x078) -#define QSERDES_TX_L0_BIST_PATTERN3 (0x07C) -#define QSERDES_TX_L0_BIST_PATTERN4 (0x080) -#define QSERDES_TX_L0_BIST_PATTERN5 (0x084) -#define QSERDES_TX_L0_BIST_PATTERN6 (0x088) -#define QSERDES_TX_L0_BIST_PATTERN7 (0x08C) -#define QSERDES_TX_L0_BIST_PATTERN8 (0x090) -#define QSERDES_TX_L0_LANE_MODE (0x094) -#define QSERDES_TX_L0_IDAC_CAL_LANE_MODE (0x098) -#define QSERDES_TX_L0_IDAC_CAL_LANE_MODE_CONFIGURATION (0x09C) -#define QSERDES_TX_L0_ATB_SEL1 (0x0A0) -#define QSERDES_TX_L0_ATB_SEL2 (0x0A4) -#define QSERDES_TX_L0_RCV_DETECT_LVL (0x0A8) -#define QSERDES_TX_L0_RCV_DETECT_LVL_2 (0x0AC) -#define QSERDES_TX_L0_PRBS_SEED1 (0x0B0) -#define QSERDES_TX_L0_PRBS_SEED2 (0x0B4) -#define QSERDES_TX_L0_PRBS_SEED3 (0x0B8) -#define QSERDES_TX_L0_PRBS_SEED4 (0x0BC) -#define QSERDES_TX_L0_RESET_GEN (0x0C0) -#define QSERDES_TX_L0_RESET_GEN_MUXES (0x0C4) -#define QSERDES_TX_L0_TRAN_DRVR_EMP_EN (0x0C8) -#define QSERDES_TX_L0_TX_INTERFACE_MODE (0x0CC) -#define QSERDES_TX_L0_PWM_CTRL (0x0D0) -#define QSERDES_TX_L0_PWM_ENCODED_OR_DATA (0x0D4) -#define QSERDES_TX_L0_PWM_GEAR_1_DIVIDER_BAND2 (0x0D8) -#define QSERDES_TX_L0_PWM_GEAR_2_DIVIDER_BAND2 (0x0DC) -#define QSERDES_TX_L0_PWM_GEAR_3_DIVIDER_BAND2 (0x0E0) -#define QSERDES_TX_L0_PWM_GEAR_4_DIVIDER_BAND2 (0x0E4) -#define QSERDES_TX_L0_PWM_GEAR_1_DIVIDER_BAND0_1 (0x0E8) -#define QSERDES_TX_L0_PWM_GEAR_2_DIVIDER_BAND0_1 (0x0EC) -#define QSERDES_TX_L0_PWM_GEAR_3_DIVIDER_BAND0_1 (0x0F0) -#define QSERDES_TX_L0_PWM_GEAR_4_DIVIDER_BAND0_1 (0x0F4) -#define QSERDES_TX_L0_VMODE_CTRL1 (0x0F8) -#define QSERDES_TX_L0_VMODE_CTRL2 (0x0FC) -#define QSERDES_TX_L0_TX_ALOG_INTF_OBSV_CNTL (0x100) -#define QSERDES_TX_L0_BIST_STATUS (0x104) -#define QSERDES_TX_L0_BIST_ERROR_COUNT1 (0x108) -#define QSERDES_TX_L0_BIST_ERROR_COUNT2 (0x10C) -#define QSERDES_TX_L0_TX_ALOG_INTF_OBSV (0x110) - -/* HDMI PHY REGISTERS */ -#define HDMI_PHY_BASE_OFFSET (0xC00) - -#define HDMI_PHY_CFG (0x00) -#define HDMI_PHY_PD_CTL (0x04) -#define HDMI_PHY_MODE (0x08) -#define HDMI_PHY_MISR_CLEAR (0x0C) -#define HDMI_PHY_TX0_TX1_BIST_CFG0 (0x10) -#define HDMI_PHY_TX0_TX1_BIST_CFG1 (0x14) -#define HDMI_PHY_TX0_TX1_PRBS_SEED_BYTE0 (0x18) -#define HDMI_PHY_TX0_TX1_PRBS_SEED_BYTE1 (0x1C) -#define HDMI_PHY_TX0_TX1_BIST_PATTERN0 (0x20) -#define HDMI_PHY_TX0_TX1_BIST_PATTERN1 (0x24) -#define HDMI_PHY_TX2_TX3_BIST_CFG0 (0x28) -#define HDMI_PHY_TX2_TX3_BIST_CFG1 (0x2C) -#define HDMI_PHY_TX2_TX3_PRBS_SEED_BYTE0 (0x30) -#define HDMI_PHY_TX2_TX3_PRBS_SEED_BYTE1 (0x34) -#define HDMI_PHY_TX2_TX3_BIST_PATTERN0 (0x38) -#define HDMI_PHY_TX2_TX3_BIST_PATTERN1 (0x3C) -#define HDMI_PHY_DEBUG_BUS_SEL (0x40) -#define HDMI_PHY_TXCAL_CFG0 (0x44) -#define HDMI_PHY_TXCAL_CFG1 (0x48) -#define HDMI_PHY_TX0_TX1_LANE_CTL (0x4C) -#define HDMI_PHY_TX2_TX3_LANE_CTL (0x50) -#define HDMI_PHY_LANE_BIST_CONFIG (0x54) -#define HDMI_PHY_CLOCK (0x58) -#define HDMI_PHY_MISC1 (0x5C) -#define HDMI_PHY_MISC2 (0x60) -#define HDMI_PHY_TX0_TX1_BIST_STATUS0 (0x64) -#define HDMI_PHY_TX0_TX1_BIST_STATUS1 (0x68) -#define HDMI_PHY_TX0_TX1_BIST_STATUS2 (0x6C) -#define HDMI_PHY_TX2_TX3_BIST_STATUS0 (0x70) -#define HDMI_PHY_TX2_TX3_BIST_STATUS1 (0x74) -#define HDMI_PHY_TX2_TX3_BIST_STATUS2 (0x78) -#define HDMI_PHY_PRE_MISR_STATUS0 (0x7C) -#define HDMI_PHY_PRE_MISR_STATUS1 (0x80) -#define HDMI_PHY_PRE_MISR_STATUS2 (0x84) -#define HDMI_PHY_PRE_MISR_STATUS3 (0x88) -#define HDMI_PHY_POST_MISR_STATUS0 (0x8C) -#define HDMI_PHY_POST_MISR_STATUS1 (0x90) -#define HDMI_PHY_POST_MISR_STATUS2 (0x94) -#define HDMI_PHY_POST_MISR_STATUS3 (0x98) -#define HDMI_PHY_STATUS (0x9C) -#define HDMI_PHY_MISC3_STATUS (0xA0) -#define HDMI_PHY_MISC4_STATUS (0xA4) -#define HDMI_PHY_DEBUG_BUS0 (0xA8) -#define HDMI_PHY_DEBUG_BUS1 (0xAC) -#define HDMI_PHY_DEBUG_BUS2 (0xB0) -#define HDMI_PHY_DEBUG_BUS3 (0xB4) -#define HDMI_PHY_PHY_REVISION_ID0 (0xB8) -#define HDMI_PHY_PHY_REVISION_ID1 (0xBC) -#define HDMI_PHY_PHY_REVISION_ID2 (0xC0) -#define HDMI_PHY_PHY_REVISION_ID3 (0xC4) - -#define HDMI_PLL_POLL_MAX_READS 100 -#define HDMI_PLL_POLL_TIMEOUT_US 1500 - -enum hdmi_pll_freqs { - HDMI_PCLK_25200_KHZ, - HDMI_PCLK_27027_KHZ, - HDMI_PCLK_27000_KHZ, - HDMI_PCLK_74250_KHZ, - HDMI_PCLK_148500_KHZ, - HDMI_PCLK_154000_KHZ, - HDMI_PCLK_268500_KHZ, - HDMI_PCLK_297000_KHZ, - HDMI_PCLK_594000_KHZ, - HDMI_PCLK_MAX -}; - -struct hdmi_8996_phy_pll_reg_cfg { - u32 tx_l0_lane_mode; - u32 tx_l2_lane_mode; - u32 tx_l0_tx_band; - u32 tx_l1_tx_band; - u32 tx_l2_tx_band; - u32 tx_l3_tx_band; - u32 com_svs_mode_clk_sel; - u32 com_hsclk_sel; - u32 com_pll_cctrl_mode0; - u32 com_pll_rctrl_mode0; - u32 com_cp_ctrl_mode0; - u32 com_dec_start_mode0; - u32 com_div_frac_start1_mode0; - u32 com_div_frac_start2_mode0; - u32 com_div_frac_start3_mode0; - u32 com_integloop_gain0_mode0; - u32 com_integloop_gain1_mode0; - u32 com_lock_cmp_en; - u32 com_lock_cmp1_mode0; - u32 com_lock_cmp2_mode0; - u32 com_lock_cmp3_mode0; - u32 com_core_clk_en; - u32 com_coreclk_div; - u32 com_restrim_ctrl; - u32 com_vco_tune_ctrl; - - u32 tx_l0_tx_drv_lvl; - u32 tx_l0_tx_emp_post1_lvl; - u32 tx_l1_tx_drv_lvl; - u32 tx_l1_tx_emp_post1_lvl; - u32 tx_l2_tx_drv_lvl; - u32 tx_l2_tx_emp_post1_lvl; - u32 tx_l3_tx_drv_lvl; - u32 tx_l3_tx_emp_post1_lvl; - u32 tx_l0_vmode_ctrl1; - u32 tx_l0_vmode_ctrl2; - u32 tx_l1_vmode_ctrl1; - u32 tx_l1_vmode_ctrl2; - u32 tx_l2_vmode_ctrl1; - u32 tx_l2_vmode_ctrl2; - u32 tx_l3_vmode_ctrl1; - u32 tx_l3_vmode_ctrl2; - u32 tx_l0_res_code_lane_tx; - u32 tx_l1_res_code_lane_tx; - u32 tx_l2_res_code_lane_tx; - u32 tx_l3_res_code_lane_tx; - - u32 phy_mode; -}; - -struct hdmi_8996_v3_post_divider { - u64 vco_freq; - u64 hsclk_divsel; - u64 vco_ratio; - u64 tx_band_sel; - u64 half_rate_mode; -}; - -static inline struct hdmi_pll_vco_clk *to_hdmi_8996_vco_clk(struct clk *clk) -{ - return container_of(clk, struct hdmi_pll_vco_clk, c); -} - -static inline u64 hdmi_8996_v1_get_post_div_lt_2g(u64 bclk) -{ - if (bclk >= HDMI_2400MHZ_BIT_CLK_HZ) - return 2; - else if (bclk >= HDMI_1700MHZ_BIT_CLK_HZ) - return 3; - else if (bclk >= HDMI_1200MHZ_BIT_CLK_HZ) - return 4; - else if (bclk >= HDMI_850MHZ_BIT_CLK_HZ) - return 3; - else if (bclk >= HDMI_600MHZ_BIT_CLK_HZ) - return 4; - else if (bclk >= HDMI_450MHZ_BIT_CLK_HZ) - return 3; - else if (bclk >= HDMI_300MHZ_BIT_CLK_HZ) - return 4; - - return HDMI_64B_ERR_VAL; -} - -static inline u64 hdmi_8996_v2_get_post_div_lt_2g(u64 bclk, u64 vco_range) -{ - u64 hdmi_8ghz = vco_range; - u64 tmp_calc; - - hdmi_8ghz <<= 2; - tmp_calc = hdmi_8ghz; - do_div(tmp_calc, 6U); - - if (bclk >= vco_range) - return 2; - else if (bclk >= tmp_calc) - return 3; - else if (bclk >= vco_range >> 1) - return 4; - - tmp_calc = hdmi_8ghz; - do_div(tmp_calc, 12U); - if (bclk >= tmp_calc) - return 3; - else if (bclk >= vco_range >> 2) - return 4; - - tmp_calc = hdmi_8ghz; - do_div(tmp_calc, 24U); - if (bclk >= tmp_calc) - return 3; - else if (bclk >= vco_range >> 3) - return 4; - - return HDMI_64B_ERR_VAL; -} - -static inline u64 hdmi_8996_v2_get_post_div_gt_2g(u64 hsclk) -{ - if (hsclk >= 0 && hsclk <= 3) - return hsclk + 1; - - return HDMI_64B_ERR_VAL; -} - -static inline u64 hdmi_8996_get_coreclk_div_lt_2g(u64 bclk) -{ - if (bclk >= HDMI_1334MHZ_BIT_CLK_HZ) - return 1; - else if (bclk >= HDMI_1000MHZ_BIT_CLK_HZ) - return 1; - else if (bclk >= HDMI_667MHZ_BIT_CLK_HZ) - return 2; - else if (bclk >= HDMI_500MHZ_BIT_CLK_HZ) - return 2; - else if (bclk >= HDMI_334MHZ_BIT_CLK_HZ) - return 3; - else if (bclk >= HDMI_250MHZ_BIT_CLK_HZ) - return 3; - - return HDMI_64B_ERR_VAL; -} - -static inline u64 hdmi_8996_get_coreclk_div_ratio(u64 clks_pll_divsel, - u64 coreclk_div) -{ - if (clks_pll_divsel == 0) - return coreclk_div*2; - else if (clks_pll_divsel == 1) - return coreclk_div*4; - - return HDMI_64B_ERR_VAL; -} - -static inline u64 hdmi_8996_v1_get_tx_band(u64 bclk) -{ - if (bclk >= 2400000000UL) - return 0; - if (bclk >= 1200000000UL) - return 1; - if (bclk >= 600000000UL) - return 2; - if (bclk >= 300000000UL) - return 3; - - return HDMI_64B_ERR_VAL; -} - -static inline u64 hdmi_8996_v2_get_tx_band(u64 bclk, u64 vco_range) -{ - if (bclk >= vco_range) - return 0; - else if (bclk >= vco_range >> 1) - return 1; - else if (bclk >= vco_range >> 2) - return 2; - else if (bclk >= vco_range >> 3) - return 3; - - return HDMI_64B_ERR_VAL; -} - -static inline u64 hdmi_8996_v1_get_hsclk(u64 fdata) -{ - if (fdata >= 9600000000UL) - return 0; - else if (fdata >= 4800000000UL) - return 1; - else if (fdata >= 3200000000UL) - return 2; - else if (fdata >= 2400000000UL) - return 3; - - return HDMI_64B_ERR_VAL; -} - -static inline u64 hdmi_8996_v2_get_hsclk(u64 fdata, u64 vco_range) -{ - u64 tmp_calc = vco_range; - - tmp_calc <<= 2; - do_div(tmp_calc, 3U); - if (fdata >= (vco_range << 2)) - return 0; - else if (fdata >= (vco_range << 1)) - return 1; - else if (fdata >= tmp_calc) - return 2; - else if (fdata >= vco_range) - return 3; - - return HDMI_64B_ERR_VAL; - -} - -static inline u64 hdmi_8996_v2_get_vco_freq(u64 bclk, u64 vco_range) -{ - u64 tx_band_div_ratio = 1U << hdmi_8996_v2_get_tx_band(bclk, vco_range); - u64 pll_post_div_ratio; - - if (bclk >= vco_range) { - u64 hsclk = hdmi_8996_v2_get_hsclk(bclk, vco_range); - - pll_post_div_ratio = hdmi_8996_v2_get_post_div_gt_2g(hsclk); - } else { - pll_post_div_ratio = hdmi_8996_v2_get_post_div_lt_2g(bclk, - vco_range); - } - - return bclk * (pll_post_div_ratio * tx_band_div_ratio); -} - -static inline u64 hdmi_8996_v2_get_fdata(u64 bclk, u64 vco_range) -{ - if (bclk >= vco_range) - return bclk; - u64 tmp_calc = hdmi_8996_v2_get_vco_freq(bclk, vco_range); - u64 pll_post_div_ratio_lt_2g = hdmi_8996_v2_get_post_div_lt_2g( - bclk, vco_range); - if (pll_post_div_ratio_lt_2g == HDMI_64B_ERR_VAL) - return HDMI_64B_ERR_VAL; - - do_div(tmp_calc, pll_post_div_ratio_lt_2g); - return tmp_calc; -} - -static inline u64 hdmi_8996_get_cpctrl(u64 frac_start, bool gen_ssc) -{ - if ((frac_start != 0) || gen_ssc) - /* - * This should be ROUND(11/(19.2/20))). - * Since ref clock does not change, hardcoding to 11 - */ - return 0xB; - - return 0x23; -} - -static inline u64 hdmi_8996_get_rctrl(u64 frac_start, bool gen_ssc) -{ - if ((frac_start != 0) || gen_ssc) - return 0x16; - - return 0x10; -} - -static inline u64 hdmi_8996_get_cctrl(u64 frac_start, bool gen_ssc) -{ - if ((frac_start != 0) || (gen_ssc)) - return 0x28; - - return 0x1; -} - -static inline u64 hdmi_8996_get_integloop_gain(u64 frac_start, bool gen_ssc) -{ - if ((frac_start != 0) || gen_ssc) - return 0x80; - - return 0xC4; -} - -static inline u64 hdmi_8996_v3_get_integloop_gain(u64 frac_start, u64 bclk, - bool gen_ssc) -{ - u64 digclk_divsel = bclk >= HDMI_DIG_FREQ_BIT_CLK_THRESHOLD ? 1 : 2; - u64 base = ((frac_start != 0) || gen_ssc) ? 0x40 : 0xC4; - - base <<= digclk_divsel; - - return (base <= 2046 ? base : 0x7FE); -} - -static inline u64 hdmi_8996_get_vco_tune(u64 fdata, u64 div) -{ - u64 vco_tune; - - vco_tune = fdata * div; - do_div(vco_tune, 1000000); - vco_tune = 13000 - vco_tune - 256; - do_div(vco_tune, 5); - - return vco_tune; -} - -static inline u64 hdmi_8996_get_pll_cmp(u64 pll_cmp_cnt, u64 core_clk) -{ - u64 pll_cmp; - u64 rem; - - pll_cmp = pll_cmp_cnt * core_clk; - rem = do_div(pll_cmp, HDMI_REF_CLOCK); - if (rem > (HDMI_REF_CLOCK >> 1)) - pll_cmp++; - pll_cmp -= 1; - - return pll_cmp; -} - -static inline u64 hdmi_8996_v3_get_pll_cmp(u64 pll_cmp_cnt, u64 fdata) -{ - u64 dividend = pll_cmp_cnt * fdata; - u64 divisor = HDMI_REF_CLOCK * 10; - u64 rem; - - rem = do_div(dividend, divisor); - if (rem > (divisor >> 1)) - dividend++; - - return dividend - 1; -} - -static int hdmi_8996_v3_get_post_div(struct hdmi_8996_v3_post_divider *pd, - u64 bclk) -{ - u32 ratio[] = {2, 3, 4, 5, 6, 9, 10, 12, 14, 15, 20, 21, 25, 28, 35}; - u32 tx_band_sel[] = {0, 1, 2, 3}; - u64 vco_freq[60]; - u64 vco, vco_optimal, half_rate_mode = 0; - int vco_optimal_index, vco_freq_index; - int i, j, k, x; - - for (i = 0; i <= 1; i++) { - vco_optimal = HDMI_VCO_MAX_FREQ; - vco_optimal_index = -1; - vco_freq_index = 0; - for (j = 0; j < 15; j++) { - for (k = 0; k < 4; k++) { - u64 ratio_mult = ratio[j] << tx_band_sel[k]; - - vco = bclk >> half_rate_mode; - vco *= ratio_mult; - vco_freq[vco_freq_index++] = vco; - } - } - - for (x = 0; x < 60; x++) { - u64 vco_tmp = vco_freq[x]; - - if ((vco_tmp >= HDMI_VCO_MIN_FREQ) && - (vco_tmp <= vco_optimal)) { - vco_optimal = vco_tmp; - vco_optimal_index = x; - } - } - - if (vco_optimal_index == -1) { - if (!half_rate_mode) - half_rate_mode++; - else - return -EINVAL; - } else { - pd->vco_freq = vco_optimal; - pd->tx_band_sel = tx_band_sel[vco_optimal_index % 4]; - pd->vco_ratio = ratio[vco_optimal_index / 4]; - break; - } - } - - switch (pd->vco_ratio) { - case 2: - pd->hsclk_divsel = 0; - break; - case 3: - pd->hsclk_divsel = 4; - break; - case 4: - pd->hsclk_divsel = 8; - break; - case 5: - pd->hsclk_divsel = 12; - break; - case 6: - pd->hsclk_divsel = 1; - break; - case 9: - pd->hsclk_divsel = 5; - break; - case 10: - pd->hsclk_divsel = 2; - break; - case 12: - pd->hsclk_divsel = 9; - break; - case 14: - pd->hsclk_divsel = 3; - break; - case 15: - pd->hsclk_divsel = 13; - break; - case 20: - pd->hsclk_divsel = 10; - break; - case 21: - pd->hsclk_divsel = 7; - break; - case 25: - pd->hsclk_divsel = 14; - break; - case 28: - pd->hsclk_divsel = 11; - break; - case 35: - pd->hsclk_divsel = 15; - break; - } - - return 0; -} - -static int hdmi_8996_v1_calculate(u32 pix_clk, - struct hdmi_8996_phy_pll_reg_cfg *cfg) -{ - int rc = -EINVAL; - u64 fdata, clk_divtx, tmds_clk; - u64 bclk; - u64 post_div_gt_2g; - u64 post_div_lt_2g; - u64 coreclk_div1_lt_2g; - u64 core_clk_div_ratio; - u64 core_clk; - u64 pll_cmp; - u64 tx_band; - u64 tx_band_div_ratio; - u64 hsclk; - u64 dec_start; - u64 frac_start; - u64 pll_divisor = 4 * HDMI_REF_CLOCK; - u64 cpctrl; - u64 rctrl; - u64 cctrl; - u64 integloop_gain; - u64 vco_tune; - u64 vco_freq; - u64 rem; - - /* FDATA, CLK_DIVTX, PIXEL_CLK, TMDS_CLK */ - bclk = ((u64)pix_clk) * HDMI_BIT_CLK_TO_PIX_CLK_RATIO; - - if (bclk > HDMI_HIGH_FREQ_BIT_CLK_THRESHOLD) - tmds_clk = bclk/4; - else - tmds_clk = bclk; - - post_div_lt_2g = hdmi_8996_v1_get_post_div_lt_2g(bclk); - if (post_div_lt_2g == HDMI_64B_ERR_VAL) - goto fail; - - coreclk_div1_lt_2g = hdmi_8996_get_coreclk_div_lt_2g(bclk); - - core_clk_div_ratio = hdmi_8996_get_coreclk_div_ratio( - HDMI_CLKS_PLL_DIVSEL, HDMI_CORECLK_DIV); - - tx_band = hdmi_8996_v1_get_tx_band(bclk); - if (tx_band == HDMI_64B_ERR_VAL) - goto fail; - - tx_band_div_ratio = 1 << tx_band; - - if (bclk >= HDMI_2400MHZ_BIT_CLK_HZ) { - fdata = bclk; - hsclk = hdmi_8996_v1_get_hsclk(fdata); - if (hsclk == HDMI_64B_ERR_VAL) - goto fail; - - post_div_gt_2g = (hsclk <= 3) ? (hsclk + 1) : HDMI_64B_ERR_VAL; - if (post_div_gt_2g == HDMI_64B_ERR_VAL) - goto fail; - - vco_freq = bclk * (post_div_gt_2g * tx_band_div_ratio); - clk_divtx = vco_freq; - do_div(clk_divtx, post_div_gt_2g); - } else { - vco_freq = bclk * (post_div_lt_2g * tx_band_div_ratio); - fdata = vco_freq; - do_div(fdata, post_div_lt_2g); - hsclk = hdmi_8996_v1_get_hsclk(fdata); - if (hsclk == HDMI_64B_ERR_VAL) - goto fail; - - clk_divtx = vco_freq; - do_div(clk_divtx, post_div_lt_2g); - post_div_gt_2g = (hsclk <= 3) ? (hsclk + 1) : HDMI_64B_ERR_VAL; - if (post_div_gt_2g == HDMI_64B_ERR_VAL) - goto fail; - } - - /* Decimal and fraction values */ - dec_start = fdata * post_div_gt_2g; - do_div(dec_start, pll_divisor); - frac_start = ((pll_divisor - (((dec_start + 1) * pll_divisor) - - (fdata * post_div_gt_2g))) * (1 << 20)); - rem = do_div(frac_start, pll_divisor); - /* Round off frac_start to closest integer */ - if (rem >= (pll_divisor >> 1)) - frac_start++; - - cpctrl = hdmi_8996_get_cpctrl(frac_start, false); - rctrl = hdmi_8996_get_rctrl(frac_start, false); - cctrl = hdmi_8996_get_cctrl(frac_start, false); - integloop_gain = hdmi_8996_get_integloop_gain(frac_start, false); - vco_tune = hdmi_8996_get_vco_tune(fdata, post_div_gt_2g); - - core_clk = clk_divtx; - do_div(core_clk, core_clk_div_ratio); - pll_cmp = hdmi_8996_get_pll_cmp(1024, core_clk); - - /* Debug dump */ - DEV_DBG("%s: VCO freq: %llu\n", __func__, vco_freq); - DEV_DBG("%s: fdata: %llu\n", __func__, fdata); - DEV_DBG("%s: CLK_DIVTX: %llu\n", __func__, clk_divtx); - DEV_DBG("%s: pix_clk: %d\n", __func__, pix_clk); - DEV_DBG("%s: tmds clk: %llu\n", __func__, tmds_clk); - DEV_DBG("%s: HSCLK_SEL: %llu\n", __func__, hsclk); - DEV_DBG("%s: DEC_START: %llu\n", __func__, dec_start); - DEV_DBG("%s: DIV_FRAC_START: %llu\n", __func__, frac_start); - DEV_DBG("%s: PLL_CPCTRL: %llu\n", __func__, cpctrl); - DEV_DBG("%s: PLL_RCTRL: %llu\n", __func__, rctrl); - DEV_DBG("%s: PLL_CCTRL: %llu\n", __func__, cctrl); - DEV_DBG("%s: INTEGLOOP_GAIN: %llu\n", __func__, integloop_gain); - DEV_DBG("%s: VCO_TUNE: %llu\n", __func__, vco_tune); - DEV_DBG("%s: TX_BAND: %llu\n", __func__, tx_band); - DEV_DBG("%s: PLL_CMP: %llu\n", __func__, pll_cmp); - - /* Convert these values to register specific values */ - cfg->tx_l0_lane_mode = 0x3; - cfg->tx_l2_lane_mode = 0x3; - cfg->tx_l0_tx_band = tx_band + 4; - cfg->tx_l1_tx_band = tx_band + 4; - cfg->tx_l2_tx_band = tx_band + 4; - cfg->tx_l3_tx_band = tx_band + 4; - cfg->tx_l0_res_code_lane_tx = 0x33; - cfg->tx_l1_res_code_lane_tx = 0x33; - cfg->tx_l2_res_code_lane_tx = 0x33; - cfg->tx_l3_res_code_lane_tx = 0x33; - cfg->com_restrim_ctrl = 0x0; - cfg->com_vco_tune_ctrl = 0x1C; - - cfg->com_svs_mode_clk_sel = - (bclk >= HDMI_DIG_FREQ_BIT_CLK_THRESHOLD ? 1 : 2); - cfg->com_hsclk_sel = (0x28 | hsclk); - cfg->com_pll_cctrl_mode0 = cctrl; - cfg->com_pll_rctrl_mode0 = rctrl; - cfg->com_cp_ctrl_mode0 = cpctrl; - cfg->com_dec_start_mode0 = dec_start; - cfg->com_div_frac_start1_mode0 = (frac_start & 0xFF); - cfg->com_div_frac_start2_mode0 = ((frac_start & 0xFF00) >> 8); - cfg->com_div_frac_start3_mode0 = ((frac_start & 0xF0000) >> 16); - cfg->com_integloop_gain0_mode0 = (integloop_gain & 0xFF); - cfg->com_integloop_gain1_mode0 = ((integloop_gain & 0xF00) >> 8); - cfg->com_lock_cmp1_mode0 = (pll_cmp & 0xFF); - cfg->com_lock_cmp2_mode0 = ((pll_cmp & 0xFF00) >> 8); - cfg->com_lock_cmp3_mode0 = ((pll_cmp & 0x30000) >> 16); - cfg->com_core_clk_en = (0x6C | (HDMI_CLKS_PLL_DIVSEL << 4)); - cfg->com_coreclk_div = HDMI_CORECLK_DIV; - - if (bclk > HDMI_HIGH_FREQ_BIT_CLK_THRESHOLD) { - cfg->tx_l0_tx_drv_lvl = 0x25; - cfg->tx_l0_tx_emp_post1_lvl = 0x23; - cfg->tx_l1_tx_drv_lvl = 0x25; - cfg->tx_l1_tx_emp_post1_lvl = 0x23; - cfg->tx_l2_tx_drv_lvl = 0x25; - cfg->tx_l2_tx_emp_post1_lvl = 0x23; - cfg->tx_l3_tx_drv_lvl = 0x22; - cfg->tx_l3_tx_emp_post1_lvl = 0x27; - cfg->tx_l0_vmode_ctrl1 = 0x00; - cfg->tx_l0_vmode_ctrl2 = 0x0D; - cfg->tx_l1_vmode_ctrl1 = 0x00; - cfg->tx_l1_vmode_ctrl2 = 0x0D; - cfg->tx_l2_vmode_ctrl1 = 0x00; - cfg->tx_l2_vmode_ctrl2 = 0x0D; - cfg->tx_l3_vmode_ctrl1 = 0x00; - cfg->tx_l3_vmode_ctrl2 = 0x00; - cfg->com_restrim_ctrl = 0x0; - } else if (bclk > HDMI_MID_FREQ_BIT_CLK_THRESHOLD) { - cfg->tx_l0_tx_drv_lvl = 0x25; - cfg->tx_l0_tx_emp_post1_lvl = 0x23; - cfg->tx_l1_tx_drv_lvl = 0x25; - cfg->tx_l1_tx_emp_post1_lvl = 0x23; - cfg->tx_l2_tx_drv_lvl = 0x25; - cfg->tx_l2_tx_emp_post1_lvl = 0x23; - cfg->tx_l3_tx_drv_lvl = 0x25; - cfg->tx_l3_tx_emp_post1_lvl = 0x23; - cfg->tx_l0_vmode_ctrl1 = 0x00; - cfg->tx_l0_vmode_ctrl2 = 0x0D; - cfg->tx_l1_vmode_ctrl1 = 0x00; - cfg->tx_l1_vmode_ctrl2 = 0x0D; - cfg->tx_l2_vmode_ctrl1 = 0x00; - cfg->tx_l2_vmode_ctrl2 = 0x0D; - cfg->tx_l3_vmode_ctrl1 = 0x00; - cfg->tx_l3_vmode_ctrl2 = 0x00; - cfg->com_restrim_ctrl = 0x0; - } else { - cfg->tx_l0_tx_drv_lvl = 0x20; - cfg->tx_l0_tx_emp_post1_lvl = 0x20; - cfg->tx_l1_tx_drv_lvl = 0x20; - cfg->tx_l1_tx_emp_post1_lvl = 0x20; - cfg->tx_l2_tx_drv_lvl = 0x20; - cfg->tx_l2_tx_emp_post1_lvl = 0x20; - cfg->tx_l3_tx_drv_lvl = 0x20; - cfg->tx_l3_tx_emp_post1_lvl = 0x20; - cfg->tx_l0_vmode_ctrl1 = 0x00; - cfg->tx_l0_vmode_ctrl2 = 0x0E; - cfg->tx_l1_vmode_ctrl1 = 0x00; - cfg->tx_l1_vmode_ctrl2 = 0x0E; - cfg->tx_l2_vmode_ctrl1 = 0x00; - cfg->tx_l2_vmode_ctrl2 = 0x0E; - cfg->tx_l3_vmode_ctrl1 = 0x00; - cfg->tx_l3_vmode_ctrl2 = 0x0E; - cfg->com_restrim_ctrl = 0xD8; - } - - cfg->phy_mode = (bclk > HDMI_HIGH_FREQ_BIT_CLK_THRESHOLD) ? 0x10 : 0x0; - DEV_DBG("HDMI 8996 PLL: PLL Settings\n"); - DEV_DBG("PLL PARAM: tx_l0_lane_mode = 0x%x\n", cfg->tx_l0_lane_mode); - DEV_DBG("PLL PARAM: tx_l2_lane_mode = 0x%x\n", cfg->tx_l2_lane_mode); - DEV_DBG("PLL PARAM: tx_l0_tx_band = 0x%x\n", cfg->tx_l0_tx_band); - DEV_DBG("PLL PARAM: tx_l1_tx_band = 0x%x\n", cfg->tx_l1_tx_band); - DEV_DBG("PLL PARAM: tx_l2_tx_band = 0x%x\n", cfg->tx_l2_tx_band); - DEV_DBG("PLL PARAM: tx_l3_tx_band = 0x%x\n", cfg->tx_l3_tx_band); - DEV_DBG("PLL PARAM: com_svs_mode_clk_sel = 0x%x\n", - cfg->com_svs_mode_clk_sel); - DEV_DBG("PLL PARAM: com_hsclk_sel = 0x%x\n", cfg->com_hsclk_sel); - DEV_DBG("PLL PARAM: com_pll_cctrl_mode0 = 0x%x\n", - cfg->com_pll_cctrl_mode0); - DEV_DBG("PLL PARAM: com_pll_rctrl_mode0 = 0x%x\n", - cfg->com_pll_rctrl_mode0); - DEV_DBG("PLL PARAM: com_cp_ctrl_mode0 = 0x%x\n", - cfg->com_cp_ctrl_mode0); - DEV_DBG("PLL PARAM: com_dec_start_mode0 = 0x%x\n", - cfg->com_dec_start_mode0); - DEV_DBG("PLL PARAM: com_div_frac_start1_mode0 = 0x%x\n", - cfg->com_div_frac_start1_mode0); - DEV_DBG("PLL PARAM: com_div_frac_start2_mode0 = 0x%x\n", - cfg->com_div_frac_start2_mode0); - DEV_DBG("PLL PARAM: com_div_frac_start3_mode0 = 0x%x\n", - cfg->com_div_frac_start3_mode0); - DEV_DBG("PLL PARAM: com_integloop_gain0_mode0 = 0x%x\n", - cfg->com_integloop_gain0_mode0); - DEV_DBG("PLL PARAM: com_integloop_gain1_mode0 = 0x%x\n", - cfg->com_integloop_gain1_mode0); - DEV_DBG("PLL PARAM: com_lock_cmp1_mode0 = 0x%x\n", - cfg->com_lock_cmp1_mode0); - DEV_DBG("PLL PARAM: com_lock_cmp2_mode0 = 0x%x\n", - cfg->com_lock_cmp2_mode0); - DEV_DBG("PLL PARAM: com_lock_cmp3_mode0 = 0x%x\n", - cfg->com_lock_cmp3_mode0); - DEV_DBG("PLL PARAM: com_core_clk_en = 0x%x\n", cfg->com_core_clk_en); - DEV_DBG("PLL PARAM: com_coreclk_div = 0x%x\n", cfg->com_coreclk_div); - DEV_DBG("PLL PARAM: com_restrim_ctrl = 0x%x\n", cfg->com_restrim_ctrl); - - DEV_DBG("PLL PARAM: l0_tx_drv_lvl = 0x%x\n", cfg->tx_l0_tx_drv_lvl); - DEV_DBG("PLL PARAM: l0_tx_emp_post1_lvl = 0x%x\n", - cfg->tx_l0_tx_emp_post1_lvl); - DEV_DBG("PLL PARAM: l1_tx_drv_lvl = 0x%x\n", cfg->tx_l1_tx_drv_lvl); - DEV_DBG("PLL PARAM: l1_tx_emp_post1_lvl = 0x%x\n", - cfg->tx_l1_tx_emp_post1_lvl); - DEV_DBG("PLL PARAM: l2_tx_drv_lvl = 0x%x\n", cfg->tx_l2_tx_drv_lvl); - DEV_DBG("PLL PARAM: l2_tx_emp_post1_lvl = 0x%x\n", - cfg->tx_l2_tx_emp_post1_lvl); - DEV_DBG("PLL PARAM: l3_tx_drv_lvl = 0x%x\n", cfg->tx_l3_tx_drv_lvl); - DEV_DBG("PLL PARAM: l3_tx_emp_post1_lvl = 0x%x\n", - cfg->tx_l3_tx_emp_post1_lvl); - - DEV_DBG("PLL PARAM: l0_vmode_ctrl1 = 0x%x\n", cfg->tx_l0_vmode_ctrl1); - DEV_DBG("PLL PARAM: l0_vmode_ctrl2 = 0x%x\n", cfg->tx_l0_vmode_ctrl2); - DEV_DBG("PLL PARAM: l1_vmode_ctrl1 = 0x%x\n", cfg->tx_l1_vmode_ctrl1); - DEV_DBG("PLL PARAM: l1_vmode_ctrl2 = 0x%x\n", cfg->tx_l1_vmode_ctrl2); - DEV_DBG("PLL PARAM: l2_vmode_ctrl1 = 0x%x\n", cfg->tx_l2_vmode_ctrl1); - DEV_DBG("PLL PARAM: l2_vmode_ctrl2 = 0x%x\n", cfg->tx_l2_vmode_ctrl2); - DEV_DBG("PLL PARAM: l3_vmode_ctrl1 = 0x%x\n", cfg->tx_l3_vmode_ctrl1); - DEV_DBG("PLL PARAM: l3_vmode_ctrl2 = 0x%x\n", cfg->tx_l3_vmode_ctrl2); - DEV_DBG("PLL PARAM: tx_l0_res_code_lane_tx = 0x%x\n", - cfg->tx_l0_res_code_lane_tx); - DEV_DBG("PLL PARAM: tx_l1_res_code_lane_tx = 0x%x\n", - cfg->tx_l1_res_code_lane_tx); - DEV_DBG("PLL PARAM: tx_l2_res_code_lane_tx = 0x%x\n", - cfg->tx_l2_res_code_lane_tx); - DEV_DBG("PLL PARAM: tx_l3_res_code_lane_tx = 0x%x\n", - cfg->tx_l3_res_code_lane_tx); - - DEV_DBG("PLL PARAM: phy_mode = 0x%x\n", cfg->phy_mode); - rc = 0; -fail: - return rc; -} - -static int hdmi_8996_v2_calculate(u32 pix_clk, - struct hdmi_8996_phy_pll_reg_cfg *cfg) -{ - int rc = -EINVAL; - u64 fdata, clk_divtx, tmds_clk; - u64 bclk; - u64 post_div; - u64 core_clk_div; - u64 core_clk_div_ratio; - u64 core_clk; - u64 pll_cmp; - u64 tx_band; - u64 tx_band_div_ratio; - u64 hsclk; - u64 dec_start; - u64 frac_start; - u64 pll_divisor = 4 * HDMI_REF_CLOCK; - u64 cpctrl; - u64 rctrl; - u64 cctrl; - u64 integloop_gain; - u64 vco_tune; - u64 vco_freq; - u64 vco_range; - u64 rem; - - /* FDATA, CLK_DIVTX, PIXEL_CLK, TMDS_CLK */ - bclk = ((u64)pix_clk) * HDMI_BIT_CLK_TO_PIX_CLK_RATIO; - - if (bclk > HDMI_HIGH_FREQ_BIT_CLK_THRESHOLD) - tmds_clk = pix_clk >> 2; - else - tmds_clk = pix_clk; - - vco_range = bclk < HDMI_282MHZ_BIT_CLK_HZ ? HDMI_2000MHZ_BIT_CLK_HZ : - HDMI_2250MHZ_BIT_CLK_HZ; - - fdata = hdmi_8996_v2_get_fdata(bclk, vco_range); - if (fdata == HDMI_64B_ERR_VAL) - goto fail; - - hsclk = hdmi_8996_v2_get_hsclk(fdata, vco_range); - if (hsclk == HDMI_64B_ERR_VAL) - goto fail; - - if (bclk >= vco_range) - post_div = hdmi_8996_v2_get_post_div_gt_2g(hsclk); - else - post_div = hdmi_8996_v2_get_post_div_lt_2g(bclk, vco_range); - - if (post_div == HDMI_64B_ERR_VAL) - goto fail; - - core_clk_div = 5; - core_clk_div_ratio = core_clk_div * 2; - - tx_band = hdmi_8996_v2_get_tx_band(bclk, vco_range); - if (tx_band == HDMI_64B_ERR_VAL) - goto fail; - - tx_band_div_ratio = 1 << tx_band; - - vco_freq = hdmi_8996_v2_get_vco_freq(bclk, vco_range); - clk_divtx = vco_freq; - do_div(clk_divtx, post_div); - - /* Decimal and fraction values */ - dec_start = fdata * post_div; - do_div(dec_start, pll_divisor); - frac_start = ((pll_divisor - (((dec_start + 1) * pll_divisor) - - (fdata * post_div))) * (1 << 20)); - rem = do_div(frac_start, pll_divisor); - /* Round off frac_start to closest integer */ - if (rem >= (pll_divisor >> 1)) - frac_start++; - - cpctrl = hdmi_8996_get_cpctrl(frac_start, false); - rctrl = hdmi_8996_get_rctrl(frac_start, false); - cctrl = hdmi_8996_get_cctrl(frac_start, false); - integloop_gain = hdmi_8996_get_integloop_gain(frac_start, false); - vco_tune = hdmi_8996_get_vco_tune(fdata, post_div); - - core_clk = clk_divtx; - do_div(core_clk, core_clk_div_ratio); - pll_cmp = hdmi_8996_get_pll_cmp(1024, core_clk); - - /* Debug dump */ - DEV_DBG("%s: VCO freq: %llu\n", __func__, vco_freq); - DEV_DBG("%s: fdata: %llu\n", __func__, fdata); - DEV_DBG("%s: CLK_DIVTX: %llu\n", __func__, clk_divtx); - DEV_DBG("%s: pix_clk: %d\n", __func__, pix_clk); - DEV_DBG("%s: tmds clk: %llu\n", __func__, tmds_clk); - DEV_DBG("%s: HSCLK_SEL: %llu\n", __func__, hsclk); - DEV_DBG("%s: DEC_START: %llu\n", __func__, dec_start); - DEV_DBG("%s: DIV_FRAC_START: %llu\n", __func__, frac_start); - DEV_DBG("%s: PLL_CPCTRL: %llu\n", __func__, cpctrl); - DEV_DBG("%s: PLL_RCTRL: %llu\n", __func__, rctrl); - DEV_DBG("%s: PLL_CCTRL: %llu\n", __func__, cctrl); - DEV_DBG("%s: INTEGLOOP_GAIN: %llu\n", __func__, integloop_gain); - DEV_DBG("%s: VCO_TUNE: %llu\n", __func__, vco_tune); - DEV_DBG("%s: TX_BAND: %llu\n", __func__, tx_band); - DEV_DBG("%s: PLL_CMP: %llu\n", __func__, pll_cmp); - - /* Convert these values to register specific values */ - cfg->tx_l0_lane_mode = 0x3; - cfg->tx_l2_lane_mode = 0x3; - cfg->tx_l0_tx_band = tx_band + 4; - cfg->tx_l1_tx_band = tx_band + 4; - cfg->tx_l2_tx_band = tx_band + 4; - cfg->tx_l3_tx_band = tx_band + 4; - - if (bclk > HDMI_DIG_FREQ_BIT_CLK_THRESHOLD) - cfg->com_svs_mode_clk_sel = 1; - else - cfg->com_svs_mode_clk_sel = 2; - - cfg->com_hsclk_sel = (0x28 | hsclk); - cfg->com_pll_cctrl_mode0 = cctrl; - cfg->com_pll_rctrl_mode0 = rctrl; - cfg->com_cp_ctrl_mode0 = cpctrl; - cfg->com_dec_start_mode0 = dec_start; - cfg->com_div_frac_start1_mode0 = (frac_start & 0xFF); - cfg->com_div_frac_start2_mode0 = ((frac_start & 0xFF00) >> 8); - cfg->com_div_frac_start3_mode0 = ((frac_start & 0xF0000) >> 16); - cfg->com_integloop_gain0_mode0 = (integloop_gain & 0xFF); - cfg->com_integloop_gain1_mode0 = ((integloop_gain & 0xF00) >> 8); - cfg->com_lock_cmp1_mode0 = (pll_cmp & 0xFF); - cfg->com_lock_cmp2_mode0 = ((pll_cmp & 0xFF00) >> 8); - cfg->com_lock_cmp3_mode0 = ((pll_cmp & 0x30000) >> 16); - cfg->com_core_clk_en = (0x6C | (HDMI_CLKS_PLL_DIVSEL << 4)); - cfg->com_coreclk_div = HDMI_CORECLK_DIV; - cfg->com_vco_tune_ctrl = 0x0; - - if (bclk > HDMI_HIGH_FREQ_BIT_CLK_THRESHOLD) { - cfg->tx_l0_tx_drv_lvl = 0x25; - cfg->tx_l0_tx_emp_post1_lvl = 0x23; - cfg->tx_l1_tx_drv_lvl = 0x25; - cfg->tx_l1_tx_emp_post1_lvl = 0x23; - cfg->tx_l2_tx_drv_lvl = 0x25; - cfg->tx_l2_tx_emp_post1_lvl = 0x23; - cfg->tx_l3_tx_drv_lvl = 0x22; - cfg->tx_l3_tx_emp_post1_lvl = 0x27; - cfg->tx_l0_vmode_ctrl1 = 0x00; - cfg->tx_l0_vmode_ctrl2 = 0x0D; - cfg->tx_l1_vmode_ctrl1 = 0x00; - cfg->tx_l1_vmode_ctrl2 = 0x0D; - cfg->tx_l2_vmode_ctrl1 = 0x00; - cfg->tx_l2_vmode_ctrl2 = 0x0D; - cfg->tx_l3_vmode_ctrl1 = 0x00; - cfg->tx_l3_vmode_ctrl2 = 0x00; - cfg->tx_l0_res_code_lane_tx = 0x3F; - cfg->tx_l1_res_code_lane_tx = 0x3F; - cfg->tx_l2_res_code_lane_tx = 0x3F; - cfg->tx_l3_res_code_lane_tx = 0x3F; - cfg->com_restrim_ctrl = 0x0; - } else if (bclk > HDMI_MID_FREQ_BIT_CLK_THRESHOLD) { - cfg->tx_l0_tx_drv_lvl = 0x25; - cfg->tx_l0_tx_emp_post1_lvl = 0x23; - cfg->tx_l1_tx_drv_lvl = 0x25; - cfg->tx_l1_tx_emp_post1_lvl = 0x23; - cfg->tx_l2_tx_drv_lvl = 0x25; - cfg->tx_l2_tx_emp_post1_lvl = 0x23; - cfg->tx_l3_tx_drv_lvl = 0x25; - cfg->tx_l3_tx_emp_post1_lvl = 0x23; - cfg->tx_l0_vmode_ctrl1 = 0x00; - cfg->tx_l0_vmode_ctrl2 = 0x0D; - cfg->tx_l1_vmode_ctrl1 = 0x00; - cfg->tx_l1_vmode_ctrl2 = 0x0D; - cfg->tx_l2_vmode_ctrl1 = 0x00; - cfg->tx_l2_vmode_ctrl2 = 0x0D; - cfg->tx_l3_vmode_ctrl1 = 0x00; - cfg->tx_l3_vmode_ctrl2 = 0x00; - cfg->tx_l0_res_code_lane_tx = 0x39; - cfg->tx_l1_res_code_lane_tx = 0x39; - cfg->tx_l2_res_code_lane_tx = 0x39; - cfg->tx_l3_res_code_lane_tx = 0x39; - cfg->com_restrim_ctrl = 0x0; - } else { - cfg->tx_l0_tx_drv_lvl = 0x20; - cfg->tx_l0_tx_emp_post1_lvl = 0x20; - cfg->tx_l1_tx_drv_lvl = 0x20; - cfg->tx_l1_tx_emp_post1_lvl = 0x20; - cfg->tx_l2_tx_drv_lvl = 0x20; - cfg->tx_l2_tx_emp_post1_lvl = 0x20; - cfg->tx_l3_tx_drv_lvl = 0x20; - cfg->tx_l3_tx_emp_post1_lvl = 0x20; - cfg->tx_l0_vmode_ctrl1 = 0x00; - cfg->tx_l0_vmode_ctrl2 = 0x0E; - cfg->tx_l1_vmode_ctrl1 = 0x00; - cfg->tx_l1_vmode_ctrl2 = 0x0E; - cfg->tx_l2_vmode_ctrl1 = 0x00; - cfg->tx_l2_vmode_ctrl2 = 0x0E; - cfg->tx_l3_vmode_ctrl1 = 0x00; - cfg->tx_l3_vmode_ctrl2 = 0x0E; - cfg->tx_l0_res_code_lane_tx = 0x3F; - cfg->tx_l1_res_code_lane_tx = 0x3F; - cfg->tx_l2_res_code_lane_tx = 0x3F; - cfg->tx_l3_res_code_lane_tx = 0x3F; - cfg->com_restrim_ctrl = 0xD8; - } - - cfg->phy_mode = (bclk > HDMI_HIGH_FREQ_BIT_CLK_THRESHOLD) ? 0x10 : 0x0; - DEV_DBG("HDMI 8996 PLL: PLL Settings\n"); - DEV_DBG("PLL PARAM: tx_l0_lane_mode = 0x%x\n", cfg->tx_l0_lane_mode); - DEV_DBG("PLL PARAM: tx_l2_lane_mode = 0x%x\n", cfg->tx_l2_lane_mode); - DEV_DBG("PLL PARAM: tx_l0_tx_band = 0x%x\n", cfg->tx_l0_tx_band); - DEV_DBG("PLL PARAM: tx_l1_tx_band = 0x%x\n", cfg->tx_l1_tx_band); - DEV_DBG("PLL PARAM: tx_l2_tx_band = 0x%x\n", cfg->tx_l2_tx_band); - DEV_DBG("PLL PARAM: tx_l3_tx_band = 0x%x\n", cfg->tx_l3_tx_band); - DEV_DBG("PLL PARAM: com_svs_mode_clk_sel = 0x%x\n", - cfg->com_svs_mode_clk_sel); - DEV_DBG("PLL PARAM: com_vco_tune_ctrl = 0x%x\n", - cfg->com_vco_tune_ctrl); - DEV_DBG("PLL PARAM: com_hsclk_sel = 0x%x\n", cfg->com_hsclk_sel); - DEV_DBG("PLL PARAM: com_lock_cmp_en = 0x%x\n", cfg->com_lock_cmp_en); - DEV_DBG("PLL PARAM: com_pll_cctrl_mode0 = 0x%x\n", - cfg->com_pll_cctrl_mode0); - DEV_DBG("PLL PARAM: com_pll_rctrl_mode0 = 0x%x\n", - cfg->com_pll_rctrl_mode0); - DEV_DBG("PLL PARAM: com_cp_ctrl_mode0 = 0x%x\n", - cfg->com_cp_ctrl_mode0); - DEV_DBG("PLL PARAM: com_dec_start_mode0 = 0x%x\n", - cfg->com_dec_start_mode0); - DEV_DBG("PLL PARAM: com_div_frac_start1_mode0 = 0x%x\n", - cfg->com_div_frac_start1_mode0); - DEV_DBG("PLL PARAM: com_div_frac_start2_mode0 = 0x%x\n", - cfg->com_div_frac_start2_mode0); - DEV_DBG("PLL PARAM: com_div_frac_start3_mode0 = 0x%x\n", - cfg->com_div_frac_start3_mode0); - DEV_DBG("PLL PARAM: com_integloop_gain0_mode0 = 0x%x\n", - cfg->com_integloop_gain0_mode0); - DEV_DBG("PLL PARAM: com_integloop_gain1_mode0 = 0x%x\n", - cfg->com_integloop_gain1_mode0); - DEV_DBG("PLL PARAM: com_lock_cmp1_mode0 = 0x%x\n", - cfg->com_lock_cmp1_mode0); - DEV_DBG("PLL PARAM: com_lock_cmp2_mode0 = 0x%x\n", - cfg->com_lock_cmp2_mode0); - DEV_DBG("PLL PARAM: com_lock_cmp3_mode0 = 0x%x\n", - cfg->com_lock_cmp3_mode0); - DEV_DBG("PLL PARAM: com_core_clk_en = 0x%x\n", cfg->com_core_clk_en); - DEV_DBG("PLL PARAM: com_coreclk_div = 0x%x\n", cfg->com_coreclk_div); - - DEV_DBG("PLL PARAM: l0_tx_drv_lvl = 0x%x\n", cfg->tx_l0_tx_drv_lvl); - DEV_DBG("PLL PARAM: l0_tx_emp_post1_lvl = 0x%x\n", - cfg->tx_l0_tx_emp_post1_lvl); - DEV_DBG("PLL PARAM: l1_tx_drv_lvl = 0x%x\n", cfg->tx_l1_tx_drv_lvl); - DEV_DBG("PLL PARAM: l1_tx_emp_post1_lvl = 0x%x\n", - cfg->tx_l1_tx_emp_post1_lvl); - DEV_DBG("PLL PARAM: l2_tx_drv_lvl = 0x%x\n", cfg->tx_l2_tx_drv_lvl); - DEV_DBG("PLL PARAM: l2_tx_emp_post1_lvl = 0x%x\n", - cfg->tx_l2_tx_emp_post1_lvl); - DEV_DBG("PLL PARAM: l3_tx_drv_lvl = 0x%x\n", cfg->tx_l3_tx_drv_lvl); - DEV_DBG("PLL PARAM: l3_tx_emp_post1_lvl = 0x%x\n", - cfg->tx_l3_tx_emp_post1_lvl); - - DEV_DBG("PLL PARAM: l0_vmode_ctrl1 = 0x%x\n", cfg->tx_l0_vmode_ctrl1); - DEV_DBG("PLL PARAM: l0_vmode_ctrl2 = 0x%x\n", cfg->tx_l0_vmode_ctrl2); - DEV_DBG("PLL PARAM: l1_vmode_ctrl1 = 0x%x\n", cfg->tx_l1_vmode_ctrl1); - DEV_DBG("PLL PARAM: l1_vmode_ctrl2 = 0x%x\n", cfg->tx_l1_vmode_ctrl2); - DEV_DBG("PLL PARAM: l2_vmode_ctrl1 = 0x%x\n", cfg->tx_l2_vmode_ctrl1); - DEV_DBG("PLL PARAM: l2_vmode_ctrl2 = 0x%x\n", cfg->tx_l2_vmode_ctrl2); - DEV_DBG("PLL PARAM: l3_vmode_ctrl1 = 0x%x\n", cfg->tx_l3_vmode_ctrl1); - DEV_DBG("PLL PARAM: l3_vmode_ctrl2 = 0x%x\n", cfg->tx_l3_vmode_ctrl2); - DEV_DBG("PLL PARAM: tx_l0_res_code_lane_tx = 0x%x\n", - cfg->tx_l0_res_code_lane_tx); - DEV_DBG("PLL PARAM: tx_l1_res_code_lane_tx = 0x%x\n", - cfg->tx_l1_res_code_lane_tx); - DEV_DBG("PLL PARAM: tx_l2_res_code_lane_tx = 0x%x\n", - cfg->tx_l2_res_code_lane_tx); - DEV_DBG("PLL PARAM: tx_l3_res_code_lane_tx = 0x%x\n", - cfg->tx_l3_res_code_lane_tx); - DEV_DBG("PLL PARAM: com_restrim_ctrl = 0x%x\n", cfg->com_restrim_ctrl); - - DEV_DBG("PLL PARAM: phy_mode = 0x%x\n", cfg->phy_mode); - rc = 0; -fail: - return rc; -} - -static int hdmi_8996_v3_calculate(u32 pix_clk, - struct hdmi_8996_phy_pll_reg_cfg *cfg) -{ - int rc = -EINVAL; - struct hdmi_8996_v3_post_divider pd; - u64 fdata, tmds_clk; - u64 bclk; - u64 pll_cmp; - u64 tx_band; - u64 hsclk; - u64 dec_start; - u64 frac_start; - u64 pll_divisor = 4 * HDMI_REF_CLOCK; - u64 cpctrl; - u64 rctrl; - u64 cctrl; - u64 integloop_gain; - u64 vco_freq; - u64 rem; - - /* FDATA, HSCLK, PIXEL_CLK, TMDS_CLK */ - bclk = ((u64)pix_clk) * HDMI_BIT_CLK_TO_PIX_CLK_RATIO; - - if (bclk > HDMI_HIGH_FREQ_BIT_CLK_THRESHOLD) - tmds_clk = pix_clk >> 2; - else - tmds_clk = pix_clk; - - if (hdmi_8996_v3_get_post_div(&pd, bclk) || pd.vco_ratio <= 0 || - pd.vco_freq <= 0) - goto fail; - - vco_freq = pd.vco_freq; - fdata = pd.vco_freq; - do_div(fdata, pd.vco_ratio); - - hsclk = pd.hsclk_divsel; - dec_start = vco_freq; - do_div(dec_start, pll_divisor); - - frac_start = vco_freq * (1 << 20); - rem = do_div(frac_start, pll_divisor); - frac_start -= dec_start * (1 << 20); - if (rem > (pll_divisor >> 1)) - frac_start++; - - cpctrl = hdmi_8996_get_cpctrl(frac_start, false); - rctrl = hdmi_8996_get_rctrl(frac_start, false); - cctrl = hdmi_8996_get_cctrl(frac_start, false); - integloop_gain = hdmi_8996_v3_get_integloop_gain(frac_start, bclk, - false); - pll_cmp = hdmi_8996_v3_get_pll_cmp(1024, fdata); - tx_band = pd.tx_band_sel; - - /* Debug dump */ - DEV_DBG("%s: VCO freq: %llu\n", __func__, vco_freq); - DEV_DBG("%s: fdata: %llu\n", __func__, fdata); - DEV_DBG("%s: pix_clk: %d\n", __func__, pix_clk); - DEV_DBG("%s: tmds clk: %llu\n", __func__, tmds_clk); - DEV_DBG("%s: HSCLK_SEL: %llu\n", __func__, hsclk); - DEV_DBG("%s: DEC_START: %llu\n", __func__, dec_start); - DEV_DBG("%s: DIV_FRAC_START: %llu\n", __func__, frac_start); - DEV_DBG("%s: PLL_CPCTRL: %llu\n", __func__, cpctrl); - DEV_DBG("%s: PLL_RCTRL: %llu\n", __func__, rctrl); - DEV_DBG("%s: PLL_CCTRL: %llu\n", __func__, cctrl); - DEV_DBG("%s: INTEGLOOP_GAIN: %llu\n", __func__, integloop_gain); - DEV_DBG("%s: TX_BAND: %llu\n", __func__, tx_band); - DEV_DBG("%s: PLL_CMP: %llu\n", __func__, pll_cmp); - - /* Convert these values to register specific values */ - cfg->tx_l0_tx_band = tx_band + 4; - cfg->tx_l1_tx_band = tx_band + 4; - cfg->tx_l2_tx_band = tx_band + 4; - cfg->tx_l3_tx_band = tx_band + 4; - - if (bclk > HDMI_DIG_FREQ_BIT_CLK_THRESHOLD) - cfg->com_svs_mode_clk_sel = 1; - else - cfg->com_svs_mode_clk_sel = 2; - - cfg->com_hsclk_sel = (0x20 | hsclk); - cfg->com_pll_cctrl_mode0 = cctrl; - cfg->com_pll_rctrl_mode0 = rctrl; - cfg->com_cp_ctrl_mode0 = cpctrl; - cfg->com_dec_start_mode0 = dec_start; - cfg->com_div_frac_start1_mode0 = (frac_start & 0xFF); - cfg->com_div_frac_start2_mode0 = ((frac_start & 0xFF00) >> 8); - cfg->com_div_frac_start3_mode0 = ((frac_start & 0xF0000) >> 16); - cfg->com_integloop_gain0_mode0 = (integloop_gain & 0xFF); - cfg->com_integloop_gain1_mode0 = ((integloop_gain & 0xF00) >> 8); - cfg->com_lock_cmp1_mode0 = (pll_cmp & 0xFF); - cfg->com_lock_cmp2_mode0 = ((pll_cmp & 0xFF00) >> 8); - cfg->com_lock_cmp3_mode0 = ((pll_cmp & 0x30000) >> 16); - cfg->com_lock_cmp_en = 0x04; - cfg->com_core_clk_en = 0x2C; - cfg->com_coreclk_div = HDMI_CORECLK_DIV; - cfg->phy_mode = (bclk > HDMI_HIGH_FREQ_BIT_CLK_THRESHOLD) ? 0x10 : 0x0; - cfg->com_vco_tune_ctrl = 0x0; - - cfg->tx_l0_lane_mode = 0x43; - cfg->tx_l2_lane_mode = 0x43; - - if (bclk > HDMI_HIGH_FREQ_BIT_CLK_THRESHOLD) { - cfg->tx_l0_tx_drv_lvl = 0x25; - cfg->tx_l0_tx_emp_post1_lvl = 0x23; - cfg->tx_l1_tx_drv_lvl = 0x25; - cfg->tx_l1_tx_emp_post1_lvl = 0x23; - cfg->tx_l2_tx_drv_lvl = 0x25; - cfg->tx_l2_tx_emp_post1_lvl = 0x23; - cfg->tx_l3_tx_drv_lvl = 0x22; - cfg->tx_l3_tx_emp_post1_lvl = 0x27; - cfg->tx_l0_vmode_ctrl1 = 0x00; - cfg->tx_l0_vmode_ctrl2 = 0x0D; - cfg->tx_l1_vmode_ctrl1 = 0x00; - cfg->tx_l1_vmode_ctrl2 = 0x0D; - cfg->tx_l2_vmode_ctrl1 = 0x00; - cfg->tx_l2_vmode_ctrl2 = 0x0D; - cfg->tx_l3_vmode_ctrl1 = 0x00; - cfg->tx_l3_vmode_ctrl2 = 0x00; - } else if (bclk > HDMI_MID_FREQ_BIT_CLK_THRESHOLD) { - cfg->tx_l0_tx_drv_lvl = 0x25; - cfg->tx_l0_tx_emp_post1_lvl = 0x23; - cfg->tx_l1_tx_drv_lvl = 0x25; - cfg->tx_l1_tx_emp_post1_lvl = 0x23; - cfg->tx_l2_tx_drv_lvl = 0x25; - cfg->tx_l2_tx_emp_post1_lvl = 0x23; - cfg->tx_l3_tx_drv_lvl = 0x25; - cfg->tx_l3_tx_emp_post1_lvl = 0x23; - cfg->tx_l0_vmode_ctrl1 = 0x00; - cfg->tx_l0_vmode_ctrl2 = 0x0D; - cfg->tx_l1_vmode_ctrl1 = 0x00; - cfg->tx_l1_vmode_ctrl2 = 0x0D; - cfg->tx_l2_vmode_ctrl1 = 0x00; - cfg->tx_l2_vmode_ctrl2 = 0x0D; - cfg->tx_l3_vmode_ctrl1 = 0x00; - cfg->tx_l3_vmode_ctrl2 = 0x00; - } else { - cfg->tx_l0_tx_drv_lvl = 0x20; - cfg->tx_l0_tx_emp_post1_lvl = 0x20; - cfg->tx_l1_tx_drv_lvl = 0x20; - cfg->tx_l1_tx_emp_post1_lvl = 0x20; - cfg->tx_l2_tx_drv_lvl = 0x20; - cfg->tx_l2_tx_emp_post1_lvl = 0x20; - cfg->tx_l3_tx_drv_lvl = 0x20; - cfg->tx_l3_tx_emp_post1_lvl = 0x20; - cfg->tx_l0_vmode_ctrl1 = 0x00; - cfg->tx_l0_vmode_ctrl2 = 0x0E; - cfg->tx_l1_vmode_ctrl1 = 0x00; - cfg->tx_l1_vmode_ctrl2 = 0x0E; - cfg->tx_l2_vmode_ctrl1 = 0x00; - cfg->tx_l2_vmode_ctrl2 = 0x0E; - cfg->tx_l3_vmode_ctrl1 = 0x00; - cfg->tx_l3_vmode_ctrl2 = 0x0E; - } - - DEV_DBG("HDMI 8996 PLL: PLL Settings\n"); - DEV_DBG("PLL PARAM: tx_l0_tx_band = 0x%x\n", cfg->tx_l0_tx_band); - DEV_DBG("PLL PARAM: tx_l1_tx_band = 0x%x\n", cfg->tx_l1_tx_band); - DEV_DBG("PLL PARAM: tx_l2_tx_band = 0x%x\n", cfg->tx_l2_tx_band); - DEV_DBG("PLL PARAM: tx_l3_tx_band = 0x%x\n", cfg->tx_l3_tx_band); - DEV_DBG("PLL PARAM: com_svs_mode_clk_sel = 0x%x\n", - cfg->com_svs_mode_clk_sel); - DEV_DBG("PLL PARAM: com_hsclk_sel = 0x%x\n", cfg->com_hsclk_sel); - DEV_DBG("PLL PARAM: com_lock_cmp_en = 0x%x\n", cfg->com_lock_cmp_en); - DEV_DBG("PLL PARAM: com_pll_cctrl_mode0 = 0x%x\n", - cfg->com_pll_cctrl_mode0); - DEV_DBG("PLL PARAM: com_pll_rctrl_mode0 = 0x%x\n", - cfg->com_pll_rctrl_mode0); - DEV_DBG("PLL PARAM: com_cp_ctrl_mode0 = 0x%x\n", - cfg->com_cp_ctrl_mode0); - DEV_DBG("PLL PARAM: com_dec_start_mode0 = 0x%x\n", - cfg->com_dec_start_mode0); - DEV_DBG("PLL PARAM: com_div_frac_start1_mode0 = 0x%x\n", - cfg->com_div_frac_start1_mode0); - DEV_DBG("PLL PARAM: com_div_frac_start2_mode0 = 0x%x\n", - cfg->com_div_frac_start2_mode0); - DEV_DBG("PLL PARAM: com_div_frac_start3_mode0 = 0x%x\n", - cfg->com_div_frac_start3_mode0); - DEV_DBG("PLL PARAM: com_integloop_gain0_mode0 = 0x%x\n", - cfg->com_integloop_gain0_mode0); - DEV_DBG("PLL PARAM: com_integloop_gain1_mode0 = 0x%x\n", - cfg->com_integloop_gain1_mode0); - DEV_DBG("PLL PARAM: com_lock_cmp1_mode0 = 0x%x\n", - cfg->com_lock_cmp1_mode0); - DEV_DBG("PLL PARAM: com_lock_cmp2_mode0 = 0x%x\n", - cfg->com_lock_cmp2_mode0); - DEV_DBG("PLL PARAM: com_lock_cmp3_mode0 = 0x%x\n", - cfg->com_lock_cmp3_mode0); - DEV_DBG("PLL PARAM: com_core_clk_en = 0x%x\n", cfg->com_core_clk_en); - DEV_DBG("PLL PARAM: com_coreclk_div = 0x%x\n", cfg->com_coreclk_div); - DEV_DBG("PLL PARAM: phy_mode = 0x%x\n", cfg->phy_mode); - - DEV_DBG("PLL PARAM: tx_l0_lane_mode = 0x%x\n", cfg->tx_l0_lane_mode); - DEV_DBG("PLL PARAM: tx_l2_lane_mode = 0x%x\n", cfg->tx_l2_lane_mode); - DEV_DBG("PLL PARAM: l0_tx_drv_lvl = 0x%x\n", cfg->tx_l0_tx_drv_lvl); - DEV_DBG("PLL PARAM: l0_tx_emp_post1_lvl = 0x%x\n", - cfg->tx_l0_tx_emp_post1_lvl); - DEV_DBG("PLL PARAM: l1_tx_drv_lvl = 0x%x\n", cfg->tx_l1_tx_drv_lvl); - DEV_DBG("PLL PARAM: l1_tx_emp_post1_lvl = 0x%x\n", - cfg->tx_l1_tx_emp_post1_lvl); - DEV_DBG("PLL PARAM: l2_tx_drv_lvl = 0x%x\n", cfg->tx_l2_tx_drv_lvl); - DEV_DBG("PLL PARAM: l2_tx_emp_post1_lvl = 0x%x\n", - cfg->tx_l2_tx_emp_post1_lvl); - DEV_DBG("PLL PARAM: l3_tx_drv_lvl = 0x%x\n", cfg->tx_l3_tx_drv_lvl); - DEV_DBG("PLL PARAM: l3_tx_emp_post1_lvl = 0x%x\n", - cfg->tx_l3_tx_emp_post1_lvl); - - DEV_DBG("PLL PARAM: l0_vmode_ctrl1 = 0x%x\n", cfg->tx_l0_vmode_ctrl1); - DEV_DBG("PLL PARAM: l0_vmode_ctrl2 = 0x%x\n", cfg->tx_l0_vmode_ctrl2); - DEV_DBG("PLL PARAM: l1_vmode_ctrl1 = 0x%x\n", cfg->tx_l1_vmode_ctrl1); - DEV_DBG("PLL PARAM: l1_vmode_ctrl2 = 0x%x\n", cfg->tx_l1_vmode_ctrl2); - DEV_DBG("PLL PARAM: l2_vmode_ctrl1 = 0x%x\n", cfg->tx_l2_vmode_ctrl1); - DEV_DBG("PLL PARAM: l2_vmode_ctrl2 = 0x%x\n", cfg->tx_l2_vmode_ctrl2); - DEV_DBG("PLL PARAM: l3_vmode_ctrl1 = 0x%x\n", cfg->tx_l3_vmode_ctrl1); - DEV_DBG("PLL PARAM: l3_vmode_ctrl2 = 0x%x\n", cfg->tx_l3_vmode_ctrl2); - rc = 0; -fail: - return rc; -} - -static int hdmi_8996_calculate(u32 pix_clk, - struct hdmi_8996_phy_pll_reg_cfg *cfg, u32 ver) -{ - switch (ver) { - case HDMI_VERSION_8996_V3: - case HDMI_VERSION_8996_V3_1_8: - return hdmi_8996_v3_calculate(pix_clk, cfg); - case HDMI_VERSION_8996_V2: - return hdmi_8996_v2_calculate(pix_clk, cfg); - default: - return hdmi_8996_v1_calculate(pix_clk, cfg); - } -} - -static int hdmi_8996_phy_pll_set_clk_rate(struct clk *c, u32 tmds_clk, u32 ver) -{ - int rc = 0; - struct hdmi_pll_vco_clk *vco = to_hdmi_8996_vco_clk(c); - struct mdss_pll_resources *io = vco->priv; - struct hdmi_8996_phy_pll_reg_cfg cfg = {0}; - - rc = hdmi_8996_calculate(tmds_clk, &cfg, ver); - if (rc) { - DEV_ERR("%s: PLL calculation failed\n", __func__); - return rc; - } - - /* Initially shut down PHY */ - DEV_DBG("%s: Disabling PHY\n", __func__); - MDSS_PLL_REG_W(io->phy_base, HDMI_PHY_PD_CTL, 0x0); - udelay(500); - - /* Power up sequence */ - switch (ver) { - case HDMI_VERSION_8996_V2: - case HDMI_VERSION_8996_V3: - case HDMI_VERSION_8996_V3_1_8: - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_BG_CTRL, 0x04); - break; - } - - MDSS_PLL_REG_W(io->phy_base, HDMI_PHY_PD_CTL, 0x1); - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_RESETSM_CNTRL, 0x20); - MDSS_PLL_REG_W(io->phy_base, HDMI_PHY_TX0_TX1_LANE_CTL, 0x0F); - MDSS_PLL_REG_W(io->phy_base, HDMI_PHY_TX2_TX3_LANE_CTL, 0x0F); - MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L0_BASE_OFFSET, - QSERDES_TX_L0_CLKBUF_ENABLE, 0x03); - MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L1_BASE_OFFSET, - QSERDES_TX_L0_CLKBUF_ENABLE, 0x03); - MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L2_BASE_OFFSET, - QSERDES_TX_L0_CLKBUF_ENABLE, 0x03); - MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L3_BASE_OFFSET, - QSERDES_TX_L0_CLKBUF_ENABLE, 0x03); - - MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L0_BASE_OFFSET, - QSERDES_TX_L0_LANE_MODE, cfg.tx_l0_lane_mode); - MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L2_BASE_OFFSET, - QSERDES_TX_L0_LANE_MODE, cfg.tx_l2_lane_mode); - - MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L0_BASE_OFFSET, - QSERDES_TX_L0_TX_BAND, cfg.tx_l0_tx_band); - MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L1_BASE_OFFSET, - QSERDES_TX_L0_TX_BAND, cfg.tx_l1_tx_band); - MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L2_BASE_OFFSET, - QSERDES_TX_L0_TX_BAND, cfg.tx_l2_tx_band); - MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L3_BASE_OFFSET, - QSERDES_TX_L0_TX_BAND, cfg.tx_l3_tx_band); - - MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L0_BASE_OFFSET, - QSERDES_TX_L0_RESET_TSYNC_EN, 0x03); - MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L1_BASE_OFFSET, - QSERDES_TX_L0_RESET_TSYNC_EN, 0x03); - MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L2_BASE_OFFSET, - QSERDES_TX_L0_RESET_TSYNC_EN, 0x03); - MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L3_BASE_OFFSET, - QSERDES_TX_L0_RESET_TSYNC_EN, 0x03); - - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_SYSCLK_BUF_ENABLE, 0x1E); - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x07); - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_SYSCLK_EN_SEL, 0x37); - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_SYS_CLK_CTRL, 0x02); - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_CLK_ENABLE1, 0x0E); - if (ver == HDMI_VERSION_8996_V1) - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_BG_CTRL, 0x06); - - /* Bypass VCO calibration */ - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_SVS_MODE_CLK_SEL, - cfg.com_svs_mode_clk_sel); - - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_BG_TRIM, 0x0F); - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_PLL_IVCO, 0x0F); - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_VCO_TUNE_CTRL, - cfg.com_vco_tune_ctrl); - - switch (ver) { - case HDMI_VERSION_8996_V1: - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_SVS_MODE_CLK_SEL, - cfg.com_svs_mode_clk_sel); - break; - default: - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_BG_CTRL, 0x06); - } - - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_CLK_SELECT, 0x30); - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_HSCLK_SEL, - cfg.com_hsclk_sel); - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_LOCK_CMP_EN, - cfg.com_lock_cmp_en); - - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_PLL_CCTRL_MODE0, - cfg.com_pll_cctrl_mode0); - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_PLL_RCTRL_MODE0, - cfg.com_pll_rctrl_mode0); - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_CP_CTRL_MODE0, - cfg.com_cp_ctrl_mode0); - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_DEC_START_MODE0, - cfg.com_dec_start_mode0); - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_DIV_FRAC_START1_MODE0, - cfg.com_div_frac_start1_mode0); - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_DIV_FRAC_START2_MODE0, - cfg.com_div_frac_start2_mode0); - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_DIV_FRAC_START3_MODE0, - cfg.com_div_frac_start3_mode0); - - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_INTEGLOOP_GAIN0_MODE0, - cfg.com_integloop_gain0_mode0); - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_INTEGLOOP_GAIN1_MODE0, - cfg.com_integloop_gain1_mode0); - - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_LOCK_CMP1_MODE0, - cfg.com_lock_cmp1_mode0); - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_LOCK_CMP2_MODE0, - cfg.com_lock_cmp2_mode0); - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_LOCK_CMP3_MODE0, - cfg.com_lock_cmp3_mode0); - - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_VCO_TUNE_MAP, 0x00); - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_CORE_CLK_EN, - cfg.com_core_clk_en); - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_CORECLK_DIV, - cfg.com_coreclk_div); - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_CMN_CONFIG, 0x02); - - if (ver == HDMI_VERSION_8996_V3 || ver == HDMI_VERSION_8996_V3_1_8) - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_RESCODE_DIV_NUM, 0x15); - - /* TX lanes setup (TX 0/1/2/3) */ - if (ver == HDMI_VERSION_8996_V3_1_8) { - MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L0_BASE_OFFSET, - QSERDES_TX_L0_TX_DRV_LVL, - 0x00000023); - } else { - MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L0_BASE_OFFSET, - QSERDES_TX_L0_TX_DRV_LVL, - cfg.tx_l0_tx_drv_lvl); - } - MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L0_BASE_OFFSET, - QSERDES_TX_L0_TX_EMP_POST1_LVL, - cfg.tx_l0_tx_emp_post1_lvl); - - if (ver == HDMI_VERSION_8996_V3_1_8) { - MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L1_BASE_OFFSET, - QSERDES_TX_L0_TX_DRV_LVL, - 0x00000023); - } else { - MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L1_BASE_OFFSET, - QSERDES_TX_L0_TX_DRV_LVL, - cfg.tx_l1_tx_drv_lvl); - } - MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L1_BASE_OFFSET, - QSERDES_TX_L0_TX_EMP_POST1_LVL, - cfg.tx_l1_tx_emp_post1_lvl); - - if (ver == HDMI_VERSION_8996_V3_1_8) { - MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L2_BASE_OFFSET, - QSERDES_TX_L0_TX_DRV_LVL, - 0x00000023); - } else { - MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L2_BASE_OFFSET, - QSERDES_TX_L0_TX_DRV_LVL, - cfg.tx_l2_tx_drv_lvl); - } - MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L2_BASE_OFFSET, - QSERDES_TX_L0_TX_EMP_POST1_LVL, - cfg.tx_l2_tx_emp_post1_lvl); - - if (ver == HDMI_VERSION_8996_V3_1_8) { - MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L3_BASE_OFFSET, - QSERDES_TX_L0_TX_DRV_LVL, - 0x00000020); - } else { - MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L3_BASE_OFFSET, - QSERDES_TX_L0_TX_DRV_LVL, - cfg.tx_l3_tx_drv_lvl); - } - MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L3_BASE_OFFSET, - QSERDES_TX_L0_TX_EMP_POST1_LVL, - cfg.tx_l3_tx_emp_post1_lvl); - - MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L0_BASE_OFFSET, - QSERDES_TX_L0_VMODE_CTRL1, - cfg.tx_l0_vmode_ctrl1); - MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L0_BASE_OFFSET, - QSERDES_TX_L0_VMODE_CTRL2, - cfg.tx_l0_vmode_ctrl2); - - MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L1_BASE_OFFSET, - QSERDES_TX_L0_VMODE_CTRL1, - cfg.tx_l1_vmode_ctrl1); - MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L1_BASE_OFFSET, - QSERDES_TX_L0_VMODE_CTRL2, - cfg.tx_l1_vmode_ctrl2); - - MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L2_BASE_OFFSET, - QSERDES_TX_L0_VMODE_CTRL1, - cfg.tx_l2_vmode_ctrl1); - MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L2_BASE_OFFSET, - QSERDES_TX_L0_VMODE_CTRL2, - cfg.tx_l2_vmode_ctrl2); - - MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L3_BASE_OFFSET, - QSERDES_TX_L0_VMODE_CTRL1, - cfg.tx_l3_vmode_ctrl1); - if (ver == HDMI_VERSION_8996_V3_1_8) { - MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L3_BASE_OFFSET, - QSERDES_TX_L0_VMODE_CTRL2, - 0x0000000D); - } else { - MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L3_BASE_OFFSET, - QSERDES_TX_L0_VMODE_CTRL2, - cfg.tx_l3_vmode_ctrl2); - } - - MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L0_BASE_OFFSET, - QSERDES_TX_L0_TX_DRV_LVL_OFFSET, 0x00); - MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L1_BASE_OFFSET, - QSERDES_TX_L0_TX_DRV_LVL_OFFSET, 0x00); - MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L2_BASE_OFFSET, - QSERDES_TX_L0_TX_DRV_LVL_OFFSET, 0x00); - MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L3_BASE_OFFSET, - QSERDES_TX_L0_TX_DRV_LVL_OFFSET, 0x00); - - MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L0_BASE_OFFSET, - QSERDES_TX_L0_RES_CODE_LANE_OFFSET, 0x00); - MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L1_BASE_OFFSET, - QSERDES_TX_L0_RES_CODE_LANE_OFFSET, 0x00); - MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L2_BASE_OFFSET, - QSERDES_TX_L0_RES_CODE_LANE_OFFSET, 0x00); - MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L3_BASE_OFFSET, - QSERDES_TX_L0_RES_CODE_LANE_OFFSET, 0x00); - - if (ver < HDMI_VERSION_8996_V3) { - MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L0_BASE_OFFSET, - QSERDES_TX_L0_RES_CODE_LANE_TX, - cfg.tx_l0_res_code_lane_tx); - MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L1_BASE_OFFSET, - QSERDES_TX_L0_RES_CODE_LANE_TX, - cfg.tx_l1_res_code_lane_tx); - MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L2_BASE_OFFSET, - QSERDES_TX_L0_RES_CODE_LANE_TX, - cfg.tx_l2_res_code_lane_tx); - MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L3_BASE_OFFSET, - QSERDES_TX_L0_RES_CODE_LANE_TX, - cfg.tx_l3_res_code_lane_tx); - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_RESTRIM_CTRL, - cfg.com_restrim_ctrl); - - MDSS_PLL_REG_W(io->phy_base, HDMI_PHY_TXCAL_CFG0, 0x00); - MDSS_PLL_REG_W(io->phy_base, HDMI_PHY_TXCAL_CFG1, 0x05); - } - - MDSS_PLL_REG_W(io->phy_base, HDMI_PHY_MODE, cfg.phy_mode); - MDSS_PLL_REG_W(io->phy_base, HDMI_PHY_PD_CTL, 0x1F); - - MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L0_BASE_OFFSET, - QSERDES_TX_L0_TRAN_DRVR_EMP_EN, 0x03); - MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L1_BASE_OFFSET, - QSERDES_TX_L0_TRAN_DRVR_EMP_EN, 0x03); - MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L2_BASE_OFFSET, - QSERDES_TX_L0_TRAN_DRVR_EMP_EN, 0x03); - MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L3_BASE_OFFSET, - QSERDES_TX_L0_TRAN_DRVR_EMP_EN, 0x03); - - MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L0_BASE_OFFSET, - QSERDES_TX_L0_PARRATE_REC_DETECT_IDLE_EN, 0x40); - MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L1_BASE_OFFSET, - QSERDES_TX_L0_PARRATE_REC_DETECT_IDLE_EN, 0x40); - MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L2_BASE_OFFSET, - QSERDES_TX_L0_PARRATE_REC_DETECT_IDLE_EN, 0x40); - MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L3_BASE_OFFSET, - QSERDES_TX_L0_PARRATE_REC_DETECT_IDLE_EN, 0x40); - - MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L0_BASE_OFFSET, - QSERDES_TX_L0_HP_PD_ENABLES, 0x0C); - MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L1_BASE_OFFSET, - QSERDES_TX_L0_HP_PD_ENABLES, 0x0C); - MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L2_BASE_OFFSET, - QSERDES_TX_L0_HP_PD_ENABLES, 0x0C); - MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L3_BASE_OFFSET, - QSERDES_TX_L0_HP_PD_ENABLES, 0x03); - - if (ver == HDMI_VERSION_8996_V2) { - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_ATB_SEL1, 0x01); - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_ATB_SEL2, 0x01); - } - /* - * Ensure that vco configuration gets flushed to hardware before - * enabling the PLL - */ - wmb(); - return 0; -} - -static int hdmi_8996_phy_ready_status(struct mdss_pll_resources *io) -{ - u32 status = 0; - int phy_ready = 0; - int rc; - u32 read_count = 0; - - rc = mdss_pll_resource_enable(io, true); - if (rc) { - DEV_ERR("%s: pll resource can't be enabled\n", __func__); - return rc; - } - - DEV_DBG("%s: Waiting for PHY Ready\n", __func__); - - /* Poll for PHY read status */ - while (read_count < HDMI_PLL_POLL_MAX_READS) { - status = MDSS_PLL_REG_R(io->phy_base, HDMI_PHY_STATUS); - if ((status & BIT(0)) == 1) { - phy_ready = 1; - DEV_DBG("%s: PHY READY\n", __func__); - break; - } - udelay(HDMI_PLL_POLL_TIMEOUT_US); - read_count++; - } - - if (read_count == HDMI_PLL_POLL_MAX_READS) { - phy_ready = 0; - DEV_DBG("%s: PHY READY TIMEOUT\n", __func__); - } - - mdss_pll_resource_enable(io, false); - - return phy_ready; -} - -static int hdmi_8996_pll_lock_status(struct mdss_pll_resources *io) -{ - u32 status; - int pll_locked = 0; - int rc; - u32 read_count = 0; - - rc = mdss_pll_resource_enable(io, true); - if (rc) { - DEV_ERR("%s: pll resource can't be enabled\n", __func__); - return rc; - } - - DEV_DBG("%s: Waiting for PLL lock\n", __func__); - - while (read_count < HDMI_PLL_POLL_MAX_READS) { - status = MDSS_PLL_REG_R(io->pll_base, - QSERDES_COM_C_READY_STATUS); - if ((status & BIT(0)) == 1) { - pll_locked = 1; - DEV_DBG("%s: C READY\n", __func__); - break; - } - udelay(HDMI_PLL_POLL_TIMEOUT_US); - read_count++; - } - - if (read_count == HDMI_PLL_POLL_MAX_READS) { - pll_locked = 0; - DEV_DBG("%s: C READY TIMEOUT\n", __func__); - } - - mdss_pll_resource_enable(io, false); - - return pll_locked; -} - -static int hdmi_8996_v1_perform_sw_calibration(struct clk *c) -{ - int rc = 0; - struct hdmi_pll_vco_clk *vco = to_hdmi_8996_vco_clk(c); - struct mdss_pll_resources *io = vco->priv; - - u32 max_code = 0x190; - u32 min_code = 0x0; - u32 max_cnt = 0; - u32 min_cnt = 0; - u32 expected_counter_value = 0; - u32 step = 0; - u32 dbus_all = 0; - u32 dbus_sel = 0; - u32 vco_code = 0; - u32 val = 0; - - vco_code = 0xC8; - - DEV_DBG("%s: Starting SW calibration with vco_code = %d\n", __func__, - vco_code); - - expected_counter_value = - (MDSS_PLL_REG_R(io->pll_base, QSERDES_COM_LOCK_CMP3_MODE0) << 16) | - (MDSS_PLL_REG_R(io->pll_base, QSERDES_COM_LOCK_CMP2_MODE0) << 8) | - (MDSS_PLL_REG_R(io->pll_base, QSERDES_COM_LOCK_CMP1_MODE0)); - - DEV_DBG("%s: expected_counter_value = %d\n", __func__, - expected_counter_value); - - val = MDSS_PLL_REG_R(io->pll_base, QSERDES_COM_CMN_MISC1); - val |= BIT(4); - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_CMN_MISC1, val); - - val = MDSS_PLL_REG_R(io->pll_base, QSERDES_COM_CMN_MISC1); - val |= BIT(3); - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_CMN_MISC1, val); - - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_DEBUG_BUS_SEL, 0x4); - - val = MDSS_PLL_REG_R(io->pll_base, QSERDES_COM_LOCK_CMP_CFG); - val |= BIT(1); - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_LOCK_CMP_CFG, val); - - udelay(60); - - while (1) { - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_VCO_TUNE1_MODE0, - vco_code & 0xFF); - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_VCO_TUNE2_MODE0, - (vco_code >> 8) & 0x3); - - udelay(20); - - val = MDSS_PLL_REG_R(io->pll_base, QSERDES_COM_LOCK_CMP_CFG); - val &= ~BIT(1); - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_LOCK_CMP_CFG, val); - - udelay(60); - - val = MDSS_PLL_REG_R(io->pll_base, QSERDES_COM_LOCK_CMP_CFG); - val |= BIT(1); - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_LOCK_CMP_CFG, val); - - udelay(60); - - dbus_all = - (MDSS_PLL_REG_R(io->pll_base, QSERDES_COM_DEBUG_BUS3) << 24) | - (MDSS_PLL_REG_R(io->pll_base, QSERDES_COM_DEBUG_BUS2) << 16) | - (MDSS_PLL_REG_R(io->pll_base, QSERDES_COM_DEBUG_BUS1) << 8) | - (MDSS_PLL_REG_R(io->pll_base, QSERDES_COM_DEBUG_BUS0)); - - dbus_sel = (dbus_all >> 9) & 0x3FFFF; - DEV_DBG("%s: loop[%d], dbus_all = 0x%x, dbus_sel = 0x%x\n", - __func__, step, dbus_all, dbus_sel); - if (dbus_sel == 0) - DEV_ERR("%s: CHECK HDMI REF CLK\n", __func__); - - if (dbus_sel == expected_counter_value) { - max_code = vco_code; - max_cnt = dbus_sel; - min_code = vco_code; - min_cnt = dbus_sel; - } else if (dbus_sel == 0) { - max_code = vco_code; - max_cnt = dbus_sel; - vco_code = (max_code + min_code)/2; - } else if (dbus_sel > expected_counter_value) { - min_code = vco_code; - min_cnt = dbus_sel; - vco_code = (max_code + min_code)/2; - } else if (dbus_sel < expected_counter_value) { - max_code = vco_code; - max_cnt = dbus_sel; - vco_code = (max_code + min_code)/2; - } - - step++; - - if ((vco_code == 0) || (vco_code == 0x3FF) || (step > 0x3FF)) { - DEV_ERR("%s: VCO tune code search failed\n", __func__); - rc = -ENOTSUPP; - break; - } - if ((max_code - min_code) <= 1) { - if ((max_code - min_code) == 1) { - if (abs((int)(max_cnt - expected_counter_value)) - < abs((int)(min_cnt - expected_counter_value - ))) { - vco_code = max_code; - } else { - vco_code = min_code; - } - } - break; - } - DEV_DBG("%s: loop[%d], new vco_code = %d\n", __func__, step, - vco_code); - } - - DEV_DBG("%s: CALIB done. vco_code = %d\n", __func__, vco_code); - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_VCO_TUNE1_MODE0, - vco_code & 0xFF); - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_VCO_TUNE2_MODE0, - (vco_code >> 8) & 0x3); - val = MDSS_PLL_REG_R(io->pll_base, QSERDES_COM_LOCK_CMP_CFG); - val &= ~BIT(1); - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_LOCK_CMP_CFG, val); - - val = MDSS_PLL_REG_R(io->pll_base, QSERDES_COM_CMN_MISC1); - val |= BIT(4); - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_CMN_MISC1, val); - - val = MDSS_PLL_REG_R(io->pll_base, QSERDES_COM_CMN_MISC1); - val &= ~BIT(3); - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_CMN_MISC1, val); - - return rc; -} - -static int hdmi_8996_v2_perform_sw_calibration(struct clk *c) -{ - struct hdmi_pll_vco_clk *vco = to_hdmi_8996_vco_clk(c); - struct mdss_pll_resources *io = vco->priv; - u32 vco_code1, vco_code2, integral_loop, ready_poll; - u32 read_count = 0; - - while (read_count < (HDMI_PLL_POLL_MAX_READS << 1)) { - ready_poll = MDSS_PLL_REG_R(io->pll_base, - QSERDES_COM_C_READY_STATUS); - if ((ready_poll & BIT(0)) == 1) { - ready_poll = 1; - DEV_DBG("%s: C READY\n", __func__); - break; - } - udelay(HDMI_PLL_POLL_TIMEOUT_US); - read_count++; - } - - if (read_count == (HDMI_PLL_POLL_MAX_READS << 1)) { - ready_poll = 0; - DEV_DBG("%s: C READY TIMEOUT, TRYING SW CALIBRATION\n", - __func__); - } - - vco_code1 = MDSS_PLL_REG_R(io->pll_base, - QSERDES_COM_PLLCAL_CODE1_STATUS); - vco_code2 = MDSS_PLL_REG_R(io->pll_base, - QSERDES_COM_PLLCAL_CODE2_STATUS); - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_DEBUG_BUS_SEL, 0x5); - integral_loop = MDSS_PLL_REG_R(io->pll_base, - QSERDES_COM_DEBUG_BUS0); - - if (((ready_poll & 0x1) == 0) || (((ready_poll & 1) == 1) && - (vco_code1 == 0xFF) && ((vco_code2 & 0x3) == 0x1) && - (integral_loop > 0xC0))) { - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_ATB_SEL1, 0x04); - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_ATB_SEL2, 0x00); - MDSS_PLL_REG_W(io->phy_base, HDMI_PHY_CFG, 0x17); - udelay(100); - - MDSS_PLL_REG_W(io->phy_base, HDMI_PHY_CFG, 0x11); - udelay(100); - - MDSS_PLL_REG_W(io->phy_base, HDMI_PHY_CFG, 0x19); - } - return 0; -} - -static int hdmi_8996_perform_sw_calibration(struct clk *c, u32 ver) -{ - switch (ver) { - case HDMI_VERSION_8996_V1: - return hdmi_8996_v1_perform_sw_calibration(c); - case HDMI_VERSION_8996_V2: - return hdmi_8996_v2_perform_sw_calibration(c); - } - return 0; -} - -static int hdmi_8996_vco_enable(struct clk *c, u32 ver) -{ - int rc = 0; - struct hdmi_pll_vco_clk *vco = to_hdmi_8996_vco_clk(c); - struct mdss_pll_resources *io = vco->priv; - - MDSS_PLL_REG_W(io->phy_base, HDMI_PHY_CFG, 0x1); - udelay(100); - - MDSS_PLL_REG_W(io->phy_base, HDMI_PHY_CFG, 0x19); - udelay(100); - - rc = hdmi_8996_perform_sw_calibration(c, ver); - if (rc) { - DEV_ERR("%s: software calibration failed\n", __func__); - return rc; - } - - rc = hdmi_8996_pll_lock_status(io); - if (!rc) { - DEV_ERR("%s: PLL not locked\n", __func__); - return rc; - } - - MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L0_BASE_OFFSET, - QSERDES_TX_L0_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN, - 0x6F); - MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L1_BASE_OFFSET, - QSERDES_TX_L0_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN, - 0x6F); - MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L2_BASE_OFFSET, - QSERDES_TX_L0_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN, - 0x6F); - MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L3_BASE_OFFSET, - QSERDES_TX_L0_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN, - 0x6F); - - /* Disable SSC */ - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_SSC_PER1, 0x0); - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_SSC_PER2, 0x0); - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_SSC_STEP_SIZE1, 0x0); - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_SSC_STEP_SIZE2, 0x0); - MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_SSC_EN_CENTER, 0x2); - - rc = hdmi_8996_phy_ready_status(io); - if (!rc) { - DEV_ERR("%s: PHY not READY\n", __func__); - return rc; - } - - /* Restart the retiming buffer */ - MDSS_PLL_REG_W(io->phy_base, HDMI_PHY_CFG, 0x18); - udelay(1); - MDSS_PLL_REG_W(io->phy_base, HDMI_PHY_CFG, 0x19); - - io->pll_on = true; - return 0; -} - -static int hdmi_8996_v1_vco_enable(struct clk *c) -{ - return hdmi_8996_vco_enable(c, HDMI_VERSION_8996_V1); -} - -static int hdmi_8996_v2_vco_enable(struct clk *c) -{ - return hdmi_8996_vco_enable(c, HDMI_VERSION_8996_V2); -} - -static int hdmi_8996_v3_vco_enable(struct clk *c) -{ - return hdmi_8996_vco_enable(c, HDMI_VERSION_8996_V3); -} - -static int hdmi_8996_v3_1p8_vco_enable(struct clk *c) -{ - return hdmi_8996_vco_enable(c, HDMI_VERSION_8996_V3_1_8); -} - -static int hdmi_8996_vco_get_lock_range(struct clk *c, unsigned long pixel_clk) -{ - u32 rng = 64, cmp_cnt = 1024; - u32 coreclk_div = 5, clks_pll_divsel = 2; - u32 vco_freq, vco_ratio, ppm_range; - u64 bclk; - struct hdmi_8996_v3_post_divider pd; - - bclk = ((u64)pixel_clk) * HDMI_BIT_CLK_TO_PIX_CLK_RATIO; - - DEV_DBG("%s: rate=%ld\n", __func__, pixel_clk); - - if (hdmi_8996_v3_get_post_div(&pd, bclk) || - pd.vco_ratio <= 0 || pd.vco_freq <= 0) { - DEV_ERR("%s: couldn't get post div\n", __func__); - return -EINVAL; - } - - do_div(pd.vco_freq, HDMI_KHZ_TO_HZ * HDMI_KHZ_TO_HZ); - - vco_freq = (u32) pd.vco_freq; - vco_ratio = (u32) pd.vco_ratio; - - DEV_DBG("%s: freq %d, ratio %d\n", __func__, - vco_freq, vco_ratio); - - ppm_range = (rng * HDMI_REF_CLOCK) / cmp_cnt; - ppm_range /= vco_freq / vco_ratio; - ppm_range *= coreclk_div * clks_pll_divsel; - - DEV_DBG("%s: ppm range: %d\n", __func__, ppm_range); - - return ppm_range; -} - -static int hdmi_8996_vco_rate_atomic_update(struct clk *c, - unsigned long rate, u32 ver) -{ - struct hdmi_pll_vco_clk *vco = to_hdmi_8996_vco_clk(c); - struct mdss_pll_resources *io = vco->priv; - void __iomem *pll; - struct hdmi_8996_phy_pll_reg_cfg cfg = {0}; - int rc = 0; - - rc = hdmi_8996_calculate(rate, &cfg, ver); - if (rc) { - DEV_ERR("%s: PLL calculation failed\n", __func__); - goto end; - } - - pll = io->pll_base; - - MDSS_PLL_REG_W(pll, QSERDES_COM_DEC_START_MODE0, - cfg.com_dec_start_mode0); - MDSS_PLL_REG_W(pll, QSERDES_COM_DIV_FRAC_START1_MODE0, - cfg.com_div_frac_start1_mode0); - MDSS_PLL_REG_W(pll, QSERDES_COM_DIV_FRAC_START2_MODE0, - cfg.com_div_frac_start2_mode0); - MDSS_PLL_REG_W(pll, QSERDES_COM_DIV_FRAC_START3_MODE0, - cfg.com_div_frac_start3_mode0); - - MDSS_PLL_REG_W(pll, QSERDES_COM_FREQ_UPDATE, 0x01); - MDSS_PLL_REG_W(pll, QSERDES_COM_FREQ_UPDATE, 0x00); - - DEV_DBG("%s: updated to rate %ld\n", __func__, rate); -end: - return rc; -} - -static int hdmi_8996_vco_set_rate(struct clk *c, unsigned long rate, u32 ver) -{ - struct hdmi_pll_vco_clk *vco = to_hdmi_8996_vco_clk(c); - struct mdss_pll_resources *io = vco->priv; - unsigned int set_power_dwn = 0; - bool atomic_update = false; - int rc, pll_lock_range; - - rc = mdss_pll_resource_enable(io, true); - if (rc) { - DEV_ERR("pll resource can't be enabled\n"); - return rc; - } - - DEV_DBG("%s: rate %ld\n", __func__, rate); - - if (MDSS_PLL_REG_R(io->pll_base, QSERDES_COM_C_READY_STATUS) & BIT(0) && - MDSS_PLL_REG_R(io->phy_base, HDMI_PHY_STATUS) & BIT(0)) { - pll_lock_range = hdmi_8996_vco_get_lock_range(c, vco->rate); - - if (pll_lock_range > 0 && vco->rate) { - u32 range_limit; - - range_limit = vco->rate * - (pll_lock_range / HDMI_KHZ_TO_HZ); - range_limit /= HDMI_KHZ_TO_HZ; - - DEV_DBG("%s: range limit %d\n", __func__, range_limit); - - if (abs(rate - vco->rate) < range_limit) - atomic_update = true; - } - } - - if (io->pll_on && !atomic_update) - set_power_dwn = 1; - - if (atomic_update) { - hdmi_8996_vco_rate_atomic_update(c, rate, ver); - } else { - rc = hdmi_8996_phy_pll_set_clk_rate(c, rate, ver); - if (rc) - DEV_ERR("%s: Failed to set clk rate\n", __func__); - } - - mdss_pll_resource_enable(io, false); - - if (set_power_dwn) - hdmi_8996_vco_enable(c, ver); - - vco->rate = rate; - vco->rate_set = true; - - return 0; -} - -static int hdmi_8996_v1_vco_set_rate(struct clk *c, unsigned long rate) -{ - return hdmi_8996_vco_set_rate(c, rate, HDMI_VERSION_8996_V1); -} - -static int hdmi_8996_v2_vco_set_rate(struct clk *c, unsigned long rate) -{ - return hdmi_8996_vco_set_rate(c, rate, HDMI_VERSION_8996_V2); -} - -static int hdmi_8996_v3_vco_set_rate(struct clk *c, unsigned long rate) -{ - return hdmi_8996_vco_set_rate(c, rate, HDMI_VERSION_8996_V3); -} - -static int hdmi_8996_v3_1p8_vco_set_rate(struct clk *c, unsigned long rate) -{ - return hdmi_8996_vco_set_rate(c, rate, HDMI_VERSION_8996_V3_1_8); -} - -static unsigned long hdmi_get_hsclk_sel_divisor(unsigned long hsclk_sel) -{ - unsigned long divisor; - - switch (hsclk_sel) { - case 0: - divisor = 2; - break; - case 1: - divisor = 6; - break; - case 2: - divisor = 10; - break; - case 3: - divisor = 14; - break; - case 4: - divisor = 3; - break; - case 5: - divisor = 9; - break; - case 6: - case 13: - divisor = 15; - break; - case 7: - divisor = 21; - break; - case 8: - divisor = 4; - break; - case 9: - divisor = 12; - break; - case 10: - divisor = 20; - break; - case 11: - divisor = 28; - break; - case 12: - divisor = 5; - break; - case 14: - divisor = 25; - break; - case 15: - divisor = 35; - break; - default: - divisor = 1; - DEV_ERR("%s: invalid hsclk_sel value = %lu", - __func__, hsclk_sel); - break; - } - - return divisor; -} - -static unsigned long hdmi_8996_vco_get_rate(struct clk *c) -{ - unsigned long freq = 0, hsclk_sel = 0, tx_band = 0, dec_start = 0, - div_frac_start = 0, vco_clock_freq = 0; - struct hdmi_pll_vco_clk *vco = to_hdmi_8996_vco_clk(c); - struct mdss_pll_resources *io = vco->priv; - - if (mdss_pll_resource_enable(io, true)) { - DEV_ERR("%s: pll resource can't be enabled\n", __func__); - return freq; - } - - dec_start = MDSS_PLL_REG_R(io->pll_base, QSERDES_COM_DEC_START_MODE0); - - div_frac_start = - MDSS_PLL_REG_R(io->pll_base, - QSERDES_COM_DIV_FRAC_START1_MODE0) | - MDSS_PLL_REG_R(io->pll_base, - QSERDES_COM_DIV_FRAC_START2_MODE0) << 8 | - MDSS_PLL_REG_R(io->pll_base, - QSERDES_COM_DIV_FRAC_START3_MODE0) << 16; - - vco_clock_freq = (dec_start + (div_frac_start / (1 << 20))) - * 4 * (HDMI_REF_CLOCK); - - hsclk_sel = MDSS_PLL_REG_R(io->pll_base, QSERDES_COM_HSCLK_SEL) & 0x15; - hsclk_sel = hdmi_get_hsclk_sel_divisor(hsclk_sel); - tx_band = MDSS_PLL_REG_R(io->pll_base + HDMI_TX_L0_BASE_OFFSET, - QSERDES_TX_L0_TX_BAND) & 0x3; - - freq = vco_clock_freq / (10 * hsclk_sel * (1 << tx_band)); - - mdss_pll_resource_enable(io, false); - - DEV_DBG("%s: freq = %lu\n", __func__, freq); - - return freq; -} - -static long hdmi_8996_vco_round_rate(struct clk *c, unsigned long rate) -{ - unsigned long rrate = rate; - - DEV_DBG("rrate=%ld\n", rrate); - - return rrate; -} - -static int hdmi_8996_vco_prepare(struct clk *c, u32 ver) -{ - struct hdmi_pll_vco_clk *vco = to_hdmi_8996_vco_clk(c); - struct mdss_pll_resources *io = vco->priv; - int ret = 0; - - DEV_DBG("rate=%ld\n", vco->rate); - - if (!vco->rate_set && vco->rate) - ret = hdmi_8996_vco_set_rate(c, vco->rate, ver); - - if (!ret) { - ret = mdss_pll_resource_enable(io, true); - if (ret) - DEV_ERR("pll resource can't be enabled\n"); - } - - return ret; -} - -static int hdmi_8996_v1_vco_prepare(struct clk *c) -{ - return hdmi_8996_vco_prepare(c, HDMI_VERSION_8996_V1); -} - -static int hdmi_8996_v2_vco_prepare(struct clk *c) -{ - return hdmi_8996_vco_prepare(c, HDMI_VERSION_8996_V2); -} - -static int hdmi_8996_v3_vco_prepare(struct clk *c) -{ - return hdmi_8996_vco_prepare(c, HDMI_VERSION_8996_V3); -} - -static int hdmi_8996_v3_1p8_vco_prepare(struct clk *c) -{ - return hdmi_8996_vco_prepare(c, HDMI_VERSION_8996_V3_1_8); -} - -static void hdmi_8996_vco_unprepare(struct clk *c) -{ - struct hdmi_pll_vco_clk *vco = to_hdmi_8996_vco_clk(c); - struct mdss_pll_resources *io = vco->priv; - - vco->rate_set = false; - - if (!io) { - DEV_ERR("Invalid input parameter\n"); - return; - } - - if (!io->pll_on && - mdss_pll_resource_enable(io, true)) { - DEV_ERR("pll resource can't be enabled\n"); - return; - } - - io->handoff_resources = false; - mdss_pll_resource_enable(io, false); - io->pll_on = false; -} - -static enum handoff hdmi_8996_vco_handoff(struct clk *c) -{ - enum handoff ret = HANDOFF_DISABLED_CLK; - struct hdmi_pll_vco_clk *vco = to_hdmi_8996_vco_clk(c); - struct mdss_pll_resources *io = vco->priv; - - if (is_gdsc_disabled(io)) - return HANDOFF_DISABLED_CLK; - - if (mdss_pll_resource_enable(io, true)) { - DEV_ERR("pll resource can't be enabled\n"); - return ret; - } - - io->handoff_resources = true; - - if (MDSS_PLL_REG_R(io->pll_base, QSERDES_COM_C_READY_STATUS) & BIT(0)) { - if (MDSS_PLL_REG_R(io->phy_base, HDMI_PHY_STATUS) & BIT(0)) { - io->pll_on = true; - c->rate = hdmi_8996_vco_get_rate(c); - vco->rate = c->rate; - ret = HANDOFF_ENABLED_CLK; - } else { - io->handoff_resources = false; - mdss_pll_resource_enable(io, false); - DEV_DBG("%s: PHY not ready\n", __func__); - } - } else { - io->handoff_resources = false; - mdss_pll_resource_enable(io, false); - DEV_DBG("%s: PLL not locked\n", __func__); - } - - DEV_DBG("done, ret=%d\n", ret); - return ret; -} - -static const struct clk_ops hdmi_8996_v1_vco_clk_ops = { - .enable = hdmi_8996_v1_vco_enable, - .set_rate = hdmi_8996_v1_vco_set_rate, - .get_rate = hdmi_8996_vco_get_rate, - .round_rate = hdmi_8996_vco_round_rate, - .prepare = hdmi_8996_v1_vco_prepare, - .unprepare = hdmi_8996_vco_unprepare, - .handoff = hdmi_8996_vco_handoff, -}; - -static const struct clk_ops hdmi_8996_v2_vco_clk_ops = { - .enable = hdmi_8996_v2_vco_enable, - .set_rate = hdmi_8996_v2_vco_set_rate, - .get_rate = hdmi_8996_vco_get_rate, - .round_rate = hdmi_8996_vco_round_rate, - .prepare = hdmi_8996_v2_vco_prepare, - .unprepare = hdmi_8996_vco_unprepare, - .handoff = hdmi_8996_vco_handoff, -}; - -static const struct clk_ops hdmi_8996_v3_vco_clk_ops = { - .enable = hdmi_8996_v3_vco_enable, - .set_rate = hdmi_8996_v3_vco_set_rate, - .get_rate = hdmi_8996_vco_get_rate, - .round_rate = hdmi_8996_vco_round_rate, - .prepare = hdmi_8996_v3_vco_prepare, - .unprepare = hdmi_8996_vco_unprepare, - .handoff = hdmi_8996_vco_handoff, -}; - -static const struct clk_ops hdmi_8996_v3_1p8_vco_clk_ops = { - .enable = hdmi_8996_v3_1p8_vco_enable, - .set_rate = hdmi_8996_v3_1p8_vco_set_rate, - .get_rate = hdmi_8996_vco_get_rate, - .round_rate = hdmi_8996_vco_round_rate, - .prepare = hdmi_8996_v3_1p8_vco_prepare, - .unprepare = hdmi_8996_vco_unprepare, - .handoff = hdmi_8996_vco_handoff, -}; - - -static struct hdmi_pll_vco_clk hdmi_vco_clk = { - .c = { - .dbg_name = "hdmi_8996_vco_clk", - .ops = &hdmi_8996_v1_vco_clk_ops, - CLK_INIT(hdmi_vco_clk.c), - }, -}; - -static struct clk_lookup hdmipllcc_8996[] = { - CLK_LIST(hdmi_vco_clk), -}; - -int hdmi_8996_pll_clock_register(struct platform_device *pdev, - struct mdss_pll_resources *pll_res, u32 ver) -{ - int rc = -ENOTSUPP; - - if (!pll_res || !pll_res->phy_base || !pll_res->pll_base) { - DEV_ERR("%s: Invalid input parameters\n", __func__); - return -EPROBE_DEFER; - } - - /* Set client data for vco, mux and div clocks */ - hdmi_vco_clk.priv = pll_res; - - switch (ver) { - case HDMI_VERSION_8996_V2: - hdmi_vco_clk.c.ops = &hdmi_8996_v2_vco_clk_ops; - break; - case HDMI_VERSION_8996_V3: - hdmi_vco_clk.c.ops = &hdmi_8996_v3_vco_clk_ops; - break; - case HDMI_VERSION_8996_V3_1_8: - hdmi_vco_clk.c.ops = &hdmi_8996_v3_1p8_vco_clk_ops; - break; - default: - hdmi_vco_clk.c.ops = &hdmi_8996_v1_vco_clk_ops; - break; - } - - rc = of_msm_clock_register(pdev->dev.of_node, hdmipllcc_8996, - ARRAY_SIZE(hdmipllcc_8996)); - if (rc) { - DEV_ERR("%s: Clock register failed rc=%d\n", __func__, rc); - rc = -EPROBE_DEFER; - } else { - DEV_DBG("%s SUCCESS\n", __func__); - } - - return rc; -} - -int hdmi_8996_v1_pll_clock_register(struct platform_device *pdev, - struct mdss_pll_resources *pll_res) -{ - return hdmi_8996_pll_clock_register(pdev, pll_res, - HDMI_VERSION_8996_V1); -} - -int hdmi_8996_v2_pll_clock_register(struct platform_device *pdev, - struct mdss_pll_resources *pll_res) -{ - return hdmi_8996_pll_clock_register(pdev, pll_res, - HDMI_VERSION_8996_V2); -} - -int hdmi_8996_v3_pll_clock_register(struct platform_device *pdev, - struct mdss_pll_resources *pll_res) -{ - return hdmi_8996_pll_clock_register(pdev, pll_res, - HDMI_VERSION_8996_V3); -} - -int hdmi_8996_v3_1p8_pll_clock_register(struct platform_device *pdev, - struct mdss_pll_resources *pll_res) -{ - return hdmi_8996_pll_clock_register(pdev, pll_res, - HDMI_VERSION_8996_V3_1_8); -} diff --git a/pll/hdmi_pll_8998.c b/pll/hdmi_pll_8998.c deleted file mode 100644 index b4321df435f6..000000000000 --- a/pll/hdmi_pll_8998.c +++ /dev/null @@ -1,827 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. - */ - -#define pr_fmt(fmt) "%s: " fmt, __func__ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "pll_drv.h" -#include "hdmi_pll.h" - -#define _W(x, y, z) MDSS_PLL_REG_W(x, y, z) -#define _R(x, y) MDSS_PLL_REG_R(x, y) - -/* PLL REGISTERS */ -#define BIAS_EN_CLKBUFLR_EN (0x034) -#define CLK_ENABLE1 (0x038) -#define SYS_CLK_CTRL (0x03C) -#define SYSCLK_BUF_ENABLE (0x040) -#define PLL_IVCO (0x048) -#define CP_CTRL_MODE0 (0x060) -#define PLL_RCTRL_MODE0 (0x068) -#define PLL_CCTRL_MODE0 (0x070) -#define SYSCLK_EN_SEL (0x080) -#define RESETSM_CNTRL (0x088) -#define LOCK_CMP_EN (0x090) -#define LOCK_CMP1_MODE0 (0x098) -#define LOCK_CMP2_MODE0 (0x09C) -#define LOCK_CMP3_MODE0 (0x0A0) -#define DEC_START_MODE0 (0x0B0) -#define DIV_FRAC_START1_MODE0 (0x0B8) -#define DIV_FRAC_START2_MODE0 (0x0BC) -#define DIV_FRAC_START3_MODE0 (0x0C0) -#define INTEGLOOP_GAIN0_MODE0 (0x0D8) -#define INTEGLOOP_GAIN1_MODE0 (0x0DC) -#define VCO_TUNE_CTRL (0x0EC) -#define VCO_TUNE_MAP (0x0F0) -#define CLK_SELECT (0x138) -#define HSCLK_SEL (0x13C) -#define CORECLK_DIV_MODE0 (0x148) -#define CORE_CLK_EN (0x154) -#define C_READY_STATUS (0x158) -#define SVS_MODE_CLK_SEL (0x164) - -/* Tx Channel PHY registers */ -#define PHY_TX_EMP_POST1_LVL(n) ((((n) * 0x200) + 0x400) + 0x000) -#define PHY_TX_INTERFACE_SELECT_TX_BAND(n) ((((n) * 0x200) + 0x400) + 0x008) -#define PHY_TX_CLKBUF_TERM_ENABLE(n) ((((n) * 0x200) + 0x400) + 0x00C) -#define PHY_TX_DRV_LVL_RES_CODE_OFFSET(n) ((((n) * 0x200) + 0x400) + 0x014) -#define PHY_TX_DRV_LVL(n) ((((n) * 0x200) + 0x400) + 0x018) -#define PHY_TX_LANE_CONFIG(n) ((((n) * 0x200) + 0x400) + 0x01C) -#define PHY_TX_PRE_DRIVER_1(n) ((((n) * 0x200) + 0x400) + 0x024) -#define PHY_TX_PRE_DRIVER_2(n) ((((n) * 0x200) + 0x400) + 0x028) -#define PHY_TX_LANE_MODE(n) ((((n) * 0x200) + 0x400) + 0x02C) - -/* HDMI PHY registers */ -#define PHY_CFG (0x00) -#define PHY_PD_CTL (0x04) -#define PHY_MODE (0x10) -#define PHY_CLOCK (0x5C) -#define PHY_CMN_CTRL (0x68) -#define PHY_STATUS (0xB4) - -#define HDMI_BIT_CLK_TO_PIX_CLK_RATIO 10 -#define HDMI_MHZ_TO_HZ 1000000 -#define HDMI_HZ_TO_MHZ 1000000 -#define HDMI_REF_CLOCK_MHZ 19.2 -#define HDMI_REF_CLOCK_HZ (HDMI_REF_CLOCK_MHZ * 1000000) -#define HDMI_VCO_MIN_RATE_HZ 25000000 -#define HDMI_VCO_MAX_RATE_HZ 600000000 - -struct 8998_reg_cfg { - u32 tx_band; - u32 svs_mode_clk_sel; - u32 hsclk_sel; - u32 lock_cmp_en; - u32 cctrl_mode0; - u32 rctrl_mode0; - u32 cpctrl_mode0; - u32 dec_start_mode0; - u32 div_frac_start1_mode0; - u32 div_frac_start2_mode0; - u32 div_frac_start3_mode0; - u32 integloop_gain0_mode0; - u32 integloop_gain1_mode0; - u32 lock_cmp1_mode0; - u32 lock_cmp2_mode0; - u32 lock_cmp3_mode0; - u32 ssc_per1; - u32 ssc_per2; - u32 ssc_step_size1; - u32 ssc_step_size2; - u32 core_clk_en; - u32 coreclk_div_mode0; - u32 phy_mode; - u32 vco_freq; - u32 hsclk_divsel; - u32 vco_ratio; - u32 ssc_en_center; - - u32 l0_tx_drv_lvl; - u32 l0_tx_emp_post1_lvl; - u32 l1_tx_drv_lvl; - u32 l1_tx_emp_post1_lvl; - u32 l2_tx_drv_lvl; - u32 l2_tx_emp_post1_lvl; - u32 l3_tx_drv_lvl; - u32 l3_tx_emp_post1_lvl; - - u32 l0_pre_driver_1; - u32 l0_pre_driver_2; - u32 l1_pre_driver_1; - u32 l1_pre_driver_2; - u32 l2_pre_driver_1; - u32 l2_pre_driver_2; - u32 l3_pre_driver_1; - u32 l3_pre_driver_2; - - bool debug; -}; - -static void hdmi_8998_get_div(struct 8998_reg_cfg * cfg, unsigned long pclk) -{ - u32 const ratio_list[] = {1, 2, 3, 4, 5, 6, - 9, 10, 12, 15, 25}; - u32 const band_list[] = {0, 1, 2, 3}; - u32 const sz_ratio = ARRAY_SIZE(ratio_list); - u32 const sz_band = ARRAY_SIZE(band_list); - u32 const min_freq = 8000, max_freq = 12000; - u32 const cmp_cnt = 1024; - u32 const th_min = 500, th_max = 1000; - u64 bit_clk = pclk * HDMI_BIT_CLK_TO_PIX_CLK_RATIO; - u32 half_rate_mode = 0; - u32 freq_optimal, list_elements; - int optimal_index; - u32 i, j, k; - u32 freq_list[sz_ratio * sz_band]; - u32 found_hsclk_divsel = 0, found_vco_ratio; - u32 found_tx_band_sel, found_vco_freq; - -find_optimal_index: - freq_optimal = max_freq; - optimal_index = -1; - list_elements = 0; - - for (i = 0; i < sz_ratio; i++) { - for (j = 0; j < sz_band; j++) { - u64 freq = (bit_clk / (1 << half_rate_mode)); - - freq *= (ratio_list[i] * (1 << band_list[j])); - do_div(freq, (u64) HDMI_MHZ_TO_HZ); - freq_list[list_elements++] = freq; - } - } - - for (k = 0; k < ARRAY_SIZE(freq_list); k++) { - u32 const clks_pll_div = 2, core_clk_div = 5; - u32 const rng1 = 16, rng2 = 8; - u32 core_clk, rvar1; - u32 th1, th2; - - core_clk = (((freq_list[k] / - ratio_list[k / sz_band]) / - clks_pll_div) / core_clk_div); - - rvar1 = HDMI_REF_CLOCK_HZ / cmp_cnt; - rvar1 *= rng1; - rvar1 /= core_clk; - - th1 = rvar1; - - rvar1 = HDMI_REF_CLOCK_HZ / cmp_cnt; - rvar1 *= rng2; - rvar1 /= core_clk; - - th2 = rvar1; - - if (freq_list[k] >= min_freq && - freq_list[k] <= max_freq) { - if ((th1 >= th_min && th1 <= th_max) || - (th2 >= th_min && th2 <= th_max)) { - if (freq_list[k] <= freq_optimal) { - freq_optimal = freq_list[k]; - optimal_index = k; - } - } - } - } - - if (optimal_index == -1) { - if (!half_rate_mode) { - half_rate_mode = 1; - goto find_optimal_index; - } else { - /* set to default values */ - found_vco_freq = max_freq; - found_hsclk_divsel = 0; - found_vco_ratio = 2; - found_tx_band_sel = 0; - pr_err("Config error for pclk %ld\n", pclk); - } - } else { - found_vco_ratio = ratio_list[optimal_index / sz_band]; - found_tx_band_sel = band_list[optimal_index % sz_band]; - found_vco_freq = freq_optimal; - } - - switch (found_vco_ratio) { - case 1: - found_hsclk_divsel = 15; - break; - case 2: - found_hsclk_divsel = 0; - break; - case 3: - found_hsclk_divsel = 4; - break; - case 4: - found_hsclk_divsel = 8; - break; - case 5: - found_hsclk_divsel = 12; - break; - case 6: - found_hsclk_divsel = 1; - break; - case 9: - found_hsclk_divsel = 5; - break; - case 10: - found_hsclk_divsel = 2; - break; - case 12: - found_hsclk_divsel = 9; - break; - case 15: - found_hsclk_divsel = 13; - break; - case 25: - found_hsclk_divsel = 14; - break; - } - - pr_debug("found_vco_freq=%d\n", found_vco_freq); - pr_debug("found_hsclk_divsel=%d\n", found_hsclk_divsel); - pr_debug("found_vco_ratio=%d\n", found_vco_ratio); - pr_debug("found_tx_band_sel=%d\n", found_tx_band_sel); - pr_debug("half_rate_mode=%d\n", half_rate_mode); - pr_debug("optimal_index=%d\n", optimal_index); - - cfg->vco_freq = found_vco_freq; - cfg->hsclk_divsel = found_hsclk_divsel; - cfg->vco_ratio = found_vco_ratio; - cfg->tx_band = found_tx_band_sel; -} - -static int hdmi_8998_config_phy(unsigned long rate, - struct 8998_reg_cfg * cfg) -{ - u64 const high_freq_bit_clk_threshold = 3400000000UL; - u64 const dig_freq_bit_clk_threshold = 1500000000UL; - u64 const mid_freq_bit_clk_threshold = 750000000; - u64 fdata, tmds_clk; - u64 pll_div = 4 * HDMI_REF_CLOCK_HZ; - u64 bclk; - u64 vco_freq_mhz; - u64 hsclk_sel, dec_start, div_frac_start; - u64 rem; - u64 cpctrl, rctrl, cctrl; - u64 integloop_gain; - u32 digclk_divsel; - u32 tmds_bclk_ratio; - u64 cmp_rng, cmp_cnt = 1024, pll_cmp; - bool gen_ssc = false; - - bclk = rate * HDMI_BIT_CLK_TO_PIX_CLK_RATIO; - - if (bclk > high_freq_bit_clk_threshold) { - tmds_clk = rate / 4; - tmds_bclk_ratio = 1; - } else { - tmds_clk = rate; - tmds_bclk_ratio = 0; - } - - hdmi_8998_get_div(cfg, rate); - - vco_freq_mhz = cfg->vco_freq * (u64) HDMI_HZ_TO_MHZ; - fdata = cfg->vco_freq; - do_div(fdata, cfg->vco_ratio); - - hsclk_sel = cfg->hsclk_divsel; - dec_start = vco_freq_mhz; - do_div(dec_start, pll_div); - - div_frac_start = vco_freq_mhz * (1 << 20); - rem = do_div(div_frac_start, pll_div); - div_frac_start -= (dec_start * (1 << 20)); - if (rem > (pll_div >> 1)) - div_frac_start++; - - if ((div_frac_start != 0) || gen_ssc) { - cpctrl = 0x8; - rctrl = 0x16; - cctrl = 0x34; - } else { - cpctrl = 0x30; - rctrl = 0x18; - cctrl = 0x2; - } - - digclk_divsel = (bclk > dig_freq_bit_clk_threshold) ? 0x1 : 0x2; - - integloop_gain = ((div_frac_start != 0) || - gen_ssc) ? 0x3F : 0xC4; - integloop_gain <<= digclk_divsel; - integloop_gain = (integloop_gain <= 2046 ? integloop_gain : 0x7FE); - - cmp_rng = gen_ssc ? 0x40 : 0x10; - - pll_cmp = cmp_cnt * fdata; - rem = do_div(pll_cmp, (u64)(HDMI_REF_CLOCK_MHZ * 10)); - if (rem > ((u64)(HDMI_REF_CLOCK_MHZ * 10) >> 1)) - pll_cmp++; - - pll_cmp = pll_cmp - 1; - - pr_debug("VCO_FREQ = %u\n", cfg->vco_freq); - pr_debug("FDATA = %llu\n", fdata); - pr_debug("DEC_START = %llu\n", dec_start); - pr_debug("DIV_FRAC_START = %llu\n", div_frac_start); - pr_debug("CPCTRL = %llu\n", cpctrl); - pr_debug("RCTRL = %llu\n", rctrl); - pr_debug("CCTRL = %llu\n", cctrl); - pr_debug("DIGCLK_DIVSEL = %u\n", digclk_divsel); - pr_debug("INTEGLOOP_GAIN = %llu\n", integloop_gain); - pr_debug("CMP_RNG = %llu\n", cmp_rng); - pr_debug("PLL_CMP = %llu\n", pll_cmp); - - cfg->svs_mode_clk_sel = (digclk_divsel & 0xFF); - cfg->hsclk_sel = (0x20 | hsclk_sel); - cfg->lock_cmp_en = (gen_ssc ? 0x4 : 0x0); - cfg->cctrl_mode0 = (cctrl & 0xFF); - cfg->rctrl_mode0 = (rctrl & 0xFF); - cfg->cpctrl_mode0 = (cpctrl & 0xFF); - cfg->dec_start_mode0 = (dec_start & 0xFF); - cfg->div_frac_start1_mode0 = (div_frac_start & 0xFF); - cfg->div_frac_start2_mode0 = ((div_frac_start & 0xFF00) >> 8); - cfg->div_frac_start3_mode0 = ((div_frac_start & 0xF0000) >> 16); - cfg->integloop_gain0_mode0 = (integloop_gain & 0xFF); - cfg->integloop_gain1_mode0 = (integloop_gain & 0xF00) >> 8; - cfg->lock_cmp1_mode0 = (pll_cmp & 0xFF); - cfg->lock_cmp2_mode0 = ((pll_cmp & 0xFF00) >> 8); - cfg->lock_cmp3_mode0 = ((pll_cmp & 0x30000) >> 16); - cfg->ssc_per1 = 0; - cfg->ssc_per2 = 0; - cfg->ssc_step_size1 = 0; - cfg->ssc_step_size2 = 0; - cfg->core_clk_en = 0x2C; - cfg->coreclk_div_mode0 = 0x5; - cfg->phy_mode = (tmds_bclk_ratio ? 0x5 : 0x4); - cfg->ssc_en_center = 0x0; - - if (bclk > high_freq_bit_clk_threshold) { - cfg->l0_tx_drv_lvl = 0xA; - cfg->l0_tx_emp_post1_lvl = 0x3; - cfg->l1_tx_drv_lvl = 0xA; - cfg->l1_tx_emp_post1_lvl = 0x3; - cfg->l2_tx_drv_lvl = 0xA; - cfg->l2_tx_emp_post1_lvl = 0x3; - cfg->l3_tx_drv_lvl = 0x8; - cfg->l3_tx_emp_post1_lvl = 0x3; - cfg->l0_pre_driver_1 = 0x0; - cfg->l0_pre_driver_2 = 0x1C; - cfg->l1_pre_driver_1 = 0x0; - cfg->l1_pre_driver_2 = 0x1C; - cfg->l2_pre_driver_1 = 0x0; - cfg->l2_pre_driver_2 = 0x1C; - cfg->l3_pre_driver_1 = 0x0; - cfg->l3_pre_driver_2 = 0x0; - } else if (bclk > dig_freq_bit_clk_threshold) { - cfg->l0_tx_drv_lvl = 0x9; - cfg->l0_tx_emp_post1_lvl = 0x3; - cfg->l1_tx_drv_lvl = 0x9; - cfg->l1_tx_emp_post1_lvl = 0x3; - cfg->l2_tx_drv_lvl = 0x9; - cfg->l2_tx_emp_post1_lvl = 0x3; - cfg->l3_tx_drv_lvl = 0x8; - cfg->l3_tx_emp_post1_lvl = 0x3; - cfg->l0_pre_driver_1 = 0x0; - cfg->l0_pre_driver_2 = 0x16; - cfg->l1_pre_driver_1 = 0x0; - cfg->l1_pre_driver_2 = 0x16; - cfg->l2_pre_driver_1 = 0x0; - cfg->l2_pre_driver_2 = 0x16; - cfg->l3_pre_driver_1 = 0x0; - cfg->l3_pre_driver_2 = 0x0; - } else if (bclk > mid_freq_bit_clk_threshold) { - cfg->l0_tx_drv_lvl = 0x9; - cfg->l0_tx_emp_post1_lvl = 0x3; - cfg->l1_tx_drv_lvl = 0x9; - cfg->l1_tx_emp_post1_lvl = 0x3; - cfg->l2_tx_drv_lvl = 0x9; - cfg->l2_tx_emp_post1_lvl = 0x3; - cfg->l3_tx_drv_lvl = 0x8; - cfg->l3_tx_emp_post1_lvl = 0x3; - cfg->l0_pre_driver_1 = 0x0; - cfg->l0_pre_driver_2 = 0x0E; - cfg->l1_pre_driver_1 = 0x0; - cfg->l1_pre_driver_2 = 0x0E; - cfg->l2_pre_driver_1 = 0x0; - cfg->l2_pre_driver_2 = 0x0E; - cfg->l3_pre_driver_1 = 0x0; - cfg->l3_pre_driver_2 = 0x0; - } else { - cfg->l0_tx_drv_lvl = 0x0; - cfg->l0_tx_emp_post1_lvl = 0x0; - cfg->l1_tx_drv_lvl = 0x0; - cfg->l1_tx_emp_post1_lvl = 0x0; - cfg->l2_tx_drv_lvl = 0x0; - cfg->l2_tx_emp_post1_lvl = 0x0; - cfg->l3_tx_drv_lvl = 0x0; - cfg->l3_tx_emp_post1_lvl = 0x0; - cfg->l0_pre_driver_1 = 0x0; - cfg->l0_pre_driver_2 = 0x01; - cfg->l1_pre_driver_1 = 0x0; - cfg->l1_pre_driver_2 = 0x01; - cfg->l2_pre_driver_1 = 0x0; - cfg->l2_pre_driver_2 = 0x01; - cfg->l3_pre_driver_1 = 0x0; - cfg->l3_pre_driver_2 = 0x0; - } - - return 0; -} - -static int hdmi_8998_pll_set_clk_rate(struct clk *c, unsigned long rate) -{ - int rc = 0; - struct hdmi_pll_vco_clk *vco = to_hdmi_vco_clk(c); - struct mdss_pll_resources *io = vco->priv; - struct 8998_reg_cfg cfg = {0}; - void __iomem *phy = io->phy_base, *pll = io->pll_base; - - rc = hdmi_8998_config_phy(rate, &cfg); - if (rc) { - pr_err("rate calculation failed\n, rc=%d\n", rc); - return rc; - } - - _W(phy, PHY_PD_CTL, 0x0); - udelay(500); - - _W(phy, PHY_PD_CTL, 0x1); - _W(pll, RESETSM_CNTRL, 0x20); - _W(phy, PHY_CMN_CTRL, 0x6); - _W(pll, PHY_TX_INTERFACE_SELECT_TX_BAND(0), cfg.tx_band); - _W(pll, PHY_TX_INTERFACE_SELECT_TX_BAND(1), cfg.tx_band); - _W(pll, PHY_TX_INTERFACE_SELECT_TX_BAND(2), cfg.tx_band); - _W(pll, PHY_TX_INTERFACE_SELECT_TX_BAND(3), cfg.tx_band); - _W(pll, PHY_TX_CLKBUF_TERM_ENABLE(0), 0x1); - _W(pll, PHY_TX_LANE_MODE(0), 0x20); - _W(pll, PHY_TX_LANE_MODE(1), 0x20); - _W(pll, PHY_TX_LANE_MODE(2), 0x20); - _W(pll, PHY_TX_LANE_MODE(3), 0x20); - _W(pll, PHY_TX_CLKBUF_TERM_ENABLE(1), 0x1); - _W(pll, PHY_TX_CLKBUF_TERM_ENABLE(2), 0x1); - _W(pll, PHY_TX_CLKBUF_TERM_ENABLE(3), 0x1); - _W(pll, SYSCLK_BUF_ENABLE, 0x2); - _W(pll, BIAS_EN_CLKBUFLR_EN, 0xB); - _W(pll, SYSCLK_EN_SEL, 0x37); - _W(pll, SYS_CLK_CTRL, 0x2); - _W(pll, CLK_ENABLE1, 0xE); - _W(pll, PLL_IVCO, 0xF); - _W(pll, VCO_TUNE_CTRL, 0x0); - _W(pll, SVS_MODE_CLK_SEL, cfg.svs_mode_clk_sel); - _W(pll, CLK_SELECT, 0x30); - _W(pll, HSCLK_SEL, cfg.hsclk_sel); - _W(pll, LOCK_CMP_EN, cfg.lock_cmp_en); - _W(pll, PLL_CCTRL_MODE0, cfg.cctrl_mode0); - _W(pll, PLL_RCTRL_MODE0, cfg.rctrl_mode0); - _W(pll, CP_CTRL_MODE0, cfg.cpctrl_mode0); - _W(pll, DEC_START_MODE0, cfg.dec_start_mode0); - _W(pll, DIV_FRAC_START1_MODE0, cfg.div_frac_start1_mode0); - _W(pll, DIV_FRAC_START2_MODE0, cfg.div_frac_start2_mode0); - _W(pll, DIV_FRAC_START3_MODE0, cfg.div_frac_start3_mode0); - _W(pll, INTEGLOOP_GAIN0_MODE0, cfg.integloop_gain0_mode0); - _W(pll, INTEGLOOP_GAIN1_MODE0, cfg.integloop_gain1_mode0); - _W(pll, LOCK_CMP1_MODE0, cfg.lock_cmp1_mode0); - _W(pll, LOCK_CMP2_MODE0, cfg.lock_cmp2_mode0); - _W(pll, LOCK_CMP3_MODE0, cfg.lock_cmp3_mode0); - _W(pll, VCO_TUNE_MAP, 0x0); - _W(pll, CORE_CLK_EN, cfg.core_clk_en); - _W(pll, CORECLK_DIV_MODE0, cfg.coreclk_div_mode0); - - _W(pll, PHY_TX_DRV_LVL(0), cfg.l0_tx_drv_lvl); - _W(pll, PHY_TX_DRV_LVL(1), cfg.l1_tx_drv_lvl); - _W(pll, PHY_TX_DRV_LVL(2), cfg.l2_tx_drv_lvl); - _W(pll, PHY_TX_DRV_LVL(3), cfg.l3_tx_drv_lvl); - - _W(pll, PHY_TX_EMP_POST1_LVL(0), cfg.l0_tx_emp_post1_lvl); - _W(pll, PHY_TX_EMP_POST1_LVL(1), cfg.l1_tx_emp_post1_lvl); - _W(pll, PHY_TX_EMP_POST1_LVL(2), cfg.l2_tx_emp_post1_lvl); - _W(pll, PHY_TX_EMP_POST1_LVL(3), cfg.l3_tx_emp_post1_lvl); - - _W(pll, PHY_TX_PRE_DRIVER_1(0), cfg.l0_pre_driver_1); - _W(pll, PHY_TX_PRE_DRIVER_1(1), cfg.l1_pre_driver_1); - _W(pll, PHY_TX_PRE_DRIVER_1(2), cfg.l2_pre_driver_1); - _W(pll, PHY_TX_PRE_DRIVER_1(3), cfg.l3_pre_driver_1); - - _W(pll, PHY_TX_PRE_DRIVER_2(0), cfg.l0_pre_driver_2); - _W(pll, PHY_TX_PRE_DRIVER_2(1), cfg.l1_pre_driver_2); - _W(pll, PHY_TX_PRE_DRIVER_2(2), cfg.l2_pre_driver_2); - _W(pll, PHY_TX_PRE_DRIVER_2(3), cfg.l3_pre_driver_2); - - _W(pll, PHY_TX_DRV_LVL_RES_CODE_OFFSET(0), 0x0); - _W(pll, PHY_TX_DRV_LVL_RES_CODE_OFFSET(1), 0x0); - _W(pll, PHY_TX_DRV_LVL_RES_CODE_OFFSET(2), 0x0); - _W(pll, PHY_TX_DRV_LVL_RES_CODE_OFFSET(3), 0x0); - - _W(phy, PHY_MODE, cfg.phy_mode); - - _W(pll, PHY_TX_LANE_CONFIG(0), 0x10); - _W(pll, PHY_TX_LANE_CONFIG(1), 0x10); - _W(pll, PHY_TX_LANE_CONFIG(2), 0x10); - _W(pll, PHY_TX_LANE_CONFIG(3), 0x10); - - /* Ensure all registers are flushed to hardware */ - wmb(); - - return 0; -} - -static int hdmi_8998_pll_lock_status(struct mdss_pll_resources *io) -{ - u32 const delay_us = 100; - u32 const timeout_us = 5000; - u32 status; - int rc = 0; - void __iomem *pll = io->pll_base; - - rc = mdss_pll_resource_enable(io, true); - if (rc) { - pr_err("pll resource can't be enabled\n"); - return rc; - } - rc = readl_poll_timeout_atomic(pll + C_READY_STATUS, - status, - ((status & BIT(0)) > 0), - delay_us, - timeout_us); - if (rc) - pr_err("HDMI PLL(%d) lock failed, status=0x%08x\n", - io->index, status); - else - pr_debug("HDMI PLL(%d) lock passed, status=0x%08x\n", - io->index, status); - - mdss_pll_resource_enable(io, false); - - return rc; -} - -static int hdmi_8998_phy_ready_status(struct mdss_pll_resources *io) -{ - u32 const delay_us = 100; - u32 const timeout_us = 5000; - u32 status; - int rc = 0; - void __iomem *phy = io->phy_base; - - rc = mdss_pll_resource_enable(io, true); - if (rc) { - pr_err("pll resource can't be enabled\n"); - return rc; - } - - rc = readl_poll_timeout_atomic(phy + PHY_STATUS, - status, - ((status & BIT(0)) > 0), - delay_us, - timeout_us); - if (rc) - pr_err("HDMI PHY(%d) not ready, status=0x%08x\n", - io->index, status); - else - pr_debug("HDMI PHY(%d) ready, status=0x%08x\n", - io->index, status); - - mdss_pll_resource_enable(io, false); - - return rc; -} - -static int hdmi_8998_vco_set_rate(struct clk *c, unsigned long rate) -{ - int rc = 0; - struct hdmi_pll_vco_clk *vco = to_hdmi_vco_clk(c); - struct mdss_pll_resources *io = vco->priv; - - rc = mdss_pll_resource_enable(io, true); - if (rc) { - pr_err("pll resource enable failed, rc=%d\n", rc); - return rc; - } - - if (io->pll_on) - goto error; - - rc = hdmi_8998_pll_set_clk_rate(c, rate); - if (rc) { - pr_err("failed to set clk rate, rc=%d\n", rc); - goto error; - } - - vco->rate = rate; - vco->rate_set = true; - -error: - (void)mdss_pll_resource_enable(io, false); - - return rc; -} - -static long hdmi_8998_vco_round_rate(struct clk *c, unsigned long rate) -{ - unsigned long rrate = rate; - struct hdmi_pll_vco_clk *vco = to_hdmi_vco_clk(c); - - if (rate < vco->min_rate) - rrate = vco->min_rate; - if (rate > vco->max_rate) - rrate = vco->max_rate; - - return rrate; -} - -static int hdmi_8998_pll_enable(struct clk *c) -{ - int rc = 0; - struct hdmi_pll_vco_clk *vco = to_hdmi_vco_clk(c); - struct mdss_pll_resources *io = vco->priv; - void __iomem *phy = io->phy_base, *pll = io->pll_base; - - _W(phy, PHY_CFG, 0x1); - udelay(100); - _W(phy, PHY_CFG, 0x59); - udelay(100); - - _W(phy, PHY_CLOCK, 0x6); - - /* Ensure all registers are flushed to hardware */ - wmb(); - - rc = hdmi_8998_pll_lock_status(io); - if (rc) { - pr_err("PLL not locked, rc=%d\n", rc); - return rc; - } - - _W(pll, PHY_TX_LANE_CONFIG(0), 0x1F); - _W(pll, PHY_TX_LANE_CONFIG(1), 0x1F); - _W(pll, PHY_TX_LANE_CONFIG(2), 0x1F); - _W(pll, PHY_TX_LANE_CONFIG(3), 0x1F); - - /* Ensure all registers are flushed to hardware */ - wmb(); - - rc = hdmi_8998_phy_ready_status(io); - if (rc) { - pr_err("PHY NOT READY, rc=%d\n", rc); - return rc; - } - - _W(phy, PHY_CFG, 0x58); - udelay(1); - _W(phy, PHY_CFG, 0x59); - - /* Ensure all registers are flushed to hardware */ - wmb(); - - io->pll_on = true; - return rc; -} - -static int hdmi_8998_vco_prepare(struct clk *c) -{ - struct hdmi_pll_vco_clk *vco = to_hdmi_vco_clk(c); - struct mdss_pll_resources *io = vco->priv; - int rc = 0; - - if (!io) { - pr_err("hdmi pll resources are not available\n"); - return -EINVAL; - } - - rc = mdss_pll_resource_enable(io, true); - if (rc) { - pr_err("pll resource enable failed, rc=%d\n", rc); - return rc; - } - - if (!vco->rate_set && vco->rate) { - rc = hdmi_8998_pll_set_clk_rate(c, vco->rate); - if (rc) { - pr_err("set rate failed, rc=%d\n", rc); - goto error; - } - } - - rc = hdmi_8998_pll_enable(c); - if (rc) - pr_err("pll enabled failed, rc=%d\n", rc); - -error: - if (rc) - mdss_pll_resource_enable(io, false); - - return rc; -} - -static void hdmi_8998_pll_disable(struct hdmi_pll_vco_clk *vco) -{ - struct mdss_pll_resources *io = vco->priv; - void __iomem *phy = io->phy_base; - - if (!io->pll_on) - return; - - _W(phy, PHY_PD_CTL, 0x0); - - /* Ensure all registers are flushed to hardware */ - wmb(); - - vco->rate_set = false; - io->handoff_resources = false; - io->pll_on = false; -} - -static void hdmi_8998_vco_unprepare(struct clk *c) -{ - struct hdmi_pll_vco_clk *vco = to_hdmi_vco_clk(c); - struct mdss_pll_resources *io = vco->priv; - - if (!io) { - pr_err("HDMI pll resources not available\n"); - return; - } - - hdmi_8998_pll_disable(vco); - mdss_pll_resource_enable(io, false); -} - -static enum handoff hdmi_8998_vco_handoff(struct clk *c) -{ - enum handoff ret = HANDOFF_DISABLED_CLK; - struct hdmi_pll_vco_clk *vco = to_hdmi_vco_clk(c); - struct mdss_pll_resources *io = vco->priv; - - if (mdss_pll_resource_enable(io, true)) { - pr_err("pll resource can't be enabled\n"); - return ret; - } - - io->handoff_resources = true; - - if (_R(io->pll_base, C_READY_STATUS) & BIT(0) && - _R(io->phy_base, PHY_STATUS) & BIT(0)) { - io->pll_on = true; - /* TODO: calculate rate based on the phy/pll register values. */ - ret = HANDOFF_ENABLED_CLK; - } else { - io->handoff_resources = false; - mdss_pll_resource_enable(io, false); - pr_debug("%s: PHY/PLL not ready\n", __func__); - } - - pr_debug("done, ret=%d\n", ret); - return ret; -} - -static const struct clk_ops hdmi_8998_vco_clk_ops = { - .set_rate = hdmi_8998_vco_set_rate, - .round_rate = hdmi_8998_vco_round_rate, - .prepare = hdmi_8998_vco_prepare, - .unprepare = hdmi_8998_vco_unprepare, - .handoff = hdmi_8998_vco_handoff, -}; - -static struct hdmi_pll_vco_clk hdmi_vco_clk = { - .min_rate = HDMI_VCO_MIN_RATE_HZ, - .max_rate = HDMI_VCO_MAX_RATE_HZ, - .c = { - .dbg_name = "hdmi_8998_vco_clk", - .ops = &hdmi_8998_vco_clk_ops, - CLK_INIT(hdmi_vco_clk.c), - }, -}; - -static struct clk_lookup hdmipllcc_8998[] = { - CLK_LIST(hdmi_vco_clk), -}; - -int hdmi_8998_pll_clock_register(struct platform_device *pdev, - struct mdss_pll_resources *pll_res) -{ - int rc = 0; - - hdmi_vco_clk.priv = pll_res; - - rc = of_msm_clock_register(pdev->dev.of_node, hdmipllcc_8998, - ARRAY_SIZE(hdmipllcc_8998)); - if (rc) { - pr_err("clock register failed, rc=%d\n", rc); - return rc; - } - - return rc; -} diff --git a/pll/pll_drv.c b/pll/pll_drv.c deleted file mode 100644 index 5e0cd4cf4e7a..000000000000 --- a/pll/pll_drv.c +++ /dev/null @@ -1,424 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (c) 2013-2019, The Linux Foundation. All rights reserved. - */ - -#define pr_fmt(fmt) "%s: " fmt, __func__ - -#include -#include -#include -#include -#include -#include -#include "pll_drv.h" -#include "dsi_pll.h" -#include "dp_pll.h" -#include "hdmi_pll.h" - -int mdss_pll_resource_enable(struct mdss_pll_resources *pll_res, bool enable) -{ - int rc = 0; - int changed = 0; - - if (!pll_res) { - pr_err("Invalid input parameters\n"); - return -EINVAL; - } - - /* - * Don't turn off resources during handoff or add more than - * 1 refcount. - */ - if (pll_res->handoff_resources && - (!enable || (enable & pll_res->resource_enable))) { - pr_debug("Do not turn on/off pll resources during handoff case\n"); - return rc; - } - - if (enable) { - if (pll_res->resource_ref_cnt == 0) - changed++; - pll_res->resource_ref_cnt++; - } else { - if (pll_res->resource_ref_cnt) { - pll_res->resource_ref_cnt--; - if (pll_res->resource_ref_cnt == 0) - changed++; - } else { - pr_err("PLL Resources already OFF\n"); - } - } - - if (changed) { - rc = mdss_pll_util_resource_enable(pll_res, enable); - if (rc) - pr_err("Resource update failed rc=%d\n", rc); - else - pll_res->resource_enable = enable; - } - - return rc; -} - -static int mdss_pll_resource_init(struct platform_device *pdev, - struct mdss_pll_resources *pll_res) -{ - int rc = 0; - struct dss_module_power *mp = &pll_res->mp; - - rc = msm_dss_config_vreg(&pdev->dev, - mp->vreg_config, mp->num_vreg, 1); - if (rc) { - pr_err("Vreg config failed rc=%d\n", rc); - goto vreg_err; - } - - rc = msm_dss_get_clk(&pdev->dev, mp->clk_config, mp->num_clk); - if (rc) { - pr_err("Clock get failed rc=%d\n", rc); - goto clk_err; - } - - return rc; - -clk_err: - msm_dss_config_vreg(&pdev->dev, mp->vreg_config, mp->num_vreg, 0); -vreg_err: - return rc; -} - -static void mdss_pll_resource_deinit(struct platform_device *pdev, - struct mdss_pll_resources *pll_res) -{ - struct dss_module_power *mp = &pll_res->mp; - - msm_dss_put_clk(mp->clk_config, mp->num_clk); - - msm_dss_config_vreg(&pdev->dev, mp->vreg_config, mp->num_vreg, 0); -} - -static void mdss_pll_resource_release(struct platform_device *pdev, - struct mdss_pll_resources *pll_res) -{ - struct dss_module_power *mp = &pll_res->mp; - - mp->num_vreg = 0; - mp->num_clk = 0; -} - -static int mdss_pll_resource_parse(struct platform_device *pdev, - struct mdss_pll_resources *pll_res) -{ - int rc = 0; - const char *compatible_stream; - - rc = mdss_pll_util_resource_parse(pdev, pll_res); - if (rc) { - pr_err("Failed to parse the resources rc=%d\n", rc); - goto end; - } - - compatible_stream = of_get_property(pdev->dev.of_node, - "compatible", NULL); - if (!compatible_stream) { - pr_err("Failed to parse the compatible stream\n"); - goto err; - } - - if (!strcmp(compatible_stream, "qcom,mdss_dsi_pll_10nm")) - pll_res->pll_interface_type = MDSS_DSI_PLL_10NM; - if (!strcmp(compatible_stream, "qcom,mdss_dp_pll_10nm")) - pll_res->pll_interface_type = MDSS_DP_PLL_10NM; - else if (!strcmp(compatible_stream, "qcom,mdss_dp_pll_7nm")) - pll_res->pll_interface_type = MDSS_DP_PLL_7NM; - else if (!strcmp(compatible_stream, "qcom,mdss_dp_pll_7nm_v2")) - pll_res->pll_interface_type = MDSS_DP_PLL_7NM_V2; - else if (!strcmp(compatible_stream, "qcom,mdss_dsi_pll_7nm")) - pll_res->pll_interface_type = MDSS_DSI_PLL_7NM; - else if (!strcmp(compatible_stream, "qcom,mdss_dsi_pll_7nm_v2")) - pll_res->pll_interface_type = MDSS_DSI_PLL_7NM_V2; - else if (!strcmp(compatible_stream, "qcom,mdss_dsi_pll_7nm_v4_1")) - pll_res->pll_interface_type = MDSS_DSI_PLL_7NM_V4_1; - else if (!strcmp(compatible_stream, "qcom,mdss_dsi_pll_28lpm")) - pll_res->pll_interface_type = MDSS_DSI_PLL_28LPM; - else if (!strcmp(compatible_stream, "qcom,mdss_dsi_pll_14nm")) - pll_res->pll_interface_type = MDSS_DSI_PLL_14NM; - else if (!strcmp(compatible_stream, "qcom,mdss_dp_pll_14nm")) - pll_res->pll_interface_type = MDSS_DP_PLL_14NM; - else if (!strcmp(compatible_stream, "qcom,mdss_hdmi_pll_28lpm")) - pll_res->pll_interface_type = MDSS_HDMI_PLL_28LPM; - else - goto err; - - return rc; - -err: - mdss_pll_resource_release(pdev, pll_res); -end: - return rc; -} -static int mdss_pll_clock_register(struct platform_device *pdev, - struct mdss_pll_resources *pll_res) -{ - int rc; - - switch (pll_res->pll_interface_type) { - case MDSS_DSI_PLL_10NM: - rc = dsi_pll_clock_register_10nm(pdev, pll_res); - break; - case MDSS_DP_PLL_10NM: - rc = dp_pll_clock_register_10nm(pdev, pll_res); - break; - case MDSS_DSI_PLL_7NM: - case MDSS_DSI_PLL_7NM_V2: - case MDSS_DSI_PLL_7NM_V4_1: - rc = dsi_pll_clock_register_7nm(pdev, pll_res); - break; - case MDSS_DP_PLL_7NM: - case MDSS_DP_PLL_7NM_V2: - rc = dp_pll_clock_register_7nm(pdev, pll_res); - break; - case MDSS_DSI_PLL_28LPM: - rc = dsi_pll_clock_register_28lpm(pdev, pll_res); - break; - case MDSS_DSI_PLL_14NM: - rc = dsi_pll_clock_register_14nm(pdev, pll_res); - break; - case MDSS_DP_PLL_14NM: - rc = dp_pll_clock_register_14nm(pdev, pll_res); - break; - case MDSS_HDMI_PLL_28LPM: - rc = hdmi_pll_clock_register_28lpm(pdev, pll_res); - break; - case MDSS_UNKNOWN_PLL: - default: - rc = -EINVAL; - break; - } - - if (rc) - pr_err("Pll ndx=%d clock register failed rc=%d\n", - pll_res->index, rc); - - return rc; -} - -static inline int mdss_pll_get_ioresurces(struct platform_device *pdev, - void __iomem **regmap, char *resource_name) -{ - int rc = 0; - struct resource *rsc = platform_get_resource_byname(pdev, - IORESOURCE_MEM, resource_name); - if (rsc) { - if (!regmap) - return -ENOMEM; - - *regmap = devm_ioremap(&pdev->dev, - rsc->start, resource_size(rsc)); - if (!*regmap) - return -ENOMEM; - } - return rc; -} - -static int mdss_pll_probe(struct platform_device *pdev) -{ - int rc = 0; - const char *label; - struct mdss_pll_resources *pll_res; - - if (!pdev->dev.of_node) { - pr_err("MDSS pll driver only supports device tree probe\n"); - return -ENOTSUPP; - } - - label = of_get_property(pdev->dev.of_node, "label", NULL); - if (!label) - pr_info("MDSS pll label not specified\n"); - else - pr_info("MDSS pll label = %s\n", label); - - pll_res = devm_kzalloc(&pdev->dev, sizeof(struct mdss_pll_resources), - GFP_KERNEL); - if (!pll_res) - return -ENOMEM; - - platform_set_drvdata(pdev, pll_res); - - rc = of_property_read_u32(pdev->dev.of_node, "cell-index", - &pll_res->index); - if (rc) { - pr_err("Unable to get the cell-index rc=%d\n", rc); - pll_res->index = 0; - } - - pll_res->ssc_en = of_property_read_bool(pdev->dev.of_node, - "qcom,dsi-pll-ssc-en"); - - if (pll_res->ssc_en) { - pr_info("%s: label=%s PLL SSC enabled\n", __func__, label); - - rc = of_property_read_u32(pdev->dev.of_node, - "qcom,ssc-frequency-hz", &pll_res->ssc_freq); - - rc = of_property_read_u32(pdev->dev.of_node, - "qcom,ssc-ppm", &pll_res->ssc_ppm); - - pll_res->ssc_center = false; - - label = of_get_property(pdev->dev.of_node, - "qcom,dsi-pll-ssc-mode", NULL); - - if (label && !strcmp(label, "center-spread")) - pll_res->ssc_center = true; - } - - - if (mdss_pll_get_ioresurces(pdev, &pll_res->pll_base, "pll_base")) { - pr_err("Unable to remap pll base resources\n"); - return -ENOMEM; - } - - pr_debug("%s: ndx=%d base=%p\n", __func__, - pll_res->index, pll_res->pll_base); - - rc = mdss_pll_resource_parse(pdev, pll_res); - if (rc) { - pr_err("Pll resource parsing from dt failed rc=%d\n", rc); - return rc; - } - - if (mdss_pll_get_ioresurces(pdev, &pll_res->phy_base, "phy_base")) { - pr_err("Unable to remap pll phy base resources\n"); - return -ENOMEM; - } - - if (mdss_pll_get_ioresurces(pdev, &pll_res->dyn_pll_base, - "dynamic_pll_base")) { - pr_err("Unable to remap dynamic pll base resources\n"); - return -ENOMEM; - } - - if (mdss_pll_get_ioresurces(pdev, &pll_res->ln_tx0_base, - "ln_tx0_base")) { - pr_err("Unable to remap Lane TX0 base resources\n"); - return -ENOMEM; - } - - if (mdss_pll_get_ioresurces(pdev, &pll_res->ln_tx0_tran_base, - "ln_tx0_tran_base")) { - pr_err("Unable to remap Lane TX0 base resources\n"); - return -ENOMEM; - } - - if (mdss_pll_get_ioresurces(pdev, &pll_res->ln_tx0_vmode_base, - "ln_tx0_vmode_base")) { - pr_err("Unable to remap Lane TX0 base resources\n"); - return -ENOMEM; - } - - if (mdss_pll_get_ioresurces(pdev, &pll_res->ln_tx1_base, - "ln_tx1_base")) { - pr_err("Unable to remap Lane TX1 base resources\n"); - return -ENOMEM; - } - - if (mdss_pll_get_ioresurces(pdev, &pll_res->ln_tx1_tran_base, - "ln_tx1_tran_base")) { - pr_err("Unable to remap Lane TX1 base resources\n"); - return -ENOMEM; - } - - if (mdss_pll_get_ioresurces(pdev, &pll_res->ln_tx1_vmode_base, - "ln_tx1_vmode_base")) { - pr_err("Unable to remap Lane TX1 base resources\n"); - return -ENOMEM; - } - - if (mdss_pll_get_ioresurces(pdev, &pll_res->gdsc_base, "gdsc_base")) { - pr_err("Unable to remap gdsc base resources\n"); - return -ENOMEM; - } - - rc = mdss_pll_resource_init(pdev, pll_res); - if (rc) { - pr_err("Pll ndx=%d resource init failed rc=%d\n", - pll_res->index, rc); - return rc; - } - - rc = mdss_pll_clock_register(pdev, pll_res); - if (rc) { - pr_err("Pll ndx=%d clock register failed rc=%d\n", - pll_res->index, rc); - goto clock_register_error; - } - - return rc; - -clock_register_error: - mdss_pll_resource_deinit(pdev, pll_res); - return rc; -} - -static int mdss_pll_remove(struct platform_device *pdev) -{ - struct mdss_pll_resources *pll_res; - - pll_res = platform_get_drvdata(pdev); - if (!pll_res) { - pr_err("Invalid PLL resource data\n"); - return 0; - } - - mdss_pll_resource_deinit(pdev, pll_res); - mdss_pll_resource_release(pdev, pll_res); - return 0; -} - -static const struct of_device_id mdss_pll_dt_match[] = { - {.compatible = "qcom,mdss_dsi_pll_10nm"}, - {.compatible = "qcom,mdss_dp_pll_10nm"}, - {.compatible = "qcom,mdss_dsi_pll_7nm"}, - {.compatible = "qcom,mdss_dsi_pll_7nm_v2"}, - {.compatible = "qcom,mdss_dsi_pll_7nm_v4_1"}, - {.compatible = "qcom,mdss_dp_pll_7nm"}, - {.compatible = "qcom,mdss_dp_pll_7nm_v2"}, - {.compatible = "qcom,mdss_dsi_pll_28lpm"}, - {.compatible = "qcom,mdss_dsi_pll_14nm"}, - {.compatible = "qcom,mdss_dp_pll_14nm"}, - {}, -}; - -MODULE_DEVICE_TABLE(of, mdss_clock_dt_match); - -static struct platform_driver mdss_pll_driver = { - .probe = mdss_pll_probe, - .remove = mdss_pll_remove, - .driver = { - .name = "mdss_pll", - .of_match_table = mdss_pll_dt_match, - }, -}; - -static int __init mdss_pll_driver_init(void) -{ - int rc; - - rc = platform_driver_register(&mdss_pll_driver); - if (rc) - pr_err("mdss_register_pll_driver() failed!\n"); - - return rc; -} -fs_initcall(mdss_pll_driver_init); - -static void __exit mdss_pll_driver_deinit(void) -{ - platform_driver_unregister(&mdss_pll_driver); -} -module_exit(mdss_pll_driver_deinit); - -MODULE_LICENSE("GPL v2"); -MODULE_DESCRIPTION("mdss pll driver"); diff --git a/pll/pll_trace.h b/pll/pll_trace.h deleted file mode 100644 index d847920c99c5..000000000000 --- a/pll/pll_trace.h +++ /dev/null @@ -1,109 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. - */ - -#if !defined(_MDSS_PLL_TRACE_H_) || defined(TRACE_HEADER_MULTI_READ) -#define _MDSS_PLL_TRACE_H_ - -#include -#include -#include - -#undef TRACE_SYSTEM -#define TRACE_SYSTEM mdss_pll -#undef TRACE_INCLUDE_FILE -#define TRACE_INCLUDE_FILE pll_trace - - -TRACE_EVENT(mdss_pll_lock_start, - TP_PROTO( - u64 vco_cached_rate, - s64 vco_current_rate, - u32 cached_cfg0, - u32 cached_cfg1, - u32 cached_outdiv, - u32 resource_ref_cnt), - TP_ARGS( - vco_cached_rate, - vco_current_rate, - cached_cfg0, - cached_cfg1, - cached_outdiv, - resource_ref_cnt), - TP_STRUCT__entry( - __field(u64, vco_cached_rate) - __field(s64, vco_current_rate) - __field(u32, cached_cfg0) - __field(u32, cached_cfg1) - __field(u32, cached_outdiv) - __field(u32, resource_ref_cnt) - - ), - TP_fast_assign( - __entry->vco_cached_rate = vco_cached_rate; - __entry->vco_current_rate = vco_current_rate; - __entry->cached_cfg0 = cached_cfg0; - __entry->cached_cfg1 = cached_cfg1; - __entry->cached_outdiv = cached_outdiv; - __entry->resource_ref_cnt = resource_ref_cnt; - ), - TP_printk( - "vco_cached_rate=%llu vco_current_rate=%lld cached_cfg0=%d cached_cfg1=%d cached_outdiv=%d resource_ref_cnt=%d", - __entry->vco_cached_rate, - __entry->vco_current_rate, - __entry->cached_cfg0, - __entry->cached_cfg1, - __entry->cached_outdiv, - __entry->resource_ref_cnt) -); - -TRACE_EVENT(pll_tracing_mark_write, - TP_PROTO(int pid, const char *name, bool trace_begin), - TP_ARGS(pid, name, trace_begin), - TP_STRUCT__entry( - __field(int, pid) - __string(trace_name, name) - __field(bool, trace_begin) - ), - TP_fast_assign( - __entry->pid = pid; - __assign_str(trace_name, name); - __entry->trace_begin = trace_begin; - ), - TP_printk("%s|%d|%s", __entry->trace_begin ? "B" : "E", - __entry->pid, __get_str(trace_name)) -) - -TRACE_EVENT(mdss_pll_trace_counter, - TP_PROTO(int pid, char *name, int value), - TP_ARGS(pid, name, value), - TP_STRUCT__entry( - __field(int, pid) - __string(counter_name, name) - __field(int, value) - ), - TP_fast_assign( - __entry->pid = current->tgid; - __assign_str(counter_name, name); - __entry->value = value; - ), - TP_printk("%d|%s|%d", __entry->pid, - __get_str(counter_name), __entry->value) -) - -#define MDSS_PLL_ATRACE_END(name) trace_pll_tracing_mark_write(current->tgid,\ - name, 0) -#define MDSS_PLL_ATRACE_BEGIN(name) trace_pll_tracing_mark_write(current->tgid,\ - name, 1) -#define MDSS_PLL_ATRACE_FUNC() MDSS_PLL_ATRACE_BEGIN(__func__) -#define MDSS_PLL_ATRACE_INT(name, value) \ - trace_mdss_pll_trace_counter(current->tgid, name, value) - - -#endif /* _MDSS_PLL_TRACE_H_ */ - -/* This part must be outside protection */ -#undef TRACE_INCLUDE_PATH -#define TRACE_INCLUDE_PATH . -#include diff --git a/pll/pll_util.c b/pll/pll_util.c deleted file mode 100644 index 1fe6ebe037d8..000000000000 --- a/pll/pll_util.c +++ /dev/null @@ -1,380 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (c) 2013-2019, The Linux Foundation. All rights reserved. - */ - -#define pr_fmt(fmt) "%s: " fmt, __func__ - -#include -#include -#include -#include -#include -#include -#include - -#include "pll_drv.h" - -/** - * mdss_pll_get_mp_by_reg_name() -- Find power module by regulator name - *@pll_res: Pointer to the PLL resource - *@name: Regulator name as specified in the pll dtsi - * - * This is a helper function to retrieve the regulator information - * for each pll resource. - */ -struct dss_vreg *mdss_pll_get_mp_by_reg_name(struct mdss_pll_resources *pll_res - , char *name) -{ - - struct dss_vreg *regulator = NULL; - int i; - - if ((pll_res == NULL) || (pll_res->mp.vreg_config == NULL)) { - pr_err("%s Invalid PLL resource\n", __func__); - goto error; - } - - regulator = pll_res->mp.vreg_config; - - for (i = 0; i < pll_res->mp.num_vreg; i++) { - if (!strcmp(name, regulator->vreg_name)) { - pr_debug("Found regulator match for %s\n", name); - break; - } - regulator++; - } - -error: - return regulator; -} - -int mdss_pll_util_resource_enable(struct mdss_pll_resources *pll_res, - bool enable) -{ - int rc = 0; - struct dss_module_power *mp = &pll_res->mp; - - if (enable) { - rc = msm_dss_enable_vreg(mp->vreg_config, mp->num_vreg, enable); - if (rc) { - pr_err("Failed to enable vregs rc=%d\n", rc); - goto vreg_err; - } - - rc = msm_dss_clk_set_rate(mp->clk_config, mp->num_clk); - if (rc) { - pr_err("Failed to set clock rate rc=%d\n", rc); - goto clk_err; - } - - rc = msm_dss_enable_clk(mp->clk_config, mp->num_clk, enable); - if (rc) { - pr_err("clock enable failed rc:%d\n", rc); - goto clk_err; - } - } else { - msm_dss_enable_clk(mp->clk_config, mp->num_clk, enable); - - msm_dss_enable_vreg(mp->vreg_config, mp->num_vreg, enable); - } - - return rc; - -clk_err: - msm_dss_enable_vreg(mp->vreg_config, mp->num_vreg, 0); -vreg_err: - return rc; -} - -static int mdss_pll_util_parse_dt_supply(struct platform_device *pdev, - struct mdss_pll_resources *pll_res) -{ - int i = 0, rc = 0; - u32 tmp = 0; - struct device_node *of_node = NULL, *supply_root_node = NULL; - struct device_node *supply_node = NULL; - struct dss_module_power *mp = &pll_res->mp; - - of_node = pdev->dev.of_node; - - mp->num_vreg = 0; - supply_root_node = of_get_child_by_name(of_node, - "qcom,platform-supply-entries"); - if (!supply_root_node) { - pr_err("no supply entry present\n"); - return rc; - } - - for_each_child_of_node(supply_root_node, supply_node) { - mp->num_vreg++; - } - - if (mp->num_vreg == 0) { - pr_debug("no vreg\n"); - return rc; - } - pr_debug("vreg found. count=%d\n", mp->num_vreg); - - mp->vreg_config = devm_kzalloc(&pdev->dev, sizeof(struct dss_vreg) * - mp->num_vreg, GFP_KERNEL); - if (!mp->vreg_config) { - rc = -ENOMEM; - return rc; - } - - for_each_child_of_node(supply_root_node, supply_node) { - - const char *st = NULL; - - rc = of_property_read_string(supply_node, - "qcom,supply-name", &st); - if (rc) { - pr_err(":error reading name. rc=%d\n", rc); - goto error; - } - - strlcpy(mp->vreg_config[i].vreg_name, st, - sizeof(mp->vreg_config[i].vreg_name)); - - rc = of_property_read_u32(supply_node, - "qcom,supply-min-voltage", &tmp); - if (rc) { - pr_err(": error reading min volt. rc=%d\n", rc); - goto error; - } - mp->vreg_config[i].min_voltage = tmp; - - rc = of_property_read_u32(supply_node, - "qcom,supply-max-voltage", &tmp); - if (rc) { - pr_err(": error reading max volt. rc=%d\n", rc); - goto error; - } - mp->vreg_config[i].max_voltage = tmp; - - rc = of_property_read_u32(supply_node, - "qcom,supply-enable-load", &tmp); - if (rc) { - pr_err(": error reading enable load. rc=%d\n", rc); - goto error; - } - mp->vreg_config[i].enable_load = tmp; - - rc = of_property_read_u32(supply_node, - "qcom,supply-disable-load", &tmp); - if (rc) { - pr_err(": error reading disable load. rc=%d\n", rc); - goto error; - } - mp->vreg_config[i].disable_load = tmp; - - rc = of_property_read_u32(supply_node, - "qcom,supply-pre-on-sleep", &tmp); - if (rc) - pr_debug("error reading supply pre sleep value. rc=%d\n", - rc); - - mp->vreg_config[i].pre_on_sleep = (!rc ? tmp : 0); - - rc = of_property_read_u32(supply_node, - "qcom,supply-pre-off-sleep", &tmp); - if (rc) - pr_debug("error reading supply pre sleep value. rc=%d\n", - rc); - - mp->vreg_config[i].pre_off_sleep = (!rc ? tmp : 0); - - rc = of_property_read_u32(supply_node, - "qcom,supply-post-on-sleep", &tmp); - if (rc) - pr_debug("error reading supply post sleep value. rc=%d\n", - rc); - - mp->vreg_config[i].post_on_sleep = (!rc ? tmp : 0); - - rc = of_property_read_u32(supply_node, - "qcom,supply-post-off-sleep", &tmp); - if (rc) - pr_debug("error reading supply post sleep value. rc=%d\n", - rc); - - mp->vreg_config[i].post_off_sleep = (!rc ? tmp : 0); - - pr_debug("%s min=%d, max=%d, enable=%d, disable=%d, preonsleep=%d, postonsleep=%d, preoffsleep=%d, postoffsleep=%d\n", - mp->vreg_config[i].vreg_name, - mp->vreg_config[i].min_voltage, - mp->vreg_config[i].max_voltage, - mp->vreg_config[i].enable_load, - mp->vreg_config[i].disable_load, - mp->vreg_config[i].pre_on_sleep, - mp->vreg_config[i].post_on_sleep, - mp->vreg_config[i].pre_off_sleep, - mp->vreg_config[i].post_off_sleep); - ++i; - - rc = 0; - } - - return rc; - -error: - if (mp->vreg_config) { - devm_kfree(&pdev->dev, mp->vreg_config); - mp->vreg_config = NULL; - mp->num_vreg = 0; - } - - return rc; -} - -static int mdss_pll_util_parse_dt_clock(struct platform_device *pdev, - struct mdss_pll_resources *pll_res) -{ - u32 i = 0, rc = 0; - struct dss_module_power *mp = &pll_res->mp; - const char *clock_name; - u32 clock_rate; - - mp->num_clk = of_property_count_strings(pdev->dev.of_node, - "clock-names"); - if (mp->num_clk <= 0) { - pr_err("clocks are not defined\n"); - goto clk_err; - } - - mp->clk_config = devm_kzalloc(&pdev->dev, - sizeof(struct dss_clk) * mp->num_clk, GFP_KERNEL); - if (!mp->clk_config) { - rc = -ENOMEM; - mp->num_clk = 0; - goto clk_err; - } - - for (i = 0; i < mp->num_clk; i++) { - of_property_read_string_index(pdev->dev.of_node, "clock-names", - i, &clock_name); - strlcpy(mp->clk_config[i].clk_name, clock_name, - sizeof(mp->clk_config[i].clk_name)); - - of_property_read_u32_index(pdev->dev.of_node, "clock-rate", - i, &clock_rate); - mp->clk_config[i].rate = clock_rate; - - if (!clock_rate) - mp->clk_config[i].type = DSS_CLK_AHB; - else - mp->clk_config[i].type = DSS_CLK_PCLK; - } - -clk_err: - return rc; -} - -static void mdss_pll_free_bootmem(u32 mem_addr, u32 size) -{ - unsigned long pfn_start, pfn_end, pfn_idx; - - pfn_start = mem_addr >> PAGE_SHIFT; - pfn_end = (mem_addr + size) >> PAGE_SHIFT; - for (pfn_idx = pfn_start; pfn_idx < pfn_end; pfn_idx++) - free_reserved_page(pfn_to_page(pfn_idx)); -} - -static int mdss_pll_util_parse_dt_dfps(struct platform_device *pdev, - struct mdss_pll_resources *pll_res) -{ - int rc = 0; - struct device_node *pnode; - const u32 *addr; - struct vm_struct *area; - u64 size; - u32 offsets[2]; - unsigned long virt_add; - - pnode = of_parse_phandle(pdev->dev.of_node, "memory-region", 0); - if (IS_ERR_OR_NULL(pnode)) { - rc = PTR_ERR(pnode); - goto pnode_err; - } - - addr = of_get_address(pnode, 0, &size, NULL); - if (!addr) { - pr_err("failed to parse the dfps memory address\n"); - rc = -EINVAL; - goto pnode_err; - } - /* maintain compatibility for 32/64 bit */ - offsets[0] = (u32) of_read_ulong(addr, 2); - offsets[1] = (u32) size; - - area = get_vm_area(offsets[1], VM_IOREMAP); - if (!area) { - rc = -ENOMEM; - goto dfps_mem_err; - } - - virt_add = (unsigned long)area->addr; - rc = ioremap_page_range(virt_add, (virt_add + offsets[1]), - offsets[0], PAGE_KERNEL); - if (rc) { - rc = -ENOMEM; - goto ioremap_err; - } - - pll_res->dfps = kzalloc(sizeof(struct dfps_info), GFP_KERNEL); - if (IS_ERR_OR_NULL(pll_res->dfps)) { - rc = PTR_ERR(pll_res->dfps); - pr_err("couldn't allocate dfps kernel memory\n"); - goto addr_err; - } - - /* memcopy complete dfps structure from kernel virtual memory */ - memcpy_fromio(pll_res->dfps, area->addr, sizeof(struct dfps_info)); - -addr_err: - if (virt_add) - unmap_kernel_range(virt_add, (unsigned long) size); -ioremap_err: - if (area) - vfree(area->addr); -dfps_mem_err: - /* free the dfps memory here */ - memblock_free(offsets[0], offsets[1]); - mdss_pll_free_bootmem(offsets[0], offsets[1]); -pnode_err: - if (pnode) - of_node_put(pnode); - - return rc; -} - -int mdss_pll_util_resource_parse(struct platform_device *pdev, - struct mdss_pll_resources *pll_res) -{ - int rc = 0; - struct dss_module_power *mp = &pll_res->mp; - - rc = mdss_pll_util_parse_dt_supply(pdev, pll_res); - if (rc) { - pr_err("vreg parsing failed rc=%d\n", rc); - goto end; - } - - rc = mdss_pll_util_parse_dt_clock(pdev, pll_res); - if (rc) { - pr_err("clock name parsing failed rc=%d\n", rc); - goto clk_err; - } - - if (mdss_pll_util_parse_dt_dfps(pdev, pll_res)) - pr_err("dfps not enabled!\n"); - - return rc; - -clk_err: - devm_kfree(&pdev->dev, mp->vreg_config); - mp->num_vreg = 0; -end: - return rc; -}