diff options
author | Stefano Babic <sbabic@denx.de> | 2014-09-22 15:51:01 +0200 |
---|---|---|
committer | Stefano Babic <sbabic@denx.de> | 2014-09-22 15:51:01 +0200 |
commit | 42817eb85de1d7dec399c75dbd133ea6b5351a72 (patch) | |
tree | cf93368fd5642cc995055f764103f85d7abbedf1 /board/freescale/ls1021aqds | |
parent | 7a56bddd7fb9fe27c775cadd18ebde6f883d7cff (diff) | |
parent | 2a8c9c86b92a9ccee3c27286de317e19bb0530b3 (diff) | |
download | u-boot-imx-42817eb85de1d7dec399c75dbd133ea6b5351a72.zip u-boot-imx-42817eb85de1d7dec399c75dbd133ea6b5351a72.tar.gz u-boot-imx-42817eb85de1d7dec399c75dbd133ea6b5351a72.tar.bz2 |
Merge branch 'master' of git://git.denx.de/u-boot-arm
Diffstat (limited to 'board/freescale/ls1021aqds')
-rw-r--r-- | board/freescale/ls1021aqds/Kconfig | 18 | ||||
-rw-r--r-- | board/freescale/ls1021aqds/MAINTAINERS | 6 | ||||
-rw-r--r-- | board/freescale/ls1021aqds/Makefile | 9 | ||||
-rw-r--r-- | board/freescale/ls1021aqds/README | 112 | ||||
-rw-r--r-- | board/freescale/ls1021aqds/ddr.c | 159 | ||||
-rw-r--r-- | board/freescale/ls1021aqds/ddr.h | 49 | ||||
-rw-r--r-- | board/freescale/ls1021aqds/eth.c | 186 | ||||
-rw-r--r-- | board/freescale/ls1021aqds/ls1021aqds.c | 255 | ||||
-rw-r--r-- | board/freescale/ls1021aqds/ls1021aqds_qixis.h | 35 |
9 files changed, 829 insertions, 0 deletions
diff --git a/board/freescale/ls1021aqds/Kconfig b/board/freescale/ls1021aqds/Kconfig new file mode 100644 index 0000000..3cee468 --- /dev/null +++ b/board/freescale/ls1021aqds/Kconfig @@ -0,0 +1,18 @@ +if TARGET_LS1021AQDS + +config SYS_CPU + default "armv7" + +config SYS_BOARD + default "ls1021aqds" + +config SYS_VENDOR + default "freescale" + +config SYS_SOC + default "ls102xa" + +config SYS_CONFIG_NAME + default "ls1021aqds" + +endif diff --git a/board/freescale/ls1021aqds/MAINTAINERS b/board/freescale/ls1021aqds/MAINTAINERS new file mode 100644 index 0000000..021d82b --- /dev/null +++ b/board/freescale/ls1021aqds/MAINTAINERS @@ -0,0 +1,6 @@ +LS1021AQDS BOARD +M: Alison Wang <alison.wang@freescale.com> +S: Maintained +F: board/freescale/ls1021aqds/ +F: include/configs/ls1021aqds.h +F: configs/ls1021aqds_nor_defconfig diff --git a/board/freescale/ls1021aqds/Makefile b/board/freescale/ls1021aqds/Makefile new file mode 100644 index 0000000..3b6903c --- /dev/null +++ b/board/freescale/ls1021aqds/Makefile @@ -0,0 +1,9 @@ +# +# Copyright 2014 Freescale Semiconductor, Inc. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y += ls1021aqds.o +obj-y += ddr.o +obj-y += eth.o diff --git a/board/freescale/ls1021aqds/README b/board/freescale/ls1021aqds/README new file mode 100644 index 0000000..c561776 --- /dev/null +++ b/board/freescale/ls1021aqds/README @@ -0,0 +1,112 @@ +Overview +-------- +The LS1021AQDS is a Freescale reference board that hosts the LS1021A SoC. + +LS1021A SoC Overview +------------------ +The QorIQ LS1 family, which includes the LS1021A communications processor, +is built on Layerscape architecture, the industry's first software-aware, +core-agnostic networking architecture to offer unprecedented efficiency +and scale. + +A member of the value-performance tier, the QorIQ LS1021A processor provides +extensive integration and power efficiency for fanless, small form factor +enterprise networking applications. Incorporating dual ARM Cortex-A7 cores +running up to 1.0 GHz, the LS1021A processor delivers pre-silicon CoreMark +performance of over 6,000, as well as virtualization support, advanced +security features and the broadest array of high-speed interconnects and +optimized peripheral features ever offered in a sub-3 W processor. + +The QorIQ LS1021A processor features an integrated LCD controller, +CAN controller for implementing industrial protocols, DDR3L/4 running +up to 1600 MHz, integrated security engine and QUICC Engine, and ECC +protection on both L1 and L2 caches. The LS1021A processor is pin- and +software-compatible with the QorIQ LS1020A and LS1022A processors. + +The LS1021A SoC includes the following function and features: + + - ARM Cortex-A7 MPCore compliant with ARMv7-A architecture + - Dual high-preformance ARM Cortex-A7 cores, each core includes: + - 32 Kbyte L1 Instruction Cache and Data Cache for each core (ECC protection) + - 512 Kbyte shared coherent L2 Cache (with ECC protection) + - NEON Co-processor (per core) + - 40-bit physical addressing + - Vector floating-point support + - ARM Core-Link CCI-400 Cache Coherent Interconnect + - One DDR3L/DDR4 SDRAM memory controller with x8/x16/x32-bit configuration + supporting speeds up to 1600Mtps + - ECC and interleaving support + - VeTSEC Ethernet complex + - Up to 3x virtualized 10/100/1000 Ethernet controllers + - MII, RMII, RGMII, and SGMII support + - QoS, lossless flow control, and IEEE 1588 support + - 4-lane 6GHz SerDes + - High speed interconnect (4 SerDes lanes with are muxed for these protocol) + - Two PCI Express Gen2 controllers running at up to 5 GHz + - One Serial ATA 3.0 supporting 6 GT/s operation + - Two SGMII interfaces supporting 1000 Mbps + - Additional peripheral interfaces + - One high-speed USB 3.0 controller with integrated PHY and one high-speed + USB 2.00 controller with ULPI + - Integrated flash controller (IFC) with 16-bit interface + - Quad SPI NOR Flash + - One enhanced Secure digital host controller + - Display controller unit (DCU) 24-bit RGB (12-bit DDR pin interface) + - Ten UARTs comprised of two 16550 compliant DUARTs, and six low power + UARTs + - Three I2C controllers + - Eight FlexTimers four supporting PWM and four FlexCAN ports + - Four GPIO controllers supporting up to 109 general purpose I/O signals + - Integrated advanced audio block: + - Four synchronous audio interfaces (SAI) + - Sony/Philips Digital Interconnect Format (SPDIF) + - Asynchronous Sample Rate Converter (ASRC) + - Hardware based crypto offload engine + - IPSec forwarding at up to 1Gbps + - QorIQ Trust Architecture, Secure Boot, and ARM TrustZone supported + - Public key hardware accelerator + - True Random Number Generator (NIST Certified) + - Advanced Encryption Standard Accelerators (AESA) + - Data Encryption Standard Accelerators + - QUICC Engine ULite block + - Two universal communication controllers (TDM and HDLC) supporting 64 + multichannels, each running at 64 Kbps + - Support for 256 channels of HDLC + - QorIQ TrustArchitecture with Secure Boot, as well as ARM TrustZone supported + +LS1021AQDS board Overview +------------------------- + - DDR Controller + - Supports rates of up to 1600 MHz data-rate + - Supports one DDR3LP UDIMM, of single-, dual- types. + - IFC/Local Bus + - NAND flash: 512M 8-bit NAND flash + - NOR: 128MB 16-bit NOR Flash + - Ethernet + - Three on-board RGMII 10/100/1G ethernet ports. + - FPGA + - Clocks + - System and DDR clock (SYSCLK, DDRCLK) + - SERDES clocks + - Power Supplies + - SDHC + - SDHC/SDXC connector + - Other IO + - Two Serial ports + - Three I2C ports + +Memory map +----------- +The addresses in brackets are physical addresses. + +Start Address End Address Description Size +0x00_0000_0000 0x00_000F_FFFF Secure Boot ROM 1MB +0x00_0100_0000 0x00_0FFF_FFFF CCSRBAR 240MB +0x00_1000_0000 0x00_1000_FFFF OCRAM0 64KB +0x00_1001_0000 0x00_1001_FFFF OCRAM1 64KB +0x00_2000_0000 0x00_20FF_FFFF DCSR 16MB +0x00_4000_0000 0x00_5FFF_FFFF QSPI 512MB +0x00_6000_0000 0x00_67FF_FFFF IFC - NOR Flash 128MB +0x00_7E80_0000 0x00_7E80_FFFF IFC - NAND Flash 64KB +0x00_7FB0_0000 0x00_7FB0_0FFF IFC - FPGA 4KB +0x00_8000_0000 0x00_FFFF_FFFF DRAM1 2GB diff --git a/board/freescale/ls1021aqds/ddr.c b/board/freescale/ls1021aqds/ddr.c new file mode 100644 index 0000000..679c654 --- /dev/null +++ b/board/freescale/ls1021aqds/ddr.c @@ -0,0 +1,159 @@ +/* + * Copyright 2014 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <fsl_ddr_sdram.h> +#include <fsl_ddr_dimm_params.h> +#include "ddr.h" + +DECLARE_GLOBAL_DATA_PTR; + +void fsl_ddr_board_options(memctl_options_t *popts, + dimm_params_t *pdimm, + unsigned int ctrl_num) +{ + const struct board_specific_parameters *pbsp, *pbsp_highest = NULL; + ulong ddr_freq; + + if (ctrl_num > 3) { + printf("Not supported controller number %d\n", ctrl_num); + return; + } + if (!pdimm->n_ranks) + return; + + pbsp = udimms[0]; + + /* Get clk_adjust, wrlvl_start, wrlvl_ctl, according to the board ddr + * freqency and n_banks specified in board_specific_parameters table. + */ + ddr_freq = get_ddr_freq(0) / 1000000; + while (pbsp->datarate_mhz_high) { + if (pbsp->n_ranks == pdimm->n_ranks) { + if (ddr_freq <= pbsp->datarate_mhz_high) { + popts->clk_adjust = pbsp->clk_adjust; + popts->wrlvl_start = pbsp->wrlvl_start; + popts->wrlvl_ctl_2 = pbsp->wrlvl_ctl_2; + popts->wrlvl_ctl_3 = pbsp->wrlvl_ctl_3; + popts->cpo_override = pbsp->cpo_override; + popts->write_data_delay = + pbsp->write_data_delay; + goto found; + } + pbsp_highest = pbsp; + } + pbsp++; + } + + if (pbsp_highest) { + printf("Error: board specific timing not found for %lu MT/s\n", + ddr_freq); + printf("Trying to use the highest speed (%u) parameters\n", + pbsp_highest->datarate_mhz_high); + popts->clk_adjust = pbsp_highest->clk_adjust; + popts->wrlvl_start = pbsp_highest->wrlvl_start; + popts->wrlvl_ctl_2 = pbsp->wrlvl_ctl_2; + popts->wrlvl_ctl_3 = pbsp->wrlvl_ctl_3; + } else { + panic("DIMM is not supported by this board"); + } +found: + debug("Found timing match: n_ranks %d, data rate %d, rank_gb %d\n", + pbsp->n_ranks, pbsp->datarate_mhz_high, pbsp->rank_gb); + + /* force DDR bus width to 32 bits */ + popts->data_bus_width = 1; + popts->otf_burst_chop_en = 0; + popts->burst_length = DDR_BL8; + + /* + * Factors to consider for half-strength driver enable: + * - number of DIMMs installed + */ + popts->half_strength_driver_enable = 1; + /* + * Write leveling override + */ + popts->wrlvl_override = 1; + popts->wrlvl_sample = 0xf; + popts->cswl_override = DDR_CSWL_CS0; + + /* + * Rtt and Rtt_WR override + */ + popts->rtt_override = 0; + + /* Enable ZQ calibration */ + popts->zq_en = 1; + + /* DHC_EN =1, ODT = 75 Ohm */ + popts->ddr_cdr1 = DDR_CDR1_DHC_EN | DDR_CDR1_ODT(DDR_CDR_ODT_75ohm); + popts->ddr_cdr2 = DDR_CDR2_ODT(DDR_CDR_ODT_75ohm); +} + +#ifdef CONFIG_SYS_DDR_RAW_TIMING +dimm_params_t ddr_raw_timing = { + .n_ranks = 1, + .rank_density = 1073741824u, + .capacity = 1073741824u, + .primary_sdram_width = 32, + .ec_sdram_width = 0, + .registered_dimm = 0, + .mirrored_dimm = 0, + .n_row_addr = 15, + .n_col_addr = 10, + .n_banks_per_sdram_device = 8, + .edc_config = 0, + .burst_lengths_bitmask = 0x0c, + + .tckmin_x_ps = 1071, + .caslat_x = 0xfe << 4, /* 5,6,7,8 */ + .taa_ps = 13125, + .twr_ps = 15000, + .trcd_ps = 13125, + .trrd_ps = 7500, + .trp_ps = 13125, + .tras_ps = 37500, + .trc_ps = 50625, + .trfc_ps = 160000, + .twtr_ps = 7500, + .trtp_ps = 7500, + .refresh_rate_ps = 7800000, + .tfaw_ps = 37500, +}; + +int fsl_ddr_get_dimm_params(dimm_params_t *pdimm, + unsigned int controller_number, + unsigned int dimm_number) +{ + static const char dimm_model[] = "Fixed DDR on board"; + + if (((controller_number == 0) && (dimm_number == 0)) || + ((controller_number == 1) && (dimm_number == 0))) { + memcpy(pdimm, &ddr_raw_timing, sizeof(dimm_params_t)); + memset(pdimm->mpart, 0, sizeof(pdimm->mpart)); + memcpy(pdimm->mpart, dimm_model, sizeof(dimm_model) - 1); + } + + return 0; +} +#endif + +phys_size_t initdram(int board_type) +{ + phys_size_t dram_size; + + puts("Initializing DDR....using SPD\n"); + dram_size = fsl_ddr_sdram(); + + return dram_size; +} + +void dram_init_banksize(void) +{ + gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE; + gd->bd->bi_dram[0].size = gd->ram_size; +} diff --git a/board/freescale/ls1021aqds/ddr.h b/board/freescale/ls1021aqds/ddr.h new file mode 100644 index 0000000..16d87cb --- /dev/null +++ b/board/freescale/ls1021aqds/ddr.h @@ -0,0 +1,49 @@ +/* + * Copyright 2014 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __DDR_H__ +#define __DDR_H__ +struct board_specific_parameters { + u32 n_ranks; + u32 datarate_mhz_high; + u32 rank_gb; + u32 clk_adjust; + u32 wrlvl_start; + u32 wrlvl_ctl_2; + u32 wrlvl_ctl_3; + u32 cpo_override; + u32 write_data_delay; + u32 force_2t; +}; + +/* + * These tables contain all valid speeds we want to override with board + * specific parameters. datarate_mhz_high values need to be in ascending order + * for each n_ranks group. + */ +static const struct board_specific_parameters udimm0[] = { + /* + * memory controller 0 + * num| hi| rank| clk| wrlvl | wrlvl | wrlvl | cpo |wrdata|2T + * ranks| mhz| GB |adjst| start | ctl2 | ctl3 | |delay | + */ + {1, 833, 1, 6, 8, 0x06060607, 0x08080807, 0x1f, 2, 0}, + {1, 1350, 1, 6, 8, 0x0708080A, 0x0A0B0C09, 0x1f, 2, 0}, + {1, 833, 2, 6, 8, 0x06060607, 0x08080807, 0x1f, 2, 0}, + {1, 1350, 2, 6, 8, 0x0708080A, 0x0A0B0C09, 0x1f, 2, 0}, + {2, 833, 4, 6, 8, 0x06060607, 0x08080807, 0x1f, 2, 0}, + {2, 1350, 4, 6, 8, 0x0708080A, 0x0A0B0C09, 0x1f, 2, 0}, + {2, 1350, 0, 6, 8, 0x0708080A, 0x0A0B0C09, 0x1f, 2, 0}, + {2, 1666, 4, 4, 0xa, 0x0B08090C, 0x0B0E0D0A, 0x1f, 2, 0}, + {2, 1666, 0, 4, 0xa, 0x0B08090C, 0x0B0E0D0A, 0x1f, 2, 0}, + {} +}; + +static const struct board_specific_parameters *udimms[] = { + udimm0, +}; + +#endif diff --git a/board/freescale/ls1021aqds/eth.c b/board/freescale/ls1021aqds/eth.c new file mode 100644 index 0000000..be351be --- /dev/null +++ b/board/freescale/ls1021aqds/eth.c @@ -0,0 +1,186 @@ +/* + * Copyright 2014 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + * + * This file handles the board muxing between the RGMII/SGMII PHYs on + * Freescale LS1021AQDS board. The RGMII PHYs are the three on-board 1Gb + * ports. The SGMII PHYs are provided by the standard Freescale four-port + * SGMII riser card. + * + * Muxing is handled via the PIXIS BRDCFG4 register. The EMI1 bits control + * muxing among the RGMII PHYs and the SGMII PHYs. The value for RGMII depends + * on which port is used. The value for SGMII depends on which slot the riser + * is inserted in. + */ + +#include <common.h> +#include <netdev.h> +#include <asm/arch/fsl_serdes.h> +#include <fsl_mdio.h> +#include <tsec.h> +#include <malloc.h> + +#include "../common/sgmii_riser.h" +#include "../common/qixis.h" + +#define EMI1_MASK 0x1f +#define EMI1_RGMII0 1 +#define EMI1_RGMII1 2 +#define EMI1_RGMII2 3 +#define EMI1_SGMII1 0x1c +#define EMI1_SGMII2 0x1d + +struct ls1021a_mdio { + struct mii_dev *realbus; +}; + +static void ls1021a_mux_mdio(int addr) +{ + u8 brdcfg4; + + brdcfg4 = QIXIS_READ(brdcfg[4]); + brdcfg4 &= EMI1_MASK; + + switch (addr) { + case EMI1_RGMII0: + brdcfg4 |= 0; + break; + case EMI1_RGMII1: + brdcfg4 |= 0x20; + break; + case EMI1_RGMII2: + brdcfg4 |= 0x40; + break; + case EMI1_SGMII1: + brdcfg4 |= 0x60; + break; + case EMI1_SGMII2: + brdcfg4 |= 0x80; + break; + default: + brdcfg4 |= 0xa0; + break; + } + + QIXIS_WRITE(brdcfg[4], brdcfg4); +} + +static int ls1021a_mdio_read(struct mii_dev *bus, int addr, int devad, + int regnum) +{ + struct ls1021a_mdio *priv = bus->priv; + + ls1021a_mux_mdio(addr); + + return priv->realbus->read(priv->realbus, addr, devad, regnum); +} + +static int ls1021a_mdio_write(struct mii_dev *bus, int addr, int devad, + int regnum, u16 value) +{ + struct ls1021a_mdio *priv = bus->priv; + + ls1021a_mux_mdio(addr); + + return priv->realbus->write(priv->realbus, addr, devad, regnum, value); +} + +static int ls1021a_mdio_reset(struct mii_dev *bus) +{ + struct ls1021a_mdio *priv = bus->priv; + + return priv->realbus->reset(priv->realbus); +} + +static int ls1021a_mdio_init(char *realbusname, char *fakebusname) +{ + struct ls1021a_mdio *lsmdio; + struct mii_dev *bus = mdio_alloc(); + + if (!bus) { + printf("Failed to allocate LS102xA MDIO bus\n"); + return -1; + } + + lsmdio = malloc(sizeof(*lsmdio)); + if (!lsmdio) { + printf("Failed to allocate LS102xA private data\n"); + free(bus); + return -1; + } + + bus->read = ls1021a_mdio_read; + bus->write = ls1021a_mdio_write; + bus->reset = ls1021a_mdio_reset; + sprintf(bus->name, fakebusname); + + lsmdio->realbus = miiphy_get_dev_by_name(realbusname); + + if (!lsmdio->realbus) { + printf("No bus with name %s\n", realbusname); + free(bus); + free(lsmdio); + return -1; + } + + bus->priv = lsmdio; + + return mdio_register(bus); +} + +int board_eth_init(bd_t *bis) +{ + struct fsl_pq_mdio_info mdio_info; + struct tsec_info_struct tsec_info[3]; + int num = 0; + +#ifdef CONFIG_TSEC1 + SET_STD_TSEC_INFO(tsec_info[num], 1); + if (is_serdes_configured(SGMII_TSEC1)) { + puts("eTSEC1 is in sgmii mode\n"); + tsec_info[num].flags |= TSEC_SGMII; + tsec_info[num].mii_devname = "LS1021A_SGMII_MDIO"; + } else { + tsec_info[num].mii_devname = "LS1021A_RGMII_MDIO"; + } + num++; +#endif +#ifdef CONFIG_TSEC2 + SET_STD_TSEC_INFO(tsec_info[num], 2); + if (is_serdes_configured(SGMII_TSEC2)) { + puts("eTSEC2 is in sgmii mode\n"); + tsec_info[num].flags |= TSEC_SGMII; + tsec_info[num].mii_devname = "LS1021A_SGMII_MDIO"; + } else { + tsec_info[num].mii_devname = "LS1021A_RGMII_MDIO"; + } + num++; +#endif +#ifdef CONFIG_TSEC3 + SET_STD_TSEC_INFO(tsec_info[num], 3); + tsec_info[num].mii_devname = "LS1021A_RGMII_MDIO"; + num++; +#endif + if (!num) { + printf("No TSECs initialized\n"); + return 0; + } + +#ifdef CONFIG_FSL_SGMII_RISER + fsl_sgmii_riser_init(tsec_info, num); +#endif + + mdio_info.regs = (struct tsec_mii_mng *)CONFIG_SYS_MDIO_BASE_ADDR; + mdio_info.name = DEFAULT_MII_NAME; + + fsl_pq_mdio_init(bis, &mdio_info); + + /* Register the virtual MDIO front-ends */ + ls1021a_mdio_init(DEFAULT_MII_NAME, "LS1021A_RGMII_MDIO"); + ls1021a_mdio_init(DEFAULT_MII_NAME, "LS1021A_SGMII_MDIO"); + + tsec_eth_init(bis, tsec_info, num); + + return pci_eth_init(bis); +} diff --git a/board/freescale/ls1021aqds/ls1021aqds.c b/board/freescale/ls1021aqds/ls1021aqds.c new file mode 100644 index 0000000..12e83f7 --- /dev/null +++ b/board/freescale/ls1021aqds/ls1021aqds.c @@ -0,0 +1,255 @@ +/* + * Copyright 2014 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <i2c.h> +#include <asm/io.h> +#include <asm/arch/immap_ls102xa.h> +#include <asm/arch/clock.h> +#include <asm/arch/fsl_serdes.h> +#include <mmc.h> +#include <fsl_esdhc.h> +#include <fsl_ifc.h> + +#include "../common/qixis.h" +#include "ls1021aqds_qixis.h" + +DECLARE_GLOBAL_DATA_PTR; + +enum { + MUX_TYPE_SD_PCI4, + MUX_TYPE_SD_PC_SA_SG_SG, + MUX_TYPE_SD_PC_SA_PC_SG, + MUX_TYPE_SD_PC_SG_SG, +}; + +int checkboard(void) +{ + char buf[64]; + u8 sw; + + puts("Board: LS1021AQDS\n"); + + sw = QIXIS_READ(brdcfg[0]); + sw = (sw & QIXIS_LBMAP_MASK) >> QIXIS_LBMAP_SHIFT; + + if (sw < 0x8) + printf("vBank: %d\n", sw); + else if (sw == 0x8) + puts("PromJet\n"); + else if (sw == 0x9) + puts("NAND\n"); + else if (sw == 0x15) + printf("IFCCard\n"); + else + printf("invalid setting of SW%u\n", QIXIS_LBMAP_SWITCH); + + printf("Sys ID:0x%02x, Sys Ver: 0x%02x\n", + QIXIS_READ(id), QIXIS_READ(arch)); + + printf("FPGA: v%d (%s), build %d\n", + (int)QIXIS_READ(scver), qixis_read_tag(buf), + (int)qixis_read_minor()); + + return 0; +} + +unsigned long get_board_sys_clk(void) +{ + u8 sysclk_conf = QIXIS_READ(brdcfg[1]); + + switch (sysclk_conf & 0x0f) { + case QIXIS_SYSCLK_64: + return 64000000; + case QIXIS_SYSCLK_83: + return 83333333; + case QIXIS_SYSCLK_100: + return 100000000; + case QIXIS_SYSCLK_125: + return 125000000; + case QIXIS_SYSCLK_133: + return 133333333; + case QIXIS_SYSCLK_150: + return 150000000; + case QIXIS_SYSCLK_160: + return 160000000; + case QIXIS_SYSCLK_166: + return 166666666; + } + return 66666666; +} + +unsigned long get_board_ddr_clk(void) +{ + u8 ddrclk_conf = QIXIS_READ(brdcfg[1]); + + switch ((ddrclk_conf & 0x30) >> 4) { + case QIXIS_DDRCLK_100: + return 100000000; + case QIXIS_DDRCLK_125: + return 125000000; + case QIXIS_DDRCLK_133: + return 133333333; + } + return 66666666; +} + +int dram_init(void) +{ + gd->ram_size = initdram(0); + + return 0; +} + +#ifdef CONFIG_FSL_ESDHC +struct fsl_esdhc_cfg esdhc_cfg[1] = { + {CONFIG_SYS_FSL_ESDHC_ADDR}, +}; + +int board_mmc_init(bd_t *bis) +{ + esdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK); + + return fsl_esdhc_initialize(bis, &esdhc_cfg[0]); +} +#endif + +int select_i2c_ch_pca9547(u8 ch) +{ + int ret; + + ret = i2c_write(I2C_MUX_PCA_ADDR_PRI, 0, 1, &ch, 1); + if (ret) { + puts("PCA: failed to select proper channel\n"); + return ret; + } + + return 0; +} + +int board_early_init_f(void) +{ + struct ccsr_scfg *scfg = (struct ccsr_scfg *)CONFIG_SYS_FSL_SCFG_ADDR; + struct ccsr_cci400 *cci = (struct ccsr_cci400 *)CONFIG_SYS_CCI400_ADDR; + +#ifdef CONFIG_TSEC_ENET + out_be32(&scfg->scfgrevcr, SCFG_SCFGREVCR_REV); + out_be32(&scfg->etsecdmamcr, SCFG_ETSECDMAMCR_LE_BD_FR); + out_be32(&scfg->scfgrevcr, SCFG_SCFGREVCR_NOREV); +#endif + +#ifdef CONFIG_FSL_IFC + init_early_memctl_regs(); +#endif + + /* Workaround for the issue that DDR could not respond to + * barrier transaction which is generated by executing DSB/ISB + * instruction. Set CCI-400 control override register to + * terminate the barrier transaction. After DDR is initialized, + * allow barrier transaction to DDR again */ + out_le32(&cci->ctrl_ord, CCI400_CTRLORD_TERM_BARRIER); + + return 0; +} + +int config_board_mux(int ctrl_type) +{ + u8 reg12; + + reg12 = QIXIS_READ(brdcfg[12]); + + switch (ctrl_type) { + case MUX_TYPE_SD_PCI4: + reg12 = 0x38; + break; + case MUX_TYPE_SD_PC_SA_SG_SG: + reg12 = 0x01; + break; + case MUX_TYPE_SD_PC_SA_PC_SG: + reg12 = 0x01; + break; + case MUX_TYPE_SD_PC_SG_SG: + reg12 = 0x21; + break; + default: + printf("Wrong mux interface type\n"); + return -1; + } + + QIXIS_WRITE(brdcfg[12], reg12); + + return 0; +} + +int config_serdes_mux(void) +{ + struct ccsr_gur *gur = (struct ccsr_gur *)CONFIG_SYS_FSL_GUTS_ADDR; + u32 cfg; + + cfg = in_be32(&gur->rcwsr[4]) & RCWSR4_SRDS1_PRTCL_MASK; + cfg >>= RCWSR4_SRDS1_PRTCL_SHIFT; + + switch (cfg) { + case 0x0: + config_board_mux(MUX_TYPE_SD_PCI4); + break; + case 0x30: + config_board_mux(MUX_TYPE_SD_PC_SA_SG_SG); + break; + case 0x60: + config_board_mux(MUX_TYPE_SD_PC_SG_SG); + break; + case 0x70: + config_board_mux(MUX_TYPE_SD_PC_SA_PC_SG); + break; + default: + printf("SRDS1 prtcl:0x%x\n", cfg); + break; + } + + return 0; +} + +int board_init(void) +{ + struct ccsr_cci400 *cci = (struct ccsr_cci400 *)CONFIG_SYS_CCI400_ADDR; + + /* Set CCI-400 control override register to + * enable barrier transaction */ + out_le32(&cci->ctrl_ord, CCI400_CTRLORD_EN_BARRIER); + + select_i2c_ch_pca9547(I2C_MUX_CH_DEFAULT); + +#ifndef CONFIG_SYS_FSL_NO_SERDES + fsl_serdes_init(); + config_serdes_mux(); +#endif + return 0; +} + +void ft_board_setup(void *blob, bd_t *bd) +{ + ft_cpu_setup(blob, bd); +} + +u8 flash_read8(void *addr) +{ + return __raw_readb(addr + 1); +} + +void flash_write16(u16 val, void *addr) +{ + u16 shftval = (((val >> 8) & 0xff) | ((val << 8) & 0xff00)); + + __raw_writew(shftval, addr); +} + +u16 flash_read16(void *addr) +{ + u16 val = __raw_readw(addr); + + return (((val) >> 8) & 0x00ff) | (((val) << 8) & 0xff00); +} diff --git a/board/freescale/ls1021aqds/ls1021aqds_qixis.h b/board/freescale/ls1021aqds/ls1021aqds_qixis.h new file mode 100644 index 0000000..09b3be2 --- /dev/null +++ b/board/freescale/ls1021aqds/ls1021aqds_qixis.h @@ -0,0 +1,35 @@ +/* + * Copyright 2014 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __LS1021AQDS_QIXIS_H__ +#define __LS1021AQDS_QIXIS_H__ + +/* Definitions of QIXIS Registers for LS1021AQDS */ + +/* BRDCFG4[4:7]] select EC1 and EC2 as a pair */ +#define BRDCFG4_EMISEL_MASK 0xe0 +#define BRDCFG4_EMISEL_SHIFT 5 + +/* SYSCLK */ +#define QIXIS_SYSCLK_66 0x0 +#define QIXIS_SYSCLK_83 0x1 +#define QIXIS_SYSCLK_100 0x2 +#define QIXIS_SYSCLK_125 0x3 +#define QIXIS_SYSCLK_133 0x4 +#define QIXIS_SYSCLK_150 0x5 +#define QIXIS_SYSCLK_160 0x6 +#define QIXIS_SYSCLK_166 0x7 +#define QIXIS_SYSCLK_64 0x8 + +/* DDRCLK */ +#define QIXIS_DDRCLK_66 0x0 +#define QIXIS_DDRCLK_100 0x1 +#define QIXIS_DDRCLK_125 0x2 +#define QIXIS_DDRCLK_133 0x3 + +#define QIXIS_SRDS1CLK_100 0x0 + +#endif |