blob: 0e34409067a30c20a000e6855471ab2676682c89 [file] [log] [blame]
Padmarao Begari4216f342019-05-28 15:47:51 +05301// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Copyright (C) 2019 Microchip Technology Inc.
4 * Padmarao Begari <padmarao.begari@microchip.com>
5 */
6
7#include <common.h>
8#include <dm.h>
Padmarao Begari68eccfa2021-01-15 08:20:40 +05309#include <env.h>
Simon Glass97589732020-05-10 11:40:02 -060010#include <init.h>
Padmarao Begari4216f342019-05-28 15:47:51 +053011#include <asm/io.h>
12
Padmarao Begari68eccfa2021-01-15 08:20:40 +053013DECLARE_GLOBAL_DATA_PTR;
14
15#define MPFS_SYSREG_SOFT_RESET ((unsigned int *)0x20002088)
16#define MPFS_SYS_SERVICE_CR ((unsigned int *)0x37020050)
17#define MPFS_SYS_SERVICE_SR ((unsigned int *)0x37020054)
18#define MPFS_SYS_SERVICE_MAILBOX ((unsigned char *)0x37020800)
19
20#define PERIPH_RESET_VALUE 0x1e8u
21#define SERVICE_CR_REQ 0x1u
22#define SERVICE_SR_BUSY 0x2u
23
24static void read_device_serial_number(u8 *response, u8 response_size)
25{
26 u8 idx;
27 u8 *response_buf;
28 unsigned int val;
29
30 response_buf = (u8 *)response;
31
32 writel(SERVICE_CR_REQ, MPFS_SYS_SERVICE_CR);
33 /*
34 * REQ bit will remain set till the system controller starts
35 * processing.
36 */
37 do {
38 val = readl(MPFS_SYS_SERVICE_CR);
39 } while (SERVICE_CR_REQ == (val & SERVICE_CR_REQ));
40
41 /*
42 * Once system controller starts processing the busy bit will
43 * go high and service is completed when busy bit is gone low
44 */
45 do {
46 val = readl(MPFS_SYS_SERVICE_SR);
47 } while (SERVICE_SR_BUSY == (val & SERVICE_SR_BUSY));
48
49 for (idx = 0; idx < response_size; idx++)
50 response_buf[idx] = readb(MPFS_SYS_SERVICE_MAILBOX + idx);
51}
Padmarao Begari4216f342019-05-28 15:47:51 +053052
53int board_init(void)
54{
55 /* For now nothing to do here. */
56
57 return 0;
58}
59
60int board_early_init_f(void)
61{
62 unsigned int val;
63
Padmarao Begari68eccfa2021-01-15 08:20:40 +053064 /* Reset uart, mmc peripheral */
Padmarao Begari4216f342019-05-28 15:47:51 +053065 val = readl(MPFS_SYSREG_SOFT_RESET);
Padmarao Begari68eccfa2021-01-15 08:20:40 +053066 val = (val & ~(PERIPH_RESET_VALUE));
Padmarao Begari4216f342019-05-28 15:47:51 +053067 writel(val, MPFS_SYSREG_SOFT_RESET);
68
69 return 0;
70}
Padmarao Begari68eccfa2021-01-15 08:20:40 +053071
72int board_late_init(void)
73{
74 u32 ret;
75 u32 node;
76 u8 idx;
77 u8 device_serial_number[16] = { 0 };
78 unsigned char mac_addr[6];
79 char icicle_mac_addr[20];
80 void *blob = (void *)gd->fdt_blob;
81
82 node = fdt_path_offset(blob, "ethernet0");
83 if (node < 0) {
84 printf("No ethernet0 path offset\n");
85 return -ENODEV;
86 }
87
88 ret = fdtdec_get_byte_array(blob, node, "local-mac-address", mac_addr, 6);
89 if (ret) {
90 printf("No local-mac-address property\n");
91 return -EINVAL;
92 }
93
94 read_device_serial_number(device_serial_number, 16);
95
96 /* Update MAC address with device serial number */
97 mac_addr[0] = 0x00;
98 mac_addr[1] = 0x04;
99 mac_addr[2] = 0xA3;
100 mac_addr[3] = device_serial_number[2];
101 mac_addr[4] = device_serial_number[1];
102 mac_addr[5] = device_serial_number[0];
103
104 ret = fdt_setprop(blob, node, "local-mac-address", mac_addr, 6);
105 if (ret) {
106 printf("Error setting local-mac-address property\n");
107 return -ENODEV;
108 }
109
110 icicle_mac_addr[0] = '[';
111
112 sprintf(&icicle_mac_addr[1], "%pM", mac_addr);
113
114 icicle_mac_addr[18] = ']';
115 icicle_mac_addr[19] = '\0';
116
117 for (idx = 0; idx < 20; idx++) {
118 if (icicle_mac_addr[idx] == ':')
119 icicle_mac_addr[idx] = ' ';
120 }
121 env_set("icicle_mac_addr", icicle_mac_addr);
122
123 return 0;
124}