]> git.sur5r.net Git - u-boot/blobdiff - drivers/spi/ich.c
dm: core: Add a function to decode a memory region
[u-boot] / drivers / spi / ich.c
index 373bc2683b0a0f78cd6db9adf58c182c2bf3a69e..03531a8c0c3f403ccf156f8782e743caf5f99990 100644 (file)
@@ -1,8 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * Copyright (c) 2011-12 The Chromium OS Authors.
  *
- * SPDX-License-Identifier:    GPL-2.0+
- *
  * This file is derived from the flashrom project.
  */
 
@@ -184,6 +183,19 @@ static inline void spi_use_in(struct spi_trans *trans, unsigned bytes)
        trans->bytesin -= bytes;
 }
 
+static void spi_lock_down(struct ich_spi_platdata *plat, void *sbase)
+{
+       if (plat->ich_version == ICHV_7) {
+               struct ich7_spi_regs *ich7_spi = sbase;
+
+               setbits_le16(&ich7_spi->spis, SPIS_LOCK);
+       } else if (plat->ich_version == ICHV_9) {
+               struct ich9_spi_regs *ich9_spi = sbase;
+
+               setbits_le16(&ich9_spi->hsfs, HSFS_FLOCKDN);
+       }
+}
+
 static bool spi_lock_status(struct ich_spi_platdata *plat, void *sbase)
 {
        int lock = 0;
@@ -468,8 +480,6 @@ static int ich_spi_xfer(struct udevice *dev, unsigned int bitlen,
        }
 
        /* Preset control fields */
-       control = ich_readw(ctlr, ctlr->control);
-       control &= ~SSFC_RESERVED;
        control = SPIC_SCGO | ((opcode_index & 0x07) << 4);
 
        /* Issue atomic preop cycle if needed */
@@ -565,7 +575,8 @@ static int ich_spi_xfer(struct udevice *dev, unsigned int bitlen,
        }
 
        /* Clear atomic preop now that xfer is done */
-       ich_writew(ctlr, 0, ctlr->preop);
+       if (!lock)
+               ich_writew(ctlr, 0, ctlr->preop);
 
        return 0;
 }
@@ -593,6 +604,12 @@ static int ich_spi_probe(struct udevice *dev)
                return ret;
        }
 
+       /* Lock down SPI controller settings if required */
+       if (plat->lockdown) {
+               ich_spi_config_opcode(dev);
+               spi_lock_down(plat, priv->base);
+       }
+
        priv->cur_speed = priv->max_speed;
 
        return 0;
@@ -663,6 +680,9 @@ static int ich_spi_ofdata_to_platdata(struct udevice *dev)
                        plat->ich_version = ICHV_9;
        }
 
+       plat->lockdown = fdtdec_get_bool(gd->fdt_blob, node,
+                                        "intel,spi-lock-down");
+
        return ret;
 }