lx2160: Enable support of EMC2305
[platform/kernel/u-boot.git] / board / freescale / lx2160a / lx2160a.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright 2018 NXP
4  */
5
6 #include <common.h>
7 #include <dm.h>
8 #include <dm/platform_data/serial_pl01x.h>
9 #include <i2c.h>
10 #include <malloc.h>
11 #include <errno.h>
12 #include <netdev.h>
13 #include <fsl_ddr.h>
14 #include <fsl_sec.h>
15 #include <asm/io.h>
16 #include <fdt_support.h>
17 #include <linux/libfdt.h>
18 #include <fsl-mc/fsl_mc.h>
19 #include <environment.h>
20 #include <efi_loader.h>
21 #include <asm/arch/mmu.h>
22 #include <hwconfig.h>
23 #include <asm/arch/fsl_serdes.h>
24 #include <asm/arch/soc.h>
25 #include "../common/qixis.h"
26 #include "../common/vid.h"
27 #include <fsl_immap.h>
28
29 #ifdef CONFIG_EMC2305
30 #include "../common/emc2305.h"
31 #endif
32
33 DECLARE_GLOBAL_DATA_PTR;
34
35 static struct pl01x_serial_platdata serial0 = {
36 #if CONFIG_CONS_INDEX == 0
37         .base = CONFIG_SYS_SERIAL0,
38 #elif CONFIG_CONS_INDEX == 1
39         .base = CONFIG_SYS_SERIAL1,
40 #else
41 #error "Unsupported console index value."
42 #endif
43         .type = TYPE_PL011,
44 };
45
46 U_BOOT_DEVICE(nxp_serial0) = {
47         .name = "serial_pl01x",
48         .platdata = &serial0,
49 };
50
51 static struct pl01x_serial_platdata serial1 = {
52         .base = CONFIG_SYS_SERIAL1,
53         .type = TYPE_PL011,
54 };
55
56 U_BOOT_DEVICE(nxp_serial1) = {
57         .name = "serial_pl01x",
58         .platdata = &serial1,
59 };
60
61 int select_i2c_ch_pca9547(u8 ch)
62 {
63         int ret;
64
65         ret = i2c_write(I2C_MUX_PCA_ADDR_PRI, 0, 1, &ch, 1);
66         if (ret) {
67                 puts("PCA: failed to select proper channel\n");
68                 return ret;
69         }
70
71         return 0;
72 }
73
74 static void uart_get_clock(void)
75 {
76         serial0.clock = get_serial_clock();
77         serial1.clock = get_serial_clock();
78 }
79
80 int board_early_init_f(void)
81 {
82 #ifdef CONFIG_SYS_I2C_EARLY_INIT
83         i2c_early_init_f();
84 #endif
85         /* get required clock for UART IP */
86         uart_get_clock();
87
88 #ifdef CONFIG_EMC2305
89         select_i2c_ch_pca9547(I2C_MUX_CH_EMC2305);
90         emc2305_init();
91         set_fan_speed(I2C_EMC2305_PWM);
92         select_i2c_ch_pca9547(I2C_MUX_CH_DEFAULT);
93 #endif
94
95         fsl_lsch3_early_init_f();
96         return 0;
97 }
98
99 int esdhc_status_fixup(void *blob, const char *compat)
100 {
101         /* Enable both esdhc DT nodes for LX2160ARDB */
102         do_fixup_by_compat(blob, compat, "status", "okay",
103                            sizeof("okay"), 1);
104
105         return 0;
106 }
107
108 #if defined(CONFIG_VID)
109 int i2c_multiplexer_select_vid_channel(u8 channel)
110 {
111         return select_i2c_ch_pca9547(channel);
112 }
113
114 #endif
115
116 int checkboard(void)
117 {
118         enum boot_src src = get_boot_src();
119         char buf[64];
120         u8 sw;
121
122         cpu_name(buf);
123         printf("Board: %s-RDB, ", buf);
124
125         sw = QIXIS_READ(arch);
126         printf("Board version: %c, boot from ", (sw & 0xf) - 1 + 'A');
127
128         if (src == BOOT_SOURCE_SD_MMC) {
129                 puts("SD\n");
130         } else {
131                 sw = QIXIS_READ(brdcfg[0]);
132                 sw = (sw >> QIXIS_XMAP_SHIFT) & QIXIS_XMAP_MASK;
133                 switch (sw) {
134                 case 0:
135                 case 4:
136                         puts("FlexSPI DEV#0\n");
137                         break;
138                 case 1:
139                         puts("FlexSPI DEV#1\n");
140                         break;
141                 case 2:
142                 case 3:
143                         puts("FlexSPI EMU\n");
144                         break;
145                 default:
146                         printf("invalid setting, xmap: %d\n", sw);
147                         break;
148                 }
149         }
150         printf("FPGA: v%d.%d\n", QIXIS_READ(scver), QIXIS_READ(tagdata));
151
152         puts("SERDES1 Reference: Clock1 = 161.13MHz Clock2 = 161.13MHz\n");
153         puts("SERDES2 Reference: Clock1 = 100MHz Clock2 = 100MHz\n");
154         puts("SERDES3 Reference: Clock1 = 100MHz Clock2 = 100Hz\n");
155         return 0;
156 }
157
158 unsigned long get_board_sys_clk(void)
159 {
160         return 100000000;
161 }
162
163 unsigned long get_board_ddr_clk(void)
164 {
165         return 100000000;
166 }
167
168 int board_init(void)
169 {
170 #ifdef CONFIG_ENV_IS_NOWHERE
171         gd->env_addr = (ulong)&default_environment[0];
172 #endif
173
174         select_i2c_ch_pca9547(I2C_MUX_CH_DEFAULT);
175
176 #ifdef CONFIG_FSL_CAAM
177         sec_init();
178 #endif
179
180         return 0;
181 }
182
183 void detail_board_ddr_info(void)
184 {
185         int i;
186         u64 ddr_size = 0;
187
188         puts("\nDDR    ");
189         for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++)
190                 ddr_size += gd->bd->bi_dram[i].size;
191         print_size(ddr_size, "");
192         print_ddr_info(0);
193 }
194
195 #if defined(CONFIG_ARCH_MISC_INIT)
196 int arch_misc_init(void)
197 {
198         return 0;
199 }
200 #endif
201
202 #ifdef CONFIG_FSL_MC_ENET
203 extern int fdt_fixup_board_phy(void *fdt);
204
205 void fdt_fixup_board_enet(void *fdt)
206 {
207         int offset;
208
209         offset = fdt_path_offset(fdt, "/soc/fsl-mc");
210
211         if (offset < 0)
212                 offset = fdt_path_offset(fdt, "/fsl-mc");
213
214         if (offset < 0) {
215                 printf("%s: fsl-mc node not found in device tree (error %d)\n",
216                        __func__, offset);
217                 return;
218         }
219
220         if ((get_mc_boot_status() == 0) && (get_dpl_apply_status() == 0)) {
221                 fdt_status_okay(fdt, offset);
222                 fdt_fixup_board_phy(fdt);
223         } else {
224                 fdt_status_fail(fdt, offset);
225         }
226 }
227
228 void board_quiesce_devices(void)
229 {
230         fsl_mc_ldpaa_exit(gd->bd);
231 }
232 #endif
233
234 #ifdef CONFIG_OF_BOARD_SETUP
235
236 int ft_board_setup(void *blob, bd_t *bd)
237 {
238         int i;
239         u64 base[CONFIG_NR_DRAM_BANKS];
240         u64 size[CONFIG_NR_DRAM_BANKS];
241
242         ft_cpu_setup(blob, bd);
243
244         /* fixup DT for the three GPP DDR banks */
245         for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
246                 base[i] = gd->bd->bi_dram[i].start;
247                 size[i] = gd->bd->bi_dram[i].size;
248         }
249
250 #ifdef CONFIG_RESV_RAM
251         /* reduce size if reserved memory is within this bank */
252         if (gd->arch.resv_ram >= base[0] &&
253             gd->arch.resv_ram < base[0] + size[0])
254                 size[0] = gd->arch.resv_ram - base[0];
255         else if (gd->arch.resv_ram >= base[1] &&
256                  gd->arch.resv_ram < base[1] + size[1])
257                 size[1] = gd->arch.resv_ram - base[1];
258         else if (gd->arch.resv_ram >= base[2] &&
259                  gd->arch.resv_ram < base[2] + size[2])
260                 size[2] = gd->arch.resv_ram - base[2];
261 #endif
262
263         fdt_fixup_memory_banks(blob, base, size, CONFIG_NR_DRAM_BANKS);
264
265 #ifdef CONFIG_USB
266         fsl_fdt_fixup_dr_usb(blob, bd);
267 #endif
268
269 #ifdef CONFIG_FSL_MC_ENET
270         fdt_fsl_mc_fixup_iommu_map_entry(blob);
271         fdt_fixup_board_enet(blob);
272 #endif
273
274         return 0;
275 }
276 #endif
277
278 void qixis_dump_switch(void)
279 {
280         int i, nr_of_cfgsw;
281
282         QIXIS_WRITE(cms[0], 0x00);
283         nr_of_cfgsw = QIXIS_READ(cms[1]);
284
285         puts("DIP switch settings dump:\n");
286         for (i = 1; i <= nr_of_cfgsw; i++) {
287                 QIXIS_WRITE(cms[0], i);
288                 printf("SW%d = (0x%02x)\n", i, QIXIS_READ(cms[1]));
289         }
290 }