Commit be69e55d authored by Ben Peled's avatar Ben Peled Committed by Stephen Boyd
Browse files

clk: mvebu: ap806: Prepare the introduction of AP807 clock support



Factor out the code that is only useful to AP806 so it will be easier
to support AP807. No functional changes.

Signed-off-by: default avatarBen Peled <bpeled@marvell.com>
Signed-off-by: default avatarMiquel Raynal <miquel.raynal@bootlin.com>
Link: https://lkml.kernel.org/r/20190805100310.29048-8-miquel.raynal@bootlin.com


Signed-off-by: default avatarStephen Boyd <sboyd@kernel.org>
parent 0099dc44
Loading
Loading
Loading
Loading
+77 −63
Original line number Diff line number Diff line
@@ -30,100 +30,114 @@ static struct clk_onecell_data ap806_clk_data = {
	.clk_num = AP806_CLK_NUM,
};

static int ap806_syscon_common_probe(struct platform_device *pdev,
				     struct device_node *syscon_node)
static int ap806_get_sar_clocks(unsigned int freq_mode,
				unsigned int *cpuclk_freq,
				unsigned int *dclk_freq)
{
	unsigned int freq_mode, cpuclk_freq, dclk_freq;
	const char *name, *fixedclk_name;
	struct device *dev = &pdev->dev;
	struct device_node *np = dev->of_node;
	struct regmap *regmap;
	u32 reg;
	int ret;

	regmap = syscon_node_to_regmap(syscon_node);
	if (IS_ERR(regmap)) {
		dev_err(dev, "cannot get regmap\n");
		return PTR_ERR(regmap);
	}

	ret = regmap_read(regmap, AP806_SAR_REG, &reg);
	if (ret) {
		dev_err(dev, "cannot read from regmap\n");
		return ret;
	}

	freq_mode = reg & AP806_SAR_CLKFREQ_MODE_MASK;
	switch (freq_mode) {
	case 0x0:
		*cpuclk_freq = 2000;
		*dclk_freq = 600;
		break;
	case 0x1:
		cpuclk_freq = 2000;
		*cpuclk_freq = 2000;
		*dclk_freq = 525;
		break;
	case 0x6:
		*cpuclk_freq = 1800;
		*dclk_freq = 600;
		break;
	case 0x7:
		cpuclk_freq = 1800;
		*cpuclk_freq = 1800;
		*dclk_freq = 525;
		break;
	case 0x4:
		*cpuclk_freq = 1600;
		*dclk_freq = 400;
		break;
	case 0xB:
		*cpuclk_freq = 1600;
		*dclk_freq = 450;
		break;
	case 0xD:
		cpuclk_freq = 1600;
		*cpuclk_freq = 1600;
		*dclk_freq = 525;
		break;
	case 0x1a:
		cpuclk_freq = 1400;
		*cpuclk_freq = 1400;
		*dclk_freq = 400;
		break;
	case 0x14:
		*cpuclk_freq = 1300;
		*dclk_freq = 400;
		break;
	case 0x17:
		cpuclk_freq = 1300;
		*cpuclk_freq = 1300;
		*dclk_freq = 325;
		break;
	case 0x19:
		cpuclk_freq = 1200;
		*cpuclk_freq = 1200;
		*dclk_freq = 400;
		break;
	case 0x13:
		*cpuclk_freq = 1000;
		*dclk_freq = 325;
		break;
	case 0x1d:
		cpuclk_freq = 1000;
		*cpuclk_freq = 1000;
		*dclk_freq = 400;
		break;
	case 0x1c:
		cpuclk_freq = 800;
		*cpuclk_freq = 800;
		*dclk_freq = 400;
		break;
	case 0x1b:
		cpuclk_freq = 600;
		*cpuclk_freq = 600;
		*dclk_freq = 400;
		break;
	default:
		dev_err(dev, "invalid Sample at Reset value\n");
		return -EINVAL;
	}

	/* Get DCLK frequency (DCLK = DDR_CLK / 2) */
	switch (freq_mode) {
	case 0x0:
	case 0x6:
		/* DDR_CLK = 1200Mhz */
		dclk_freq = 600;
		break;
	case 0x1:
	case 0x7:
	case 0xD:
		/* DDR_CLK = 1050Mhz */
		dclk_freq = 525;
		break;
	case 0x13:
	case 0x17:
		/* DDR_CLK = 650Mhz */
		dclk_freq = 325;
		break;
	case 0x4:
	case 0x14:
	case 0x19:
	case 0x1A:
	case 0x1B:
	case 0x1C:
	case 0x1D:
		/* DDR_CLK = 800Mhz */
		dclk_freq = 400;
		break;
	default:
		dclk_freq = 0;
	return 0;
}

static int ap806_syscon_common_probe(struct platform_device *pdev,
				     struct device_node *syscon_node)
{
	unsigned int freq_mode, cpuclk_freq, dclk_freq;
	const char *name, *fixedclk_name;
	struct device *dev = &pdev->dev;
	struct device_node *np = dev->of_node;
	struct regmap *regmap;
	u32 reg;
	int ret;

	regmap = syscon_node_to_regmap(syscon_node);
	if (IS_ERR(regmap)) {
		dev_err(dev, "cannot get regmap\n");
		return PTR_ERR(regmap);
	}

	ret = regmap_read(regmap, AP806_SAR_REG, &reg);
	if (ret) {
		dev_err(dev, "cannot read from regmap\n");
		return ret;
	}

	freq_mode = reg & AP806_SAR_CLKFREQ_MODE_MASK;

	if (of_device_is_compatible(pdev->dev.of_node,
				    "marvell,ap806-clock")) {
		ret = ap806_get_sar_clocks(freq_mode, &cpuclk_freq, &dclk_freq);
	} else {
		dev_err(dev, "compatible not supported\n");
		return -EINVAL;
	}

	if (ret) {
		dev_err(dev, "invalid Sample at Reset value\n");
		return ret;
	}

	/* Convert to hertz */