uboot/board/siemens/taurus/taurus.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Board functions for Siemens TAURUS (AT91SAM9G20) based boards
   4 * (C) Copyright Siemens AG
   5 *
   6 * Based on:
   7 * U-Boot file: board/atmel/at91sam9260ek/at91sam9260ek.c
   8 *
   9 * (C) Copyright 2007-2008
  10 * Stelian Pop <stelian@popies.net>
  11 * Lead Tech Design <www.leadtechdesign.com>
  12 */
  13
  14#include <command.h>
  15#include <common.h>
  16#include <dm.h>
  17#include <environment.h>
  18#include <asm/io.h>
  19#include <asm/arch/at91sam9260_matrix.h>
  20#include <asm/arch/at91sam9_smc.h>
  21#include <asm/arch/at91_common.h>
  22#include <asm/arch/at91_rstc.h>
  23#include <asm/arch/gpio.h>
  24#include <asm/arch/at91sam9_sdramc.h>
  25#include <asm/arch/atmel_serial.h>
  26#include <asm/arch/clk.h>
  27#include <asm/gpio.h>
  28#include <linux/mtd/rawnand.h>
  29#include <atmel_mci.h>
  30#include <asm/arch/at91_spi.h>
  31#include <spi.h>
  32
  33#include <net.h>
  34#ifndef CONFIG_DM_ETH
  35#include <netdev.h>
  36#endif
  37
  38DECLARE_GLOBAL_DATA_PTR;
  39
  40static void taurus_request_gpio(void)
  41{
  42        gpio_request(CONFIG_SYS_NAND_ENABLE_PIN, "nand ena");
  43        gpio_request(CONFIG_SYS_NAND_READY_PIN, "nand rdy");
  44        gpio_request(AT91_PIN_PA25, "ena PHY");
  45}
  46
  47static void taurus_nand_hw_init(void)
  48{
  49        struct at91_smc *smc = (struct at91_smc *)ATMEL_BASE_SMC;
  50        struct at91_matrix *matrix = (struct at91_matrix *)ATMEL_BASE_MATRIX;
  51        unsigned long csa;
  52
  53        /* Assign CS3 to NAND/SmartMedia Interface */
  54        csa = readl(&matrix->ebicsa);
  55        csa |= AT91_MATRIX_CS3A_SMC_SMARTMEDIA;
  56        writel(csa, &matrix->ebicsa);
  57
  58        /* Configure SMC CS3 for NAND/SmartMedia */
  59        writel(AT91_SMC_SETUP_NWE(2) | AT91_SMC_SETUP_NCS_WR(0) |
  60               AT91_SMC_SETUP_NRD(2) | AT91_SMC_SETUP_NCS_RD(0),
  61               &smc->cs[3].setup);
  62        writel(AT91_SMC_PULSE_NWE(4) | AT91_SMC_PULSE_NCS_WR(3) |
  63               AT91_SMC_PULSE_NRD(4) | AT91_SMC_PULSE_NCS_RD(3),
  64               &smc->cs[3].pulse);
  65        writel(AT91_SMC_CYCLE_NWE(7) | AT91_SMC_CYCLE_NRD(7),
  66               &smc->cs[3].cycle);
  67        writel(AT91_SMC_MODE_RM_NRD | AT91_SMC_MODE_WM_NWE |
  68               AT91_SMC_MODE_EXNW_DISABLE |
  69               AT91_SMC_MODE_DBW_8 |
  70               AT91_SMC_MODE_TDF_CYCLE(3),
  71               &smc->cs[3].mode);
  72
  73        /* Configure RDY/BSY */
  74        at91_set_gpio_input(CONFIG_SYS_NAND_READY_PIN, 1);
  75
  76        /* Enable NandFlash */
  77        at91_set_gpio_output(CONFIG_SYS_NAND_ENABLE_PIN, 1);
  78}
  79
  80#if defined(CONFIG_SPL_BUILD)
  81#include <spl.h>
  82#include <nand.h>
  83#include <spi_flash.h>
  84
  85void matrix_init(void)
  86{
  87        struct at91_matrix *mat = (struct at91_matrix *)ATMEL_BASE_MATRIX;
  88
  89        writel((readl(&mat->scfg[3]) & (~AT91_MATRIX_SLOT_CYCLE))
  90                        | AT91_MATRIX_SLOT_CYCLE_(0x40),
  91                        &mat->scfg[3]);
  92}
  93
  94#if defined(CONFIG_BOARD_AXM)
  95static int at91_is_recovery(void)
  96{
  97        if ((at91_get_gpio_value(AT91_PIN_PA26) == 0) &&
  98            (at91_get_gpio_value(AT91_PIN_PA27) == 0))
  99                return 1;
 100
 101        return 0;
 102}
 103#elif defined(CONFIG_BOARD_TAURUS)
 104static int at91_is_recovery(void)
 105{
 106        if (at91_get_gpio_value(AT91_PIN_PA31) == 0)
 107                return 1;
 108
 109        return 0;
 110}
 111#endif
 112
 113void spl_board_init(void)
 114{
 115        taurus_nand_hw_init();
 116        at91_spi0_hw_init(TAURUS_SPI_MASK);
 117
 118#if defined(CONFIG_BOARD_AXM)
 119        /* Configure LED PINs */
 120        at91_set_gpio_output(AT91_PIN_PA6, 0);
 121        at91_set_gpio_output(AT91_PIN_PA8, 0);
 122        at91_set_gpio_output(AT91_PIN_PA9, 0);
 123        at91_set_gpio_output(AT91_PIN_PA10, 0);
 124        at91_set_gpio_output(AT91_PIN_PA11, 0);
 125        at91_set_gpio_output(AT91_PIN_PA12, 0);
 126
 127        /* Configure recovery button PINs */
 128        at91_set_gpio_input(AT91_PIN_PA26, 1);
 129        at91_set_gpio_input(AT91_PIN_PA27, 1);
 130#elif defined(CONFIG_BOARD_TAURUS)
 131        at91_set_gpio_input(AT91_PIN_PA31, 1);
 132#endif
 133
 134        /* check for recovery mode */
 135        if (at91_is_recovery() == 1) {
 136                struct spi_flash *flash;
 137
 138                puts("Recovery button pressed\n");
 139                nand_init();
 140                spl_nand_erase_one(0, 0);
 141                flash = spi_flash_probe(CONFIG_SF_DEFAULT_BUS,
 142                                        0,
 143                                        CONFIG_SF_DEFAULT_SPEED,
 144                                        CONFIG_SF_DEFAULT_MODE);
 145                if (!flash) {
 146                        puts("no flash\n");
 147                } else {
 148                        puts("erase spi flash sector 0\n");
 149                        spi_flash_erase(flash, 0,
 150                                        CONFIG_SYS_NAND_U_BOOT_SIZE);
 151                }
 152        }
 153}
 154
 155#define SDRAM_BASE_CONF (AT91_SDRAMC_NR_13 | AT91_SDRAMC_CAS_3 \
 156                         |AT91_SDRAMC_NB_4 | AT91_SDRAMC_DBW_32 \
 157                         | AT91_SDRAMC_TWR_VAL(3) | AT91_SDRAMC_TRC_VAL(9) \
 158                         | AT91_SDRAMC_TRP_VAL(3) | AT91_SDRAMC_TRCD_VAL(3) \
 159                         | AT91_SDRAMC_TRAS_VAL(6) | AT91_SDRAMC_TXSR_VAL(10))
 160
 161void sdramc_configure(unsigned int mask)
 162{
 163        struct at91_matrix *ma = (struct at91_matrix *)ATMEL_BASE_MATRIX;
 164        struct sdramc_reg setting;
 165
 166        at91_sdram_hw_init();
 167        setting.cr = SDRAM_BASE_CONF | mask;
 168        setting.mdr = AT91_SDRAMC_MD_SDRAM;
 169        setting.tr = (CONFIG_SYS_MASTER_CLOCK * 7) / 1000000;
 170
 171        writel(readl(&ma->ebicsa) | AT91_MATRIX_CS1A_SDRAMC |
 172                AT91_MATRIX_VDDIOMSEL_3_3V | AT91_MATRIX_EBI_IOSR_SEL,
 173                &ma->ebicsa);
 174
 175        sdramc_initialize(ATMEL_BASE_CS1, &setting);
 176}
 177
 178void mem_init(void)
 179{
 180        unsigned int ram_size = 0;
 181
 182        /* Configure SDRAM for 128MB */
 183        sdramc_configure(AT91_SDRAMC_NC_10);
 184
 185        /* Do memtest for 128MB */
 186        ram_size = get_ram_size((void *)CONFIG_SYS_SDRAM_BASE,
 187                                CONFIG_SYS_SDRAM_SIZE);
 188
 189        /*
 190         * If 32MB or 16MB should be supported check also for
 191         * expected mirroring at A16 and A17
 192         * To find mirror addresses depends how the collumns are connected
 193         * at RAM (internaly or externaly)
 194         * If the collumns are not in inverted order the mirror size effect
 195         * behaves like normal SRAM with A0,A1,A2,etc. connected incremantal
 196         */
 197
 198        /* Mirrors at A15 on ATMEL G20 SDRAM Controller with 64MB*/
 199        if (ram_size == 0x800) {
 200                printf("\n\r 64MB");
 201                sdramc_configure(AT91_SDRAMC_NC_9);
 202        } else {
 203                /* Size already initialized */
 204                printf("\n\r 128MB");
 205        }
 206}
 207#endif
 208
 209#ifdef CONFIG_MACB
 210static void siemens_phy_reset(void)
 211{
 212        /*
 213         * we need to reset PHY for 200us
 214         * because of bug in ATMEL G20 CPU (undefined initial state of GPIO)
 215         */
 216        if ((readl(AT91_ASM_RSTC_SR) & AT91_RSTC_RSTTYP) ==
 217            AT91_RSTC_RSTTYP_GENERAL)
 218                at91_set_gpio_value(AT91_PIN_PA25, 0); /* reset eth switch */
 219}
 220
 221static void taurus_macb_hw_init(void)
 222{
 223        /* Enable EMAC clock */
 224        at91_periph_clk_enable(ATMEL_ID_EMAC0);
 225
 226        /*
 227         * Disable pull-up on:
 228         *      RXDV (PA17) => PHY normal mode (not Test mode)
 229         *      ERX0 (PA14) => PHY ADDR0
 230         *      ERX1 (PA15) => PHY ADDR1
 231         *      ERX2 (PA25) => PHY ADDR2
 232         *      ERX3 (PA26) => PHY ADDR3
 233         *      ECRS (PA28) => PHY ADDR4  => PHYADDR = 0x0
 234         *
 235         * PHY has internal pull-down
 236         */
 237        at91_set_pio_pullup(AT91_PIO_PORTA, 14, 0);
 238        at91_set_pio_pullup(AT91_PIO_PORTA, 15, 0);
 239        at91_set_pio_pullup(AT91_PIO_PORTA, 17, 0);
 240        at91_set_pio_pullup(AT91_PIO_PORTA, 25, 0);
 241        at91_set_pio_pullup(AT91_PIO_PORTA, 26, 0);
 242        at91_set_pio_pullup(AT91_PIO_PORTA, 28, 0);
 243
 244        siemens_phy_reset();
 245
 246        at91_phy_reset();
 247
 248        at91_set_gpio_input(AT91_PIN_PA25, 1);   /* ERST tri-state */
 249
 250        /* Re-enable pull-up */
 251        at91_set_pio_pullup(AT91_PIO_PORTA, 14, 1);
 252        at91_set_pio_pullup(AT91_PIO_PORTA, 15, 1);
 253        at91_set_pio_pullup(AT91_PIO_PORTA, 17, 1);
 254        at91_set_pio_pullup(AT91_PIO_PORTA, 25, 1);
 255        at91_set_pio_pullup(AT91_PIO_PORTA, 26, 1);
 256        at91_set_pio_pullup(AT91_PIO_PORTA, 28, 1);
 257
 258        /* Initialize EMAC=MACB hardware */
 259        at91_macb_hw_init();
 260}
 261#endif
 262
 263#ifdef CONFIG_GENERIC_ATMEL_MCI
 264int board_mmc_init(bd_t *bd)
 265{
 266        at91_mci_hw_init();
 267
 268        return atmel_mci_init((void *)ATMEL_BASE_MCI);
 269}
 270#endif
 271
 272int board_early_init_f(void)
 273{
 274        /* Enable clocks for all PIOs */
 275        at91_periph_clk_enable(ATMEL_ID_PIOA);
 276        at91_periph_clk_enable(ATMEL_ID_PIOB);
 277        at91_periph_clk_enable(ATMEL_ID_PIOC);
 278
 279        at91_seriald_hw_init();
 280        taurus_request_gpio();
 281
 282        return 0;
 283}
 284
 285/* FIXME gpio code here need to handle through DM_GPIO */
 286#ifndef CONFIG_DM_SPI
 287int spi_cs_is_valid(unsigned int bus, unsigned int cs)
 288{
 289        return bus == 0 && cs == 0;
 290}
 291
 292void spi_cs_activate(struct spi_slave *slave)
 293{
 294        at91_set_gpio_value(TAURUS_SPI_CS_PIN, 0);
 295}
 296
 297void spi_cs_deactivate(struct spi_slave *slave)
 298{
 299        at91_set_gpio_value(TAURUS_SPI_CS_PIN, 1);
 300}
 301#endif
 302
 303#ifdef CONFIG_USB_GADGET_AT91
 304#include <linux/usb/at91_udc.h>
 305
 306void at91_udp_hw_init(void)
 307{
 308        /* Enable PLLB */
 309        at91_pllb_clk_enable(get_pllb_init());
 310
 311        /* Enable UDPCK clock, MCK is enabled in at91_clock_init() */
 312        at91_periph_clk_enable(ATMEL_ID_UDP);
 313
 314        at91_system_clk_enable(AT91SAM926x_PMC_UDP);
 315}
 316
 317struct at91_udc_data board_udc_data  = {
 318        .baseaddr = ATMEL_BASE_UDP0,
 319};
 320#endif
 321
 322int board_init(void)
 323{
 324        /* adress of boot parameters */
 325        gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100;
 326
 327        taurus_request_gpio();
 328#ifdef CONFIG_CMD_NAND
 329        taurus_nand_hw_init();
 330#endif
 331#ifdef CONFIG_MACB
 332        taurus_macb_hw_init();
 333#endif
 334        at91_spi0_hw_init(TAURUS_SPI_MASK);
 335#ifdef CONFIG_USB_GADGET_AT91
 336        at91_udp_hw_init();
 337        at91_udc_probe(&board_udc_data);
 338#endif
 339
 340        return 0;
 341}
 342
 343int dram_init(void)
 344{
 345        gd->ram_size = get_ram_size((void *)CONFIG_SYS_SDRAM_BASE,
 346                                    CONFIG_SYS_SDRAM_SIZE);
 347        return 0;
 348}
 349
 350#ifndef CONFIG_DM_ETH
 351int board_eth_init(bd_t *bis)
 352{
 353        int rc = 0;
 354#ifdef CONFIG_MACB
 355        rc = macb_eth_initialize(0, (void *)ATMEL_BASE_EMAC0, 0x00);
 356#endif
 357        return rc;
 358}
 359#endif
 360
 361#if !defined(CONFIG_SPL_BUILD)
 362#if defined(CONFIG_BOARD_AXM)
 363/*
 364 * Booting the Fallback Image.
 365 *
 366 *  The function is used to provide and
 367 *  boot the image with the fallback
 368 *  parameters, incase if the faulty image
 369 *  in upgraded over the base firmware.
 370 *
 371 */
 372static int upgrade_failure_fallback(void)
 373{
 374        char *partitionset_active = NULL;
 375        char *rootfs = NULL;
 376        char *rootfs_fallback = NULL;
 377        char *kern_off;
 378        char *kern_off_fb;
 379        char *kern_size;
 380        char *kern_size_fb;
 381
 382        partitionset_active = env_get("partitionset_active");
 383        if (partitionset_active) {
 384                if (partitionset_active[0] == 'A')
 385                        env_set("partitionset_active", "B");
 386                else
 387                        env_set("partitionset_active", "A");
 388        } else {
 389                printf("partitionset_active missing.\n");
 390                return -ENOENT;
 391        }
 392
 393        rootfs = env_get("rootfs");
 394        rootfs_fallback = env_get("rootfs_fallback");
 395        env_set("rootfs", rootfs_fallback);
 396        env_set("rootfs_fallback", rootfs);
 397
 398        kern_size = env_get("kernel_size");
 399        kern_size_fb = env_get("kernel_size_fallback");
 400        env_set("kernel_size", kern_size_fb);
 401        env_set("kernel_size_fallback", kern_size);
 402
 403        kern_off = env_get("kernel_Off");
 404        kern_off_fb = env_get("kernel_Off_fallback");
 405        env_set("kernel_Off", kern_off_fb);
 406        env_set("kernel_Off_fallback", kern_off);
 407
 408        env_set("bootargs", '\0');
 409        env_set("upgrade_available", '\0');
 410        env_set("boot_retries", '\0');
 411        env_save();
 412
 413        return 0;
 414}
 415
 416static int do_upgrade_available(cmd_tbl_t *cmdtp, int flag, int argc,
 417                        char * const argv[])
 418{
 419        unsigned long upgrade_available = 0;
 420        unsigned long boot_retry = 0;
 421        char boot_buf[10];
 422
 423        upgrade_available = simple_strtoul(env_get("upgrade_available"), NULL,
 424                                           10);
 425        if (upgrade_available) {
 426                boot_retry = simple_strtoul(env_get("boot_retries"), NULL, 10);
 427                boot_retry++;
 428                sprintf(boot_buf, "%lx", boot_retry);
 429                env_set("boot_retries", boot_buf);
 430                env_save();
 431
 432                /*
 433                 * Here the boot_retries count is checked, and if the
 434                 * count becomes greater than 2 switch back to the
 435                 * fallback, and reset the board.
 436                 */
 437
 438                if (boot_retry > 2) {
 439                        if (upgrade_failure_fallback() == 0)
 440                                do_reset(NULL, 0, 0, NULL);
 441                        return -1;
 442                }
 443        }
 444        return 0;
 445}
 446
 447U_BOOT_CMD(
 448        upgrade_available,      1,      1,      do_upgrade_available,
 449        "check Siemens update",
 450        "no parameters"
 451);
 452#endif
 453#endif
 454