#include <linux/of_device.h>
 #include <linux/platform_device.h>
 #include <linux/pm_qos.h>
+#include <linux/regmap.h>
 #include <linux/sizes.h>
+#include <linux/sys_soc.h>
 
+#include <linux/mfd/syscon.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/spi-mem.h>
 
 #define NXP_FSPI_MAX_CHIPSELECT                4
 #define NXP_FSPI_MIN_IOMAP     SZ_4M
 
+#define DCFG_RCWSR1            0x100
+
 /* Access flash memory using IP bus only */
 #define FSPI_QUIRK_USE_IP_ONLY BIT(0)
 
        bool little_endian;
 };
 
-static const struct nxp_fspi_devtype_data lx2160a_data = {
+static struct nxp_fspi_devtype_data lx2160a_data = {
        .rxfifo = SZ_512,       /* (64  * 64 bits)  */
        .txfifo = SZ_1K,        /* (128 * 64 bits)  */
        .ahb_buf_size = SZ_2K,  /* (256 * 64 bits)  */
        .little_endian = true,  /* little-endian    */
 };
 
-static const struct nxp_fspi_devtype_data imx8mm_data = {
+static struct nxp_fspi_devtype_data imx8mm_data = {
        .rxfifo = SZ_512,       /* (64  * 64 bits)  */
        .txfifo = SZ_1K,        /* (128 * 64 bits)  */
        .ahb_buf_size = SZ_2K,  /* (256 * 64 bits)  */
        .little_endian = true,  /* little-endian    */
 };
 
-static const struct nxp_fspi_devtype_data imx8qxp_data = {
+static struct nxp_fspi_devtype_data imx8qxp_data = {
        .rxfifo = SZ_512,       /* (64  * 64 bits)  */
        .txfifo = SZ_1K,        /* (128 * 64 bits)  */
        .ahb_buf_size = SZ_2K,  /* (256 * 64 bits)  */
        .little_endian = true,  /* little-endian    */
 };
 
-static const struct nxp_fspi_devtype_data imx8dxl_data = {
+static struct nxp_fspi_devtype_data imx8dxl_data = {
        .rxfifo = SZ_512,       /* (64  * 64 bits)  */
        .txfifo = SZ_1K,        /* (128 * 64 bits)  */
        .ahb_buf_size = SZ_2K,  /* (256 * 64 bits)  */
        struct clk *clk, *clk_en;
        struct device *dev;
        struct completion c;
-       const struct nxp_fspi_devtype_data *devtype_data;
+       struct nxp_fspi_devtype_data *devtype_data;
        struct mutex lock;
        struct pm_qos_request pm_qos_req;
        int selected;
        return 0;
 }
 
+static void erratum_err050568(struct nxp_fspi *f)
+{
+       const struct soc_device_attribute ls1028a_soc_attr[] = {
+               { .family = "QorIQ LS1028A" },
+               { /* sentinel */ }
+       };
+       struct device_node *np;
+       struct regmap *map;
+       u32 val = 0, sysclk = 0;
+       int ret;
+
+       /* Check for LS1028A family */
+       if (!soc_device_match(ls1028a_soc_attr)) {
+               dev_dbg(f->dev, "Errata applicable only for LS1028A\n");
+               return;
+       }
+
+       /* Compute system clock frequency multiplier ratio */
+       map = syscon_regmap_lookup_by_compatible("fsl,ls1028a-dcfg");
+       if (IS_ERR(map)) {
+               dev_err(f->dev, "No syscon regmap\n");
+               goto err;
+       }
+
+       ret = regmap_read(map, DCFG_RCWSR1, &val);
+       if (ret < 0)
+               goto err;
+
+       /* Strap bits 6:2 define SYS_PLL_RAT i.e frequency multiplier ratio */
+       val = (val >> 2) & 0x1F;
+       WARN(val == 0, "Strapping is zero: Cannot determine ratio");
+
+       /* Compute system clock frequency */
+       np = of_find_node_by_name(NULL, "clock-sysclk");
+       if (!np)
+               goto err;
+
+       if (of_property_read_u32(np, "clock-frequency", &sysclk))
+               goto err;
+
+       sysclk = (sysclk * val) / 1000000; /* Convert sysclk to Mhz */
+       dev_dbg(f->dev, "val: 0x%08x, sysclk: %dMhz\n", val, sysclk);
+
+       /* Use IP bus only if PLL is 300MHz */
+       if (sysclk == 300)
+               f->devtype_data->quirks |= FSPI_QUIRK_USE_IP_ONLY;
+
+       return;
+
+err:
+       dev_err(f->dev, "Errata cannot be executed. Read via IP bus may not work\n");
+}
+
 static int nxp_fspi_default_setup(struct nxp_fspi *f)
 {
        void __iomem *base = f->iobase;
        if (ret)
                return ret;
 
+       /*
+        * ERR050568: Flash access by FlexSPI AHB command may not work with
+        * platform frequency equal to 300 MHz on LS1028A.
+        * LS1028A reuses LX2160A compatible entry. Make errata applicable for
+        * Layerscape LS1028A platform.
+        */
+       if (of_device_is_compatible(f->dev->of_node, "nxp,lx2160a-fspi"))
+               erratum_err050568(f);
+
        /* Reset the module */
        /* w1c register, wait unit clear */
        ret = fspi_readl_poll_tout(f, f->iobase + FSPI_MCR0,
 
        f = spi_controller_get_devdata(ctlr);
        f->dev = dev;
-       f->devtype_data = device_get_match_data(dev);
+       f->devtype_data = (struct nxp_fspi_devtype_data *)device_get_match_data(dev);
        if (!f->devtype_data) {
                ret = -ENODEV;
                goto err_put_ctrl;