211 lines
		
	
	
	
		
			4.7 KiB
			
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			211 lines
		
	
	
	
		
			4.7 KiB
			
		
	
	
	
		
			C
		
	
	
	
	
	
|   | /*
 | ||
|  |  * Marvell Orion SoC clocks | ||
|  |  * | ||
|  |  * Copyright (C) 2014 Thomas Petazzoni | ||
|  |  * | ||
|  |  * Thomas Petazzoni <thomas.petazzoni@free-electrons.com> | ||
|  |  * | ||
|  |  * This file is licensed under the terms of the GNU General Public | ||
|  |  * License version 2.  This program is licensed "as is" without any | ||
|  |  * warranty of any kind, whether express or implied. | ||
|  |  */ | ||
|  | 
 | ||
|  | #include <linux/kernel.h>
 | ||
|  | #include <linux/clk-provider.h>
 | ||
|  | #include <linux/io.h>
 | ||
|  | #include <linux/of.h>
 | ||
|  | #include "common.h"
 | ||
|  | 
 | ||
|  | static const struct coreclk_ratio orion_coreclk_ratios[] __initconst = { | ||
|  | 	{ .id = 0, .name = "ddrclk", } | ||
|  | }; | ||
|  | 
 | ||
|  | /*
 | ||
|  |  * Orion 5182 | ||
|  |  */ | ||
|  | 
 | ||
|  | #define SAR_MV88F5182_TCLK_FREQ      8
 | ||
|  | #define SAR_MV88F5182_TCLK_FREQ_MASK 0x3
 | ||
|  | 
 | ||
|  | static u32 __init mv88f5182_get_tclk_freq(void __iomem *sar) | ||
|  | { | ||
|  | 	u32 opt = (readl(sar) >> SAR_MV88F5182_TCLK_FREQ) & | ||
|  | 		SAR_MV88F5182_TCLK_FREQ_MASK; | ||
|  | 	if (opt == 1) | ||
|  | 		return 150000000; | ||
|  | 	else if (opt == 2) | ||
|  | 		return 166666667; | ||
|  | 	else | ||
|  | 		return 0; | ||
|  | } | ||
|  | 
 | ||
|  | #define SAR_MV88F5182_CPU_FREQ       4
 | ||
|  | #define SAR_MV88F5182_CPU_FREQ_MASK  0xf
 | ||
|  | 
 | ||
|  | static u32 __init mv88f5182_get_cpu_freq(void __iomem *sar) | ||
|  | { | ||
|  | 	u32 opt = (readl(sar) >> SAR_MV88F5182_CPU_FREQ) & | ||
|  | 		SAR_MV88F5182_CPU_FREQ_MASK; | ||
|  | 	if (opt == 0) | ||
|  | 		return 333333333; | ||
|  | 	else if (opt == 1 || opt == 2) | ||
|  | 		return 400000000; | ||
|  | 	else if (opt == 3) | ||
|  | 		return 500000000; | ||
|  | 	else | ||
|  | 		return 0; | ||
|  | } | ||
|  | 
 | ||
|  | static void __init mv88f5182_get_clk_ratio(void __iomem *sar, int id, | ||
|  | 					   int *mult, int *div) | ||
|  | { | ||
|  | 	u32 opt = (readl(sar) >> SAR_MV88F5182_CPU_FREQ) & | ||
|  | 		SAR_MV88F5182_CPU_FREQ_MASK; | ||
|  | 	if (opt == 0 || opt == 1) { | ||
|  | 		*mult = 1; | ||
|  | 		*div  = 2; | ||
|  | 	} else if (opt == 2 || opt == 3) { | ||
|  | 		*mult = 1; | ||
|  | 		*div  = 3; | ||
|  | 	} else { | ||
|  | 		*mult = 0; | ||
|  | 		*div  = 1; | ||
|  | 	} | ||
|  | } | ||
|  | 
 | ||
|  | static const struct coreclk_soc_desc mv88f5182_coreclks = { | ||
|  | 	.get_tclk_freq = mv88f5182_get_tclk_freq, | ||
|  | 	.get_cpu_freq = mv88f5182_get_cpu_freq, | ||
|  | 	.get_clk_ratio = mv88f5182_get_clk_ratio, | ||
|  | 	.ratios = orion_coreclk_ratios, | ||
|  | 	.num_ratios = ARRAY_SIZE(orion_coreclk_ratios), | ||
|  | }; | ||
|  | 
 | ||
|  | static void __init mv88f5182_clk_init(struct device_node *np) | ||
|  | { | ||
|  | 	return mvebu_coreclk_setup(np, &mv88f5182_coreclks); | ||
|  | } | ||
|  | 
 | ||
|  | CLK_OF_DECLARE(mv88f5182_clk, "marvell,mv88f5182-core-clock", mv88f5182_clk_init); | ||
|  | 
 | ||
|  | /*
 | ||
|  |  * Orion 5281 | ||
|  |  */ | ||
|  | 
 | ||
|  | static u32 __init mv88f5281_get_tclk_freq(void __iomem *sar) | ||
|  | { | ||
|  | 	/* On 5281, tclk is always 166 Mhz */ | ||
|  | 	return 166666667; | ||
|  | } | ||
|  | 
 | ||
|  | #define SAR_MV88F5281_CPU_FREQ       4
 | ||
|  | #define SAR_MV88F5281_CPU_FREQ_MASK  0xf
 | ||
|  | 
 | ||
|  | static u32 __init mv88f5281_get_cpu_freq(void __iomem *sar) | ||
|  | { | ||
|  | 	u32 opt = (readl(sar) >> SAR_MV88F5281_CPU_FREQ) & | ||
|  | 		SAR_MV88F5281_CPU_FREQ_MASK; | ||
|  | 	if (opt == 1 || opt == 2) | ||
|  | 		return 400000000; | ||
|  | 	else if (opt == 3) | ||
|  | 		return 500000000; | ||
|  | 	else | ||
|  | 		return 0; | ||
|  | } | ||
|  | 
 | ||
|  | static void __init mv88f5281_get_clk_ratio(void __iomem *sar, int id, | ||
|  | 					   int *mult, int *div) | ||
|  | { | ||
|  | 	u32 opt = (readl(sar) >> SAR_MV88F5281_CPU_FREQ) & | ||
|  | 		SAR_MV88F5281_CPU_FREQ_MASK; | ||
|  | 	if (opt == 1) { | ||
|  | 		*mult = 1; | ||
|  | 		*div = 2; | ||
|  | 	} else if (opt == 2 || opt == 3) { | ||
|  | 		*mult = 1; | ||
|  | 		*div = 3; | ||
|  | 	} else { | ||
|  | 		*mult = 0; | ||
|  | 		*div = 1; | ||
|  | 	} | ||
|  | } | ||
|  | 
 | ||
|  | static const struct coreclk_soc_desc mv88f5281_coreclks = { | ||
|  | 	.get_tclk_freq = mv88f5281_get_tclk_freq, | ||
|  | 	.get_cpu_freq = mv88f5281_get_cpu_freq, | ||
|  | 	.get_clk_ratio = mv88f5281_get_clk_ratio, | ||
|  | 	.ratios = orion_coreclk_ratios, | ||
|  | 	.num_ratios = ARRAY_SIZE(orion_coreclk_ratios), | ||
|  | }; | ||
|  | 
 | ||
|  | static void __init mv88f5281_clk_init(struct device_node *np) | ||
|  | { | ||
|  | 	return mvebu_coreclk_setup(np, &mv88f5281_coreclks); | ||
|  | } | ||
|  | 
 | ||
|  | CLK_OF_DECLARE(mv88f5281_clk, "marvell,mv88f5281-core-clock", mv88f5281_clk_init); | ||
|  | 
 | ||
|  | /*
 | ||
|  |  * Orion 6183 | ||
|  |  */ | ||
|  | 
 | ||
|  | #define SAR_MV88F6183_TCLK_FREQ      9
 | ||
|  | #define SAR_MV88F6183_TCLK_FREQ_MASK 0x1
 | ||
|  | 
 | ||
|  | static u32 __init mv88f6183_get_tclk_freq(void __iomem *sar) | ||
|  | { | ||
|  | 	u32 opt = (readl(sar) >> SAR_MV88F6183_TCLK_FREQ) & | ||
|  | 		SAR_MV88F6183_TCLK_FREQ_MASK; | ||
|  | 	if (opt == 0) | ||
|  | 		return 133333333; | ||
|  | 	else if (opt == 1) | ||
|  | 		return 166666667; | ||
|  | 	else | ||
|  | 		return 0; | ||
|  | } | ||
|  | 
 | ||
|  | #define SAR_MV88F6183_CPU_FREQ       1
 | ||
|  | #define SAR_MV88F6183_CPU_FREQ_MASK  0x3f
 | ||
|  | 
 | ||
|  | static u32 __init mv88f6183_get_cpu_freq(void __iomem *sar) | ||
|  | { | ||
|  | 	u32 opt = (readl(sar) >> SAR_MV88F6183_CPU_FREQ) & | ||
|  | 		SAR_MV88F6183_CPU_FREQ_MASK; | ||
|  | 	if (opt == 9) | ||
|  | 		return 333333333; | ||
|  | 	else if (opt == 17) | ||
|  | 		return 400000000; | ||
|  | 	else | ||
|  | 		return 0; | ||
|  | } | ||
|  | 
 | ||
|  | static void __init mv88f6183_get_clk_ratio(void __iomem *sar, int id, | ||
|  | 					   int *mult, int *div) | ||
|  | { | ||
|  | 	u32 opt = (readl(sar) >> SAR_MV88F6183_CPU_FREQ) & | ||
|  | 		SAR_MV88F6183_CPU_FREQ_MASK; | ||
|  | 	if (opt == 9 || opt == 17) { | ||
|  | 		*mult = 1; | ||
|  | 		*div  = 2; | ||
|  | 	} else { | ||
|  | 		*mult = 0; | ||
|  | 		*div  = 1; | ||
|  | 	} | ||
|  | } | ||
|  | 
 | ||
|  | static const struct coreclk_soc_desc mv88f6183_coreclks = { | ||
|  | 	.get_tclk_freq = mv88f6183_get_tclk_freq, | ||
|  | 	.get_cpu_freq = mv88f6183_get_cpu_freq, | ||
|  | 	.get_clk_ratio = mv88f6183_get_clk_ratio, | ||
|  | 	.ratios = orion_coreclk_ratios, | ||
|  | 	.num_ratios = ARRAY_SIZE(orion_coreclk_ratios), | ||
|  | }; | ||
|  | 
 | ||
|  | 
 | ||
|  | static void __init mv88f6183_clk_init(struct device_node *np) | ||
|  | { | ||
|  | 	return mvebu_coreclk_setup(np, &mv88f6183_coreclks); | ||
|  | } | ||
|  | 
 | ||
|  | CLK_OF_DECLARE(mv88f6183_clk, "marvell,mv88f6183-core-clock", mv88f6183_clk_init); |