1 /* 2 * (C) Copyright 2012 3 * Valentin Lontgchamp, Keymile AG, valentin.longchamp@keymile.com 4 * 5 * SPDX-License-Identifier: GPL-2.0+ 6 */ 7 8 #include <common.h> 9 #include <i2c.h> 10 #include <linux/errno.h> 11 12 /* GPIO Pin from kirkwood connected to PROGRAM_B pin of the xilinx FPGA */ 13 #define KM_XLX_PROGRAM_B_PIN 39 14 15 #define BOCO_ADDR 0x10 16 17 #define ID_REG 0x00 18 #define BOCO2_ID 0x5b 19 20 static int check_boco2(void) 21 { 22 int ret; 23 u8 id; 24 25 ret = i2c_read(BOCO_ADDR, ID_REG, 1, &id, 1); 26 if (ret) { 27 printf("%s: error reading the BOCO id !!\n", __func__); 28 return ret; 29 } 30 31 return (id == BOCO2_ID); 32 } 33 34 static int boco_clear_bits(u8 reg, u8 flags) 35 { 36 int ret; 37 u8 regval; 38 39 /* give access to the EEPROM from FPGA */ 40 ret = i2c_read(BOCO_ADDR, reg, 1, ®val, 1); 41 if (ret) { 42 printf("%s: error reading the BOCO @%#x !!\n", 43 __func__, reg); 44 return ret; 45 } 46 regval &= ~flags; 47 ret = i2c_write(BOCO_ADDR, reg, 1, ®val, 1); 48 if (ret) { 49 printf("%s: error writing the BOCO @%#x !!\n", 50 __func__, reg); 51 return ret; 52 } 53 54 return 0; 55 } 56 57 static int boco_set_bits(u8 reg, u8 flags) 58 { 59 int ret; 60 u8 regval; 61 62 /* give access to the EEPROM from FPGA */ 63 ret = i2c_read(BOCO_ADDR, reg, 1, ®val, 1); 64 if (ret) { 65 printf("%s: error reading the BOCO @%#x !!\n", 66 __func__, reg); 67 return ret; 68 } 69 regval |= flags; 70 ret = i2c_write(BOCO_ADDR, reg, 1, ®val, 1); 71 if (ret) { 72 printf("%s: error writing the BOCO @%#x !!\n", 73 __func__, reg); 74 return ret; 75 } 76 77 return 0; 78 } 79 80 #define SPI_REG 0x06 81 #define CFG_EEPROM 0x02 82 #define FPGA_PROG 0x04 83 #define FPGA_INIT_B 0x10 84 #define FPGA_DONE 0x20 85 86 static int fpga_done(void) 87 { 88 int ret = 0; 89 u8 regval; 90 91 /* this is only supported with the boco2 design */ 92 if (!check_boco2()) 93 return 0; 94 95 ret = i2c_read(BOCO_ADDR, SPI_REG, 1, ®val, 1); 96 if (ret) { 97 printf("%s: error reading the BOCO @%#x !!\n", 98 __func__, SPI_REG); 99 return 0; 100 } 101 102 return regval & FPGA_DONE ? 1 : 0; 103 } 104 105 int skip; 106 107 int trigger_fpga_config(void) 108 { 109 int ret = 0; 110 111 /* if the FPGA is already configured, we do not want to 112 * reconfigure it */ 113 skip = 0; 114 if (fpga_done()) { 115 printf("PCIe FPGA config: skipped\n"); 116 skip = 1; 117 return 0; 118 } 119 120 if (check_boco2()) { 121 /* we have a BOCO2, this has to be triggered here */ 122 123 /* make sure the FPGA_can access the EEPROM */ 124 ret = boco_clear_bits(SPI_REG, CFG_EEPROM); 125 if (ret) 126 return ret; 127 128 /* trigger the config start */ 129 ret = boco_clear_bits(SPI_REG, FPGA_PROG | FPGA_INIT_B); 130 if (ret) 131 return ret; 132 133 /* small delay for the pulse */ 134 udelay(10); 135 136 /* up signal for pulse end */ 137 ret = boco_set_bits(SPI_REG, FPGA_PROG); 138 if (ret) 139 return ret; 140 141 /* finally, raise INIT_B to remove the config delay */ 142 ret = boco_set_bits(SPI_REG, FPGA_INIT_B); 143 if (ret) 144 return ret; 145 146 } else { 147 /* we do it the old way, with the gpio pin */ 148 kw_gpio_set_valid(KM_XLX_PROGRAM_B_PIN, 1); 149 kw_gpio_direction_output(KM_XLX_PROGRAM_B_PIN, 0); 150 /* small delay for the pulse */ 151 udelay(10); 152 kw_gpio_direction_input(KM_XLX_PROGRAM_B_PIN); 153 } 154 155 return 0; 156 } 157 158 int wait_for_fpga_config(void) 159 { 160 int ret = 0; 161 u8 spictrl; 162 u32 timeout = 20000; 163 164 if (skip) 165 return 0; 166 167 if (!check_boco2()) { 168 /* we do not have BOCO2, this is not really used */ 169 return 0; 170 } 171 172 printf("PCIe FPGA config:"); 173 do { 174 ret = i2c_read(BOCO_ADDR, SPI_REG, 1, &spictrl, 1); 175 if (ret) { 176 printf("%s: error reading the BOCO spictrl !!\n", 177 __func__); 178 return ret; 179 } 180 if (timeout-- == 0) { 181 printf(" FPGA_DONE timeout\n"); 182 return -EFAULT; 183 } 184 udelay(10); 185 } while (!(spictrl & FPGA_DONE)); 186 187 printf(" done\n"); 188 189 return 0; 190 } 191 192 #if defined(KM_PCIE_RESET_MPP7) 193 194 #define KM_PEX_RST_GPIO_PIN 7 195 int fpga_reset(void) 196 { 197 if (!check_boco2()) { 198 /* we do not have BOCO2, this is not really used */ 199 return 0; 200 } 201 202 printf("PCIe reset through GPIO7: "); 203 /* apply PCIe reset via GPIO */ 204 kw_gpio_set_valid(KM_PEX_RST_GPIO_PIN, 1); 205 kw_gpio_direction_output(KM_PEX_RST_GPIO_PIN, 1); 206 kw_gpio_set_value(KM_PEX_RST_GPIO_PIN, 0); 207 udelay(1000*10); 208 kw_gpio_set_value(KM_PEX_RST_GPIO_PIN, 1); 209 210 printf(" done\n"); 211 212 return 0; 213 } 214 215 #else 216 217 #define PRST1 0x4 218 #define PCIE_RST 0x10 219 #define TRAFFIC_RST 0x04 220 221 int fpga_reset(void) 222 { 223 int ret = 0; 224 u8 resets; 225 226 if (!check_boco2()) { 227 /* we do not have BOCO2, this is not really used */ 228 return 0; 229 } 230 231 /* if we have skipped, we only want to reset the PCIe part */ 232 resets = skip ? PCIE_RST : PCIE_RST | TRAFFIC_RST; 233 234 ret = boco_clear_bits(PRST1, resets); 235 if (ret) 236 return ret; 237 238 /* small delay for the pulse */ 239 udelay(10); 240 241 ret = boco_set_bits(PRST1, resets); 242 if (ret) 243 return ret; 244 245 return 0; 246 } 247 #endif 248 249 /* the FPGA was configured, we configure the BOCO2 so that the EEPROM 250 * is available from the Bobcat SPI bus */ 251 int toggle_eeprom_spi_bus(void) 252 { 253 int ret = 0; 254 255 if (!check_boco2()) { 256 /* we do not have BOCO2, this is not really used */ 257 return 0; 258 } 259 260 ret = boco_set_bits(SPI_REG, CFG_EEPROM); 261 if (ret) 262 return ret; 263 264 return 0; 265 } 266