Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6fce6cb7 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "clk: qcom: mdss: Enable mdss 28lpm pll driver"

parents cee6dde6 089c4a01
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -4,3 +4,5 @@ obj-$(CONFIG_MDSS_PLL) += mdss-pll.o
obj-$(CONFIG_MDSS_PLL) += mdss-dsi-pll-14nm.o
obj-$(CONFIG_MDSS_PLL) += mdss-dsi-pll-14nm-util.o
obj-$(CONFIG_MDSS_PLL) += mdss-dp-pll-14nm.o
obj-$(CONFIG_MDSS_PLL) += mdss-dsi-pll-28lpm.o
obj-$(CONFIG_MDSS_PLL) += mdss-dsi-pll-28nm-util.o
+557 −0
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/* Copyright (c) 2012-2018, 2021,  The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * only version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 */

#define pr_fmt(fmt)	"%s: " fmt, __func__

#include <linux/kernel.h>
#include <linux/err.h>
#include <linux/delay.h>
#include <dt-bindings/clock/mdss-28nm-pll-clk.h>

#include "mdss-pll.h"
#include "mdss-dsi-pll.h"
#include "mdss-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 */

	if (!pdev || !pdev->dev.of_node ||
		!pll_res || !pll_res->pll_base) {
		pr_err("Invalid params\n");
		return -EINVAL;
	}

	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(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)
		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;
}
+660 −0

File added.

Preview size limit exceeded, changes collapsed.

+73 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-only */
/* Copyright (c) 2012-2018, 2021, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * only version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 */

#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 */
+3 −1
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-only */
/* Copyright (c) 2012-2018, 2020 The Linux Foundation. All rights reserved. */
/* Copyright (c) 2012-2018, 2020, 2021, The Linux Foundation. All rights reserved. */

#ifndef __MDSS_DSI_PLL_H
#define __MDSS_DSI_PLL_H
@@ -39,4 +39,6 @@ static inline struct dsi_pll_vco_clk *to_vco_clk_hw(struct clk_hw *hw)

int dsi_pll_clock_register_14nm(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);
#endif
Loading