Re: [RESEND v2 1/1] log: don't show function by default

2020-06-14 Thread Heinrich Schuchardt

On 6/7/20 8:50 PM, Heinrich Schuchardt wrote:

The name of the function emitting a log message may be of interest for a
developer but is distracting for normal users. See the example below:

 try_load_entry() Booting: Debian

Make the default format for log messages customizable. By default show
only the message text.

Signed-off-by: Heinrich Schuchardt 


Hello Simon,

thanks for accepting my other log related patches. I did not yet get any
feedback for this one. I would need it before upstreaming patches for
using log functions in the UEFI sub-system instead of printf().

My target is to collect log messages about the boot process on my syslog
server.

Best regards

Heinrich


---
v2:
adjust logging tests
adjust description of log command
---
  cmd/log.c |  2 +-
  common/Kconfig| 18 ++
  include/log.h | 12 +++-
  test/log/syslog_test.c| 20 ++--
  test/py/tests/test_log.py |  2 ++
  5 files changed, 46 insertions(+), 8 deletions(-)

diff --git a/cmd/log.c b/cmd/log.c
index 78352b2cb9..2c91545c0d 100644
--- a/cmd/log.c
+++ b/cmd/log.c
@@ -139,7 +139,7 @@ static char log_help_text[] =
"log format  - set log output format.  is a string where\n"
"\teach letter indicates something that should be displayed:\n"
"\tc=category, l=level, F=file, L=line number, f=function, m=msg\n"
-   "\tor 'default', equivalent to 'fm', or 'all' for all\n"
+   "\tor 'default', or 'all' for all\n"
"log rec   - "
"output a log record"
;
diff --git a/common/Kconfig b/common/Kconfig
index 7872bc46cd..60cae77f20 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -792,6 +792,24 @@ config TPL_LOG_CONSOLE

  endif

+config LOGF_FILE
+   bool "Show source file name in log messages by default"
+   help
+ Show the source file name in log messages by default. This value
+ can be overridden using the 'log format' command.
+
+config LOGF_LINE
+   bool "Show source line number in log messages by default"
+   help
+ Show the source line number in log messages by default. This value
+ can be overridden using the 'log format' command.
+
+config LOGF_FUNC
+   bool "Show function name in log messages by default"
+   help
+ Show the function name in log messages by default. This value can
+ be overridden using the 'log format' command.
+
  config LOG_ERROR_RETURN
bool "Log all functions which return an error"
help
diff --git a/include/log.h b/include/log.h
index df65398c04..ec471c3a01 100644
--- a/include/log.h
+++ b/include/log.h
@@ -411,7 +411,17 @@ enum log_fmt {
LOGF_MSG,

LOGF_COUNT,
-   LOGF_DEFAULT = (1 << LOGF_FUNC) | (1 << LOGF_MSG),
+   LOGF_DEFAULT =
+#ifdef CONFIG_LOGF_FILE
+   (1 << LOGF_FILE) |
+#endif
+#ifdef CONFIG_LOGF_LINE
+   (1 << LOGF_LINE) |
+#endif
+#ifdef CONFIG_LOGF_FUNC
+   (1 << LOGF_FUNC) |
+#endif
+   (1 << LOGF_MSG),
LOGF_ALL = 0x3f,
  };

diff --git a/test/log/syslog_test.c b/test/log/syslog_test.c
index 26536ebca7..d1dfd08581 100644
--- a/test/log/syslog_test.c
+++ b/test/log/syslog_test.c
@@ -21,6 +21,8 @@

  DECLARE_GLOBAL_DATA_PTR;

+#define LOGF_TEST ((1 << LOGF_FUNC) | (1 << LOGF_MSG))
+
  /**
   * struct sb_log_env - private data for sandbox ethernet driver
   *
@@ -102,7 +104,7 @@ static int log_test_syslog_err(struct unit_test_state *uts)
int old_log_level = gd->default_log_level;
struct sb_log_env env;

-   gd->log_fmt = LOGF_DEFAULT;
+   gd->log_fmt = LOGF_TEST;
gd->default_log_level = LOGL_INFO;
env_set("ethact", "eth@10002000");
env_set("log_hostname", "sandbox");
@@ -116,6 +118,7 @@ static int log_test_syslog_err(struct unit_test_state *uts)
/* Check that the callback function was called */
sandbox_eth_set_tx_handler(0, NULL);
gd->default_log_level = old_log_level;
+   gd->log_fmt = LOGF_DEFAULT;

return 0;
  }
@@ -132,7 +135,7 @@ static int log_test_syslog_warning(struct unit_test_state 
*uts)
int old_log_level = gd->default_log_level;
struct sb_log_env env;

-   gd->log_fmt = LOGF_DEFAULT;
+   gd->log_fmt = LOGF_TEST;
gd->default_log_level = LOGL_INFO;
env_set("ethact", "eth@10002000");
env_set("log_hostname", "sandbox");
@@ -147,6 +150,7 @@ static int log_test_syslog_warning(struct unit_test_state 
*uts)
/* Check that the callback function was called */
ut_assertnull(env.expected);
gd->default_log_level = old_log_level;
+   gd->log_fmt = LOGF_DEFAULT;

return 0;
  }
@@ -163,7 +167,7 @@ static int log_test_syslog_notice(struct unit_test_state 
*uts)
int old_log_level = gd->default_log_level;
struct sb_log_env env;

-   gd->log_fmt = LOGF_DEFAULT;
+   gd->log_fmt = LOGF_TEST;
  

[PATCH] ARM: rmobile: Increase PHY auto-negotiation timeout to 20s

2020-06-14 Thread Marek Vasut
The ethernet PHY on all known Gen3 boards takes a while to come out
of reset, increase the auto-negotiation timeout to prevent it from
timing out in case the ethernet is used right after the board was
reset.

Signed-off-by: Marek Vasut 
Cc: Nobuhiro Iwamatsu 
---
 include/configs/rcar-gen3-common.h | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/include/configs/rcar-gen3-common.h 
b/include/configs/rcar-gen3-common.h
index 8f400ba05a..cf4d3bad2e 100644
--- a/include/configs/rcar-gen3-common.h
+++ b/include/configs/rcar-gen3-common.h
@@ -34,6 +34,9 @@
 #define CONFIG_SYS_MAXARGS 64
 #define CONFIG_SYS_BAUDRATE_TABLE  { 115200, 38400 }
 
+/* PHY needs a longer autoneg timeout */
+#define PHY_ANEG_TIMEOUT   2
+
 /* MEMORY */
 #define CONFIG_SYS_INIT_SP_ADDRCONFIG_SYS_TEXT_BASE
 
-- 
2.26.2



Re: [PATCH v2] arm: dts: socfpga: cyclone5: Update i2c-scl-falling-time-ns

2020-06-14 Thread Marek Vasut
On 6/10/20 7:24 AM, Ley Foon Tan wrote:
> Commit e71b6f6622d6 ("i2c: designware_i2c: Rewrite timing calculation")
> change the hcnt and lcnt timing calculation. New timing calculation is
> based on calculation from Designware i2c databook.
> 
> After this new timing calculation, hcnt will have negative value
> with i2c-scl-falling-time-ns 5000 that set in socfpga_cyclone5_socdk.dts.
> 
> This patch overwrite i2c-scl-falling-time-ns to 300ns (default SCL fall
> time used in Designware i2c driver) for Uboot.

Applied, thanks.


Re: [RESEND v2 1/1] log: don't show function by default

2020-06-14 Thread Simon Glass
Hi Heinrich,

On Sun, 14 Jun 2020 at 04:34, Heinrich Schuchardt  wrote:
>
> On 6/7/20 8:50 PM, Heinrich Schuchardt wrote:
> > The name of the function emitting a log message may be of interest for a
> > developer but is distracting for normal users. See the example below:
> >
> >  try_load_entry() Booting: Debian
> >
> > Make the default format for log messages customizable. By default show
> > only the message text.
> >
> > Signed-off-by: Heinrich Schuchardt 
>
> Hello Simon,
>
> thanks for accepting my other log related patches. I did not yet get any
> feedback for this one. I would need it before upstreaming patches for
> using log functions in the UEFI sub-system instead of printf().
>
> My target is to collect log messages about the boot process on my syslog
> server.

I think I emailed you about this one. Somehow I did not receive it by
email but noticed it in patchwork. Can you please do a resend?

Regards,
Simon


Re: [PATCH 0/2] omap4: panda: convert to device model

2020-06-14 Thread Lokesh Vutla
Hi Tero,

On 02/06/20 4:49 pm, Tero Kristo wrote:
> Hi,
> 
> As there is looming death to OMAP4 Panda board u-boot support, I decided
> to take a shot and convert it to device model myself. With these patches
> it boots up fine, and there are no DM_SPL conversion complaints during
> compile time anymore. I think USB ethernet does not work anymore with
> this, but its better than dropping the support for the board completely.
> USB itself appears working, so it should be relatively easy for someone
> to fix the networking support if they need it.

I see the below warning with these patches:

board/ti/panda/panda.c:329:35: warning: ‘struct ehci_hcor’ declared inside 
parameter list will not be visible outside of this definition or declaration
  329 |   struct ehci_hccr **hccr, struct ehci_hcor **hcor)
  |   ^
board/ti/panda/panda.c:329:10: warning: ‘struct ehci_hccr’ declared inside 
parameter list will not be visible outside of this definition or declaration
  329 |   struct ehci_hccr **hccr, struct ehci_hcor **hcor)
  |  ^
board/ti/panda/panda.c: In function ‘ehci_hcd_init’:
board/ti/panda/panda.c:339:8: warning: implicit declaration of function 
‘omap_ehci_hcd_init’; did you mean ‘ehci_hcd_init’? 
[-Wimplicit-function-declaration]
  339 |  ret = omap_ehci_hcd_init(index, &usbhs_bdata, hccr, hcor);
  |^~
  |ehci_hcd_init
board/ti/panda/panda.c: In function ‘ehci_hcd_stop’:
board/ti/panda/panda.c:348:9: warning: implicit declaration of function 
‘omap_ehci_hcd_stop’; did you mean ‘ehci_hcd_stop’? 
[-Wimplicit-function-declaration]
  348 |  return omap_ehci_hcd_stop();
  | ^~
  | ehci_hcd_stop


Thanks and regards,
Lokesh


> 
> -Tero
> 
> 
> --
> Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. 
> Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
> 


RE: [v2 1/3] Watchdog: introduce ARM SBSA watchdog driver

2020-06-14 Thread Biwen Li (OSS)


> > According to Server Base System Architecture (SBSA) specification, the
> > SBSA Generic Watchdog has two stage timeouts: the first signal
> > (WS0) is for alerting the system by interrupt, the second one (WS1) is
> > a real hardware reset.
> > More details about the hardware specification of this device:
> > ARM DEN0029B - Server Base System Architecture (SBSA)
> >
> > This driver can operate ARM SBSA Generic Watchdog as a single stage In
> > the single stage mode, when the timeout is reached, your system will
> > be reset by WS1. The first signal (WS0) is ignored.
> >
> > Signed-off-by: Zhao Qiang 
> > Signed-off-by: Biwen Li 
> > ---
> > Change in v2:
> > - fix copyright
> >
> >   MAINTAINERS  |   1 +
> >   drivers/watchdog/Kconfig |   6 ++
> >   drivers/watchdog/Makefile|   1 +
> >   drivers/watchdog/sbsa_gwdt.c | 131
> +++
> >   4 files changed, 139 insertions(+)
> >   create mode 100644 drivers/watchdog/sbsa_gwdt.c
> >
> > diff --git a/MAINTAINERS b/MAINTAINERS index 1fd975c..09554c0 100644
> > --- a/MAINTAINERS
> > +++ b/MAINTAINERS
> > @@ -685,6 +685,7 @@ M:  Priyanka Jain 
> >   S:Maintained
> >   T:git 
> > https://gitlab.denx.de/u-boot/custodians/u-boot-fsl-qoriq.git
> >   F:drivers/watchdog/sp805_wdt.c
> > +F: drivers/watchdog/sbsa_gwdt.c
> >
> >   I2C
> >   M:Heiko Schocher 
> > diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index
> > bf06180..191891c 100644
> > --- a/drivers/watchdog/Kconfig
> > +++ b/drivers/watchdog/Kconfig
> > @@ -163,6 +163,12 @@ config WDT_SANDBOX
> >   can be probed and supports all of the methods of WDT, but does not
> >   really do anything.
> >
> > +config WDT_SBSA
> > +   bool "SBSA watchdog timer support"
> > +   depends on WDT
> > +   help
> > +  Select this to enable SBSA watchdog timer.
> 
> Please extend this help text a bit (add something from the commit text) to
> make it more descriptive.
Okay, it will be updated in v3.
> 
> > +
> >   config WDT_SP805
> > bool "SP805 watchdog timer support"
> > depends on WDT
> > diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
> > index 519bbd3..0f0b2eb 100644
> > --- a/drivers/watchdog/Makefile
> > +++ b/drivers/watchdog/Makefile
> > @@ -27,6 +27,7 @@ obj-$(CONFIG_WDT_MPC8xx) += mpc8xx_wdt.o
> >   obj-$(CONFIG_WDT_MT7621) += mt7621_wdt.o
> >   obj-$(CONFIG_WDT_MTK) += mtk_wdt.o
> >   obj-$(CONFIG_WDT_OMAP3) += omap_wdt.o
> > +obj-$(CONFIG_WDT_SBSA) += sbsa_gwdt.o
> >   obj-$(CONFIG_WDT_SP805) += sp805_wdt.o
> >   obj-$(CONFIG_WDT_STM32MP) += stm32mp_wdt.o
> >   obj-$(CONFIG_WDT_TANGIER) += tangier_wdt.o diff --git
> > a/drivers/watchdog/sbsa_gwdt.c b/drivers/watchdog/sbsa_gwdt.c new file
> > mode 100644 index 000..ddac668
> > --- /dev/null
> > +++ b/drivers/watchdog/sbsa_gwdt.c
> > @@ -0,0 +1,131 @@
> > +// SPDX-License-Identifier: GPL-2.0+
> > +/*
> > + * Watchdog driver for SBSA
> > + *
> > + * Copyright 2020 NXP
> > + */
> > +
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +
> > +DECLARE_GLOBAL_DATA_PTR;
> > +
> > +/* SBSA Generic Watchdog register definitions */
> > +/* refresh frame */
> > +#define SBSA_GWDT_WRR  0x000
> > +
> > +/* control frame */
> > +#define SBSA_GWDT_WCS  0x000
> > +#define SBSA_GWDT_WOR  0x008
> > +#define SBSA_GWDT_WCV  0x010
> > +
> > +/* refresh/control frame */
> > +#define SBSA_GWDT_W_IIDR   0xfcc
> > +#define SBSA_GWDT_IDR  0xfd0
> > +
> > +/* Watchdog Control and Status Register */
> > +#define SBSA_GWDT_WCS_EN   BIT(0)
> > +#define SBSA_GWDT_WCS_WS0  BIT(1)
> > +#define SBSA_GWDT_WCS_WS1  BIT(2)
> > +
> > +struct sbsa_gwdt_priv {
> > +   void __iomem *reg_refresh;
> > +   void __iomem *reg_control;
> > +};
> > +
> > +static int sbsa_gwdt_reset(struct udevice *dev) {
> > +   struct sbsa_gwdt_priv *priv = dev_get_priv(dev);
> > +
> > +   writel(0, priv->reg_refresh + SBSA_GWDT_WRR);
> > +
> > +   return 0;
> > +}
> > +
> > +static int sbsa_gwdt_start(struct udevice *dev, u64 timeout, ulong
> > +flags) {
> > +   u32 clk;
> > +   u32 load_value;
> > +
> > +   struct sbsa_gwdt_priv *priv = dev_get_priv(dev);
> 
> Nitpicking:
> 
> Remove empty line above and add sone below the variable declarations
> (reverse x-max tree is preferred):
> 
>   struct sbsa_gwdt_priv *priv = dev_get_priv(dev);
>   u32 load_value;
>   u32 clk;
Okay, it will be updated in v3.
> 
> Other than that:
> 
> Reviewed-by: Stefan Roese 
> 
Okay, got it.

> Thanks,
> Stefan
> 
> > +   /*
> > +* it work in the single stage mode in u-boot,
> > +* The first signal (WS0) is ignored,
> > +* the timeout is (WOR * 2), so the WOR should be configured
> > +* to half value of timeout.
> > +*/
> > +   clk = get_tbclk();
> > +   writel(clk / 2 * timeout,
> > +  priv->reg_control + SBSA_GWDT_WOR);

[PATCH RESEND v2 1/1] log: don't show function by default

2020-06-14 Thread Heinrich Schuchardt
The name of the function emitting a log message may be of interest for a
developer but is distracting for normal users. See the example below:

try_load_entry() Booting: Debian

Make the default format for log messages customizable. By default show
only the message text.

Signed-off-by: Heinrich Schuchardt 
---
v2:
adjust logging tests
adjust description of log command
---
 cmd/log.c |  2 +-
 common/Kconfig| 18 ++
 include/log.h | 12 +++-
 test/log/syslog_test.c| 20 ++--
 test/py/tests/test_log.py |  2 ++
 5 files changed, 46 insertions(+), 8 deletions(-)

diff --git a/cmd/log.c b/cmd/log.c
index 78352b2cb9..2c91545c0d 100644
--- a/cmd/log.c
+++ b/cmd/log.c
@@ -139,7 +139,7 @@ static char log_help_text[] =
"log format  - set log output format.  is a string where\n"
"\teach letter indicates something that should be displayed:\n"
"\tc=category, l=level, F=file, L=line number, f=function, m=msg\n"
-   "\tor 'default', equivalent to 'fm', or 'all' for all\n"
+   "\tor 'default', or 'all' for all\n"
"log rec   - "
"output a log record"
;
diff --git a/common/Kconfig b/common/Kconfig
index 7872bc46cd..60cae77f20 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -792,6 +792,24 @@ config TPL_LOG_CONSOLE

 endif

+config LOGF_FILE
+   bool "Show source file name in log messages by default"
+   help
+ Show the source file name in log messages by default. This value
+ can be overridden using the 'log format' command.
+
+config LOGF_LINE
+   bool "Show source line number in log messages by default"
+   help
+ Show the source line number in log messages by default. This value
+ can be overridden using the 'log format' command.
+
+config LOGF_FUNC
+   bool "Show function name in log messages by default"
+   help
+ Show the function name in log messages by default. This value can
+ be overridden using the 'log format' command.
+
 config LOG_ERROR_RETURN
bool "Log all functions which return an error"
help
diff --git a/include/log.h b/include/log.h
index df65398c04..ec471c3a01 100644
--- a/include/log.h
+++ b/include/log.h
@@ -411,7 +411,17 @@ enum log_fmt {
LOGF_MSG,

LOGF_COUNT,
-   LOGF_DEFAULT = (1 << LOGF_FUNC) | (1 << LOGF_MSG),
+   LOGF_DEFAULT =
+#ifdef CONFIG_LOGF_FILE
+   (1 << LOGF_FILE) |
+#endif
+#ifdef CONFIG_LOGF_LINE
+   (1 << LOGF_LINE) |
+#endif
+#ifdef CONFIG_LOGF_FUNC
+   (1 << LOGF_FUNC) |
+#endif
+   (1 << LOGF_MSG),
LOGF_ALL = 0x3f,
 };

diff --git a/test/log/syslog_test.c b/test/log/syslog_test.c
index 26536ebca7..d1dfd08581 100644
--- a/test/log/syslog_test.c
+++ b/test/log/syslog_test.c
@@ -21,6 +21,8 @@

 DECLARE_GLOBAL_DATA_PTR;

+#define LOGF_TEST ((1 << LOGF_FUNC) | (1 << LOGF_MSG))
+
 /**
  * struct sb_log_env - private data for sandbox ethernet driver
  *
@@ -102,7 +104,7 @@ static int log_test_syslog_err(struct unit_test_state *uts)
int old_log_level = gd->default_log_level;
struct sb_log_env env;

-   gd->log_fmt = LOGF_DEFAULT;
+   gd->log_fmt = LOGF_TEST;
gd->default_log_level = LOGL_INFO;
env_set("ethact", "eth@10002000");
env_set("log_hostname", "sandbox");
@@ -116,6 +118,7 @@ static int log_test_syslog_err(struct unit_test_state *uts)
/* Check that the callback function was called */
sandbox_eth_set_tx_handler(0, NULL);
gd->default_log_level = old_log_level;
+   gd->log_fmt = LOGF_DEFAULT;

return 0;
 }
@@ -132,7 +135,7 @@ static int log_test_syslog_warning(struct unit_test_state 
*uts)
int old_log_level = gd->default_log_level;
struct sb_log_env env;

-   gd->log_fmt = LOGF_DEFAULT;
+   gd->log_fmt = LOGF_TEST;
gd->default_log_level = LOGL_INFO;
env_set("ethact", "eth@10002000");
env_set("log_hostname", "sandbox");
@@ -147,6 +150,7 @@ static int log_test_syslog_warning(struct unit_test_state 
*uts)
/* Check that the callback function was called */
ut_assertnull(env.expected);
gd->default_log_level = old_log_level;
+   gd->log_fmt = LOGF_DEFAULT;

return 0;
 }
@@ -163,7 +167,7 @@ static int log_test_syslog_notice(struct unit_test_state 
*uts)
int old_log_level = gd->default_log_level;
struct sb_log_env env;

-   gd->log_fmt = LOGF_DEFAULT;
+   gd->log_fmt = LOGF_TEST;
gd->default_log_level = LOGL_INFO;
env_set("ethact", "eth@10002000");
env_set("log_hostname", "sandbox");
@@ -178,6 +182,7 @@ static int log_test_syslog_notice(struct unit_test_state 
*uts)
/* Check that the callback function was called */
ut_assertnull(env.expected);
gd->default_log_level = old_log_level;
+   gd->log_fmt = LOGF_DEFAULT;


[PATCH] dm: core: Correct comment on uclass_id_foreach_dev()

2020-06-14 Thread Simon Glass
This parameter should be a struct uclass, not struct udevice. Correct it.

Signed-off-by: Simon Glass 
---

 include/dm/uclass.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/dm/uclass.h b/include/dm/uclass.h
index 70fca79b44..67ff7466c8 100644
--- a/include/dm/uclass.h
+++ b/include/dm/uclass.h
@@ -390,7 +390,7 @@ int uclass_resolve_seq(struct udevice *dev);
  * @id: enum uclass_id ID to use
  * @pos: struct udevice * to hold the current device. Set to NULL when there
  * are no more devices.
- * @uc: temporary uclass variable (struct udevice *)
+ * @uc: temporary uclass variable (struct uclass *)
  */
 #define uclass_id_foreach_dev(id, pos, uc) \
if (!uclass_get(id, &uc)) \
-- 
2.27.0.290.gba653c62da-goog



Re: [PATCH] dm: core: Correct comment on uclass_id_foreach_dev()

2020-06-14 Thread Michael Nazzareno Trimarchi
On Sun, Jun 14, 2020 at 4:49 PM Simon Glass  wrote:
>
> This parameter should be a struct uclass, not struct udevice. Correct it.
>
> Signed-off-by: Simon Glass 
> ---
>
>  include/dm/uclass.h | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/include/dm/uclass.h b/include/dm/uclass.h
> index 70fca79b44..67ff7466c8 100644
> --- a/include/dm/uclass.h
> +++ b/include/dm/uclass.h
> @@ -390,7 +390,7 @@ int uclass_resolve_seq(struct udevice *dev);
>   * @id: enum uclass_id ID to use
>   * @pos: struct udevice * to hold the current device. Set to NULL when there
>   * are no more devices.
> - * @uc: temporary uclass variable (struct udevice *)
> + * @uc: temporary uclass variable (struct uclass *)
>   */
>  #define uclass_id_foreach_dev(id, pos, uc) \
> if (!uclass_get(id, &uc)) \
> --
> 2.27.0.290.gba653c62da-goog
>

Reviewed-By: Michael Trimarchi 


-- 
| Michael Nazzareno Trimarchi Amarula Solutions BV |
| COO  -  Founder  Cruquiuskade 47 |
| +31(0)851119172 Amsterdam 1018 AM NL |
|  [`as] http://www.amarulasolutions.com   |


[v3 1/3] Watchdog: introduce ARM SBSA watchdog driver

2020-06-14 Thread Biwen Li
From: Zhao Qiang 

According to Server Base System Architecture (SBSA) specification,
the SBSA Generic Watchdog has two stage timeouts: the first signal
(WS0) is for alerting the system by interrupt, the second one (WS1) is a
real hardware reset.
More details about the hardware specification of this device:
ARM DEN0029B - Server Base System Architecture (SBSA)

This driver can operate ARM SBSA Generic Watchdog as a single stage
In the single stage mode, when the timeout is reached, your system
will be reset by WS1. The first signal (WS0) is ignored.

Signed-off-by: Zhao Qiang 
Signed-off-by: Biwen Li 
Reviewed-by: Stefan Roese 
---
Change in v3:
- add description
- remove empty line

Change in v2:
- fix copyright

 MAINTAINERS  |   1 +
 drivers/watchdog/Kconfig |   9 +++
 drivers/watchdog/Makefile|   1 +
 drivers/watchdog/sbsa_gwdt.c | 131 +++
 4 files changed, 142 insertions(+)
 create mode 100644 drivers/watchdog/sbsa_gwdt.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 1fd975c..09554c0 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -685,6 +685,7 @@ M:  Priyanka Jain 
 S: Maintained
 T: git https://gitlab.denx.de/u-boot/custodians/u-boot-fsl-qoriq.git
 F: drivers/watchdog/sp805_wdt.c
+F: drivers/watchdog/sbsa_gwdt.c
 
 I2C
 M: Heiko Schocher 
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index bf06180..6d5c4fc 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -163,6 +163,15 @@ config WDT_SANDBOX
  can be probed and supports all of the methods of WDT, but does not
  really do anything.
 
+config WDT_SBSA
+   bool "SBSA watchdog timer support"
+   depends on WDT
+   help
+  Select this to enable SBSA watchdog timer.
+  This driver can operate ARM SBSA Generic Watchdog as a single stage.
+  In the single stage mode, when the timeout is reached, your system
+  will be reset by WS1. The first signal (WS0) is ignored.
+
 config WDT_SP805
bool "SP805 watchdog timer support"
depends on WDT
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index 519bbd3..0f0b2eb 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -27,6 +27,7 @@ obj-$(CONFIG_WDT_MPC8xx) += mpc8xx_wdt.o
 obj-$(CONFIG_WDT_MT7621) += mt7621_wdt.o
 obj-$(CONFIG_WDT_MTK) += mtk_wdt.o
 obj-$(CONFIG_WDT_OMAP3) += omap_wdt.o
+obj-$(CONFIG_WDT_SBSA) += sbsa_gwdt.o
 obj-$(CONFIG_WDT_SP805) += sp805_wdt.o
 obj-$(CONFIG_WDT_STM32MP) += stm32mp_wdt.o
 obj-$(CONFIG_WDT_TANGIER) += tangier_wdt.o
diff --git a/drivers/watchdog/sbsa_gwdt.c b/drivers/watchdog/sbsa_gwdt.c
new file mode 100644
index 000..ad5dc76
--- /dev/null
+++ b/drivers/watchdog/sbsa_gwdt.c
@@ -0,0 +1,131 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Watchdog driver for SBSA
+ *
+ * Copyright 2020 NXP
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* SBSA Generic Watchdog register definitions */
+/* refresh frame */
+#define SBSA_GWDT_WRR  0x000
+
+/* control frame */
+#define SBSA_GWDT_WCS  0x000
+#define SBSA_GWDT_WOR  0x008
+#define SBSA_GWDT_WCV  0x010
+
+/* refresh/control frame */
+#define SBSA_GWDT_W_IIDR   0xfcc
+#define SBSA_GWDT_IDR  0xfd0
+
+/* Watchdog Control and Status Register */
+#define SBSA_GWDT_WCS_EN   BIT(0)
+#define SBSA_GWDT_WCS_WS0  BIT(1)
+#define SBSA_GWDT_WCS_WS1  BIT(2)
+
+struct sbsa_gwdt_priv {
+   void __iomem *reg_refresh;
+   void __iomem *reg_control;
+};
+
+static int sbsa_gwdt_reset(struct udevice *dev)
+{
+   struct sbsa_gwdt_priv *priv = dev_get_priv(dev);
+
+   writel(0, priv->reg_refresh + SBSA_GWDT_WRR);
+
+   return 0;
+}
+
+static int sbsa_gwdt_start(struct udevice *dev, u64 timeout, ulong flags)
+{
+   struct sbsa_gwdt_priv *priv = dev_get_priv(dev);
+   u32 load_value;
+   u32 clk;
+
+   /*
+* it work in the single stage mode in u-boot,
+* The first signal (WS0) is ignored,
+* the timeout is (WOR * 2), so the WOR should be configured
+* to half value of timeout.
+*/
+   clk = get_tbclk();
+   writel(clk / 2 * timeout,
+  priv->reg_control + SBSA_GWDT_WOR);
+
+   /* writing WCS will cause an explicit watchdog refresh */
+   writel(SBSA_GWDT_WCS_EN, priv->reg_control + SBSA_GWDT_WCS);
+
+   return 0;
+}
+
+static int sbsa_gwdt_stop(struct udevice *dev)
+{
+   struct sbsa_gwdt_priv *priv = dev_get_priv(dev);
+
+   writel(0, priv->reg_control + SBSA_GWDT_WCS);
+
+   return 0;
+}
+
+static int sbsa_gwdt_expire_now(struct udevice *dev, ulong flags)
+{
+   sbsa_gwdt_start(dev, 0, flags);
+
+   return 0;
+}
+
+static int sbsa_gwdt_probe(struct udevice *dev)
+{
+   debug("%s: Probing wdt%u (sbsa-gwdt)\n", __func__, dev->seq);
+
+   

[v3 3/3] configs: lx2160a: Enable Watchdog support

2020-06-14 Thread Biwen Li
From: Zhao Qiang 

Enable support to compile SBSA driver.

Signed-off-by: Zhao Qiang 
---
Change in v3:
- none

Change in v2:
- none

 configs/lx2160aqds_tfa_defconfig | 3 +++
 configs/lx2160ardb_tfa_defconfig | 3 +++
 2 files changed, 6 insertions(+)

diff --git a/configs/lx2160aqds_tfa_defconfig b/configs/lx2160aqds_tfa_defconfig
index 716c089..93e6a05 100644
--- a/configs/lx2160aqds_tfa_defconfig
+++ b/configs/lx2160aqds_tfa_defconfig
@@ -29,6 +29,7 @@ CONFIG_CMD_I2C=y
 CONFIG_CMD_MMC=y
 CONFIG_CMD_PCI=y
 CONFIG_CMD_USB=y
+CONFIG_CMD_WDT=y
 CONFIG_CMD_CACHE=y
 CONFIG_MP=y
 CONFIG_OF_CONTROL=y
@@ -82,4 +83,6 @@ CONFIG_USB=y
 CONFIG_DM_USB=y
 CONFIG_USB_XHCI_HCD=y
 CONFIG_USB_XHCI_DWC3=y
+CONFIG_WDT=y
+CONFIG_WDT_SBSA=y
 CONFIG_EFI_LOADER_BOUNCE_BUFFER=y
diff --git a/configs/lx2160ardb_tfa_defconfig b/configs/lx2160ardb_tfa_defconfig
index bc654cf..8504a50 100644
--- a/configs/lx2160ardb_tfa_defconfig
+++ b/configs/lx2160ardb_tfa_defconfig
@@ -30,6 +30,7 @@ CONFIG_CMD_I2C=y
 CONFIG_CMD_MMC=y
 CONFIG_CMD_PCI=y
 CONFIG_CMD_USB=y
+CONFIG_CMD_WDT=y
 CONFIG_CMD_CACHE=y
 CONFIG_MP=y
 CONFIG_OF_CONTROL=y
@@ -76,4 +77,6 @@ CONFIG_USB=y
 CONFIG_DM_USB=y
 CONFIG_USB_XHCI_HCD=y
 CONFIG_USB_XHCI_DWC3=y
+CONFIG_WDT=y
+CONFIG_WDT_SBSA=y
 CONFIG_EFI_LOADER_BOUNCE_BUFFER=y
-- 
2.7.4



[v3 2/3] arm64: lx2160a: dts: Add watchdog node

2020-06-14 Thread Biwen Li
From: Zhao Qiang 

Add watchdog node which is sbsa into lx2160a dtsi

Signed-off-by: Zhao Qiang 
---
Change in v3:
- none

Change in v2:
- none

 arch/arm/dts/fsl-lx2160a.dtsi | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm/dts/fsl-lx2160a.dtsi b/arch/arm/dts/fsl-lx2160a.dtsi
index 1789da8..a2421f6 100644
--- a/arch/arm/dts/fsl-lx2160a.dtsi
+++ b/arch/arm/dts/fsl-lx2160a.dtsi
@@ -204,6 +204,13 @@
#interrupt-cells = <2>;
};
 
+   watchdog@23a {
+   compatible = "arm,sbsa-gwdt";
+   reg = <0x0 0x23a 0 0x1000>,
+ <0x0 0x239 0 0x1000>;
+   timeout-sec = <30>;
+   };
+
usb0: usb3@310 {
compatible = "fsl,layerscape-dwc3";
reg = <0x0 0x310 0x0 0x1>;
-- 
2.7.4



Re: [PATCH 2/2] [RFC] clk: stm32mp1: Handle SoC speed grade configs

2020-06-14 Thread Marek Vasut
On 5/13/20 11:12 AM, Patrick DELAUNAY wrote:
> Dear Marek,

Hi,

[...]

>> @@ -1783,6 +1800,11 @@ static int stm32mp1_clktree(struct udevice *dev)
>>  continue;
>>
>>  fracv = ofnode_read_u32_default(plloff[i], "frac", 0);
>> +if (!fracv) {
>> +fracv = ofnode_read_u32_default(plloff[i],
>> +stm32mp1_is_df() ? "frac-df" : 
>> "frac-ac",
>> +0);
>> +}
>>  pll_config(priv, i, pllcfg[i], fracv);
>>  ret = ofnode_read_u32_array(plloff[i], "csg", csg, PLLCSG_NB);
>>  if (!ret) {
>> --
>> 2.25.1
> 
> The 2 speed grade will be supported with OPP information and HW 
> support,present in kernel device tree (upstream in progress) 

Great, thanks!


[PULL] u-boot-usb/master

2020-06-14 Thread Marek Vasut
The following changes since commit be79009f3b9bbdbce283e67a865121e576d790ea:

  Merge tag 'u-boot-imx-20200609' of
https://gitlab.denx.de/u-boot/custodians/u-boot-imx (2020-06-09 09:17:24
-0400)

are available in the Git repository at:

  git://git.denx.de/u-boot-usb.git master

for you to fetch changes up to 65f7551b6e8e389ae6a6b43ccfd18da31258a9ba:

  eth/r8152: update the firmware (2020-06-14 13:36:29 +0200)


Hayes Wang (1):
  eth/r8152: update the firmware

 drivers/usb/eth/r8152.h|   8 ++
 drivers/usb/eth/r8152_fw.c | 481
+-
 2 files changed, 265 insertions(+), 224 deletions(-)


[PULL] u-boot-socfpga/master

2020-06-14 Thread Marek Vasut
The following changes since commit be79009f3b9bbdbce283e67a865121e576d790ea:

  Merge tag 'u-boot-imx-20200609' of
https://gitlab.denx.de/u-boot/custodians/u-boot-imx (2020-06-09 09:17:24
-0400)

are available in the Git repository at:

  git://git.denx.de/u-boot-socfpga.git master

for you to fetch changes up to a0bda1dd8382be57389833024ba40518ec098ac3:

  arm: dts: socfpga: cyclone5: Update i2c-scl-falling-time-ns
(2020-06-14 13:37:31 +0200)


Ley Foon Tan (1):
  arm: dts: socfpga: cyclone5: Update i2c-scl-falling-time-ns

 arch/arm/dts/socfpga_cyclone5_socdk-u-boot.dtsi | 4 
 1 file changed, 4 insertions(+)


Re: [PATCH 1/1] sunxi: Pine64-LTS: SMBIOS properties

2020-06-14 Thread Heinrich Schuchardt

On 6/1/20 6:20 PM, Heinrich Schuchardt wrote:

On 6/1/20 4:43 PM, André Przywara wrote:

On 01/06/2020 14:56, Heinrich Schuchardt wrote:

Provide accurate values of the manufacturer and the product name.

PINE Microsystems Inc. is referred to on https://www.pine64.org/contact/.


While this patch looks alright, I wonder if we can just use the "model"
property in the DT's root node, at least for the product name? This
would not only avoid every defconfig to be touched, but would also cover
all other platforms (at least ARM based ones, probably PPC and MIPS as
well).


The relevant code is in lib/smbios.c. For boards that follow the driver
model you could read the model node here. But that would unnecessarily
increase the code size of the resulting binary. I doubt this would find
Tom's sympathy. So you would have to generate the value at compile time.
I have no clue how to do that.

The model property for the PINE A64 LTS is "Pine64 LTS" while the board
is called "PINE A64-LTS" by the manufacturer
(https://www.pine64.org/devices/single-board-computers/pine-a64-lts/).
So this approach does not lead to the correct result.



The manufacturer is less straight-forward to handle generically, but the
string before the comma in the DT root's compatible property should give
a hint. The Linux kernel contains a machine readable list of those
prefixes: Documentation/devicetree/bindings/vendor-prefixes.yaml
So we could pick the vendor at compile time based on that.
Of course any config could still overwrite this.


SMBIOS_MANUFACTURER defaults to SYS_VENDOR which is defined as "sunxi".

The Linux vendor-prefix exists for ARM64 and is missing for the ARM
architecture. So this cannot be a general solution.

For the Pine64 A64-LTS the vendor-prefix is "allwinner". Neither "sunxi"
nor "Allwinner" is the manufacturer of the PINE A64-LTS board.

You have to set SMBIOS_MANUFACTURER on the board level.



Does that make sense?
If people agree, I could try to make a patch for that.


Please, reconsider the patch as is.


Hello Andr+e

any comments?

Best regards

Heinrich



Best regards

Heinrich



Cheers,
Andre.



Signed-off-by: Heinrich Schuchardt 
---
  configs/pine64-lts_defconfig | 2 ++
  1 file changed, 2 insertions(+)

diff --git a/configs/pine64-lts_defconfig b/configs/pine64-lts_defconfig
index ef108a1a31..a8ff34a376 100644
--- a/configs/pine64-lts_defconfig
+++ b/configs/pine64-lts_defconfig
@@ -8,8 +8,10 @@ CONFIG_DRAM_ZQ=3881949
  CONFIG_MMC0_CD_PIN=""
  CONFIG_MMC_SUNXI_SLOT_EXTRA=2
  CONFIG_SPL_SPI_SUNXI=y
+CONFIG_SMBIOS_PRODUCT_NAME="PINE A64-LTS"
  # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
  CONFIG_DEFAULT_DEVICE_TREE="sun50i-a64-pine64-lts"
  CONFIG_SUN8I_EMAC=y
  CONFIG_USB_EHCI_HCD=y
  CONFIG_USB_OHCI_HCD=y
+CONFIG_SMBIOS_MANUFACTURER="PINE Microsystems Inc."
--
2.26.2









Re: [PATCH 0/4] arm: fix clang build errors

2020-06-14 Thread Heinrich Schuchardt

On 5/27/20 8:04 PM, Heinrich Schuchardt wrote:

With this patch series most ARM boards both 32bit and 64bit can be built
using Clang 9.

On ARM systems gd is stored in register r9 or x18. When compiling with
clang gd is defined as a macro calling function gd_ptr(). So we can not
make assignments to gd. Fixes for the UEFI sub-system and lib/trace.c
are provided.

Incorrect argument sizes when accessing special registers with inline
assembly are fixed.


Hello Tom,

will you take this series via next?

https://patchwork.ozlabs.org/project/uboot/list/?series=179688

1/4 is already merged via an EFI pull request.

Best regards

Heinrich



Heinrich Schuchardt (4):
   efi_loader: allow compiling with clang
   trace: clang compatible handling of gd register
   arm: remove outdated comment concerning -ffixed-x18
   arm: use correct argument size of special registers

  arch/arm/include/asm/global_data.h | 13 +
  arch/arm/include/asm/system.h  | 10 ++
  lib/efi_loader/efi_boottime.c  | 10 +-
  lib/trace.c|  8 
  4 files changed, 24 insertions(+), 17 deletions(-)

--
2.26.2





Re: [PATCH 0/4] arm: fix clang build errors

2020-06-14 Thread Tom Rini
On Sun, Jun 14, 2020 at 05:51:21PM +0200, Heinrich Schuchardt wrote:

> On 5/27/20 8:04 PM, Heinrich Schuchardt wrote:
> > With this patch series most ARM boards both 32bit and 64bit can be built
> > using Clang 9.
> > 
> > On ARM systems gd is stored in register r9 or x18. When compiling with
> > clang gd is defined as a macro calling function gd_ptr(). So we can not
> > make assignments to gd. Fixes for the UEFI sub-system and lib/trace.c
> > are provided.
> > 
> > Incorrect argument sizes when accessing special registers with inline
> > assembly are fixed.
> 
> Hello Tom,
> 
> will you take this series via next?
> 
> https://patchwork.ozlabs.org/project/uboot/list/?series=179688
> 
> 1/4 is already merged via an EFI pull request.

Either -next or the MW when it opens itself.  As this doesn't look too
tricky overall it's not at the top of my TODO list for -next as I'm
focusing on longer outstanding or tricky thingy first.  Thanks!

-- 
Tom


signature.asc
Description: PGP signature


Re: Pull request: u-boot-spi/master

2020-06-14 Thread Tom Rini
On Thu, Jun 11, 2020 at 11:23:13PM +0530, Jagan Teki wrote:

> Hi Tom,
> 
> This PR is for next release.
> 
> I'm sending the PR for migration early hoping it can avoid conflicts 
> from your series or in general.
> 
> May be applied on next would help keep migrations changes inline.
> 
> Summary:
> - Drop davinci, mxs spi nondm code
> - Zap nondm soft_spi
> - Switch few board to DM_SPI
> - Drop omap3_pandora, pcm051 boards
> 
> Travis-CI:
> https://travis-ci.org/github/openedev/u-boot-amarula/builds/697164896
> 
> The following changes since commit be79009f3b9bbdbce283e67a865121e576d790ea:
> 
>   Merge tag 'u-boot-imx-20200609' of 
> https://gitlab.denx.de/u-boot/custodians/u-boot-imx (2020-06-09 09:17:24 
> -0400)
> 
> are available in the Git repository at:
> 
>   https://gitlab.denx.de/u-boot/custodians/u-boot-spi master
> 
> for you to fetch changes up to b45926fa1d5a1be2a55d0eb208bff8f04f00f875:
> 
>   am335x: sl50: Enable DM_SPI (2020-06-11 15:14:04 +0530)
> 

Applied to u-boot/master, thanks!

-- 
Tom


signature.asc
Description: PGP signature


Re: Please pull u-boot-dm/next

2020-06-14 Thread Tom Rini
On Fri, Jun 12, 2020 at 09:17:28PM -0600, Simon Glass wrote:

> Hi Tom,
> 
> This is for -next
> 
> But I based it on master to avoid pulling in other people's commits. I hope
> that works OK.
> 
> 
> The following changes since commit be79009f3b9bbdbce283e67a865121e576d790ea:
> 
>   Merge tag 'u-boot-imx-20200609' of
> https://gitlab.denx.de/u-boot/custodians/u-boot-imx (2020-06-09 09:17:24
> -0400)
> 
> are available in the Git repository at:
> 
>   git://git.denx.de/u-boot-dm.git tags/dm-pull-12jun20
> 
> for you to fetch changes up to cea8f2c995b9d87af6ef42f967402e1c8a3506db:
> 
>   doc: driver-model: fix typo in design.rst (2020-06-11 20:52:11 -0600)
> 

Applied to u-boot/master, thanks!

-- 
Tom


signature.asc
Description: PGP signature


[PATCH 1/5] patman: Rename test.py to test_checkpatch.py

2020-06-14 Thread Simon Glass
These tests check checkpatch.pl operation and can server as our tests for
the U-Boot-specific updates to that script. Rename the file and update
comments to indicate this.

Signed-off-by: Simon Glass 
---

 tools/patman/main.py | 4 ++--
 tools/patman/{test.py => test_checkpatch.py} | 7 +++
 2 files changed, 5 insertions(+), 6 deletions(-)
 rename tools/patman/{test.py => test_checkpatch.py} (98%)

diff --git a/tools/patman/main.py b/tools/patman/main.py
index 0974c84059..4a11f80db5 100755
--- a/tools/patman/main.py
+++ b/tools/patman/main.py
@@ -25,7 +25,7 @@ from patman import patchstream
 from patman import project
 from patman import settings
 from patman import terminal
-from patman import test
+from patman import test_checkpatch
 
 
 parser = OptionParser()
@@ -93,7 +93,7 @@ elif options.test:
 
 sys.argv = [sys.argv[0]]
 result = unittest.TestResult()
-for module in (test.TestPatch, func_test.TestFunctional):
+for module in (test_checkpatch.TestPatch, func_test.TestFunctional):
 suite = unittest.TestLoader().loadTestsFromTestCase(module)
 suite.run(result)
 
diff --git a/tools/patman/test.py b/tools/patman/test_checkpatch.py
similarity index 98%
rename from tools/patman/test.py
rename to tools/patman/test_checkpatch.py
index e7f709e34c..03ff576c9e 100644
--- a/tools/patman/test.py
+++ b/tools/patman/test_checkpatch.py
@@ -1,6 +1,8 @@
 # -*- coding: utf-8 -*-
 # SPDX-License-Identifier: GPL-2.0+
 #
+# Tests for U-Boot-specific checkpatch.pl features
+#
 # Copyright (c) 2011 The Chromium OS Authors.
 #
 
@@ -16,10 +18,7 @@ from patman import commit
 
 
 class TestPatch(unittest.TestCase):
-"""Test this program
-
-TODO: Write tests for the rest of the functionality
-"""
+"""Test the u_boot_line() function in checkpatch.pl"""
 
 def testBasic(self):
 """Test basic filter operation"""
-- 
2.27.0.290.gba653c62da-goog



[PATCH 2/5] patman: Add a test for the 'possible new uclass' check

2020-06-14 Thread Simon Glass
It is quite likely that the number of U-Boot-specific tests in
checkpatch.pl will increase over time. We should have tests for these to
avoid undefined behaviour and bugs being introduced, which might cause
people to ignore the warnings.

Add a simple new class that can generate a patch with a single-line
addition in it. Use that to add a test for one of the checkpatch checks.

Signed-off-by: Simon Glass 
---

 tools/patman/test_checkpatch.py | 77 +
 1 file changed, 77 insertions(+)

diff --git a/tools/patman/test_checkpatch.py b/tools/patman/test_checkpatch.py
index 03ff576c9e..e841b9abca 100644
--- a/tools/patman/test_checkpatch.py
+++ b/tools/patman/test_checkpatch.py
@@ -17,6 +17,74 @@ from patman import series
 from patman import commit
 
 
+class Line:
+def __init__(self, fname, text):
+self.fname = fname
+self.text = text
+
+
+class PatchMaker:
+def __init__(self):
+self.lines = []
+
+def add_line(self, fname, text):
+self.lines.append(Line(fname, text))
+
+def get_patch_text(self):
+base = '''From 125b77450f4c66b8fd9654319520bbe795c9ef31 Mon Sep 17 
00:00:00 2001
+From: Simon Glass 
+Date: Sun, 14 Jun 2020 09:45:14 -0600
+Subject: [PATCH] Test commit
+
+This is a test commit.
+
+Signed-off-by: Simon Glass 
+---
+
+'''
+lines = base.splitlines()
+
+# Create the diffstat
+change = 0
+insert = 0
+for line in self.lines:
+lines.append(' %s  | 1 +' % line.fname)
+change += 1
+insert += 1
+lines.append(' %d files changed, %d insertions(+)' % (change, insert))
+lines.append('')
+
+# Create the patch info for each file
+for line in self.lines:
+lines.append('diff --git a/%s b/%s' % (line.fname, line.fname))
+lines.append('index 7837d459f18..5ba7840f68e 100644')
+lines.append('--- a/%s' % line.fname)
+lines.append('+++ b/%s' % line.fname)
+lines += ('''@@ -121,6 +121,7 @@ enum uclass_id {
+   UCLASS_W1,  /* Dallas 1-Wire bus */
+   UCLASS_W1_EEPROM,   /* one-wire EEPROMs */
+   UCLASS_WDT, /* Watchdog Timer driver */
++%s
+
+   UCLASS_COUNT,
+   UCLASS_INVALID = -1,
+''' % line.text).splitlines()
+lines.append('---')
+lines.append('2.17.1')
+
+return '\n'.join(lines)
+
+def get_patch(self):
+inhandle, inname = tempfile.mkstemp()
+infd = os.fdopen(inhandle, 'w')
+infd.write(self.get_patch_text())
+infd.close()
+return inname
+
+def run_checkpatch(self):
+return checkpatch.CheckPatch(self.get_patch())
+
+
 class TestPatch(unittest.TestCase):
 """Test the u_boot_line() function in checkpatch.pl"""
 
@@ -280,6 +348,15 @@ index 000..2234c87
 self.assertEqual(result.lines, 62)
 os.remove(inf)
 
+def testUclass(self):
+"""Test for possible new uclass"""
+pm = PatchMaker()
+pm.add_line('include/dm/uclass-id.h', 'UCLASS_WIBBLE,')
+result = pm.run_checkpatch()
+self.assertEqual(result.warnings, 1)
+self.assertEqual(len(result.problems), 1)
+self.assertIn('Possible new uclass', result.problems[0]['msg'])
+
 
 if __name__ == "__main__":
 unittest.main()
-- 
2.27.0.290.gba653c62da-goog



[PATCH 0/5] patman: Add tests for U-Boot-specific checkpatch checks

2020-06-14 Thread Simon Glass


It is quite likely that the number of U-Boot-specific tests in
checkpatch.pl will increase over time. We should have tests for these to
avoid undefined behaviour and bugs being introduced, which might cause
people to ignore the warnings.

This series adds the tests and modifies one check to be more specific.


Simon Glass (5):
  patman: Rename test.py to test_checkpatch.py
  patman: Add a test for the 'possible new uclass' check
  patman: Decode output from the '--show-types' option
  patman: Add tests for the rest of the checkpatch checks
  checkpatch: Don't warn about PREFER_IF in headers/DT files

 scripts/checkpatch.pl|   2 +-
 tools/patman/checkpatch.py   |  24 ++--
 tools/patman/main.py |   4 +-
 tools/patman/{test.py => test_checkpatch.py} | 125 ++-
 4 files changed, 139 insertions(+), 16 deletions(-)
 rename tools/patman/{test.py => test_checkpatch.py} (69%)

-- 
2.27.0.290.gba653c62da-goog



[PATCH 5/5] checkpatch: Don't warn about PREFER_IF in headers/DT files

2020-06-14 Thread Simon Glass
This warning should only be displayed for C files. Fix it and update the
test.

Signed-off-by: Simon Glass 
---

 scripts/checkpatch.pl   | 2 +-
 tools/patman/test_checkpatch.py | 2 ++
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index edba365651..5731cd221e 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -2263,7 +2263,7 @@ sub u_boot_line {
}
 
# use if instead of #if
-   if ($line =~ /^\+#if.*CONFIG.*/) {
+   if ($realfile =~ /\.c$/ && $line =~ /^\+#if.*CONFIG.*/) {
WARN("PREFER_IF",
 "Use 'if (IS_ENABLED(CONFIG...))' instead of '#if or 
#ifdef' where possible\n" . $herecurr);
}
diff --git a/tools/patman/test_checkpatch.py b/tools/patman/test_checkpatch.py
index 710b4a7d88..c9580adb54 100644
--- a/tools/patman/test_checkpatch.py
+++ b/tools/patman/test_checkpatch.py
@@ -388,6 +388,8 @@ index 000..2234c87
 """Test for Use the livetree API"""
 pm = PatchMaker()
 pm.add_line('common/main.c', '#ifdef CONFIG_YELLOW')
+pm.add_line('common/init.h', '#ifdef CONFIG_YELLOW')
+pm.add_line('fred.dtsi', '#ifdef CONFIG_YELLOW')
 self.checkSingleMessage(pm, "PREFER_IF")
 
 def testCommandUseDefconfig(self):
-- 
2.27.0.290.gba653c62da-goog



[PATCH 4/5] patman: Add tests for the rest of the checkpatch checks

2020-06-14 Thread Simon Glass
Finish off the tests for our small collection of checkpatch checks.

Signed-off-by: Simon Glass 
---

 tools/patman/test_checkpatch.py | 47 ++---
 1 file changed, 43 insertions(+), 4 deletions(-)

diff --git a/tools/patman/test_checkpatch.py b/tools/patman/test_checkpatch.py
index 7f40133b33..710b4a7d88 100644
--- a/tools/patman/test_checkpatch.py
+++ b/tools/patman/test_checkpatch.py
@@ -348,14 +348,53 @@ index 000..2234c87
 self.assertEqual(result.lines, 62)
 os.remove(inf)
 
+def checkSingleMessage(self, pm, msg, pmtype = 'warning'):
+"""Helper function to run checkpatch and check the result
+
+Args:
+pm: PatchMaker object to use
+msg" Expected message (e.g. 'LIVETREE')
+pmtype: Type of problem ('error', 'warning')
+"""
+result = pm.run_checkpatch()
+if pmtype == 'warning':
+self.assertEqual(result.warnings, 1)
+elif pmtype == 'error':
+self.assertEqual(result.errors, 1)
+if len(result.problems) != 1:
+print(result.problems)
+self.assertEqual(len(result.problems), 1)
+self.assertIn(msg, result.problems[0]['cptype'])
+
 def testUclass(self):
 """Test for possible new uclass"""
 pm = PatchMaker()
 pm.add_line('include/dm/uclass-id.h', 'UCLASS_WIBBLE,')
-result = pm.run_checkpatch()
-self.assertEqual(result.warnings, 1)
-self.assertEqual(len(result.problems), 1)
-self.assertIn('NEW_UCLASS', result.problems[0]['cptype'])
+self.checkSingleMessage(pm, 'NEW_UCLASS')
+
+def testLivetree(self):
+"""Test for Use the livetree API"""
+pm = PatchMaker()
+pm.add_line('common/main.c', 'fdtdec_do_something()')
+self.checkSingleMessage(pm, 'LIVETREE')
+
+def testNewCommand(self):
+"""Test for Use the livetree API"""
+pm = PatchMaker()
+pm.add_line('common/main.c', 'do_wibble(struct cmd_tbl *cmd_tbl)')
+self.checkSingleMessage(pm, 'CMD_TEST')
+
+def testNewCommand(self):
+"""Test for Use the livetree API"""
+pm = PatchMaker()
+pm.add_line('common/main.c', '#ifdef CONFIG_YELLOW')
+self.checkSingleMessage(pm, "PREFER_IF")
+
+def testCommandUseDefconfig(self):
+"""Test for Use the livetree API"""
+pm = PatchMaker()
+pm.add_line('common/main.c', '#undef CONFIG_CMD_WHICH')
+self.checkSingleMessage(pm, 'DEFINE_CONFIG_CMD', 'error')
 
 
 if __name__ == "__main__":
-- 
2.27.0.290.gba653c62da-goog



[PATCH 3/5] patman: Decode output from the '--show-types' option

2020-06-14 Thread Simon Glass
Collect the 'checkpatch type' from each error, warning and check. Provide
this to patman and update the uclass test to use it.

Signed-off-by: Simon Glass 
---

 tools/patman/checkpatch.py  | 24 +++-
 tools/patman/test_checkpatch.py |  4 ++--
 2 files changed, 17 insertions(+), 11 deletions(-)

diff --git a/tools/patman/checkpatch.py b/tools/patman/checkpatch.py
index 98c63af1dd..07c3e2739a 100644
--- a/tools/patman/checkpatch.py
+++ b/tools/patman/checkpatch.py
@@ -38,7 +38,7 @@ def FindCheckPatch():
 sys.exit('Cannot find checkpatch.pl - please put it in your ' +
  '~/bin directory or use --no-check')
 
-def CheckPatch(fname, verbose=False):
+def CheckPatch(fname, verbose=False, show_types=False):
 """Run checkpatch.pl on a file.
 
 Returns:
@@ -64,8 +64,10 @@ def CheckPatch(fname, verbose=False):
 result.problems = []
 chk = FindCheckPatch()
 item = {}
-result.stdout = command.Output(chk, '--no-tree', fname,
-   raise_on_error=False)
+args = [chk, '--no-tree']
+if show_types:
+args.append('--show-types')
+result.stdout = command.Output(*args, fname, raise_on_error=False)
 #pipe = subprocess.Popen(cmd, stdout=subprocess.PIPE)
 #stdout, stderr = pipe.communicate()
 
@@ -81,9 +83,10 @@ def CheckPatch(fname, verbose=False):
' checks, (\d+)')
 re_ok = re.compile('.*has no obvious style problems')
 re_bad = re.compile('.*has style problems, please review')
-re_error = re.compile('ERROR: (.*)')
-re_warning = re.compile(emacs_prefix + 'WARNING:(?:[A-Z_]+:)? (.*)')
-re_check = re.compile('CHECK: (.*)')
+type_name = '([A-Z_]+:)?'
+re_error = re.compile('ERROR:%s (.*)' % type_name)
+re_warning = re.compile(emacs_prefix + 'WARNING:%s (.*)' % type_name)
+re_check = re.compile('CHECK:%s (.*)' % type_name)
 re_file = re.compile('#\d+: FILE: ([^:]*):(\d+):')
 re_note = re.compile('NOTE: (.*)')
 indent = ' ' * 6
@@ -129,13 +132,16 @@ def CheckPatch(fname, verbose=False):
 check_match = re_check.match(line)
 subject_match = line.startswith('Subject:')
 if err_match:
-item['msg'] = err_match.group(1)
+item['cptype'] = err_match.group(1)
+item['msg'] = err_match.group(2)
 item['type'] = 'error'
 elif warn_match:
-item['msg'] = warn_match.group(1)
+item['cptype'] = warn_match.group(1)
+item['msg'] = warn_match.group(2)
 item['type'] = 'warning'
 elif check_match:
-item['msg'] = check_match.group(1)
+item['cptype'] = check_match.group(1)
+item['msg'] = check_match.group(2)
 item['type'] = 'check'
 elif file_match:
 item['file'] = file_match.group(1)
diff --git a/tools/patman/test_checkpatch.py b/tools/patman/test_checkpatch.py
index e841b9abca..7f40133b33 100644
--- a/tools/patman/test_checkpatch.py
+++ b/tools/patman/test_checkpatch.py
@@ -82,7 +82,7 @@ Signed-off-by: Simon Glass 
 return inname
 
 def run_checkpatch(self):
-return checkpatch.CheckPatch(self.get_patch())
+return checkpatch.CheckPatch(self.get_patch(), show_types=True)
 
 
 class TestPatch(unittest.TestCase):
@@ -355,7 +355,7 @@ index 000..2234c87
 result = pm.run_checkpatch()
 self.assertEqual(result.warnings, 1)
 self.assertEqual(len(result.problems), 1)
-self.assertIn('Possible new uclass', result.problems[0]['msg'])
+self.assertIn('NEW_UCLASS', result.problems[0]['cptype'])
 
 
 if __name__ == "__main__":
-- 
2.27.0.290.gba653c62da-goog



[PATCH v2 00/25] x86: Enhance MTRR functionality to support multiple CPUs

2020-06-14 Thread Simon Glass
At present MTRRs are mirrored to the secondary CPUs only once, as those
CPUs are started up. But U-Boot may add more MTRRs later, e.g. if it
decides that a video console must be set up.

This series enhances the x86 multi-processor support to allow MTRRs to
be updated at any time. It also updates the 'mtrr' command to support
setting the MTRRs on CPUs other than the boot CPU.

Changes in v2:
- Add comments to explain what start_aps() does
- Drop change to include/dm/uclass.h
- Mention error return in get_bsp()
- Add more comments
- Add a comment to run_ap_work()
- Rename mtrr_save_all() to mtrr_read_all()
- Add a new patch to avoid enabling SMP in SPL
- Add new patch to add AP_DEFAULT_BASE to coral's memory map
- Rename function to mtrr_write_all()
- Keep things building by temporarily renaming the function in cmd/
- Drop the renamed mtrr_set_valid_() instead of mtrr_set_valid()
- Add a new patch with more comments

Simon Glass (25):
  x86: mp_init: Switch to livetree
  x86: Move MP code into mp_init
  x86: mp_init: Avoid declarations in header files
  x86: mp_init: Switch parameter names in start_aps()
  x86: mp_init: Drop the num_cpus static variable
  x86: mtrr: Fix 'ensable' typo
  x86: mp_init: Set up the CPU numbers at the start
  x86: mp_init: Adjust bsp_init() to return more information
  x86: cpu: Remove unnecessary #ifdefs
  x86: mp: Support APs waiting for instructions
  global_data: Add a generic global_data flag for SMP state
  x86: Set the SMP flag when MP init is complete
  x86: mp: Allow running functions on multiple CPUs
  x86: mp: Park CPUs before running the OS
  x86: mp: Add iterators for CPUs
  x86: mtrr: Use MP calls to list the MTRRs
  x86: Don't enable SMP in SPL
  x86: coral: Update the memory map
  x86: mtrr: Update MTRRs on all CPUs
  x86: mtrr: Add support for writing to MTRRs on any CPU
  x86: mtrr: Update the command to use the new mtrr calls
  x86: mtrr: Restructure so command execution is in one place
  x86: mtrr: Update 'mtrr' to allow setting MTRRs on any CPU
  x86: mp: Add more comments to the module
  x86: mtrr: Enhance 'mtrr' command to list MTRRs on any CPU

 arch/x86/cpu/Makefile |   2 +-
 arch/x86/cpu/cpu.c|  63 ++--
 arch/x86/cpu/i386/cpu.c   |  26 +-
 arch/x86/cpu/mp_init.c| 520 ++
 arch/x86/cpu/mtrr.c   | 149 
 arch/x86/include/asm/mp.h | 132 ++-
 arch/x86/include/asm/mtrr.h   |  51 +++
 cmd/x86/mtrr.c| 148 +---
 doc/board/google/chromebook_coral.rst |   1 +
 include/asm-generic/global_data.h |   1 +
 10 files changed, 904 insertions(+), 189 deletions(-)

-- 
2.27.0.290.gba653c62da-goog



[PATCH v2 04/25] x86: mp_init: Switch parameter names in start_aps()

2020-06-14 Thread Simon Glass
These parameters are named differently from elsewhere in this file. Switch
them to avoid confusion.

Also add comments to this function.

Signed-off-by: Simon Glass 
---

Changes in v2:
- Add comments to explain what start_aps() does

 arch/x86/cpu/mp_init.c | 25 +++--
 1 file changed, 19 insertions(+), 6 deletions(-)

diff --git a/arch/x86/cpu/mp_init.c b/arch/x86/cpu/mp_init.c
index e77d7f2cd6..8b00d57c88 100644
--- a/arch/x86/cpu/mp_init.c
+++ b/arch/x86/cpu/mp_init.c
@@ -308,13 +308,26 @@ static int apic_wait_timeout(int total_delay, const char 
*msg)
return 0;
 }
 
-static int start_aps(int ap_count, atomic_t *num_aps)
+/**
+ * start_aps() - Start up the APs and count how many we find
+ *
+ * This is called on the boot processor to start up all the other processors
+ * (here called APs).
+ *
+ * @num_aps: Number of APs we expect to find
+ * @ap_count: Initially zero. Incremented by this function for each AP found
+ * @return 0 if all APs were set up correctly or there are none to set up,
+ * -ENOSPC if the SIPI vector is too high in memory,
+ * -ETIMEDOUT if the ICR is busy or the second SIPI fails to complete
+ * -EIO if not all APs check in correctly
+ */
+static int start_aps(int num_aps, atomic_t *ap_count)
 {
int sipi_vector;
/* Max location is 4KiB below 1MiB */
const int max_vector_loc = ((1 << 20) - (1 << 12)) >> 12;
 
-   if (ap_count == 0)
+   if (num_aps == 0)
return 0;
 
/* The vector is sent as a 4k aligned address in one byte */
@@ -326,7 +339,7 @@ static int start_aps(int ap_count, atomic_t *num_aps)
return -ENOSPC;
}
 
-   debug("Attempting to start %d APs\n", ap_count);
+   debug("Attempting to start %d APs\n", num_aps);
 
if (apic_wait_timeout(1000, "ICR not to be busy"))
return -ETIMEDOUT;
@@ -349,7 +362,7 @@ static int start_aps(int ap_count, atomic_t *num_aps)
return -ETIMEDOUT;
 
/* Wait for CPUs to check in up to 200 us */
-   wait_for_aps(num_aps, ap_count, 200, 15);
+   wait_for_aps(ap_count, num_aps, 200, 15);
 
/* Send 2nd SIPI */
if (apic_wait_timeout(1000, "ICR not to be busy"))
@@ -362,9 +375,9 @@ static int start_aps(int ap_count, atomic_t *num_aps)
return -ETIMEDOUT;
 
/* Wait for CPUs to check in */
-   if (wait_for_aps(num_aps, ap_count, 1, 50)) {
+   if (wait_for_aps(ap_count, num_aps, 1, 50)) {
debug("Not all APs checked in: %d/%d\n",
- atomic_read(num_aps), ap_count);
+ atomic_read(ap_count), num_aps);
return -EIO;
}
 
-- 
2.27.0.290.gba653c62da-goog



[PATCH v2 01/25] x86: mp_init: Switch to livetree

2020-06-14 Thread Simon Glass
Update this code to use livetree calls instead of flat-tree.

Signed-off-by: Simon Glass 
Reviewed-by: Wolfgang Wallner 
---

(no changes since v1)

 arch/x86/cpu/mp_init.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/arch/x86/cpu/mp_init.c b/arch/x86/cpu/mp_init.c
index 7fde4ff7e1..c25d17c647 100644
--- a/arch/x86/cpu/mp_init.c
+++ b/arch/x86/cpu/mp_init.c
@@ -507,8 +507,7 @@ int mp_init_cpu(struct udevice *cpu, void *unused)
 * seq num in the uclass_resolve_seq() during device_probe(). To avoid
 * this, set req_seq to the reg number in the device tree in advance.
 */
-   cpu->req_seq = fdtdec_get_int(gd->fdt_blob, dev_of_offset(cpu), "reg",
- -1);
+   cpu->req_seq = dev_read_u32_default(cpu, "reg", -1);
plat->ucode_version = microcode_read_rev();
plat->device_id = gd->arch.x86_device;
 
-- 
2.27.0.290.gba653c62da-goog



[PATCH v2 02/25] x86: Move MP code into mp_init

2020-06-14 Thread Simon Glass
At present the 'flight plan' for CPUs is passed into mp_init. But it is
always the same. Move it into the mp_init file so everything is in one
place. Also drop the SMI function since it does nothing. If we implement
SMIs, more refactoring will be needed anyway.

Signed-off-by: Simon Glass 
Reviewed-by: Wolfgang Wallner 
---

(no changes since v1)

 arch/x86/cpu/i386/cpu.c   | 24 +---
 arch/x86/cpu/mp_init.c| 22 ++
 arch/x86/include/asm/mp.h | 17 +
 3 files changed, 16 insertions(+), 47 deletions(-)

diff --git a/arch/x86/cpu/i386/cpu.c b/arch/x86/cpu/i386/cpu.c
index d27324cb4e..9809ac5111 100644
--- a/arch/x86/cpu/i386/cpu.c
+++ b/arch/x86/cpu/i386/cpu.c
@@ -21,6 +21,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -626,29 +627,14 @@ int cpu_jump_to_64bit_uboot(ulong target)
 }
 
 #ifdef CONFIG_SMP
-static int enable_smis(struct udevice *cpu, void *unused)
-{
-   return 0;
-}
-
-static struct mp_flight_record mp_steps[] = {
-   MP_FR_BLOCK_APS(mp_init_cpu, NULL, mp_init_cpu, NULL),
-   /* Wait for APs to finish initialization before proceeding */
-   MP_FR_BLOCK_APS(NULL, NULL, enable_smis, NULL),
-};
-
 int x86_mp_init(void)
 {
-   struct mp_params mp_params;
-
-   mp_params.parallel_microcode_load = 0,
-   mp_params.flight_plan = &mp_steps[0];
-   mp_params.num_records = ARRAY_SIZE(mp_steps);
-   mp_params.microcode_pointer = 0;
+   int ret;
 
-   if (mp_init(&mp_params)) {
+   ret = mp_init();
+   if (ret) {
printf("Warning: MP init failure\n");
-   return -EIO;
+   return log_ret(ret);
}
 
return 0;
diff --git a/arch/x86/cpu/mp_init.c b/arch/x86/cpu/mp_init.c
index c25d17c647..831fd7035d 100644
--- a/arch/x86/cpu/mp_init.c
+++ b/arch/x86/cpu/mp_init.c
@@ -41,6 +41,9 @@ struct saved_msr {
uint32_t hi;
 } __packed;
 
+static struct mp_flight_record mp_steps[] = {
+   MP_FR_BLOCK_APS(mp_init_cpu, NULL, mp_init_cpu, NULL),
+};
 
 struct mp_flight_plan {
int num_records;
@@ -372,7 +375,7 @@ static int start_aps(int ap_count, atomic_t *num_aps)
return 0;
 }
 
-static int bsp_do_flight_plan(struct udevice *cpu, struct mp_params *mp_params)
+static int bsp_do_flight_plan(struct udevice *cpu, struct mp_flight_plan *plan)
 {
int i;
int ret = 0;
@@ -380,8 +383,8 @@ static int bsp_do_flight_plan(struct udevice *cpu, struct 
mp_params *mp_params)
const int step_us = 100;
int num_aps = num_cpus - 1;
 
-   for (i = 0; i < mp_params->num_records; i++) {
-   struct mp_flight_record *rec = &mp_params->flight_plan[i];
+   for (i = 0; i < plan->num_records; i++) {
+   struct mp_flight_record *rec = &plan->records[i];
 
/* Wait for APs if the record is not released */
if (atomic_read(&rec->barrier) == 0) {
@@ -420,7 +423,7 @@ static int init_bsp(struct udevice **devp)
return 0;
 }
 
-int mp_init(struct mp_params *p)
+int mp_init(void)
 {
int num_aps;
atomic_t *ap_count;
@@ -445,11 +448,6 @@ int mp_init(struct mp_params *p)
return ret;
}
 
-   if (p == NULL || p->flight_plan == NULL || p->num_records < 1) {
-   printf("Invalid MP parameters\n");
-   return -EINVAL;
-   }
-
num_cpus = cpu_get_count(cpu);
if (num_cpus < 0) {
debug("Cannot get number of CPUs: err=%d\n", num_cpus);
@@ -464,8 +462,8 @@ int mp_init(struct mp_params *p)
debug("Warning: Device tree does not describe all CPUs. Extra 
ones will not be started correctly\n");
 
/* Copy needed parameters so that APs have a reference to the plan */
-   mp_info.num_records = p->num_records;
-   mp_info.records = p->flight_plan;
+   mp_info.num_records = ARRAY_SIZE(mp_steps);
+   mp_info.records = mp_steps;
 
/* Load the SIPI vector */
ret = load_sipi_vector(&ap_count, num_cpus);
@@ -489,7 +487,7 @@ int mp_init(struct mp_params *p)
}
 
/* Walk the flight plan for the BSP */
-   ret = bsp_do_flight_plan(cpu, p);
+   ret = bsp_do_flight_plan(cpu, &mp_info);
if (ret) {
debug("CPU init failed: err=%d\n", ret);
return ret;
diff --git a/arch/x86/include/asm/mp.h b/arch/x86/include/asm/mp.h
index 9dddf88b5a..db02904ecb 100644
--- a/arch/x86/include/asm/mp.h
+++ b/arch/x86/include/asm/mp.h
@@ -51,21 +51,6 @@ struct mp_flight_record {
 #define MP_FR_NOBLOCK_APS(ap_func, ap_arg, bsp_func, bsp_arg) \
MP_FLIGHT_RECORD(1, ap_func, ap_arg, bsp_func, bsp_arg)
 
-/*
- * The mp_params structure provides the arguments to the mp subsystem
- * for bringing up APs.
- *
- * At present this is overkill for U-Boot, but it may make it easier to add
- * SMM support.
- */
-struct mp_params {
-   int parallel_microcode_load;
-   const

[PATCH v2 05/25] x86: mp_init: Drop the num_cpus static variable

2020-06-14 Thread Simon Glass
This does not need to be global across all functions in this file. Pass a
parameter instead.

Signed-off-by: Simon Glass 
Reviewed-by: Wolfgang Wallner 
---

(no changes since v1)

 arch/x86/cpu/mp_init.c | 22 +++---
 1 file changed, 15 insertions(+), 7 deletions(-)

diff --git a/arch/x86/cpu/mp_init.c b/arch/x86/cpu/mp_init.c
index 8b00d57c88..aebbca6618 100644
--- a/arch/x86/cpu/mp_init.c
+++ b/arch/x86/cpu/mp_init.c
@@ -31,9 +31,6 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
-/* Total CPUs include BSP */
-static int num_cpus;
-
 /* This also needs to match the sipi.S assembly code for saved MSR encoding */
 struct saved_msr {
uint32_t index;
@@ -384,13 +381,23 @@ static int start_aps(int num_aps, atomic_t *ap_count)
return 0;
 }
 
-static int bsp_do_flight_plan(struct udevice *cpu, struct mp_flight_plan *plan)
+/**
+ * bsp_do_flight_plan() - Do the flight plan on all CPUs
+ *
+ * This runs the flight plan on the main CPU used to boot U-Boot
+ *
+ * @cpu: Device for the main CPU
+ * @plan: Flight plan to run
+ * @num_aps: Number of APs (CPUs other than the BSP)
+ * @returns 0 on success, -ETIMEDOUT if an AP failed to come up
+ */
+static int bsp_do_flight_plan(struct udevice *cpu, struct mp_flight_plan *plan,
+ int num_aps)
 {
int i;
int ret = 0;
const int timeout_us = 10;
const int step_us = 100;
-   int num_aps = num_cpus - 1;
 
for (i = 0; i < plan->num_records; i++) {
struct mp_flight_record *rec = &plan->records[i];
@@ -410,6 +417,7 @@ static int bsp_do_flight_plan(struct udevice *cpu, struct 
mp_flight_plan *plan)
 
release_barrier(&rec->barrier);
}
+
return ret;
 }
 
@@ -454,7 +462,7 @@ static struct mp_flight_record mp_steps[] = {
 
 int mp_init(void)
 {
-   int num_aps;
+   int num_aps, num_cpus;
atomic_t *ap_count;
struct udevice *cpu;
int ret;
@@ -516,7 +524,7 @@ int mp_init(void)
}
 
/* Walk the flight plan for the BSP */
-   ret = bsp_do_flight_plan(cpu, &mp_info);
+   ret = bsp_do_flight_plan(cpu, &mp_info, num_aps);
if (ret) {
debug("CPU init failed: err=%d\n", ret);
return ret;
-- 
2.27.0.290.gba653c62da-goog



[PATCH v2 03/25] x86: mp_init: Avoid declarations in header files

2020-06-14 Thread Simon Glass
The functions used by the flight plan are declared in the header file but
are not used in any other file.

Move the flight plan steps down to just above where it is used so that we
can make these function static.

Signed-off-by: Simon Glass 
Reviewed-by: Wolfgang Wallner 
---

(no changes since v1)

 arch/x86/cpu/mp_init.c| 40 +++
 arch/x86/include/asm/mp.h |  3 ---
 2 files changed, 20 insertions(+), 23 deletions(-)

diff --git a/arch/x86/cpu/mp_init.c b/arch/x86/cpu/mp_init.c
index 831fd7035d..e77d7f2cd6 100644
--- a/arch/x86/cpu/mp_init.c
+++ b/arch/x86/cpu/mp_init.c
@@ -41,10 +41,6 @@ struct saved_msr {
uint32_t hi;
 } __packed;
 
-static struct mp_flight_record mp_steps[] = {
-   MP_FR_BLOCK_APS(mp_init_cpu, NULL, mp_init_cpu, NULL),
-};
-
 struct mp_flight_plan {
int num_records;
struct mp_flight_record *records;
@@ -423,6 +419,26 @@ static int init_bsp(struct udevice **devp)
return 0;
 }
 
+static int mp_init_cpu(struct udevice *cpu, void *unused)
+{
+   struct cpu_platdata *plat = dev_get_parent_platdata(cpu);
+
+   /*
+* Multiple APs are brought up simultaneously and they may get the same
+* seq num in the uclass_resolve_seq() during device_probe(). To avoid
+* this, set req_seq to the reg number in the device tree in advance.
+*/
+   cpu->req_seq = dev_read_u32_default(cpu, "reg", -1);
+   plat->ucode_version = microcode_read_rev();
+   plat->device_id = gd->arch.x86_device;
+
+   return device_probe(cpu);
+}
+
+static struct mp_flight_record mp_steps[] = {
+   MP_FR_BLOCK_APS(mp_init_cpu, NULL, mp_init_cpu, NULL),
+};
+
 int mp_init(void)
 {
int num_aps;
@@ -495,19 +511,3 @@ int mp_init(void)
 
return 0;
 }
-
-int mp_init_cpu(struct udevice *cpu, void *unused)
-{
-   struct cpu_platdata *plat = dev_get_parent_platdata(cpu);
-
-   /*
-* Multiple APs are brought up simultaneously and they may get the same
-* seq num in the uclass_resolve_seq() during device_probe(). To avoid
-* this, set req_seq to the reg number in the device tree in advance.
-*/
-   cpu->req_seq = dev_read_u32_default(cpu, "reg", -1);
-   plat->ucode_version = microcode_read_rev();
-   plat->device_id = gd->arch.x86_device;
-
-   return device_probe(cpu);
-}
diff --git a/arch/x86/include/asm/mp.h b/arch/x86/include/asm/mp.h
index db02904ecb..94af819ad9 100644
--- a/arch/x86/include/asm/mp.h
+++ b/arch/x86/include/asm/mp.h
@@ -72,9 +72,6 @@ struct mp_flight_record {
  */
 int mp_init(void);
 
-/* Probes the CPU device */
-int mp_init_cpu(struct udevice *cpu, void *unused);
-
 /* Set up additional CPUs */
 int x86_mp_init(void);
 
-- 
2.27.0.290.gba653c62da-goog



[PATCH v2 07/25] x86: mp_init: Set up the CPU numbers at the start

2020-06-14 Thread Simon Glass
At present each CPU is given a number when it starts itself up. While this
saves a tiny amount of time by doing the device-tree read in parallel, it
is confusing that the numbering happens on the fly.

Move this code into mp_init() and do it at the start.

Signed-off-by: Simon Glass 
Reviewed-by: Wolfgang Wallner 
---

(no changes since v1)

 arch/x86/cpu/mp_init.c | 21 +
 1 file changed, 9 insertions(+), 12 deletions(-)

diff --git a/arch/x86/cpu/mp_init.c b/arch/x86/cpu/mp_init.c
index aebbca6618..e0270e71db 100644
--- a/arch/x86/cpu/mp_init.c
+++ b/arch/x86/cpu/mp_init.c
@@ -444,12 +444,6 @@ static int mp_init_cpu(struct udevice *cpu, void *unused)
 {
struct cpu_platdata *plat = dev_get_parent_platdata(cpu);
 
-   /*
-* Multiple APs are brought up simultaneously and they may get the same
-* seq num in the uclass_resolve_seq() during device_probe(). To avoid
-* this, set req_seq to the reg number in the device tree in advance.
-*/
-   cpu->req_seq = dev_read_u32_default(cpu, "reg", -1);
plat->ucode_version = microcode_read_rev();
plat->device_id = gd->arch.x86_device;
 
@@ -465,13 +459,8 @@ int mp_init(void)
int num_aps, num_cpus;
atomic_t *ap_count;
struct udevice *cpu;
-   int ret;
-
-   /* This will cause the CPUs devices to be bound */
struct uclass *uc;
-   ret = uclass_get(UCLASS_CPU, &uc);
-   if (ret)
-   return ret;
+   int ret;
 
if (IS_ENABLED(CONFIG_QFW)) {
ret = qemu_cpu_fixup();
@@ -479,6 +468,14 @@ int mp_init(void)
return ret;
}
 
+   /*
+* Multiple APs are brought up simultaneously and they may get the same
+* seq num in the uclass_resolve_seq() during device_probe(). To avoid
+* this, set req_seq to the reg number in the device tree in advance.
+*/
+   uclass_id_foreach_dev(UCLASS_CPU, cpu, uc)
+   cpu->req_seq = dev_read_u32_default(cpu, "reg", -1);
+
ret = init_bsp(&cpu);
if (ret) {
debug("Cannot init boot CPU: err=%d\n", ret);
-- 
2.27.0.290.gba653c62da-goog



[PATCH v2 09/25] x86: cpu: Remove unnecessary #ifdefs

2020-06-14 Thread Simon Glass
Drop some #ifdefs that are not needed or can be converted to compile-time
checks.

Signed-off-by: Simon Glass 
Reviewed-by: Wolfgang Wallner 
---

(no changes since v1)

 arch/x86/cpu/cpu.c  | 58 -
 arch/x86/cpu/i386/cpu.c |  2 --
 2 files changed, 28 insertions(+), 32 deletions(-)

diff --git a/arch/x86/cpu/cpu.c b/arch/x86/cpu/cpu.c
index 23a4d633d2..d0720fb7fb 100644
--- a/arch/x86/cpu/cpu.c
+++ b/arch/x86/cpu/cpu.c
@@ -66,10 +66,8 @@ static const char *const x86_vendor_name[] = {
 
 int __weak x86_cleanup_before_linux(void)
 {
-#ifdef CONFIG_BOOTSTAGE_STASH
bootstage_stash((void *)CONFIG_BOOTSTAGE_STASH_ADDR,
CONFIG_BOOTSTAGE_STASH_SIZE);
-#endif
 
return 0;
 }
@@ -200,18 +198,19 @@ int last_stage_init(void)
 
write_tables();
 
-#ifdef CONFIG_GENERATE_ACPI_TABLE
-   fadt = acpi_find_fadt();
+   if (IS_ENABLED(CONFIG_GENERATE_ACPI_TABLE)) {
+   fadt = acpi_find_fadt();
 
-   /* Don't touch ACPI hardware on HW reduced platforms */
-   if (fadt && !(fadt->flags & ACPI_FADT_HW_REDUCED_ACPI)) {
-   /*
-* Other than waiting for OSPM to request us to switch to ACPI
-* mode, do it by ourselves, since SMI will not be triggered.
-*/
-   enter_acpi_mode(fadt->pm1a_cnt_blk);
+   /* Don't touch ACPI hardware on HW reduced platforms */
+   if (fadt && !(fadt->flags & ACPI_FADT_HW_REDUCED_ACPI)) {
+   /*
+* Other than waiting for OSPM to request us to switch
+* to ACPI * mode, do it by ourselves, since SMI will
+* not be triggered.
+*/
+   enter_acpi_mode(fadt->pm1a_cnt_blk);
+   }
}
-#endif
 
return 0;
 }
@@ -219,19 +218,20 @@ int last_stage_init(void)
 
 static int x86_init_cpus(void)
 {
-#ifdef CONFIG_SMP
-   debug("Init additional CPUs\n");
-   x86_mp_init();
-#else
-   struct udevice *dev;
+   if (IS_ENABLED(CONFIG_SMP)) {
+   debug("Init additional CPUs\n");
+   x86_mp_init();
+   } else {
+   struct udevice *dev;
 
-   /*
-* This causes the cpu-x86 driver to be probed.
-* We don't check return value here as we want to allow boards
-* which have not been converted to use cpu uclass driver to boot.
-*/
-   uclass_first_device(UCLASS_CPU, &dev);
-#endif
+   /*
+* This causes the cpu-x86 driver to be probed.
+* We don't check return value here as we want to allow boards
+* which have not been converted to use cpu uclass driver to
+* boot.
+*/
+   uclass_first_device(UCLASS_CPU, &dev);
+   }
 
return 0;
 }
@@ -269,13 +269,11 @@ int cpu_init_r(void)
 #ifndef CONFIG_EFI_STUB
 int reserve_arch(void)
 {
-#ifdef CONFIG_ENABLE_MRC_CACHE
-   mrccache_reserve();
-#endif
+   if (IS_ENABLED(CONFIG_ENABLE_MRC_CACHE))
+   mrccache_reserve();
 
-#ifdef CONFIG_SEABIOS
-   high_table_reserve();
-#endif
+   if (IS_ENABLED(CONFIG_SEABIOS))
+   high_table_reserve();
 
if (IS_ENABLED(CONFIG_HAVE_ACPI_RESUME)) {
acpi_s3_reserve();
diff --git a/arch/x86/cpu/i386/cpu.c b/arch/x86/cpu/i386/cpu.c
index 9809ac5111..fca3f79b69 100644
--- a/arch/x86/cpu/i386/cpu.c
+++ b/arch/x86/cpu/i386/cpu.c
@@ -626,7 +626,6 @@ int cpu_jump_to_64bit_uboot(ulong target)
return -EFAULT;
 }
 
-#ifdef CONFIG_SMP
 int x86_mp_init(void)
 {
int ret;
@@ -639,4 +638,3 @@ int x86_mp_init(void)
 
return 0;
 }
-#endif
-- 
2.27.0.290.gba653c62da-goog



[PATCH v2 10/25] x86: mp: Support APs waiting for instructions

2020-06-14 Thread Simon Glass
At present the APs (non-boot CPUs) are inited once and then parked ready
for the OS to use them. However in some cases we want to send new requests
through, such as to change MTRRs and keep them consistent across CPUs.

Change the last state of the flight plan to go into a wait loop, accepting
instructions from the main CPU.

Signed-off-by: Simon Glass 
---

Changes in v2:
- Add more comments

 arch/x86/cpu/mp_init.c| 126 +++---
 arch/x86/include/asm/mp.h |  11 
 2 files changed, 128 insertions(+), 9 deletions(-)

diff --git a/arch/x86/cpu/mp_init.c b/arch/x86/cpu/mp_init.c
index cd4cae559d..673fdc9628 100644
--- a/arch/x86/cpu/mp_init.c
+++ b/arch/x86/cpu/mp_init.c
@@ -43,13 +43,38 @@ struct mp_flight_plan {
struct mp_flight_record *records;
 };
 
+/**
+ * struct mp_callback - Callback information for APs
+ *
+ * @func: Function to run
+ * @arg: Argument to pass to the function
+ * @logical_cpu_number: Either a CPU number (i.e. dev->req_seq) or a special
+ * value like MP_SELECT_BSP. It tells the AP whether it should process this
+ * callback
+ */
+struct mp_callback {
+   /**
+* func() - Function to call on the AP
+*
+* @arg: Argument to pass
+*/
+   void (*func)(void *arg);
+   void *arg;
+   int logical_cpu_number;
+};
+
 static struct mp_flight_plan mp_info;
 
-struct cpu_map {
-   struct udevice *dev;
-   int apic_id;
-   int err_code;
-};
+/*
+ * ap_callbacks - Callback mailbox array
+ *
+ * Array of callback, one entry for each available CPU, indexed by the CPU
+ * number, which is dev->req_seq. The entry for the main CPU is never used.
+ * When this is NULL, there is no pending work for the CPU to run. When
+ * non-NULL it points to the mp_callback structure. This is shared between all
+ * CPUs, so should only be written by the main CPU.
+ */
+static struct mp_callback **ap_callbacks;
 
 static inline void barrier_wait(atomic_t *b)
 {
@@ -147,11 +172,9 @@ static void ap_init(unsigned int cpu_index)
debug("AP: slot %d apic_id %x, dev %s\n", cpu_index, apic_id,
  dev ? dev->name : "(apic_id not found)");
 
-   /* Walk the flight plan */
+   /* Walk the flight plan, which never returns */
ap_do_flight_plan(dev);
-
-   /* Park the AP */
-   debug("parking\n");
+   debug("Unexpected return\n");
 done:
stop_this_cpu();
 }
@@ -455,6 +478,86 @@ static int get_bsp(struct udevice **devp, int *cpu_countp)
return dev->req_seq;
 }
 
+/**
+ * read_callback() - Read the pointer in a callback slot
+ *
+ * This is called by APs to read their callback slow to see if there is a
+ * pointer to new instructions
+ *
+ * @slot: Pointer to the AP's callback slot
+ * @return value of that pointer
+ */
+static struct mp_callback *read_callback(struct mp_callback **slot)
+{
+   struct mp_callback *ret;
+
+   asm volatile ("mov  %1, %0\n"
+   : "=r" (ret)
+   : "m" (*slot)
+   : "memory"
+   );
+   return ret;
+}
+
+/**
+ * store_callback() - Store a pointer to the callback slot
+ *
+ * This is called by APs to write NULL into the callback slot when they have
+ * finished the work requested by the BSP.
+ *
+ * @slot: Pointer to the AP's callback slot
+ * @val: Value to write (e.g. NULL)
+ */
+static void store_callback(struct mp_callback **slot, struct mp_callback *val)
+{
+   asm volatile ("mov  %1, %0\n"
+   : "=m" (*slot)
+   : "r" (val)
+   : "memory"
+   );
+}
+
+/**
+ * ap_wait_for_instruction() - Wait for and process requests from the main CPU
+ *
+ * This is called by APs (here, everything other than the main boot CPU) to
+ * await instructions. They arrive in the form of a function call and argument,
+ * which is then called. This uses a simple mailbox with atomic read/set
+ *
+ * @cpu: CPU that is waiting
+ * @unused: Optional argument provided by struct mp_flight_record, not used 
here
+ * @return Does not return
+ */
+static int ap_wait_for_instruction(struct udevice *cpu, void *unused)
+{
+   struct mp_callback lcb;
+   struct mp_callback **per_cpu_slot;
+
+   per_cpu_slot = &ap_callbacks[cpu->req_seq];
+
+   while (1) {
+   struct mp_callback *cb = read_callback(per_cpu_slot);
+
+   if (!cb) {
+   asm ("pause");
+   continue;
+   }
+
+   /* Copy to local variable before using the value */
+   memcpy(&lcb, cb, sizeof(lcb));
+   mfence();
+   if (lcb.logical_cpu_number == MP_SELECT_ALL ||
+   lcb.logical_cpu_number == MP_SELECT_APS ||
+   cpu->req_seq == lcb.logical_cpu_number)
+   lcb.func(lcb.arg);
+
+   /* Indicate we are finished */
+   store_callback(per_cpu_slot, NULL);
+   }
+
+   return 0;
+}
+
 static int 

[PATCH v2 08/25] x86: mp_init: Adjust bsp_init() to return more information

2020-06-14 Thread Simon Glass
This function is misnamed since it does not actually init the BSP. Also
it is convenient to adjust it to return a little more information.

Rename and update the function, to allow it to return the BSP CPU device
and number, as well as the total number of CPUs.

Signed-off-by: Simon Glass 
Reviewed-by: Wolfgang Wallner 
---

Changes in v2:
- Drop change to include/dm/uclass.h
- Mention error return in get_bsp()

 arch/x86/cpu/mp_init.c | 35 ++-
 1 file changed, 22 insertions(+), 13 deletions(-)

diff --git a/arch/x86/cpu/mp_init.c b/arch/x86/cpu/mp_init.c
index e0270e71db..cd4cae559d 100644
--- a/arch/x86/cpu/mp_init.c
+++ b/arch/x86/cpu/mp_init.c
@@ -421,9 +421,17 @@ static int bsp_do_flight_plan(struct udevice *cpu, struct 
mp_flight_plan *plan,
return ret;
 }
 
-static int init_bsp(struct udevice **devp)
+/**
+ * get_bsp() - Get information about the bootstrap processor
+ *
+ * @devp: If non-NULL, returns CPU device corresponding to the BSP
+ * @cpu_countp: If non-NULL, returns the total number of CPUs
+ * @return CPU number of the BSP, or -ve on error
+ */
+static int get_bsp(struct udevice **devp, int *cpu_countp)
 {
char processor_name[CPU_MAX_NAME_LEN];
+   struct udevice *dev;
int apic_id;
int ret;
 
@@ -431,13 +439,20 @@ static int init_bsp(struct udevice **devp)
debug("CPU: %s\n", processor_name);
 
apic_id = lapicid();
-   ret = find_cpu_by_apic_id(apic_id, devp);
-   if (ret) {
+   ret = find_cpu_by_apic_id(apic_id, &dev);
+   if (ret < 0) {
printf("Cannot find boot CPU, APIC ID %d\n", apic_id);
return ret;
}
+   ret = cpu_get_count(dev);
+   if (ret < 0)
+   return log_msg_ret("count", ret);
+   if (devp)
+   *devp = dev;
+   if (cpu_countp)
+   *cpu_countp = ret;
 
-   return 0;
+   return dev->req_seq;
 }
 
 static int mp_init_cpu(struct udevice *cpu, void *unused)
@@ -476,24 +491,18 @@ int mp_init(void)
uclass_id_foreach_dev(UCLASS_CPU, cpu, uc)
cpu->req_seq = dev_read_u32_default(cpu, "reg", -1);
 
-   ret = init_bsp(&cpu);
-   if (ret) {
+   ret = get_bsp(&cpu, &num_cpus);
+   if (ret < 0) {
debug("Cannot init boot CPU: err=%d\n", ret);
return ret;
}
 
-   num_cpus = cpu_get_count(cpu);
-   if (num_cpus < 0) {
-   debug("Cannot get number of CPUs: err=%d\n", num_cpus);
-   return num_cpus;
-   }
-
if (num_cpus < 2)
debug("Warning: Only 1 CPU is detected\n");
 
ret = check_cpu_devices(num_cpus);
if (ret)
-   debug("Warning: Device tree does not describe all CPUs. Extra 
ones will not be started correctly\n");
+   log_warning("Warning: Device tree does not describe all CPUs. 
Extra ones will not be started correctly\n");
 
/* Copy needed parameters so that APs have a reference to the plan */
mp_info.num_records = ARRAY_SIZE(mp_steps);
-- 
2.27.0.290.gba653c62da-goog



[PATCH v2 11/25] global_data: Add a generic global_data flag for SMP state

2020-06-14 Thread Simon Glass
Allow keeping track of whether all CPUs have been enabled yet. This allows
us to know whether other CPUs need to be considered when updating
CPU-specific settings such as MTRRs on x86.

Signed-off-by: Simon Glass 
Reviewed-by: Wolfgang Wallner 
---

(no changes since v1)

 include/asm-generic/global_data.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/include/asm-generic/global_data.h 
b/include/asm-generic/global_data.h
index 8c78792cc9..345f365d79 100644
--- a/include/asm-generic/global_data.h
+++ b/include/asm-generic/global_data.h
@@ -167,5 +167,6 @@ typedef struct global_data {
 #define GD_FLG_LOG_READY   0x08000 /* Log system is ready for use */
 #define GD_FLG_WDT_READY   0x1 /* Watchdog is ready for use   */
 #define GD_FLG_SKIP_LL_INIT0x2 /* Don't perform low-level init*/
+#define GD_FLG_SMP_INIT0x4 /* SMP init is complete 
   */
 
 #endif /* __ASM_GENERIC_GBL_DATA_H */
-- 
2.27.0.290.gba653c62da-goog



[PATCH v2 13/25] x86: mp: Allow running functions on multiple CPUs

2020-06-14 Thread Simon Glass
Add a way to run a function on a selection of CPUs. This supports either
a single CPU, all CPUs, just the main CPU or just the 'APs', in Intel
terminology.

It works by writing into a mailbox and then waiting for the CPUs to notice
it, take action and indicate they are done.

When SMP is not yet enabled, this just calls the function on the main CPU.

Signed-off-by: Simon Glass 
---

Changes in v2:
- Add a comment to run_ap_work()

 arch/x86/cpu/mp_init.c| 96 ---
 arch/x86/include/asm/mp.h | 30 
 2 files changed, 120 insertions(+), 6 deletions(-)

diff --git a/arch/x86/cpu/mp_init.c b/arch/x86/cpu/mp_init.c
index b0df7a3965..e65c82c8fd 100644
--- a/arch/x86/cpu/mp_init.c
+++ b/arch/x86/cpu/mp_init.c
@@ -53,12 +53,7 @@ struct mp_flight_plan {
  * callback
  */
 struct mp_callback {
-   /**
-* func() - Function to call on the AP
-*
-* @arg: Argument to pass
-*/
-   void (*func)(void *arg);
+   mp_run_func func;
void *arg;
int logical_cpu_number;
 };
@@ -517,6 +512,64 @@ static void store_callback(struct mp_callback **slot, 
struct mp_callback *val)
);
 }
 
+/**
+ * run_ap_work() - Run a callback on selected APs
+ *
+ * This writes @callback to all APs and waits for them all to acknowledge it,
+ * Note that whether each AP actually calls the callback depends on the value
+ * of logical_cpu_number.
+ *
+ * @callback: Callback information to pass to all APs
+ * @bsp: CPU device for the BSP
+ * @num_cpus: The number of CPUs in the system (= number of APs + 1)
+ * @expire_ms: Timeout to wait for all APs to finish, in milliseconds, or 0 for
+ * no timeout
+ * @return 0 if OK, -ETIMEDOUT if one or more APs failed to respond in time
+ */
+static int run_ap_work(struct mp_callback *callback, struct udevice *bsp,
+  int num_cpus, uint expire_ms)
+{
+   int cur_cpu = bsp->req_seq;
+   int num_aps = num_cpus - 1; /* number of non-BSPs to get this message */
+   int cpus_accepted;
+   ulong start;
+   int i;
+
+   /* Signal to all the APs to run the func. */
+   for (i = 0; i < num_cpus; i++) {
+   if (cur_cpu != i)
+   store_callback(&ap_callbacks[i], callback);
+   }
+   mfence();
+
+   /* Wait for all the APs to signal back that call has been accepted. */
+   start = get_timer(0);
+
+   do {
+   mdelay(1);
+   cpus_accepted = 0;
+
+   for (i = 0; i < num_cpus; i++) {
+   if (cur_cpu == i)
+   continue;
+   if (!read_callback(&ap_callbacks[i]))
+   cpus_accepted++;
+   }
+
+   if (expire_ms && get_timer(start) >= expire_ms) {
+   log(UCLASS_CPU, LOGL_CRIT,
+   "AP call expired; %d/%d CPUs accepted\n",
+   cpus_accepted, num_aps);
+   return -ETIMEDOUT;
+   }
+   } while (cpus_accepted != num_aps);
+
+   /* Make sure we can see any data written by the APs */
+   mfence();
+
+   return 0;
+}
+
 /**
  * ap_wait_for_instruction() - Wait for and process requests from the main CPU
  *
@@ -573,6 +626,37 @@ static struct mp_flight_record mp_steps[] = {
MP_FR_BLOCK_APS(ap_wait_for_instruction, NULL, NULL, NULL),
 };
 
+int mp_run_on_cpus(int cpu_select, mp_run_func func, void *arg)
+{
+   struct mp_callback lcb = {
+   .func = func,
+   .arg = arg,
+   .logical_cpu_number = cpu_select,
+   };
+   struct udevice *dev;
+   int num_cpus;
+   int ret;
+
+   if (!(gd->flags & GD_FLG_SMP_INIT))
+   return -ENXIO;
+
+   ret = get_bsp(&dev, &num_cpus);
+   if (ret < 0)
+   return log_msg_ret("bsp", ret);
+   if (cpu_select == MP_SELECT_ALL || cpu_select == MP_SELECT_BSP ||
+   cpu_select == ret) {
+   /* Run on BSP first */
+   func(arg);
+   }
+
+   /* Allow up to 1 second for all APs to finish */
+   ret = run_ap_work(&lcb, dev, num_cpus, 1000 /* ms */);
+   if (ret)
+   return log_msg_ret("aps", ret);
+
+   return 0;
+}
+
 int mp_init(void)
 {
int num_aps, num_cpus;
diff --git a/arch/x86/include/asm/mp.h b/arch/x86/include/asm/mp.h
index 41b1575f4b..0272b3c0b6 100644
--- a/arch/x86/include/asm/mp.h
+++ b/arch/x86/include/asm/mp.h
@@ -86,4 +86,34 @@ int mp_init(void);
 /* Set up additional CPUs */
 int x86_mp_init(void);
 
+/**
+ * mp_run_func() - Function to call on the AP
+ *
+ * @arg: Argument to pass
+ */
+typedef void (*mp_run_func)(void *arg);
+
+#if defined(CONFIG_SMP) && !CONFIG_IS_ENABLED(X86_64)
+/**
+ * mp_run_on_cpus() - Run a function on one or all CPUs
+ *
+ * This does not return until all CPUs have completed the work
+ *
+ * @cpu_select: CPU to run on, or 

[PATCH v2 16/25] x86: mtrr: Use MP calls to list the MTRRs

2020-06-14 Thread Simon Glass
Update the mtrr command to use mp_run_on_cpus() to obtain its information.
Since the selected CPU is the boot CPU this does not change the result,
but it sets the stage for supporting other CPUs.

Signed-off-by: Simon Glass 
Reviewed-by: Wolfgang Wallner 
---

Changes in v2:
- Rename mtrr_save_all() to mtrr_read_all()

 arch/x86/cpu/mtrr.c | 11 +++
 arch/x86/include/asm/mtrr.h | 30 ++
 cmd/x86/mtrr.c  | 25 +
 3 files changed, 62 insertions(+), 4 deletions(-)

diff --git a/arch/x86/cpu/mtrr.c b/arch/x86/cpu/mtrr.c
index 7ec077..c9b4e7d06e 100644
--- a/arch/x86/cpu/mtrr.c
+++ b/arch/x86/cpu/mtrr.c
@@ -21,6 +21,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -63,6 +64,16 @@ static void set_var_mtrr(uint reg, uint type, uint64_t 
start, uint64_t size)
wrmsrl(MTRR_PHYS_MASK_MSR(reg), mask | MTRR_PHYS_MASK_VALID);
 }
 
+void mtrr_read_all(struct mtrr_info *info)
+{
+   int i;
+
+   for (i = 0; i < MTRR_COUNT; i++) {
+   info->mtrr[i].base = native_read_msr(MTRR_PHYS_BASE_MSR(i));
+   info->mtrr[i].mask = native_read_msr(MTRR_PHYS_MASK_MSR(i));
+   }
+}
+
 int mtrr_commit(bool do_caches)
 {
struct mtrr_request *req = gd->arch.mtrr_req;
diff --git a/arch/x86/include/asm/mtrr.h b/arch/x86/include/asm/mtrr.h
index 212a699c1b..e1f1a44643 100644
--- a/arch/x86/include/asm/mtrr.h
+++ b/arch/x86/include/asm/mtrr.h
@@ -70,6 +70,26 @@ struct mtrr_state {
bool enable_cache;
 };
 
+/**
+ * struct mtrr - Information about a single MTRR
+ *
+ * @base: Base address and MTRR_BASE_TYPE_MASK
+ * @mask: Mask and MTRR_PHYS_MASK_VALID
+ */
+struct mtrr {
+   u64 base;
+   u64 mask;
+};
+
+/**
+ * struct mtrr_info - Information about all MTRRs
+ *
+ * @mtrr: Information about each mtrr
+ */
+struct mtrr_info {
+   struct mtrr mtrr[MTRR_COUNT];
+};
+
 /**
  * mtrr_open() - Prepare to adjust MTRRs
  *
@@ -129,6 +149,16 @@ int mtrr_commit(bool do_caches);
  */
 int mtrr_set_next_var(uint type, uint64_t base, uint64_t size);
 
+/**
+ * mtrr_read_all() - Save all the MTRRs
+ *
+ * This reads all MTRRs from the boot CPU into a struct so they can be loaded
+ * onto other CPUs
+ *
+ * @info: Place to put the MTRR info
+ */
+void mtrr_read_all(struct mtrr_info *info);
+
 #endif
 
 #if ((CONFIG_XIP_ROM_SIZE & (CONFIG_XIP_ROM_SIZE - 1)) != 0)
diff --git a/cmd/x86/mtrr.c b/cmd/x86/mtrr.c
index 5d25c5802a..f357f58767 100644
--- a/cmd/x86/mtrr.c
+++ b/cmd/x86/mtrr.c
@@ -5,7 +5,9 @@
 
 #include 
 #include 
+#include 
 #include 
+#include 
 #include 
 
 static const char *const mtrr_type_name[MTRR_TYPE_COUNT] = {
@@ -18,19 +20,32 @@ static const char *const mtrr_type_name[MTRR_TYPE_COUNT] = {
"Back",
 };
 
-static int do_mtrr_list(void)
+static void read_mtrrs(void *arg)
 {
+   struct mtrr_info *info = arg;
+
+   mtrr_read_all(info);
+}
+
+static int do_mtrr_list(int cpu_select)
+{
+   struct mtrr_info info;
+   int ret;
int i;
 
printf("Reg Valid Write-type   %-16s %-16s %-16s\n", "Base   ||",
   "Mask   ||", "Size   ||");
+   memset(&info, '\0', sizeof(info));
+   ret = mp_run_on_cpus(cpu_select, read_mtrrs, &info);
+   if (ret)
+   return log_msg_ret("run", ret);
for (i = 0; i < MTRR_COUNT; i++) {
const char *type = "Invalid";
uint64_t base, mask, size;
bool valid;
 
-   base = native_read_msr(MTRR_PHYS_BASE_MSR(i));
-   mask = native_read_msr(MTRR_PHYS_MASK_MSR(i));
+   base = info.mtrr[i].base;
+   mask = info.mtrr[i].mask;
size = ~mask & ((1ULL << CONFIG_CPU_ADDR_BITS) - 1);
size |= (1 << 12) - 1;
size += 1;
@@ -102,11 +117,13 @@ static int do_mtrr(struct cmd_tbl *cmdtp, int flag, int 
argc,
   char *const argv[])
 {
const char *cmd;
+   int cpu_select;
uint reg;
 
+   cpu_select = MP_SELECT_BSP;
cmd = argv[1];
if (argc < 2 || *cmd == 'l')
-   return do_mtrr_list();
+   return do_mtrr_list(cpu_select);
argc -= 2;
argv += 2;
if (argc <= 0)
-- 
2.27.0.290.gba653c62da-goog



[PATCH v2 15/25] x86: mp: Add iterators for CPUs

2020-06-14 Thread Simon Glass
It is convenient to iterate through the CPUs performing work on each one
and processing the result. Add a few iterator functions which handle this.
These can be used by any client code. It can call mp_run_on_cpus() on
each CPU that is returned, handling them one at a time.

Signed-off-by: Simon Glass 
Reviewed-by: Wolfgang Wallner 
---

(no changes since v1)

 arch/x86/cpu/mp_init.c| 62 +++
 arch/x86/include/asm/mp.h | 40 +
 2 files changed, 102 insertions(+)

diff --git a/arch/x86/cpu/mp_init.c b/arch/x86/cpu/mp_init.c
index 9970b51c8d..c708c3e3c0 100644
--- a/arch/x86/cpu/mp_init.c
+++ b/arch/x86/cpu/mp_init.c
@@ -675,6 +675,68 @@ int mp_park_aps(void)
return get_timer(start);
 }
 
+int mp_first_cpu(int cpu_select)
+{
+   struct udevice *dev;
+   int num_cpus;
+   int ret;
+
+   /*
+* This assumes that CPUs are numbered from 0. This function tries to
+* avoid assuming the CPU 0 is the boot CPU
+*/
+   if (cpu_select == MP_SELECT_ALL)
+   return 0;   /* start with the first one */
+
+   ret = get_bsp(&dev, &num_cpus);
+   if (ret < 0)
+   return log_msg_ret("bsp", ret);
+
+   /* Return boot CPU if requested */
+   if (cpu_select == MP_SELECT_BSP)
+   return ret;
+
+   /* Return something other than the boot CPU, if APs requested */
+   if (cpu_select == MP_SELECT_APS && num_cpus > 1)
+   return ret == 0 ? 1 : 0;
+
+   /* Try to check for an invalid value */
+   if (cpu_select < 0 || cpu_select >= num_cpus)
+   return -EINVAL;
+
+   return cpu_select;  /* return the only selected one */
+}
+
+int mp_next_cpu(int cpu_select, int prev_cpu)
+{
+   struct udevice *dev;
+   int num_cpus;
+   int ret;
+   int bsp;
+
+   /* If we selected the BSP or a particular single CPU, we are done */
+   if (cpu_select == MP_SELECT_BSP || cpu_select >= 0)
+   return -EFBIG;
+
+   /* Must be doing MP_SELECT_ALL or MP_SELECT_APS; return the next CPU */
+   ret = get_bsp(&dev, &num_cpus);
+   if (ret < 0)
+   return log_msg_ret("bsp", ret);
+   bsp = ret;
+
+   /* Move to the next CPU */
+   assert(prev_cpu >= 0);
+   ret = prev_cpu + 1;
+
+   /* Skip the BSP if needed */
+   if (cpu_select == MP_SELECT_APS && ret == bsp)
+   ret++;
+   if (ret >= num_cpus)
+   return -EFBIG;
+
+   return ret;
+}
+
 int mp_init(void)
 {
int num_aps, num_cpus;
diff --git a/arch/x86/include/asm/mp.h b/arch/x86/include/asm/mp.h
index 38961ca44b..9f4223ae8c 100644
--- a/arch/x86/include/asm/mp.h
+++ b/arch/x86/include/asm/mp.h
@@ -115,6 +115,31 @@ int mp_run_on_cpus(int cpu_select, mp_run_func func, void 
*arg);
  * @return 0 on success, -ve on error
  */
 int mp_park_aps(void);
+
+/**
+ * mp_first_cpu() - Get the first CPU to process, from a selection
+ *
+ * This is used to iterate through selected CPUs. Call this function first, 
then
+ * call mp_next_cpu() repeatedly until it returns -EFBIG.
+ *
+ * @cpu_select: Selected CPUs (either a CPU number or MP_SELECT_...)
+ * @return next CPU number to run on (e.g. 0)
+ */
+int mp_first_cpu(int cpu_select);
+
+/**
+ * mp_next_cpu() - Get the next CPU to process, from a selection
+ *
+ * This is used to iterate through selected CPUs. After first calling
+ * mp_first_cpu() once, call this function repeatedly until it returns -EFBIG.
+ *
+ * The value of @cpu_select must be the same for all calls.
+ *
+ * @cpu_select: Selected CPUs (either a CPU number or MP_SELECT_...)
+ * @prev_cpu: Previous value returned by mp_first_cpu()/mp_next_cpu()
+ * @return next CPU number to run on (e.g. 0)
+ */
+int mp_next_cpu(int cpu_select, int prev_cpu);
 #else
 static inline int mp_run_on_cpus(int cpu_select, mp_run_func func, void *arg)
 {
@@ -131,6 +156,21 @@ static inline int mp_park_aps(void)
return 0;
 }
 
+static inline int mp_first_cpu(int cpu_select)
+{
+   /* We cannot run on any APs, nor a selected CPU */
+   return cpu_select == MP_SELECT_APS ? -EFBIG : MP_SELECT_BSP;
+}
+
+static inline int mp_next_cpu(int cpu_select, int prev_cpu)
+{
+   /*
+* When MP is not enabled, there is only one CPU and we did it in
+* mp_first_cpu()
+*/
+   return -EFBIG;
+}
+
 #endif
 
 #endif /* _X86_MP_H_ */
-- 
2.27.0.290.gba653c62da-goog



[PATCH v2 12/25] x86: Set the SMP flag when MP init is complete

2020-06-14 Thread Simon Glass
Set this flag so we can track when it is safe to use CPUs other than the
main one.

Signed-off-by: Simon Glass 
Reviewed-by: Wolfgang Wallner 
---

(no changes since v1)

 arch/x86/cpu/mp_init.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/x86/cpu/mp_init.c b/arch/x86/cpu/mp_init.c
index 673fdc9628..b0df7a3965 100644
--- a/arch/x86/cpu/mp_init.c
+++ b/arch/x86/cpu/mp_init.c
@@ -643,6 +643,7 @@ int mp_init(void)
debug("CPU init failed: err=%d\n", ret);
return ret;
}
+   gd->flags |= GD_FLG_SMP_INIT;
 
return 0;
 }
-- 
2.27.0.290.gba653c62da-goog



[PATCH v2 14/25] x86: mp: Park CPUs before running the OS

2020-06-14 Thread Simon Glass
With the new MP features the CPUs are no-longer parked when the OS is run.
Fix this by calling a special function to park them, just before the OS is
started.

Signed-off-by: Simon Glass 
Reviewed-by: Wolfgang Wallner 
---

(no changes since v1)

 arch/x86/cpu/cpu.c|  5 +
 arch/x86/cpu/mp_init.c| 18 ++
 arch/x86/include/asm/mp.h | 17 +
 3 files changed, 40 insertions(+)

diff --git a/arch/x86/cpu/cpu.c b/arch/x86/cpu/cpu.c
index d0720fb7fb..baa7dae172 100644
--- a/arch/x86/cpu/cpu.c
+++ b/arch/x86/cpu/cpu.c
@@ -66,6 +66,11 @@ static const char *const x86_vendor_name[] = {
 
 int __weak x86_cleanup_before_linux(void)
 {
+   int ret;
+
+   ret = mp_park_aps();
+   if (ret)
+   return log_msg_ret("park", ret);
bootstage_stash((void *)CONFIG_BOOTSTAGE_STASH_ADDR,
CONFIG_BOOTSTAGE_STASH_SIZE);
 
diff --git a/arch/x86/cpu/mp_init.c b/arch/x86/cpu/mp_init.c
index e65c82c8fd..9970b51c8d 100644
--- a/arch/x86/cpu/mp_init.c
+++ b/arch/x86/cpu/mp_init.c
@@ -657,6 +657,24 @@ int mp_run_on_cpus(int cpu_select, mp_run_func func, void 
*arg)
return 0;
 }
 
+static void park_this_cpu(void *unused)
+{
+   stop_this_cpu();
+}
+
+int mp_park_aps(void)
+{
+   unsigned long start;
+   int ret;
+
+   start = get_timer(0);
+   ret = mp_run_on_cpus(MP_SELECT_APS, park_this_cpu, NULL);
+   if (ret)
+   return ret;
+
+   return get_timer(start);
+}
+
 int mp_init(void)
 {
int num_aps, num_cpus;
diff --git a/arch/x86/include/asm/mp.h b/arch/x86/include/asm/mp.h
index 0272b3c0b6..38961ca44b 100644
--- a/arch/x86/include/asm/mp.h
+++ b/arch/x86/include/asm/mp.h
@@ -106,6 +106,15 @@ typedef void (*mp_run_func)(void *arg);
  * @return 0 on success, -ve on error
  */
 int mp_run_on_cpus(int cpu_select, mp_run_func func, void *arg);
+
+/**
+ * mp_park_aps() - Park the APs ready for the OS
+ *
+ * This halts all CPUs except the main one, ready for the OS to use them
+ *
+ * @return 0 on success, -ve on error
+ */
+int mp_park_aps(void);
 #else
 static inline int mp_run_on_cpus(int cpu_select, mp_run_func func, void *arg)
 {
@@ -114,6 +123,14 @@ static inline int mp_run_on_cpus(int cpu_select, 
mp_run_func func, void *arg)
 
return 0;
 }
+
+static inline int mp_park_aps(void)
+{
+   /* No APs to park */
+
+   return 0;
+}
+
 #endif
 
 #endif /* _X86_MP_H_ */
-- 
2.27.0.290.gba653c62da-goog



[PATCH v2 06/25] x86: mtrr: Fix 'ensable' typo

2020-06-14 Thread Simon Glass
Fix a typo in the command help.

Signed-off-by: Simon Glass 
Reviewed-by: Wolfgang Wallner 
---

(no changes since v1)

 cmd/x86/mtrr.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/cmd/x86/mtrr.c b/cmd/x86/mtrr.c
index 084d7315f4..5d25c5802a 100644
--- a/cmd/x86/mtrr.c
+++ b/cmd/x86/mtrr.c
@@ -135,5 +135,5 @@ U_BOOT_CMD(
"set   - set a register\n"
"\t is Uncacheable, Combine, Through, Protect, Back\n"
"disable   - disable a register\n"
-   "ensable   - enable a register"
+   "enable- enable a register"
 );
-- 
2.27.0.290.gba653c62da-goog



[PATCH v2 19/25] x86: mtrr: Update MTRRs on all CPUs

2020-06-14 Thread Simon Glass
When the boot CPU MTRRs are updated, perform the same update on all other
CPUs so they are kept in sync.

This avoids kernel warnings about mismatched MTRRs.

Signed-off-by: Simon Glass 
Reviewed-by: Wolfgang Wallner 
---

Changes in v2:
- Rename function to mtrr_write_all()

 arch/x86/cpu/mtrr.c | 57 +
 1 file changed, 57 insertions(+)

diff --git a/arch/x86/cpu/mtrr.c b/arch/x86/cpu/mtrr.c
index c9b4e7d06e..5c567551e5 100644
--- a/arch/x86/cpu/mtrr.c
+++ b/arch/x86/cpu/mtrr.c
@@ -74,10 +74,61 @@ void mtrr_read_all(struct mtrr_info *info)
}
 }
 
+void mtrr_write_all(struct mtrr_info *info)
+{
+   struct mtrr_state state;
+   int i;
+
+   for (i = 0; i < MTRR_COUNT; i++) {
+   mtrr_open(&state, true);
+   wrmsrl(MTRR_PHYS_BASE_MSR(i), info->mtrr[i].base);
+   wrmsrl(MTRR_PHYS_MASK_MSR(i), info->mtrr[i].mask);
+   mtrr_close(&state, true);
+   }
+}
+
+static void write_mtrrs(void *arg)
+{
+   struct mtrr_info *info = arg;
+
+   mtrr_write_all(info);
+}
+
+static void read_mtrrs(void *arg)
+{
+   struct mtrr_info *info = arg;
+
+   mtrr_read_all(info);
+}
+
+/**
+ * mtrr_copy_to_aps() - Copy the MTRRs from the boot CPU to other CPUs
+ *
+ * @return 0 on success, -ve on failure
+ */
+static int mtrr_copy_to_aps(void)
+{
+   struct mtrr_info info;
+   int ret;
+
+   ret = mp_run_on_cpus(MP_SELECT_BSP, read_mtrrs, &info);
+   if (ret == -ENXIO)
+   return 0;
+   else if (ret)
+   return log_msg_ret("bsp", ret);
+
+   ret = mp_run_on_cpus(MP_SELECT_APS, write_mtrrs, &info);
+   if (ret)
+   return log_msg_ret("bsp", ret);
+
+   return 0;
+}
+
 int mtrr_commit(bool do_caches)
 {
struct mtrr_request *req = gd->arch.mtrr_req;
struct mtrr_state state;
+   int ret;
int i;
 
debug("%s: enabled=%d, count=%d\n", __func__, gd->arch.has_mtrr,
@@ -99,6 +150,12 @@ int mtrr_commit(bool do_caches)
mtrr_close(&state, do_caches);
debug("mtrr done\n");
 
+   if (gd->flags & GD_FLG_RELOC) {
+   ret = mtrr_copy_to_aps();
+   if (ret)
+   return log_msg_ret("copy", ret);
+   }
+
return 0;
 }
 
-- 
2.27.0.290.gba653c62da-goog



[PATCH v2 18/25] x86: coral: Update the memory map

2020-06-14 Thread Simon Glass
This currently excludes the temporary memory used to start up the APs.
Add it.

Signed-off-by: Simon Glass 
---

Changes in v2:
- Add new patch to add AP_DEFAULT_BASE to coral's memory map

 doc/board/google/chromebook_coral.rst | 1 +
 1 file changed, 1 insertion(+)

diff --git a/doc/board/google/chromebook_coral.rst 
b/doc/board/google/chromebook_coral.rst
index 40bd9397d4..c39f1e310c 100644
--- a/doc/board/google/chromebook_coral.rst
+++ b/doc/board/google/chromebook_coral.rst
@@ -188,6 +188,7 @@ Partial memory map
 fef0  1000 CONFIG_BOOTSTAGE_STASH_ADDR
 fef0   Base of CAR region
 
+   3   AP_DEFAULT_BASE (used to start up additional CPUs)
f   CONFIG_ROM_TABLE_ADDR
   12   BSS (defined in u-boot-spl.lds)
   20   FSP-S (which is run after U-Boot is relocated)
-- 
2.27.0.290.gba653c62da-goog



[PATCH v2 20/25] x86: mtrr: Add support for writing to MTRRs on any CPU

2020-06-14 Thread Simon Glass
To enable support for the 'mtrr' command, add a way to perform MTRR
operations on selected CPUs.

This works by setting up a little 'operation' structure and sending it
around the CPUs for action.

Signed-off-by: Simon Glass 
---

Changes in v2:
- Keep things building by temporarily renaming the function in cmd/

 arch/x86/cpu/mtrr.c | 81 +
 arch/x86/include/asm/mtrr.h | 21 ++
 cmd/x86/mtrr.c  |  6 +--
 3 files changed, 105 insertions(+), 3 deletions(-)

diff --git a/arch/x86/cpu/mtrr.c b/arch/x86/cpu/mtrr.c
index 5c567551e5..2468d88a80 100644
--- a/arch/x86/cpu/mtrr.c
+++ b/arch/x86/cpu/mtrr.c
@@ -221,3 +221,84 @@ int mtrr_set_next_var(uint type, uint64_t start, uint64_t 
size)
 
return 0;
 }
+
+/** enum mtrr_opcode - supported operations for mtrr_do_oper() */
+enum mtrr_opcode {
+   MTRR_OP_SET,
+   MTRR_OP_SET_VALID,
+};
+
+/**
+ * struct mtrr_oper - An MTRR operation to perform on a CPU
+ *
+ * @opcode: Indicates operation to perform
+ * @reg: MTRR reg number to select (0-7, -1 = all)
+ * @valid: Valid value to write for MTRR_OP_SET_VALID
+ * @base: Base value to write for MTRR_OP_SET
+ * @mask: Mask value to write for MTRR_OP_SET
+ */
+struct mtrr_oper {
+   enum mtrr_opcode opcode;
+   int reg;
+   bool valid;
+   u64 base;
+   u64 mask;
+};
+
+static void mtrr_do_oper(void *arg)
+{
+   struct mtrr_oper *oper = arg;
+   u64 mask;
+
+   switch (oper->opcode) {
+   case MTRR_OP_SET_VALID:
+   mask = native_read_msr(MTRR_PHYS_MASK_MSR(oper->reg));
+   if (oper->valid)
+   mask |= MTRR_PHYS_MASK_VALID;
+   else
+   mask &= ~MTRR_PHYS_MASK_VALID;
+   wrmsrl(MTRR_PHYS_MASK_MSR(oper->reg), mask);
+   break;
+   case MTRR_OP_SET:
+   wrmsrl(MTRR_PHYS_BASE_MSR(oper->reg), oper->base);
+   wrmsrl(MTRR_PHYS_MASK_MSR(oper->reg), oper->mask);
+   break;
+   }
+}
+
+static int mtrr_start_op(int cpu_select, struct mtrr_oper *oper)
+{
+   struct mtrr_state state;
+   int ret;
+
+   mtrr_open(&state, true);
+   ret = mp_run_on_cpus(cpu_select, mtrr_do_oper, oper);
+   mtrr_close(&state, true);
+   if (ret)
+   return log_msg_ret("run", ret);
+
+   return 0;
+}
+
+int mtrr_set_valid(int cpu_select, int reg, bool valid)
+{
+   struct mtrr_oper oper;
+
+   oper.opcode = MTRR_OP_SET_VALID;
+   oper.reg = reg;
+   oper.valid = valid;
+
+   return mtrr_start_op(cpu_select, &oper);
+}
+
+int mtrr_set(int cpu_select, int reg, u64 base, u64 mask)
+{
+   struct mtrr_oper oper;
+
+   oper.opcode = MTRR_OP_SET;
+   oper.reg = reg;
+   oper.base = base;
+   oper.mask = mask;
+
+   return mtrr_start_op(cpu_select, &oper);
+}
diff --git a/arch/x86/include/asm/mtrr.h b/arch/x86/include/asm/mtrr.h
index e1f1a44643..48db1dd82f 100644
--- a/arch/x86/include/asm/mtrr.h
+++ b/arch/x86/include/asm/mtrr.h
@@ -159,6 +159,27 @@ int mtrr_set_next_var(uint type, uint64_t base, uint64_t 
size);
  */
 void mtrr_read_all(struct mtrr_info *info);
 
+/**
+ * mtrr_set_valid() - Set the valid flag for a selected MTRR and CPU(s)
+ *
+ * @cpu_select: Selected CPUs (either a CPU number or MP_SELECT_...)
+ * @reg: MTRR register to write (0-7)
+ * @valid: Valid flag to write
+ * @return 0 on success, -ve on error
+ */
+int mtrr_set_valid(int cpu_select, int reg, bool valid);
+
+/**
+ * mtrr_set() - Set the valid flag for a selected MTRR and CPU(s)
+ *
+ * @cpu_select: Selected CPUs (either a CPU number or MP_SELECT_...)
+ * @reg: MTRR register to write (0-7)
+ * @base: Base address and MTRR_BASE_TYPE_MASK
+ * @mask: Mask and MTRR_PHYS_MASK_VALID
+ * @return 0 on success, -ve on error
+ */
+int mtrr_set(int cpu_select, int reg, u64 base, u64 mask);
+
 #endif
 
 #if ((CONFIG_XIP_ROM_SIZE & (CONFIG_XIP_ROM_SIZE - 1)) != 0)
diff --git a/cmd/x86/mtrr.c b/cmd/x86/mtrr.c
index f357f58767..46ef6a2830 100644
--- a/cmd/x86/mtrr.c
+++ b/cmd/x86/mtrr.c
@@ -96,7 +96,7 @@ static int do_mtrr_set(uint reg, int argc, char *const argv[])
return 0;
 }
 
-static int mtrr_set_valid(int reg, bool valid)
+static int mtrr_set_valid_(int reg, bool valid)
 {
struct mtrr_state state;
uint64_t mask;
@@ -134,9 +134,9 @@ static int do_mtrr(struct cmd_tbl *cmdtp, int flag, int 
argc,
return CMD_RET_USAGE;
}
if (*cmd == 'e')
-   return mtrr_set_valid(reg, true);
+   return mtrr_set_valid_(reg, true);
else if (*cmd == 'd')
-   return mtrr_set_valid(reg, false);
+   return mtrr_set_valid_(reg, false);
else if (*cmd == 's')
return do_mtrr_set(reg, argc - 1, argv + 1);
else
-- 
2.27.0.290.gba653c62da-goog



[PATCH v2 17/25] x86: Don't enable SMP in SPL

2020-06-14 Thread Simon Glass
SMP should be set up in U-Boot where possible, not SPL. Disable it in SPL.
For 64-bit U-Boot we should find a way to allow SMP operations in U-Boot,
but this is somewhat more complicated. For now that is disabled too.

Signed-off-by: Simon Glass 
---

Changes in v2:
- Add a new patch to avoid enabling SMP in SPL

 arch/x86/cpu/Makefile | 2 +-
 arch/x86/include/asm/mp.h | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/x86/cpu/Makefile b/arch/x86/cpu/Makefile
index ee0499f5d7..16e67e3da2 100644
--- a/arch/x86/cpu/Makefile
+++ b/arch/x86/cpu/Makefile
@@ -60,7 +60,7 @@ ifndef CONFIG_SYS_COREBOOT
 obj-$(CONFIG_$(SPL_TPL_)X86_32BIT_INIT) += irq.o
 endif
 ifndef CONFIG_$(SPL_)X86_64
-obj-$(CONFIG_SMP) += mp_init.o
+obj-$(CONFIG_$(SPL_)SMP) += mp_init.o
 endif
 obj-y += mtrr.o
 obj-$(CONFIG_PCI) += pci.o
diff --git a/arch/x86/include/asm/mp.h b/arch/x86/include/asm/mp.h
index 9f4223ae8c..0fabfca8df 100644
--- a/arch/x86/include/asm/mp.h
+++ b/arch/x86/include/asm/mp.h
@@ -93,7 +93,7 @@ int x86_mp_init(void);
  */
 typedef void (*mp_run_func)(void *arg);
 
-#if defined(CONFIG_SMP) && !CONFIG_IS_ENABLED(X86_64)
+#if CONFIG_IS_ENABLED(SMP) && !CONFIG_IS_ENABLED(X86_64)
 /**
  * mp_run_on_cpus() - Run a function on one or all CPUs
  *
-- 
2.27.0.290.gba653c62da-goog



[PATCH v2 21/25] x86: mtrr: Update the command to use the new mtrr calls

2020-06-14 Thread Simon Glass
Use the multi-CPU calls to set the MTRR values. This still supports only
the boot CPU for now.

Signed-off-by: Simon Glass 
Reviewed-by: Wolfgang Wallner 
---

Changes in v2:
- Drop the renamed mtrr_set_valid_() instead of mtrr_set_valid()

 cmd/x86/mtrr.c | 34 --
 1 file changed, 8 insertions(+), 26 deletions(-)

diff --git a/cmd/x86/mtrr.c b/cmd/x86/mtrr.c
index 46ef6a2830..b047a9897c 100644
--- a/cmd/x86/mtrr.c
+++ b/cmd/x86/mtrr.c
@@ -59,14 +59,14 @@ static int do_mtrr_list(int cpu_select)
return 0;
 }
 
-static int do_mtrr_set(uint reg, int argc, char *const argv[])
+static int do_mtrr_set(int cpu_select, uint reg, int argc, char *const argv[])
 {
const char *typename = argv[0];
-   struct mtrr_state state;
uint32_t start, size;
uint64_t base, mask;
int i, type = -1;
bool valid;
+   int ret;
 
if (argc < 3)
return CMD_RET_USAGE;
@@ -88,27 +88,9 @@ static int do_mtrr_set(uint reg, int argc, char *const 
argv[])
if (valid)
mask |= MTRR_PHYS_MASK_VALID;
 
-   mtrr_open(&state, true);
-   wrmsrl(MTRR_PHYS_BASE_MSR(reg), base);
-   wrmsrl(MTRR_PHYS_MASK_MSR(reg), mask);
-   mtrr_close(&state, true);
-
-   return 0;
-}
-
-static int mtrr_set_valid_(int reg, bool valid)
-{
-   struct mtrr_state state;
-   uint64_t mask;
-
-   mtrr_open(&state, true);
-   mask = native_read_msr(MTRR_PHYS_MASK_MSR(reg));
-   if (valid)
-   mask |= MTRR_PHYS_MASK_VALID;
-   else
-   mask &= ~MTRR_PHYS_MASK_VALID;
-   wrmsrl(MTRR_PHYS_MASK_MSR(reg), mask);
-   mtrr_close(&state, true);
+   ret = mtrr_set(cpu_select, reg, base, mask);
+   if (ret)
+   return CMD_RET_FAILURE;
 
return 0;
 }
@@ -134,11 +116,11 @@ static int do_mtrr(struct cmd_tbl *cmdtp, int flag, int 
argc,
return CMD_RET_USAGE;
}
if (*cmd == 'e')
-   return mtrr_set_valid_(reg, true);
+   return mtrr_set_valid(cpu_select, reg, true);
else if (*cmd == 'd')
-   return mtrr_set_valid_(reg, false);
+   return mtrr_set_valid(cpu_select, reg, false);
else if (*cmd == 's')
-   return do_mtrr_set(reg, argc - 1, argv + 1);
+   return do_mtrr_set(cpu_select, reg, argc - 1, argv + 1);
else
return CMD_RET_USAGE;
 
-- 
2.27.0.290.gba653c62da-goog



[PATCH v2 22/25] x86: mtrr: Restructure so command execution is in one place

2020-06-14 Thread Simon Glass
At present do_mtrr() does the 'list' subcommand at the top and the rest
below. Update it to do them all in the same place so we can (in a later
patch) add parsing of the CPU number for all subcommands.

Signed-off-by: Simon Glass 
Reviewed-by: Wolfgang Wallner 
---

(no changes since v1)

 cmd/x86/mtrr.c | 55 +-
 1 file changed, 36 insertions(+), 19 deletions(-)

diff --git a/cmd/x86/mtrr.c b/cmd/x86/mtrr.c
index b047a9897c..b51b1cd7e2 100644
--- a/cmd/x86/mtrr.c
+++ b/cmd/x86/mtrr.c
@@ -98,31 +98,48 @@ static int do_mtrr_set(int cpu_select, uint reg, int argc, 
char *const argv[])
 static int do_mtrr(struct cmd_tbl *cmdtp, int flag, int argc,
   char *const argv[])
 {
-   const char *cmd;
+   int cmd;
int cpu_select;
uint reg;
+   int ret;
 
cpu_select = MP_SELECT_BSP;
-   cmd = argv[1];
-   if (argc < 2 || *cmd == 'l')
+   argc--;
+   argv++;
+   cmd = argv[0] ? *argv[0] : 0;
+   if (argc < 1 || !cmd) {
+   cmd = 'l';
+   reg = 0;
+   } else {
+   if (argc < 2)
+   return CMD_RET_USAGE;
+   reg = simple_strtoul(argv[1], NULL, 16);
+   if (reg >= MTRR_COUNT) {
+   printf("Invalid register number\n");
+   return CMD_RET_USAGE;
+   }
+   }
+   if (cmd == 'l') {
return do_mtrr_list(cpu_select);
-   argc -= 2;
-   argv += 2;
-   if (argc <= 0)
-   return CMD_RET_USAGE;
-   reg = simple_strtoul(argv[0], NULL, 16);
-   if (reg >= MTRR_COUNT) {
-   printf("Invalid register number\n");
-   return CMD_RET_USAGE;
+   } else {
+   switch (cmd) {
+   case 'e':
+   ret = mtrr_set_valid(cpu_select, reg, true);
+   break;
+   case 'd':
+   ret = mtrr_set_valid(cpu_select, reg, false);
+   break;
+   case 's':
+   ret = do_mtrr_set(cpu_select, reg, argc - 2, argv + 2);
+   break;
+   default:
+   return CMD_RET_USAGE;
+   }
+   if (ret) {
+   printf("Operation failed (err=%d)\n", ret);
+   return CMD_RET_FAILURE;
+   }
}
-   if (*cmd == 'e')
-   return mtrr_set_valid(cpu_select, reg, true);
-   else if (*cmd == 'd')
-   return mtrr_set_valid(cpu_select, reg, false);
-   else if (*cmd == 's')
-   return do_mtrr_set(cpu_select, reg, argc - 1, argv + 1);
-   else
-   return CMD_RET_USAGE;
 
return 0;
 }
-- 
2.27.0.290.gba653c62da-goog



[PATCH v2 24/25] x86: mp: Add more comments to the module

2020-06-14 Thread Simon Glass
Add a description of how this module works and also some missing function
comments.

Drop struct cpu_map since it is not used.

Signed-off-by: Simon Glass 
---

Changes in v2:
- Add a new patch with more comments

 arch/x86/cpu/mp_init.c| 91 ++-
 arch/x86/include/asm/mp.h | 14 +-
 2 files changed, 102 insertions(+), 3 deletions(-)

diff --git a/arch/x86/cpu/mp_init.c b/arch/x86/cpu/mp_init.c
index c708c3e3c0..873b36a81d 100644
--- a/arch/x86/cpu/mp_init.c
+++ b/arch/x86/cpu/mp_init.c
@@ -31,13 +31,99 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
+/*
+ * Setting up multiprocessing
+ *
+ * See 
https://www.intel.com/content/www/us/en/intelligent-systems/intel-boot-loader-development-kit/minimal-intel-architecture-boot-loader-paper.html
+ *
+ * Note that this file refers to the boot CPU (the one U-Boot is running on) as
+ * the BSP (BootStrap Processor) and the others as APs (Application 
Processors).
+ *
+ * This module works by loading some setup code into RAM at AP_DEFAULT_BASE and
+ * telling each AP to execute it. The code that each AP runs is in
+ * sipi_vector.S (see ap_start16) which includes a struct sipi_params at the
+ * end of it. Those parameters are set up by the C code.
+
+ * Setting up is handled by load_sipi_vector(). It inits the common block of
+ * parameters (sipi_params) which tell the APs what to do. This block includes
+ * microcode and the MTTRs (Memory-Type-Range Registers) from the main CPU.
+ * There is also an ap_count which each AP increments as it starts up, so the
+ * BSP can tell how many checked in.
+ *
+ * The APs are started with a SIPI (Startup Inter-Processor Interrupt) which
+ * tells an AP to start executing at a particular address, in this case
+ * AP_DEFAULT_BASE which contains the code copied from ap_start16. This 
protocol
+ * is handled by start_aps().
+ *
+ * After being started, each AP runs the code in ap_start16, switches to 32-bit
+ * mode, runs the code at ap_start, then jumps to c_handler which is ap_init().
+ * This runs a very simple 'flight plan' described in* mp_steps. This sets up
+ * the CPU and waits for further instructions by looking at its entry in
+ * ap_callbacks[]. Note that the flight plan is only actually run for each CPU
+ * in bsp_do_flight_plan(): once the BSP completes each flight record, it sets
+ * mp_flight_record->barrier to 1 to allow the APs to executed the record one
+ * by one.
+ *
+ * CPUS are numbered sequentially from 0 using the device tree:
+ *
+ * cpus {
+ * u-boot,dm-pre-reloc;
+ * #address-cells = <1>;
+ * #size-cells = <0>;
+ *
+ * cpu@0 {
+ * u-boot,dm-pre-reloc;
+ * device_type = "cpu";
+ * compatible = "intel,apl-cpu";
+ * reg = <0>;
+ * intel,apic-id = <0>;
+ * };
+ *
+ * cpu@1 {
+ * device_type = "cpu";
+ * compatible = "intel,apl-cpu";
+ * reg = <1>;
+ * intel,apic-id = <2>;
+ * };
+ *
+ * Here the 'reg' property is the CPU number and then is placed in dev->req_seq
+ * so that we can index into ap_callbacks[] using that. The APIC ID is 
different
+ * and may not be sequential (it typically is if hyperthreading is supported).
+ *
+ * Once APs are inited they wait in ap_wait_for_instruction() for instructions.
+ * Instructions come in the form of a function to run. This logic is in
+ * mp_run_on_cpus() which supports running on any one AP, all APs, just the BSP
+ * or all CPUs. The BSP logic is handled directly in mp_run_on_cpus(), by
+ * calling the function. For the APs, callback information is stored in a
+ * single, common struct mp_callback and a pointer to this is written to each
+ * AP's slot in ap_callbacks[] by run_ap_work(). All APs get the message even
+ * if it is only for one of them. When an AP notices a message it checks 
whether
+ * it should call the function (see check in ap_wait_for_instruction()) and 
then
+ * does so if needed. After that it sets its slot to NULL to indicate it is
+ * done.
+ *
+ * While U-Boot is running it can use mp_run_on_cpus() to run code on the APs.
+ * An example of this is the 'mtrr' command which allows reading and changing
+ * the MTRRs on all CPUs.
+ *
+ * Before U-Boot exits it calls mp_park_aps() which tells all CPUs to halt by
+ * executing a 'hlt' instruction. That allows them to be used by Linux when it
+ * starts up.
+ */
+
 /* This also needs to match the sipi.S assembly code for saved MSR encoding */
-struct saved_msr {
+struct __packed saved_msr {
uint32_t index;
uint32_t lo;
uint32_t hi;
-} __packed;
+};
 
+/**
+ * struct mp_flight_plan - Holds the flight plan
+ *
+ * @num_records: Number of flight records
+ * @records: Pointer to each record
+ */
 struct mp_flight_plan {
int num_records;
struct mp_flight_record *records;
@@ -58

[PATCH v2 23/25] x86: mtrr: Update 'mtrr' to allow setting MTRRs on any CPU

2020-06-14 Thread Simon Glass
Add a -c option to mtrr to allow any CPU to be updated with this command.

Signed-off-by: Simon Glass 
Reviewed-by: Wolfgang Wallner 
---

(no changes since v1)

 cmd/x86/mtrr.c | 18 --
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/cmd/x86/mtrr.c b/cmd/x86/mtrr.c
index b51b1cd7e2..d88a875d92 100644
--- a/cmd/x86/mtrr.c
+++ b/cmd/x86/mtrr.c
@@ -104,6 +104,17 @@ static int do_mtrr(struct cmd_tbl *cmdtp, int flag, int 
argc,
int ret;
 
cpu_select = MP_SELECT_BSP;
+   if (argc >= 3 && !strcmp("-c", argv[1])) {
+   const char *cpustr;
+
+   cpustr = argv[2];
+   if (*cpustr == 'a')
+   cpu_select = MP_SELECT_ALL;
+   else
+   cpu_select = simple_strtol(cpustr, NULL, 16);
+   argc -= 2;
+   argv += 2;
+   }
argc--;
argv++;
cmd = argv[0] ? *argv[0] : 0;
@@ -145,11 +156,14 @@ static int do_mtrr(struct cmd_tbl *cmdtp, int flag, int 
argc,
 }
 
 U_BOOT_CMD(
-   mtrr,   6,  1,  do_mtrr,
+   mtrr,   8,  1,  do_mtrr,
"Use x86 memory type range registers (32-bit only)",
"[list]- list current registers\n"
"set   - set a register\n"
"\t is Uncacheable, Combine, Through, Protect, Back\n"
"disable   - disable a register\n"
-   "enable- enable a register"
+   "enable- enable a register\n"
+   "\n"
+   "Precede command with '-c |all' to access a particular CPU, e.g.\n"
+   "   mtrr -c all list; mtrr -c 2e list"
 );
-- 
2.27.0.290.gba653c62da-goog



[PATCH v2 25/25] x86: mtrr: Enhance 'mtrr' command to list MTRRs on any CPU

2020-06-14 Thread Simon Glass
Update this command so it can list the MTRRs on a selected CPU. If
'-c all' is used, then all CPUs are listed.

Signed-off-by: Simon Glass 
Reviewed-by: Wolfgang Wallner 
---

(no changes since v1)

 cmd/x86/mtrr.c | 22 +-
 1 file changed, 21 insertions(+), 1 deletion(-)

diff --git a/cmd/x86/mtrr.c b/cmd/x86/mtrr.c
index d88a875d92..e688c64052 100644
--- a/cmd/x86/mtrr.c
+++ b/cmd/x86/mtrr.c
@@ -131,7 +131,27 @@ static int do_mtrr(struct cmd_tbl *cmdtp, int flag, int 
argc,
}
}
if (cmd == 'l') {
-   return do_mtrr_list(cpu_select);
+   bool first;
+   int i;
+
+   i = mp_first_cpu(cpu_select);
+   if (i < 0) {
+   printf("Invalid CPU (err=%d)\n", i);
+   return CMD_RET_FAILURE;
+   }
+   first = true;
+   for (; i >= 0; i = mp_next_cpu(cpu_select, i)) {
+   if (!first)
+   printf("\n");
+   printf("CPU %d:\n", i);
+   ret = do_mtrr_list(i);
+   if (ret) {
+   printf("Failed to read CPU %d (err=%d)\n", i,
+  ret);
+   return CMD_RET_FAILURE;
+   }
+   first = false;
+   }
} else {
switch (cmd) {
case 'e':
-- 
2.27.0.290.gba653c62da-goog



Re: [PATCH RESEND v2 1/1] log: don't show function by default

2020-06-14 Thread Simon Glass
Hi Heinrich,

On Sun, 14 Jun 2020 at 08:48, Heinrich Schuchardt  wrote:
>
> The name of the function emitting a log message may be of interest for a
> developer but is distracting for normal users. See the example below:
>
> try_load_entry() Booting: Debian
>
> Make the default format for log messages customizable. By default show
> only the message text.
>
> Signed-off-by: Heinrich Schuchardt 
> ---
> v2:
> adjust logging tests
> adjust description of log command
> ---
>  cmd/log.c |  2 +-
>  common/Kconfig| 18 ++
>  include/log.h | 12 +++-
>  test/log/syslog_test.c| 20 ++--
>  test/py/tests/test_log.py |  2 ++
>  5 files changed, 46 insertions(+), 8 deletions(-)
>
> diff --git a/cmd/log.c b/cmd/log.c
> index 78352b2cb9..2c91545c0d 100644
> --- a/cmd/log.c
> +++ b/cmd/log.c
> @@ -139,7 +139,7 @@ static char log_help_text[] =
> "log format  - set log output format.  is a string where\n"
> "\teach letter indicates something that should be displayed:\n"
> "\tc=category, l=level, F=file, L=line number, f=function, m=msg\n"
> -   "\tor 'default', equivalent to 'fm', or 'all' for all\n"
> +   "\tor 'default', or 'all' for all\n"
> "log rec   - "
> "output a log record"
> ;
> diff --git a/common/Kconfig b/common/Kconfig
> index 7872bc46cd..60cae77f20 100644
> --- a/common/Kconfig
> +++ b/common/Kconfig
> @@ -792,6 +792,24 @@ config TPL_LOG_CONSOLE
>
>  endif
>
> +config LOGF_FILE
> +   bool "Show source file name in log messages by default"
> +   help
> + Show the source file name in log messages by default. This value
> + can be overridden using the 'log format' command.
> +
> +config LOGF_LINE
> +   bool "Show source line number in log messages by default"
> +   help
> + Show the source line number in log messages by default. This value
> + can be overridden using the 'log format' command.
> +
> +config LOGF_FUNC
> +   bool "Show function name in log messages by default"
> +   help
> + Show the function name in log messages by default. This value can
> + be overridden using the 'log format' command.
> +
>  config LOG_ERROR_RETURN
> bool "Log all functions which return an error"
> help
> diff --git a/include/log.h b/include/log.h
> index df65398c04..ec471c3a01 100644
> --- a/include/log.h
> +++ b/include/log.h
> @@ -411,7 +411,17 @@ enum log_fmt {
> LOGF_MSG,
>
> LOGF_COUNT,
> -   LOGF_DEFAULT = (1 << LOGF_FUNC) | (1 << LOGF_MSG),
> +   LOGF_DEFAULT =
> +#ifdef CONFIG_LOGF_FILE
> +   (1 << LOGF_FILE) |
> +#endif
> +#ifdef CONFIG_LOGF_LINE
> +   (1 << LOGF_LINE) |
> +#endif
> +#ifdef CONFIG_LOGF_FUNC
> +   (1 << LOGF_FUNC) |
> +#endif

I don't like having these #ifdefs here. Could we instead add a
function to common/log.c like log_get_default_format() that uses
IS_ENABLED to return the value?

> +   (1 << LOGF_MSG),
> LOGF_ALL = 0x3f,
>  };
>

Regards,
Simon


Re: [PATCH v2 03/23] am335x: baltos: Enable DM_SPI

2020-06-14 Thread Yegor Yefremov
On Sat, Jun 13, 2020 at 8:01 PM Jagan Teki  wrote:
>
> On Wed, May 27, 2020 at 6:26 PM Jagan Teki  wrote:
> >
> > Enable DM_SPI for am355x baltos board.
> >
> > Build is fine, but not tested.
> >
> > Cc: Yegor Yefremov 
>
> Any comments?

Reviewed-by: Yegor Yefremov 


[PATCH v3 01/10] pinctrl: Add pinmux property support to pinctrl-generic

2020-06-14 Thread Sean Anderson
The pinmux property allows for smaller and more compact device trees,
especially when there are many pins which need to be assigned individually.
Instead of specifying an array of strings to be parsed as pins and a
function property, the pinmux property contains an array of integers
representing pinmux groups. A pinmux group consists of the pin identifier
and mux settings represented as a single integer or an array of integers.
Each individual pin controller driver specifies the exact format of a
pinmux group. As specified in the Linux documentation, a pinmux group may
be multiple integers long. However, no existing drivers use multi-integer
pinmux groups, so I have chosen to omit this feature. This makes the
implementation easier, since there is no need to allocate a buffer to do
endian conversions.

Support for the pinmux property is done differently than in Linux.  As far
as I can tell, inversion of control is used when implementing support for
the pins and groups properties to avoid allocating. This results in some
duplication of effort; every property in a config node is parsed once for
each pin in that node. This is not such an overhead with pins and groups
properties, since having multiple pins in one config node does not occur
especially often. However, the semantics of the pinmux property make such a
configuration much more appealing. A future patch could parse all config
properties at once and store them in an array. This would make it easier to
create drivers which do not function solely as callbacks from
pinctrl-generic.

This commit increases the size of the sandbox build by approximately 48
bytes.  However, it also decreases the size of the K210 device tree by 2
KiB from the previous version of this series.

The documentation has been updated from the last Linux commit before it was
split off into yaml files.

Signed-off-by: Sean Anderson 
---

(no changes since v2)

Changes in v2:
- New

 .../pinctrl/pinctrl-bindings.txt  |  65 -
 drivers/pinctrl/pinctrl-generic.c | 125 ++
 include/dm/pinctrl.h  |  21 +--
 3 files changed, 168 insertions(+), 43 deletions(-)

diff --git a/doc/device-tree-bindings/pinctrl/pinctrl-bindings.txt 
b/doc/device-tree-bindings/pinctrl/pinctrl-bindings.txt
index b73c96d24f..603796f169 100644
--- a/doc/device-tree-bindings/pinctrl/pinctrl-bindings.txt
+++ b/doc/device-tree-bindings/pinctrl/pinctrl-bindings.txt
@@ -119,7 +119,8 @@ For example:
 
 The contents of each of those pin configuration child nodes is defined
 entirely by the binding for the individual pin controller device. There
-exists no common standard for this content.
+exists no common standard for this content. The pinctrl framework only
+provides generic helper bindings that the pin controller driver can use.
 
 The pin configuration nodes need not be direct children of the pin controller
 device; they may be grandchildren, for example. Whether this is legal, and
@@ -156,6 +157,29 @@ state_2_node_a {
pins = "mfio29", "mfio30";
 };
 
+For hardware where pin multiplexing configurations have to be specified for
+each single pin the number of required sub-nodes containing "pin" and
+"function" properties can quickly escalate and become hard to write and
+maintain.
+
+For cases like this, the pin controller driver may use the pinmux helper
+property, where the pin identifier is provided with mux configuration settings
+in a pinmux group. A pinmux group consists of the pin identifier and mux
+settings represented as a single integer or an array of integers.
+
+The pinmux property accepts an array of pinmux groups, each of them describing
+a single pin multiplexing configuration.
+
+pincontroller {
+   state_0_node_a {
+   pinmux = , , ...;
+   };
+};
+
+Each individual pin controller driver bindings documentation shall specify
+how pin IDs and pin multiplexing configuration are defined and assembled
+together in a pinmux group.
+
 == Generic pin configuration node content ==
 
 Many data items that are represented in a pin configuration node are common
@@ -168,12 +192,15 @@ structure of the DT nodes that contain these properties.
 Supported generic properties are:
 
 pins   - the list of pins that properties in the node
- apply to (either this or "group" has to be
+ apply to (either this, "group" or "pinmux" has to be
  specified)
 group  - the group to apply the properties to, if the driver
  supports configuration of whole groups rather than
- individual pins (either this or "pins" has to be
- specified)
+ individual pins (either this, "pins" or "pinmux" has
+ to be specified)
+pinmux - the list of numeric pin ids and their mux settings
+ that propert

[PATCH v3 04/10] gpio: sifive: Use generic reg read function

2020-06-14 Thread Sean Anderson
Using an fdt-specific function causes problems with a live tree.

Signed-off-by: Sean Anderson 
Reviewed-by: Bin Meng 
---
This patch was previously submitted as part of
https://patchwork.ozlabs.org/project/uboot/list/?series=161576

(no changes since v1)

 drivers/gpio/sifive-gpio.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpio/sifive-gpio.c b/drivers/gpio/sifive-gpio.c
index 24da3b3c23..bf3537b76b 100644
--- a/drivers/gpio/sifive-gpio.c
+++ b/drivers/gpio/sifive-gpio.c
@@ -159,7 +159,7 @@ static int sifive_gpio_ofdata_to_platdata(struct udevice 
*dev)
struct sifive_gpio_platdata *plat = dev_get_platdata(dev);
fdt_addr_t addr;
 
-   addr = devfdt_get_addr(dev);
+   addr = dev_read_addr(dev);
if (addr == FDT_ADDR_T_NONE)
return -EINVAL;
 
-- 
2.26.2



[PATCH v3 00/10] riscv: Add FPIOA and GPIO support for Kendryte K210

2020-06-14 Thread Sean Anderson
This patch series adds support for pinmuxing, gpios, and leds on the Kendyte
K210.

This patch series was previously part of
https://patchwork.ozlabs.org/project/uboot/list/?series=161576

This patch series depends on
https://patchwork.ozlabs.org/project/uboot/list/?series=178480

Changes in v3:
- Add dt-bindings/pinctrl/sandbox-pinmux.h to patch

Changes in v2:
- Add test for pinmuxing
- Don't clear existing pinctrl settings on probe
- Re-order GPIOs to match the defaults more closely
- Rebase onto v13 of "riscv: Add Sipeed Maix support"
- Rewrite FPIOA driver to use pinmux property
- Support muxing the output enable signal for each function in the FPIOA
- Support output and input inversion in the pinmux driver
- Support pinmux property in pinctrl-generic

Sean Anderson (10):
  pinctrl: Add pinmux property support to pinctrl-generic
  test: pinmux: Add test for pin muxing
  pinctrl: Add support for Kendryte K210 FPIOA
  gpio: sifive: Use generic reg read function
  gpio: dw: Fix warnings about casting int to pointer
  gpio: dw: Add a trailing underscore to generated name
  gpio: dw: Return output value when direction is out
  led: gpio: Default to using node name if label is absent
  riscv: Add pinmux and gpio bindings for Kendryte K210
  riscv: Add FPIOA and GPIO support for Kendryte K210

 MAINTAINERS   |   2 +
 arch/riscv/dts/k210-maix-bit.dts  | 104 +++
 arch/riscv/dts/k210.dtsi  |  12 +
 arch/sandbox/dts/test.dts |  45 +-
 board/sipeed/maix/Kconfig |   9 +
 doc/board/sipeed/maix.rst |  64 +-
 .../pinctrl/kendryte,k210-fpioa.txt   | 102 +++
 .../pinctrl/pinctrl-bindings.txt  |  65 +-
 drivers/gpio/dwapb_gpio.c |  33 +-
 drivers/gpio/sifive-gpio.c|   2 +-
 drivers/led/led_gpio.c|   7 +-
 drivers/pinctrl/Kconfig   |   1 +
 drivers/pinctrl/Makefile  |   1 +
 drivers/pinctrl/kendryte/Kconfig  |   7 +
 drivers/pinctrl/kendryte/Makefile |   1 +
 drivers/pinctrl/kendryte/pinctrl.c| 678 ++
 drivers/pinctrl/kendryte/pinctrl.h|  70 ++
 drivers/pinctrl/pinctrl-generic.c | 125 +++-
 drivers/pinctrl/pinctrl-sandbox.c | 155 +++-
 include/dm/pinctrl.h  |  21 +-
 include/dt-bindings/pinctrl/k210-pinctrl.h| 277 +++
 include/dt-bindings/pinctrl/sandbox-pinmux.h  |  19 +
 test/dm/Makefile  |   3 +
 test/py/tests/test_pinmux.py  |  36 +-
 24 files changed, 1717 insertions(+), 122 deletions(-)
 create mode 100644 doc/device-tree-bindings/pinctrl/kendryte,k210-fpioa.txt
 create mode 100644 drivers/pinctrl/kendryte/Kconfig
 create mode 100644 drivers/pinctrl/kendryte/Makefile
 create mode 100644 drivers/pinctrl/kendryte/pinctrl.c
 create mode 100644 drivers/pinctrl/kendryte/pinctrl.h
 create mode 100644 include/dt-bindings/pinctrl/k210-pinctrl.h
 create mode 100644 include/dt-bindings/pinctrl/sandbox-pinmux.h

-- 
2.26.2



[PATCH v3 02/10] test: pinmux: Add test for pin muxing

2020-06-14 Thread Sean Anderson
This extends the pinctrl-sandbox driver to support pin muxing, and adds a
test for that behaviour. The test is done in C and not python (like the
existing tests for the pinctrl uclass) because it needs to call
pinctrl_select_state.  Another option could be to add a command that
invokes pinctrl_select_state and then test everything in
test/py/tests/test_pinmux.py.

The pinctrl-sandbox driver now mimics the way that many pinmux devices
work.  There are two groups of pins which are muxed together, as well as
four pins which are muxed individually. I have tried to test all normal
paths. However, very few error cases are explicitly checked for.

Signed-off-by: Sean Anderson 
---

Changes in v3:
- Add dt-bindings/pinctrl/sandbox-pinmux.h to patch

Changes in v2:
- New

 arch/sandbox/dts/test.dts|  45 +-
 drivers/pinctrl/pinctrl-sandbox.c| 155 ++-
 include/dt-bindings/pinctrl/sandbox-pinmux.h |  19 +++
 test/dm/Makefile |   3 +
 test/py/tests/test_pinmux.py |  36 ++---
 5 files changed, 197 insertions(+), 61 deletions(-)
 create mode 100644 include/dt-bindings/pinctrl/sandbox-pinmux.h

diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
index f5b685f7fe..36736f374d 100644
--- a/arch/sandbox/dts/test.dts
+++ b/arch/sandbox/dts/test.dts
@@ -2,6 +2,7 @@
 
 #include 
 #include 
+#include 
 
 / {
model = "sandbox";
@@ -967,30 +968,60 @@
pinctrl {
compatible = "sandbox,pinctrl";
 
-   pinctrl-names = "default";
-   pinctrl-0 = <&gpios>;
+   pinctrl-names = "default", "alternate";
+   pinctrl-0 = <&pinctrl_gpios>, <&pinctrl_i2s>;
+   pinctrl-1 = <&pinctrl_spi>, <&pinctrl_i2c>;
 
-   gpios: gpios {
+   pinctrl_gpios: gpios {
gpio0 {
-   pins = "GPIO0";
+   pins = "P5";
+   function = "GPIO";
bias-pull-up;
input-disable;
};
gpio1 {
-   pins = "GPIO1";
+   pins = "P6";
+   function = "GPIO";
output-high;
drive-open-drain;
};
gpio2 {
-   pins = "GPIO2";
+   pinmux = ;
bias-pull-down;
input-enable;
};
gpio3 {
-   pins = "GPIO3";
+   pinmux = ;
bias-disable;
};
};
+
+   pinctrl_i2c: i2c {
+   groups {
+   groups = "I2C_UART";
+   function = "I2C";
+   };
+
+   pins {
+   pins = "P0", "P1";
+   drive-open-drain;
+   };
+   };
+
+   pinctrl_i2s: i2s {
+   groups = "SPI_I2S";
+   function = "I2S";
+   };
+
+   pinctrl_spi: spi {
+   groups = "SPI_I2S";
+   function = "SPI";
+
+   cs {
+   pinmux = ,
+;
+   };
+   };
};
 
hwspinlock@0 {
diff --git a/drivers/pinctrl/pinctrl-sandbox.c 
b/drivers/pinctrl/pinctrl-sandbox.c
index ac0119d198..9aa13fbd55 100644
--- a/drivers/pinctrl/pinctrl-sandbox.c
+++ b/drivers/pinctrl/pinctrl-sandbox.c
@@ -3,55 +3,67 @@
  * Copyright (C) 2015  Masahiro Yamada 
  */
 
-/* #define DEBUG */
-
 #include 
 #include 
-#include 
 #include 
+#include 
+#include 
 #include 
 
+/*
+ * This driver emulates a pin controller with the following rules:
+ * - The pinctrl config for each pin must be set individually
+ * - The first three pins (P0-P2) must be muxed as a group
+ * - The next two pins (P3-P4) must be muxed as a group
+ * - The last four pins (P5-P8) must be muxed individually
+ */
+
 static const char * const sandbox_pins[] = {
-   "SCL",
-   "SDA",
-   "TX",
-   "RX",
-   "W1",
-   "GPIO0",
-   "GPIO1",
-   "GPIO2",
-   "GPIO3",
+#define PIN(x) \
+   [x] = "P" #x
+   PIN(0),
+   PIN(1),
+   PIN(2),
+   PIN(3),
+   PIN(4),
+   PIN(5),
+   PIN(6),
+   PIN(7),
+   PIN(8),
+#undef PIN
 };
 
-static const char * const sandbox_pins_muxing[] = {
-   "I2C SCL",
-   "I2C SDA",
-   "Uart TX",
-   "Uart RX",
-   "1-wire gpio",
-   "gp

[PATCH v3 06/10] gpio: dw: Add a trailing underscore to generated name

2020-06-14 Thread Sean Anderson
Previously, if there was no bank-name property, it was easy to have
confusing gpio names like "gpio1@08", instead of "gpio1@0_8". This patch
follows the example of the sifive gpio driver.

Signed-off-by: Sean Anderson 
---
This patch was previously submitted as part of
https://patchwork.ozlabs.org/project/uboot/list/?series=161576

(no changes since v1)

 drivers/gpio/dwapb_gpio.c | 10 +-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/drivers/gpio/dwapb_gpio.c b/drivers/gpio/dwapb_gpio.c
index bf324f5239..a52c9e18e3 100644
--- a/drivers/gpio/dwapb_gpio.c
+++ b/drivers/gpio/dwapb_gpio.c
@@ -186,7 +186,15 @@ static int gpio_dwapb_bind(struct udevice *dev)
 * Fall back to node name. This means accessing pins
 * via bank name won't work.
 */
-   plat->name = ofnode_get_name(node);
+   char name[32];
+
+   snprintf(name, sizeof(name), "%s_",
+ofnode_get_name(node));
+   plat->name = strdup(name);
+   if (!plat->name) {
+   kfree(plat);
+   return -ENOMEM;
+   }
}
 
ret = device_bind_ofnode(dev, dev->driver, plat->name,
-- 
2.26.2



[PATCH v3 08/10] led: gpio: Default to using node name if label is absent

2020-06-14 Thread Sean Anderson
This more closely mirrors Linux's behaviour, and will make it easier to
transition to using function+color in the future.

Signed-off-by: Sean Anderson 
---
This patch was previously submitted as part of
https://patchwork.ozlabs.org/project/uboot/list/?series=161576

(no changes since v1)

 drivers/led/led_gpio.c | 7 ++-
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/drivers/led/led_gpio.c b/drivers/led/led_gpio.c
index ef9b61ee62..2cdb0269f4 100644
--- a/drivers/led/led_gpio.c
+++ b/drivers/led/led_gpio.c
@@ -99,11 +99,8 @@ static int led_gpio_bind(struct udevice *parent)
const char *label;
 
label = ofnode_read_string(node, "label");
-   if (!label) {
-   debug("%s: node %s has no label\n", __func__,
- ofnode_get_name(node));
-   return -EINVAL;
-   }
+   if (!label)
+   label = ofnode_get_name(node);
ret = device_bind_driver_to_node(parent, "gpio_led",
 ofnode_get_name(node),
 node, &dev);
-- 
2.26.2



[PATCH v3 07/10] gpio: dw: Return output value when direction is out

2020-06-14 Thread Sean Anderson
dm_gpio_ops.get_value can be called when the gpio is either input or
output. The current dw code always returns the input value, which is
invalid if the direction is set to out.

Signed-off-by: Sean Anderson 
Reviewed-by: Ley Foon Tan 
---
This patch was previously submitted as part of
https://patchwork.ozlabs.org/project/uboot/list/?series=161576

Changes in v3:
- Undo reorder to prevent use-before-declared error

Changes in v2:
- Reorder changes to minimize diff

 drivers/gpio/dwapb_gpio.c | 19 ---
 1 file changed, 12 insertions(+), 7 deletions(-)

diff --git a/drivers/gpio/dwapb_gpio.c b/drivers/gpio/dwapb_gpio.c
index a52c9e18e3..37916e7771 100644
--- a/drivers/gpio/dwapb_gpio.c
+++ b/drivers/gpio/dwapb_gpio.c
@@ -66,13 +66,6 @@ static int dwapb_gpio_direction_output(struct udevice *dev, 
unsigned pin,
return 0;
 }
 
-static int dwapb_gpio_get_value(struct udevice *dev, unsigned pin)
-{
-   struct gpio_dwapb_platdata *plat = dev_get_platdata(dev);
-   return !!(readl(plat->base + GPIO_EXT_PORT(plat->bank)) & (1 << pin));
-}
-
-
 static int dwapb_gpio_set_value(struct udevice *dev, unsigned pin, int val)
 {
struct gpio_dwapb_platdata *plat = dev_get_platdata(dev);
@@ -98,6 +91,18 @@ static int dwapb_gpio_get_function(struct udevice *dev, 
unsigned offset)
return GPIOF_INPUT;
 }
 
+static int dwapb_gpio_get_value(struct udevice *dev, unsigned pin)
+{
+   struct gpio_dwapb_platdata *plat = dev_get_platdata(dev);
+   u32 value;
+
+   if (dwapb_gpio_get_function(dev, pin) == GPIOF_OUTPUT)
+   value = readl(plat->base + GPIO_SWPORT_DR(plat->bank));
+   else
+   value = readl(plat->base + GPIO_EXT_PORT(plat->bank));
+   return !!(value & BIT(pin));
+}
+
 static const struct dm_gpio_ops gpio_dwapb_ops = {
.direction_input= dwapb_gpio_direction_input,
.direction_output   = dwapb_gpio_direction_output,
-- 
2.26.2



[PATCH v3 03/10] pinctrl: Add support for Kendryte K210 FPIOA

2020-06-14 Thread Sean Anderson
The Fully-Programmable Input/Output Array (FPIOA) device controls pin
multiplexing on the K210. The FPIOA can remap any supported function to any
multifunctional IO pin. It can also perform basic GPIO functions, such as
reading the current value of a pin. However, GPIO functionality remains
largely unimplemented (in favor of the dedicated GPIO peripherals).

Signed-off-by: Sean Anderson 
---
This patch was previously submitted as part of
https://patchwork.ozlabs.org/project/uboot/list/?series=161576

Changes from that version include:
- Reformat to reduce errors from checkpatch

(no changes since v2)

Changes in v2:
- Don't clear existing pinctrl settings on probe
- Rewrite to use pinmux property
- Support muxing the output enable signal for each function
- Support output and input inversion
- Update binding documentation

 MAINTAINERS   |   2 +
 .../pinctrl/kendryte,k210-fpioa.txt   | 102 +++
 drivers/pinctrl/Kconfig   |   1 +
 drivers/pinctrl/Makefile  |   1 +
 drivers/pinctrl/kendryte/Kconfig  |   7 +
 drivers/pinctrl/kendryte/Makefile |   1 +
 drivers/pinctrl/kendryte/pinctrl.c| 678 ++
 drivers/pinctrl/kendryte/pinctrl.h|  70 ++
 include/dt-bindings/pinctrl/k210-pinctrl.h| 277 +++
 9 files changed, 1139 insertions(+)
 create mode 100644 doc/device-tree-bindings/pinctrl/kendryte,k210-fpioa.txt
 create mode 100644 drivers/pinctrl/kendryte/Kconfig
 create mode 100644 drivers/pinctrl/kendryte/Makefile
 create mode 100644 drivers/pinctrl/kendryte/pinctrl.c
 create mode 100644 drivers/pinctrl/kendryte/pinctrl.h
 create mode 100644 include/dt-bindings/pinctrl/k210-pinctrl.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 2b58cf7d94..e0bae4f199 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -876,7 +876,9 @@ RISC-V KENDRYTE
 M: Sean Anderson 
 S: Maintained
 F: doc/device-tree-bindings/mfd/kendryte,k210-sysctl.txt
+F: doc/device-tree-bindings/pinctrl/kendryte,k210-fpioa.txt
 F: drivers/clk/kendryte/
+F: drivers/pinctrl/kendryte/
 F: include/kendryte/
 
 RNG
diff --git a/doc/device-tree-bindings/pinctrl/kendryte,k210-fpioa.txt 
b/doc/device-tree-bindings/pinctrl/kendryte,k210-fpioa.txt
new file mode 100644
index 00..06a9cc060f
--- /dev/null
+++ b/doc/device-tree-bindings/pinctrl/kendryte,k210-fpioa.txt
@@ -0,0 +1,102 @@
+Kendryte K210 FPIOA
+
+This binding describes the Fully-Programmable Input/Output Array (FPIOA) found
+in Kendryte K210 SoCs. Any of the 256 functions can be mapped to any of the 48
+pins.
+
+Required properties:
+- compatible: should be "kendryte,k210-fpioa"
+- reg: address and length of the FPIOA registers
+- kendryte,sysctl: phandle to the "sysctl" register map node
+- kendryte,power-offset: offset in the register map of the power bank control
+  register (in bytes)
+
+Configuration nodes
+
+Pin configuration nodes are documented in pinctrl-bindings.txt
+
+Required properties for pin-configuration nodes or sub-nodes are:
+- groups: list of power groups to which the configuration applies. Valid groups
+  are:
+   A0, A1, A2, B0, B1, B2, C0, C1
+  (either this or "pinmux" must be specified)
+- pinmux: integer array representing pin multiplexing configuration. In 
addition
+  to the 256 standard functions, each pin can also output the direction
+  indicator (DO) of any function. This signal is high whenever the function
+  would normally drive the output. Helper macros to ease assembling the 
"pinmux"
+  arguments from the pin and function are provided by the FPIOA header file at:
+  
+  Integer values in the "pinmux" argument list are assembled as:
+  ((PIN << 16) | (DO << 8) | (FUNC))
+  Valid values for PIN are numbers 0 through 47.
+  Valid values for DO are 0 or 1.
+  Valid values for FUNC are numbers 0 through 255. For a complete list of
+  acceptable functions, consult the FPIOA header file.
+  (either this or "groups" must be specified)
+
+Optional properties for "pinmux" nodes are:
+   bias-disable, bias-pull-down, bias-pull-up, drive-strength,
+   drive-strength-ua, input-enable, input-disable, input-schmitt-enable,
+   input-schmitt-disable, output-low, output-high, output-enable,
+   output-disable, slew-rate, output-polarity-invert, input-polarity-invert
+
+Optional properties for "groups" nodes are:
+   power-source
+
+Notes on specific properties include:
+- bias-pull-up, -down, and -pin-default: The pull strength cannot be 
configured.
+- drive-strength: There are 8 drive strength settings between 11 and 50 mA.
+- input- and output-polarity-invert: Invert the polarity of either the input or
+  the output, respectively.
+- power-source: Controls the output voltage of a bank of pins. Either
+  K210_PC_POWER_1V8 or K210_PC_POWER_3V3 may be specified.
+- slew-rate: Specifying this property reduces the slew rate.
+
+Example:
+fpioa: pinmux@502B {
+   compatible = "kendryt

[PATCH v3 05/10] gpio: dw: Fix warnings about casting int to pointer

2020-06-14 Thread Sean Anderson
Change the type of gpio_dwabp_platdata.base from fdt_addr_t to a void
pointer, since we pass it to readl.

Signed-off-by: Sean Anderson 
Reviewed-by: Ley Foon Tan 
Reviewed-by: Bin Meng 
---
This patch was previously submitted as part of
https://patchwork.ozlabs.org/project/uboot/list/?series=161576

(no changes since v1)

 drivers/gpio/dwapb_gpio.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpio/dwapb_gpio.c b/drivers/gpio/dwapb_gpio.c
index e5e3518194..bf324f5239 100644
--- a/drivers/gpio/dwapb_gpio.c
+++ b/drivers/gpio/dwapb_gpio.c
@@ -40,7 +40,7 @@ struct gpio_dwapb_platdata {
const char  *name;
int bank;
int pins;
-   fdt_addr_t  base;
+   void __iomem*base;
 };
 
 static int dwapb_gpio_direction_input(struct udevice *dev, unsigned pin)
@@ -176,7 +176,7 @@ static int gpio_dwapb_bind(struct udevice *dev)
if (!plat)
return -ENOMEM;
 
-   plat->base = base;
+   plat->base = (void *)base;
plat->bank = bank;
plat->pins = ofnode_read_u32_default(node, "snps,nr-gpios", 0);
 
-- 
2.26.2



[PATCH v3 09/10] riscv: Add pinmux and gpio bindings for Kendryte K210

2020-06-14 Thread Sean Anderson
This patch adds the necessary device tree bindings.

Signed-off-by: Sean Anderson 

---

(no changes since v2)

Changes in v2:
- Convert to use pinmux property
- Don't hog ISP on boot
- Re-order GPIOs to match the defaults more closely

 arch/riscv/dts/k210-maix-bit.dts | 104 +++
 arch/riscv/dts/k210.dtsi |  12 
 2 files changed, 116 insertions(+)

diff --git a/arch/riscv/dts/k210-maix-bit.dts b/arch/riscv/dts/k210-maix-bit.dts
index 5b32c5fd5f..e840e04ada 100644
--- a/arch/riscv/dts/k210-maix-bit.dts
+++ b/arch/riscv/dts/k210-maix-bit.dts
@@ -17,6 +17,22 @@
stdout-path = "serial0:115200";
};
 
+   gpio-leds {
+   compatible = "gpio-leds";
+
+   green {
+   gpios = <&gpio1_0 4 GPIO_ACTIVE_LOW>;
+   };
+
+   red {
+   gpios = <&gpio1_0 5 GPIO_ACTIVE_LOW>;
+   };
+
+   blue {
+   gpios = <&gpio1_0 6 GPIO_ACTIVE_LOW>;
+   };
+   };
+
sound {
compatible = "simple-audio-card";
simple-audio-card,format = "i2s";
@@ -39,9 +55,97 @@
 };
 
 &uarths0 {
+   pinctrl-0 = <&fpioa_uarths>;
+   pinctrl-names = "default";
+   status = "okay";
+};
+
+&gpio0 {
+   pinctrl-0 = <&fpioa_gpiohs>;
+   pinctrl-names = "default";
+   status = "okay";
+};
+
+&gpio1 {
+   pinctrl-0 = <&fpioa_gpio>;
+   pinctrl-names = "default";
status = "okay";
 };
 
 &i2s0 {
#sound-dai-cells = <1>;
+   pinctrl-0 = <&fpioa_i2s0>;
+   pinctrl-names = "default";
+};
+
+&fpioa {
+   status = "okay";
+
+   fpioa_uarths: uarths {
+   pinmux = ,
+;
+   };
+
+   fpioa_gpio: gpio {
+   pinmux = ,
+,
+,
+,
+,
+,
+,
+;
+   };
+
+   fpioa_gpiohs: gpiohs {
+   pinmux = ,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+;
+   };
+
+   fpioa_i2s0: i2s0 {
+   pinmux = ,
+,
+;
+   };
+
+   fpioa_dvp: dvp {
+   pinmux = ,
+,
+,
+,
+,
+,
+,
+;
+   };
+
+   fpioa_spi0: spi0 {
+   pinmux = ,  /* cs */
+,  /* rst */
+,  /* dc */
+; /* wr */
+   };
+
+   fpioa_spi1: spi1 {
+   pinmux = ,
+,
+,
+;
+   };
+};
+
+&dvp0 {
+   pinctrl-0 = <&fpioa_dvp>;
+   pinctrl-names = "default";
 };
diff --git a/arch/riscv/dts/k210.dtsi b/arch/riscv/dts/k210.dtsi
index 2546c7d4e0..fc7986b326 100644
--- a/arch/riscv/dts/k210.dtsi
+++ b/arch/riscv/dts/k210.dtsi
@@ -5,6 +5,7 @@
 
 #include 
 #include 
+#include 
 #include 
 
 / {
@@ -367,7 +368,18 @@
reg = <0x502B 0x100>;
clocks = <&sysclk K210_CLK_FPIOA>;
resets = <&sysrst K210_RST_FPIOA>;
+   kendryte,sysctl = <&sysctl>;
+   kendryte,power-offset = ;
+   pinctrl-0 = <&fpioa_jtag>;
+   pinctrl-names = "default";
status = "disabled";
+
+   fpioa_jtag: jtag {
+   pinmux = ,
+,
+,
+;
+   };
};
 
sha256: sha256@502C {
-- 
2.26.2



[PATCH v3 10/10] riscv: Add FPIOA and GPIO support for Kendryte K210

2020-06-14 Thread Sean Anderson
This patch adds the necessary configs and docs for FPIOA and GPIO support
on the K210.

Signed-off-by: Sean Anderson 
---

Changes in v3:
- Document pins 6 and 7 as not set

Changes in v2:
- Remove SPI flash related Kconfig settings

 board/sipeed/maix/Kconfig |  9 ++
 doc/board/sipeed/maix.rst | 64 +--
 2 files changed, 71 insertions(+), 2 deletions(-)

diff --git a/board/sipeed/maix/Kconfig b/board/sipeed/maix/Kconfig
index 0cdcd32adc..4c42dd2087 100644
--- a/board/sipeed/maix/Kconfig
+++ b/board/sipeed/maix/Kconfig
@@ -44,4 +44,13 @@ config BOARD_SPECIFIC_OPTIONS
imply RESET_SYSCON
imply SYSRESET
imply SYSRESET_SYSCON
+   imply PINCTRL
+   imply PINCONF
+   imply PINCTRL_K210
+   imply DM_GPIO
+   imply DWAPB_GPIO
+   imply SIFIVE_GPIO
+   imply CMD_GPIO
+   imply LED
+   imply LED_GPIO
 endif
diff --git a/doc/board/sipeed/maix.rst b/doc/board/sipeed/maix.rst
index 06e0008b9f..1865e2adfb 100644
--- a/doc/board/sipeed/maix.rst
+++ b/doc/board/sipeed/maix.rst
@@ -132,7 +132,7 @@ To run legacy images, use the ``bootm`` command:
 Load Address: 8000
 Entry Point:  8000
 
-$ picocom -b 115200 /dev/ttyUSB0i
+$ picocom -b 115200 /dev/ttyUSB0
 => loady
 ## Ready for binary (ymodem) download to 0x8000 at 115200 bps...
 C
@@ -163,6 +163,66 @@ To run legacy images, use the ``bootm`` command:
 argv[0] = ""
 Hit any key to exit ...
 
+Pin Assignment
+--
+
+The K210 contains a Fully Programmable I/O Array (FPIOA), which can remap any 
of
+its 256 input functions to any any of 48 output pins. The following table has
+the default pin assignments for the BitM.
+
+= == ===
+Pin   Function   Comment
+= == ===
+IO_0  JTAG_TCLK
+IO_1  JTAG_TDI
+IO_2  JTAG_TMS
+IO_3  JTAG_TDO
+IO_4  UARTHS_RX
+IO_5  UARTHS_TX
+IO_6 Not set
+IO_7 Not set
+IO_8  GPIO_0
+IO_9  GPIO_1
+IO_10 GPIO_2
+IO_11 GPIO_3
+IO_12 GPIO_4 Green LED
+IO_13 GPIO_5 Red LED
+IO_14 GPIO_6 Blue LED
+IO_15 GPIO_7
+IO_16 GPIOHS_0   ISP
+IO_17 GPIOHS_1
+IO_18 I2S0_SCLK  MIC CLK
+IO_19 I2S0_WSMIC WS
+IO_20 I2S0_IN_D0 MIC SD
+IO_21 GPIOHS_5
+IO_22 GPIOHS_6
+IO_23 GPIOHS_7
+IO_24 GPIOHS_8
+IO_25 GPIOHS_9
+IO_26 SPI1_D1MMC MISO
+IO_27 SPI1_SCLK  MMC CLK
+IO_28 SPI1_D0MMC MOSI
+IO_29 GPIOHS_13  MMC CS
+IO_30 GPIOHS_14
+IO_31 GPIOHS_15
+IO_32 GPIOHS_16
+IO_33 GPIOHS_17
+IO_34 GPIOHS_18
+IO_35 GPIOHS_19
+IO_36 GPIOHS_20  Panel CS
+IO_37 GPIOHS_21  Panel RST
+IO_38 GPIOHS_22  Panel DC
+IO_39 SPI0_SCK   Panel WR
+IO_40 SCCP_SDA
+IO_41 SCCP_SCLK
+IO_42 DVP_RST
+IO_43 DVP_VSYNC
+IO_44 DVP_PWDN
+IO_45 DVP_HSYNC
+IO_46 DVP_XCLK
+IO_47 DVP_PCLK
+= == ===
+
 Over- and Under-clocking
 
 
@@ -294,5 +354,5 @@ AddressSize  Description
 0x8801C000 0x1000riscv priv spec 1.9 config
 0x8801D000 0x2000flattened device tree (contains only addresses and
  interrupts)
-0x8801f000 0x1000credits
+0x8801F000 0x1000credits
 == = ===
-- 
2.26.2



Re: [PATCH 6/6] checkpatch.pl: Request if() instead #ifdef

2020-06-14 Thread AKASHI Takahiro
On Thu, Jun 04, 2020 at 07:39:35PM -0400, Tom Rini wrote:
> On Fri, May 22, 2020 at 04:32:40PM -0600, Simon Glass wrote:
> 
> > There is a lot of use of #ifdefs in U-Boot. In an effort reduce this,
> > suggest using the compile-time construct.
> > 
> > Signed-off-by: Simon Glass 
> 
> Applied to u-boot/master, thanks!

This check is simple, but IMHO, too simple.
It will generate false-positive, or pointless, warnings
for some common use cases. Say,

In an include header,
#ifdef CONFIG_xxx
extern int foo_data;
int foo(void);
#endif

Or in a C file (foo_common.c),
#ifdef CONFIG_xxx_a
int foo_a(void)
...
#endif
#ifdef CONFIG_xxx_b
int foo_b(void)
...
#endif

Or,

struct baa baa_list[] = {
#ifdef CONFIG_xxx
data_xxx,
#endif
...

They are harmless and can be ignored, but also annoying.
Can you sophisticate this check?

In addition, if I want to stick to this rule, there can co-exist
an "old" style and "new" style of code in a single file.
(particularly tons of examples in UEFI subsystem)

How should we deal with this?

Thanks,
-Takahiro Akashi

> -- 
> Tom




Re: [RESEND PATCH v2 02/11] net: dwc_eth_qos: Add option "snps,reset-gpio" phy-rst gpio for stm32

2020-06-14 Thread David Wu

Hi Patrick,

Yes, this is the case, it should be add at PHY node, and I also used the 
original writing "snps,reset*" at MAC node. Anyway, I will try to put 
the reset gpio in the PHY node.


在 2020/5/13 下午8:55, Patrick DELAUNAY 写道:

Hi David


From: David Wu 
Sent: mardi 12 mai 2020 11:56

It can be seen that most of the Socs using STM mac, "snps,reset-gpio"
gpio is used, adding this option makes reset function more general.

Signed-off-by: David Wu 
---

Changes in v2:
- Remove the code is not related (Patrice)

  drivers/net/dwc_eth_qos.c | 32 +++-
  1 file changed, 31 insertions(+), 1 deletion(-)

diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c index
66a02aa80b..92dab678c7 100644
--- a/drivers/net/dwc_eth_qos.c
+++ b/drivers/net/dwc_eth_qos.c
@@ -314,6 +314,7 @@ struct eqos_priv {
struct eqos_tegra186_regs *tegra186_regs;
struct reset_ctl reset_ctl;
struct gpio_desc phy_reset_gpio;
+   u32 reset_delays[3];
struct clk clk_master_bus;
struct clk clk_rx;
struct clk clk_ptp_ref;
@@ -739,6 +740,15 @@ static int eqos_start_resets_stm32(struct udevice *dev)

debug("%s(dev=%p):\n", __func__, dev);
if (dm_gpio_is_valid(&eqos->phy_reset_gpio)) {
+   ret = dm_gpio_set_value(&eqos->phy_reset_gpio, 0);
+   if (ret < 0) {
+   pr_err("dm_gpio_set_value(phy_reset, deassert) failed:
%d",
+  ret);
+   return ret;
+   }
+
+   udelay(eqos->reset_delays[0]);
+
ret = dm_gpio_set_value(&eqos->phy_reset_gpio, 1);
if (ret < 0) {
pr_err("dm_gpio_set_value(phy_reset, assert) failed: 
%d",
@@ -746,7 +756,7 @@ static int eqos_start_resets_stm32(struct udevice *dev)
return ret;
}

-   udelay(2);
+   udelay(eqos->reset_delays[1]);

ret = dm_gpio_set_value(&eqos->phy_reset_gpio, 0);
if (ret < 0) {
@@ -754,6 +764,8 @@ static int eqos_start_resets_stm32(struct udevice *dev)
   ret);
return ret;
}
+
+   udelay(eqos->reset_delays[2]);
}
debug("%s: OK\n", __func__);

@@ -1864,11 +1876,29 @@ static int eqos_probe_resources_stm32(struct
udevice *dev)
if (ret)
pr_warn("gpio_request_by_name(phy reset) not provided
%d",
ret);
+   else
+   eqos->reset_delays[1] = 2;

eqos->phyaddr = ofnode_read_u32_default(phandle_args.node,
"reg", -1);
}

+   if (!dm_gpio_is_valid(&eqos->phy_reset_gpio)) {
+   int reset_flags = GPIOD_IS_OUT;
+
+   if (dev_read_bool(dev, "snps,reset-active-low"))
+   reset_flags |= GPIOD_ACTIVE_LOW;
+
+   ret = gpio_request_by_name(dev, "snps,reset-gpio", 0,
+  &eqos->phy_reset_gpio, reset_flags);
+   if (ret == 0)
+   ret = dev_read_u32_array(dev, "snps,reset-delays-us",
+eqos->reset_delays, 3);
+   else
+   pr_warn("gpio_request_by_name(snps,reset-gpio) failed:
%d",
+   ret);
+   }
+
debug("%s: OK\n", __func__);
return 0;

--
2.19.1




This obsolete binding isn't expected to be supported in stm32 glue for dwmac
(and it tis the purpose of eqos_stm32_config)

Reference in linux binding
./Documentation/devicetree/bindings/net/stm32-dwmac.txt (the glue)
./Documentation/devicetree/bindings/net/snps,dwmac.yaml

   snps,reset-gpio:
 deprecated: true

   snps,reset-active-low:
 deprecated: true

   snps,reset-delays-us:
 deprecated: true

I expected that gpio reset in future device tree should be managed by only by 
PHY generic binding
(upstream in progress on Linux side for STM32MP15x), as described in:

Documentation/devicetree/bindings/net/ethernet-phy.yaml

   reset-gpios:
 maxItems: 1
 description:
   The GPIO phandle and specifier for the PHY reset signal.

   reset-assert-us:
 description:
   Delay after the reset was asserted in microseconds. If this
   property is missing the delay will be skipped.

   reset-deassert-us:
 description:
   Delay after the reset was deasserted in microseconds. If
   this property is missing the delay will be skipped.

See alsoU-Boot: doc/device-tree-bindings/net/phy.txt

Something as

&mac {
status = "okay";
pinctrl-0   = <ðernet_mii>;
pinctrl-names   = "default";
phy-mode= "mii";
phy-handle  = <&phy1>;
mdio0 {
#address-cells = <1>;
#size-cells =

[PATCH v1 01/43] binman: Allow setting the ROM offset

2020-06-14 Thread Simon Glass
On x86 the SPI ROM can be memory-mapped, at least most of it. Add a way
to tell binman the offset from a ROM address to a RAM address.

Signed-off-by: Simon Glass 
---

Changes in v1:
- Add a way to set the binman ROM offset

 include/binman.h |  8 
 lib/binman.c | 17 +
 2 files changed, 25 insertions(+)

diff --git a/include/binman.h b/include/binman.h
index b462dc8542..baf49f7876 100644
--- a/include/binman.h
+++ b/include/binman.h
@@ -20,6 +20,14 @@ struct binman_entry {
u32 size;
 };
 
+/**
+ * binman_set_rom_offset() - Set the ROM memory-map offset
+ *
+ * @rom_offset: Offset from an image_pos to the memory-mapped address. This
+ * tells binman that ROM image_pos x can be addressed at rom_offset + x
+ */
+void binman_set_rom_offset(int rom_offset);
+
 /**
  * binman_entry_find() - Find a binman symbol
  *
diff --git a/lib/binman.c b/lib/binman.c
index fd7de24bd2..dc3a880882 100644
--- a/lib/binman.c
+++ b/lib/binman.c
@@ -12,10 +12,21 @@
 #include 
 #include 
 
+/**
+ * struct binman_info - Information needed by the binman library
+ *
+ * @image: Node describing the image we are running from
+ * @rom_offset: Offset from an image_pos to the memory-mapped address, or
+ * ROM_OFFSET_NONE if the ROM is not memory-mapped. Can be positive or
+ * negative
+ */
 struct binman_info {
ofnode image;
+   int rom_offset;
 };
 
+#define ROM_OFFSET_NONE(-1)
+
 static struct binman_info *binman;
 
 int binman_entry_find(const char *name, struct binman_entry *entry)
@@ -37,6 +48,11 @@ int binman_entry_find(const char *name, struct binman_entry 
*entry)
return 0;
 }
 
+void binman_set_rom_offset(int rom_offset)
+{
+   binman->rom_offset = rom_offset;
+}
+
 int binman_init(void)
 {
binman = malloc(sizeof(struct binman_info));
@@ -45,6 +61,7 @@ int binman_init(void)
binman->image = ofnode_path("/binman");
if (!ofnode_valid(binman->image))
return log_msg_ret("binman node", -EINVAL);
+   binman->rom_offset = ROM_OFFSET_NONE;
 
return 0;
 }
-- 
2.27.0.290.gba653c62da-goog



[PATCH v1 04/43] acpi: Allow creating the GNVS to fail

2020-06-14 Thread Simon Glass
In some cases an internal error may prevent this from working. Update the
function return value and report the error. At present the API for writing
tables does not easily support reporting errors, but once it is fully
updated to use a context pointer, this will be easier.

Signed-off-by: Simon Glass 
---

Changes in v1:
- Add linux/err.h header

 arch/x86/cpu/baytrail/acpi.c  |  4 +++-
 arch/x86/cpu/quark/acpi.c |  4 +++-
 arch/x86/cpu/tangier/acpi.c   |  4 +++-
 arch/x86/include/asm/acpi_table.h | 10 +-
 arch/x86/lib/acpi_table.c | 11 +--
 5 files changed, 27 insertions(+), 6 deletions(-)

diff --git a/arch/x86/cpu/baytrail/acpi.c b/arch/x86/cpu/baytrail/acpi.c
index b17bc62a2d..07757b88a3 100644
--- a/arch/x86/cpu/baytrail/acpi.c
+++ b/arch/x86/cpu/baytrail/acpi.c
@@ -139,7 +139,7 @@ void acpi_create_fadt(struct acpi_fadt *fadt, struct 
acpi_facs *facs,
header->checksum = table_compute_checksum(fadt, header->length);
 }
 
-void acpi_create_gnvs(struct acpi_global_nvs *gnvs)
+int acpi_create_gnvs(struct acpi_global_nvs *gnvs)
 {
struct udevice *dev;
int ret;
@@ -159,6 +159,8 @@ void acpi_create_gnvs(struct acpi_global_nvs *gnvs)
gnvs->iuart_en = 1;
else
gnvs->iuart_en = 0;
+
+   return 0;
 }
 
 /*
diff --git a/arch/x86/cpu/quark/acpi.c b/arch/x86/cpu/quark/acpi.c
index 26cda3b337..b0406a04e9 100644
--- a/arch/x86/cpu/quark/acpi.c
+++ b/arch/x86/cpu/quark/acpi.c
@@ -133,8 +133,10 @@ void acpi_create_fadt(struct acpi_fadt *fadt, struct 
acpi_facs *facs,
header->checksum = table_compute_checksum(fadt, header->length);
 }
 
-void acpi_create_gnvs(struct acpi_global_nvs *gnvs)
+int acpi_create_gnvs(struct acpi_global_nvs *gnvs)
 {
/* quark is a uni-processor */
gnvs->pcnt = 1;
+
+   return 0;
 }
diff --git a/arch/x86/cpu/tangier/acpi.c b/arch/x86/cpu/tangier/acpi.c
index 4ec8fdd6f8..41bd177e09 100644
--- a/arch/x86/cpu/tangier/acpi.c
+++ b/arch/x86/cpu/tangier/acpi.c
@@ -107,7 +107,7 @@ u32 acpi_fill_csrt(u32 current)
return current;
 }
 
-void acpi_create_gnvs(struct acpi_global_nvs *gnvs)
+int acpi_create_gnvs(struct acpi_global_nvs *gnvs)
 {
struct udevice *dev;
int ret;
@@ -122,4 +122,6 @@ void acpi_create_gnvs(struct acpi_global_nvs *gnvs)
if (ret > 0)
gnvs->pcnt = ret;
}
+
+   return 0;
 }
diff --git a/arch/x86/include/asm/acpi_table.h 
b/arch/x86/include/asm/acpi_table.h
index 928475cef4..733085c178 100644
--- a/arch/x86/include/asm/acpi_table.h
+++ b/arch/x86/include/asm/acpi_table.h
@@ -35,7 +35,15 @@ int acpi_create_mcfg_mmconfig(struct acpi_mcfg_mmconfig 
*mmconfig, u32 base,
  u16 seg_nr, u8 start, u8 end);
 u32 acpi_fill_mcfg(u32 current);
 u32 acpi_fill_csrt(u32 current);
-void acpi_create_gnvs(struct acpi_global_nvs *gnvs);
+
+/**
+ * acpi_create_gnvs() - Create a GNVS (Global Non Volatile Storage) table
+ *
+ * @gnvs: Table to fill in
+ * @return 0 if OK, -ve on error
+ */
+int acpi_create_gnvs(struct acpi_global_nvs *gnvs);
+
 ulong write_acpi_tables(ulong start);
 
 /**
diff --git a/arch/x86/lib/acpi_table.c b/arch/x86/lib/acpi_table.c
index eeacfe9b06..27869a0e5e 100644
--- a/arch/x86/lib/acpi_table.c
+++ b/arch/x86/lib/acpi_table.c
@@ -23,6 +23,7 @@
 #include 
 #include 
 #include 
+#include 
 
 /*
  * IASL compiles the dsdt entries and writes the hex values
@@ -443,8 +444,14 @@ ulong write_acpi_tables(ulong start_addr)
dsdt->checksum = 0;
dsdt->checksum = table_compute_checksum((void *)dsdt, dsdt->length);
 
-   /* Fill in platform-specific global NVS variables */
-   acpi_create_gnvs(ctx->current);
+   /*
+* Fill in platform-specific global NVS variables. If this fails we
+* cannot return the error but this should only happen while debugging.
+*/
+   addr = acpi_create_gnvs(ctx->current);
+   if (IS_ERR_VALUE(addr))
+   printf("Error: Gailed to create GNVS\n");
+
acpi_inc_align(ctx, sizeof(struct acpi_global_nvs));
 
debug("ACPI:* FADT\n");
-- 
2.27.0.290.gba653c62da-goog



[PATCH v1 06/43] dm: core: Add a way of overriding the ACPI device path

2020-06-14 Thread Simon Glass
Some devices such as GPIO need to override the normal path that would be
generated by driver model. Add a device-tree property for this.

Signed-off-by: Simon Glass 
---

 doc/device-tree-bindings/device.txt | 23 +++
 drivers/core/acpi.c | 19 +++
 include/dm/acpi.h   | 13 +
 3 files changed, 55 insertions(+)

diff --git a/doc/device-tree-bindings/device.txt 
b/doc/device-tree-bindings/device.txt
index 7140339623..2a5736c598 100644
--- a/doc/device-tree-bindings/device.txt
+++ b/doc/device-tree-bindings/device.txt
@@ -17,6 +17,8 @@ the acpi,compatible property.
 System) Device Name)
  - acpi,hid : Contains the string to use as the HID (Hardware ID)
 identifier _HID
+ - acpi,path : Specifies the full ACPI path for a device. This overrides the
+normal path built from the driver-model hierarchy
  - acpi,name : Provides the ACPI name for a device, which is a string 
consisting
of four alphanumeric character (upper case)
  - acpi,uid : _UID value for device
@@ -47,3 +49,24 @@ pcie-a0@14,0 {
interrupts-extended = <&acpi_gpe 0x3c 0>;
};
 };
+
+p2sb: p2sb@d,0 {
+   u-boot,dm-pre-reloc;
+   reg = <0x02006810 0 0 0 0>;
+   compatible = "intel,apl-p2sb";
+   early-regs = ;
+   pci,no-autoconfig;
+
+   n {
+   compatible = "intel,apl-pinctrl";
+   u-boot,dm-pre-reloc;
+   intel,p2sb-port-id = ;
+   acpi,path = "\\_SB.GPO0";
+   gpio_n: gpio-n {
+   compatible = "intel,gpio";
+   u-boot,dm-pre-reloc;
+   gpio-controller;
+   #gpio-cells = <2>;
+   linux-name = "INT3452:00";
+   };
+   };
diff --git a/drivers/core/acpi.c b/drivers/core/acpi.c
index fd58c76087..ea304a3067 100644
--- a/drivers/core/acpi.c
+++ b/drivers/core/acpi.c
@@ -82,6 +82,25 @@ int acpi_get_name(const struct udevice *dev, char *out_name)
return 0;
 }
 
+int acpi_get_path(const struct udevice *dev, char *out_path, int maxlen)
+{
+   const char *path;
+   int ret;
+
+   path = dev_read_string(dev, "acpi,path");
+   if (path) {
+   if (strlen(path) >= maxlen)
+   return -E2BIG;
+   strcpy(out_path, path);
+   return 0;
+   }
+   ret = acpi_device_path(dev, out_path, maxlen);
+   if (ret)
+   return log_msg_ret("dev", ret);
+
+   return 0;
+}
+
 /**
  * acpi_add_item() - Add a new item to the list of data collected
  *
diff --git a/include/dm/acpi.h b/include/dm/acpi.h
index 28d9275ccc..b6308b9fa6 100644
--- a/include/dm/acpi.h
+++ b/include/dm/acpi.h
@@ -180,6 +180,19 @@ int acpi_inject_dsdt(struct acpi_ctx *ctx);
  */
 void acpi_dump_items(enum acpi_dump_option option);
 
+/**
+ * acpi_get_path() - Get the full ACPI path for a device
+ *
+ * This checks for any override in the device tree and calls acpi_device_path()
+ * if not
+ *
+ * @dev: Device to check
+ * @out_path: Buffer to place the path in (should be ACPI_PATH_MAX long)
+ * @maxlen: Size of buffer (typically ACPI_PATH_MAX)
+ * @return 0 if OK, -ve on error
+ */
+int acpi_get_path(const struct udevice *dev, char *out_path, int maxlen);
+
 #endif /* __ACPI__ */
 
 #endif
-- 
2.27.0.290.gba653c62da-goog



[PATCH v1 00/43] x86: Programmatic generation of ACPI tables (Part C)

2020-06-14 Thread Simon Glass
This series is split off from the original ACPI series and renumbered to
version 1.

It includes functions for generating more ACPI constructs as well as I2C,
GPIO and sound support. There are also quite a few patches related to
getting coral to work correctly with ACPI.

Changes in v1:
- Add a way to set the binman ROM offset
- Add linux/err.h header
- Capitalise ACPI_OPS_PTR
- Use acpi,ddn instead of acpi,desc
- Add a check for invalid node
- Add NHLT support
- Capitalise ACPI_OPS_PTR
- Rebase to master
- Use acpi,ddn instead of acpi,desc
- Drop the unwanted acpi_device_write_gpio_desc()
- Rename max97357a to max98357a
- Add NHLT support
- Capitalise ACPI_OPS_PTR
- Rebase to master
- Add a new patch to support building up an NHLT structure
- Add new patch to add error checking for csrt table generation
- Use acpi_get_path() to get device path
- Add new patch to improve designware_i2c debugging
- Capitalise ACPI_OPS_PTR

Simon Glass (43):
  binman: Allow setting the ROM offset
  binman: Refactor binman_entry_find() to allow other nodes
  binman: Add way to locate an entry in memory
  acpi: Allow creating the GNVS to fail
  dtoc: Support ACPI paths in of-platdata
  dm: core: Add a way of overriding the ACPI device path
  dm: acpi: Add support for the NHLT table
  acpi: Export functions to write sized values
  acpi: Support generation of a scope
  acpi: Support generation of a generic register
  acpi: mmc: Generate ACPI info for the PCI SD Card
  x86: Add bindings for NHLT
  acpi: Support generation of a device
  acpi: Support writing named values
  sound: Add an ACPI driver for Dialog Semicondutor da7219
  sound: Add an ACPI driver for Maxim MAX98357ac
  x86: pinctrl: Add a way to get the pinctrl reg address
  x86: pinctrl: Update comment for intel_pinctrl_get_pad()
  x86: pinctrl: Add multi-ACPI control
  x86: pinctrl: Set up itss in the probe() method
  x86: pinctrl: Drop the acpi_name member
  x86: Add support for building up an NHLT structure
  x86: Add error checking for csrt table generation
  x86: apl: Use memory-mapped access for VBT
  x86: gpio: Add support for obtaining ACPI info for a GPIO
  i2c: designware_i2c: Add a little more debugging
  i2c: Add log_ret() on error
  i2c: designware_i2c: Support ACPI table generation
  p2sb: Add a method to hide the bus
  x86: apl: Support set_hide() in p2sb driver
  x86: apl: Hide the p2sb on exit from U-Boot
  pmc: Move common registers to the header file
  x86: irq: Support flags for acpi_gpe
  x86: apl: Fix save/restore of ITSS priorities
  x86: Add debugging to table writing
  x86: apl: Adjust FSP-M code to avoid hard-coded address
  x86: Store the coreboot table address in global_data
  x86: mp: Allow use of mp_run_on_cpus() without MP
  x86: Update the comment about booting for FSP2
  x86: Drop setup_pcat_compatibility()
  x86: acpi: Correct the version of the MADT
  x86: Rename board_final_cleanup() to board_final_init()
  acpi: Enable ACPI table generation by default on x86

 arch/Kconfig  |   1 +
 arch/x86/cpu/acpi_gpe.c   |  26 +
 arch/x86/cpu/apollolake/fsp_m.c   |   6 +-
 arch/x86/cpu/apollolake/fsp_s.c   |  56 +-
 arch/x86/cpu/baytrail/acpi.c  |   4 +-
 arch/x86/cpu/coreboot/coreboot.c  |   4 +-
 arch/x86/cpu/coreboot/tables.c|   8 +-
 arch/x86/cpu/cpu.c|  21 +-
 arch/x86/cpu/efi/app.c|   2 +-
 arch/x86/cpu/i386/cpu.c   |   7 +-
 arch/x86/cpu/intel_common/itss.c  |  25 +-
 arch/x86/cpu/intel_common/p2sb.c  |  44 ++
 arch/x86/cpu/mp_init.c|  12 +-
 arch/x86/cpu/quark/acpi.c |   4 +-
 arch/x86/cpu/quark/quark.c|   2 +-
 arch/x86/cpu/start.S  |   1 +
 arch/x86/cpu/tangier/acpi.c   |   4 +-
 arch/x86/include/asm/acpi_nhlt.h  | 314 
 arch/x86/include/asm/acpi_table.h |  10 +-
 arch/x86/include/asm/global_data.h|   2 +
 arch/x86/include/asm/intel_pinctrl.h  |  19 +-
 arch/x86/include/asm/itss.h   |   2 +-
 arch/x86/include/asm/u-boot-x86.h |   2 -
 arch/x86/lib/Makefile |   1 +
 arch/x86/lib/acpi_nhlt.c  | 482 ++
 arch/x86/lib/acpi_table.c |  32 +-
 arch/x86/lib/fsp/fsp_common.c |   2 +-
 arch/x86/lib/fsp2/fsp_silicon_init.c  |   1 +
 arch/x86/lib/tables.c |  38 +-
 configs/sandbox_defconfig |   4 +
 doc/device-tree-bindings/device.txt   |  23 +
 doc/device-tree-bindings/sound/da7219.txt | 113 
 doc/device-tree-bindings/sound/max98357a.txt  |  22 +
 drivers/core/acpi.c   |  34 ++
 drivers/gpio/intel_gpio.c |  49 +-
 drivers/i2c/designware_i2c.c  

[PATCH v1 03/43] binman: Add way to locate an entry in memory

2020-06-14 Thread Simon Glass
Add support for accessing an entry's contents in memory-mapped SPI flash.

Signed-off-by: Simon Glass 
---

 include/binman.h | 22 ++
 lib/binman.c | 23 +++
 2 files changed, 45 insertions(+)

diff --git a/include/binman.h b/include/binman.h
index baf49f7876..e0b92075e2 100644
--- a/include/binman.h
+++ b/include/binman.h
@@ -9,6 +9,8 @@
 #ifndef _BINMAN_H_
 #define _BINMAN_H_
 
+#include 
+
 /**
  *struct binman_entry - information about a binman entry
  *
@@ -20,6 +22,18 @@ struct binman_entry {
u32 size;
 };
 
+/**
+ * binman_entry_map() - Look up the address of an entry in memory
+ *
+ * @parent: Parent binman node
+ * @name: Name of entry
+ * @bufp: Returns a pointer to the entry
+ * @sizep: Returns the size of the entry
+ * @return 0 on success, -EPERM if the ROM offset is not set, -ENOENT if the
+ * entry cannot be found, other error code other error
+ */
+int binman_entry_map(ofnode parent, const char *name, void **bufp, int *sizep);
+
 /**
  * binman_set_rom_offset() - Set the ROM memory-map offset
  *
@@ -41,6 +55,14 @@ void binman_set_rom_offset(int rom_offset);
  */
 int binman_entry_find(const char *name, struct binman_entry *entry);
 
+/**
+ * binman_section_find_node() - Find a binman node
+ *
+ * @name: Name of node to look for
+ * @return Node that was found, ofnode_null() if not found
+ */
+ofnode binman_section_find_node(const char *name);
+
 /**
  * binman_init() - Set up the binman symbol information
  *
diff --git a/lib/binman.c b/lib/binman.c
index 79d01230dd..ba4d82963d 100644
--- a/lib/binman.c
+++ b/lib/binman.c
@@ -11,6 +11,7 @@
 #include 
 #include 
 #include 
+#include 
 
 /**
  * struct binman_info - Information needed by the binman library
@@ -54,6 +55,28 @@ int binman_entry_find(const char *name, struct binman_entry 
*entry)
return binman_entry_find_(binman->image, name, entry);
 }
 
+int binman_entry_map(ofnode parent, const char *name, void **bufp, int *sizep)
+{
+   struct binman_entry entry;
+   int ret;
+
+   if (binman->rom_offset == ROM_OFFSET_NONE)
+   return -EPERM;
+   ret = binman_entry_find_(parent, name, &entry);
+   if (ret)
+   return log_msg_ret("entry", ret);
+   if (sizep)
+   *sizep = entry.size;
+   *bufp = map_sysmem(entry.image_pos + binman->rom_offset, entry.size);
+
+   return 0;
+}
+
+ofnode binman_section_find_node(const char *name)
+{
+   return ofnode_find_subnode(binman->image, name);
+}
+
 void binman_set_rom_offset(int rom_offset)
 {
binman->rom_offset = rom_offset;
-- 
2.27.0.290.gba653c62da-goog



[PATCH v1 05/43] dtoc: Support ACPI paths in of-platdata

2020-06-14 Thread Simon Glass
The start of an ACPI path typically has backslashes in it. These are not
preserved during the translation from device tree to C code, since dtc
(correctly) uses the first backslash as an escape character, and dtoc
therefore leaves it out of the C string.

Fix this with special-case handling.

Signed-off-by: Simon Glass 
---

 tools/dtoc/dtb_platdata.py  | 4 +++-
 tools/dtoc/dtoc_test_simple.dts | 1 +
 tools/dtoc/test_dtoc.py | 3 +++
 3 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/tools/dtoc/dtb_platdata.py b/tools/dtoc/dtb_platdata.py
index ecfe0624d1..0f903f54e8 100644
--- a/tools/dtoc/dtb_platdata.py
+++ b/tools/dtoc/dtb_platdata.py
@@ -102,7 +102,9 @@ def get_value(ftype, value):
 elif ftype == fdt.TYPE_BYTE:
 return '%#x' % tools.ToByte(value[0])
 elif ftype == fdt.TYPE_STRING:
-return '"%s"' % value
+# Handle evil ACPI backslashes by adding another backslash before them.
+# So "\\_SB.GPO0" in the device tree effectively stays like that in C
+return '"%s"' % value.replace('\\', '')
 elif ftype == fdt.TYPE_BOOL:
 return 'true'
 elif ftype == fdt.TYPE_INT64:
diff --git a/tools/dtoc/dtoc_test_simple.dts b/tools/dtoc/dtoc_test_simple.dts
index 165680bd4b..11bfc4c47a 100644
--- a/tools/dtoc/dtoc_test_simple.dts
+++ b/tools/dtoc/dtoc_test_simple.dts
@@ -34,6 +34,7 @@
longbytearray = [09 0a 0b 0c];
stringval = "message2";
stringarray = "another", "multi-word", "message";
+   acpi-name =  "\\_SB.GPO0";
};
 
spl-test3 {
diff --git a/tools/dtoc/test_dtoc.py b/tools/dtoc/test_dtoc.py
index 8498e8303c..86cb5a7c05 100755
--- a/tools/dtoc/test_dtoc.py
+++ b/tools/dtoc/test_dtoc.py
@@ -68,6 +68,7 @@ class TestDtoc(unittest.TestCase):
 @classmethod
 def setUpClass(cls):
 tools.PrepareOutputDir(None)
+cls.maxDiff = None
 
 @classmethod
 def tearDownClass(cls):
@@ -179,6 +180,7 @@ struct dtd_sandbox_pmic_test {
 \tfdt64_t\t\treg[2];
 };
 struct dtd_sandbox_spl_test {
+\tconst char * acpi_name;
 \tbool\t\tboolval;
 \tunsigned char\tbytearray[3];
 \tunsigned char\tbyteval;
@@ -216,6 +218,7 @@ U_BOOT_DEVICE(spl_test) = {
 };
 
 static const struct dtd_sandbox_spl_test dtv_spl_test2 = {
+\t.acpi_name\t\t= "_SB.GPO0",
 \t.bytearray\t\t= {0x1, 0x23, 0x34},
 \t.byteval\t\t= 0x8,
 \t.intarray\t\t= {0x5, 0x0, 0x0, 0x0},
-- 
2.27.0.290.gba653c62da-goog



[PATCH v1 02/43] binman: Refactor binman_entry_find() to allow other nodes

2020-06-14 Thread Simon Glass
At present we can only read from a top-level binman node entry. Refactor
this function to produce a second local function which supports reading
from any node.

Signed-off-by: Simon Glass 
---

 lib/binman.c | 18 --
 1 file changed, 12 insertions(+), 6 deletions(-)

diff --git a/lib/binman.c b/lib/binman.c
index dc3a880882..79d01230dd 100644
--- a/lib/binman.c
+++ b/lib/binman.c
@@ -29,25 +29,31 @@ struct binman_info {
 
 static struct binman_info *binman;
 
-int binman_entry_find(const char *name, struct binman_entry *entry)
+int binman_entry_find_(ofnode node, const char *name, struct binman_entry 
*entry)
 {
-   ofnode node;
int ret;
 
-   node = ofnode_find_subnode(binman->image, name);
if (!ofnode_valid(node))
-   return log_msg_ret("no binman node", -ENOENT);
+   node = binman->image;
+   node = ofnode_find_subnode(node, name);
+   if (!ofnode_valid(node))
+   return log_msg_ret("node", -ENOENT);
 
ret = ofnode_read_u32(node, "image-pos", &entry->image_pos);
if (ret)
-   return log_msg_ret("bad binman node1", ret);
+   return log_msg_ret("import-pos", ret);
ret = ofnode_read_u32(node, "size", &entry->size);
if (ret)
-   return log_msg_ret("bad binman node2", ret);
+   return log_msg_ret("size", ret);
 
return 0;
 }
 
+int binman_entry_find(const char *name, struct binman_entry *entry)
+{
+   return binman_entry_find_(binman->image, name, entry);
+}
+
 void binman_set_rom_offset(int rom_offset)
 {
binman->rom_offset = rom_offset;
-- 
2.27.0.290.gba653c62da-goog



[PATCH v1 09/43] acpi: Support generation of a scope

2020-06-14 Thread Simon Glass
Add a function to write a scope to the generated ACPI code.

Signed-off-by: Simon Glass 
---

 include/acpi/acpigen.h | 10 ++
 lib/acpi/acpigen.c |  7 +++
 test/dm/acpi.c |  3 +--
 test/dm/acpigen.c  | 33 -
 4 files changed, 50 insertions(+), 3 deletions(-)

diff --git a/include/acpi/acpigen.h b/include/acpi/acpigen.h
index 7c117c1cf6..af66c9828f 100644
--- a/include/acpi/acpigen.h
+++ b/include/acpi/acpigen.h
@@ -31,6 +31,7 @@ enum {
DWORD_PREFIX= 0x0c,
STRING_PREFIX   = 0x0d,
QWORD_PREFIX= 0x0e,
+   SCOPE_OP= 0x10,
BUFFER_OP   = 0x11,
PACKAGE_OP  = 0x12,
METHOD_OP   = 0x14,
@@ -258,6 +259,14 @@ void acpigen_emit_namestring(struct acpi_ctx *ctx, const 
char *namepath);
  */
 void acpigen_write_name(struct acpi_ctx *ctx, const char *namepath);
 
+/**
+ * acpigen_write_scope() - Write a scope
+ *
+ * @ctx: ACPI context pointer
+ * @name: Scope to write (e.g. "\\_SB.ABCD")
+ */
+void acpigen_write_scope(struct acpi_ctx *ctx, const char *name);
+
 /**
  * acpigen_write_uuid() - Write a UUID
  *
@@ -396,6 +405,7 @@ void acpigen_write_power_res(struct acpi_ctx *ctx, const 
char *name, uint level,
  */
 int acpigen_set_enable_tx_gpio(struct acpi_ctx *ctx, u32 tx_state_val,
   const char *dw0_name, struct acpi_gpio *gpio,
+
   bool enable);
 
 #endif
diff --git a/lib/acpi/acpigen.c b/lib/acpi/acpigen.c
index e0af36f775..77d6434806 100644
--- a/lib/acpi/acpigen.c
+++ b/lib/acpi/acpigen.c
@@ -257,6 +257,13 @@ void acpigen_write_name(struct acpi_ctx *ctx, const char 
*namepath)
acpigen_emit_namestring(ctx, namepath);
 }
 
+void acpigen_write_scope(struct acpi_ctx *ctx, const char *name)
+{
+   acpigen_emit_byte(ctx, SCOPE_OP);
+   acpigen_write_len_f(ctx);
+   acpigen_emit_namestring(ctx, name);
+}
+
 static void acpigen_write_method_(struct acpi_ctx *ctx, const char *name,
  uint flags)
 {
diff --git a/test/dm/acpi.c b/test/dm/acpi.c
index 7768f9514c..b94c4ba4d1 100644
--- a/test/dm/acpi.c
+++ b/test/dm/acpi.c
@@ -20,9 +20,8 @@
 #include 
 #include 
 #include 
+#include "acpi.h"
 
-#define ACPI_TEST_DEV_NAME "ABCD"
-#define ACPI_TEST_CHILD_NAME   "EFGH"
 #define BUF_SIZE   4096
 
 /**
diff --git a/test/dm/acpigen.c b/test/dm/acpigen.c
index 0322dd4f60..93dfa301d6 100644
--- a/test/dm/acpigen.c
+++ b/test/dm/acpigen.c
@@ -18,6 +18,7 @@
 #include 
 #include 
 #include 
+#include "acpi.h"
 
 #define TEST_STRING"frogmore"
 #define TEST_STRING2   "ranch"
@@ -359,7 +360,7 @@ DM_TEST(dm_test_acpi_spi, DM_TESTF_SCAN_PDATA | 
DM_TESTF_SCAN_FDT);
  */
 static int get_length(u8 *ptr)
 {
-   if (!(*ptr & 0x80))
+   if (!(*ptr & ACPI_PKG_LEN_3_BYTES))
return -EINVAL;
 
return (*ptr & 0xf) | ptr[1] << 4 | ptr[2] << 12;
@@ -906,3 +907,33 @@ static int dm_test_acpi_write_values(struct 
unit_test_state *uts)
 }
 DM_TEST(dm_test_acpi_write_values, 0);
 
+/* Test writing a scope */
+static int dm_test_acpi_scope(struct unit_test_state *uts)
+{
+   char buf[ACPI_PATH_MAX];
+   struct acpi_ctx *ctx;
+   struct udevice *dev;
+   u8 *ptr;
+
+   ut_assertok(alloc_context(&ctx));
+   ptr = acpigen_get_current(ctx);
+
+   ut_assertok(uclass_first_device_err(UCLASS_TEST_ACPI, &dev));
+   ut_assertok(acpi_device_path(dev, buf, sizeof(buf)));
+   acpigen_write_scope(ctx, buf);
+   acpigen_pop_len(ctx);
+
+   ut_asserteq(SCOPE_OP, *ptr++);
+   ut_asserteq(13, get_length(ptr));
+   ptr += 3;
+   ut_asserteq(ROOT_PREFIX, *ptr++);
+   ut_asserteq(DUAL_NAME_PREFIX, *ptr++);
+   ut_asserteq_strn("_SB_" ACPI_TEST_DEV_NAME, (char *)ptr);
+   ptr += 8;
+   ut_asserteq_ptr(ptr, ctx->current);
+
+   free_context(&ctx);
+
+   return 0;
+}
+DM_TEST(dm_test_acpi_scope, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
-- 
2.27.0.290.gba653c62da-goog



[PATCH v1 07/43] dm: acpi: Add support for the NHLT table

2020-06-14 Thread Simon Glass
The Intel Non-High-Definition-Audio Link Table (NHLT) table describes the
audio codecs and connections in a system. Various devices can contribute
information to produce the table.

Add core support for this, based on a structure which is built up through
calls to the driver.

Signed-off-by: Simon Glass 
---

 drivers/core/acpi.c | 15 +++
 include/dm/acpi.h   | 26 ++
 2 files changed, 41 insertions(+)

diff --git a/drivers/core/acpi.c b/drivers/core/acpi.c
index ea304a3067..a5053fec6f 100644
--- a/drivers/core/acpi.c
+++ b/drivers/core/acpi.c
@@ -31,6 +31,7 @@ enum method_t {
METHOD_WRITE_TABLES,
METHOD_FILL_SSDT,
METHOD_INJECT_DSDT,
+   METHOD_SETUP_NHLT,
 };
 
 /* Prototype for all methods */
@@ -239,6 +240,8 @@ acpi_method acpi_get_method(struct udevice *dev, enum 
method_t method)
return aops->fill_ssdt;
case METHOD_INJECT_DSDT:
return aops->inject_dsdt;
+   case METHOD_SETUP_NHLT:
+   return aops->setup_nhlt;
}
}
 
@@ -325,3 +328,15 @@ int acpi_write_dev_tables(struct acpi_ctx *ctx)
 
return ret;
 }
+
+int acpi_setup_nhlt(struct acpi_ctx *ctx, struct nhlt *nhlt)
+{
+   int ret;
+
+   log_debug("Setup NHLT\n");
+   ctx->nhlt = nhlt;
+   ret = acpi_recurse_method(ctx, dm_root(), METHOD_SETUP_NHLT, TYPE_NONE);
+   log_debug("Setup finished, err=%d\n", ret);
+
+   return ret;
+}
diff --git a/include/dm/acpi.h b/include/dm/acpi.h
index b6308b9fa6..a7f8e10ee2 100644
--- a/include/dm/acpi.h
+++ b/include/dm/acpi.h
@@ -27,6 +27,8 @@
 
 #if !defined(__ACPI__)
 
+struct nhlt;
+
 /** enum acpi_dump_option - selects what ACPI information to dump */
 enum acpi_dump_option {
ACPI_DUMP_LIST, /* Just the list of items */
@@ -44,6 +46,9 @@ enum acpi_dump_option {
  * adding a new table. The RSDP holds pointers to the RSDT and XSDT.
  * @rsdt: Pointer to the Root System Description Table
  * @xsdt: Pointer to the Extended System Description Table
+ * @nhlt: Intel Non-High-Definition-Audio Link Table (NHLT) pointer, used to
+ * build up information that audio codecs need to provide in the NHLT ACPI
+ * table
  * @len_stack: Stack of 'length' words to fix up later
  * @ltop: Points to current top of stack (0 = empty)
  */
@@ -53,6 +58,7 @@ struct acpi_ctx {
struct acpi_rsdp *rsdp;
struct acpi_rsdt *rsdt;
struct acpi_xsdt *xsdt;
+   struct nhlt *nhlt;
char *len_stack[ACPIGEN_LENSTACK_SIZE];
int ltop;
 };
@@ -106,6 +112,15 @@ struct acpi_ops {
 * @return 0 if OK, -ve on error
 */
int (*inject_dsdt)(const struct udevice *dev, struct acpi_ctx *ctx);
+
+   /**
+* setup_nhlt() - Set up audio information for this device
+*
+* The method can add information to ctx->nhlt if it likes
+*
+* @return 0 if OK, -ENODATA if nothing to add, -ve on error
+*/
+   int (*setup_nhlt)(const struct udevice *dev, struct acpi_ctx *ctx);
 };
 
 #define device_get_acpi_ops(dev)   ((dev)->driver->acpi_ops)
@@ -170,6 +185,17 @@ int acpi_fill_ssdt(struct acpi_ctx *ctx);
  */
 int acpi_inject_dsdt(struct acpi_ctx *ctx);
 
+/**
+ * acpi_setup_nhlt() - Set up audio information
+ *
+ * This is called to set up the nhlt information for all devices.
+ *
+ * @ctx: ACPI context to use
+ * @nhlt: Pointer to nhlt information to add to
+ * @return 0 if OK, -ve on error
+ */
+int acpi_setup_nhlt(struct acpi_ctx *ctx, struct nhlt *nhlt);
+
 /**
  * acpi_dump_items() - Dump out the collected ACPI items
  *
-- 
2.27.0.290.gba653c62da-goog



[PATCH v1 08/43] acpi: Export functions to write sized values

2020-06-14 Thread Simon Glass
At present only acpigen_write_integer() is exported for use by other code.
But in some cases it is useful to call the specific function depending on
the size of the value.

Export these functions and add a test.

Signed-off-by: Simon Glass 
---

 include/acpi/acpigen.h | 46 ++
 test/dm/acpigen.c  | 45 -
 2 files changed, 90 insertions(+), 1 deletion(-)

diff --git a/include/acpi/acpigen.h b/include/acpi/acpigen.h
index d68dca5dde..7c117c1cf6 100644
--- a/include/acpi/acpigen.h
+++ b/include/acpi/acpigen.h
@@ -169,6 +169,52 @@ void acpigen_pop_len(struct acpi_ctx *ctx);
  */
 char *acpigen_write_package(struct acpi_ctx *ctx, int nr_el);
 
+/**
+ * acpigen_write_byte() - Write a byte
+ *
+ * @ctx: ACPI context pointer
+ * @data: Value to write
+ */
+void acpigen_write_byte(struct acpi_ctx *ctx, unsigned int data);
+
+/**
+ * acpigen_write_word() - Write a word
+ *
+ * @ctx: ACPI context pointer
+ * @data: Value to write
+ */
+void acpigen_write_word(struct acpi_ctx *ctx, unsigned int data);
+
+/**
+ * acpigen_write_dword() - Write a dword
+ *
+ * @ctx: ACPI context pointer
+ * @data: Value to write
+ */
+void acpigen_write_dword(struct acpi_ctx *ctx, unsigned int data);
+
+/**
+ * acpigen_write_qword() - Write a qword
+ *
+ * @ctx: ACPI context pointer
+ * @data: Value to write
+ */
+void acpigen_write_qword(struct acpi_ctx *ctx, u64 data);
+
+/**
+ * acpigen_write_zero() - Write zero
+ *
+ * @ctx: ACPI context pointer
+ */
+void acpigen_write_zero(struct acpi_ctx *ctx);
+
+/**
+ * acpigen_write_one() - Write one
+ *
+ * @ctx: ACPI context pointer
+ */
+void acpigen_write_one(struct acpi_ctx *ctx);
+
 /**
  * acpigen_write_integer() - Write an integer
  *
diff --git a/test/dm/acpigen.c b/test/dm/acpigen.c
index ea2033a27c..0322dd4f60 100644
--- a/test/dm/acpigen.c
+++ b/test/dm/acpigen.c
@@ -861,5 +861,48 @@ static int dm_test_acpi_power_seq(struct unit_test_state 
*uts)
 
return 0;
 }
-
 DM_TEST(dm_test_acpi_power_seq, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+
+/* Test writing values */
+static int dm_test_acpi_write_values(struct unit_test_state *uts)
+{
+   struct acpi_ctx *ctx;
+   u8 *ptr;
+
+   ut_assertok(alloc_context(&ctx));
+   ptr = acpigen_get_current(ctx);
+
+   acpigen_write_zero(ctx);
+   acpigen_write_one(ctx);
+   acpigen_write_byte(ctx, TEST_INT8);
+   acpigen_write_word(ctx, TEST_INT16);
+   acpigen_write_dword(ctx, TEST_INT32);
+   acpigen_write_qword(ctx, TEST_INT64);
+
+   ut_asserteq(ZERO_OP, *ptr++);
+
+   ut_asserteq(ONE_OP, *ptr++);
+
+   ut_asserteq(BYTE_PREFIX, *ptr++);
+   ut_asserteq(TEST_INT8, *ptr++);
+
+   ut_asserteq(WORD_PREFIX, *ptr++);
+   ut_asserteq(TEST_INT16, get_unaligned((u16 *)ptr));
+   ptr += 2;
+
+   ut_asserteq(DWORD_PREFIX, *ptr++);
+   ut_asserteq(TEST_INT32, get_unaligned((u32 *)ptr));
+   ptr += 4;
+
+   ut_asserteq(QWORD_PREFIX, *ptr++);
+   ut_asserteq_64(TEST_INT64, get_unaligned((u64 *)ptr));
+   ptr += 8;
+
+   ut_asserteq_ptr(ptr, ctx->current);
+
+   free_context(&ctx);
+
+   return 0;
+}
+DM_TEST(dm_test_acpi_write_values, 0);
+
-- 
2.27.0.290.gba653c62da-goog



[PATCH v1 10/43] acpi: Support generation of a generic register

2020-06-14 Thread Simon Glass
Allow writing out a generic register.

Signed-off-by: Simon Glass 
---

 include/acpi/acpi_device.h |  1 +
 include/acpi/acpigen.h | 28 +++
 lib/acpi/acpigen.c | 71 ++
 test/dm/acpigen.c  | 46 
 4 files changed, 146 insertions(+)

diff --git a/include/acpi/acpi_device.h b/include/acpi/acpi_device.h
index d076b452b5..474ac8955f 100644
--- a/include/acpi/acpi_device.h
+++ b/include/acpi/acpi_device.h
@@ -20,6 +20,7 @@ struct udevice;
 
 /* ACPI descriptor values for common descriptors: SERIAL_BUS means I2C */
 #define ACPI_DESCRIPTOR_LARGE  BIT(7)
+#define ACPI_DESCRIPTOR_REGISTER   (ACPI_DESCRIPTOR_LARGE | 2)
 #define ACPI_DESCRIPTOR_INTERRUPT  (ACPI_DESCRIPTOR_LARGE | 9)
 #define ACPI_DESCRIPTOR_GPIO   (ACPI_DESCRIPTOR_LARGE | 12)
 #define ACPI_DESCRIPTOR_SERIAL_BUS (ACPI_DESCRIPTOR_LARGE | 14)
diff --git a/include/acpi/acpigen.h b/include/acpi/acpigen.h
index af66c9828f..4361a28a08 100644
--- a/include/acpi/acpigen.h
+++ b/include/acpi/acpigen.h
@@ -13,6 +13,7 @@
 #include 
 
 struct acpi_ctx;
+struct acpi_gen_regaddr;
 struct acpi_gpio;
 
 /* Top 4 bits of the value used to indicate a three-byte length value */
@@ -21,6 +22,8 @@ struct acpi_gpio;
 #define ACPI_METHOD_NARGS_MASK 0x7
 #define ACPI_METHOD_SERIALIZED_MASKBIT(3)
 
+#define ACPI_END_TAG   0x79
+
 /* ACPI Op/Prefix codes */
 enum {
ZERO_OP = 0x00,
@@ -315,6 +318,31 @@ void acpigen_write_method_serialized(struct acpi_ctx *ctx, 
const char *name,
  */
 void acpigen_write_sta(struct acpi_ctx *ctx, uint status);
 
+/**
+ * acpigen_write_resourcetemplate_header() - Write a ResourceTemplate header
+ *
+ * @ctx: ACPI context pointer
+ */
+void acpigen_write_resourcetemplate_header(struct acpi_ctx *ctx);
+
+/**
+ * acpigen_write_resourcetemplate_footer() - Write a ResourceTemplate footer
+ *
+ * @ctx: ACPI context pointer
+ */
+void acpigen_write_resourcetemplate_footer(struct acpi_ctx *ctx);
+
+/**
+ * acpigen_write_register_resource() - Write a register resource
+ *
+ * This writes a header, the address information and a footer
+ *
+ * @ctx: ACPI context pointer
+ * @addr: Address to write
+ */
+void acpigen_write_register_resource(struct acpi_ctx *ctx,
+const struct acpi_gen_regaddr *addr);
+
 /**
  * acpigen_write_sleep() - Write a sleep operation
  *
diff --git a/lib/acpi/acpigen.c b/lib/acpi/acpigen.c
index 77d6434806..6f5972f1f7 100644
--- a/lib/acpi/acpigen.c
+++ b/lib/acpi/acpigen.c
@@ -14,6 +14,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 u8 *acpigen_get_current(struct acpi_ctx *ctx)
@@ -296,6 +297,76 @@ void acpigen_write_sta(struct acpi_ctx *ctx, uint status)
acpigen_pop_len(ctx);
 }
 
+static void acpigen_write_register(struct acpi_ctx *ctx,
+  const struct acpi_gen_regaddr *addr)
+{
+   /* See ACPI v6.3 section 6.4.3.7: Generic Register Descriptor */
+   acpigen_emit_byte(ctx, ACPI_DESCRIPTOR_REGISTER);
+   acpigen_emit_byte(ctx, 0x0c);   /* Register Length 7:0 */
+   acpigen_emit_byte(ctx, 0x00);   /* Register Length 15:8 */
+   acpigen_emit_byte(ctx, addr->space_id);
+   acpigen_emit_byte(ctx, addr->bit_width);
+   acpigen_emit_byte(ctx, addr->bit_offset);
+   acpigen_emit_byte(ctx, addr->access_size);
+   acpigen_emit_dword(ctx, addr->addrl);
+   acpigen_emit_dword(ctx, addr->addrh);
+}
+
+void acpigen_write_resourcetemplate_header(struct acpi_ctx *ctx)
+{
+   /*
+* A ResourceTemplate() is a Buffer() with a
+* (Byte|Word|DWord) containing the length, followed by one or more
+* resource items, terminated by the end tag.
+* (small item 0xf, len 1)
+*/
+   acpigen_emit_byte(ctx, BUFFER_OP);
+   acpigen_write_len_f(ctx);
+   acpigen_emit_byte(ctx, WORD_PREFIX);
+   ctx->len_stack[ctx->ltop++] = ctx->current;
+
+   /*
+* Add two dummy bytes for the ACPI word (keep aligned with the
+* calculation in acpigen_write_resourcetemplate_footer() below)
+*/
+   acpigen_emit_byte(ctx, 0x00);
+   acpigen_emit_byte(ctx, 0x00);
+}
+
+void acpigen_write_resourcetemplate_footer(struct acpi_ctx *ctx)
+{
+   char *p = ctx->len_stack[--ctx->ltop];
+   int len;
+   /*
+* See ACPI v6.3 section 6.4.2.9: End Tag
+* 0x79 
+* 0x00 is treated as a good checksum according to the spec
+* and is what iasl generates.
+*/
+   acpigen_emit_byte(ctx, ACPI_END_TAG);
+   acpigen_emit_byte(ctx, 0x00);
+
+   /*
+* Start counting past the 2-bytes length added in
+* acpigen_write_resourcetemplate_header() above
+*/
+   len = (char *)ctx->current - (p + 2);
+
+   /* patch len word */
+   p[0] = len & 0xff;
+   p[1] = (len >> 8) & 0xff;
+
+   acpigen_pop_len(ctx);

[PATCH v1 14/43] acpi: Support writing named values

2020-06-14 Thread Simon Glass
Allow writing named integers and strings to the generated ACPI code.

Signed-off-by: Simon Glass 
---

 include/acpi/acpigen.h | 72 ++
 lib/acpi/acpigen.c | 49 ++
 test/dm/acpigen.c  | 78 ++
 3 files changed, 199 insertions(+)

diff --git a/include/acpi/acpigen.h b/include/acpi/acpigen.h
index 19f84dc867..01620fd36b 100644
--- a/include/acpi/acpigen.h
+++ b/include/acpi/acpigen.h
@@ -231,6 +231,78 @@ void acpigen_write_one(struct acpi_ctx *ctx);
  */
 void acpigen_write_integer(struct acpi_ctx *ctx, u64 data);
 
+/**
+ * acpigen_write_name_zero() - Write a named zero value
+ *
+ * @ctx: ACPI context pointer
+ * @name: Name of the value
+ */
+void acpigen_write_name_zero(struct acpi_ctx *ctx, const char *name);
+
+/**
+ * acpigen_write_name_one() - Write a named one value
+ *
+ * @ctx: ACPI context pointer
+ * @name: Name of the value
+ */
+void acpigen_write_name_one(struct acpi_ctx *ctx, const char *name);
+
+/**
+ * acpigen_write_name_byte() - Write a named byte value
+ *
+ * @ctx: ACPI context pointer
+ * @name: Name of the value
+ * @val: Value to write
+ */
+void acpigen_write_name_byte(struct acpi_ctx *ctx, const char *name, uint val);
+
+/**
+ * acpigen_write_name_word() - Write a named word value
+ *
+ * @ctx: ACPI context pointer
+ * @name: Name of the value
+ * @val: Value to write
+ */
+void acpigen_write_name_word(struct acpi_ctx *ctx, const char *name, uint val);
+
+/**
+ * acpigen_write_name_dword() - Write a named dword value
+ *
+ * @ctx: ACPI context pointer
+ * @name: Name of the value
+ * @val: Value to write
+ */
+void acpigen_write_name_dword(struct acpi_ctx *ctx, const char *name, uint 
val);
+
+/**
+ * acpigen_write_name_qword() - Write a named qword value
+ *
+ * @ctx: ACPI context pointer
+ * @name: Name of the value
+ * @val: Value to write
+ */
+void acpigen_write_name_qword(struct acpi_ctx *ctx, const char *name, u64 val);
+
+/**
+ * acpigen_write_name_integer() - Write a named integer value
+ *
+ * @ctx: ACPI context pointer
+ * @name: Name of the value
+ * @val: Value to write
+ */
+void acpigen_write_name_integer(struct acpi_ctx *ctx, const char *name,
+   u64 val);
+
+/**
+ * acpigen_write_name_string() - Write a named string value
+ *
+ * @ctx: ACPI context pointer
+ * @name: Name of the value
+ * @string: String to write
+ */
+void acpigen_write_name_string(struct acpi_ctx *ctx, const char *name,
+  const char *string);
+
 /**
  * acpigen_write_string() - Write a string
  *
diff --git a/lib/acpi/acpigen.c b/lib/acpi/acpigen.c
index 5fe1f59f82..86af88d1bc 100644
--- a/lib/acpi/acpigen.c
+++ b/lib/acpi/acpigen.c
@@ -142,6 +142,55 @@ void acpigen_write_integer(struct acpi_ctx *ctx, u64 data)
acpigen_write_qword(ctx, data);
 }
 
+void acpigen_write_name_zero(struct acpi_ctx *ctx, const char *name)
+{
+   acpigen_write_name(ctx, name);
+   acpigen_write_zero(ctx);
+}
+
+void acpigen_write_name_one(struct acpi_ctx *ctx, const char *name)
+{
+   acpigen_write_name(ctx, name);
+   acpigen_write_one(ctx);
+}
+
+void acpigen_write_name_byte(struct acpi_ctx *ctx, const char *name, uint val)
+{
+   acpigen_write_name(ctx, name);
+   acpigen_write_byte(ctx, val);
+}
+
+void acpigen_write_name_word(struct acpi_ctx *ctx, const char *name, uint val)
+{
+   acpigen_write_name(ctx, name);
+   acpigen_write_word(ctx, val);
+}
+
+void acpigen_write_name_dword(struct acpi_ctx *ctx, const char *name, uint val)
+{
+   acpigen_write_name(ctx, name);
+   acpigen_write_dword(ctx, val);
+}
+
+void acpigen_write_name_qword(struct acpi_ctx *ctx, const char *name, u64 val)
+{
+   acpigen_write_name(ctx, name);
+   acpigen_write_qword(ctx, val);
+}
+
+void acpigen_write_name_integer(struct acpi_ctx *ctx, const char *name, u64 
val)
+{
+   acpigen_write_name(ctx, name);
+   acpigen_write_integer(ctx, val);
+}
+
+void acpigen_write_name_string(struct acpi_ctx *ctx, const char *name,
+  const char *string)
+{
+   acpigen_write_name(ctx, name);
+   acpigen_write_string(ctx, string);
+}
+
 void acpigen_emit_stream(struct acpi_ctx *ctx, const char *data, int size)
 {
int i;
diff --git a/test/dm/acpigen.c b/test/dm/acpigen.c
index 5cd7fb5657..4fcd155b93 100644
--- a/test/dm/acpigen.c
+++ b/test/dm/acpigen.c
@@ -1010,3 +1010,81 @@ static int dm_test_acpi_device(struct unit_test_state 
*uts)
return 0;
 }
 DM_TEST(dm_test_acpi_device, 0);
+
+/* Test writing named values */
+static int dm_test_acpi_write_name(struct unit_test_state *uts)
+{
+   const char *name = "\\_SB." ACPI_TEST_DEV_NAME;
+   struct acpi_ctx *ctx;
+   u8 *ptr;
+
+   ut_assertok(alloc_context(&ctx));
+   ptr = acpigen_get_current(ctx);
+
+   acpigen_write_name_zero(ctx, name);
+   acpigen_write_name_one(ctx, name);
+   acpigen_writ

[PATCH v1 11/43] acpi: mmc: Generate ACPI info for the PCI SD Card

2020-06-14 Thread Simon Glass
Write required information into the SSDT to describe the SD card
card-detect pin. Since the required GPIO properties are not present in
the device-tree binding, set them manually for now.

Signed-off-by: Simon Glass 
---

Changes in v1:
- Capitalise ACPI_OPS_PTR

 configs/sandbox_defconfig |  2 +
 drivers/mmc/pci_mmc.c | 78 ++-
 2 files changed, 79 insertions(+), 1 deletion(-)

diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
index 982075c568..cb6b4b0ee7 100644
--- a/configs/sandbox_defconfig
+++ b/configs/sandbox_defconfig
@@ -143,7 +143,9 @@ CONFIG_P2SB=y
 CONFIG_PWRSEQ=y
 CONFIG_SPL_PWRSEQ=y
 CONFIG_I2C_EEPROM=y
+CONFIG_MMC_PCI=y
 CONFIG_MMC_SANDBOX=y
+CONFIG_MMC_SDHCI=y
 CONFIG_MTD=y
 CONFIG_SPI_FLASH_SANDBOX=y
 CONFIG_SPI_FLASH_ATMEL=y
diff --git a/drivers/mmc/pci_mmc.c b/drivers/mmc/pci_mmc.c
index 404264a697..0c45e1b893 100644
--- a/drivers/mmc/pci_mmc.c
+++ b/drivers/mmc/pci_mmc.c
@@ -7,10 +7,15 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
-#include 
+#include 
+#include 
+#include 
+#include 
+#include 
 
 struct pci_mmc_plat {
struct mmc_config cfg;
@@ -20,6 +25,7 @@ struct pci_mmc_plat {
 struct pci_mmc_priv {
struct sdhci_host host;
void *base;
+   struct gpio_desc cd_gpio;
 };
 
 static int pci_mmc_probe(struct udevice *dev)
@@ -44,6 +50,15 @@ static int pci_mmc_probe(struct udevice *dev)
return sdhci_probe(dev);
 }
 
+static int pci_mmc_ofdata_to_platdata(struct udevice *dev)
+{
+   struct pci_mmc_priv *priv = dev_get_priv(dev);
+
+   gpio_request_by_name(dev, "cd-gpios", 0, &priv->cd_gpio, GPIOD_IS_IN);
+
+   return 0;
+}
+
 static int pci_mmc_bind(struct udevice *dev)
 {
struct pci_mmc_plat *plat = dev_get_platdata(dev);
@@ -51,14 +66,75 @@ static int pci_mmc_bind(struct udevice *dev)
return sdhci_bind(dev, &plat->mmc, &plat->cfg);
 }
 
+static int pci_mmc_acpi_fill_ssdt(const struct udevice *dev,
+ struct acpi_ctx *ctx)
+{
+   struct pci_mmc_priv *priv = dev_get_priv(dev);
+   char path[ACPI_PATH_MAX];
+   struct acpi_gpio gpio;
+   struct acpi_dp *dp;
+   int ret;
+
+   if (!dev_of_valid(dev))
+   return 0;
+
+   ret = gpio_get_acpi(&priv->cd_gpio, &gpio);
+   if (ret)
+   return log_msg_ret("gpio", ret);
+   gpio.type = ACPI_GPIO_TYPE_INTERRUPT;
+   gpio.pull = ACPI_GPIO_PULL_NONE;
+   gpio.irq.mode = ACPI_IRQ_EDGE_TRIGGERED;
+   gpio.irq.polarity = ACPI_IRQ_ACTIVE_BOTH;
+   gpio.irq.shared = ACPI_IRQ_SHARED;
+   gpio.irq.wake = ACPI_IRQ_WAKE;
+   gpio.interrupt_debounce_timeout = 1; /* 100ms */
+
+   /* Use device path as the Scope for the SSDT */
+   ret = acpi_device_path(dev, path, sizeof(path));
+   if (ret)
+   return log_msg_ret("path", ret);
+   acpigen_write_scope(ctx, path);
+   acpigen_write_name(ctx, "_CRS");
+
+   /* Write GpioInt() as default (if set) or custom from devicetree */
+   acpigen_write_resourcetemplate_header(ctx);
+   acpi_device_write_gpio(ctx, &gpio);
+   acpigen_write_resourcetemplate_footer(ctx);
+
+   /* Bind the cd-gpio name to the GpioInt() resource */
+   dp = acpi_dp_new_table("_DSD");
+   if (!dp)
+   return -ENOMEM;
+   acpi_dp_add_gpio(dp, "cd-gpio", path, 0, 0, 1);
+   ret = acpi_dp_write(ctx, dp);
+   if (ret)
+   return log_msg_ret("cd", ret);
+
+   acpigen_pop_len(ctx);
+
+   return 0;
+}
+
+struct acpi_ops pci_mmc_acpi_ops = {
+   .fill_ssdt  = pci_mmc_acpi_fill_ssdt,
+};
+
+static const struct udevice_id pci_mmc_match[] = {
+   { .compatible = "intel,apl-sd" },
+   { }
+};
+
 U_BOOT_DRIVER(pci_mmc) = {
.name   = "pci_mmc",
.id = UCLASS_MMC,
+   .of_match = pci_mmc_match,
.bind   = pci_mmc_bind,
+   .ofdata_to_platdata = pci_mmc_ofdata_to_platdata,
.probe  = pci_mmc_probe,
.ops= &sdhci_ops,
.priv_auto_alloc_size = sizeof(struct pci_mmc_priv),
.platdata_auto_alloc_size = sizeof(struct pci_mmc_plat),
+   ACPI_OPS_PTR(&pci_mmc_acpi_ops)
 };
 
 static struct pci_device_id mmc_supported[] = {
-- 
2.27.0.290.gba653c62da-goog



[PATCH v1 12/43] x86: Add bindings for NHLT

2020-06-14 Thread Simon Glass
Add devicetree bindings for the Intel Non-High-Definition-Audio Link Table
(NHLT).

Signed-off-by: Simon Glass 
---

 include/dt-bindings/sound/nhlt.h | 23 +++
 1 file changed, 23 insertions(+)
 create mode 100644 include/dt-bindings/sound/nhlt.h

diff --git a/include/dt-bindings/sound/nhlt.h b/include/dt-bindings/sound/nhlt.h
new file mode 100644
index 00..c33f874966
--- /dev/null
+++ b/include/dt-bindings/sound/nhlt.h
@@ -0,0 +1,23 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2019 Google LLC
+ */
+
+#ifndef _DT_BINDINGS_SOUND_NHLT_H
+#define _DT_BINDINGS_SOUND_NHLT_H
+
+#define NHLT_VID   0x8086
+#define NHLT_DID_DMIC  0xae20
+#define NHLT_DID_BT0xae30
+#define NHLT_DID_SSP   0xae34
+
+/* Hardware links available to use for codecs */
+#define AUDIO_LINK_SSP00
+#define AUDIO_LINK_SSP11
+#define AUDIO_LINK_SSP22
+#define AUDIO_LINK_SSP33
+#define AUDIO_LINK_SSP44
+#define AUDIO_LINK_SSP55
+#define AUDIO_LINK_DMIC6
+
+#endif /* _DT_BINDINGS_SOUND_NHLT_H */
-- 
2.27.0.290.gba653c62da-goog



[PATCH v1 13/43] acpi: Support generation of a device

2020-06-14 Thread Simon Glass
Allow writing an ACPI device to the generated ACPI code.

Signed-off-by: Simon Glass 
---

 include/acpi/acpigen.h |  9 +
 lib/acpi/acpigen.c |  7 +++
 test/dm/acpigen.c  | 27 +++
 3 files changed, 43 insertions(+)

diff --git a/include/acpi/acpigen.h b/include/acpi/acpigen.h
index 4361a28a08..19f84dc867 100644
--- a/include/acpi/acpigen.h
+++ b/include/acpi/acpigen.h
@@ -56,6 +56,7 @@ enum {
AND_OP  = 0x7b,
OR_OP   = 0x7d,
NOT_OP  = 0x80,
+   DEVICE_OP   = 0x82,
POWER_RES_OP= 0x84,
RETURN_OP   = 0xa4,
 };
@@ -310,6 +311,14 @@ void acpigen_write_method(struct acpi_ctx *ctx, const char 
*name, int nargs);
 void acpigen_write_method_serialized(struct acpi_ctx *ctx, const char *name,
 int nargs);
 
+/**
+ * acpigen_write_device() - Write an ACPI device
+ *
+ * @ctx: ACPI context pointer
+ * @name: Device name to write
+ */
+void acpigen_write_device(struct acpi_ctx *ctx, const char *name);
+
 /**
  * acpigen_write_sta() - Write a _STA method
  *
diff --git a/lib/acpi/acpigen.c b/lib/acpi/acpigen.c
index 6f5972f1f7..5fe1f59f82 100644
--- a/lib/acpi/acpigen.c
+++ b/lib/acpi/acpigen.c
@@ -288,6 +288,13 @@ void acpigen_write_method_serialized(struct acpi_ctx *ctx, 
const char *name,
  ACPI_METHOD_SERIALIZED_MASK);
 }
 
+void acpigen_write_device(struct acpi_ctx *ctx, const char *name)
+{
+   acpigen_emit_ext_op(ctx, DEVICE_OP);
+   acpigen_write_len_f(ctx);
+   acpigen_emit_namestring(ctx, name);
+}
+
 void acpigen_write_sta(struct acpi_ctx *ctx, uint status)
 {
/* Method (_STA, 0, NotSerialized) { Return (status) } */
diff --git a/test/dm/acpigen.c b/test/dm/acpigen.c
index 80697300e7..5cd7fb5657 100644
--- a/test/dm/acpigen.c
+++ b/test/dm/acpigen.c
@@ -983,3 +983,30 @@ static int dm_test_acpi_resource_template(struct 
unit_test_state *uts)
return 0;
 }
 DM_TEST(dm_test_acpi_resource_template, 0);
+
+/* Test writing a device */
+static int dm_test_acpi_device(struct unit_test_state *uts)
+{
+   struct acpi_ctx *ctx;
+   u8 *ptr;
+
+   ut_assertok(alloc_context(&ctx));
+   ptr = acpigen_get_current(ctx);
+
+   acpigen_write_device(ctx, "\\_SB." ACPI_TEST_DEV_NAME);
+   acpigen_pop_len(ctx);
+
+   ut_asserteq(EXT_OP_PREFIX, *ptr++);
+   ut_asserteq(DEVICE_OP, *ptr++);
+   ut_asserteq(0xd, get_length(ptr));
+   ptr += 3;
+   ut_asserteq(ROOT_PREFIX, *ptr++);
+   ut_asserteq(DUAL_NAME_PREFIX, *ptr++);
+   ptr += 8;
+   ut_asserteq_ptr(ptr, ctx->current);
+
+   free_context(&ctx);
+
+   return 0;
+}
+DM_TEST(dm_test_acpi_device, 0);
-- 
2.27.0.290.gba653c62da-goog



[PATCH v1 19/43] x86: pinctrl: Add multi-ACPI control

2020-06-14 Thread Simon Glass
Add a Kconfig to control whether pinctrl is represented as a single ACPI
device or as multiple devices. In the latter case (the default) we should
return the pin number relative to the pinctrl device.

Signed-off-by: Simon Glass 
---

 drivers/pinctrl/intel/Kconfig   | 4 
 drivers/pinctrl/intel/pinctrl.c | 2 ++
 2 files changed, 6 insertions(+)

diff --git a/drivers/pinctrl/intel/Kconfig b/drivers/pinctrl/intel/Kconfig
index e62a2e0349..05a314af88 100644
--- a/drivers/pinctrl/intel/Kconfig
+++ b/drivers/pinctrl/intel/Kconfig
@@ -15,6 +15,10 @@ config INTEL_PINCTRL_IOSTANDBY
bool
default y
 
+config INTEL_PINCTRL_MULTI_ACPI_DEVICES
+   bool
+   default y
+
 config PINCTRL_INTEL_APL
bool "Support Intel Apollo Lake (APL)"
help
diff --git a/drivers/pinctrl/intel/pinctrl.c b/drivers/pinctrl/intel/pinctrl.c
index bf3989bf32..32ca303b27 100644
--- a/drivers/pinctrl/intel/pinctrl.c
+++ b/drivers/pinctrl/intel/pinctrl.c
@@ -427,6 +427,8 @@ int intel_pinctrl_get_acpi_pin(struct udevice *dev, uint 
offset)
const struct pad_community *comm = priv->comm;
int group;
 
+   if (IS_ENABLED(CONFIG_INTEL_PINCTRL_MULTI_ACPI_DEVICES))
+   return offset;
group = pinctrl_group_index(comm, offset);
 
/* If pad base is not set then use GPIO number as ACPI pin number */
-- 
2.27.0.290.gba653c62da-goog



[PATCH v1 15/43] sound: Add an ACPI driver for Dialog Semicondutor da7219

2020-06-14 Thread Simon Glass
This chip is used on coral and we need to generate ACPI tables for sound
to make it work. Add a driver that does just this (i.e. at present does
not actually support playing sound).

Signed-off-by: Simon Glass 
---

Changes in v1:
- Use acpi,ddn instead of acpi,desc
- Add a check for invalid node
- Add NHLT support
- Capitalise ACPI_OPS_PTR
- Rebase to master

 configs/sandbox_defconfig |   1 +
 doc/device-tree-bindings/sound/da7219.txt | 113 +
 drivers/sound/Kconfig |   9 ++
 drivers/sound/Makefile|   1 +
 drivers/sound/da7219.c| 189 ++
 5 files changed, 313 insertions(+)
 create mode 100644 doc/device-tree-bindings/sound/da7219.txt
 create mode 100644 drivers/sound/da7219.c

diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
index cb6b4b0ee7..6368e278f2 100644
--- a/configs/sandbox_defconfig
+++ b/configs/sandbox_defconfig
@@ -202,6 +202,7 @@ CONFIG_SANDBOX_SERIAL=y
 CONFIG_SMEM=y
 CONFIG_SANDBOX_SMEM=y
 CONFIG_SOUND=y
+CONFIG_SOUND_DA7219=y
 CONFIG_SOUND_SANDBOX=y
 CONFIG_SANDBOX_SPI=y
 CONFIG_SPMI=y
diff --git a/doc/device-tree-bindings/sound/da7219.txt 
b/doc/device-tree-bindings/sound/da7219.txt
new file mode 100644
index 00..5fd8a9f1e7
--- /dev/null
+++ b/doc/device-tree-bindings/sound/da7219.txt
@@ -0,0 +1,113 @@
+Dialog Semiconductor DA7219 Audio Codec bindings
+
+DA7219 is an audio codec with advanced accessory detect features.
+
+==
+
+Required properties:
+- compatible : Should be "dlg,da7219"
+- reg: Specifies the I2C slave address
+
+- interrupts : IRQ line info for DA7219.
+  (See Documentation/devicetree/bindings/interrupt-controller/interrupts.txt 
for
+   further information relating to interrupt properties)
+
+- VDD-supply: VDD power supply for the device
+- VDDMIC-supply: VDDMIC power supply for the device
+- VDDIO-supply: VDDIO power supply for the device
+  (See Documentation/devicetree/bindings/regulator/regulator.txt for further
+   information relating to regulators)
+
+Optional properties:
+- interrupt-names : Name associated with interrupt line. Should be "wakeup" if
+  interrupt is to be used to wake system, otherwise "irq" should be used.
+- wakeup-source: Flag to indicate this device can wake system (suspend/resume).
+
+- #clock-cells :  Should be set to '<0>', only one clock source provided;
+- clock-output-names : Name given for DAI clocks output;
+
+- clocks : phandle and clock specifier for codec MCLK.
+- clock-names : Clock name string for 'clocks' attribute, should be "mclk".
+
+- dlg,micbias-lvl : Voltage (mV) for Mic Bias
+   [<1600>, <1800>, <2000>, <2200>, <2400>, <2600>]
+- dlg,mic-amp-in-sel : Mic input source type
+   ["diff", "se_p", "se_n"]
+- dlg,mclk-name : String name of MCLK for ACPI
+
+Deprecated properties:
+- dlg,ldo-lvl : Required internal LDO voltage (mV) level for digital engine
+  (LDO unavailable in production HW so property no longer required).
+
+==
+
+Child node - 'da7219_aad':
+
+Optional properties:
+- dlg,micbias-pulse-lvl : Mic bias higher voltage pulse level (mV).
+   [<2800>, <2900>]
+- dlg,micbias-pulse-time : Mic bias higher voltage pulse duration (ms)
+- dlg,btn-cfg : Periodic button press measurements for 4-pole jack (ms)
+   [<2>, <5>, <10>, <50>, <100>, <200>, <500>]
+- dlg,mic-det-thr : Impedance threshold for mic detection measurement (Ohms)
+   [<200>, <500>, <750>, <1000>]
+- dlg,jack-ins-deb : Debounce time for jack insertion (ms)
+   [<5>, <10>, <20>, <50>, <100>, <200>, <500>, <1000>]
+- dlg,jack-det-rate: Jack type detection latency (3/4 pole)
+   ["32ms_64ms", "64ms_128ms", "128ms_256ms", "256ms_512ms"]
+- dlg,jack-rem-deb : Debounce time for jack removal (ms)
+   [<1>, <5>, <10>, <20>]
+- dlg,a-d-btn-thr : Impedance threshold between buttons A and D
+   [0x0 - 0xFF]
+- dlg,d-b-btn-thr : Impedance threshold between buttons D and B
+   [0x0 - 0xFF]
+- dlg,b-c-btn-thr : Impedance threshold between buttons B and C
+   [0x0 - 0xFF]
+- dlg,c-mic-btn-thr : Impedance threshold between button C and Mic
+   [0x0 - 0xFF]
+- dlg,btn-avg : Number of 8-bit readings for averaged button measurement
+   [<1>, <2>, <4>, <8>]
+- dlg,adc-1bit-rpt : Repeat count for 1-bit button measurement
+   [<1>, <2>, <4>, <8>]
+
+==
+
+Example:
+
+   codec: da7219@1a {
+   compatible = "dlg,da7219";
+   reg = <0x1a>;
+
+   interrupt-parent = <&gpio6>;
+   interrupts = <11 IRQ_TYPE_LEVEL_LOW>;
+
+   VDD-supply = <®_audio>;
+   VDDMIC-supply = <®_audio>;
+   VDDIO-supply = <®_audio>;
+
+   #clock-cells = <0>;
+   clock-output-names = "dai-clks";
+
+   clocks = <&clks 201>;
+   clock-names = "mclk";
+
+   dlg,ldo-lvl = <1200>;
+   dlg,micbias-lvl = <2600>;
+   dlg,mic-amp-in-sel = "diff";
+
+

[PATCH v1 16/43] sound: Add an ACPI driver for Maxim MAX98357ac

2020-06-14 Thread Simon Glass
This chip is used on coral and we need to generate ACPI tables for sound
to make it work. Add a driver that does just this (i.e. at present does
not actually support playing sound).

Signed-off-by: Simon Glass 
---

Changes in v1:
- Use acpi,ddn instead of acpi,desc
- Drop the unwanted acpi_device_write_gpio_desc()
- Rename max97357a to max98357a
- Add NHLT support
- Capitalise ACPI_OPS_PTR
- Rebase to master

 configs/sandbox_defconfig|   1 +
 doc/device-tree-bindings/sound/max98357a.txt |  22 +++
 drivers/sound/Kconfig|   9 ++
 drivers/sound/Makefile   |   1 +
 drivers/sound/max98357a.c| 160 +++
 5 files changed, 193 insertions(+)
 create mode 100644 doc/device-tree-bindings/sound/max98357a.txt
 create mode 100644 drivers/sound/max98357a.c

diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
index 6368e278f2..96c6e0fcd5 100644
--- a/configs/sandbox_defconfig
+++ b/configs/sandbox_defconfig
@@ -203,6 +203,7 @@ CONFIG_SMEM=y
 CONFIG_SANDBOX_SMEM=y
 CONFIG_SOUND=y
 CONFIG_SOUND_DA7219=y
+CONFIG_SOUND_MAX98357A=y
 CONFIG_SOUND_SANDBOX=y
 CONFIG_SANDBOX_SPI=y
 CONFIG_SPMI=y
diff --git a/doc/device-tree-bindings/sound/max98357a.txt 
b/doc/device-tree-bindings/sound/max98357a.txt
new file mode 100644
index 00..4bce14ce80
--- /dev/null
+++ b/doc/device-tree-bindings/sound/max98357a.txt
@@ -0,0 +1,22 @@
+Maxim MAX98357A audio DAC
+
+This node models the Maxim MAX98357A DAC.
+
+Required properties:
+- compatible   : "maxim,max98357a"
+
+Optional properties:
+- sdmode-gpios : GPIO specifier for the chip's SD_MODE pin.
+If this option is not specified then driver does not manage
+the pin state (e.g. chip is always on).
+- sdmode-delay : specify delay time for SD_MODE pin.
+If this option is specified, which means it's required i2s clocks
+ready before SD_MODE is unmuted in order to avoid the speaker pop 
noise.
+It's observed that 5ms is sufficient.
+
+Example:
+
+max98357a {
+   compatible = "maxim,max98357a";
+   sdmode-gpios = <&qcom_pinmux 25 0>;
+};
diff --git a/drivers/sound/Kconfig b/drivers/sound/Kconfig
index 7f214b97be..0948d8caab 100644
--- a/drivers/sound/Kconfig
+++ b/drivers/sound/Kconfig
@@ -113,6 +113,15 @@ config SOUND_MAX98095
  audio data and I2C for codec control. At present it only works
  with the Samsung I2S driver.
 
+config SOUND_MAX98357A
+   bool "Support Maxim max98357a audio codec"
+   depends on PCI
+   help
+ Enable the max98357a audio codec. This is connected on PCI for
+ audio data codec control. This is currently only capable of providing
+ ACPI information. A full driver (with sound in U-Boot) is currently
+ not available.
+
 config SOUND_RT5677
bool "Support Realtek RT5677 audio codec"
depends on SOUND
diff --git a/drivers/sound/Makefile b/drivers/sound/Makefile
index 8c3933ad15..9b40c8012f 100644
--- a/drivers/sound/Makefile
+++ b/drivers/sound/Makefile
@@ -17,6 +17,7 @@ obj-$(CONFIG_SOUND_WM8994)+= wm8994.o
 obj-$(CONFIG_SOUND_MAX98088)   += max98088.o maxim_codec.o
 obj-$(CONFIG_SOUND_MAX98090)   += max98090.o maxim_codec.o
 obj-$(CONFIG_SOUND_MAX98095)   += max98095.o maxim_codec.o
+obj-$(CONFIG_SOUND_MAX98357A)  += max98357a.o
 obj-$(CONFIG_SOUND_INTEL_HDA)  += hda_codec.o
 obj-$(CONFIG_SOUND_I8254)  += i8254_beep.o
 obj-$(CONFIG_SOUND_RT5677) += rt5677.o
diff --git a/drivers/sound/max98357a.c b/drivers/sound/max98357a.c
new file mode 100644
index 00..33fdd0ba1e
--- /dev/null
+++ b/drivers/sound/max98357a.c
@@ -0,0 +1,160 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * max98357a.c -- MAX98357A Audio driver
+ *
+ * Copyright 2019 Google LLC
+ * Parts taken from coreboot
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#ifdef CONFIG_X86
+#include 
+#endif
+#include 
+#include 
+
+struct max98357a_priv {
+   struct gpio_desc sdmode_gpio;
+};
+
+static int max98357a_ofdata_to_platdata(struct udevice *dev)
+{
+   struct max98357a_priv *priv = dev_get_priv(dev);
+   int ret;
+
+   ret = gpio_request_by_name(dev, "sdmode-gpios", 0, &priv->sdmode_gpio,
+  GPIOD_IS_IN);
+   if (ret)
+   return log_msg_ret("gpio", ret);
+
+   return 0;
+}
+
+static int max98357a_acpi_fill_ssdt(const struct udevice *dev,
+   struct acpi_ctx *ctx)
+{
+   struct max98357a_priv *priv = dev_get_priv(dev);
+   char scope[ACPI_PATH_MAX];
+   char name[ACPI_NAME_MAX];
+   char path[ACPI_PATH_MAX];
+   struct acpi_dp *dp;
+   int ret;
+
+   ret = acpi_device_scope(dev, scope, sizeof(scope));
+   if (ret)
+   return log_msg_ret("scope", ret);
+   ret = acpi_get_name(dev, name);
+   if (ret)
+   return log_msg_ret("name", ret);
+
+  

[PATCH v1 18/43] x86: pinctrl: Update comment for intel_pinctrl_get_pad()

2020-06-14 Thread Simon Glass
Add information about what is returned on error.

Signed-off-by: Simon Glass 
---

 arch/x86/include/asm/intel_pinctrl.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/x86/include/asm/intel_pinctrl.h 
b/arch/x86/include/asm/intel_pinctrl.h
index f39ebde539..982b2514a0 100644
--- a/arch/x86/include/asm/intel_pinctrl.h
+++ b/arch/x86/include/asm/intel_pinctrl.h
@@ -300,6 +300,7 @@ u32 intel_pinctrl_get_config_reg(struct udevice *dev, uint 
offset);
  * @pad: Pad to check
  * @devp: Returns pinctrl device containing that pad
  * @offsetp: Returns offset of pad within that pinctrl device
+ * @return 0 if OK, -ENOTBLK if pad number is invalid
  */
 int intel_pinctrl_get_pad(uint pad, struct udevice **devp, uint *offsetp);
 
-- 
2.27.0.290.gba653c62da-goog



[PATCH v1 24/43] x86: apl: Use memory-mapped access for VBT

2020-06-14 Thread Simon Glass
Use the new binman memory-mapping function to access the VBT, to simplify
the code.

Signed-off-by: Simon Glass 
---

 arch/x86/cpu/apollolake/fsp_s.c  | 19 +--
 arch/x86/lib/fsp2/fsp_silicon_init.c |  1 +
 2 files changed, 6 insertions(+), 14 deletions(-)

diff --git a/arch/x86/cpu/apollolake/fsp_s.c b/arch/x86/cpu/apollolake/fsp_s.c
index 13e6b20f08..0f5520fc7d 100644
--- a/arch/x86/cpu/apollolake/fsp_s.c
+++ b/arch/x86/cpu/apollolake/fsp_s.c
@@ -36,29 +36,20 @@ int fsps_update_config(struct udevice *dev, ulong 
rom_offset,
ofnode node;
 
if (IS_ENABLED(CONFIG_HAVE_VBT)) {
-   struct binman_entry vbt;
-   void *vbt_buf;
+   void *buf;
int ret;
 
-   ret = binman_entry_find("intel-vbt", &vbt);
+   ret = binman_entry_map(ofnode_null(), "intel-vbt", &buf, NULL);
if (ret)
return log_msg_ret("Cannot find VBT", ret);
-   vbt.image_pos += rom_offset;
-   vbt_buf = malloc(vbt.size);
-   if (!vbt_buf)
-   return log_msg_ret("Alloc VBT", -ENOMEM);
+   if (*(u32 *)buf != VBT_SIGNATURE)
+   return log_msg_ret("VBT signature", -EINVAL);
 
/*
 * Load VBT before devicetree-specific config. This only
 * supports memory-mapped SPI at present.
 */
-   bootstage_start(BOOTSTAGE_ID_ACCUM_MMAP_SPI, "mmap_spi");
-   memcpy(vbt_buf, (void *)vbt.image_pos, vbt.size);
-   bootstage_accum(BOOTSTAGE_ID_ACCUM_MMAP_SPI);
-   if (*(u32 *)vbt_buf != VBT_SIGNATURE)
-   return log_msg_ret("VBT signature", -EINVAL);
-
-   cfg->graphics_config_ptr = (ulong)vbt_buf;
+   cfg->graphics_config_ptr = (ulong)buf;
}
 
node = dev_read_subnode(dev, "fsp-s");
diff --git a/arch/x86/lib/fsp2/fsp_silicon_init.c 
b/arch/x86/lib/fsp2/fsp_silicon_init.c
index 45c0c7d90b..0f221a864f 100644
--- a/arch/x86/lib/fsp2/fsp_silicon_init.c
+++ b/arch/x86/lib/fsp2/fsp_silicon_init.c
@@ -32,6 +32,7 @@ int fsp_silicon_init(bool s3wake, bool use_spi_flash)
 &rom_offset);
if (ret)
return log_msg_ret("locate FSP", ret);
+   binman_set_rom_offset(rom_offset);
gd->arch.fsp_s_hdr = hdr;
 
/* Copy over the default config */
-- 
2.27.0.290.gba653c62da-goog



[PATCH v1 20/43] x86: pinctrl: Set up itss in the probe() method

2020-06-14 Thread Simon Glass
At present the itss is probed in the ofdata_to_platdata() method. This is
incorrect since itss is a child of p2sb which itself needs to probe the
pinctrl device. This means that p2sb is effectively not probed when the
itss is probed, so we get the wrong register address from p2sb.

Fix this by moving the itss probe to the correct place.

Signed-off-by: Simon Glass 
---

 drivers/pinctrl/intel/pinctrl.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/pinctrl/intel/pinctrl.c b/drivers/pinctrl/intel/pinctrl.c
index 32ca303b27..ba21c9dcc2 100644
--- a/drivers/pinctrl/intel/pinctrl.c
+++ b/drivers/pinctrl/intel/pinctrl.c
@@ -619,15 +619,11 @@ int intel_pinctrl_ofdata_to_platdata(struct udevice *dev,
 {
struct p2sb_child_platdata *pplat = dev_get_parent_platdata(dev);
struct intel_pinctrl_priv *priv = dev_get_priv(dev);
-   int ret;
 
if (!comm) {
log_err("Cannot find community for pid %d\n", pplat->pid);
return -EDOM;
}
-   ret = irq_first_device_type(X86_IRQT_ITSS, &priv->itss);
-   if (ret)
-   return log_msg_ret("Cannot find ITSS", ret);
priv->comm = comm;
priv->num_cfgs = num_cfgs;
 
@@ -637,8 +633,12 @@ int intel_pinctrl_ofdata_to_platdata(struct udevice *dev,
 int intel_pinctrl_probe(struct udevice *dev)
 {
struct intel_pinctrl_priv *priv = dev_get_priv(dev);
+   int ret;
 
priv->itss_pol_cfg = true;
+   ret = irq_first_device_type(X86_IRQT_ITSS, &priv->itss);
+   if (ret)
+   return log_msg_ret("Cannot find ITSS", ret);
 
return 0;
 }
-- 
2.27.0.290.gba653c62da-goog



[PATCH v1 17/43] x86: pinctrl: Add a way to get the pinctrl reg address

2020-06-14 Thread Simon Glass
At present we can query the offset of a pinctrl register within the p2sb.
For ACPI we need to get the actual address of the register. Add a function
to handle this and rename the old one to more accurately reflect its
purpose.

Signed-off-by: Simon Glass 
---

 arch/x86/include/asm/intel_pinctrl.h | 16 ++--
 drivers/gpio/intel_gpio.c| 15 +++
 drivers/misc/p2sb-uclass.c   | 16 
 drivers/pinctrl/intel/pinctrl.c  | 11 +--
 include/p2sb.h   |  9 +
 5 files changed, 51 insertions(+), 16 deletions(-)

diff --git a/arch/x86/include/asm/intel_pinctrl.h 
b/arch/x86/include/asm/intel_pinctrl.h
index e2524b089d..f39ebde539 100644
--- a/arch/x86/include/asm/intel_pinctrl.h
+++ b/arch/x86/include/asm/intel_pinctrl.h
@@ -263,11 +263,23 @@ int pinctrl_read_pads(struct udevice *dev, ofnode node, 
const char *prop,
 int pinctrl_count_pads(struct udevice *dev, u32 *pads, int size);
 
 /**
- * intel_pinctrl_get_config_reg_addr() - Get address of the pin config 
registers
+ * intel_pinctrl_get_config_reg_offset() - Get offset of pin config registers
  *
+ * This works out the register offset of a pin within the p2sb region.
+ *
+ * @dev: Pinctrl device
+ * @offset: GPIO offset within this device
+ * @return register offset of first register within the GPIO p2sb region
+ */
+u32 intel_pinctrl_get_config_reg_offset(struct udevice *dev, uint offset);
+
+/**
+ * intel_pinctrl_get_config_reg_offset() - Get address of pin config registers
+ *
+ * This works out the absolute address of the registers for a pin
  * @dev: Pinctrl device
  * @offset: GPIO offset within this device
- * @return register offset within the GPIO p2sb region
+ * @return register offset of first register within the GPIO p2sb region
  */
 u32 intel_pinctrl_get_config_reg_addr(struct udevice *dev, uint offset);
 
diff --git a/drivers/gpio/intel_gpio.c b/drivers/gpio/intel_gpio.c
index 711fea1b58..b4d5be97da 100644
--- a/drivers/gpio/intel_gpio.c
+++ b/drivers/gpio/intel_gpio.c
@@ -24,7 +24,9 @@
 static int intel_gpio_direction_input(struct udevice *dev, uint offset)
 {
struct udevice *pinctrl = dev_get_parent(dev);
-   uint config_offset = intel_pinctrl_get_config_reg_addr(pinctrl, offset);
+   uint config_offset;
+
+   config_offset = intel_pinctrl_get_config_reg_offset(pinctrl, offset);
 
pcr_clrsetbits32(pinctrl, config_offset,
 PAD_CFG0_MODE_MASK | PAD_CFG0_TX_STATE |
@@ -38,7 +40,9 @@ static int intel_gpio_direction_output(struct udevice *dev, 
uint offset,
   int value)
 {
struct udevice *pinctrl = dev_get_parent(dev);
-   uint config_offset = intel_pinctrl_get_config_reg_addr(pinctrl, offset);
+   uint config_offset;
+
+   config_offset = intel_pinctrl_get_config_reg_offset(pinctrl, offset);
 
pcr_clrsetbits32(pinctrl, config_offset,
 PAD_CFG0_MODE_MASK | PAD_CFG0_RX_STATE |
@@ -68,10 +72,13 @@ static int intel_gpio_get_value(struct udevice *dev, uint 
offset)
return 0;
 }
 
-static int intel_gpio_set_value(struct udevice *dev, unsigned offset, int 
value)
+static int intel_gpio_set_value(struct udevice *dev, unsigned int offset,
+   int value)
 {
struct udevice *pinctrl = dev_get_parent(dev);
-   uint config_offset = intel_pinctrl_get_config_reg_addr(pinctrl, offset);
+   uint config_offset;
+
+   config_offset = intel_pinctrl_get_config_reg_offset(pinctrl, offset);
 
pcr_clrsetbits32(pinctrl, config_offset, PAD_CFG0_TX_STATE,
 value ? PAD_CFG0_TX_STATE : 0);
diff --git a/drivers/misc/p2sb-uclass.c b/drivers/misc/p2sb-uclass.c
index 06b1e8d9ad..d5fe12ebd8 100644
--- a/drivers/misc/p2sb-uclass.c
+++ b/drivers/misc/p2sb-uclass.c
@@ -18,7 +18,7 @@
 
 #define PCR_COMMON_IOSF_1_01
 
-static void *_pcr_reg_address(struct udevice *dev, uint offset)
+void *pcr_reg_address(struct udevice *dev, uint offset)
 {
struct p2sb_child_platdata *pplat = dev_get_parent_platdata(dev);
struct udevice *p2sb = dev_get_parent(dev);
@@ -55,7 +55,7 @@ uint pcr_read32(struct udevice *dev, uint offset)
/* Ensure the PCR offset is correctly aligned */
assert(IS_ALIGNED(offset, sizeof(uint32_t)));
 
-   ptr = _pcr_reg_address(dev, offset);
+   ptr = pcr_reg_address(dev, offset);
val = readl(ptr);
unmap_sysmem(ptr);
 
@@ -67,7 +67,7 @@ uint pcr_read16(struct udevice *dev, uint offset)
/* Ensure the PCR offset is correctly aligned */
check_pcr_offset_align(offset, sizeof(uint16_t));
 
-   return readw(_pcr_reg_address(dev, offset));
+   return readw(pcr_reg_address(dev, offset));
 }
 
 uint pcr_read8(struct udevice *dev, uint offset)
@@ -75,7 +75,7 @@ uint pcr_read8(struct udevice *dev, uint offset)
/* Ensure the PCR offset is correctly aligned */
check_pcr_offset_a

[PATCH v1 23/43] x86: Add error checking for csrt table generation

2020-06-14 Thread Simon Glass
Generation of this table can fail, so update the function to return an
error code.

Signed-off-by: Simon Glass 
---

Changes in v1:
- Add new patch to add error checking for csrt table generation

 arch/x86/lib/acpi_table.c | 19 +--
 1 file changed, 13 insertions(+), 6 deletions(-)

diff --git a/arch/x86/lib/acpi_table.c b/arch/x86/lib/acpi_table.c
index 27869a0e5e..b6ba547b6a 100644
--- a/arch/x86/lib/acpi_table.c
+++ b/arch/x86/lib/acpi_table.c
@@ -212,13 +212,14 @@ static void acpi_create_mcfg(struct acpi_mcfg *mcfg)
 
 __weak u32 acpi_fill_csrt(u32 current)
 {
-   return current;
+   return 0;
 }
 
-static void acpi_create_csrt(struct acpi_csrt *csrt)
+static int acpi_create_csrt(struct acpi_csrt *csrt)
 {
struct acpi_table_header *header = &(csrt->header);
u32 current = (u32)csrt + sizeof(struct acpi_csrt);
+   uint ptr;
 
memset((void *)csrt, 0, sizeof(struct acpi_csrt));
 
@@ -227,11 +228,16 @@ static void acpi_create_csrt(struct acpi_csrt *csrt)
header->length = sizeof(struct acpi_csrt);
header->revision = 0;
 
-   current = acpi_fill_csrt(current);
+   ptr = acpi_fill_csrt(current);
+   if (!ptr)
+   return -ENOENT;
+   current = ptr;
 
/* (Re)calculate length and checksum */
header->length = current - (u32)csrt;
header->checksum = table_compute_checksum((void *)csrt, header->length);
+
+   return 0;
 }
 
 static void acpi_create_spcr(struct acpi_spcr *spcr)
@@ -482,9 +488,10 @@ ulong write_acpi_tables(ulong start_addr)
 
debug("ACPI:* CSRT\n");
csrt = ctx->current;
-   acpi_create_csrt(csrt);
-   acpi_inc_align(ctx, csrt->header.length);
-   acpi_add_table(ctx, csrt);
+   if (!acpi_create_csrt(csrt)) {
+   acpi_inc_align(ctx, csrt->header.length);
+   acpi_add_table(ctx, csrt);
+   }
 
debug("ACPI:* SPCR\n");
spcr = ctx->current;
-- 
2.27.0.290.gba653c62da-goog



[PATCH v1 26/43] i2c: designware_i2c: Add a little more debugging

2020-06-14 Thread Simon Glass
Add debugging for a few more values and also use log to show return values
when something goes wrong. This makes it easier to see the root cause.

Signed-off-by: Simon Glass 
---

Changes in v1:
- Add new patch to improve designware_i2c debugging

 drivers/i2c/designware_i2c.c | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/i2c/designware_i2c.c b/drivers/i2c/designware_i2c.c
index 3616e2105f..44a1f33398 100644
--- a/drivers/i2c/designware_i2c.c
+++ b/drivers/i2c/designware_i2c.c
@@ -160,9 +160,9 @@ static int dw_i2c_calc_timing(struct dw_i2c *priv, enum 
i2c_speed_mode mode,
min_tlow_cnt = calc_counts(ic_clk, info->min_scl_lowtime_ns);
min_thigh_cnt = calc_counts(ic_clk, info->min_scl_hightime_ns);
 
-   debug("dw_i2c: period %d rise %d fall %d tlow %d thigh %d spk %d\n",
- period_cnt, rise_cnt, fall_cnt, min_tlow_cnt, min_thigh_cnt,
- spk_cnt);
+   debug("dw_i2c: mode %d, ic_clk %d, speed %d, period %d rise %d fall %d 
tlow %d thigh %d spk %d\n",
+ mode, ic_clk, info->speed, period_cnt, rise_cnt, fall_cnt,
+ min_tlow_cnt, min_thigh_cnt, spk_cnt);
 
/*
 * Back-solve for hcnt and lcnt according to the following equations:
@@ -174,7 +174,7 @@ static int dw_i2c_calc_timing(struct dw_i2c *priv, enum 
i2c_speed_mode mode,
 
if (hcnt < 0 || lcnt < 0) {
debug("dw_i2c: bad counts. hcnt = %d lcnt = %d\n", hcnt, lcnt);
-   return -EINVAL;
+   return log_msg_ret("counts", -EINVAL);
}
 
/*
@@ -713,7 +713,7 @@ static int designware_i2c_set_bus_speed(struct udevice 
*bus, unsigned int speed)
 #if CONFIG_IS_ENABLED(CLK)
rate = clk_get_rate(&i2c->clk);
if (IS_ERR_VALUE(rate))
-   return -EINVAL;
+   return log_ret(-EINVAL);
 #else
rate = IC_CLK;
 #endif
-- 
2.27.0.290.gba653c62da-goog



[PATCH v1 28/43] i2c: designware_i2c: Support ACPI table generation

2020-06-14 Thread Simon Glass
Update the PCI driver to generate ACPI information so that Linux has the
full information about each I2C bus.

Signed-off-by: Simon Glass 

---

Changes in v1:
- Capitalise ACPI_OPS_PTR

 drivers/i2c/designware_i2c.c |  25 
 drivers/i2c/designware_i2c.h |  15 +
 drivers/i2c/designware_i2c_pci.c | 104 ++-
 3 files changed, 143 insertions(+), 1 deletion(-)

diff --git a/drivers/i2c/designware_i2c.c b/drivers/i2c/designware_i2c.c
index 44a1f33398..630938743f 100644
--- a/drivers/i2c/designware_i2c.c
+++ b/drivers/i2c/designware_i2c.c
@@ -333,6 +333,31 @@ static int _dw_i2c_set_bus_speed(struct dw_i2c *priv, 
struct i2c_regs *i2c_base,
/* Restore back i2c now speed set */
if (ena == IC_ENABLE_0B)
dw_i2c_enable(i2c_base, true);
+   if (priv)
+   priv->config = config;
+   return 0;
+}
+
+int dw_i2c_gen_speed_config(const struct udevice *dev, int speed_hz,
+   struct dw_i2c_speed_config *config)
+{
+   struct dw_i2c *priv = dev_get_priv(dev);
+   ulong rate;
+   int ret;
+
+#if CONFIG_IS_ENABLED(CLK)
+   rate = clk_get_rate(&priv->clk);
+   if (IS_ERR_VALUE(rate))
+   return log_msg_ret("clk", -EINVAL);
+#else
+   rate = IC_CLK;
+#endif
+
+   ret = calc_bus_speed(priv, priv->regs, speed_hz, rate, config);
+   if (ret)
+   printf("%s: ret=%d\n", __func__, ret);
+   if (ret)
+   return log_msg_ret("calc_bus_speed", ret);
 
return 0;
 }
diff --git a/drivers/i2c/designware_i2c.h b/drivers/i2c/designware_i2c.h
index dc9a6ccb63..d87a3bff93 100644
--- a/drivers/i2c/designware_i2c.h
+++ b/drivers/i2c/designware_i2c.h
@@ -205,6 +205,7 @@ struct dw_i2c {
 #if CONFIG_IS_ENABLED(CLK)
struct clk clk;
 #endif
+   struct dw_i2c_speed_config config;
 };
 
 extern const struct dm_i2c_ops designware_i2c_ops;
@@ -213,4 +214,18 @@ int designware_i2c_probe(struct udevice *bus);
 int designware_i2c_remove(struct udevice *dev);
 int designware_i2c_ofdata_to_platdata(struct udevice *bus);
 
+/**
+ * dw_i2c_gen_speed_config() - Calculate config info from requested speed1
+ *
+ * Calculate the speed config from the given @speed_hz and return it so that
+ * it can be incorporated in ACPI tables
+ *
+ * @dev: I2C bus to check
+ * @speed_hz: Requested speed in Hz
+ * @config: Returns config to use for that speed
+ * @return 0 if OK, -ve on error
+ */
+int dw_i2c_gen_speed_config(const struct udevice *dev, int speed_hz,
+   struct dw_i2c_speed_config *config);
+
 #endif /* __DW_I2C_H_ */
diff --git a/drivers/i2c/designware_i2c_pci.c b/drivers/i2c/designware_i2c_pci.c
index bd34ec0b47..d5108e9064 100644
--- a/drivers/i2c/designware_i2c_pci.c
+++ b/drivers/i2c/designware_i2c_pci.c
@@ -9,7 +9,12 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 #include 
+#include 
+#include 
+#include 
 #include "designware_i2c.h"
 
 enum {
@@ -87,6 +92,8 @@ static int designware_i2c_pci_bind(struct udevice *dev)
 {
char name[20];
 
+   if (dev_of_valid(dev))
+   return 0;
/*
 * Create a unique device name for PCI type devices
 * ToDo:
@@ -100,13 +107,107 @@ static int designware_i2c_pci_bind(struct udevice *dev)
 * be possible. We cannot use static data in drivers since they may be
 * used in SPL or before relocation.
 */
-   dev->req_seq = gd->arch.dw_i2c_num_cards++;
+   dev->req_seq = uclass_find_next_free_req_seq(UCLASS_I2C);
sprintf(name, "i2c_designware#%u", dev->req_seq);
device_set_name(dev, name);
 
return 0;
 }
 
+/*
+ * Write ACPI object to describe speed configuration.
+ *
+ * ACPI Object: Name ("", Package () { scl_lcnt, scl_hcnt, sda_hold }
+ *
+ * SSCN: I2C_SPEED_STANDARD
+ * FMCN: I2C_SPEED_FAST
+ * FPCN: I2C_SPEED_FAST_PLUS
+ * HSCN: I2C_SPEED_HIGH
+ */
+static void dw_i2c_acpi_write_speed_config(struct acpi_ctx *ctx,
+  struct dw_i2c_speed_config *config)
+{
+   switch (config->speed_mode) {
+   case IC_SPEED_MODE_HIGH:
+   acpigen_write_name(ctx, "HSCN");
+   break;
+   case IC_SPEED_MODE_FAST_PLUS:
+   acpigen_write_name(ctx, "FPCN");
+   break;
+   case IC_SPEED_MODE_FAST:
+   acpigen_write_name(ctx, "FMCN");
+   break;
+   case IC_SPEED_MODE_STANDARD:
+   default:
+   acpigen_write_name(ctx, "SSCN");
+   }
+
+   /* Package () { scl_lcnt, scl_hcnt, sda_hold } */
+   acpigen_write_package(ctx, 3);
+   acpigen_write_word(ctx, config->scl_hcnt);
+   acpigen_write_word(ctx, config->scl_lcnt);
+   acpigen_write_dword(ctx, config->sda_hold);
+   acpigen_pop_len(ctx);
+}
+
+/*
+ * Generate I2C timing information into the SSDT for the OS driver to consume,
+ * optionally applying override values provided by the caller.
+ */

[PATCH v1 21/43] x86: pinctrl: Drop the acpi_name member

2020-06-14 Thread Simon Glass
This is in the device tree now, so drop the unnecessary field here.

Signed-off-by: Simon Glass 
---

 arch/x86/include/asm/intel_pinctrl.h | 2 --
 drivers/pinctrl/intel/pinctrl_apl.c  | 4 
 2 files changed, 6 deletions(-)

diff --git a/arch/x86/include/asm/intel_pinctrl.h 
b/arch/x86/include/asm/intel_pinctrl.h
index 982b2514a0..e734f4a7f0 100644
--- a/arch/x86/include/asm/intel_pinctrl.h
+++ b/arch/x86/include/asm/intel_pinctrl.h
@@ -99,7 +99,6 @@ struct pad_group {
  * groups exist inside a community
  *
  * @name: Community name
- * @acpi_path: ACPI path
  * @num_gpi_regs: number of gpi registers in community
  * @max_pads_per_group: number of pads in each group; number of pads bit-mapped
  * in each GPI status/en and Host Own Reg
@@ -120,7 +119,6 @@ struct pad_group {
  */
 struct pad_community {
const char *name;
-   const char *acpi_path;
size_t num_gpi_regs;
size_t max_pads_per_group;
uint first_pad;
diff --git a/drivers/pinctrl/intel/pinctrl_apl.c 
b/drivers/pinctrl/intel/pinctrl_apl.c
index c14176d4a7..7624a9974f 100644
--- a/drivers/pinctrl/intel/pinctrl_apl.c
+++ b/drivers/pinctrl/intel/pinctrl_apl.c
@@ -75,7 +75,6 @@ static const struct pad_community apl_gpio_communities[] = {
.gpi_smi_en_reg_0 = GPI_SMI_EN_0,
.max_pads_per_group = GPIO_MAX_NUM_PER_GROUP,
.name = "GPIO_GPE_N",
-   .acpi_path = "\\_SB.GPO0",
.reset_map = rst_map,
.num_reset_vals = ARRAY_SIZE(rst_map),
.groups = apl_community_n_groups,
@@ -94,7 +93,6 @@ static const struct pad_community apl_gpio_communities[] = {
.gpi_smi_en_reg_0 = GPI_SMI_EN_0,
.max_pads_per_group = GPIO_MAX_NUM_PER_GROUP,
.name = "GPIO_GPE_NW",
-   .acpi_path = "\\_SB.GPO1",
.reset_map = rst_map,
.num_reset_vals = ARRAY_SIZE(rst_map),
.groups = apl_community_nw_groups,
@@ -113,7 +111,6 @@ static const struct pad_community apl_gpio_communities[] = {
.gpi_smi_en_reg_0 = GPI_SMI_EN_0,
.max_pads_per_group = GPIO_MAX_NUM_PER_GROUP,
.name = "GPIO_GPE_W",
-   .acpi_path = "\\_SB.GPO2",
.reset_map = rst_map,
.num_reset_vals = ARRAY_SIZE(rst_map),
.groups = apl_community_w_groups,
@@ -132,7 +129,6 @@ static const struct pad_community apl_gpio_communities[] = {
.gpi_smi_en_reg_0 = GPI_SMI_EN_0,
.max_pads_per_group = GPIO_MAX_NUM_PER_GROUP,
.name = "GPIO_GPE_SW",
-   .acpi_path = "\\_SB.GPO3",
.reset_map = rst_map,
.num_reset_vals = ARRAY_SIZE(rst_map),
.groups = apl_community_sw_groups,
-- 
2.27.0.290.gba653c62da-goog



[PATCH v1 22/43] x86: Add support for building up an NHLT structure

2020-06-14 Thread Simon Glass
The Intel Non-High-Definition-Audio Link Table (NHLT) table describes the
audio codecs and connections in a system. Various devices can contribute
information to produce the table.

Add functions to allow adding to the structure that is eventually written
to the ACPI tables. Also add the device-tree bindings.

Signed-off-by: Simon Glass 
---

Changes in v1:
- Add a new patch to support building up an NHLT structure

 arch/x86/include/asm/acpi_nhlt.h | 314 
 arch/x86/lib/Makefile|   1 +
 arch/x86/lib/acpi_nhlt.c | 482 +++
 3 files changed, 797 insertions(+)
 create mode 100644 arch/x86/include/asm/acpi_nhlt.h
 create mode 100644 arch/x86/lib/acpi_nhlt.c

diff --git a/arch/x86/include/asm/acpi_nhlt.h b/arch/x86/include/asm/acpi_nhlt.h
new file mode 100644
index 00..4d2573d5ff
--- /dev/null
+++ b/arch/x86/include/asm/acpi_nhlt.h
@@ -0,0 +1,314 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2020 Google LLC
+ *
+ * Modified from coreboot nhlt.h
+ */
+
+#ifndef _NHLT_H_
+#define _NHLT_H_
+
+struct acpi_ctx;
+struct nhlt;
+struct nhlt_endpoint;
+struct nhlt_format;
+struct nhlt_format_config;
+
+/*
+ * Non HD Audio ACPI support. This table is typically used for Intel Smart
+ * Sound Technology DSP. It provides a way to encode opaque settings in
+ * the ACPI tables.
+ *
+ * While the structure fields of the NHLT structs are exposed below
+ * the SoC/chipset code should be the only other user manipulating the
+ * fields directly aside from the library itself.
+ *
+ * The NHLT table consists of endpoints which in turn contain different
+ * supporting stream formats. Each endpoint may contain a device specific
+ * configuration payload as well as each stream format.
+ *
+ * Most code should use the SoC variants of the functions because
+ * there is required logic needed to be performed by the SoC. The SoC
+ * code should be abstracting the inner details of these functions that
+ * specically apply to NHLT objects for that SoC.
+ *
+ * An example sequence:
+ *
+ * nhlt = nhlt_init()
+ * ep = nhlt_add_endpoint()
+ * nhlt_endpoint_append_config(ep)
+ * nhlt_endpoint_add_formats(ep)
+ * nhlt_soc_serialise()
+ */
+
+/* Obtain an nhlt object for adding endpoints. Returns NULL on error. */
+struct nhlt *nhlt_init(void);
+
+/* Return the size of the NHLT table including ACPI header. */
+size_t nhlt_current_size(struct nhlt *nhlt);
+
+/*
+ * Helper functions for adding NHLT devices utilizing an nhlt_endp_descriptor
+ * to drive the logic.
+ */
+
+struct nhlt_endp_descriptor {
+   /* NHLT endpoint types. */
+   int link;
+   int device;
+   int direction;
+   u16 vid;
+   u16 did;
+   /* Optional endpoint specific configuration data. */
+   const void *cfg;
+   size_t cfg_size;
+   /* Formats supported for endpoint. */
+   const struct nhlt_format_config *formats;
+   size_t num_formats;
+};
+
+/*
+ * Add the number of endpoints described by each descriptor. The virtual bus
+ * id for each descriptor is the default value of 0.
+ * Returns < 0 on error, 0 on success.
+ */
+int nhlt_add_endpoints(struct nhlt *nhlt,
+  const struct nhlt_endp_descriptor *epds,
+  size_t num_epds);
+
+/*
+ * Add the number of endpoints associated with a single NHLT SSP instance id.
+ * Each endpoint described in the endpoint descriptor array uses the provided
+ * virtual bus id. Returns < 0 on error, 0 on success.
+ */
+int nhlt_add_ssp_endpoints(struct nhlt *nhlt, int virtual_bus_id,
+  const struct nhlt_endp_descriptor *epds,
+  size_t num_epds);
+
+/*
+ * Add endpoint to NHLT object. Returns NULL on error.
+ *
+ * generic nhlt_add_endpoint() is called by the SoC code to provide
+ * the specific assumptions/uses for NHLT for that platform. All fields
+ * are the NHLT enumerations found within this header file.
+ */
+struct nhlt_endpoint *nhlt_add_endpoint(struct nhlt *nhlt, int link_type,
+   int device_type, int dir,
+   u16 vid, u16 did);
+
+/*
+ * Append blob of configuration to the endpoint proper. Returns 0 on
+ * success, < 0 on error. A copy of the configuration is made so any
+ * resources pointed to by config can be freed after the call.
+ */
+int nhlt_endpoint_append_config(struct nhlt_endpoint *endpoint,
+   const void *config, size_t config_sz);
+
+/* Add a format type to the provided endpoint. Returns NULL on error. */
+struct nhlt_format *nhlt_add_format(struct nhlt_endpoint *endpoint,
+   int num_channels, int sample_freq_khz,
+   int container_bits_per_sample,
+   int valid_bits_per_sample,
+   u32 speaker_mask);
+
+/*
+ * Append blob of configuration to the format proper. Returns 0 o

[PATCH v1 25/43] x86: gpio: Add support for obtaining ACPI info for a GPIO

2020-06-14 Thread Simon Glass
Implement the method that converts a GPIO into the form used by ACPI, so
that GPIOs can be added to ACPI tables.

Signed-off-by: Simon Glass 
---

Changes in v1:
- Use acpi_get_path() to get device path

 drivers/gpio/intel_gpio.c | 34 ++
 1 file changed, 34 insertions(+)

diff --git a/drivers/gpio/intel_gpio.c b/drivers/gpio/intel_gpio.c
index b4d5be97da..6a3a8c4cfa 100644
--- a/drivers/gpio/intel_gpio.c
+++ b/drivers/gpio/intel_gpio.c
@@ -12,6 +12,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -19,6 +20,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 static int intel_gpio_direction_input(struct udevice *dev, uint offset)
@@ -128,6 +130,35 @@ static int intel_gpio_xlate(struct udevice *orig_dev, 
struct gpio_desc *desc,
return 0;
 }
 
+#if CONFIG_IS_ENABLED(ACPIGEN)
+static int intel_gpio_get_acpi(const struct gpio_desc *desc,
+  struct acpi_gpio *gpio)
+{
+   struct udevice *pinctrl;
+   int ret;
+
+   if (!dm_gpio_is_valid(desc))
+   return -ENOENT;
+   pinctrl = dev_get_parent(desc->dev);
+
+   memset(gpio, '\0', sizeof(*gpio));
+
+   gpio->type = ACPI_GPIO_TYPE_IO;
+   gpio->pull = ACPI_GPIO_PULL_DEFAULT;
+   gpio->io_restrict = ACPI_GPIO_IO_RESTRICT_OUTPUT;
+   gpio->polarity = ACPI_GPIO_ACTIVE_HIGH;
+   gpio->pin_count = 1;
+   gpio->pins[0] = intel_pinctrl_get_acpi_pin(pinctrl, desc->offset);
+   gpio->pin0_addr = intel_pinctrl_get_config_reg_addr(pinctrl,
+   desc->offset);
+   ret = acpi_get_path(pinctrl, gpio->resource, sizeof(gpio->resource));
+   if (ret)
+   return log_msg_ret("resource", ret);
+
+   return 0;
+}
+#endif
+
 static int intel_gpio_probe(struct udevice *dev)
 {
return 0;
@@ -152,6 +183,9 @@ static const struct dm_gpio_ops gpio_intel_ops = {
.set_value  = intel_gpio_set_value,
.get_function   = intel_gpio_get_function,
.xlate  = intel_gpio_xlate,
+#if CONFIG_IS_ENABLED(ACPIGEN)
+   .get_acpi   = intel_gpio_get_acpi,
+#endif
 };
 
 static const struct udevice_id intel_intel_gpio_ids[] = {
-- 
2.27.0.290.gba653c62da-goog



[PATCH v1 27/43] i2c: Add log_ret() on error

2020-06-14 Thread Simon Glass
Add a few of these calls to make it easier to see where an error occurs,
if CONFIG_LOG_ERROR_RETURN is enabled.

Signed-off-by: Simon Glass 
---

 drivers/i2c/i2c-uclass.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/i2c/i2c-uclass.c b/drivers/i2c/i2c-uclass.c
index 8bc69e870f..2373aa2ea4 100644
--- a/drivers/i2c/i2c-uclass.c
+++ b/drivers/i2c/i2c-uclass.c
@@ -458,7 +458,7 @@ int i2c_set_chip_offset_len(struct udevice *dev, uint 
offset_len)
struct dm_i2c_chip *chip = dev_get_parent_platdata(dev);
 
if (offset_len > I2C_MAX_OFFSET_LEN)
-   return -EINVAL;
+   return log_ret(-EINVAL);
chip->offset_len = offset_len;
 
return 0;
@@ -625,7 +625,7 @@ int i2c_chip_ofdata_to_platdata(struct udevice *dev, struct 
dm_i2c_chip *chip)
if (addr == -1) {
debug("%s: I2C Node '%s' has no 'reg' property %s\n", __func__,
  dev_read_name(dev), dev->name);
-   return -EINVAL;
+   return log_ret(-EINVAL);
}
chip->chip_addr = addr;
 
-- 
2.27.0.290.gba653c62da-goog



[PATCH v1 31/43] x86: apl: Hide the p2sb on exit from U-Boot

2020-06-14 Thread Simon Glass
This confuses Linux's PCI probing so needs to be hidden when booting
Linux. Add a remove() method to handle this.

Signed-off-by: Simon Glass 
---

 arch/x86/cpu/intel_common/p2sb.c | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/arch/x86/cpu/intel_common/p2sb.c b/arch/x86/cpu/intel_common/p2sb.c
index ebf8f62aea..361d4c90cb 100644
--- a/arch/x86/cpu/intel_common/p2sb.c
+++ b/arch/x86/cpu/intel_common/p2sb.c
@@ -153,6 +153,17 @@ static int intel_p2sb_set_hide(struct udevice *dev, bool 
hide)
return 0;
 }
 
+static int p2sb_remove(struct udevice *dev)
+{
+   int ret;
+
+   ret = intel_p2sb_set_hide(dev, true);
+   if (ret)
+   return log_msg_ret("hide", ret);
+
+   return 0;
+}
+
 static int p2sb_child_post_bind(struct udevice *dev)
 {
 #if !CONFIG_IS_ENABLED(OF_PLATDATA)
@@ -183,9 +194,12 @@ U_BOOT_DRIVER(p2sb_drv) = {
.id = UCLASS_P2SB,
.of_match   = p2sb_ids,
.probe  = p2sb_probe,
+   .remove = p2sb_remove,
+   .ops= &p2sb_ops,
.ofdata_to_platdata = p2sb_ofdata_to_platdata,
.platdata_auto_alloc_size = sizeof(struct p2sb_platdata),
.per_child_platdata_auto_alloc_size =
sizeof(struct p2sb_child_platdata),
.child_post_bind = p2sb_child_post_bind,
+   .flags  = DM_FLAG_OS_PREPARE,
 };
-- 
2.27.0.290.gba653c62da-goog



[PATCH v1 30/43] x86: apl: Support set_hide() in p2sb driver

2020-06-14 Thread Simon Glass
Add support for this new method in the driver and in the fsp-s setup.

Signed-off-by: Simon Glass 
---

 arch/x86/cpu/apollolake/fsp_s.c  | 26 +++---
 arch/x86/cpu/intel_common/p2sb.c | 30 ++
 2 files changed, 41 insertions(+), 15 deletions(-)

diff --git a/arch/x86/cpu/apollolake/fsp_s.c b/arch/x86/cpu/apollolake/fsp_s.c
index 0f5520fc7d..3a54297a28 100644
--- a/arch/x86/cpu/apollolake/fsp_s.c
+++ b/arch/x86/cpu/apollolake/fsp_s.c
@@ -12,6 +12,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -21,10 +22,11 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
+#include 
 #include 
-#include 
 
 #define PCH_P2SB_E00xe0
 #define HIDE_BIT   BIT(0)
@@ -59,12 +61,6 @@ int fsps_update_config(struct udevice *dev, ulong rom_offset,
return fsp_s_update_config_from_dtb(node, cfg);
 }
 
-static void p2sb_set_hide_bit(pci_dev_t dev, int hide)
-{
-   pci_x86_clrset_config(dev, PCH_P2SB_E0 + 1, HIDE_BIT,
- hide ? HIDE_BIT : 0, PCI_SIZE_8);
-}
-
 /* Configure package power limits */
 static int set_power_limits(struct udevice *dev)
 {
@@ -137,15 +133,15 @@ static int set_power_limits(struct udevice *dev)
 
 int p2sb_unhide(void)
 {
-   pci_dev_t dev = PCI_BDF(0, 0xd, 0);
-   ulong val;
-
-   p2sb_set_hide_bit(dev, 0);
-
-   pci_x86_read_config(dev, PCI_VENDOR_ID, &val, PCI_SIZE_16);
+   struct udevice *dev;
+   int ret;
 
-   if (val != PCI_VENDOR_ID_INTEL)
-   return log_msg_ret("p2sb unhide", -EIO);
+   ret = uclass_find_first_device(UCLASS_P2SB, &dev);
+   if (ret)
+   return log_msg_ret("p2sb", ret);
+   ret = p2sb_set_hide(dev, false);
+   if (ret)
+   return log_msg_ret("hide", ret);
 
return 0;
 }
diff --git a/arch/x86/cpu/intel_common/p2sb.c b/arch/x86/cpu/intel_common/p2sb.c
index ec35d04ae5..ebf8f62aea 100644
--- a/arch/x86/cpu/intel_common/p2sb.c
+++ b/arch/x86/cpu/intel_common/p2sb.c
@@ -16,6 +16,9 @@
 #include 
 #include 
 
+#define PCH_P2SB_E00xe0
+#define HIDE_BIT   BIT(0)
+
 struct p2sb_platdata {
 #if CONFIG_IS_ENABLED(OF_PLATDATA)
struct dtd_intel_p2sb dtplat;
@@ -127,6 +130,29 @@ static int p2sb_probe(struct udevice *dev)
return 0;
 }
 
+static void p2sb_set_hide_bit(struct udevice *dev, bool hide)
+{
+   dm_pci_clrset_config8(dev, PCH_P2SB_E0 + 1, HIDE_BIT,
+ hide ? HIDE_BIT : 0);
+}
+
+static int intel_p2sb_set_hide(struct udevice *dev, bool hide)
+{
+   u16 vendor;
+
+   if (!CONFIG_IS_ENABLED(PCI))
+   return -EPERM;
+   p2sb_set_hide_bit(dev, hide);
+
+   dm_pci_read_config16(dev, PCI_VENDOR_ID, &vendor);
+   if (hide && vendor != 0x)
+   return log_msg_ret("hide", -EEXIST);
+   else if (!hide && vendor != PCI_VENDOR_ID_INTEL)
+   return log_msg_ret("unhide", -ENOMEDIUM);
+
+   return 0;
+}
+
 static int p2sb_child_post_bind(struct udevice *dev)
 {
 #if !CONFIG_IS_ENABLED(OF_PLATDATA)
@@ -143,6 +169,10 @@ static int p2sb_child_post_bind(struct udevice *dev)
return 0;
 }
 
+struct p2sb_ops p2sb_ops = {
+   .set_hide   = intel_p2sb_set_hide,
+};
+
 static const struct udevice_id p2sb_ids[] = {
{ .compatible = "intel,p2sb" },
{ }
-- 
2.27.0.290.gba653c62da-goog



[PATCH v1 32/43] pmc: Move common registers to the header file

2020-06-14 Thread Simon Glass
These registers need to be accesses from ACPI code, so move them to the
header file.

Signed-off-by: Simon Glass 
---

 drivers/power/acpi_pmc/acpi-pmc-uclass.c |  9 -
 include/power/acpi_pmc.h | 14 ++
 2 files changed, 14 insertions(+), 9 deletions(-)

diff --git a/drivers/power/acpi_pmc/acpi-pmc-uclass.c 
b/drivers/power/acpi_pmc/acpi-pmc-uclass.c
index 1c79f835c6..828963d8a0 100644
--- a/drivers/power/acpi_pmc/acpi-pmc-uclass.c
+++ b/drivers/power/acpi_pmc/acpi-pmc-uclass.c
@@ -15,15 +15,6 @@
 #include 
 #include 
 
-enum {
-   PM1_STS = 0x00,
-   PM1_EN  = 0x02,
-   PM1_CNT = 0x04,
-
-   GPE0_STS= 0x20,
-   GPE0_EN = 0x30,
-};
-
 struct tco_regs {
u32 tco_rld;
u32 tco_sts;
diff --git a/include/power/acpi_pmc.h b/include/power/acpi_pmc.h
index 1f50c23f5f..5fbf745136 100644
--- a/include/power/acpi_pmc.h
+++ b/include/power/acpi_pmc.h
@@ -6,10 +6,22 @@
 #ifndef __ACPI_PMC_H
 #define __ACPI_PMC_H
 
+#ifndef __ACPI__
+
 enum {
GPE0_REG_MAX= 4,
 };
 
+enum {
+   PM1_STS = 0x00,
+   PM1_EN  = 0x02,
+   PM1_CNT = 0x04,
+   PM1_TMR = 0x08,
+
+   GPE0_STS= 0x20,
+   GPE0_EN = 0x30,
+};
+
 /**
  * struct acpi_pmc_upriv - holds common data for the x86 PMC
  *
@@ -182,4 +194,6 @@ void pmc_dump_info(struct udevice *dev);
  */
 int pmc_gpe_init(struct udevice *dev);
 
+#endif /* !__ACPI__ */
+
 #endif
-- 
2.27.0.290.gba653c62da-goog



[PATCH v1 29/43] p2sb: Add a method to hide the bus

2020-06-14 Thread Simon Glass
The P2SB bus needs to be hidden in some cases so that it does not get
auto-configured by Linux. Add a method for this.

Signed-off-by: Simon Glass 
---

 drivers/misc/p2sb-uclass.c | 10 ++
 include/p2sb.h | 25 -
 2 files changed, 34 insertions(+), 1 deletion(-)

diff --git a/drivers/misc/p2sb-uclass.c b/drivers/misc/p2sb-uclass.c
index d5fe12ebd8..b5219df46b 100644
--- a/drivers/misc/p2sb-uclass.c
+++ b/drivers/misc/p2sb-uclass.c
@@ -18,6 +18,16 @@
 
 #define PCR_COMMON_IOSF_1_01
 
+int p2sb_set_hide(struct udevice *dev, bool hide)
+{
+   struct p2sb_ops *ops = p2sb_get_ops(dev);
+
+   if (!ops->set_hide)
+   return -ENOSYS;
+
+   return ops->set_hide(dev, hide);
+}
+
 void *pcr_reg_address(struct udevice *dev, uint offset)
 {
struct p2sb_child_platdata *pplat = dev_get_parent_platdata(dev);
diff --git a/include/p2sb.h b/include/p2sb.h
index 74eb08b7ff..93e1155dca 100644
--- a/include/p2sb.h
+++ b/include/p2sb.h
@@ -31,13 +31,36 @@ struct p2sb_uc_priv {
 };
 
 /**
- * struct p2sb_ops - Operations for the P2SB (none at present)
+ * struct p2sb_ops - Operations for the P2SB
  */
 struct p2sb_ops {
+   /**
+* set_hide() - Set/clear the 'hide' bit on the p2sb
+*
+* This device can be hidden from the PCI bus if needed. This method
+* can be called before the p2sb is probed.
+*
+* @dev: P2SB device
+* @hide: true to hide the device, false to show it
+* @return 0 if OK, -ve on error
+*/
+   int (*set_hide)(struct udevice *dev, bool hide);
 };
 
 #define p2sb_get_ops(dev)((struct p2sb_ops *)(dev)->driver->ops)
 
+/**
+ * p2sb_set_hide() - Set/clear the 'hide' bit on the p2sb
+ *
+ * This device can be hidden from the PCI bus if needed. This method
+ * can be called before the p2sb is probed.
+ *
+ * @dev: P2SB device
+ * @hide: true to hide the device, false to show it
+ * @return 0 if OK, -ve on error
+ */
+int p2sb_set_hide(struct udevice *dev, bool hide);
+
 /**
  * pcr_read32/16/8() - Read from a PCR device
  *
-- 
2.27.0.290.gba653c62da-goog



  1   2   >