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