mail archive of the barebox mailing list
 help / color / mirror / Atom feed
* [PATCH v2 00/12] ARM: i.MX8MQ and EVK support, part II
@ 2018-07-20  1:03 Andrey Smirnov
  2018-07-20  1:03 ` [PATCH v2 01/12] ARM: nxp-imx8mq-evk: Update DDR initialization code Andrey Smirnov
                   ` (12 more replies)
  0 siblings, 13 replies; 14+ messages in thread
From: Andrey Smirnov @ 2018-07-20  1:03 UTC (permalink / raw)
  To: barebox; +Cc: Andrey Smirnov

Everyone:

This is part II of i.MX8MQ EVK board support patches. This time this
is bits and pieces that were necessary in order to allow booting
vendor Linux kernel availible here (tag: rel_imx_4.9.51_8mq_ga):

    https://source.codeaurora.org/external/imx/linux-imx

Sources for ATF were taken from here (tag: rel_imx_4.9.51_8mq_ga):

    https://source.codeaurora.org/external/imx/imx-atf

This patchest is also availible at:

    https://github.com/ndreys/barebox/tree/imx8m-support-part-II-v2

Feedback is welcome!

Changes since [v1]:

    - Opcode patching is replaced with placing barebox image at the
      right spot

    - ATF loading code is converted into a function (was a macro
      originally)

    - It is now up to the user to check current EL when calling
      imx8mq_atf_load_bl31()

    - Other various small change as per Sascha's feedback

[v1] http://lists.infradead.org/pipermail/barebox/2018-June/033922.html

Thanks,
Andrey Smirnov

Andrey Smirnov (12):
  ARM: nxp-imx8mq-evk: Update DDR initialization code
  ARM: Add code to support SMCCC on AArch64
  ARM: i.MX8MQ: Configure cntfrq only in EL3
  ARM: i.MX8MQ: Add code to load BL31 ATF blob
  ARM: i.MX: fimware: Add pre-built BL31 ATF blob
  ARM: i.MX: Move i.MX header definitions to mach-imx
  ARM: i.MX: xload-esdhc: Make use of <mach/imx-header.h>
  ARM: i.MX: xload-esdhc: Allow placing image to align its etnry point
  ARM: nxp-imx8mq-evk: Add code to load ATF BL31 blob
  ARM: i.MX8MQ: Query and display ATF fimware hash if availible
  ARM: nxp-imx8mq-evk: Add bootflow comments
  firmware: Fix copy-paste comment mistake

 arch/arm/Kconfig                              |   4 +
 arch/arm/boards/nxp-imx8mq-evk/ddr_init.c     | 120 +++++-----
 arch/arm/boards/nxp-imx8mq-evk/ddrphy_train.c | 219 +++++-------------
 arch/arm/boards/nxp-imx8mq-evk/lowlevel.c     |  50 +++-
 arch/arm/cpu/Makefile                         |   4 +-
 arch/arm/cpu/smccc-call_64.S                  |  52 +++++
 arch/arm/include/asm/asm-offsets.h            |   1 +
 arch/arm/lib/asm-offsets.c                    |   7 +-
 arch/arm/mach-imx/Kconfig                     |   2 +
 arch/arm/mach-imx/Makefile                    |   2 +-
 arch/arm/mach-imx/atf.c                       |  41 ++++
 arch/arm/mach-imx/imx8mq.c                    |  29 ++-
 arch/arm/mach-imx/include/mach/atf.h          |  13 ++
 arch/arm/mach-imx/include/mach/imx-header.h   | 128 ++++++++++
 arch/arm/mach-imx/xload-esdhc.c               |  51 +++-
 firmware/Kconfig                              |   3 +
 firmware/Makefile                             |   6 +-
 firmware/imx/imx8m-bl31.bin                   | Bin 0 -> 46744 bytes
 include/linux/arm-smccc.h                     | 135 +++++++++++
 scripts/imx/imx.h                             | 114 +--------
 20 files changed, 631 insertions(+), 350 deletions(-)
 create mode 100644 arch/arm/cpu/smccc-call_64.S
 create mode 100644 arch/arm/include/asm/asm-offsets.h
 create mode 100644 arch/arm/mach-imx/atf.c
 create mode 100644 arch/arm/mach-imx/include/mach/atf.h
 create mode 100644 arch/arm/mach-imx/include/mach/imx-header.h
 create mode 100755 firmware/imx/imx8m-bl31.bin
 create mode 100644 include/linux/arm-smccc.h

-- 
2.17.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH v2 01/12] ARM: nxp-imx8mq-evk: Update DDR initialization code
  2018-07-20  1:03 [PATCH v2 00/12] ARM: i.MX8MQ and EVK support, part II Andrey Smirnov
@ 2018-07-20  1:03 ` Andrey Smirnov
  2018-07-20  1:03 ` [PATCH v2 02/12] ARM: Add code to support SMCCC on AArch64 Andrey Smirnov
                   ` (11 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: Andrey Smirnov @ 2018-07-20  1:03 UTC (permalink / raw)
  To: barebox; +Cc: Andrey Smirnov

Previous version of DDR initialization code was generated by a beta
version of MX8_DDR_tool. This updates the code to the output of
MX8_DDR_tool v1.0, which seem to fix the vendor Linux kernel hang*
that was happening with the previous version.

* The kernel would hang as soon as it tried to utilize DDR's DVFS
  features and switch DDR frequency (disabling busfreq-imx8mq.c would
  fix the problem).

Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
 arch/arm/boards/nxp-imx8mq-evk/ddr_init.c     | 120 +++++-----
 arch/arm/boards/nxp-imx8mq-evk/ddrphy_train.c | 219 +++++-------------
 2 files changed, 125 insertions(+), 214 deletions(-)

diff --git a/arch/arm/boards/nxp-imx8mq-evk/ddr_init.c b/arch/arm/boards/nxp-imx8mq-evk/ddr_init.c
index 81691b2fa..44103b5e2 100644
--- a/arch/arm/boards/nxp-imx8mq-evk/ddr_init.c
+++ b/arch/arm/boards/nxp-imx8mq-evk/ddr_init.c
@@ -2,7 +2,8 @@
  * Copyright 2017 NXP
  *
  * SPDX-License-Identifier:	GPL-2.0+
- * Generated code from MX8_DDR_tool
+ *
+ * Generated code from MX8M_DDR_tool
  */
 
 #include "ddr.h"
@@ -21,7 +22,7 @@ void ddr_init(void)
 	reg32_write(0x303a00f8,tmp);
 	reg32_write(0x30391000,0x8f000000);
 	reg32_write(0x30391004,0x8f000000);
-	reg32_write(0x30360068,0xbbe580);
+	reg32_write(0x30360068,0xece580);
 	tmp=reg32_read(0x30360060);
 	tmp &= ~0x80;
 	reg32_write(0x30360060,tmp);
@@ -41,18 +42,19 @@ void ddr_init(void)
 	reg32_write(0x30391000,0x8f000006);
 	reg32_write(0x3d400304,0x1);
 	reg32_write(0x3d400030,0x1);
-	reg32_write(0x3d400000,0x83080020);
+	reg32_write(0x3d400000,0xa3080020);
+	reg32_write(0x3d400028,0x0);
+	reg32_write(0x3d400020,0x203);
+	reg32_write(0x3d400024,0x186a000);
 	reg32_write(0x3d400064,0x6100e0);
 	reg32_write(0x3d4000d0,0xc003061c);
 	reg32_write(0x3d4000d4,0x9e0000);
 	reg32_write(0x3d4000dc,0xd4002d);
 	reg32_write(0x3d4000e0,0x310008);
-	reg32_write(0x3d4000e8,0x46004d);
-	reg32_write(0x3d4000ec,0x15004d);
-	reg32_write(0x3d4000f4,0x639);
+	reg32_write(0x3d4000e8,0x66004a);
+	reg32_write(0x3d4000ec,0x16004a);
 	reg32_write(0x3d400100,0x1a201b22);
 	reg32_write(0x3d400104,0x60633);
-	reg32_write(0x3d400108,0x70e1214);
 	reg32_write(0x3d40010c,0xc0c000);
 	reg32_write(0x3d400110,0xf04080f);
 	reg32_write(0x3d400114,0x2040c0c);
@@ -64,78 +66,77 @@ void ddr_init(void)
 	reg32_write(0x3d400144,0xa00050);
 	reg32_write(0x3d400180,0x3200018);
 	reg32_write(0x3d400184,0x28061a8);
+	reg32_write(0x3d400188,0x0);
 	reg32_write(0x3d400190,0x497820a);
 	reg32_write(0x3d400194,0x80303);
-	reg32_write(0x3d4001b4,0x170a);
-	reg32_write(0x3d4001b0,0x11);
 	reg32_write(0x3d4001a0,0xe0400018);
 	reg32_write(0x3d4001a4,0xdf00e4);
-	reg32_write(0x3d4001a8,0x0);
+	reg32_write(0x3d4001a8,0x80000000);
+	reg32_write(0x3d4001b0,0x11);
+	reg32_write(0x3d4001b4,0x170a);
 	reg32_write(0x3d4001c0,0x1);
 	reg32_write(0x3d4001c4,0x1);
+	reg32_write(0x3d4000f4,0x639);
+	reg32_write(0x3d400108,0x70e1214);
 	reg32_write(0x3d400200,0x15);
 	reg32_write(0x3d40020c,0x0);
 	reg32_write(0x3d400210,0x1f1f);
 	reg32_write(0x3d400204,0x80808);
 	reg32_write(0x3d400214,0x7070707);
 	reg32_write(0x3d400218,0x48080707);
+	reg32_write(0x3d402020,0x1);
+	reg32_write(0x3d402024,0x518b00);
+	reg32_write(0x3d402050,0x20d040);
+	reg32_write(0x3d402064,0x14002f);
+	reg32_write(0x3d4020dc,0x940009);
+	reg32_write(0x3d4020e0,0x310000);
+	reg32_write(0x3d4020e8,0x66004a);
+	reg32_write(0x3d4020ec,0x16004a);
+	reg32_write(0x3d402100,0xb070508);
+	reg32_write(0x3d402104,0x3040b);
+	reg32_write(0x3d402108,0x305090c);
+	reg32_write(0x3d40210c,0x505000);
+	reg32_write(0x3d402110,0x4040204);
+	reg32_write(0x3d402114,0x2030303);
+	reg32_write(0x3d402118,0x1010004);
+	reg32_write(0x3d40211c,0x301);
+	reg32_write(0x3d402130,0x20300);
+	reg32_write(0x3d402134,0xa100002);
+	reg32_write(0x3d402138,0x31);
+	reg32_write(0x3d402144,0x220011);
+	reg32_write(0x3d402180,0xa70006);
+	reg32_write(0x3d402190,0x3858202);
+	reg32_write(0x3d402194,0x80303);
+	reg32_write(0x3d4021b4,0x502);
 	reg32_write(0x3d400244,0x0);
-	reg32_write(0x3d400490,0x1);
-	reg32_write(0x3d400250,0x29001f01);
+	reg32_write(0x3d400250,0x29001505);
 	reg32_write(0x3d400254,0x2c);
-	reg32_write(0x3d400264,0x900093e7);
+	reg32_write(0x3d40025c,0x5900575b);
+	reg32_write(0x3d400264,0x9);
 	reg32_write(0x3d40026c,0x2005574);
-	reg32_write(0x3d400400,0x400);
+	reg32_write(0x3d400300,0x16);
+	reg32_write(0x3d400304,0x0);
+	reg32_write(0x3d40030c,0x0);
+	reg32_write(0x3d400320,0x1);
+	reg32_write(0x3d40036c,0x11);
+	reg32_write(0x3d400400,0x111);
+	reg32_write(0x3d400404,0x10f3);
 	reg32_write(0x3d400408,0x72ff);
-	reg32_write(0x3d400494,0x10e00);
-	reg32_write(0x3d400498,0x620096);
-	reg32_write(0x3d40049c,0x10e00);
-	reg32_write(0x3d4004a0,0x12c);
+	reg32_write(0x3d400490,0x1);
+	reg32_write(0x3d400494,0x1110d00);
+	reg32_write(0x3d400498,0x620790);
+	reg32_write(0x3d40049c,0x100001);
+	reg32_write(0x3d4004a0,0x41f);
 	reg32_write(0x30391000,0x8f000004);
 	reg32_write(0x30391000,0x8f000000);
-	reg32_write(0x3d400304,0x0);
 	reg32_write(0x3d400030,0xa8);
+	do{
+		tmp=reg32_read(0x3d400004);
+		if(tmp&0x223) break;
+	}while(1);
 	reg32_write(0x3d400320,0x0);
 	reg32_write(0x3d000000,0x1);
 	reg32_write(0x3d4001b0,0x10);
-	reg32_write(0x3d402100,0xa040305);
-	reg32_write(0x3d402104,0x30407);
-	reg32_write(0x3d402108,0x203060b);
-	reg32_write(0x3d40210c,0x505000);
-	reg32_write(0x3d402110,0x2040202);
-	reg32_write(0x3d402114,0x2030202);
-	reg32_write(0x3d402118,0x1010004);
-	reg32_write(0x3d40211c,0x301);
-	reg32_write(0x3d402138,0x1d);
-	reg32_write(0x3d402144,0x14000a);
-	reg32_write(0x3d403024,0x30d400);
-	reg32_write(0x3d402050,0x20d040);
-	reg32_write(0x3d402190,0x3818200);
-	reg32_write(0x3d4021b4,0x100);
-	reg32_write(0x3d402064,0xc001c);
-	reg32_write(0x3d4020dc,0x840000);
-	reg32_write(0x3d4020e8,0x46004d);
-	reg32_write(0x3d4020ec,0x15004d);
-	reg32_write(0x3d4020e0,0x310000);
-	reg32_write(0x3d403100,0x6010102);
-	reg32_write(0x3d403104,0x30404);
-	reg32_write(0x3d403108,0x203060b);
-	reg32_write(0x3d40310c,0x505000);
-	reg32_write(0x3d403110,0x2040202);
-	reg32_write(0x3d403114,0x2030202);
-	reg32_write(0x3d403118,0x1010004);
-	reg32_write(0x3d40311c,0x301);
-	reg32_write(0x3d403138,0x8);
-	reg32_write(0x3d403144,0x50003);
-	reg32_write(0x3d403024,0xc3500);
-	reg32_write(0x3d403050,0x20d040);
-	reg32_write(0x3d403190,0x3818200);
-	reg32_write(0x3d4031b4,0x100);
-	reg32_write(0x3d403064,0x30007);
-	reg32_write(0x3d4030dc,0x840000);
-	reg32_write(0x3d4030e8,0x46004d);
-	reg32_write(0x3d4030ec,0x15004d);
-	reg32_write(0x3d4030e0,0x310000);
 	reg32_write(0x3c040280,0x0);
 	reg32_write(0x3c040284,0x1);
 	reg32_write(0x3c040288,0x2);
@@ -218,6 +219,7 @@ void ddr_init(void)
 
 	/* enable port 0 */
 	reg32_write(DDRC_PCTRL_0(0), 0x00000001);
-	tmp = reg32_read(DDRC_CRCPARSTAT(0));
-	reg32_write(DDRC_RFSHCTL3(0), 0x00000000);
+	/* enable DDR auto-refresh mode */
+	tmp = reg32_read(DDRC_RFSHCTL3(0)) & ~0x1;
+	reg32_write(DDRC_RFSHCTL3(0), tmp);
 }
\ No newline at end of file
diff --git a/arch/arm/boards/nxp-imx8mq-evk/ddrphy_train.c b/arch/arm/boards/nxp-imx8mq-evk/ddrphy_train.c
index 156d7cf87..1b30ff725 100644
--- a/arch/arm/boards/nxp-imx8mq-evk/ddrphy_train.c
+++ b/arch/arm/boards/nxp-imx8mq-evk/ddrphy_train.c
@@ -2,6 +2,8 @@
  * Copyright 2017 NXP
  *
  * SPDX-License-Identifier:	GPL-2.0+
+ *
+ * Generated code from MX8M_DDR_tool
  */
 
 #include "ddr.h"
@@ -32,14 +34,6 @@ void ddr_cfg_phy(void) {
 	reg32_write(0x3c44857c,0x1ff);
 	reg32_write(0x3c44c17c,0x1ff);
 	reg32_write(0x3c44c57c,0x1ff);
-	reg32_write(0x3c84017c,0x1ff);
-	reg32_write(0x3c84057c,0x1ff);
-	reg32_write(0x3c84417c,0x1ff);
-	reg32_write(0x3c84457c,0x1ff);
-	reg32_write(0x3c84817c,0x1ff);
-	reg32_write(0x3c84857c,0x1ff);
-	reg32_write(0x3c84c17c,0x1ff);
-	reg32_write(0x3c84c57c,0x1ff);
 	reg32_write(0x3c000154,0x1ff);
 	reg32_write(0x3c004154,0x1ff);
 	reg32_write(0x3c008154,0x1ff);
@@ -52,22 +46,16 @@ void ddr_cfg_phy(void) {
 	reg32_write(0x3c024154,0x1ff);
 	reg32_write(0x3c080314,0x19);
 	reg32_write(0x3c480314,0x7);
-	reg32_write(0x3c880314,0x7);
 	reg32_write(0x3c0800b8,0x2);
-	reg32_write(0x3c4800b8,0x2);
-	reg32_write(0x3c8800b8,0x2);
+	reg32_write(0x3c4800b8,0x1);
 	reg32_write(0x3c240810,0x0);
 	reg32_write(0x3c640810,0x0);
-	reg32_write(0x3ca40810,0x0);
 	reg32_write(0x3c080090,0xab);
 	reg32_write(0x3c0800e8,0x0);
 	reg32_write(0x3c480090,0xab);
 	reg32_write(0x3c0800e8,0x0);
-	reg32_write(0x3c880090,0xab);
-	reg32_write(0x3c0800e8,0x0);
-	reg32_write(0x3c080158,0x7);
+	reg32_write(0x3c080158,0x3);
 	reg32_write(0x3c480158,0xa);
-	reg32_write(0x3c880158,0xa);
 	reg32_write(0x3c040134,0xe00);
 	reg32_write(0x3c040534,0xe00);
 	reg32_write(0x3c044134,0xe00);
@@ -84,14 +72,6 @@ void ddr_cfg_phy(void) {
 	reg32_write(0x3c448534,0xe00);
 	reg32_write(0x3c44c134,0xe00);
 	reg32_write(0x3c44c534,0xe00);
-	reg32_write(0x3c840134,0xe00);
-	reg32_write(0x3c840534,0xe00);
-	reg32_write(0x3c844134,0xe00);
-	reg32_write(0x3c844534,0xe00);
-	reg32_write(0x3c848134,0xe00);
-	reg32_write(0x3c848534,0xe00);
-	reg32_write(0x3c84c134,0xe00);
-	reg32_write(0x3c84c534,0xe00);
 	reg32_write(0x3c040124,0xfbe);
 	reg32_write(0x3c040524,0xfbe);
 	reg32_write(0x3c044124,0xfbe);
@@ -108,14 +88,6 @@ void ddr_cfg_phy(void) {
 	reg32_write(0x3c448524,0xfbe);
 	reg32_write(0x3c44c124,0xfbe);
 	reg32_write(0x3c44c524,0xfbe);
-	reg32_write(0x3c840124,0xfbe);
-	reg32_write(0x3c840524,0xfbe);
-	reg32_write(0x3c844124,0xfbe);
-	reg32_write(0x3c844524,0xfbe);
-	reg32_write(0x3c848124,0xfbe);
-	reg32_write(0x3c848524,0xfbe);
-	reg32_write(0x3c84c124,0xfbe);
-	reg32_write(0x3c84c524,0xfbe);
 	reg32_write(0x3c00010c,0x63);
 	reg32_write(0x3c00410c,0x63);
 	reg32_write(0x3c00810c,0x63);
@@ -130,8 +102,7 @@ void ddr_cfg_phy(void) {
 	reg32_write(0x3c0801d4,0x4);
 	reg32_write(0x3c080140,0x0);
 	reg32_write(0x3c080020,0x320);
-	reg32_write(0x3c480020,0x64);
-	reg32_write(0x3c880020,0x19);
+	reg32_write(0x3c480020,0xa7);
 	reg32_write(0x3c080220,0x9);
 	reg32_write(0x3c0802c8,0xdc);
 	reg32_write(0x3c04010c,0x5a1);
@@ -151,33 +122,21 @@ void ddr_cfg_phy(void) {
 	reg32_write(0x3c44850c,0x5a1);
 	reg32_write(0x3c44c10c,0x5a1);
 	reg32_write(0x3c44c50c,0x5a1);
-	reg32_write(0x3c8802c8,0xdc);
-	reg32_write(0x3c84010c,0x5a1);
-	reg32_write(0x3c84050c,0x5a1);
-	reg32_write(0x3c84410c,0x5a1);
-	reg32_write(0x3c84450c,0x5a1);
-	reg32_write(0x3c84810c,0x5a1);
-	reg32_write(0x3c84850c,0x5a1);
-	reg32_write(0x3c84c10c,0x5a1);
-	reg32_write(0x3c84c50c,0x5a1);
 	reg32_write(0x3c0803e8,0x1);
 	reg32_write(0x3c4803e8,0x1);
-	reg32_write(0x3c8803e8,0x1);
 	reg32_write(0x3c080064,0x1);
 	reg32_write(0x3c480064,0x1);
-	reg32_write(0x3c880064,0x1);
-	reg32_write(0x3c0803c0,0x660);
+	reg32_write(0x3c0803c0,0x0);
 	reg32_write(0x3c0803c4,0x0);
 	reg32_write(0x3c0803c8,0x4444);
 	reg32_write(0x3c0803cc,0x8888);
-	reg32_write(0x3c0803d0,0x5665);
+	reg32_write(0x3c0803d0,0x5555);
 	reg32_write(0x3c0803d4,0x0);
 	reg32_write(0x3c0803d8,0x0);
 	reg32_write(0x3c0803dc,0xf000);
 	reg32_write(0x3c080094,0x0);
 	reg32_write(0x3c0800b4,0x0);
 	reg32_write(0x3c4800b4,0x0);
-	reg32_write(0x3c8800b4,0x0);
 	reg32_write(0x3c080180,0x2);
 
 	//enable APB bus to access DDRPHY RAM
@@ -195,31 +154,32 @@ void ddr_cfg_phy(void) {
 	reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x54008,0x131f);
 	reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x54009,0xc8);
 	reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x5400b,0x2);
+	reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x5400d,0x100);
 	reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x54012,0x310);
 	reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x54019,0x2dd4);
 	reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x5401a,0x31);
-	reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x5401b,0x4d46);
-	reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x5401c,0x4d08);
-	reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x5401e,0x15);
+	reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x5401b,0x4a66);
+	reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x5401c,0x4a08);
+	reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x5401e,0x16);
 	reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x5401f,0x2dd4);
 	reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x54020,0x31);
-	reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x54021,0x4d46);
-	reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x54022,0x4d08);
-	reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x54024,0x15);
+	reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x54021,0x4a66);
+	reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x54022,0x4a08);
+	reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x54024,0x16);
 	reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x5402b,0x1000);
 	reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x5402c,0x3);
 	reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x54032,0xd400);
 	reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x54033,0x312d);
-	reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x54034,0x4600);
-	reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x54035,0x84d);
-	reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x54036,0x4d);
-	reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x54037,0x1500);
+	reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x54034,0x6600);
+	reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x54035,0x84a);
+	reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x54036,0x4a);
+	reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x54037,0x1600);
 	reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x54038,0xd400);
 	reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x54039,0x312d);
-	reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x5403a,0x4600);
-	reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x5403b,0x84d);
-	reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x5403c,0x4d);
-	reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x5403d,0x1500);
+	reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x5403a,0x6600);
+	reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x5403b,0x84a);
+	reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x5403c,0x4a);
+	reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x5403d,0x1600);
 
 	//disable APB bus to access DDRPHY RAM
 	reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0xd0000, 0x1);
@@ -233,96 +193,57 @@ void ddr_cfg_phy(void) {
 	reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0xd0099, 0x1);
 
 	//set the PHY input clock to the desired frequency for pstate 1
-	reg32_write(0x3038a008,0x7070000);
-	reg32_write(0x3038a004,0x5000000);
-	reg32_write(0x3038a088,0x7070000);
-	reg32_write(0x3038a084,0x2010000);
-	reg32_write(0x303a00ec,0xffff);
-	tmp=reg32_read(0x303a00f8);
-	tmp |= 0x20;
-	reg32_write(0x303a00f8,tmp);
-	reg32_write(0x30389804,0x1000000);
-
-	//enable APB bus to access DDRPHY RAM
-	reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0xd0000, 0x0);
-
-	reg32_write(0x3c150008,0x101);
-	reg32_write(0x3c15000c,0x190);
-	reg32_write(0x3c150020,0x121f);
-	reg32_write(0x3c150064,0x84);
-	reg32_write(0x3c150068,0x31);
-	reg32_write(0x3c15006c,0x4d46);
-	reg32_write(0x3c150070,0x4d08);
-	reg32_write(0x3c150074,0x0);
-	reg32_write(0x3c150078,0x15);
-	reg32_write(0x3c15007c,0x84);
-	reg32_write(0x3c150080,0x31);
-	reg32_write(0x3c150084,0x4d46);
-	reg32_write(0x3c150088,0x4d08);
-	reg32_write(0x3c15008c,0x0);
-	reg32_write(0x3c150090,0x15);
-	reg32_write(0x3c1500c8,0x8400);
-	reg32_write(0x3c1500cc,0x3100);
-	reg32_write(0x3c1500d0,0x4600);
-	reg32_write(0x3c1500d4,0x84d);
-	reg32_write(0x3c1500d8,0x4d);
-	reg32_write(0x3c1500dc,0x1500);
-	reg32_write(0x3c1500e0,0x8400);
-	reg32_write(0x3c1500e4,0x3100);
-	reg32_write(0x3c1500e8,0x4600);
-	reg32_write(0x3c1500ec,0x84d);
-	reg32_write(0x3c1500f0,0x4d);
-	reg32_write(0x3c1500f4,0x1500);
-	reg32_write(0x3c1500f8,0x0);
-
-	//disable APB bus to access DDRPHY RAM
-	reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0xd0000, 0x1);
-	//Reset MPU and run
-	reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0xd0099, 0x9);
-	reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0xd0099, 0x1);
-	reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0xd0099, 0x0);
-	wait_ddrphy_training_complete();
-
-	//configure DDRPHY-FW DMEM structure @clock2...
-	reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0xd0099, 0x1);
-
-	//set the PHY input clock to the desired frequency for pstate 2
-	reg32_write(0x3038a008,0x7070000);
-	reg32_write(0x3038a004,0x2000000);
 	reg32_write(0x3038a088,0x7070000);
-	reg32_write(0x3038a084,0x2010000);
+	reg32_write(0x3038a084,0x4030000);
 	reg32_write(0x303a00ec,0xffff);
 	tmp=reg32_read(0x303a00f8);
 	tmp |= 0x20;
 	reg32_write(0x303a00f8,tmp);
-	reg32_write(0x30389804,0x1000000);
+	reg32_write(0x30360068,0xf5a406);
+	tmp=reg32_read(0x30360060);
+	tmp &= ~0x80;
+	reg32_write(0x30360060,tmp);
+	tmp=reg32_read(0x30360060);
+	tmp |= 0x200;
+	reg32_write(0x30360060,tmp);
+	tmp=reg32_read(0x30360060);
+	tmp &= ~0x20;
+	reg32_write(0x30360060,tmp);
+	tmp=reg32_read(0x30360060);
+	tmp &= ~0x10;
+	reg32_write(0x30360060,tmp);
+	do{
+		tmp=reg32_read(0x30360060);
+		if(tmp&0x80000000) break;
+	}while(1);
+	reg32_write(0x30389808,0x1000000);
 
 	//enable APB bus to access DDRPHY RAM
 	reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0xd0000, 0x0);
 
-	reg32_write(0x3c150008,0x102);
-	reg32_write(0x3c15000c,0x64);
+	reg32_write(0x3c150008,0x1);
+	reg32_write(0x3c15000c,0x29c);
 	reg32_write(0x3c150020,0x121f);
-	reg32_write(0x3c150064,0x84);
+	reg32_write(0x3c150064,0x994);
 	reg32_write(0x3c150068,0x31);
 	reg32_write(0x3c15006c,0x4d46);
 	reg32_write(0x3c150070,0x4d08);
 	reg32_write(0x3c150074,0x0);
 	reg32_write(0x3c150078,0x15);
-	reg32_write(0x3c15007c,0x84);
+	reg32_write(0x3c15007c,0x994);
 	reg32_write(0x3c150080,0x31);
 	reg32_write(0x3c150084,0x4d46);
 	reg32_write(0x3c150088,0x4d08);
 	reg32_write(0x3c15008c,0x0);
 	reg32_write(0x3c150090,0x15);
-	reg32_write(0x3c1500c8,0x8400);
-	reg32_write(0x3c1500cc,0x3100);
+	reg32_write(0x3c1500c8,0x9400);
+	reg32_write(0x3c1500cc,0x3109);
 	reg32_write(0x3c1500d0,0x4600);
 	reg32_write(0x3c1500d4,0x84d);
 	reg32_write(0x3c1500d8,0x4d);
 	reg32_write(0x3c1500dc,0x1500);
-	reg32_write(0x3c1500e0,0x8400);
-	reg32_write(0x3c1500e4,0x3100);
+	reg32_write(0x3c1500e0,0x9400);
+	reg32_write(0x3c1500e4,0x3109);
 	reg32_write(0x3c1500e8,0x4600);
 	reg32_write(0x3c1500ec,0x84d);
 	reg32_write(0x3c1500f0,0x4d);
@@ -344,7 +265,7 @@ void ddr_cfg_phy(void) {
 	tmp=reg32_read(0x303a00f8);
 	tmp |= 0x20;
 	reg32_write(0x303a00f8,tmp);
-	reg32_write(0x30360068,0xbbe580);
+	reg32_write(0x30360068,0xece580);
 	tmp=reg32_read(0x30360060);
 	tmp &= ~0x80;
 	reg32_write(0x30360060,tmp);
@@ -380,28 +301,28 @@ void ddr_cfg_phy(void) {
 	reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x54012,0x310);
 	reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x54019,0x2dd4);
 	reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x5401a,0x31);
-	reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x5401b,0x4d46);
-	reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x5401c,0x4d08);
-	reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x5401e,0x15);
+	reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x5401b,0x4a66);
+	reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x5401c,0x4a08);
+	reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x5401e,0x16);
 	reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x5401f,0x2dd4);
 	reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x54020,0x31);
-	reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x54021,0x4d46);
-	reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x54022,0x4d08);
-	reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x54024,0x15);
+	reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x54021,0x4a66);
+	reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x54022,0x4a08);
+	reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x54024,0x16);
 	reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x5402b,0x1000);
 	reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x5402c,0x3);
 	reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x54032,0xd400);
 	reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x54033,0x312d);
-	reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x54034,0x4600);
-	reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x54035,0x84d);
-	reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x54036,0x4d);
-	reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x54037,0x1500);
+	reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x54034,0x6600);
+	reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x54035,0x84a);
+	reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x54036,0x4a);
+	reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x54037,0x1600);
 	reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x54038,0xd400);
 	reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x54039,0x312d);
-	reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x5403a,0x4600);
-	reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x5403b,0x84d);
-	reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x5403c,0x4d);
-	reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x5403d,0x1500);
+	reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x5403a,0x6600);
+	reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x5403b,0x84a);
+	reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x5403c,0x4a);
+	reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x5403d,0x1600);
 
 	//disable APB bus to access DDRPHY RAM
 	reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0xd0000, 0x1);
@@ -912,10 +833,6 @@ void ddr_cfg_phy(void) {
 	reg32_write(0x3c480030,0xc9);
 	reg32_write(0x3c480034,0x7d1);
 	reg32_write(0x3c480038,0x2c);
-	reg32_write(0x3c88002c,0x65);
-	reg32_write(0x3c880030,0xc9);
-	reg32_write(0x3c880034,0x7d1);
-	reg32_write(0x3c880038,0x2c);
 	reg32_write(0x3c240030,0x0);
 	reg32_write(0x3c240034,0x173);
 	reg32_write(0x3c240038,0x60);
@@ -928,8 +845,6 @@ void ddr_cfg_phy(void) {
 	reg32_write(0x3c080044,0x3);
 	reg32_write(0x3c480040,0x5a);
 	reg32_write(0x3c480044,0x3);
-	reg32_write(0x3c880040,0x5a);
-	reg32_write(0x3c880044,0x3);
 	reg32_write(0x3c100200,0xe0);
 	reg32_write(0x3c100204,0x12);
 	reg32_write(0x3c100208,0xe0);
@@ -942,12 +857,6 @@ void ddr_cfg_phy(void) {
 	reg32_write(0x3c50020c,0x12);
 	reg32_write(0x3c500210,0xe0);
 	reg32_write(0x3c500214,0x12);
-	reg32_write(0x3c900200,0xe0);
-	reg32_write(0x3c900204,0x12);
-	reg32_write(0x3c900208,0xe0);
-	reg32_write(0x3c90020c,0x12);
-	reg32_write(0x3c900210,0xe0);
-	reg32_write(0x3c900214,0x12);
 	reg32_write(0x3c1003f4,0xf);
 	reg32_write(0x3c040044,0x1);
 	reg32_write(0x3c040048,0x1);
-- 
2.17.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH v2 02/12] ARM: Add code to support SMCCC on AArch64
  2018-07-20  1:03 [PATCH v2 00/12] ARM: i.MX8MQ and EVK support, part II Andrey Smirnov
  2018-07-20  1:03 ` [PATCH v2 01/12] ARM: nxp-imx8mq-evk: Update DDR initialization code Andrey Smirnov
@ 2018-07-20  1:03 ` Andrey Smirnov
  2018-07-20  1:03 ` [PATCH v2 03/12] ARM: i.MX8MQ: Configure cntfrq only in EL3 Andrey Smirnov
                   ` (10 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: Andrey Smirnov @ 2018-07-20  1:03 UTC (permalink / raw)
  To: barebox; +Cc: Andrey Smirnov

Port SMCCC code from Linux kernel. To accomodate that:

  - Introduce CONFIG_ARM_SMCCC, to allow enabling the code
    independent of CONFIG_ARM_SECURE_MONITOR

  - Bring <linux/arm-smccc.h> in

  - Add necessary constants to arch/arm/asm-offsets.c

Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
 arch/arm/Kconfig                   |   4 +
 arch/arm/cpu/Makefile              |   4 +-
 arch/arm/cpu/smccc-call_64.S       |  52 +++++++++++
 arch/arm/include/asm/asm-offsets.h |   1 +
 arch/arm/lib/asm-offsets.c         |   7 +-
 include/linux/arm-smccc.h          | 135 +++++++++++++++++++++++++++++
 6 files changed, 200 insertions(+), 3 deletions(-)
 create mode 100644 arch/arm/cpu/smccc-call_64.S
 create mode 100644 arch/arm/include/asm/asm-offsets.h
 create mode 100644 include/linux/arm-smccc.h

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 3555b4ee5..00c893bd0 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -388,7 +388,11 @@ config ARM_SEMIHOSTING
 	  the data on the host computer connected to the target via
 	  debugging channel (JTAG, SWD). If unsure say N
 
+config ARM_SMCCC
+	bool
+
 config ARM_SECURE_MONITOR
+	select ARM_SMCCC
 	bool
 
 config ARM_PSCI
diff --git a/arch/arm/cpu/Makefile b/arch/arm/cpu/Makefile
index 5b4b832e8..874d723e2 100644
--- a/arch/arm/cpu/Makefile
+++ b/arch/arm/cpu/Makefile
@@ -21,8 +21,8 @@ obj-$(CONFIG_CPU_32v7) += no-mmu.o
 endif
 
 obj-$(CONFIG_ARM_PSCI) += psci.o
-obj-$(CONFIG_ARM_SECURE_MONITOR) += smccc-call.o
-AFLAGS_smccc-call.o	:=-Wa,-march=armv7-a
+obj-pbl-$(CONFIG_ARM_SMCCC) += smccc-call$(S64).o
+AFLAGS_smccc-call$(S64).o :=-Wa,-march=armv$(if $(S64),8,7)-a
 obj-$(CONFIG_ARM_SECURE_MONITOR) += sm.o sm_as.o
 AFLAGS_sm_as.o		:=-Wa,-march=armv7-a
 
diff --git a/arch/arm/cpu/smccc-call_64.S b/arch/arm/cpu/smccc-call_64.S
new file mode 100644
index 000000000..44888fb59
--- /dev/null
+++ b/arch/arm/cpu/smccc-call_64.S
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2015, Linaro Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+#include <linux/linkage.h>
+#include <linux/arm-smccc.h>
+#include <asm/asm-offsets.h>
+
+	.macro SMCCC instr
+	.cfi_startproc
+	\instr	#0
+	ldr	x4, [sp]
+	stp	x0, x1, [x4, #ARM_SMCCC_RES_X0_OFFS]
+	stp	x2, x3, [x4, #ARM_SMCCC_RES_X2_OFFS]
+	ldr	x4, [sp, #8]
+	cbz	x4, 1f /* no quirk structure */
+	ldr	x9, [x4, #ARM_SMCCC_QUIRK_ID_OFFS]
+	cmp	x9, #ARM_SMCCC_QUIRK_QCOM_A6
+	b.ne	1f
+	str	x6, [x4, ARM_SMCCC_QUIRK_STATE_OFFS]
+1:	ret
+	.cfi_endproc
+	.endm
+
+/*
+ * void arm_smccc_smc(unsigned long a0, unsigned long a1, unsigned long a2,
+ *		  unsigned long a3, unsigned long a4, unsigned long a5,
+ *		  unsigned long a6, unsigned long a7, struct arm_smccc_res *res,
+ *		  struct arm_smccc_quirk *quirk)
+ */
+ENTRY(__arm_smccc_smc)
+	SMCCC	smc
+ENDPROC(__arm_smccc_smc)
+
+/*
+ * void arm_smccc_hvc(unsigned long a0, unsigned long a1, unsigned long a2,
+ *		  unsigned long a3, unsigned long a4, unsigned long a5,
+ *		  unsigned long a6, unsigned long a7, struct arm_smccc_res *res,
+ *		  struct arm_smccc_quirk *quirk)
+ */
+ENTRY(__arm_smccc_hvc)
+	SMCCC	hvc
+ENDPROC(__arm_smccc_hvc)
\ No newline at end of file
diff --git a/arch/arm/include/asm/asm-offsets.h b/arch/arm/include/asm/asm-offsets.h
new file mode 100644
index 000000000..2f84e8399
--- /dev/null
+++ b/arch/arm/include/asm/asm-offsets.h
@@ -0,0 +1 @@
+#include <generated/asm-offsets.h>
\ No newline at end of file
diff --git a/arch/arm/lib/asm-offsets.c b/arch/arm/lib/asm-offsets.c
index 7bf6d129c..cdff6f782 100644
--- a/arch/arm/lib/asm-offsets.c
+++ b/arch/arm/lib/asm-offsets.c
@@ -9,8 +9,13 @@
  */
 
 #include <linux/kbuild.h>
+#include <linux/arm-smccc.h>
 
 int main(void)
 {
-	return 0;
+  DEFINE(ARM_SMCCC_RES_X0_OFFS,		offsetof(struct arm_smccc_res, a0));
+  DEFINE(ARM_SMCCC_RES_X2_OFFS,		offsetof(struct arm_smccc_res, a2));
+  DEFINE(ARM_SMCCC_QUIRK_ID_OFFS,	offsetof(struct arm_smccc_quirk, id));
+  DEFINE(ARM_SMCCC_QUIRK_STATE_OFFS,	offsetof(struct arm_smccc_quirk, state));
+  return 0;
 }
diff --git a/include/linux/arm-smccc.h b/include/linux/arm-smccc.h
new file mode 100644
index 000000000..1b38b7b37
--- /dev/null
+++ b/include/linux/arm-smccc.h
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 2015, Linaro Limited
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+#ifndef __LINUX_ARM_SMCCC_H
+#define __LINUX_ARM_SMCCC_H
+
+/*
+ * This file provides common defines for ARM SMC Calling Convention as
+ * specified in
+ * http://infocenter.arm.com/help/topic/com.arm.doc.den0028a/index.html
+ */
+
+/* This constant is shifted by 31, make sure it's of an unsigned type */
+#define ARM_SMCCC_STD_CALL		0UL
+#define ARM_SMCCC_FAST_CALL		1UL
+#define ARM_SMCCC_TYPE_SHIFT		31
+
+#define ARM_SMCCC_SMC_32		0
+#define ARM_SMCCC_SMC_64		1
+#define ARM_SMCCC_CALL_CONV_SHIFT	30
+
+#define ARM_SMCCC_OWNER_MASK		0x3F
+#define ARM_SMCCC_OWNER_SHIFT		24
+
+#define ARM_SMCCC_FUNC_MASK		0xFFFF
+
+#define ARM_SMCCC_IS_FAST_CALL(smc_val)	\
+	((smc_val) & (ARM_SMCCC_FAST_CALL << ARM_SMCCC_TYPE_SHIFT))
+#define ARM_SMCCC_IS_64(smc_val) \
+	((smc_val) & (ARM_SMCCC_SMC_64 << ARM_SMCCC_CALL_CONV_SHIFT))
+#define ARM_SMCCC_FUNC_NUM(smc_val)	((smc_val) & ARM_SMCCC_FUNC_MASK)
+#define ARM_SMCCC_OWNER_NUM(smc_val) \
+	(((smc_val) >> ARM_SMCCC_OWNER_SHIFT) & ARM_SMCCC_OWNER_MASK)
+
+#define ARM_SMCCC_CALL_VAL(type, calling_convention, owner, func_num) \
+	(((type) << ARM_SMCCC_TYPE_SHIFT) | \
+	((calling_convention) << ARM_SMCCC_CALL_CONV_SHIFT) | \
+	(((owner) & ARM_SMCCC_OWNER_MASK) << ARM_SMCCC_OWNER_SHIFT) | \
+	((func_num) & ARM_SMCCC_FUNC_MASK))
+
+#define ARM_SMCCC_OWNER_ARCH		0
+#define ARM_SMCCC_OWNER_CPU		1
+#define ARM_SMCCC_OWNER_SIP		2
+#define ARM_SMCCC_OWNER_OEM		3
+#define ARM_SMCCC_OWNER_STANDARD	4
+#define ARM_SMCCC_OWNER_TRUSTED_APP	48
+#define ARM_SMCCC_OWNER_TRUSTED_APP_END	49
+#define ARM_SMCCC_OWNER_TRUSTED_OS	50
+#define ARM_SMCCC_OWNER_TRUSTED_OS_END	63
+
+#define ARM_SMCCC_QUIRK_NONE		0
+#define ARM_SMCCC_QUIRK_QCOM_A6		1 /* Save/restore register a6 */
+
+#ifndef __ASSEMBLY__
+
+#include <linux/linkage.h>
+#include <linux/types.h>
+/**
+ * struct arm_smccc_res - Result from SMC/HVC call
+ * @a0-a3 result values from registers 0 to 3
+ */
+struct arm_smccc_res {
+	unsigned long a0;
+	unsigned long a1;
+	unsigned long a2;
+	unsigned long a3;
+};
+
+/**
+ * struct arm_smccc_quirk - Contains quirk information
+ * @id: quirk identification
+ * @state: quirk specific information
+ * @a6: Qualcomm quirk entry for returning post-smc call contents of a6
+ */
+struct arm_smccc_quirk {
+	int	id;
+	union {
+		unsigned long a6;
+	} state;
+};
+
+/**
+ * __arm_smccc_smc() - make SMC calls
+ * @a0-a7: arguments passed in registers 0 to 7
+ * @res: result values from registers 0 to 3
+ * @quirk: points to an arm_smccc_quirk, or NULL when no quirks are required.
+ *
+ * This function is used to make SMC calls following SMC Calling Convention.
+ * The content of the supplied param are copied to registers 0 to 7 prior
+ * to the SMC instruction. The return values are updated with the content
+ * from register 0 to 3 on return from the SMC instruction.  An optional
+ * quirk structure provides vendor specific behavior.
+ */
+asmlinkage void __arm_smccc_smc(unsigned long a0, unsigned long a1,
+			unsigned long a2, unsigned long a3, unsigned long a4,
+			unsigned long a5, unsigned long a6, unsigned long a7,
+			struct arm_smccc_res *res, struct arm_smccc_quirk *quirk);
+
+/**
+ * __arm_smccc_hvc() - make HVC calls
+ * @a0-a7: arguments passed in registers 0 to 7
+ * @res: result values from registers 0 to 3
+ * @quirk: points to an arm_smccc_quirk, or NULL when no quirks are required.
+ *
+ * This function is used to make HVC calls following SMC Calling
+ * Convention.  The content of the supplied param are copied to registers 0
+ * to 7 prior to the HVC instruction. The return values are updated with
+ * the content from register 0 to 3 on return from the HVC instruction.  An
+ * optional quirk structure provides vendor specific behavior.
+ */
+asmlinkage void __arm_smccc_hvc(unsigned long a0, unsigned long a1,
+			unsigned long a2, unsigned long a3, unsigned long a4,
+			unsigned long a5, unsigned long a6, unsigned long a7,
+			struct arm_smccc_res *res, struct arm_smccc_quirk *quirk);
+
+#define arm_smccc_smc(...) __arm_smccc_smc(__VA_ARGS__, NULL)
+
+#define arm_smccc_smc_quirk(...) __arm_smccc_smc(__VA_ARGS__)
+
+#define arm_smccc_hvc(...) __arm_smccc_hvc(__VA_ARGS__, NULL)
+
+#define arm_smccc_hvc_quirk(...) __arm_smccc_hvc(__VA_ARGS__)
+
+#endif /*__ASSEMBLY__*/
+#endif /*__LINUX_ARM_SMCCC_H*/
-- 
2.17.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH v2 03/12] ARM: i.MX8MQ: Configure cntfrq only in EL3
  2018-07-20  1:03 [PATCH v2 00/12] ARM: i.MX8MQ and EVK support, part II Andrey Smirnov
  2018-07-20  1:03 ` [PATCH v2 01/12] ARM: nxp-imx8mq-evk: Update DDR initialization code Andrey Smirnov
  2018-07-20  1:03 ` [PATCH v2 02/12] ARM: Add code to support SMCCC on AArch64 Andrey Smirnov
@ 2018-07-20  1:03 ` Andrey Smirnov
  2018-07-20  1:03 ` [PATCH v2 04/12] ARM: i.MX8MQ: Add code to load BL31 ATF blob Andrey Smirnov
                   ` (9 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: Andrey Smirnov @ 2018-07-20  1:03 UTC (permalink / raw)
  To: barebox; +Cc: Andrey Smirnov

We only can (and should only need to) configure cntfrq when running in
EL3 and executing this code in any other exception level will result
in exception.

Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
 arch/arm/mach-imx/imx8mq.c | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/arch/arm/mach-imx/imx8mq.c b/arch/arm/mach-imx/imx8mq.c
index f3246e437..dbcf4fa59 100644
--- a/arch/arm/mach-imx/imx8mq.c
+++ b/arch/arm/mach-imx/imx8mq.c
@@ -62,12 +62,14 @@ static void imx8mq_silicon_revision(void)
 
 static int imx8mq_init_syscnt_frequency(void)
 {
-	void __iomem *syscnt = IOMEM(MX8MQ_SYSCNT_CTRL_BASE_ADDR);
-	/*
-	 * Update with accurate clock frequency
-	 */
-	set_cntfrq(syscnt_get_cntfrq(syscnt));
-	syscnt_enable(syscnt);
+	if (current_el() == 3) {
+		void __iomem *syscnt = IOMEM(MX8MQ_SYSCNT_CTRL_BASE_ADDR);
+		/*
+		 * Update with accurate clock frequency
+		 */
+		set_cntfrq(syscnt_get_cntfrq(syscnt));
+		syscnt_enable(syscnt);
+	}
 
 	return 0;
 }
-- 
2.17.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH v2 04/12] ARM: i.MX8MQ: Add code to load BL31 ATF blob
  2018-07-20  1:03 [PATCH v2 00/12] ARM: i.MX8MQ and EVK support, part II Andrey Smirnov
                   ` (2 preceding siblings ...)
  2018-07-20  1:03 ` [PATCH v2 03/12] ARM: i.MX8MQ: Configure cntfrq only in EL3 Andrey Smirnov
@ 2018-07-20  1:03 ` Andrey Smirnov
  2018-07-20  1:03 ` [PATCH v2 05/12] ARM: i.MX: fimware: Add pre-built " Andrey Smirnov
                   ` (8 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: Andrey Smirnov @ 2018-07-20  1:03 UTC (permalink / raw)
  To: barebox; +Cc: Andrey Smirnov

Add imx8mq_atf_load_bl31() containing all of the code needed to load
and transfer control to BL31 ATF blob on i.MX8M.

Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
 arch/arm/mach-imx/Makefile           |  2 +-
 arch/arm/mach-imx/atf.c              | 41 ++++++++++++++++++++++++++++
 arch/arm/mach-imx/include/mach/atf.h | 13 +++++++++
 3 files changed, 55 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/mach-imx/atf.c
 create mode 100644 arch/arm/mach-imx/include/mach/atf.h

diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index 28fe60dba..595a7512c 100644
--- a/arch/arm/mach-imx/Makefile
+++ b/arch/arm/mach-imx/Makefile
@@ -17,7 +17,7 @@ lwl-$(CONFIG_ARCH_IMX6) += imx6-mmdc.o
 obj-$(CONFIG_ARCH_IMX7) += imx7.o
 obj-$(CONFIG_ARCH_VF610) += vf610.o
 obj-$(CONFIG_ARCH_IMX8MQ) += imx8mq.o
-lwl-$(CONFIG_ARCH_IMX8MQ) += imx8-ddrc.o
+lwl-$(CONFIG_ARCH_IMX8MQ) += imx8-ddrc.o atf.o
 obj-$(CONFIG_ARCH_IMX_XLOAD) += xload.o
 obj-$(CONFIG_IMX_IIM)	+= iim.o
 obj-$(CONFIG_NAND_IMX) += nand.o
diff --git a/arch/arm/mach-imx/atf.c b/arch/arm/mach-imx/atf.c
new file mode 100644
index 000000000..2b956b6bd
--- /dev/null
+++ b/arch/arm/mach-imx/atf.c
@@ -0,0 +1,41 @@
+#include <common.h>
+#include <mach/atf.h>
+
+/**
+ * imx8mq_atf_load_bl31 - Load ATF BL31 blob and transfer contol to it
+ *
+ * @fw:		Pointer to the BL31 blob
+ * @fw_size:	Size of the BL31 blob
+ *
+ * This function:
+
+ *     1. Copies built-in BL31 blob to an address i.MX8M's BL31
+ *        expects to be placed
+ *
+ *     2. Sets up temporary stack pointer for EL2, which is execution
+ *        level that BL31 will drop us off at after it completes its
+ *        initialization routine
+ *
+ *     3. Transfers control to BL31
+ *
+ * NOTE: This function expects NXP's implementation of ATF that can be
+ * found at:
+ *     https://source.codeaurora.org/external/imx/imx-atf
+ *
+ * any other implementation may or may not work
+ *
+ */
+void imx8mq_atf_load_bl31(const void *fw, size_t fw_size)
+{
+	void __noreturn (*bl31)(void) = (void *)MX8MQ_ATF_BL31_BASE_ADDR;
+
+	if (WARN_ON(fw_size > MX8MQ_ATF_BL31_SIZE_LIMIT))
+		return;
+
+	memcpy(bl31, fw, fw_size);
+
+	asm volatile("msr sp_el2, %0" : :
+		     "r" (MX8MQ_ATF_BL33_BASE_ADDR - 16) :
+		     "cc");
+	bl31();
+}
\ No newline at end of file
diff --git a/arch/arm/mach-imx/include/mach/atf.h b/arch/arm/mach-imx/include/mach/atf.h
new file mode 100644
index 000000000..aeb24bad0
--- /dev/null
+++ b/arch/arm/mach-imx/include/mach/atf.h
@@ -0,0 +1,13 @@
+#ifndef __IMX_ATF_H__
+#define __IMX_ATF_H__
+
+#include <linux/sizes.h>
+#include <asm/system.h>
+
+#define MX8MQ_ATF_BL31_SIZE_LIMIT	SZ_64K
+#define MX8MQ_ATF_BL31_BASE_ADDR	0x00910000
+#define MX8MQ_ATF_BL33_BASE_ADDR	0x40200000
+
+void imx8mq_atf_load_bl31(const void *fw, size_t fw_size);
+
+#endif
\ No newline at end of file
-- 
2.17.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH v2 05/12] ARM: i.MX: fimware: Add pre-built BL31 ATF blob
  2018-07-20  1:03 [PATCH v2 00/12] ARM: i.MX8MQ and EVK support, part II Andrey Smirnov
                   ` (3 preceding siblings ...)
  2018-07-20  1:03 ` [PATCH v2 04/12] ARM: i.MX8MQ: Add code to load BL31 ATF blob Andrey Smirnov
@ 2018-07-20  1:03 ` Andrey Smirnov
  2018-07-20  1:03 ` [PATCH v2 06/12] ARM: i.MX: Move i.MX header definitions to mach-imx Andrey Smirnov
                   ` (7 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: Andrey Smirnov @ 2018-07-20  1:03 UTC (permalink / raw)
  To: barebox; +Cc: Andrey Smirnov

Running Linux on i.MX8M requires us to use and proerly set up a ARM
Trusted Firmware blob. For the sake of convenience, add a pre-built
blob to our firmware tree, so it can be used by individual boards.

This blob was built using Buildroot:

 - commit: 6b02b8210acb18773f2c4b26cfc11d1f9bc4fb88
 - defconig: freescale_imx8mqevk_defconfig

The resulting file of interest is output/images/bl31.bin

Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
 firmware/Kconfig            |   3 +++
 firmware/Makefile           |   2 ++
 firmware/imx/imx8m-bl31.bin | Bin 0 -> 46744 bytes
 3 files changed, 5 insertions(+)
 create mode 100755 firmware/imx/imx8m-bl31.bin

diff --git a/firmware/Kconfig b/firmware/Kconfig
index b6449644b..a6f79e8a9 100644
--- a/firmware/Kconfig
+++ b/firmware/Kconfig
@@ -7,4 +7,7 @@ config EXTRA_FIRMWARE_DIR
 config FIRMWARE_IMX_LPDDR4_PMU_TRAIN
        	bool
 
+config FIRMWARE_IMX8MQ_ATF
+        bool
+
 endmenu
diff --git a/firmware/Makefile b/firmware/Makefile
index c82e81ae4..62124933d 100644
--- a/firmware/Makefile
+++ b/firmware/Makefile
@@ -9,6 +9,8 @@ firmware-$(CONFIG_FIRMWARE_IMX_LPDDR4_PMU_TRAIN) += \
 	imx/lpddr4_pmu_train_2d_dmem.bin \
 	imx/lpddr4_pmu_train_2d_imem.bin
 
+firmware-$(CONFIG_FIRMWARE_IMX8MQ_ATF) += imx/imx8m-bl31.bin
+
 # Create $(fwabs) from $(CONFIG_EXTRA_FIRMWARE_DIR) -- if it doesn't have a
 # leading /, it's relative to $(srctree).
 fwdir := $(subst $(quote),,$(CONFIG_EXTRA_FIRMWARE_DIR))
diff --git a/firmware/imx/imx8m-bl31.bin b/firmware/imx/imx8m-bl31.bin
new file mode 100755
index 0000000000000000000000000000000000000000..b2310e4334c498686550a2ecab796ba905a13ebe
GIT binary patch
literal 46744
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
T1f8H0bnadH=+w{g^6$?d>FQ|r

literal 0
HcmV?d00001

-- 
2.17.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH v2 06/12] ARM: i.MX: Move i.MX header definitions to mach-imx
  2018-07-20  1:03 [PATCH v2 00/12] ARM: i.MX8MQ and EVK support, part II Andrey Smirnov
                   ` (4 preceding siblings ...)
  2018-07-20  1:03 ` [PATCH v2 05/12] ARM: i.MX: fimware: Add pre-built " Andrey Smirnov
@ 2018-07-20  1:03 ` Andrey Smirnov
  2018-07-20  1:03 ` [PATCH v2 07/12] ARM: i.MX: xload-esdhc: Make use of <mach/imx-header.h> Andrey Smirnov
                   ` (6 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: Andrey Smirnov @ 2018-07-20  1:03 UTC (permalink / raw)
  To: barebox; +Cc: Andrey Smirnov

Move i.MX header definitions from scripts to mach-imx in order to make
it availible to both script and bootloader code.

Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
 arch/arm/mach-imx/include/mach/imx-header.h | 118 ++++++++++++++++++++
 scripts/imx/imx.h                           | 114 +------------------
 2 files changed, 119 insertions(+), 113 deletions(-)
 create mode 100644 arch/arm/mach-imx/include/mach/imx-header.h

diff --git a/arch/arm/mach-imx/include/mach/imx-header.h b/arch/arm/mach-imx/include/mach/imx-header.h
new file mode 100644
index 000000000..4fedba7ad
--- /dev/null
+++ b/arch/arm/mach-imx/include/mach/imx-header.h
@@ -0,0 +1,118 @@
+#ifndef __IMX_HEADER_H__
+#define __IMX_HEADER_H__
+
+#define HEADER_LEN 0x1000	/* length of the blank area + IVT + DCD */
+
+/*
+ * ============================================================================
+ * i.MX flash header v1 handling. Found on i.MX35 and i.MX51
+ * ============================================================================
+ */
+#define DCD_BARKER       0xb17219e9
+
+struct imx_flash_header {
+	uint32_t app_code_jump_vector;
+	uint32_t app_code_barker;
+	uint32_t app_code_csf;
+	uint32_t dcd_ptr_ptr;
+	uint32_t super_root_key;
+	uint32_t dcd;
+	uint32_t app_dest;
+	uint32_t dcd_barker;
+	uint32_t dcd_block_len;
+} __attribute__((packed));
+
+struct imx_boot_data {
+	uint32_t start;
+	uint32_t size;
+	uint32_t plugin;
+} __attribute__((packed));
+
+struct imx_dcd_rec_v1 {
+	uint32_t type;
+	uint32_t addr;
+	uint32_t val;
+} __attribute__((packed));
+
+#define TAG_IVT_HEADER	0xd1
+#define IVT_VERSION	0x40
+#define TAG_DCD_HEADER	0xd2
+#define DCD_VERSION	0x40
+#define TAG_UNLOCK	0xb2
+#define TAG_NOP		0xc0
+#define TAG_WRITE	0xcc
+#define TAG_CHECK	0xcf
+#define PARAMETER_FLAG_MASK	(1 << 3)
+#define PARAMETER_FLAG_SET	(1 << 4)
+
+struct imx_ivt_header {
+	uint8_t tag;
+	uint16_t length;
+	uint8_t version;
+} __attribute__((packed));
+
+struct imx_flash_header_v2 {
+	struct imx_ivt_header header;
+
+	uint32_t entry;
+	uint32_t reserved1;
+	uint32_t dcd_ptr;
+	uint32_t boot_data_ptr;
+	uint32_t self;
+	uint32_t csf;
+	uint32_t reserved2;
+
+	struct imx_boot_data boot_data;
+	struct imx_ivt_header dcd_header;
+} __attribute__((packed));
+
+struct config_data {
+	uint32_t image_load_addr;
+	uint32_t image_dcd_offset;
+	uint32_t image_size;
+	uint32_t load_size;
+	char *outfile;
+	char *srkfile;
+	int header_version;
+	off_t header_gap;
+	uint32_t first_opcode;
+	int cpu_type;
+	int (*check)(const struct config_data *data, uint32_t cmd,
+		     uint32_t addr, uint32_t mask);
+	int (*write_mem)(const struct config_data *data, uint32_t addr,
+			 uint32_t val, int width, int set_bits, int clear_bits);
+	int (*nop)(const struct config_data *data);
+	int csf_space;
+	char *csf;
+};
+
+#define MAX_RECORDS_DCD_V2 1024
+struct imx_dcd_v2_write_rec {
+	uint32_t addr;
+	uint32_t val;
+} __attribute__((packed));
+
+struct imx_dcd_v2_write {
+	uint8_t tag;
+	uint16_t length;
+	uint8_t param;
+	struct imx_dcd_v2_write_rec data[MAX_RECORDS_DCD_V2];
+} __attribute__((packed));
+
+struct imx_dcd_v2_check {
+	uint8_t tag;
+	uint16_t length;
+	uint8_t param;
+	uint32_t addr;
+	uint32_t mask;
+	uint32_t count;
+} __attribute__((packed));
+
+enum imx_dcd_v2_check_cond {
+	until_all_bits_clear = 0, /* until ((*address & mask) == 0) { ...} */
+	until_any_bit_clear = 1, /* until ((*address & mask) != mask) { ...} */
+	until_all_bits_set = 2, /* until ((*address & mask) == mask) { ...} */
+	until_any_bit_set = 3, /* until ((*address & mask) != 0) { ...} */
+} __attribute__((packed));
+
+#endif
diff --git a/scripts/imx/imx.h b/scripts/imx/imx.h
index 92a3fd316..20fb1e876 100644
--- a/scripts/imx/imx.h
+++ b/scripts/imx/imx.h
@@ -1,116 +1,4 @@
 
-#define HEADER_LEN 0x1000	/* length of the blank area + IVT + DCD */
-
-/*
- * ============================================================================
- * i.MX flash header v1 handling. Found on i.MX35 and i.MX51
- * ============================================================================
- */
-#define DCD_BARKER       0xb17219e9
-
-struct imx_flash_header {
-	uint32_t app_code_jump_vector;
-	uint32_t app_code_barker;
-	uint32_t app_code_csf;
-	uint32_t dcd_ptr_ptr;
-	uint32_t super_root_key;
-	uint32_t dcd;
-	uint32_t app_dest;
-	uint32_t dcd_barker;
-	uint32_t dcd_block_len;
-} __attribute__((packed));
-
-struct imx_boot_data {
-	uint32_t start;
-	uint32_t size;
-	uint32_t plugin;
-} __attribute__((packed));
-
-struct imx_dcd_rec_v1 {
-	uint32_t type;
-	uint32_t addr;
-	uint32_t val;
-} __attribute__((packed));
-
-#define TAG_IVT_HEADER	0xd1
-#define IVT_VERSION	0x40
-#define TAG_DCD_HEADER	0xd2
-#define DCD_VERSION	0x40
-#define TAG_UNLOCK	0xb2
-#define TAG_NOP		0xc0
-#define TAG_WRITE	0xcc
-#define TAG_CHECK	0xcf
-#define PARAMETER_FLAG_MASK	(1 << 3)
-#define PARAMETER_FLAG_SET	(1 << 4)
-
-struct imx_ivt_header {
-	uint8_t tag;
-	uint16_t length;
-	uint8_t version;
-} __attribute__((packed));
-
-struct imx_flash_header_v2 {
-	struct imx_ivt_header header;
-
-	uint32_t entry;
-	uint32_t reserved1;
-	uint32_t dcd_ptr;
-	uint32_t boot_data_ptr;
-	uint32_t self;
-	uint32_t csf;
-	uint32_t reserved2;
-
-	struct imx_boot_data boot_data;
-	struct imx_ivt_header dcd_header;
-} __attribute__((packed));
-
-struct config_data {
-	uint32_t image_load_addr;
-	uint32_t image_dcd_offset;
-	uint32_t image_size;
-	uint32_t load_size;
-	char *outfile;
-	char *srkfile;
-	int header_version;
-	off_t header_gap;
-	uint32_t first_opcode;
-	int cpu_type;
-	int (*check)(const struct config_data *data, uint32_t cmd,
-		     uint32_t addr, uint32_t mask);
-	int (*write_mem)(const struct config_data *data, uint32_t addr,
-			 uint32_t val, int width, int set_bits, int clear_bits);
-	int (*nop)(const struct config_data *data);
-	int csf_space;
-	char *csf;
-};
-
-#define MAX_RECORDS_DCD_V2 1024
-struct imx_dcd_v2_write_rec {
-	uint32_t addr;
-	uint32_t val;
-} __attribute__((packed));
-
-struct imx_dcd_v2_write {
-	uint8_t tag;
-	uint16_t length;
-	uint8_t param;
-	struct imx_dcd_v2_write_rec data[MAX_RECORDS_DCD_V2];
-} __attribute__((packed));
-
-struct imx_dcd_v2_check {
-	uint8_t tag;
-	uint16_t length;
-	uint8_t param;
-	uint32_t addr;
-	uint32_t mask;
-	uint32_t count;
-} __attribute__((packed));
-
-enum imx_dcd_v2_check_cond {
-	until_all_bits_clear = 0, /* until ((*address & mask) == 0) { ...} */
-	until_any_bit_clear = 1, /* until ((*address & mask) != mask) { ...} */
-	until_all_bits_set = 2, /* until ((*address & mask) == mask) { ...} */
-	until_any_bit_set = 3, /* until ((*address & mask) != 0) { ...} */
-} __attribute__((packed));
+#include <mach/imx-header.h>
 
 int parse_config(struct config_data *data, const char *filename);
-- 
2.17.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH v2 07/12] ARM: i.MX: xload-esdhc: Make use of <mach/imx-header.h>
  2018-07-20  1:03 [PATCH v2 00/12] ARM: i.MX8MQ and EVK support, part II Andrey Smirnov
                   ` (5 preceding siblings ...)
  2018-07-20  1:03 ` [PATCH v2 06/12] ARM: i.MX: Move i.MX header definitions to mach-imx Andrey Smirnov
@ 2018-07-20  1:03 ` Andrey Smirnov
  2018-07-20  1:03 ` [PATCH v2 08/12] ARM: i.MX: xload-esdhc: Allow placing image to align its etnry point Andrey Smirnov
                   ` (5 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: Andrey Smirnov @ 2018-07-20  1:03 UTC (permalink / raw)
  To: barebox; +Cc: Andrey Smirnov

Convert esdhc_start_image() to use constants and data types from
<mach/imx-header.h>. Also, while at it, define a simple inline
function to test if an arbitrary binary blob is i.MX flash header v2.

Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
 arch/arm/mach-imx/include/mach/imx-header.h | 10 ++++++++++
 arch/arm/mach-imx/xload-esdhc.c             | 14 +++++++++-----
 2 files changed, 19 insertions(+), 5 deletions(-)

diff --git a/arch/arm/mach-imx/include/mach/imx-header.h b/arch/arm/mach-imx/include/mach/imx-header.h
index 4fedba7ad..c9b2a5881 100644
--- a/arch/arm/mach-imx/include/mach/imx-header.h
+++ b/arch/arm/mach-imx/include/mach/imx-header.h
@@ -1,6 +1,8 @@
 #ifndef __IMX_HEADER_H__
 #define __IMX_HEADER_H__
 
+#include <linux/types.h>
+
 #define HEADER_LEN 0x1000	/* length of the blank area + IVT + DCD */
 
 /*
@@ -66,6 +68,14 @@ struct imx_flash_header_v2 {
 	struct imx_ivt_header dcd_header;
 } __attribute__((packed));
 
+static inline bool is_imx_flash_header_v2(const void *blob)
+{
+	const struct imx_flash_header_v2 *hdr = blob;
+
+	return  hdr->header.tag == TAG_IVT_HEADER &&
+		hdr->header.version >= IVT_VERSION;
+}
+
 struct config_data {
 	uint32_t image_load_addr;
 	uint32_t image_dcd_offset;
diff --git a/arch/arm/mach-imx/xload-esdhc.c b/arch/arm/mach-imx/xload-esdhc.c
index 08ba9b08d..5ce83b0bf 100644
--- a/arch/arm/mach-imx/xload-esdhc.c
+++ b/arch/arm/mach-imx/xload-esdhc.c
@@ -18,6 +18,7 @@
 #include <mach/imx8mq-regs.h>
 #include <mach/xload.h>
 #include <linux/sizes.h>
+#include <mach/imx-header.h>
 #include "../../../drivers/mci/sdhci.h"
 #include "../../../drivers/mci/imx-esdhc.h"
 
@@ -220,8 +221,9 @@ static int esdhc_read_blocks(struct esdhc *esdhc, void *dst, size_t len)
 static int
 esdhc_start_image(struct esdhc *esdhc, ptrdiff_t address, u32 offset)
 {
+
 	void *buf = (void *)address;
-	u32 *ivt = buf + offset + SZ_1K;
+	struct imx_flash_header_v2 *hdr = buf + offset + SZ_1K;
 	int ret, len;
 	void __noreturn (*bb)(void);
 	unsigned int ofs;
@@ -233,9 +235,11 @@ esdhc_start_image(struct esdhc *esdhc, ptrdiff_t address, u32 offset)
 	if (ret)
 		return ret;
 
-	if (*(u32 *)(ivt) != 0x402000d1) {
-		pr_debug("IVT header not found on SD card. Found 0x%08x instead of 0x402000d1\n",
-				*ivt);
+	if (!is_imx_flash_header_v2(hdr)) {
+		pr_debug("IVT header not found on SD card. "
+			 "Found tag: 0x%02x length: 0x%04x version: %02x\n",
+			 hdr->header.tag, hdr->header.length,
+			 hdr->header.version);
 		return -EINVAL;
 	}
 
@@ -249,7 +253,7 @@ esdhc_start_image(struct esdhc *esdhc, ptrdiff_t address, u32 offset)
 
 	pr_debug("Image loaded successfully\n");
 
-	ofs = offset + *(ivt + 1) - *(ivt + 8);
+	ofs = offset + hdr->entry - hdr->boot_data.start;
 
 	bb = buf + ofs;
 
-- 
2.17.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH v2 08/12] ARM: i.MX: xload-esdhc: Allow placing image to align its etnry point
  2018-07-20  1:03 [PATCH v2 00/12] ARM: i.MX8MQ and EVK support, part II Andrey Smirnov
                   ` (6 preceding siblings ...)
  2018-07-20  1:03 ` [PATCH v2 07/12] ARM: i.MX: xload-esdhc: Make use of <mach/imx-header.h> Andrey Smirnov
@ 2018-07-20  1:03 ` Andrey Smirnov
  2018-07-20  1:03 ` [PATCH v2 09/12] ARM: nxp-imx8mq-evk: Add code to load ATF BL31 blob Andrey Smirnov
                   ` (4 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: Andrey Smirnov @ 2018-07-20  1:03 UTC (permalink / raw)
  To: barebox; +Cc: Andrey Smirnov

Allow placing image to align its etnry point with a particular entry
point address. This is needed for SoC's like i.MX8M where
vendor-provided ARM Trusted Firmware blob will exit at specific
pre-determined address and we need to be able to pick execution up
form there.

Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
 arch/arm/mach-imx/xload-esdhc.c | 39 ++++++++++++++++++++++++++++-----
 1 file changed, 34 insertions(+), 5 deletions(-)

diff --git a/arch/arm/mach-imx/xload-esdhc.c b/arch/arm/mach-imx/xload-esdhc.c
index 5ce83b0bf..55d6c6929 100644
--- a/arch/arm/mach-imx/xload-esdhc.c
+++ b/arch/arm/mach-imx/xload-esdhc.c
@@ -14,6 +14,7 @@
 #include <common.h>
 #include <io.h>
 #include <mci.h>
+#include <mach/atf.h>
 #include <mach/imx6-regs.h>
 #include <mach/imx8mq-regs.h>
 #include <mach/xload.h>
@@ -219,7 +220,7 @@ static int esdhc_read_blocks(struct esdhc *esdhc, void *dst, size_t len)
 }
 
 static int
-esdhc_start_image(struct esdhc *esdhc, ptrdiff_t address, u32 offset)
+esdhc_start_image(struct esdhc *esdhc, ptrdiff_t address, ptrdiff_t entry, u32 offset)
 {
 
 	void *buf = (void *)address;
@@ -245,6 +246,35 @@ esdhc_start_image(struct esdhc *esdhc, ptrdiff_t address, u32 offset)
 
 	pr_debug("Check ok, loading image\n");
 
+	ofs = offset + hdr->entry - hdr->boot_data.start;
+
+	if (entry != address) {
+		/*
+		 * Passing entry different from address is interpreted
+		 * as a request to place the image such that its entry
+		 * point would be exactly at 'entry', that is:
+		 *
+		 *     buf + ofs = entry
+		 *
+		 * solving the above for 'buf' gvies us the
+		 * adjustement that needs to be made:
+		 *
+		 *     buf = entry - ofs
+		 *
+		 */
+		if (WARN_ON(entry - ofs < address)) {
+			/*
+			 * We want to make sure we won't try to place
+			 * the start of the image before the beginning
+			 * of the memory buffer we were given in
+			 * address.
+			 */
+			return -EINVAL;
+		}
+
+		buf = (void *)(entry - ofs);
+	}
+
 	ret = esdhc_read_blocks(esdhc, buf, offset + len);
 	if (ret) {
 		pr_err("Loading image failed with %d\n", ret);
@@ -253,8 +283,6 @@ esdhc_start_image(struct esdhc *esdhc, ptrdiff_t address, u32 offset)
 
 	pr_debug("Image loaded successfully\n");
 
-	ofs = offset + hdr->entry - hdr->boot_data.start;
-
 	bb = buf + ofs;
 
 	bb();
@@ -295,7 +323,7 @@ int imx6_esdhc_start_image(int instance)
 
 	esdhc.is_mx6 = 1;
 
-	return esdhc_start_image(&esdhc, 0x10000000, 0);
+	return esdhc_start_image(&esdhc, 0x10000000, 0x10000000, 0);
 }
 
 /**
@@ -327,5 +355,6 @@ int imx8_esdhc_start_image(int instance)
 
 	esdhc.is_mx6 = 1;
 
-	return esdhc_start_image(&esdhc, MX8MQ_DDR_CSD1_BASE_ADDR, SZ_32K);
+	return esdhc_start_image(&esdhc, MX8MQ_DDR_CSD1_BASE_ADDR,
+				 MX8MQ_ATF_BL33_BASE_ADDR, SZ_32K);
 }
\ No newline at end of file
-- 
2.17.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH v2 09/12] ARM: nxp-imx8mq-evk: Add code to load ATF BL31 blob
  2018-07-20  1:03 [PATCH v2 00/12] ARM: i.MX8MQ and EVK support, part II Andrey Smirnov
                   ` (7 preceding siblings ...)
  2018-07-20  1:03 ` [PATCH v2 08/12] ARM: i.MX: xload-esdhc: Allow placing image to align its etnry point Andrey Smirnov
@ 2018-07-20  1:03 ` Andrey Smirnov
  2018-07-20  1:03 ` [PATCH v2 10/12] ARM: i.MX8MQ: Query and display ATF fimware hash if availible Andrey Smirnov
                   ` (3 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: Andrey Smirnov @ 2018-07-20  1:03 UTC (permalink / raw)
  To: barebox; +Cc: Andrey Smirnov

Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
 arch/arm/boards/nxp-imx8mq-evk/lowlevel.c | 9 +++++++++
 arch/arm/mach-imx/Kconfig                 | 2 ++
 2 files changed, 11 insertions(+)

diff --git a/arch/arm/boards/nxp-imx8mq-evk/lowlevel.c b/arch/arm/boards/nxp-imx8mq-evk/lowlevel.c
index 1ed918ee0..db746bb94 100644
--- a/arch/arm/boards/nxp-imx8mq-evk/lowlevel.c
+++ b/arch/arm/boards/nxp-imx8mq-evk/lowlevel.c
@@ -23,6 +23,7 @@
 #include <asm/cache.h>
 #include <asm/sections.h>
 #include <asm/mmu.h>
+#include <mach/atf.h>
 
 #include "ddr.h"
 
@@ -75,6 +76,14 @@ ENTRY_FUNCTION(start_nxp_imx8mq_evk, r0, r1, r2)
 	if (get_pc() < MX8MQ_DDR_CSD1_BASE_ADDR)
 		nxp_imx8mq_evk_sram_setup();
 
+	if (current_el() == 3) {
+		const u8 *bl31;
+		size_t bl31_size;
+
+		get_builtin_firmware(imx_imx8m_bl31_bin, &bl31, &bl31_size);
+		imx8mq_atf_load_bl31(bl31, bl31_size);
+	}
+
 	barebox_arm_entry(MX8MQ_DDR_CSD1_BASE_ADDR,
 			  SZ_2G + SZ_1G, __dtb_imx8mq_evk_start);
 }
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index 73b7ea1b6..7cb9138d2 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -461,6 +461,8 @@ config MACH_NXP_IMX8MQ_EVK
 	bool "NXP i.MX8MQ EVK Board"
 	select ARCH_IMX8MQ
 	select FIRMWARE_IMX_LPDDR4_PMU_TRAIN
+	select FIRMWARE_IMX8MQ_ATF
+	select ARM_SMCCC
 
 endif
 
-- 
2.17.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH v2 10/12] ARM: i.MX8MQ: Query and display ATF fimware hash if availible
  2018-07-20  1:03 [PATCH v2 00/12] ARM: i.MX8MQ and EVK support, part II Andrey Smirnov
                   ` (8 preceding siblings ...)
  2018-07-20  1:03 ` [PATCH v2 09/12] ARM: nxp-imx8mq-evk: Add code to load ATF BL31 blob Andrey Smirnov
@ 2018-07-20  1:03 ` Andrey Smirnov
  2018-07-20  1:03 ` [PATCH v2 11/12] ARM: nxp-imx8mq-evk: Add bootflow comments Andrey Smirnov
                   ` (2 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: Andrey Smirnov @ 2018-07-20  1:03 UTC (permalink / raw)
  To: barebox; +Cc: Andrey Smirnov

Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
 arch/arm/mach-imx/imx8mq.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/arch/arm/mach-imx/imx8mq.c b/arch/arm/mach-imx/imx8mq.c
index dbcf4fa59..152f07bc1 100644
--- a/arch/arm/mach-imx/imx8mq.c
+++ b/arch/arm/mach-imx/imx8mq.c
@@ -20,11 +20,16 @@
 #include <mach/revision.h>
 #include <mach/imx8mq-regs.h>
 
+#include <linux/arm-smccc.h>
+
 #define IMX8MQ_ROM_VERSION_A0	0x800
 #define IMX8MQ_ROM_VERSION_B0	0x83C
 
 #define MX8MQ_ANATOP_DIGPROG	0x6c
 
+#define FSL_SIP_BUILDINFO			0xC2000003
+#define FSL_SIP_BUILDINFO_GET_COMMITHASH	0x00
+
 static void imx8mq_silicon_revision(void)
 {
 	void __iomem *anatop = IOMEM(MX8MQ_ANATOP_BASE_ADDR);
@@ -81,7 +86,17 @@ core_initcall(imx8mq_init_syscnt_frequency);
 
 int imx8mq_init(void)
 {
+	struct arm_smccc_res res;
+
 	imx8mq_silicon_revision();
 
+	if (IS_ENABLED(CONFIG_ARM_SMCCC) &&
+	    IS_ENABLED(CONFIG_FIRMWARE_IMX8MQ_ATF)) {
+		arm_smccc_smc(FSL_SIP_BUILDINFO,
+			      FSL_SIP_BUILDINFO_GET_COMMITHASH,
+			      0, 0, 0, 0, 0, 0, &res);
+		pr_info("i.MX ARM Trusted Firmware: %s\n", (char *)&res.a0);
+	}
+
 	return 0;
 }
-- 
2.17.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH v2 11/12] ARM: nxp-imx8mq-evk: Add bootflow comments
  2018-07-20  1:03 [PATCH v2 00/12] ARM: i.MX8MQ and EVK support, part II Andrey Smirnov
                   ` (9 preceding siblings ...)
  2018-07-20  1:03 ` [PATCH v2 10/12] ARM: i.MX8MQ: Query and display ATF fimware hash if availible Andrey Smirnov
@ 2018-07-20  1:03 ` Andrey Smirnov
  2018-07-20  1:03 ` [PATCH v2 12/12] firmware: Fix copy-paste comment mistake Andrey Smirnov
  2018-08-08  6:34 ` [PATCH v2 00/12] ARM: i.MX8MQ and EVK support, part II Sascha Hauer
  12 siblings, 0 replies; 14+ messages in thread
From: Andrey Smirnov @ 2018-07-20  1:03 UTC (permalink / raw)
  To: barebox; +Cc: Andrey Smirnov

Add some notes on how the boot-flow goes while I still remember it.

Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
 arch/arm/boards/nxp-imx8mq-evk/lowlevel.c | 41 +++++++++++++++++++++--
 1 file changed, 39 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boards/nxp-imx8mq-evk/lowlevel.c b/arch/arm/boards/nxp-imx8mq-evk/lowlevel.c
index db746bb94..fdc964ac9 100644
--- a/arch/arm/boards/nxp-imx8mq-evk/lowlevel.c
+++ b/arch/arm/boards/nxp-imx8mq-evk/lowlevel.c
@@ -66,6 +66,26 @@ static void nxp_imx8mq_evk_sram_setup(void)
 	BUG_ON(ret);
 }
 
+/*
+ * Power-on execution flow of start_nxp_imx8mq_evk() might not be
+ * obvious for a very frist read, so here's, hopefully helpful,
+ * summary:
+ *
+ * 1. MaskROM uploads PBL into OCRAM and that's where this function is
+ *    executed for the first time
+ *
+ * 2. DDR is initialized and full i.MX image is loaded to the
+ *    beginning of RAM
+ *
+ * 3. start_nxp_imx8mq_evk, now in RAM, is executed again
+ *
+ * 4. BL31 blob is uploaded to OCRAM and the control is transfer to it
+ *
+ * 5. BL31 exits EL3 into EL2 at address MX8MQ_ATF_BL33_BASE_ADDR,
+ *    executing start_nxp_imx8mq_evk() the third time
+ *
+ * 6. Standard barebox boot flow continues
+ */
 ENTRY_FUNCTION(start_nxp_imx8mq_evk, r0, r1, r2)
 {
 	arm_cpu_lowlevel_init();
@@ -73,9 +93,23 @@ ENTRY_FUNCTION(start_nxp_imx8mq_evk, r0, r1, r2)
 	if (IS_ENABLED(CONFIG_DEBUG_LL))
 		setup_uart();
 
-	if (get_pc() < MX8MQ_DDR_CSD1_BASE_ADDR)
+	if (get_pc() < MX8MQ_DDR_CSD1_BASE_ADDR) {
+		/*
+		 * We assume that we were just loaded by MaskROM into
+		 * SRAM if we are not running from DDR. We also assume
+		 * that means DDR needs to be initialized for the
+		 * first time.
+		 */
 		nxp_imx8mq_evk_sram_setup();
-
+	}
+	/*
+	 * Straight from the power-on we are at EL3, so the following
+	 * code _will_ load and jump to ATF.
+	 *
+	 * However when we are re-executed upon exit from ATF's
+	 * initialization routine, it is EL2 which means we'll skip
+	 * loadting ATF blob again
+	 */
 	if (current_el() == 3) {
 		const u8 *bl31;
 		size_t bl31_size;
@@ -84,6 +118,9 @@ ENTRY_FUNCTION(start_nxp_imx8mq_evk, r0, r1, r2)
 		imx8mq_atf_load_bl31(bl31, bl31_size);
 	}
 
+	/*
+	 * Standard entry we hit once we initialized both DDR and ATF
+	 */
 	barebox_arm_entry(MX8MQ_DDR_CSD1_BASE_ADDR,
 			  SZ_2G + SZ_1G, __dtb_imx8mq_evk_start);
 }
-- 
2.17.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH v2 12/12] firmware: Fix copy-paste comment mistake
  2018-07-20  1:03 [PATCH v2 00/12] ARM: i.MX8MQ and EVK support, part II Andrey Smirnov
                   ` (10 preceding siblings ...)
  2018-07-20  1:03 ` [PATCH v2 11/12] ARM: nxp-imx8mq-evk: Add bootflow comments Andrey Smirnov
@ 2018-07-20  1:03 ` Andrey Smirnov
  2018-08-08  6:34 ` [PATCH v2 00/12] ARM: i.MX8MQ and EVK support, part II Sascha Hauer
  12 siblings, 0 replies; 14+ messages in thread
From: Andrey Smirnov @ 2018-07-20  1:03 UTC (permalink / raw)
  To: barebox; +Cc: Andrey Smirnov

Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
 firmware/Makefile | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/firmware/Makefile b/firmware/Makefile
index 62124933d..7f4dc4932 100644
--- a/firmware/Makefile
+++ b/firmware/Makefile
@@ -57,6 +57,6 @@ endif
 targets := $(patsubst $(obj)/%,%, \
                                 $(shell find $(obj) -name \*.gen.S 2>/dev/null))
 
-# just to build a built-in.o. Otherwise compilation fails when no devicetree is
-# created.
+# just to build a built-in.o. Otherwise compilation fails when no
+# firmware is built.
 obj- += dummy.o
-- 
2.17.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v2 00/12] ARM: i.MX8MQ and EVK support, part II
  2018-07-20  1:03 [PATCH v2 00/12] ARM: i.MX8MQ and EVK support, part II Andrey Smirnov
                   ` (11 preceding siblings ...)
  2018-07-20  1:03 ` [PATCH v2 12/12] firmware: Fix copy-paste comment mistake Andrey Smirnov
@ 2018-08-08  6:34 ` Sascha Hauer
  12 siblings, 0 replies; 14+ messages in thread
From: Sascha Hauer @ 2018-08-08  6:34 UTC (permalink / raw)
  To: Andrey Smirnov; +Cc: barebox

On Thu, Jul 19, 2018 at 06:03:45PM -0700, Andrey Smirnov wrote:
> Everyone:
> 
> This is part II of i.MX8MQ EVK board support patches. This time this
> is bits and pieces that were necessary in order to allow booting
> vendor Linux kernel availible here (tag: rel_imx_4.9.51_8mq_ga):
> 
>     https://source.codeaurora.org/external/imx/linux-imx
> 
> Sources for ATF were taken from here (tag: rel_imx_4.9.51_8mq_ga):
> 
>     https://source.codeaurora.org/external/imx/imx-atf
> 
> This patchest is also availible at:
> 
>     https://github.com/ndreys/barebox/tree/imx8m-support-part-II-v2
> 
> Feedback is welcome!
> 
> Changes since [v1]:
> 
>     - Opcode patching is replaced with placing barebox image at the
>       right spot
> 
>     - ATF loading code is converted into a function (was a macro
>       originally)
> 
>     - It is now up to the user to check current EL when calling
>       imx8mq_atf_load_bl31()
> 
>     - Other various small change as per Sascha's feedback
> 
> [v1] http://lists.infradead.org/pipermail/barebox/2018-June/033922.html
> 
> Thanks,
> Andrey Smirnov

Applied with some typos fixed, thanks

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2018-08-08  6:34 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-07-20  1:03 [PATCH v2 00/12] ARM: i.MX8MQ and EVK support, part II Andrey Smirnov
2018-07-20  1:03 ` [PATCH v2 01/12] ARM: nxp-imx8mq-evk: Update DDR initialization code Andrey Smirnov
2018-07-20  1:03 ` [PATCH v2 02/12] ARM: Add code to support SMCCC on AArch64 Andrey Smirnov
2018-07-20  1:03 ` [PATCH v2 03/12] ARM: i.MX8MQ: Configure cntfrq only in EL3 Andrey Smirnov
2018-07-20  1:03 ` [PATCH v2 04/12] ARM: i.MX8MQ: Add code to load BL31 ATF blob Andrey Smirnov
2018-07-20  1:03 ` [PATCH v2 05/12] ARM: i.MX: fimware: Add pre-built " Andrey Smirnov
2018-07-20  1:03 ` [PATCH v2 06/12] ARM: i.MX: Move i.MX header definitions to mach-imx Andrey Smirnov
2018-07-20  1:03 ` [PATCH v2 07/12] ARM: i.MX: xload-esdhc: Make use of <mach/imx-header.h> Andrey Smirnov
2018-07-20  1:03 ` [PATCH v2 08/12] ARM: i.MX: xload-esdhc: Allow placing image to align its etnry point Andrey Smirnov
2018-07-20  1:03 ` [PATCH v2 09/12] ARM: nxp-imx8mq-evk: Add code to load ATF BL31 blob Andrey Smirnov
2018-07-20  1:03 ` [PATCH v2 10/12] ARM: i.MX8MQ: Query and display ATF fimware hash if availible Andrey Smirnov
2018-07-20  1:03 ` [PATCH v2 11/12] ARM: nxp-imx8mq-evk: Add bootflow comments Andrey Smirnov
2018-07-20  1:03 ` [PATCH v2 12/12] firmware: Fix copy-paste comment mistake Andrey Smirnov
2018-08-08  6:34 ` [PATCH v2 00/12] ARM: i.MX8MQ and EVK support, part II Sascha Hauer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox