a84a409f43f83e95b761322fd7b6b1351a549c75
[platform/kernel/u-boot.git] / board / CZ.NIC / turris_omnia / turris_omnia.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (C) 2017 Marek Behun <marek.behun@nic.cz>
4  * Copyright (C) 2016 Tomas Hlavacek <tomas.hlavacek@nic.cz>
5  *
6  * Derived from the code for
7  *   Marvell/db-88f6820-gp by Stefan Roese <sr@denx.de>
8  */
9
10 #include <common.h>
11 #include <env.h>
12 #include <i2c.h>
13 #include <init.h>
14 #include <log.h>
15 #include <miiphy.h>
16 #include <mtd.h>
17 #include <net.h>
18 #include <netdev.h>
19 #include <asm/global_data.h>
20 #include <asm/io.h>
21 #include <asm/arch/cpu.h>
22 #include <asm/arch/soc.h>
23 #include <dm/uclass.h>
24 #include <fdt_support.h>
25 #include <time.h>
26 #include <linux/bitops.h>
27 #include <u-boot/crc.h>
28 # include <atsha204a-i2c.h>
29
30 #include "../drivers/ddr/marvell/a38x/ddr3_init.h"
31 #include <../serdes/a38x/high_speed_env_spec.h>
32
33 DECLARE_GLOBAL_DATA_PTR;
34
35 #define OMNIA_SPI_NOR_PATH              "/soc/spi@10600/spi-nor@0"
36
37 #define OMNIA_I2C_BUS_NAME              "i2c@11000->i2cmux@70->i2c@0"
38
39 #define OMNIA_I2C_MCU_CHIP_ADDR         0x2a
40 #define OMNIA_I2C_MCU_CHIP_LEN          1
41
42 #define OMNIA_I2C_EEPROM_CHIP_ADDR      0x54
43 #define OMNIA_I2C_EEPROM_CHIP_LEN       2
44 #define OMNIA_I2C_EEPROM_MAGIC          0x0341a034
45
46 enum mcu_commands {
47         CMD_GET_STATUS_WORD     = 0x01,
48         CMD_GET_RESET           = 0x09,
49         CMD_WATCHDOG_STATE      = 0x0b,
50 };
51
52 enum status_word_bits {
53         CARD_DET_STSBIT         = 0x0010,
54         MSATA_IND_STSBIT        = 0x0020,
55 };
56
57 #define OMNIA_ATSHA204_OTP_VERSION      0
58 #define OMNIA_ATSHA204_OTP_SERIAL       1
59 #define OMNIA_ATSHA204_OTP_MAC0         3
60 #define OMNIA_ATSHA204_OTP_MAC1         4
61
62 /*
63  * Those values and defines are taken from the Marvell U-Boot version
64  * "u-boot-2013.01-2014_T3.0"
65  */
66 #define OMNIA_GPP_OUT_ENA_LOW                                   \
67         (~(BIT(1)  | BIT(4)  | BIT(6)  | BIT(7)  | BIT(8)  | BIT(9)  |  \
68            BIT(10) | BIT(11) | BIT(19) | BIT(22) | BIT(23) | BIT(25) |  \
69            BIT(26) | BIT(27) | BIT(29) | BIT(30) | BIT(31)))
70 #define OMNIA_GPP_OUT_ENA_MID                                   \
71         (~(BIT(0) | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(15) |       \
72            BIT(16) | BIT(17) | BIT(18)))
73
74 #define OMNIA_GPP_OUT_VAL_LOW   0x0
75 #define OMNIA_GPP_OUT_VAL_MID   0x0
76 #define OMNIA_GPP_POL_LOW       0x0
77 #define OMNIA_GPP_POL_MID       0x0
78
79 static struct serdes_map board_serdes_map_pex[] = {
80         {PEX0, SERDES_SPEED_5_GBPS, PEX_ROOT_COMPLEX_X1, 0, 0},
81         {USB3_HOST0, SERDES_SPEED_5_GBPS, SERDES_DEFAULT_MODE, 0, 0},
82         {PEX1, SERDES_SPEED_5_GBPS, PEX_ROOT_COMPLEX_X1, 0, 0},
83         {USB3_HOST1, SERDES_SPEED_5_GBPS, SERDES_DEFAULT_MODE, 0, 0},
84         {PEX2, SERDES_SPEED_5_GBPS, PEX_ROOT_COMPLEX_X1, 0, 0},
85         {SGMII2, SERDES_SPEED_1_25_GBPS, SERDES_DEFAULT_MODE, 0, 0}
86 };
87
88 static struct serdes_map board_serdes_map_sata[] = {
89         {SATA0, SERDES_SPEED_6_GBPS, SERDES_DEFAULT_MODE, 0, 0},
90         {USB3_HOST0, SERDES_SPEED_5_GBPS, SERDES_DEFAULT_MODE, 0, 0},
91         {PEX1, SERDES_SPEED_5_GBPS, PEX_ROOT_COMPLEX_X1, 0, 0},
92         {USB3_HOST1, SERDES_SPEED_5_GBPS, SERDES_DEFAULT_MODE, 0, 0},
93         {PEX2, SERDES_SPEED_5_GBPS, PEX_ROOT_COMPLEX_X1, 0, 0},
94         {SGMII2, SERDES_SPEED_1_25_GBPS, SERDES_DEFAULT_MODE, 0, 0}
95 };
96
97 static struct udevice *omnia_get_i2c_chip(const char *name, uint addr,
98                                           uint offset_len)
99 {
100         struct udevice *bus, *dev;
101         int ret;
102
103         ret = uclass_get_device_by_name(UCLASS_I2C, OMNIA_I2C_BUS_NAME, &bus);
104         if (ret) {
105                 printf("Cannot get I2C bus %s: uclass_get_device_by_name failed: %i\n",
106                        OMNIA_I2C_BUS_NAME, ret);
107                 return NULL;
108         }
109
110         ret = i2c_get_chip(bus, addr, offset_len, &dev);
111         if (ret) {
112                 printf("Cannot get %s I2C chip: i2c_get_chip failed: %i\n",
113                        name, ret);
114                 return NULL;
115         }
116
117         return dev;
118 }
119
120 static int omnia_mcu_read(u8 cmd, void *buf, int len)
121 {
122         struct udevice *chip;
123
124         chip = omnia_get_i2c_chip("MCU", OMNIA_I2C_MCU_CHIP_ADDR,
125                                   OMNIA_I2C_MCU_CHIP_LEN);
126         if (!chip)
127                 return -ENODEV;
128
129         return dm_i2c_read(chip, cmd, buf, len);
130 }
131
132 static int omnia_mcu_write(u8 cmd, const void *buf, int len)
133 {
134         struct udevice *chip;
135
136         chip = omnia_get_i2c_chip("MCU", OMNIA_I2C_MCU_CHIP_ADDR,
137                                   OMNIA_I2C_MCU_CHIP_LEN);
138         if (!chip)
139                 return -ENODEV;
140
141         return dm_i2c_write(chip, cmd, buf, len);
142 }
143
144 static bool disable_mcu_watchdog(void)
145 {
146         int ret;
147
148         puts("Disabling MCU watchdog... ");
149
150         ret = omnia_mcu_write(CMD_WATCHDOG_STATE, "\x00", 1);
151         if (ret) {
152                 printf("omnia_mcu_write failed: %i\n", ret);
153                 return false;
154         }
155
156         puts("disabled\n");
157
158         return true;
159 }
160
161 static bool omnia_detect_sata(void)
162 {
163         int ret;
164         u16 stsword;
165
166         puts("MiniPCIe/mSATA card detection... ");
167
168         ret = omnia_mcu_read(CMD_GET_STATUS_WORD, &stsword, sizeof(stsword));
169         if (ret) {
170                 printf("omnia_mcu_read failed: %i, defaulting to MiniPCIe card\n",
171                        ret);
172                 return false;
173         }
174
175         if (!(stsword & CARD_DET_STSBIT)) {
176                 puts("none\n");
177                 return false;
178         }
179
180         if (stsword & MSATA_IND_STSBIT)
181                 puts("mSATA\n");
182         else
183                 puts("MiniPCIe\n");
184
185         return stsword & MSATA_IND_STSBIT ? true : false;
186 }
187
188 int hws_board_topology_load(struct serdes_map **serdes_map_array, u8 *count)
189 {
190         if (omnia_detect_sata()) {
191                 *serdes_map_array = board_serdes_map_sata;
192                 *count = ARRAY_SIZE(board_serdes_map_sata);
193         } else {
194                 *serdes_map_array = board_serdes_map_pex;
195                 *count = ARRAY_SIZE(board_serdes_map_pex);
196         }
197
198         return 0;
199 }
200
201 struct omnia_eeprom {
202         u32 magic;
203         u32 ramsize;
204         char region[4];
205         u32 crc;
206 };
207
208 static bool omnia_read_eeprom(struct omnia_eeprom *oep)
209 {
210         struct udevice *chip;
211         u32 crc;
212         int ret;
213
214         chip = omnia_get_i2c_chip("EEPROM", OMNIA_I2C_EEPROM_CHIP_ADDR,
215                                   OMNIA_I2C_EEPROM_CHIP_LEN);
216
217         if (!chip)
218                 return false;
219
220         ret = dm_i2c_read(chip, 0, (void *)oep, sizeof(*oep));
221         if (ret) {
222                 printf("dm_i2c_read failed: %i, cannot read EEPROM\n", ret);
223                 return false;
224         }
225
226         if (oep->magic != OMNIA_I2C_EEPROM_MAGIC) {
227                 printf("bad EEPROM magic number (%08x, should be %08x)\n",
228                        oep->magic, OMNIA_I2C_EEPROM_MAGIC);
229                 return false;
230         }
231
232         crc = crc32(0, (void *)oep, sizeof(*oep) - 4);
233         if (crc != oep->crc) {
234                 printf("bad EEPROM CRC (stored %08x, computed %08x)\n",
235                        oep->crc, crc);
236                 return false;
237         }
238
239         return true;
240 }
241
242 static int omnia_get_ram_size_gb(void)
243 {
244         static int ram_size;
245         struct omnia_eeprom oep;
246
247         if (!ram_size) {
248                 /* Get the board config from EEPROM */
249                 if (omnia_read_eeprom(&oep)) {
250                         debug("Memory config in EEPROM: 0x%02x\n", oep.ramsize);
251
252                         if (oep.ramsize == 0x2)
253                                 ram_size = 2;
254                         else
255                                 ram_size = 1;
256                 } else {
257                         /* Hardcoded fallback */
258                         puts("Memory config from EEPROM read failed!\n");
259                         puts("Falling back to default 1 GiB!\n");
260                         ram_size = 1;
261                 }
262         }
263
264         return ram_size;
265 }
266
267 /*
268  * Define the DDR layout / topology here in the board file. This will
269  * be used by the DDR3 init code in the SPL U-Boot version to configure
270  * the DDR3 controller.
271  */
272 static struct mv_ddr_topology_map board_topology_map_1g = {
273         DEBUG_LEVEL_ERROR,
274         0x1, /* active interfaces */
275         /* cs_mask, mirror, dqs_swap, ck_swap X PUPs */
276         { { { {0x1, 0, 0, 0},
277               {0x1, 0, 0, 0},
278               {0x1, 0, 0, 0},
279               {0x1, 0, 0, 0},
280               {0x1, 0, 0, 0} },
281             SPEED_BIN_DDR_1600K,        /* speed_bin */
282             MV_DDR_DEV_WIDTH_16BIT,     /* memory_width */
283             MV_DDR_DIE_CAP_4GBIT,                       /* mem_size */
284             MV_DDR_FREQ_800,            /* frequency */
285             0, 0,                       /* cas_wl cas_l */
286             MV_DDR_TEMP_NORMAL,         /* temperature */
287             MV_DDR_TIM_2T} },           /* timing */
288         BUS_MASK_32BIT,                 /* Busses mask */
289         MV_DDR_CFG_DEFAULT,             /* ddr configuration data source */
290         NOT_COMBINED,                   /* ddr twin-die combined */
291         { {0} },                        /* raw spd data */
292         {0}                             /* timing parameters */
293 };
294
295 static struct mv_ddr_topology_map board_topology_map_2g = {
296         DEBUG_LEVEL_ERROR,
297         0x1, /* active interfaces */
298         /* cs_mask, mirror, dqs_swap, ck_swap X PUPs */
299         { { { {0x1, 0, 0, 0},
300               {0x1, 0, 0, 0},
301               {0x1, 0, 0, 0},
302               {0x1, 0, 0, 0},
303               {0x1, 0, 0, 0} },
304             SPEED_BIN_DDR_1600K,        /* speed_bin */
305             MV_DDR_DEV_WIDTH_16BIT,     /* memory_width */
306             MV_DDR_DIE_CAP_8GBIT,                       /* mem_size */
307             MV_DDR_FREQ_800,            /* frequency */
308             0, 0,                       /* cas_wl cas_l */
309             MV_DDR_TEMP_NORMAL,         /* temperature */
310             MV_DDR_TIM_2T} },           /* timing */
311         BUS_MASK_32BIT,                 /* Busses mask */
312         MV_DDR_CFG_DEFAULT,             /* ddr configuration data source */
313         NOT_COMBINED,                   /* ddr twin-die combined */
314         { {0} },                        /* raw spd data */
315         {0}                             /* timing parameters */
316 };
317
318 struct mv_ddr_topology_map *mv_ddr_topology_map_get(void)
319 {
320         if (omnia_get_ram_size_gb() == 2)
321                 return &board_topology_map_2g;
322         else
323                 return &board_topology_map_1g;
324 }
325
326 static int set_regdomain(void)
327 {
328         struct omnia_eeprom oep;
329         char rd[3] = {' ', ' ', 0};
330
331         if (omnia_read_eeprom(&oep))
332                 memcpy(rd, &oep.region, 2);
333         else
334                 puts("EEPROM regdomain read failed.\n");
335
336         printf("Regdomain set to %s\n", rd);
337         return env_set("regdomain", rd);
338 }
339
340 static void handle_reset_button(void)
341 {
342         const char * const vars[1] = { "bootcmd_rescue", };
343         int ret;
344         u8 reset_status;
345
346         /*
347          * Ensure that bootcmd_rescue has always stock value, so that running
348          *   run bootcmd_rescue
349          * always works correctly.
350          */
351         env_set_default_vars(1, (char * const *)vars, 0);
352
353         ret = omnia_mcu_read(CMD_GET_RESET, &reset_status, 1);
354         if (ret) {
355                 printf("omnia_mcu_read failed: %i, reset status unknown!\n",
356                        ret);
357                 return;
358         }
359
360         env_set_ulong("omnia_reset", reset_status);
361
362         if (reset_status) {
363                 const char * const vars[2] = {
364                         "bootcmd",
365                         "distro_bootcmd",
366                 };
367
368                 /*
369                  * Set the above envs to their default values, in case the user
370                  * managed to break them.
371                  */
372                 env_set_default_vars(2, (char * const *)vars, 0);
373
374                 /* Ensure bootcmd_rescue is used by distroboot */
375                 env_set("boot_targets", "rescue");
376
377                 printf("RESET button was pressed, overwriting bootcmd!\n");
378         } else {
379                 /*
380                  * In case the user somehow managed to save environment with
381                  * boot_targets=rescue, reset boot_targets to default value.
382                  * This could happen in subsequent commands if bootcmd_rescue
383                  * failed.
384                  */
385                 if (!strcmp(env_get("boot_targets"), "rescue")) {
386                         const char * const vars[1] = {
387                                 "boot_targets",
388                         };
389
390                         env_set_default_vars(1, (char * const *)vars, 0);
391                 }
392         }
393 }
394
395 int board_early_init_f(void)
396 {
397         /* Configure MPP */
398         writel(0x11111111, MVEBU_MPP_BASE + 0x00);
399         writel(0x11111111, MVEBU_MPP_BASE + 0x04);
400         writel(0x11244011, MVEBU_MPP_BASE + 0x08);
401         writel(0x22222111, MVEBU_MPP_BASE + 0x0c);
402         writel(0x22200002, MVEBU_MPP_BASE + 0x10);
403         writel(0x30042022, MVEBU_MPP_BASE + 0x14);
404         writel(0x55550555, MVEBU_MPP_BASE + 0x18);
405         writel(0x00005550, MVEBU_MPP_BASE + 0x1c);
406
407         /* Set GPP Out value */
408         writel(OMNIA_GPP_OUT_VAL_LOW, MVEBU_GPIO0_BASE + 0x00);
409         writel(OMNIA_GPP_OUT_VAL_MID, MVEBU_GPIO1_BASE + 0x00);
410
411         /* Set GPP Polarity */
412         writel(OMNIA_GPP_POL_LOW, MVEBU_GPIO0_BASE + 0x0c);
413         writel(OMNIA_GPP_POL_MID, MVEBU_GPIO1_BASE + 0x0c);
414
415         /* Set GPP Out Enable */
416         writel(OMNIA_GPP_OUT_ENA_LOW, MVEBU_GPIO0_BASE + 0x04);
417         writel(OMNIA_GPP_OUT_ENA_MID, MVEBU_GPIO1_BASE + 0x04);
418
419         return 0;
420 }
421
422 int board_init(void)
423 {
424         /* address of boot parameters */
425         gd->bd->bi_boot_params = mvebu_sdram_bar(0) + 0x100;
426
427         disable_mcu_watchdog();
428
429         return 0;
430 }
431
432 int board_late_init(void)
433 {
434         set_regdomain();
435         handle_reset_button();
436         pci_init();
437
438         return 0;
439 }
440
441 static struct udevice *get_atsha204a_dev(void)
442 {
443         static struct udevice *dev;
444
445         if (dev)
446                 return dev;
447
448         if (uclass_get_device_by_name(UCLASS_MISC, "atsha204a@64", &dev)) {
449                 puts("Cannot find ATSHA204A on I2C bus!\n");
450                 dev = NULL;
451         }
452
453         return dev;
454 }
455
456 int checkboard(void)
457 {
458         u32 version_num, serial_num;
459         int err = 1;
460
461         struct udevice *dev = get_atsha204a_dev();
462
463         if (dev) {
464                 err = atsha204a_wakeup(dev);
465                 if (err)
466                         goto out;
467
468                 err = atsha204a_read(dev, ATSHA204A_ZONE_OTP, false,
469                                      OMNIA_ATSHA204_OTP_VERSION,
470                                      (u8 *)&version_num);
471                 if (err)
472                         goto out;
473
474                 err = atsha204a_read(dev, ATSHA204A_ZONE_OTP, false,
475                                      OMNIA_ATSHA204_OTP_SERIAL,
476                                      (u8 *)&serial_num);
477                 if (err)
478                         goto out;
479
480                 atsha204a_sleep(dev);
481         }
482
483 out:
484         printf("Turris Omnia:\n");
485         printf("  RAM size: %i MiB\n", omnia_get_ram_size_gb() * 1024);
486         if (err)
487                 printf("  Serial Number: unknown\n");
488         else
489                 printf("  Serial Number: %08X%08X\n", be32_to_cpu(version_num),
490                        be32_to_cpu(serial_num));
491
492         return 0;
493 }
494
495 static void increment_mac(u8 *mac)
496 {
497         int i;
498
499         for (i = 5; i >= 3; i--) {
500                 mac[i] += 1;
501                 if (mac[i])
502                         break;
503         }
504 }
505
506 int misc_init_r(void)
507 {
508         int err;
509         struct udevice *dev = get_atsha204a_dev();
510         u8 mac0[4], mac1[4], mac[6];
511
512         if (!dev)
513                 goto out;
514
515         err = atsha204a_wakeup(dev);
516         if (err)
517                 goto out;
518
519         err = atsha204a_read(dev, ATSHA204A_ZONE_OTP, false,
520                              OMNIA_ATSHA204_OTP_MAC0, mac0);
521         if (err)
522                 goto out;
523
524         err = atsha204a_read(dev, ATSHA204A_ZONE_OTP, false,
525                              OMNIA_ATSHA204_OTP_MAC1, mac1);
526         if (err)
527                 goto out;
528
529         atsha204a_sleep(dev);
530
531         mac[0] = mac0[1];
532         mac[1] = mac0[2];
533         mac[2] = mac0[3];
534         mac[3] = mac1[1];
535         mac[4] = mac1[2];
536         mac[5] = mac1[3];
537
538         if (is_valid_ethaddr(mac))
539                 eth_env_set_enetaddr("eth1addr", mac);
540
541         increment_mac(mac);
542
543         if (is_valid_ethaddr(mac))
544                 eth_env_set_enetaddr("eth2addr", mac);
545
546         increment_mac(mac);
547
548         if (is_valid_ethaddr(mac))
549                 eth_env_set_enetaddr("ethaddr", mac);
550
551 out:
552         return 0;
553 }
554
555 #if defined(CONFIG_OF_BOARD_SETUP)
556 /*
557  * I plan to generalize this function and move it to common/fdt_support.c.
558  * This will require some more work on multiple boards, though, so for now leave
559  * it here.
560  */
561 static bool fixup_mtd_partitions(void *blob, int offset, struct mtd_info *mtd)
562 {
563         struct mtd_info *slave;
564         int parts;
565
566         parts = fdt_subnode_offset(blob, offset, "partitions");
567         if (parts < 0)
568                 return false;
569
570         if (fdt_del_node(blob, parts) < 0)
571                 return false;
572
573         parts = fdt_add_subnode(blob, offset, "partitions");
574         if (parts < 0)
575                 return false;
576
577         if (fdt_setprop_u32(blob, parts, "#address-cells", 1) < 0)
578                 return false;
579
580         if (fdt_setprop_u32(blob, parts, "#size-cells", 1) < 0)
581                 return false;
582
583         if (fdt_setprop_string(blob, parts, "compatible",
584                                "fixed-partitions") < 0)
585                 return false;
586
587         mtd_probe_devices();
588
589         list_for_each_entry(slave, &mtd->partitions, node) {
590                 char name[32];
591                 int part;
592
593                 snprintf(name, sizeof(name), "partition@%llx", slave->offset);
594                 part = fdt_add_subnode(blob, parts, name);
595                 if (part < 0)
596                         return false;
597
598                 if (fdt_setprop_u32(blob, part, "reg", slave->offset) < 0)
599                         return false;
600
601                 if (fdt_appendprop_u32(blob, part, "reg", slave->size) < 0)
602                         return false;
603
604                 if (fdt_setprop_string(blob, part, "label", slave->name) < 0)
605                         return false;
606
607                 if (!(slave->flags & MTD_WRITEABLE))
608                         if (fdt_setprop_empty(blob, part, "read-only") < 0)
609                                 return false;
610
611                 if (slave->flags & MTD_POWERUP_LOCK)
612                         if (fdt_setprop_empty(blob, part, "lock") < 0)
613                                 return false;
614         }
615
616         return true;
617 }
618
619 int ft_board_setup(void *blob, struct bd_info *bd)
620 {
621         struct mtd_info *mtd;
622         int node;
623
624         mtd = get_mtd_device_nm(OMNIA_SPI_NOR_PATH);
625         if (IS_ERR_OR_NULL(mtd))
626                 goto fail;
627
628         node = fdt_path_offset(blob, OMNIA_SPI_NOR_PATH);
629         if (node < 0)
630                 goto fail;
631
632         if (!fixup_mtd_partitions(blob, node, mtd))
633                 goto fail;
634
635         return 0;
636
637 fail:
638         printf("Failed fixing SPI NOR partitions!\n");
639         return 0;
640 }
641 #endif