diff --git a/Makefile b/Makefile index b2829628ff..f874aa3cb7 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 3b4d225945..f3ba4a7040 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 1bc14666da..7d0434365d 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 c3935d60a0..8de634cc1e 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 2f5519229c..39ccc73a53 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 abe770101c..830016e94f 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 e2e5efd97d..1068304612 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 2f5f23920e..7700520c24 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 ac5e7b0e6e..442a9b4599 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 948e2038de..c10d986de5 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 0000000000..c323bd050f --- /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 2f03d860ec..ba1abbce1b 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 6eaa7f383b..271eb76ef7 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 0b29a90caf..0000000000 --- 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 2ef7358330..0000000000 --- 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 9c4db5ba3f..0000000000 --- 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 2adbdf3e66..0000000000 --- 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 4eb859c319..0000000000 --- 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 05641bb843..0000000000 --- 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 f8c9c3043b..0000000000 --- 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 480c00fda6..0000000000 --- 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 87037f9c60..0000000000 --- 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 4ce47a7f54..0000000000 --- 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 2a0ab26e70..0000000000 --- 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 35aa814941..0000000000 --- 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 5f4140dccc..0000000000 --- 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 5ec50bf8d6..0000000000 --- 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 abc08f639a..0000000000 --- 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 5cd7869cf7..0000000000 --- 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 f9e22c6abe..0000000000 --- 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 ba9052342d..0000000000 --- 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 16c2eff92e..0000000000 --- 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 2c59a6477f..0000000000 --- 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 6ec5a70b83..0000000000 --- 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 963c56c06f..0000000000 --- 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 94e16d86fd..0000000000 --- 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 543548eaa5..0000000000 --- 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 0769bf3061..0000000000 --- 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 b2053ec891..0000000000 --- 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 03f6fa20ea..0000000000 --- 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 847ddf261a..0000000000 --- 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 962a4cec49..0000000000 --- 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 a0fba39c2c..0000000000 --- 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 04e93fd950..0000000000 --- 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 b4321df435..0000000000 --- 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 5e0cd4cf4e..0000000000 --- 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 d847920c99..0000000000 --- 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 1fe6ebe037..0000000000 --- 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; -}