diff mbox series

[U-Boot,v3,086/108] spi: ich: Add TPL support

Message ID 20191021033913.220758-81-sjg@chromium.org
State Superseded
Delegated to: Bin Meng
Headers show
Series x86: Add initial support for apollolake | expand

Commit Message

Simon Glass Oct. 21, 2019, 3:38 a.m. UTC
In TPL we want to reduce code size and support running with CONFIG_PCI
disabled. Add special code to handle this using a fixed BAR programmed
into the SPI on boot. Also cache the SPI flash to speed up boot.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v3: None
Changes in v2: None

 drivers/spi/ich.c | 46 ++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 42 insertions(+), 4 deletions(-)

Comments

Bin Meng Nov. 19, 2019, 2:52 p.m. UTC | #1
Hi Simon,

On Mon, Oct 21, 2019 at 11:40 AM Simon Glass <sjg@chromium.org> wrote:
>
> In TPL we want to reduce code size and support running with CONFIG_PCI
> disabled. Add special code to handle this using a fixed BAR programmed
> into the SPI on boot. Also cache the SPI flash to speed up boot.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v3: None
> Changes in v2: None
>
>  drivers/spi/ich.c | 46 ++++++++++++++++++++++++++++++++++++++++++----
>  1 file changed, 42 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/spi/ich.c b/drivers/spi/ich.c
> index ec0f77f6e40..daa69c25a3a 100644
> --- a/drivers/spi/ich.c
> +++ b/drivers/spi/ich.c
> @@ -19,8 +19,10 @@
>  #include <spi.h>
>  #include <spi_flash.h>
>  #include <spi-mem.h>
> +#include <spl.h>
>  #include <asm/fast_spi.h>
>  #include <asm/io.h>
> +#include <asm/mtrr.h>
>
>  #include "ich.h"
>
> @@ -114,6 +116,8 @@ static bool ich9_can_do_33mhz(struct udevice *dev)
>  {
>         u32 fdod, speed;
>
> +       if (!CONFIG_IS_ENABLED(PCI))
> +               return false;
>         /* Observe SPI Descriptor Component Section 0 */
>         dm_pci_write_config32(dev->parent, 0xb0, 0x1000);
>
> @@ -705,6 +709,15 @@ static int ich_init_controller(struct udevice *dev,
>                                struct ich_spi_platdata *plat,
>                                struct ich_spi_priv *ctlr)
>  {
> +       if (spl_phase() == PHASE_TPL) {
> +               struct ich_spi_platdata *plat = dev_get_platdata(dev);
> +               int ret;
> +
> +               ret = fast_spi_early_init(plat->bdf, plat->mmio_base);

Can we move the fast_spi_early_init() contents to ich_spi_probe(),
where the bios_cntl register is programmed to disable the write
protect for ICH_V7? This helps reading as it's disabling write
protect, but for different ICH SPI variants.

> +               if (ret)
> +                       return ret;
> +       }
> +
>         ctlr->base = (void *)plat->mmio_base;
>         if (plat->ich_version == ICHV_7) {
>                 struct ich7_spi_regs *ich7_spi = ctlr->base;
> @@ -753,6 +766,25 @@ static int ich_init_controller(struct udevice *dev,
>         return 0;
>  }
>
> +static int ich_cache_bios_region(struct udevice *dev)
> +{
> +       ulong map_base;
> +       uint map_size;
> +       uint offset;
> +       ulong base;
> +       int ret;
> +
> +       ret = ich_get_mmap_bus(dev, &map_base, &map_size, &offset);
> +       if (ret)
> +               return ret;
> +
> +       base = (4ULL << 30) - map_size;
> +       mtrr_set_next_var(MTRR_TYPE_WRPROT, base, map_size);
> +       log_debug("BIOS cache base=%lx, size=%x\n", base, (uint)map_size);
> +
> +       return 0;
> +}
> +
>  static int ich_spi_probe(struct udevice *dev)
>  {
>         struct ich_spi_platdata *plat = dev_get_platdata(dev);
> @@ -766,10 +798,16 @@ static int ich_spi_probe(struct udevice *dev)
>         if (ret)
>                 return ret;
>
> -       ret = ich_protect_lockdown(dev);
> -       if (ret)
> -               return ret;
> -
> +       if (spl_phase() == PHASE_TPL) {
> +               /* Cache the BIOS to speed things up */
> +               ret = ich_cache_bios_region(dev);
> +               if (ret)
> +                       return ret;
> +       } else {
> +               ret = ich_protect_lockdown(dev);
> +               if (ret)
> +                       return ret;
> +       }
>         priv->cur_speed = priv->max_speed;
>
>         return 0;
> --

Regards,
Bin
Simon Glass Nov. 21, 2019, 1:50 p.m. UTC | #2
Hi Bin,

On Tue, 19 Nov 2019 at 07:52, Bin Meng <bmeng.cn@gmail.com> wrote:
>
> Hi Simon,
>
> On Mon, Oct 21, 2019 at 11:40 AM Simon Glass <sjg@chromium.org> wrote:
> >
> > In TPL we want to reduce code size and support running with CONFIG_PCI
> > disabled. Add special code to handle this using a fixed BAR programmed
> > into the SPI on boot. Also cache the SPI flash to speed up boot.
> >
> > Signed-off-by: Simon Glass <sjg@chromium.org>
> > ---
> >
> > Changes in v3: None
> > Changes in v2: None
> >
> >  drivers/spi/ich.c | 46 ++++++++++++++++++++++++++++++++++++++++++----
> >  1 file changed, 42 insertions(+), 4 deletions(-)
> >
> > diff --git a/drivers/spi/ich.c b/drivers/spi/ich.c
> > index ec0f77f6e40..daa69c25a3a 100644
> > --- a/drivers/spi/ich.c
> > +++ b/drivers/spi/ich.c
> > @@ -19,8 +19,10 @@
> >  #include <spi.h>
> >  #include <spi_flash.h>
> >  #include <spi-mem.h>
> > +#include <spl.h>
> >  #include <asm/fast_spi.h>
> >  #include <asm/io.h>
> > +#include <asm/mtrr.h>
> >
> >  #include "ich.h"
> >
> > @@ -114,6 +116,8 @@ static bool ich9_can_do_33mhz(struct udevice *dev)
> >  {
> >         u32 fdod, speed;
> >
> > +       if (!CONFIG_IS_ENABLED(PCI))
> > +               return false;
> >         /* Observe SPI Descriptor Component Section 0 */
> >         dm_pci_write_config32(dev->parent, 0xb0, 0x1000);
> >
> > @@ -705,6 +709,15 @@ static int ich_init_controller(struct udevice *dev,
> >                                struct ich_spi_platdata *plat,
> >                                struct ich_spi_priv *ctlr)
> >  {
> > +       if (spl_phase() == PHASE_TPL) {
> > +               struct ich_spi_platdata *plat = dev_get_platdata(dev);
> > +               int ret;
> > +
> > +               ret = fast_spi_early_init(plat->bdf, plat->mmio_base);
>
> Can we move the fast_spi_early_init() contents to ich_spi_probe(),
> where the bios_cntl register is programmed to disable the write
> protect for ICH_V7? This helps reading as it's disabling write
> protect, but for different ICH SPI variants.

That driver is not included in TPL. It adds about 7KB to code size and
puts us very close to the limit.

Regards,
Simon
diff mbox series

Patch

diff --git a/drivers/spi/ich.c b/drivers/spi/ich.c
index ec0f77f6e40..daa69c25a3a 100644
--- a/drivers/spi/ich.c
+++ b/drivers/spi/ich.c
@@ -19,8 +19,10 @@ 
 #include <spi.h>
 #include <spi_flash.h>
 #include <spi-mem.h>
+#include <spl.h>
 #include <asm/fast_spi.h>
 #include <asm/io.h>
+#include <asm/mtrr.h>
 
 #include "ich.h"
 
@@ -114,6 +116,8 @@  static bool ich9_can_do_33mhz(struct udevice *dev)
 {
 	u32 fdod, speed;
 
+	if (!CONFIG_IS_ENABLED(PCI))
+		return false;
 	/* Observe SPI Descriptor Component Section 0 */
 	dm_pci_write_config32(dev->parent, 0xb0, 0x1000);
 
@@ -705,6 +709,15 @@  static int ich_init_controller(struct udevice *dev,
 			       struct ich_spi_platdata *plat,
 			       struct ich_spi_priv *ctlr)
 {
+	if (spl_phase() == PHASE_TPL) {
+		struct ich_spi_platdata *plat = dev_get_platdata(dev);
+		int ret;
+
+		ret = fast_spi_early_init(plat->bdf, plat->mmio_base);
+		if (ret)
+			return ret;
+	}
+
 	ctlr->base = (void *)plat->mmio_base;
 	if (plat->ich_version == ICHV_7) {
 		struct ich7_spi_regs *ich7_spi = ctlr->base;
@@ -753,6 +766,25 @@  static int ich_init_controller(struct udevice *dev,
 	return 0;
 }
 
+static int ich_cache_bios_region(struct udevice *dev)
+{
+	ulong map_base;
+	uint map_size;
+	uint offset;
+	ulong base;
+	int ret;
+
+	ret = ich_get_mmap_bus(dev, &map_base, &map_size, &offset);
+	if (ret)
+		return ret;
+
+	base = (4ULL << 30) - map_size;
+	mtrr_set_next_var(MTRR_TYPE_WRPROT, base, map_size);
+	log_debug("BIOS cache base=%lx, size=%x\n", base, (uint)map_size);
+
+	return 0;
+}
+
 static int ich_spi_probe(struct udevice *dev)
 {
 	struct ich_spi_platdata *plat = dev_get_platdata(dev);
@@ -766,10 +798,16 @@  static int ich_spi_probe(struct udevice *dev)
 	if (ret)
 		return ret;
 
-	ret = ich_protect_lockdown(dev);
-	if (ret)
-		return ret;
-
+	if (spl_phase() == PHASE_TPL) {
+		/* Cache the BIOS to speed things up */
+		ret = ich_cache_bios_region(dev);
+		if (ret)
+			return ret;
+	} else {
+		ret = ich_protect_lockdown(dev);
+		if (ret)
+			return ret;
+	}
 	priv->cur_speed = priv->max_speed;
 
 	return 0;