1 // 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 
17 DECLARE_GLOBAL_DATA_PTR;
18 
19 static 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 
print_cpuinfo(void)28 int 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 
get_xtal_mhz(void)87 unsigned 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 
xhci_config_40mhz(void __iomem * usbh)103 static 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 
xhci_config_25mhz(void __iomem * usbh)164 static 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 
lowlevel_init(void)223 void 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 
get_tbclk(void)235 ulong notrace get_tbclk(void)
236 {
237 	return gd->arch.timer_freq;
238 }
239 
_machine_restart(void)240 void _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 }
247