avionic design with actual uboot and tooling
submodule of avionic design uboot bootloader and with included tools to get you started , read readme.md and readme-tk1-loader.md
This commit is contained in:
16
u-boot/board/freescale/ls2080aqds/Kconfig
Normal file
16
u-boot/board/freescale/ls2080aqds/Kconfig
Normal file
@@ -0,0 +1,16 @@
|
||||
|
||||
if TARGET_LS2080AQDS
|
||||
|
||||
config SYS_BOARD
|
||||
default "ls2080aqds"
|
||||
|
||||
config SYS_VENDOR
|
||||
default "freescale"
|
||||
|
||||
config SYS_SOC
|
||||
default "fsl-layerscape"
|
||||
|
||||
config SYS_CONFIG_NAME
|
||||
default "ls2080aqds"
|
||||
|
||||
endif
|
||||
13
u-boot/board/freescale/ls2080aqds/MAINTAINERS
Normal file
13
u-boot/board/freescale/ls2080aqds/MAINTAINERS
Normal file
@@ -0,0 +1,13 @@
|
||||
LS2080A BOARD
|
||||
M: Prabhakar Kushwaha <prabhakar.kushwaha@nxp.com>
|
||||
S: Maintained
|
||||
F: board/freescale/ls2080aqds/
|
||||
F: board/freescale/ls2080a/ls2080aqds.c
|
||||
F: include/configs/ls2080aqds.h
|
||||
F: configs/ls2080aqds_defconfig
|
||||
F: configs/ls2080aqds_nand_defconfig
|
||||
|
||||
LS2080A_SECURE_BOOT BOARD
|
||||
M: Saksham Jain <saksham.jain@nxp.freescale.com>
|
||||
S: Maintained
|
||||
F: configs/ls2080aqds_SECURE_BOOT_defconfig
|
||||
9
u-boot/board/freescale/ls2080aqds/Makefile
Normal file
9
u-boot/board/freescale/ls2080aqds/Makefile
Normal file
@@ -0,0 +1,9 @@
|
||||
#
|
||||
# Copyright 2015 Freescale Semiconductor
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0+
|
||||
#
|
||||
|
||||
obj-y += ls2080aqds.o
|
||||
obj-y += ddr.o
|
||||
obj-y += eth.o
|
||||
190
u-boot/board/freescale/ls2080aqds/README
Normal file
190
u-boot/board/freescale/ls2080aqds/README
Normal file
@@ -0,0 +1,190 @@
|
||||
Overview
|
||||
--------
|
||||
The LS2080A Development System (QDS) is a high-performance computing,
|
||||
evaluation, and development platform that supports the QorIQ LS2080A
|
||||
Layerscape Architecture processor. The LS2080AQDS provides validation and
|
||||
SW development platform for the Freescale LS2080A processor series, with
|
||||
a complete debugging environment.
|
||||
|
||||
LS2080A SoC Overview
|
||||
--------------------
|
||||
Please refer arch/arm/cpu/armv8/fsl-layerscape/doc/README.soc for LS2080A
|
||||
SoC overview.
|
||||
|
||||
LS2080AQDS board Overview
|
||||
-----------------------
|
||||
- SERDES Connections, 16 lanes supporting:
|
||||
- PCI Express - 3.0
|
||||
- SGMII, SGMII 2.5
|
||||
- QSGMII
|
||||
- SATA 3.0
|
||||
- XAUI
|
||||
- XFI
|
||||
- DDR Controller
|
||||
- Two ports of 72-bits (8-bits ECC) DDR4. Each port supports four
|
||||
chip-selects and two DIMM connectors. Support is up to 2133MT/s.
|
||||
- One port of 40-bits (8-bits ECC) DDR4 which supports four chip-selects
|
||||
and two DIMM connectors. Support is up to 1600MT/s.
|
||||
-IFC/Local Bus
|
||||
- IFC rev. 2.0 implementation supporting Little Endian connection scheme.
|
||||
- One in-socket 128 MB NOR flash 16-bit data bus
|
||||
- One 512 MB NAND flash with ECC support
|
||||
- IFC Test Port
|
||||
- PromJet Port
|
||||
- FPGA connection
|
||||
- USB 3.0
|
||||
- Two high speed USB 3.0 ports
|
||||
- First USB 3.0 port configured as Host with Type-A connector
|
||||
- Second USB 3.0 port configured as OTG with micro-AB connector
|
||||
- SDHC: PCIe x1 Right Angle connector for supporting following cards
|
||||
- 1/4-/8-bit SD/MMC Legacy CARD supporting 3.3V devices only
|
||||
- 1-/4-/8-bit SD/MMC Card supporting 1.8V devices only
|
||||
- 4-bit eMMC Card Rev 4.4 (1.8V only)
|
||||
- 8-bit eMMC Card Rev 4.5 (1.8V only)
|
||||
- SD Card Rev 2.0 and Rev 3.0
|
||||
- DSPI: 3 high-speed flash Memory for storage
|
||||
- 16 MB high-speed flash Memory for boot code and storage (up to 108MHz)
|
||||
- 8 MB high-speed flash Memory (up to 104 MHz)
|
||||
- 512 MB low-speed flash Memory (up to 40 MHz)
|
||||
- QSPI: via NAND/QSPI Card
|
||||
- 4 I2C controllers
|
||||
- Two SATA onboard connectors
|
||||
- UART
|
||||
- Two 4-pin (HW control) or four 2-pin (SW control) serial ports at up to 115.2 Kbit/s
|
||||
- Two DB9 D-Type connectors supporting one Serial port each
|
||||
- ARM JTAG support
|
||||
|
||||
Memory map from core's view
|
||||
----------------------------
|
||||
0x00_0000_0000 .. 0x00_000F_FFFF Boot Rom
|
||||
0x00_0100_0000 .. 0x00_0FFF_FFFF CCSR
|
||||
0x00_1800_0000 .. 0x00_181F_FFFF OCRAM
|
||||
0x00_3000_0000 .. 0x00_3FFF_FFFF IFC region #1
|
||||
0x00_8000_0000 .. 0x00_FFFF_FFFF DDR region #1
|
||||
0x05_1000_0000 .. 0x05_FFFF_FFFF IFC region #2
|
||||
0x80_8000_0000 .. 0xFF_FFFF_FFFF DDR region #2
|
||||
|
||||
Other addresses are either reserved, or not used directly by U-Boot.
|
||||
This list should be updated when more addresses are used.
|
||||
|
||||
IFC region map from core's view
|
||||
-------------------------------
|
||||
During boot i.e. IFC Region #1:-
|
||||
0x30000000 - 0x37ffffff : 128MB : NOR flash
|
||||
0x38000000 - 0x3BFFFFFF : 64MB : Promjet
|
||||
0x3C000000 - 0x40000000 : 64MB : FPGA etc
|
||||
|
||||
After relocate to DDR i.e. IFC Region #2:-
|
||||
0x5_1000_0000..0x5_1fff_ffff Memory Hole
|
||||
0x5_2000_0000..0x5_3fff_ffff IFC CSx (FPGA, NAND and others 512MB)
|
||||
0x5_4000_0000..0x5_7fff_ffff ASIC or others 1GB
|
||||
0x5_8000_0000..0x5_bfff_ffff IFC CS0 1GB (NOR/Promjet)
|
||||
0x5_C000_0000..0x5_ffff_ffff IFC CS1 1GB (NOR/Promjet)
|
||||
|
||||
Booting Options
|
||||
---------------
|
||||
a) Promjet Boot
|
||||
b) NOR boot
|
||||
c) NAND boot
|
||||
d) SD boot
|
||||
e) QSPI boot
|
||||
|
||||
Environment Variables
|
||||
---------------------
|
||||
- mcboottimeout: MC boot timeout in milliseconds. If this variable is not defined
|
||||
the value CONFIG_SYS_LS_MC_BOOT_TIMEOUT_MS will be assumed.
|
||||
|
||||
- mcmemsize: MC DRAM block size. If this variable is not defined
|
||||
the value CONFIG_SYS_LS_MC_DRAM_BLOCK_MIN_SIZE will be assumed.
|
||||
|
||||
Booting Linux flavors which do not support 48-bit VA (< Linux 3.18)
|
||||
-------------------------------------------------------------------
|
||||
One needs to use appropriate bootargs to boot Linux flavors which do
|
||||
not support 48-bit VA (for e.g. < Linux 3.18) by appending mem=2048M, as shown
|
||||
below:
|
||||
|
||||
=> setenv bootargs 'console=ttyS1,115200 root=/dev/ram
|
||||
earlycon=uart8250,mmio,0x21c0600,115200 default_hugepagesz=2m hugepagesz=2m
|
||||
hugepages=16 mem=2048M'
|
||||
|
||||
|
||||
X-QSGMII-16PORT riser card
|
||||
----------------------------
|
||||
The X-QSGMII-16PORT is a 4xQSGMII/8xSGMII riser card with eighth SerDes
|
||||
interfaces implemented in PCIe form factor board.
|
||||
It supports followings
|
||||
- Card can operate with up to 4 QSGMII lane simultaneously
|
||||
- Card can operate with up to 8 SGMII lane simultaneously
|
||||
|
||||
Supported card configuration
|
||||
- CSEL : ON ON ON ON
|
||||
- MSEL1 : ON ON ON ON OFF OFF OFF OFF
|
||||
- MSEL2 : OFF OFF OFF OFF ON ON ON ON
|
||||
|
||||
To enable this card: modify hwconfig to add "xqsgmii" variable.
|
||||
|
||||
Supported PHY addresses during SGMII:
|
||||
#define XQSGMII_CARD_PHY1_PORT0_ADDR 0x0
|
||||
#define XQSGMII_CARD_PHY1_PORT2_ADDR 0x2
|
||||
#define XQSGMII_CARD_PHY2_PORT0_ADDR 0x4
|
||||
#define XQSGMII_CARD_PHY2_PORT2_ADDR 0x6
|
||||
#define XQSGMII_CARD_PHY3_PORT0_ADDR 0x8
|
||||
#define XQSGMII_CARD_PHY3_PORT2_ADDR 0xa
|
||||
#define XQSGMII_CARD_PHY4_PORT0_ADDR 0xc
|
||||
#define XQSGMII_CARD_PHY4_PORT2_ADDR 0xe
|
||||
|
||||
Mapping DPMACx to PHY during SGMII
|
||||
DPMAC1 -> PHY1-P0
|
||||
DPMAC2 -> PHY2-P0
|
||||
DPMAC3 -> PHY3-P0
|
||||
DPMAC4 -> PHY4-P0
|
||||
DPMAC5 -> PHY3-P2
|
||||
DPMAC6 -> PHY1-P2
|
||||
DPMAC7 -> PHY4-P1
|
||||
DPMAC8 -> PHY2-P2
|
||||
DPMAC9 -> PHY1-P0
|
||||
DPMAC10 -> PHY2-P0
|
||||
DPMAC11 -> PHY3-P0
|
||||
DPMAC12 -> PHY4-P0
|
||||
DPMAC13 -> PHY3-P2
|
||||
DPMAC14 -> PHY1-P2
|
||||
DPMAC15 -> PHY4-P1
|
||||
DPMAC16 -> PHY2-P2
|
||||
|
||||
|
||||
Supported PHY address during QSGMII
|
||||
#define XQSGMII_CARD_PHY1_PORT0_ADDR 0x0
|
||||
#define XQSGMII_CARD_PHY1_PORT1_ADDR 0x1
|
||||
#define XQSGMII_CARD_PHY1_PORT2_ADDR 0x2
|
||||
#define XQSGMII_CARD_PHY1_PORT3_ADDR 0x3
|
||||
#define XQSGMII_CARD_PHY2_PORT0_ADDR 0x4
|
||||
#define XQSGMII_CARD_PHY2_PORT1_ADDR 0x5
|
||||
#define XQSGMII_CARD_PHY2_PORT2_ADDR 0x6
|
||||
#define XQSGMII_CARD_PHY2_PORT3_ADDR 0x7
|
||||
#define XQSGMII_CARD_PHY3_PORT0_ADDR 0x8
|
||||
#define XQSGMII_CARD_PHY3_PORT1_ADDR 0x9
|
||||
#define XQSGMII_CARD_PHY3_PORT2_ADDR 0xa
|
||||
#define XQSGMII_CARD_PHY3_PORT3_ADDR 0xb
|
||||
#define XQSGMII_CARD_PHY4_PORT0_ADDR 0xc
|
||||
#define XQSGMII_CARD_PHY4_PORT1_ADDR 0xd
|
||||
#define XQSGMII_CARD_PHY4_PORT2_ADDR 0xe
|
||||
#define XQSGMII_CARD_PHY4_PORT3_ADDR 0xf
|
||||
|
||||
Mapping DPMACx to PHY during QSGMII
|
||||
DPMAC1 -> PHY1-P3
|
||||
DPMAC2 -> PHY1-P2
|
||||
DPMAC3 -> PHY1-P1
|
||||
DPMAC4 -> PHY1-P0
|
||||
DPMAC5 -> PHY2-P3
|
||||
DPMAC6 -> PHY2-P2
|
||||
DPMAC7 -> PHY2-P1
|
||||
DPMAC8 -> PHY2-P0
|
||||
DPMAC9 -> PHY3-P0
|
||||
DPMAC10 -> PHY3-P1
|
||||
DPMAC11 -> PHY3-P2
|
||||
DPMAC12 -> PHY3-P3
|
||||
DPMAC13 -> PHY4-P0
|
||||
DPMAC14 -> PHY4-P1
|
||||
DPMAC15 -> PHY4-P2
|
||||
DPMAC16 -> PHY4-P3
|
||||
|
||||
225
u-boot/board/freescale/ls2080aqds/ddr.c
Normal file
225
u-boot/board/freescale/ls2080aqds/ddr.c
Normal file
@@ -0,0 +1,225 @@
|
||||
/*
|
||||
* Copyright 2015 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <fsl_ddr_sdram.h>
|
||||
#include <fsl_ddr_dimm_params.h>
|
||||
#include <asm/arch/soc.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)
|
||||
{
|
||||
#ifdef CONFIG_SYS_FSL_HAS_DP_DDR
|
||||
u8 dq_mapping_0, dq_mapping_2, dq_mapping_3;
|
||||
#endif
|
||||
const struct board_specific_parameters *pbsp, *pbsp_highest = NULL;
|
||||
ulong ddr_freq;
|
||||
int slot;
|
||||
|
||||
if (ctrl_num > 2) {
|
||||
printf("Not supported controller number %d\n", ctrl_num);
|
||||
return;
|
||||
}
|
||||
|
||||
for (slot = 0; slot < CONFIG_DIMM_SLOTS_PER_CTLR; slot++) {
|
||||
if (pdimm[slot].n_ranks)
|
||||
break;
|
||||
}
|
||||
|
||||
if (slot >= CONFIG_DIMM_SLOTS_PER_CTLR)
|
||||
return;
|
||||
|
||||
/*
|
||||
* we use identical timing for all slots. If needed, change the code
|
||||
* to pbsp = rdimms[ctrl_num] or pbsp = udimms[ctrl_num];
|
||||
*/
|
||||
if (popts->registered_dimm_en)
|
||||
pbsp = rdimms[ctrl_num];
|
||||
else
|
||||
pbsp = udimms[ctrl_num];
|
||||
|
||||
|
||||
/* 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(ctrl_num) / 1000000;
|
||||
while (pbsp->datarate_mhz_high) {
|
||||
if (pbsp->n_ranks == pdimm[slot].n_ranks &&
|
||||
(pdimm[slot].rank_density >> 30) >= pbsp->rank_gb) {
|
||||
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;
|
||||
goto found;
|
||||
}
|
||||
pbsp_highest = pbsp;
|
||||
}
|
||||
pbsp++;
|
||||
}
|
||||
|
||||
if (pbsp_highest) {
|
||||
printf("Error: board specific timing not found for data rate %lu MT/s\n"
|
||||
"Trying to use the highest speed (%u) parameters\n",
|
||||
ddr_freq, 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"
|
||||
"\tclk_adjust %d, wrlvl_start %d, wrlvl_ctrl_2 0x%x, wrlvl_ctrl_3 0x%x\n",
|
||||
pbsp->n_ranks, pbsp->datarate_mhz_high, pbsp->rank_gb,
|
||||
pbsp->clk_adjust, pbsp->wrlvl_start, pbsp->wrlvl_ctl_2,
|
||||
pbsp->wrlvl_ctl_3);
|
||||
#ifdef CONFIG_SYS_FSL_HAS_DP_DDR
|
||||
if (ctrl_num == CONFIG_DP_DDR_CTRL) {
|
||||
/* force DDR bus width to 32 bits */
|
||||
popts->data_bus_width = 1;
|
||||
popts->otf_burst_chop_en = 0;
|
||||
popts->burst_length = DDR_BL8;
|
||||
popts->bstopre = 0; /* enable auto precharge */
|
||||
/*
|
||||
* Layout optimization results byte mapping
|
||||
* Byte 0 -> Byte ECC
|
||||
* Byte 1 -> Byte 3
|
||||
* Byte 2 -> Byte 2
|
||||
* Byte 3 -> Byte 1
|
||||
* Byte ECC -> Byte 0
|
||||
*/
|
||||
dq_mapping_0 = pdimm[slot].dq_mapping[0];
|
||||
dq_mapping_2 = pdimm[slot].dq_mapping[2];
|
||||
dq_mapping_3 = pdimm[slot].dq_mapping[3];
|
||||
pdimm[slot].dq_mapping[0] = pdimm[slot].dq_mapping[8];
|
||||
pdimm[slot].dq_mapping[1] = pdimm[slot].dq_mapping[9];
|
||||
pdimm[slot].dq_mapping[2] = pdimm[slot].dq_mapping[6];
|
||||
pdimm[slot].dq_mapping[3] = pdimm[slot].dq_mapping[7];
|
||||
pdimm[slot].dq_mapping[6] = dq_mapping_2;
|
||||
pdimm[slot].dq_mapping[7] = dq_mapping_3;
|
||||
pdimm[slot].dq_mapping[8] = dq_mapping_0;
|
||||
pdimm[slot].dq_mapping[9] = 0;
|
||||
pdimm[slot].dq_mapping[10] = 0;
|
||||
pdimm[slot].dq_mapping[11] = 0;
|
||||
pdimm[slot].dq_mapping[12] = 0;
|
||||
pdimm[slot].dq_mapping[13] = 0;
|
||||
pdimm[slot].dq_mapping[14] = 0;
|
||||
pdimm[slot].dq_mapping[15] = 0;
|
||||
pdimm[slot].dq_mapping[16] = 0;
|
||||
pdimm[slot].dq_mapping[17] = 0;
|
||||
}
|
||||
#endif
|
||||
/* To work at higher than 1333MT/s */
|
||||
popts->half_strength_driver_enable = 0;
|
||||
/*
|
||||
* Write leveling override
|
||||
*/
|
||||
popts->wrlvl_override = 1;
|
||||
popts->wrlvl_sample = 0x0; /* 32 clocks */
|
||||
|
||||
/*
|
||||
* Rtt and Rtt_WR override
|
||||
*/
|
||||
popts->rtt_override = 0;
|
||||
|
||||
/* Enable ZQ calibration */
|
||||
popts->zq_en = 1;
|
||||
|
||||
if (ddr_freq < 2350) {
|
||||
if (pdimm[0].n_ranks == 2 && pdimm[1].n_ranks == 2) {
|
||||
/* four chip-selects */
|
||||
popts->ddr_cdr1 = DDR_CDR1_DHC_EN |
|
||||
DDR_CDR1_ODT(DDR_CDR_ODT_80ohm);
|
||||
popts->ddr_cdr2 = DDR_CDR2_ODT(DDR_CDR_ODT_80ohm);
|
||||
popts->twot_en = 1; /* enable 2T timing */
|
||||
} else {
|
||||
popts->ddr_cdr1 = DDR_CDR1_DHC_EN |
|
||||
DDR_CDR1_ODT(DDR_CDR_ODT_60ohm);
|
||||
popts->ddr_cdr2 = DDR_CDR2_ODT(DDR_CDR_ODT_60ohm) |
|
||||
DDR_CDR2_VREF_RANGE_2;
|
||||
}
|
||||
} else {
|
||||
popts->ddr_cdr1 = DDR_CDR1_DHC_EN |
|
||||
DDR_CDR1_ODT(DDR_CDR_ODT_100ohm);
|
||||
popts->ddr_cdr2 = DDR_CDR2_ODT(DDR_CDR_ODT_100ohm) |
|
||||
DDR_CDR2_VREF_RANGE_2;
|
||||
}
|
||||
}
|
||||
|
||||
phys_size_t initdram(int board_type)
|
||||
{
|
||||
phys_size_t dram_size;
|
||||
|
||||
#if defined(CONFIG_SPL) && !defined(CONFIG_SPL_BUILD)
|
||||
return fsl_ddr_sdram_size();
|
||||
#else
|
||||
puts("Initializing DDR....using SPD\n");
|
||||
|
||||
dram_size = fsl_ddr_sdram();
|
||||
#endif
|
||||
|
||||
return dram_size;
|
||||
}
|
||||
|
||||
void dram_init_banksize(void)
|
||||
{
|
||||
#ifdef CONFIG_SYS_DP_DDR_BASE_PHY
|
||||
phys_size_t dp_ddr_size;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* gd->secure_ram tracks the location of secure memory.
|
||||
* It was set as if the memory starts from 0.
|
||||
* The address needs to add the offset of its bank.
|
||||
*/
|
||||
gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE;
|
||||
if (gd->ram_size > CONFIG_SYS_LS2_DDR_BLOCK1_SIZE) {
|
||||
gd->bd->bi_dram[0].size = CONFIG_SYS_LS2_DDR_BLOCK1_SIZE;
|
||||
gd->bd->bi_dram[1].start = CONFIG_SYS_DDR_BLOCK2_BASE;
|
||||
gd->bd->bi_dram[1].size = gd->ram_size -
|
||||
CONFIG_SYS_LS2_DDR_BLOCK1_SIZE;
|
||||
#ifdef CONFIG_SYS_MEM_RESERVE_SECURE
|
||||
gd->secure_ram = gd->bd->bi_dram[1].start +
|
||||
gd->secure_ram -
|
||||
CONFIG_SYS_LS2_DDR_BLOCK1_SIZE;
|
||||
gd->secure_ram |= MEM_RESERVE_SECURE_MAINTAINED;
|
||||
#endif
|
||||
} else {
|
||||
gd->bd->bi_dram[0].size = gd->ram_size;
|
||||
#ifdef CONFIG_SYS_MEM_RESERVE_SECURE
|
||||
gd->secure_ram = gd->bd->bi_dram[0].start + gd->secure_ram;
|
||||
gd->secure_ram |= MEM_RESERVE_SECURE_MAINTAINED;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SYS_DP_DDR_BASE_PHY
|
||||
if (soc_has_dp_ddr()) {
|
||||
/* initialize DP-DDR here */
|
||||
puts("DP-DDR: ");
|
||||
/*
|
||||
* DDR controller use 0 as the base address for binding.
|
||||
* It is mapped to CONFIG_SYS_DP_DDR_BASE for core to access.
|
||||
*/
|
||||
dp_ddr_size = fsl_other_ddr_sdram(CONFIG_SYS_DP_DDR_BASE_PHY,
|
||||
CONFIG_DP_DDR_CTRL,
|
||||
CONFIG_DP_DDR_NUM_CTRLS,
|
||||
CONFIG_DP_DDR_DIMM_SLOTS_PER_CTLR,
|
||||
NULL, NULL, NULL);
|
||||
if (dp_ddr_size) {
|
||||
gd->bd->bi_dram[2].start = CONFIG_SYS_DP_DDR_BASE;
|
||||
gd->bd->bi_dram[2].size = dp_ddr_size;
|
||||
} else {
|
||||
puts("Not detected");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
92
u-boot/board/freescale/ls2080aqds/ddr.h
Normal file
92
u-boot/board/freescale/ls2080aqds/ddr.h
Normal file
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright 2015 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;
|
||||
};
|
||||
|
||||
/*
|
||||
* 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
|
||||
* ranks| mhz| GB |adjst| start | ctl2 | ctl3
|
||||
*/
|
||||
{2, 1350, 0, 8, 6, 0x0708090B, 0x0C0D0E09,},
|
||||
{2, 1666, 0, 8, 7, 0x08090A0C, 0x0D0F100B,},
|
||||
{2, 1900, 0, 8, 7, 0x09090B0D, 0x0E10120B,},
|
||||
{2, 2300, 0, 8, 8, 0x090A0C0F, 0x1012130C,},
|
||||
{}
|
||||
};
|
||||
|
||||
/* DP-DDR DIMM */
|
||||
static const struct board_specific_parameters udimm2[] = {
|
||||
/*
|
||||
* memory controller 2
|
||||
* num| hi| rank| clk| wrlvl | wrlvl | wrlvl
|
||||
* ranks| mhz| GB |adjst| start | ctl2 | ctl3
|
||||
*/
|
||||
{2, 1350, 0, 8, 0xd, 0x0C0A0A00, 0x00000009,},
|
||||
{2, 1666, 0, 8, 0xd, 0x0C0A0A00, 0x00000009,},
|
||||
{2, 1900, 0, 8, 0xe, 0x0D0C0B00, 0x0000000A,},
|
||||
{2, 2200, 0, 8, 0xe, 0x0D0C0B00, 0x0000000A,},
|
||||
{}
|
||||
};
|
||||
|
||||
static const struct board_specific_parameters rdimm0[] = {
|
||||
/*
|
||||
* memory controller 0
|
||||
* num| hi| rank| clk| wrlvl | wrlvl | wrlvl
|
||||
* ranks| mhz| GB |adjst| start | ctl2 | ctl3
|
||||
*/
|
||||
{2, 1350, 0, 8, 6, 0x0708090B, 0x0C0D0E09,},
|
||||
{2, 1666, 0, 8, 7, 0x08090A0C, 0x0D0F100B,},
|
||||
{2, 1900, 0, 8, 7, 0x09090B0D, 0x0E10120B,},
|
||||
{2, 2200, 0, 8, 8, 0x090A0C0F, 0x1012130C,},
|
||||
{}
|
||||
};
|
||||
|
||||
/* DP-DDR DIMM */
|
||||
static const struct board_specific_parameters rdimm2[] = {
|
||||
/*
|
||||
* memory controller 2
|
||||
* num| hi| rank| clk| wrlvl | wrlvl | wrlvl
|
||||
* ranks| mhz| GB |adjst| start | ctl2 | ctl3
|
||||
*/
|
||||
{2, 1350, 0, 8, 6, 0x0708090B, 0x0C0D0E09,},
|
||||
{2, 1666, 0, 8, 7, 0x0B0A090C, 0x0D0F100B,},
|
||||
{2, 1900, 0, 8, 7, 0x09090B0D, 0x0E10120B,},
|
||||
{2, 2200, 0, 8, 8, 0x090A0C0F, 0x1012130C,},
|
||||
{}
|
||||
};
|
||||
|
||||
static const struct board_specific_parameters *udimms[] = {
|
||||
udimm0,
|
||||
udimm0,
|
||||
udimm2,
|
||||
};
|
||||
|
||||
static const struct board_specific_parameters *rdimms[] = {
|
||||
rdimm0,
|
||||
rdimm0,
|
||||
rdimm2,
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
805
u-boot/board/freescale/ls2080aqds/eth.c
Normal file
805
u-boot/board/freescale/ls2080aqds/eth.c
Normal file
@@ -0,0 +1,805 @@
|
||||
/*
|
||||
* Copyright 2015 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <netdev.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch/fsl_serdes.h>
|
||||
#include <hwconfig.h>
|
||||
#include <fsl_mdio.h>
|
||||
#include <malloc.h>
|
||||
#include <fm_eth.h>
|
||||
#include <i2c.h>
|
||||
#include <miiphy.h>
|
||||
#include <fsl-mc/ldpaa_wriop.h>
|
||||
|
||||
#include "../common/qixis.h"
|
||||
|
||||
#include "ls2080aqds_qixis.h"
|
||||
|
||||
#define MC_BOOT_ENV_VAR "mcinitcmd"
|
||||
|
||||
#ifdef CONFIG_FSL_MC_ENET
|
||||
/* - In LS2080A there are only 16 SERDES lanes, spread across 2 SERDES banks.
|
||||
* Bank 1 -> Lanes A, B, C, D, E, F, G, H
|
||||
* Bank 2 -> Lanes A,B, C, D, E, F, G, H
|
||||
*/
|
||||
|
||||
/* Mapping of 16 SERDES lanes to LS2080A QDS board slots. A value of '0' here
|
||||
* means that the mapping must be determined dynamically, or that the lane
|
||||
* maps to something other than a board slot.
|
||||
*/
|
||||
|
||||
static u8 lane_to_slot_fsm1[] = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
static u8 lane_to_slot_fsm2[] = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
/* On the Vitesse VSC8234XHG SGMII riser card there are 4 SGMII PHYs
|
||||
* housed.
|
||||
*/
|
||||
|
||||
static int xqsgii_riser_phy_addr[] = {
|
||||
XQSGMII_CARD_PHY1_PORT0_ADDR,
|
||||
XQSGMII_CARD_PHY2_PORT0_ADDR,
|
||||
XQSGMII_CARD_PHY3_PORT0_ADDR,
|
||||
XQSGMII_CARD_PHY4_PORT0_ADDR,
|
||||
XQSGMII_CARD_PHY3_PORT2_ADDR,
|
||||
XQSGMII_CARD_PHY1_PORT2_ADDR,
|
||||
XQSGMII_CARD_PHY4_PORT2_ADDR,
|
||||
XQSGMII_CARD_PHY2_PORT2_ADDR,
|
||||
};
|
||||
|
||||
static int sgmii_riser_phy_addr[] = {
|
||||
SGMII_CARD_PORT1_PHY_ADDR,
|
||||
SGMII_CARD_PORT2_PHY_ADDR,
|
||||
SGMII_CARD_PORT3_PHY_ADDR,
|
||||
SGMII_CARD_PORT4_PHY_ADDR,
|
||||
};
|
||||
|
||||
/* Slot2 does not have EMI connections */
|
||||
#define EMI_NONE 0xFFFFFFFF
|
||||
#define EMI1_SLOT1 0
|
||||
#define EMI1_SLOT2 1
|
||||
#define EMI1_SLOT3 2
|
||||
#define EMI1_SLOT4 3
|
||||
#define EMI1_SLOT5 4
|
||||
#define EMI1_SLOT6 5
|
||||
#define EMI2 6
|
||||
#define SFP_TX 0
|
||||
|
||||
static const char * const mdio_names[] = {
|
||||
"LS2080A_QDS_MDIO0",
|
||||
"LS2080A_QDS_MDIO1",
|
||||
"LS2080A_QDS_MDIO2",
|
||||
"LS2080A_QDS_MDIO3",
|
||||
"LS2080A_QDS_MDIO4",
|
||||
"LS2080A_QDS_MDIO5",
|
||||
DEFAULT_WRIOP_MDIO2_NAME,
|
||||
};
|
||||
|
||||
struct ls2080a_qds_mdio {
|
||||
u8 muxval;
|
||||
struct mii_dev *realbus;
|
||||
};
|
||||
|
||||
static void sgmii_configure_repeater(int serdes_port)
|
||||
{
|
||||
struct mii_dev *bus;
|
||||
uint8_t a = 0xf;
|
||||
int i, j, ret;
|
||||
int dpmac_id = 0, dpmac, mii_bus = 0;
|
||||
unsigned short value;
|
||||
char dev[2][20] = {"LS2080A_QDS_MDIO0", "LS2080A_QDS_MDIO3"};
|
||||
uint8_t i2c_addr[] = {0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5f, 0x60};
|
||||
|
||||
uint8_t ch_a_eq[] = {0x1, 0x2, 0x3, 0x7};
|
||||
uint8_t ch_a_ctl2[] = {0x81, 0x82, 0x83, 0x84};
|
||||
uint8_t ch_b_eq[] = {0x1, 0x2, 0x3, 0x7};
|
||||
uint8_t ch_b_ctl2[] = {0x81, 0x82, 0x83, 0x84};
|
||||
|
||||
int *riser_phy_addr = &xqsgii_riser_phy_addr[0];
|
||||
|
||||
/* Set I2c to Slot 1 */
|
||||
i2c_write(0x77, 0, 0, &a, 1);
|
||||
|
||||
for (dpmac = 0; dpmac < 8; dpmac++) {
|
||||
/* Check the PHY status */
|
||||
switch (serdes_port) {
|
||||
case 1:
|
||||
mii_bus = 0;
|
||||
dpmac_id = dpmac + 1;
|
||||
break;
|
||||
case 2:
|
||||
mii_bus = 1;
|
||||
dpmac_id = dpmac + 9;
|
||||
a = 0xb;
|
||||
i2c_write(0x76, 0, 0, &a, 1);
|
||||
break;
|
||||
}
|
||||
|
||||
ret = miiphy_set_current_dev(dev[mii_bus]);
|
||||
if (ret > 0)
|
||||
goto error;
|
||||
|
||||
bus = mdio_get_current_dev();
|
||||
debug("Reading from bus %s\n", bus->name);
|
||||
|
||||
ret = miiphy_write(dev[mii_bus], riser_phy_addr[dpmac], 0x1f,
|
||||
3);
|
||||
if (ret > 0)
|
||||
goto error;
|
||||
|
||||
mdelay(10);
|
||||
ret = miiphy_read(dev[mii_bus], riser_phy_addr[dpmac], 0x11,
|
||||
&value);
|
||||
if (ret > 0)
|
||||
goto error;
|
||||
|
||||
mdelay(10);
|
||||
|
||||
if ((value & 0xfff) == 0x40f) {
|
||||
printf("DPMAC %d:PHY is ..... Configured\n", dpmac_id);
|
||||
continue;
|
||||
}
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
for (j = 0; j < 4; j++) {
|
||||
a = 0x18;
|
||||
i2c_write(i2c_addr[dpmac], 6, 1, &a, 1);
|
||||
a = 0x38;
|
||||
i2c_write(i2c_addr[dpmac], 4, 1, &a, 1);
|
||||
a = 0x4;
|
||||
i2c_write(i2c_addr[dpmac], 8, 1, &a, 1);
|
||||
|
||||
i2c_write(i2c_addr[dpmac], 0xf, 1,
|
||||
&ch_a_eq[i], 1);
|
||||
i2c_write(i2c_addr[dpmac], 0x11, 1,
|
||||
&ch_a_ctl2[j], 1);
|
||||
|
||||
i2c_write(i2c_addr[dpmac], 0x16, 1,
|
||||
&ch_b_eq[i], 1);
|
||||
i2c_write(i2c_addr[dpmac], 0x18, 1,
|
||||
&ch_b_ctl2[j], 1);
|
||||
|
||||
a = 0x14;
|
||||
i2c_write(i2c_addr[dpmac], 0x23, 1, &a, 1);
|
||||
a = 0xb5;
|
||||
i2c_write(i2c_addr[dpmac], 0x2d, 1, &a, 1);
|
||||
a = 0x20;
|
||||
i2c_write(i2c_addr[dpmac], 4, 1, &a, 1);
|
||||
mdelay(100);
|
||||
ret = miiphy_read(dev[mii_bus],
|
||||
riser_phy_addr[dpmac],
|
||||
0x11, &value);
|
||||
if (ret > 0)
|
||||
goto error;
|
||||
|
||||
mdelay(1);
|
||||
ret = miiphy_read(dev[mii_bus],
|
||||
riser_phy_addr[dpmac],
|
||||
0x11, &value);
|
||||
if (ret > 0)
|
||||
goto error;
|
||||
mdelay(10);
|
||||
|
||||
if ((value & 0xfff) == 0x40f) {
|
||||
printf("DPMAC %d :PHY is configured ",
|
||||
dpmac_id);
|
||||
printf("after setting repeater 0x%x\n",
|
||||
value);
|
||||
i = 5;
|
||||
j = 5;
|
||||
} else
|
||||
printf("DPMAC %d :PHY is failed to ",
|
||||
dpmac_id);
|
||||
printf("configure the repeater 0x%x\n",
|
||||
value);
|
||||
}
|
||||
}
|
||||
}
|
||||
error:
|
||||
if (ret)
|
||||
printf("DPMAC %d ..... FAILED to configure PHY\n", dpmac_id);
|
||||
return;
|
||||
}
|
||||
|
||||
static void qsgmii_configure_repeater(int dpmac)
|
||||
{
|
||||
uint8_t a = 0xf;
|
||||
int i, j;
|
||||
int i2c_phy_addr = 0;
|
||||
int phy_addr = 0;
|
||||
int i2c_addr[] = {0x58, 0x59, 0x5a, 0x5b};
|
||||
|
||||
uint8_t ch_a_eq[] = {0x1, 0x2, 0x3, 0x7};
|
||||
uint8_t ch_a_ctl2[] = {0x81, 0x82, 0x83, 0x84};
|
||||
uint8_t ch_b_eq[] = {0x1, 0x2, 0x3, 0x7};
|
||||
uint8_t ch_b_ctl2[] = {0x81, 0x82, 0x83, 0x84};
|
||||
|
||||
const char *dev = "LS2080A_QDS_MDIO0";
|
||||
int ret = 0;
|
||||
unsigned short value;
|
||||
|
||||
/* Set I2c to Slot 1 */
|
||||
i2c_write(0x77, 0, 0, &a, 1);
|
||||
|
||||
switch (dpmac) {
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
i2c_phy_addr = i2c_addr[0];
|
||||
phy_addr = 0;
|
||||
break;
|
||||
|
||||
case 5:
|
||||
case 6:
|
||||
case 7:
|
||||
case 8:
|
||||
i2c_phy_addr = i2c_addr[1];
|
||||
phy_addr = 4;
|
||||
break;
|
||||
|
||||
case 9:
|
||||
case 10:
|
||||
case 11:
|
||||
case 12:
|
||||
i2c_phy_addr = i2c_addr[2];
|
||||
phy_addr = 8;
|
||||
break;
|
||||
|
||||
case 13:
|
||||
case 14:
|
||||
case 15:
|
||||
case 16:
|
||||
i2c_phy_addr = i2c_addr[3];
|
||||
phy_addr = 0xc;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Check the PHY status */
|
||||
ret = miiphy_set_current_dev(dev);
|
||||
ret = miiphy_write(dev, phy_addr, 0x1f, 3);
|
||||
mdelay(10);
|
||||
ret = miiphy_read(dev, phy_addr, 0x11, &value);
|
||||
mdelay(10);
|
||||
ret = miiphy_read(dev, phy_addr, 0x11, &value);
|
||||
mdelay(10);
|
||||
if ((value & 0xf) == 0xf) {
|
||||
printf("DPMAC %d :PHY is ..... Configured\n", dpmac);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
for (j = 0; j < 4; j++) {
|
||||
a = 0x18;
|
||||
i2c_write(i2c_phy_addr, 6, 1, &a, 1);
|
||||
a = 0x38;
|
||||
i2c_write(i2c_phy_addr, 4, 1, &a, 1);
|
||||
a = 0x4;
|
||||
i2c_write(i2c_phy_addr, 8, 1, &a, 1);
|
||||
|
||||
i2c_write(i2c_phy_addr, 0xf, 1, &ch_a_eq[i], 1);
|
||||
i2c_write(i2c_phy_addr, 0x11, 1, &ch_a_ctl2[j], 1);
|
||||
|
||||
i2c_write(i2c_phy_addr, 0x16, 1, &ch_b_eq[i], 1);
|
||||
i2c_write(i2c_phy_addr, 0x18, 1, &ch_b_ctl2[j], 1);
|
||||
|
||||
a = 0x14;
|
||||
i2c_write(i2c_phy_addr, 0x23, 1, &a, 1);
|
||||
a = 0xb5;
|
||||
i2c_write(i2c_phy_addr, 0x2d, 1, &a, 1);
|
||||
a = 0x20;
|
||||
i2c_write(i2c_phy_addr, 4, 1, &a, 1);
|
||||
mdelay(100);
|
||||
ret = miiphy_read(dev, phy_addr, 0x11, &value);
|
||||
if (ret > 0)
|
||||
goto error;
|
||||
mdelay(1);
|
||||
ret = miiphy_read(dev, phy_addr, 0x11, &value);
|
||||
if (ret > 0)
|
||||
goto error;
|
||||
mdelay(10);
|
||||
if ((value & 0xf) == 0xf) {
|
||||
printf("DPMAC %d :PHY is ..... Configured\n",
|
||||
dpmac);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
error:
|
||||
printf("DPMAC %d :PHY ..... FAILED to configure PHY\n", dpmac);
|
||||
return;
|
||||
}
|
||||
|
||||
static const char *ls2080a_qds_mdio_name_for_muxval(u8 muxval)
|
||||
{
|
||||
return mdio_names[muxval];
|
||||
}
|
||||
|
||||
struct mii_dev *mii_dev_for_muxval(u8 muxval)
|
||||
{
|
||||
struct mii_dev *bus;
|
||||
const char *name = ls2080a_qds_mdio_name_for_muxval(muxval);
|
||||
|
||||
if (!name) {
|
||||
printf("No bus for muxval %x\n", muxval);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bus = miiphy_get_dev_by_name(name);
|
||||
|
||||
if (!bus) {
|
||||
printf("No bus by name %s\n", name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return bus;
|
||||
}
|
||||
|
||||
static void ls2080a_qds_enable_SFP_TX(u8 muxval)
|
||||
{
|
||||
u8 brdcfg9;
|
||||
|
||||
brdcfg9 = QIXIS_READ(brdcfg[9]);
|
||||
brdcfg9 &= ~BRDCFG9_SFPTX_MASK;
|
||||
brdcfg9 |= (muxval << BRDCFG9_SFPTX_SHIFT);
|
||||
QIXIS_WRITE(brdcfg[9], brdcfg9);
|
||||
}
|
||||
|
||||
static void ls2080a_qds_mux_mdio(u8 muxval)
|
||||
{
|
||||
u8 brdcfg4;
|
||||
|
||||
if (muxval <= 5) {
|
||||
brdcfg4 = QIXIS_READ(brdcfg[4]);
|
||||
brdcfg4 &= ~BRDCFG4_EMISEL_MASK;
|
||||
brdcfg4 |= (muxval << BRDCFG4_EMISEL_SHIFT);
|
||||
QIXIS_WRITE(brdcfg[4], brdcfg4);
|
||||
}
|
||||
}
|
||||
|
||||
static int ls2080a_qds_mdio_read(struct mii_dev *bus, int addr,
|
||||
int devad, int regnum)
|
||||
{
|
||||
struct ls2080a_qds_mdio *priv = bus->priv;
|
||||
|
||||
ls2080a_qds_mux_mdio(priv->muxval);
|
||||
|
||||
return priv->realbus->read(priv->realbus, addr, devad, regnum);
|
||||
}
|
||||
|
||||
static int ls2080a_qds_mdio_write(struct mii_dev *bus, int addr, int devad,
|
||||
int regnum, u16 value)
|
||||
{
|
||||
struct ls2080a_qds_mdio *priv = bus->priv;
|
||||
|
||||
ls2080a_qds_mux_mdio(priv->muxval);
|
||||
|
||||
return priv->realbus->write(priv->realbus, addr, devad, regnum, value);
|
||||
}
|
||||
|
||||
static int ls2080a_qds_mdio_reset(struct mii_dev *bus)
|
||||
{
|
||||
struct ls2080a_qds_mdio *priv = bus->priv;
|
||||
|
||||
return priv->realbus->reset(priv->realbus);
|
||||
}
|
||||
|
||||
static int ls2080a_qds_mdio_init(char *realbusname, u8 muxval)
|
||||
{
|
||||
struct ls2080a_qds_mdio *pmdio;
|
||||
struct mii_dev *bus = mdio_alloc();
|
||||
|
||||
if (!bus) {
|
||||
printf("Failed to allocate ls2080a_qds MDIO bus\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
pmdio = malloc(sizeof(*pmdio));
|
||||
if (!pmdio) {
|
||||
printf("Failed to allocate ls2080a_qds private data\n");
|
||||
free(bus);
|
||||
return -1;
|
||||
}
|
||||
|
||||
bus->read = ls2080a_qds_mdio_read;
|
||||
bus->write = ls2080a_qds_mdio_write;
|
||||
bus->reset = ls2080a_qds_mdio_reset;
|
||||
strcpy(bus->name, ls2080a_qds_mdio_name_for_muxval(muxval));
|
||||
|
||||
pmdio->realbus = miiphy_get_dev_by_name(realbusname);
|
||||
|
||||
if (!pmdio->realbus) {
|
||||
printf("No bus with name %s\n", realbusname);
|
||||
free(bus);
|
||||
free(pmdio);
|
||||
return -1;
|
||||
}
|
||||
|
||||
pmdio->muxval = muxval;
|
||||
bus->priv = pmdio;
|
||||
|
||||
return mdio_register(bus);
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize the dpmac_info array.
|
||||
*
|
||||
*/
|
||||
static void initialize_dpmac_to_slot(void)
|
||||
{
|
||||
struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR;
|
||||
int serdes1_prtcl = (in_le32(&gur->rcwsr[28]) &
|
||||
FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_MASK)
|
||||
>> FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_SHIFT;
|
||||
int serdes2_prtcl = (in_le32(&gur->rcwsr[28]) &
|
||||
FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_MASK)
|
||||
>> FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_SHIFT;
|
||||
|
||||
char *env_hwconfig;
|
||||
env_hwconfig = getenv("hwconfig");
|
||||
|
||||
switch (serdes1_prtcl) {
|
||||
case 0x07:
|
||||
case 0x09:
|
||||
case 0x33:
|
||||
printf("qds: WRIOP: Supported SerDes1 Protocol 0x%02x\n",
|
||||
serdes1_prtcl);
|
||||
lane_to_slot_fsm1[0] = EMI1_SLOT1;
|
||||
lane_to_slot_fsm1[1] = EMI1_SLOT1;
|
||||
lane_to_slot_fsm1[2] = EMI1_SLOT1;
|
||||
lane_to_slot_fsm1[3] = EMI1_SLOT1;
|
||||
if (hwconfig_f("xqsgmii", env_hwconfig)) {
|
||||
lane_to_slot_fsm1[4] = EMI1_SLOT1;
|
||||
lane_to_slot_fsm1[5] = EMI1_SLOT1;
|
||||
lane_to_slot_fsm1[6] = EMI1_SLOT1;
|
||||
lane_to_slot_fsm1[7] = EMI1_SLOT1;
|
||||
} else {
|
||||
lane_to_slot_fsm1[4] = EMI1_SLOT2;
|
||||
lane_to_slot_fsm1[5] = EMI1_SLOT2;
|
||||
lane_to_slot_fsm1[6] = EMI1_SLOT2;
|
||||
lane_to_slot_fsm1[7] = EMI1_SLOT2;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x2A:
|
||||
printf("qds: WRIOP: Supported SerDes1 Protocol 0x%02x\n",
|
||||
serdes1_prtcl);
|
||||
break;
|
||||
default:
|
||||
printf("%s qds: WRIOP: Unsupported SerDes1 Protocol 0x%02x\n",
|
||||
__func__, serdes1_prtcl);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (serdes2_prtcl) {
|
||||
case 0x07:
|
||||
case 0x08:
|
||||
case 0x09:
|
||||
case 0x49:
|
||||
printf("qds: WRIOP: Supported SerDes2 Protocol 0x%02x\n",
|
||||
serdes2_prtcl);
|
||||
lane_to_slot_fsm2[0] = EMI1_SLOT4;
|
||||
lane_to_slot_fsm2[1] = EMI1_SLOT4;
|
||||
lane_to_slot_fsm2[2] = EMI1_SLOT4;
|
||||
lane_to_slot_fsm2[3] = EMI1_SLOT4;
|
||||
|
||||
if (hwconfig_f("xqsgmii", env_hwconfig)) {
|
||||
lane_to_slot_fsm2[4] = EMI1_SLOT4;
|
||||
lane_to_slot_fsm2[5] = EMI1_SLOT4;
|
||||
lane_to_slot_fsm2[6] = EMI1_SLOT4;
|
||||
lane_to_slot_fsm2[7] = EMI1_SLOT4;
|
||||
} else {
|
||||
/* No MDIO physical connection */
|
||||
lane_to_slot_fsm2[4] = EMI1_SLOT6;
|
||||
lane_to_slot_fsm2[5] = EMI1_SLOT6;
|
||||
lane_to_slot_fsm2[6] = EMI1_SLOT6;
|
||||
lane_to_slot_fsm2[7] = EMI1_SLOT6;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
printf(" %s qds: WRIOP: Unsupported SerDes2 Protocol 0x%02x\n",
|
||||
__func__ , serdes2_prtcl);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ls2080a_handle_phy_interface_sgmii(int dpmac_id)
|
||||
{
|
||||
int lane, slot;
|
||||
struct mii_dev *bus;
|
||||
struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR;
|
||||
int serdes1_prtcl = (in_le32(&gur->rcwsr[28]) &
|
||||
FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_MASK)
|
||||
>> FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_SHIFT;
|
||||
int serdes2_prtcl = (in_le32(&gur->rcwsr[28]) &
|
||||
FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_MASK)
|
||||
>> FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_SHIFT;
|
||||
|
||||
int *riser_phy_addr;
|
||||
char *env_hwconfig = getenv("hwconfig");
|
||||
|
||||
if (hwconfig_f("xqsgmii", env_hwconfig))
|
||||
riser_phy_addr = &xqsgii_riser_phy_addr[0];
|
||||
else
|
||||
riser_phy_addr = &sgmii_riser_phy_addr[0];
|
||||
|
||||
if (dpmac_id > WRIOP1_DPMAC9)
|
||||
goto serdes2;
|
||||
|
||||
switch (serdes1_prtcl) {
|
||||
case 0x07:
|
||||
|
||||
lane = serdes_get_first_lane(FSL_SRDS_1, SGMII1 + dpmac_id);
|
||||
slot = lane_to_slot_fsm1[lane];
|
||||
|
||||
switch (++slot) {
|
||||
case 1:
|
||||
/* Slot housing a SGMII riser card? */
|
||||
wriop_set_phy_address(dpmac_id,
|
||||
riser_phy_addr[dpmac_id - 1]);
|
||||
dpmac_info[dpmac_id].board_mux = EMI1_SLOT1;
|
||||
bus = mii_dev_for_muxval(EMI1_SLOT1);
|
||||
wriop_set_mdio(dpmac_id, bus);
|
||||
break;
|
||||
case 2:
|
||||
/* Slot housing a SGMII riser card? */
|
||||
wriop_set_phy_address(dpmac_id,
|
||||
riser_phy_addr[dpmac_id - 1]);
|
||||
dpmac_info[dpmac_id].board_mux = EMI1_SLOT2;
|
||||
bus = mii_dev_for_muxval(EMI1_SLOT2);
|
||||
wriop_set_mdio(dpmac_id, bus);
|
||||
break;
|
||||
case 3:
|
||||
break;
|
||||
case 4:
|
||||
break;
|
||||
case 5:
|
||||
break;
|
||||
case 6:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
printf("%s qds: WRIOP: Unsupported SerDes1 Protocol 0x%02x\n",
|
||||
__func__ , serdes1_prtcl);
|
||||
break;
|
||||
}
|
||||
|
||||
serdes2:
|
||||
switch (serdes2_prtcl) {
|
||||
case 0x07:
|
||||
case 0x08:
|
||||
case 0x49:
|
||||
lane = serdes_get_first_lane(FSL_SRDS_2, SGMII9 +
|
||||
(dpmac_id - 9));
|
||||
slot = lane_to_slot_fsm2[lane];
|
||||
|
||||
switch (++slot) {
|
||||
case 1:
|
||||
break;
|
||||
case 3:
|
||||
break;
|
||||
case 4:
|
||||
/* Slot housing a SGMII riser card? */
|
||||
wriop_set_phy_address(dpmac_id,
|
||||
riser_phy_addr[dpmac_id - 9]);
|
||||
dpmac_info[dpmac_id].board_mux = EMI1_SLOT4;
|
||||
bus = mii_dev_for_muxval(EMI1_SLOT4);
|
||||
wriop_set_mdio(dpmac_id, bus);
|
||||
break;
|
||||
case 5:
|
||||
break;
|
||||
case 6:
|
||||
/* Slot housing a SGMII riser card? */
|
||||
wriop_set_phy_address(dpmac_id,
|
||||
riser_phy_addr[dpmac_id - 13]);
|
||||
dpmac_info[dpmac_id].board_mux = EMI1_SLOT6;
|
||||
bus = mii_dev_for_muxval(EMI1_SLOT6);
|
||||
wriop_set_mdio(dpmac_id, bus);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
printf("%s qds: WRIOP: Unsupported SerDes2 Protocol 0x%02x\n",
|
||||
__func__, serdes2_prtcl);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ls2080a_handle_phy_interface_qsgmii(int dpmac_id)
|
||||
{
|
||||
int lane = 0, slot;
|
||||
struct mii_dev *bus;
|
||||
struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR;
|
||||
int serdes1_prtcl = (in_le32(&gur->rcwsr[28]) &
|
||||
FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_MASK)
|
||||
>> FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_SHIFT;
|
||||
|
||||
switch (serdes1_prtcl) {
|
||||
case 0x33:
|
||||
switch (dpmac_id) {
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
lane = serdes_get_first_lane(FSL_SRDS_1, QSGMII_A);
|
||||
break;
|
||||
case 5:
|
||||
case 6:
|
||||
case 7:
|
||||
case 8:
|
||||
lane = serdes_get_first_lane(FSL_SRDS_1, QSGMII_B);
|
||||
break;
|
||||
case 9:
|
||||
case 10:
|
||||
case 11:
|
||||
case 12:
|
||||
lane = serdes_get_first_lane(FSL_SRDS_1, QSGMII_C);
|
||||
break;
|
||||
case 13:
|
||||
case 14:
|
||||
case 15:
|
||||
case 16:
|
||||
lane = serdes_get_first_lane(FSL_SRDS_1, QSGMII_D);
|
||||
break;
|
||||
}
|
||||
|
||||
slot = lane_to_slot_fsm1[lane];
|
||||
|
||||
switch (++slot) {
|
||||
case 1:
|
||||
/* Slot housing a QSGMII riser card? */
|
||||
wriop_set_phy_address(dpmac_id, dpmac_id - 1);
|
||||
dpmac_info[dpmac_id].board_mux = EMI1_SLOT1;
|
||||
bus = mii_dev_for_muxval(EMI1_SLOT1);
|
||||
wriop_set_mdio(dpmac_id, bus);
|
||||
break;
|
||||
case 3:
|
||||
break;
|
||||
case 4:
|
||||
break;
|
||||
case 5:
|
||||
break;
|
||||
case 6:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
printf("qds: WRIOP: Unsupported SerDes Protocol 0x%02x\n",
|
||||
serdes1_prtcl);
|
||||
break;
|
||||
}
|
||||
|
||||
qsgmii_configure_repeater(dpmac_id);
|
||||
}
|
||||
|
||||
void ls2080a_handle_phy_interface_xsgmii(int i)
|
||||
{
|
||||
struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR;
|
||||
int serdes1_prtcl = (in_le32(&gur->rcwsr[28]) &
|
||||
FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_MASK)
|
||||
>> FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_SHIFT;
|
||||
|
||||
switch (serdes1_prtcl) {
|
||||
case 0x2A:
|
||||
/*
|
||||
* XFI does not need a PHY to work, but to avoid U-Boot use
|
||||
* default PHY address which is zero to a MAC when it found
|
||||
* a MAC has no PHY address, we give a PHY address to XFI
|
||||
* MAC, and should not use a real XAUI PHY address, since
|
||||
* MDIO can access it successfully, and then MDIO thinks
|
||||
* the XAUI card is used for the XFI MAC, which will cause
|
||||
* error.
|
||||
*/
|
||||
wriop_set_phy_address(i, i + 4);
|
||||
ls2080a_qds_enable_SFP_TX(SFP_TX);
|
||||
|
||||
break;
|
||||
default:
|
||||
printf("qds: WRIOP: Unsupported SerDes Protocol 0x%02x\n",
|
||||
serdes1_prtcl);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
int board_eth_init(bd_t *bis)
|
||||
{
|
||||
int error;
|
||||
char *mc_boot_env_var;
|
||||
#ifdef CONFIG_FSL_MC_ENET
|
||||
struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR;
|
||||
int serdes1_prtcl = (in_le32(&gur->rcwsr[28]) &
|
||||
FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_MASK)
|
||||
>> FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_SHIFT;
|
||||
int serdes2_prtcl = (in_le32(&gur->rcwsr[28]) &
|
||||
FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_MASK)
|
||||
>> FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_SHIFT;
|
||||
|
||||
struct memac_mdio_info *memac_mdio0_info;
|
||||
struct memac_mdio_info *memac_mdio1_info;
|
||||
unsigned int i;
|
||||
char *env_hwconfig;
|
||||
|
||||
env_hwconfig = getenv("hwconfig");
|
||||
|
||||
initialize_dpmac_to_slot();
|
||||
|
||||
memac_mdio0_info = (struct memac_mdio_info *)malloc(
|
||||
sizeof(struct memac_mdio_info));
|
||||
memac_mdio0_info->regs =
|
||||
(struct memac_mdio_controller *)
|
||||
CONFIG_SYS_FSL_WRIOP1_MDIO1;
|
||||
memac_mdio0_info->name = DEFAULT_WRIOP_MDIO1_NAME;
|
||||
|
||||
/* Register the real MDIO1 bus */
|
||||
fm_memac_mdio_init(bis, memac_mdio0_info);
|
||||
|
||||
memac_mdio1_info = (struct memac_mdio_info *)malloc(
|
||||
sizeof(struct memac_mdio_info));
|
||||
memac_mdio1_info->regs =
|
||||
(struct memac_mdio_controller *)
|
||||
CONFIG_SYS_FSL_WRIOP1_MDIO2;
|
||||
memac_mdio1_info->name = DEFAULT_WRIOP_MDIO2_NAME;
|
||||
|
||||
/* Register the real MDIO2 bus */
|
||||
fm_memac_mdio_init(bis, memac_mdio1_info);
|
||||
|
||||
/* Register the muxing front-ends to the MDIO buses */
|
||||
ls2080a_qds_mdio_init(DEFAULT_WRIOP_MDIO1_NAME, EMI1_SLOT1);
|
||||
ls2080a_qds_mdio_init(DEFAULT_WRIOP_MDIO1_NAME, EMI1_SLOT2);
|
||||
ls2080a_qds_mdio_init(DEFAULT_WRIOP_MDIO1_NAME, EMI1_SLOT3);
|
||||
ls2080a_qds_mdio_init(DEFAULT_WRIOP_MDIO1_NAME, EMI1_SLOT4);
|
||||
ls2080a_qds_mdio_init(DEFAULT_WRIOP_MDIO1_NAME, EMI1_SLOT5);
|
||||
ls2080a_qds_mdio_init(DEFAULT_WRIOP_MDIO1_NAME, EMI1_SLOT6);
|
||||
|
||||
ls2080a_qds_mdio_init(DEFAULT_WRIOP_MDIO2_NAME, EMI2);
|
||||
|
||||
for (i = WRIOP1_DPMAC1; i < NUM_WRIOP_PORTS; i++) {
|
||||
switch (wriop_get_enet_if(i)) {
|
||||
case PHY_INTERFACE_MODE_QSGMII:
|
||||
ls2080a_handle_phy_interface_qsgmii(i);
|
||||
break;
|
||||
case PHY_INTERFACE_MODE_SGMII:
|
||||
ls2080a_handle_phy_interface_sgmii(i);
|
||||
break;
|
||||
case PHY_INTERFACE_MODE_XGMII:
|
||||
ls2080a_handle_phy_interface_xsgmii(i);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
if (i == 16)
|
||||
i = NUM_WRIOP_PORTS;
|
||||
}
|
||||
}
|
||||
|
||||
mc_boot_env_var = getenv(MC_BOOT_ENV_VAR);
|
||||
if (mc_boot_env_var)
|
||||
run_command_list(mc_boot_env_var, -1, 0);
|
||||
error = cpu_eth_init(bis);
|
||||
|
||||
if (hwconfig_f("xqsgmii", env_hwconfig)) {
|
||||
if (serdes1_prtcl == 0x7)
|
||||
sgmii_configure_repeater(1);
|
||||
if (serdes2_prtcl == 0x7 || serdes2_prtcl == 0x8 ||
|
||||
serdes2_prtcl == 0x49)
|
||||
sgmii_configure_repeater(2);
|
||||
}
|
||||
#endif
|
||||
error = pci_eth_init(bis);
|
||||
return error;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_FSL_MC_ENET
|
||||
|
||||
#endif
|
||||
345
u-boot/board/freescale/ls2080aqds/ls2080aqds.c
Normal file
345
u-boot/board/freescale/ls2080aqds/ls2080aqds.c
Normal file
@@ -0,0 +1,345 @@
|
||||
/*
|
||||
* Copyright 2015 Freescale Semiconductor
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
#include <common.h>
|
||||
#include <malloc.h>
|
||||
#include <errno.h>
|
||||
#include <netdev.h>
|
||||
#include <fsl_ifc.h>
|
||||
#include <fsl_ddr.h>
|
||||
#include <asm/io.h>
|
||||
#include <fdt_support.h>
|
||||
#include <libfdt.h>
|
||||
#include <fsl_debug_server.h>
|
||||
#include <fsl-mc/fsl_mc.h>
|
||||
#include <environment.h>
|
||||
#include <i2c.h>
|
||||
#include <rtc.h>
|
||||
#include <asm/arch/soc.h>
|
||||
#include <hwconfig.h>
|
||||
#include <fsl_sec.h>
|
||||
|
||||
#include "../common/qixis.h"
|
||||
#include "ls2080aqds_qixis.h"
|
||||
|
||||
#define PIN_MUX_SEL_SDHC 0x00
|
||||
#define PIN_MUX_SEL_DSPI 0x0a
|
||||
#define SCFG_QSPICLKCTRL_DIV_20 (5 << 27)
|
||||
|
||||
#define SET_SDHC_MUX_SEL(reg, value) ((reg & 0xf0) | value)
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
enum {
|
||||
MUX_TYPE_SDHC,
|
||||
MUX_TYPE_DSPI,
|
||||
};
|
||||
|
||||
unsigned long long get_qixis_addr(void)
|
||||
{
|
||||
unsigned long long addr;
|
||||
|
||||
if (gd->flags & GD_FLG_RELOC)
|
||||
addr = QIXIS_BASE_PHYS;
|
||||
else
|
||||
addr = QIXIS_BASE_PHYS_EARLY;
|
||||
|
||||
/*
|
||||
* IFC address under 256MB is mapped to 0x30000000, any address above
|
||||
* is mapped to 0x5_10000000 up to 4GB.
|
||||
*/
|
||||
addr = addr > 0x10000000 ? addr + 0x500000000ULL : addr + 0x30000000;
|
||||
|
||||
return addr;
|
||||
}
|
||||
|
||||
int checkboard(void)
|
||||
{
|
||||
char buf[64];
|
||||
u8 sw;
|
||||
static const char *const freq[] = {"100", "125", "156.25",
|
||||
"100 separate SSCG"};
|
||||
int clock;
|
||||
|
||||
cpu_name(buf);
|
||||
printf("Board: %s-QDS, ", buf);
|
||||
|
||||
sw = QIXIS_READ(arch);
|
||||
printf("Board Arch: V%d, ", sw >> 4);
|
||||
printf("Board version: %c, boot from ", (sw & 0xf) + 'A' - 1);
|
||||
|
||||
memset((u8 *)buf, 0x00, ARRAY_SIZE(buf));
|
||||
|
||||
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 == 0xf)
|
||||
puts("QSPI\n");
|
||||
else if (sw == 0x15)
|
||||
printf("IFCCard\n");
|
||||
else
|
||||
printf("invalid setting of SW%u\n", QIXIS_LBMAP_SWITCH);
|
||||
|
||||
printf("FPGA: v%d (%s), build %d",
|
||||
(int)QIXIS_READ(scver), qixis_read_tag(buf),
|
||||
(int)qixis_read_minor());
|
||||
/* the timestamp string contains "\n" at the end */
|
||||
printf(" on %s", qixis_read_time(buf));
|
||||
|
||||
/*
|
||||
* Display the actual SERDES reference clocks as configured by the
|
||||
* dip switches on the board. Note that the SWx registers could
|
||||
* technically be set to force the reference clocks to match the
|
||||
* values that the SERDES expects (or vice versa). For now, however,
|
||||
* we just display both values and hope the user notices when they
|
||||
* don't match.
|
||||
*/
|
||||
puts("SERDES1 Reference : ");
|
||||
sw = QIXIS_READ(brdcfg[2]);
|
||||
clock = (sw >> 6) & 3;
|
||||
printf("Clock1 = %sMHz ", freq[clock]);
|
||||
clock = (sw >> 4) & 3;
|
||||
printf("Clock2 = %sMHz", freq[clock]);
|
||||
|
||||
puts("\nSERDES2 Reference : ");
|
||||
clock = (sw >> 2) & 3;
|
||||
printf("Clock1 = %sMHz ", freq[clock]);
|
||||
clock = (sw >> 0) & 3;
|
||||
printf("Clock2 = %sMHz\n", freq[clock]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned long get_board_sys_clk(void)
|
||||
{
|
||||
u8 sysclk_conf = QIXIS_READ(brdcfg[1]);
|
||||
|
||||
switch (sysclk_conf & 0x0F) {
|
||||
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 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 config_board_mux(int ctrl_type)
|
||||
{
|
||||
u8 reg5;
|
||||
|
||||
reg5 = QIXIS_READ(brdcfg[5]);
|
||||
|
||||
switch (ctrl_type) {
|
||||
case MUX_TYPE_SDHC:
|
||||
reg5 = SET_SDHC_MUX_SEL(reg5, PIN_MUX_SEL_SDHC);
|
||||
break;
|
||||
case MUX_TYPE_DSPI:
|
||||
reg5 = SET_SDHC_MUX_SEL(reg5, PIN_MUX_SEL_DSPI);
|
||||
break;
|
||||
default:
|
||||
printf("Wrong mux interface type\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
QIXIS_WRITE(brdcfg[5], reg5);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int board_init(void)
|
||||
{
|
||||
char *env_hwconfig;
|
||||
u32 __iomem *dcfg_ccsr = (u32 __iomem *)DCFG_BASE;
|
||||
u32 val;
|
||||
|
||||
init_final_memctl_regs();
|
||||
|
||||
val = in_le32(dcfg_ccsr + DCFG_RCWSR13 / 4);
|
||||
|
||||
env_hwconfig = getenv("hwconfig");
|
||||
|
||||
if (hwconfig_f("dspi", env_hwconfig) &&
|
||||
DCFG_RCWSR13_DSPI == (val & (u32)(0xf << 8)))
|
||||
config_board_mux(MUX_TYPE_DSPI);
|
||||
else
|
||||
config_board_mux(MUX_TYPE_SDHC);
|
||||
|
||||
#if defined(CONFIG_NAND) && defined(CONFIG_FSL_QSPI)
|
||||
val = in_le32(dcfg_ccsr + DCFG_RCWSR15 / 4);
|
||||
|
||||
if (DCFG_RCWSR15_IFCGRPABASE_QSPI == (val & (u32)0x3))
|
||||
QIXIS_WRITE(brdcfg[9],
|
||||
(QIXIS_READ(brdcfg[9]) & 0xf8) |
|
||||
FSL_QIXIS_BRDCFG9_QSPI);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ENV_IS_NOWHERE
|
||||
gd->env_addr = (ulong)&default_environment[0];
|
||||
#endif
|
||||
select_i2c_ch_pca9547(I2C_MUX_CH_DEFAULT);
|
||||
rtc_enable_32khz_output();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int board_early_init_f(void)
|
||||
{
|
||||
#ifdef CONFIG_SYS_I2C_EARLY_INIT
|
||||
i2c_early_init_f();
|
||||
#endif
|
||||
fsl_lsch3_early_init_f();
|
||||
#ifdef CONFIG_FSL_QSPI
|
||||
/* input clk: 1/2 platform clk, output: input/20 */
|
||||
out_le32(SCFG_BASE + SCFG_QSPICLKCTLR, SCFG_QSPICLKCTRL_DIV_20);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
void detail_board_ddr_info(void)
|
||||
{
|
||||
puts("\nDDR ");
|
||||
print_size(gd->bd->bi_dram[0].size + gd->bd->bi_dram[1].size, "");
|
||||
print_ddr_info(0);
|
||||
#ifdef CONFIG_SYS_FSL_HAS_DP_DDR
|
||||
if (soc_has_dp_ddr() && gd->bd->bi_dram[2].size) {
|
||||
puts("\nDP-DDR ");
|
||||
print_size(gd->bd->bi_dram[2].size, "");
|
||||
print_ddr_info(CONFIG_DP_DDR_CTRL);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
int dram_init(void)
|
||||
{
|
||||
gd->ram_size = initdram(0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_ARCH_MISC_INIT)
|
||||
int arch_misc_init(void)
|
||||
{
|
||||
#ifdef CONFIG_FSL_DEBUG_SERVER
|
||||
debug_server_init();
|
||||
#endif
|
||||
#ifdef CONFIG_FSL_CAAM
|
||||
sec_init();
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_FSL_MC_ENET
|
||||
void fdt_fixup_board_enet(void *fdt)
|
||||
{
|
||||
int offset;
|
||||
|
||||
offset = fdt_path_offset(fdt, "/soc/fsl-mc");
|
||||
|
||||
if (offset < 0)
|
||||
offset = fdt_path_offset(fdt, "/fsl-mc");
|
||||
|
||||
if (offset < 0) {
|
||||
printf("%s: ERROR: fsl-mc node not found in device tree (error %d)\n",
|
||||
__func__, offset);
|
||||
return;
|
||||
}
|
||||
|
||||
if (get_mc_boot_status() == 0)
|
||||
fdt_status_okay(fdt, offset);
|
||||
else
|
||||
fdt_status_fail(fdt, offset);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_OF_BOARD_SETUP
|
||||
int ft_board_setup(void *blob, bd_t *bd)
|
||||
{
|
||||
#ifdef CONFIG_FSL_MC_ENET
|
||||
int err;
|
||||
#endif
|
||||
u64 base[CONFIG_NR_DRAM_BANKS];
|
||||
u64 size[CONFIG_NR_DRAM_BANKS];
|
||||
|
||||
ft_cpu_setup(blob, bd);
|
||||
|
||||
/* fixup DT for the two GPP DDR banks */
|
||||
base[0] = gd->bd->bi_dram[0].start;
|
||||
size[0] = gd->bd->bi_dram[0].size;
|
||||
base[1] = gd->bd->bi_dram[1].start;
|
||||
size[1] = gd->bd->bi_dram[1].size;
|
||||
|
||||
fdt_fixup_memory_banks(blob, base, size, 2);
|
||||
|
||||
fdt_fixup_dr_usb(blob, bd);
|
||||
|
||||
#ifdef CONFIG_FSL_MC_ENET
|
||||
fdt_fixup_board_enet(blob);
|
||||
err = fsl_mc_ldpaa_exit(bd);
|
||||
if (err)
|
||||
return err;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
void qixis_dump_switch(void)
|
||||
{
|
||||
int i, nr_of_cfgsw;
|
||||
|
||||
QIXIS_WRITE(cms[0], 0x00);
|
||||
nr_of_cfgsw = QIXIS_READ(cms[1]);
|
||||
|
||||
puts("DIP switch settings dump:\n");
|
||||
for (i = 1; i <= nr_of_cfgsw; i++) {
|
||||
QIXIS_WRITE(cms[0], i);
|
||||
printf("SW%d = (0x%02x)\n", i, QIXIS_READ(cms[1]));
|
||||
}
|
||||
}
|
||||
30
u-boot/board/freescale/ls2080aqds/ls2080aqds_qixis.h
Normal file
30
u-boot/board/freescale/ls2080aqds/ls2080aqds_qixis.h
Normal file
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright 2015 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#ifndef __LS2_QDS_QIXIS_H__
|
||||
#define __LS2_QDS_QIXIS_H__
|
||||
|
||||
/* 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
|
||||
|
||||
/* DDRCLK */
|
||||
#define QIXIS_DDRCLK_66 0x0
|
||||
#define QIXIS_DDRCLK_100 0x1
|
||||
#define QIXIS_DDRCLK_125 0x2
|
||||
#define QIXIS_DDRCLK_133 0x3
|
||||
|
||||
#define BRDCFG4_EMISEL_MASK 0xE0
|
||||
#define BRDCFG4_EMISEL_SHIFT 5
|
||||
#define BRDCFG9_SFPTX_MASK 0x10
|
||||
#define BRDCFG9_SFPTX_SHIFT 4
|
||||
#endif /*__LS2_QDS_QIXIS_H__*/
|
||||
Reference in New Issue
Block a user