From 6ce83fb3d6ac1cd25772b3c8c1265afbfa42f718 Mon Sep 17 00:00:00 2001 From: Joakim Tjernlund Date: Tue, 12 Sep 2017 19:56:41 +0200 Subject: FSL PCI: Configure PCIe reference ratio Most FSL PCIe controllers expects 333 MHz PCI reference clock. This clock is derived from the CCB but in many cases the ref. clock is not 333 MHz and a divisor needs to be configured. This adds PEX_CCB_DIV #define which can be defined for each type of CPU/platform. Signed-off-by: Joakim Tjernlund Reviewed-by: York Sun --- drivers/pci/fsl_pci_init.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/pci/fsl_pci_init.c b/drivers/pci/fsl_pci_init.c index 375b8549c59..b4c85566861 100644 --- a/drivers/pci/fsl_pci_init.c +++ b/drivers/pci/fsl_pci_init.c @@ -321,6 +321,12 @@ void fsl_pci_init(struct pci_controller *hose, struct fsl_pci_info *pci_info) pci_setup_indirect(hose, cfg_addr, cfg_data); +#ifdef PEX_CCB_DIV + /* Configure the PCIE controller core clock ratio */ + pci_hose_write_config_dword(hose, dev, 0x440, + ((gd->bus_clk / 1000000) * + (16 / PEX_CCB_DIV)) / 333); +#endif block_rev = in_be32(&pci->block_rev1); if (PEX_IP_BLK_REV_2_2 <= block_rev) { pi = &pci->pit[2]; /* 0xDC0 */ -- cgit v1.3.1 From c022ec039d3f32a153a1f7d3b1ffe3dd548d9be4 Mon Sep 17 00:00:00 2001 From: Pankaj Bansal Date: Thu, 2 Aug 2018 16:31:28 +0530 Subject: fsl/mc: Limit the ethernet name to ETH_NAME_LEN The ethernet name should be within the ETH_NAME_LEN, as this is the buffer space allocated to ethernet name. Otherwise, this causes buffer overflow. Reported-by: Ioana Ciornei Signed-off-by: Pankaj Bansal Reviewed-by: York Sun --- drivers/net/fsl-mc/mc.c | 6 +++--- drivers/net/ldpaa_eth/ldpaa_eth.c | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/fsl-mc/mc.c b/drivers/net/fsl-mc/mc.c index 982024e31ea..940025a4673 100644 --- a/drivers/net/fsl-mc/mc.c +++ b/drivers/net/fsl-mc/mc.c @@ -322,7 +322,7 @@ static int mc_fixup_dpc_mac_addr(void *blob, int dpmac_id, static int mc_fixup_mac_addrs(void *blob, enum mc_fixup_type type) { int i, err = 0, ret = 0; - char ethname[10]; + char ethname[ETH_NAME_LEN]; struct eth_device *eth_dev; for (i = WRIOP1_DPMAC1; i < NUM_WRIOP_PORTS; i++) { @@ -331,8 +331,8 @@ static int mc_fixup_mac_addrs(void *blob, enum mc_fixup_type type) (wriop_get_phy_address(i) == -1)) continue; - sprintf(ethname, "DPMAC%d@%s", i, - phy_interface_strings[wriop_get_enet_if(i)]); + snprintf(ethname, ETH_NAME_LEN, "DPMAC%d@%s", i, + phy_interface_strings[wriop_get_enet_if(i)]); eth_dev = eth_get_dev_by_name(ethname); if (eth_dev == NULL) diff --git a/drivers/net/ldpaa_eth/ldpaa_eth.c b/drivers/net/ldpaa_eth/ldpaa_eth.c index 79facb4a445..a25b7cd9067 100644 --- a/drivers/net/ldpaa_eth/ldpaa_eth.c +++ b/drivers/net/ldpaa_eth/ldpaa_eth.c @@ -993,8 +993,8 @@ static int ldpaa_eth_netdev_init(struct eth_device *net_dev, int err; struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv; - sprintf(net_dev->name, "DPMAC%d@%s", priv->dpmac_id, - phy_interface_strings[enet_if]); + snprintf(net_dev->name, ETH_NAME_LEN, "DPMAC%d@%s", priv->dpmac_id, + phy_interface_strings[enet_if]); net_dev->iobase = 0; net_dev->init = ldpaa_eth_open; -- cgit v1.3.1 From 92d2e89c8c44a8f41d5f296e46c9cd6c9b34e4f8 Mon Sep 17 00:00:00 2001 From: Laurentiu Tudor Date: Thu, 9 Aug 2018 15:19:44 +0300 Subject: misc: fsl_portals: setup QMAN_BAR{E} also on ARM platforms QMAN_BAR{E} register setup was disabled on ARM platforms, however the register does need to be set. Enable the code also on ARMs and fix the CONFIG_SYS_QMAN_MEM_PHYS define to the correct value so that the newly enabled code works. Reviewed-by: Bharat Bhushan Signed-off-by: Laurentiu Tudor Reviewed-by: York Sun --- arch/arm/include/asm/arch-fsl-layerscape/immap_lsch2.h | 3 +-- drivers/misc/fsl_portals.c | 2 -- 2 files changed, 1 insertion(+), 4 deletions(-) (limited to 'drivers') diff --git a/arch/arm/include/asm/arch-fsl-layerscape/immap_lsch2.h b/arch/arm/include/asm/arch-fsl-layerscape/immap_lsch2.h index 644a16dd30b..d22ec70aa55 100644 --- a/arch/arm/include/asm/arch-fsl-layerscape/immap_lsch2.h +++ b/arch/arm/include/asm/arch-fsl-layerscape/immap_lsch2.h @@ -57,8 +57,7 @@ #define CONFIG_SYS_BMAN_SWP_ISDR_REG 0x3E80 #define CONFIG_SYS_QMAN_NUM_PORTALS 10 #define CONFIG_SYS_QMAN_MEM_BASE 0x500000000 -#define CONFIG_SYS_QMAN_MEM_PHYS (0xf00000000ull + \ - CONFIG_SYS_QMAN_MEM_BASE) +#define CONFIG_SYS_QMAN_MEM_PHYS CONFIG_SYS_QMAN_MEM_BASE #define CONFIG_SYS_QMAN_MEM_SIZE 0x08000000 #define CONFIG_SYS_QMAN_SP_CENA_SIZE 0x10000 #define CONFIG_SYS_QMAN_SP_CINH_SIZE 0x10000 diff --git a/drivers/misc/fsl_portals.c b/drivers/misc/fsl_portals.c index 7c22b8d2099..22faf16751e 100644 --- a/drivers/misc/fsl_portals.c +++ b/drivers/misc/fsl_portals.c @@ -24,7 +24,6 @@ void setup_qbman_portals(void) CONFIG_SYS_BMAN_SWP_ISDR_REG; void __iomem *qpaddr = (void *)CONFIG_SYS_QMAN_CINH_BASE + CONFIG_SYS_QMAN_SWP_ISDR_REG; -#ifdef CONFIG_PPC struct ccsr_qman *qman = (void *)CONFIG_SYS_FSL_QMAN_ADDR; /* Set the Qman initiator BAR to match the LAW (for DQRR stashing) */ @@ -32,7 +31,6 @@ void setup_qbman_portals(void) out_be32(&qman->qcsp_bare, (u32)(CONFIG_SYS_QMAN_MEM_PHYS >> 32)); #endif out_be32(&qman->qcsp_bar, (u32)CONFIG_SYS_QMAN_MEM_PHYS); -#endif #ifdef CONFIG_FSL_CORENET int i; -- cgit v1.3.1 From 599a97d49cee04aaa6c2c8cbecc4f47a7c088dbe Mon Sep 17 00:00:00 2001 From: Laurentiu Tudor Date: Thu, 9 Aug 2018 15:19:47 +0300 Subject: armv8: ls1046a: add icid setup for qman portals Add support for ICID setting of qman portals and the required device tree fixups. Also fix an endiness issue in portal setup code. Signed-off-by: Laurentiu Tudor Reviewed-by: York Sun --- arch/arm/cpu/armv8/fsl-layerscape/ls1046_ids.c | 16 ++++++++ .../include/asm/arch-fsl-layerscape/fsl_portals.h | 24 ++++++++++++ drivers/misc/fsl_portals.c | 43 ++++++++++++++++++++-- 3 files changed, 79 insertions(+), 4 deletions(-) create mode 100644 arch/arm/include/asm/arch-fsl-layerscape/fsl_portals.h (limited to 'drivers') diff --git a/arch/arm/cpu/armv8/fsl-layerscape/ls1046_ids.c b/arch/arm/cpu/armv8/fsl-layerscape/ls1046_ids.c index 1c528ab751e..80e1ceadc0b 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/ls1046_ids.c +++ b/arch/arm/cpu/armv8/fsl-layerscape/ls1046_ids.c @@ -6,6 +6,22 @@ #include #include #include +#include + +#ifdef CONFIG_SYS_DPAA_QBMAN +struct qportal_info qp_info[CONFIG_SYS_QMAN_NUM_PORTALS] = { + SET_QP_INFO(FSL_DPAA1_STREAM_ID_END, 0), + SET_QP_INFO(FSL_DPAA1_STREAM_ID_END, 0), + SET_QP_INFO(FSL_DPAA1_STREAM_ID_END, 0), + SET_QP_INFO(FSL_DPAA1_STREAM_ID_END, 0), + SET_QP_INFO(FSL_DPAA1_STREAM_ID_END, 0), + SET_QP_INFO(FSL_DPAA1_STREAM_ID_END, 0), + SET_QP_INFO(FSL_DPAA1_STREAM_ID_END, 0), + SET_QP_INFO(FSL_DPAA1_STREAM_ID_END, 0), + SET_QP_INFO(FSL_DPAA1_STREAM_ID_END, 0), + SET_QP_INFO(FSL_DPAA1_STREAM_ID_END, 0), +}; +#endif struct icid_id_table icid_tbl[] = { #ifdef CONFIG_SYS_DPAA_QBMAN diff --git a/arch/arm/include/asm/arch-fsl-layerscape/fsl_portals.h b/arch/arm/include/asm/arch-fsl-layerscape/fsl_portals.h new file mode 100644 index 00000000000..1577e935a60 --- /dev/null +++ b/arch/arm/include/asm/arch-fsl-layerscape/fsl_portals.h @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright 2018 NXP + */ + +#ifndef _FSL_PORTALS_H_ +#define _FSL_PORTALS_H_ + +struct qportal_info { + u16 dicid; /* DQRR ICID */ + u16 ficid; /* frame data ICID */ + u16 icid; + u8 sdest; +}; + +#define SET_QP_INFO(streamid, dest) \ + { .dicid = (streamid), .ficid = (streamid), .icid = (streamid), \ + .sdest = (dest) } + +extern struct qportal_info qp_info[]; +void fdt_portal(void *blob, const char *compat, const char *container, + u64 addr, u32 size); + +#endif diff --git a/drivers/misc/fsl_portals.c b/drivers/misc/fsl_portals.c index 22faf16751e..d3137680ade 100644 --- a/drivers/misc/fsl_portals.c +++ b/drivers/misc/fsl_portals.c @@ -13,6 +13,9 @@ #ifdef CONFIG_PPC #include #include +#else +#include +#include #endif #include @@ -45,6 +48,22 @@ void setup_qbman_portals(void) /* set frame liodn */ out_be32(&qman->qcsp[i].qcsp_io_cfg, (sdest << 16) | fliodn); } +#else +#ifdef CONFIG_ARCH_LS1046A + int i; + + for (i = 0; i < CONFIG_SYS_QMAN_NUM_PORTALS; i++) { + u8 sdest = qp_info[i].sdest; + u16 ficid = qp_info[i].ficid; + u16 dicid = qp_info[i].dicid; + u16 icid = qp_info[i].icid; + + out_be32(&qman->qcsp[i].qcsp_lio_cfg, (icid << 16) | + dicid); + /* set frame icid */ + out_be32(&qman->qcsp[i].qcsp_io_cfg, (sdest << 16) | ficid); + } +#endif #endif /* Change default state of BMan ISDR portals to all 1s */ @@ -178,6 +197,10 @@ void fdt_fixup_qportals(void *blob) char compat[64]; int compat_len; +#ifdef CONFIG_ARCH_LS1046A + int smmu_ph = fdt_get_smmu_phandle(blob); +#endif + maj = (rev_1 >> 8) & 0xff; min = rev_1 & 0xff; ip_cfg = rev_2 & 0xff; @@ -188,7 +211,7 @@ void fdt_fixup_qportals(void *blob) off = fdt_node_offset_by_compatible(blob, -1, "fsl,qman-portal"); while (off != -FDT_ERR_NOTFOUND) { -#ifdef CONFIG_PPC +#if defined(CONFIG_PPC) || defined(CONFIG_ARCH_LS1046A) #ifdef CONFIG_FSL_CORENET u32 liodns[2]; #endif @@ -198,12 +221,12 @@ void fdt_fixup_qportals(void *blob) if (!ci) goto err; - i = *ci; -#ifdef CONFIG_SYS_DPAA_FMAN + i = fdt32_to_cpu(*ci); +#if defined(CONFIG_SYS_DPAA_FMAN) && defined(CONFIG_PPC) int j; #endif -#endif /* CONFIG_PPC */ +#endif /* CONFIG_PPC || CONFIG_ARCH_LS1046A */ err = fdt_setprop(blob, off, "compatible", compat, compat_len); if (err < 0) goto err; @@ -251,6 +274,18 @@ void fdt_fixup_qportals(void *blob) if (err < 0) goto err; #endif +#else +#ifdef CONFIG_ARCH_LS1046A + if (smmu_ph >= 0) { + u32 icids[3]; + + icids[0] = qp_info[i].icid; + icids[1] = qp_info[i].dicid; + icids[2] = qp_info[i].ficid; + + fdt_set_iommu_prop(blob, off, smmu_ph, icids, 3); + } +#endif #endif /* CONFIG_PPC */ err: -- cgit v1.3.1 From 1711add3dca291376072ec0c66b01023a3462daf Mon Sep 17 00:00:00 2001 From: Darwin Dingel Date: Thu, 2 Aug 2018 10:02:45 +0200 Subject: mtd: nand: fsl_ifc: Fix handling of bitflips in erased pages This is a fix made for the fsl_ifc_nand driver on linux kernel by Pavel Machek and is applied to uboot. It is currently on applied on linux-mtd. https://patchwork.kernel.org/patch/9758117/ IFC always raises ECC errors on erased pages. It is only ignored when the buffer is checked for all 0xFF by is_blank(). The problem is a single bitflip will cause is_blank() and then mtd_read to fail. The fix makes use of nand_check_erased_ecc_chunk() to check for empty pages instead of is_blank(). This also makes sure that reads are made at ECC page size granularity to get a proper bitflip count. If the number of bitflips does not exceed the ECC strength, the page is considered empty and the bitflips will be corrected when data is sent to the higher layers (e.g. ubi). Signed-off-by: Darwin Dingel Cc: Pavel Machek Cc: Scott Wood Acked-by: Pavel Machek [Kurt: Replaced dev_err by printf due to compiler warnings] Tested-by: Kurt Kanzenbach Signed-off-by: Kurt Kanzenbach Reviewed-by: York Sun --- drivers/mtd/nand/fsl_ifc_nand.c | 69 +++++++++++++++++++++++------------------ 1 file changed, 39 insertions(+), 30 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/nand/fsl_ifc_nand.c b/drivers/mtd/nand/fsl_ifc_nand.c index a47226bd215..29f30d8ccc4 100644 --- a/drivers/mtd/nand/fsl_ifc_nand.c +++ b/drivers/mtd/nand/fsl_ifc_nand.c @@ -242,31 +242,6 @@ static void set_addr(struct mtd_info *mtd, int column, int page_addr, int oob) ctrl->index += mtd->writesize; } -static int is_blank(struct mtd_info *mtd, struct fsl_ifc_ctrl *ctrl, - unsigned int bufnum) -{ - struct nand_chip *chip = mtd_to_nand(mtd); - struct fsl_ifc_mtd *priv = nand_get_controller_data(chip); - u8 __iomem *addr = priv->vbase + bufnum * (mtd->writesize * 2); - u32 __iomem *main = (u32 *)addr; - u8 __iomem *oob = addr + mtd->writesize; - int i; - - for (i = 0; i < mtd->writesize / 4; i++) { - if (__raw_readl(&main[i]) != 0xffffffff) - return 0; - } - - for (i = 0; i < chip->ecc.layout->eccbytes; i++) { - int pos = chip->ecc.layout->eccpos[i]; - - if (__raw_readb(&oob[pos]) != 0xff) - return 0; - } - - return 1; -} - /* returns nonzero if entire page is blank */ static int check_read_ecc(struct mtd_info *mtd, struct fsl_ifc_ctrl *ctrl, u32 eccstat, unsigned int bufnum) @@ -331,16 +306,14 @@ static int fsl_ifc_run_command(struct mtd_info *mtd) if (errors == 15) { /* * Uncorrectable error. - * OK only if the whole page is blank. + * We'll check for blank pages later. * * We disable ECCER reporting due to erratum * IFC-A002770 -- so report it now if we * see an uncorrectable error in ECCSTAT. */ - if (!is_blank(mtd, ctrl, bufnum)) - ctrl->status |= - IFC_NAND_EVTER_STAT_ECCER; - break; + ctrl->status |= IFC_NAND_EVTER_STAT_ECCER; + continue; } mtd->ecc_stats.corrected += errors; @@ -727,6 +700,39 @@ static int fsl_ifc_wait(struct mtd_info *mtd, struct nand_chip *chip) return status | NAND_STATUS_WP; } +/* + * The controller does not check for bitflips in erased pages, + * therefore software must check instead. + */ +static int +check_erased_page(struct nand_chip *chip, u8 *buf, struct mtd_info *mtd) +{ + u8 *ecc = chip->oob_poi; + const int ecc_size = chip->ecc.bytes; + const int pkt_size = chip->ecc.size; + int i, res, bitflips; + + /* IFC starts ecc bytes at offset 8 in the spare area. */ + ecc += 8; + bitflips = 0; + for (i = 0; i < chip->ecc.steps; i++) { + res = nand_check_erased_ecc_chunk(buf, pkt_size, ecc, ecc_size, + NULL, 0, chip->ecc.strength); + + if (res < 0) { + printf("fsl-ifc: NAND Flash ECC Uncorrectable Error\n"); + mtd->ecc_stats.failed++; + } else if (res > 0) { + mtd->ecc_stats.corrected += res; + } + bitflips = max(res, bitflips); + buf += pkt_size; + ecc += ecc_size; + } + + return bitflips; +} + static int fsl_ifc_read_page(struct mtd_info *mtd, struct nand_chip *chip, uint8_t *buf, int oob_required, int page) { @@ -736,6 +742,9 @@ static int fsl_ifc_read_page(struct mtd_info *mtd, struct nand_chip *chip, fsl_ifc_read_buf(mtd, buf, mtd->writesize); fsl_ifc_read_buf(mtd, chip->oob_poi, mtd->oobsize); + if (ctrl->status & IFC_NAND_EVTER_STAT_ECCER) + return check_erased_page(chip, buf, mtd); + if (ctrl->status != IFC_NAND_EVTER_STAT_OPC) mtd->ecc_stats.failed++; -- cgit v1.3.1