blob: d21848ad23ba49564ba44370ad8422fe81636667 [file] [log] [blame]
developer2fddd722022-05-20 11:22:21 +08001// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright (C) 2022 MediaTek Inc. All rights reserved.
4 *
5 * Author: Weijie Gao <weijie.gao@mediatek.com>
6 */
7
8#include <clk.h>
9#include <dm.h>
10#include <dm/uclass.h>
11#include <dt-bindings/clock/mt7621-clk.h>
12#include <asm/global_data.h>
13#include <linux/io.h>
14#include <linux/bitfield.h>
15#include "mt7621.h"
16
17DECLARE_GLOBAL_DATA_PTR;
18
19static const char *const boot_mode[(CHIP_MODE_M >> CHIP_MODE_S) + 1] = {
20 [1] = "NAND 2K+64",
21 [2] = "SPI-NOR 3-Byte Addr",
22 [3] = "SPI-NOR 4-Byte Addr",
23 [10] = "NAND 2K+128",
24 [11] = "NAND 4K+128",
25 [12] = "NAND 4K+256",
26};
27
28int print_cpuinfo(void)
29{
30 void __iomem *sysc = ioremap_nocache(SYSCTL_BASE, SYSCTL_SIZE);
31 u32 val, ver, eco, pkg, core, dram, chipmode;
32 u32 cpu_clk, ddr_clk, bus_clk, xtal_clk;
33 struct udevice *clkdev;
34 const char *bootdev;
35 struct clk clk;
36 int ret;
37
38 val = readl(sysc + SYSCTL_CHIP_REV_ID_REG);
39 ver = FIELD_GET(VER_ID_M, val);
40 eco = FIELD_GET(ECO_ID_M, val);
41 pkg = FIELD_GET(PKG_ID, val);
42 core = FIELD_GET(CPU_ID, val);
43
44 val = readl(sysc + SYSCTL_SYSCFG0_REG);
45 dram = FIELD_GET(DRAM_TYPE, val);
46 chipmode = FIELD_GET(CHIP_MODE_M, val);
47
48 bootdev = boot_mode[chipmode];
49 if (!bootdev)
50 bootdev = "Unsupported boot mode";
51
52 printf("CPU: MediaTek MT7621%c ver %u, eco %u\n",
53 core ? (pkg ? 'A' : 'N') : 'S', ver, eco);
54
55 printf("Boot: DDR%u, %s\n", dram ? 2 : 3, bootdev);
56
57 ret = uclass_get_device_by_driver(UCLASS_CLK, DM_DRIVER_GET(mt7621_clk),
58 &clkdev);
59 if (ret)
60 return ret;
61
62 clk.dev = clkdev;
63
64 clk.id = MT7621_CLK_CPU;
65 cpu_clk = clk_get_rate(&clk);
66
67 clk.id = MT7621_CLK_BUS;
68 bus_clk = clk_get_rate(&clk);
69
70 clk.id = MT7621_CLK_DDR;
71 ddr_clk = clk_get_rate(&clk);
72
73 clk.id = MT7621_CLK_XTAL;
74 xtal_clk = clk_get_rate(&clk);
75
76 /* Set final timer frequency */
77 if (cpu_clk)
78 gd->arch.timer_freq = cpu_clk / 2;
79
80 printf("Clock: CPU: %uMHz, DDR: %uMT/s, Bus: %uMHz, XTAL: %uMHz\n",
81 cpu_clk / 1000000, ddr_clk / 500000, bus_clk / 1000000,
82 xtal_clk / 1000000);
83
84 return 0;
85}
86
87unsigned long get_xtal_mhz(void)
88{
89 void __iomem *sysc = ioremap_nocache(SYSCTL_BASE, SYSCTL_SIZE);
90 u32 bs, xtal_sel;
91
92 bs = readl(sysc + SYSCTL_SYSCFG0_REG);
93 xtal_sel = FIELD_GET(XTAL_MODE_SEL_M, bs);
94
95 if (xtal_sel <= 2)
96 return 20;
97 else if (xtal_sel <= 5)
98 return 40;
99 else
100 return 25;
101}
102
103static void xhci_config_40mhz(void __iomem *usbh)
104{
105 writel(FIELD_PREP(SSUSB_MAC3_SYS_CK_GATE_MASK_TIME_M, 0x20) |
106 FIELD_PREP(SSUSB_MAC2_SYS_CK_GATE_MASK_TIME_M, 0x20) |
107 FIELD_PREP(SSUSB_MAC3_SYS_CK_GATE_MODE_M, 2) |
108 FIELD_PREP(SSUSB_MAC2_SYS_CK_GATE_MODE_M, 2) | 0x10,
109 usbh + SSUSB_MAC_CK_CTRL_REG);
110
111 writel(FIELD_PREP(SSUSB_PLL_PREDIV_PE1D_M, 2) |
112 FIELD_PREP(SSUSB_PLL_PREDIV_U3_M, 1) |
113 FIELD_PREP(SSUSB_PLL_FBKDI_M, 4),
114 usbh + DA_SSUSB_U3PHYA_10_REG);
115
116 writel(FIELD_PREP(SSUSB_PLL_FBKDIV_PE2H_M, 0x18) |
117 FIELD_PREP(SSUSB_PLL_FBKDIV_PE1D_M, 0x18) |
118 FIELD_PREP(SSUSB_PLL_FBKDIV_PE1H_M, 0x18) |
119 FIELD_PREP(SSUSB_PLL_FBKDIV_U3_M, 0x1e),
120 usbh + DA_SSUSB_PLL_FBKDIV_REG);
121
122 writel(FIELD_PREP(SSUSB_PLL_PCW_NCPO_U3_M, 0x1e400000),
123 usbh + DA_SSUSB_PLL_PCW_NCPO_REG);
124
125 writel(FIELD_PREP(SSUSB_PLL_SSC_DELTA1_PE1H_M, 0x25) |
126 FIELD_PREP(SSUSB_PLL_SSC_DELTA1_U3_M, 0x73),
127 usbh + DA_SSUSB_PLL_SSC_DELTA1_REG);
128
129 writel(FIELD_PREP(SSUSB_PLL_SSC_DELTA_U3_M, 0x71) |
130 FIELD_PREP(SSUSB_PLL_SSC_DELTA1_PE2D_M, 0x4a),
131 usbh + DA_SSUSB_U3PHYA_21_REG);
132
133 writel(FIELD_PREP(SSUSB_PLL_SSC_PRD_M, 0x140),
134 usbh + SSUSB_U3PHYA_9_REG);
135
136 writel(FIELD_PREP(SSUSB_SYSPLL_PCW_NCPO_M, 0x11c00000),
137 usbh + SSUSB_U3PHYA_3_REG);
138
139 writel(FIELD_PREP(SSUSB_PCIE_CLKDRV_AMP_M, 4) |
140 FIELD_PREP(SSUSB_SYSPLL_FBSEL_M, 1) |
141 FIELD_PREP(SSUSB_SYSPLL_PREDIV_M, 1),
142 usbh + SSUSB_U3PHYA_1_REG);
143
144 writel(FIELD_PREP(SSUSB_SYSPLL_FBDIV_M, 0x12) |
145 SSUSB_SYSPLL_VCO_DIV_SEL | SSUSB_SYSPLL_FPEN |
146 SSUSB_SYSPLL_MONCK_EN | SSUSB_SYSPLL_VOD_EN,
147 usbh + SSUSB_U3PHYA_2_REG);
148
149 writel(SSUSB_EQ_CURSEL | FIELD_PREP(SSUSB_RX_DAC_MUX_M, 8) |
150 FIELD_PREP(SSUSB_PCIE_SIGDET_VTH_M, 1) |
151 FIELD_PREP(SSUSB_PCIE_SIGDET_LPF_M, 1),
152 usbh + SSUSB_U3PHYA_11_REG);
153
154 writel(FIELD_PREP(SSUSB_RING_OSC_CNTEND_M, 0x1ff) |
155 FIELD_PREP(SSUSB_XTAL_OSC_CNTEND_M, 0x7f) |
156 SSUSB_RING_BYPASS_DET,
157 usbh + SSUSB_B2_ROSC_0_REG);
158
159 writel(FIELD_PREP(SSUSB_RING_OSC_FRC_RECAL_M, 3) |
160 SSUSB_RING_OSC_FRC_SEL,
161 usbh + SSUSB_B2_ROSC_1_REG);
162}
163
164static void xhci_config_25mhz(void __iomem *usbh)
165{
166 writel(FIELD_PREP(SSUSB_MAC3_SYS_CK_GATE_MASK_TIME_M, 0x20) |
167 FIELD_PREP(SSUSB_MAC2_SYS_CK_GATE_MASK_TIME_M, 0x20) |
168 FIELD_PREP(SSUSB_MAC3_SYS_CK_GATE_MODE_M, 2) |
169 FIELD_PREP(SSUSB_MAC2_SYS_CK_GATE_MODE_M, 2) | 0x10,
170 usbh + SSUSB_MAC_CK_CTRL_REG);
171
172 writel(FIELD_PREP(SSUSB_PLL_PREDIV_PE1D_M, 2) |
173 FIELD_PREP(SSUSB_PLL_FBKDI_M, 4),
174 usbh + DA_SSUSB_U3PHYA_10_REG);
175
176 writel(FIELD_PREP(SSUSB_PLL_FBKDIV_PE2H_M, 0x18) |
177 FIELD_PREP(SSUSB_PLL_FBKDIV_PE1D_M, 0x18) |
178 FIELD_PREP(SSUSB_PLL_FBKDIV_PE1H_M, 0x18) |
179 FIELD_PREP(SSUSB_PLL_FBKDIV_U3_M, 0x19),
180 usbh + DA_SSUSB_PLL_FBKDIV_REG);
181
182 writel(FIELD_PREP(SSUSB_PLL_PCW_NCPO_U3_M, 0x18000000),
183 usbh + DA_SSUSB_PLL_PCW_NCPO_REG);
184
185 writel(FIELD_PREP(SSUSB_PLL_SSC_DELTA1_PE1H_M, 0x25) |
186 FIELD_PREP(SSUSB_PLL_SSC_DELTA1_U3_M, 0x4a),
187 usbh + DA_SSUSB_PLL_SSC_DELTA1_REG);
188
189 writel(FIELD_PREP(SSUSB_PLL_SSC_DELTA_U3_M, 0x48) |
190 FIELD_PREP(SSUSB_PLL_SSC_DELTA1_PE2D_M, 0x4a),
191 usbh + DA_SSUSB_U3PHYA_21_REG);
192
193 writel(FIELD_PREP(SSUSB_PLL_SSC_PRD_M, 0x190),
194 usbh + SSUSB_U3PHYA_9_REG);
195
196 writel(FIELD_PREP(SSUSB_SYSPLL_PCW_NCPO_M, 0xe000000),
197 usbh + SSUSB_U3PHYA_3_REG);
198
199 writel(FIELD_PREP(SSUSB_PCIE_CLKDRV_AMP_M, 4) |
200 FIELD_PREP(SSUSB_SYSPLL_FBSEL_M, 1),
201 usbh + SSUSB_U3PHYA_1_REG);
202
203 writel(FIELD_PREP(SSUSB_SYSPLL_FBDIV_M, 0xf) |
204 SSUSB_SYSPLL_VCO_DIV_SEL | SSUSB_SYSPLL_FPEN |
205 SSUSB_SYSPLL_MONCK_EN | SSUSB_SYSPLL_VOD_EN,
206 usbh + SSUSB_U3PHYA_2_REG);
207
208 writel(SSUSB_EQ_CURSEL | FIELD_PREP(SSUSB_RX_DAC_MUX_M, 8) |
209 FIELD_PREP(SSUSB_PCIE_SIGDET_VTH_M, 1) |
210 FIELD_PREP(SSUSB_PCIE_SIGDET_LPF_M, 1),
211 usbh + SSUSB_U3PHYA_11_REG);
212
213 writel(FIELD_PREP(SSUSB_RING_OSC_CNTEND_M, 0x1ff) |
214 FIELD_PREP(SSUSB_XTAL_OSC_CNTEND_M, 0x7f) |
215 SSUSB_RING_BYPASS_DET,
216 usbh + SSUSB_B2_ROSC_0_REG);
217
218 writel(FIELD_PREP(SSUSB_RING_OSC_FRC_RECAL_M, 3) |
219 SSUSB_RING_OSC_FRC_SEL,
220 usbh + SSUSB_B2_ROSC_1_REG);
221}
222
223void lowlevel_init(void)
224{
225 void __iomem *usbh = ioremap_nocache(SSUSB_BASE, SSUSB_SIZE);
226 u32 xtal = get_xtal_mhz();
227
228 /* Setup USB xHCI */
229 if (xtal == 40)
230 xhci_config_40mhz(usbh);
231 else if (xtal == 25)
232 xhci_config_25mhz(usbh);
233}
234
235ulong notrace get_tbclk(void)
236{
237 return gd->arch.timer_freq;
238}
239
240void _machine_restart(void)
241{
242 void __iomem *sysc = ioremap_nocache(SYSCTL_BASE, SYSCTL_SIZE);
243
244 while (1)
245 writel(SYS_RST, sysc + SYSCTL_RSTCTL_REG);
246}