uboot/board/freescale/ls2080ardb/ls2080ardb.c
<<
>>
Prefs
   1/*
   2 * Copyright 2015 Freescale Semiconductor
   3 *
   4 * SPDX-License-Identifier:     GPL-2.0+
   5 */
   6#include <common.h>
   7#include <malloc.h>
   8#include <errno.h>
   9#include <netdev.h>
  10#include <fsl_ifc.h>
  11#include <fsl_ddr.h>
  12#include <asm/io.h>
  13#include <hwconfig.h>
  14#include <fdt_support.h>
  15#include <libfdt.h>
  16#include <fsl_debug_server.h>
  17#include <fsl-mc/fsl_mc.h>
  18#include <environment.h>
  19#include <i2c.h>
  20#include <asm/arch/soc.h>
  21#include <fsl_sec.h>
  22
  23#include "../common/qixis.h"
  24#include "ls2080ardb_qixis.h"
  25#include "../common/vid.h"
  26
  27#define PIN_MUX_SEL_SDHC        0x00
  28#define PIN_MUX_SEL_DSPI        0x0a
  29
  30#define SET_SDHC_MUX_SEL(reg, value)    ((reg & 0xf0) | value)
  31DECLARE_GLOBAL_DATA_PTR;
  32
  33enum {
  34        MUX_TYPE_SDHC,
  35        MUX_TYPE_DSPI,
  36};
  37
  38unsigned long long get_qixis_addr(void)
  39{
  40        unsigned long long addr;
  41
  42        if (gd->flags & GD_FLG_RELOC)
  43                addr = QIXIS_BASE_PHYS;
  44        else
  45                addr = QIXIS_BASE_PHYS_EARLY;
  46
  47        /*
  48         * IFC address under 256MB is mapped to 0x30000000, any address above
  49         * is mapped to 0x5_10000000 up to 4GB.
  50         */
  51        addr = addr  > 0x10000000 ? addr + 0x500000000ULL : addr + 0x30000000;
  52
  53        return addr;
  54}
  55
  56int checkboard(void)
  57{
  58        u8 sw;
  59        char buf[15];
  60
  61        cpu_name(buf);
  62        printf("Board: %s-RDB, ", buf);
  63
  64        sw = QIXIS_READ(arch);
  65        printf("Board Arch: V%d, ", sw >> 4);
  66        printf("Board version: %c, boot from ", (sw & 0xf) + 'A');
  67
  68        sw = QIXIS_READ(brdcfg[0]);
  69        sw = (sw & QIXIS_LBMAP_MASK) >> QIXIS_LBMAP_SHIFT;
  70
  71        if (sw < 0x8)
  72                printf("vBank: %d\n", sw);
  73        else if (sw == 0x9)
  74                puts("NAND\n");
  75        else
  76                printf("invalid setting of SW%u\n", QIXIS_LBMAP_SWITCH);
  77
  78        printf("FPGA: v%d.%d\n", QIXIS_READ(scver), QIXIS_READ(tagdata));
  79
  80        puts("SERDES1 Reference : ");
  81        printf("Clock1 = 156.25MHz ");
  82        printf("Clock2 = 156.25MHz");
  83
  84        puts("\nSERDES2 Reference : ");
  85        printf("Clock1 = 100MHz ");
  86        printf("Clock2 = 100MHz\n");
  87
  88        return 0;
  89}
  90
  91unsigned long get_board_sys_clk(void)
  92{
  93        u8 sysclk_conf = QIXIS_READ(brdcfg[1]);
  94
  95        switch (sysclk_conf & 0x0F) {
  96        case QIXIS_SYSCLK_83:
  97                return 83333333;
  98        case QIXIS_SYSCLK_100:
  99                return 100000000;
 100        case QIXIS_SYSCLK_125:
 101                return 125000000;
 102        case QIXIS_SYSCLK_133:
 103                return 133333333;
 104        case QIXIS_SYSCLK_150:
 105                return 150000000;
 106        case QIXIS_SYSCLK_160:
 107                return 160000000;
 108        case QIXIS_SYSCLK_166:
 109                return 166666666;
 110        }
 111        return 66666666;
 112}
 113
 114int select_i2c_ch_pca9547(u8 ch)
 115{
 116        int ret;
 117
 118        ret = i2c_write(I2C_MUX_PCA_ADDR_PRI, 0, 1, &ch, 1);
 119        if (ret) {
 120                puts("PCA: failed to select proper channel\n");
 121                return ret;
 122        }
 123
 124        return 0;
 125}
 126
 127int i2c_multiplexer_select_vid_channel(u8 channel)
 128{
 129        return select_i2c_ch_pca9547(channel);
 130}
 131
 132int config_board_mux(int ctrl_type)
 133{
 134        u8 reg5;
 135
 136        reg5 = QIXIS_READ(brdcfg[5]);
 137
 138        switch (ctrl_type) {
 139        case MUX_TYPE_SDHC:
 140                reg5 = SET_SDHC_MUX_SEL(reg5, PIN_MUX_SEL_SDHC);
 141                break;
 142        case MUX_TYPE_DSPI:
 143                reg5 = SET_SDHC_MUX_SEL(reg5, PIN_MUX_SEL_DSPI);
 144                break;
 145        default:
 146                printf("Wrong mux interface type\n");
 147                return -1;
 148        }
 149
 150        QIXIS_WRITE(brdcfg[5], reg5);
 151
 152        return 0;
 153}
 154
 155int board_init(void)
 156{
 157        char *env_hwconfig;
 158        u32 __iomem *dcfg_ccsr = (u32 __iomem *)DCFG_BASE;
 159#ifdef CONFIG_FSL_MC_ENET
 160        u32 __iomem *irq_ccsr = (u32 __iomem *)ISC_BASE;
 161#endif
 162        u32 val;
 163
 164        init_final_memctl_regs();
 165
 166        val = in_le32(dcfg_ccsr + DCFG_RCWSR13 / 4);
 167
 168        env_hwconfig = getenv("hwconfig");
 169
 170        if (hwconfig_f("dspi", env_hwconfig) &&
 171            DCFG_RCWSR13_DSPI == (val & (u32)(0xf << 8)))
 172                config_board_mux(MUX_TYPE_DSPI);
 173        else
 174                config_board_mux(MUX_TYPE_SDHC);
 175
 176#ifdef CONFIG_ENV_IS_NOWHERE
 177        gd->env_addr = (ulong)&default_environment[0];
 178#endif
 179        select_i2c_ch_pca9547(I2C_MUX_CH_DEFAULT);
 180
 181        QIXIS_WRITE(rst_ctl, QIXIS_RST_CTL_RESET_EN);
 182
 183#ifdef CONFIG_FSL_MC_ENET
 184        /* invert AQR405 IRQ pins polarity */
 185        out_le32(irq_ccsr + IRQCR_OFFSET / 4, AQR405_IRQ_MASK);
 186#endif
 187
 188        return 0;
 189}
 190
 191int board_early_init_f(void)
 192{
 193        fsl_lsch3_early_init_f();
 194        return 0;
 195}
 196
 197int misc_init_r(void)
 198{
 199        if (hwconfig("sdhc"))
 200                config_board_mux(MUX_TYPE_SDHC);
 201
 202        if (adjust_vdd(0))
 203                printf("Warning: Adjusting core voltage failed.\n");
 204
 205        return 0;
 206}
 207
 208void detail_board_ddr_info(void)
 209{
 210        puts("\nDDR    ");
 211        print_size(gd->bd->bi_dram[0].size + gd->bd->bi_dram[1].size, "");
 212        print_ddr_info(0);
 213#ifdef CONFIG_SYS_FSL_HAS_DP_DDR
 214        if (soc_has_dp_ddr() && gd->bd->bi_dram[2].size) {
 215                puts("\nDP-DDR ");
 216                print_size(gd->bd->bi_dram[2].size, "");
 217                print_ddr_info(CONFIG_DP_DDR_CTRL);
 218        }
 219#endif
 220}
 221
 222int dram_init(void)
 223{
 224        gd->ram_size = initdram(0);
 225
 226        return 0;
 227}
 228
 229#if defined(CONFIG_ARCH_MISC_INIT)
 230int arch_misc_init(void)
 231{
 232#ifdef CONFIG_FSL_DEBUG_SERVER
 233        debug_server_init();
 234#endif
 235#ifdef CONFIG_FSL_CAAM
 236        sec_init();
 237#endif
 238        return 0;
 239}
 240#endif
 241
 242#ifdef CONFIG_FSL_MC_ENET
 243void fdt_fixup_board_enet(void *fdt)
 244{
 245        int offset;
 246
 247        offset = fdt_path_offset(fdt, "/soc/fsl-mc");
 248
 249        if (offset < 0)
 250                offset = fdt_path_offset(fdt, "/fsl-mc");
 251
 252        if (offset < 0) {
 253                printf("%s: ERROR: fsl-mc node not found in device tree (error %d)\n",
 254                       __func__, offset);
 255                return;
 256        }
 257
 258        if (get_mc_boot_status() == 0)
 259                fdt_status_okay(fdt, offset);
 260        else
 261                fdt_status_fail(fdt, offset);
 262}
 263#endif
 264
 265#ifdef CONFIG_OF_BOARD_SETUP
 266int ft_board_setup(void *blob, bd_t *bd)
 267{
 268#ifdef CONFIG_FSL_MC_ENET
 269        int err;
 270#endif
 271        u64 base[CONFIG_NR_DRAM_BANKS];
 272        u64 size[CONFIG_NR_DRAM_BANKS];
 273
 274        ft_cpu_setup(blob, bd);
 275
 276        /* fixup DT for the two GPP DDR banks */
 277        base[0] = gd->bd->bi_dram[0].start;
 278        size[0] = gd->bd->bi_dram[0].size;
 279        base[1] = gd->bd->bi_dram[1].start;
 280        size[1] = gd->bd->bi_dram[1].size;
 281
 282        fdt_fixup_memory_banks(blob, base, size, 2);
 283
 284        fdt_fixup_dr_usb(blob, bd);
 285
 286#ifdef CONFIG_FSL_MC_ENET
 287        fdt_fixup_board_enet(blob);
 288        err = fsl_mc_ldpaa_exit(bd);
 289        if (err)
 290                return err;
 291#endif
 292
 293        return 0;
 294}
 295#endif
 296
 297void qixis_dump_switch(void)
 298{
 299        int i, nr_of_cfgsw;
 300
 301        QIXIS_WRITE(cms[0], 0x00);
 302        nr_of_cfgsw = QIXIS_READ(cms[1]);
 303
 304        puts("DIP switch settings dump:\n");
 305        for (i = 1; i <= nr_of_cfgsw; i++) {
 306                QIXIS_WRITE(cms[0], i);
 307                printf("SW%d = (0x%02x)\n", i, QIXIS_READ(cms[1]));
 308        }
 309}
 310
 311/*
 312 * Board rev C and earlier has duplicated I2C addresses for 2nd controller.
 313 * Both slots has 0x54, resulting 2nd slot unusable.
 314 */
 315void update_spd_address(unsigned int ctrl_num,
 316                        unsigned int slot,
 317                        unsigned int *addr)
 318{
 319        u8 sw;
 320
 321        sw = QIXIS_READ(arch);
 322        if ((sw & 0xf) < 0x3) {
 323                if (ctrl_num == 1 && slot == 0)
 324                        *addr = SPD_EEPROM_ADDRESS4;
 325                else if (ctrl_num == 1 && slot == 1)
 326                        *addr = SPD_EEPROM_ADDRESS3;
 327        }
 328}
 329