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