From 3484d953073cae069b8c41a63a9955e551117f01 Mon Sep 17 00:00:00 2001 From: Prabhakar Kushwaha Date: Thu, 28 May 2015 14:53:54 +0530 Subject: armv8/ls2085ardb: Add eth & phy firmware loading support Add support for board eth initialization and support for loading phy firmware. PHY firmware needs to be loaded from board_eth_init() because all the MACs are not initialized by ldpaa_eth driver. Signed-off-by: pankaj chauhan Signed-off-by: Prabhakar Kushwaha Reviewed-by: York Sun diff --git a/board/freescale/ls2085ardb/Makefile b/board/freescale/ls2085ardb/Makefile index 0bfe21c..de383cc 100644 --- a/board/freescale/ls2085ardb/Makefile +++ b/board/freescale/ls2085ardb/Makefile @@ -4,5 +4,5 @@ # SPDX-License-Identifier: GPL-2.0+ # -obj-y += ls2085ardb.o +obj-y += ls2085ardb.o eth_ls2085rdb.o obj-y += ddr.o diff --git a/board/freescale/ls2085ardb/eth_ls2085rdb.c b/board/freescale/ls2085ardb/eth_ls2085rdb.c new file mode 100644 index 0000000..60af079 --- /dev/null +++ b/board/freescale/ls2085ardb/eth_ls2085rdb.c @@ -0,0 +1,133 @@ +/* + * Copyright 2015 Freescale Semiconductor, Inc. + * + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int load_firmware_cortina(struct phy_device *phy_dev) +{ + if (phy_dev->drv->config) + return phy_dev->drv->config(phy_dev); + + return 0; +} + +void load_phy_firmware(void) +{ + int i; + u8 phy_addr; + struct phy_device *phy_dev; + struct mii_dev *dev; + phy_interface_t interface; + + /*Initialize and upload firmware for all the PHYs*/ + for (i = WRIOP1_DPMAC1; i <= WRIOP1_DPMAC8; i++) { + interface = wriop_get_enet_if(i); + if (interface == PHY_INTERFACE_MODE_XGMII) { + dev = wriop_get_mdio(i); + phy_addr = wriop_get_phy_address(i); + phy_dev = phy_find_by_mask(dev, 1 << phy_addr, + interface); + if (!phy_dev) { + printf("No phydev for phyaddr %d\n", phy_addr); + continue; + } + + /*Flash firmware for All CS4340 PHYS */ + if (phy_dev->phy_id == PHY_UID_CS4340) + load_firmware_cortina(phy_dev); + } + } +} + +int board_eth_init(bd_t *bis) +{ +#if defined(CONFIG_FSL_MC_ENET) + int i, interface; + struct memac_mdio_info mdio_info; + struct mii_dev *dev; + struct ccsr_gur *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR); + u32 srds_s1; + struct memac_mdio_controller *reg; + + srds_s1 = in_le32(&gur->rcwsr[28]) & + FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_MASK; + srds_s1 >>= FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_SHIFT; + + reg = (struct memac_mdio_controller *)CONFIG_SYS_FSL_WRIOP1_MDIO1; + mdio_info.regs = reg; + mdio_info.name = DEFAULT_WRIOP_MDIO1_NAME; + + /* Register the EMI 1 */ + fm_memac_mdio_init(bis, &mdio_info); + + reg = (struct memac_mdio_controller *)CONFIG_SYS_FSL_WRIOP1_MDIO2; + mdio_info.regs = reg; + mdio_info.name = DEFAULT_WRIOP_MDIO2_NAME; + + /* Register the EMI 2 */ + fm_memac_mdio_init(bis, &mdio_info); + + switch (srds_s1) { + case 0x2A: + wriop_set_phy_address(WRIOP1_DPMAC1, CORTINA_PHY_ADDR1); + wriop_set_phy_address(WRIOP1_DPMAC2, CORTINA_PHY_ADDR2); + wriop_set_phy_address(WRIOP1_DPMAC3, CORTINA_PHY_ADDR3); + wriop_set_phy_address(WRIOP1_DPMAC4, CORTINA_PHY_ADDR4); + wriop_set_phy_address(WRIOP1_DPMAC5, AQ_PHY_ADDR1); + wriop_set_phy_address(WRIOP1_DPMAC6, AQ_PHY_ADDR2); + wriop_set_phy_address(WRIOP1_DPMAC7, AQ_PHY_ADDR3); + wriop_set_phy_address(WRIOP1_DPMAC8, AQ_PHY_ADDR4); + + break; + default: + printf("SerDes1 protocol 0x%x is not supported on LS2085aRDB\n", + srds_s1); + break; + } + + for (i = WRIOP1_DPMAC1; i <= WRIOP1_DPMAC4; i++) { + interface = wriop_get_enet_if(i); + switch (interface) { + case PHY_INTERFACE_MODE_XGMII: + dev = miiphy_get_dev_by_name(DEFAULT_WRIOP_MDIO1_NAME); + wriop_set_mdio(i, dev); + break; + default: + break; + } + } + + for (i = WRIOP1_DPMAC5; i <= WRIOP1_DPMAC8; i++) { + switch (wriop_get_enet_if(i)) { + case PHY_INTERFACE_MODE_XGMII: + dev = miiphy_get_dev_by_name(DEFAULT_WRIOP_MDIO2_NAME); + wriop_set_mdio(i, dev); + break; + default: + break; + } + } + + /* Load CORTINA CS4340 PHY firmware */ + load_phy_firmware(); + + cpu_eth_init(bis); +#endif /* CONFIG_FMAN_ENET */ + + return pci_eth_init(bis); +} diff --git a/board/freescale/ls2085ardb/ls2085ardb.c b/board/freescale/ls2085ardb/ls2085ardb.c index d05f2bc..6cb7b13 100644 --- a/board/freescale/ls2085ardb/ls2085ardb.c +++ b/board/freescale/ls2085ardb/ls2085ardb.c @@ -176,19 +176,6 @@ unsigned long get_dram_size_to_hide(void) return dram_to_hide; } -int board_eth_init(bd_t *bis) -{ - int error = 0; - -#ifdef CONFIG_FSL_MC_ENET - error = cpu_eth_init(bis); -#endif - - error = pci_eth_init(bis); - - return error; -} - #ifdef CONFIG_FSL_MC_ENET void fdt_fixup_board_enet(void *fdt) { diff --git a/include/configs/ls2085ardb.h b/include/configs/ls2085ardb.h index 600261e..920560c 100644 --- a/include/configs/ls2085ardb.h +++ b/include/configs/ls2085ardb.h @@ -298,4 +298,27 @@ unsigned long get_board_sys_clk(void); "kernel_load=0xa0000000\0" \ "kernel_size=0x1000000\0" +/* MAC/PHY configuration */ +#ifdef CONFIG_FSL_MC_ENET +#define CONFIG_PHYLIB_10G +#define CONFIG_PHY_CORTINA +#define CONFIG_PHYLIB +#define CONFIG_SYS_CORTINA_FW_IN_NOR +#define CONFIG_CORTINA_FW_ADDR 0x581000000 +#define CONFIG_CORTINA_FW_LENGTH 0x40000 + +#define CORTINA_PHY_ADDR1 0x10 +#define CORTINA_PHY_ADDR2 0x11 +#define CORTINA_PHY_ADDR3 0x12 +#define CORTINA_PHY_ADDR4 0x13 +#define AQ_PHY_ADDR1 0x00 +#define AQ_PHY_ADDR2 0x01 +#define AQ_PHY_ADDR3 0x02 +#define AQ_PHY_ADDR4 0x03 + +#define CONFIG_MII +#define CONFIG_ETHPRIME "DPNI1" +#define CONFIG_PHY_GIGE +#endif + #endif /* __LS2_RDB_H */ -- cgit v0.10.2 From 5a4d744c905258433cc15792989a7abba9b1efe0 Mon Sep 17 00:00:00 2001 From: Yangbo Lu Date: Thu, 28 May 2015 14:53:55 +0530 Subject: armv8/ls2085ardb: add hwconfig setting for eSDHC Add hwconfig setting for eSDHC since it shares some pins with other IP block. Signed-off-by: Yangbo Lu Signed-off-by: Prabhakar Kushwaha Reviewed-by: York Sun diff --git a/board/freescale/ls2085ardb/ls2085ardb.c b/board/freescale/ls2085ardb/ls2085ardb.c index 6cb7b13..e0a8a41 100644 --- a/board/freescale/ls2085ardb/ls2085ardb.c +++ b/board/freescale/ls2085ardb/ls2085ardb.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -21,8 +22,15 @@ #include "../common/qixis.h" #include "ls2085ardb_qixis.h" +#define PIN_MUX_SEL_SDHC 0x00 + +#define SET_SDHC_MUX_SEL(reg, value) ((reg & 0xf0) | value) DECLARE_GLOBAL_DATA_PTR; +enum { + MUX_TYPE_SDHC, +}; + unsigned long long get_qixis_addr(void) { unsigned long long addr; @@ -129,6 +137,34 @@ int board_early_init_f(void) 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; + default: + printf("Wrong mux interface type\n"); + return -1; + } + + QIXIS_WRITE(brdcfg[5], reg5); + + return 0; +} + +int misc_init_r(void) +{ + if (hwconfig("sdhc")) + config_board_mux(MUX_TYPE_SDHC); + + return 0; +} + void detail_board_ddr_info(void) { puts("\nDDR "); diff --git a/include/configs/ls2085ardb.h b/include/configs/ls2085ardb.h index 920560c..ecc445e 100644 --- a/include/configs/ls2085ardb.h +++ b/include/configs/ls2085ardb.h @@ -284,6 +284,8 @@ unsigned long get_board_sys_clk(void); #define CONFIG_DOS_PARTITION #endif +#define CONFIG_MISC_INIT_R + /* Initial environment variables */ #undef CONFIG_EXTRA_ENV_SETTINGS #define CONFIG_EXTRA_ENV_SETTINGS \ -- cgit v0.10.2 From 6581440c1d5c49a7a80a40a827a83d98888ada11 Mon Sep 17 00:00:00 2001 From: Priyanka Jain Date: Thu, 28 May 2015 14:53:56 +0530 Subject: armv8/ls2085a: Enable "date" command for QDS and RDB Enable "date" command for QDS and RDB boards Signed-off-by: Priyanka Jain Signed-off-by: Prabhakar Kushwaha Reviewed-by: York Sun diff --git a/include/configs/ls2085aqds.h b/include/configs/ls2085aqds.h index e488ac8..7f0534d 100644 --- a/include/configs/ls2085aqds.h +++ b/include/configs/ls2085aqds.h @@ -287,6 +287,7 @@ unsigned long get_board_ddr_clk(void); #define RTC #define CONFIG_RTC_DS3231 1 #define CONFIG_SYS_I2C_RTC_ADDR 0x68 +#define CONFIG_CMD_DATE /* EEPROM */ #define CONFIG_ID_EEPROM diff --git a/include/configs/ls2085ardb.h b/include/configs/ls2085ardb.h index ecc445e..ed0ed7a 100644 --- a/include/configs/ls2085ardb.h +++ b/include/configs/ls2085ardb.h @@ -251,6 +251,7 @@ unsigned long get_board_sys_clk(void); #define RTC #define CONFIG_RTC_DS3231 1 #define CONFIG_SYS_I2C_RTC_ADDR 0x68 +#define CONFIG_CMD_DATE /* EEPROM */ #define CONFIG_ID_EEPROM -- cgit v0.10.2 From 94540c56044893343b9d84dff88ecab3e6e3182b Mon Sep 17 00:00:00 2001 From: Prabhakar Kushwaha Date: Thu, 28 May 2015 14:53:57 +0530 Subject: armv8/ls2085aqds: Add support of SerDes protocol 0x49 SerDes Protocol 0x49 enables 4 SGMII, PEX4, SATA1 and SATA2. Add support of 0x49 SerDes protocol to enable 4SGMII on slot4 of ls2085aqds platform. Signed-off-by: Prabhakar Kushwaha Reviewed-by: York Sun diff --git a/board/freescale/ls2085aqds/eth.c b/board/freescale/ls2085aqds/eth.c index 5ba4770..f32ace2 100644 --- a/board/freescale/ls2085aqds/eth.c +++ b/board/freescale/ls2085aqds/eth.c @@ -210,6 +210,7 @@ static void initialize_dpmac_to_slot(void) switch (serdes2_prtcl) { case 0x07: case 0x08: + case 0x49: printf("qds: WRIOP: Supported SerDes Protocol 0x%02x\n", serdes2_prtcl); lane_to_slot_fsm2[0] = EMI1_SLOT4; @@ -247,6 +248,7 @@ void ls2085a_handle_phy_interface_sgmii(int dpmac_id) 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]; -- cgit v0.10.2 From 252b17e0ec1e807e9acd71c43d2cdd7f8d91bf97 Mon Sep 17 00:00:00 2001 From: Prabhakar Kushwaha Date: Thu, 28 May 2015 14:53:58 +0530 Subject: armv8/ls2085a: Update LS2085a PCIe compatible Compatible field "fsl,20851a-pcie" is not correct. So update it to "fsl,ls2085a-pcie" Signed-off-by: Minghuan Lian Signed-off-by: Prabhakar Kushwaha Reviewed-by: York Sun diff --git a/include/configs/ls2085a_common.h b/include/configs/ls2085a_common.h index 72ba3b3..a74a547 100644 --- a/include/configs/ls2085a_common.h +++ b/include/configs/ls2085a_common.h @@ -186,7 +186,8 @@ unsigned long long get_qixis_addr(void); #define CONFIG_PCIE2 /* PCIE controler 2 */ #define CONFIG_PCIE3 /* PCIE controler 3 */ #define CONFIG_PCIE4 /* PCIE controler 4 */ -#define FSL_PCIE_COMPAT "fsl,20851a-pcie" +#define CONFIG_PCIE_LAYERSCAPE /* Use common FSL Layerscape PCIe code */ +#define FSL_PCIE_COMPAT "fsl,ls2085a-pcie" #define CONFIG_SYS_PCI_64BIT -- cgit v0.10.2 From 5be3b44cd4ce88adf5f43f38b24c6019945756ec Mon Sep 17 00:00:00 2001 From: Prabhakar Kushwaha Date: Thu, 28 May 2015 14:53:59 +0530 Subject: armv8/ls2085a: call ft_pcie_setup() to change dts status call ft_pci_setup() to disable PCIe dts node if corresponding PCIe controller is disabled according to RCW Signed-off-by: Minghuan Lian Signed-off-by: Prabhakar Kushwaha Reviewed-by: York Sun diff --git a/arch/arm/cpu/armv8/fsl-lsch3/fdt.c b/arch/arm/cpu/armv8/fsl-lsch3/fdt.c index d370023..b9fd559 100644 --- a/arch/arm/cpu/armv8/fsl-lsch3/fdt.c +++ b/arch/arm/cpu/armv8/fsl-lsch3/fdt.c @@ -69,6 +69,10 @@ void ft_cpu_setup(void *blob, bd_t *bd) "clock-frequency", CONFIG_SYS_NS16550_CLK, 1); #endif +#ifdef CONFIG_PCI + ft_pci_setup(blob, bd); +#endif + #if defined(CONFIG_FSL_ESDHC) fdt_fixup_esdhc(blob, bd); #endif -- cgit v0.10.2 From d7b76e89ed68345e6ff7dd85d1b29bd9df411b0c Mon Sep 17 00:00:00 2001 From: Prabhakar Kushwaha Date: Thu, 28 May 2015 14:54:00 +0530 Subject: armv8/ls2085qds: Update SFP TX bit as "0" to enable XFI FPGA BRDCFG9[SFP_TX] should be clear in order to enable XFI ports. Signed-off-by: Dai Haruki Signed-off-by: Prabhakar Kushwaha Reviewed-by: York Sun diff --git a/board/freescale/ls2085aqds/eth.c b/board/freescale/ls2085aqds/eth.c index f32ace2..1f8a31f 100644 --- a/board/freescale/ls2085aqds/eth.c +++ b/board/freescale/ls2085aqds/eth.c @@ -53,7 +53,7 @@ static int riser_phy_addr[] = { #define EMI1_SLOT5 4 #define EMI1_SLOT6 5 #define EMI2 6 -#define SFP_TX 1 +#define SFP_TX 0 static const char * const mdio_names[] = { "LS2085A_QDS_MDIO0", -- cgit v0.10.2 From 4012350deae86af50c9e1f3bf769b78a99b2072b Mon Sep 17 00:00:00 2001 From: Prabhakar Kushwaha Date: Thu, 28 May 2015 14:54:01 +0530 Subject: armv8/ls2085rdb: Update PCA9547PW slave address Primary Mux on I2C1 controller has slave address as 0x75. So update its address. Signed-off-by: Prabhakar Kushwaha Reviewed-by: York Sun diff --git a/include/configs/ls2085ardb.h b/include/configs/ls2085ardb.h index ed0ed7a..3408b13 100644 --- a/include/configs/ls2085ardb.h +++ b/include/configs/ls2085ardb.h @@ -239,8 +239,8 @@ unsigned long get_board_sys_clk(void); /* * I2C */ -#define I2C_MUX_PCA_ADDR 0x77 -#define I2C_MUX_PCA_ADDR_PRI 0x77 /* Primary Mux*/ +#define I2C_MUX_PCA_ADDR 0x75 +#define I2C_MUX_PCA_ADDR_PRI 0x75 /* Primary Mux*/ /* I2C bus multiplexer */ #define I2C_MUX_CH_DEFAULT 0x8 -- cgit v0.10.2 From 34cc75469fad1749525458a41c8f52ed1e13e147 Mon Sep 17 00:00:00 2001 From: Bhupesh Sharma Date: Thu, 28 May 2015 14:54:02 +0530 Subject: armv8/ls2085a: Increase the supported kernel size Increases the kernel size supported for LS2085A platforms:- - Update environment variables - Add ramdisk_size in bootargs env variable - Define CONFIG_SYS_BOOTM_LEN to 64MB Signed-off-by: Bhupesh Sharma Signed-off-by: Prabhakar Kushwaha Reviewed-by: York Sun diff --git a/include/configs/ls2085a_common.h b/include/configs/ls2085a_common.h index a74a547..1969696 100644 --- a/include/configs/ls2085a_common.h +++ b/include/configs/ls2085a_common.h @@ -237,13 +237,13 @@ unsigned long long get_qixis_addr(void); "initrd_high=0xffffffffffffffff\0" \ "kernel_start=0x581200000\0" \ "kernel_load=0xa0000000\0" \ - "kernel_size=0x1000000\0" \ + "kernel_size=0x2000000\0" \ "console=ttyAMA0,38400n8\0" #define CONFIG_BOOTARGS "console=ttyS1,115200 root=/dev/ram0 " \ "earlycon=uart8250,mmio,0x21c0600,115200 " \ - "default_hugepagesz=2m hugepagesz=2m " \ - "hugepages=16" + "ramdisk_size=0x2000000 default_hugepagesz=2m" \ + " hugepagesz=2m hugepages=16" #define CONFIG_BOOTCOMMAND "cp.b $kernel_start $kernel_load " \ "$kernel_size && bootm $kernel_load" #define CONFIG_BOOTDELAY 10 @@ -290,4 +290,7 @@ unsigned long get_dram_size_to_hide(void); #define CONFIG_SYS_SPL_MALLOC_START 0x80200000 #define CONFIG_SYS_MONITOR_LEN (512 * 1024) +#define CONFIG_SYS_BOOTM_LEN (64 << 20) /* Increase max gunzip size */ + + #endif /* __LS2_COMMON_H */ diff --git a/include/configs/ls2085aqds.h b/include/configs/ls2085aqds.h index 7f0534d..c9f3236 100644 --- a/include/configs/ls2085aqds.h +++ b/include/configs/ls2085aqds.h @@ -333,7 +333,7 @@ unsigned long get_board_ddr_clk(void); "initrd_high=0xffffffffffffffff\0" \ "kernel_start=0x581100000\0" \ "kernel_load=0xa0000000\0" \ - "kernel_size=0x1000000\0" + "kernel_size=0x2000000\0" #ifdef CONFIG_FSL_MC_ENET #define CONFIG_FSL_MEMAC diff --git a/include/configs/ls2085ardb.h b/include/configs/ls2085ardb.h index 3408b13..dd5505b 100644 --- a/include/configs/ls2085ardb.h +++ b/include/configs/ls2085ardb.h @@ -299,7 +299,7 @@ unsigned long get_board_sys_clk(void); "initrd_high=0xffffffffffffffff\0" \ "kernel_start=0x581100000\0" \ "kernel_load=0xa0000000\0" \ - "kernel_size=0x1000000\0" + "kernel_size=0x2000000\0" /* MAC/PHY configuration */ #ifdef CONFIG_FSL_MC_ENET -- cgit v0.10.2 From b8baf460ee978f9f704a658b31f9b074f546d6e1 Mon Sep 17 00:00:00 2001 From: Jaiprakash Singh Date: Thu, 28 May 2015 14:54:03 +0530 Subject: board/fsl/common: Fix eeprom system version endianness SYSTEM ID EPPROM always store SYSTEM version info in big endian format. SoC with ARM or PowerPC core should read/write version info from eeprom in BIG endian format. So use cpu-specific APIs to read SYSTEM version. Signed-off-by: Jaiprakash Singh Signed-off-by: Prabhakar Kushwaha Reviewed-by: York Sun diff --git a/board/freescale/common/sys_eeprom.c b/board/freescale/common/sys_eeprom.c index 5cb7570..29aa778 100644 --- a/board/freescale/common/sys_eeprom.c +++ b/board/freescale/common/sys_eeprom.c @@ -90,7 +90,7 @@ static void show_eeprom(void) /* EEPROM tag ID, either CCID or NXID */ #ifdef CONFIG_SYS_I2C_EEPROM_NXID printf("ID: %c%c%c%c v%u\n", e.id[0], e.id[1], e.id[2], e.id[3], - e.version); + be32_to_cpu(e.version)); #else printf("ID: %c%c%c%c\n", e.id[0], e.id[1], e.id[2], e.id[3]); #endif @@ -340,7 +340,7 @@ int do_mac(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) if (cmd == 'i') { #ifdef CONFIG_SYS_I2C_EEPROM_NXID memcpy(e.id, "NXID", sizeof(e.id)); - e.version = NXID_VERSION; + e.version = cpu_to_be32(NXID_VERSION); #else memcpy(e.id, "CCID", sizeof(e.id)); #endif @@ -485,7 +485,7 @@ int mac_read_from_eeprom(void) #ifdef CONFIG_SYS_I2C_EEPROM_NXID printf("%c%c%c%c v%u\n", e.id[0], e.id[1], e.id[2], e.id[3], - e.version); + be32_to_cpu(e.version)); #else printf("%c%c%c%c\n", e.id[0], e.id[1], e.id[2], e.id[3]); #endif @@ -496,7 +496,7 @@ int mac_read_from_eeprom(void) * that at boot time, U-Boot will still say "NXID v0". */ if (e.version == 0) { - e.version = NXID_VERSION; + e.version = cpu_to_be32(NXID_VERSION); update_crc(); } #endif -- cgit v0.10.2 From 27df54b16390416190cb799de389955d9e0d7b12 Mon Sep 17 00:00:00 2001 From: Prabhakar Kushwaha Date: Thu, 28 May 2015 14:54:04 +0530 Subject: armv8/ls2085RDB: Update board version print logic As per updated board document, no need to substract 1 from arch[BRD] bit field. Default value + 'A' represents the board revision. So update board version print logic to reflect the same. Signed-off-by: Prabhakar Kushwaha Reviewed-by: York Sun diff --git a/board/freescale/ls2085ardb/ls2085ardb.c b/board/freescale/ls2085ardb/ls2085ardb.c index e0a8a41..ff4b6a0 100644 --- a/board/freescale/ls2085ardb/ls2085ardb.c +++ b/board/freescale/ls2085ardb/ls2085ardb.c @@ -56,7 +56,7 @@ int checkboard(void) sw = QIXIS_READ(arch); printf("Board: %s, ", CONFIG_IDENT_STRING); printf("Board Arch: V%d, ", sw >> 4); - printf("Board version: %c, boot from ", (sw & 0xf) + 'A' - 1); + printf("Board version: %c, boot from ", (sw & 0xf) + 'A'); sw = QIXIS_READ(brdcfg[0]); sw = (sw & QIXIS_LBMAP_MASK) >> QIXIS_LBMAP_SHIFT; -- cgit v0.10.2 From d4c711f0ad20f30ee299f3d100366e9029d17c24 Mon Sep 17 00:00:00 2001 From: York Sun Date: Thu, 28 May 2015 14:54:05 +0530 Subject: armv8/fsl-lsch3: Fix DDR speed message DDR speed should be in MT/s, not MHz. Signed-off-by: York Sun Signed-off-by: Prabhakar Kushwaha diff --git a/arch/arm/cpu/armv8/fsl-lsch3/cpu.c b/arch/arm/cpu/armv8/fsl-lsch3/cpu.c index 6714577..19c3995 100644 --- a/arch/arm/cpu/armv8/fsl-lsch3/cpu.c +++ b/arch/arm/cpu/armv8/fsl-lsch3/cpu.c @@ -394,8 +394,8 @@ int print_cpuinfo(void) } printf("\n Bus: %-4s MHz ", strmhz(buf, sysinfo.freq_systembus)); - printf("DDR: %-4s MHz", strmhz(buf, sysinfo.freq_ddrbus)); - printf(" DP-DDR: %-4s MHz", strmhz(buf, sysinfo.freq_ddrbus2)); + printf("DDR: %-4s MT/s", strmhz(buf, sysinfo.freq_ddrbus)); + printf(" DP-DDR: %-4s MT/s", strmhz(buf, sysinfo.freq_ddrbus2)); puts("\n"); /* Display the RCW, so that no one gets confused as to what RCW -- cgit v0.10.2 From 226296656c6efe4eb2b26dbbebc417455bdfd99d Mon Sep 17 00:00:00 2001 From: Prabhakar Kushwaha Date: Thu, 28 May 2015 14:54:06 +0530 Subject: armv8/fsl-ch3: Add support to print SoC personality This patch adds support to print out the SoC personality. Freescale LS20xx SoCs (compliant to Chassis-3 specifications) can have 6 personalities: LS2045AE, LS2045A, LS2080AE, LS2080A, LS2085AE and LS2085A Signed-off-by: Bhupesh Sharma Signed-off-by: Prabhakar Kushwaha Reviewed-by: York Sun diff --git a/arch/arm/cpu/armv8/fsl-lsch3/cpu.c b/arch/arm/cpu/armv8/fsl-lsch3/cpu.c index 19c3995..52bc731 100644 --- a/arch/arm/cpu/armv8/fsl-lsch3/cpu.c +++ b/arch/arm/cpu/armv8/fsl-lsch3/cpu.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -22,6 +23,35 @@ DECLARE_GLOBAL_DATA_PTR; +static struct cpu_type cpu_type_list[] = { +#ifdef CONFIG_LS2085A + CPU_TYPE_ENTRY(LS2085, LS2085, 8), + CPU_TYPE_ENTRY(LS2080, LS2080, 8), + CPU_TYPE_ENTRY(LS2045, LS2045, 4), +#endif +}; + +void cpu_name(char *name) +{ + struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR); + unsigned int i, svr, ver; + + svr = in_le32(&gur->svr); + ver = SVR_SOC_VER(svr); + + for (i = 0; i < ARRAY_SIZE(cpu_type_list); i++) + if ((cpu_type_list[i].soc_ver & SVR_WO_E) == ver) { + strcpy(name, cpu_type_list[i].name); + + if (IS_E_PROCESSOR(svr)) + strcat(name, "E"); + break; + } + + if (i == ARRAY_SIZE(cpu_type_list)) + strcpy(name, "unknown"); +} + #ifndef CONFIG_SYS_DCACHE_OFF /* * To start MMU before DDR is available, we create MMU table in SRAM. @@ -380,6 +410,13 @@ int print_cpuinfo(void) unsigned int i, core; u32 type; + puts("SoC: "); + + cpu_name(buf); + printf(" %s (0x%x)\n", buf, in_le32(&gur->svr)); + + memset((u8 *)buf, 0x00, ARRAY_SIZE(buf)); + get_sys_info(&sysinfo); puts("Clock Configuration:"); for_each_cpu(i, core, cpu_numcores(), cpu_mask()) { diff --git a/arch/arm/include/asm/arch-fsl-lsch3/soc.h b/arch/arm/include/asm/arch-fsl-lsch3/soc.h index 16b723d..9a29272 100644 --- a/arch/arm/include/asm/arch-fsl-lsch3/soc.h +++ b/arch/arm/include/asm/arch-fsl-lsch3/soc.h @@ -4,5 +4,25 @@ * SPDX-License-Identifier: GPL-2.0+ */ +struct cpu_type { + char name[15]; + u32 soc_ver; + u32 num_cores; +}; + +#define CPU_TYPE_ENTRY(n, v, nc) \ + { .name = #n, .soc_ver = SVR_##v, .num_cores = (nc)} + +#define SVR_WO_E 0xFFFFFE +#define SVR_LS2045 0x870120 +#define SVR_LS2080 0x870110 +#define SVR_LS2085 0x870100 + +#define SVR_MAJ(svr) (((svr) >> 4) & 0xf) +#define SVR_MIN(svr) (((svr) >> 0) & 0xf) +#define SVR_SOC_VER(svr) (((svr) >> 8) & SVR_WO_E) +#define IS_E_PROCESSOR(svr) (!((svr >> 8) & 0x1)) + void fsl_lsch3_early_init_f(void); +void cpu_name(char *name); -- cgit v0.10.2 From ff1b8e3f556ca8e339e9b85c31575592e3100e02 Mon Sep 17 00:00:00 2001 From: Prabhakar Kushwaha Date: Thu, 28 May 2015 14:54:07 +0530 Subject: armv8/ls2085a: Avoid hard-coding for board name print LS2085A supports 6 personalities i.e. LS2045AE, LS2045A, LS2080AE, LS2080A, LS2085AE and LS2085A personlities. Instead of hard-coding, board name should change as per selected personality. Signed-off-by: Prabhakar Kushwaha Reviewed-by: York Sun diff --git a/board/freescale/ls2085aqds/ls2085aqds.c b/board/freescale/ls2085aqds/ls2085aqds.c index 6a22122..27a23ec 100644 --- a/board/freescale/ls2085aqds/ls2085aqds.c +++ b/board/freescale/ls2085aqds/ls2085aqds.c @@ -49,11 +49,15 @@ int checkboard(void) "100 separate SSCG"}; int clock; + cpu_name(buf); + printf("Board: %s-QDS, ", buf); + sw = QIXIS_READ(arch); - printf("Board: %s, ", CONFIG_IDENT_STRING); 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; diff --git a/board/freescale/ls2085ardb/ls2085ardb.c b/board/freescale/ls2085ardb/ls2085ardb.c index ff4b6a0..5f25328 100644 --- a/board/freescale/ls2085ardb/ls2085ardb.c +++ b/board/freescale/ls2085ardb/ls2085ardb.c @@ -52,9 +52,12 @@ unsigned long long get_qixis_addr(void) int checkboard(void) { u8 sw; + char buf[15]; + + cpu_name(buf); + printf("Board: %s-RDB, ", buf); sw = QIXIS_READ(arch); - printf("Board: %s, ", CONFIG_IDENT_STRING); printf("Board Arch: V%d, ", sw >> 4); printf("Board version: %c, boot from ", (sw & 0xf) + 'A'); diff --git a/include/configs/ls2085aqds.h b/include/configs/ls2085aqds.h index c9f3236..da73067 100644 --- a/include/configs/ls2085aqds.h +++ b/include/configs/ls2085aqds.h @@ -9,9 +9,6 @@ #include "ls2085a_common.h" -#define CONFIG_IDENT_STRING " LS2085A-QDS" -#define CONFIG_BOOTP_VCI_STRING "U-boot.LS2085A-QDS" - #define CONFIG_DISPLAY_BOARDINFO #ifndef __ASSEMBLY__ diff --git a/include/configs/ls2085ardb.h b/include/configs/ls2085ardb.h index dd5505b..ccb85d0 100644 --- a/include/configs/ls2085ardb.h +++ b/include/configs/ls2085ardb.h @@ -8,8 +8,6 @@ #define __LS2_RDB_H #include "ls2085a_common.h" -#define CONFIG_IDENT_STRING " LS2085A-RDB" -#define CONFIG_BOOTP_VCI_STRING "U-boot.LS2085A-RDB" #undef CONFIG_CONS_INDEX #define CONFIG_CONS_INDEX 2 -- cgit v0.10.2 From b92557cd3f37538fbd813e72f447109cbde4ff87 Mon Sep 17 00:00:00 2001 From: York Sun Date: Thu, 28 May 2015 14:54:08 +0530 Subject: driver/ddr/fsl: Add a hook to update SPD address In case SPD address changes between board revisions, updating SPD address can be called from board file. Signed-off-by: York Sun Signed-off-by: Prabhakar Kushwaha diff --git a/drivers/ddr/fsl/main.c b/drivers/ddr/fsl/main.c index fa22383..14ecf12 100644 --- a/drivers/ddr/fsl/main.c +++ b/drivers/ddr/fsl/main.c @@ -135,6 +135,13 @@ static void __get_spd(generic_spd_eeprom_t *spd, u8 i2c_address) __attribute__((weak, alias("__get_spd"))) void get_spd(generic_spd_eeprom_t *spd, u8 i2c_address); +/* This function allows boards to update SPD address */ +__weak void update_spd_address(unsigned int ctrl_num, + unsigned int slot, + unsigned int *addr) +{ +} + void fsl_ddr_get_spd(generic_spd_eeprom_t *ctrl_dimms_spd, unsigned int ctrl_num, unsigned int dimm_slots_per_ctrl) { @@ -148,6 +155,7 @@ void fsl_ddr_get_spd(generic_spd_eeprom_t *ctrl_dimms_spd, for (i = 0; i < dimm_slots_per_ctrl; i++) { i2c_address = spd_i2c_addr[ctrl_num][i]; + update_spd_address(ctrl_num, i, &i2c_address); get_spd(&(ctrl_dimms_spd[i]), i2c_address); } } diff --git a/include/fsl_ddr.h b/include/fsl_ddr.h index 4099a74..728503b 100644 --- a/include/fsl_ddr.h +++ b/include/fsl_ddr.h @@ -136,4 +136,7 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs, int fsl_ddr_get_dimm_params(dimm_params_t *pdimm, unsigned int controller_number, unsigned int dimm_number); +void update_spd_address(unsigned int ctrl_num, + unsigned int slot, + unsigned int *addr); #endif -- cgit v0.10.2 From fc7b3855e1c285e59487699d898f4415a8f62c05 Mon Sep 17 00:00:00 2001 From: York Sun Date: Thu, 28 May 2015 14:54:09 +0530 Subject: armv8/ls2085ardb: Fix SPD address error on early boards Board rev C and earlier has duplicated SPD address on 2nd DDR controller slots. It is fixed on rev D and later. SPD addresses need to be updated accordingly. Signed-off-by: York Sun Signed-off-by: Prabhakar Kushwaha diff --git a/board/freescale/ls2085ardb/ls2085ardb.c b/board/freescale/ls2085ardb/ls2085ardb.c index 5f25328..abe2114 100644 --- a/board/freescale/ls2085ardb/ls2085ardb.c +++ b/board/freescale/ls2085ardb/ls2085ardb.c @@ -273,3 +273,22 @@ void qixis_dump_switch(void) printf("SW%d = (0x%02x)\n", i, QIXIS_READ(cms[1])); } } + +/* + * Board rev C and earlier has duplicated I2C addresses for 2nd controller. + * Both slots has 0x54, resulting 2nd slot unusable. + */ +void update_spd_address(unsigned int ctrl_num, + unsigned int slot, + unsigned int *addr) +{ + u8 sw; + + sw = QIXIS_READ(arch); + if ((sw & 0xf) < 0x3) { + if (ctrl_num == 1 && slot == 0) + *addr = SPD_EEPROM_ADDRESS4; + else if (ctrl_num == 1 && slot == 1) + *addr = SPD_EEPROM_ADDRESS3; + } +} diff --git a/include/configs/ls2085ardb.h b/include/configs/ls2085ardb.h index ccb85d0..ec10393 100644 --- a/include/configs/ls2085ardb.h +++ b/include/configs/ls2085ardb.h @@ -28,8 +28,8 @@ unsigned long get_board_sys_clk(void); #define CONFIG_MEM_INIT_VALUE 0xdeadbeef #define SPD_EEPROM_ADDRESS1 0x51 #define SPD_EEPROM_ADDRESS2 0x52 -#define SPD_EEPROM_ADDRESS3 0x54 -#define SPD_EEPROM_ADDRESS4 0x53 /* Board error */ +#define SPD_EEPROM_ADDRESS3 0x53 +#define SPD_EEPROM_ADDRESS4 0x54 #define SPD_EEPROM_ADDRESS5 0x55 #define SPD_EEPROM_ADDRESS6 0x56 /* dummy address */ #define SPD_EEPROM_ADDRESS SPD_EEPROM_ADDRESS1 -- cgit v0.10.2 From a2dc818f21cf216c486d267f7a983b8e7808519c Mon Sep 17 00:00:00 2001 From: Bhupesh Sharma Date: Thu, 28 May 2015 14:54:10 +0530 Subject: armv8/ls2085a: Expose all DDR region(s) to Linux This patch allows u-boot to expose the complete DDR region(s) to Linux (after subtracting the memory hidden via MEM_TOP_HIDE mechanism). This allows the u-boot to support the 48-bit VA support provided by ARM64 Linux in flavors 3.18 and above, by passing the appropriate 'memory' DTS nodes. Signed-off-by: Bhupesh Sharma Signed-off-by: Prabhakar Kushwaha Reviewed-by: York Sun diff --git a/board/freescale/ls2085a/README b/board/freescale/ls2085a/README index b7023e1..bc1d0bb 100644 --- a/board/freescale/ls2085a/README +++ b/board/freescale/ls2085a/README @@ -14,3 +14,14 @@ Memory map from core's view Other addresses are either reserved, or not used directly by u-boot. This list should be updated when more addresses are used. + +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' + diff --git a/board/freescale/ls2085a/ls2085a.c b/board/freescale/ls2085a/ls2085a.c index dd0acf2..e43dd4c 100644 --- a/board/freescale/ls2085a/ls2085a.c +++ b/board/freescale/ls2085a/ls2085a.c @@ -127,15 +127,18 @@ void fdt_fixup_board_enet(void *fdt) #ifdef CONFIG_OF_BOARD_SETUP int ft_board_setup(void *blob, bd_t *bd) { - phys_addr_t base; - phys_size_t size; + u64 base[CONFIG_NR_DRAM_BANKS]; + u64 size[CONFIG_NR_DRAM_BANKS]; ft_cpu_setup(blob, bd); - /* limit the memory size to bank 1 until Linux can handle 40-bit PA */ - base = getenv_bootm_low(); - size = getenv_bootm_size(); - fdt_fixup_memory(blob, (u64)base, (u64)size); + /* 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); #ifdef CONFIG_FSL_MC_ENET fdt_fixup_board_enet(blob); diff --git a/board/freescale/ls2085aqds/README b/board/freescale/ls2085aqds/README index fb3938e..11b2e79 100644 --- a/board/freescale/ls2085aqds/README +++ b/board/freescale/ls2085aqds/README @@ -127,3 +127,22 @@ 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' + diff --git a/board/freescale/ls2085aqds/ls2085aqds.c b/board/freescale/ls2085aqds/ls2085aqds.c index 27a23ec..9b57799 100644 --- a/board/freescale/ls2085aqds/ls2085aqds.c +++ b/board/freescale/ls2085aqds/ls2085aqds.c @@ -244,15 +244,18 @@ void fdt_fixup_board_enet(void *fdt) #ifdef CONFIG_OF_BOARD_SETUP int ft_board_setup(void *blob, bd_t *bd) { - phys_addr_t base; - phys_size_t size; + u64 base[CONFIG_NR_DRAM_BANKS]; + u64 size[CONFIG_NR_DRAM_BANKS]; ft_cpu_setup(blob, bd); - /* limit the memory size to bank 1 until Linux can handle 40-bit PA */ - base = getenv_bootm_low(); - size = getenv_bootm_size(); - fdt_fixup_memory(blob, (u64)base, (u64)size); + /* 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); #ifdef CONFIG_FSL_MC_ENET fdt_fixup_board_enet(blob); diff --git a/board/freescale/ls2085ardb/README b/board/freescale/ls2085ardb/README index cfd5185..2f18243 100644 --- a/board/freescale/ls2085ardb/README +++ b/board/freescale/ls2085ardb/README @@ -107,3 +107,14 @@ Booting Options --------------- a) NOR boot b) NAND boot + +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' + diff --git a/board/freescale/ls2085ardb/ls2085ardb.c b/board/freescale/ls2085ardb/ls2085ardb.c index abe2114..15cb251 100644 --- a/board/freescale/ls2085ardb/ls2085ardb.c +++ b/board/freescale/ls2085ardb/ls2085ardb.c @@ -241,15 +241,18 @@ void fdt_fixup_board_enet(void *fdt) #ifdef CONFIG_OF_BOARD_SETUP int ft_board_setup(void *blob, bd_t *bd) { - phys_addr_t base; - phys_size_t size; + u64 base[CONFIG_NR_DRAM_BANKS]; + u64 size[CONFIG_NR_DRAM_BANKS]; ft_cpu_setup(blob, bd); - /* limit the memory size to bank 1 until Linux can handle 40-bit PA */ - base = getenv_bootm_low(); - size = getenv_bootm_size(); - fdt_fixup_memory(blob, (u64)base, (u64)size); + /* 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); #ifdef CONFIG_FSL_MC_ENET fdt_fixup_board_enet(blob); -- cgit v0.10.2 From 092da485c7e685745b6e6f9ab5540fb002046201 Mon Sep 17 00:00:00 2001 From: Prabhakar Kushwaha Date: Thu, 28 May 2015 14:54:11 +0530 Subject: armv8/ls2085a: Update SoC README for DDR layout Update SoC README to provide details of - Memory regions - Memory used by MC and Debug server Signed-off-by: Bhupesh Sharma Signed-off-by: Prabhakar Kushwaha Reviewed-by: York Sun diff --git a/arch/arm/cpu/armv8/fsl-lsch3/README b/arch/arm/cpu/armv8/fsl-lsch3/README index 37f07fb..3c15479 100644 --- a/arch/arm/cpu/armv8/fsl-lsch3/README +++ b/arch/arm/cpu/armv8/fsl-lsch3/README @@ -9,6 +9,31 @@ Freescale LayerScape with Chassis Generation 3 This architecture supports Freescale ARMv8 SoCs with Chassis generation 3, for example LS2085A. +DDR Layout +============ +Entire DDR region splits into two regions. + - Region 1 is at address 0x8000_0000 to 0xffff_ffff. + - Region 2 is at 0x80_8000_0000 to the top of total memory, + for example 16GB, 0x83_ffff_ffff. + +All DDR memory is marked as cache-enabled. + +When MC and Debug server is enabled, they carve 512MB away from the high +end of DDR. For example, if the total DDR is 16GB, it shrinks to 15.5GB +with MC and Debug server enabled. Linux only sees 15.5GB. + +The reserved 512MB layout looks like + + +---------------+ <-- top/end of memory + | 256MB | debug server + +---------------+ + | 256MB | MC + +---------------+ + | ... | + +MC requires the memory to be aligned with 512MB, so even debug server is +not enabled, 512MB is reserved, not 256MB. + Flash Layout ============ -- cgit v0.10.2 From dbe94dd11c241e4aa5cd3b04330dfa0d0f634d15 Mon Sep 17 00:00:00 2001 From: Bhupesh Sharma Date: Thu, 28 May 2015 14:54:12 +0530 Subject: driver/fsl_debug_server: Fix the DDR hide logic for LS2085a This patch fixes the DDR hide logic for LS2085a, correcting the way the Debug Server FW and MC FW images are placed on the top of system DDR and how the rest of the system DDR space is made visibile to Linux. Signed-off-by: Bhupesh Sharma Signed-off-by: Prabhakar Kushwaha Reviewed-by: York Sun diff --git a/drivers/misc/fsl_debug_server.c b/drivers/misc/fsl_debug_server.c index e080fe6..44cd9b9 100644 --- a/drivers/misc/fsl_debug_server.c +++ b/drivers/misc/fsl_debug_server.c @@ -10,6 +10,7 @@ #include #include +#include #include DECLARE_GLOBAL_DATA_PTR; @@ -151,6 +152,10 @@ int debug_server_init(void) debug_server_ram_addr = gd->bd->bi_dram[0].start + gd->bd->bi_dram[0].size; +#ifdef CONFIG_FSL_MC_ENET + debug_server_ram_addr += mc_get_dram_block_size(); +#endif + error = debug_server_parse_firmware_fit_image(&raw_image_addr, &raw_image_size); if (error != 0) diff --git a/drivers/net/fsl-mc/mc.c b/drivers/net/fsl-mc/mc.c index c5c44bc..f4a050a 100644 --- a/drivers/net/fsl-mc/mc.c +++ b/drivers/net/fsl-mc/mc.c @@ -9,7 +9,6 @@ #include #include #include -#include #include #include #include @@ -403,13 +402,6 @@ int mc_init(void) gd->bd->bi_dram[0].start + gd->bd->bi_dram[0].size; } -#ifdef CONFIG_FSL_DEBUG_SERVER - /* - * FIXME: I don't think this is right. See get_dram_size_to_hide() - */ - mc_ram_addr -= debug_server_get_dram_block_size(); -#endif - error = calculate_mc_private_ram_params(mc_ram_addr, mc_ram_size, &mc_ram_aligned_base_addr, -- cgit v0.10.2 From f299b5b0d244b7c4ef4820acb83fc562ff099413 Mon Sep 17 00:00:00 2001 From: Bhupesh Sharma Date: Thu, 28 May 2015 14:54:13 +0530 Subject: arm/errata: Update required bits for A57 cores erratas This patch updates the setting of required bits for A57 cores erratas - 828024 and 826974 Signed-off-by: Bhupesh Sharma Signed-off-by: Dai Haruki Signed-off-by: Prabhakar Kushwaha Reviewed-by: York Sun diff --git a/arch/arm/cpu/armv8/start.S b/arch/arm/cpu/armv8/start.S index e5f2766..e70bed4 100644 --- a/arch/arm/cpu/armv8/start.S +++ b/arch/arm/cpu/armv8/start.S @@ -115,18 +115,18 @@ apply_a57_core_errata: #ifdef CONFIG_ARM_ERRATA_828024 mrs x0, S3_1_c15_c2_0 /* cpuactlr_el1 */ /* Disable non-allocate hint of w-b-n-a memory type */ - mov x0, #0x1 << 49 + orr x0, x0, #1 << 49 /* Disable write streaming no L1-allocate threshold */ - mov x0, #0x3 << 25 + orr x0, x0, #3 << 25 /* Disable write streaming no-allocate threshold */ - mov x0, #0x3 << 27 + orr x0, x0, #3 << 27 msr S3_1_c15_c2_0, x0 /* cpuactlr_el1 */ #endif #ifdef CONFIG_ARM_ERRATA_826974 mrs x0, S3_1_c15_c2_0 /* cpuactlr_el1 */ /* Disable speculative load execution ahead of a DMB */ - mov x0, #0x1 << 59 + orr x0, x0, #1 << 59 msr S3_1_c15_c2_0, x0 /* cpuactlr_el1 */ #endif -- cgit v0.10.2 From 5c05508971ff9cd0a989f2013d8cd036c89f3e5c Mon Sep 17 00:00:00 2001 From: Prabhakar Kushwaha Date: Tue, 2 Jun 2015 10:55:52 +0530 Subject: armv8/fsl-lsch3: Support 256M mem split for MC & dbg-srvr The agreed split of the top of memory is 256M for debug server and 256M for MC. This patch implements the split. In addition, the MC mem must be 512MB aligned, so the amount of memory to hide must be 512MB to achieve that alignment. Signed-off-by: Stuart Yoder Signed-off-by: Prabhakar Kushwaha Reviewed-by: York Sun diff --git a/README b/README index 53fc28e..b564640 100644 --- a/README +++ b/README @@ -5063,6 +5063,21 @@ within that device. normal addressable memory via the LBC. CONFIG_SYS_LS_MC_FW_ADDR is the virtual address in NOR flash. +Freescale Layerscape Debug Server Support: +------------------------------------------- +The Freescale Layerscape Debug Server Support supports the loading of +"Debug Server firmware" and triggering SP boot-rom. +This firmware often needs to be loaded during U-Boot booting. + +- CONFIG_FSL_DEBUG_SERVER + Enable the Debug Server for Layerscape SoCs. + +- CONFIG_SYS_DEBUG_SERVER_DRAM_BLOCK_MIN_SIZE + Define minimum DDR size required for debug server image + +- CONFIG_SYS_MEM_TOP_HIDE_MIN + Define minimum DDR size to be hided from top of the DDR memory + Building the Software: ====================== diff --git a/board/freescale/ls2085a/ls2085a.c b/board/freescale/ls2085a/ls2085a.c index e43dd4c..73c4410 100644 --- a/board/freescale/ls2085a/ls2085a.c +++ b/board/freescale/ls2085a/ls2085a.c @@ -80,7 +80,7 @@ unsigned long get_dram_size_to_hide(void) dram_to_hide += mc_get_dram_block_size(); #endif - return dram_to_hide; + return roundup(dram_to_hide, CONFIG_SYS_MEM_TOP_HIDE_MIN); } int board_eth_init(bd_t *bis) diff --git a/board/freescale/ls2085aqds/ls2085aqds.c b/board/freescale/ls2085aqds/ls2085aqds.c index 9b57799..c492c7e 100644 --- a/board/freescale/ls2085aqds/ls2085aqds.c +++ b/board/freescale/ls2085aqds/ls2085aqds.c @@ -215,7 +215,7 @@ unsigned long get_dram_size_to_hide(void) dram_to_hide += mc_get_dram_block_size(); #endif - return dram_to_hide; + return roundup(dram_to_hide, CONFIG_SYS_MEM_TOP_HIDE_MIN); } #ifdef CONFIG_FSL_MC_ENET diff --git a/board/freescale/ls2085ardb/ls2085ardb.c b/board/freescale/ls2085ardb/ls2085ardb.c index 15cb251..1f8cf8a 100644 --- a/board/freescale/ls2085ardb/ls2085ardb.c +++ b/board/freescale/ls2085ardb/ls2085ardb.c @@ -212,7 +212,7 @@ unsigned long get_dram_size_to_hide(void) dram_to_hide += mc_get_dram_block_size(); #endif - return dram_to_hide; + return roundup(dram_to_hide, CONFIG_SYS_MEM_TOP_HIDE_MIN); } #ifdef CONFIG_FSL_MC_ENET diff --git a/include/configs/ls2085a_common.h b/include/configs/ls2085a_common.h index 1969696..1b4a35a 100644 --- a/include/configs/ls2085a_common.h +++ b/include/configs/ls2085a_common.h @@ -163,21 +163,27 @@ unsigned long long get_qixis_addr(void); #define CONFIG_SYS_NAND_BASE_PHYS 0x30000000 /* Debug Server firmware */ -#define CONFIG_SYS_DEBUG_SERVER_DRAM_BLOCK_MIN_SIZE (512UL * 1024 * 1024) /* 2 sec timeout */ #define CONFIG_SYS_DEBUG_SERVER_TIMEOUT (2 * 1000 * 1000) /* MC firmware */ #define CONFIG_FSL_MC_ENET -#define CONFIG_SYS_LS_MC_DRAM_BLOCK_MIN_SIZE (512UL * 1024 * 1024) /* TODO Actual DPL max length needs to be confirmed with the MC FW team */ #define CONFIG_SYS_LS_MC_DPC_MAX_LENGTH 0x20000 #define CONFIG_SYS_LS_MC_DRAM_DPC_OFFSET 0x00F00000 #define CONFIG_SYS_LS_MC_DPL_MAX_LENGTH 0x20000 #define CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET 0x00F20000 -/* Carve out a DDR region which will not be used by u-boot/Linux */ +/* + * Carve out a DDR region which will not be used by u-boot/Linux + * + * It will be used by MC and Debug Server. The MC region must be + * 512MB aligned, so the min size to hide is 512MB. + */ #if defined(CONFIG_FSL_MC_ENET) || defined(CONFIG_FSL_DEBUG_SERVER) +#define CONFIG_SYS_DEBUG_SERVER_DRAM_BLOCK_MIN_SIZE (256UL * 1024 * 1024) +#define CONFIG_SYS_LS_MC_DRAM_BLOCK_MIN_SIZE (256UL * 1024 * 1024) +#define CONFIG_SYS_MEM_TOP_HIDE_MIN (512UL * 1024 * 1024) #define CONFIG_SYS_MEM_TOP_HIDE get_dram_size_to_hide() #endif -- cgit v0.10.2 From b0ba9d48a449d16e0476b9508fbe25a311145df2 Mon Sep 17 00:00:00 2001 From: Stuart Yoder Date: Thu, 28 May 2015 14:54:15 +0530 Subject: armv8/ls2085a: enable debug server Signed-off-by: Stuart Yoder Signed-off-by: Prabhakar Kushwaha Reviewed-by: York Sun diff --git a/include/configs/ls2085a_common.h b/include/configs/ls2085a_common.h index 1b4a35a..4ee69ff 100644 --- a/include/configs/ls2085a_common.h +++ b/include/configs/ls2085a_common.h @@ -163,6 +163,7 @@ unsigned long long get_qixis_addr(void); #define CONFIG_SYS_NAND_BASE_PHYS 0x30000000 /* Debug Server firmware */ +#define CONFIG_FSL_DEBUG_SERVER /* 2 sec timeout */ #define CONFIG_SYS_DEBUG_SERVER_TIMEOUT (2 * 1000 * 1000) -- cgit v0.10.2 From cc088c3ac63e3decca1a84c7e64cb31b863bc111 Mon Sep 17 00:00:00 2001 From: "J. German Rivera" Date: Thu, 2 Jul 2015 11:28:56 +0530 Subject: drivers/fsl-mc: Make MC boot error messages more readable Make it easier for the user to notice when the MC firmware had problems booting. Signed-off-by: J. German Rivera Signed-off-by: Prabhakar Kushwaha Reviewed-by: York Sun diff --git a/drivers/net/fsl-mc/mc.c b/drivers/net/fsl-mc/mc.c index f4a050a..d02da9d 100644 --- a/drivers/net/fsl-mc/mc.c +++ b/drivers/net/fsl-mc/mc.c @@ -224,13 +224,13 @@ static int load_mc_dpc(u64 mc_ram_addr, size_t mc_ram_size) * Don't return with error here, since the MC firmware can * still boot without a DPC */ - printf("fsl-mc: WARNING: No DPC image found\n"); + printf("\nfsl-mc: WARNING: No DPC image found"); return 0; } dpc_size = fdt_totalsize(dpc_fdt_hdr); if (dpc_size > CONFIG_SYS_LS_MC_DPC_MAX_LENGTH) { - printf("fsl-mc: ERROR: Bad DPC image (too large: %d)\n", + printf("\nfsl-mc: ERROR: Bad DPC image (too large: %d)\n", dpc_size); return -EINVAL; } @@ -278,13 +278,13 @@ static int load_mc_dpl(u64 mc_ram_addr, size_t mc_ram_size) error = fdt_check_header(dpl_fdt_hdr); if (error != 0) { - printf("fsl-mc: ERROR: Bad DPL image (bad header)\n"); + printf("\nfsl-mc: ERROR: Bad DPL image (bad header)\n"); return error; } dpl_size = fdt_totalsize(dpl_fdt_hdr); if (dpl_size > CONFIG_SYS_LS_MC_DPL_MAX_LENGTH) { - printf("fsl-mc: ERROR: Bad DPL image (too large: %d)\n", + printf("\nfsl-mc: ERROR: Bad DPL image (too large: %d)\n", dpl_size); return -EINVAL; } @@ -329,7 +329,6 @@ static int wait_for_mc(bool booting_mc, u32 *final_reg_gsr) struct mc_ccsr_registers __iomem *mc_ccsr_regs = MC_CCSR_BASE_ADDR; dmb(); - debug("Polling mc_ccsr_regs->reg_gsr ...\n"); assert(timeout_ms > 0); for (;;) { udelay(1000); /* throttle polling */ @@ -344,10 +343,7 @@ static int wait_for_mc(bool booting_mc, u32 *final_reg_gsr) } if (timeout_ms == 0) { - if (booting_mc) - printf("fsl-mc: timeout booting management complex firmware\n"); - else - printf("fsl-mc: timeout deploying data path layout\n"); + printf("ERROR: timeout\n"); /* TODO: Get an error status from an MC CCSR register */ return -ETIMEDOUT; @@ -360,15 +356,13 @@ static int wait_for_mc(bool booting_mc, u32 *final_reg_gsr) * appropriate errno, so that the status property is set to * failure in the fsl,dprc device tree node. */ - if (booting_mc) { - printf("fsl-mc: WARNING: Firmware booted with error (GSR: %#x)\n", - reg_gsr); - } else { - printf("fsl-mc: WARNING: Data path layout deployed with error (GSR: %#x)\n", - reg_gsr); - } + printf("WARNING: Firmware returned an error (GSR: %#x)\n", + reg_gsr); + } else { + printf("SUCCESS\n"); } + *final_reg_gsr = reg_gsr; return 0; } @@ -464,7 +458,7 @@ int mc_init(void) */ out_le32(&mc_ccsr_regs->reg_gsr, 0xDD00); - printf("\nfsl-mc: Booting Management Complex ...\n"); + printf("\nfsl-mc: Booting Management Complex ... "); /* * Deassert reset and release MC core 0 to run @@ -517,10 +511,11 @@ int mc_init(void) * Tell the MC to deploy the DPL: */ out_le32(&mc_ccsr_regs->reg_gsr, 0x0); - printf("\nfsl-mc: Deploying data path layout ...\n"); + printf("fsl-mc: Deploying data path layout ... "); error = wait_for_mc(false, ®_gsr); if (error != 0) goto out; + out: if (error != 0) mc_boot_status = -error; -- cgit v0.10.2 From e247db4fadc4e00b6f61f28f4df012bcb3b083c1 Mon Sep 17 00:00:00 2001 From: Prabhakar Kushwaha Date: Thu, 2 Jul 2015 11:28:57 +0530 Subject: driver/ldpaa_eth:Flush buffer before seeding BMAN after TX_conf Flush buffer before releasing to BMan after TX_conf to ensure, the core does not have any cachelines that the WRIOP will DMA to. Signed-off-by: Prabhakar Kushwaha Reviewed-by: York Sun diff --git a/drivers/net/ldpaa_eth/ldpaa_eth.c b/drivers/net/ldpaa_eth/ldpaa_eth.c index d4be1ba..5636511 100644 --- a/drivers/net/ldpaa_eth/ldpaa_eth.c +++ b/drivers/net/ldpaa_eth/ldpaa_eth.c @@ -153,6 +153,7 @@ static void ldpaa_eth_tx_conf(struct ldpaa_eth_priv *priv, } } + flush_dcache_range(fd_addr, fd_addr + LDPAA_ETH_RX_BUFFER_SIZE); qbman_release_desc_clear(&releasedesc); qbman_release_desc_set_bpid(&releasedesc, dflt_dpbp->dpbp_attr.bpid); do { -- cgit v0.10.2 From c1000c12d3105898909e77d265d2eb4affb91f6c Mon Sep 17 00:00:00 2001 From: "J. German Rivera" Date: Thu, 2 Jul 2015 11:28:58 +0530 Subject: drivers/fsl-mc: Autoload AOIP image from NOR flash Load AIOP image from NOR flash into DDR so that the MC firmware the MC fw can start it at boot time Signed-off-by: J. German Rivera Signed-off-by: Prabhakar Kushwaha Reviewed-by: York Sun diff --git a/drivers/net/fsl-mc/mc.c b/drivers/net/fsl-mc/mc.c index d02da9d..2b38b50 100644 --- a/drivers/net/fsl-mc/mc.c +++ b/drivers/net/fsl-mc/mc.c @@ -321,6 +321,23 @@ static unsigned long get_mc_boot_timeout_ms(void) return timeout_ms; } +#ifdef CONFIG_SYS_LS_MC_AIOP_IMG_IN_NOR +static int load_mc_aiop_img(u64 mc_ram_addr, size_t mc_ram_size) +{ + void *aiop_img; + + /* + * Load the MC AIOP image in the MC private DRAM block: + */ + + aiop_img = (void *)CONFIG_SYS_LS_MC_AIOP_IMG_ADDR; + mc_copy_image("MC AIOP image", + (u64)aiop_img, CONFIG_SYS_LS_MC_AIOP_IMG_MAX_LENGTH, + mc_ram_addr + CONFIG_SYS_LS_MC_DRAM_AIOP_IMG_OFFSET); + + return 0; +} +#endif static int wait_for_mc(bool booting_mc, u32 *final_reg_gsr) { u32 reg_gsr; @@ -440,6 +457,12 @@ int mc_init(void) if (error != 0) goto out; +#ifdef CONFIG_SYS_LS_MC_AIOP_IMG_IN_NOR + error = load_mc_aiop_img(mc_ram_addr, mc_ram_size); + if (error != 0) + goto out; +#endif + debug("mc_ccsr_regs %p\n", mc_ccsr_regs); dump_mc_ccsr_regs(mc_ccsr_regs); diff --git a/include/configs/ls2085a_common.h b/include/configs/ls2085a_common.h index 4ee69ff..951410d 100644 --- a/include/configs/ls2085a_common.h +++ b/include/configs/ls2085a_common.h @@ -174,6 +174,8 @@ unsigned long long get_qixis_addr(void); #define CONFIG_SYS_LS_MC_DRAM_DPC_OFFSET 0x00F00000 #define CONFIG_SYS_LS_MC_DPL_MAX_LENGTH 0x20000 #define CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET 0x00F20000 +#define CONFIG_SYS_LS_MC_AIOP_IMG_MAX_LENGTH 0x200000 +#define CONFIG_SYS_LS_MC_DRAM_AIOP_IMG_OFFSET 0x07000000 /* * Carve out a DDR region which will not be used by u-boot/Linux diff --git a/include/configs/ls2085aqds.h b/include/configs/ls2085aqds.h index da73067..dcdd316 100644 --- a/include/configs/ls2085aqds.h +++ b/include/configs/ls2085aqds.h @@ -260,6 +260,8 @@ unsigned long get_board_ddr_clk(void); #define CONFIG_SYS_LS_MC_DPC_ADDR 0x580800000ULL #define CONFIG_SYS_LS_MC_BOOT_TIMEOUT_MS 5000 +#define CONFIG_SYS_LS_MC_AIOP_IMG_IN_NOR +#define CONFIG_SYS_LS_MC_AIOP_IMG_ADDR 0x580900000ULL /* * I2C diff --git a/include/configs/ls2085ardb.h b/include/configs/ls2085ardb.h index ec10393..891fabe 100644 --- a/include/configs/ls2085ardb.h +++ b/include/configs/ls2085ardb.h @@ -233,6 +233,8 @@ unsigned long get_board_sys_clk(void); #define CONFIG_SYS_LS_MC_DPC_ADDR 0x580800000ULL #define CONFIG_SYS_LS_MC_BOOT_TIMEOUT_MS 5000 +#define CONFIG_SYS_LS_MC_AIOP_IMG_IN_NOR +#define CONFIG_SYS_LS_MC_AIOP_IMG_ADDR 0x580900000ULL /* * I2C -- cgit v0.10.2 From 1f1c25c745d7916c460bb67b6a4159581573ba18 Mon Sep 17 00:00:00 2001 From: Prabhakar Kushwaha Date: Thu, 2 Jul 2015 11:28:59 +0530 Subject: drivers: fsl-mc: Update flibs to mc-0.6.0.1 Update flibs changes to mc-0.6.0.1 for dpmang, dprc, dpni and dpio objects Also rename qbman_portal_ce/ci_paddr to qbman_portal_ce/ci_offset in dpio_attr. These are now offsets from the SoC QBMan portals base. Signed-off-by: J. German Rivera Signed-off-by: Prabhakar Kushwaha Reviewed-by: York Sun diff --git a/drivers/net/fsl-mc/dpni.c b/drivers/net/fsl-mc/dpni.c index b384401..7bc2504 100644 --- a/drivers/net/fsl-mc/dpni.c +++ b/drivers/net/fsl-mc/dpni.c @@ -313,7 +313,7 @@ int dpni_set_counter(struct fsl_mc_io *mc_io, int dpni_set_link_cfg(struct fsl_mc_io *mc_io, uint16_t token, - struct dpni_link_cfg *cfg) + const struct dpni_link_cfg *cfg) { struct mc_command cmd = { 0 }; diff --git a/drivers/net/fsl-mc/mc.c b/drivers/net/fsl-mc/mc.c index 2b38b50..2094595 100644 --- a/drivers/net/fsl-mc/mc.c +++ b/drivers/net/fsl-mc/mc.c @@ -610,14 +610,16 @@ int dpio_init(struct dprc_obj_desc obj_desc) printf("dpio_enable() failed %d\n", err); goto err_get_enable; } - debug("ce_paddr=0x%llx, ci_paddr=0x%llx, portalid=%d, prios=%d\n", - attr.qbman_portal_ce_paddr, - attr.qbman_portal_ci_paddr, + debug("ce_offset=0x%llx, ci_offset=0x%llx, portalid=%d, prios=%d\n", + attr.qbman_portal_ce_offset, + attr.qbman_portal_ci_offset, attr.qbman_portal_id, attr.num_priorities); - p_des.cena_bar = (void *)attr.qbman_portal_ce_paddr; - p_des.cinh_bar = (void *)attr.qbman_portal_ci_paddr; + p_des.cena_bar = (void *)(SOC_QBMAN_PORTALS_BASE_ADDR + + attr.qbman_portal_ce_offset); + p_des.cinh_bar = (void *)(SOC_QBMAN_PORTALS_BASE_ADDR + + attr.qbman_portal_ci_offset); dflt_dpio->sw_portal = qbman_swp_init(&p_des); if (dflt_dpio->sw_portal == NULL) { diff --git a/include/fsl-mc/fsl_dpio.h b/include/fsl-mc/fsl_dpio.h index e84b419..e779909 100644 --- a/include/fsl-mc/fsl_dpio.h +++ b/include/fsl-mc/fsl_dpio.h @@ -8,8 +8,8 @@ #define _FSL_DPIO_H /* DPIO Version */ -#define DPIO_VER_MAJOR 2 -#define DPIO_VER_MINOR 1 +#define DPIO_VER_MAJOR 3 +#define DPIO_VER_MINOR 0 /* Command IDs */ #define DPIO_CMDID_CLOSE 0x800 @@ -31,8 +31,8 @@ do { \ MC_RSP_OP(cmd, 0, 32, 16, uint16_t, attr->qbman_portal_id);\ MC_RSP_OP(cmd, 0, 48, 8, uint8_t, attr->num_priorities);\ MC_RSP_OP(cmd, 0, 56, 4, enum dpio_channel_mode, attr->channel_mode);\ - MC_RSP_OP(cmd, 1, 0, 64, uint64_t, attr->qbman_portal_ce_paddr);\ - MC_RSP_OP(cmd, 2, 0, 64, uint64_t, attr->qbman_portal_ci_paddr);\ + MC_RSP_OP(cmd, 1, 0, 64, uint64_t, attr->qbman_portal_ce_offset);\ + MC_RSP_OP(cmd, 2, 0, 64, uint64_t, attr->qbman_portal_ci_offset);\ MC_RSP_OP(cmd, 3, 0, 16, uint16_t, attr->version.major);\ MC_RSP_OP(cmd, 3, 16, 16, uint16_t, attr->version.minor);\ } while (0) @@ -42,6 +42,7 @@ do { \ */ struct fsl_mc_io; + /** * dpio_open() - Open a control session for the specified object * @mc_io: Pointer to MC portal's I/O object @@ -61,18 +62,9 @@ struct fsl_mc_io; int dpio_open(struct fsl_mc_io *mc_io, int dpio_id, uint16_t *token); /** - * dpio_open() - Open a control session for the specified object + * dpio_close() - Close the control session of the object * @mc_io: Pointer to MC portal's I/O object - * @dpio_id: DPIO unique ID - * @token: Returned token; use in subsequent API calls - * - * This function can be used to open a control session for an - * already created object; an object may have been declared in - * the DPL or by calling the dpio_create() function. - * This function returns a unique authentication token, - * associated with the specific object ID and the specific MC - * portal; this token must be used in all subsequent commands for - * this specific object. + * @token: Token of DPIO object * * Return: '0' on Success; Error code otherwise. */ @@ -121,10 +113,8 @@ int dpio_reset(struct fsl_mc_io *mc_io, uint16_t token); * struct dpio_attr - Structure representing DPIO attributes * @id: DPIO object ID * @version: DPIO version - * @qbman_portal_ce_paddr: Physical address of the software portal - * cache-enabled area - * @qbman_portal_ci_paddr: Physical address of the software portal - * cache-inhibited area + * @qbman_portal_ce_offset: offset of the software portal cache-enabled area + * @qbman_portal_ci_offset: offset of the software portal cache-inhibited area * @qbman_portal_id: Software portal ID * @channel_mode: Notification channel mode * @num_priorities: Number of priorities for the notification channel (1-8); @@ -141,8 +131,8 @@ struct dpio_attr { uint16_t major; uint16_t minor; } version; - uint64_t qbman_portal_ce_paddr; - uint64_t qbman_portal_ci_paddr; + uint64_t qbman_portal_ce_offset; + uint64_t qbman_portal_ci_offset; uint16_t qbman_portal_id; enum dpio_channel_mode channel_mode; uint8_t num_priorities; diff --git a/include/fsl-mc/fsl_dpmng.h b/include/fsl-mc/fsl_dpmng.h index 986e7c8..6feb292 100644 --- a/include/fsl-mc/fsl_dpmng.h +++ b/include/fsl-mc/fsl_dpmng.h @@ -14,7 +14,7 @@ struct fsl_mc_io; /** * Management Complex firmware version information */ -#define MC_VER_MAJOR 6 +#define MC_VER_MAJOR 7 #define MC_VER_MINOR 0 /** diff --git a/include/fsl-mc/fsl_dpni.h b/include/fsl-mc/fsl_dpni.h index 67c087d..26b67f0 100644 --- a/include/fsl-mc/fsl_dpni.h +++ b/include/fsl-mc/fsl_dpni.h @@ -7,7 +7,7 @@ #define _FSL_DPNI_H /* DPNI Version */ -#define DPNI_VER_MAJOR 4 +#define DPNI_VER_MAJOR 5 #define DPNI_VER_MINOR 0 /* Command IDs */ @@ -78,7 +78,7 @@ do { \ MC_RSP_OP(cmd, 0, 32, 8, uint8_t, attr->max_tcs); \ MC_RSP_OP(cmd, 0, 40, 8, uint8_t, attr->max_senders); \ MC_RSP_OP(cmd, 0, 48, 8, enum net_prot, attr->start_hdr); \ - MC_RSP_OP(cmd, 1, 0, 64, uint64_t, attr->options); \ + MC_RSP_OP(cmd, 1, 0, 32, uint32_t, attr->options); \ MC_RSP_OP(cmd, 2, 0, 8, uint8_t, attr->max_unicast_filters); \ MC_RSP_OP(cmd, 2, 8, 8, uint8_t, attr->max_multicast_filters);\ MC_RSP_OP(cmd, 2, 16, 8, uint8_t, attr->max_vlan_filters); \ @@ -98,7 +98,9 @@ do { \ MC_RSP_OP(cmd, 4, 16, 16, uint16_t, \ attr->ipr_cfg.min_frag_size_ipv4); \ MC_RSP_OP(cmd, 4, 32, 16, uint16_t, \ - attr->ipr_cfg.min_frag_size_ipv6); \ + attr->ipr_cfg.min_frag_size_ipv6);\ + MC_RSP_OP(cmd, 4, 48, 8, uint8_t, attr->max_policers); \ + MC_RSP_OP(cmd, 4, 56, 8, uint8_t, attr->max_congestion_ctrl); \ MC_RSP_OP(cmd, 5, 0, 16, uint16_t, \ attr->ipr_cfg.max_open_frames_ipv4); \ MC_RSP_OP(cmd, 5, 16, 16, uint16_t, \ @@ -208,7 +210,7 @@ do { \ /* cmd, param, offset, width, type, arg_name */ #define DPNI_CMD_SET_LINK_CFG(cmd, cfg) \ do { \ - MC_CMD_OP(cmd, 1, 0, 64, uint64_t, cfg->rate);\ + MC_CMD_OP(cmd, 1, 0, 32, uint32_t, cfg->rate);\ MC_CMD_OP(cmd, 2, 0, 64, uint64_t, cfg->options);\ } while (0) @@ -216,7 +218,7 @@ do { \ #define DPNI_RSP_GET_LINK_STATE(cmd, state) \ do { \ MC_RSP_OP(cmd, 0, 32, 1, int, state->up);\ - MC_RSP_OP(cmd, 1, 0, 64, uint64_t, state->rate);\ + MC_RSP_OP(cmd, 1, 0, 32, uint32_t, state->rate);\ MC_RSP_OP(cmd, 2, 0, 64, uint64_t, state->options);\ } while (0) @@ -326,6 +328,13 @@ do { \ MC_CMD_OP(cmd, 1, 0, 64, uint64_t, cfg->user_ctx); \ MC_CMD_OP(cmd, 2, 16, 8, uint8_t, tc_id); \ MC_CMD_OP(cmd, 2, 32, 32, uint32_t, cfg->options); \ + MC_CMD_OP(cmd, 3, 0, 4, enum dpni_flc_type, cfg->flc_cfg.flc_type); \ + MC_CMD_OP(cmd, 3, 4, 4, enum dpni_stash_size, \ + cfg->flc_cfg.frame_data_size);\ + MC_CMD_OP(cmd, 3, 8, 4, enum dpni_stash_size, \ + cfg->flc_cfg.flow_context_size);\ + MC_CMD_OP(cmd, 3, 32, 32, uint32_t, cfg->flc_cfg.options);\ + MC_CMD_OP(cmd, 4, 0, 64, uint64_t, cfg->flc_cfg.flow_context);\ } while (0) /* cmd, param, offset, width, type, arg_name */ @@ -343,6 +352,13 @@ do { \ MC_RSP_OP(cmd, 0, 40, 2, enum dpni_dest, attr->dest_cfg.dest_type); \ MC_RSP_OP(cmd, 1, 0, 64, uint64_t, attr->user_ctx); \ MC_RSP_OP(cmd, 2, 32, 32, uint32_t, attr->fqid); \ + MC_RSP_OP(cmd, 3, 0, 4, enum dpni_flc_type, attr->flc_cfg.flc_type); \ + MC_RSP_OP(cmd, 3, 4, 4, enum dpni_stash_size, \ + attr->flc_cfg.frame_data_size);\ + MC_RSP_OP(cmd, 3, 8, 4, enum dpni_stash_size, \ + attr->flc_cfg.flow_context_size);\ + MC_RSP_OP(cmd, 3, 32, 32, uint32_t, attr->flc_cfg.options);\ + MC_RSP_OP(cmd, 4, 0, 64, uint64_t, attr->flc_cfg.flow_context);\ } while (0) enum net_prot { @@ -399,7 +415,8 @@ enum net_prot { NET_PROT_DUMMY_LAST }; -/* Data Path Network Interface API +/** + * Data Path Network Interface API * Contains initialization APIs and runtime control APIs for DPNI */ @@ -545,6 +562,8 @@ int dpni_reset(struct fsl_mc_io *mc_io, uint16_t token); * @max_qos_entries: if 'max_tcs > 1', declares the maximum entries in QoS table * @max_qos_key_size: Maximum key size for the QoS look-up * @max_dist_key_size: Maximum key size for the distribution look-up + * @max_policers: Maximum number of policers; + * @max_congestion_ctrl: Maximum number of congestion control groups (CGs); * @ipr_cfg: IP reassembly configuration */ struct dpni_attr { @@ -559,7 +578,7 @@ struct dpni_attr { uint16_t minor; } version; enum net_prot start_hdr; - uint64_t options; + uint32_t options; uint8_t max_senders; uint8_t max_tcs; uint8_t max_dist_per_tc[DPNI_MAX_TC]; @@ -569,8 +588,11 @@ struct dpni_attr { uint8_t max_qos_entries; uint8_t max_qos_key_size; uint8_t max_dist_key_size; + uint8_t max_policers; + uint8_t max_congestion_ctrl; struct dpni_ipr_cfg ipr_cfg; }; + /** * dpni_get_attributes() - Retrieve DPNI attributes. * @mc_io: Pointer to MC portal's I/O objec @@ -634,6 +656,7 @@ struct dpni_buffer_layout { int dpni_get_rx_buffer_layout(struct fsl_mc_io *mc_io, uint16_t token, struct dpni_buffer_layout *layout); + /** * dpni_set_rx_buffer_layout() - Set Rx buffer layout configuration. * @mc_io: Pointer to MC portal's I/O object @@ -661,19 +684,19 @@ int dpni_get_tx_buffer_layout(struct fsl_mc_io *mc_io, struct dpni_buffer_layout *layout); /** - * @brief Set Tx buffer layout configuration. - * - * @param[in] mc_io Pointer to MC portal's I/O object - * @param[in] token Token of DPNI object - * @param[in] layout Buffer layout configuration + * dpni_set_tx_buffer_layout() - Set Tx buffer layout configuration. + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPNI object + * @layout: Buffer layout configuration * - * @returns '0' on Success; Error code otherwise. + * Return: '0' on Success; Error code otherwise. * * @warning Allowed only when DPNI is disabled */ int dpni_set_tx_buffer_layout(struct fsl_mc_io *mc_io, uint16_t token, const struct dpni_buffer_layout *layout); + /** * dpni_get_tx_conf_buffer_layout() - Retrieve Tx confirmation buffer layout * attributes. @@ -686,6 +709,7 @@ int dpni_set_tx_buffer_layout(struct fsl_mc_io *mc_io, int dpni_get_tx_conf_buffer_layout(struct fsl_mc_io *mc_io, uint16_t token, struct dpni_buffer_layout *layout); + /** * dpni_set_tx_conf_buffer_layout() - Set Tx confirmation buffer layout * configuration. @@ -700,15 +724,16 @@ int dpni_get_tx_conf_buffer_layout(struct fsl_mc_io *mc_io, int dpni_set_tx_conf_buffer_layout(struct fsl_mc_io *mc_io, uint16_t token, const struct dpni_buffer_layout *layout); + /** - * dpni_get_spid() - Get the AIOP storage profile ID associated with the DPNI + * dpni_get_qdid() - Get the Queuing Destination ID (QDID) that should be used + * for enqueue operations * @mc_io: Pointer to MC portal's I/O object * @token: Token of DPNI object - * @spid: Returned aiop storage-profile ID + * @qdid: Returned virtual QDID value that should be used as an argument + * in all enqueue operations * * Return: '0' on Success; Error code otherwise. - * - * @warning Only relevant for DPNI that belongs to AIOP container. */ int dpni_get_qdid(struct fsl_mc_io *mc_io, uint16_t token, uint16_t *qdid); @@ -781,13 +806,23 @@ int dpni_set_counter(struct fsl_mc_io *mc_io, uint16_t token, enum dpni_counter counter, uint64_t value); + +/* Enable auto-negotiation */ +#define DPNI_LINK_OPT_AUTONEG 0x0000000000000001ULL +/* Enable half-duplex mode */ +#define DPNI_LINK_OPT_HALF_DUPLEX 0x0000000000000002ULL +/* Enable pause frames */ +#define DPNI_LINK_OPT_PAUSE 0x0000000000000004ULL +/* Enable a-symmetric pause frames */ +#define DPNI_LINK_OPT_ASYM_PAUSE 0x0000000000000008ULL + /** * struct - Structure representing DPNI link configuration * @rate: Rate * @options: Mask of available options; use 'DPNI_LINK_OPT_' values */ struct dpni_link_cfg { - uint64_t rate; + uint32_t rate; uint64_t options; }; @@ -801,7 +836,7 @@ struct dpni_link_cfg { */ int dpni_set_link_cfg(struct fsl_mc_io *mc_io, uint16_t token, - struct dpni_link_cfg *cfg); + const struct dpni_link_cfg *cfg); /** * struct dpni_link_state - Structure representing DPNI link state @@ -810,7 +845,7 @@ int dpni_set_link_cfg(struct fsl_mc_io *mc_io, * @up: Link state; '0' for down, '1' for up */ struct dpni_link_state { - uint64_t rate; + uint32_t rate; uint64_t options; int up; }; @@ -838,6 +873,7 @@ int dpni_get_link_state(struct fsl_mc_io *mc_io, int dpni_set_primary_mac_addr(struct fsl_mc_io *mc_io, uint16_t token, const uint8_t mac_addr[6]); + /** * dpni_get_primary_mac_addr() - Get the primary MAC address * @mc_io: Pointer to MC portal's I/O object @@ -849,6 +885,7 @@ int dpni_set_primary_mac_addr(struct fsl_mc_io *mc_io, int dpni_get_primary_mac_addr(struct fsl_mc_io *mc_io, uint16_t token, uint8_t mac_addr[6]); + /** * dpni_add_mac_addr() - Add MAC address filter * @mc_io: Pointer to MC portal's I/O object @@ -875,7 +912,7 @@ int dpni_remove_mac_addr(struct fsl_mc_io *mc_io, /** * enum dpni_dest - DPNI destination types - * DPNI_DEST_NONE: Unassigned destination; The queue is set in parked mode and + * @DPNI_DEST_NONE: Unassigned destination; The queue is set in parked mode and * does not generate FQDAN notifications; user is expected to * dequeue from the queue based on polling or other user-defined * method @@ -906,12 +943,69 @@ struct dpni_dest_cfg { uint8_t priority; }; +/** + * enum dpni_flc_type - DPNI FLC types + * @DPNI_FLC_USER_DEFINED: select the FLC to be used for user defined value + * @DPNI_FLC_STASH: select the FLC to be used for stash control + */ +enum dpni_flc_type { + DPNI_FLC_USER_DEFINED = 0, + DPNI_FLC_STASH = 1, +}; + +/** + * enum dpni_stash_size - DPNI FLC stashing size + * @DPNI_STASH_SIZE_0B: no stash + * @DPNI_STASH_SIZE_64B: stashes 64 bytes + * @DPNI_STASH_SIZE_128B: stashes 128 bytes + * @DPNI_STASH_SIZE_192B: stashes 192 bytes + */ +enum dpni_stash_size { + DPNI_STASH_SIZE_0B = 0, + DPNI_STASH_SIZE_64B = 1, + DPNI_STASH_SIZE_128B = 2, + DPNI_STASH_SIZE_192B = 3, +}; + +/* DPNI FLC stash options */ + +/* stashes the whole annotation area (up to 192 bytes) */ +#define DPNI_FLC_STASH_FRAME_ANNOTATION 0x00000001 + +/** + * struct dpni_flc_cfg - Structure representing DPNI FLC configuration + * @flc_type: FLC type + * @options: Mask of available options; + * use 'DPNI_FLC_STASH_' values + * @frame_data_size: Size of frame data to be stashed + * @flow_context_size: Size of flow context to be stashed + * @flow_context: 1. In case flc_type is 'DPNI_FLC_USER_DEFINED': + * this value will be provided in the frame descriptor + * (FD[FLC]) + * 2. In case flc_type is 'DPNI_FLC_STASH': + * this value will be I/O virtual address of the + * flow-context; + * Must be cacheline-aligned and DMA-able memory + */ +struct dpni_flc_cfg { + enum dpni_flc_type flc_type; + uint32_t options; + enum dpni_stash_size frame_data_size; + enum dpni_stash_size flow_context_size; + uint64_t flow_context; +}; + /* DPNI queue modification options */ /* Select to modify the user's context associated with the queue */ #define DPNI_QUEUE_OPT_USER_CTX 0x00000001 /* Select to modify the queue's destination */ #define DPNI_QUEUE_OPT_DEST 0x00000002 +/** Select to modify the flow-context parameters; + * not applicable for Tx-conf/Err queues as the FD comes from the user + */ +#define DPNI_QUEUE_OPT_FLC 0x00000004 + /** * struct dpni_queue_cfg - Structure representing queue configuration @@ -922,11 +1016,17 @@ struct dpni_dest_cfg { * is contained in 'options' * @dest_cfg: Queue destination parameters; * valid only if 'DPNI_QUEUE_OPT_DEST' is contained in 'options' + * @flc_cfg: Flow context configuration; in case the TC's distribution + * is either NONE or HASH the FLC's settings of flow#0 are used. + * in the case of FS (flow-steering) the flow's FLC settings + * are used. + * valid only if 'DPNI_QUEUE_OPT_FLC' is contained in 'options' */ struct dpni_queue_cfg { uint32_t options; uint64_t user_ctx; struct dpni_dest_cfg dest_cfg; + struct dpni_flc_cfg flc_cfg; }; /** @@ -934,11 +1034,13 @@ struct dpni_queue_cfg { * @user_ctx: User context value provided in the frame descriptor of each * dequeued frame * @dest_cfg: Queue destination configuration + * @flc_cfg: Flow context configuration * @fqid: Virtual fqid value to be used for dequeue operations */ struct dpni_queue_attr { uint64_t user_ctx; struct dpni_dest_cfg dest_cfg; + struct dpni_flc_cfg flc_cfg; uint32_t fqid; }; diff --git a/include/fsl-mc/fsl_dprc.h b/include/fsl-mc/fsl_dprc.h index f837e89..26a4598 100644 --- a/include/fsl-mc/fsl_dprc.h +++ b/include/fsl-mc/fsl_dprc.h @@ -10,7 +10,7 @@ #define _FSL_DPRC_H /* DPRC Version */ -#define DPRC_VER_MAJOR 2 +#define DPRC_VER_MAJOR 4 #define DPRC_VER_MINOR 0 /* Command IDs */ @@ -88,6 +88,22 @@ do { \ MC_RSP_OP(cmd, 4, 40, 8, char, obj_desc->type[13]);\ MC_RSP_OP(cmd, 4, 48, 8, char, obj_desc->type[14]);\ MC_RSP_OP(cmd, 4, 56, 8, char, obj_desc->type[15]);\ + MC_RSP_OP(cmd, 5, 0, 8, char, obj_desc->label[0]);\ + MC_RSP_OP(cmd, 5, 8, 8, char, obj_desc->label[1]);\ + MC_RSP_OP(cmd, 5, 16, 8, char, obj_desc->label[2]);\ + MC_RSP_OP(cmd, 5, 24, 8, char, obj_desc->label[3]);\ + MC_RSP_OP(cmd, 5, 32, 8, char, obj_desc->label[4]);\ + MC_RSP_OP(cmd, 5, 40, 8, char, obj_desc->label[5]);\ + MC_RSP_OP(cmd, 5, 48, 8, char, obj_desc->label[6]);\ + MC_RSP_OP(cmd, 5, 56, 8, char, obj_desc->label[7]);\ + MC_RSP_OP(cmd, 6, 0, 8, char, obj_desc->label[8]);\ + MC_RSP_OP(cmd, 6, 8, 8, char, obj_desc->label[9]);\ + MC_RSP_OP(cmd, 6, 16, 8, char, obj_desc->label[10]);\ + MC_RSP_OP(cmd, 6, 24, 8, char, obj_desc->label[11]);\ + MC_RSP_OP(cmd, 6, 32, 8, char, obj_desc->label[12]);\ + MC_RSP_OP(cmd, 6, 40, 8, char, obj_desc->label[13]);\ + MC_RSP_OP(cmd, 6, 48, 8, char, obj_desc->label[14]);\ + MC_RSP_OP(cmd, 6, 56, 8, char, obj_desc->label[15]);\ } while (0) /* cmd, param, offset, width, type, arg_name */ @@ -175,11 +191,33 @@ do { \ /* param, offset, width, type, arg_name */ #define DPRC_RSP_GET_OBJ_REGION(cmd, region_desc) \ do { \ - MC_RSP_OP(cmd, 1, 0, 64, uint64_t, region_desc->base_paddr);\ + MC_RSP_OP(cmd, 1, 0, 64, uint64_t, region_desc->base_offset);\ MC_RSP_OP(cmd, 2, 0, 32, uint32_t, region_desc->size); \ } while (0) /* cmd, param, offset, width, type, arg_name */ +#define DPRC_CMD_SET_OBJ_LABEL(cmd, obj_index, label) \ +do { \ + MC_CMD_OP(cmd, 0, 0, 32, int, obj_index); \ + MC_CMD_OP(cmd, 1, 0, 8, char, label[0]);\ + MC_CMD_OP(cmd, 1, 8, 8, char, label[1]);\ + MC_CMD_OP(cmd, 1, 16, 8, char, label[2]);\ + MC_CMD_OP(cmd, 1, 24, 8, char, label[3]);\ + MC_CMD_OP(cmd, 1, 32, 8, char, label[4]);\ + MC_CMD_OP(cmd, 1, 40, 8, char, label[5]);\ + MC_CMD_OP(cmd, 1, 48, 8, char, label[6]);\ + MC_CMD_OP(cmd, 1, 56, 8, char, label[7]);\ + MC_CMD_OP(cmd, 2, 0, 8, char, label[8]);\ + MC_CMD_OP(cmd, 2, 8, 8, char, label[9]);\ + MC_CMD_OP(cmd, 2, 16, 8, char, label[10]);\ + MC_CMD_OP(cmd, 2, 24, 8, char, label[11]);\ + MC_CMD_OP(cmd, 2, 32, 8, char, label[12]);\ + MC_CMD_OP(cmd, 2, 40, 8, char, label[13]);\ + MC_CMD_OP(cmd, 2, 48, 8, char, label[14]);\ + MC_CMD_OP(cmd, 2, 56, 8, char, label[15]);\ +} while (0) + +/* cmd, param, offset, width, type, arg_name */ #define DPRC_CMD_CONNECT(cmd, endpoint1, endpoint2) \ do { \ MC_CMD_OP(cmd, 0, 0, 32, int, endpoint1->id); \ @@ -294,6 +332,7 @@ do { \ /* Data Path Resource Container API * Contains DPRC API for managing and querying DPAA resources */ + struct fsl_mc_io; /** @@ -366,7 +405,7 @@ int dprc_close(struct fsl_mc_io *mc_io, uint16_t token); /* Object initialization allowed - software context associated with this * container is allowed to invoke object initialization operations. */ -#define DPRC_CFG_OPT_OBJ_CREATE_ALLOWED 0x00000004 +#define DPRC_CFG_OPT_OBJ_CREATE_ALLOWED 0x00000004 /* Topology change allowed - software context associated with this * container is allowed to invoke topology operations, such as attach/detach @@ -389,11 +428,13 @@ int dprc_close(struct fsl_mc_io *mc_io, uint16_t token); * @portal_id: Portal ID; if set to 'DPRC_GET_PORTAL_ID_FROM_POOL', a free * portal ID is allocated by the DPRC * @options: Combination of 'DPRC_CFG_OPT_' options + * @label: Object's label */ struct dprc_cfg { uint16_t icid; int portal_id; uint64_t options; + char label[16]; }; /** @@ -484,6 +525,7 @@ int dprc_get_obj_count(struct fsl_mc_io *mc_io, uint16_t token, int *obj_count); * @irq_count: Number of interrupts supported by the object * @region_count: Number of mappable regions supported by the object * @state: Object state: combination of DPRC_OBJ_STATE_ states + * @label: Object label */ struct dprc_obj_desc { char type[16]; @@ -494,6 +536,7 @@ struct dprc_obj_desc { uint8_t irq_count; uint8_t region_count; uint32_t state; + char label[16]; }; /** @@ -516,8 +559,8 @@ int dprc_get_obj(struct fsl_mc_io *mc_io, struct dprc_obj_desc *obj_desc); /** - * dprc_get_res_count() - Obtains the number of free resources that are assigned - * to this container, by pool type + * dprc_get_res_count() - Obtains the number of free resources that are + * assigned to this container, by pool type * @mc_io: Pointer to MC portal's I/O object * @token: Token of DPRC object * @type: pool type @@ -574,11 +617,14 @@ int dprc_get_res_ids(struct fsl_mc_io *mc_io, /** * struct dprc_region_desc - Mappable region descriptor - * @base_paddr: Region base physical address + * @base_offset: Region offset from region's base address. + * For DPMCP and DPRC objects, region base is offset from SoC MC portals + * base address; For DPIO, region base is offset from SoC QMan portals + * base address * @size: Region size (in bytes) */ struct dprc_region_desc { - uint64_t base_paddr; + uint64_t base_offset; uint32_t size; }; @@ -642,8 +688,8 @@ int dprc_disconnect(struct fsl_mc_io *mc_io, /** * dprc_get_connection() - Get connected endpoint and link status if connection * exists. -* @mc_io Pointer to MC portal's I/O object -* @token Token of DPRC object +* @mc_io Pointer to MC portal's I/O object +* @token Token of DPRC object * @endpoint1 Endpoint 1 configuration parameters * @endpoint2 Returned endpoint 2 configuration parameters * @state: Returned link state: 1 - link is up, 0 - link is down diff --git a/include/fsl-mc/fsl_mc.h b/include/fsl-mc/fsl_mc.h index ec24415..0e799f5 100644 --- a/include/fsl-mc/fsl_mc.h +++ b/include/fsl-mc/fsl_mc.h @@ -27,6 +27,7 @@ (MCFAPR_PL_MASK | MCFAPR_BMT_MASK) #define SOC_MC_PORTALS_BASE_ADDR ((void __iomem *)0x00080C000000) +#define SOC_QBMAN_PORTALS_BASE_ADDR ((void __iomem *)0x000818000000) #define SOC_MC_PORTAL_STRIDE 0x10000 #define SOC_MC_PORTAL_ADDR(_portal_id) \ -- cgit v0.10.2 From cd8aefc076ebac3e01499a55fd0830144e854985 Mon Sep 17 00:00:00 2001 From: Prabhakar Kushwaha Date: Thu, 2 Jul 2015 11:29:00 +0530 Subject: drivers: fsl-mc: Update qbman driver Update qbman driver - As per latest available qbman driver - Use of atomic APIs Signed-off-by: Prabhakar Kushwaha CC: Geoff Thorpe CC: Haiying Wang CC: Roy Pledge Reviewed-by: York Sun diff --git a/drivers/net/fsl-mc/dpio/qbman_portal.c b/drivers/net/fsl-mc/dpio/qbman_portal.c index dd2a7de..5fa8d95 100644 --- a/drivers/net/fsl-mc/dpio/qbman_portal.c +++ b/drivers/net/fsl-mc/dpio/qbman_portal.c @@ -64,7 +64,7 @@ enum qbman_sdqcr_fc { struct qbman_swp *qbman_swp_init(const struct qbman_swp_desc *d) { int ret; - struct qbman_swp *p = kmalloc(sizeof(*p), GFP_KERNEL); + struct qbman_swp *p = malloc(sizeof(struct qbman_swp)); if (!p) return NULL; @@ -77,7 +77,7 @@ struct qbman_swp *qbman_swp_init(const struct qbman_swp_desc *d) qb_attr_code_encode(&code_sdqcr_dct, &p->sdq, qbman_sdqcr_dct_prio_ics); qb_attr_code_encode(&code_sdqcr_fc, &p->sdq, qbman_sdqcr_fc_up_to_3); qb_attr_code_encode(&code_sdqcr_tok, &p->sdq, 0xbb); - p->vdq.busy = 0; /* TODO: convert to atomic_t */ + atomic_set(&p->vdq.busy, 1); p->vdq.valid_bit = QB_VALID_BIT; p->dqrr.next_idx = 0; p->dqrr.valid_bit = QB_VALID_BIT; @@ -165,7 +165,6 @@ static struct qb_attr_code code_eq_qd_bin = QB_CODE(4, 0, 16); static struct qb_attr_code code_eq_qd_pri = QB_CODE(4, 16, 4); static struct qb_attr_code code_eq_rsp_stash = QB_CODE(5, 16, 1); static struct qb_attr_code code_eq_rsp_lo = QB_CODE(6, 0, 32); -static struct qb_attr_code code_eq_rsp_hi = QB_CODE(7, 0, 32); enum qbman_eq_cmd_e { /* No enqueue, primarily for plugging ORP gaps for dropped frames */ @@ -197,8 +196,7 @@ void qbman_eq_desc_set_response(struct qbman_eq_desc *d, { uint32_t *cl = qb_cl(d); - qb_attr_code_encode(&code_eq_rsp_lo, cl, lower32(storage_phys)); - qb_attr_code_encode(&code_eq_rsp_hi, cl, upper32(storage_phys)); + qb_attr_code_encode_64(&code_eq_rsp_lo, (uint64_t *)cl, storage_phys); qb_attr_code_encode(&code_eq_rsp_stash, cl, !!stash); } @@ -253,7 +251,6 @@ static struct qb_attr_code code_pull_numframes = QB_CODE(0, 8, 4); static struct qb_attr_code code_pull_token = QB_CODE(0, 16, 8); static struct qb_attr_code code_pull_dqsource = QB_CODE(1, 0, 24); static struct qb_attr_code code_pull_rsp_lo = QB_CODE(2, 0, 32); -static struct qb_attr_code code_pull_rsp_hi = QB_CODE(3, 0, 32); enum qb_pull_dt_e { qb_pull_dt_channel, @@ -282,8 +279,7 @@ void qbman_pull_desc_set_storage(struct qbman_pull_desc *d, } qb_attr_code_encode(&code_pull_rls, cl, 1); qb_attr_code_encode(&code_pull_stash, cl, !!stash); - qb_attr_code_encode(&code_pull_rsp_lo, cl, lower32(storage_phys)); - qb_attr_code_encode(&code_pull_rsp_hi, cl, upper32(storage_phys)); + qb_attr_code_encode_64(&code_pull_rsp_lo, (uint64_t *)cl, storage_phys); } void qbman_pull_desc_set_numframes(struct qbman_pull_desc *d, uint8_t numframes) @@ -316,10 +312,10 @@ int qbman_swp_pull(struct qbman_swp *s, struct qbman_pull_desc *d) uint32_t *p; uint32_t *cl = qb_cl(d); - /* TODO: convert to atomic_t */ - if (s->vdq.busy) + if (!atomic_dec_and_test(&s->vdq.busy)) { + atomic_inc(&s->vdq.busy); return -EBUSY; - s->vdq.busy = 1; + } s->vdq.storage = *(void **)&cl[4]; s->vdq.token = qb_attr_code_decode(&code_pull_token, cl); p = qbman_cena_write_start(&s->sys, QBMAN_CENA_SWP_VDQCR); @@ -359,36 +355,44 @@ const struct ldpaa_dq *qbman_swp_dqrr_next(struct qbman_swp *s) { uint32_t verb; uint32_t response_verb; - const struct ldpaa_dq *dq = qbman_cena_read(&s->sys, - QBMAN_CENA_SWP_DQRR(s->dqrr.next_idx)); - const uint32_t *p = qb_cl(dq); + uint32_t flags; + const struct ldpaa_dq *dq; + const uint32_t *p; + dq = qbman_cena_read(&s->sys, QBMAN_CENA_SWP_DQRR(s->dqrr.next_idx)); + p = qb_cl(dq); verb = qb_attr_code_decode(&code_dqrr_verb, p); - /* If the valid-bit isn't of the expected polarity, nothing there */ + + /* If the valid-bit isn't of the expected polarity, nothing there. Note, + * in the DQRR reset bug workaround, we shouldn't need to skip these + * check, because we've already determined that a new entry is available + * and we've invalidated the cacheline before reading it, so the + * valid-bit behaviour is repaired and should tell us what we already + * knew from reading PI. + */ if ((verb & QB_VALID_BIT) != s->dqrr.valid_bit) { qbman_cena_invalidate_prefetch(&s->sys, - QBMAN_CENA_SWP_DQRR( - s->dqrr.next_idx)); + QBMAN_CENA_SWP_DQRR(s->dqrr.next_idx)); return NULL; } /* There's something there. Move "next_idx" attention to the next ring * entry (and prefetch it) before returning what we found. */ s->dqrr.next_idx++; - s->dqrr.next_idx &= 3; /* Wrap around at 4 */ + s->dqrr.next_idx &= QBMAN_DQRR_SIZE - 1; /* Wrap around at 4 */ /* TODO: it's possible to do all this without conditionals, optimise it * later. */ if (!s->dqrr.next_idx) s->dqrr.valid_bit ^= QB_VALID_BIT; - /* VDQCR "no longer busy" hook - if VDQCR shows "busy" and this is a - * VDQCR result, mark it as non-busy. */ - if (s->vdq.busy) { - uint32_t flags = ldpaa_dq_flags(dq); - - response_verb = qb_attr_code_decode(&code_dqrr_response, &verb); - if ((response_verb == QBMAN_DQRR_RESPONSE_DQ) && - (flags & LDPAA_DQ_STAT_VOLATILE)) - s->vdq.busy = 0; - } + + /* If this is the final response to a volatile dequeue command + indicate that the vdq is no longer busy */ + flags = ldpaa_dq_flags(dq); + response_verb = qb_attr_code_decode(&code_dqrr_response, &verb); + if ((response_verb == QBMAN_DQRR_RESPONSE_DQ) && + (flags & LDPAA_DQ_STAT_VOLATILE) && + (flags & LDPAA_DQ_STAT_EXPIRED)) + atomic_inc(&s->vdq.busy); + qbman_cena_invalidate_prefetch(&s->sys, QBMAN_CENA_SWP_DQRR(s->dqrr.next_idx)); return dq; @@ -448,8 +452,10 @@ int qbman_dq_entry_has_newtoken(struct qbman_swp *s, * reset "busy". We instead base the decision on whether the current * result is sitting at the first 'storage' location of the busy * command. */ - if (s->vdq.busy && (s->vdq.storage == dq)) - s->vdq.busy = 0; + if (s->vdq.storage == dq) { + s->vdq.storage = NULL; + atomic_inc(&s->vdq.busy); + } return 1; } diff --git a/drivers/net/fsl-mc/dpio/qbman_portal.h b/drivers/net/fsl-mc/dpio/qbman_portal.h index bb67c3b..86e2c3a 100644 --- a/drivers/net/fsl-mc/dpio/qbman_portal.h +++ b/drivers/net/fsl-mc/dpio/qbman_portal.h @@ -14,6 +14,10 @@ /* Management command result codes */ #define QBMAN_MC_RSLT_OK 0xf0 +/* TBD: as of QBMan 4.1, DQRR will be 8 rather than 4! */ +#define QBMAN_DQRR_SIZE 4 + + /* --------------------- */ /* portal data structure */ /* --------------------- */ @@ -48,14 +52,13 @@ struct qbman_swp { * to whether or not a command can be submitted, not whether or * not a previously-submitted command is still executing. In * other words, once proof is seen that the previously-submitted - * command is executing, "vdq" is no longer "busy". TODO: - * convert this to "atomic_t" so that it is thread-safe (without - * locking). */ - int busy; + * command is executing, "vdq" is no longer "busy". + */ + atomic_t busy; uint32_t valid_bit; /* 0x00 or 0x80 */ /* We need to determine when vdq is no longer busy. This depends * on whether the "busy" (last-submitted) dequeue command is - * targetting DQRR or main-memory, and detected is based on the + * targeting DQRR or main-memory, and detected is based on the * presence of the dequeue command's "token" showing up in * dequeue entries in DQRR or main-memory (respectively). Debug * builds will, when submitting vdq commands, verify that the @@ -127,6 +130,7 @@ static inline uint32_t qb_attr_code_decode(const struct qb_attr_code *code, return d32_uint32_t(code->lsoffset, code->width, cacheline[code->word]); } + /* encode a field to a cacheline */ static inline void qb_attr_code_encode(const struct qb_attr_code *code, uint32_t *cacheline, uint32_t val) @@ -136,6 +140,12 @@ static inline void qb_attr_code_encode(const struct qb_attr_code *code, | e32_uint32_t(code->lsoffset, code->width, val); } +static inline void qb_attr_code_encode_64(const struct qb_attr_code *code, + uint64_t *cacheline, uint64_t val) +{ + cacheline[code->word / 2] = val; +} + /* ---------------------- */ /* Descriptors/cachelines */ /* ---------------------- */ @@ -144,7 +154,7 @@ static inline void qb_attr_code_encode(const struct qb_attr_code *code, * a "descriptor" type that the caller can instantiate however they like. * Ultimately though, it is just a cacheline of binary storage (or something * smaller when it is known that the descriptor doesn't need all 64 bytes) for - * holding pre-formatted pieces of harware commands. The performance-critical + * holding pre-formatted pieces of hardware commands. The performance-critical * code can then copy these descriptors directly into hardware command * registers more efficiently than trying to construct/format commands * on-the-fly. The API user sees the descriptor as an array of 32-bit words in diff --git a/drivers/net/fsl-mc/dpio/qbman_private.h b/drivers/net/fsl-mc/dpio/qbman_private.h index 2d2556b..f1f16b8 100644 --- a/drivers/net/fsl-mc/dpio/qbman_private.h +++ b/drivers/net/fsl-mc/dpio/qbman_private.h @@ -9,7 +9,7 @@ #include #include #include -#include +#include #include #include -- cgit v0.10.2 From 2b7c4a19835dab608bbd8662a60b03aa0f37a423 Mon Sep 17 00:00:00 2001 From: Prabhakar Kushwaha Date: Thu, 2 Jul 2015 11:29:01 +0530 Subject: drivers: fsl-mc: Return error for major version mismatch Management complex major version should match to the firmware present in flash. Return error during mismatch of major version. Signed-off-by: Prabhakar Kushwaha Acked-by: Joe Hershberger Reviewed-by: York Sun diff --git a/drivers/net/fsl-mc/mc.c b/drivers/net/fsl-mc/mc.c index 2094595..b2babfb 100644 --- a/drivers/net/fsl-mc/mc.c +++ b/drivers/net/fsl-mc/mc.c @@ -518,9 +518,14 @@ int mc_init(void) goto out; } - if (MC_VER_MAJOR != mc_ver_info.major) + if (MC_VER_MAJOR != mc_ver_info.major) { printf("fsl-mc: ERROR: Firmware major version mismatch (found: %d, expected: %d)\n", mc_ver_info.major, MC_VER_MAJOR); + printf("fsl-mc: Update the Management Complex firmware\n"); + + error = -ENODEV; + goto out; + } if (MC_VER_MINOR != mc_ver_info.minor) printf("fsl-mc: WARNING: Firmware minor version mismatch (found: %d, expected: %d)\n", @@ -541,7 +546,7 @@ int mc_init(void) out: if (error != 0) - mc_boot_status = -error; + mc_boot_status = error; else mc_boot_status = 0; -- cgit v0.10.2 From 39da644ea86beb8786c09bd536a184a8642c9e10 Mon Sep 17 00:00:00 2001 From: Stuart Yoder Date: Thu, 2 Jul 2015 11:29:02 +0530 Subject: armv8/fsl-lsch3: partition stream IDs Stream IDs on ls2085a devices are not hardwired and are programmed by sw. There are a limited number of stream IDs available, and the partitioning of them is scenario dependent. This header defines the partitioning between legacy, PCI, and DPAA2 devices. Signed-off-by: Stuart Yoder Signed-off-by: Prabhakar Kushwaha Reviewed-by: York Sun diff --git a/arch/arm/include/asm/arch-fsl-lsch3/ls2085a_stream_id.h b/arch/arm/include/asm/arch-fsl-lsch3/ls2085a_stream_id.h new file mode 100644 index 0000000..5c94530 --- /dev/null +++ b/arch/arm/include/asm/arch-fsl-lsch3/ls2085a_stream_id.h @@ -0,0 +1,64 @@ +/* + * Copyright 2014 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + * + */ +#ifndef __FSL_STREAM_ID_H +#define __FSL_STREAM_ID_H + +/* Stream IDs on ls2085a devices are not hardwired and are + * programmed by sw. There are a limited number of stream IDs + * available, and the partitioning of them is scenario dependent. + * This header defines the partitioning between legacy, PCI, + * and DPAA2 devices. + * + * This partitiong can be customized in this file depending + * on the specific hardware config-- e.g. perhaps not all + * PEX controllers are in use. + * + * On LS2085 stream IDs are programmed in AMQ registers (32-bits) for + * each of the different bus masters. The relationship between + * the AMQ registers and stream IDs is defined in the table below: + * AMQ bit streamID bit + * --------------------------- + * PL[18] 9 + * BMT[17] 8 + * VA[16] 7 + * [15] - + * ICID[14:7] - + * ICID[6:0] 6-0 + * ---------------------------- + */ + +#define AMQ_PL_MASK (0x1 << 18) /* priviledge bit */ +#define AMQ_BMT_MASK (0x1 << 17) /* bypass bit */ + +#define FSL_INVALID_STREAM_ID 0 + +#define FSL_BYPASS_AMQ (AMQ_PL_MASK | AMQ_BMT_MASK) + +/* legacy devices */ +#define FSL_USB1_STREAM_ID 1 +#define FSL_USB2_STREAM_ID 2 +#define FSL_SDMMC_STREAM_ID 3 +#define FSL_SATA1_STREAM_ID 4 +#define FSL_SATA2_STREAM_ID 5 +#define FSL_DMA_STREAM_ID 6 + +/* PCI - programmed in PEXn_LUT by OS */ +/* 4 IDs per controller */ +#define FSL_PEX1_STREAM_ID_START 7 +#define FSL_PEX1_STREAM_ID_END 10 +#define FSL_PEX2_STREAM_ID_START 11 +#define FSL_PEX2_STREAM_ID_END 14 +#define FSL_PEX3_STREAM_ID_START 15 +#define FSL_PEX3_STREAM_ID_END 18 +#define FSL_PEX4_STREAM_ID_START 19 +#define FSL_PEX4_STREAM_ID_END 22 + +/* DPAA2 - set in MC DPC and alloced by MC */ +#define FSL_DPAA2_STREAM_ID_START 23 +#define FSL_DPAA2_STREAM_ID_END 63 + +#endif diff --git a/drivers/net/fsl-mc/mc.c b/drivers/net/fsl-mc/mc.c index b2babfb..8e26fa4 100644 --- a/drivers/net/fsl-mc/mc.c +++ b/drivers/net/fsl-mc/mc.c @@ -474,7 +474,7 @@ int mc_init(void) out_le32(&mc_ccsr_regs->reg_mcfbalr, reg_mcfbalr); out_le32(&mc_ccsr_regs->reg_mcfbahr, (u32)(mc_ram_aligned_base_addr >> 32)); - out_le32(&mc_ccsr_regs->reg_mcfapr, MCFAPR_BYPASS_ICID_MASK); + out_le32(&mc_ccsr_regs->reg_mcfapr, FSL_BYPASS_AMQ); /* * Tell the MC that we want delayed DPL deployment. diff --git a/include/configs/ls2085a_common.h b/include/configs/ls2085a_common.h index 951410d..60e5532 100644 --- a/include/configs/ls2085a_common.h +++ b/include/configs/ls2085a_common.h @@ -19,6 +19,7 @@ #define CONFIG_ARM_ERRATA_828024 #define CONFIG_ARM_ERRATA_826974 +#include #include #if (defined(CONFIG_SYS_FSL_SRDS_1) || defined(CONFIG_SYS_FSL_SRDS_2)) #define CONFIG_SYS_HAS_SERDES diff --git a/include/fsl-mc/fsl_mc.h b/include/fsl-mc/fsl_mc.h index 0e799f5..9106f25 100644 --- a/include/fsl-mc/fsl_mc.h +++ b/include/fsl-mc/fsl_mc.h @@ -21,10 +21,6 @@ #define GCR1_M2_DE_RST BIT(14) #define GCR1_M_ALL_DE_RST (GCR1_M1_DE_RST | GCR1_M2_DE_RST) #define GSR_FS_MASK 0x3fffffff -#define MCFAPR_PL_MASK (0x1 << 18) -#define MCFAPR_BMT_MASK (0x1 << 17) -#define MCFAPR_BYPASS_ICID_MASK \ - (MCFAPR_PL_MASK | MCFAPR_BMT_MASK) #define SOC_MC_PORTALS_BASE_ADDR ((void __iomem *)0x00080C000000) #define SOC_QBMAN_PORTALS_BASE_ADDR ((void __iomem *)0x000818000000) -- cgit v0.10.2 From 21c69870679d6a99d5d5b73471bb0330fc75e1af Mon Sep 17 00:00:00 2001 From: Stuart Yoder Date: Thu, 2 Jul 2015 11:29:03 +0530 Subject: drivers/fsl-mc: dynamically create ICID pool in DPC delete any existing ICID pools in the DPC and create a new one based on the stream ID partitioning for the SoC Signed-off-by: Stuart Yoder Signed-off-by: Prabhakar Kushwaha Reviewed-by: York Sun diff --git a/drivers/net/fsl-mc/mc.c b/drivers/net/fsl-mc/mc.c index 8e26fa4..62a68c2 100644 --- a/drivers/net/fsl-mc/mc.c +++ b/drivers/net/fsl-mc/mc.c @@ -3,8 +3,11 @@ * * SPDX-License-Identifier: GPL-2.0+ */ +#include #include #include +#include +#include #include #include #include @@ -185,6 +188,36 @@ static int calculate_mc_private_ram_params(u64 mc_private_ram_start_addr, return 0; } +static int mc_fixup_dpc(u64 dpc_addr) +{ + void *blob = (void *)dpc_addr; + int nodeoffset; + + /* delete any existing ICID pools */ + nodeoffset = fdt_path_offset(blob, "/resources/icid_pools"); + if (fdt_del_node(blob, nodeoffset) < 0) + printf("\nfsl-mc: WARNING: could not delete ICID pool\n"); + + /* add a new pool */ + nodeoffset = fdt_path_offset(blob, "/resources"); + if (nodeoffset < 0) { + printf("\nfsl-mc: ERROR: DPC is missing /resources\n"); + return -EINVAL; + } + nodeoffset = fdt_add_subnode(blob, nodeoffset, "icid_pools"); + nodeoffset = fdt_add_subnode(blob, nodeoffset, "icid_pool@0"); + do_fixup_by_path_u32(blob, "/resources/icid_pools/icid_pool@0", + "base_icid", FSL_DPAA2_STREAM_ID_START, 1); + do_fixup_by_path_u32(blob, "/resources/icid_pools/icid_pool@0", + "num", + FSL_DPAA2_STREAM_ID_END - + FSL_DPAA2_STREAM_ID_START + 1, 1); + + flush_dcache_range(dpc_addr, dpc_addr + fdt_totalsize(blob)); + + return 0; +} + static int load_mc_dpc(u64 mc_ram_addr, size_t mc_ram_size) { u64 mc_dpc_offset; @@ -239,6 +272,9 @@ static int load_mc_dpc(u64 mc_ram_addr, size_t mc_ram_size) (u64)dpc_fdt_hdr, dpc_size, mc_ram_addr + mc_dpc_offset); #endif /* not defined CONFIG_SYS_LS_MC_DPC_IN_DDR */ + if (mc_fixup_dpc(mc_ram_addr + mc_dpc_offset)) + return -EINVAL; + dump_ram_words("DPC", (void *)(mc_ram_addr + mc_dpc_offset)); return 0; } -- cgit v0.10.2 From 70e52d211533c45f0d26c4d87cbeee31560fbe04 Mon Sep 17 00:00:00 2001 From: Stuart Yoder Date: Thu, 2 Jul 2015 11:29:04 +0530 Subject: armv8/fsl-lsch3: device tree fixups for PCI stream IDs This patch adds the infrastructure to update device tree nodes to convey SMMU stream IDs in the device tree. Fixups are implemented for PCI controllers initially. Signed-off-by: Stuart Yoder Signed-off-by: Prabhakar Kushwaha Reviewed-by: York Sun diff --git a/arch/arm/cpu/armv8/fsl-lsch3/fdt.c b/arch/arm/cpu/armv8/fsl-lsch3/fdt.c index b9fd559..567c419 100644 --- a/arch/arm/cpu/armv8/fsl-lsch3/fdt.c +++ b/arch/arm/cpu/armv8/fsl-lsch3/fdt.c @@ -7,6 +7,7 @@ #include #include #include +#include #ifdef CONFIG_FSL_ESDHC #include #endif @@ -58,6 +59,113 @@ void ft_fixup_cpu(void *blob) } #endif +/* + * the burden is on the the caller to not request a count + * exceeding the bounds of the stream_ids[] array + */ +void alloc_stream_ids(int start_id, int count, u32 *stream_ids, int max_cnt) +{ + int i; + + if (count > max_cnt) { + printf("\n%s: ERROR: max per-device stream ID count exceed\n", + __func__); + return; + } + + for (i = 0; i < count; i++) + stream_ids[i] = start_id++; +} + +/* + * This function updates the mmu-masters property on the SMMU + * node as per the SMMU binding-- phandle and list of stream IDs + * for each MMU master. + */ +void append_mmu_masters(void *blob, const char *smmu_path, + const char *master_name, u32 *stream_ids, int count) +{ + u32 phandle; + int smmu_nodeoffset; + int master_nodeoffset; + int i; + + /* get phandle of mmu master device */ + master_nodeoffset = fdt_path_offset(blob, master_name); + if (master_nodeoffset < 0) { + printf("\n%s: ERROR: master not found\n", __func__); + return; + } + phandle = fdt_get_phandle(blob, master_nodeoffset); + if (!phandle) { /* if master has no phandle, create one */ + phandle = fdt_create_phandle(blob, master_nodeoffset); + if (!phandle) { + printf("\n%s: ERROR: unable to create phandle\n", + __func__); + return; + } + } + + /* append it to mmu-masters */ + smmu_nodeoffset = fdt_path_offset(blob, smmu_path); + if (fdt_appendprop_u32(blob, smmu_nodeoffset, "mmu-masters", + phandle) < 0) { + printf("\n%s: ERROR: unable to update SMMU node\n", __func__); + return; + } + + /* for each stream ID, append to mmu-masters */ + for (i = 0; i < count; i++) { + fdt_appendprop_u32(blob, smmu_nodeoffset, "mmu-masters", + stream_ids[i]); + } + + /* fix up #stream-id-cells with stream ID count */ + if (fdt_setprop_u32(blob, master_nodeoffset, "#stream-id-cells", + count) < 0) + printf("\n%s: ERROR: unable to update #stream-id-cells\n", + __func__); +} + + +/* + * The info below summarizes how streamID partitioning works + * for ls2085a and how it is conveyed to the OS via the device tree. + * + * -non-PCI legacy, platform devices (USB, SD/MMC, SATA, DMA) + * -all legacy devices get a unique ICID assigned and programmed in + * their AMQR registers by u-boot + * -u-boot updates the hardware device tree with streamID properties + * for each platform/legacy device (smmu-masters property) + * + * -PCIe + * -for each PCI controller that is active (as per RCW settings), + * u-boot will allocate a range of ICID and convey that to Linux via + * the device tree (smmu-masters property) + * + * -DPAA2 + * -u-boot will allocate a range of ICIDs to be used by the Management + * Complex for containers and will set these values in the MC DPC image. + * -the MC is responsible for allocating and setting up ICIDs + * for all DPAA2 devices. + * + */ +static void fdt_fixup_smmu(void *blob) +{ + int nodeoffset; + + nodeoffset = fdt_path_offset(blob, "/iommu@5000000"); + if (nodeoffset < 0) { + printf("\n%s: WARNING: no SMMU node found\n", __func__); + return; + } + + /* fixup for all PCI controllers */ +#ifdef CONFIG_PCI + fdt_fixup_smmu_pcie(blob); +#endif +} + void ft_cpu_setup(void *blob, bd_t *bd) { #ifdef CONFIG_MP @@ -76,4 +184,6 @@ void ft_cpu_setup(void *blob, bd_t *bd) #if defined(CONFIG_FSL_ESDHC) fdt_fixup_esdhc(blob, bd); #endif + + fdt_fixup_smmu(blob); } diff --git a/arch/arm/include/asm/arch-fsl-lsch3/fdt.h b/arch/arm/include/asm/arch-fsl-lsch3/fdt.h new file mode 100644 index 0000000..21d20fb --- /dev/null +++ b/arch/arm/include/asm/arch-fsl-lsch3/fdt.h @@ -0,0 +1,10 @@ +/* + * Copyright 2015 Freescale Semiconductor + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +void alloc_stream_ids(int start_id, int count, u32 *stream_ids, int max_cnt); +void append_mmu_masters(void *blob, const char *smmu_path, + const char *master_name, u32 *stream_ids, int count); +void fdt_fixup_smmu_pcie(void *blob); diff --git a/drivers/pci/pcie_layerscape.c b/drivers/pci/pcie_layerscape.c index 402c519..3ef4975 100644 --- a/drivers/pci/pcie_layerscape.c +++ b/drivers/pci/pcie_layerscape.c @@ -11,6 +11,7 @@ #include #include #include +#include #ifndef CONFIG_SYS_PCI_MEMORY_BUS #define CONFIG_SYS_PCI_MEMORY_BUS CONFIG_SYS_SDRAM_BASE @@ -528,3 +529,64 @@ void ft_pci_setup(void *blob, bd_t *bd) { } #endif + +#ifdef CONFIG_LS2085A + +void pcie_set_available_streamids(void *blob, const char *pcie_path, + u32 *stream_ids, int count) +{ + int nodeoffset; + int i; + + nodeoffset = fdt_path_offset(blob, pcie_path); + if (nodeoffset < 0) { + printf("\n%s: ERROR: unable to update PCIe node\n", __func__); + return; + } + + /* for each stream ID, append to mmu-masters */ + for (i = 0; i < count; i++) { + fdt_appendprop_u32(blob, nodeoffset, "available-stream-ids", + stream_ids[i]); + } +} + +#define MAX_STREAM_IDS 4 +void fdt_fixup_smmu_pcie(void *blob) +{ + int count; + u32 stream_ids[MAX_STREAM_IDS]; + + #ifdef CONFIG_PCIE1 + /* PEX1 stream ID fixup */ + count = FSL_PEX1_STREAM_ID_END - FSL_PEX1_STREAM_ID_START + 1; + alloc_stream_ids(FSL_PEX1_STREAM_ID_START, count, stream_ids, + MAX_STREAM_IDS); + pcie_set_available_streamids(blob, "/pcie@3400000", stream_ids, count); + #endif + + #ifdef CONFIG_PCIE2 + /* PEX2 stream ID fixup */ + count = FSL_PEX2_STREAM_ID_END - FSL_PEX2_STREAM_ID_START + 1; + alloc_stream_ids(FSL_PEX2_STREAM_ID_START, count, stream_ids, + MAX_STREAM_IDS); + pcie_set_available_streamids(blob, "/pcie@3500000", stream_ids, count); + #endif + + #ifdef CONFIG_PCIE3 + /* PEX3 stream ID fixup */ + count = FSL_PEX3_STREAM_ID_END - FSL_PEX3_STREAM_ID_START + 1; + alloc_stream_ids(FSL_PEX3_STREAM_ID_START, count, stream_ids, + MAX_STREAM_IDS); + pcie_set_available_streamids(blob, "/pcie@3600000", stream_ids, count); + #endif + + #ifdef CONFIG_PCIE4 + /* PEX4 stream ID fixup */ + count = FSL_PEX4_STREAM_ID_END - FSL_PEX4_STREAM_ID_START + 1; + alloc_stream_ids(FSL_PEX4_STREAM_ID_START, count, stream_ids, + MAX_STREAM_IDS); + pcie_set_available_streamids(blob, "/pcie@3700000", stream_ids, count); + #endif +} +#endif -- cgit v0.10.2 From e48df52b69069dac7f00841fc89701604c5f1bef Mon Sep 17 00:00:00 2001 From: Prabhakar Kushwaha Date: Thu, 2 Jul 2015 11:29:05 +0530 Subject: driver/ldpaa_eth: Retry enqueue if portal was busy Do not immediately return if the enqueue function returns -EBUSY; re-try mulitple times. if timeout occures, release the buffer. Signed-off-by: Prabhakar Kushwaha Acked-by: Joe Hershberger Reviewed-by: York Sun diff --git a/drivers/net/ldpaa_eth/ldpaa_eth.c b/drivers/net/ldpaa_eth/ldpaa_eth.c index 5636511..82c0ce7 100644 --- a/drivers/net/ldpaa_eth/ldpaa_eth.c +++ b/drivers/net/ldpaa_eth/ldpaa_eth.c @@ -221,8 +221,11 @@ static int ldpaa_eth_tx(struct eth_device *net_dev, void *buf, int len) struct dpaa_fd fd; u64 buffer_start; int data_offset, err; + u32 timeo = (CONFIG_SYS_HZ * 10) / 1000; + u32 time_start; struct qbman_swp *swp = dflt_dpio->sw_portal; struct qbman_eq_desc ed; + struct qbman_release_desc releasedesc; /* Setup the FD fields */ memset(&fd, 0, sizeof(fd)); @@ -258,9 +261,20 @@ static int ldpaa_eth_tx(struct eth_device *net_dev, void *buf, int len) qbman_eq_desc_clear(&ed); qbman_eq_desc_set_no_orp(&ed, 0); qbman_eq_desc_set_qd(&ed, priv->tx_qdid, priv->tx_flow_id, 0); - err = qbman_swp_enqueue(swp, &ed, (const struct qbman_fd *)(&fd)); - if (err < 0) + + time_start = get_timer(0); + + while (get_timer(time_start) < timeo) { + err = qbman_swp_enqueue(swp, &ed, + (const struct qbman_fd *)(&fd)); + if (err != -EBUSY) + break; + } + + if (err < 0) { printf("error enqueueing Tx frame\n"); + goto error; + } mdelay(1); @@ -269,6 +283,20 @@ static int ldpaa_eth_tx(struct eth_device *net_dev, void *buf, int len) printf("error Tx Conf frame\n"); return err; + +error: + qbman_release_desc_clear(&releasedesc); + qbman_release_desc_set_bpid(&releasedesc, dflt_dpbp->dpbp_attr.bpid); + time_start = get_timer(0); + do { + /* Release buffer into the QBMAN */ + err = qbman_swp_release(swp, &releasedesc, &buffer_start, 1); + } while (get_timer(time_start) < timeo && err == -EBUSY); + + if (err == -EBUSY) + printf("TX data: QBMAN buffer release fails\n"); + + return err; } static int ldpaa_eth_open(struct eth_device *net_dev, bd_t *bd) -- cgit v0.10.2 From b4c3a35dc07380e931f6a0bd49332703769352b5 Mon Sep 17 00:00:00 2001 From: Prabhakar Kushwaha Date: Thu, 2 Jul 2015 11:29:06 +0530 Subject: driver/ldpaa_eth: Add timeout handling DQRR entry read Volatile command does not return frame immidiately, need to wait till a frame is available in DQRR. Ideally it should be a blocking call. Add timeout handling for DQRR frame instead of retry counter. Signed-off-by: Prabhakar Kushwaha Acked-by: Joe Hershberger Reviewed-by: York Sun diff --git a/drivers/net/ldpaa_eth/ldpaa_eth.c b/drivers/net/ldpaa_eth/ldpaa_eth.c index 82c0ce7..cc949f5 100644 --- a/drivers/net/ldpaa_eth/ldpaa_eth.c +++ b/drivers/net/ldpaa_eth/ldpaa_eth.c @@ -77,7 +77,9 @@ static int ldpaa_eth_pull_dequeue_rx(struct eth_device *dev) struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)dev->priv; const struct ldpaa_dq *dq; const struct dpaa_fd *fd; - int i = 5, err = 0, status, loop = 20; + int i = 5, err = 0, status; + u32 timeo = (CONFIG_SYS_HZ * 2) / 1000; + u32 time_start; static struct qbman_pull_desc pulldesc; struct qbman_swp *swp = dflt_dpio->sw_portal; @@ -92,13 +94,11 @@ static int ldpaa_eth_pull_dequeue_rx(struct eth_device *dev) continue; } - do { - loop--; - dq = qbman_swp_dqrr_next(swp); + time_start = get_timer(0); - if (!loop) - break; - } while (!dq); + do { + dq = qbman_swp_dqrr_next(swp); + } while (get_timer(time_start) < timeo && !dq); if (dq) { /* Check for valid frame. If not sent a consume @@ -121,6 +121,10 @@ static int ldpaa_eth_pull_dequeue_rx(struct eth_device *dev) ldpaa_eth_rx(priv, fd); qbman_swp_dqrr_consume(swp, dq); break; + } else { + err = -ENODATA; + debug("No DQRR entries\n"); + break; } } @@ -167,7 +171,9 @@ static int ldpaa_eth_pull_dequeue_tx_conf(struct ldpaa_eth_priv *priv) const struct ldpaa_dq *dq; const struct dpaa_fd *fd; int err = 0; - int i = 5, status, loop = 20; + int i = 5, status; + u32 timeo = (CONFIG_SYS_HZ * 10) / 1000; + u32 time_start; static struct qbman_pull_desc pulldesc; struct qbman_swp *swp = dflt_dpio->sw_portal; @@ -182,13 +188,11 @@ static int ldpaa_eth_pull_dequeue_tx_conf(struct ldpaa_eth_priv *priv) continue; } - do { - loop--; - dq = qbman_swp_dqrr_next(swp); + time_start = get_timer(0); - if (!loop) - break; - } while (!dq); + do { + dq = qbman_swp_dqrr_next(swp); + } while (get_timer(time_start) < timeo && !dq); if (dq) { /* Check for valid frame. If not sent a consume @@ -209,6 +213,10 @@ static int ldpaa_eth_pull_dequeue_tx_conf(struct ldpaa_eth_priv *priv) ldpaa_eth_tx_conf(priv, fd); qbman_swp_dqrr_consume(swp, dq); break; + } else { + err = -ENODATA; + debug("No DQRR entries\n"); + break; } } -- cgit v0.10.2 From 0c7c87a4ac3bb532f785fb6a19f68dcc2a588d1c Mon Sep 17 00:00:00 2001 From: Prabhakar Kushwaha Date: Thu, 2 Jul 2015 11:29:07 +0530 Subject: driver/ldpaa_eth: Avoid TX conf frames Polling of TX conf frames is not a mandatory option. Packets can be transferred via WRIOP without TX conf frame. Configure ldpaa_eth driver to use TX path without confirmation frame Signed-off-by: Prabhakar Kushwaha Acked-by: Joe Hershberger Reviewed-by: York Sun diff --git a/drivers/net/ldpaa_eth/ldpaa_eth.c b/drivers/net/ldpaa_eth/ldpaa_eth.c index cc949f5..6de5f30 100644 --- a/drivers/net/ldpaa_eth/ldpaa_eth.c +++ b/drivers/net/ldpaa_eth/ldpaa_eth.c @@ -112,7 +112,7 @@ static int ldpaa_eth_pull_dequeue_rx(struct eth_device *dev) debug("No frame delivered\n"); qbman_swp_dqrr_consume(swp, dq); - break; + continue; } fd = ldpaa_dq_fd(dq); @@ -131,98 +131,6 @@ static int ldpaa_eth_pull_dequeue_rx(struct eth_device *dev) return err; } -static void ldpaa_eth_tx_conf(struct ldpaa_eth_priv *priv, - const struct dpaa_fd *fd) -{ - uint64_t fd_addr; - struct ldpaa_fas *fas; - uint32_t status, err; - struct qbman_release_desc releasedesc; - struct qbman_swp *swp = dflt_dpio->sw_portal; - - fd_addr = ldpaa_fd_get_addr(fd); - - - debug("TX Conf frame:data addr=0x%p\n", (u64 *)fd_addr); - - /* Check the status from the Frame Annotation */ - if (fd->simple.frc & LDPAA_FD_FRC_FASV) { - fas = (struct ldpaa_fas *) - ((uint8_t *)(fd_addr) + - priv->buf_layout.private_data_size); - status = le32_to_cpu(fas->status); - if (status & LDPAA_ETH_TXCONF_ERR_MASK) { - printf("TxConf frame error(s): 0x%08x\n", - status & LDPAA_ETH_TXCONF_ERR_MASK); - } - } - - flush_dcache_range(fd_addr, fd_addr + LDPAA_ETH_RX_BUFFER_SIZE); - qbman_release_desc_clear(&releasedesc); - qbman_release_desc_set_bpid(&releasedesc, dflt_dpbp->dpbp_attr.bpid); - do { - /* Release buffer into the QBMAN */ - err = qbman_swp_release(swp, &releasedesc, &fd_addr, 1); - } while (err == -EBUSY); -} - -static int ldpaa_eth_pull_dequeue_tx_conf(struct ldpaa_eth_priv *priv) -{ - const struct ldpaa_dq *dq; - const struct dpaa_fd *fd; - int err = 0; - int i = 5, status; - u32 timeo = (CONFIG_SYS_HZ * 10) / 1000; - u32 time_start; - static struct qbman_pull_desc pulldesc; - struct qbman_swp *swp = dflt_dpio->sw_portal; - - while (--i) { - qbman_pull_desc_clear(&pulldesc); - qbman_pull_desc_set_numframes(&pulldesc, 1); - qbman_pull_desc_set_fq(&pulldesc, priv->tx_conf_fqid); - - err = qbman_swp_pull(swp, &pulldesc); - if (err < 0) { - printf("Dequeue TX conf frames error:0x%08x\n", err); - continue; - } - - time_start = get_timer(0); - - do { - dq = qbman_swp_dqrr_next(swp); - } while (get_timer(time_start) < timeo && !dq); - - if (dq) { - /* Check for valid frame. If not sent a consume - * confirmation to QBMAN otherwise give it to NADK - * application and then send consume confirmation to - * QBMAN. - */ - status = (uint8_t)ldpaa_dq_flags(dq); - if ((status & LDPAA_DQ_STAT_VALIDFRAME) == 0) { - debug("Dequeue TX conf frames:"); - debug("No frame is delivered\n"); - - qbman_swp_dqrr_consume(swp, dq); - break; - } - fd = ldpaa_dq_fd(dq); - - ldpaa_eth_tx_conf(priv, fd); - qbman_swp_dqrr_consume(swp, dq); - break; - } else { - err = -ENODATA; - debug("No DQRR entries\n"); - break; - } - } - - return err; -} - static int ldpaa_eth_tx(struct eth_device *net_dev, void *buf, int len) { struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv; @@ -284,12 +192,6 @@ static int ldpaa_eth_tx(struct eth_device *net_dev, void *buf, int len) goto error; } - mdelay(1); - - err = ldpaa_eth_pull_dequeue_tx_conf(priv); - if (err < 0) - printf("error Tx Conf frame\n"); - return err; error: @@ -311,7 +213,6 @@ static int ldpaa_eth_open(struct eth_device *net_dev, bd_t *bd) { struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv; struct dpni_queue_attr rx_queue_attr; - struct dpni_tx_flow_attr tx_flow_attr; uint8_t mac_addr[6]; int err; @@ -382,21 +283,11 @@ static int ldpaa_eth_open(struct eth_device *net_dev, bd_t *bd) goto err_qdid; } - err = dpni_get_tx_flow(dflt_mc_io, priv->dpni_handle, priv->tx_flow_id, - &tx_flow_attr); - if (err) { - printf("dpni_get_tx_flow() failed\n"); - goto err_tx_flow; - } - - priv->tx_conf_fqid = tx_flow_attr.conf_err_attr.queue_attr.fqid; - if (!priv->phydev->link) printf("%s: No link.\n", priv->phydev->dev->name); return priv->phydev->link ? 0 : -1; -err_tx_flow: err_qdid: err_rx_flow: dpni_disable(dflt_mc_io, priv->dpni_handle); @@ -663,6 +554,9 @@ static int ldpaa_dpni_bind(struct ldpaa_eth_priv *priv) priv->tx_flow_id = DPNI_NEW_FLOW_ID; memset(&dflt_tx_flow, 0, sizeof(dflt_tx_flow)); + dflt_tx_flow.options = DPNI_TX_FLOW_OPT_ONLY_TX_ERROR; + dflt_tx_flow.conf_err_cfg.use_default_queue = 0; + dflt_tx_flow.conf_err_cfg.errors_only = 1; err = dpni_set_tx_flow(dflt_mc_io, priv->dpni_handle, &priv->tx_flow_id, &dflt_tx_flow); if (err) { diff --git a/drivers/net/ldpaa_eth/ldpaa_eth.h b/drivers/net/ldpaa_eth/ldpaa_eth.h index 3107ab6..b4ef700 100644 --- a/drivers/net/ldpaa_eth/ldpaa_eth.h +++ b/drivers/net/ldpaa_eth/ldpaa_eth.h @@ -128,7 +128,6 @@ struct ldpaa_eth_priv { uint32_t rx_dflt_fqid; uint16_t tx_qdid; - uint32_t tx_conf_fqid; uint16_t tx_flow_id; enum ldpaa_eth_type type; /* 1G or 10G ethernet */ -- cgit v0.10.2 From 56c57cf7e9bc760d6d02b50f8d0b384fbb58d0fb Mon Sep 17 00:00:00 2001 From: Prabhakar Kushwaha Date: Thu, 2 Jul 2015 11:29:08 +0530 Subject: driver/ldpaa_eth:Avoid infinite loop in ldpaa_eth_rx Change infinite loop mechanism to timer based polling for QBMAN release in ldpaa_eth_rx. Signed-off-by: Prabhakar Kushwaha Reviewed-by: York Sun diff --git a/drivers/net/ldpaa_eth/ldpaa_eth.c b/drivers/net/ldpaa_eth/ldpaa_eth.c index 6de5f30..50ca6e4 100644 --- a/drivers/net/ldpaa_eth/ldpaa_eth.c +++ b/drivers/net/ldpaa_eth/ldpaa_eth.c @@ -31,6 +31,8 @@ static void ldpaa_eth_rx(struct ldpaa_eth_priv *priv, uint32_t fd_length; struct ldpaa_fas *fas; uint32_t status, err; + u32 timeo = (CONFIG_SYS_HZ * 2) / 1000; + u32 time_start; struct qbman_release_desc releasedesc; struct qbman_swp *swp = dflt_dpio->sw_portal; @@ -65,10 +67,15 @@ error: flush_dcache_range(fd_addr, fd_addr + LDPAA_ETH_RX_BUFFER_SIZE); qbman_release_desc_clear(&releasedesc); qbman_release_desc_set_bpid(&releasedesc, dflt_dpbp->dpbp_attr.bpid); + time_start = get_timer(0); do { /* Release buffer into the QBMAN */ err = qbman_swp_release(swp, &releasedesc, &fd_addr, 1); - } while (err == -EBUSY); + } while (get_timer(time_start) < timeo && err == -EBUSY); + + if (err == -EBUSY) + printf("Rx frame: QBMAN buffer release fails\n"); + return; } -- cgit v0.10.2 From 95279315076c6f719be9ff0501a6a5addc061416 Mon Sep 17 00:00:00 2001 From: Prabhakar Kushwaha Date: Sun, 28 Jun 2015 11:03:59 +0530 Subject: board/ls2085rdb: Export functions for standalone AQ FW load apps Export functions required by Aquntia PHY firmware load application. functions are memset, strcpy, mdelay, mdio_get_current_dev, phy_find_by_mask, mdio_phydev_for_ethname and miiphy_set_current_dev Signed-off-by: Prabhakar Kushwaha Reviewed-by: York Sun diff --git a/board/freescale/ls2085ardb/eth_ls2085rdb.c b/board/freescale/ls2085ardb/eth_ls2085rdb.c index 60af079..0a1163a 100644 --- a/board/freescale/ls2085ardb/eth_ls2085rdb.c +++ b/board/freescale/ls2085ardb/eth_ls2085rdb.c @@ -14,10 +14,13 @@ #include #include #include +#include #include #include #include +DECLARE_GLOBAL_DATA_PTR; + int load_firmware_cortina(struct phy_device *phy_dev) { if (phy_dev->drv->config) @@ -129,5 +132,17 @@ int board_eth_init(bd_t *bis) cpu_eth_init(bis); #endif /* CONFIG_FMAN_ENET */ +#ifdef CONFIG_PHY_AQUANTIA + /* + * Export functions to be used by AQ firmware + * upload application + */ + gd->jt->strcpy = strcpy; + gd->jt->mdelay = mdelay; + gd->jt->mdio_get_current_dev = mdio_get_current_dev; + gd->jt->phy_find_by_mask = phy_find_by_mask; + gd->jt->mdio_phydev_for_ethname = mdio_phydev_for_ethname; + gd->jt->miiphy_set_current_dev = miiphy_set_current_dev; +#endif return pci_eth_init(bis); } diff --git a/common/exports.c b/common/exports.c index 333107c..b4f1f7a 100644 --- a/common/exports.c +++ b/common/exports.c @@ -16,6 +16,13 @@ unsigned long get_version(void) #define EXPORT_FUNC(f, a, x, ...) gd->jt->x = f; +#ifndef CONFIG_PHY_AQUANTIA +# define mdio_get_current_dev dummy +# define phy_find_by_mask dummy +# define mdio_phydev_for_ethname dummy +# define miiphy_set_current_dev dummy +#endif + void jumptable_init(void) { gd->jt = malloc(sizeof(struct jt_funcs)); diff --git a/include/_exports.h b/include/_exports.h index 279017e..74a882a 100644 --- a/include/_exports.h +++ b/include/_exports.h @@ -73,3 +73,16 @@ const char *, char **, unsigned int) EXPORT_FUNC(ustrtoull, unsigned long long, ustrtoull, const char *, char **, unsigned int) + EXPORT_FUNC(strcpy, char *, strcpy, char *dest, const char *src) + EXPORT_FUNC(mdelay, void, mdelay, unsigned long msec) +#ifdef CONFIG_PHY_AQUANTIA + EXPORT_FUNC(mdio_get_current_dev, struct mii_dev *, + mdio_get_current_dev, void) + EXPORT_FUNC(phy_find_by_mask, struct phy_device *, phy_find_by_mask, + struct mii_dev *bus, unsigned phy_mask, + phy_interface_t interface) + EXPORT_FUNC(mdio_phydev_for_ethname, struct phy_device *, + mdio_phydev_for_ethname, const char *ethname) + EXPORT_FUNC(miiphy_set_current_dev, int, miiphy_set_current_dev, + const char *devname) +#endif diff --git a/include/configs/ls2085ardb.h b/include/configs/ls2085ardb.h index 891fabe..dfd5900 100644 --- a/include/configs/ls2085ardb.h +++ b/include/configs/ls2085ardb.h @@ -322,6 +322,7 @@ unsigned long get_board_sys_clk(void); #define CONFIG_MII #define CONFIG_ETHPRIME "DPNI1" #define CONFIG_PHY_GIGE +#define CONFIG_PHY_AQUANTIA #endif #endif /* __LS2_RDB_H */ diff --git a/include/exports.h b/include/exports.h index 1a01e43..a3e0469 100644 --- a/include/exports.h +++ b/include/exports.h @@ -2,6 +2,10 @@ #define __EXPORTS_H__ #ifndef __ASSEMBLY__ +#ifdef CONFIG_PHY_AQUANTIA +#include +#include +#endif struct spi_slave; @@ -34,6 +38,13 @@ unsigned long long ustrtoull(const char *cp, char **endp, unsigned int base); int i2c_write (uchar, uint, int , uchar* , int); int i2c_read (uchar, uint, int , uchar* , int); #endif +#ifdef CONFIG_PHY_AQUANTIA +struct mii_dev *mdio_get_current_dev(void); +struct phy_device *phy_find_by_mask(struct mii_dev *bus, unsigned phy_mask, + phy_interface_t interface); +struct phy_device *mdio_phydev_for_ethname(const char *ethname); +int miiphy_set_current_dev(const char *devname); +#endif void app_startup(char * const *); @@ -46,7 +57,7 @@ struct jt_funcs { }; -#define XF_VERSION 7 +#define XF_VERSION 8 #if defined(CONFIG_X86) extern gd_t *global_data; -- cgit v0.10.2 From 97421bd2c010479504947a80b18f79d0485d6eb4 Mon Sep 17 00:00:00 2001 From: Prabhakar Kushwaha Date: Wed, 1 Jul 2015 16:28:22 +0530 Subject: board/ls2085a: Increase kernel_size value in env variable Linux itb image size has been increased from 30MB. So updating kernel_size to 40MB in env variable. Signed-off-by: Prabhakar Kushwaha Reviewed-by: York Sun diff --git a/include/configs/ls2085a_common.h b/include/configs/ls2085a_common.h index 60e5532..5afee55 100644 --- a/include/configs/ls2085a_common.h +++ b/include/configs/ls2085a_common.h @@ -247,7 +247,7 @@ unsigned long long get_qixis_addr(void); "initrd_high=0xffffffffffffffff\0" \ "kernel_start=0x581200000\0" \ "kernel_load=0xa0000000\0" \ - "kernel_size=0x2000000\0" \ + "kernel_size=0x2800000\0" \ "console=ttyAMA0,38400n8\0" #define CONFIG_BOOTARGS "console=ttyS1,115200 root=/dev/ram0 " \ diff --git a/include/configs/ls2085aqds.h b/include/configs/ls2085aqds.h index dcdd316..5a42164 100644 --- a/include/configs/ls2085aqds.h +++ b/include/configs/ls2085aqds.h @@ -332,7 +332,7 @@ unsigned long get_board_ddr_clk(void); "initrd_high=0xffffffffffffffff\0" \ "kernel_start=0x581100000\0" \ "kernel_load=0xa0000000\0" \ - "kernel_size=0x2000000\0" + "kernel_size=0x28000000\0" #ifdef CONFIG_FSL_MC_ENET #define CONFIG_FSL_MEMAC diff --git a/include/configs/ls2085ardb.h b/include/configs/ls2085ardb.h index dfd5900..24d5880 100644 --- a/include/configs/ls2085ardb.h +++ b/include/configs/ls2085ardb.h @@ -299,7 +299,7 @@ unsigned long get_board_sys_clk(void); "initrd_high=0xffffffffffffffff\0" \ "kernel_start=0x581100000\0" \ "kernel_load=0xa0000000\0" \ - "kernel_size=0x2000000\0" + "kernel_size=0x2800000\0" /* MAC/PHY configuration */ #ifdef CONFIG_FSL_MC_ENET -- cgit v0.10.2 From 49a5e42a780dadf69fcac177143b0c8619ec467b Mon Sep 17 00:00:00 2001 From: Alison Wang Date: Mon, 11 May 2015 15:39:47 +0800 Subject: arm: ls1021a: Remove the inappropriate use of the function 'sprintf' As the function 'sprintf' does not check buffer boundaries but outputs to the buffer 'enet' of fixed size (16), this patch removes the function 'sprintf', and uses 'strcpy' instead. It will assign the character arrays 'enet' and 'phy' the corresponding character strings. Signed-off-by: Alison Wang Reviewed-by: Joe Hershberger Reviewed-by: York Sun diff --git a/arch/arm/cpu/armv7/ls102xa/fdt.c b/arch/arm/cpu/armv7/ls102xa/fdt.c index 71a1753..e01d911 100644 --- a/arch/arm/cpu/armv7/ls102xa/fdt.c +++ b/arch/arm/cpu/armv7/ls102xa/fdt.c @@ -29,29 +29,30 @@ void ft_fixup_enet_phy_connect_type(void *fdt) char phy[16]; int phy_node; int i = 0; - int enet_id = 0; uint32_t ph; while ((dev = eth_get_dev_by_index(i++)) != NULL) { - if (strstr(dev->name, "eTSEC1")) - enet_id = 0; - else if (strstr(dev->name, "eTSEC2")) - enet_id = 1; - else if (strstr(dev->name, "eTSEC3")) - enet_id = 2; - else + if (strstr(dev->name, "eTSEC1")) { + strcpy(enet, "ethernet0"); + strcpy(phy, "enet0_rgmii_phy"); + } else if (strstr(dev->name, "eTSEC2")) { + strcpy(enet, "ethernet1"); + strcpy(phy, "enet1_rgmii_phy"); + } else if (strstr(dev->name, "eTSEC3")) { + strcpy(enet, "ethernet2"); + strcpy(phy, "enet2_rgmii_phy"); + } else { continue; + } priv = dev->priv; if (priv->flags & TSEC_SGMII) continue; - sprintf(enet, "ethernet%d", enet_id); enet_path = fdt_get_alias(fdt, enet); if (!enet_path) continue; - sprintf(phy, "enet%d_rgmii_phy", enet_id); phy_path = fdt_get_alias(fdt, phy); if (!phy_path) continue; -- cgit v0.10.2 From 972af2ab515fe0d0a39271966c9c6df0d9349f37 Mon Sep 17 00:00:00 2001 From: Wang Dongsheng Date: Thu, 4 Jun 2015 12:01:08 +0800 Subject: ARMv7: Factor out reusable timer_wait from sunxi/psci_sun7i.S timer_wait is moved from sunxi/psci_sun7i.S, and it can be converted completely into a reusable armv7 generic timer. LS1021A will use it as well. Signed-off-by: Wang Dongsheng Reviewed-by: Hans de Goede Reviewed-by: York Sun diff --git a/arch/arm/cpu/armv7/sunxi/psci_sun6i.S b/arch/arm/cpu/armv7/sunxi/psci_sun6i.S index d4cb51e..4ff46e4 100644 --- a/arch/arm/cpu/armv7/sunxi/psci_sun6i.S +++ b/arch/arm/cpu/armv7/sunxi/psci_sun6i.S @@ -18,6 +18,8 @@ */ #include + +#include #include #include #include @@ -43,26 +45,6 @@ #define GICD_BASE 0x1c81000 #define GICC_BASE 0x1c82000 -.macro timer_wait reg, ticks - @ Program CNTP_TVAL - movw \reg, #(\ticks & 0xffff) - movt \reg, #(\ticks >> 16) - mcr p15, 0, \reg, c14, c2, 0 - isb - @ Enable physical timer, mask interrupt - mov \reg, #3 - mcr p15, 0, \reg, c14, c2, 1 - @ Poll physical timer until ISTATUS is on -1: isb - mrc p15, 0, \reg, c14, c2, 1 - ands \reg, \reg, #4 - bne 1b - @ Disable timer - mov \reg, #0 - mcr p15, 0, \reg, c14, c2, 1 - isb -.endm - .globl psci_fiq_enter psci_fiq_enter: push {r0-r12} diff --git a/arch/arm/cpu/armv7/sunxi/psci_sun7i.S b/arch/arm/cpu/armv7/sunxi/psci_sun7i.S index bbfeec8..e15d587 100644 --- a/arch/arm/cpu/armv7/sunxi/psci_sun7i.S +++ b/arch/arm/cpu/armv7/sunxi/psci_sun7i.S @@ -18,6 +18,8 @@ */ #include + +#include #include #include #include @@ -43,26 +45,6 @@ #define GICD_BASE 0x1c81000 #define GICC_BASE 0x1c82000 -.macro timer_wait reg, ticks - @ Program CNTP_TVAL - movw \reg, #(\ticks & 0xffff) - movt \reg, #(\ticks >> 16) - mcr p15, 0, \reg, c14, c2, 0 - isb - @ Enable physical timer, mask interrupt - mov \reg, #3 - mcr p15, 0, \reg, c14, c2, 1 - @ Poll physical timer until ISTATUS is on -1: isb - mrc p15, 0, \reg, c14, c2, 1 - ands \reg, \reg, #4 - bne 1b - @ Disable timer - mov \reg, #0 - mcr p15, 0, \reg, c14, c2, 1 - isb -.endm - .globl psci_fiq_enter psci_fiq_enter: push {r0-r12} diff --git a/arch/arm/include/asm/arch-armv7/generictimer.h b/arch/arm/include/asm/arch-armv7/generictimer.h new file mode 100644 index 0000000..f402686 --- /dev/null +++ b/arch/arm/include/asm/arch-armv7/generictimer.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2013 - ARM Ltd + * Author: Marc Zyngier + * + * Based on code by Carl van Schaik . + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef _GENERICTIMER_H_ +#define _GENERICTIMER_H_ + +#ifdef __ASSEMBLY__ + +/* + * This macro provide a physical timer that can be used for delay in the code. + * The macro is moved from sunxi/psci_sun7i.S + * + * reg: is used in this macro. + * ticks: The freq is based on generic timer. + */ +.macro timer_wait reg, ticks + movw \reg, #(\ticks & 0xffff) + movt \reg, #(\ticks >> 16) + mcr p15, 0, \reg, c14, c2, 0 + isb + mov \reg, #3 + mcr p15, 0, \reg, c14, c2, 1 +1 : isb + mrc p15, 0, \reg, c14, c2, 1 + ands \reg, \reg, #4 + bne 1b + mov \reg, #0 + mcr p15, 0, \reg, c14, c2, 1 + isb +.endm + +#endif /* __ASSEMBLY__ */ + +#endif /* _GENERICTIMER_H_ */ -- cgit v0.10.2 From 340848b1853fde95991cb76fee78a69eafd83335 Mon Sep 17 00:00:00 2001 From: Wang Dongsheng Date: Thu, 4 Jun 2015 12:01:09 +0800 Subject: arm/ls102xa: Add PSCI support for ls102xa Base on PSCI services, implement CPU_ON/CPU_OFF for ls102xa platform. Tested on LS1021AQDS, LS1021ATWR. Test CPU hotplug times: 60K Test kernel boot times: 1.2K Signed-off-by: Wang Dongsheng Acked-by: Alison Wang Reviewed-by: York Sun diff --git a/arch/arm/cpu/armv7/ls102xa/Makefile b/arch/arm/cpu/armv7/ls102xa/Makefile index 2e6a207..2d55782 100644 --- a/arch/arm/cpu/armv7/ls102xa/Makefile +++ b/arch/arm/cpu/armv7/ls102xa/Makefile @@ -12,3 +12,7 @@ obj-y += fsl_epu.o obj-$(CONFIG_OF_LIBFDT) += fdt.o obj-$(CONFIG_SYS_HAS_SERDES) += fsl_ls1_serdes.o ls102xa_serdes.o obj-$(CONFIG_SPL) += spl.o + +ifdef CONFIG_ARMV7_PSCI +obj-y += psci.o +endif diff --git a/arch/arm/cpu/armv7/ls102xa/psci.S b/arch/arm/cpu/armv7/ls102xa/psci.S new file mode 100644 index 0000000..cf5cd48 --- /dev/null +++ b/arch/arm/cpu/armv7/ls102xa/psci.S @@ -0,0 +1,126 @@ +/* + * Copyright 2015 Freescale Semiconductor, Inc. + * Author: Wang Dongsheng + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include + +#include +#include +#include + +#define SCFG_CORE0_SFT_RST 0x130 +#define SCFG_CORESRENCR 0x204 + +#define DCFG_CCSR_BRR 0x0E4 +#define DCFG_CCSR_SCRATCHRW1 0x200 + + .pushsection ._secure.text, "ax" + + .arch_extension sec + +#define ONE_MS (GENERIC_TIMER_CLK / 1000) +#define RESET_WAIT (30 * ONE_MS) + + @ r1 = target CPU + @ r2 = target PC +.globl psci_cpu_on +psci_cpu_on: + push {lr} + + @ Clear and Get the correct CPU number + @ r1 = 0xf01 + and r1, r1, #0xff + + mov r0, r1 + bl psci_get_cpu_stack_top + str r2, [r0] + dsb + + @ Get DCFG base address + movw r4, #(CONFIG_SYS_FSL_GUTS_ADDR & 0xffff) + movt r4, #(CONFIG_SYS_FSL_GUTS_ADDR >> 16) + + @ Detect target CPU state + ldr r2, [r4, #DCFG_CCSR_BRR] + rev r2, r2 + lsr r2, r2, r1 + ands r2, r2, #1 + beq holdoff_release + + @ Reset target CPU + @ Get SCFG base address + movw r0, #(CONFIG_SYS_FSL_SCFG_ADDR & 0xffff) + movt r0, #(CONFIG_SYS_FSL_SCFG_ADDR >> 16) + + @ Enable CORE Soft Reset + movw r5, #0 + movt r5, #(1 << 15) + rev r5, r5 + str r5, [r0, #SCFG_CORESRENCR] + + @ Get CPUx offset register + mov r6, #0x4 + mul r6, r6, r1 + add r2, r0, r6 + + @ Do reset on target CPU + movw r5, #0 + movt r5, #(1 << 15) + rev r5, r5 + str r5, [r2, #SCFG_CORE0_SFT_RST] + + @ Wait target CPU up + timer_wait r2, RESET_WAIT + + @ Disable CORE soft reset + mov r5, #0 + str r5, [r0, #SCFG_CORESRENCR] + +holdoff_release: + @ Release on target CPU + ldr r2, [r4, #DCFG_CCSR_BRR] + mov r6, #1 + lsl r6, r6, r1 @ 32 bytes per CPU + + rev r6, r6 + orr r2, r2, r6 + str r2, [r4, #DCFG_CCSR_BRR] + + @ Set secondary boot entry + ldr r6, =psci_cpu_entry + rev r6, r6 + str r6, [r4, #DCFG_CCSR_SCRATCHRW1] + + isb + dsb + + @ Return + mov r0, #ARM_PSCI_RET_SUCCESS + + pop {lr} + bx lr + +.globl psci_cpu_off +psci_cpu_off: + bl psci_cpu_off_common + +1: wfi + b 1b + +.globl psci_arch_init +psci_arch_init: + mov r6, lr + + bl psci_get_cpu_id + bl psci_get_cpu_stack_top + mov sp, r0 + + bx r6 + + .globl psci_text_end +psci_text_end: + .popsection diff --git a/include/configs/ls1021aqds.h b/include/configs/ls1021aqds.h index 8a5a707..cacbae7 100644 --- a/include/configs/ls1021aqds.h +++ b/include/configs/ls1021aqds.h @@ -9,6 +9,8 @@ #define CONFIG_LS102XA +#define CONFIG_ARMV7_PSCI + #define CONFIG_SYS_GENERIC_BOARD #define CONFIG_DISPLAY_CPUINFO diff --git a/include/configs/ls1021atwr.h b/include/configs/ls1021atwr.h index 233b3d0..d0432c3 100644 --- a/include/configs/ls1021atwr.h +++ b/include/configs/ls1021atwr.h @@ -9,6 +9,8 @@ #define CONFIG_LS102XA +#define CONFIG_ARMV7_PSCI + #define CONFIG_SYS_GENERIC_BOARD #define CONFIG_DISPLAY_CPUINFO -- cgit v0.10.2 From 88c857df8cf4956195b10afbbe08cc3912d45429 Mon Sep 17 00:00:00 2001 From: Alison Wang Date: Tue, 9 Jun 2015 16:07:49 +0800 Subject: arm/ls102xa: Add little-endian mode support for audio IPs As SCFG_ENDIANCR register is added to choose little-endian or big-endian for audio IPs on Rev2.0 silion, little-endian mode is selected. Signed-off-by: Alison Wang Reviewed-by: York Sun diff --git a/arch/arm/include/asm/arch-ls102xa/immap_ls102xa.h b/arch/arm/include/asm/arch-ls102xa/immap_ls102xa.h index ee547fb..6a330cc 100644 --- a/arch/arm/include/asm/arch-ls102xa/immap_ls102xa.h +++ b/arch/arm/include/asm/arch-ls102xa/immap_ls102xa.h @@ -149,6 +149,7 @@ struct ccsr_gur { #define SCFG_ETSECCMCR_GE1_CLK125 0x08000000 #define SCFG_PIXCLKCR_PXCKEN 0x80000000 #define SCFG_QSPI_CLKSEL 0xc0100000 +#define SCFG_ENDIANCR_LE 0x80000000 /* Supplemental Configuration Unit */ struct ccsr_scfg { @@ -207,7 +208,7 @@ struct ccsr_scfg { u32 qos2; u32 qos3; u32 cci_cfg; - u32 resv8[1]; + u32 endiancr; u32 etsecdmamcr; u32 usb3prm3cr; u32 resv9[1]; diff --git a/board/freescale/ls1021aqds/ls1021aqds.c b/board/freescale/ls1021aqds/ls1021aqds.c index 92f613a..ce5cb52 100644 --- a/board/freescale/ls1021aqds/ls1021aqds.c +++ b/board/freescale/ls1021aqds/ls1021aqds.c @@ -209,6 +209,9 @@ int board_early_init_f(void) out_be32(&scfg->pixclkcr, SCFG_PIXCLKCR_PXCKEN); #endif + /* Configure Little endian for SAI, ASRC and SPDIF */ + out_be32(&scfg->endiancr, SCFG_ENDIANCR_LE); + /* * Enable snoop requests and DVM message requests for * Slave insterface S4 (A7 core cluster) diff --git a/board/freescale/ls1021atwr/ls1021atwr.c b/board/freescale/ls1021atwr/ls1021atwr.c index 043d938..8fef8e9 100644 --- a/board/freescale/ls1021atwr/ls1021atwr.c +++ b/board/freescale/ls1021atwr/ls1021atwr.c @@ -368,6 +368,9 @@ int board_early_init_f(void) out_be32(&scfg->qspi_cfg, SCFG_QSPI_CLKSEL); #endif + /* Configure Little endian for SAI, ASRC and SPDIF */ + out_be32(&scfg->endiancr, SCFG_ENDIANCR_LE); + /* * Enable snoop requests and DVM message requests for * Slave insterface S4 (A7 core cluster) -- cgit v0.10.2 From d941f71084aab787228a2a8bad614f8770e6f384 Mon Sep 17 00:00:00 2001 From: Haikun Wang Date: Fri, 26 Jun 2015 19:48:36 +0800 Subject: arm/dts/ls2085a: Bring in ls2085a dts files from linux kernel Bring in required device tree files for ls2085a from Linux. These are initially unchanged and have a number of pieces not needed by U-Boot. Signed-off-by: Haikun Wang Reviewed-by: York Sun diff --git a/arch/arm/dts/fsl-ls2085a.dtsi b/arch/arm/dts/fsl-ls2085a.dtsi new file mode 100644 index 0000000..f0679a8 --- /dev/null +++ b/arch/arm/dts/fsl-ls2085a.dtsi @@ -0,0 +1,120 @@ +/* + * Freescale ls2085a SOC common device tree source + * + * Copyright 2013-2015 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/ { + compatible = "fsl,ls2085a"; + interrupt-parent = <&gic>; + #address-cells = <2>; + #size-cells = <2>; + + cpus { + #address-cells = <2>; + #size-cells = <0>; + + /* + * We expect the enable-method for cpu's to be "psci", but this + * is dependent on the SoC FW, which will fill this in. + * + * Currently supported enable-method is psci v0.2 + */ + + /* We have 4 clusters having 2 Cortex-A57 cores each */ + cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a57"; + reg = <0x0 0x0>; + }; + + cpu@1 { + device_type = "cpu"; + compatible = "arm,cortex-a57"; + reg = <0x0 0x1>; + }; + + cpu@100 { + device_type = "cpu"; + compatible = "arm,cortex-a57"; + reg = <0x0 0x100>; + }; + + cpu@101 { + device_type = "cpu"; + compatible = "arm,cortex-a57"; + reg = <0x0 0x101>; + }; + + cpu@200 { + device_type = "cpu"; + compatible = "arm,cortex-a57"; + reg = <0x0 0x200>; + }; + + cpu@201 { + device_type = "cpu"; + compatible = "arm,cortex-a57"; + reg = <0x0 0x201>; + }; + + cpu@300 { + device_type = "cpu"; + compatible = "arm,cortex-a57"; + reg = <0x0 0x300>; + }; + + cpu@301 { + device_type = "cpu"; + compatible = "arm,cortex-a57"; + reg = <0x0 0x301>; + }; + }; + + memory@80000000 { + device_type = "memory"; + reg = <0x00000000 0x80000000 0 0x80000000>; + /* DRAM space - 1, size : 2 GB DRAM */ + }; + + gic: interrupt-controller@6000000 { + compatible = "arm,gic-v3"; + reg = <0x0 0x06000000 0 0x10000>, /* GIC Dist */ + <0x0 0x06100000 0 0x100000>; /* GICR (RD_base + SGI_base) */ + #interrupt-cells = <3>; + interrupt-controller; + interrupts = <1 9 0x4>; + }; + + timer { + compatible = "arm,armv8-timer"; + interrupts = <1 13 0x8>, /* Physical Secure PPI, active-low */ + <1 14 0x8>, /* Physical Non-Secure PPI, active-low */ + <1 11 0x8>, /* Virtual PPI, active-low */ + <1 10 0x8>; /* Hypervisor PPI, active-low */ + }; + + serial0: serial@21c0500 { + device_type = "serial"; + compatible = "fsl,ns16550", "ns16550a"; + reg = <0x0 0x21c0500 0x0 0x100>; + clock-frequency = <0>; /* Updated by bootloader */ + interrupts = <0 32 0x1>; /* edge triggered */ + }; + + serial1: serial@21c0600 { + device_type = "serial"; + compatible = "fsl,ns16550", "ns16550a"; + reg = <0x0 0x21c0600 0x0 0x100>; + clock-frequency = <0>; /* Updated by bootloader */ + interrupts = <0 32 0x1>; /* edge triggered */ + }; + + fsl_mc: fsl-mc@80c000000 { + compatible = "fsl,qoriq-mc"; + reg = <0x00000008 0x0c000000 0 0x40>, /* MC portal base */ + <0x00000000 0x08340000 0 0x40000>; /* MC control reg */ + }; +}; -- cgit v0.10.2 From fe69a0e86bc714ce8d7d8251ec31b77b89c96db5 Mon Sep 17 00:00:00 2001 From: Haikun Wang Date: Fri, 26 Jun 2015 19:48:45 +0800 Subject: arm/dts/ls2085a: Add DSPI dts node Add DSPI controller dts node in fsl-ls2085a.dtsi Signed-off-by: Haikun Wang Reviewed-by: York Sun diff --git a/arch/arm/dts/fsl-ls2085a.dtsi b/arch/arm/dts/fsl-ls2085a.dtsi index f0679a8..96404c5 100644 --- a/arch/arm/dts/fsl-ls2085a.dtsi +++ b/arch/arm/dts/fsl-ls2085a.dtsi @@ -117,4 +117,13 @@ reg = <0x00000008 0x0c000000 0 0x40>, /* MC portal base */ <0x00000000 0x08340000 0 0x40000>; /* MC control reg */ }; + + dspi: dspi@2100000 { + compatible = "fsl,vf610-dspi"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x0 0x2100000 0x0 0x10000>; + interrupts = <0 26 0x4>; /* Level high type */ + num-cs = <6>; + }; }; -- cgit v0.10.2 From 193e7e5a8e93fa3076a80fa6c7b687401f08108b Mon Sep 17 00:00:00 2001 From: Haikun Wang Date: Fri, 26 Jun 2015 19:48:58 +0800 Subject: arm/dts/ls2085a: Add dts files for LS2085AQDS and LS2085ARDB Add dts source files for LS2085AQDS and LS2085ARDB boards. Signed-off-by: Haikun Wang Reviewed-by: York Sun diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 19e1de6..8ebd693 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -57,6 +57,8 @@ dtb-$(CONFIG_TARGET_STV0991) += stv0991.dtb dtb-$(CONFIG_LS102XA) += ls1021a-qds.dtb \ ls1021a-twr.dtb +dtb-$(CONFIG_FSL_LSCH3) += fsl-ls2085a-qds.dtb \ + fsl-ls2085a-rdb.dtb dtb-$(CONFIG_MACH_SUN4I) += \ sun4i-a10-a1000.dtb \ diff --git a/arch/arm/dts/fsl-ls2085a-qds.dts b/arch/arm/dts/fsl-ls2085a-qds.dts new file mode 100644 index 0000000..4477e54 --- /dev/null +++ b/arch/arm/dts/fsl-ls2085a-qds.dts @@ -0,0 +1,53 @@ +/* + * Freescale ls2085a QDS board device tree source + * + * Copyright 2013-2015 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/dts-v1/; + +#include "fsl-ls2085a.dtsi" + +/ { + model = "Freescale Layerscape 2085a QDS Board"; + compatible = "fsl,ls2085a-qds", "fsl,ls2085a"; + + aliases { + spi1 = &dspi; + }; +}; + +&dspi { + bus-num = <0>; + status = "okay"; + + dflash0: n25q128a { + #address-cells = <1>; + #size-cells = <1>; + compatible = "spi-flash"; + spi-max-frequency = <3000000>; + spi-cpol; + spi-cpha; + reg = <0>; + }; + dflash1: sst25wf040b { + #address-cells = <1>; + #size-cells = <1>; + compatible = "spi-flash"; + spi-max-frequency = <3000000>; + spi-cpol; + spi-cpha; + reg = <1>; + }; + dflash2: en25s64 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "spi-flash"; + spi-max-frequency = <3000000>; + spi-cpol; + spi-cpha; + reg = <2>; + }; +}; diff --git a/arch/arm/dts/fsl-ls2085a-rdb.dts b/arch/arm/dts/fsl-ls2085a-rdb.dts new file mode 100644 index 0000000..25278df --- /dev/null +++ b/arch/arm/dts/fsl-ls2085a-rdb.dts @@ -0,0 +1,35 @@ +/* + * Freescale ls2085a RDB board device tree source + * + * Copyright 2013-2015 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/dts-v1/; + +#include "fsl-ls2085a.dtsi" + +/ { + model = "Freescale Layerscape 2085a RDB Board"; + compatible = "fsl,ls2085a-rdb", "fsl,ls2085a"; + + aliases { + spi1 = &dspi; + }; +}; + +&dspi { + bus-num = <0>; + status = "okay"; + + dflash0: n25q512a { + #address-cells = <1>; + #size-cells = <1>; + compatible = "spi-flash"; + spi-max-frequency = <3000000>; + spi-cpol; + spi-cpha; + reg = <0>; + }; +}; -- cgit v0.10.2 From b0e209dc636d76afa90e330c37d29cea6deeea33 Mon Sep 17 00:00:00 2001 From: Haikun Wang Date: Fri, 26 Jun 2015 19:56:11 +0800 Subject: armv8/ls2085a: Enable DSPI get input clk form 'mxc_get_clock' Signed-off-by: Haikun Wang Reviewed-by: York Sun diff --git a/arch/arm/cpu/armv8/fsl-lsch3/speed.c b/arch/arm/cpu/armv8/fsl-lsch3/speed.c index cac4f92..d9f137c 100644 --- a/arch/arm/cpu/armv8/fsl-lsch3/speed.c +++ b/arch/arm/cpu/armv8/fsl-lsch3/speed.c @@ -180,6 +180,8 @@ unsigned int mxc_get_clock(enum mxc_clock clk) switch (clk) { case MXC_I2C_CLK: return get_bus_freq(0) / 2; + case MXC_DSPI_CLK: + return get_bus_freq(0) / 2; default: printf("Unsupported clock\n"); } diff --git a/arch/arm/include/asm/arch-fsl-lsch3/clock.h b/arch/arm/include/asm/arch-fsl-lsch3/clock.h index 831af0b..62bc53c 100644 --- a/arch/arm/include/asm/arch-fsl-lsch3/clock.h +++ b/arch/arm/include/asm/arch-fsl-lsch3/clock.h @@ -16,6 +16,7 @@ enum mxc_clock { MXC_UART_CLK, MXC_ESDHC_CLK, MXC_I2C_CLK, + MXC_DSPI_CLK, }; unsigned int mxc_get_clock(enum mxc_clock clk); -- cgit v0.10.2 From e71a980a4d4eb01bc3eb7624fc59cd8f999bf4b2 Mon Sep 17 00:00:00 2001 From: Haikun Wang Date: Fri, 26 Jun 2015 19:58:12 +0800 Subject: armv8/ls2085aqds: DSPI pin muxing configure through QIXIS DSPI has pin muxing with SDHC and other IPs, this patch check the value of RCW SPI_PCS_BASE and SPI_BASE_BASE fields, it also check the "hwconfig" variable. If those pins are configured to DSPI and "hwconfig" enable DSPI, set the BRDCFG5 of QIXIS FPGA to configure the routing to on-board SPI memory. Otherwise will configure to SDHC. DSPI is enabled in "hwconfig" by appending "dspi", eg. setenv hwconfig "$hwconfig;dspi" Signed-off-by: Haikun Wang Reviewed-by: York Sun diff --git a/arch/arm/include/asm/arch-fsl-lsch3/config.h b/arch/arm/include/asm/arch-fsl-lsch3/config.h index ca8d38c..8675e91 100644 --- a/arch/arm/include/asm/arch-fsl-lsch3/config.h +++ b/arch/arm/include/asm/arch-fsl-lsch3/config.h @@ -137,6 +137,8 @@ #define DCFG_PORSR1 0x000 #define DCFG_PORSR1_RCW_SRC 0xff800000 #define DCFG_PORSR1_RCW_SRC_NOR 0x12f00000 +#define DCFG_RCWSR13 0x130 +#define DCFG_RCWSR13_DSPI (0 << 8) #define DCFG_DCSR_BASE 0X700100000ULL #define DCFG_DCSR_PORCR1 0x000 diff --git a/board/freescale/ls2085aqds/ls2085aqds.c b/board/freescale/ls2085aqds/ls2085aqds.c index c492c7e..08906a6 100644 --- a/board/freescale/ls2085aqds/ls2085aqds.c +++ b/board/freescale/ls2085aqds/ls2085aqds.c @@ -17,12 +17,23 @@ #include #include #include +#include #include "../common/qixis.h" #include "ls2085aqds_qixis.h" +#define PIN_MUX_SEL_SDHC 0x00 +#define PIN_MUX_SEL_DSPI 0x0a + +#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; @@ -153,10 +164,47 @@ int select_i2c_ch_pca9547(u8 ch) 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); + #ifdef CONFIG_ENV_IS_NOWHERE gd->env_addr = (ulong)&default_environment[0]; #endif -- cgit v0.10.2 From 5989df7e2cfb5ac0d8c9a509aad2b84f9141cc13 Mon Sep 17 00:00:00 2001 From: "Haikun.Wang@freescale.com" Date: Fri, 26 Jun 2015 19:58:24 +0800 Subject: armv8/ls2085ardb: DSPI pin muxing configure through QIXIS CPLD DSPI has pin muxing with SDHC and other IPs, this patch check the value of RCW SPI_PCS_BASE and SPI_BASE_BASE fields, it also check the "hwconfig" variable. If those pins are configured to DSPI and "hwconfig" enable DSPI, set the BRDCFG5 of QIXIS CPLD to configure the routing to on-board SPI memory. Otherwise will configure to SDHC. DSPI is enabled in "hwconfig" by appending "dspi", eg. setenv hwconfig "$hwconfig;dspi" Signed-off-by: Haikun Wang Reviewed-by: York Sun diff --git a/board/freescale/ls2085ardb/ls2085ardb.c b/board/freescale/ls2085ardb/ls2085ardb.c index 1f8cf8a..5e7997c 100644 --- a/board/freescale/ls2085ardb/ls2085ardb.c +++ b/board/freescale/ls2085ardb/ls2085ardb.c @@ -23,12 +23,14 @@ #include "ls2085ardb_qixis.h" #define PIN_MUX_SEL_SDHC 0x00 +#define PIN_MUX_SEL_DSPI 0x0a #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) @@ -120,26 +122,6 @@ int select_i2c_ch_pca9547(u8 ch) return 0; } -int board_init(void) -{ - init_final_memctl_regs(); - -#ifdef CONFIG_ENV_IS_NOWHERE - gd->env_addr = (ulong)&default_environment[0]; -#endif - select_i2c_ch_pca9547(I2C_MUX_CH_DEFAULT); - - QIXIS_WRITE(rst_ctl, QIXIS_RST_CTL_RESET_EN); - - return 0; -} - -int board_early_init_f(void) -{ - fsl_lsch3_early_init_f(); - return 0; -} - int config_board_mux(int ctrl_type) { u8 reg5; @@ -150,6 +132,9 @@ int config_board_mux(int 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; @@ -160,6 +145,40 @@ int config_board_mux(int ctrl_type) 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); + +#ifdef CONFIG_ENV_IS_NOWHERE + gd->env_addr = (ulong)&default_environment[0]; +#endif + select_i2c_ch_pca9547(I2C_MUX_CH_DEFAULT); + + QIXIS_WRITE(rst_ctl, QIXIS_RST_CTL_RESET_EN); + + return 0; +} + +int board_early_init_f(void) +{ + fsl_lsch3_early_init_f(); + return 0; +} + int misc_init_r(void) { if (hwconfig("sdhc")) -- cgit v0.10.2 From b7774b05222961c88598661c19d92c70d52d6949 Mon Sep 17 00:00:00 2001 From: Haikun Wang Date: Fri, 3 Jul 2015 16:51:34 +0800 Subject: armv8/ls2085aqds: Enable DSPI flash support for LS2085AQDS Enable DSPI flash related configurations. Signed-off-by: Haikun Wang Reviewed-by: York Sun diff --git a/include/configs/ls2085aqds.h b/include/configs/ls2085aqds.h index 5a42164..a6ef356 100644 --- a/include/configs/ls2085aqds.h +++ b/include/configs/ls2085aqds.h @@ -272,6 +272,15 @@ unsigned long get_board_ddr_clk(void); /* I2C bus multiplexer */ #define I2C_MUX_CH_DEFAULT 0x8 +/* SPI */ +#ifdef CONFIG_FSL_DSPI +#define CONFIG_CMD_SF +#define CONFIG_SPI_FLASH +#define CONFIG_SPI_FLASH_STMICRO +#define CONFIG_SPI_FLASH_SST +#define CONFIG_SPI_FLASH_EON +#endif + /* * MMC */ -- cgit v0.10.2 From 0c42a8de85f15e2f212d2f281406f8a3e68a29e2 Mon Sep 17 00:00:00 2001 From: Haikun Wang Date: Fri, 3 Jul 2015 16:51:35 +0800 Subject: armv8/ls2085ardb: Enable DSPI flash support for LS2085ARDB Enable DSPI flash related configurations for LS2085ARDB. Signed-off-by: Haikun Wang Reviewed-by: York Sun diff --git a/include/configs/ls2085ardb.h b/include/configs/ls2085ardb.h index 24d5880..41eb55b 100644 --- a/include/configs/ls2085ardb.h +++ b/include/configs/ls2085ardb.h @@ -245,6 +245,14 @@ unsigned long get_board_sys_clk(void); /* I2C bus multiplexer */ #define I2C_MUX_CH_DEFAULT 0x8 +/* SPI */ +#ifdef CONFIG_FSL_DSPI +#define CONFIG_CMD_SF +#define CONFIG_SPI_FLASH +#define CONFIG_SPI_FLASH_STMICRO +#define CONFIG_SPI_FLASH_BAR +#endif + /* * RTC configuration */ -- cgit v0.10.2 From 25195600173e618b1cf693bcf38d48973e3a08fb Mon Sep 17 00:00:00 2001 From: "Haikun.Wang@freescale.com" Date: Fri, 3 Jul 2015 16:51:36 +0800 Subject: armv8/ls2085a/defconfig: Enable FSL_DSPI, OF_CONTROL and DM support Freescale DSPI driver has been converted to Driver Model. The new driver depends on OF_CONTROL, DM, DM_SPI. This patch enable FSL_DSPI and its dependence configure options. Signed-off-by: Haikun Wang Reviewed-by: York Sun diff --git a/configs/ls2085aqds_defconfig b/configs/ls2085aqds_defconfig index fd208b18..00b062b 100644 --- a/configs/ls2085aqds_defconfig +++ b/configs/ls2085aqds_defconfig @@ -1,4 +1,11 @@ CONFIG_ARM=y CONFIG_TARGET_LS2085AQDS=y +CONFIG_DEFAULT_DEVICE_TREE="fsl-ls2085a-qds" +# CONFIG_SYS_MALLOC_F is not set CONFIG_SYS_EXTRA_OPTIONS="SYS_FSL_DDR4" # CONFIG_CMD_SETEXPR is not set +CONFIG_OF_CONTROL=y +CONFIG_DM=y +CONFIG_DM_SPI_FLASH=y +CONFIG_DM_SPI=y +CONFIG_FSL_DSPI=y diff --git a/configs/ls2085ardb_defconfig b/configs/ls2085ardb_defconfig index 308e935..c7dae4b 100644 --- a/configs/ls2085ardb_defconfig +++ b/configs/ls2085ardb_defconfig @@ -1,4 +1,11 @@ CONFIG_ARM=y CONFIG_TARGET_LS2085ARDB=y +CONFIG_DEFAULT_DEVICE_TREE="fsl-ls2085a-rdb" +# CONFIG_SYS_MALLOC_F is not set CONFIG_SYS_EXTRA_OPTIONS="SYS_FSL_DDR4" # CONFIG_CMD_SETEXPR is not set +CONFIG_OF_CONTROL=y +CONFIG_DM=y +CONFIG_DM_SPI_FLASH=y +CONFIG_DM_SPI=y +CONFIG_FSL_DSPI=y -- cgit v0.10.2 From 21a257b9b3b29ddb1445fdafe12e05727080a198 Mon Sep 17 00:00:00 2001 From: Zhichun Hua Date: Mon, 29 Jun 2015 15:49:37 +0800 Subject: armv8: Fix TCR macros for shareability attribute For ARMv8, outer shareable is 0b10, inner shareable is 0b11 at bit position [13:12] of TCR_ELx register. Signed-off-by: Zhichun Hua Signed-off-by: York Sun diff --git a/arch/arm/include/asm/armv8/mmu.h b/arch/arm/include/asm/armv8/mmu.h index 4b9cb52..04fa0be 100644 --- a/arch/arm/include/asm/armv8/mmu.h +++ b/arch/arm/include/asm/armv8/mmu.h @@ -93,8 +93,8 @@ #define TCR_ORGN_WBNWA (3 << 10) #define TCR_ORGN_MASK (3 << 10) #define TCR_SHARED_NON (0 << 12) -#define TCR_SHARED_OUTER (1 << 12) -#define TCR_SHARED_INNER (2 << 12) +#define TCR_SHARED_OUTER (2 << 12) +#define TCR_SHARED_INNER (3 << 12) #define TCR_TG0_4K (0 << 14) #define TCR_TG0_64K (1 << 14) #define TCR_TG0_16K (2 << 14) -- cgit v0.10.2 From db14f11dfe348550d8c10c6609277488d9f500d6 Mon Sep 17 00:00:00 2001 From: Zhichun Hua Date: Mon, 29 Jun 2015 15:50:42 +0800 Subject: armv8/fsl-lsch3: Fix TCR_EL3 for the final MMU setup. When final MMU table is setup in DDR, TCR attributes must match those of the memroy for cacheability and shareability. Signed-off-by: Zhichun Hua Signed-off-by: York Sun diff --git a/arch/arm/cpu/armv8/fsl-lsch3/cpu.c b/arch/arm/cpu/armv8/fsl-lsch3/cpu.c index 52bc731..d02c0be 100644 --- a/arch/arm/cpu/armv8/fsl-lsch3/cpu.c +++ b/arch/arm/cpu/armv8/fsl-lsch3/cpu.c @@ -82,6 +82,12 @@ void cpu_name(char *name) TCR_ORGN_NC | \ TCR_IRGN_NC | \ TCR_T0SZ(LSCH3_VA_BITS)) +#define LSCH3_TCR_FINAL (TCR_TG0_4K | \ + TCR_EL2_PS_40BIT | \ + TCR_SHARED_OUTER | \ + TCR_ORGN_WBWA | \ + TCR_IRGN_WBWA | \ + TCR_T0SZ(LSCH3_VA_BITS)) /* * Final MMU @@ -266,21 +272,8 @@ static inline void final_mmu_setup(void) /* point TTBR to the new table */ el = current_el(); - asm volatile("dsb sy"); - if (el == 1) { - asm volatile("msr ttbr0_el1, %0" - : : "r" ((u64)level0_table) : "memory"); - } else if (el == 2) { - asm volatile("msr ttbr0_el2, %0" - : : "r" ((u64)level0_table) : "memory"); - } else if (el == 3) { - asm volatile("msr ttbr0_el3, %0" - : : "r" ((u64)level0_table) : "memory"); - } else { - hang(); - } - asm volatile("isb"); - + set_ttbr_tcr_mair(el, (u64)level0_table, LSCH3_TCR_FINAL, + MEMORY_ATTRIBUTES); /* * MMU is already enabled, just need to invalidate TLB to load the * new table. The new table is compatible with the current table, if -- cgit v0.10.2