diff options
Diffstat (limited to 'board/freescale')
-rw-r--r-- | board/freescale/common/Makefile | 2 | ||||
-rw-r--r-- | board/freescale/common/diu_ch7301.c | 136 | ||||
-rw-r--r-- | board/freescale/common/diu_ch7301.h | 13 | ||||
-rw-r--r-- | board/freescale/t1040qds/diu.c | 134 | ||||
-rw-r--r-- | board/freescale/t104xrdb/Makefile | 1 | ||||
-rw-r--r-- | board/freescale/t104xrdb/diu.c | 84 | ||||
-rw-r--r-- | board/freescale/t104xrdb/spl.c | 19 | ||||
-rw-r--r-- | board/freescale/t4qds/README | 194 | ||||
-rw-r--r-- | board/freescale/t4qds/eth.c | 136 |
9 files changed, 575 insertions, 144 deletions
diff --git a/board/freescale/common/Makefile b/board/freescale/common/Makefile index 22b57cc..50d7731 100644 --- a/board/freescale/common/Makefile +++ b/board/freescale/common/Makefile @@ -34,6 +34,8 @@ ifndef CONFIG_RAMBOOT_PBL obj-$(CONFIG_FSL_FIXED_MMC_LOCATION) += sdhc_boot.o endif +obj-$(CONFIG_FSL_DIU_CH7301) += diu_ch7301.o + obj-$(CONFIG_MPC8541CDS) += cds_pci_ft.o obj-$(CONFIG_MPC8548CDS) += cds_pci_ft.o obj-$(CONFIG_MPC8555CDS) += cds_pci_ft.o diff --git a/board/freescale/common/diu_ch7301.c b/board/freescale/common/diu_ch7301.c new file mode 100644 index 0000000..82ce870 --- /dev/null +++ b/board/freescale/common/diu_ch7301.c @@ -0,0 +1,136 @@ +/* + * Copyright 2014 Freescale Semiconductor, Inc. + * Authors: Priyanka Jain <Priyanka.Jain@freescale.com> + * Wang Dongsheng <dongsheng.wang@freescale.com> + * + * This file is copied and modified from the original t1040qds/diu.c. + * Encoder can be used in T104x and LSx Platform. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <stdio_dev.h> +#include <i2c.h> + +#define I2C_DVI_INPUT_DATA_FORMAT_REG 0x1F +#define I2C_DVI_PLL_CHARGE_CNTL_REG 0x33 +#define I2C_DVI_PLL_DIVIDER_REG 0x34 +#define I2C_DVI_PLL_SUPPLY_CNTL_REG 0x35 +#define I2C_DVI_PLL_FILTER_REG 0x36 +#define I2C_DVI_TEST_PATTERN_REG 0x48 +#define I2C_DVI_POWER_MGMT_REG 0x49 +#define I2C_DVI_LOCK_STATE_REG 0x4D +#define I2C_DVI_SYNC_POLARITY_REG 0x56 + +/* + * Set VSYNC/HSYNC to active high. This is polarity of sync signals + * from DIU->DVI. The DIU default is active igh, so DVI is set to + * active high. + */ +#define I2C_DVI_INPUT_DATA_FORMAT_VAL 0x98 + +#define I2C_DVI_PLL_CHARGE_CNTL_HIGH_SPEED_VAL 0x06 +#define I2C_DVI_PLL_DIVIDER_HIGH_SPEED_VAL 0x26 +#define I2C_DVI_PLL_FILTER_HIGH_SPEED_VAL 0xA0 +#define I2C_DVI_PLL_CHARGE_CNTL_LOW_SPEED_VAL 0x08 +#define I2C_DVI_PLL_DIVIDER_LOW_SPEED_VAL 0x16 +#define I2C_DVI_PLL_FILTER_LOW_SPEED_VAL 0x60 + +/* Clear test pattern */ +#define I2C_DVI_TEST_PATTERN_VAL 0x18 +/* Exit Power-down mode */ +#define I2C_DVI_POWER_MGMT_VAL 0xC0 + +/* Monitor polarity is handled via DVI Sync Polarity Register */ +#define I2C_DVI_SYNC_POLARITY_VAL 0x00 + +/* Programming of HDMI Chrontel CH7301 connector */ +int diu_set_dvi_encoder(unsigned int pixclock) +{ + int ret; + u8 temp; + + temp = I2C_DVI_TEST_PATTERN_VAL; + ret = i2c_write(CONFIG_SYS_I2C_DVI_ADDR, I2C_DVI_TEST_PATTERN_REG, 1, + &temp, 1); + if (ret) { + puts("I2C: failed to select proper dvi test pattern\n"); + return ret; + } + temp = I2C_DVI_INPUT_DATA_FORMAT_VAL; + ret = i2c_write(CONFIG_SYS_I2C_DVI_ADDR, I2C_DVI_INPUT_DATA_FORMAT_REG, + 1, &temp, 1); + if (ret) { + puts("I2C: failed to select dvi input data format\n"); + return ret; + } + + /* Set Sync polarity register */ + temp = I2C_DVI_SYNC_POLARITY_VAL; + ret = i2c_write(CONFIG_SYS_I2C_DVI_ADDR, I2C_DVI_SYNC_POLARITY_REG, 1, + &temp, 1); + if (ret) { + puts("I2C: failed to select dvi syc polarity\n"); + return ret; + } + + /* Set PLL registers based on pixel clock rate*/ + if (pixclock > 65000000) { + temp = I2C_DVI_PLL_CHARGE_CNTL_HIGH_SPEED_VAL; + ret = i2c_write(CONFIG_SYS_I2C_DVI_ADDR, + I2C_DVI_PLL_CHARGE_CNTL_REG, 1, &temp, 1); + if (ret) { + puts("I2C: failed to select dvi pll charge_cntl\n"); + return ret; + } + temp = I2C_DVI_PLL_DIVIDER_HIGH_SPEED_VAL; + ret = i2c_write(CONFIG_SYS_I2C_DVI_ADDR, + I2C_DVI_PLL_DIVIDER_REG, 1, &temp, 1); + if (ret) { + puts("I2C: failed to select dvi pll divider\n"); + return ret; + } + temp = I2C_DVI_PLL_FILTER_HIGH_SPEED_VAL; + ret = i2c_write(CONFIG_SYS_I2C_DVI_ADDR, + I2C_DVI_PLL_FILTER_REG, 1, &temp, 1); + if (ret) { + puts("I2C: failed to select dvi pll filter\n"); + return ret; + } + } else { + temp = I2C_DVI_PLL_CHARGE_CNTL_LOW_SPEED_VAL; + ret = i2c_write(CONFIG_SYS_I2C_DVI_ADDR, + I2C_DVI_PLL_CHARGE_CNTL_REG, 1, &temp, 1); + if (ret) { + puts("I2C: failed to select dvi pll charge_cntl\n"); + return ret; + } + temp = I2C_DVI_PLL_DIVIDER_LOW_SPEED_VAL; + ret = i2c_write(CONFIG_SYS_I2C_DVI_ADDR, + I2C_DVI_PLL_DIVIDER_REG, 1, &temp, 1); + if (ret) { + puts("I2C: failed to select dvi pll divider\n"); + return ret; + } + temp = I2C_DVI_PLL_FILTER_LOW_SPEED_VAL; + ret = i2c_write(CONFIG_SYS_I2C_DVI_ADDR, + I2C_DVI_PLL_FILTER_REG, 1, &temp, 1); + if (ret) { + puts("I2C: failed to select dvi pll filter\n"); + return ret; + } + } + + temp = I2C_DVI_POWER_MGMT_VAL; + ret = i2c_write(CONFIG_SYS_I2C_DVI_ADDR, I2C_DVI_POWER_MGMT_REG, 1, + &temp, 1); + if (ret) { + puts("I2C: failed to select dvi power mgmt\n"); + return ret; + } + + udelay(500); + + return 0; +} diff --git a/board/freescale/common/diu_ch7301.h b/board/freescale/common/diu_ch7301.h new file mode 100644 index 0000000..8b6ead0 --- /dev/null +++ b/board/freescale/common/diu_ch7301.h @@ -0,0 +1,13 @@ +/* + * Copyright 2014 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __DIU_HDMI_CH7301__ +#define __DIU_HDMI_CH7301__ + +/* Programming of HDMI Chrontel CH7301 connector */ +int diu_set_dvi_encoder(unsigned int pixclock); + +#endif diff --git a/board/freescale/t1040qds/diu.c b/board/freescale/t1040qds/diu.c index ffd074b..0214224 100644 --- a/board/freescale/t1040qds/diu.c +++ b/board/freescale/t1040qds/diu.c @@ -13,42 +13,9 @@ #include <video_fb.h> #include <fsl_diu_fb.h> #include "../common/qixis.h" +#include "../common/diu_ch7301.h" #include "t1040qds.h" #include "t1040qds_qixis.h" -#include <i2c.h> - - -#define I2C_DVI_INPUT_DATA_FORMAT_REG 0x1F -#define I2C_DVI_PLL_CHARGE_CNTL_REG 0x33 -#define I2C_DVI_PLL_DIVIDER_REG 0x34 -#define I2C_DVI_PLL_SUPPLY_CNTL_REG 0x35 -#define I2C_DVI_PLL_FILTER_REG 0x36 -#define I2C_DVI_TEST_PATTERN_REG 0x48 -#define I2C_DVI_POWER_MGMT_REG 0x49 -#define I2C_DVI_LOCK_STATE_REG 0x4D -#define I2C_DVI_SYNC_POLARITY_REG 0x56 - -/* - * Set VSYNC/HSYNC to active high. This is polarity of sync signals - * from DIU->DVI. The DIU default is active igh, so DVI is set to - * active high. - */ -#define I2C_DVI_INPUT_DATA_FORMAT_VAL 0x98 - -#define I2C_DVI_PLL_CHARGE_CNTL_HIGH_SPEED_VAL 0x06 -#define I2C_DVI_PLL_DIVIDER_HIGH_SPEED_VAL 0x26 -#define I2C_DVI_PLL_FILTER_HIGH_SPEED_VAL 0xA0 -#define I2C_DVI_PLL_CHARGE_CNTL_LOW_SPEED_VAL 0x08 -#define I2C_DVI_PLL_DIVIDER_LOW_SPEED_VAL 0x16 -#define I2C_DVI_PLL_FILTER_LOW_SPEED_VAL 0x60 - -/* Clear test pattern */ -#define I2C_DVI_TEST_PATTERN_VAL 0x18 -/* Exit Power-down mode */ -#define I2C_DVI_POWER_MGMT_VAL 0xC0 - -/* Monitor polarity is handled via DVI Sync Polarity Register */ -#define I2C_DVI_SYNC_POLARITY_VAL 0x00 /* * DIU Area Descriptor @@ -69,98 +36,6 @@ #define AD_COMP_1_SHIFT 4 #define AD_COMP_0_SHIFT 0 -/* Programming of HDMI Chrontel CH7301 connector */ -int diu_set_dvi_encoder(unsigned int pixclock) -{ - int ret; - u8 temp; - select_i2c_ch_pca9547(I2C_MUX_CH_DIU); - - temp = I2C_DVI_TEST_PATTERN_VAL; - ret = i2c_write(CONFIG_SYS_I2C_DVI_ADDR, I2C_DVI_TEST_PATTERN_REG, 1, - &temp, 1); - if (ret) { - puts("I2C: failed to select proper dvi test pattern\n"); - return ret; - } - temp = I2C_DVI_INPUT_DATA_FORMAT_VAL; - ret = i2c_write(CONFIG_SYS_I2C_DVI_ADDR, I2C_DVI_INPUT_DATA_FORMAT_REG, - 1, &temp, 1); - if (ret) { - puts("I2C: failed to select dvi input data format\n"); - return ret; - } - - /* Set Sync polarity register */ - temp = I2C_DVI_SYNC_POLARITY_VAL; - ret = i2c_write(CONFIG_SYS_I2C_DVI_ADDR, I2C_DVI_SYNC_POLARITY_REG, 1, - &temp, 1); - if (ret) { - puts("I2C: failed to select dvi syc polarity\n"); - return ret; - } - - /* Set PLL registers based on pixel clock rate*/ - if (pixclock > 65000000) { - temp = I2C_DVI_PLL_CHARGE_CNTL_HIGH_SPEED_VAL; - ret = i2c_write(CONFIG_SYS_I2C_DVI_ADDR, - I2C_DVI_PLL_CHARGE_CNTL_REG, 1, &temp, 1); - if (ret) { - puts("I2C: failed to select dvi pll charge_cntl\n"); - return ret; - } - temp = I2C_DVI_PLL_DIVIDER_HIGH_SPEED_VAL; - ret = i2c_write(CONFIG_SYS_I2C_DVI_ADDR, - I2C_DVI_PLL_DIVIDER_REG, 1, &temp, 1); - if (ret) { - puts("I2C: failed to select dvi pll divider\n"); - return ret; - } - temp = I2C_DVI_PLL_FILTER_HIGH_SPEED_VAL; - ret = i2c_write(CONFIG_SYS_I2C_DVI_ADDR, - I2C_DVI_PLL_FILTER_REG, 1, &temp, 1); - if (ret) { - puts("I2C: failed to select dvi pll filter\n"); - return ret; - } - } else { - temp = I2C_DVI_PLL_CHARGE_CNTL_LOW_SPEED_VAL; - ret = i2c_write(CONFIG_SYS_I2C_DVI_ADDR, - I2C_DVI_PLL_CHARGE_CNTL_REG, 1, &temp, 1); - if (ret) { - puts("I2C: failed to select dvi pll charge_cntl\n"); - return ret; - } - temp = I2C_DVI_PLL_DIVIDER_LOW_SPEED_VAL; - ret = i2c_write(CONFIG_SYS_I2C_DVI_ADDR, - I2C_DVI_PLL_DIVIDER_REG, 1, &temp, 1); - if (ret) { - puts("I2C: failed to select dvi pll divider\n"); - return ret; - } - temp = I2C_DVI_PLL_FILTER_LOW_SPEED_VAL; - ret = i2c_write(CONFIG_SYS_I2C_DVI_ADDR, - I2C_DVI_PLL_FILTER_REG, 1, &temp, 1); - if (ret) { - puts("I2C: failed to select dvi pll filter\n"); - return ret; - } - } - - temp = I2C_DVI_POWER_MGMT_VAL; - ret = i2c_write(CONFIG_SYS_I2C_DVI_ADDR, I2C_DVI_POWER_MGMT_REG, 1, - &temp, 1); - if (ret) { - puts("I2C: failed to select dvi power mgmt\n"); - return ret; - } - - udelay(500); - - select_i2c_ch_pca9547(I2C_MUX_CH_DEFAULT); - return 0; -} - void diu_set_pixel_clock(unsigned int pixclock) { unsigned long speed_ccb, temp; @@ -172,12 +47,19 @@ void diu_set_pixel_clock(unsigned int pixclock) pixval = speed_ccb / temp; /* Program HDMI encoder */ + /* Switch channel to DIU */ + select_i2c_ch_pca9547(I2C_MUX_CH_DIU); + + /* Set dispaly encoder */ ret = diu_set_dvi_encoder(temp); if (ret) { puts("Failed to set DVI encoder\n"); return; } + /* Switch channel to default */ + select_i2c_ch_pca9547(I2C_MUX_CH_DEFAULT); + /* Program pixel clock */ out_be32((unsigned *)CONFIG_SYS_FSL_SCFG_PIXCLK_ADDR, ((pixval << PXCK_BITS_START) & PXCK_MASK)); diff --git a/board/freescale/t104xrdb/Makefile b/board/freescale/t104xrdb/Makefile index 6cd304c..b9ef17f 100644 --- a/board/freescale/t104xrdb/Makefile +++ b/board/freescale/t104xrdb/Makefile @@ -11,6 +11,7 @@ obj-y += t104xrdb.o obj-y += cpld.o obj-y += eth.o obj-$(CONFIG_PCI) += pci.o +obj-$(CONFIG_FSL_DIU_FB)+= diu.o endif obj-y += ddr.o obj-y += law.o diff --git a/board/freescale/t104xrdb/diu.c b/board/freescale/t104xrdb/diu.c new file mode 100644 index 0000000..3285bef --- /dev/null +++ b/board/freescale/t104xrdb/diu.c @@ -0,0 +1,84 @@ +/* + * Copyright 2014 Freescale Semiconductor, Inc. + * Author: Priyanka Jain <Priyanka.Jain@freescale.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <asm/io.h> +#include <common.h> +#include <command.h> +#include <fsl_diu_fb.h> +#include <linux/ctype.h> +#include <video_fb.h> + +#include "../common/diu_ch7301.h" + +#include "cpld.h" +#include "t104xrdb.h" + +/* + * DIU Area Descriptor + * + * Note that we need to byte-swap the value before it's written to the AD + * register. So even though the registers don't look like they're in the same + * bit positions as they are on the MPC8610, the same value is written to the + * AD register on the MPC8610 and on the P1022. + */ +#define AD_BYTE_F 0x10000000 +#define AD_ALPHA_C_SHIFT 25 +#define AD_BLUE_C_SHIFT 23 +#define AD_GREEN_C_SHIFT 21 +#define AD_RED_C_SHIFT 19 +#define AD_PIXEL_S_SHIFT 16 +#define AD_COMP_3_SHIFT 12 +#define AD_COMP_2_SHIFT 8 +#define AD_COMP_1_SHIFT 4 +#define AD_COMP_0_SHIFT 0 + +void diu_set_pixel_clock(unsigned int pixclock) +{ + unsigned long speed_ccb, temp; + u32 pixval; + int ret; + + speed_ccb = get_bus_freq(0); + temp = 1000000000 / pixclock; + temp *= 1000; + pixval = speed_ccb / temp; + + /* Program HDMI encoder */ + ret = diu_set_dvi_encoder(temp); + if (ret) { + puts("Failed to set DVI encoder\n"); + return; + } + + /* Program pixel clock */ + out_be32((unsigned *)CONFIG_SYS_FSL_SCFG_PIXCLK_ADDR, + ((pixval << PXCK_BITS_START) & PXCK_MASK)); + + /* enable clock*/ + out_be32((unsigned *)CONFIG_SYS_FSL_SCFG_PIXCLK_ADDR, PXCKEN_MASK | + ((pixval << PXCK_BITS_START) & PXCK_MASK)); +} + +int platform_diu_init(unsigned int xres, unsigned int yres, const char *port) +{ + u32 pixel_format; + u8 sw; + + /*Configure Display ouput port as HDMI*/ + sw = CPLD_READ(sfp_ctl_status); + CPLD_WRITE(sfp_ctl_status , sw & ~(CPLD_DIU_SEL_DFP)); + + pixel_format = cpu_to_le32(AD_BYTE_F | (3 << AD_ALPHA_C_SHIFT) | + (0 << AD_BLUE_C_SHIFT) | (1 << AD_GREEN_C_SHIFT) | + (2 << AD_RED_C_SHIFT) | (8 << AD_COMP_3_SHIFT) | + (8 << AD_COMP_2_SHIFT) | (8 << AD_COMP_1_SHIFT) | + (8 << AD_COMP_0_SHIFT) | (3 << AD_PIXEL_S_SHIFT)); + + printf("DIU: Switching to monitor DVI @ %ux%u\n", xres, yres); + + return fsl_diu_init(xres, yres, pixel_format, 0); +} diff --git a/board/freescale/t104xrdb/spl.c b/board/freescale/t104xrdb/spl.c index c628c95..3822a37 100644 --- a/board/freescale/t104xrdb/spl.c +++ b/board/freescale/t104xrdb/spl.c @@ -11,6 +11,7 @@ #include <mmc.h> #include <fsl_esdhc.h> #include <spi_flash.h> +#include <asm/mpc85xx_gpio.h> DECLARE_GLOBAL_DATA_PTR; @@ -55,6 +56,11 @@ void board_init_f(ulong bootflag) /* Update GD pointer */ gd = (gd_t *)(CONFIG_SPL_GD_ADDR); +#ifdef CONFIG_DEEP_SLEEP + /* disable the console if boot from deep sleep */ + if (in_be32(&gur->scrtsr[0]) & (1 << 3)) + gd->flags |= GD_FLG_SILENT | GD_FLG_DISABLE_CONSOLE; +#endif /* compiler optimization barrier needed for GCC >= 3.4 */ __asm__ __volatile__("" : : : "memory"); @@ -120,3 +126,16 @@ void board_init_r(gd_t *gd, ulong dest_addr) nand_boot(); #endif } + +#ifdef CONFIG_DEEP_SLEEP +void board_mem_sleep_setup(void) +{ + void __iomem *cpld_base = (void *)CONFIG_SYS_CPLD_BASE; + + /* does not provide HW signals for power management */ + clrbits_8(cpld_base + 0x17, 0x40); + /* Disable MCKE isolation */ + gpio_set_value(2, 0); + udelay(1); +} +#endif diff --git a/board/freescale/t4qds/README b/board/freescale/t4qds/README new file mode 100644 index 0000000..3962fee --- /dev/null +++ b/board/freescale/t4qds/README @@ -0,0 +1,194 @@ +Overview +-------- +The T4240QDS is a high-performance computing evaluation, development and test +platform supporting the T4240 QorIQ™ Power Architecture™ processor. T4240QDS is +optimized to support the high-bandwidth DDR3 memory ports, as well as the +highly-configurable SerDes ports. The system is lead-free and RoHS-compliant. + +Board Features + SERDES Connections + 32 lanes grouped into four 8-lane banks + Two “front side” banks dedicated to Ethernet + - High-speed crosspoint switch fabric on selected lanes + - Two PCI Express slots with side-band connector supporting + - SGMII + - XAUI + - HiGig + - I-pass connectors allow board-to-board and loopback support + Two “back side” banks dedicated to other protocols + - High-speed crosspoint switch fabric on all lanes + - Four PCI Express slots with side-band connector supporting + - PCI Express 3.0 + - SATA 2.0 + - SRIO 2.0 + - Supports 4X Aurora debug with two connectors + DDR Controllers + Three independant 64-bit DDR3 controllers + Supports rates of 1866 up to 2133 MHz data-rate + Supports two DDR3/DDR3LP UDIMM/RDIMMs per controller + DDR power supplies 1.5V to all devices with automatic tracking of VTT. + Power software-switchable to 1.35V if software detects all DDR3LP devices. + MT9JSF25672AZ-2G1KZESZF has been tested at 1333, 1600, 1867, 2000 and + 2133MT/s speeds. For 1867MT/s and above, read-to-write turnaround time + increases by 1 clock. + + IFC/Local Bus + NAND flash: 8-bit, async or sync, up to 2GB. + NOR: 16-bit, Address/Data Multiplexed (ADM), up to 128 MB + NOR: 8-bit or 16-bit, non-multiplexed, up to 512MB + - NOR devices support 16 virtual banks + GASIC: Minimal target within Qixis FPGA + PromJET rapid memory download support + Address demultiplexing handled within FPGA. + - Flexible demux allows 8 or 16 bit evaluation. + IFC Debug/Development card + - Support for 32-bit devices + Ethernet + Support two on-board RGMII 10/100/1G ethernet ports. + SGMII and XAUI support via SERDES block (see above). + 1588 support via Symmetricom board. + QIXIS System Logic FPGA + Manages system power and reset sequencing + Manages DUT, board, clock, etc. configuration for dynamic shmoo + Collects V-I-T data in background for code/power profiling. + Supports legacy TMT test features (POSt, IRS, SYSCLK-synchronous assertion) + General fault monitoring and logging + Runs from ATX “hot” power rails allowing operation while system is off. + Clocks + System and DDR clock (SYSCLK, “DDRCLK”) + - Switch selectable to one of 16 common settings in the interval 33MHz-166MHz. + - Software selectable in 1MHz increments from 1-200MHz. + SERDES clocks + - Provides clocks to all SerDes blocks and slots + - 100, 125 and 156.25 MHz + Power Supplies + Dedicated regulators for VDD + - Adjustable from (0.7V to 1.3V at 80A + - Regulators can be controlled by VID and/or software + Dedicated regulator for GVDD_PL: 1.35/1.5V at 22A + - VTT/MVREF automatically track operating voltage + Dedicated regulators/filters for AVDD supplies + Dedicated regulators for other supplies: OVDD, BVDD, DVDD, LVDD, POVDD, etc. + USB + Supports two USB 2.0 ports with integrated PHYs + - One type A, one type micro-AB with 1.0A power per port. + Other IO + eSDHC/MMC + - SDHC card slot + eSPI port + - High-speed serial flash + Two Serial port + Four I2C ports + XFI + XFI is supported on T4QDS-XFI board which removed slot3 and routed + four Lanes A/B/C/D to a SFP+ cages, which to house fiber cable or + direct attach cable(copper), the copper cable is used to emulate + 10GBASE-KR scenario. + So, for XFI usage, there are two scenarios, one will use fiber cable, + another will use copper cable. An hwconfig env "fsl_10gkr_copper" is + introduced to indicate a XFI port will use copper cable, and U-boot + will fixup the dtb accordingly. + It's used as: fsl_10gkr_copper:<10g_mac_name> + The <10g_mac_name> can be fm1_10g1, fm1_10g2, fm2_10g1, fm2_10g2, they + do not have to be coexist in hwconfig. If a MAC is listed in the env + "fsl_10gkr_copper", it will use copper cable, otherwise, fiber cable + will be used by default. + for ex. set "fsl_10gkr_copper:fm1_10g1,fm1_10g2,fm2_10g1,fm2_10g2" in + hwconfig, then both four XFI ports will use copper cable. + set "fsl_10gkr_copper:fm1_10g1,fm1_10g2" in hwconfig, then first two + XFI ports will use copper cable, the other two XFI ports will use fiber + cable. + +Memory map +---------- +The addresses in brackets are physical addresses. + +0x0_0000_0000 (0x0_0000_0000) - 0x0_7fff_ffff 2GB DDR (more than 2GB is initialized but not mapped under with TLB) +0x0_8000_0000 (0xc_0000_0000) - 0x0_dfff_ffff 1.5GB PCIE memory +0x0_f000_0000 (0xf_0000_0000) - 0x0_f1ff_ffff 32MB DCSR (includes trace buffers) +0x0_f400_0000 (0xf_f400_0000) - 0x0_f5ff_ffff 32MB BMan +0x0_f600_0000 (0xf_f600_0000) - 0x0_f7ff_ffff 32MB QMan +0x0_f800_0000 (0xf_f800_0000) - 0x0_f803_ffff 256KB PCIE IO +0x0_e000_0000 (0xf_e000_0000) - 0x0_efff_ffff 256MB NOR flash +0x0_fe00_0000 (0xf_fe00_0000) - 0x0_feff_ffff 16MB CCSR +0x0_ffdf_0000 (0xf_ffdf_0000) - 0x0_ffdf_03ff 4KB QIXIS +0x0_ffff_f000 (0x0_7fff_fff0) - 0x0_ffff_ffff 4KB Boot page translation for secondary cores + +The physical address of the last (boot page translation) varies with the actual DDR size. + +Voltage ID and VDD override +-------------------- +T4240 has a VID feature. U-boot reads the VID efuses and adjust the voltage +accordingly. The voltage can also be override by command vdd_override. The +syntax is + +vdd_override <voltage in mV>, eg. 1050 is for 1.050v. + +Upon success, the actual voltage will be read back. The value is checked +for safety and any invalid value will not adjust the voltage. + +Another way to override VDD is to use environmental variable, in case of using +command is too late for some debugging. The syntax is + +setenv t4240qds_vdd_mv <voltage in mV> +saveenv +reset + +The override voltage takes effect when booting. + +Note: voltage adjustment needs to be done step by step. Changing voltage too +rapidly may cause current surge. The voltage stepping is done by software. +Users can set the final voltage directly. + +2-stage NAND/SD boot loader +------------------------------- +PBL initializes the internal SRAM and copy SPL(160K) in SRAM. +SPL further initialise DDR using SPD and environment variables +and copy u-boot(768 KB) from NAND/SD device to DDR. +Finally SPL transers control to u-boot for futher booting. + +SPL has following features: + - Executes within 256K + - No relocation required + +Run time view of SPL framework +------------------------------------------------- +|Area | Address | +------------------------------------------------- +|SecureBoot header | 0xFFFC0000 (32KB) | +------------------------------------------------- +|GD, BD | 0xFFFC8000 (4KB) | +------------------------------------------------- +|ENV | 0xFFFC9000 (8KB) | +------------------------------------------------- +|HEAP | 0xFFFCB000 (50KB) | +------------------------------------------------- +|STACK | 0xFFFD8000 (22KB) | +------------------------------------------------- +|U-boot SPL | 0xFFFD8000 (160KB) | +------------------------------------------------- + +NAND Flash memory Map on T4QDS +-------------------------------------------------------------- +Start End Definition Size +0x000000 0x0FFFFF u-boot img 1MB +0x140000 0x15FFFF u-boot env 128KB +0x160000 0x17FFFF FMAN Ucode 128KB + +Micro SD Card memory Map on T4QDS +---------------------------------------------------- +Block #blocks Definition Size +0x008 2048 u-boot img 1MB +0x800 0016 u-boot env 8KB +0x820 0128 FMAN ucode 64KB + +Switch Settings: (ON is 1, OFF is 0) +=============== +NAND boot SW setting: +SW1[1:8] = 10000010 +SW2[1.1] = 0 +SW6[1:4] = 1001 + +SD boot SW setting: +SW1[1:8] = 00100000 +SW2[1.1] = 0 diff --git a/board/freescale/t4qds/eth.c b/board/freescale/t4qds/eth.c index 6210e46..9b416b1 100644 --- a/board/freescale/t4qds/eth.c +++ b/board/freescale/t4qds/eth.c @@ -23,6 +23,7 @@ #include <phy.h> #include <asm/fsl_dtsec.h> #include <asm/fsl_serdes.h> +#include <hwconfig.h> #include "../common/qixis.h" #include "../common/fman.h" @@ -173,6 +174,10 @@ void board_ft_fman_fixup_port(void *blob, char * prop, phys_addr_t pa, enum fm_port port, int offset) { int interface = fm_info_get_enet_if(port); + ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); + u32 prtcl2 = in_be32(&gur->rcwsr[4]) & FSL_CORENET2_RCWSR4_SRDS2_PRTCL; + + prtcl2 >>= FSL_CORENET2_RCWSR4_SRDS2_PRTCL_SHIFT; if (interface == PHY_INTERFACE_MODE_SGMII || interface == PHY_INTERFACE_MODE_QSGMII) { @@ -262,6 +267,76 @@ void board_ft_fman_fixup_port(void *blob, char * prop, phys_addr_t pa, default: break; } + } else if (interface == PHY_INTERFACE_MODE_XGMII && + ((prtcl2 == 55) || (prtcl2 == 57))) { + /* + * if the 10G is XFI, check hwconfig to see what is the + * media type, there are two types, fiber or copper, + * fix the dtb accordingly. + */ + int media_type = 0; + struct fixed_link f_link; + char lane_mode[20] = {"10GBASE-KR"}; + char buf[32] = "serdes-2,"; + int off; + + switch (port) { + case FM1_10GEC1: + if (hwconfig_sub("fsl_10gkr_copper", "fm1_10g1")) { + media_type = 1; + fdt_set_phy_handle(blob, prop, pa, + "phy_xfi1"); + sprintf(buf, "%s%s%s", buf, "lane-a,", + (char *)lane_mode); + } + break; + case FM1_10GEC2: + if (hwconfig_sub("fsl_10gkr_copper", "fm1_10g2")) { + media_type = 1; + fdt_set_phy_handle(blob, prop, pa, + "phy_xfi2"); + sprintf(buf, "%s%s%s", buf, "lane-b,", + (char *)lane_mode); + } + break; + case FM2_10GEC1: + if (hwconfig_sub("fsl_10gkr_copper", "fm2_10g1")) { + media_type = 1; + fdt_set_phy_handle(blob, prop, pa, + "phy_xfi3"); + sprintf(buf, "%s%s%s", buf, "lane-d,", + (char *)lane_mode); + } + break; + case FM2_10GEC2: + if (hwconfig_sub("fsl_10gkr_copper", "fm2_10g2")) { + media_type = 1; + fdt_set_phy_handle(blob, prop, pa, + "phy_xfi4"); + sprintf(buf, "%s%s%s", buf, "lane-c,", + (char *)lane_mode); + } + break; + default: + return; + } + + if (!media_type) { + /* fixed-link is used for XFI fiber cable */ + fdt_delprop(blob, offset, "phy-handle"); + f_link.phy_id = port; + f_link.duplex = 1; + f_link.link_speed = 10000; + f_link.pause = 0; + f_link.asym_pause = 0; + fdt_setprop(blob, offset, "fixed-link", &f_link, + sizeof(f_link)); + } else { + /* set property for copper cable */ + off = fdt_node_offset_by_compat_reg(blob, + "fsl,fman-memac-mdio", pa + 0x1000); + fdt_setprop_string(blob, off, "lane-instance", buf); + } } } @@ -295,8 +370,23 @@ void fdt_fixup_board_enet(void *fdt) break; case PHY_INTERFACE_MODE_XGMII: /* check if it's XFI interface for 10g */ - if ((prtcl2 == 56) || (prtcl2 == 57)) { - fdt_status_okay_by_alias(fdt, "emi2_xfislot3"); + if ((prtcl2 == 55) || (prtcl2 == 57)) { + if (i == FM1_10GEC1 && hwconfig_sub( + "fsl_10gkr_copper", "fm1_10g1")) + fdt_status_okay_by_alias( + fdt, "xfi_pcs_mdio1"); + if (i == FM1_10GEC2 && hwconfig_sub( + "fsl_10gkr_copper", "fm1_10g2")) + fdt_status_okay_by_alias( + fdt, "xfi_pcs_mdio2"); + if (i == FM2_10GEC1 && hwconfig_sub( + "fsl_10gkr_copper", "fm2_10g1")) + fdt_status_okay_by_alias( + fdt, "xfi_pcs_mdio3"); + if (i == FM2_10GEC2 && hwconfig_sub( + "fsl_10gkr_copper", "fm2_10g2")) + fdt_status_okay_by_alias( + fdt, "xfi_pcs_mdio4"); break; } switch (i) { @@ -460,7 +550,7 @@ int board_eth_init(bd_t *bis) fm_info_set_phy_address(FM1_DTSEC4, slot_qsgmii_phyaddr[2][3]); fm_info_set_phy_address(FM1_DTSEC5, slot_qsgmii_phyaddr[1][0]); fm_info_set_phy_address(FM1_DTSEC6, slot_qsgmii_phyaddr[1][1]); - if ((srds_prtcl_s2 != 56) && (srds_prtcl_s2 != 57)) { + if ((srds_prtcl_s2 != 55) && (srds_prtcl_s2 != 57)) { fm_info_set_phy_address(FM1_DTSEC9, slot_qsgmii_phyaddr[1][3]); fm_info_set_phy_address(FM1_DTSEC10, @@ -475,7 +565,7 @@ int board_eth_init(bd_t *bis) fm_info_set_phy_address(FM1_DTSEC4, slot_qsgmii_phyaddr[2][3]); fm_info_set_phy_address(FM1_DTSEC5, slot_qsgmii_phyaddr[1][0]); fm_info_set_phy_address(FM1_DTSEC6, slot_qsgmii_phyaddr[1][1]); - if ((srds_prtcl_s2 != 56) && (srds_prtcl_s2 != 57)) { + if ((srds_prtcl_s2 != 55) && (srds_prtcl_s2 != 57)) { fm_info_set_phy_address(FM1_DTSEC9, slot_qsgmii_phyaddr[1][2]); fm_info_set_phy_address(FM1_DTSEC10, @@ -490,7 +580,7 @@ int board_eth_init(bd_t *bis) case 48: fm_info_set_phy_address(FM1_DTSEC5, slot_qsgmii_phyaddr[1][0]); fm_info_set_phy_address(FM1_DTSEC6, slot_qsgmii_phyaddr[1][1]); - if ((srds_prtcl_s2 != 56) && (srds_prtcl_s2 != 57)) { + if ((srds_prtcl_s2 != 55) && (srds_prtcl_s2 != 57)) { fm_info_set_phy_address(FM1_DTSEC10, slot_qsgmii_phyaddr[1][2]); fm_info_set_phy_address(FM1_DTSEC9, @@ -567,13 +657,18 @@ int board_eth_init(bd_t *bis) idx = i - FM1_10GEC1; switch (fm_info_get_enet_if(i)) { case PHY_INTERFACE_MODE_XGMII: - lane = serdes_get_first_lane(FSL_SRDS_1, + if ((srds_prtcl_s2 == 55) || (srds_prtcl_s2 == 57)) { + /* A fake PHY address to make U-boot happy */ + fm_info_set_phy_address(i, i); + } else { + lane = serdes_get_first_lane(FSL_SRDS_1, XAUI_FM1_MAC9 + idx); - if (lane < 0) - break; - slot = lane_to_slot_fsm1[lane]; - if (QIXIS_READ(present2) & (1 << (slot - 1))) - fm_disable_port(i); + if (lane < 0) + break; + slot = lane_to_slot_fsm1[lane]; + if (QIXIS_READ(present2) & (1 << (slot - 1))) + fm_disable_port(i); + } mdio_mux[i] = EMI2; fm_info_set_mdio(i, mii_dev_for_muxval(mdio_mux[i])); break; @@ -666,7 +761,7 @@ int board_eth_init(bd_t *bis) fm_info_set_phy_address(FM2_DTSEC3, slot_qsgmii_phyaddr[4][2]); fm_info_set_phy_address(FM2_DTSEC4, slot_qsgmii_phyaddr[4][3]); break; - case 56: + case 55: case 57: /* XFI in Slot3, SGMII in Slot4 */ fm_info_set_phy_address(FM2_DTSEC1, slot_qsgmii_phyaddr[4][0]); @@ -743,13 +838,18 @@ int board_eth_init(bd_t *bis) idx = i - FM2_10GEC1; switch (fm_info_get_enet_if(i)) { case PHY_INTERFACE_MODE_XGMII: - lane = serdes_get_first_lane(FSL_SRDS_2, + if ((srds_prtcl_s2 == 55) || (srds_prtcl_s2 == 57)) { + /* A fake PHY address to make U-boot happy */ + fm_info_set_phy_address(i, i); + } else { + lane = serdes_get_first_lane(FSL_SRDS_2, XAUI_FM2_MAC9 + idx); - if (lane < 0) - break; - slot = lane_to_slot_fsm2[lane]; - if (QIXIS_READ(present2) & (1 << (slot - 1))) - fm_disable_port(i); + if (lane < 0) + break; + slot = lane_to_slot_fsm2[lane]; + if (QIXIS_READ(present2) & (1 << (slot - 1))) + fm_disable_port(i); + } mdio_mux[i] = EMI2; fm_info_set_mdio(i, mii_dev_for_muxval(mdio_mux[i])); break; |