brintos

brintos / linux-shallow public Read only

0
0
Text · 4.7 KiB · 1c8ab4f Raw
181 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Marvell MV98DX3236 SoC clocks4 *5 * Copyright (C) 2012 Marvell6 *7 * Gregory CLEMENT <gregory.clement@free-electrons.com>8 * Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>9 * Andrew Lunn <andrew@lunn.ch>10 *11 */12 13#include <linux/kernel.h>14#include <linux/clk-provider.h>15#include <linux/io.h>16#include <linux/of.h>17#include "common.h"18 19 20/*21 * For 98DX4251 Sample At Reset the CPU, DDR and Main PLL clocks are all22 * defined at the same time23 *24 * SAR1[20:18]   : CPU frequency    DDR frequency   MPLL frequency25 *		 0  =  400 MHz	    400 MHz	    800 MHz26 *		 2  =  667 MHz	    667 MHz	    2000 MHz27 *		 3  =  800 MHz	    800 MHz	    1600 MHz28 *		 others reserved.29 *30 * For 98DX3236 Sample At Reset the CPU, DDR and Main PLL clocks are all31 * defined at the same time32 *33 * SAR1[20:18]   : CPU frequency    DDR frequency   MPLL frequency34 *		 1  =  667 MHz	    667 MHz	    2000 MHz35 *		 2  =  400 MHz	    400 MHz	    400 MHz36 *		 3  =  800 MHz	    800 MHz	    800 MHz37 *		 5  =  800 MHz	    400 MHz	    800 MHz38 *		 others reserved.39 */40 41#define SAR1_MV98DX3236_CPU_DDR_MPLL_FREQ_OPT		1842#define SAR1_MV98DX3236_CPU_DDR_MPLL_FREQ_OPT_MASK	0x743 44static u32 __init mv98dx3236_get_tclk_freq(void __iomem *sar)45{46	/* Tclk = 200MHz, no SaR dependency */47	return 200000000;48}49 50static const u32 mv98dx3236_cpu_frequencies[] __initconst = {51	0,52	667000000,53	400000000,54	800000000,55	0,56	800000000,57	0, 0,58};59 60static const u32 mv98dx4251_cpu_frequencies[] __initconst = {61	400000000,62	0,63	667000000,64	800000000,65	0, 0, 0, 0,66};67 68static u32 __init mv98dx3236_get_cpu_freq(void __iomem *sar)69{70	u32 cpu_freq = 0;71	u8 cpu_freq_select = 0;72 73	cpu_freq_select = ((readl(sar) >> SAR1_MV98DX3236_CPU_DDR_MPLL_FREQ_OPT) &74			   SAR1_MV98DX3236_CPU_DDR_MPLL_FREQ_OPT_MASK);75 76	if (of_machine_is_compatible("marvell,armadaxp-98dx4251"))77		cpu_freq = mv98dx4251_cpu_frequencies[cpu_freq_select];78	else if (of_machine_is_compatible("marvell,armadaxp-98dx3236"))79		cpu_freq = mv98dx3236_cpu_frequencies[cpu_freq_select];80 81	if (!cpu_freq)82		pr_err("CPU freq select unsupported %d\n", cpu_freq_select);83 84	return cpu_freq;85}86 87enum {88	MV98DX3236_CPU_TO_DDR,89	MV98DX3236_CPU_TO_MPLL90};91 92static const struct coreclk_ratio mv98dx3236_core_ratios[] __initconst = {93	{ .id = MV98DX3236_CPU_TO_DDR, .name = "ddrclk" },94	{ .id = MV98DX3236_CPU_TO_MPLL, .name = "mpll" },95};96 97static const int __initconst mv98dx3236_cpu_mpll_ratios[8][2] = {98	{0, 1}, {3, 1}, {1, 1}, {1, 1},99	{0, 1}, {1, 1}, {0, 1}, {0, 1},100};101 102static const int __initconst mv98dx3236_cpu_ddr_ratios[8][2] = {103	{0, 1}, {1, 1}, {1, 1}, {1, 1},104	{0, 1}, {1, 2}, {0, 1}, {0, 1},105};106 107static const int __initconst mv98dx4251_cpu_mpll_ratios[8][2] = {108	{2, 1}, {0, 1}, {3, 1}, {2, 1},109	{0, 1}, {0, 1}, {0, 1}, {0, 1},110};111 112static const int __initconst mv98dx4251_cpu_ddr_ratios[8][2] = {113	{1, 1}, {0, 1}, {1, 1}, {1, 1},114	{0, 1}, {0, 1}, {0, 1}, {0, 1},115};116 117static void __init mv98dx3236_get_clk_ratio(118	void __iomem *sar, int id, int *mult, int *div)119{120	u32 opt = ((readl(sar) >> SAR1_MV98DX3236_CPU_DDR_MPLL_FREQ_OPT) &121		SAR1_MV98DX3236_CPU_DDR_MPLL_FREQ_OPT_MASK);122 123	switch (id) {124	case MV98DX3236_CPU_TO_DDR:125		if (of_machine_is_compatible("marvell,armadaxp-98dx4251")) {126			*mult = mv98dx4251_cpu_ddr_ratios[opt][0];127			*div = mv98dx4251_cpu_ddr_ratios[opt][1];128		} else if (of_machine_is_compatible("marvell,armadaxp-98dx3236")) {129			*mult = mv98dx3236_cpu_ddr_ratios[opt][0];130			*div = mv98dx3236_cpu_ddr_ratios[opt][1];131		}132		break;133	case MV98DX3236_CPU_TO_MPLL:134		if (of_machine_is_compatible("marvell,armadaxp-98dx4251")) {135			*mult = mv98dx4251_cpu_mpll_ratios[opt][0];136			*div = mv98dx4251_cpu_mpll_ratios[opt][1];137		} else if (of_machine_is_compatible("marvell,armadaxp-98dx3236")) {138			*mult = mv98dx3236_cpu_mpll_ratios[opt][0];139			*div = mv98dx3236_cpu_mpll_ratios[opt][1];140		}141		break;142	}143}144 145static const struct coreclk_soc_desc mv98dx3236_core_clocks = {146	.get_tclk_freq = mv98dx3236_get_tclk_freq,147	.get_cpu_freq = mv98dx3236_get_cpu_freq,148	.get_clk_ratio = mv98dx3236_get_clk_ratio,149	.ratios = mv98dx3236_core_ratios,150	.num_ratios = ARRAY_SIZE(mv98dx3236_core_ratios),151};152 153 154/*155 * Clock Gating Control156 */157 158static const struct clk_gating_soc_desc mv98dx3236_gating_desc[] __initconst = {159	{ "ge1", NULL, 3, 0 },160	{ "ge0", NULL, 4, 0 },161	{ "pex00", NULL, 5, 0 },162	{ "sdio", NULL, 17, 0 },163	{ "usb0", NULL, 18, 0 },164	{ "xor0", NULL, 22, 0 },165	{ }166};167 168static void __init mv98dx3236_clk_init(struct device_node *np)169{170	struct device_node *cgnp =171		of_find_compatible_node(NULL, NULL, "marvell,mv98dx3236-gating-clock");172 173	mvebu_coreclk_setup(np, &mv98dx3236_core_clocks);174 175	if (cgnp) {176		mvebu_clk_gating_setup(cgnp, mv98dx3236_gating_desc);177		of_node_put(cgnp);178	}179}180CLK_OF_DECLARE(mv98dx3236_clk, "marvell,mv98dx3236-core-clock", mv98dx3236_clk_init);181