uboot/board/armadeus/apf27/apf27.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2008-2013 Eric Jarrige <eric.jarrige@armadeus.org>
   3 *
   4 * based on the files by
   5 * Sascha Hauer, Pengutronix
   6 *
   7 * SPDX-License-Identifier:    GPL-2.0+
   8 */
   9
  10#include <common.h>
  11#include <environment.h>
  12#include <jffs2/jffs2.h>
  13#include <nand.h>
  14#include <netdev.h>
  15#include <asm/io.h>
  16#include <asm/arch/imx-regs.h>
  17#include <asm/arch/gpio.h>
  18#include <asm/gpio.h>
  19#include <linux/errno.h>
  20#include "apf27.h"
  21#include "crc.h"
  22#include "fpga.h"
  23
  24DECLARE_GLOBAL_DATA_PTR;
  25
  26/*
  27 * Fuse bank 1 row 8 is "reserved for future use" and therefore available for
  28 * customer use. The APF27 board uses this fuse to store the board revision:
  29 * 0: initial board revision
  30 * 1: first revision - Presence of the second RAM chip on the board is blown in
  31 *     fuse bank 1 row 9  bit 0 - No hardware change
  32 * N: to be defined
  33 */
  34static u32 get_board_rev(void)
  35{
  36        struct iim_regs *iim = (struct iim_regs *)IMX_IIM_BASE;
  37
  38        return readl(&iim->bank[1].fuse_regs[8]);
  39}
  40
  41/*
  42 * Fuse bank 1 row 9 is "reserved for future use" and therefore available for
  43 * customer use. The APF27 board revision 1 uses the bit 0 to permanently store
  44 * the presence of the second RAM chip
  45 * 0: AFP27 with 1 RAM of 64 MiB
  46 * 1: AFP27 with 2 RAM chips of 64 MiB each (128MB)
  47 */
  48static int get_num_ram_bank(void)
  49{
  50        struct iim_regs *iim = (struct iim_regs *)IMX_IIM_BASE;
  51        int nr_dram_banks = 1;
  52
  53        if ((get_board_rev() > 0) && (CONFIG_NR_DRAM_BANKS > 1))
  54                nr_dram_banks += readl(&iim->bank[1].fuse_regs[9]) & 0x01;
  55        else
  56                nr_dram_banks = CONFIG_NR_DRAM_POPULATED;
  57
  58        return nr_dram_banks;
  59}
  60
  61static void apf27_port_init(int port, u32 gpio_dr, u32 ocr1, u32 ocr2,
  62                            u32 iconfa1, u32 iconfa2, u32 iconfb1, u32 iconfb2,
  63                            u32 icr1, u32 icr2, u32 imr, u32 gpio_dir, u32 gpr,
  64                            u32 puen, u32 gius)
  65{
  66        struct gpio_port_regs *regs = (struct gpio_port_regs *)IMX_GPIO_BASE;
  67
  68        writel(gpio_dr,   &regs->port[port].gpio_dr);
  69        writel(ocr1,      &regs->port[port].ocr1);
  70        writel(ocr2,      &regs->port[port].ocr2);
  71        writel(iconfa1,   &regs->port[port].iconfa1);
  72        writel(iconfa2,   &regs->port[port].iconfa2);
  73        writel(iconfb1,   &regs->port[port].iconfb1);
  74        writel(iconfb2,   &regs->port[port].iconfb2);
  75        writel(icr1,      &regs->port[port].icr1);
  76        writel(icr2,      &regs->port[port].icr2);
  77        writel(imr,       &regs->port[port].imr);
  78        writel(gpio_dir,  &regs->port[port].gpio_dir);
  79        writel(gpr,       &regs->port[port].gpr);
  80        writel(puen,      &regs->port[port].puen);
  81        writel(gius,      &regs->port[port].gius);
  82}
  83
  84#define APF27_PORT_INIT(n) apf27_port_init(PORT##n, ACFG_DR_##n##_VAL,    \
  85        ACFG_OCR1_##n##_VAL, ACFG_OCR2_##n##_VAL, ACFG_ICFA1_##n##_VAL,   \
  86        ACFG_ICFA2_##n##_VAL, ACFG_ICFB1_##n##_VAL, ACFG_ICFB2_##n##_VAL, \
  87        ACFG_ICR1_##n##_VAL, ACFG_ICR2_##n##_VAL, ACFG_IMR_##n##_VAL,     \
  88        ACFG_DDIR_##n##_VAL, ACFG_GPR_##n##_VAL, ACFG_PUEN_##n##_VAL,     \
  89        ACFG_GIUS_##n##_VAL)
  90
  91static void apf27_iomux_init(void)
  92{
  93        APF27_PORT_INIT(A);
  94        APF27_PORT_INIT(B);
  95        APF27_PORT_INIT(C);
  96        APF27_PORT_INIT(D);
  97        APF27_PORT_INIT(E);
  98        APF27_PORT_INIT(F);
  99}
 100
 101static int apf27_devices_init(void)
 102{
 103        int i;
 104        unsigned int mode[] = {
 105                PC5_PF_I2C2_DATA,
 106                PC6_PF_I2C2_CLK,
 107                PD17_PF_I2C_DATA,
 108                PD18_PF_I2C_CLK,
 109        };
 110
 111        for (i = 0; i < ARRAY_SIZE(mode); i++)
 112                imx_gpio_mode(mode[i]);
 113
 114#ifdef CONFIG_MXC_UART
 115        mx27_uart1_init_pins();
 116#endif
 117
 118#ifdef CONFIG_FEC_MXC
 119        mx27_fec_init_pins();
 120#endif
 121
 122#ifdef CONFIG_MMC_MXC
 123        mx27_sd2_init_pins();
 124        imx_gpio_mode((GPIO_PORTF | GPIO_OUT | GPIO_PUEN | GPIO_GPIO | 16));
 125        gpio_request(PC_PWRON, "pc_pwron");
 126        gpio_set_value(PC_PWRON, 1);
 127#endif
 128        return 0;
 129}
 130
 131static void apf27_setup_csx(void)
 132{
 133        struct weim_regs *weim = (struct weim_regs *)IMX_WEIM_BASE;
 134
 135        writel(ACFG_CS0U_VAL, &weim->cs0u);
 136        writel(ACFG_CS0L_VAL, &weim->cs0l);
 137        writel(ACFG_CS0A_VAL, &weim->cs0a);
 138
 139        writel(ACFG_CS1U_VAL, &weim->cs1u);
 140        writel(ACFG_CS1L_VAL, &weim->cs1l);
 141        writel(ACFG_CS1A_VAL, &weim->cs1a);
 142
 143        writel(ACFG_CS2U_VAL, &weim->cs2u);
 144        writel(ACFG_CS2L_VAL, &weim->cs2l);
 145        writel(ACFG_CS2A_VAL, &weim->cs2a);
 146
 147        writel(ACFG_CS3U_VAL, &weim->cs3u);
 148        writel(ACFG_CS3L_VAL, &weim->cs3l);
 149        writel(ACFG_CS3A_VAL, &weim->cs3a);
 150
 151        writel(ACFG_CS4U_VAL, &weim->cs4u);
 152        writel(ACFG_CS4L_VAL, &weim->cs4l);
 153        writel(ACFG_CS4A_VAL, &weim->cs4a);
 154
 155        writel(ACFG_CS5U_VAL, &weim->cs5u);
 156        writel(ACFG_CS5L_VAL, &weim->cs5l);
 157        writel(ACFG_CS5A_VAL, &weim->cs5a);
 158
 159        writel(ACFG_EIM_VAL, &weim->eim);
 160}
 161
 162static void apf27_setup_port(void)
 163{
 164        struct system_control_regs *system =
 165                (struct system_control_regs *)IMX_SYSTEM_CTL_BASE;
 166
 167        writel(ACFG_FMCR_VAL, &system->fmcr);
 168}
 169
 170int board_init(void)
 171{
 172        gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100;
 173
 174        apf27_setup_csx();
 175        apf27_setup_port();
 176        apf27_iomux_init();
 177        apf27_devices_init();
 178#if defined(CONFIG_FPGA)
 179        APF27_init_fpga();
 180#endif
 181
 182
 183        return 0;
 184}
 185
 186int dram_init(void)
 187{
 188        gd->ram_size = get_ram_size((void *)PHYS_SDRAM_1, PHYS_SDRAM_1_SIZE);
 189        if (get_num_ram_bank() > 1)
 190                gd->ram_size += get_ram_size((void *)PHYS_SDRAM_2,
 191                                             PHYS_SDRAM_2_SIZE);
 192
 193        return 0;
 194}
 195
 196int dram_init_banksize(void)
 197{
 198        gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
 199        gd->bd->bi_dram[0].size  = get_ram_size((void *)PHYS_SDRAM_1,
 200                                                PHYS_SDRAM_1_SIZE);
 201        gd->bd->bi_dram[1].start = PHYS_SDRAM_2;
 202        if (get_num_ram_bank() > 1)
 203                gd->bd->bi_dram[1].size = get_ram_size((void *)PHYS_SDRAM_2,
 204                                             PHYS_SDRAM_2_SIZE);
 205        else
 206                gd->bd->bi_dram[1].size = 0;
 207
 208        return 0;
 209}
 210
 211ulong board_get_usable_ram_top(ulong total_size)
 212{
 213        ulong ramtop;
 214
 215        if (get_num_ram_bank() > 1)
 216                ramtop = PHYS_SDRAM_2 + get_ram_size((void *)PHYS_SDRAM_2,
 217                                                     PHYS_SDRAM_2_SIZE);
 218        else
 219                ramtop = PHYS_SDRAM_1 + get_ram_size((void *)PHYS_SDRAM_1,
 220                                                     PHYS_SDRAM_1_SIZE);
 221
 222        return ramtop;
 223}
 224
 225int checkboard(void)
 226{
 227        printf("Board: Armadeus APF27 revision %d\n", get_board_rev());
 228        return 0;
 229}
 230
 231#ifdef CONFIG_SPL_BUILD
 232inline void hang(void)
 233{
 234        for (;;)
 235                ;
 236}
 237
 238void board_init_f(ulong bootflag)
 239{
 240        /*
 241         * copy ourselves from where we are running to where we were
 242         * linked at. Use ulong pointers as all addresses involved
 243         * are 4-byte-aligned.
 244         */
 245        ulong *start_ptr, *end_ptr, *link_ptr, *run_ptr, *dst;
 246        asm volatile ("ldr %0, =_start" : "=r"(start_ptr));
 247        asm volatile ("ldr %0, =_end" : "=r"(end_ptr));
 248        asm volatile ("ldr %0, =board_init_f" : "=r"(link_ptr));
 249        asm volatile ("adr %0, board_init_f" : "=r"(run_ptr));
 250        for (dst = start_ptr; dst < end_ptr; dst++)
 251                *dst = *(dst+(run_ptr-link_ptr));
 252
 253        /*
 254         * branch to nand_boot's link-time address.
 255         */
 256        asm volatile("ldr pc, =nand_boot");
 257}
 258#endif /* CONFIG_SPL_BUILD */
 259