b2aa70feb66760834d55fdecf42b3ebd9017196f
[oweals/u-boot_mod.git] / u-boot / board / ar7240 / common / common.c
1 /*
2  * Common functions for QC/A WiSoCs support
3  * Copyright (C) 2016 Piotr Dymacz <piotr@dymacz.pl>
4  *
5  * SPDX-License-Identifier: GPL-2.0
6  */
7
8 #include <config.h>
9 #include <common.h>
10 #include <flash.h>
11 #include <asm/mipsregs.h>
12 #include <asm/addrspace.h>
13 #include <soc/qca_soc_common.h>
14
15 #ifndef CONFIG_BOARD_CUSTOM_STRING
16         #define CONFIG_BOARD_CUSTOM_STRING      "Unknown/OEM"
17 #endif
18
19 #define ALIGN_SIZE              "8"
20
21 DECLARE_GLOBAL_DATA_PTR;
22
23 static u32 mac_is_not_valid = 1;
24
25 /*
26  * Prints available information about the board
27  */
28 void print_board_info(void)
29 {
30         u32 ahb_clk, cpu_clk, ddr_clk, spi_clk, ref_clk;
31         u32 bank;
32         bd_t *bd = gd->bd;
33         char buffer[24];
34
35         /* Board name */
36         printf("%" ALIGN_SIZE "s %s\n", "BOARD:", CONFIG_BOARD_CUSTOM_STRING);
37
38         /* SOC name, version and revision */
39         qca_soc_name_rev(buffer);
40         printf("%" ALIGN_SIZE "s %s\n", "SOC:", buffer);
41
42         /* MIPS CPU type */
43         cpu_name(buffer);
44         printf("%" ALIGN_SIZE "s %s\n", "CPU:", buffer);
45
46         /* RAM size and type */
47         printf("%" ALIGN_SIZE "s ", "RAM:");
48         print_size(bd->bi_memsize, "");
49
50         switch (qca_mem_type()) {
51                 case QCA_RST_BOOTSTRAP_MEM_TYPE_SDR_VAL:
52                         puts(" SDR\n");
53                         break;
54                 case QCA_RST_BOOTSTRAP_MEM_TYPE_DDR1_VAL:
55                         puts(" DDR1\n");
56                         break;
57                 case QCA_RST_BOOTSTRAP_MEM_TYPE_DDR2_VAL:
58                         puts(" DDR2\n");
59                         break;
60                 default:
61                         puts("\n");
62                         break;
63         }
64
65         /* SPI NOR FLASH sizes and types */
66         printf("%" ALIGN_SIZE "s ", "FLASH:");
67
68         for (bank = 0; bank < CFG_MAX_FLASH_BANKS; bank++) {
69                 if (flash_info[bank].size == 0)
70                         continue;
71
72                 if (bank > 0)
73                         printf("%" ALIGN_SIZE "s ", " ");
74
75                 print_size(flash_info[bank].size, "");
76
77                 if (flash_info[bank].manuf_name != NULL)
78                         printf(" %s", flash_info[bank].manuf_name);
79
80                 if (flash_info[bank].model_name != NULL)
81                         printf(" %s", flash_info[bank].model_name);
82
83                 puts("\n");
84         }
85
86         /* MAC address */
87         printf("%" ALIGN_SIZE "s %02X:%02X:%02X:%02X:%02X:%02X", "MAC:",
88                 bd->bi_enetaddr[0],bd->bi_enetaddr[1], bd->bi_enetaddr[2],
89                 bd->bi_enetaddr[3], bd->bi_enetaddr[4], bd->bi_enetaddr[5]);
90
91         if (mac_is_not_valid) {
92                 puts(" (fixed)\n");
93         } else {
94                 puts("\n");
95         }
96
97         /* System clocks */
98         printf("%" ALIGN_SIZE "s CPU/RAM/AHB/SPI/REF\n", "CLOCKS:");
99
100         qca_sys_clocks(&cpu_clk, &ddr_clk, &ahb_clk, &spi_clk, &ref_clk);
101         cpu_clk = cpu_clk / 1000000;
102         ddr_clk = ddr_clk / 1000000;
103         ahb_clk = ahb_clk / 1000000;
104         spi_clk = spi_clk / 1000000;
105         ref_clk = ref_clk / 1000000;
106
107         printf("%" ALIGN_SIZE "s %3d/%3d/%3d/%3d/%3d MHz\n",
108                 " ", cpu_clk, ddr_clk, ahb_clk, spi_clk, ref_clk);
109
110         puts("\n");
111 }
112
113 /*
114  * Reads MAC address if available or uses fixed one
115  */
116 void macaddr_init(u8 *mac_addr)
117 {
118         u8 buffer[6];
119         u8 fixed_mac[6] = {0x00, 0x03, 0x7F, 0x09, 0x0B, 0xAD};
120
121 #if defined(OFFSET_MAC_ADDRESS)
122         memcpy(buffer, (void *)(CFG_FLASH_BASE
123                 + OFFSET_MAC_DATA_BLOCK + OFFSET_MAC_ADDRESS), 6);
124
125         /*
126          * Check first LSBit (I/G bit) and second LSBit (U/L bit) in MSByte of vendor part
127          * both of them should be 0:
128          * I/G bit == 0 -> Individual MAC address (unicast address)
129          * U/L bit == 0 -> Burned-In-Address (BIA) MAC address
130          */
131         if (CHECK_BIT((buffer[0] & 0xFF), 0) != 0 ||
132                 CHECK_BIT((buffer[0] & 0xFF), 1) != 0) {
133                 memcpy(buffer, fixed_mac, 6);
134         } else {
135                 mac_is_not_valid = 0;
136         }
137 #else
138         memcpy(buffer, fixed_mac, 6);
139 #endif
140
141         memcpy(mac_addr, buffer, 6);
142 }
143
144 /*
145  * Returns "reset button" status:
146  * 1 -> button is pressed
147  * 0 -> button is not pressed
148  */
149 int reset_button_status(void)
150 {
151 #ifdef CONFIG_GPIO_RESET_BTN
152         u32 gpio;
153
154         gpio = qca_soc_reg_read(QCA_GPIO_IN_REG);
155
156         if (gpio & (1 << CONFIG_GPIO_RESET_BTN)) {
157         #if defined(CONFIG_GPIO_RESET_BTN_ACTIVE_LOW)
158                 return 0;
159         #else
160                 return 1;
161         #endif
162         } else {
163         #if defined(CONFIG_GPIO_RESET_BTN_ACTIVE_LOW)
164                 return 1;
165         #else
166                 return 0;
167         #endif
168         }
169 #else
170         return 0;
171 #endif
172 }
173
174 /*
175  * Returns main CPU clock in Hz
176  */
177 u32 main_cpu_clk(void)
178 {
179         u32 cpu_clk;
180
181         qca_sys_clocks(&cpu_clk, NULL, NULL, NULL, NULL);
182
183         return cpu_clk;
184 }
185
186 /*
187  * Calls full chip reset
188  */
189 void full_reset(void)
190 {
191         qca_full_chip_reset();
192 }