xref: /openbmc/linux/arch/arm/mach-mv78xx0/common.c (revision 4b01f735)
10fdebc5eSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
2794d15b2SStanislav Samsonov /*
3794d15b2SStanislav Samsonov  * arch/arm/mach-mv78xx0/common.c
4794d15b2SStanislav Samsonov  *
5794d15b2SStanislav Samsonov  * Core functions for Marvell MV78xx0 SoCs
6794d15b2SStanislav Samsonov  */
7794d15b2SStanislav Samsonov 
8794d15b2SStanislav Samsonov #include <linux/kernel.h>
9794d15b2SStanislav Samsonov #include <linux/init.h>
1062e59c4eSStephen Boyd #include <linux/io.h>
11794d15b2SStanislav Samsonov #include <linux/platform_device.h>
12794d15b2SStanislav Samsonov #include <linux/serial_8250.h>
13794d15b2SStanislav Samsonov #include <linux/ata_platform.h>
142f129bf4SAndrew Lunn #include <linux/clk-provider.h>
15712424fdSLennert Buytenhek #include <linux/ethtool.h>
163c317d00SAndrew Lunn #include <asm/hardware/cache-feroceon-l2.h>
17794d15b2SStanislav Samsonov #include <asm/mach/map.h>
18794d15b2SStanislav Samsonov #include <asm/mach/time.h>
19c02cecb9SArnd Bergmann #include <linux/platform_data/usb-ehci-orion.h>
20c02cecb9SArnd Bergmann #include <linux/platform_data/mtd-orion_nand.h>
216f088f1dSLennert Buytenhek #include <plat/time.h>
2228a2b450SAndrew Lunn #include <plat/common.h>
2345173d5eSAndrew Lunn #include <plat/addr-map.h>
244c811b99SArnd Bergmann #include "mv78xx0.h"
254c811b99SArnd Bergmann #include "bridge-regs.h"
26794d15b2SStanislav Samsonov #include "common.h"
27794d15b2SStanislav Samsonov 
2828a2b450SAndrew Lunn static int get_tclk(void);
29794d15b2SStanislav Samsonov 
30794d15b2SStanislav Samsonov /*****************************************************************************
31794d15b2SStanislav Samsonov  * Common bits
32794d15b2SStanislav Samsonov  ****************************************************************************/
mv78xx0_core_index(void)33794d15b2SStanislav Samsonov int mv78xx0_core_index(void)
34794d15b2SStanislav Samsonov {
35794d15b2SStanislav Samsonov 	u32 extra;
36794d15b2SStanislav Samsonov 
37794d15b2SStanislav Samsonov 	/*
38794d15b2SStanislav Samsonov 	 * Read Extra Features register.
39794d15b2SStanislav Samsonov 	 */
40794d15b2SStanislav Samsonov 	__asm__("mrc p15, 1, %0, c15, c1, 0" : "=r" (extra));
41794d15b2SStanislav Samsonov 
42794d15b2SStanislav Samsonov 	return !!(extra & 0x00004000);
43794d15b2SStanislav Samsonov }
44794d15b2SStanislav Samsonov 
get_hclk(void)45794d15b2SStanislav Samsonov static int get_hclk(void)
46794d15b2SStanislav Samsonov {
47794d15b2SStanislav Samsonov 	int hclk;
48794d15b2SStanislav Samsonov 
49794d15b2SStanislav Samsonov 	/*
50794d15b2SStanislav Samsonov 	 * HCLK tick rate is configured by DEV_D[7:5] pins.
51794d15b2SStanislav Samsonov 	 */
52794d15b2SStanislav Samsonov 	switch ((readl(SAMPLE_AT_RESET_LOW) >> 5) & 7) {
53794d15b2SStanislav Samsonov 	case 0:
54794d15b2SStanislav Samsonov 		hclk = 166666667;
55794d15b2SStanislav Samsonov 		break;
56794d15b2SStanislav Samsonov 	case 1:
57794d15b2SStanislav Samsonov 		hclk = 200000000;
58794d15b2SStanislav Samsonov 		break;
59794d15b2SStanislav Samsonov 	case 2:
60794d15b2SStanislav Samsonov 		hclk = 266666667;
61794d15b2SStanislav Samsonov 		break;
62794d15b2SStanislav Samsonov 	case 3:
63794d15b2SStanislav Samsonov 		hclk = 333333333;
64794d15b2SStanislav Samsonov 		break;
65794d15b2SStanislav Samsonov 	case 4:
66794d15b2SStanislav Samsonov 		hclk = 400000000;
67794d15b2SStanislav Samsonov 		break;
68794d15b2SStanislav Samsonov 	default:
69794d15b2SStanislav Samsonov 		panic("unknown HCLK PLL setting: %.8x\n",
70794d15b2SStanislav Samsonov 			readl(SAMPLE_AT_RESET_LOW));
71794d15b2SStanislav Samsonov 	}
72794d15b2SStanislav Samsonov 
73794d15b2SStanislav Samsonov 	return hclk;
74794d15b2SStanislav Samsonov }
75794d15b2SStanislav Samsonov 
get_pclk_l2clk(int hclk,int core_index,int * pclk,int * l2clk)76794d15b2SStanislav Samsonov static void get_pclk_l2clk(int hclk, int core_index, int *pclk, int *l2clk)
77794d15b2SStanislav Samsonov {
78794d15b2SStanislav Samsonov 	u32 cfg;
79794d15b2SStanislav Samsonov 
80794d15b2SStanislav Samsonov 	/*
81794d15b2SStanislav Samsonov 	 * Core #0 PCLK/L2CLK is configured by bits [13:8], core #1
82794d15b2SStanislav Samsonov 	 * PCLK/L2CLK by bits [19:14].
83794d15b2SStanislav Samsonov 	 */
84794d15b2SStanislav Samsonov 	if (core_index == 0) {
85794d15b2SStanislav Samsonov 		cfg = (readl(SAMPLE_AT_RESET_LOW) >> 8) & 0x3f;
86794d15b2SStanislav Samsonov 	} else {
87794d15b2SStanislav Samsonov 		cfg = (readl(SAMPLE_AT_RESET_LOW) >> 14) & 0x3f;
88794d15b2SStanislav Samsonov 	}
89794d15b2SStanislav Samsonov 
90794d15b2SStanislav Samsonov 	/*
91794d15b2SStanislav Samsonov 	 * Bits [11:8] ([17:14] for core #1) configure the PCLK:HCLK
92794d15b2SStanislav Samsonov 	 * ratio (1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5, 5, 5.5, 6).
93794d15b2SStanislav Samsonov 	 */
94794d15b2SStanislav Samsonov 	*pclk = ((u64)hclk * (2 + (cfg & 0xf))) >> 1;
95794d15b2SStanislav Samsonov 
96794d15b2SStanislav Samsonov 	/*
97794d15b2SStanislav Samsonov 	 * Bits [13:12] ([19:18] for core #1) configure the PCLK:L2CLK
98794d15b2SStanislav Samsonov 	 * ratio (1, 2, 3).
99794d15b2SStanislav Samsonov 	 */
100794d15b2SStanislav Samsonov 	*l2clk = *pclk / (((cfg >> 4) & 3) + 1);
101794d15b2SStanislav Samsonov }
102794d15b2SStanislav Samsonov 
get_tclk(void)103794d15b2SStanislav Samsonov static int get_tclk(void)
104794d15b2SStanislav Samsonov {
1052f129bf4SAndrew Lunn 	int tclk_freq;
106794d15b2SStanislav Samsonov 
107794d15b2SStanislav Samsonov 	/*
108794d15b2SStanislav Samsonov 	 * TCLK tick rate is configured by DEV_A[2:0] strap pins.
109794d15b2SStanislav Samsonov 	 */
110794d15b2SStanislav Samsonov 	switch ((readl(SAMPLE_AT_RESET_HIGH) >> 6) & 7) {
111794d15b2SStanislav Samsonov 	case 1:
1122f129bf4SAndrew Lunn 		tclk_freq = 166666667;
113794d15b2SStanislav Samsonov 		break;
114794d15b2SStanislav Samsonov 	case 3:
1152f129bf4SAndrew Lunn 		tclk_freq = 200000000;
116794d15b2SStanislav Samsonov 		break;
117794d15b2SStanislav Samsonov 	default:
118794d15b2SStanislav Samsonov 		panic("unknown TCLK PLL setting: %.8x\n",
119794d15b2SStanislav Samsonov 			readl(SAMPLE_AT_RESET_HIGH));
120794d15b2SStanislav Samsonov 	}
121794d15b2SStanislav Samsonov 
1222f129bf4SAndrew Lunn 	return tclk_freq;
123794d15b2SStanislav Samsonov }
124794d15b2SStanislav Samsonov 
125794d15b2SStanislav Samsonov 
126794d15b2SStanislav Samsonov /*****************************************************************************
127794d15b2SStanislav Samsonov  * I/O Address Mapping
128794d15b2SStanislav Samsonov  ****************************************************************************/
129794d15b2SStanislav Samsonov static struct map_desc mv78xx0_io_desc[] __initdata = {
130794d15b2SStanislav Samsonov 	{
131383b9961SThomas Petazzoni 		.virtual	= (unsigned long) MV78XX0_CORE_REGS_VIRT_BASE,
132794d15b2SStanislav Samsonov 		.pfn		= 0,
133794d15b2SStanislav Samsonov 		.length		= MV78XX0_CORE_REGS_SIZE,
134794d15b2SStanislav Samsonov 		.type		= MT_DEVICE,
135794d15b2SStanislav Samsonov 	}, {
136383b9961SThomas Petazzoni 		.virtual	= (unsigned long) MV78XX0_REGS_VIRT_BASE,
137794d15b2SStanislav Samsonov 		.pfn		= __phys_to_pfn(MV78XX0_REGS_PHYS_BASE),
138794d15b2SStanislav Samsonov 		.length		= MV78XX0_REGS_SIZE,
139794d15b2SStanislav Samsonov 		.type		= MT_DEVICE,
140794d15b2SStanislav Samsonov 	},
141794d15b2SStanislav Samsonov };
142794d15b2SStanislav Samsonov 
mv78xx0_map_io(void)143794d15b2SStanislav Samsonov void __init mv78xx0_map_io(void)
144794d15b2SStanislav Samsonov {
145794d15b2SStanislav Samsonov 	unsigned long phys;
146794d15b2SStanislav Samsonov 
147794d15b2SStanislav Samsonov 	/*
148794d15b2SStanislav Samsonov 	 * Map the right set of per-core registers depending on
149794d15b2SStanislav Samsonov 	 * which core we are running on.
150794d15b2SStanislav Samsonov 	 */
151794d15b2SStanislav Samsonov 	if (mv78xx0_core_index() == 0) {
152794d15b2SStanislav Samsonov 		phys = MV78XX0_CORE0_REGS_PHYS_BASE;
153794d15b2SStanislav Samsonov 	} else {
154794d15b2SStanislav Samsonov 		phys = MV78XX0_CORE1_REGS_PHYS_BASE;
155794d15b2SStanislav Samsonov 	}
156794d15b2SStanislav Samsonov 	mv78xx0_io_desc[0].pfn = __phys_to_pfn(phys);
157794d15b2SStanislav Samsonov 
158794d15b2SStanislav Samsonov 	iotable_init(mv78xx0_io_desc, ARRAY_SIZE(mv78xx0_io_desc));
159794d15b2SStanislav Samsonov }
160794d15b2SStanislav Samsonov 
161794d15b2SStanislav Samsonov 
162794d15b2SStanislav Samsonov /*****************************************************************************
1632f129bf4SAndrew Lunn  * CLK tree
1642f129bf4SAndrew Lunn  ****************************************************************************/
1652f129bf4SAndrew Lunn static struct clk *tclk;
1662f129bf4SAndrew Lunn 
clk_init(void)1672f129bf4SAndrew Lunn static void __init clk_init(void)
1682f129bf4SAndrew Lunn {
169313a98faSStephen Boyd 	tclk = clk_register_fixed_rate(NULL, "tclk", NULL, 0, get_tclk());
1704574b886SAndrew Lunn 
1714574b886SAndrew Lunn 	orion_clkdev_init(tclk);
1722f129bf4SAndrew Lunn }
1732f129bf4SAndrew Lunn 
1742f129bf4SAndrew Lunn /*****************************************************************************
175794d15b2SStanislav Samsonov  * EHCI
176794d15b2SStanislav Samsonov  ****************************************************************************/
mv78xx0_ehci0_init(void)177794d15b2SStanislav Samsonov void __init mv78xx0_ehci0_init(void)
178794d15b2SStanislav Samsonov {
17972053353SAndrew Lunn 	orion_ehci_init(USB0_PHYS_BASE, IRQ_MV78XX0_USB_0, EHCI_PHY_NA);
180794d15b2SStanislav Samsonov }
181794d15b2SStanislav Samsonov 
182794d15b2SStanislav Samsonov 
183794d15b2SStanislav Samsonov /*****************************************************************************
184794d15b2SStanislav Samsonov  * EHCI1
185794d15b2SStanislav Samsonov  ****************************************************************************/
mv78xx0_ehci1_init(void)186794d15b2SStanislav Samsonov void __init mv78xx0_ehci1_init(void)
187794d15b2SStanislav Samsonov {
188db33f4deSAndrew Lunn 	orion_ehci_1_init(USB1_PHYS_BASE, IRQ_MV78XX0_USB_1);
189794d15b2SStanislav Samsonov }
190794d15b2SStanislav Samsonov 
191794d15b2SStanislav Samsonov 
192794d15b2SStanislav Samsonov /*****************************************************************************
193794d15b2SStanislav Samsonov  * EHCI2
194794d15b2SStanislav Samsonov  ****************************************************************************/
mv78xx0_ehci2_init(void)195794d15b2SStanislav Samsonov void __init mv78xx0_ehci2_init(void)
196794d15b2SStanislav Samsonov {
197db33f4deSAndrew Lunn 	orion_ehci_2_init(USB2_PHYS_BASE, IRQ_MV78XX0_USB_2);
198794d15b2SStanislav Samsonov }
199794d15b2SStanislav Samsonov 
200794d15b2SStanislav Samsonov 
201794d15b2SStanislav Samsonov /*****************************************************************************
202794d15b2SStanislav Samsonov  * GE00
203794d15b2SStanislav Samsonov  ****************************************************************************/
mv78xx0_ge00_init(struct mv643xx_eth_platform_data * eth_data)204794d15b2SStanislav Samsonov void __init mv78xx0_ge00_init(struct mv643xx_eth_platform_data *eth_data)
205794d15b2SStanislav Samsonov {
206db33f4deSAndrew Lunn 	orion_ge00_init(eth_data,
2077e3819d8SAndrew Lunn 			GE00_PHYS_BASE, IRQ_MV78XX0_GE00_SUM,
20858569aeeSArnaud Patard (Rtp) 			IRQ_MV78XX0_GE_ERR,
20958569aeeSArnaud Patard (Rtp) 			MV643XX_TX_CSUM_DEFAULT_LIMIT);
210794d15b2SStanislav Samsonov }
211794d15b2SStanislav Samsonov 
212794d15b2SStanislav Samsonov 
213794d15b2SStanislav Samsonov /*****************************************************************************
214794d15b2SStanislav Samsonov  * GE01
215794d15b2SStanislav Samsonov  ****************************************************************************/
mv78xx0_ge01_init(struct mv643xx_eth_platform_data * eth_data)216794d15b2SStanislav Samsonov void __init mv78xx0_ge01_init(struct mv643xx_eth_platform_data *eth_data)
217794d15b2SStanislav Samsonov {
218db33f4deSAndrew Lunn 	orion_ge01_init(eth_data,
2197e3819d8SAndrew Lunn 			GE01_PHYS_BASE, IRQ_MV78XX0_GE01_SUM,
22058569aeeSArnaud Patard (Rtp) 			MV643XX_TX_CSUM_DEFAULT_LIMIT);
221794d15b2SStanislav Samsonov }
222794d15b2SStanislav Samsonov 
223794d15b2SStanislav Samsonov 
224794d15b2SStanislav Samsonov /*****************************************************************************
225794d15b2SStanislav Samsonov  * GE10
226794d15b2SStanislav Samsonov  ****************************************************************************/
mv78xx0_ge10_init(struct mv643xx_eth_platform_data * eth_data)227794d15b2SStanislav Samsonov void __init mv78xx0_ge10_init(struct mv643xx_eth_platform_data *eth_data)
228794d15b2SStanislav Samsonov {
229712424fdSLennert Buytenhek 	u32 dev, rev;
230712424fdSLennert Buytenhek 
231712424fdSLennert Buytenhek 	/*
232712424fdSLennert Buytenhek 	 * On the Z0, ge10 and ge11 are internally connected back
233712424fdSLennert Buytenhek 	 * to back, and not brought out.
234712424fdSLennert Buytenhek 	 */
235712424fdSLennert Buytenhek 	mv78xx0_pcie_id(&dev, &rev);
236712424fdSLennert Buytenhek 	if (dev == MV78X00_Z0_DEV_ID) {
237712424fdSLennert Buytenhek 		eth_data->phy_addr = MV643XX_ETH_PHY_NONE;
238712424fdSLennert Buytenhek 		eth_data->speed = SPEED_1000;
239712424fdSLennert Buytenhek 		eth_data->duplex = DUPLEX_FULL;
240712424fdSLennert Buytenhek 	}
241712424fdSLennert Buytenhek 
2427d619d8aSArnd Bergmann 	orion_ge10_init(eth_data, GE10_PHYS_BASE, IRQ_MV78XX0_GE10_SUM);
243794d15b2SStanislav Samsonov }
244794d15b2SStanislav Samsonov 
245794d15b2SStanislav Samsonov 
246794d15b2SStanislav Samsonov /*****************************************************************************
247794d15b2SStanislav Samsonov  * GE11
248794d15b2SStanislav Samsonov  ****************************************************************************/
mv78xx0_ge11_init(struct mv643xx_eth_platform_data * eth_data)249794d15b2SStanislav Samsonov void __init mv78xx0_ge11_init(struct mv643xx_eth_platform_data *eth_data)
250794d15b2SStanislav Samsonov {
251712424fdSLennert Buytenhek 	u32 dev, rev;
252712424fdSLennert Buytenhek 
253712424fdSLennert Buytenhek 	/*
254712424fdSLennert Buytenhek 	 * On the Z0, ge10 and ge11 are internally connected back
255712424fdSLennert Buytenhek 	 * to back, and not brought out.
256712424fdSLennert Buytenhek 	 */
257712424fdSLennert Buytenhek 	mv78xx0_pcie_id(&dev, &rev);
258712424fdSLennert Buytenhek 	if (dev == MV78X00_Z0_DEV_ID) {
259712424fdSLennert Buytenhek 		eth_data->phy_addr = MV643XX_ETH_PHY_NONE;
260712424fdSLennert Buytenhek 		eth_data->speed = SPEED_1000;
261712424fdSLennert Buytenhek 		eth_data->duplex = DUPLEX_FULL;
262712424fdSLennert Buytenhek 	}
263712424fdSLennert Buytenhek 
2647d619d8aSArnd Bergmann 	orion_ge11_init(eth_data, GE11_PHYS_BASE, IRQ_MV78XX0_GE11_SUM);
265794d15b2SStanislav Samsonov }
266794d15b2SStanislav Samsonov 
26769359943SRiku Voipio /*****************************************************************************
268aac7ffa3SAndrew Lunn  * I2C
26969359943SRiku Voipio  ****************************************************************************/
mv78xx0_i2c_init(void)27069359943SRiku Voipio void __init mv78xx0_i2c_init(void)
27169359943SRiku Voipio {
272aac7ffa3SAndrew Lunn 	orion_i2c_init(I2C_0_PHYS_BASE, IRQ_MV78XX0_I2C_0, 8);
273aac7ffa3SAndrew Lunn 	orion_i2c_1_init(I2C_1_PHYS_BASE, IRQ_MV78XX0_I2C_1, 8);
27469359943SRiku Voipio }
275794d15b2SStanislav Samsonov 
276794d15b2SStanislav Samsonov /*****************************************************************************
277794d15b2SStanislav Samsonov  * SATA
278794d15b2SStanislav Samsonov  ****************************************************************************/
mv78xx0_sata_init(struct mv_sata_platform_data * sata_data)279794d15b2SStanislav Samsonov void __init mv78xx0_sata_init(struct mv_sata_platform_data *sata_data)
280794d15b2SStanislav Samsonov {
281db33f4deSAndrew Lunn 	orion_sata_init(sata_data, SATA_PHYS_BASE, IRQ_MV78XX0_SATA);
282794d15b2SStanislav Samsonov }
283794d15b2SStanislav Samsonov 
284794d15b2SStanislav Samsonov 
285794d15b2SStanislav Samsonov /*****************************************************************************
286794d15b2SStanislav Samsonov  * UART0
287794d15b2SStanislav Samsonov  ****************************************************************************/
mv78xx0_uart0_init(void)288794d15b2SStanislav Samsonov void __init mv78xx0_uart0_init(void)
289794d15b2SStanislav Samsonov {
29028a2b450SAndrew Lunn 	orion_uart0_init(UART0_VIRT_BASE, UART0_PHYS_BASE,
29174c33576SAndrew Lunn 			 IRQ_MV78XX0_UART_0, tclk);
292794d15b2SStanislav Samsonov }
293794d15b2SStanislav Samsonov 
294794d15b2SStanislav Samsonov 
295794d15b2SStanislav Samsonov /*****************************************************************************
296794d15b2SStanislav Samsonov  * UART1
297794d15b2SStanislav Samsonov  ****************************************************************************/
mv78xx0_uart1_init(void)298794d15b2SStanislav Samsonov void __init mv78xx0_uart1_init(void)
299794d15b2SStanislav Samsonov {
30028a2b450SAndrew Lunn 	orion_uart1_init(UART1_VIRT_BASE, UART1_PHYS_BASE,
30174c33576SAndrew Lunn 			 IRQ_MV78XX0_UART_1, tclk);
302794d15b2SStanislav Samsonov }
303794d15b2SStanislav Samsonov 
304794d15b2SStanislav Samsonov 
305794d15b2SStanislav Samsonov /*****************************************************************************
306794d15b2SStanislav Samsonov  * UART2
307794d15b2SStanislav Samsonov  ****************************************************************************/
mv78xx0_uart2_init(void)308794d15b2SStanislav Samsonov void __init mv78xx0_uart2_init(void)
309794d15b2SStanislav Samsonov {
31028a2b450SAndrew Lunn 	orion_uart2_init(UART2_VIRT_BASE, UART2_PHYS_BASE,
31174c33576SAndrew Lunn 			 IRQ_MV78XX0_UART_2, tclk);
312794d15b2SStanislav Samsonov }
313794d15b2SStanislav Samsonov 
314794d15b2SStanislav Samsonov /*****************************************************************************
315794d15b2SStanislav Samsonov  * UART3
316794d15b2SStanislav Samsonov  ****************************************************************************/
mv78xx0_uart3_init(void)317794d15b2SStanislav Samsonov void __init mv78xx0_uart3_init(void)
318794d15b2SStanislav Samsonov {
31928a2b450SAndrew Lunn 	orion_uart3_init(UART3_VIRT_BASE, UART3_PHYS_BASE,
32074c33576SAndrew Lunn 			 IRQ_MV78XX0_UART_3, tclk);
321794d15b2SStanislav Samsonov }
322794d15b2SStanislav Samsonov 
323794d15b2SStanislav Samsonov /*****************************************************************************
324794d15b2SStanislav Samsonov  * Time handling
325794d15b2SStanislav Samsonov  ****************************************************************************/
mv78xx0_init_early(void)3264ee1f6b5SLennert Buytenhek void __init mv78xx0_init_early(void)
3274ee1f6b5SLennert Buytenhek {
3284ee1f6b5SLennert Buytenhek 	orion_time_set_base(TIMER_VIRT_BASE);
32995b80e0aSThomas Petazzoni 	if (mv78xx0_core_index() == 0)
33095b80e0aSThomas Petazzoni 		mvebu_mbus_init("marvell,mv78xx0-mbus",
33195b80e0aSThomas Petazzoni 				BRIDGE_WINS_CPU0_BASE, BRIDGE_WINS_SZ,
33295b80e0aSThomas Petazzoni 				DDR_WINDOW_CPU0_BASE, DDR_WINDOW_CPU_SZ);
33395b80e0aSThomas Petazzoni 	else
33495b80e0aSThomas Petazzoni 		mvebu_mbus_init("marvell,mv78xx0-mbus",
33595b80e0aSThomas Petazzoni 				BRIDGE_WINS_CPU1_BASE, BRIDGE_WINS_SZ,
33695b80e0aSThomas Petazzoni 				DDR_WINDOW_CPU1_BASE, DDR_WINDOW_CPU_SZ);
3374ee1f6b5SLennert Buytenhek }
3384ee1f6b5SLennert Buytenhek 
mv78xx0_timer_init(void)339bd721ea7SFabian Frederick void __ref mv78xx0_timer_init(void)
340794d15b2SStanislav Samsonov {
3414ee1f6b5SLennert Buytenhek 	orion_time_init(BRIDGE_VIRT_BASE, BRIDGE_INT_TIMER1_CLR,
3424ee1f6b5SLennert Buytenhek 			IRQ_MV78XX0_TIMER_1, get_tclk());
343794d15b2SStanislav Samsonov }
344794d15b2SStanislav Samsonov 
345*4b01f735SJeremy J. Peper /****************************************************************************
346*4b01f735SJeremy J. Peper * XOR engine
347*4b01f735SJeremy J. Peper ****************************************************************************/
mv78xx0_xor_init(void)348*4b01f735SJeremy J. Peper void __init mv78xx0_xor_init(void)
349*4b01f735SJeremy J. Peper {
350*4b01f735SJeremy J. Peper 	orion_xor0_init(XOR_PHYS_BASE,
351*4b01f735SJeremy J. Peper 		XOR_PHYS_BASE + 0x200,
352*4b01f735SJeremy J. Peper 		IRQ_MV78XX0_XOR_0, IRQ_MV78XX0_XOR_1);
353*4b01f735SJeremy J. Peper }
354*4b01f735SJeremy J. Peper 
355*4b01f735SJeremy J. Peper /****************************************************************************
356*4b01f735SJeremy J. Peper  * Cryptographic Engines and Security Accelerator (CESA)
357*4b01f735SJeremy J. Peper ****************************************************************************/
mv78xx0_crypto_init(void)358*4b01f735SJeremy J. Peper void __init mv78xx0_crypto_init(void)
359*4b01f735SJeremy J. Peper {
360*4b01f735SJeremy J. Peper 	mvebu_mbus_add_window_by_id(MV78XX0_MBUS_SRAM_TARGET,
361*4b01f735SJeremy J. Peper 				MV78XX0_MBUS_SRAM_ATTR,
362*4b01f735SJeremy J. Peper 				MV78XX0_SRAM_PHYS_BASE,
363*4b01f735SJeremy J. Peper 			MV78XX0_SRAM_SIZE);
364*4b01f735SJeremy J. Peper 	orion_crypto_init(CRYPTO_PHYS_BASE, MV78XX0_SRAM_PHYS_BASE,
365*4b01f735SJeremy J. Peper 		SZ_8K, IRQ_MV78XX0_CRYPTO);
366*4b01f735SJeremy J. Peper }
367*4b01f735SJeremy J. Peper 
368794d15b2SStanislav Samsonov 
369794d15b2SStanislav Samsonov /*****************************************************************************
370794d15b2SStanislav Samsonov  * General
371794d15b2SStanislav Samsonov  ****************************************************************************/
mv78xx0_id(void)372cfdeb637SLennert Buytenhek static char * __init mv78xx0_id(void)
373cfdeb637SLennert Buytenhek {
374cfdeb637SLennert Buytenhek 	u32 dev, rev;
375cfdeb637SLennert Buytenhek 
376cfdeb637SLennert Buytenhek 	mv78xx0_pcie_id(&dev, &rev);
377cfdeb637SLennert Buytenhek 
378cfdeb637SLennert Buytenhek 	if (dev == MV78X00_Z0_DEV_ID) {
379cfdeb637SLennert Buytenhek 		if (rev == MV78X00_REV_Z0)
380cfdeb637SLennert Buytenhek 			return "MV78X00-Z0";
381cfdeb637SLennert Buytenhek 		else
382cfdeb637SLennert Buytenhek 			return "MV78X00-Rev-Unsupported";
383cfdeb637SLennert Buytenhek 	} else if (dev == MV78100_DEV_ID) {
384cfdeb637SLennert Buytenhek 		if (rev == MV78100_REV_A0)
385cfdeb637SLennert Buytenhek 			return "MV78100-A0";
386662aecedSLennert Buytenhek 		else if (rev == MV78100_REV_A1)
387662aecedSLennert Buytenhek 			return "MV78100-A1";
388cfdeb637SLennert Buytenhek 		else
389cfdeb637SLennert Buytenhek 			return "MV78100-Rev-Unsupported";
390cfdeb637SLennert Buytenhek 	} else if (dev == MV78200_DEV_ID) {
391cfdeb637SLennert Buytenhek 		if (rev == MV78100_REV_A0)
392cfdeb637SLennert Buytenhek 			return "MV78200-A0";
393cfdeb637SLennert Buytenhek 		else
394cfdeb637SLennert Buytenhek 			return "MV78200-Rev-Unsupported";
395cfdeb637SLennert Buytenhek 	} else {
396cfdeb637SLennert Buytenhek 		return "Device-Unknown";
397cfdeb637SLennert Buytenhek 	}
398cfdeb637SLennert Buytenhek }
399cfdeb637SLennert Buytenhek 
is_l2_writethrough(void)400794d15b2SStanislav Samsonov static int __init is_l2_writethrough(void)
401794d15b2SStanislav Samsonov {
402794d15b2SStanislav Samsonov 	return !!(readl(CPU_CONTROL) & L2_WRITETHROUGH);
403794d15b2SStanislav Samsonov }
404794d15b2SStanislav Samsonov 
mv78xx0_init(void)405794d15b2SStanislav Samsonov void __init mv78xx0_init(void)
406794d15b2SStanislav Samsonov {
407794d15b2SStanislav Samsonov 	int core_index;
408794d15b2SStanislav Samsonov 	int hclk;
409794d15b2SStanislav Samsonov 	int pclk;
410794d15b2SStanislav Samsonov 	int l2clk;
411794d15b2SStanislav Samsonov 
412794d15b2SStanislav Samsonov 	core_index = mv78xx0_core_index();
413794d15b2SStanislav Samsonov 	hclk = get_hclk();
414794d15b2SStanislav Samsonov 	get_pclk_l2clk(hclk, core_index, &pclk, &l2clk);
415794d15b2SStanislav Samsonov 
416cfdeb637SLennert Buytenhek 	printk(KERN_INFO "%s ", mv78xx0_id());
417cfdeb637SLennert Buytenhek 	printk("core #%d, ", core_index);
418794d15b2SStanislav Samsonov 	printk("PCLK = %dMHz, ", (pclk + 499999) / 1000000);
419794d15b2SStanislav Samsonov 	printk("L2 = %dMHz, ", (l2clk + 499999) / 1000000);
420794d15b2SStanislav Samsonov 	printk("HCLK = %dMHz, ", (hclk + 499999) / 1000000);
4212f129bf4SAndrew Lunn 	printk("TCLK = %dMHz\n", (get_tclk() + 499999) / 1000000);
422794d15b2SStanislav Samsonov 
423d3201edeSArnd Bergmann 	if (IS_ENABLED(CONFIG_CACHE_FEROCEON_L2))
424794d15b2SStanislav Samsonov 		feroceon_l2_init(is_l2_writethrough());
4252f129bf4SAndrew Lunn 
4262f129bf4SAndrew Lunn 	/* Setup root of clk tree */
4272f129bf4SAndrew Lunn 	clk_init();
428794d15b2SStanislav Samsonov }
4299635f9cdSRussell King 
mv78xx0_restart(enum reboot_mode mode,const char * cmd)4307b6d864bSRobin Holt void mv78xx0_restart(enum reboot_mode mode, const char *cmd)
4319635f9cdSRussell King {
4329635f9cdSRussell King 	/*
4339635f9cdSRussell King 	 * Enable soft reset to assert RSTOUTn.
4349635f9cdSRussell King 	 */
4359635f9cdSRussell King 	writel(SOFT_RESET_OUT_EN, RSTOUTn_MASK);
4369635f9cdSRussell King 
4379635f9cdSRussell King 	/*
4389635f9cdSRussell King 	 * Assert soft reset.
4399635f9cdSRussell King 	 */
4409635f9cdSRussell King 	writel(SOFT_RESET, SYSTEM_SOFT_RESET);
4419635f9cdSRussell King 
4429635f9cdSRussell King 	while (1)
4439635f9cdSRussell King 		;
4449635f9cdSRussell King }
445