Commit 14b9f16c401206097c361ae4198c6b2ece805964

Authored by Heiko Schocher
Committed by Albert ARIBAUD
1 parent 2ab2810375

arm,davinci: update for enbw_cmc board

- change gpio pin settings:

  - gpio pin 6[13] (PLC reset) default value low
  - gpio pin 6[0] (TPM reset) default value low
  - 4 new GPIO pins
      pin  i/o   name
    - 3[9] input Board Type
    - 2[7] input HW-ID0
    - 2[6] input HW-ID1
    - 2[3] input HW-ID2

- read board type and hw id from gpio pins on the enbw_cmc board,
  and use board type for setting up different gpio pin settings.

- do not pass "davinci_mmc.use_dma=0" to linux, as MMC now
  works with DMA.

- update logbuf support:
  store post word in RTC scratch register

- add support for configuring KSZ8864RMN switch through
  a config file on u-boot startup. For more infos see:
  doc/README.switch_config

Signed-off-by: Heiko Schocher <hs@denx.de>
Cc: Wolfgang Denk <wd@denx.de>
Cc: Tom Rini <tom.rini@gmail.com>
Cc: Christian Riesch <christian.riesch@omicron.at>
Cc: Sandeep Paulraj <s-paulraj@ti.com>

Showing 3 changed files with 364 additions and 28 deletions Side-by-side Diff

board/enbw/enbw_cmc/enbw_cmc.c
... ... @@ -35,6 +35,8 @@
35 35 #include <mmc.h>
36 36 #include <net.h>
37 37 #include <netdev.h>
  38 +#include <spi.h>
  39 +#include <linux/ctype.h>
38 40 #include <asm/gpio.h>
39 41 #include <asm/io.h>
40 42 #include <asm/arch/da850_lowlevel.h>
41 43  
42 44  
... ... @@ -86,16 +88,22 @@
86 88 { pinmux(5), 1, 0 },
87 89 { pinmux(5), 1, 3 },
88 90 { pinmux(5), 1, 7 },
89   - { pinmux(6), 1, 0 },
90   - { pinmux(6), 1, 1 },
  91 + { pinmux(5), 1, 5 },
  92 + { pinmux(5), 1, 4 },
  93 + { pinmux(5), 1, 3 },
  94 + { pinmux(5), 1, 2 },
  95 + { pinmux(5), 1, 1 },
  96 + { pinmux(5), 1, 0 },
  97 + { pinmux(6), 8, 0 },
  98 + { pinmux(6), 8, 1 },
91 99 { pinmux(6), 8, 2 },
92 100 { pinmux(6), 8, 3 },
93   - { pinmux(6), 1, 4 },
  101 + { pinmux(6), 8, 4 },
94 102 { pinmux(6), 8, 5 },
95 103 { pinmux(6), 1, 7 },
96 104 { pinmux(7), 8, 2 },
97 105 { pinmux(7), 1, 3 },
98   - { pinmux(7), 1, 6 },
  106 + { pinmux(7), 8, 6 },
99 107 { pinmux(7), 1, 7 },
100 108 { pinmux(13), 8, 2 },
101 109 { pinmux(13), 8, 3 },
102 110  
103 111  
104 112  
105 113  
... ... @@ -163,24 +171,37 @@
163 171 unsigned char value;
164 172 };
165 173  
166   -static const struct gpio_config enbw_gpio_config[] = {
  174 +static const struct gpio_config enbw_gpio_config_hut[] = {
167 175 { "RS485 enable", 8, 11, 1, 0 },
  176 + { "RS485 iso", 8, 10, 1, 1 },
  177 + { "W2HUT RS485 Rx ena", 8, 9, 1, 0 },
  178 + { "W2HUT RS485 iso", 8, 8, 1, 1 },
  179 +};
  180 +
  181 +static const struct gpio_config enbw_gpio_config_w[] = {
  182 + { "RS485 enable", 8, 11, 1, 0 },
168 183 { "RS485 iso", 8, 10, 1, 0 },
169 184 { "W2HUT RS485 Rx ena", 8, 9, 1, 0 },
170 185 { "W2HUT RS485 iso", 8, 8, 1, 0 },
  186 +};
  187 +
  188 +static const struct gpio_config enbw_gpio_config[] = {
171 189 { "LAN reset", 7, 15, 1, 1 },
172 190 { "ena 11V PLC", 7, 14, 1, 0 },
173 191 { "ena 1.5V PLC", 7, 13, 1, 0 },
174 192 { "disable VBUS", 7, 12, 1, 1 },
175   - { "PLC reset", 6, 13, 1, 1 },
  193 + { "PLC reset", 6, 13, 1, 0 },
176 194 { "LCM RS", 6, 12, 1, 0 },
177 195 { "LCM R/W", 6, 11, 1, 0 },
178 196 { "PLC pairing", 6, 10, 1, 1 },
179 197 { "PLC MDIO CLK", 6, 9, 1, 0 },
180 198 { "HK218", 6, 8, 1, 0 },
181 199 { "HK218 Rx", 6, 1, 1, 1 },
182   - { "TPM reset", 6, 0, 1, 1 },
183   - { "LCM E", 2, 2, 1, 1 },
  200 + { "TPM reset", 6, 0, 1, 0 },
  201 + { "Board-Type", 3, 9, 0, 0 },
  202 + { "HW-ID0", 2, 7, 0, 0 },
  203 + { "HW-ID1", 2, 6, 0, 0 },
  204 + { "HW-ID2", 2, 3, 0, 0 },
184 205 { "PV-IF RxD ena", 0, 15, 1, 1 },
185 206 { "LED1", 1, 15, 1, 1 },
186 207 { "LED2", 0, 1, 1, 1 },
187 208  
188 209  
189 210  
190 211  
191 212  
192 213  
... ... @@ -229,34 +250,57 @@
229 250 }
230 251 }
231 252  
232   -int board_init(void)
  253 +static int enbw_cmc_init_gpio(const struct gpio_config *conf, int sz)
233 254 {
234 255 int i, ret;
235 256  
236   -#ifndef CONFIG_USE_IRQ
237   - irq_init();
238   -#endif
239   - /* address of boot parameters, not used as booting with DTT */
240   - gd->bd->bi_boot_params = 0;
  257 + for (i = 0; i < sz; i++) {
  258 + int gpio = conf[i].bank * 16 +
  259 + conf[i].gpio;
241 260  
242   - for (i = 0; i < ARRAY_SIZE(enbw_gpio_config); i++) {
243   - int gpio = enbw_gpio_config[i].bank * 16 +
244   - enbw_gpio_config[i].gpio;
245   -
246   - ret = gpio_request(gpio, enbw_gpio_config[i].name);
  261 + ret = gpio_request(gpio, conf[i].name);
247 262 if (ret) {
248 263 printf("%s: Could not get %s gpio\n", __func__,
249   - enbw_gpio_config[i].name);
250   - return -1;
  264 + conf[i].name);
  265 + return ret;
251 266 }
252 267  
253   - if (enbw_gpio_config[i].out)
  268 + if (conf[i].out)
254 269 gpio_direction_output(gpio,
255   - enbw_gpio_config[i].value);
  270 + conf[i].value);
256 271 else
257 272 gpio_direction_input(gpio);
258 273 }
259 274  
  275 + return 0;
  276 +}
  277 +
  278 +int board_init(void)
  279 +{
  280 + int board_type, hw_id;
  281 +
  282 +#ifndef CONFIG_USE_IRQ
  283 + irq_init();
  284 +#endif
  285 + /* address of boot parameters, not used as booting with DTT */
  286 + gd->bd->bi_boot_params = 0;
  287 +
  288 + enbw_cmc_init_gpio(enbw_gpio_config, ARRAY_SIZE(enbw_gpio_config));
  289 +
  290 + /* detect HW version */
  291 + board_type = gpio_get_value(CONFIG_ENBW_CMC_BOARD_TYPE);
  292 + hw_id = gpio_get_value(CONFIG_ENBW_CMC_HW_ID_BIT0) +
  293 + (gpio_get_value(CONFIG_ENBW_CMC_HW_ID_BIT1) << 1) +
  294 + (gpio_get_value(CONFIG_ENBW_CMC_HW_ID_BIT2) << 2);
  295 + printf("BOARD: CMC-%s hw id: %d\n", (board_type ? "w2" : "hut"),
  296 + hw_id);
  297 + if (board_type)
  298 + enbw_cmc_init_gpio(enbw_gpio_config_w,
  299 + ARRAY_SIZE(enbw_gpio_config_w));
  300 + else
  301 + enbw_cmc_init_gpio(enbw_gpio_config_hut,
  302 + ARRAY_SIZE(enbw_gpio_config_hut));
  303 +
260 304 /* setup the SUSPSRC for ARM to control emulation suspend */
261 305 clrbits_le32(&davinci_syscfg_regs->suspsrc,
262 306 (DAVINCI_SYSCFG_SUSPSRC_EMAC | DAVINCI_SYSCFG_SUSPSRC_I2C |
263 307  
264 308  
265 309  
... ... @@ -267,15 +311,232 @@
267 311 }
268 312  
269 313 #ifdef CONFIG_DRIVER_TI_EMAC
  314 +
  315 +#define KSZ_CMD_READ 0x03
  316 +#define KSZ_CMD_WRITE 0x02
  317 +#define KSZ_ID 0x95
  318 +
  319 +static int enbw_cmc_switch_read(struct spi_slave *spi, u8 reg, u8 *val)
  320 +{
  321 + unsigned long flags = SPI_XFER_BEGIN;
  322 + int ret;
  323 + int cmd_len;
  324 + u8 cmd[2];
  325 +
  326 + cmd[0] = KSZ_CMD_READ;
  327 + cmd[1] = reg;
  328 + cmd_len = 2;
  329 +
  330 + ret = spi_xfer(spi, cmd_len * 8, cmd, NULL, flags);
  331 + if (ret) {
  332 + debug("Failed to send command (%zu bytes): %d\n",
  333 + cmd_len, ret);
  334 + return -EINVAL;
  335 + }
  336 + flags |= SPI_XFER_END;
  337 + *val = 0;
  338 + cmd_len = 1;
  339 + ret = spi_xfer(spi, cmd_len * 8, NULL, val, flags);
  340 + if (ret) {
  341 + debug("Failed to read (%zu bytes): %d\n",
  342 + cmd_len, ret);
  343 + return -EINVAL;
  344 + }
  345 +
  346 + return 0;
  347 +}
  348 +
  349 +static int enbw_cmc_switch_read_ident(struct spi_slave *spi)
  350 +{
  351 + int ret;
  352 + u8 val;
  353 +
  354 + ret = enbw_cmc_switch_read(spi, 0, &val);
  355 + if (ret) {
  356 + debug("Failed to read\n");
  357 + return -EINVAL;
  358 + }
  359 +
  360 + if (val != KSZ_ID)
  361 + return -EINVAL;
  362 +
  363 + return 0;
  364 +}
  365 +
  366 +static int enbw_cmc_switch_write(struct spi_slave *spi, unsigned long reg,
  367 + unsigned long val)
  368 +{
  369 + unsigned long flags = SPI_XFER_BEGIN;
  370 + int ret;
  371 + int cmd_len;
  372 + u8 cmd[3];
  373 +
  374 + cmd[0] = KSZ_CMD_WRITE;
  375 + cmd[1] = reg;
  376 + cmd[2] = val;
  377 + cmd_len = 3;
  378 + flags |= SPI_XFER_END;
  379 +
  380 + ret = spi_xfer(spi, cmd_len * 8, cmd, NULL, flags);
  381 + if (ret) {
  382 + debug("Failed to send command (%zu bytes): %d\n",
  383 + cmd_len, ret);
  384 + return -EINVAL;
  385 + }
  386 +
  387 + udelay(1000);
  388 + ret = enbw_cmc_switch_read(spi, reg, &cmd[0]);
  389 + if (ret) {
  390 + debug("Failed to read\n");
  391 + return -EINVAL;
  392 + }
  393 + if (val != cmd[0])
  394 + debug("warning: reg: %lx va: %x soll: %lx\n",
  395 + reg, cmd[0], val);
  396 +
  397 + return 0;
  398 +}
  399 +
  400 +static int enbw_cmc_eof(unsigned char *ptr)
  401 +{
  402 + if (*ptr == 0xff)
  403 + return 1;
  404 +
  405 + return 0;
  406 +}
  407 +
  408 +static char *enbw_cmc_getnewline(char *ptr)
  409 +{
  410 + while (*ptr != 0x0a) {
  411 + ptr++;
  412 + if (enbw_cmc_eof((unsigned char *)ptr))
  413 + return NULL;
  414 + }
  415 +
  416 + ptr++;
  417 + return ptr;
  418 +}
  419 +
  420 +static char *enbw_cmc_getvalue(char *ptr, int *value)
  421 +{
  422 + int end = 0;
  423 +
  424 + *value = -EINVAL;
  425 +
  426 + if (!isxdigit(*ptr))
  427 + end = 1;
  428 +
  429 + while (end) {
  430 + if ((*ptr == '#') || (*ptr == ';')) {
  431 + ptr = enbw_cmc_getnewline(ptr);
  432 + return ptr;
  433 + }
  434 + if (ptr != NULL) {
  435 + if (isxdigit(*ptr)) {
  436 + end = 0;
  437 + } else if (*ptr == 0x0a) {
  438 + ptr++;
  439 + return ptr;
  440 + } else {
  441 + ptr++;
  442 + if (enbw_cmc_eof((unsigned char *)ptr))
  443 + return NULL;
  444 + }
  445 + } else {
  446 + return NULL;
  447 + }
  448 + }
  449 + *value = (int)simple_strtoul((const char *)ptr, &ptr, 16);
  450 + ptr++;
  451 + return ptr;
  452 +}
  453 +
  454 +static int enbw_cmc_config_switch(unsigned long addr)
  455 +{
  456 + struct spi_slave *spi;
  457 + char *ptr = (char *)addr;
  458 + int value, reg;
  459 + int ret;
  460 + int bus, cs, max_hz, spi_mode;
  461 +
  462 + debug("configure switch with file on addr: 0x%lx\n", addr);
  463 +
  464 + bus = 0;
  465 + cs = 0;
  466 + max_hz = 1000000;
  467 + spi_mode = 0;
  468 +
  469 + spi = spi_setup_slave(bus, cs, max_hz, spi_mode);
  470 + if (!spi) {
  471 + printf("Failed to set up slave\n");
  472 + return -EINVAL;
  473 + }
  474 +
  475 + ret = spi_claim_bus(spi);
  476 + if (ret) {
  477 + debug("Failed to claim SPI bus: %d\n", ret);
  478 + goto err_claim_bus;
  479 + }
  480 +
  481 + ret = enbw_cmc_switch_read_ident(spi);
  482 + if (ret)
  483 + goto err_claim_bus;
  484 +
  485 + ptr = (char *)addr;
  486 + while (ptr != NULL) {
  487 + ptr = enbw_cmc_getvalue(ptr, &reg);
  488 + if (ptr != NULL) {
  489 + ptr = enbw_cmc_getvalue(ptr, &value);
  490 + if ((ptr != NULL) && (value >= 0))
  491 + if (enbw_cmc_switch_write(spi, reg, value))
  492 + goto err_read;
  493 + }
  494 + }
  495 + return 0;
  496 +
  497 +err_read:
  498 + spi_release_bus(spi);
  499 +err_claim_bus:
  500 + spi_free_slave(spi);
  501 + return -EINVAL;
  502 +}
  503 +
  504 +static int do_switch(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
  505 +{
  506 + unsigned long addr;
  507 +
  508 + if (argc < 2)
  509 + return cmd_usage(cmdtp);
  510 +
  511 + addr = simple_strtoul(argv[1], NULL, 16);
  512 + enbw_cmc_config_switch(addr);
  513 +
  514 + return 0;
  515 +}
  516 +
  517 +U_BOOT_CMD(switch, 3, 1, do_switch,
  518 + "switch addr",
  519 + "[addr]"
  520 +);
  521 +
270 522 /*
271 523 * Initializes on-board ethernet controllers.
272 524 */
273 525 int board_eth_init(bd_t *bis)
274 526 {
275   -#ifdef CONFIG_DRIVER_TI_EMAC
  527 + const char *s;
  528 + size_t len;
  529 +
276 530 davinci_emac_mii_mode_sel(0);
277   -#endif /* CONFIG_DRIVER_TI_EMAC */
278 531  
  532 + /* send a config file to the switch */
  533 + s = hwconfig_subarg("switch", "config", &len);
  534 + if (len) {
  535 + unsigned long addr = simple_strtoul(s, NULL, 16);
  536 +
  537 + enbw_cmc_config_switch(addr);
  538 + }
  539 +
279 540 if (!davinci_emac_initialize()) {
280 541 printf("Error: Ethernet init failed!\n");
281 542 return -1;
... ... @@ -546,6 +807,29 @@
546 807 }
547 808 #endif
548 809  
  810 +ulong post_word_load(void)
  811 +{
  812 + struct davinci_rtc *reg =
  813 + (struct davinci_rtc *)CONFIG_SYS_POST_WORD_ADDR;
  814 +
  815 + return in_be32(&reg->scratch2);
  816 +}
  817 +
  818 +void post_word_store(ulong value)
  819 +{
  820 + struct davinci_rtc *reg =
  821 + (struct davinci_rtc *)CONFIG_SYS_POST_WORD_ADDR;
  822 +
  823 + /*
  824 + * write RTC kick register to enable write
  825 + * for RTC Scratch registers. Cratch0 and 1 are
  826 + * used for bootcount values.
  827 + */
  828 + writel(RTC_KICK0R_WE, &reg->kick0r);
  829 + writel(RTC_KICK1R_WE, &reg->kick1r);
  830 + out_be32(&reg->scratch2, value);
  831 +}
  832 +
549 833 void board_gpio_init(void)
550 834 {
551 835 struct davinci_gpio *gpio = davinci_gpio_bank01;
... ... @@ -558,6 +842,19 @@
558 842 clrbits_le32(&gpio->out_data, 0x8000407e);
559 843 /* set LED 1 - 5 to state on */
560 844 setbits_le32(&gpio->out_data, 0x8000001e);
  845 +
  846 + /*
  847 + * set some gpio pins to low, this is needed early,
  848 + * so we have no gpio Interface here
  849 + * gpios:
  850 + * 8[8] Mode PV select low
  851 + * 8[9] Debug Rx Enable low
  852 + * 8[10] Mode Select PV low
  853 + * 8[11] Counter Interface RS485 Rx-Enable low
  854 + */
  855 + gpio = davinci_gpio_bank8;
  856 + clrbits_le32(&gpio->dir, 0x00000f00);
  857 + clrbits_le32(&gpio->out_data, 0x0f00);
561 858 }
562 859  
563 860 int board_late_init(void)
doc/README.switch_config
  1 +On the enbw_cmc board is a KSZ8864RMN switch which needs
  2 +configured through spi before working. This is done on
  3 +startup from u-boot through a config file stored at an
  4 +address specified in the "hwconfig" environment variable,
  5 +subcommand "config".
  6 +
  7 +For example on the enbw_cmc board:
  8 +
  9 +hwconfig=switch:lan=on,pwl=off,config=0x60160000
  10 +
  11 +The file has the following structure:
  12 +
  13 +- a comment starts with a '#' or a ';' and ends with a newline
  14 +- The switch needs for its config a reg/value pair, so we
  15 + have two columns in the file:
  16 + reg : contains the register address
  17 + value: contains a 8 bit register value
  18 + This 2 columns are seperated through space or tab.
  19 +
  20 +example (minimal configuration on the enbw_cmc board):
  21 +
  22 +;reg value comment
  23 +;-----------------------------------------
  24 +0x01 0x00
  25 +0x01 0x01 ; Start Switch with this configuration
include/configs/enbw_cmc.h
... ... @@ -102,6 +102,14 @@
102 102 #define CONFIG_SYS_DTT_HYSTERESIS 3
103 103  
104 104 /*
  105 + * SPI Configuration
  106 + */
  107 +#define CONFIG_DAVINCI_SPI
  108 +#define CONFIG_SYS_SPI_BASE DAVINCI_SPI1_BASE
  109 +#define CONFIG_SYS_SPI_CLK clk_get(DAVINCI_SPI1_CLKID)
  110 +#define CONFIG_CMD_SPI
  111 +
  112 +/*
105 113 * Flash & Environment
106 114 */
107 115 #ifdef CONFIG_USE_NAND
108 116  
... ... @@ -225,9 +233,9 @@
225 233 "key_magic_2=2\0" \
226 234 "key_magic_3=3\0" \
227 235 "magic_keys=0123\0" \
228   - "hwconfig=switch:lan=on,pwl=off\0" \
  236 + "hwconfig=switch:lan=on,pwl=off,config=0x60100000\0" \
229 237 "addmtd=setenv bootargs ${bootargs} ${mtdparts}\0" \
230   - "addmisc=setenv bootargs ${bootargs} davinci_mmc.use_dma=0\0" \
  238 + "addmisc=setenv bootargs ${bootargs}\0" \
231 239 "mtdids=" MTDIDS_DEFAULT "\0" \
232 240 "mtdparts=" MTDPARTS_DEFAULT "\0" \
233 241 "logversion=2\0" \
... ... @@ -336,6 +344,11 @@
336 344 #define CONFIG_CMD_FAT
337 345 #define CONFIG_CMD_MMC
338 346  
  347 +/* GPIO */
  348 +#define CONFIG_ENBW_CMC_BOARD_TYPE 57
  349 +#define CONFIG_ENBW_CMC_HW_ID_BIT0 39
  350 +#define CONFIG_ENBW_CMC_HW_ID_BIT1 38
  351 +#define CONFIG_ENBW_CMC_HW_ID_BIT2 35
339 352  
340 353 /* FDT support */
341 354 #define CONFIG_OF_LIBFDT
... ... @@ -438,7 +451,8 @@
438 451 #define CONFIG_SYS_DV_NOR_BOOT_CFG (0x11)
439 452  
440 453 #define CONFIG_POST (CONFIG_SYS_POST_MEMORY)
441   -#define CONFIG_SYS_POST_WORD_ADDR 0x8001FFF0
  454 +#define CONFIG_POST_EXTERNAL_WORD_FUNCS
  455 +#define CONFIG_SYS_POST_WORD_ADDR DAVINCI_RTC_BASE
442 456 #define CONFIG_LOGBUFFER
443 457 #define CONFIG_SYS_CONSOLE_IS_IN_ENV
444 458