"Das U-Boot" Source Tree
at master 255 lines 5.3 kB view raw
1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * Copyright (C) 2010-2020 CS Group 4 * Charles Frey <charles.frey@c-s.fr> 5 * Florent Trinh Thai <florent.trinh-thai@c-s.fr> 6 * Christophe Leroy <christophe.leroy@c-s.fr> 7 * 8 * Common specific routines for the CS Group boards 9 */ 10 11#include <dm.h> 12#include <env.h> 13#include <fdt_support.h> 14#include <hang.h> 15#include <spi.h> 16#include <linux/delay.h> 17#include <asm/io.h> 18 19#include "common.h" 20 21#define ADDR_FPGA_R_BASE ((unsigned char __iomem *)CONFIG_FPGA_BASE) 22 23#define FPGA_R_ACQ_AL_FAV 0x04 24 25#define TYPE_MCR 0x22 26#define TYPE_MIAE 0x23 27 28#define FAR_CASRSA 2 29#define FAR_VGOIP 4 30#define FAV_CLA 7 31#define FAV_SRSA 8 32 33#define SPI_EEPROM_READ 0x03 34 35static int fdt_set_node_and_value(void *blob, char *node, const char *prop, 36 void *var, int size) 37{ 38 int ret, off; 39 40 off = fdt_path_offset(blob, node); 41 42 if (off < 0) { 43 printf("Cannot find %s node err:%s\n", node, fdt_strerror(off)); 44 45 return off; 46 } 47 48 ret = fdt_setprop(blob, off, prop, var, size); 49 50 if (ret < 0) 51 printf("Cannot set %s/%s prop err: %s\n", node, prop, fdt_strerror(ret)); 52 53 return ret; 54} 55 56/* Checks front/rear id and remove unneeded nodes from the blob */ 57static void ft_cleanup(void *blob, unsigned long id, const char *prop, const char *compatible) 58{ 59 int off; 60 61 off = fdt_node_offset_by_compatible(blob, -1, compatible); 62 63 while (off != -FDT_ERR_NOTFOUND) { 64 const struct fdt_property *ids; 65 int nb_ids, idx; 66 int tmp = -1; 67 68 ids = fdt_get_property(blob, off, prop, &nb_ids); 69 70 for (idx = 0; idx < nb_ids; idx += 4) { 71 if (*((uint32_t *)&ids->data[idx]) == id) 72 break; 73 } 74 75 if (idx >= nb_ids) 76 fdt_del_node(blob, off); 77 else 78 tmp = off; 79 80 off = fdt_node_offset_by_compatible(blob, tmp, compatible); 81 } 82 83 fdt_set_node_and_value(blob, "/", prop, &id, sizeof(uint32_t)); 84} 85 86int read_eeprom(u8 *din, int len) 87{ 88 struct udevice *eeprom; 89 struct spi_slave *slave; 90 uchar dout[3] = {SPI_EEPROM_READ, 0, 0}; 91 int ret; 92 93 ret = uclass_get_device(UCLASS_SPI, 0, &eeprom); 94 if (ret) 95 return ret; 96 97 ret = _spi_get_bus_and_cs(0, 0, 1000000, 0, "spi_generic_drv", 98 "generic_0:0", &eeprom, &slave); 99 if (ret) 100 return ret; 101 102 ret = spi_claim_bus(slave); 103 104 ret = spi_xfer(slave, sizeof(dout) << 3, dout, NULL, SPI_XFER_BEGIN); 105 if (ret) 106 return ret; 107 108 ret = spi_xfer(slave, len << 3, NULL, din, SPI_XFER_END); 109 if (ret) 110 return ret; 111 112 spi_release_bus(slave); 113 114 return 0; 115} 116 117int ft_board_setup_common(void *blob) 118{ 119 u8 far_id, fav_id; 120 121 if (in_8(ADDR_FPGA_R_BASE) != TYPE_MIAE) 122 return 0; 123 124 far_id = in_8(ADDR_FPGA_R_BASE + 0x43) >> 5; 125 ft_cleanup(blob, far_id, "far-id", "cs,mia-far"); 126 127 fav_id = in_8(ADDR_FPGA_R_BASE + 0x44) >> 5; 128 129 if (far_id == FAR_CASRSA && fav_id == FAV_CLA) 130 fav_id = FAV_SRSA; 131 132 ft_cleanup(blob, fav_id, "fav-id", "cs,mia-fav"); 133 134 if (far_id == FAR_CASRSA) 135 ft_board_setup_phy3(); 136 137 return 0; 138} 139 140int checkboard_common(void) 141{ 142 switch (in_8(ADDR_FPGA_R_BASE)) { 143 int far_id; 144 case TYPE_MCR: 145 printf("MCR3000_2G (CS GROUP)\n"); 146 break; 147 case TYPE_MIAE: 148 far_id = in_8(ADDR_FPGA_R_BASE + 0x43) >> 5; 149 150 if (far_id == FAR_VGOIP) 151 printf("VGoIP (CS GROUP)\n"); 152 else 153 printf("MIAE (CS GROUP)\n"); 154 155 break; 156 default: 157 printf("Unknown\n"); 158 for (;;) 159 ; 160 break; 161 } 162 return 0; 163} 164 165void misc_init_r_common(void) 166{ 167 u8 tmp, far_id, addr; 168 int count = 3; 169 170 switch (in_8(ADDR_FPGA_R_BASE)) { 171 case TYPE_MCR: 172 /* if at boot alarm button is pressed, delay boot */ 173 if ((in_8(ADDR_FPGA_R_BASE + 0x31) & FPGA_R_ACQ_AL_FAV) == 0) 174 env_set("bootdelay", "60"); 175 176 addr = in_8(ADDR_FPGA_R_BASE + 0x43); 177 printf("Board address: 0x%2.2x (System %d Rack %d Slot %d)\n", 178 addr, addr >> 7, (addr >> 4) & 7, addr & 15); 179 180 env_set("config", CFG_BOARD_MCR3000_2G); 181 env_set("hostname", CFG_BOARD_MCR3000_2G); 182 break; 183 184 case TYPE_MIAE: 185 do { 186 tmp = in_8(ADDR_FPGA_R_BASE + 0x41); 187 count--; 188 mdelay(10); /* 10msec wait */ 189 } while (count && tmp != in_8(ADDR_FPGA_R_BASE + 0x41)); 190 191 if (!count) { 192 printf("Cannot read the reset factory switch position\n"); 193 hang(); 194 } 195 196 if (tmp & 0x1) 197 env_set_default("Factory settings switch ON", 0); 198 199 env_set("config", CFG_BOARD_MIAE); 200 far_id = in_8(ADDR_FPGA_R_BASE + 0x43) >> 5; 201 202 if (far_id == FAR_VGOIP) 203 env_set("hostname", CFG_BOARD_VGOIP); 204 else 205 env_set("hostname", CFG_BOARD_MIAE); 206 break; 207 208 default: 209 env_set("config", CFG_BOARD_CMPCXXX); 210 env_set("hostname", CFG_BOARD_CMPCXXX); 211 break; 212 } 213} 214 215static void iop_setup_fpgam_common(void) 216{ 217 u8 far_id = in_8(ADDR_FPGA_R_BASE + 0x43) >> 5; 218 219 if (far_id == FAR_CASRSA) { 220 /* 221 * PFDIR[15] = 0 [0x01] 222 * PFDIR[14] = 1 [0x02] 223 * PFDIR[13] = 1 [0x04] 224 */ 225 clrsetbits_8(ADDR_FPGA_R_BASE + 0x37, 0x01, 0x06); 226 /* 227 * PFODR[15] = 1 [0x01] 228 * PFODR[14] = 0 [0x02] 229 * PFODR[13] = 0 [0x04] 230 */ 231 clrsetbits_8(ADDR_FPGA_R_BASE + 0x39, 0x06, 0x01); 232 /* 233 * PFDAT[15] = 0 [0x01] 234 * PFDAT[14] = 1 [0x02] 235 * PFDAT[13] = 1 [0x04] 236 * PFDAT[12] = 1 [0x08] 237 */ 238 clrsetbits_8(ADDR_FPGA_R_BASE + 0x3B, 0x01, 0x0E); 239 240 /* Setup TOR_OUT */ 241 out_8(ADDR_FPGA_R_BASE + 0x32, 0x2A); 242 } 243} 244 245void iop_setup_common(void) 246{ 247 u8 type = in_8(ADDR_FPGA_R_BASE); 248 249 if (type == TYPE_MCR) { 250 iop_setup_mcr(); 251 } else if (type == TYPE_MIAE) { 252 iop_setup_miae(); 253 iop_setup_fpgam_common(); 254 } 255}