diff mbox series

arm: Add (back) VExpress boards support

Message ID 20210629114555.20805-1-andre.przywara@arm.com
State Changes Requested
Delegated to: Tom Rini
Headers show
Series arm: Add (back) VExpress boards support | expand

Commit Message

Andre Przywara June 29, 2021, 11:45 a.m. UTC
The v2021.07 merge window saw the removal of the Arm Ltd. Versatile
Express platform, along with their CA5, CA9 and TC2 boards. The trigger
was the missing conversion of the MMC driver.

Some folks complained about that internally, so bring those boards back,
but better than ever:
- Use DM and OF_CONTROL for all the boards. Use the .dts files from the
  latest Linux kernel (5.13) for that.
- Move the board selection choice into the platform's Kconfig.
- Clean up some shared config and common definitions.
- Drop obsolete features like ATAGs support.
- Switch to the DM_ETH version of the SMC911X Ethernet driver.
- Drop MMC support.

The PL180 MMC driver actually supports DM_MMC, but that requires a
DM_GPIO driver for the card detect GPIO, which we don't have. This
specific GPIO is actually handled via the "sysregs" device, so we would
need a driver for that. QEMU does not emulate this part, also the DT
description is somewhat "special", so this is left for later.

This version compiles without any warning for all three boards now.
Tested on QEMU.

Signed-off-by: Andre Przywara <andre.przywara@arm.com>
---
Hi,

this relies on the SMC911x driver DT changes, as posted here:
https://lists.denx.de/pipermail/u-boot/2021-June/452989.html
I put a version with the changes broken down here:
https://github.com/Andre-ARM/u-boot/commits/tc2-history

This was tested on QEMU, for vexpress_ca15_tc2_defconfig with:
$ qemu-system-arm -M vexpress-a15,secure=on -cpu cortex-a15 -m 1G -smp 1 \
  -drive file=tramp-tc2.bin,if=pflash,format=raw,read-only \
  -device loader,file=u-boot.bin,addr=0x80800000 -nographic

Where tramp-tc2.bin is a trampoline replacing the board's firmware:
00000000  00 00 a0 e3 80 00 48 e3  10 ff 2f e1
(mov r0, #0; movt r0, #0x8080; bx r0)

The vexpress_ca9x4_defconfig uses a different memory map, so the runes are:
$ qemu-system-arm -M vexpress-a9 -cpu cortex-a9 -m 1G -smp 1 \
  -drive file=tramp-ca9.bin,if=pflash,format=raw,read-only \
  -device loader,file=u-boot.bin,addr=0x60800000 -nographic

tramp-ca9.bin:
00000000  00 00 a0 e3 80 00 46 e3  10 ff 2f e1
(mov r0, #0; movt r0, #0x6080; bx r0)

Cheers,
Andre

 .azure-pipelines.yml                          |   6 +
 .gitlab-ci.yml                                |  12 +
 Kconfig                                       |   2 +-
 arch/arm/Kconfig                              |  16 +
 arch/arm/dts/Makefile                         |   5 +
 arch/arm/dts/vexpress-v2m-rs1.dtsi            | 441 +++++++++++
 arch/arm/dts/vexpress-v2m.dtsi                | 454 ++++++++++++
 arch/arm/dts/vexpress-v2p-ca15_a7.dts         | 691 ++++++++++++++++++
 arch/arm/dts/vexpress-v2p-ca5s.dts            | 280 +++++++
 arch/arm/dts/vexpress-v2p-ca9.dts             | 368 ++++++++++
 board/armltd/vexpress/Kconfig                 |  39 +
 board/armltd/vexpress/MAINTAINERS             |   8 +
 board/armltd/vexpress/Makefile                |   7 +
 board/armltd/vexpress/vexpress_common.c       | 196 +++++
 board/armltd/vexpress/vexpress_tc2.c          |  82 +++
 configs/vexpress_ca15_tc2_defconfig           |  16 +
 configs/vexpress_ca5x2_defconfig              |  15 +
 configs/vexpress_ca9x4_defconfig              |  15 +
 drivers/i2c/Kconfig                           |   2 +-
 env/Kconfig                                   |   5 +-
 .../configs/{vexpress_common.h => vexpress.h} |  99 +--
 scripts/config_whitelist.txt                  |   1 -
 22 files changed, 2671 insertions(+), 89 deletions(-)
 create mode 100644 arch/arm/dts/vexpress-v2m-rs1.dtsi
 create mode 100644 arch/arm/dts/vexpress-v2m.dtsi
 create mode 100644 arch/arm/dts/vexpress-v2p-ca15_a7.dts
 create mode 100644 arch/arm/dts/vexpress-v2p-ca5s.dts
 create mode 100644 arch/arm/dts/vexpress-v2p-ca9.dts
 create mode 100644 board/armltd/vexpress/Kconfig
 create mode 100644 board/armltd/vexpress/MAINTAINERS
 create mode 100644 board/armltd/vexpress/Makefile
 create mode 100644 board/armltd/vexpress/vexpress_common.c
 create mode 100644 board/armltd/vexpress/vexpress_tc2.c
 create mode 100644 configs/vexpress_ca15_tc2_defconfig
 create mode 100644 configs/vexpress_ca5x2_defconfig
 create mode 100644 configs/vexpress_ca9x4_defconfig
 rename include/configs/{vexpress_common.h => vexpress.h} (62%)

Comments

Tom Rini June 29, 2021, 12:11 p.m. UTC | #1
On Tue, Jun 29, 2021 at 12:45:55PM +0100, Andre Przywara wrote:

> The v2021.07 merge window saw the removal of the Arm Ltd. Versatile
> Express platform, along with their CA5, CA9 and TC2 boards. The trigger
> was the missing conversion of the MMC driver.
> 
> Some folks complained about that internally, so bring those boards back,
> but better than ever:
> - Use DM and OF_CONTROL for all the boards. Use the .dts files from the
>   latest Linux kernel (5.13) for that.
> - Move the board selection choice into the platform's Kconfig.
> - Clean up some shared config and common definitions.
> - Drop obsolete features like ATAGs support.
> - Switch to the DM_ETH version of the SMC911X Ethernet driver.
> - Drop MMC support.
> 
> The PL180 MMC driver actually supports DM_MMC, but that requires a
> DM_GPIO driver for the card detect GPIO, which we don't have. This
> specific GPIO is actually handled via the "sysregs" device, so we would
> need a driver for that. QEMU does not emulate this part, also the DT
> description is somewhat "special", so this is left for later.
> 
> This version compiles without any warning for all three boards now.
> Tested on QEMU.
> 
> Signed-off-by: Andre Przywara <andre.przywara@arm.com>
> ---
> Hi,
> 
> this relies on the SMC911x driver DT changes, as posted here:
> https://lists.denx.de/pipermail/u-boot/2021-June/452989.html
> I put a version with the changes broken down here:
> https://github.com/Andre-ARM/u-boot/commits/tc2-history
> 
> This was tested on QEMU, for vexpress_ca15_tc2_defconfig with:
> $ qemu-system-arm -M vexpress-a15,secure=on -cpu cortex-a15 -m 1G -smp 1 \
>   -drive file=tramp-tc2.bin,if=pflash,format=raw,read-only \
>   -device loader,file=u-boot.bin,addr=0x80800000 -nographic
> 
> Where tramp-tc2.bin is a trampoline replacing the board's firmware:
> 00000000  00 00 a0 e3 80 00 48 e3  10 ff 2f e1
> (mov r0, #0; movt r0, #0x8080; bx r0)
> 
> The vexpress_ca9x4_defconfig uses a different memory map, so the runes are:
> $ qemu-system-arm -M vexpress-a9 -cpu cortex-a9 -m 1G -smp 1 \
>   -drive file=tramp-ca9.bin,if=pflash,format=raw,read-only \
>   -device loader,file=u-boot.bin,addr=0x60800000 -nographic
> 
> tramp-ca9.bin:
> 00000000  00 00 a0 e3 80 00 46 e3  10 ff 2f e1
> (mov r0, #0; movt r0, #0x6080; bx r0)

My big question is how do we run this in CI?  Or does it not _need_ that
firmware file to really exist?  Or is there a pending change to
https://gitlab.denx.de/u-boot/u-boot-test-hooks.git to generate / just
have exist those magic empty bins?  Thanks!
Andre Przywara June 29, 2021, 2:15 p.m. UTC | #2
On Tue, 29 Jun 2021 08:11:22 -0400
Tom Rini <trini@konsulko.com> wrote:

> On Tue, Jun 29, 2021 at 12:45:55PM +0100, Andre Przywara wrote:
> 
> > The v2021.07 merge window saw the removal of the Arm Ltd. Versatile
> > Express platform, along with their CA5, CA9 and TC2 boards. The trigger
> > was the missing conversion of the MMC driver.
> > 
> > Some folks complained about that internally, so bring those boards back,
> > but better than ever:
> > - Use DM and OF_CONTROL for all the boards. Use the .dts files from the
> >   latest Linux kernel (5.13) for that.
> > - Move the board selection choice into the platform's Kconfig.
> > - Clean up some shared config and common definitions.
> > - Drop obsolete features like ATAGs support.
> > - Switch to the DM_ETH version of the SMC911X Ethernet driver.
> > - Drop MMC support.
> > 
> > The PL180 MMC driver actually supports DM_MMC, but that requires a
> > DM_GPIO driver for the card detect GPIO, which we don't have. This
> > specific GPIO is actually handled via the "sysregs" device, so we would
> > need a driver for that. QEMU does not emulate this part, also the DT
> > description is somewhat "special", so this is left for later.
> > 
> > This version compiles without any warning for all three boards now.
> > Tested on QEMU.
> > 
> > Signed-off-by: Andre Przywara <andre.przywara@arm.com>
> > ---
> > Hi,
> > 
> > this relies on the SMC911x driver DT changes, as posted here:
> > https://lists.denx.de/pipermail/u-boot/2021-June/452989.html
> > I put a version with the changes broken down here:
> > https://github.com/Andre-ARM/u-boot/commits/tc2-history
> > 
> > This was tested on QEMU, for vexpress_ca15_tc2_defconfig with:
> > $ qemu-system-arm -M vexpress-a15,secure=on -cpu cortex-a15 -m 1G -smp 1 \
> >   -drive file=tramp-tc2.bin,if=pflash,format=raw,read-only \
> >   -device loader,file=u-boot.bin,addr=0x80800000 -nographic
> > 
> > Where tramp-tc2.bin is a trampoline replacing the board's firmware:
> > 00000000  00 00 a0 e3 80 00 48 e3  10 ff 2f e1
> > (mov r0, #0; movt r0, #0x8080; bx r0)
> > 
> > The vexpress_ca9x4_defconfig uses a different memory map, so the runes are:
> > $ qemu-system-arm -M vexpress-a9 -cpu cortex-a9 -m 1G -smp 1 \
> >   -drive file=tramp-ca9.bin,if=pflash,format=raw,read-only \
> >   -device loader,file=u-boot.bin,addr=0x60800000 -nographic
> > 
> > tramp-ca9.bin:
> > 00000000  00 00 a0 e3 80 00 46 e3  10 ff 2f e1
> > (mov r0, #0; movt r0, #0x6080; bx r0)  
> 
> My big question is how do we run this in CI?  Or does it not _need_ that
> firmware file to really exist?  Or is there a pending change to
> https://gitlab.denx.de/u-boot/u-boot-test-hooks.git to generate / just
> have exist those magic empty bins?  Thanks!

So from digging into this I see that this loads U-Boot's ELF build, via
QEMU's -kernel parameter. Which is fine, but not really what is
happening on real hardware.
I checked and the v2021.04 version worked with this approach, but my
build does not.
I will have a look into this now.

Thanks!
Andre
Andre Przywara June 29, 2021, 4:52 p.m. UTC | #3
On Tue, 29 Jun 2021 15:15:52 +0100
Andre Przywara <andre.przywara@arm.com> wrote:

Hi,

> On Tue, 29 Jun 2021 08:11:22 -0400
> Tom Rini <trini@konsulko.com> wrote:
> 
> > On Tue, Jun 29, 2021 at 12:45:55PM +0100, Andre Przywara wrote:
> >   
> > > The v2021.07 merge window saw the removal of the Arm Ltd. Versatile
> > > Express platform, along with their CA5, CA9 and TC2 boards. The trigger
> > > was the missing conversion of the MMC driver.
> > > 
> > > Some folks complained about that internally, so bring those boards back,
> > > but better than ever:
> > > - Use DM and OF_CONTROL for all the boards. Use the .dts files from the
> > >   latest Linux kernel (5.13) for that.
> > > - Move the board selection choice into the platform's Kconfig.
> > > - Clean up some shared config and common definitions.
> > > - Drop obsolete features like ATAGs support.
> > > - Switch to the DM_ETH version of the SMC911X Ethernet driver.
> > > - Drop MMC support.
> > > 
> > > The PL180 MMC driver actually supports DM_MMC, but that requires a
> > > DM_GPIO driver for the card detect GPIO, which we don't have. This
> > > specific GPIO is actually handled via the "sysregs" device, so we would
> > > need a driver for that. QEMU does not emulate this part, also the DT
> > > description is somewhat "special", so this is left for later.
> > > 
> > > This version compiles without any warning for all three boards now.
> > > Tested on QEMU.
> > > 
> > > Signed-off-by: Andre Przywara <andre.przywara@arm.com>
> > > ---
> > > Hi,
> > > 
> > > this relies on the SMC911x driver DT changes, as posted here:
> > > https://lists.denx.de/pipermail/u-boot/2021-June/452989.html
> > > I put a version with the changes broken down here:
> > > https://github.com/Andre-ARM/u-boot/commits/tc2-history
> > > 
> > > This was tested on QEMU, for vexpress_ca15_tc2_defconfig with:
> > > $ qemu-system-arm -M vexpress-a15,secure=on -cpu cortex-a15 -m 1G -smp 1 \
> > >   -drive file=tramp-tc2.bin,if=pflash,format=raw,read-only \
> > >   -device loader,file=u-boot.bin,addr=0x80800000 -nographic
> > > 
> > > Where tramp-tc2.bin is a trampoline replacing the board's firmware:
> > > 00000000  00 00 a0 e3 80 00 48 e3  10 ff 2f e1
> > > (mov r0, #0; movt r0, #0x8080; bx r0)
> > > 
> > > The vexpress_ca9x4_defconfig uses a different memory map, so the runes are:
> > > $ qemu-system-arm -M vexpress-a9 -cpu cortex-a9 -m 1G -smp 1 \
> > >   -drive file=tramp-ca9.bin,if=pflash,format=raw,read-only \
> > >   -device loader,file=u-boot.bin,addr=0x60800000 -nographic
> > > 
> > > tramp-ca9.bin:
> > > 00000000  00 00 a0 e3 80 00 46 e3  10 ff 2f e1
> > > (mov r0, #0; movt r0, #0x6080; bx r0)    
> > 
> > My big question is how do we run this in CI?  Or does it not _need_ that
> > firmware file to really exist?  Or is there a pending change to
> > https://gitlab.denx.de/u-boot/u-boot-test-hooks.git to generate / just
> > have exist those magic empty bins?  Thanks!  
> 
> So from digging into this I see that this loads U-Boot's ELF build, via
> QEMU's -kernel parameter. Which is fine, but not really what is
> happening on real hardware.
> I checked and the v2021.04 version worked with this approach, but my
> build does not.
> I will have a look into this now.

The new build uses OF_CONTROL and OF_SEPARATE, so the DTB gets appended
to the U-Boot *image*. The ELF file is not treated this way, so the
code reads only 0s after the end of the U-Boot code - which makes it
die silently. Manually loading the DTB into DRAM would be fragile at
best, but is also rejected by QEMU, because the LOAD program header
extend for a few dozen bytes beyond U-Boot's "end" symbol, so it
overlaps.

IIRC we don't have position independent code for ARM, so we can't load
U-Boot into flash directly (which also would require some code changes
first).

Anyway I don't think we should change any code to cope with that (by
using another method to find the DTB), so adjusting the QEMU recipe
sounds like a better idea.

Is there a way to add those 12 byte trampoline files to the CI repo? Or
shall they be created on the fly somehow?

Or can you think of another way to get those builds tested?

Cheers,
Andre
Tom Rini June 29, 2021, 6:03 p.m. UTC | #4
On Tue, Jun 29, 2021 at 05:52:10PM +0100, Andre Przywara wrote:
> On Tue, 29 Jun 2021 15:15:52 +0100
> Andre Przywara <andre.przywara@arm.com> wrote:
> 
> Hi,
> 
> > On Tue, 29 Jun 2021 08:11:22 -0400
> > Tom Rini <trini@konsulko.com> wrote:
> > 
> > > On Tue, Jun 29, 2021 at 12:45:55PM +0100, Andre Przywara wrote:
> > >   
> > > > The v2021.07 merge window saw the removal of the Arm Ltd. Versatile
> > > > Express platform, along with their CA5, CA9 and TC2 boards. The trigger
> > > > was the missing conversion of the MMC driver.
> > > > 
> > > > Some folks complained about that internally, so bring those boards back,
> > > > but better than ever:
> > > > - Use DM and OF_CONTROL for all the boards. Use the .dts files from the
> > > >   latest Linux kernel (5.13) for that.
> > > > - Move the board selection choice into the platform's Kconfig.
> > > > - Clean up some shared config and common definitions.
> > > > - Drop obsolete features like ATAGs support.
> > > > - Switch to the DM_ETH version of the SMC911X Ethernet driver.
> > > > - Drop MMC support.
> > > > 
> > > > The PL180 MMC driver actually supports DM_MMC, but that requires a
> > > > DM_GPIO driver for the card detect GPIO, which we don't have. This
> > > > specific GPIO is actually handled via the "sysregs" device, so we would
> > > > need a driver for that. QEMU does not emulate this part, also the DT
> > > > description is somewhat "special", so this is left for later.
> > > > 
> > > > This version compiles without any warning for all three boards now.
> > > > Tested on QEMU.
> > > > 
> > > > Signed-off-by: Andre Przywara <andre.przywara@arm.com>
> > > > ---
> > > > Hi,
> > > > 
> > > > this relies on the SMC911x driver DT changes, as posted here:
> > > > https://lists.denx.de/pipermail/u-boot/2021-June/452989.html
> > > > I put a version with the changes broken down here:
> > > > https://github.com/Andre-ARM/u-boot/commits/tc2-history
> > > > 
> > > > This was tested on QEMU, for vexpress_ca15_tc2_defconfig with:
> > > > $ qemu-system-arm -M vexpress-a15,secure=on -cpu cortex-a15 -m 1G -smp 1 \
> > > >   -drive file=tramp-tc2.bin,if=pflash,format=raw,read-only \
> > > >   -device loader,file=u-boot.bin,addr=0x80800000 -nographic
> > > > 
> > > > Where tramp-tc2.bin is a trampoline replacing the board's firmware:
> > > > 00000000  00 00 a0 e3 80 00 48 e3  10 ff 2f e1
> > > > (mov r0, #0; movt r0, #0x8080; bx r0)
> > > > 
> > > > The vexpress_ca9x4_defconfig uses a different memory map, so the runes are:
> > > > $ qemu-system-arm -M vexpress-a9 -cpu cortex-a9 -m 1G -smp 1 \
> > > >   -drive file=tramp-ca9.bin,if=pflash,format=raw,read-only \
> > > >   -device loader,file=u-boot.bin,addr=0x60800000 -nographic
> > > > 
> > > > tramp-ca9.bin:
> > > > 00000000  00 00 a0 e3 80 00 46 e3  10 ff 2f e1
> > > > (mov r0, #0; movt r0, #0x6080; bx r0)    
> > > 
> > > My big question is how do we run this in CI?  Or does it not _need_ that
> > > firmware file to really exist?  Or is there a pending change to
> > > https://gitlab.denx.de/u-boot/u-boot-test-hooks.git to generate / just
> > > have exist those magic empty bins?  Thanks!  
> > 
> > So from digging into this I see that this loads U-Boot's ELF build, via
> > QEMU's -kernel parameter. Which is fine, but not really what is
> > happening on real hardware.
> > I checked and the v2021.04 version worked with this approach, but my
> > build does not.
> > I will have a look into this now.
> 
> The new build uses OF_CONTROL and OF_SEPARATE, so the DTB gets appended
> to the U-Boot *image*. The ELF file is not treated this way, so the
> code reads only 0s after the end of the U-Boot code - which makes it
> die silently. Manually loading the DTB into DRAM would be fragile at
> best, but is also rejected by QEMU, because the LOAD program header
> extend for a few dozen bytes beyond U-Boot's "end" symbol, so it
> overlaps.

Can't we pass the device tree to qemu (and in turn through to U-Boot) in
a clean and out of the box way?  I thought there was a way to do that..

> IIRC we don't have position independent code for ARM, so we can't load
> U-Boot into flash directly (which also would require some code changes
> first).

Do you mean generate a file to use as the system flash and have U-Boot
be in the correct spot within that file?  If so
bin/travis-ci/conf.qemu_mips_na in the test hooks repo might give you
some hints.

> Anyway I don't think we should change any code to cope with that (by
> using another method to find the DTB), so adjusting the QEMU recipe
> sounds like a better idea.
> 
> Is there a way to add those 12 byte trampoline files to the CI repo? Or
> shall they be created on the fly somehow?

If we need to include the trampoline files, however it's easiest is
fine.
Andre Przywara June 30, 2021, 12:12 a.m. UTC | #5
On Tue, 29 Jun 2021 14:03:23 -0400
Tom Rini <trini@konsulko.com> wrote:

Hi Tom,

> On Tue, Jun 29, 2021 at 05:52:10PM +0100, Andre Przywara wrote:
> > On Tue, 29 Jun 2021 15:15:52 +0100
> > Andre Przywara <andre.przywara@arm.com> wrote:
> > 
> > Hi,
> >   
> > > On Tue, 29 Jun 2021 08:11:22 -0400
> > > Tom Rini <trini@konsulko.com> wrote:
> > >   
> > > > On Tue, Jun 29, 2021 at 12:45:55PM +0100, Andre Przywara wrote:
> > > >     
> > > > > The v2021.07 merge window saw the removal of the Arm Ltd. Versatile
> > > > > Express platform, along with their CA5, CA9 and TC2 boards. The trigger
> > > > > was the missing conversion of the MMC driver.
> > > > > 
> > > > > Some folks complained about that internally, so bring those boards back,
> > > > > but better than ever:
> > > > > - Use DM and OF_CONTROL for all the boards. Use the .dts files from the
> > > > >   latest Linux kernel (5.13) for that.
> > > > > - Move the board selection choice into the platform's Kconfig.
> > > > > - Clean up some shared config and common definitions.
> > > > > - Drop obsolete features like ATAGs support.
> > > > > - Switch to the DM_ETH version of the SMC911X Ethernet driver.
> > > > > - Drop MMC support.
> > > > > 
> > > > > The PL180 MMC driver actually supports DM_MMC, but that requires a
> > > > > DM_GPIO driver for the card detect GPIO, which we don't have. This
> > > > > specific GPIO is actually handled via the "sysregs" device, so we would
> > > > > need a driver for that. QEMU does not emulate this part, also the DT
> > > > > description is somewhat "special", so this is left for later.
> > > > > 
> > > > > This version compiles without any warning for all three boards now.
> > > > > Tested on QEMU.
> > > > > 
> > > > > Signed-off-by: Andre Przywara <andre.przywara@arm.com>
> > > > > ---
> > > > > Hi,
> > > > > 
> > > > > this relies on the SMC911x driver DT changes, as posted here:
> > > > > https://lists.denx.de/pipermail/u-boot/2021-June/452989.html
> > > > > I put a version with the changes broken down here:
> > > > > https://github.com/Andre-ARM/u-boot/commits/tc2-history
> > > > > 
> > > > > This was tested on QEMU, for vexpress_ca15_tc2_defconfig with:
> > > > > $ qemu-system-arm -M vexpress-a15,secure=on -cpu cortex-a15 -m 1G -smp 1 \
> > > > >   -drive file=tramp-tc2.bin,if=pflash,format=raw,read-only \
> > > > >   -device loader,file=u-boot.bin,addr=0x80800000 -nographic
> > > > > 
> > > > > Where tramp-tc2.bin is a trampoline replacing the board's firmware:
> > > > > 00000000  00 00 a0 e3 80 00 48 e3  10 ff 2f e1
> > > > > (mov r0, #0; movt r0, #0x8080; bx r0)
> > > > > 
> > > > > The vexpress_ca9x4_defconfig uses a different memory map, so the runes are:
> > > > > $ qemu-system-arm -M vexpress-a9 -cpu cortex-a9 -m 1G -smp 1 \
> > > > >   -drive file=tramp-ca9.bin,if=pflash,format=raw,read-only \
> > > > >   -device loader,file=u-boot.bin,addr=0x60800000 -nographic
> > > > > 
> > > > > tramp-ca9.bin:
> > > > > 00000000  00 00 a0 e3 80 00 46 e3  10 ff 2f e1
> > > > > (mov r0, #0; movt r0, #0x6080; bx r0)      
> > > > 
> > > > My big question is how do we run this in CI?  Or does it not _need_ that
> > > > firmware file to really exist?  Or is there a pending change to
> > > > https://gitlab.denx.de/u-boot/u-boot-test-hooks.git to generate / just
> > > > have exist those magic empty bins?  Thanks!    
> > > 
> > > So from digging into this I see that this loads U-Boot's ELF build, via
> > > QEMU's -kernel parameter. Which is fine, but not really what is
> > > happening on real hardware.
> > > I checked and the v2021.04 version worked with this approach, but my
> > > build does not.
> > > I will have a look into this now.  
> > 
> > The new build uses OF_CONTROL and OF_SEPARATE, so the DTB gets appended
> > to the U-Boot *image*. The ELF file is not treated this way, so the
> > code reads only 0s after the end of the U-Boot code - which makes it
> > die silently. Manually loading the DTB into DRAM would be fragile at
> > best, but is also rejected by QEMU, because the LOAD program header
> > extend for a few dozen bytes beyond U-Boot's "end" symbol, so it
> > overlaps.  
> 
> Can't we pass the device tree to qemu (and in turn through to U-Boot) in
> a clean and out of the box way?  I thought there was a way to do that..

QEMU has a -dtb command, to take a DTB file, and puts that at the
beginning of DRAM (if possible). Also we could load the DTB from the
(emulated) NOR flash, like we do for the Juno board.
But I think this is not the point: we don't really want this U-Boot
port for the *QEMU* vexpress machine, but for the real hardware: and
there is no DTB by default, not on the NOR flash, and certainly
not in DRAM. The previous U-Boot port didn't need any DTBs at all, so
we can't and shouldn't rely on any extra firmware provision.
I think appending the DTBs to the U-Boot image is the right solution,
so we get a self-contained U-Boot binary, acting as a drop-in
replacement for the older port.
Running under QEMU should just be a some easy way of CI testing, not
a goal in itself. Hence I'd rather adapt the CI than the code.

> > IIRC we don't have position independent code for ARM, so we can't load
> > U-Boot into flash directly (which also would require some code changes
> > first).  
> 
> Do you mean generate a file to use as the system flash and have U-Boot
> be in the correct spot within that file?  If so
> bin/travis-ci/conf.qemu_mips_na in the test hooks repo might give you
> some hints.

Well yes, this was what I was thinking about, but just for the
trampoline. The actual firmware loads U-Boot into DRAM, so we have to
provide that load address in DRAM when building the image. If we were
position independent (like arm64 is), we could cover both cases with
one build, but this is not the case for ARM, IIUC.

> > Anyway I don't think we should change any code to cope with that (by
> > using another method to find the DTB), so adjusting the QEMU recipe
> > sounds like a better idea.
> > 
> > Is there a way to add those 12 byte trampoline files to the CI repo? Or
> > shall they be created on the fly somehow?  
> 
> If we need to include the trampoline files, however it's easiest is
> fine.

So I can try to provide some recipe for travis-ci, based on what I
see in the repo, but don't really know how to test this. I think I have
a Travis-CI account, but would be glad about some hints or instructions
how to test those u-boot-test-hooks bits easily.

Cheers,
Andre
Tom Rini June 30, 2021, 12:52 a.m. UTC | #6
On Wed, Jun 30, 2021 at 01:12:44AM +0100, Andre Przywara wrote:
> On Tue, 29 Jun 2021 14:03:23 -0400
> Tom Rini <trini@konsulko.com> wrote:
> 
> Hi Tom,
> 
> > On Tue, Jun 29, 2021 at 05:52:10PM +0100, Andre Przywara wrote:
> > > On Tue, 29 Jun 2021 15:15:52 +0100
> > > Andre Przywara <andre.przywara@arm.com> wrote:
> > > 
> > > Hi,
> > >   
> > > > On Tue, 29 Jun 2021 08:11:22 -0400
> > > > Tom Rini <trini@konsulko.com> wrote:
> > > >   
> > > > > On Tue, Jun 29, 2021 at 12:45:55PM +0100, Andre Przywara wrote:
> > > > >     
> > > > > > The v2021.07 merge window saw the removal of the Arm Ltd. Versatile
> > > > > > Express platform, along with their CA5, CA9 and TC2 boards. The trigger
> > > > > > was the missing conversion of the MMC driver.
> > > > > > 
> > > > > > Some folks complained about that internally, so bring those boards back,
> > > > > > but better than ever:
> > > > > > - Use DM and OF_CONTROL for all the boards. Use the .dts files from the
> > > > > >   latest Linux kernel (5.13) for that.
> > > > > > - Move the board selection choice into the platform's Kconfig.
> > > > > > - Clean up some shared config and common definitions.
> > > > > > - Drop obsolete features like ATAGs support.
> > > > > > - Switch to the DM_ETH version of the SMC911X Ethernet driver.
> > > > > > - Drop MMC support.
> > > > > > 
> > > > > > The PL180 MMC driver actually supports DM_MMC, but that requires a
> > > > > > DM_GPIO driver for the card detect GPIO, which we don't have. This
> > > > > > specific GPIO is actually handled via the "sysregs" device, so we would
> > > > > > need a driver for that. QEMU does not emulate this part, also the DT
> > > > > > description is somewhat "special", so this is left for later.
> > > > > > 
> > > > > > This version compiles without any warning for all three boards now.
> > > > > > Tested on QEMU.
> > > > > > 
> > > > > > Signed-off-by: Andre Przywara <andre.przywara@arm.com>
> > > > > > ---
> > > > > > Hi,
> > > > > > 
> > > > > > this relies on the SMC911x driver DT changes, as posted here:
> > > > > > https://lists.denx.de/pipermail/u-boot/2021-June/452989.html
> > > > > > I put a version with the changes broken down here:
> > > > > > https://github.com/Andre-ARM/u-boot/commits/tc2-history
> > > > > > 
> > > > > > This was tested on QEMU, for vexpress_ca15_tc2_defconfig with:
> > > > > > $ qemu-system-arm -M vexpress-a15,secure=on -cpu cortex-a15 -m 1G -smp 1 \
> > > > > >   -drive file=tramp-tc2.bin,if=pflash,format=raw,read-only \
> > > > > >   -device loader,file=u-boot.bin,addr=0x80800000 -nographic
> > > > > > 
> > > > > > Where tramp-tc2.bin is a trampoline replacing the board's firmware:
> > > > > > 00000000  00 00 a0 e3 80 00 48 e3  10 ff 2f e1
> > > > > > (mov r0, #0; movt r0, #0x8080; bx r0)
> > > > > > 
> > > > > > The vexpress_ca9x4_defconfig uses a different memory map, so the runes are:
> > > > > > $ qemu-system-arm -M vexpress-a9 -cpu cortex-a9 -m 1G -smp 1 \
> > > > > >   -drive file=tramp-ca9.bin,if=pflash,format=raw,read-only \
> > > > > >   -device loader,file=u-boot.bin,addr=0x60800000 -nographic
> > > > > > 
> > > > > > tramp-ca9.bin:
> > > > > > 00000000  00 00 a0 e3 80 00 46 e3  10 ff 2f e1
> > > > > > (mov r0, #0; movt r0, #0x6080; bx r0)      
> > > > > 
> > > > > My big question is how do we run this in CI?  Or does it not _need_ that
> > > > > firmware file to really exist?  Or is there a pending change to
> > > > > https://gitlab.denx.de/u-boot/u-boot-test-hooks.git to generate / just
> > > > > have exist those magic empty bins?  Thanks!    
> > > > 
> > > > So from digging into this I see that this loads U-Boot's ELF build, via
> > > > QEMU's -kernel parameter. Which is fine, but not really what is
> > > > happening on real hardware.
> > > > I checked and the v2021.04 version worked with this approach, but my
> > > > build does not.
> > > > I will have a look into this now.  
> > > 
> > > The new build uses OF_CONTROL and OF_SEPARATE, so the DTB gets appended
> > > to the U-Boot *image*. The ELF file is not treated this way, so the
> > > code reads only 0s after the end of the U-Boot code - which makes it
> > > die silently. Manually loading the DTB into DRAM would be fragile at
> > > best, but is also rejected by QEMU, because the LOAD program header
> > > extend for a few dozen bytes beyond U-Boot's "end" symbol, so it
> > > overlaps.  
> > 
> > Can't we pass the device tree to qemu (and in turn through to U-Boot) in
> > a clean and out of the box way?  I thought there was a way to do that..
> 
> QEMU has a -dtb command, to take a DTB file, and puts that at the
> beginning of DRAM (if possible). Also we could load the DTB from the
> (emulated) NOR flash, like we do for the Juno board.
> But I think this is not the point: we don't really want this U-Boot
> port for the *QEMU* vexpress machine, but for the real hardware: and
> there is no DTB by default, not on the NOR flash, and certainly
> not in DRAM. The previous U-Boot port didn't need any DTBs at all, so
> we can't and shouldn't rely on any extra firmware provision.
> I think appending the DTBs to the U-Boot image is the right solution,
> so we get a self-contained U-Boot binary, acting as a drop-in
> replacement for the older port.
> Running under QEMU should just be a some easy way of CI testing, not
> a goal in itself. Hence I'd rather adapt the CI than the code.

Ah right, yes, we do want this to look / act as real HW like as
possible.

> > > IIRC we don't have position independent code for ARM, so we can't load
> > > U-Boot into flash directly (which also would require some code changes
> > > first).  
> > 
> > Do you mean generate a file to use as the system flash and have U-Boot
> > be in the correct spot within that file?  If so
> > bin/travis-ci/conf.qemu_mips_na in the test hooks repo might give you
> > some hints.
> 
> Well yes, this was what I was thinking about, but just for the
> trampoline. The actual firmware loads U-Boot into DRAM, so we have to
> provide that load address in DRAM when building the image. If we were
> position independent (like arm64 is), we could cover both cases with
> one build, but this is not the case for ARM, IIUC.
> 
> > > Anyway I don't think we should change any code to cope with that (by
> > > using another method to find the DTB), so adjusting the QEMU recipe
> > > sounds like a better idea.
> > > 
> > > Is there a way to add those 12 byte trampoline files to the CI repo? Or
> > > shall they be created on the fly somehow?  
> > 
> > If we need to include the trampoline files, however it's easiest is
> > fine.
> 
> So I can try to provide some recipe for travis-ci, based on what I
> see in the repo, but don't really know how to test this. I think I have
> a Travis-CI account, but would be glad about some hints or instructions
> how to test those u-boot-test-hooks bits easily.

So, the travis-ci in the paths names is a relic of when we only had
Travis-CI as the CI, rather than Azure/GitLab.  In terms of testing, you
can either push to the sunxi tree which I assume has CI jobs enabled, or
a PR on GitHub against the u-boot tree there triggers an Azure run.
diff mbox series

Patch

diff --git a/.azure-pipelines.yml b/.azure-pipelines.yml
index 221e6008062..ddfbd606530 100644
--- a/.azure-pipelines.yml
+++ b/.azure-pipelines.yml
@@ -195,6 +195,12 @@  jobs:
         evb_ast2500:
           TEST_PY_BD: "evb-ast2500"
           TEST_PY_ID: "--id qemu"
+        vexpress_ca15_tc2:
+          TEST_PY_BD: "vexpress_ca15_tc2"
+          TEST_PY_ID: "--id qemu"
+        vexpress_ca9x4:
+          TEST_PY_BD: "vexpress_ca9x4"
+          TEST_PY_ID: "--id qemu"
         integratorcp_cm926ejs:
           TEST_PY_BD: "integratorcp_cm926ejs"
           TEST_PY_ID: "--id qemu"
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index d072e833a3d..c6498e3b4fd 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -205,6 +205,18 @@  sandbox_flattree test.py:
     TEST_PY_BD: "sandbox_flattree"
   <<: *buildman_and_testpy_dfn
 
+vexpress_ca15_tc2 test.py:
+  variables:
+    TEST_PY_BD: "vexpress_ca15_tc2"
+    TEST_PY_ID: "--id qemu"
+  <<: *buildman_and_testpy_dfn
+
+vexpress_ca9x4 test.py:
+  variables:
+    TEST_PY_BD: "vexpress_ca9x4"
+    TEST_PY_ID: "--id qemu"
+  <<: *buildman_and_testpy_dfn
+
 integratorcp_cm926ejs test.py:
   variables:
     TEST_PY_BD: "integratorcp_cm926ejs"
diff --git a/Kconfig b/Kconfig
index f8c1a77bedb..4d0673ad327 100644
--- a/Kconfig
+++ b/Kconfig
@@ -189,7 +189,7 @@  config ENV_VARS_UBOOT_CONFIG
 
 config NR_DRAM_BANKS
 	int "Number of DRAM banks"
-	default 1 if ARCH_SUNXI || ARCH_OWL
+	default 1 if ARCH_SUNXI || ARCH_OWL || ARCH_VEXPRESS
 	default 4
 	help
 	  This defines the number of DRAM banks.
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 0448787b8bc..3a94849e20e 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -646,6 +646,21 @@  config ARCH_BCM6858
 	select OF_CONTROL
 	imply CMD_DM
 
+config ARCH_VEXPRESS
+	bool "Support Arm Ltd. Versatile Express (VExpress) family"
+	select CPU_V7A
+	select PL01X_SERIAL
+	select DM
+	select DM_SERIAL
+	select DM_ETH
+	select OF_CONTROL
+	select OF_SEPARATE
+	imply DISTRO_DEFAULTS
+	select MTD
+	select MTD_NOR_FLASH
+	select FLASH_CFI_DRIVER
+	imply CONS_INDEX_0
+
 config ARCH_BCMSTB
 	bool "Broadcom BCM7XXX family"
 	select CPU_V7A
@@ -1992,6 +2007,7 @@  source "board/Marvell/aspenite/Kconfig"
 source "board/Marvell/gplugd/Kconfig"
 source "board/Marvell/octeontx/Kconfig"
 source "board/Marvell/octeontx2/Kconfig"
+source "board/armltd/vexpress/Kconfig"
 source "board/armltd/vexpress64/Kconfig"
 source "board/cortina/presidio-asic/Kconfig"
 source "board/broadcom/bcm963158/Kconfig"
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index 9fb38682e61..69736b3ddbe 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -1104,6 +1104,11 @@  dtb-$(CONFIG_TARGET_GE_BX50V3) += \
 dtb-$(CONFIG_TARGET_GE_B1X5V2) += imx6dl-b1x5v2.dtb
 dtb-$(CONFIG_TARGET_MX53PPD) += imx53-ppd.dtb
 
+dtb-$(CONFIG_ARCH_VEXPRESS) += \
+	vexpress-v2p-ca5s.dtb \
+	vexpress-v2p-ca9.dtb \
+	vexpress-v2p-ca15_a7.dtb
+
 dtb-$(CONFIG_TARGET_TOTAL_COMPUTE) += total_compute.dtb
 
 dtb-$(CONFIG_TARGET_DURIAN) += phytium-durian.dtb
diff --git a/arch/arm/dts/vexpress-v2m-rs1.dtsi b/arch/arm/dts/vexpress-v2m-rs1.dtsi
new file mode 100644
index 00000000000..4f7220b11f2
--- /dev/null
+++ b/arch/arm/dts/vexpress-v2m-rs1.dtsi
@@ -0,0 +1,441 @@ 
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * ARM Ltd. Versatile Express
+ *
+ * Motherboard Express uATX
+ * V2M-P1
+ *
+ * HBI-0190D
+ *
+ * RS1 memory map ("ARM Cortex-A Series memory map" in the board's
+ * Technical Reference Manual)
+ *
+ * WARNING! The hardware described in this file is independent from the
+ * original variant (vexpress-v2m.dtsi), but there is a strong
+ * correspondence between the two configurations.
+ *
+ * TAKE CARE WHEN MAINTAINING THIS FILE TO PROPAGATE ANY RELEVANT
+ * CHANGES TO vexpress-v2m.dtsi!
+ */
+
+/ {
+	v2m_fixed_3v3: fixed-regulator-0 {
+		compatible = "regulator-fixed";
+		regulator-name = "3V3";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		regulator-always-on;
+	};
+
+	v2m_clk24mhz: clk24mhz {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <24000000>;
+		clock-output-names = "v2m:clk24mhz";
+	};
+
+	v2m_refclk1mhz: refclk1mhz {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <1000000>;
+		clock-output-names = "v2m:refclk1mhz";
+	};
+
+	v2m_refclk32khz: refclk32khz {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <32768>;
+		clock-output-names = "v2m:refclk32khz";
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led-1 {
+			label = "v2m:green:user1";
+			gpios = <&v2m_led_gpios 0 0>;
+			linux,default-trigger = "heartbeat";
+		};
+
+		led-2 {
+			label = "v2m:green:user2";
+			gpios = <&v2m_led_gpios 1 0>;
+			linux,default-trigger = "disk-activity";
+		};
+
+		led-3 {
+			label = "v2m:green:user3";
+			gpios = <&v2m_led_gpios 2 0>;
+			linux,default-trigger = "cpu0";
+		};
+
+		led-4 {
+			label = "v2m:green:user4";
+			gpios = <&v2m_led_gpios 3 0>;
+			linux,default-trigger = "cpu1";
+		};
+
+		led-5 {
+			label = "v2m:green:user5";
+			gpios = <&v2m_led_gpios 4 0>;
+			linux,default-trigger = "cpu2";
+		};
+
+		led-6 {
+			label = "v2m:green:user6";
+			gpios = <&v2m_led_gpios 5 0>;
+			linux,default-trigger = "cpu3";
+		};
+
+		led-7 {
+			label = "v2m:green:user7";
+			gpios = <&v2m_led_gpios 6 0>;
+			linux,default-trigger = "cpu4";
+		};
+
+		led-8 {
+			label = "v2m:green:user8";
+			gpios = <&v2m_led_gpios 7 0>;
+			linux,default-trigger = "cpu5";
+		};
+	};
+
+	bus@8000000 {
+		motherboard-bus {
+			model = "V2M-P1";
+			arm,hbi = <0x190>;
+			arm,vexpress,site = <0>;
+			arm,v2m-memory-map = "rs1";
+			compatible = "arm,vexpress,v2m-p1", "simple-bus";
+			#address-cells = <2>; /* SMB chipselect number and offset */
+			#size-cells = <1>;
+			#interrupt-cells = <1>;
+			ranges;
+
+			nor_flash: flash@0 {
+				compatible = "arm,vexpress-flash", "cfi-flash";
+				reg = <0 0x00000000 0x04000000>,
+				      <4 0x00000000 0x04000000>;
+				bank-width = <4>;
+				partitions {
+					compatible = "arm,arm-firmware-suite";
+				};
+			};
+
+			psram@100000000 {
+				compatible = "arm,vexpress-psram", "mtd-ram";
+				reg = <1 0x00000000 0x02000000>;
+				bank-width = <4>;
+			};
+
+			ethernet@202000000 {
+				compatible = "smsc,lan9118", "smsc,lan9115";
+				reg = <2 0x02000000 0x10000>;
+				interrupts = <15>;
+				phy-mode = "mii";
+				reg-io-width = <4>;
+				smsc,irq-active-high;
+				smsc,irq-push-pull;
+				vdd33a-supply = <&v2m_fixed_3v3>;
+				vddvario-supply = <&v2m_fixed_3v3>;
+			};
+
+			usb@203000000 {
+				compatible = "nxp,usb-isp1761";
+				reg = <2 0x03000000 0x20000>;
+				interrupts = <16>;
+				port1-otg;
+			};
+
+			iofpga-bus@300000000 {
+				compatible = "simple-bus";
+				#address-cells = <1>;
+				#size-cells = <1>;
+				ranges = <0 3 0 0x200000>;
+
+				v2m_sysreg: sysreg@10000 {
+					compatible = "arm,vexpress-sysreg";
+					reg = <0x010000 0x1000>;
+					#address-cells = <1>;
+					#size-cells = <1>;
+					ranges = <0 0x10000 0x1000>;
+
+					v2m_led_gpios: gpio@8 {
+						compatible = "arm,vexpress-sysreg,sys_led";
+						reg = <0x008 4>;
+						gpio-controller;
+						#gpio-cells = <2>;
+					};
+
+					v2m_mmc_gpios: gpio@48 {
+						compatible = "arm,vexpress-sysreg,sys_mci";
+						reg = <0x048 4>;
+						gpio-controller;
+						#gpio-cells = <2>;
+					};
+
+					v2m_flash_gpios: gpio@4c {
+						compatible = "arm,vexpress-sysreg,sys_flash";
+						reg = <0x04c 4>;
+						gpio-controller;
+						#gpio-cells = <2>;
+					};
+				};
+
+				v2m_sysctl: sysctl@20000 {
+					compatible = "arm,sp810", "arm,primecell";
+					reg = <0x020000 0x1000>;
+					clocks = <&v2m_refclk32khz>, <&v2m_refclk1mhz>, <&smbclk>;
+					clock-names = "refclk", "timclk", "apb_pclk";
+					#clock-cells = <1>;
+					clock-output-names = "timerclken0", "timerclken1", "timerclken2", "timerclken3";
+					assigned-clocks = <&v2m_sysctl 0>, <&v2m_sysctl 1>, <&v2m_sysctl 3>, <&v2m_sysctl 3>;
+					assigned-clock-parents = <&v2m_refclk1mhz>, <&v2m_refclk1mhz>, <&v2m_refclk1mhz>, <&v2m_refclk1mhz>;
+				};
+
+				/* PCI-E I2C bus */
+				v2m_i2c_pcie: i2c@30000 {
+					compatible = "arm,versatile-i2c";
+					reg = <0x030000 0x1000>;
+
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					pcie-switch@60 {
+						compatible = "idt,89hpes32h8";
+						reg = <0x60>;
+					};
+				};
+
+				aaci@40000 {
+					compatible = "arm,pl041", "arm,primecell";
+					reg = <0x040000 0x1000>;
+					interrupts = <11>;
+					clocks = <&smbclk>;
+					clock-names = "apb_pclk";
+				};
+
+				mmci@50000 {
+					compatible = "arm,pl180", "arm,primecell";
+					reg = <0x050000 0x1000>;
+					interrupts = <9>, <10>;
+					cd-gpios = <&v2m_mmc_gpios 0 0>;
+					wp-gpios = <&v2m_mmc_gpios 1 0>;
+					max-frequency = <12000000>;
+					vmmc-supply = <&v2m_fixed_3v3>;
+					clocks = <&v2m_clk24mhz>, <&smbclk>;
+					clock-names = "mclk", "apb_pclk";
+				};
+
+				kmi@60000 {
+					compatible = "arm,pl050", "arm,primecell";
+					reg = <0x060000 0x1000>;
+					interrupts = <12>;
+					clocks = <&v2m_clk24mhz>, <&smbclk>;
+					clock-names = "KMIREFCLK", "apb_pclk";
+				};
+
+				kmi@70000 {
+					compatible = "arm,pl050", "arm,primecell";
+					reg = <0x070000 0x1000>;
+					interrupts = <13>;
+					clocks = <&v2m_clk24mhz>, <&smbclk>;
+					clock-names = "KMIREFCLK", "apb_pclk";
+				};
+
+				v2m_serial0: serial@90000 {
+					compatible = "arm,pl011", "arm,primecell";
+					reg = <0x090000 0x1000>;
+					interrupts = <5>;
+					clocks = <&v2m_oscclk2>, <&smbclk>;
+					clock-names = "uartclk", "apb_pclk";
+				};
+
+				v2m_serial1: serial@a0000 {
+					compatible = "arm,pl011", "arm,primecell";
+					reg = <0x0a0000 0x1000>;
+					interrupts = <6>;
+					clocks = <&v2m_oscclk2>, <&smbclk>;
+					clock-names = "uartclk", "apb_pclk";
+				};
+
+				v2m_serial2: serial@b0000 {
+					compatible = "arm,pl011", "arm,primecell";
+					reg = <0x0b0000 0x1000>;
+					interrupts = <7>;
+					clocks = <&v2m_oscclk2>, <&smbclk>;
+					clock-names = "uartclk", "apb_pclk";
+				};
+
+				v2m_serial3: serial@c0000 {
+					compatible = "arm,pl011", "arm,primecell";
+					reg = <0x0c0000 0x1000>;
+					interrupts = <8>;
+					clocks = <&v2m_oscclk2>, <&smbclk>;
+					clock-names = "uartclk", "apb_pclk";
+				};
+
+				wdt@f0000 {
+					compatible = "arm,sp805", "arm,primecell";
+					reg = <0x0f0000 0x1000>;
+					interrupts = <0>;
+					clocks = <&v2m_refclk32khz>, <&smbclk>;
+					clock-names = "wdog_clk", "apb_pclk";
+				};
+
+				v2m_timer01: timer@110000 {
+					compatible = "arm,sp804", "arm,primecell";
+					reg = <0x110000 0x1000>;
+					interrupts = <2>;
+					clocks = <&v2m_sysctl 0>, <&v2m_sysctl 1>, <&smbclk>;
+					clock-names = "timclken1", "timclken2", "apb_pclk";
+				};
+
+				v2m_timer23: timer@120000 {
+					compatible = "arm,sp804", "arm,primecell";
+					reg = <0x120000 0x1000>;
+					interrupts = <3>;
+					clocks = <&v2m_sysctl 2>, <&v2m_sysctl 3>, <&smbclk>;
+					clock-names = "timclken1", "timclken2", "apb_pclk";
+				};
+
+				/* DVI I2C bus */
+				v2m_i2c_dvi: i2c@160000 {
+					compatible = "arm,versatile-i2c";
+					reg = <0x160000 0x1000>;
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					dvi-transmitter@39 {
+						compatible = "sil,sii9022-tpi", "sil,sii9022";
+						reg = <0x39>;
+
+						ports {
+							#address-cells = <1>;
+							#size-cells = <0>;
+
+							port@0 {
+								reg = <0>;
+								dvi_bridge_in: endpoint {
+									remote-endpoint = <&clcd_pads>;
+								};
+							};
+						};
+					};
+
+					dvi-transmitter@60 {
+						compatible = "sil,sii9022-cpi", "sil,sii9022";
+						reg = <0x60>;
+					};
+				};
+
+				rtc@170000 {
+					compatible = "arm,pl031", "arm,primecell";
+					reg = <0x170000 0x1000>;
+					interrupts = <4>;
+					clocks = <&smbclk>;
+					clock-names = "apb_pclk";
+				};
+
+				compact-flash@1a0000 {
+					compatible = "arm,vexpress-cf", "ata-generic";
+					reg = <0x1a0000 0x100
+					       0x1a0100 0xf00>;
+					reg-shift = <2>;
+				};
+
+				clcd@1f0000 {
+					compatible = "arm,pl111", "arm,primecell";
+					reg = <0x1f0000 0x1000>;
+					interrupt-names = "combined";
+					interrupts = <14>;
+					clocks = <&v2m_oscclk1>, <&smbclk>;
+					clock-names = "clcdclk", "apb_pclk";
+					/* 800x600 16bpp @36MHz works fine */
+					max-memory-bandwidth = <54000000>;
+					memory-region = <&vram>;
+
+					port {
+						clcd_pads: endpoint {
+							remote-endpoint = <&dvi_bridge_in>;
+							arm,pl11x,tft-r0g0b0-pads = <0 8 16>;
+						};
+					};
+				};
+
+				mcc {
+					compatible = "arm,vexpress,config-bus";
+					arm,vexpress,config-bridge = <&v2m_sysreg>;
+
+					oscclk0 {
+						/* MCC static memory clock */
+						compatible = "arm,vexpress-osc";
+						arm,vexpress-sysreg,func = <1 0>;
+						freq-range = <25000000 60000000>;
+						#clock-cells = <0>;
+						clock-output-names = "v2m:oscclk0";
+					};
+
+					v2m_oscclk1: oscclk1 {
+						/* CLCD clock */
+						compatible = "arm,vexpress-osc";
+						arm,vexpress-sysreg,func = <1 1>;
+						freq-range = <23750000 65000000>;
+						#clock-cells = <0>;
+						clock-output-names = "v2m:oscclk1";
+					};
+
+					v2m_oscclk2: oscclk2 {
+						/* IO FPGA peripheral clock */
+						compatible = "arm,vexpress-osc";
+						arm,vexpress-sysreg,func = <1 2>;
+						freq-range = <24000000 24000000>;
+						#clock-cells = <0>;
+						clock-output-names = "v2m:oscclk2";
+					};
+
+					volt-vio {
+						/* Logic level voltage */
+						compatible = "arm,vexpress-volt";
+						arm,vexpress-sysreg,func = <2 0>;
+						regulator-name = "VIO";
+						regulator-always-on;
+						label = "VIO";
+					};
+
+					temp-mcc {
+						/* MCC internal operating temperature */
+						compatible = "arm,vexpress-temp";
+						arm,vexpress-sysreg,func = <4 0>;
+						label = "MCC";
+					};
+
+					reset {
+						compatible = "arm,vexpress-reset";
+						arm,vexpress-sysreg,func = <5 0>;
+					};
+
+					muxfpga {
+						compatible = "arm,vexpress-muxfpga";
+						arm,vexpress-sysreg,func = <7 0>;
+					};
+
+					shutdown {
+						compatible = "arm,vexpress-shutdown";
+						arm,vexpress-sysreg,func = <8 0>;
+					};
+
+					reboot {
+						compatible = "arm,vexpress-reboot";
+						arm,vexpress-sysreg,func = <9 0>;
+					};
+
+					dvimode {
+						compatible = "arm,vexpress-dvimode";
+						arm,vexpress-sysreg,func = <11 0>;
+					};
+				};
+			};
+		};
+	};
+};
diff --git a/arch/arm/dts/vexpress-v2m.dtsi b/arch/arm/dts/vexpress-v2m.dtsi
new file mode 100644
index 00000000000..2ac41ed3a57
--- /dev/null
+++ b/arch/arm/dts/vexpress-v2m.dtsi
@@ -0,0 +1,454 @@ 
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * ARM Ltd. Versatile Express
+ *
+ * Motherboard Express uATX
+ * V2M-P1
+ *
+ * HBI-0190D
+ *
+ * Original memory map ("Legacy memory map" in the board's
+ * Technical Reference Manual)
+ *
+ * WARNING! The hardware described in this file is independent from the
+ * RS1 variant (vexpress-v2m-rs1.dtsi), but there is a strong
+ * correspondence between the two configurations.
+ *
+ * TAKE CARE WHEN MAINTAINING THIS FILE TO PROPAGATE ANY RELEVANT
+ * CHANGES TO vexpress-v2m-rs1.dtsi!
+ */
+
+/ {
+	bus@4000000 {
+		motherboard {
+			model = "V2M-P1";
+			arm,hbi = <0x190>;
+			arm,vexpress,site = <0>;
+			compatible = "arm,vexpress,v2m-p1", "simple-bus";
+			#address-cells = <2>; /* SMB chipselect number and offset */
+			#size-cells = <1>;
+			#interrupt-cells = <1>;
+			ranges;
+
+			flash@0,00000000 {
+				compatible = "arm,vexpress-flash", "cfi-flash";
+				reg = <0 0x00000000 0x04000000>,
+				      <1 0x00000000 0x04000000>;
+				bank-width = <4>;
+				partitions {
+					compatible = "arm,arm-firmware-suite";
+				};
+			};
+
+			psram@2,00000000 {
+				compatible = "arm,vexpress-psram", "mtd-ram";
+				reg = <2 0x00000000 0x02000000>;
+				bank-width = <4>;
+			};
+
+			ethernet@3,02000000 {
+				compatible = "smsc,lan9118", "smsc,lan9115";
+				reg = <3 0x02000000 0x10000>;
+				interrupts = <15>;
+				phy-mode = "mii";
+				reg-io-width = <4>;
+				smsc,irq-active-high;
+				smsc,irq-push-pull;
+				vdd33a-supply = <&v2m_fixed_3v3>;
+				vddvario-supply = <&v2m_fixed_3v3>;
+			};
+
+			usb@3,03000000 {
+				compatible = "nxp,usb-isp1761";
+				reg = <3 0x03000000 0x20000>;
+				interrupts = <16>;
+				port1-otg;
+			};
+
+			iofpga@7,00000000 {
+				compatible = "simple-bus";
+				#address-cells = <1>;
+				#size-cells = <1>;
+				ranges = <0 7 0 0x20000>;
+
+				v2m_sysreg: sysreg@0 {
+					compatible = "arm,vexpress-sysreg";
+					reg = <0x00000 0x1000>;
+					#address-cells = <1>;
+					#size-cells = <1>;
+					ranges = <0 0 0x1000>;
+
+					v2m_led_gpios: gpio@8 {
+						compatible = "arm,vexpress-sysreg,sys_led";
+						reg = <0x008 4>;
+						gpio-controller;
+						#gpio-cells = <2>;
+					};
+
+					v2m_mmc_gpios: gpio@48 {
+						compatible = "arm,vexpress-sysreg,sys_mci";
+						reg = <0x048 4>;
+						gpio-controller;
+						#gpio-cells = <2>;
+					};
+
+					v2m_flash_gpios: gpio@4c {
+						compatible = "arm,vexpress-sysreg,sys_flash";
+						reg = <0x04c 4>;
+						gpio-controller;
+						#gpio-cells = <2>;
+					};
+				};
+
+				v2m_sysctl: sysctl@1000 {
+					compatible = "arm,sp810", "arm,primecell";
+					reg = <0x01000 0x1000>;
+					clocks = <&v2m_refclk32khz>, <&v2m_refclk1mhz>, <&smbclk>;
+					clock-names = "refclk", "timclk", "apb_pclk";
+					#clock-cells = <1>;
+					clock-output-names = "timerclken0", "timerclken1", "timerclken2", "timerclken3";
+					assigned-clocks = <&v2m_sysctl 0>, <&v2m_sysctl 1>, <&v2m_sysctl 3>, <&v2m_sysctl 3>;
+					assigned-clock-parents = <&v2m_refclk1mhz>, <&v2m_refclk1mhz>, <&v2m_refclk1mhz>, <&v2m_refclk1mhz>;
+				};
+
+				/* PCI-E I2C bus */
+				v2m_i2c_pcie: i2c@2000 {
+					compatible = "arm,versatile-i2c";
+					reg = <0x02000 0x1000>;
+
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					pcie-switch@60 {
+						compatible = "idt,89hpes32h8";
+						reg = <0x60>;
+					};
+				};
+
+				aaci@4000 {
+					compatible = "arm,pl041", "arm,primecell";
+					reg = <0x04000 0x1000>;
+					interrupts = <11>;
+					clocks = <&smbclk>;
+					clock-names = "apb_pclk";
+				};
+
+				mmci@5000 {
+					compatible = "arm,pl180", "arm,primecell";
+					reg = <0x05000 0x1000>;
+					interrupts = <9>, <10>;
+					cd-gpios = <&v2m_mmc_gpios 0 0>;
+					wp-gpios = <&v2m_mmc_gpios 1 0>;
+					max-frequency = <12000000>;
+					vmmc-supply = <&v2m_fixed_3v3>;
+					clocks = <&v2m_clk24mhz>, <&smbclk>;
+					clock-names = "mclk", "apb_pclk";
+				};
+
+				kmi@6000 {
+					compatible = "arm,pl050", "arm,primecell";
+					reg = <0x06000 0x1000>;
+					interrupts = <12>;
+					clocks = <&v2m_clk24mhz>, <&smbclk>;
+					clock-names = "KMIREFCLK", "apb_pclk";
+				};
+
+				kmi@7000 {
+					compatible = "arm,pl050", "arm,primecell";
+					reg = <0x07000 0x1000>;
+					interrupts = <13>;
+					clocks = <&v2m_clk24mhz>, <&smbclk>;
+					clock-names = "KMIREFCLK", "apb_pclk";
+				};
+
+				v2m_serial0: uart@9000 {
+					compatible = "arm,pl011", "arm,primecell";
+					reg = <0x09000 0x1000>;
+					interrupts = <5>;
+					clocks = <&v2m_oscclk2>, <&smbclk>;
+					clock-names = "uartclk", "apb_pclk";
+				};
+
+				v2m_serial1: uart@a000 {
+					compatible = "arm,pl011", "arm,primecell";
+					reg = <0x0a000 0x1000>;
+					interrupts = <6>;
+					clocks = <&v2m_oscclk2>, <&smbclk>;
+					clock-names = "uartclk", "apb_pclk";
+				};
+
+				v2m_serial2: uart@b000 {
+					compatible = "arm,pl011", "arm,primecell";
+					reg = <0x0b000 0x1000>;
+					interrupts = <7>;
+					clocks = <&v2m_oscclk2>, <&smbclk>;
+					clock-names = "uartclk", "apb_pclk";
+				};
+
+				v2m_serial3: uart@c000 {
+					compatible = "arm,pl011", "arm,primecell";
+					reg = <0x0c000 0x1000>;
+					interrupts = <8>;
+					clocks = <&v2m_oscclk2>, <&smbclk>;
+					clock-names = "uartclk", "apb_pclk";
+				};
+
+				wdt@f000 {
+					compatible = "arm,sp805", "arm,primecell";
+					reg = <0x0f000 0x1000>;
+					interrupts = <0>;
+					clocks = <&v2m_refclk32khz>, <&smbclk>;
+					clock-names = "wdog_clk", "apb_pclk";
+				};
+
+				v2m_timer01: timer@11000 {
+					compatible = "arm,sp804", "arm,primecell";
+					reg = <0x11000 0x1000>;
+					interrupts = <2>;
+					clocks = <&v2m_sysctl 0>, <&v2m_sysctl 1>, <&smbclk>;
+					clock-names = "timclken1", "timclken2", "apb_pclk";
+				};
+
+				v2m_timer23: timer@12000 {
+					compatible = "arm,sp804", "arm,primecell";
+					reg = <0x12000 0x1000>;
+					interrupts = <3>;
+					clocks = <&v2m_sysctl 2>, <&v2m_sysctl 3>, <&smbclk>;
+					clock-names = "timclken1", "timclken2", "apb_pclk";
+				};
+
+				/* DVI I2C bus */
+				v2m_i2c_dvi: i2c@16000 {
+					compatible = "arm,versatile-i2c";
+					reg = <0x16000 0x1000>;
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					dvi-transmitter@39 {
+						compatible = "sil,sii9022-tpi", "sil,sii9022";
+						reg = <0x39>;
+
+						ports {
+							#address-cells = <1>;
+							#size-cells = <0>;
+
+							/*
+							 * Both the core tile and the motherboard routes their output
+							 * pads to this transmitter. The motherboard system controller
+							 * can select one of them as input using a mux register in
+							 * "arm,vexpress-muxfpga". The Vexpress with the CA9 core tile is
+							 * the only platform with this specific set-up.
+							 */
+							port@0 {
+								reg = <0>;
+								dvi_bridge_in_ct: endpoint {
+									remote-endpoint = <&clcd_pads_ct>;
+								};
+							};
+							port@1 {
+								reg = <1>;
+								dvi_bridge_in_mb: endpoint {
+									remote-endpoint = <&clcd_pads_mb>;
+								};
+							};
+						};
+					};
+
+					dvi-transmitter@60 {
+						compatible = "sil,sii9022-cpi", "sil,sii9022";
+						reg = <0x60>;
+					};
+				};
+
+				rtc@17000 {
+					compatible = "arm,pl031", "arm,primecell";
+					reg = <0x17000 0x1000>;
+					interrupts = <4>;
+					clocks = <&smbclk>;
+					clock-names = "apb_pclk";
+				};
+
+				compact-flash@1a000 {
+					compatible = "arm,vexpress-cf", "ata-generic";
+					reg = <0x1a000 0x100
+					       0x1a100 0xf00>;
+					reg-shift = <2>;
+				};
+
+
+				clcd@1f000 {
+					compatible = "arm,pl111", "arm,primecell";
+					reg = <0x1f000 0x1000>;
+					interrupt-names = "combined";
+					interrupts = <14>;
+					clocks = <&v2m_oscclk1>, <&smbclk>;
+					clock-names = "clcdclk", "apb_pclk";
+					/* 800x600 16bpp @36MHz works fine */
+					max-memory-bandwidth = <54000000>;
+					memory-region = <&vram>;
+
+					port {
+						clcd_pads_mb: endpoint {
+							remote-endpoint = <&dvi_bridge_in_mb>;
+							arm,pl11x,tft-r0g0b0-pads = <0 8 16>;
+						};
+					};
+				};
+			};
+
+			v2m_fixed_3v3: fixed-regulator-0 {
+				compatible = "regulator-fixed";
+				regulator-name = "3V3";
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-always-on;
+			};
+
+			v2m_clk24mhz: clk24mhz {
+				compatible = "fixed-clock";
+				#clock-cells = <0>;
+				clock-frequency = <24000000>;
+				clock-output-names = "v2m:clk24mhz";
+			};
+
+			v2m_refclk1mhz: refclk1mhz {
+				compatible = "fixed-clock";
+				#clock-cells = <0>;
+				clock-frequency = <1000000>;
+				clock-output-names = "v2m:refclk1mhz";
+			};
+
+			v2m_refclk32khz: refclk32khz {
+				compatible = "fixed-clock";
+				#clock-cells = <0>;
+				clock-frequency = <32768>;
+				clock-output-names = "v2m:refclk32khz";
+			};
+
+			leds {
+				compatible = "gpio-leds";
+
+				user1 {
+					label = "v2m:green:user1";
+					gpios = <&v2m_led_gpios 0 0>;
+					linux,default-trigger = "heartbeat";
+				};
+
+				user2 {
+					label = "v2m:green:user2";
+					gpios = <&v2m_led_gpios 1 0>;
+					linux,default-trigger = "mmc0";
+				};
+
+				user3 {
+					label = "v2m:green:user3";
+					gpios = <&v2m_led_gpios 2 0>;
+					linux,default-trigger = "cpu0";
+				};
+
+				user4 {
+					label = "v2m:green:user4";
+					gpios = <&v2m_led_gpios 3 0>;
+					linux,default-trigger = "cpu1";
+				};
+
+				user5 {
+					label = "v2m:green:user5";
+					gpios = <&v2m_led_gpios 4 0>;
+					linux,default-trigger = "cpu2";
+				};
+
+				user6 {
+					label = "v2m:green:user6";
+					gpios = <&v2m_led_gpios 5 0>;
+					linux,default-trigger = "cpu3";
+				};
+
+				user7 {
+					label = "v2m:green:user7";
+					gpios = <&v2m_led_gpios 6 0>;
+					linux,default-trigger = "cpu4";
+				};
+
+				user8 {
+					label = "v2m:green:user8";
+					gpios = <&v2m_led_gpios 7 0>;
+					linux,default-trigger = "cpu5";
+				};
+			};
+
+			mcc {
+				compatible = "arm,vexpress,config-bus";
+				arm,vexpress,config-bridge = <&v2m_sysreg>;
+
+				oscclk0 {
+					/* MCC static memory clock */
+					compatible = "arm,vexpress-osc";
+					arm,vexpress-sysreg,func = <1 0>;
+					freq-range = <25000000 60000000>;
+					#clock-cells = <0>;
+					clock-output-names = "v2m:oscclk0";
+				};
+
+				v2m_oscclk1: oscclk1 {
+					/* CLCD clock */
+					compatible = "arm,vexpress-osc";
+					arm,vexpress-sysreg,func = <1 1>;
+					freq-range = <23750000 65000000>;
+					#clock-cells = <0>;
+					clock-output-names = "v2m:oscclk1";
+				};
+
+				v2m_oscclk2: oscclk2 {
+					/* IO FPGA peripheral clock */
+					compatible = "arm,vexpress-osc";
+					arm,vexpress-sysreg,func = <1 2>;
+					freq-range = <24000000 24000000>;
+					#clock-cells = <0>;
+					clock-output-names = "v2m:oscclk2";
+				};
+
+				volt-vio {
+					/* Logic level voltage */
+					compatible = "arm,vexpress-volt";
+					arm,vexpress-sysreg,func = <2 0>;
+					regulator-name = "VIO";
+					regulator-always-on;
+					label = "VIO";
+				};
+
+				temp-mcc {
+					/* MCC internal operating temperature */
+					compatible = "arm,vexpress-temp";
+					arm,vexpress-sysreg,func = <4 0>;
+					label = "MCC";
+				};
+
+				reset {
+					compatible = "arm,vexpress-reset";
+					arm,vexpress-sysreg,func = <5 0>;
+				};
+
+				muxfpga {
+					compatible = "arm,vexpress-muxfpga";
+					arm,vexpress-sysreg,func = <7 0>;
+				};
+
+				shutdown {
+					compatible = "arm,vexpress-shutdown";
+					arm,vexpress-sysreg,func = <8 0>;
+				};
+
+				reboot {
+					compatible = "arm,vexpress-reboot";
+					arm,vexpress-sysreg,func = <9 0>;
+				};
+
+				dvimode {
+					compatible = "arm,vexpress-dvimode";
+					arm,vexpress-sysreg,func = <11 0>;
+				};
+			};
+		};
+	};
+};
diff --git a/arch/arm/dts/vexpress-v2p-ca15_a7.dts b/arch/arm/dts/vexpress-v2p-ca15_a7.dts
new file mode 100644
index 00000000000..012d40a7228
--- /dev/null
+++ b/arch/arm/dts/vexpress-v2p-ca15_a7.dts
@@ -0,0 +1,691 @@ 
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * ARM Ltd. Versatile Express
+ *
+ * CoreTile Express A15x2 A7x3
+ * Cortex-A15_A7 MPCore (V2P-CA15_A7)
+ *
+ * HBI-0249A
+ */
+
+/dts-v1/;
+#include "vexpress-v2m-rs1.dtsi"
+
+/ {
+	model = "V2P-CA15_CA7";
+	arm,hbi = <0x249>;
+	arm,vexpress,site = <0xf>;
+	compatible = "arm,vexpress,v2p-ca15_a7", "arm,vexpress";
+	interrupt-parent = <&gic>;
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	chosen { };
+
+	aliases {
+		serial0 = &v2m_serial0;
+		serial1 = &v2m_serial1;
+		serial2 = &v2m_serial2;
+		serial3 = &v2m_serial3;
+		i2c0 = &v2m_i2c_dvi;
+		i2c1 = &v2m_i2c_pcie;
+	};
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu0: cpu@0 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a15";
+			reg = <0>;
+			cci-control-port = <&cci_control1>;
+			cpu-idle-states = <&CLUSTER_SLEEP_BIG>;
+			capacity-dmips-mhz = <1024>;
+			dynamic-power-coefficient = <990>;
+		};
+
+		cpu1: cpu@1 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a15";
+			reg = <1>;
+			cci-control-port = <&cci_control1>;
+			cpu-idle-states = <&CLUSTER_SLEEP_BIG>;
+			capacity-dmips-mhz = <1024>;
+			dynamic-power-coefficient = <990>;
+		};
+
+		cpu2: cpu@2 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a7";
+			reg = <0x100>;
+			cci-control-port = <&cci_control2>;
+			cpu-idle-states = <&CLUSTER_SLEEP_LITTLE>;
+			capacity-dmips-mhz = <516>;
+			dynamic-power-coefficient = <133>;
+		};
+
+		cpu3: cpu@3 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a7";
+			reg = <0x101>;
+			cci-control-port = <&cci_control2>;
+			cpu-idle-states = <&CLUSTER_SLEEP_LITTLE>;
+			capacity-dmips-mhz = <516>;
+			dynamic-power-coefficient = <133>;
+		};
+
+		cpu4: cpu@4 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a7";
+			reg = <0x102>;
+			cci-control-port = <&cci_control2>;
+			cpu-idle-states = <&CLUSTER_SLEEP_LITTLE>;
+			capacity-dmips-mhz = <516>;
+			dynamic-power-coefficient = <133>;
+		};
+
+		idle-states {
+			CLUSTER_SLEEP_BIG: cluster-sleep-big {
+				compatible = "arm,idle-state";
+				local-timer-stop;
+				entry-latency-us = <1000>;
+				exit-latency-us = <700>;
+				min-residency-us = <2000>;
+			};
+
+			CLUSTER_SLEEP_LITTLE: cluster-sleep-little {
+				compatible = "arm,idle-state";
+				local-timer-stop;
+				entry-latency-us = <1000>;
+				exit-latency-us = <500>;
+				min-residency-us = <2500>;
+			};
+		};
+	};
+
+	memory@80000000 {
+		device_type = "memory";
+		reg = <0 0x80000000 0 0x40000000>;
+	};
+
+	reserved-memory {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		/* Chipselect 2 is physically at 0x18000000 */
+		vram: vram@18000000 {
+			/* 8 MB of designated video RAM */
+			compatible = "shared-dma-pool";
+			reg = <0 0x18000000 0 0x00800000>;
+			no-map;
+		};
+	};
+
+	wdt@2a490000 {
+		compatible = "arm,sp805", "arm,primecell";
+		reg = <0 0x2a490000 0 0x1000>;
+		interrupts = <0 98 4>;
+		clocks = <&oscclk6a>, <&oscclk6a>;
+		clock-names = "wdog_clk", "apb_pclk";
+	};
+
+	hdlcd@2b000000 {
+		compatible = "arm,hdlcd";
+		reg = <0 0x2b000000 0 0x1000>;
+		interrupts = <0 85 4>;
+		clocks = <&hdlcd_clk>;
+		clock-names = "pxlclk";
+	};
+
+	memory-controller@2b0a0000 {
+		compatible = "arm,pl341", "arm,primecell";
+		reg = <0 0x2b0a0000 0 0x1000>;
+		clocks = <&oscclk6a>;
+		clock-names = "apb_pclk";
+	};
+
+	gic: interrupt-controller@2c001000 {
+		compatible = "arm,cortex-a15-gic", "arm,cortex-a9-gic";
+		#interrupt-cells = <3>;
+		#address-cells = <0>;
+		interrupt-controller;
+		reg = <0 0x2c001000 0 0x1000>,
+		      <0 0x2c002000 0 0x2000>,
+		      <0 0x2c004000 0 0x2000>,
+		      <0 0x2c006000 0 0x2000>;
+		interrupts = <1 9 0xf04>;
+	};
+
+	cci@2c090000 {
+		compatible = "arm,cci-400";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		reg = <0 0x2c090000 0 0x1000>;
+		ranges = <0x0 0x0 0x2c090000 0x10000>;
+
+		cci_control1: slave-if@4000 {
+			compatible = "arm,cci-400-ctrl-if";
+			interface-type = "ace";
+			reg = <0x4000 0x1000>;
+		};
+
+		cci_control2: slave-if@5000 {
+			compatible = "arm,cci-400-ctrl-if";
+			interface-type = "ace";
+			reg = <0x5000 0x1000>;
+		};
+
+		pmu@9000 {
+			 compatible = "arm,cci-400-pmu,r0";
+			 reg = <0x9000 0x5000>;
+			 interrupts = <0 105 4>,
+				      <0 101 4>,
+				      <0 102 4>,
+				      <0 103 4>,
+				      <0 104 4>;
+		};
+	};
+
+	memory-controller@7ffd0000 {
+		compatible = "arm,pl354", "arm,primecell";
+		reg = <0 0x7ffd0000 0 0x1000>;
+		interrupts = <0 86 4>,
+			     <0 87 4>;
+		clocks = <&oscclk6a>;
+		clock-names = "apb_pclk";
+	};
+
+	dma@7ff00000 {
+		compatible = "arm,pl330", "arm,primecell";
+		reg = <0 0x7ff00000 0 0x1000>;
+		interrupts = <0 92 4>,
+			     <0 88 4>,
+			     <0 89 4>,
+			     <0 90 4>,
+			     <0 91 4>;
+		clocks = <&oscclk6a>;
+		clock-names = "apb_pclk";
+	};
+
+        scc@7fff0000 {
+		compatible = "arm,vexpress-scc,v2p-ca15_a7", "arm,vexpress-scc";
+		reg = <0 0x7fff0000 0 0x1000>;
+		interrupts = <0 95 4>;
+        };
+
+	timer {
+		compatible = "arm,armv7-timer";
+		interrupts = <1 13 0xf08>,
+			     <1 14 0xf08>,
+			     <1 11 0xf08>,
+			     <1 10 0xf08>;
+	};
+
+	pmu-a15 {
+		compatible = "arm,cortex-a15-pmu";
+		interrupts = <0 68 4>,
+			     <0 69 4>;
+		interrupt-affinity = <&cpu0>,
+				     <&cpu1>;
+	};
+
+	pmu-a7 {
+		compatible = "arm,cortex-a7-pmu";
+		interrupts = <0 128 4>,
+			     <0 129 4>,
+			     <0 130 4>;
+		interrupt-affinity = <&cpu2>,
+				     <&cpu3>,
+				     <&cpu4>;
+	};
+
+	oscclk6a: oscclk6a {
+		/* Reference 24MHz clock */
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <24000000>;
+		clock-output-names = "oscclk6a";
+	};
+
+	dcc {
+		compatible = "arm,vexpress,config-bus";
+		arm,vexpress,config-bridge = <&v2m_sysreg>;
+
+		oscclk0 {
+			/* A15 PLL 0 reference clock */
+			compatible = "arm,vexpress-osc";
+			arm,vexpress-sysreg,func = <1 0>;
+			freq-range = <17000000 50000000>;
+			#clock-cells = <0>;
+			clock-output-names = "oscclk0";
+		};
+
+		oscclk1 {
+			/* A15 PLL 1 reference clock */
+			compatible = "arm,vexpress-osc";
+			arm,vexpress-sysreg,func = <1 1>;
+			freq-range = <17000000 50000000>;
+			#clock-cells = <0>;
+			clock-output-names = "oscclk1";
+		};
+
+		oscclk2 {
+			/* A7 PLL 0 reference clock */
+			compatible = "arm,vexpress-osc";
+			arm,vexpress-sysreg,func = <1 2>;
+			freq-range = <17000000 50000000>;
+			#clock-cells = <0>;
+			clock-output-names = "oscclk2";
+		};
+
+		oscclk3 {
+			/* A7 PLL 1 reference clock */
+			compatible = "arm,vexpress-osc";
+			arm,vexpress-sysreg,func = <1 3>;
+			freq-range = <17000000 50000000>;
+			#clock-cells = <0>;
+			clock-output-names = "oscclk3";
+		};
+
+		oscclk4 {
+			/* External AXI master clock */
+			compatible = "arm,vexpress-osc";
+			arm,vexpress-sysreg,func = <1 4>;
+			freq-range = <20000000 40000000>;
+			#clock-cells = <0>;
+			clock-output-names = "oscclk4";
+		};
+
+		hdlcd_clk: oscclk5 {
+			/* HDLCD PLL reference clock */
+			compatible = "arm,vexpress-osc";
+			arm,vexpress-sysreg,func = <1 5>;
+			freq-range = <23750000 165000000>;
+			#clock-cells = <0>;
+			clock-output-names = "oscclk5";
+		};
+
+		smbclk: oscclk6 {
+			/* Static memory controller clock */
+			compatible = "arm,vexpress-osc";
+			arm,vexpress-sysreg,func = <1 6>;
+			freq-range = <20000000 40000000>;
+			#clock-cells = <0>;
+			clock-output-names = "oscclk6";
+		};
+
+		oscclk7 {
+			/* SYS PLL reference clock */
+			compatible = "arm,vexpress-osc";
+			arm,vexpress-sysreg,func = <1 7>;
+			freq-range = <17000000 50000000>;
+			#clock-cells = <0>;
+			clock-output-names = "oscclk7";
+		};
+
+		oscclk8 {
+			/* DDR2 PLL reference clock */
+			compatible = "arm,vexpress-osc";
+			arm,vexpress-sysreg,func = <1 8>;
+			freq-range = <20000000 50000000>;
+			#clock-cells = <0>;
+			clock-output-names = "oscclk8";
+		};
+
+		volt-a15 {
+			/* A15 CPU core voltage */
+			compatible = "arm,vexpress-volt";
+			arm,vexpress-sysreg,func = <2 0>;
+			regulator-name = "A15 Vcore";
+			regulator-min-microvolt = <800000>;
+			regulator-max-microvolt = <1050000>;
+			regulator-always-on;
+			label = "A15 Vcore";
+		};
+
+		volt-a7 {
+			/* A7 CPU core voltage */
+			compatible = "arm,vexpress-volt";
+			arm,vexpress-sysreg,func = <2 1>;
+			regulator-name = "A7 Vcore";
+			regulator-min-microvolt = <800000>;
+			regulator-max-microvolt = <1050000>;
+			regulator-always-on;
+			label = "A7 Vcore";
+		};
+
+		amp-a15 {
+			/* Total current for the two A15 cores */
+			compatible = "arm,vexpress-amp";
+			arm,vexpress-sysreg,func = <3 0>;
+			label = "A15 Icore";
+		};
+
+		amp-a7 {
+			/* Total current for the three A7 cores */
+			compatible = "arm,vexpress-amp";
+			arm,vexpress-sysreg,func = <3 1>;
+			label = "A7 Icore";
+		};
+
+		temp-dcc {
+			/* DCC internal temperature */
+			compatible = "arm,vexpress-temp";
+			arm,vexpress-sysreg,func = <4 0>;
+			label = "DCC";
+		};
+
+		power-a15 {
+			/* Total power for the two A15 cores */
+			compatible = "arm,vexpress-power";
+			arm,vexpress-sysreg,func = <12 0>;
+			label = "A15 Pcore";
+		};
+
+		power-a7 {
+			/* Total power for the three A7 cores */
+			compatible = "arm,vexpress-power";
+			arm,vexpress-sysreg,func = <12 1>;
+			label = "A7 Pcore";
+		};
+
+		energy-a15 {
+			/* Total energy for the two A15 cores */
+			compatible = "arm,vexpress-energy";
+			arm,vexpress-sysreg,func = <13 0>, <13 1>;
+			label = "A15 Jcore";
+		};
+
+		energy-a7 {
+			/* Total energy for the three A7 cores */
+			compatible = "arm,vexpress-energy";
+			arm,vexpress-sysreg,func = <13 2>, <13 3>;
+			label = "A7 Jcore";
+		};
+	};
+
+	etb@20010000 {
+		compatible = "arm,coresight-etb10", "arm,primecell";
+		reg = <0 0x20010000 0 0x1000>;
+
+		clocks = <&oscclk6a>;
+		clock-names = "apb_pclk";
+		in-ports {
+			port {
+				etb_in_port: endpoint {
+					remote-endpoint = <&replicator_out_port0>;
+				};
+			};
+		};
+	};
+
+	tpiu@20030000 {
+		compatible = "arm,coresight-tpiu", "arm,primecell";
+		reg = <0 0x20030000 0 0x1000>;
+
+		clocks = <&oscclk6a>;
+		clock-names = "apb_pclk";
+		in-ports {
+			port {
+				tpiu_in_port: endpoint {
+					remote-endpoint = <&replicator_out_port1>;
+				};
+			};
+		};
+	};
+
+	replicator {
+		/* non-configurable replicators don't show up on the
+		 * AMBA bus.  As such no need to add "arm,primecell".
+		 */
+		compatible = "arm,coresight-static-replicator";
+
+		out-ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port@0 {
+				reg = <0>;
+				replicator_out_port0: endpoint {
+					remote-endpoint = <&etb_in_port>;
+				};
+			};
+
+			port@1 {
+				reg = <1>;
+				replicator_out_port1: endpoint {
+					remote-endpoint = <&tpiu_in_port>;
+				};
+			};
+		};
+
+		in-ports {
+			port {
+				replicator_in_port0: endpoint {
+					remote-endpoint = <&funnel_out_port0>;
+				};
+			};
+		};
+	};
+
+	funnel@20040000 {
+		compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+		reg = <0 0x20040000 0 0x1000>;
+
+		clocks = <&oscclk6a>;
+		clock-names = "apb_pclk";
+		out-ports {
+			port {
+				funnel_out_port0: endpoint {
+					remote-endpoint =
+						<&replicator_in_port0>;
+				};
+			};
+		};
+
+		in-ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port@0 {
+				reg = <0>;
+				funnel_in_port0: endpoint {
+					remote-endpoint = <&ptm0_out_port>;
+				};
+			};
+
+			port@1 {
+				reg = <1>;
+				funnel_in_port1: endpoint {
+					remote-endpoint = <&ptm1_out_port>;
+				};
+			};
+
+			port@2 {
+				reg = <2>;
+				funnel_in_port2: endpoint {
+					remote-endpoint = <&etm0_out_port>;
+				};
+			};
+
+			/* Input port #3 is for ITM, not supported here */
+
+			port@4 {
+				reg = <4>;
+				funnel_in_port4: endpoint {
+					remote-endpoint = <&etm1_out_port>;
+				};
+			};
+
+			port@5 {
+				reg = <5>;
+				funnel_in_port5: endpoint {
+					remote-endpoint = <&etm2_out_port>;
+				};
+			};
+		};
+	};
+
+	ptm@2201c000 {
+		compatible = "arm,coresight-etm3x", "arm,primecell";
+		reg = <0 0x2201c000 0 0x1000>;
+
+		cpu = <&cpu0>;
+		clocks = <&oscclk6a>;
+		clock-names = "apb_pclk";
+		out-ports {
+			port {
+				ptm0_out_port: endpoint {
+					remote-endpoint = <&funnel_in_port0>;
+				};
+			};
+		};
+	};
+
+	ptm@2201d000 {
+		compatible = "arm,coresight-etm3x", "arm,primecell";
+		reg = <0 0x2201d000 0 0x1000>;
+
+		cpu = <&cpu1>;
+		clocks = <&oscclk6a>;
+		clock-names = "apb_pclk";
+		out-ports {
+			port {
+				ptm1_out_port: endpoint {
+					remote-endpoint = <&funnel_in_port1>;
+				};
+			};
+		};
+	};
+
+	etm@2203c000 {
+		compatible = "arm,coresight-etm3x", "arm,primecell";
+		reg = <0 0x2203c000 0 0x1000>;
+
+		cpu = <&cpu2>;
+		clocks = <&oscclk6a>;
+		clock-names = "apb_pclk";
+		out-ports {
+			port {
+				etm0_out_port: endpoint {
+					remote-endpoint = <&funnel_in_port2>;
+				};
+			};
+		};
+	};
+
+	etm@2203d000 {
+		compatible = "arm,coresight-etm3x", "arm,primecell";
+		reg = <0 0x2203d000 0 0x1000>;
+
+		cpu = <&cpu3>;
+		clocks = <&oscclk6a>;
+		clock-names = "apb_pclk";
+		out-ports {
+			port {
+				etm1_out_port: endpoint {
+					remote-endpoint = <&funnel_in_port4>;
+				};
+			};
+		};
+	};
+
+	etm@2203e000 {
+		compatible = "arm,coresight-etm3x", "arm,primecell";
+		reg = <0 0x2203e000 0 0x1000>;
+
+		cpu = <&cpu4>;
+		clocks = <&oscclk6a>;
+		clock-names = "apb_pclk";
+		out-ports {
+			port {
+				etm2_out_port: endpoint {
+					remote-endpoint = <&funnel_in_port5>;
+				};
+			};
+		};
+	};
+
+	smb: bus@8000000 {
+		compatible = "simple-bus";
+
+		#address-cells = <2>;
+		#size-cells = <1>;
+		ranges = <0 0 0 0x08000000 0x04000000>,
+			 <1 0 0 0x14000000 0x04000000>,
+			 <2 0 0 0x18000000 0x04000000>,
+			 <3 0 0 0x1c000000 0x04000000>,
+			 <4 0 0 0x0c000000 0x04000000>,
+			 <5 0 0 0x10000000 0x04000000>;
+
+		#interrupt-cells = <1>;
+		interrupt-map-mask = <0 0 63>;
+		interrupt-map = <0 0  0 &gic 0  0 4>,
+				<0 0  1 &gic 0  1 4>,
+				<0 0  2 &gic 0  2 4>,
+				<0 0  3 &gic 0  3 4>,
+				<0 0  4 &gic 0  4 4>,
+				<0 0  5 &gic 0  5 4>,
+				<0 0  6 &gic 0  6 4>,
+				<0 0  7 &gic 0  7 4>,
+				<0 0  8 &gic 0  8 4>,
+				<0 0  9 &gic 0  9 4>,
+				<0 0 10 &gic 0 10 4>,
+				<0 0 11 &gic 0 11 4>,
+				<0 0 12 &gic 0 12 4>,
+				<0 0 13 &gic 0 13 4>,
+				<0 0 14 &gic 0 14 4>,
+				<0 0 15 &gic 0 15 4>,
+				<0 0 16 &gic 0 16 4>,
+				<0 0 17 &gic 0 17 4>,
+				<0 0 18 &gic 0 18 4>,
+				<0 0 19 &gic 0 19 4>,
+				<0 0 20 &gic 0 20 4>,
+				<0 0 21 &gic 0 21 4>,
+				<0 0 22 &gic 0 22 4>,
+				<0 0 23 &gic 0 23 4>,
+				<0 0 24 &gic 0 24 4>,
+				<0 0 25 &gic 0 25 4>,
+				<0 0 26 &gic 0 26 4>,
+				<0 0 27 &gic 0 27 4>,
+				<0 0 28 &gic 0 28 4>,
+				<0 0 29 &gic 0 29 4>,
+				<0 0 30 &gic 0 30 4>,
+				<0 0 31 &gic 0 31 4>,
+				<0 0 32 &gic 0 32 4>,
+				<0 0 33 &gic 0 33 4>,
+				<0 0 34 &gic 0 34 4>,
+				<0 0 35 &gic 0 35 4>,
+				<0 0 36 &gic 0 36 4>,
+				<0 0 37 &gic 0 37 4>,
+				<0 0 38 &gic 0 38 4>,
+				<0 0 39 &gic 0 39 4>,
+				<0 0 40 &gic 0 40 4>,
+				<0 0 41 &gic 0 41 4>,
+				<0 0 42 &gic 0 42 4>;
+	};
+
+	site2: hsb@40000000 {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges = <0 0 0x40000000 0x3fef0000>;
+		#interrupt-cells = <1>;
+		interrupt-map-mask = <0 3>;
+		interrupt-map = <0 0 &gic 0 36 4>,
+				<0 1 &gic 0 37 4>,
+				<0 2 &gic 0 38 4>,
+				<0 3 &gic 0 39 4>;
+	};
+};
+
+&nor_flash {
+	/*
+	 * Unfortunately, accessing the flash disturbs the CPU idle states
+	 * (suspend) and CPU hotplug of this platform. For this reason, flash
+	 * hardware access is disabled by default on this platform alone.
+	 */
+	status = "disabled";
+};
diff --git a/arch/arm/dts/vexpress-v2p-ca5s.dts b/arch/arm/dts/vexpress-v2p-ca5s.dts
new file mode 100644
index 00000000000..7aa64ae2577
--- /dev/null
+++ b/arch/arm/dts/vexpress-v2p-ca5s.dts
@@ -0,0 +1,280 @@ 
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * ARM Ltd. Versatile Express
+ *
+ * CoreTile Express A5x2
+ * Cortex-A5 MPCore (V2P-CA5s)
+ *
+ * HBI-0225B
+ */
+
+/dts-v1/;
+#include "vexpress-v2m-rs1.dtsi"
+
+/ {
+	model = "V2P-CA5s";
+	arm,hbi = <0x225>;
+	arm,vexpress,site = <0xf>;
+	compatible = "arm,vexpress,v2p-ca5s", "arm,vexpress";
+	interrupt-parent = <&gic>;
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	chosen { };
+
+	aliases {
+		serial0 = &v2m_serial0;
+		serial1 = &v2m_serial1;
+		serial2 = &v2m_serial2;
+		serial3 = &v2m_serial3;
+		i2c0 = &v2m_i2c_dvi;
+		i2c1 = &v2m_i2c_pcie;
+	};
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu@0 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a5";
+			reg = <0>;
+			next-level-cache = <&L2>;
+		};
+
+		cpu@1 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a5";
+			reg = <1>;
+			next-level-cache = <&L2>;
+		};
+	};
+
+	memory@80000000 {
+		device_type = "memory";
+		reg = <0x80000000 0x40000000>;
+	};
+
+	reserved-memory {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+
+		/* Chipselect 2 is physically at 0x18000000 */
+		vram: vram@18000000 {
+			/* 8 MB of designated video RAM */
+			compatible = "shared-dma-pool";
+			reg = <0x18000000 0x00800000>;
+			no-map;
+		};
+	};
+
+	hdlcd@2a110000 {
+		compatible = "arm,hdlcd";
+		reg = <0x2a110000 0x1000>;
+		interrupts = <0 85 4>;
+		clocks = <&hdlcd_clk>;
+		clock-names = "pxlclk";
+	};
+
+	memory-controller@2a150000 {
+		compatible = "arm,pl341", "arm,primecell";
+		reg = <0x2a150000 0x1000>;
+		clocks = <&axi_clk>;
+		clock-names = "apb_pclk";
+	};
+
+	memory-controller@2a190000 {
+		compatible = "arm,pl354", "arm,primecell";
+		reg = <0x2a190000 0x1000>;
+		interrupts = <0 86 4>,
+			     <0 87 4>;
+		clocks = <&axi_clk>;
+		clock-names = "apb_pclk";
+	};
+
+	scu@2c000000 {
+		compatible = "arm,cortex-a5-scu";
+		reg = <0x2c000000 0x58>;
+	};
+
+	timer@2c000600 {
+		compatible = "arm,cortex-a5-twd-timer";
+		reg = <0x2c000600 0x20>;
+		interrupts = <1 13 0x304>;
+	};
+
+	timer@2c000200 {
+		compatible = "arm,cortex-a5-global-timer",
+		             "arm,cortex-a9-global-timer";
+		reg = <0x2c000200 0x20>;
+		interrupts = <1 11 0x304>;
+		clocks = <&cpu_clk>;
+	};
+
+	watchdog@2c000620 {
+		compatible = "arm,cortex-a5-twd-wdt";
+		reg = <0x2c000620 0x20>;
+		interrupts = <1 14 0x304>;
+	};
+
+	gic: interrupt-controller@2c001000 {
+		compatible = "arm,cortex-a5-gic", "arm,cortex-a9-gic";
+		#interrupt-cells = <3>;
+		#address-cells = <0>;
+		interrupt-controller;
+		reg = <0x2c001000 0x1000>,
+		      <0x2c000100 0x100>;
+	};
+
+	L2: cache-controller@2c0f0000 {
+		compatible = "arm,pl310-cache";
+		reg = <0x2c0f0000 0x1000>;
+		interrupts = <0 84 4>;
+		cache-level = <2>;
+	};
+
+	pmu {
+		compatible = "arm,cortex-a5-pmu";
+		interrupts = <0 68 4>,
+			     <0 69 4>;
+	};
+
+	dcc {
+		compatible = "arm,vexpress,config-bus";
+		arm,vexpress,config-bridge = <&v2m_sysreg>;
+
+		cpu_clk: oscclk0 {
+			/* CPU and internal AXI reference clock */
+			compatible = "arm,vexpress-osc";
+			arm,vexpress-sysreg,func = <1 0>;
+			freq-range = <50000000 100000000>;
+			#clock-cells = <0>;
+			clock-output-names = "oscclk0";
+		};
+
+		axi_clk: oscclk1 {
+			/* Multiplexed AXI master clock */
+			compatible = "arm,vexpress-osc";
+			arm,vexpress-sysreg,func = <1 1>;
+			freq-range = <5000000 50000000>;
+			#clock-cells = <0>;
+			clock-output-names = "oscclk1";
+		};
+
+		oscclk2 {
+			/* DDR2 */
+			compatible = "arm,vexpress-osc";
+			arm,vexpress-sysreg,func = <1 2>;
+			freq-range = <80000000 120000000>;
+			#clock-cells = <0>;
+			clock-output-names = "oscclk2";
+		};
+
+		hdlcd_clk: oscclk3 {
+			/* HDLCD */
+			compatible = "arm,vexpress-osc";
+			arm,vexpress-sysreg,func = <1 3>;
+			freq-range = <23750000 165000000>;
+			#clock-cells = <0>;
+			clock-output-names = "oscclk3";
+		};
+
+		oscclk4 {
+			/* Test chip gate configuration */
+			compatible = "arm,vexpress-osc";
+			arm,vexpress-sysreg,func = <1 4>;
+			freq-range = <80000000 80000000>;
+			#clock-cells = <0>;
+			clock-output-names = "oscclk4";
+		};
+
+		smbclk: oscclk5 {
+			/* SMB clock */
+			compatible = "arm,vexpress-osc";
+			arm,vexpress-sysreg,func = <1 5>;
+			freq-range = <25000000 60000000>;
+			#clock-cells = <0>;
+			clock-output-names = "oscclk5";
+		};
+
+		temp-dcc {
+			/* DCC internal operating temperature */
+			compatible = "arm,vexpress-temp";
+			arm,vexpress-sysreg,func = <4 0>;
+			label = "DCC";
+		};
+	};
+
+	smb: bus@8000000 {
+		compatible = "simple-bus";
+
+		#address-cells = <2>;
+		#size-cells = <1>;
+		ranges = <0 0 0x08000000 0x04000000>,
+			 <1 0 0x14000000 0x04000000>,
+			 <2 0 0x18000000 0x04000000>,
+			 <3 0 0x1c000000 0x04000000>,
+			 <4 0 0x0c000000 0x04000000>,
+			 <5 0 0x10000000 0x04000000>;
+
+		#interrupt-cells = <1>;
+		interrupt-map-mask = <0 0 63>;
+		interrupt-map = <0 0  0 &gic 0  0 4>,
+				<0 0  1 &gic 0  1 4>,
+				<0 0  2 &gic 0  2 4>,
+				<0 0  3 &gic 0  3 4>,
+				<0 0  4 &gic 0  4 4>,
+				<0 0  5 &gic 0  5 4>,
+				<0 0  6 &gic 0  6 4>,
+				<0 0  7 &gic 0  7 4>,
+				<0 0  8 &gic 0  8 4>,
+				<0 0  9 &gic 0  9 4>,
+				<0 0 10 &gic 0 10 4>,
+				<0 0 11 &gic 0 11 4>,
+				<0 0 12 &gic 0 12 4>,
+				<0 0 13 &gic 0 13 4>,
+				<0 0 14 &gic 0 14 4>,
+				<0 0 15 &gic 0 15 4>,
+				<0 0 16 &gic 0 16 4>,
+				<0 0 17 &gic 0 17 4>,
+				<0 0 18 &gic 0 18 4>,
+				<0 0 19 &gic 0 19 4>,
+				<0 0 20 &gic 0 20 4>,
+				<0 0 21 &gic 0 21 4>,
+				<0 0 22 &gic 0 22 4>,
+				<0 0 23 &gic 0 23 4>,
+				<0 0 24 &gic 0 24 4>,
+				<0 0 25 &gic 0 25 4>,
+				<0 0 26 &gic 0 26 4>,
+				<0 0 27 &gic 0 27 4>,
+				<0 0 28 &gic 0 28 4>,
+				<0 0 29 &gic 0 29 4>,
+				<0 0 30 &gic 0 30 4>,
+				<0 0 31 &gic 0 31 4>,
+				<0 0 32 &gic 0 32 4>,
+				<0 0 33 &gic 0 33 4>,
+				<0 0 34 &gic 0 34 4>,
+				<0 0 35 &gic 0 35 4>,
+				<0 0 36 &gic 0 36 4>,
+				<0 0 37 &gic 0 37 4>,
+				<0 0 38 &gic 0 38 4>,
+				<0 0 39 &gic 0 39 4>,
+				<0 0 40 &gic 0 40 4>,
+				<0 0 41 &gic 0 41 4>,
+				<0 0 42 &gic 0 42 4>;
+	};
+
+	site2: hsb@40000000 {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges = <0 0x40000000 0x40000000>;
+		#interrupt-cells = <1>;
+		interrupt-map-mask = <0 3>;
+		interrupt-map = <0 0 &gic 0 36 4>,
+				<0 1 &gic 0 37 4>,
+				<0 2 &gic 0 38 4>,
+				<0 3 &gic 0 39 4>;
+	};
+};
diff --git a/arch/arm/dts/vexpress-v2p-ca9.dts b/arch/arm/dts/vexpress-v2p-ca9.dts
new file mode 100644
index 00000000000..4c584795585
--- /dev/null
+++ b/arch/arm/dts/vexpress-v2p-ca9.dts
@@ -0,0 +1,368 @@ 
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * ARM Ltd. Versatile Express
+ *
+ * CoreTile Express A9x4
+ * Cortex-A9 MPCore (V2P-CA9)
+ *
+ * HBI-0191B
+ */
+
+/dts-v1/;
+#include "vexpress-v2m.dtsi"
+
+/ {
+	model = "V2P-CA9";
+	arm,hbi = <0x191>;
+	arm,vexpress,site = <0xf>;
+	compatible = "arm,vexpress,v2p-ca9", "arm,vexpress";
+	interrupt-parent = <&gic>;
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	chosen { };
+
+	aliases {
+		serial0 = &v2m_serial0;
+		serial1 = &v2m_serial1;
+		serial2 = &v2m_serial2;
+		serial3 = &v2m_serial3;
+		i2c0 = &v2m_i2c_dvi;
+		i2c1 = &v2m_i2c_pcie;
+	};
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		A9_0: cpu@0 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a9";
+			reg = <0>;
+			next-level-cache = <&L2>;
+		};
+
+		A9_1: cpu@1 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a9";
+			reg = <1>;
+			next-level-cache = <&L2>;
+		};
+
+		A9_2: cpu@2 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a9";
+			reg = <2>;
+			next-level-cache = <&L2>;
+		};
+
+		A9_3: cpu@3 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a9";
+			reg = <3>;
+			next-level-cache = <&L2>;
+		};
+	};
+
+	memory@60000000 {
+		device_type = "memory";
+		reg = <0x60000000 0x40000000>;
+	};
+
+	reserved-memory {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+
+		/* Chipselect 3 is physically at 0x4c000000 */
+		vram: vram@4c000000 {
+			/* 8 MB of designated video RAM */
+			compatible = "shared-dma-pool";
+			reg = <0x4c000000 0x00800000>;
+			no-map;
+		};
+	};
+
+	clcd@10020000 {
+		compatible = "arm,pl111", "arm,primecell";
+		reg = <0x10020000 0x1000>;
+		interrupt-names = "combined";
+		interrupts = <0 44 4>;
+		clocks = <&oscclk1>, <&oscclk2>;
+		clock-names = "clcdclk", "apb_pclk";
+		/* 1024x768 16bpp @65MHz */
+		max-memory-bandwidth = <95000000>;
+
+		port {
+			clcd_pads_ct: endpoint {
+				remote-endpoint = <&dvi_bridge_in_ct>;
+				arm,pl11x,tft-r0g0b0-pads = <0 8 16>;
+			};
+		};
+	};
+
+	memory-controller@100e0000 {
+		compatible = "arm,pl341", "arm,primecell";
+		reg = <0x100e0000 0x1000>;
+		clocks = <&oscclk2>;
+		clock-names = "apb_pclk";
+	};
+
+	memory-controller@100e1000 {
+		compatible = "arm,pl354", "arm,primecell";
+		reg = <0x100e1000 0x1000>;
+		interrupts = <0 45 4>,
+			     <0 46 4>;
+		clocks = <&oscclk2>;
+		clock-names = "apb_pclk";
+	};
+
+	timer@100e4000 {
+		compatible = "arm,sp804", "arm,primecell";
+		reg = <0x100e4000 0x1000>;
+		interrupts = <0 48 4>,
+			     <0 49 4>;
+		clocks = <&oscclk2>, <&oscclk2>, <&oscclk2>;
+		clock-names = "timer0clk", "timer1clk", "apb_pclk";
+		status = "disabled";
+	};
+
+	watchdog@100e5000 {
+		compatible = "arm,sp805", "arm,primecell";
+		reg = <0x100e5000 0x1000>;
+		interrupts = <0 51 4>;
+		clocks = <&oscclk2>, <&oscclk2>;
+		clock-names = "wdog_clk", "apb_pclk";
+	};
+
+	scu@1e000000 {
+		compatible = "arm,cortex-a9-scu";
+		reg = <0x1e000000 0x58>;
+	};
+
+	timer@1e000600 {
+		compatible = "arm,cortex-a9-twd-timer";
+		reg = <0x1e000600 0x20>;
+		interrupts = <1 13 0xf04>;
+	};
+
+	watchdog@1e000620 {
+		compatible = "arm,cortex-a9-twd-wdt";
+		reg = <0x1e000620 0x20>;
+		interrupts = <1 14 0xf04>;
+	};
+
+	gic: interrupt-controller@1e001000 {
+		compatible = "arm,cortex-a9-gic";
+		#interrupt-cells = <3>;
+		#address-cells = <0>;
+		interrupt-controller;
+		reg = <0x1e001000 0x1000>,
+		      <0x1e000100 0x100>;
+	};
+
+	L2: cache-controller@1e00a000 {
+		compatible = "arm,pl310-cache";
+		reg = <0x1e00a000 0x1000>;
+		interrupts = <0 43 4>;
+		cache-unified;
+		cache-level = <2>;
+		arm,data-latency = <1 1 1>;
+		arm,tag-latency = <1 1 1>;
+	};
+
+	pmu {
+		compatible = "arm,cortex-a9-pmu";
+		interrupts = <0 60 4>,
+			     <0 61 4>,
+			     <0 62 4>,
+			     <0 63 4>;
+		interrupt-affinity = <&A9_0>, <&A9_1>, <&A9_2>, <&A9_3>;
+
+	};
+
+	dcc {
+		compatible = "arm,vexpress,config-bus";
+		arm,vexpress,config-bridge = <&v2m_sysreg>;
+
+		oscclk0: extsaxiclk {
+			/* ACLK clock to the AXI master port on the test chip */
+			compatible = "arm,vexpress-osc";
+			arm,vexpress-sysreg,func = <1 0>;
+			freq-range = <30000000 50000000>;
+			#clock-cells = <0>;
+			clock-output-names = "extsaxiclk";
+		};
+
+		oscclk1: clcdclk {
+			/* Reference clock for the CLCD */
+			compatible = "arm,vexpress-osc";
+			arm,vexpress-sysreg,func = <1 1>;
+			freq-range = <10000000 80000000>;
+			#clock-cells = <0>;
+			clock-output-names = "clcdclk";
+		};
+
+		smbclk: oscclk2: tcrefclk {
+			/* Reference clock for the test chip internal PLLs */
+			compatible = "arm,vexpress-osc";
+			arm,vexpress-sysreg,func = <1 2>;
+			freq-range = <33000000 100000000>;
+			#clock-cells = <0>;
+			clock-output-names = "tcrefclk";
+		};
+
+		volt-vd10 {
+			/* Test Chip internal logic voltage */
+			compatible = "arm,vexpress-volt";
+			arm,vexpress-sysreg,func = <2 0>;
+			regulator-name = "VD10";
+			regulator-always-on;
+			label = "VD10";
+		};
+
+		volt-vd10-s2 {
+			/* PL310, L2 cache, RAM cell supply (not PL310 logic) */
+			compatible = "arm,vexpress-volt";
+			arm,vexpress-sysreg,func = <2 1>;
+			regulator-name = "VD10_S2";
+			regulator-always-on;
+			label = "VD10_S2";
+		};
+
+		volt-vd10-s3 {
+			/* Cortex-A9 system supply, Cores, MPEs, SCU and PL310 logic */
+			compatible = "arm,vexpress-volt";
+			arm,vexpress-sysreg,func = <2 2>;
+			regulator-name = "VD10_S3";
+			regulator-always-on;
+			label = "VD10_S3";
+		};
+
+		volt-vcc1v8 {
+			/* DDR2 SDRAM and Test Chip DDR2 I/O supply */
+			compatible = "arm,vexpress-volt";
+			arm,vexpress-sysreg,func = <2 3>;
+			regulator-name = "VCC1V8";
+			regulator-always-on;
+			label = "VCC1V8";
+		};
+
+		volt-ddr2vtt {
+			/* DDR2 SDRAM VTT termination voltage */
+			compatible = "arm,vexpress-volt";
+			arm,vexpress-sysreg,func = <2 4>;
+			regulator-name = "DDR2VTT";
+			regulator-always-on;
+			label = "DDR2VTT";
+		};
+
+		volt-vcc3v3 {
+			/* Local board supply for miscellaneous logic external to the Test Chip */
+			arm,vexpress-sysreg,func = <2 5>;
+			compatible = "arm,vexpress-volt";
+			regulator-name = "VCC3V3";
+			regulator-always-on;
+			label = "VCC3V3";
+		};
+
+		amp-vd10-s2 {
+			/* PL310, L2 cache, RAM cell supply (not PL310 logic) */
+			compatible = "arm,vexpress-amp";
+			arm,vexpress-sysreg,func = <3 0>;
+			label = "VD10_S2";
+		};
+
+		amp-vd10-s3 {
+			/* Cortex-A9 system supply, Cores, MPEs, SCU and PL310 logic */
+			compatible = "arm,vexpress-amp";
+			arm,vexpress-sysreg,func = <3 1>;
+			label = "VD10_S3";
+		};
+
+		power-vd10-s2 {
+			/* PL310, L2 cache, RAM cell supply (not PL310 logic) */
+			compatible = "arm,vexpress-power";
+			arm,vexpress-sysreg,func = <12 0>;
+			label = "PVD10_S2";
+		};
+
+		power-vd10-s3 {
+			/* Cortex-A9 system supply, Cores, MPEs, SCU and PL310 logic */
+			compatible = "arm,vexpress-power";
+			arm,vexpress-sysreg,func = <12 1>;
+			label = "PVD10_S3";
+		};
+	};
+
+	smb: bus@4000000 {
+		compatible = "simple-bus";
+
+		#address-cells = <2>;
+		#size-cells = <1>;
+		ranges = <0 0 0x40000000 0x04000000>,
+			 <1 0 0x44000000 0x04000000>,
+			 <2 0 0x48000000 0x04000000>,
+			 <3 0 0x4c000000 0x04000000>,
+			 <7 0 0x10000000 0x00020000>;
+
+		#interrupt-cells = <1>;
+		interrupt-map-mask = <0 0 63>;
+		interrupt-map = <0 0  0 &gic 0  0 4>,
+				<0 0  1 &gic 0  1 4>,
+				<0 0  2 &gic 0  2 4>,
+				<0 0  3 &gic 0  3 4>,
+				<0 0  4 &gic 0  4 4>,
+				<0 0  5 &gic 0  5 4>,
+				<0 0  6 &gic 0  6 4>,
+				<0 0  7 &gic 0  7 4>,
+				<0 0  8 &gic 0  8 4>,
+				<0 0  9 &gic 0  9 4>,
+				<0 0 10 &gic 0 10 4>,
+				<0 0 11 &gic 0 11 4>,
+				<0 0 12 &gic 0 12 4>,
+				<0 0 13 &gic 0 13 4>,
+				<0 0 14 &gic 0 14 4>,
+				<0 0 15 &gic 0 15 4>,
+				<0 0 16 &gic 0 16 4>,
+				<0 0 17 &gic 0 17 4>,
+				<0 0 18 &gic 0 18 4>,
+				<0 0 19 &gic 0 19 4>,
+				<0 0 20 &gic 0 20 4>,
+				<0 0 21 &gic 0 21 4>,
+				<0 0 22 &gic 0 22 4>,
+				<0 0 23 &gic 0 23 4>,
+				<0 0 24 &gic 0 24 4>,
+				<0 0 25 &gic 0 25 4>,
+				<0 0 26 &gic 0 26 4>,
+				<0 0 27 &gic 0 27 4>,
+				<0 0 28 &gic 0 28 4>,
+				<0 0 29 &gic 0 29 4>,
+				<0 0 30 &gic 0 30 4>,
+				<0 0 31 &gic 0 31 4>,
+				<0 0 32 &gic 0 32 4>,
+				<0 0 33 &gic 0 33 4>,
+				<0 0 34 &gic 0 34 4>,
+				<0 0 35 &gic 0 35 4>,
+				<0 0 36 &gic 0 36 4>,
+				<0 0 37 &gic 0 37 4>,
+				<0 0 38 &gic 0 38 4>,
+				<0 0 39 &gic 0 39 4>,
+				<0 0 40 &gic 0 40 4>,
+				<0 0 41 &gic 0 41 4>,
+				<0 0 42 &gic 0 42 4>;
+	};
+
+	site2: hsb@e0000000 {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges = <0 0xe0000000 0x20000000>;
+		#interrupt-cells = <1>;
+		interrupt-map-mask = <0 3>;
+		interrupt-map = <0 0 &gic 0 36 4>,
+				<0 1 &gic 0 37 4>,
+				<0 2 &gic 0 38 4>,
+				<0 3 &gic 0 39 4>;
+	};
+};
diff --git a/board/armltd/vexpress/Kconfig b/board/armltd/vexpress/Kconfig
new file mode 100644
index 00000000000..009296e69c4
--- /dev/null
+++ b/board/armltd/vexpress/Kconfig
@@ -0,0 +1,39 @@ 
+if ARCH_VEXPRESS
+
+config SYS_BOARD
+	default "vexpress"
+
+config SYS_VENDOR
+	default "armltd"
+
+config SYS_CONFIG_NAME
+	default "vexpress"
+
+config VEXPRESS_EXTENDED_MEMORY_MAP
+	bool
+	default n
+
+choice
+        prompt "Arm VExpress coretile"
+
+config TARGET_VEXPRESS_CA15_TC2
+	bool "Arm Versatile Express TC2 (Cortex-A15/A7)"
+	select CPU_V7_HAS_NONSEC
+	select CPU_V7_HAS_VIRT
+	select VEXPRESS_EXTENDED_MEMORY_MAP
+	select OF_BOARD_SETUP
+
+config TARGET_VEXPRESS_CA5X2
+	bool "Arm Versatile Express Cortex-A5x2"
+	select VEXPRESS_EXTENDED_MEMORY_MAP
+
+config TARGET_VEXPRESS_CA9X4
+	bool "Arm Versatile Express Cortex-A9x4"
+
+endchoice
+
+config SYS_TEXT_BASE
+	default 0x80800000 if VEXPRESS_EXTENDED_MEMORY_MAP
+	default 0x60800000
+
+endif
diff --git a/board/armltd/vexpress/MAINTAINERS b/board/armltd/vexpress/MAINTAINERS
new file mode 100644
index 00000000000..7ccbea61f40
--- /dev/null
+++ b/board/armltd/vexpress/MAINTAINERS
@@ -0,0 +1,8 @@ 
+VERSATILE EXPRESS BOARDS
+M:	Linus Walleij <linus.walleij@linaro.org>
+S:	Maintained
+F:	board/armltd/vexpress/
+F:	include/configs/vexpress.h
+F:	configs/vexpress_ca15_tc2_defconfig
+F:	configs/vexpress_ca5x2_defconfig
+F:	configs/vexpress_ca9x4_defconfig
diff --git a/board/armltd/vexpress/Makefile b/board/armltd/vexpress/Makefile
new file mode 100644
index 00000000000..db14c43ad14
--- /dev/null
+++ b/board/armltd/vexpress/Makefile
@@ -0,0 +1,7 @@ 
+# SPDX-License-Identifier: GPL-2.0+
+#
+# (C) Copyright 2000-2004
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+
+obj-y	:= vexpress_common.o
+obj-$(CONFIG_CPU_V7_HAS_VIRT)	+= vexpress_tc2.o
diff --git a/board/armltd/vexpress/vexpress_common.c b/board/armltd/vexpress/vexpress_common.c
new file mode 100644
index 00000000000..6ffb6061026
--- /dev/null
+++ b/board/armltd/vexpress/vexpress_common.c
@@ -0,0 +1,196 @@ 
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * (C) Copyright 2002
+ * David Mueller, ELSOFT AG, <d.mueller@elsoft.ch>
+ *
+ * (C) Copyright 2003
+ * Texas Instruments, <www.ti.com>
+ * Kshitij Gupta <Kshitij@ti.com>
+ *
+ * (C) Copyright 2004
+ * ARM Ltd.
+ * Philippe Robin, <philippe.robin@arm.com>
+ */
+#include <common.h>
+#include <bootstage.h>
+#include <cpu_func.h>
+#include <init.h>
+#include <malloc.h>
+#include <errno.h>
+#include <asm/global_data.h>
+#include <asm/io.h>
+#include <asm/mach-types.h>
+#include <asm/arch/systimer.h>
+#include <asm/arch/sysctrl.h>
+#include <asm/arch/wdt.h>
+#ifdef CONFIG_ARM_PL180_MMCI
+#include "../drivers/mmc/arm_pl180_mmci.h"
+#endif
+
+#define SYS_CFG_START           (1 << 31)
+#define SYS_CFG_WRITE           (1 << 30)
+#define SYS_CFG_OSC             (1 << 20)
+#define SYS_CFG_VOLT            (2 << 20)
+#define SYS_CFG_AMP             (3 << 20)
+#define SYS_CFG_TEMP            (4 << 20)
+#define SYS_CFG_RESET           (5 << 20)
+#define SYS_CFG_SCC             (6 << 20)
+#define SYS_CFG_MUXFPGA         (7 << 20)
+#define SYS_CFG_SHUTDOWN        (8 << 20)
+#define SYS_CFG_REBOOT          (9 << 20)
+#define SYS_CFG_DVIMODE         (11 << 20)
+#define SYS_CFG_POWER           (12 << 20)
+#define SYS_CFG_SITE_MB         (0 << 16)
+#define SYS_CFG_SITE_DB1        (1 << 16)
+#define SYS_CFG_SITE_DB2        (2 << 16)
+#define SYS_CFG_STACK(n)        ((n) << 12)
+#define SYS_CFG_ERR             (1 << 1)
+#define SYS_CFG_COMPLETE        (1 << 0)
+
+static struct systimer *systimer_base = (struct systimer *)V2M_TIMER01;
+static struct sysctrl *sysctrl_base = (struct sysctrl *)SCTL_BASE;
+
+static void flash__init(void);
+static void vexpress_timer_init(void);
+DECLARE_GLOBAL_DATA_PTR;
+
+#if defined(CONFIG_SHOW_BOOT_PROGRESS)
+void show_boot_progress(int progress)
+{
+	printf("Boot reached stage %d\n", progress);
+}
+#endif
+
+int board_init(void)
+{
+	icache_enable();
+	flash__init();
+	vexpress_timer_init();
+
+	return 0;
+}
+
+int cpu_mmc_init(struct bd_info *bis)
+{
+	int rc = 0;
+	(void) bis;
+#ifdef CONFIG_ARM_PL180_MMCI
+	struct pl180_mmc_host *host;
+	struct mmc *mmc;
+
+	host = malloc(sizeof(struct pl180_mmc_host));
+	if (!host)
+		return -ENOMEM;
+	memset(host, 0, sizeof(*host));
+
+	strcpy(host->name, "MMC");
+	host->base = (struct sdi_registers *)CONFIG_ARM_PL180_MMCI_BASE;
+	host->pwr_init = INIT_PWR;
+	host->clkdiv_init = SDI_CLKCR_CLKDIV_INIT_V1 | SDI_CLKCR_CLKEN;
+	host->voltages = VOLTAGE_WINDOW_MMC;
+	host->caps = 0;
+	host->clock_in = ARM_MCLK;
+	host->clock_min = ARM_MCLK / (2 * (SDI_CLKCR_CLKDIV_INIT_V1 + 1));
+	host->clock_max = CONFIG_ARM_PL180_MMCI_CLOCK_FREQ;
+	rc = arm_pl180_mmci_init(host, &mmc);
+#endif
+	return rc;
+}
+
+static void flash__init(void)
+{
+	/* Setup the sytem control register to allow writing to flash */
+	writel(readl(&sysctrl_base->scflashctrl) | VEXPRESS_FLASHPROG_FLVPPEN,
+	       &sysctrl_base->scflashctrl);
+}
+
+int dram_init(void)
+{
+	return fdtdec_setup_mem_size_base();
+}
+
+int dram_init_banksize(void)
+{
+	return fdtdec_setup_memory_banksize();
+}
+
+/*
+ * Start timer:
+ *    Setup a 32 bit timer, running at 1KHz
+ *    Versatile Express Motherboard provides 1 MHz timer
+ */
+static void vexpress_timer_init(void)
+{
+	/*
+	 * Set clock frequency in system controller:
+	 *   VEXPRESS_REFCLK is 32KHz
+	 *   VEXPRESS_TIMCLK is 1MHz
+	 */
+	writel(SP810_TIMER0_ENSEL | SP810_TIMER1_ENSEL |
+	       SP810_TIMER2_ENSEL | SP810_TIMER3_ENSEL |
+	       readl(&sysctrl_base->scctrl), &sysctrl_base->scctrl);
+
+	/*
+	 * Set Timer0 to be:
+	 *   Enabled, free running, no interrupt, 32-bit, wrapping
+	 */
+	writel(SYSTIMER_RELOAD, &systimer_base->timer0load);
+	writel(SYSTIMER_RELOAD, &systimer_base->timer0value);
+	writel(SYSTIMER_EN | SYSTIMER_32BIT |
+	       readl(&systimer_base->timer0control),
+	       &systimer_base->timer0control);
+}
+
+static int v2m_cfg_write(u32 devfn, u32 data)
+{
+	/* Configuration interface broken? */
+	u32 val;
+
+	devfn |= SYS_CFG_START | SYS_CFG_WRITE;
+
+	val = readl(V2M_SYS_CFGSTAT);
+	writel(val & ~SYS_CFG_COMPLETE, V2M_SYS_CFGSTAT);
+
+	writel(data, V2M_SYS_CFGDATA);
+	writel(devfn, V2M_SYS_CFGCTRL);
+
+	do {
+		val = readl(V2M_SYS_CFGSTAT);
+	} while (val == 0);
+
+	return !!(val & SYS_CFG_ERR);
+}
+
+/* Use the ARM Watchdog System to cause reset */
+void reset_cpu(void)
+{
+	if (v2m_cfg_write(SYS_CFG_REBOOT | SYS_CFG_SITE_MB, 0))
+		printf("Unable to reboot\n");
+}
+
+void lowlevel_init(void)
+{
+}
+
+ulong get_board_rev(void){
+	return readl((u32 *)SYS_ID);
+}
+
+#ifdef CONFIG_ARMV7_NONSEC
+/* Setting the address at which secondary cores start from.
+ * Versatile Express uses one address for all cores, so ignore corenr
+ */
+void smp_set_core_boot_addr(unsigned long addr, int corenr)
+{
+	/* The SYSFLAGS register on VExpress needs to be cleared first
+	 * by writing to the next address, since any writes to the address
+	 * at offset 0 will only be ORed in
+	 */
+	writel(~0, VEXPRESS_SYSFLAGS_ADDR + 4);
+	writel(addr, VEXPRESS_SYSFLAGS_ADDR);
+}
+#endif
diff --git a/board/armltd/vexpress/vexpress_tc2.c b/board/armltd/vexpress/vexpress_tc2.c
new file mode 100644
index 00000000000..f965f811982
--- /dev/null
+++ b/board/armltd/vexpress/vexpress_tc2.c
@@ -0,0 +1,82 @@ 
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2016 Linaro
+ * Jon Medhurst <tixy@linaro.org>
+ *
+ * TC2 specific code for Versatile Express.
+ */
+
+#include <asm/armv7.h>
+#include <asm/io.h>
+#include <asm/u-boot.h>
+#include <common.h>
+#include <linux/libfdt.h>
+
+#define SCC_BASE	0x7fff0000
+
+bool armv7_boot_nonsec_default(void)
+{
+#ifdef CONFIG_ARMV7_BOOT_SEC_DEFAULT
+	return false;
+#else
+	/*
+	 * The Serial Configuration Controller (SCC) register at address 0x700
+	 * contains flags for configuring the behaviour of the Boot Monitor
+	 * (which CPUs execute from reset). Two of these bits are of interest:
+	 *
+	 * bit 12 = Use per-cpu mailboxes for power management
+	 * bit 13 = Power down the non-boot cluster
+	 *
+	 * It is only when both of these are false that U-Boot's current
+	 * implementation of 'nonsec' mode can work as expected because we
+	 * rely on getting all CPUs to execute _nonsec_init, so let's check that.
+	 */
+	return (readl((u32 *)(SCC_BASE + 0x700)) & ((1 << 12) | (1 << 13))) == 0;
+#endif
+}
+
+int ft_board_setup(void *fdt, struct bd_info *bd)
+{
+	int offset, tmp, len;
+	const struct fdt_property *prop;
+	const char *cci_compatible = "arm,cci-400-ctrl-if";
+
+#ifdef CONFIG_ARMV7_NONSEC
+	if (!armv7_boot_nonsec())
+		return 0;
+#else
+	return 0;
+#endif
+	/* Booting in nonsec mode, disable CCI access */
+	offset = fdt_path_offset(fdt, "/cpus");
+	if (offset < 0) {
+		printf("couldn't find /cpus\n");
+		return offset;
+	}
+
+	/* delete cci-control-port in each cpu node */
+	for (tmp = fdt_first_subnode(fdt, offset); tmp >= 0;
+	     tmp = fdt_next_subnode(fdt, tmp))
+		fdt_delprop(fdt, tmp, "cci-control-port");
+
+	/* disable all ace cci slave ports */
+	offset = fdt_node_offset_by_prop_value(fdt, offset, "compatible",
+					       cci_compatible, 20);
+	while (offset > 0) {
+		prop = fdt_get_property(fdt, offset, "interface-type",
+					&len);
+		if (!prop)
+			continue;
+		if (len < 4)
+			continue;
+		if (strcmp(prop->data, "ace"))
+			continue;
+
+		fdt_setprop_string(fdt, offset, "status", "disabled");
+
+		offset = fdt_node_offset_by_prop_value(fdt, offset, "compatible",
+						       cci_compatible, 20);
+	}
+
+	return 0;
+}
diff --git a/configs/vexpress_ca15_tc2_defconfig b/configs/vexpress_ca15_tc2_defconfig
new file mode 100644
index 00000000000..68dfc4573e7
--- /dev/null
+++ b/configs/vexpress_ca15_tc2_defconfig
@@ -0,0 +1,16 @@ 
+CONFIG_ARM=y
+CONFIG_ARCH_VEXPRESS=y
+CONFIG_DEFAULT_DEVICE_TREE="vexpress-v2p-ca15_a7"
+CONFIG_TARGET_VEXPRESS_CA15_TC2=y
+CONFIG_BOOTCOMMAND="run distro_bootcmd; run bootflash"
+# CONFIG_DISPLAY_CPUINFO is not set
+CONFIG_CMD_UBI=y
+CONFIG_ENV_OVERWRITE=y
+CONFIG_ENV_ADDR=0xFF80000
+# CONFIG_MMC is not set
+CONFIG_SYS_FLASH_USE_BUFFER_WRITE=y
+CONFIG_SYS_FLASH_PROTECTION=y
+CONFIG_SYS_FLASH_CFI=y
+CONFIG_SMC911X=y
+CONFIG_BAUDRATE=38400
+# CONFIG_EFI_LOADER is not set
diff --git a/configs/vexpress_ca5x2_defconfig b/configs/vexpress_ca5x2_defconfig
new file mode 100644
index 00000000000..f5174b3dec3
--- /dev/null
+++ b/configs/vexpress_ca5x2_defconfig
@@ -0,0 +1,15 @@ 
+CONFIG_ARM=y
+CONFIG_ARCH_VEXPRESS=y
+CONFIG_DEFAULT_DEVICE_TREE="vexpress-v2p-ca5s"
+CONFIG_TARGET_VEXPRESS_CA5X2=y
+CONFIG_BOOTCOMMAND="run distro_bootcmd; run bootflash"
+# CONFIG_DISPLAY_CPUINFO is not set
+CONFIG_CMD_UBI=y
+CONFIG_ENV_OVERWRITE=y
+CONFIG_ENV_ADDR=0xFF80000
+# CONFIG_MMC is not set
+CONFIG_SYS_FLASH_USE_BUFFER_WRITE=y
+CONFIG_SYS_FLASH_PROTECTION=y
+CONFIG_SYS_FLASH_CFI=y
+CONFIG_SMC911X=y
+CONFIG_BAUDRATE=38400
diff --git a/configs/vexpress_ca9x4_defconfig b/configs/vexpress_ca9x4_defconfig
new file mode 100644
index 00000000000..017bf4a2f0c
--- /dev/null
+++ b/configs/vexpress_ca9x4_defconfig
@@ -0,0 +1,15 @@ 
+CONFIG_ARM=y
+CONFIG_ARCH_VEXPRESS=y
+CONFIG_DEFAULT_DEVICE_TREE="vexpress-v2p-ca9"
+CONFIG_TARGET_VEXPRESS_CA9X4=y
+CONFIG_BOOTCOMMAND="run distro_bootcmd; run bootflash"
+# CONFIG_DISPLAY_CPUINFO is not set
+CONFIG_CMD_UBI=y
+CONFIG_ENV_OVERWRITE=y
+CONFIG_ENV_ADDR=0x47F80000
+# CONFIG_MMC is not set
+CONFIG_SYS_FLASH_USE_BUFFER_WRITE=y
+CONFIG_SYS_FLASH_PROTECTION=y
+CONFIG_SYS_FLASH_CFI=y
+CONFIG_SMC911X=y
+CONFIG_BAUDRATE=38400
diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig
index 57a4efb88ed..1844941eb21 100644
--- a/drivers/i2c/Kconfig
+++ b/drivers/i2c/Kconfig
@@ -479,7 +479,7 @@  config SYS_I2C_UNIPHIER_F
 
 config SYS_I2C_VERSATILE
 	bool "Arm Ltd Versatile I2C bus driver"
-	depends on DM_I2C && TARGET_VEXPRESS64_JUNO
+	depends on DM_I2C && (TARGET_VEXPRESS_CA15_TC2 || TARGET_VEXPRESS64_JUNO)
 	help
 	  Add support for the Arm Ltd Versatile Express I2C driver. The I2C host
 	  controller is present in the development boards manufactured by Arm Ltd.
diff --git a/env/Kconfig b/env/Kconfig
index 1411f9e815e..0203983b1d6 100644
--- a/env/Kconfig
+++ b/env/Kconfig
@@ -80,7 +80,7 @@  config ENV_IS_IN_EXT4
 config ENV_IS_IN_FLASH
 	bool "Environment in flash memory"
 	depends on !CHAIN_OF_TRUST
-	default y if ARCH_CINTEGRATOR
+	default y if ARCH_CINTEGRATOR || ARCH_VEXPRESS
 	default y if ARCH_INTEGRATOR_CP
 	default y if M548x || M547x || M5282 || MCF547x_8x
 	default y if MCF532x || MCF52x2
@@ -564,6 +564,7 @@  config ENV_OFFSET_REDUND
 config ENV_SIZE
 	hex "Environment Size"
 	default 0x40000 if ENV_IS_IN_SPI_FLASH && ARCH_ZYNQMP
+	default 0x40000 if ARCH_VEXPRESS
 	default 0x20000 if ARCH_SUNXI || ARCH_ZYNQ || ARCH_OMAP2PLUS || ARCH_AT91
 	default 0x8000 if ARCH_ROCKCHIP && ENV_IS_IN_MMC
 	default 0x2000 if ARCH_ROCKCHIP && ENV_IS_IN_SPI_FLASH
@@ -577,7 +578,7 @@  config ENV_SECT_SIZE
 	hex "Environment Sector-Size"
 	depends on ENV_IS_IN_FLASH || ENV_IS_IN_SPI_FLASH
 	default 0x2000 if ARCH_ROCKCHIP
-	default 0x40000 if ARCH_ZYNQMP || ARCH_VERSAL
+	default 0x40000 if ARCH_ZYNQMP || ARCH_VERSAL || ARCH_VEXPRESS
 	default 0x20000 if ARCH_ZYNQ || ARCH_OMAP2PLUS || ARCH_AT91
 	default 0x20000 if MICROBLAZE && ENV_IS_IN_SPI_FLASH
 	help
diff --git a/include/configs/vexpress_common.h b/include/configs/vexpress.h
similarity index 62%
rename from include/configs/vexpress_common.h
rename to include/configs/vexpress.h
index b131480e5bc..5d8baf15773 100644
--- a/include/configs/vexpress_common.h
+++ b/include/configs/vexpress.h
@@ -8,14 +8,14 @@ 
  *   configurations.
  */
 
-#ifndef __VEXPRESS_COMMON_H
-#define __VEXPRESS_COMMON_H
+#ifndef __VEXPRESS_H
+#define __VEXPRESS_H
 
 /*
  * Definitions copied from linux kernel:
  * arch/arm/mach-vexpress/include/mach/motherboard.h
  */
-#ifdef CONFIG_VEXPRESS_ORIGINAL_MEMORY_MAP
+#ifndef CONFIG_VEXPRESS_EXTENDED_MEMORY_MAP
 /* CS register bases for the original memory map. */
 #define V2M_PA_CS0		0x40000000
 #define V2M_PA_CS1		0x44000000
@@ -29,8 +29,7 @@ 
 #define V2M_SERIAL_BUS_PCI	(V2M_PA_CS7 + V2M_PERIPH_OFFSET(2))
 
 #define V2M_BASE		0x60000000
-#elif defined(CONFIG_VEXPRESS_EXTENDED_MEMORY_MAP)
-/* CS register bases for the extended memory map. */
+#else		/* CS register bases for the extended memory map. */
 #define V2M_PA_CS0		0x08000000
 #define V2M_PA_CS1		0x0c000000
 #define V2M_PA_CS2		0x14000000
@@ -50,71 +49,18 @@ 
  */
 #define V2M_NOR0		(V2M_PA_CS0)
 #define V2M_NOR1		(V2M_PA_CS1)
-#define V2M_SRAM		(V2M_PA_CS2)
-#define V2M_VIDEO_SRAM		(V2M_PA_CS3 + 0x00000000)
-#define V2M_ISP1761		(V2M_PA_CS3 + 0x03000000)
 
 /* Common peripherals relative to CS7. */
-#define V2M_AACI		(V2M_PA_CS7 + V2M_PERIPH_OFFSET(4))
-#define V2M_MMCI		(V2M_PA_CS7 + V2M_PERIPH_OFFSET(5))
-#define V2M_KMI0		(V2M_PA_CS7 + V2M_PERIPH_OFFSET(6))
-#define V2M_KMI1		(V2M_PA_CS7 + V2M_PERIPH_OFFSET(7))
-
-#define V2M_UART0		(V2M_PA_CS7 + V2M_PERIPH_OFFSET(9))
-#define V2M_UART1		(V2M_PA_CS7 + V2M_PERIPH_OFFSET(10))
-#define V2M_UART2		(V2M_PA_CS7 + V2M_PERIPH_OFFSET(11))
-#define V2M_UART3		(V2M_PA_CS7 + V2M_PERIPH_OFFSET(12))
-
-#define V2M_WDT			(V2M_PA_CS7 + V2M_PERIPH_OFFSET(15))
-
 #define V2M_TIMER01		(V2M_PA_CS7 + V2M_PERIPH_OFFSET(17))
 #define V2M_TIMER23		(V2M_PA_CS7 + V2M_PERIPH_OFFSET(18))
 
-#define V2M_SERIAL_BUS_DVI	(V2M_PA_CS7 + V2M_PERIPH_OFFSET(22))
-#define V2M_RTC			(V2M_PA_CS7 + V2M_PERIPH_OFFSET(23))
-
-#define V2M_CF			(V2M_PA_CS7 + V2M_PERIPH_OFFSET(26))
-
-#define V2M_CLCD		(V2M_PA_CS7 + V2M_PERIPH_OFFSET(31))
-#define V2M_SIZE_CS7		V2M_PERIPH_OFFSET(32)
-
 /* System register offsets. */
 #define V2M_SYS_CFGDATA		(V2M_SYSREGS + 0x0a0)
 #define V2M_SYS_CFGCTRL		(V2M_SYSREGS + 0x0a4)
 #define V2M_SYS_CFGSTAT		(V2M_SYSREGS + 0x0a8)
 
-/*
- * Configuration
- */
-#define SYS_CFG_START		(1 << 31)
-#define SYS_CFG_WRITE		(1 << 30)
-#define SYS_CFG_OSC		(1 << 20)
-#define SYS_CFG_VOLT		(2 << 20)
-#define SYS_CFG_AMP		(3 << 20)
-#define SYS_CFG_TEMP		(4 << 20)
-#define SYS_CFG_RESET		(5 << 20)
-#define SYS_CFG_SCC		(6 << 20)
-#define SYS_CFG_MUXFPGA		(7 << 20)
-#define SYS_CFG_SHUTDOWN	(8 << 20)
-#define SYS_CFG_REBOOT		(9 << 20)
-#define SYS_CFG_DVIMODE		(11 << 20)
-#define SYS_CFG_POWER		(12 << 20)
-#define SYS_CFG_SITE_MB		(0 << 16)
-#define SYS_CFG_SITE_DB1	(1 << 16)
-#define SYS_CFG_SITE_DB2	(2 << 16)
-#define SYS_CFG_STACK(n)	((n) << 12)
-
-#define SYS_CFG_ERR		(1 << 1)
-#define SYS_CFG_COMPLETE	(1 << 0)
-
 /* Board info register */
 #define SYS_ID				V2M_SYSREGS
-#define CONFIG_REVISION_TAG		1
-
-#define CONFIG_CMDLINE_TAG		1	/* enable passing of ATAGs */
-#define CONFIG_SETUP_MEMORY_TAGS	1
-#define CONFIG_SYS_L2CACHE_OFF		1
-#define CONFIG_INITRD_TAG		1
 
 /* Size of malloc() pool */
 #define CONFIG_SYS_MALLOC_LEN		(CONFIG_ENV_SIZE + 512 * 1024) /* >= 512 KiB */
@@ -128,12 +74,6 @@ 
 
 /* PL011 Serial Configuration */
 #define CONFIG_PL011_CLOCK		24000000
-#define CONFIG_PL01x_PORTS		{(void *)CONFIG_SYS_SERIAL0, \
-					 (void *)CONFIG_SYS_SERIAL1}
-
-#define CONFIG_SYS_BAUDRATE_TABLE	{ 9600, 19200, 38400, 57600, 115200 }
-#define CONFIG_SYS_SERIAL0		V2M_UART0
-#define CONFIG_SYS_SERIAL1		V2M_UART1
 
 #define CONFIG_ARM_PL180_MMCI_BASE	V2M_MMCI
 #define CONFIG_SYS_MMC_MAX_BLK_COUNT	127
@@ -144,32 +84,18 @@ 
 
 /* Miscellaneous configurable options */
 #define CONFIG_SYS_LOAD_ADDR		(V2M_BASE + 0x8000)
-#define LINUX_BOOT_PARAM_ADDR		(V2M_BASE + 0x2000)
-
-/* Physical Memory Map */
-#define PHYS_SDRAM_1			(V2M_BASE)	/* SDRAM Bank #1 */
-#define PHYS_SDRAM_2			(((unsigned int)V2M_BASE) + \
-					((unsigned int)0x20000000))
-#define PHYS_SDRAM_1_SIZE		0x20000000	/* 512 MB */
-#define PHYS_SDRAM_2_SIZE		0x20000000	/* 512 MB */
 
 /* additions for new relocation code */
-#define CONFIG_SYS_SDRAM_BASE		PHYS_SDRAM_1
-#define CONFIG_SYS_INIT_RAM_SIZE		0x1000
-#define CONFIG_SYS_GBL_DATA_OFFSET	(CONFIG_SYS_SDRAM_BASE + \
-					 CONFIG_SYS_INIT_RAM_SIZE - \
-					 GENERATED_GBL_DATA_SIZE)
-#define CONFIG_SYS_INIT_SP_ADDR		CONFIG_SYS_GBL_DATA_OFFSET
+#define CONFIG_SYS_SDRAM_BASE		V2M_BASE
+#define CONFIG_SYS_INIT_SP_ADDR		(CONFIG_SYS_SDRAM_BASE + 0x1000)
 
 /* Basic environment settings */
 #define BOOT_TARGET_DEVICES(func) \
-        func(MMC, mmc, 1) \
-        func(MMC, mmc, 0) \
         func(PXE, pxe, na) \
         func(DHCP, dhcp, na)
 #include <config_distro_bootcmd.h>
 
-#ifdef CONFIG_VEXPRESS_ORIGINAL_MEMORY_MAP
+#ifndef CONFIG_VEXPRESS_EXTENDED_MEMORY_MAP
 #define CONFIG_PLATFORM_ENV_SETTINGS \
 		"loadaddr=0x80008000\0" \
 		"ramdisk_addr_r=0x61000000\0" \
@@ -179,7 +105,7 @@ 
 		"pxefile_addr_r=0x88000000\0" \
 		"scriptaddr=0x88000000\0" \
 		"kernel_addr_r=0x80008000\0"
-#elif defined(CONFIG_VEXPRESS_EXTENDED_MEMORY_MAP)
+#else
 #define CONFIG_PLATFORM_ENV_SETTINGS \
 		"loadaddr=0xa0008000\0" \
 		"ramdisk_addr_r=0x81000000\0" \
@@ -204,7 +130,7 @@ 
 		"bootflash=run flashargs; " \
 			"cp ${ramdisk_addr} ${ramdisk_addr_r} ${maxramdisk}; " \
 			"bootm ${kernel_addr} ${ramdisk_addr_r}\0" \
-		"fdtfile=" CONFIG_DEFAULT_FDT_FILE "\0"
+		"fdtfile=" CONFIG_DEFAULT_DEVICE_TREE ".dtb\0"
 
 /* FLASH and environment organization */
 #define PHYS_FLASH_SIZE			0x04000000	/* 64MB */
@@ -238,4 +164,9 @@ 
 /* Monitor Command Prompt */
 #define CONFIG_SYS_CBSIZE		512	/* Console I/O Buffer Size */
 
-#endif /* VEXPRESS_COMMON_H */
+#ifdef CONFIG_CPU_V7_HAS_VIRT
+#define VEXPRESS_SYSFLAGS_ADDR		0x1c010030
+#define CONFIG_SMP_PEN_ADDR		VEXPRESS_SYSFLAGS_ADDR
+#endif
+
+#endif /* VEXPRESS_H */
diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt
index 3dbcc042a8a..befc4e5b2b2 100644
--- a/scripts/config_whitelist.txt
+++ b/scripts/config_whitelist.txt
@@ -3827,7 +3827,6 @@  CONFIG_U_BOOT_HDR_SIZE
 CONFIG_VAL
 CONFIG_VAR_SIZE_SPL
 CONFIG_VERY_BIG_RAM
-CONFIG_VEXPRESS_ORIGINAL_MEMORY_MAP
 CONFIG_VIDEO_BCM2835
 CONFIG_VIDEO_BMP_LOGO
 CONFIG_VIDEO_DA8XX