xref: /openbmc/u-boot/arch/mips/mach-pic32/cpu.c (revision be961fa1)
132c1a6eeSPurna Chandra Mandal /*
232c1a6eeSPurna Chandra Mandal  * Copyright (C) 2015
332c1a6eeSPurna Chandra Mandal  * Purna Chandra Mandal <purna.mandal@microchip.com>
432c1a6eeSPurna Chandra Mandal  *
532c1a6eeSPurna Chandra Mandal  * SPDX-License-Identifier:	GPL-2.0+
632c1a6eeSPurna Chandra Mandal  *
732c1a6eeSPurna Chandra Mandal  */
832c1a6eeSPurna Chandra Mandal #include <common.h>
9*be961fa1SPurna Chandra Mandal #include <clk.h>
10*be961fa1SPurna Chandra Mandal #include <dm.h>
11*be961fa1SPurna Chandra Mandal #include <mach/pic32.h>
12*be961fa1SPurna Chandra Mandal #include <mach/ddr.h>
13*be961fa1SPurna Chandra Mandal #include <dt-bindings/clock/microchip,clock.h>
1432c1a6eeSPurna Chandra Mandal 
15*be961fa1SPurna Chandra Mandal /* Flash prefetch */
16*be961fa1SPurna Chandra Mandal #define PRECON          0x00
17*be961fa1SPurna Chandra Mandal 
18*be961fa1SPurna Chandra Mandal /* Flash ECCCON */
19*be961fa1SPurna Chandra Mandal #define ECC_MASK	0x03
20*be961fa1SPurna Chandra Mandal #define ECC_SHIFT	4
21*be961fa1SPurna Chandra Mandal 
22*be961fa1SPurna Chandra Mandal #define CLK_MHZ(x)	((x) / 1000000)
23*be961fa1SPurna Chandra Mandal 
24*be961fa1SPurna Chandra Mandal DECLARE_GLOBAL_DATA_PTR;
25*be961fa1SPurna Chandra Mandal 
26*be961fa1SPurna Chandra Mandal static ulong clk_get_cpu_rate(void)
2732c1a6eeSPurna Chandra Mandal {
28*be961fa1SPurna Chandra Mandal 	int ret;
29*be961fa1SPurna Chandra Mandal 	struct udevice *dev;
30*be961fa1SPurna Chandra Mandal 
31*be961fa1SPurna Chandra Mandal 	ret = uclass_get_device(UCLASS_CLK, 0, &dev);
32*be961fa1SPurna Chandra Mandal 	if (ret) {
33*be961fa1SPurna Chandra Mandal 		panic("uclass-clk: device not found\n");
3432c1a6eeSPurna Chandra Mandal 		return 0;
3532c1a6eeSPurna Chandra Mandal 	}
36*be961fa1SPurna Chandra Mandal 
37*be961fa1SPurna Chandra Mandal 	return clk_get_rate(dev);
38*be961fa1SPurna Chandra Mandal }
39*be961fa1SPurna Chandra Mandal 
40*be961fa1SPurna Chandra Mandal /* initialize prefetch module related to cpu_clk */
41*be961fa1SPurna Chandra Mandal static void prefetch_init(void)
42*be961fa1SPurna Chandra Mandal {
43*be961fa1SPurna Chandra Mandal 	struct pic32_reg_atomic *regs;
44*be961fa1SPurna Chandra Mandal 	const void __iomem *base;
45*be961fa1SPurna Chandra Mandal 	int v, nr_waits;
46*be961fa1SPurna Chandra Mandal 	ulong rate;
47*be961fa1SPurna Chandra Mandal 
48*be961fa1SPurna Chandra Mandal 	/* cpu frequency in MHZ */
49*be961fa1SPurna Chandra Mandal 	rate = clk_get_cpu_rate() / 1000000;
50*be961fa1SPurna Chandra Mandal 
51*be961fa1SPurna Chandra Mandal 	/* get flash ECC type */
52*be961fa1SPurna Chandra Mandal 	base = pic32_get_syscfg_base();
53*be961fa1SPurna Chandra Mandal 	v = (readl(base + CFGCON) >> ECC_SHIFT) & ECC_MASK;
54*be961fa1SPurna Chandra Mandal 
55*be961fa1SPurna Chandra Mandal 	if (v < 2) {
56*be961fa1SPurna Chandra Mandal 		if (rate < 66)
57*be961fa1SPurna Chandra Mandal 			nr_waits = 0;
58*be961fa1SPurna Chandra Mandal 		else if (rate < 133)
59*be961fa1SPurna Chandra Mandal 			nr_waits = 1;
60*be961fa1SPurna Chandra Mandal 		else
61*be961fa1SPurna Chandra Mandal 			nr_waits = 2;
62*be961fa1SPurna Chandra Mandal 	} else {
63*be961fa1SPurna Chandra Mandal 		if (rate <= 83)
64*be961fa1SPurna Chandra Mandal 			nr_waits = 0;
65*be961fa1SPurna Chandra Mandal 		else if (rate <= 166)
66*be961fa1SPurna Chandra Mandal 			nr_waits = 1;
67*be961fa1SPurna Chandra Mandal 		else
68*be961fa1SPurna Chandra Mandal 			nr_waits = 2;
69*be961fa1SPurna Chandra Mandal 	}
70*be961fa1SPurna Chandra Mandal 
71*be961fa1SPurna Chandra Mandal 	regs = ioremap(PREFETCH_BASE + PRECON, sizeof(*regs));
72*be961fa1SPurna Chandra Mandal 	writel(nr_waits, &regs->raw);
73*be961fa1SPurna Chandra Mandal 
74*be961fa1SPurna Chandra Mandal 	/* Enable prefetch for all */
75*be961fa1SPurna Chandra Mandal 	writel(0x30, &regs->set);
76*be961fa1SPurna Chandra Mandal 	iounmap(regs);
77*be961fa1SPurna Chandra Mandal }
78*be961fa1SPurna Chandra Mandal 
79*be961fa1SPurna Chandra Mandal /* arch specific CPU init after DM */
80*be961fa1SPurna Chandra Mandal int arch_cpu_init_dm(void)
81*be961fa1SPurna Chandra Mandal {
82*be961fa1SPurna Chandra Mandal 	/* flash prefetch */
83*be961fa1SPurna Chandra Mandal 	prefetch_init();
84*be961fa1SPurna Chandra Mandal 	return 0;
85*be961fa1SPurna Chandra Mandal }
86*be961fa1SPurna Chandra Mandal 
87*be961fa1SPurna Chandra Mandal /* Un-gate DDR2 modules (gated by default) */
88*be961fa1SPurna Chandra Mandal static void ddr2_pmd_ungate(void)
89*be961fa1SPurna Chandra Mandal {
90*be961fa1SPurna Chandra Mandal 	void __iomem *regs;
91*be961fa1SPurna Chandra Mandal 
92*be961fa1SPurna Chandra Mandal 	regs = pic32_get_syscfg_base();
93*be961fa1SPurna Chandra Mandal 	writel(0, regs + PMD7);
94*be961fa1SPurna Chandra Mandal }
95*be961fa1SPurna Chandra Mandal 
96*be961fa1SPurna Chandra Mandal /* initialize the DDR2 Controller and DDR2 PHY */
97*be961fa1SPurna Chandra Mandal phys_size_t initdram(int board_type)
98*be961fa1SPurna Chandra Mandal {
99*be961fa1SPurna Chandra Mandal 	ddr2_pmd_ungate();
100*be961fa1SPurna Chandra Mandal 	ddr2_phy_init();
101*be961fa1SPurna Chandra Mandal 	ddr2_ctrl_init();
102*be961fa1SPurna Chandra Mandal 	return ddr2_calculate_size();
103*be961fa1SPurna Chandra Mandal }
104*be961fa1SPurna Chandra Mandal 
105*be961fa1SPurna Chandra Mandal int misc_init_r(void)
106*be961fa1SPurna Chandra Mandal {
107*be961fa1SPurna Chandra Mandal 	set_io_port_base(0);
108*be961fa1SPurna Chandra Mandal 	return 0;
109*be961fa1SPurna Chandra Mandal }
110*be961fa1SPurna Chandra Mandal 
111*be961fa1SPurna Chandra Mandal #ifdef CONFIG_DISPLAY_BOARDINFO
112*be961fa1SPurna Chandra Mandal const char *get_core_name(void)
113*be961fa1SPurna Chandra Mandal {
114*be961fa1SPurna Chandra Mandal 	u32 proc_id;
115*be961fa1SPurna Chandra Mandal 	const char *str;
116*be961fa1SPurna Chandra Mandal 
117*be961fa1SPurna Chandra Mandal 	proc_id = read_c0_prid();
118*be961fa1SPurna Chandra Mandal 	switch (proc_id) {
119*be961fa1SPurna Chandra Mandal 	case 0x19e28:
120*be961fa1SPurna Chandra Mandal 		str = "PIC32MZ[DA]";
121*be961fa1SPurna Chandra Mandal 		break;
122*be961fa1SPurna Chandra Mandal 	default:
123*be961fa1SPurna Chandra Mandal 		str = "UNKNOWN";
124*be961fa1SPurna Chandra Mandal 	}
125*be961fa1SPurna Chandra Mandal 
126*be961fa1SPurna Chandra Mandal 	return str;
127*be961fa1SPurna Chandra Mandal }
128*be961fa1SPurna Chandra Mandal #endif
129*be961fa1SPurna Chandra Mandal #ifdef CONFIG_CMD_CLK
130*be961fa1SPurna Chandra Mandal int soc_clk_dump(void)
131*be961fa1SPurna Chandra Mandal {
132*be961fa1SPurna Chandra Mandal 	int i, ret;
133*be961fa1SPurna Chandra Mandal 	struct udevice *dev;
134*be961fa1SPurna Chandra Mandal 
135*be961fa1SPurna Chandra Mandal 	ret = uclass_get_device(UCLASS_CLK, 0, &dev);
136*be961fa1SPurna Chandra Mandal 	if (ret) {
137*be961fa1SPurna Chandra Mandal 		printf("clk-uclass not found\n");
138*be961fa1SPurna Chandra Mandal 		return ret;
139*be961fa1SPurna Chandra Mandal 	}
140*be961fa1SPurna Chandra Mandal 
141*be961fa1SPurna Chandra Mandal 	printf("PLL Speed: %lu MHz\n",
142*be961fa1SPurna Chandra Mandal 	       CLK_MHZ(clk_get_periph_rate(dev, PLLCLK)));
143*be961fa1SPurna Chandra Mandal 	printf("CPU Speed: %lu MHz\n", CLK_MHZ(clk_get_rate(dev)));
144*be961fa1SPurna Chandra Mandal 	printf("MPLL Speed: %lu MHz\n",
145*be961fa1SPurna Chandra Mandal 	       CLK_MHZ(clk_get_periph_rate(dev, MPLL)));
146*be961fa1SPurna Chandra Mandal 
147*be961fa1SPurna Chandra Mandal 	for (i = PB1CLK; i <= PB7CLK; i++)
148*be961fa1SPurna Chandra Mandal 		printf("PB%d Clock Speed: %lu MHz\n", i - PB1CLK + 1,
149*be961fa1SPurna Chandra Mandal 		       CLK_MHZ(clk_get_periph_rate(dev, i)));
150*be961fa1SPurna Chandra Mandal 
151*be961fa1SPurna Chandra Mandal 	for (i = REF1CLK; i <= REF5CLK; i++)
152*be961fa1SPurna Chandra Mandal 		printf("REFO%d Clock Speed: %lu MHz\n", i - REF1CLK + 1,
153*be961fa1SPurna Chandra Mandal 		       CLK_MHZ(clk_get_periph_rate(dev, i)));
154*be961fa1SPurna Chandra Mandal 	return 0;
155*be961fa1SPurna Chandra Mandal }
156*be961fa1SPurna Chandra Mandal #endif
157