Add more information about DDR timing values and print them in board info
[oweals/u-boot_mod.git] / u-boot / board / ar7240 / common / common.c
1 /*
2  * Common functions for QC/A WiSoCs based boards support
3  *
4  * Copyright (C) 2016 Piotr Dymacz <piotr@dymacz.pl>
5  *
6  * Partially based on:
7  * Linux/arch/mips/ath79/setup.c
8  *
9  * SPDX-License-Identifier: GPL-2.0
10  */
11
12 #include <config.h>
13 #include <common.h>
14 #include <flash.h>
15 #include <asm/mipsregs.h>
16 #include <asm/addrspace.h>
17 #include <soc/qca_soc_common.h>
18
19 #ifndef CONFIG_BOARD_CUSTOM_STRING
20         #define CONFIG_BOARD_CUSTOM_STRING      "Unknown/OEM"
21 #endif
22
23 #define ALIGN_SIZE              "8"
24
25 DECLARE_GLOBAL_DATA_PTR;
26
27 static u32 mac_is_not_valid = 1;
28
29 /*
30  * Put QCA SOC name, version and revision in buffer
31  */
32 void qca_soc_name_rev(char *buf)
33 {
34         u32 id;
35         u32 major;
36         u32 rev = 0;
37
38         if (buf == NULL)
39                 return;
40
41         /* Get revision ID value */
42         id = qca_soc_reg_read(QCA_RST_REVISION_ID_REG);
43
44         major = id & QCA_RST_REVISION_ID_MAJOR_MASK;
45         rev = id & QCA_RST_REVISION_ID_REV_MASK;
46
47         switch (major) {
48 #if (SOC_TYPE & QCA_AR933X_SOC)
49         case QCA_RST_REVISION_ID_MAJOR_AR9330_VAL:
50                 sprintf(buf, "AR9330 rev. %d", rev);
51                 break;
52         case QCA_RST_REVISION_ID_MAJOR_AR9331_VAL:
53                 sprintf(buf, "AR9331 rev. %d", rev);
54                 break;
55 #endif
56 #if (SOC_TYPE & QCA_AR934X_SOC)
57         case QCA_RST_REVISION_ID_MAJOR_AR9341_VAL:
58                 sprintf(buf, "AR9341 rev. %d", rev);
59                 break;
60         case QCA_RST_REVISION_ID_MAJOR_AR9344_VAL:
61                 sprintf(buf, "AR9344 rev. %d", rev);
62                 break;
63 #endif
64 #if (SOC_TYPE & QCA_QCA953X_SOC)
65         case QCA_RST_REVISION_ID_MAJOR_QCA953X_VAL:
66                 sprintf(buf, "QCA953x ver. 1 rev. %d", rev);
67                 break;
68         case QCA_RST_REVISION_ID_MAJOR_QCA953X_V2_VAL:
69                 sprintf(buf, "QCA953x ver. 2 rev. %d", rev);
70                 break;
71 #endif
72 #if (SOC_TYPE & QCA_QCA955X_SOC)
73         case QCA_RST_REVISION_ID_MAJOR_QCA9558_VAL:
74                 sprintf(buf, "QCA9558 rev. %d", rev);
75                 break;
76 #endif
77         default:
78                 sprintf(buf, "Unknown");
79                 break;
80         }
81 }
82
83 /*
84  * Prints available information about the board
85  */
86 void print_board_info(void)
87 {
88         u32 ahb_clk, cpu_clk, ddr_clk, spi_clk, ref_clk;
89         u32 bank;
90         bd_t *bd = gd->bd;
91         char buffer[24];
92
93         /* Board name */
94         printf("%" ALIGN_SIZE "s %s\n", "BOARD:", CONFIG_BOARD_CUSTOM_STRING);
95
96         /* SOC name, version and revision */
97         qca_soc_name_rev(buffer);
98         printf("%" ALIGN_SIZE "s %s\n", "SOC:", buffer);
99
100         /* MIPS CPU type */
101         cpu_name(buffer);
102         printf("%" ALIGN_SIZE "s %s\n", "CPU:", buffer);
103
104         /* RAM size and type */
105         printf("%" ALIGN_SIZE "s ", "RAM:");
106         print_size(bd->bi_memsize, "");
107
108         switch (qca_dram_type()) {
109         case RAM_MEMORY_TYPE_SDR:
110                 puts(" SDR ");
111                 break;
112         case RAM_MEMORY_TYPE_DDR1:
113                 puts(" DDR1 ");
114                 break;
115         case RAM_MEMORY_TYPE_DDR2:
116                 puts(" DDR2 ");
117                 break;
118         default:
119                 break;
120         }
121
122         /* DDR interface width */
123         printf("%d-bit ", qca_dram_ddr_width());
124
125         /* tCL-tRCD-tRP-tRAS latency */
126         printf("CL%d-%d-%d-%d\n", qca_dram_cas_lat(),
127                                                           qca_dram_trcd_lat(),
128                                                           qca_dram_trp_lat(),
129                                                           qca_dram_tras_lat());
130
131         /* SPI NOR FLASH sizes and types */
132         printf("%" ALIGN_SIZE "s ", "FLASH:");
133
134         for (bank = 0; bank < CFG_MAX_FLASH_BANKS; bank++) {
135                 if (flash_info[bank].size == 0)
136                         continue;
137
138                 if (bank > 0)
139                         printf("%" ALIGN_SIZE "s ", " ");
140
141                 print_size(flash_info[bank].size, "");
142
143                 if (flash_info[bank].manuf_name != NULL)
144                         printf(" %s", flash_info[bank].manuf_name);
145
146                 if (flash_info[bank].model_name != NULL)
147                         printf(" %s", flash_info[bank].model_name);
148
149                 puts("\n");
150         }
151
152         /* MAC address */
153         printf("%" ALIGN_SIZE "s %02X:%02X:%02X:%02X:%02X:%02X", "MAC:",
154                 bd->bi_enetaddr[0],bd->bi_enetaddr[1], bd->bi_enetaddr[2],
155                 bd->bi_enetaddr[3], bd->bi_enetaddr[4], bd->bi_enetaddr[5]);
156
157         if (mac_is_not_valid) {
158                 puts(" (fixed)\n");
159         } else {
160                 puts("\n");
161         }
162
163         /* System clocks */
164         printf("%" ALIGN_SIZE "s CPU/RAM/AHB/SPI/REF\n", "CLOCKS:");
165
166         qca_sys_clocks(&cpu_clk, &ddr_clk, &ahb_clk, &spi_clk, &ref_clk);
167         cpu_clk = cpu_clk / 1000000;
168         ddr_clk = ddr_clk / 1000000;
169         ahb_clk = ahb_clk / 1000000;
170         spi_clk = spi_clk / 1000000;
171         ref_clk = ref_clk / 1000000;
172
173         printf("%" ALIGN_SIZE "s %3d/%3d/%3d/%3d/%3d MHz\n",
174                 " ", cpu_clk, ddr_clk, ahb_clk, spi_clk, ref_clk);
175
176         puts("\n");
177 }
178
179 /*
180  * Reads MAC address if available or uses fixed one
181  */
182 void macaddr_init(u8 *mac_addr)
183 {
184         u8 buffer[6];
185         u8 fixed_mac[6] = {0x00, 0x03, 0x7F, 0x09, 0x0B, 0xAD};
186
187 #if defined(OFFSET_MAC_ADDRESS)
188         memcpy(buffer, (void *)(CFG_FLASH_BASE
189                 + OFFSET_MAC_DATA_BLOCK + OFFSET_MAC_ADDRESS), 6);
190
191         /*
192          * Check first LSBit (I/G bit) and second LSBit (U/L bit) in MSByte of vendor part
193          * both of them should be 0:
194          * I/G bit == 0 -> Individual MAC address (unicast address)
195          * U/L bit == 0 -> Burned-In-Address (BIA) MAC address
196          */
197         if (CHECK_BIT((buffer[0] & 0xFF), 0) != 0 ||
198                 CHECK_BIT((buffer[0] & 0xFF), 1) != 0) {
199                 memcpy(buffer, fixed_mac, 6);
200         } else {
201                 mac_is_not_valid = 0;
202         }
203 #else
204         memcpy(buffer, fixed_mac, 6);
205 #endif
206
207         memcpy(mac_addr, buffer, 6);
208 }
209
210 /*
211  * Returns "reset button" status:
212  * 1 -> button is pressed
213  * 0 -> button is not pressed
214  */
215 int reset_button_status(void)
216 {
217 #ifdef CONFIG_GPIO_RESET_BTN
218         u32 gpio;
219
220         gpio = qca_soc_reg_read(QCA_GPIO_IN_REG);
221
222         if (gpio & (1 << CONFIG_GPIO_RESET_BTN)) {
223         #if defined(CONFIG_GPIO_RESET_BTN_ACTIVE_LOW)
224                 return 0;
225         #else
226                 return 1;
227         #endif
228         } else {
229         #if defined(CONFIG_GPIO_RESET_BTN_ACTIVE_LOW)
230                 return 1;
231         #else
232                 return 0;
233         #endif
234         }
235 #else
236         return 0;
237 #endif
238 }
239
240 /*
241  * Returns main CPU clock in Hz
242  */
243 u32 main_cpu_clk(void)
244 {
245         u32 cpu_clk;
246
247         qca_sys_clocks(&cpu_clk, NULL, NULL, NULL, NULL);
248
249         return cpu_clk;
250 }
251
252 /*
253  * Calls full chip reset
254  */
255 void full_reset(void)
256 {
257         qca_full_chip_reset();
258 }