uboot/board/freescale/lx2160a/lx2160a.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright 2018-2021 NXP
   4 */
   5
   6#include <common.h>
   7#include <clock_legacy.h>
   8#include <dm.h>
   9#include <init.h>
  10#include <asm/global_data.h>
  11#include <dm/platform_data/serial_pl01x.h>
  12#include <i2c.h>
  13#include <malloc.h>
  14#include <errno.h>
  15#include <netdev.h>
  16#include <fsl_ddr.h>
  17#include <fsl_sec.h>
  18#include <asm/io.h>
  19#include <fdt_support.h>
  20#include <linux/bitops.h>
  21#include <linux/libfdt.h>
  22#include <linux/delay.h>
  23#include <fsl-mc/fsl_mc.h>
  24#include <env_internal.h>
  25#include <efi_loader.h>
  26#include <asm/arch/mmu.h>
  27#include <hwconfig.h>
  28#include <asm/arch/clock.h>
  29#include <asm/arch/config.h>
  30#include <asm/arch/fsl_serdes.h>
  31#include <asm/arch/soc.h>
  32#include "../common/i2c_mux.h"
  33
  34#include "../common/qixis.h"
  35#include "../common/vid.h"
  36#include <fsl_immap.h>
  37#include <asm/arch-fsl-layerscape/fsl_icid.h>
  38#include "lx2160a.h"
  39
  40#ifdef CONFIG_EMC2305
  41#include "../common/emc2305.h"
  42#endif
  43
  44#if defined(CONFIG_TARGET_LX2160AQDS) || defined(CONFIG_TARGET_LX2162AQDS)
  45#define CFG_MUX_I2C_SDHC(reg, value)            ((reg & 0x3f) | value)
  46#define SET_CFG_MUX1_SDHC1_SDHC(reg)            (reg & 0x3f)
  47#define SET_CFG_MUX2_SDHC1_SPI(reg, value)      ((reg & 0xcf) | value)
  48#define SET_CFG_MUX3_SDHC1_SPI(reg, value)      ((reg & 0xf8) | value)
  49#define SET_CFG_MUX_SDHC2_DSPI(reg, value)      ((reg & 0xf8) | value)
  50#define SET_CFG_MUX1_SDHC1_DSPI(reg, value)     ((reg & 0x3f) | value)
  51#define SDHC1_BASE_PMUX_DSPI                    2
  52#define SDHC2_BASE_PMUX_DSPI                    2
  53#define IIC5_PMUX_SPI3                          3
  54#endif /* CONFIG_TARGET_LX2160AQDS or CONFIG_TARGET_LX2162AQDS */
  55
  56DECLARE_GLOBAL_DATA_PTR;
  57
  58static struct pl01x_serial_plat serial0 = {
  59#if CONFIG_CONS_INDEX == 0
  60        .base = CONFIG_SYS_SERIAL0,
  61#elif CONFIG_CONS_INDEX == 1
  62        .base = CONFIG_SYS_SERIAL1,
  63#else
  64#error "Unsupported console index value."
  65#endif
  66        .type = TYPE_PL011,
  67};
  68
  69U_BOOT_DRVINFO(nxp_serial0) = {
  70        .name = "serial_pl01x",
  71        .plat = &serial0,
  72};
  73
  74static struct pl01x_serial_plat serial1 = {
  75        .base = CONFIG_SYS_SERIAL1,
  76        .type = TYPE_PL011,
  77};
  78
  79U_BOOT_DRVINFO(nxp_serial1) = {
  80        .name = "serial_pl01x",
  81        .plat = &serial1,
  82};
  83
  84static void uart_get_clock(void)
  85{
  86        serial0.clock = get_serial_clock();
  87        serial1.clock = get_serial_clock();
  88}
  89
  90int board_early_init_f(void)
  91{
  92#if defined(CONFIG_SYS_I2C_EARLY_INIT) && defined(CONFIG_SPL_BUILD)
  93        i2c_early_init_f();
  94#endif
  95        /* get required clock for UART IP */
  96        uart_get_clock();
  97
  98#ifdef CONFIG_EMC2305
  99        select_i2c_ch_pca9547(I2C_MUX_CH_EMC2305, 0);
 100        emc2305_init(I2C_EMC2305_ADDR);
 101        set_fan_speed(I2C_EMC2305_PWM, I2C_EMC2305_ADDR);
 102        select_i2c_ch_pca9547(I2C_MUX_CH_DEFAULT, 0);
 103#endif
 104
 105        fsl_lsch3_early_init_f();
 106        return 0;
 107}
 108
 109#ifdef CONFIG_OF_BOARD_FIXUP
 110int board_fix_fdt(void *fdt)
 111{
 112        char *reg_names, *reg_name;
 113        int names_len, old_name_len, new_name_len, remaining_names_len;
 114        struct str_map {
 115                char *old_str;
 116                char *new_str;
 117        } reg_names_map[] = {
 118                { "ccsr", "dbi" },
 119                { "pf_ctrl", "ctrl" }
 120        };
 121        int off = -1, i = 0;
 122
 123        if (IS_SVR_REV(get_svr(), 1, 0))
 124                return 0;
 125
 126        off = fdt_node_offset_by_compatible(fdt, -1, "fsl,lx2160a-pcie");
 127        while (off != -FDT_ERR_NOTFOUND) {
 128                fdt_setprop(fdt, off, "compatible", "fsl,ls-pcie",
 129                            strlen("fsl,ls-pcie") + 1);
 130
 131                reg_names = (char *)fdt_getprop(fdt, off, "reg-names",
 132                                                &names_len);
 133                if (!reg_names)
 134                        continue;
 135
 136                reg_name = reg_names;
 137                remaining_names_len = names_len - (reg_name - reg_names);
 138                i = 0;
 139                while ((i < ARRAY_SIZE(reg_names_map)) && remaining_names_len) {
 140                        old_name_len = strlen(reg_names_map[i].old_str);
 141                        new_name_len = strlen(reg_names_map[i].new_str);
 142                        if (memcmp(reg_name, reg_names_map[i].old_str,
 143                                   old_name_len) == 0) {
 144                                /* first only leave required bytes for new_str
 145                                 * and copy rest of the string after it
 146                                 */
 147                                memcpy(reg_name + new_name_len,
 148                                       reg_name + old_name_len,
 149                                       remaining_names_len - old_name_len);
 150                                /* Now copy new_str */
 151                                memcpy(reg_name, reg_names_map[i].new_str,
 152                                       new_name_len);
 153                                names_len -= old_name_len;
 154                                names_len += new_name_len;
 155                                i++;
 156                        }
 157
 158                        reg_name = memchr(reg_name, '\0', remaining_names_len);
 159                        if (!reg_name)
 160                                break;
 161
 162                        reg_name += 1;
 163
 164                        remaining_names_len = names_len -
 165                                              (reg_name - reg_names);
 166                }
 167
 168                fdt_setprop(fdt, off, "reg-names", reg_names, names_len);
 169                off = fdt_node_offset_by_compatible(fdt, off,
 170                                                    "fsl,lx2160a-pcie");
 171        }
 172
 173        return 0;
 174}
 175#endif
 176
 177#if defined(CONFIG_TARGET_LX2160AQDS) || defined(CONFIG_TARGET_LX2162AQDS)
 178void esdhc_dspi_status_fixup(void *blob)
 179{
 180        const char esdhc0_path[] = "/soc/esdhc@2140000";
 181        const char esdhc1_path[] = "/soc/esdhc@2150000";
 182        const char dspi0_path[] = "/soc/spi@2100000";
 183        const char dspi1_path[] = "/soc/spi@2110000";
 184        const char dspi2_path[] = "/soc/spi@2120000";
 185
 186        struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
 187        u32 sdhc1_base_pmux;
 188        u32 sdhc2_base_pmux;
 189        u32 iic5_pmux;
 190
 191        /* Check RCW field sdhc1_base_pmux to enable/disable
 192         * esdhc0/dspi0 DT node
 193         */
 194        sdhc1_base_pmux = gur_in32(&gur->rcwsr[FSL_CHASSIS3_RCWSR12_REGSR - 1])
 195                & FSL_CHASSIS3_SDHC1_BASE_PMUX_MASK;
 196        sdhc1_base_pmux >>= FSL_CHASSIS3_SDHC1_BASE_PMUX_SHIFT;
 197
 198        if (sdhc1_base_pmux == SDHC1_BASE_PMUX_DSPI) {
 199                do_fixup_by_path(blob, dspi0_path, "status", "okay",
 200                                 sizeof("okay"), 1);
 201                do_fixup_by_path(blob, esdhc0_path, "status", "disabled",
 202                                 sizeof("disabled"), 1);
 203        } else {
 204                do_fixup_by_path(blob, esdhc0_path, "status", "okay",
 205                                 sizeof("okay"), 1);
 206                do_fixup_by_path(blob, dspi0_path, "status", "disabled",
 207                                 sizeof("disabled"), 1);
 208        }
 209
 210        /* Check RCW field sdhc2_base_pmux to enable/disable
 211         * esdhc1/dspi1 DT node
 212         */
 213        sdhc2_base_pmux = gur_in32(&gur->rcwsr[FSL_CHASSIS3_RCWSR13_REGSR - 1])
 214                & FSL_CHASSIS3_SDHC2_BASE_PMUX_MASK;
 215        sdhc2_base_pmux >>= FSL_CHASSIS3_SDHC2_BASE_PMUX_SHIFT;
 216
 217        if (sdhc2_base_pmux == SDHC2_BASE_PMUX_DSPI) {
 218                do_fixup_by_path(blob, dspi1_path, "status", "okay",
 219                                 sizeof("okay"), 1);
 220                do_fixup_by_path(blob, esdhc1_path, "status", "disabled",
 221                                 sizeof("disabled"), 1);
 222        } else {
 223                do_fixup_by_path(blob, esdhc1_path, "status", "okay",
 224                                 sizeof("okay"), 1);
 225                do_fixup_by_path(blob, dspi1_path, "status", "disabled",
 226                                 sizeof("disabled"), 1);
 227        }
 228
 229        /* Check RCW field IIC5 to enable dspi2 DT node */
 230        iic5_pmux = gur_in32(&gur->rcwsr[FSL_CHASSIS3_RCWSR12_REGSR - 1])
 231                & FSL_CHASSIS3_IIC5_PMUX_MASK;
 232        iic5_pmux >>= FSL_CHASSIS3_IIC5_PMUX_SHIFT;
 233
 234        if (iic5_pmux == IIC5_PMUX_SPI3)
 235                do_fixup_by_path(blob, dspi2_path, "status", "okay",
 236                                 sizeof("okay"), 1);
 237        else
 238                do_fixup_by_path(blob, dspi2_path, "status", "disabled",
 239                                 sizeof("disabled"), 1);
 240}
 241#endif
 242
 243int esdhc_status_fixup(void *blob, const char *compat)
 244{
 245#if defined(CONFIG_TARGET_LX2160AQDS) || defined(CONFIG_TARGET_LX2162AQDS)
 246        /* Enable esdhc and dspi DT nodes based on RCW fields */
 247        esdhc_dspi_status_fixup(blob);
 248#else
 249        /* Enable both esdhc DT nodes for LX2160ARDB */
 250        do_fixup_by_compat(blob, compat, "status", "okay",
 251                           sizeof("okay"), 1);
 252#endif
 253        return 0;
 254}
 255
 256#if defined(CONFIG_VID)
 257int i2c_multiplexer_select_vid_channel(u8 channel)
 258{
 259        return select_i2c_ch_pca9547(channel, 0);
 260}
 261
 262int init_func_vid(void)
 263{
 264        int set_vid;
 265
 266        if (IS_SVR_REV(get_svr(), 1, 0))
 267                set_vid = adjust_vdd(800);
 268        else
 269                set_vid = adjust_vdd(0);
 270
 271        if (set_vid < 0)
 272                printf("core voltage not adjusted\n");
 273
 274        return 0;
 275}
 276#endif
 277
 278int checkboard(void)
 279{
 280        enum boot_src src = get_boot_src();
 281        char buf[64];
 282        u8 sw;
 283#if defined(CONFIG_TARGET_LX2160AQDS) || defined(CONFIG_TARGET_LX2162AQDS)
 284        int clock;
 285        static const char *const freq[] = {"100", "125", "156.25",
 286                                           "161.13", "322.26", "", "", "",
 287                                           "", "", "", "", "", "", "",
 288                                           "100 separate SSCG"};
 289#endif
 290
 291        cpu_name(buf);
 292#if defined(CONFIG_TARGET_LX2160AQDS) || defined(CONFIG_TARGET_LX2162AQDS)
 293        printf("Board: %s-QDS, ", buf);
 294#else
 295        printf("Board: %s-RDB, ", buf);
 296#endif
 297
 298        sw = QIXIS_READ(arch);
 299        printf("Board version: %c, boot from ", (sw & 0xf) - 1 + 'A');
 300
 301        if (src == BOOT_SOURCE_SD_MMC) {
 302                puts("SD\n");
 303        } else if (src == BOOT_SOURCE_SD_MMC2) {
 304                puts("eMMC\n");
 305        } else {
 306                sw = QIXIS_READ(brdcfg[0]);
 307                sw = (sw >> QIXIS_XMAP_SHIFT) & QIXIS_XMAP_MASK;
 308                switch (sw) {
 309                case 0:
 310                case 4:
 311                        puts("FlexSPI DEV#0\n");
 312                        break;
 313                case 1:
 314                        puts("FlexSPI DEV#1\n");
 315                        break;
 316                case 2:
 317                case 3:
 318                        puts("FlexSPI EMU\n");
 319                        break;
 320                default:
 321                        printf("invalid setting, xmap: %d\n", sw);
 322                        break;
 323                }
 324        }
 325#if defined(CONFIG_TARGET_LX2160ARDB)
 326        printf("FPGA: v%d.%d\n", QIXIS_READ(scver), QIXIS_READ(tagdata));
 327
 328        puts("SERDES1 Reference: Clock1 = 161.13MHz Clock2 = 161.13MHz\n");
 329        puts("SERDES2 Reference: Clock1 = 100MHz Clock2 = 100MHz\n");
 330        puts("SERDES3 Reference: Clock1 = 100MHz Clock2 = 100MHz\n");
 331#else
 332        printf("FPGA: v%d (%s), build %d",
 333               (int)QIXIS_READ(scver), qixis_read_tag(buf),
 334               (int)qixis_read_minor());
 335        /* the timestamp string contains "\n" at the end */
 336        printf(" on %s", qixis_read_time(buf));
 337
 338        puts("SERDES1 Reference : ");
 339        sw = QIXIS_READ(brdcfg[2]);
 340        clock = sw >> 4;
 341        printf("Clock1 = %sMHz ", freq[clock]);
 342#if defined(CONFIG_TARGET_LX2160AQDS)
 343        clock = sw & 0x0f;
 344        printf("Clock2 = %sMHz", freq[clock]);
 345#endif
 346        sw = QIXIS_READ(brdcfg[3]);
 347        puts("\nSERDES2 Reference : ");
 348        clock = sw >> 4;
 349        printf("Clock1 = %sMHz ", freq[clock]);
 350        clock = sw & 0x0f;
 351        printf("Clock2 = %sMHz\n", freq[clock]);
 352#if defined(CONFIG_TARGET_LX2160AQDS)
 353        sw = QIXIS_READ(brdcfg[12]);
 354        puts("SERDES3 Reference : ");
 355        clock = sw >> 4;
 356        printf("Clock1 = %sMHz Clock2 = %sMHz\n", freq[clock], freq[clock]);
 357#endif
 358#endif
 359        return 0;
 360}
 361
 362#if defined(CONFIG_TARGET_LX2160AQDS) || defined(CONFIG_TARGET_LX2162AQDS)
 363/*
 364 * implementation of CONFIG_ESDHC_DETECT_QUIRK Macro.
 365 */
 366u8 qixis_esdhc_detect_quirk(void)
 367{
 368        /*
 369         * SDHC1 Card ID:
 370         * Specifies the type of card installed in the SDHC1 adapter slot.
 371         * 000= (reserved)
 372         * 001= eMMC V4.5 adapter is installed.
 373         * 010= SD/MMC 3.3V adapter is installed.
 374         * 011= eMMC V4.4 adapter is installed.
 375         * 100= eMMC V5.0 adapter is installed.
 376         * 101= MMC card/Legacy (3.3V) adapter is installed.
 377         * 110= SDCard V2/V3 adapter installed.
 378         * 111= no adapter is installed.
 379         */
 380        return ((QIXIS_READ(sdhc1) & QIXIS_SDID_MASK) !=
 381                 QIXIS_ESDHC_NO_ADAPTER);
 382}
 383
 384static void esdhc_adapter_card_ident(void)
 385{
 386        u8 card_id, val;
 387
 388        val = QIXIS_READ(sdhc1);
 389        card_id = val & QIXIS_SDID_MASK;
 390
 391        switch (card_id) {
 392        case QIXIS_ESDHC_ADAPTER_TYPE_SD:
 393                /* Power cycle to card */
 394                val &= ~QIXIS_SDHC1_S1V3;
 395                QIXIS_WRITE(sdhc1, val);
 396                mdelay(1);
 397                val |= QIXIS_SDHC1_S1V3;
 398                QIXIS_WRITE(sdhc1, val);
 399                /* Route to SDHC1_VS */
 400                val = QIXIS_READ(brdcfg[11]);
 401                val |= QIXIS_SDHC1_VS;
 402                QIXIS_WRITE(brdcfg[11], val);
 403                break;
 404        default:
 405                break;
 406        }
 407}
 408
 409int config_board_mux(void)
 410{
 411        u8 reg11, reg5, reg13;
 412        struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
 413        u32 sdhc1_base_pmux;
 414        u32 sdhc2_base_pmux;
 415        u32 iic5_pmux;
 416
 417        /* Routes {I2C2_SCL, I2C2_SDA} to SDHC1 as {SDHC1_CD_B, SDHC1_WP}.
 418         * Routes {I2C3_SCL, I2C3_SDA} to CAN transceiver as {CAN1_TX,CAN1_RX}.
 419         * Routes {I2C4_SCL, I2C4_SDA} to CAN transceiver as {CAN2_TX,CAN2_RX}.
 420         * Qixis and remote systems are isolated from the I2C1 bus.
 421         * Processor connections are still available.
 422         * SPI2 CS2_B controls EN25S64 SPI memory device.
 423         * SPI3 CS2_B controls EN25S64 SPI memory device.
 424         * EC2 connects to PHY #2 using RGMII protocol.
 425         * CLK_OUT connects to FPGA for clock measurement.
 426         */
 427
 428        reg5 = QIXIS_READ(brdcfg[5]);
 429        reg5 = CFG_MUX_I2C_SDHC(reg5, 0x40);
 430        QIXIS_WRITE(brdcfg[5], reg5);
 431
 432        /* Check RCW field sdhc1_base_pmux
 433         * esdhc0 : sdhc1_base_pmux = 0
 434         * dspi0  : sdhc1_base_pmux = 2
 435         */
 436        sdhc1_base_pmux = gur_in32(&gur->rcwsr[FSL_CHASSIS3_RCWSR12_REGSR - 1])
 437                & FSL_CHASSIS3_SDHC1_BASE_PMUX_MASK;
 438        sdhc1_base_pmux >>= FSL_CHASSIS3_SDHC1_BASE_PMUX_SHIFT;
 439
 440        if (sdhc1_base_pmux == SDHC1_BASE_PMUX_DSPI) {
 441                reg11 = QIXIS_READ(brdcfg[11]);
 442                reg11 = SET_CFG_MUX1_SDHC1_DSPI(reg11, 0x40);
 443                QIXIS_WRITE(brdcfg[11], reg11);
 444        } else {
 445                /* - Routes {SDHC1_CMD, SDHC1_CLK } to SDHC1 adapter slot.
 446                 *          {SDHC1_DAT3, SDHC1_DAT2} to SDHC1 adapter slot.
 447                 *          {SDHC1_DAT1, SDHC1_DAT0} to SDHC1 adapter slot.
 448                 */
 449                reg11 = QIXIS_READ(brdcfg[11]);
 450                reg11 = SET_CFG_MUX1_SDHC1_SDHC(reg11);
 451                QIXIS_WRITE(brdcfg[11], reg11);
 452        }
 453
 454        /* Check RCW field sdhc2_base_pmux
 455         * esdhc1 : sdhc2_base_pmux = 0 (default)
 456         * dspi1  : sdhc2_base_pmux = 2
 457         */
 458        sdhc2_base_pmux = gur_in32(&gur->rcwsr[FSL_CHASSIS3_RCWSR13_REGSR - 1])
 459                & FSL_CHASSIS3_SDHC2_BASE_PMUX_MASK;
 460        sdhc2_base_pmux >>= FSL_CHASSIS3_SDHC2_BASE_PMUX_SHIFT;
 461
 462        if (sdhc2_base_pmux == SDHC2_BASE_PMUX_DSPI) {
 463                reg13 = QIXIS_READ(brdcfg[13]);
 464                reg13 = SET_CFG_MUX_SDHC2_DSPI(reg13, 0x01);
 465                QIXIS_WRITE(brdcfg[13], reg13);
 466        } else {
 467                reg13 = QIXIS_READ(brdcfg[13]);
 468                reg13 = SET_CFG_MUX_SDHC2_DSPI(reg13, 0x00);
 469                QIXIS_WRITE(brdcfg[13], reg13);
 470        }
 471
 472        /* Check RCW field IIC5 to enable dspi2 DT nodei
 473         * dspi2: IIC5 = 3
 474         */
 475        iic5_pmux = gur_in32(&gur->rcwsr[FSL_CHASSIS3_RCWSR12_REGSR - 1])
 476                & FSL_CHASSIS3_IIC5_PMUX_MASK;
 477        iic5_pmux >>= FSL_CHASSIS3_IIC5_PMUX_SHIFT;
 478
 479        if (iic5_pmux == IIC5_PMUX_SPI3) {
 480                /* - Routes {SDHC1_DAT4} to SPI3 devices as {SPI3_M_CS0_B}. */
 481                reg11 = QIXIS_READ(brdcfg[11]);
 482                reg11 = SET_CFG_MUX2_SDHC1_SPI(reg11, 0x10);
 483                QIXIS_WRITE(brdcfg[11], reg11);
 484
 485                /* - Routes {SDHC1_DAT5, SDHC1_DAT6} nowhere.
 486                 * {SDHC1_DAT7, SDHC1_DS } to {nothing, SPI3_M0_CLK }.
 487                 * {I2C5_SCL, I2C5_SDA } to {SPI3_M0_MOSI, SPI3_M0_MISO}.
 488                 */
 489                reg11 = QIXIS_READ(brdcfg[11]);
 490                reg11 = SET_CFG_MUX3_SDHC1_SPI(reg11, 0x01);
 491                QIXIS_WRITE(brdcfg[11], reg11);
 492        } else {
 493                /*
 494                 * If {SDHC1_DAT4} has been configured to route to SDHC1_VS,
 495                 * do not change it.
 496                 * Otherwise route {SDHC1_DAT4} to SDHC1 adapter slot.
 497                 */
 498                reg11 = QIXIS_READ(brdcfg[11]);
 499                if ((reg11 & 0x30) != 0x30) {
 500                        reg11 = SET_CFG_MUX2_SDHC1_SPI(reg11, 0x00);
 501                        QIXIS_WRITE(brdcfg[11], reg11);
 502                }
 503
 504                /* - Routes {SDHC1_DAT5, SDHC1_DAT6} to SDHC1 adapter slot.
 505                 * {SDHC1_DAT7, SDHC1_DS } to SDHC1 adapter slot.
 506                 * {I2C5_SCL, I2C5_SDA } to SDHC1 adapter slot.
 507                 */
 508                reg11 = QIXIS_READ(brdcfg[11]);
 509                reg11 = SET_CFG_MUX3_SDHC1_SPI(reg11, 0x00);
 510                QIXIS_WRITE(brdcfg[11], reg11);
 511        }
 512
 513        return 0;
 514}
 515
 516int board_early_init_r(void)
 517{
 518        esdhc_adapter_card_ident();
 519        return 0;
 520}
 521#elif defined(CONFIG_TARGET_LX2160ARDB)
 522int config_board_mux(void)
 523{
 524        u8 brdcfg;
 525
 526        brdcfg = QIXIS_READ(brdcfg[4]);
 527        /* The BRDCFG4 register controls general board configuration.
 528         *|-------------------------------------------|
 529         *|Field  | Function                          |
 530         *|-------------------------------------------|
 531         *|5      | CAN I/O Enable (net CFG_CAN_EN_B):|
 532         *|CAN_EN | 0= CAN transceivers are disabled. |
 533         *|       | 1= CAN transceivers are enabled.  |
 534         *|-------------------------------------------|
 535         */
 536        brdcfg |= BIT_MASK(5);
 537        QIXIS_WRITE(brdcfg[4], brdcfg);
 538
 539        return 0;
 540}
 541#else
 542int config_board_mux(void)
 543{
 544        return 0;
 545}
 546#endif
 547
 548unsigned long get_board_sys_clk(void)
 549{
 550#if defined(CONFIG_TARGET_LX2160AQDS) || defined(CONFIG_TARGET_LX2162AQDS)
 551        u8 sysclk_conf = QIXIS_READ(brdcfg[1]);
 552
 553        switch (sysclk_conf & 0x03) {
 554        case QIXIS_SYSCLK_100:
 555                return 100000000;
 556        case QIXIS_SYSCLK_125:
 557                return 125000000;
 558        case QIXIS_SYSCLK_133:
 559                return 133333333;
 560        }
 561        return 100000000;
 562#else
 563        return 100000000;
 564#endif
 565}
 566
 567unsigned long get_board_ddr_clk(void)
 568{
 569#if defined(CONFIG_TARGET_LX2160AQDS) || defined(CONFIG_TARGET_LX2162AQDS)
 570        u8 ddrclk_conf = QIXIS_READ(brdcfg[1]);
 571
 572        switch ((ddrclk_conf & 0x30) >> 4) {
 573        case QIXIS_DDRCLK_100:
 574                return 100000000;
 575        case QIXIS_DDRCLK_125:
 576                return 125000000;
 577        case QIXIS_DDRCLK_133:
 578                return 133333333;
 579        }
 580        return 100000000;
 581#else
 582        return 100000000;
 583#endif
 584}
 585
 586int board_init(void)
 587{
 588#if defined(CONFIG_FSL_MC_ENET) && defined(CONFIG_TARGET_LX2160ARDB)
 589        u32 __iomem *irq_ccsr = (u32 __iomem *)ISC_BASE;
 590#endif
 591
 592        select_i2c_ch_pca9547(I2C_MUX_CH_DEFAULT, 0);
 593
 594#if defined(CONFIG_FSL_MC_ENET) && defined(CONFIG_TARGET_LX2160ARDB)
 595        /* invert AQR107 IRQ pins polarity */
 596        out_le32(irq_ccsr + IRQCR_OFFSET / 4, AQR107_IRQ_MASK);
 597#endif
 598
 599#ifdef CONFIG_FSL_CAAM
 600        sec_init();
 601#endif
 602
 603#if !defined(CONFIG_SYS_EARLY_PCI_INIT) && defined(CONFIG_DM_ETH)
 604        pci_init();
 605#endif
 606        return 0;
 607}
 608
 609void detail_board_ddr_info(void)
 610{
 611        int i;
 612        u64 ddr_size = 0;
 613
 614        puts("\nDDR    ");
 615        for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++)
 616                ddr_size += gd->bd->bi_dram[i].size;
 617        print_size(ddr_size, "");
 618        print_ddr_info(0);
 619}
 620
 621#ifdef CONFIG_MISC_INIT_R
 622int misc_init_r(void)
 623{
 624        config_board_mux();
 625
 626        return 0;
 627}
 628#endif
 629
 630#ifdef CONFIG_VID
 631u16 soc_get_fuse_vid(int vid_index)
 632{
 633        static const u16 vdd[32] = {
 634                8250,
 635                7875,
 636                7750,
 637                0,      /* reserved */
 638                0,      /* reserved */
 639                0,      /* reserved */
 640                0,      /* reserved */
 641                0,      /* reserved */
 642                0,      /* reserved */
 643                0,      /* reserved */
 644                0,      /* reserved */
 645                0,      /* reserved */
 646                0,      /* reserved */
 647                0,      /* reserved */
 648                0,      /* reserved */
 649                0,      /* reserved */
 650                8000,
 651                8125,
 652                8250,
 653                0,      /* reserved */
 654                8500,
 655                0,      /* reserved */
 656                0,      /* reserved */
 657                0,      /* reserved */
 658                0,      /* reserved */
 659                0,      /* reserved */
 660                0,      /* reserved */
 661                0,      /* reserved */
 662                0,      /* reserved */
 663                0,      /* reserved */
 664                0,      /* reserved */
 665                0,      /* reserved */
 666        };
 667
 668        return vdd[vid_index];
 669};
 670#endif
 671
 672#ifdef CONFIG_FSL_MC_ENET
 673extern int fdt_fixup_board_phy(void *fdt);
 674
 675void fdt_fixup_board_enet(void *fdt)
 676{
 677        int offset;
 678
 679        offset = fdt_path_offset(fdt, "/soc/fsl-mc");
 680
 681        if (offset < 0)
 682                offset = fdt_path_offset(fdt, "/fsl-mc");
 683
 684        if (offset < 0) {
 685                printf("%s: fsl-mc node not found in device tree (error %d)\n",
 686                       __func__, offset);
 687                return;
 688        }
 689
 690        if (get_mc_boot_status() == 0 &&
 691            (is_lazy_dpl_addr_valid() || get_dpl_apply_status() == 0)) {
 692                fdt_status_okay(fdt, offset);
 693#ifndef CONFIG_DM_ETH
 694                fdt_fixup_board_phy(fdt);
 695#endif
 696        } else {
 697                fdt_status_fail(fdt, offset);
 698        }
 699}
 700
 701void board_quiesce_devices(void)
 702{
 703        fsl_mc_ldpaa_exit(gd->bd);
 704}
 705#endif
 706
 707#if CONFIG_IS_ENABLED(TARGET_LX2160ARDB)
 708int fdt_fixup_add_thermal(void *blob, int mux_node, int channel, int reg)
 709{
 710        int err;
 711        int noff;
 712        int offset;
 713        char channel_node_name[50];
 714        char thermal_node_name[50];
 715        u32 phandle;
 716
 717        snprintf(channel_node_name, sizeof(channel_node_name),
 718                 "i2c@%x", channel);
 719        debug("channel_node_name = %s\n", channel_node_name);
 720
 721        snprintf(thermal_node_name, sizeof(thermal_node_name),
 722                 "temperature-sensor@%x", reg);
 723        debug("thermal_node_name = %s\n", thermal_node_name);
 724
 725        err = fdt_increase_size(blob, 200);
 726        if (err) {
 727                printf("fdt_increase_size: err=%s\n", fdt_strerror(err));
 728                return err;
 729        }
 730
 731        noff = fdt_subnode_offset(blob, mux_node, (const char *)
 732                                  channel_node_name);
 733        if (noff < 0) {
 734                /* channel node not found - create it */
 735                noff = fdt_add_subnode(blob, mux_node, channel_node_name);
 736                if (noff < 0) {
 737                        printf("fdt_add_subnode: err=%s\n", fdt_strerror(err));
 738                        return err;
 739                }
 740                fdt_setprop_u32 (blob, noff, "#address-cells", 1);
 741                fdt_setprop_u32 (blob, noff, "#size-cells", 0);
 742                fdt_setprop_u32 (blob, noff, "reg", channel);
 743        }
 744
 745        /* Create thermal node*/
 746        offset = fdt_add_subnode(blob, noff, thermal_node_name);
 747        fdt_setprop(blob, offset, "compatible", "nxp,sa56004",
 748                    strlen("nxp,sa56004") + 1);
 749        fdt_setprop_u32 (blob, offset, "reg", reg);
 750
 751        /* fixup phandle*/
 752        noff = fdt_node_offset_by_compatible(blob, -1, "regulator-fixed");
 753        if (noff < 0) {
 754                printf("%s : failed to get phandle\n", __func__);
 755                return noff;
 756        }
 757        phandle = fdt_get_phandle(blob, noff);
 758        fdt_setprop_u32 (blob, offset, "vcc-supply", phandle);
 759
 760        return 0;
 761}
 762
 763void fdt_fixup_delete_thermal(void *blob, int mux_node, int channel, int reg)
 764{
 765        int node;
 766        int value;
 767        int err;
 768        int subnode;
 769
 770        fdt_for_each_subnode(subnode, blob, mux_node) {
 771                value = fdtdec_get_uint(blob, subnode, "reg", -1);
 772                if (value == channel) {
 773                        /* delete thermal node */
 774                        fdt_for_each_subnode(node, blob, subnode) {
 775                                value = fdtdec_get_uint(blob, node, "reg", -1);
 776                                err = fdt_node_check_compatible(blob, node,
 777                                                                "nxp,sa56004");
 778                                if (!err && value == reg) {
 779                                        fdt_del_node(blob, node);
 780                                        break;
 781                                }
 782                        }
 783                }
 784        }
 785}
 786
 787void fdt_fixup_i2c_thermal_node(void *blob)
 788{
 789        int i2coffset;
 790        int mux_node;
 791        int reg;
 792        int err;
 793
 794        i2coffset = fdt_node_offset_by_compat_reg(blob, "fsl,vf610-i2c",
 795                                                  0x2000000);
 796        if (i2coffset != -FDT_ERR_NOTFOUND) {
 797                fdt_for_each_subnode(mux_node, blob, i2coffset) {
 798                        reg = fdtdec_get_uint(blob, mux_node, "reg", -1);
 799                        err = fdt_node_check_compatible(blob, mux_node,
 800                                                        "nxp,pca9547");
 801                        if (!err && reg == 0x77) {
 802                                fdt_fixup_delete_thermal(blob, mux_node,
 803                                                         0x3, 0x4d);
 804                                err = fdt_fixup_add_thermal(blob, mux_node,
 805                                                            0x3, 0x48);
 806                                if (err)
 807                                        printf("%s: Add thermal node failed\n",
 808                                               __func__);
 809                        }
 810                }
 811        } else {
 812                printf("%s: i2c node not found\n", __func__);
 813        }
 814}
 815#endif
 816
 817#ifdef CONFIG_OF_BOARD_SETUP
 818int ft_board_setup(void *blob, struct bd_info *bd)
 819{
 820        int i;
 821        u16 mc_memory_bank = 0;
 822
 823        u64 *base;
 824        u64 *size;
 825        u64 mc_memory_base = 0;
 826        u64 mc_memory_size = 0;
 827        u16 total_memory_banks;
 828        int err;
 829#if CONFIG_IS_ENABLED(TARGET_LX2160ARDB)
 830        u8 board_rev;
 831#endif
 832
 833        err = fdt_increase_size(blob, 512);
 834        if (err) {
 835                printf("%s fdt_increase_size: err=%s\n", __func__,
 836                       fdt_strerror(err));
 837                return err;
 838        }
 839
 840        ft_cpu_setup(blob, bd);
 841
 842        fdt_fixup_mc_ddr(&mc_memory_base, &mc_memory_size);
 843
 844        if (mc_memory_base != 0)
 845                mc_memory_bank++;
 846
 847        total_memory_banks = CONFIG_NR_DRAM_BANKS + mc_memory_bank;
 848
 849        base = calloc(total_memory_banks, sizeof(u64));
 850        size = calloc(total_memory_banks, sizeof(u64));
 851
 852        /* fixup DT for the three GPP DDR banks */
 853        for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
 854                base[i] = gd->bd->bi_dram[i].start;
 855                size[i] = gd->bd->bi_dram[i].size;
 856        }
 857
 858#ifdef CONFIG_RESV_RAM
 859        /* reduce size if reserved memory is within this bank */
 860        if (gd->arch.resv_ram >= base[0] &&
 861            gd->arch.resv_ram < base[0] + size[0])
 862                size[0] = gd->arch.resv_ram - base[0];
 863        else if (gd->arch.resv_ram >= base[1] &&
 864                 gd->arch.resv_ram < base[1] + size[1])
 865                size[1] = gd->arch.resv_ram - base[1];
 866        else if (gd->arch.resv_ram >= base[2] &&
 867                 gd->arch.resv_ram < base[2] + size[2])
 868                size[2] = gd->arch.resv_ram - base[2];
 869#endif
 870
 871        if (mc_memory_base != 0) {
 872                for (i = 0; i <= total_memory_banks; i++) {
 873                        if (base[i] == 0 && size[i] == 0) {
 874                                base[i] = mc_memory_base;
 875                                size[i] = mc_memory_size;
 876                                break;
 877                        }
 878                }
 879        }
 880
 881        fdt_fixup_memory_banks(blob, base, size, total_memory_banks);
 882
 883#ifdef CONFIG_USB_HOST
 884        fsl_fdt_fixup_dr_usb(blob, bd);
 885#endif
 886
 887#ifdef CONFIG_FSL_MC_ENET
 888        fdt_fsl_mc_fixup_iommu_map_entry(blob);
 889        fdt_fixup_board_enet(blob);
 890#endif
 891        fdt_fixup_icid(blob);
 892
 893#if CONFIG_IS_ENABLED(TARGET_LX2160ARDB)
 894        board_rev = (QIXIS_READ(arch) & 0xf) - 1 + 'A';
 895        if (board_rev == 'C')
 896                fdt_fixup_i2c_thermal_node(blob);
 897#endif
 898
 899        return 0;
 900}
 901#endif
 902
 903void qixis_dump_switch(void)
 904{
 905        int i, nr_of_cfgsw;
 906
 907        QIXIS_WRITE(cms[0], 0x00);
 908        nr_of_cfgsw = QIXIS_READ(cms[1]);
 909
 910        puts("DIP switch settings dump:\n");
 911        for (i = 1; i <= nr_of_cfgsw; i++) {
 912                QIXIS_WRITE(cms[0], i);
 913                printf("SW%d = (0x%02x)\n", i, QIXIS_READ(cms[1]));
 914        }
 915}
 916