U-Boot
Threads by month
- ----- 2025 -----
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2002 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2001 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2000 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
February 2019
- 210 participants
- 662 discussions

[U-Boot] [PATCH 00/19] stm32mp1: update of stm32mp arch and stm32mp1 board
by Patrick Delaunay 27 Feb '19
by Patrick Delaunay 27 Feb '19
27 Feb '19
Need to be apply after the previous serie:
stm32mp1: add trusted boot with TF-A
http://patchwork.ozlabs.org/project/uboot/list/?series=91422
It is a first alignment on the delivery v2018.11-stm32mp-r2
available on GITHUB https://github.com/STMicroelectronics/u-boot
Patrick Delaunay (19):
stm32mp1: add runtime information in environment
stm32mp1: update boot mode management
stm32mp1: update print_cpuinfo()
stm32mp1: spl: add spl_display_print
stm32mp1: cosmetic cleanup Kconfig
stm32mp1: cosmetic: add comment on psci_migrate_info_type return value
stm32mp1: spl: hang with trace when DDR init failed
stm32mp1: update bootcmd
stm32mp1: activate FASTBOOT on eMMC
stm32mp1: support forced boot mode
stm32mp1: update memory layout
stm32mp1: activated some configuration
stm32mp1: add some syscon drivers for syscfg and etpzc
stm32mp1: add syscfg initialization
stm32mp1: align serial number on bootrom
stm32mp1: basic boot: SPL enable access to GPIOZ bank
stm32mp1: bsec: use device tree new compatible
stm32mp1: bsec: shadow all the upper OTP (no secure) during boot
stm32mp1: Replace OTP read by SHADOW read
arch/arm/Kconfig | 1 +
arch/arm/dts/stm32mp157-u-boot.dtsi | 4 +
arch/arm/dts/stm32mp157c-ed1-u-boot.dtsi | 5 +
arch/arm/dts/stm32mp157c.dtsi | 9 +-
arch/arm/mach-stm32mp/Kconfig | 12 +-
arch/arm/mach-stm32mp/bsec.c | 32 ++--
arch/arm/mach-stm32mp/cpu.c | 209 ++++++++++++++++++++++---
arch/arm/mach-stm32mp/include/mach/stm32.h | 19 ++-
arch/arm/mach-stm32mp/include/mach/sys_proto.h | 12 +-
arch/arm/mach-stm32mp/psci.c | 8 +-
arch/arm/mach-stm32mp/spl.c | 39 ++++-
arch/arm/mach-stm32mp/syscon.c | 9 +-
board/st/stm32mp1/stm32mp1.c | 200 ++++++++++++++++++++++-
configs/stm32mp15_basic_defconfig | 15 +-
configs/stm32mp15_trusted_defconfig | 15 +-
include/configs/stm32mp1.h | 60 +++++--
16 files changed, 571 insertions(+), 78 deletions(-)
--
2.7.4
1
19

27 Feb '19
This patch-set finish the previous serie:
http://patchwork.ozlabs.org/project/uboot/list/?series=76834
and also replace the serie:
"Remove defines for SPI default speed and mode "
http://patchwork.ozlabs.org/project/uboot/list/?series=80769&state=*
This new version is a complete rework after several remarks
and regression for these 2 patchset, mainly when SPI node
configuration is not in DT, when platdata is used.
I take some time to check the code and this 3rd proposal
is a rework of commit
96907c0fe50a ("dm: spi: Read default speed and mode values from DT")
This patch avoid spi_get_bus_and_cs() callers to force value of
parameter speed to 0 for some board (without DT node)
and regression for other board (as i was the case in my previous
Series V2).
I see this kind of problem in file env/sf.c with first commit
96907c0fe50a ("dm: spi: Read default speed and mode values from DT")
and come-back to the previous behavior with CONFIG_ in the commit
25a17652c9c2 ("fix: env: Fix the SPI flash device setup for DM mode")
So I decide to don't remove the defines used for default value
of speed and mode but they are no more used when platdata
is available.
That avoid regression when spi_get_bus_and_cs is directly called.
NB: I don't sure that the behavior of 'compatibility' function
spi_setup_slave() will be still is still the correct on
(in some case speed and mode will parameter will be not used).
Tested on my board only for the boot from SPI NOR
so when spl_spi_load_image() is called in SPL.
Changes in v3:
- complete rework of the patch-set to avoid regression
Changes in v2:
- use variables to avoid duplicated code
Patrick Delaunay (1):
dm: spi: Read default speed and mode values from DT
README | 3 +++
cmd/sf.c | 3 +--
common/spl/spl_spi.c | 2 ++
drivers/spi/spi-uclass.c | 4 +++-
include/spi.h | 9 +++++----
5 files changed, 14 insertions(+), 7 deletions(-)
--
2.7.4
4
7
Currently switch is unable to boot pass Nintendo logo, will revert a nand
backup to the first uboot error which includes and the files created from
Uboot. The rest of the error after that are (after running different files
like kip files are results of me trying to retrieve inital setup.
Is it because of the firmware update 6.20 that messes everything. Some
payloads returns with tesc key and tes root key. All payloads can't
retrieve biskeys. Red QR code or only 3 keys, Tesc keys, SBW and Aes key
which is only two amd it indicate Aes0 and a AES test key.
However, i did not remember what i did, and i got the crypto amd tweats for
biskeys Unable to do clean nand backup with any cfw. Restore from any
firmware will give error and can't boot normal or cfw. But can enter cfw
mainmenu to launch payload. Will let you all know what are the results
when done
Thanks and best regards
Terrance Chiang
On Wed, 27 Feb 2019, 20:00 , <u-boot-request(a)lists.denx.de> wrote:
> Send U-Boot mailing list submissions to
> u-boot(a)lists.denx.de
>
> To subscribe or unsubscribe via the World Wide Web, visit
> https://lists.denx.de/listinfo/u-boot
> or, via email, send a message with subject or body 'help' to
> u-boot-request(a)lists.denx.de
>
> You can reach the person managing the list at
> u-boot-owner(a)lists.denx.de
>
> When replying, please edit your Subject line so it is more specific
> than "Re: Contents of U-Boot digest..."
>
>
> Today's Topics:
>
> 1. Re: [PATCH] efi_loader: Fix serial console size detection
> (Matthias Brugger)
> 2. Re: [PATCH v3 1/1] configs: rk3288: Tinker Board SPL file
> must fit into 32 KiB (Simon Goldschmidt)
> 3. SDCRARD boot on Intel Arria10 SOCDK (Marcel Gielen [Celestia-STS])
> 4. [PATCH v2] fs: fat: fix reading non-cluster-aligned root
> directory (Anssi Hannula)
>
>
> ----------------------------------------------------------------------
>
> Message: 1
> Date: Wed, 27 Feb 2019 10:55:00 +0100
> From: Matthias Brugger <mbrugger(a)suse.com>
> To: Heinrich Schuchardt <xypron.glpk(a)gmx.de>, matthias.bgg(a)kernel.org,
> agraf(a)csgraf.de
> Cc: u-boot(a)lists.denx.de, Matthias Brugger <mbrugger(a)suse.com>
> Subject: Re: [U-Boot] [PATCH] efi_loader: Fix serial console size
> detection
> Message-ID: <0d3f133f-ec80-bfdd-7b6b-3b35e493ab21(a)suse.com>
> Content-Type: text/plain; charset=utf-8
>
>
>
> On 26/02/2019 17:58, Heinrich Schuchardt wrote:
> > On 2/26/19 12:46 PM, matthias.bgg(a)kernel.org wrote:
> >> From: Matthias Brugger <mbrugger(a)suse.com>
> >>
> >> Function term_read_reply tries to read from the serial console until
> >> the end_char was read. This can hang forever if we are, for some reason,
> >> not be able to read the full response (e.g. serial buffer too small,
> >> frame error). This patch moves the timeout detection into
> >> term_read_reply to assure we will make progress.
> >>
> >> Fixes: 6bb591f704 ("efi_loader: query serial console size reliably")
> >> Signed-off-by: Matthias Brugger <mbrugger(a)suse.com>
> >
> > Thanks Matthias for the patch.
> >
> > The general direction is right. Yet I would prefer if you could move the
> > waiting loop as described below.
> >
> >> ---
> >> lib/efi_loader/efi_console.c | 63 +++++++++++++++++++++---------------
> >> 1 file changed, 37 insertions(+), 26 deletions(-)
> >>
> >> diff --git a/lib/efi_loader/efi_console.c b/lib/efi_loader/efi_console.c
> >> index 66c33a551d..817220455f 100644
> >> --- a/lib/efi_loader/efi_console.c
> >> +++ b/lib/efi_loader/efi_console.c
> >> @@ -62,6 +62,16 @@ static struct simple_text_output_mode efi_con_mode =
> {
> >> .cursor_visible = 1,
> >> };
> >>
> >> +static int term_get_char(char *c)
> >> +{
> >> + if (tstc()) {
> >> + *c = getc();
> >> + return 0;
> >> + }
> >> +
> >> + return 1;
> >
> > The function signals an error if the character to read is not yet in the
> > UART buffer. I think it would be preferable to put the waiting time (100
> > ms is sufficient at 110 baud and above) into this function instead. This
> > has the following advantages:
> >
> > - We would need only one waiting loop.
> > - We could reuse the function in function efi_cin_read_key() where we
> > have another chance to hang waiting for a character.
> >
>
> Ok, I'll do that in v2.
>
> >> +}
> >> +
> >> /*
> >> * Receive and parse a reply from the terminal.
> >> *
> >> @@ -74,32 +84,42 @@ static int term_read_reply(int *n, int num, char
> end_char)
> >> {
> >> char c;
> >> int i = 0;
> >> + u64 timeout;
> >>
> >> - c = getc();
> >> - if (c != cESC)
> >> + /* Allow up to one second for the response */
> >> + timeout = timer_get_us() + 1000000;
> >
> > Even at 110 baud a waiting time of 100 ms is sufficient.
> >
>
> So we don't have to wait up to one second for the first character to
> arrive as
> we did in query_console_serial() before this patch?
>
> >> + while (!tstc())
> >> + if (timer_get_us() > timeout)
> >> + return -1;
> >
> > This loop could be moved to term_get_char().
> >
> >> +
> >> + if (term_get_char(&c) || c != cESC)
> >> return -1;
> >> - c = getc();
> >> - if (c != '[')
> >> +
> >> + if (term_get_char(&c) || c != '[')
> >
> > We should allow time for this character to arrive.
> >
> >> return -1;
> >>
> >> n[0] = 0;
> >> while (1) {
> >> - c = getc();
> >> - if (c == ';') {
> >> - i++;
> >> - if (i >= num)> + if
> (!term_get_char(&c)) {
> >
> > On loop entry there is no wait before this term_get_char().
>
> I don't understand, if the character is not yet present, we will loop in
> the
> while until it arrives or we hit the timeout.
>
> Regards,
> Matthias
>
> >
> > Best regards
> >
> > Heinrich
> >
> >> + if (c == ';') {
> >> + i++;
> >> + if (i >= num)
> >> + return -1;
> >> + n[i] = 0;
> >> + continue;
> >> + } else if (c == end_char) {
> >> + break;
> >> + } else if (c > '9' || c < '0') {
> >> return -1;
> >> - n[i] = 0;
> >> - continue;
> >> - } else if (c == end_char) {
> >> - break;
> >> - } else if (c > '9' || c < '0') {
> >> - return -1;
> >> + }
> >> +
> >> + /* Read one more decimal position */
> >> + n[i] *= 10;
> >> + n[i] += c - '0';
> >> }
> >>
> >> - /* Read one more decimal position */
> >> - n[i] *= 10;
> >> - n[i] += c - '0';
> >> + if (timer_get_us() > timeout)
> >> + return -1;
> >> }
> >> if (i != num - 1)
> >> return -1;
> >> @@ -196,7 +216,6 @@ static int query_console_serial(int *rows, int
> *cols)
> >> {
> >> int ret = 0;
> >> int n[2];
> >> - u64 timeout;
> >>
> >> /* Empty input buffer */
> >> while (tstc())
> >> @@ -216,14 +235,6 @@ static int query_console_serial(int *rows, int
> *cols)
> >> ESC "[999;999H" /* Move to bottom right corner */
> >> ESC "[6n"); /* Query cursor position */
> >>
> >> - /* Allow up to one second for a response */
> >> - timeout = timer_get_us() + 1000000;
> >> - while (!tstc())
> >> - if (timer_get_us() > timeout) {
> >> - ret = -1;
> >> - goto out;
> >> - }
> >> -
> >> /* Read {rows,cols} */
> >> if (term_read_reply(n, 2, 'R')) {
> >> ret = 1;
> >>
> >
>
>
> ------------------------------
>
> Message: 2
> Date: Wed, 27 Feb 2019 11:15:23 +0100
> From: Simon Goldschmidt <simon.k.r.goldschmidt(a)gmail.com>
> To: Heinrich Schuchardt <xypron.glpk(a)gmx.de>, Tom Rini
> <trini(a)konsulko.com>
> Cc: U-Boot Mailing List <u-boot(a)lists.denx.de>, David Wu
> <david.wu(a)rock-chips.com>, Jagan Teki <jagan(a)openedev.com>
> Subject: Re: [U-Boot] [PATCH v3 1/1] configs: rk3288: Tinker Board SPL
> file must fit into 32 KiB
> Message-ID:
> <
> CAAh8qszB72fLPHqcj6i2zJukm0ROYpRbTgC40nTeMTKKSytvFQ(a)mail.gmail.com>
> Content-Type: text/plain; charset="UTF-8"
>
> Tom,
>
> On Thu, Feb 14, 2019 at 10:20 AM Simon Goldschmidt
> <simon.k.r.goldschmidt(a)gmail.com> wrote:
> >
> > On Thu, Feb 14, 2019 at 7:26 AM Heinrich Schuchardt <xypron.glpk(a)gmx.de>
> wrote:
> > >
> > > The SPL image for the Tinker Board has to fit into 32 KiB. This
> includes
> > > up to 2 KiB for the file header.
> > >
> > > A new configuration variable CONFIG_SPL_WITH_DTB_SIZE_LIMIT is
> introduced
> > > to define the board specific limit.
> > >
> > > Signed-off-by: Heinrich Schuchardt <xypron.glpk(a)gmx.de>
> >
> > Reviewed-by: Simon Goldschmidt <simon.k.r.goldschmidt(a)gmail.com>
>
> Is this planned for v2019.04? I know we're in rc phase, but this patch
> adds a new config
> option so shouldn't interfere with boards not using it.
>
> Plus if we have this SPL size check in v2019.04, it would probably
> enable more board
> maintainers testing/fixing the SPL size check after the release.
>
> Regards,
> Simon
>
> >
> > > ---
> > > v3
> > > The maximum size should of the image should be 30 KiB. Allowing
> > > 2 KiB for the header. This is 30720 and not 32700 bytes.
> > > v2
> > > Instead of using CONFIG_SPL_MAX_SIZE with an estimate of the
> FDT
> > > size introduce a new test in scripts/Makefile.spl.
> > > ---
> > > Kconfig | 8 ++++++++
> > > configs/tinker-rk3288_defconfig | 1 +
> > > scripts/Makefile.spl | 16 ++++++++++++++++
> > > 3 files changed, 25 insertions(+)
> > >
> > > diff --git a/Kconfig b/Kconfig
> > > index 512c7beb89..7cce53da74 100644
> > > --- a/Kconfig
> > > +++ b/Kconfig
> > > @@ -172,6 +172,14 @@ config TPL_SYS_MALLOC_F_LEN
> > > particular needs this to operate, so that it can allocate the
> > > initial serial device and any others that are needed.
> > >
> > > +config SPL_WITH_DTB_SIZE_LIMIT
> > > + int "Maximum size of SPL image including device tree"
> > > + depends on SPL
> > > + default 0
> > > + help
> > > + Specifies the maximum length of the U-Boot SPL image
> including the
> > > + device tree. If this value is zero, it is ignored.
> > > +
> > > menuconfig EXPERT
> > > bool "Configure standard U-Boot features (expert users)"
> > > default y
> > > diff --git a/configs/tinker-rk3288_defconfig
> b/configs/tinker-rk3288_defconfig
> > > index fdcab28185..cc5e59bcf1 100644
> > > --- a/configs/tinker-rk3288_defconfig
> > > +++ b/configs/tinker-rk3288_defconfig
> > > @@ -3,6 +3,7 @@ CONFIG_ARCH_ROCKCHIP=y
> > > CONFIG_SYS_TEXT_BASE=0x00000000
> > > CONFIG_SYS_MALLOC_F_LEN=0x2000
> > > CONFIG_ROCKCHIP_RK3288=y
> > > +CONFIG_SPL_WITH_DTB_SIZE_LIMIT=30720
> > > CONFIG_SPL_ROCKCHIP_BACK_TO_BROM=y
> > > CONFIG_TARGET_TINKER_RK3288=y
> > > CONFIG_DEBUG_UART_BASE=0xff690000
> > > diff --git a/scripts/Makefile.spl b/scripts/Makefile.spl
> > > index 9d5921606e..afc329a410 100644
> > > --- a/scripts/Makefile.spl
> > > +++ b/scripts/Makefile.spl
> > > @@ -254,11 +254,27 @@ FINAL_DTB_CONTAINER =
> $(obj)/$(SPL_BIN).multidtb.fit
> > > endif
> > >
> > >
> > > +ifneq ($(CONFIG_SPL_WITH_DTB_SIZE_LIMIT),0)
> > > +SPL_WITH_DTB_SIZE_CHECK = \
> > > + @actual=`wc -c $@ | awk '{print $$1}'`; \
> > > + limit=`printf "%d" $(CONFIG_SPL_WITH_DTB_SIZE_LIMIT)`; \
> > > + if test $$actual -gt $$limit; then \
> > > + echo "$@ exceeds file size limit:" >&2 ; \
> > > + echo " limit: $$limit bytes" >&2 ; \
> > > + echo " actual: $$actual bytes" >&2 ; \
> > > + echo " excess: $$((actual - limit)) bytes" >&2; \
> > > + exit 1; \
> > > + fi
> > > +else
> > > +SPL_WITH_DTB_SIZE_CHECK =
> > > +endif
> > > +
> > > ifeq
> ($(CONFIG_$(SPL_TPL_)OF_CONTROL)$(CONFIG_OF_SEPARATE)$(CONFIG_$(SPL_TPL_)OF_PLATDATA),yy)
> > > $(obj)/$(SPL_BIN)-dtb.bin: $(obj)/$(SPL_BIN)-nodtb.bin \
> > > $(if
> $(CONFIG_SPL_SEPARATE_BSS),,$(obj)/$(SPL_BIN)-pad.bin) \
> > > $(FINAL_DTB_CONTAINER) FORCE
> > > $(call if_changed,cat)
> > > + $(SPL_WITH_DTB_SIZE_CHECK)
> > >
> > > $(obj)/$(SPL_BIN).bin: $(obj)/$(SPL_BIN)-dtb.bin FORCE
> > > $(call if_changed,copy)
> > > --
> > > 2.20.1
> > >
>
>
> ------------------------------
>
> Message: 3
> Date: Wed, 27 Feb 2019 10:19:57 +0000
> From: "Marcel Gielen [Celestia-STS]" <M.Gielen(a)celestia-sts.com>
> To: "u-boot(a)lists.denx.de" <u-boot(a)lists.denx.de>
> Subject: [U-Boot] SDCRARD boot on Intel Arria10 SOCDK
> Message-ID:
> <
> AM5P193MB00171669DB7FA256E080294DA3740(a)AM5P193MB0017.EURP193.PROD.OUTLOOK.COM
> >
>
> Content-Type: text/plain; charset="us-ascii"
>
>
> We are trying to setup the Arria10 SOCDK (DK-SOC-10AS066S-A) to boot
> form SDCARD in RAW mode. We are under the impression this
> has never been used before.
>
> Kconfig sets SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR to 0x200 for ARCH_SOCFPGA,
> which is correct for the Cyclone-V, but not anymore for Arria-10.
> The SPL image size handled in the A10 bootROM is increased from 64KiB to
> 256KiB, which would result in an offset 0x800.
>
> The boot process, however ends up in an MMC timeout when trying to boot (
> v2019.01 ). Didn't peform any further checks yet, but it looks like card
> is not responding
> after this stage. The board boots with an Intel branched u-boot, we like
> to avoid this branch and stick to mainline.
>
> Default arria10 config:
> Trying to boot from MMC1
> spl: could not find mmc device 0. error: -19
> SPL: failed to boot from all boot devices
>
> With CONFIG_MMC_DW enabled:
> Trying to boot from MMC1
> spl: partition error
>
> CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR:
> mmc_load_image_raw_sector: mmc block read error
>
> CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x800:
> mmc_load_image_raw_sector: mmc block read error
>
> CONFIG_SD_BOOT:
> mmc_load_image_raw_sector: mmc block read error
>
>
> Any suggestion how to setup RAW mode for A10 ? (with a C5 we have no
> issues using the same options)
> A10 does not requires SPL, but using SPL would allow more options in the
> u-boot image.
> What is the preferred bootmode to use for A10 ( No SPL, SPL with RAW mode,
> SPL with u-boot on FAT partition (We prefer to avoid FAT), SPL with u-boot
> on ext partition )
>
>
> Regards,
> Marcej
>
>
>
>
>
>
>
>
>
>
>
>
> ------------------------------
>
> Message: 4
> Date: Wed, 27 Feb 2019 12:55:57 +0200
> From: Anssi Hannula <anssi.hannula(a)bitwise.fi>
> To: u-boot(a)lists.denx.de, Bernhard Messerklinger
> <bernhard.messerklinger(a)br-automation.com>
> Subject: [U-Boot] [PATCH v2] fs: fat: fix reading non-cluster-aligned
> root directory
> Message-ID: <20190227105557.20908-1-anssi.hannula(a)bitwise.fi>
>
> A FAT12/FAT16 root directory location is specified by a sector offset and
> it might not start at a cluster boundary. It also resides before the
> data area (before cluster 2).
>
> However, the current code assumes that the root directory is located at
> a beginning of a cluster, causing no files to be found if that is not
> the case.
>
> Since the FAT12/FAT16 root directory is located before the data area
> and is not aligned to clusters, using unsigned cluster numbers to refer
> to the root directory does not work well (the "cluster number" may be
> negative, and even allowing it be signed would not make it properly
> aligned).
>
> Modify the code to not use the normal cluster numbering when referring to
> the root directory of FAT12/FAT16 and instead use a cluster-sized
> offsets counted from the root directory start sector.
>
> This is a relatively common case as at least the filesystem formatter on
> Win7 seems to create such filesystems by default on 2GB USB sticks when
> "FAT" is selected (cluster size 64 sectors, rootdir size 32 sectors,
> rootdir starts at half a cluster before cluster 2).
>
> dosfstools mkfs.vfat does not seem to create affected filesystems.
>
> Signed-off-by: Anssi Hannula <anssi.hannula(a)bitwise.fi>
> ---
>
> v2: Rewrite to avoid negative "cluster numbers".
>
>
> Hi,
>
> I'm sorry about not responding in a timely manner.
>
> Bernhard Messerklinger wrote:
> > clust_size = 2
> > rootdir_sect = 113
> > dara_begin = 132
> >
> > sect_to_clust: 0xfffffff1 = (0x113 - 132) / 2
> > sect_to_clust: 114 = 132 + 0xfffffff1 * 2
> >
> > Now my root_cluster is above the root dir but it should be below it
> (112).
>
> You are right, root_cluster going negative is not being handled properly.
>
> However, I'd rather avoid that in the first place, as the code generally
> assumes that cluster numbers are unsigned - which is the reality as well,
> it is just that the FAT12/16 rootdir is located before the clusters.
>
> So here is a different take on the original patch that instead avoids
> using the "cluster numbers" to refer to the root directory on FAT12/16
> altogether.
>
>
> fs/fat/fat.c | 47 ++++++++++++++++++++++++++++++++++-------------
> 1 file changed, 34 insertions(+), 13 deletions(-)
>
> diff --git a/fs/fat/fat.c b/fs/fat/fat.c
> index 6ade4ea54e..c5997c2173 100644
> --- a/fs/fat/fat.c
> +++ b/fs/fat/fat.c
> @@ -602,8 +602,13 @@ static int get_fs_info(fsdata *mydata)
> mydata->data_begin = mydata->rootdir_sect +
> mydata->rootdir_size -
> (mydata->clust_size * 2);
> - mydata->root_cluster =
> - sect_to_clust(mydata, mydata->rootdir_sect);
> +
> + /*
> + * The root directory is not cluster-aligned and may be on
> a
> + * "negative" cluster, this will be handled specially in
> + * next_cluster().
> + */
> + mydata->root_cluster = 0;
> }
>
> mydata->fatbufnum = -1;
> @@ -733,20 +738,38 @@ static void fat_itr_child(fat_itr *itr, fat_itr
> *parent)
> itr->last_cluster = 0;
> }
>
> -static void *next_cluster(fat_itr *itr)
> +static void *next_cluster(fat_itr *itr, unsigned *nbytes)
> {
> fsdata *mydata = itr->fsdata; /* for silly macros */
> int ret;
> u32 sect;
> + u32 read_size;
>
> /* have we reached the end? */
> if (itr->last_cluster)
> return NULL;
>
> - sect = clust_to_sect(itr->fsdata, itr->next_clust);
> + if (itr->is_root && itr->fsdata->fatsize != 32) {
> + /*
> + * The root directory is located before the data area and
> + * cannot be indexed using the regular unsigned cluster
> + * numbers (it may start at a "negative" cluster or not at
> a
> + * cluster boundary at all), so consider itr->next_clust
> to be
> + * a offset in cluster-sized units from the start of
> rootdir.
> + */
> + unsigned sect_offset = itr->next_clust *
> itr->fsdata->clust_size;
> + unsigned remaining_sects = itr->fsdata->rootdir_size -
> sect_offset;
> + sect = itr->fsdata->rootdir_sect + sect_offset;
> + /* do not read past the end of rootdir */
> + read_size = min_t(u32, itr->fsdata->clust_size,
> + remaining_sects);
> + } else {
> + sect = clust_to_sect(itr->fsdata, itr->next_clust);
> + read_size = itr->fsdata->clust_size;
> + }
>
> - debug("FAT read(sect=%d), clust_size=%d, DIRENTSPERBLOCK=%zd\n",
> - sect, itr->fsdata->clust_size, DIRENTSPERBLOCK);
> + debug("FAT read(sect=%d), clust_size=%d, read_size=%u,
> DIRENTSPERBLOCK=%zd\n",
> + sect, itr->fsdata->clust_size, read_size, DIRENTSPERBLOCK);
>
> /*
> * NOTE: do_fat_read_at() had complicated logic to deal w/
> @@ -757,18 +780,17 @@ static void *next_cluster(fat_itr *itr)
> * dent at a time and iteratively constructing the vfat long
> * name.
> */
> - ret = disk_read(sect, itr->fsdata->clust_size,
> - itr->block);
> + ret = disk_read(sect, read_size, itr->block);
> if (ret < 0) {
> debug("Error: reading block\n");
> return NULL;
> }
>
> + *nbytes = read_size * itr->fsdata->sect_size;
> itr->clust = itr->next_clust;
> if (itr->is_root && itr->fsdata->fatsize != 32) {
> itr->next_clust++;
> - sect = clust_to_sect(itr->fsdata, itr->next_clust);
> - if (sect - itr->fsdata->rootdir_sect >=
> + if (itr->next_clust * itr->fsdata->clust_size >=
> itr->fsdata->rootdir_size) {
> debug("nextclust: 0x%x\n", itr->next_clust);
> itr->last_cluster = 1;
> @@ -787,9 +809,8 @@ static void *next_cluster(fat_itr *itr)
> static dir_entry *next_dent(fat_itr *itr)
> {
> if (itr->remaining == 0) {
> - struct dir_entry *dent = next_cluster(itr);
> - unsigned nbytes = itr->fsdata->sect_size *
> - itr->fsdata->clust_size;
> + unsigned nbytes;
> + struct dir_entry *dent = next_cluster(itr, &nbytes);
>
> /* have we reached the last cluster? */
> if (!dent) {
> --
> Anssi Hannula / Bitwise Oy
>
>
>
> ------------------------------
>
> Subject: Digest Footer
>
> _______________________________________________
> U-Boot mailing list
> U-Boot(a)lists.denx.de
> https://lists.denx.de/listinfo/u-boot
>
>
> ------------------------------
>
> End of U-Boot Digest, Vol 129, Issue 63
> ***************************************
>
1
0
We are trying to setup the Arria10 SOCDK (DK-SOC-10AS066S-A) to boot form SDCARD in RAW mode. We are under the impression this
has never been used before.
Kconfig sets SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR to 0x200 for ARCH_SOCFPGA, which is correct for the Cyclone-V, but not anymore for Arria-10.
The SPL image size handled in the A10 bootROM is increased from 64KiB to 256KiB, which would result in an offset 0x800.
The boot process, however ends up in an MMC timeout when trying to boot ( v2019.01 ). Didn't peform any further checks yet, but it looks like card is not responding
after this stage. The board boots with an Intel branched u-boot, we like to avoid this branch and stick to mainline.
Default arria10 config:
Trying to boot from MMC1
spl: could not find mmc device 0. error: -19
SPL: failed to boot from all boot devices
With CONFIG_MMC_DW enabled:
Trying to boot from MMC1
spl: partition error
CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR:
mmc_load_image_raw_sector: mmc block read error
CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x800:
mmc_load_image_raw_sector: mmc block read error
CONFIG_SD_BOOT:
mmc_load_image_raw_sector: mmc block read error
Any suggestion how to setup RAW mode for A10 ? (with a C5 we have no issues using the same options)
A10 does not requires SPL, but using SPL would allow more options in the u-boot image.
What is the preferred bootmode to use for A10 ( No SPL, SPL with RAW mode, SPL with u-boot on FAT partition (We prefer to avoid FAT), SPL with u-boot on ext partition )
Regards,
Marcej
1
0
THe following patches add support for NAND and booting from
NAND in dra71x-evm.
Faiz Abbas (2):
configs: dra71x-evm: Add Support for NAND
configs: ti_omap5_common: Add NAND environment settings
Franklin S Cooper Jr (2):
board: ti: dra71: Add pinmux settings for NAND on DRA71x EVM
arm: dra7: Allow NAND to be enabled on DRA71x EVM.
board/ti/dra7xx/evm.c | 56 +++++++++++++++++++++++++++++
board/ti/dra7xx/mux_data.h | 60 ++++++++++++++++++++++---------
configs/dra7xx_evm_defconfig | 7 +++-
configs/dra7xx_hs_evm_defconfig | 7 +++-
include/configs/dra7xx_evm.h | 2 +-
include/configs/ti_omap5_common.h | 20 +++++++++++
6 files changed, 133 insertions(+), 19 deletions(-)
--
2.19.2
2
6
Hi Anup
Anup Patel <anup(a)brainfault.org> 於 2019年2月21日 週四 下午5:57寫道:
>
> On Thu, Feb 21, 2019 at 11:31 AM Bin Meng <bmeng.cn(a)gmail.com> wrote:
> >
> > On Thu, Feb 21, 2019 at 12:48 PM Anup Patel <anup(a)brainfault.org> wrote:
> > >
> > > Hi Rick,
> > >
> > > On Fri, Feb 15, 2019 at 10:19 AM Rick Chen <rickchen36(a)gmail.com> wrote:
> > > >
> > > > Hi Anup
> > > >
> > > > > > Hi All,
> > > > > >
> > > > > > Thanks for all the review comments so far.
> > > > > >
> > > > > > Is it possible to accept "[PATCH v7 00/15] SiFive FU540 Support" for
> > > > > > U-Boot-2019.04 ??
> > > > > >
> > > > > > Based on our discussion with various folks at FOSDEM19, lot of people want to
> > > > > > use U-Boot on Unleashed board. In general, it will be exciting to see U-Boot being
> > > > > > adopted as bootloader by various RISC-V HW vendors.
> > > >
> > > > I am still waiting for Simon's response about the two patchs
> > > > that he have comments.
> > >
> > > I have addressed Simon's patches and got Reviewed-by as well.
> > >
> > > I have posted "[PATCH v9 00/15] SiFive FU540 Support" which
> > > is based on U-Boot-2019.4-rc2.
> > >
> > > You can also find this patches in riscv_sifive_fu540_v9 branch of
> > > https://github.com/avpatel/u-boot.git
> >
> > Thanks for the support and hopefully we can get this one plus Lukas's
> > SMP series in the v2019.04 release.
>
> It will be awesome to have Lukas's SMP patches along with
> SiFive FU540 patches in v2019.04
>
OK
I will pull into u-boot-riscv and run Travis.
Then Send a PR to Tom.
Thanks for your efforts
B.R
Rick
> Thanks,
> Anup
3
6
Use quad write if SPI_TX_QUAD flag is set.
Signed-off-by: Ley Foon Tan <ley.foon.tan(a)intel.com>
---
drivers/spi/cadence_qspi.c | 2 +-
drivers/spi/cadence_qspi.h | 2 +-
drivers/spi/cadence_qspi_apb.c | 7 ++++++-
3 files changed, 8 insertions(+), 3 deletions(-)
mode change 100644 => 100755 drivers/spi/cadence_qspi.c
mode change 100644 => 100755 drivers/spi/cadence_qspi.h
mode change 100644 => 100755 drivers/spi/cadence_qspi_apb.c
diff --git a/drivers/spi/cadence_qspi.c b/drivers/spi/cadence_qspi.c
old mode 100644
new mode 100755
index 11fce9c4fe..efdb178450
--- a/drivers/spi/cadence_qspi.c
+++ b/drivers/spi/cadence_qspi.c
@@ -256,7 +256,7 @@ static int cadence_spi_xfer(struct udevice *dev, unsigned int bitlen,
break;
case CQSPI_INDIRECT_WRITE:
err = cadence_qspi_apb_indirect_write_setup
- (plat, priv->cmd_len, cmd_buf);
+ (plat, priv->cmd_len, dm_plat->mode, cmd_buf);
if (!err) {
err = cadence_qspi_apb_indirect_write_execute
(plat, data_bytes, dout);
diff --git a/drivers/spi/cadence_qspi.h b/drivers/spi/cadence_qspi.h
old mode 100644
new mode 100755
index 055900def0..b491407130
--- a/drivers/spi/cadence_qspi.h
+++ b/drivers/spi/cadence_qspi.h
@@ -60,7 +60,7 @@ int cadence_qspi_apb_indirect_read_setup(struct cadence_spi_platdata *plat,
int cadence_qspi_apb_indirect_read_execute(struct cadence_spi_platdata *plat,
unsigned int rxlen, u8 *rxbuf);
int cadence_qspi_apb_indirect_write_setup(struct cadence_spi_platdata *plat,
- unsigned int cmdlen, const u8 *cmdbuf);
+ unsigned int cmdlen, unsigned int tx_width, const u8 *cmdbuf);
int cadence_qspi_apb_indirect_write_execute(struct cadence_spi_platdata *plat,
unsigned int txlen, const u8 *txbuf);
diff --git a/drivers/spi/cadence_qspi_apb.c b/drivers/spi/cadence_qspi_apb.c
old mode 100644
new mode 100755
index a8af352030..55a7501913
--- a/drivers/spi/cadence_qspi_apb.c
+++ b/drivers/spi/cadence_qspi_apb.c
@@ -77,6 +77,7 @@
#define CQSPI_REG_WR_INSTR 0x08
#define CQSPI_REG_WR_INSTR_OPCODE_LSB 0
+#define CQSPI_REG_WR_INSTR_TYPE_DATA_LSB 16
#define CQSPI_REG_DELAY 0x0C
#define CQSPI_REG_DELAY_TSLCH_LSB 0
@@ -686,7 +687,7 @@ failrd:
/* Opcode + Address (3/4 bytes) */
int cadence_qspi_apb_indirect_write_setup(struct cadence_spi_platdata *plat,
- unsigned int cmdlen, const u8 *cmdbuf)
+ unsigned int cmdlen, unsigned int tx_width, const u8 *cmdbuf)
{
unsigned int reg;
unsigned int addr_bytes = cmdlen > 4 ? 4 : 3;
@@ -702,6 +703,10 @@ int cadence_qspi_apb_indirect_write_setup(struct cadence_spi_platdata *plat,
/* Configure the opcode */
reg = cmdbuf[0] << CQSPI_REG_WR_INSTR_OPCODE_LSB;
+
+ if (tx_width & SPI_TX_QUAD)
+ reg |= CQSPI_INST_TYPE_QUAD << CQSPI_REG_WR_INSTR_TYPE_DATA_LSB;
+
writel(reg, plat->regbase + CQSPI_REG_WR_INSTR);
/* Setup write address. */
--
2.19.0
2
2

[U-Boot] [PATCH 3/3] mips: fix erros on registers macros of pll-ddr-config1-nfrac for QCA956X
by Rosy Song 27 Feb '19
by Rosy Song 27 Feb '19
27 Feb '19
Signed-off-by: Rosy Song <rosysong(a)rosinson.com>
---
arch/mips/mach-ath79/include/mach/ar71xx_regs.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/mips/mach-ath79/include/mach/ar71xx_regs.h b/arch/mips/mach-ath79/include/mach/ar71xx_regs.h
index 380f387a26..016679e0f8 100644
--- a/arch/mips/mach-ath79/include/mach/ar71xx_regs.h
+++ b/arch/mips/mach-ath79/include/mach/ar71xx_regs.h
@@ -551,7 +551,7 @@
#define QCA956X_PLL_CPU_CONFIG1_NFRAC_L_SHIFT 0
#define QCA956X_PLL_CPU_CONFIG1_NFRAC_L_MASK 0x1f
#define QCA956X_PLL_CPU_CONFIG1_NFRAC_H_SHIFT 5
-#define QCA956X_PLL_CPU_CONFIG1_NFRAC_H_MASK 0x3fff
+#define QCA956X_PLL_CPU_CONFIG1_NFRAC_H_MASK 0x1fff
#define QCA956X_PLL_CPU_CONFIG1_NINT_SHIFT 18
#define QCA956X_PLL_CPU_CONFIG1_NINT_MASK 0x1ff
@@ -563,7 +563,7 @@
#define QCA956X_PLL_DDR_CONFIG1_NFRAC_L_SHIFT 0
#define QCA956X_PLL_DDR_CONFIG1_NFRAC_L_MASK 0x1f
#define QCA956X_PLL_DDR_CONFIG1_NFRAC_H_SHIFT 5
-#define QCA956X_PLL_DDR_CONFIG1_NFRAC_H_MASK 0x3fff
+#define QCA956X_PLL_DDR_CONFIG1_NFRAC_H_MASK 0x1fff
#define QCA956X_PLL_DDR_CONFIG1_NINT_SHIFT 18
#define QCA956X_PLL_DDR_CONFIG1_NINT_MASK 0x1ff
--
2.17.0
2
1

27 Feb '19
Signed-off-by: Rosy Song <rosysong(a)rosinson.com>
---
arch/mips/dts/Makefile | 1 +
arch/mips/dts/ap152.dts | 48 ++
arch/mips/dts/qca956x.dtsi | 87 ++++
arch/mips/mach-ath79/Kconfig | 14 +
arch/mips/mach-ath79/Makefile | 1 +
.../mach-ath79/include/mach/ar71xx_regs.h | 70 +++
arch/mips/mach-ath79/include/mach/ath79.h | 3 +
arch/mips/mach-ath79/qca956x/Makefile | 5 +
arch/mips/mach-ath79/qca956x/clk.c | 419 ++++++++++++++++++
arch/mips/mach-ath79/qca956x/cpu.c | 9 +
arch/mips/mach-ath79/qca956x/ddr.c | 308 +++++++++++++
arch/mips/mach-ath79/qca956x/lowlevel_init.S | 79 ++++
.../mips/mach-ath79/qca956x/qca956x-ddr-tap.S | 194 ++++++++
arch/mips/mach-ath79/reset.c | 271 +++++++++++
board/qca/ap152/Kconfig | 27 ++
board/qca/ap152/MAINTAINERS | 6 +
board/qca/ap152/Makefile | 3 +
board/qca/ap152/ap152.c | 81 ++++
configs/ap152_defconfig | 55 +++
include/configs/ap152.h | 54 +++
20 files changed, 1735 insertions(+)
create mode 100644 arch/mips/dts/ap152.dts
create mode 100644 arch/mips/dts/qca956x.dtsi
create mode 100644 arch/mips/mach-ath79/qca956x/Makefile
create mode 100644 arch/mips/mach-ath79/qca956x/clk.c
create mode 100644 arch/mips/mach-ath79/qca956x/cpu.c
create mode 100644 arch/mips/mach-ath79/qca956x/ddr.c
create mode 100644 arch/mips/mach-ath79/qca956x/lowlevel_init.S
create mode 100644 arch/mips/mach-ath79/qca956x/qca956x-ddr-tap.S
create mode 100644 board/qca/ap152/Kconfig
create mode 100644 board/qca/ap152/MAINTAINERS
create mode 100644 board/qca/ap152/Makefile
create mode 100644 board/qca/ap152/ap152.c
create mode 100644 configs/ap152_defconfig
create mode 100644 include/configs/ap152.h
diff --git a/arch/mips/dts/Makefile b/arch/mips/dts/Makefile
index b94b582837..621c35f0ef 100644
--- a/arch/mips/dts/Makefile
+++ b/arch/mips/dts/Makefile
@@ -2,6 +2,7 @@
dtb-$(CONFIG_TARGET_AP121) += ap121.dtb
dtb-$(CONFIG_TARGET_AP143) += ap143.dtb
+dtb-$(CONFIG_TARGET_AP152) += ap152.dtb
dtb-$(CONFIG_TARGET_BOSTON) += img,boston.dtb
dtb-$(CONFIG_TARGET_MALTA) += mti,malta.dtb
dtb-$(CONFIG_TARGET_PIC32MZDASK) += pic32mzda_sk.dtb
diff --git a/arch/mips/dts/ap152.dts b/arch/mips/dts/ap152.dts
new file mode 100644
index 0000000000..1722290c73
--- /dev/null
+++ b/arch/mips/dts/ap152.dts
@@ -0,0 +1,48 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Rosy Song <rosysong(a)rosinson.com>
+ */
+
+/dts-v1/;
+#include "qca956x.dtsi"
+
+/ {
+ model = "AP152 Reference Board";
+ compatible = "qca,ap152", "qca,qca956x";
+
+ aliases {
+ spi0 = &spi0;
+ serial0 = &uart0;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+};
+
+&gmac0 {
+ phy-mode = "sgmii";
+ status = "okay";
+};
+
+&xtal {
+ clock-frequency = <25000000>;
+};
+
+&uart0 {
+ clock-frequency = <25000000>;
+ status = "okay";
+};
+
+&spi0 {
+ spi-max-frequency = <25000000>;
+ status = "okay";
+ spi-flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "spi-flash";
+ memory-map = <0x9f000000 0x01000000>;
+ spi-max-frequency = <25000000>;
+ reg = <0>;
+ };
+};
diff --git a/arch/mips/dts/qca956x.dtsi b/arch/mips/dts/qca956x.dtsi
new file mode 100644
index 0000000000..6cb360b3f8
--- /dev/null
+++ b/arch/mips/dts/qca956x.dtsi
@@ -0,0 +1,87 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Rosy Song <rosysong(a)rosinson.com>
+ */
+
+#include "skeleton.dtsi"
+
+/ {
+ compatible = "qca,qca956x";
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "mips,mips74Kc";
+ reg = <0>;
+ };
+ };
+
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ xtal: xtal {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-output-names = "xtal";
+ };
+ };
+
+ ahb {
+ compatible = "simple-bus";
+ ranges;
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ apb {
+ compatible = "simple-bus";
+ ranges;
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ uart0: uart@18020000 {
+ compatible = "ns16550";
+ reg = <0x18020000 0x20>;
+ reg-shift = <2>;
+
+ status = "disabled";
+ };
+
+ gmac0: eth@0x19000000 {
+ compatible = "qca,ag956x-mac";
+ reg = <0x19000000 0x200>;
+ phy = <&phy0>;
+ phy-mode = "sgmii";
+
+ status = "disabled";
+
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ phy0: ethernet-phy@0 {
+ reg = <0>;
+ };
+ };
+ };
+ };
+
+ spi0: spi@1f000000 {
+ compatible = "qca,ar7100-spi";
+ reg = <0x1f000000 0x10>;
+
+ status = "disabled";
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+};
diff --git a/arch/mips/mach-ath79/Kconfig b/arch/mips/mach-ath79/Kconfig
index bc86f591df..bdb23b5765 100644
--- a/arch/mips/mach-ath79/Kconfig
+++ b/arch/mips/mach-ath79/Kconfig
@@ -33,6 +33,15 @@ config SOC_QCA953X
help
This supports QCA/Atheros qca953x family SOCs.
+config SOC_QCA956X
+ bool
+ select MIPS_TUNE_74KC
+ select SUPPORTS_BIG_ENDIAN
+ select SUPPORTS_CPU_MIPS32_R1
+ select SUPPORTS_CPU_MIPS32_R2
+ help
+ This supports QCA/Atheros qca956x family SOCs.
+
choice
prompt "Board select"
@@ -44,6 +53,10 @@ config TARGET_AP143
bool "AP143 Reference Board"
select SOC_QCA953X
+config TARGET_AP152
+ bool "AP152 Reference Board"
+ select SOC_QCA956X
+
config BOARD_TPLINK_WDR4300
bool "TP-Link WDR4300 Board"
select SOC_AR934X
@@ -52,6 +65,7 @@ endchoice
source "board/qca/ap121/Kconfig"
source "board/qca/ap143/Kconfig"
+source "board/qca/ap152/Kconfig"
source "board/tplink/wdr4300/Kconfig"
endmenu
diff --git a/arch/mips/mach-ath79/Makefile b/arch/mips/mach-ath79/Makefile
index 7aa40c65d3..fbd40c02be 100644
--- a/arch/mips/mach-ath79/Makefile
+++ b/arch/mips/mach-ath79/Makefile
@@ -7,3 +7,4 @@ obj-y += dram.o
obj-$(CONFIG_SOC_AR933X) += ar933x/
obj-$(CONFIG_SOC_AR934X) += ar934x/
obj-$(CONFIG_SOC_QCA953X) += qca953x/
+obj-$(CONFIG_SOC_QCA956X) += qca956x/
diff --git a/arch/mips/mach-ath79/include/mach/ar71xx_regs.h b/arch/mips/mach-ath79/include/mach/ar71xx_regs.h
index 5d371bb582..380f387a26 100644
--- a/arch/mips/mach-ath79/include/mach/ar71xx_regs.h
+++ b/arch/mips/mach-ath79/include/mach/ar71xx_regs.h
@@ -201,6 +201,10 @@
(AR71XX_APB_BASE + 0x00070000)
#define QCA956X_GMAC_SIZE 0x64
+#define QCA956X_SRIF_BASE \
+ (AR71XX_APB_BASE + 0x00116000)
+#define QCA956X_SRIF_SIZE 0x1000
+
/*
* DDR_CTRL block
*/
@@ -278,6 +282,18 @@
#define QCA953X_DDR_REG_CTL_CONF 0x108
#define QCA953X_DDR_REG_CONFIG3 0x15c
+#define QCA956X_DDR_REG_TAP_CTRL2 0x24
+#define QCA956X_DDR_REG_TAP_CTRL3 0x28
+#define QCA956X_DDR_REG_DDR2_CONFIG 0xb8
+#define QCA956X_DDR_REG_DDR2_EMR2 0xbc
+#define QCA956X_DDR_REG_DDR2_EMR3 0xc0
+#define QCA956X_DDR_REG_BURST 0xc4
+#define QCA956X_DDR_REG_BURST2 0xc8
+#define QCA956X_DDR_REG_TIMEOUT_MAX 0xcc
+#define QCA956X_DDR_REG_FSM_WAIT_CTRL 0xe4
+#define QCA956X_DDR_REG_CTL_CONF 0x108
+#define QCA956X_DDR_REG_DDR3_CONFIG 0x15c
+
/*
* PLL block
*/
@@ -519,6 +535,13 @@
#define QCA956X_PLL_DDR_CONFIG_REG 0x08
#define QCA956X_PLL_DDR_CONFIG1_REG 0x0c
#define QCA956X_PLL_CLK_CTRL_REG 0x10
+#define QCA956X_PLL_SWITCH_CLK_CTRL_REG 0x28
+#define QCA956X_PLL_ETH_XMII_CTRL_REG 0x30
+#define QCA956X_PLL_DDR_DIT_FRAC_REG 0x38
+#define QCA956X_PLL_DDR_DIT2_FRAC_REG 0x3c
+#define QCA956X_PLL_CPU_DIT_FRAC_REG 0x40
+#define QCA956X_PLL_CPU_DIT2_FRAC_REG 0x44
+#define QCA956X_PLL_ETH_SGMII_SERDES_REG 0x4c
#define QCA956X_PLL_CPU_CONFIG_REFDIV_SHIFT 12
#define QCA956X_PLL_CPU_CONFIG_REFDIV_MASK 0x1f
@@ -756,6 +779,17 @@
#define QCA955X_RESET_MBOX BIT(1)
#define QCA955X_RESET_I2S BIT(0)
+#define QCA956X_RESET_EXTERNAL BIT(28)
+#define QCA956X_RESET_FULL_CHIP BIT(24)
+#define QCA956X_RESET_GE1_MDIO BIT(23) /* Reserved in datasheet */
+#define QCA956X_RESET_GE0_MDIO BIT(22)
+#define QCA956X_RESET_GE1_MAC BIT(13) /* Reserved in datasheet */
+#define QCA956X_RESET_SGMII_ASSERT BIT(12)
+#define QCA956X_RESET_GE0_MAC BIT(9)
+#define QCA956X_RESET_SGMII BIT(8)
+#define QCA956X_RESET_SGMII_ANALOG BIT(2)
+#define QCA956X_RESET_SWITCH BIT(0)
+
#define AR933X_BOOTSTRAP_MDIO_GPIO_EN BIT(18)
#define AR933X_BOOTSTRAP_DDR2 BIT(13)
#define AR933X_BOOTSTRAP_EEPBUSY BIT(4)
@@ -1099,8 +1133,12 @@
#define QCA953X_GPIO_IN_MUX_UART0_SIN 9
#define QCA953X_GPIO_IN_MUX_SPI_DATA_IN 8
+#define QCA956X_GPIO(x) BIT(x)
+#define QCA956X_GPIO_MUX_MASK(x) (0xff << (x))
#define QCA956X_GPIO_OUT_MUX_GE0_MDO 32
#define QCA956X_GPIO_OUT_MUX_GE0_MDC 33
+#define QCA956X_GPIO_IN_MUX_UART0_SIN 0x12
+#define QCA956X_GPIO_OUT_MUX_UART0_SOUT 0x16
#define AR71XX_GPIO_COUNT 16
#define AR7240_GPIO_COUNT 18
@@ -1179,6 +1217,25 @@
#define QCA953X_SRIF_DPLL2_OUTDIV_SHIFT 13
#define QCA953X_SRIF_DPLL2_OUTDIV_MASK 0x7
+#define QCA956X_SRIF_BB_DPLL1_REG 0x180
+#define QCA956X_SRIF_BB_DPLL2_REG 0x184
+#define QCA956X_SRIF_BB_DPLL3_REG 0x188
+
+#define QCA956X_SRIF_CPU_DPLL1_REG 0xf00
+#define QCA956X_SRIF_CPU_DPLL2_REG 0xf04
+#define QCA956X_SRIF_CPU_DPLL3_REG 0xf08
+
+#define QCA956X_SRIF_DDR_DPLL1_REG 0xec0
+#define QCA956X_SRIF_DDR_DPLL2_REG 0xec4
+#define QCA956X_SRIF_DDR_DPLL3_REG 0xec8
+
+#define QCA956X_SRIF_PCIE_DPLL1_REG 0xc80
+#define QCA956X_SRIF_PCIE_DPLL2_REG 0xc84
+#define QCA956X_SRIF_PCIE_DPLL3_REG 0xc88
+
+#define QCA956X_SRIF_PMU1_REG 0xcc0
+#define QCA956X_SRIF_PMU2_REG 0xcc4
+
/*
* MII_CTRL block
*/
@@ -1261,4 +1318,17 @@
#define QCA955X_ETH_CFG_RGMII_EN BIT(0)
#define QCA955X_ETH_CFG_GE0_SGMII BIT(6)
+/*
+ * QCA956X GMAC Interface
+ */
+
+#define QCA956X_GMAC_REG_ETH_CFG 0x00
+#define QCA956X_GMAC_REG_SGMII_RESET 0x14
+#define QCA956X_GMAC_REG_SGMII_SERDES 0x18
+#define QCA956X_GMAC_REG_MR_AN_CTRL 0x1c
+#define QCA956X_GMAC_REG_SGMII_CONFIG 0x34
+#define QCA956X_GMAC_REG_SGMII_DEBUG 0x58
+
+#define QCA956X_ETH_CFG_GE0_SGMII BIT(6)
+
#endif /* __ASM_AR71XX_H */
diff --git a/arch/mips/mach-ath79/include/mach/ath79.h b/arch/mips/mach-ath79/include/mach/ath79.h
index 5de7a43f79..0fde5079b1 100644
--- a/arch/mips/mach-ath79/include/mach/ath79.h
+++ b/arch/mips/mach-ath79/include/mach/ath79.h
@@ -2,6 +2,7 @@
/*
* Atheros AR71XX/AR724X/AR913X common definitions
*
+ * Copyright (C) 2018-2019 Rosy Song <rosysong(a)rosinson.com>
* Copyright (C) 2015-2016 Wills Wang <wills.wang(a)live.com>
* Copyright (C) 2008-2011 Gabor Juhos <juhosg(a)openwrt.org>
* Copyright (C) 2008 Imre Kaloz <kaloz(a)openwrt.org>
@@ -146,4 +147,6 @@ int ath79_usb_reset(void);
void ar934x_pll_init(const u16 cpu_mhz, const u16 ddr_mhz, const u16 ahb_mhz);
void ar934x_ddr_init(const u16 cpu_mhz, const u16 ddr_mhz, const u16 ahb_mhz);
+void qca956x_pll_init(void);
+void qca956x_ddr_init(void);
#endif /* __ASM_MACH_ATH79_H */
diff --git a/arch/mips/mach-ath79/qca956x/Makefile b/arch/mips/mach-ath79/qca956x/Makefile
new file mode 100644
index 0000000000..3f5fc0363f
--- /dev/null
+++ b/arch/mips/mach-ath79/qca956x/Makefile
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0+
+
+obj-y += cpu.o
+obj-y += clk.o
+obj-y += ddr.o qca956x-ddr-tap.o
diff --git a/arch/mips/mach-ath79/qca956x/clk.c b/arch/mips/mach-ath79/qca956x/clk.c
new file mode 100644
index 0000000000..ca956d1291
--- /dev/null
+++ b/arch/mips/mach-ath79/qca956x/clk.c
@@ -0,0 +1,419 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2019 Rosy Song <rosysong(a)rosinson.com>
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/addrspace.h>
+#include <asm/types.h>
+#include <mach/ar71xx_regs.h>
+#include <mach/ath79.h>
+#include <wait_bit.h>
+
+#define PLL_SRIF_DPLL2_KI_LSB 29
+#define PLL_SRIF_DPLL2_KI_MASK 0x60000000
+#define PLL_SRIF_DPLL2_KI_SET(x) \
+ (((x) << PLL_SRIF_DPLL2_KI_LSB) & PLL_SRIF_DPLL2_KI_MASK)
+#define PLL_SRIF_DPLL2_KD_LSB 25
+#define PLL_SRIF_DPLL2_KD_MASK 0x1e000000
+#define PLL_SRIF_DPLL2_KD_SET(x) \
+ (((x) << PLL_SRIF_DPLL2_KD_LSB) & PLL_SRIF_DPLL2_KD_MASK)
+#define PLL_SRIF_DPLL2_PLL_PWD_LSB 22
+#define PLL_SRIF_DPLL2_PLL_PWD_MASK 0x00400000
+#define PLL_SRIF_DPLL2_PLL_PWD_SET(x) \
+ (((x) << PLL_SRIF_DPLL2_PLL_PWD_LSB) & PLL_SRIF_DPLL2_PLL_PWD_MASK)
+#define PLL_SRIF_DPLL2_OUTDIV_LSB 19
+#define PLL_SRIF_DPLL2_OUTDIV_MASK 0x00380000
+#define PLL_SRIF_DPLL2_OUTDIV_SET(x) \
+ (((x) << PLL_SRIF_DPLL2_OUTDIV_LSB) & PLL_SRIF_DPLL2_OUTDIV_MASK)
+#define PLL_SRIF_DPLL2_PHASE_SHIFT_LSB 12
+#define PLL_SRIF_DPLL2_PHASE_SHIFT_MASK 0x0007f000
+#define PLL_SRIF_DPLL2_PHASE_SHIFT_SET(x) \
+ (((x) << PLL_SRIF_DPLL2_PHASE_SHIFT_LSB) & PLL_SRIF_DPLL2_PHASE_SHIFT_MASK)
+#define CPU_PLL_CONFIG_PLLPWD_LSB 30
+#define CPU_PLL_CONFIG_PLLPWD_MASK 0x40000000
+#define CPU_PLL_CONFIG_PLLPWD_SET(x) \
+ (((x) << CPU_PLL_CONFIG_PLLPWD_LSB) & CPU_PLL_CONFIG_PLLPWD_MASK)
+#define CPU_PLL_CONFIG_OUTDIV_LSB 19
+#define CPU_PLL_CONFIG_OUTDIV_MASK 0x00380000
+#define CPU_PLL_CONFIG_OUTDIV_SET(x) \
+ (((x) << CPU_PLL_CONFIG_OUTDIV_LSB) & CPU_PLL_CONFIG_OUTDIV_MASK)
+#define CPU_PLL_CONFIG_RANGE_LSB 17
+#define CPU_PLL_CONFIG_RANGE_MASK 0x00060000
+#define CPU_PLL_CONFIG_RANGE_SET(x) \
+ (((x) << CPU_PLL_CONFIG_RANGE_LSB) & CPU_PLL_CONFIG_RANGE_MASK)
+#define CPU_PLL_CONFIG_REFDIV_LSB 12
+#define CPU_PLL_CONFIG_REFDIV_MASK 0x0001f000
+#define CPU_PLL_CONFIG_REFDIV_SET(x) \
+ (((x) << CPU_PLL_CONFIG_REFDIV_LSB) & CPU_PLL_CONFIG_REFDIV_MASK)
+#define CPU_PLL_CONFIG1_NINT_LSB 18
+#define CPU_PLL_CONFIG1_NINT_MASK 0x07fc0000
+#define CPU_PLL_CONFIG1_NINT_SET(x) \
+ (((x) << CPU_PLL_CONFIG1_NINT_LSB) & CPU_PLL_CONFIG1_NINT_MASK)
+#define CPU_PLL_DITHER1_DITHER_EN_LSB 31
+#define CPU_PLL_DITHER1_DITHER_EN_MASK 0x80000000
+#define CPU_PLL_DITHER1_DITHER_EN_SET(x) \
+ (((x) << CPU_PLL_DITHER1_DITHER_EN_LSB) & CPU_PLL_DITHER1_DITHER_EN_MASK)
+#define CPU_PLL_DITHER1_UPDATE_COUNT_LSB 24
+#define CPU_PLL_DITHER1_UPDATE_COUNT_MASK 0x3f000000
+#define CPU_PLL_DITHER1_UPDATE_COUNT_SET(x) \
+ (((x) << CPU_PLL_DITHER1_UPDATE_COUNT_LSB) & CPU_PLL_DITHER1_UPDATE_COUNT_MASK)
+#define CPU_PLL_DITHER1_NFRAC_STEP_LSB 18
+#define CPU_PLL_DITHER1_NFRAC_STEP_MASK 0x00fc0000
+#define CPU_PLL_DITHER1_NFRAC_STEP_SET(x) \
+ (((x) << CPU_PLL_DITHER1_NFRAC_STEP_LSB) & CPU_PLL_DITHER1_NFRAC_STEP_MASK)
+#define CPU_PLL_DITHER1_NFRAC_MIN_LSB 0
+#define CPU_PLL_DITHER1_NFRAC_MIN_MASK 0x0003ffff
+#define CPU_PLL_DITHER1_NFRAC_MIN_SET(x) \
+ (((x) << CPU_PLL_DITHER1_NFRAC_MIN_LSB) & CPU_PLL_DITHER1_NFRAC_MIN_MASK)
+#define CPU_PLL_DITHER2_NFRAC_MAX_LSB 0
+#define CPU_PLL_DITHER2_NFRAC_MAX_MASK 0x0003ffff
+#define CPU_PLL_DITHER2_NFRAC_MAX_SET(x) \
+ (((x) << CPU_PLL_DITHER2_NFRAC_MAX_LSB) & CPU_PLL_DITHER2_NFRAC_MAX_MASK)
+#define DDR_PLL_CONFIG_PLLPWD_LSB 30
+#define DDR_PLL_CONFIG_PLLPWD_MASK 0x40000000
+#define DDR_PLL_CONFIG_PLLPWD_SET(x) \
+ (((x) << DDR_PLL_CONFIG_PLLPWD_LSB) & DDR_PLL_CONFIG_PLLPWD_MASK)
+#define DDR_PLL_CONFIG_OUTDIV_LSB 23
+#define DDR_PLL_CONFIG_OUTDIV_MASK 0x03800000
+#define DDR_PLL_CONFIG_OUTDIV_SET(x) \
+ (((x) << DDR_PLL_CONFIG_OUTDIV_LSB) & DDR_PLL_CONFIG_OUTDIV_MASK)
+#define DDR_PLL_CONFIG_RANGE_LSB 21
+#define DDR_PLL_CONFIG_RANGE_MASK 0x00600000
+#define DDR_PLL_CONFIG_RANGE_SET(x) \
+ (((x) << DDR_PLL_CONFIG_RANGE_LSB) & DDR_PLL_CONFIG_RANGE_MASK)
+#define DDR_PLL_CONFIG_REFDIV_LSB 16
+#define DDR_PLL_CONFIG_REFDIV_MASK 0x001f0000
+#define DDR_PLL_CONFIG_REFDIV_SET(x) \
+ (((x) << DDR_PLL_CONFIG_REFDIV_LSB) & DDR_PLL_CONFIG_REFDIV_MASK)
+#define DDR_PLL_CONFIG1_NINT_LSB 18
+#define DDR_PLL_CONFIG1_NINT_MASK 0x07fc0000
+#define DDR_PLL_CONFIG1_NINT_SET(x) \
+ (((x) << DDR_PLL_CONFIG1_NINT_LSB) & DDR_PLL_CONFIG1_NINT_MASK)
+#define DDR_PLL_DITHER1_DITHER_EN_LSB 31
+#define DDR_PLL_DITHER1_DITHER_EN_MASK 0x80000000
+#define DDR_PLL_DITHER1_DITHER_EN_SET(x) \
+ (((x) << DDR_PLL_DITHER1_DITHER_EN_LSB) & DDR_PLL_DITHER1_DITHER_EN_MASK)
+#define DDR_PLL_DITHER1_UPDATE_COUNT_LSB 27
+#define DDR_PLL_DITHER1_UPDATE_COUNT_MASK 0x78000000
+#define DDR_PLL_DITHER1_UPDATE_COUNT_SET(x) \
+ (((x) << DDR_PLL_DITHER1_UPDATE_COUNT_LSB) & DDR_PLL_DITHER1_UPDATE_COUNT_MASK)
+#define DDR_PLL_DITHER1_NFRAC_STEP_LSB 20
+#define DDR_PLL_DITHER1_NFRAC_STEP_MASK 0x07f00000
+#define DDR_PLL_DITHER1_NFRAC_STEP_SET(x) \
+ (((x) << DDR_PLL_DITHER1_NFRAC_STEP_LSB) & DDR_PLL_DITHER1_NFRAC_STEP_MASK)
+#define DDR_PLL_DITHER1_NFRAC_MIN_LSB 0
+#define DDR_PLL_DITHER1_NFRAC_MIN_MASK 0x0003ffff
+#define DDR_PLL_DITHER1_NFRAC_MIN_SET(x) \
+ (((x) << DDR_PLL_DITHER1_NFRAC_MIN_LSB) & DDR_PLL_DITHER1_NFRAC_MIN_MASK)
+#define DDR_PLL_DITHER2_NFRAC_MAX_LSB 0
+#define DDR_PLL_DITHER2_NFRAC_MAX_MASK 0x0003ffff
+#define DDR_PLL_DITHER2_NFRAC_MAX_SET(x) \
+ (((x) << DDR_PLL_DITHER2_NFRAC_MAX_LSB) & DDR_PLL_DITHER2_NFRAC_MAX_MASK)
+#define CPU_DDR_CLOCK_CONTROL_AHBCLK_FROM_DDRPLL_LSB 24
+#define CPU_DDR_CLOCK_CONTROL_AHBCLK_FROM_DDRPLL_MASK 0x01000000
+#define CPU_DDR_CLOCK_CONTROL_AHBCLK_FROM_DDRPLL_SET(x) \
+ (((x) << CPU_DDR_CLOCK_CONTROL_AHBCLK_FROM_DDRPLL_LSB) & CPU_DDR_CLOCK_CONTROL_AHBCLK_FROM_DDRPLL_MASK)
+#define CPU_DDR_CLOCK_CONTROL_CPU_DDR_CLK_FROM_CPUPLL_LSB 21
+#define CPU_DDR_CLOCK_CONTROL_CPU_DDR_CLK_FROM_CPUPLL_MASK 0x00200000
+#define CPU_DDR_CLOCK_CONTROL_CPU_DDR_CLK_FROM_CPUPLL_SET(x) \
+ (((x) << CPU_DDR_CLOCK_CONTROL_CPU_DDR_CLK_FROM_CPUPLL_LSB) & CPU_DDR_CLOCK_CONTROL_CPU_DDR_CLK_FROM_CPUPLL_MASK)
+#define CPU_DDR_CLOCK_CONTROL_CPU_DDR_CLK_FROM_DDRPLL_LSB 20
+#define CPU_DDR_CLOCK_CONTROL_CPU_DDR_CLK_FROM_DDRPLL_MASK 0x00100000
+#define CPU_DDR_CLOCK_CONTROL_CPU_DDR_CLK_FROM_DDRPLL_SET(x) \
+ (((x) << CPU_DDR_CLOCK_CONTROL_CPU_DDR_CLK_FROM_DDRPLL_LSB) & CPU_DDR_CLOCK_CONTROL_CPU_DDR_CLK_FROM_DDRPLL_MASK)
+#define CPU_DDR_CLOCK_CONTROL_AHB_POST_DIV_LSB 15
+#define CPU_DDR_CLOCK_CONTROL_AHB_POST_DIV_MASK 0x000f8000
+#define CPU_DDR_CLOCK_CONTROL_AHB_POST_DIV_SET(x) \
+ (((x) << CPU_DDR_CLOCK_CONTROL_AHB_POST_DIV_LSB) & CPU_DDR_CLOCK_CONTROL_AHB_POST_DIV_MASK)
+#define CPU_DDR_CLOCK_CONTROL_DDR_POST_DIV_LSB 10
+#define CPU_DDR_CLOCK_CONTROL_DDR_POST_DIV_MASK 0x00007c00
+#define CPU_DDR_CLOCK_CONTROL_DDR_POST_DIV_SET(x) \
+ (((x) << CPU_DDR_CLOCK_CONTROL_DDR_POST_DIV_LSB) & CPU_DDR_CLOCK_CONTROL_DDR_POST_DIV_MASK)
+#define CPU_DDR_CLOCK_CONTROL_CPU_POST_DIV_LSB 5
+#define CPU_DDR_CLOCK_CONTROL_CPU_POST_DIV_MASK 0x000003e0
+#define CPU_DDR_CLOCK_CONTROL_CPU_POST_DIV_SET(x) \
+ (((x) << CPU_DDR_CLOCK_CONTROL_CPU_POST_DIV_LSB) & CPU_DDR_CLOCK_CONTROL_CPU_POST_DIV_MASK)
+#define CPU_DDR_CLOCK_CONTROL_AHB_PLL_BYPASS_LSB 4
+#define CPU_DDR_CLOCK_CONTROL_AHB_PLL_BYPASS_MASK 0x00000010
+#define CPU_DDR_CLOCK_CONTROL_AHB_PLL_BYPASS_SET(x) \
+ (((x) << CPU_DDR_CLOCK_CONTROL_AHB_PLL_BYPASS_LSB) & CPU_DDR_CLOCK_CONTROL_AHB_PLL_BYPASS_MASK)
+#define CPU_DDR_CLOCK_CONTROL_DDR_PLL_BYPASS_LSB 3
+#define CPU_DDR_CLOCK_CONTROL_DDR_PLL_BYPASS_MASK 0x00000008
+#define CPU_DDR_CLOCK_CONTROL_DDR_PLL_BYPASS_SET(x) \
+ (((x) << CPU_DDR_CLOCK_CONTROL_DDR_PLL_BYPASS_LSB) & CPU_DDR_CLOCK_CONTROL_DDR_PLL_BYPASS_MASK)
+#define CPU_DDR_CLOCK_CONTROL_CPU_PLL_BYPASS_LSB 2
+#define CPU_DDR_CLOCK_CONTROL_CPU_PLL_BYPASS_MASK 0x00000004
+#define CPU_DDR_CLOCK_CONTROL_CPU_PLL_BYPASS_SET(x) \
+ (((x) << CPU_DDR_CLOCK_CONTROL_CPU_PLL_BYPASS_LSB) & CPU_DDR_CLOCK_CONTROL_CPU_PLL_BYPASS_MASK)
+
+#define CPU_PLL_CONFIG1_NINT_VAL CPU_PLL_CONFIG1_NINT_SET(0x1f)
+#define CPU_PLL_CONFIG_REF_DIV_VAL CPU_PLL_CONFIG_REFDIV_SET(0x1)
+#define CPU_PLL_CONFIG_RANGE_VAL CPU_PLL_CONFIG_RANGE_SET(0)
+#define CPU_PLL_CONFIG_OUT_DIV_VAL1 CPU_PLL_CONFIG_OUTDIV_SET(0)
+#define CPU_PLL_CONFIG_OUT_DIV_VAL2 CPU_PLL_CONFIG_OUTDIV_SET(0)
+#define CPU_PLL_DITHER1_VAL CPU_PLL_DITHER1_DITHER_EN_SET(0) | \
+ CPU_PLL_DITHER1_NFRAC_MIN_SET(0) | \
+ CPU_PLL_DITHER1_NFRAC_STEP_SET(0) | \
+ CPU_PLL_DITHER1_UPDATE_COUNT_SET(0x0)
+#define CPU_PLL_DITHER2_VAL CPU_PLL_DITHER2_NFRAC_MAX_SET(0x0)
+#define DDR_PLL_CONFIG1_NINT_VAL DDR_PLL_CONFIG1_NINT_SET(0x1a)
+#define DDR_PLL_CONFIG_REF_DIV_VAL DDR_PLL_CONFIG_REFDIV_SET(0x1)
+#define DDR_PLL_CONFIG_RANGE_VAL DDR_PLL_CONFIG_RANGE_SET(0)
+#define DDR_PLL_CONFIG_OUT_DIV_VAL1 DDR_PLL_CONFIG_OUTDIV_SET(0)
+#define DDR_PLL_CONFIG_OUT_DIV_VAL2 DDR_PLL_CONFIG_OUTDIV_SET(0)
+#define DDR_PLL_DITHER1_VAL DDR_PLL_DITHER1_DITHER_EN_SET(0) | \
+ DDR_PLL_DITHER1_NFRAC_MIN_SET(0) | \
+ DDR_PLL_DITHER1_NFRAC_STEP_SET(0) | \
+ DDR_PLL_DITHER1_UPDATE_COUNT_SET(0x0)
+#define DDR_PLL_DITHER2_VAL DDR_PLL_DITHER2_NFRAC_MAX_SET(0x0)
+#define AHB_CLK_FROM_DDR CPU_DDR_CLOCK_CONTROL_AHBCLK_FROM_DDRPLL_SET(0)
+#define CPU_AND_DDR_CLK_FROM_DDR \
+ CPU_DDR_CLOCK_CONTROL_CPU_DDR_CLK_FROM_DDRPLL_SET(0)
+#define CPU_AND_DDR_CLK_FROM_CPU \
+ CPU_DDR_CLOCK_CONTROL_CPU_DDR_CLK_FROM_CPUPLL_SET(0)
+#define CPU_DDR_CLOCK_CONTROL_AHB_DIV_VAL \
+ CPU_DDR_CLOCK_CONTROL_AHB_POST_DIV_SET(0x2)
+#define CPU_DDR_CLOCK_CONTROL_DDR_POST_DIV \
+ CPU_DDR_CLOCK_CONTROL_DDR_POST_DIV_SET(0)
+#define CPU_DDR_CLOCK_CONTROL_CPU_POST_DIV \
+ CPU_DDR_CLOCK_CONTROL_CPU_POST_DIV_SET(0)
+
+static inline void set_val(u32 _reg, u32 _mask, u32 _val)
+{
+ void __iomem *pll_regs = map_physmem(AR71XX_PLL_BASE,
+ AR71XX_PLL_SIZE, MAP_NOCACHE);
+ writel((readl(pll_regs + _reg) & (~(_mask))) | _val, pll_regs + _reg);
+}
+
+#define cpu_pll_set(_mask, _val) \
+ set_val(QCA956X_PLL_CPU_CONFIG_REG, _mask, _val)
+
+#define ddr_pll_set(_mask, _val) \
+ set_val(QCA956X_PLL_DDR_CONFIG_REG, _mask, _val)
+
+#define cpu_ddr_control_set(_mask, _val) \
+ set_val(QCA956X_PLL_CLK_CTRL_REG, _mask, _val)
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static u32 qca956x_get_xtal(void)
+{
+ u32 val;
+
+ val = ath79_get_bootstrap();
+ if (val & QCA956X_BOOTSTRAP_REF_CLK_40)
+ return 40000000;
+ else
+ return 25000000;
+}
+
+int get_serial_clock(void)
+{
+ return qca956x_get_xtal();
+}
+
+void qca956x_pll_init(void)
+{
+ void __iomem *srif_regs = map_physmem(QCA956X_SRIF_BASE,
+ QCA956X_SRIF_SIZE, MAP_NOCACHE);
+ void __iomem *pll_regs = map_physmem(AR71XX_PLL_BASE,
+ AR71XX_PLL_SIZE, MAP_NOCACHE);
+
+ /* 8.16.2 Baseband DPLL2 */
+ writel(PLL_SRIF_DPLL2_KI_SET(2) | PLL_SRIF_DPLL2_KD_SET(0xa) |
+ PLL_SRIF_DPLL2_PLL_PWD_SET(1) | PLL_SRIF_DPLL2_OUTDIV_SET(1) |
+ PLL_SRIF_DPLL2_PHASE_SHIFT_SET(6), srif_regs + QCA956X_SRIF_BB_DPLL2_REG);
+
+ /* 8.16.2 PCIE DPLL2 */
+ writel(PLL_SRIF_DPLL2_KI_SET(2) | PLL_SRIF_DPLL2_KD_SET(0xa) |
+ PLL_SRIF_DPLL2_PLL_PWD_SET(1) | PLL_SRIF_DPLL2_OUTDIV_SET(3) |
+ PLL_SRIF_DPLL2_PHASE_SHIFT_SET(6), srif_regs + QCA956X_SRIF_PCIE_DPLL2_REG);
+
+ /* 8.16.2 DDR DPLL2 */
+ writel(PLL_SRIF_DPLL2_KI_SET(2) | PLL_SRIF_DPLL2_KD_SET(0xa) |
+ PLL_SRIF_DPLL2_PLL_PWD_SET(1) | PLL_SRIF_DPLL2_PHASE_SHIFT_SET(6),
+ srif_regs + QCA956X_SRIF_DDR_DPLL2_REG);
+
+ /* 8.16.2 CPU DPLL2 */
+ writel(PLL_SRIF_DPLL2_KI_SET(1) | PLL_SRIF_DPLL2_KD_SET(7) |
+ PLL_SRIF_DPLL2_PLL_PWD_SET(1) | PLL_SRIF_DPLL2_PHASE_SHIFT_SET(6),
+ srif_regs + QCA956X_SRIF_CPU_DPLL2_REG);
+
+ /* pll_bypass_set */
+ cpu_ddr_control_set(CPU_DDR_CLOCK_CONTROL_CPU_PLL_BYPASS_MASK,
+ CPU_DDR_CLOCK_CONTROL_CPU_PLL_BYPASS_SET(1));
+ cpu_ddr_control_set(CPU_DDR_CLOCK_CONTROL_DDR_PLL_BYPASS_MASK,
+ CPU_DDR_CLOCK_CONTROL_DDR_PLL_BYPASS_SET(1));
+ cpu_ddr_control_set(CPU_DDR_CLOCK_CONTROL_AHB_PLL_BYPASS_MASK,
+ CPU_DDR_CLOCK_CONTROL_AHB_PLL_BYPASS_SET(1));
+
+ /* init_cpu_pll */
+ cpu_pll_set(CPU_PLL_CONFIG_PLLPWD_MASK, CPU_PLL_CONFIG_PLLPWD_SET(1));
+ cpu_pll_set(CPU_PLL_CONFIG_REFDIV_MASK, CPU_PLL_CONFIG_REF_DIV_VAL);
+ cpu_pll_set(CPU_PLL_CONFIG_RANGE_MASK, CPU_PLL_CONFIG_RANGE_VAL);
+ cpu_pll_set(CPU_PLL_CONFIG_OUTDIV_MASK, CPU_PLL_CONFIG_OUT_DIV_VAL1);
+ set_val(QCA956X_PLL_CPU_CONFIG1_REG, CPU_PLL_CONFIG1_NINT_MASK, \
+ CPU_PLL_CONFIG1_NINT_VAL);
+
+ /* init_ddr_pll */
+ ddr_pll_set(DDR_PLL_CONFIG_PLLPWD_MASK, DDR_PLL_CONFIG_PLLPWD_SET(1));
+ ddr_pll_set(DDR_PLL_CONFIG_REFDIV_MASK, DDR_PLL_CONFIG_REF_DIV_VAL);
+ ddr_pll_set(DDR_PLL_CONFIG_RANGE_MASK, DDR_PLL_CONFIG_RANGE_VAL);
+ ddr_pll_set(DDR_PLL_CONFIG_OUTDIV_MASK, DDR_PLL_CONFIG_OUT_DIV_VAL1);
+ set_val(QCA956X_PLL_DDR_CONFIG1_REG, DDR_PLL_CONFIG1_NINT_MASK,
+ DDR_PLL_CONFIG1_NINT_VAL);
+
+ /* init_ahb_pll */
+ writel(CPU_DDR_CLOCK_CONTROL_AHB_DIV_VAL | AHB_CLK_FROM_DDR |
+ CPU_AND_DDR_CLK_FROM_DDR | CPU_AND_DDR_CLK_FROM_CPU |
+ CPU_DDR_CLOCK_CONTROL_DDR_POST_DIV | CPU_DDR_CLOCK_CONTROL_CPU_POST_DIV |
+ CPU_DDR_CLOCK_CONTROL_CPU_PLL_BYPASS_SET(1) |
+ CPU_DDR_CLOCK_CONTROL_DDR_PLL_BYPASS_SET(1) |
+ CPU_DDR_CLOCK_CONTROL_AHB_PLL_BYPASS_SET(1), pll_regs + QCA956X_PLL_CLK_CTRL_REG);
+
+ /* ddr_pll_dither_unset */
+ writel(DDR_PLL_DITHER1_VAL, pll_regs + QCA956X_PLL_DDR_DIT_FRAC_REG);
+ writel(DDR_PLL_DITHER2_VAL, pll_regs + QCA956X_PLL_DDR_DIT2_FRAC_REG);
+
+ /* cpu_pll_dither_unset */
+ writel(CPU_PLL_DITHER1_VAL, pll_regs + QCA956X_PLL_CPU_DIT_FRAC_REG);
+ writel(CPU_PLL_DITHER2_VAL, pll_regs + QCA956X_PLL_CPU_DIT2_FRAC_REG);
+
+ /* pll_pwd_unset */
+ cpu_pll_set(CPU_PLL_CONFIG_PLLPWD_MASK, CPU_PLL_CONFIG_PLLPWD_SET(0));
+ ddr_pll_set(DDR_PLL_CONFIG_PLLPWD_MASK, DDR_PLL_CONFIG_PLLPWD_SET(0));
+
+ /* outdiv_unset */
+ cpu_pll_set(CPU_PLL_CONFIG_OUTDIV_MASK, CPU_PLL_CONFIG_OUT_DIV_VAL2);
+ ddr_pll_set(DDR_PLL_CONFIG_OUTDIV_MASK, DDR_PLL_CONFIG_OUT_DIV_VAL2);
+
+ /* pll_bypass_unset */
+ cpu_ddr_control_set(CPU_DDR_CLOCK_CONTROL_CPU_PLL_BYPASS_MASK,
+ CPU_DDR_CLOCK_CONTROL_CPU_PLL_BYPASS_SET(0));
+ cpu_ddr_control_set(CPU_DDR_CLOCK_CONTROL_DDR_PLL_BYPASS_MASK,
+ CPU_DDR_CLOCK_CONTROL_DDR_PLL_BYPASS_SET(0));
+ cpu_ddr_control_set(CPU_DDR_CLOCK_CONTROL_AHB_PLL_BYPASS_MASK,
+ CPU_DDR_CLOCK_CONTROL_AHB_PLL_BYPASS_SET(0));
+
+ while (readl(pll_regs + QCA956X_PLL_CPU_CONFIG_REG) & 0x8000000)
+ /* NOP */;
+
+ while (readl(pll_regs + QCA956X_PLL_DDR_CONFIG_REG) & 0x8000000)
+ /* NOP */;
+}
+
+int get_clocks(void)
+{
+ void __iomem *regs;
+ u32 ref_rate, cpu_rate, ddr_rate, ahb_rate;
+ u32 out_div, ref_div, postdiv, nint, hfrac, lfrac, clk_ctrl;
+ u32 pll, cpu_pll, ddr_pll, misc;
+
+ /*
+ * QCA956x timer init workaround has to be applied right before setting
+ * up the clock. Else, there will be no jiffies
+ */
+ regs = map_physmem(AR71XX_RESET_BASE, AR71XX_RESET_SIZE,
+ MAP_NOCACHE);
+ misc = readl(regs + AR71XX_RESET_REG_MISC_INT_ENABLE);
+ misc |= MISC_INT_MIPS_SI_TIMERINT_MASK;
+ writel(misc, regs + AR71XX_RESET_REG_MISC_INT_ENABLE);
+
+ regs = map_physmem(AR71XX_PLL_BASE, AR71XX_PLL_SIZE,
+ MAP_NOCACHE);
+ pll = readl(regs + QCA956X_PLL_CPU_CONFIG_REG);
+ out_div = (pll >> QCA956X_PLL_CPU_CONFIG_OUTDIV_SHIFT) &
+ QCA956X_PLL_CPU_CONFIG_OUTDIV_MASK;
+ ref_div = (pll >> QCA956X_PLL_CPU_CONFIG_REFDIV_SHIFT) &
+ QCA956X_PLL_CPU_CONFIG_REFDIV_MASK;
+
+ pll = readl(regs + QCA956X_PLL_CPU_CONFIG1_REG);
+ nint = (pll >> QCA956X_PLL_CPU_CONFIG1_NINT_SHIFT) &
+ QCA956X_PLL_CPU_CONFIG1_NINT_MASK;
+ hfrac = (pll >> QCA956X_PLL_CPU_CONFIG1_NFRAC_H_SHIFT) &
+ QCA956X_PLL_CPU_CONFIG1_NFRAC_H_MASK;
+ lfrac = (pll >> QCA956X_PLL_CPU_CONFIG1_NFRAC_L_SHIFT) &
+ QCA956X_PLL_CPU_CONFIG1_NFRAC_L_MASK;
+
+ ref_rate = qca956x_get_xtal();
+
+ cpu_pll = nint * ref_rate / ref_div;
+ cpu_pll += (lfrac * ref_rate) / ((ref_div * 25) << 13);
+ cpu_pll += (hfrac >> 13) * ref_rate / ref_div;
+ cpu_pll /= (1 << out_div);
+
+ pll = readl(regs + QCA956X_PLL_DDR_CONFIG_REG);
+ out_div = (pll >> QCA956X_PLL_DDR_CONFIG_OUTDIV_SHIFT) &
+ QCA956X_PLL_DDR_CONFIG_OUTDIV_MASK;
+ ref_div = (pll >> QCA956X_PLL_DDR_CONFIG_REFDIV_SHIFT) &
+ QCA956X_PLL_DDR_CONFIG_REFDIV_MASK;
+ pll = readl(regs + QCA956X_PLL_DDR_CONFIG1_REG);
+ nint = (pll >> QCA956X_PLL_DDR_CONFIG1_NINT_SHIFT) &
+ QCA956X_PLL_DDR_CONFIG1_NINT_MASK;
+ hfrac = (pll >> QCA956X_PLL_DDR_CONFIG1_NFRAC_H_SHIFT) &
+ QCA956X_PLL_DDR_CONFIG1_NFRAC_H_MASK;
+ lfrac = (pll >> QCA956X_PLL_DDR_CONFIG1_NFRAC_L_SHIFT) &
+ QCA956X_PLL_DDR_CONFIG1_NFRAC_L_MASK;
+
+ ddr_pll = nint * ref_rate / ref_div;
+ ddr_pll += (lfrac * ref_rate) / ((ref_div * 25) << 13);
+ ddr_pll += (hfrac >> 13) * ref_rate / ref_div;
+ ddr_pll /= (1 << out_div);
+
+ clk_ctrl = readl(regs + QCA956X_PLL_CLK_CTRL_REG);
+
+ postdiv = (clk_ctrl >> QCA956X_PLL_CLK_CTRL_CPU_POST_DIV_SHIFT) &
+ QCA956X_PLL_CLK_CTRL_CPU_POST_DIV_MASK;
+
+ if (clk_ctrl & QCA956X_PLL_CLK_CTRL_CPU_PLL_BYPASS)
+ cpu_rate = ref_rate;
+ else if (clk_ctrl & QCA956X_PLL_CLK_CTRL_CPU_DDRCLK_FROM_CPUPLL)
+ cpu_rate = ddr_pll / (postdiv + 1);
+ else
+ cpu_rate = cpu_pll / (postdiv + 1);
+
+ postdiv = (clk_ctrl >> QCA956X_PLL_CLK_CTRL_DDR_POST_DIV_SHIFT) &
+ QCA956X_PLL_CLK_CTRL_DDR_POST_DIV_MASK;
+
+ if (clk_ctrl & QCA956X_PLL_CLK_CTRL_DDR_PLL_BYPASS)
+ ddr_rate = ref_rate;
+ else if (clk_ctrl & QCA956X_PLL_CLK_CTRL_CPU_DDRCLK_FROM_DDRPLL)
+ ddr_rate = cpu_pll / (postdiv + 1);
+ else
+ ddr_rate = ddr_pll / (postdiv + 1);
+
+ postdiv = (clk_ctrl >> QCA956X_PLL_CLK_CTRL_AHB_POST_DIV_SHIFT) &
+ QCA956X_PLL_CLK_CTRL_AHB_POST_DIV_MASK;
+
+ if (clk_ctrl & QCA956X_PLL_CLK_CTRL_AHB_PLL_BYPASS)
+ ahb_rate = ref_rate;
+ else if (clk_ctrl & QCA956X_PLL_CLK_CTRL_AHBCLK_FROM_DDRPLL)
+ ahb_rate = ddr_pll / (postdiv + 1);
+ else
+ ahb_rate = cpu_pll / (postdiv + 1);
+
+ gd->cpu_clk = cpu_rate;
+ gd->mem_clk = ddr_rate;
+ gd->bus_clk = ahb_rate;
+
+ debug("cpu_clk=%u, ddr_clk=%u, bus_clk=%u\n",
+ cpu_rate, ddr_rate, ahb_rate);
+
+ return 0;
+}
+
+ulong get_bus_freq(ulong dummy)
+{
+ if (!gd->bus_clk)
+ get_clocks();
+ return gd->bus_clk;
+}
+
+ulong get_ddr_freq(ulong dummy)
+{
+ if (!gd->mem_clk)
+ get_clocks();
+ return gd->mem_clk;
+}
diff --git a/arch/mips/mach-ath79/qca956x/cpu.c b/arch/mips/mach-ath79/qca956x/cpu.c
new file mode 100644
index 0000000000..08a8c84e72
--- /dev/null
+++ b/arch/mips/mach-ath79/qca956x/cpu.c
@@ -0,0 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2019 Rosy Song <rosysong(a)rosinson.com>
+ */
+
+#include <common.h>
+
+/* The lowlevel_init() is not needed on QCA956X */
+void lowlevel_init(void) {}
diff --git a/arch/mips/mach-ath79/qca956x/ddr.c b/arch/mips/mach-ath79/qca956x/ddr.c
new file mode 100644
index 0000000000..b6ea0f9654
--- /dev/null
+++ b/arch/mips/mach-ath79/qca956x/ddr.c
@@ -0,0 +1,308 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2019 Rosy Song <rosysong(a)rosinson.com>
+ *
+ * Based on QSDK
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/addrspace.h>
+#include <asm/types.h>
+#include <mach/ar71xx_regs.h>
+#include <mach/ath79.h>
+
+#define DDR_FSM_WAIT_CTRL_VAL 0xa12
+#define DDR_CTL_CONFIG_SRAM_TSEL_LSB 30
+#define DDR_CTL_CONFIG_SRAM_TSEL_MASK 0xc0000000
+#define DDR_CTL_CONFIG_SRAM_TSEL_SET(x) \
+ (((x) << DDR_CTL_CONFIG_SRAM_TSEL_LSB) & DDR_CTL_CONFIG_SRAM_TSEL_MASK)
+#define DDR_CTL_CONFIG_GE0_SRAM_SYNC_LSB 20
+#define DDR_CTL_CONFIG_GE0_SRAM_SYNC_MASK 0x00100000
+#define DDR_CTL_CONFIG_GE0_SRAM_SYNC_SET(x) \
+ (((x) << DDR_CTL_CONFIG_GE0_SRAM_SYNC_LSB) & DDR_CTL_CONFIG_GE0_SRAM_SYNC_MASK)
+#define DDR_CTL_CONFIG_GE1_SRAM_SYNC_LSB 19
+#define DDR_CTL_CONFIG_GE1_SRAM_SYNC_MASK 0x00080000
+#define DDR_CTL_CONFIG_GE1_SRAM_SYNC_SET(x) \
+ (((x) << DDR_CTL_CONFIG_GE1_SRAM_SYNC_LSB) & DDR_CTL_CONFIG_GE1_SRAM_SYNC_MASK)
+#define DDR_CTL_CONFIG_USB_SRAM_SYNC_LSB 18
+#define DDR_CTL_CONFIG_USB_SRAM_SYNC_MASK 0x00040000
+#define DDR_CTL_CONFIG_USB_SRAM_SYNC_SET(x) \
+ (((x) << DDR_CTL_CONFIG_USB_SRAM_SYNC_LSB) & DDR_CTL_CONFIG_USB_SRAM_SYNC_MASK)
+#define DDR_CTL_CONFIG_PCIE_SRAM_SYNC_LSB 17
+#define DDR_CTL_CONFIG_PCIE_SRAM_SYNC_MASK 0x00020000
+#define DDR_CTL_CONFIG_PCIE_SRAM_SYNC_SET(x) \
+ (((x) << DDR_CTL_CONFIG_PCIE_SRAM_SYNC_LSB) & DDR_CTL_CONFIG_PCIE_SRAM_SYNC_MASK)
+#define DDR_CTL_CONFIG_WMAC_SRAM_SYNC_LSB 16
+#define DDR_CTL_CONFIG_WMAC_SRAM_SYNC_MASK 0x00010000
+#define DDR_CTL_CONFIG_WMAC_SRAM_SYNC_SET(x) \
+ (((x) << DDR_CTL_CONFIG_WMAC_SRAM_SYNC_LSB) & DDR_CTL_CONFIG_WMAC_SRAM_SYNC_MASK)
+#define DDR_CTL_CONFIG_MISC_SRC1_SRAM_SYNC_LSB 15
+#define DDR_CTL_CONFIG_MISC_SRC1_SRAM_SYNC_MASK 0x00008000
+#define DDR_CTL_CONFIG_MISC_SRC1_SRAM_SYNC_SET(x) \
+ (((x) << DDR_CTL_CONFIG_MISC_SRC1_SRAM_SYNC_LSB) & DDR_CTL_CONFIG_MISC_SRC1_SRAM_SYNC_MASK)
+#define DDR_CTL_CONFIG_MISC_SRC2_SRAM_SYNC_LSB 14
+#define DDR_CTL_CONFIG_MISC_SRC2_SRAM_SYNC_MASK 0x00004000
+#define DDR_CTL_CONFIG_MISC_SRC2_SRAM_SYNC_SET(x) \
+ (((x) << DDR_CTL_CONFIG_MISC_SRC2_SRAM_SYNC_LSB) & DDR_CTL_CONFIG_MISC_SRC2_SRAM_SYNC_MASK)
+#define DDR_CTL_CONFIG_PAD_DDR2_SEL_LSB 6
+#define DDR_CTL_CONFIG_PAD_DDR2_SEL_MASK 0x00000040
+#define DDR_CTL_CONFIG_PAD_DDR2_SEL_SET(x) \
+ (((x) << DDR_CTL_CONFIG_PAD_DDR2_SEL_LSB) & DDR_CTL_CONFIG_PAD_DDR2_SEL_MASK)
+#define DDR_CTL_CONFIG_CPU_DDR_SYNC_LSB 2
+#define DDR_CTL_CONFIG_CPU_DDR_SYNC_MASK 0x00000004
+#define DDR_CTL_CONFIG_CPU_DDR_SYNC_SET(x) \
+ (((x) << DDR_CTL_CONFIG_CPU_DDR_SYNC_LSB) & DDR_CTL_CONFIG_CPU_DDR_SYNC_MASK)
+#define DDR_CTL_CONFIG_HALF_WIDTH_LSB 1
+#define DDR_CTL_CONFIG_HALF_WIDTH_MASK 0x00000002
+#define DDR_CTL_CONFIG_HALF_WIDTH_SET(x) \
+ (((x) << DDR_CTL_CONFIG_HALF_WIDTH_LSB) & DDR_CTL_CONFIG_HALF_WIDTH_MASK)
+#define DDR_CONFIG_CAS_LATENCY_MSB_LSB 31
+#define DDR_CONFIG_CAS_LATENCY_MSB_MASK 0x80000000
+#define DDR_CONFIG_CAS_LATENCY_MSB_SET(x) \
+ (((x) << DDR_CONFIG_CAS_LATENCY_MSB_LSB) & DDR_CONFIG_CAS_LATENCY_MSB_MASK)
+#define DDR_CONFIG_OPEN_PAGE_LSB 30
+#define DDR_CONFIG_OPEN_PAGE_MASK 0x40000000
+#define DDR_CONFIG_OPEN_PAGE_SET(x) \
+ (((x) << DDR_CONFIG_OPEN_PAGE_LSB) & DDR_CONFIG_OPEN_PAGE_MASK)
+#define DDR_CONFIG_CAS_LATENCY_LSB 27
+#define DDR_CONFIG_CAS_LATENCY_MASK 0x38000000
+#define DDR_CONFIG_CAS_LATENCY_SET(x) \
+ (((x) << DDR_CONFIG_CAS_LATENCY_LSB) & DDR_CONFIG_CAS_LATENCY_MASK)
+#define DDR_CONFIG_TMRD_LSB 23
+#define DDR_CONFIG_TMRD_MASK 0x07800000
+#define DDR_CONFIG_TMRD_SET(x) \
+ (((x) << DDR_CONFIG_TMRD_LSB) & DDR_CONFIG_TMRD_MASK)
+#define DDR_CONFIG_TRFC_LSB 17
+#define DDR_CONFIG_TRFC_MASK 0x007e0000
+#define DDR_CONFIG_TRFC_SET(x) \
+ (((x) << DDR_CONFIG_TRFC_LSB) & DDR_CONFIG_TRFC_MASK)
+#define DDR_CONFIG_TRRD_LSB 13
+#define DDR_CONFIG_TRRD_MASK 0x0001e000
+#define DDR_CONFIG_TRRD_SET(x) \
+ (((x) << DDR_CONFIG_TRRD_LSB) & DDR_CONFIG_TRRD_MASK)
+#define DDR_CONFIG_TRP_LSB 9
+#define DDR_CONFIG_TRP_MASK 0x00001e00
+#define DDR_CONFIG_TRP_SET(x) \
+ (((x) << DDR_CONFIG_TRP_LSB) & DDR_CONFIG_TRP_MASK)
+#define DDR_CONFIG_TRCD_LSB 5
+#define DDR_CONFIG_TRCD_MASK 0x000001e0
+#define DDR_CONFIG_TRCD_SET(x) \
+ (((x) << DDR_CONFIG_TRCD_LSB) & DDR_CONFIG_TRCD_MASK)
+#define DDR_CONFIG_TRAS_LSB 0
+#define DDR_CONFIG_TRAS_MASK 0x0000001f
+#define DDR_CONFIG_TRAS_SET(x) \
+ (((x) << DDR_CONFIG_TRAS_LSB) & DDR_CONFIG_TRAS_MASK)
+#define DDR_CONFIG2_HALF_WIDTH_LOW_LSB 31
+#define DDR_CONFIG2_HALF_WIDTH_LOW_MASK 0x80000000
+#define DDR_CONFIG2_HALF_WIDTH_LOW_SET(x) \
+ (((x) << DDR_CONFIG2_HALF_WIDTH_LOW_LSB) & DDR_CONFIG2_HALF_WIDTH_LOW_MASK)
+#define DDR_CONFIG2_SWAP_A26_A27_LSB 30
+#define DDR_CONFIG2_SWAP_A26_A27_MASK 0x40000000
+#define DDR_CONFIG2_SWAP_A26_A27_SET(x) \
+ (((x) << DDR_CONFIG2_SWAP_A26_A27_LSB) & DDR_CONFIG2_SWAP_A26_A27_MASK)
+#define DDR_CONFIG2_GATE_OPEN_LATENCY_LSB 26
+#define DDR_CONFIG2_GATE_OPEN_LATENCY_MASK 0x3c000000
+#define DDR_CONFIG2_GATE_OPEN_LATENCY_SET(x) \
+ (((x) << DDR_CONFIG2_GATE_OPEN_LATENCY_LSB) & DDR_CONFIG2_GATE_OPEN_LATENCY_MASK)
+#define DDR_CONFIG2_TWTR_LSB 21
+#define DDR_CONFIG2_TWTR_MASK 0x03e00000
+#define DDR_CONFIG2_TWTR_SET(x) \
+ (((x) << DDR_CONFIG2_TWTR_LSB) & DDR_CONFIG2_TWTR_MASK)
+#define DDR_CONFIG2_TRTP_LSB 17
+#define DDR_CONFIG2_TRTP_MASK 0x001e0000
+#define DDR_CONFIG2_TRTP_SET(x) \
+ (((x) << DDR_CONFIG2_TRTP_LSB) & DDR_CONFIG2_TRTP_MASK)
+#define DDR_CONFIG2_TRTW_LSB 12
+#define DDR_CONFIG2_TRTW_MASK 0x0001f000
+#define DDR_CONFIG2_TRTW_SET(x) \
+ (((x) << DDR_CONFIG2_TRTW_LSB) & DDR_CONFIG2_TRTW_MASK)
+#define DDR_CONFIG2_TWR_LSB 8
+#define DDR_CONFIG2_TWR_MASK 0x00000f00
+#define DDR_CONFIG2_TWR_SET(x) \
+ (((x) << DDR_CONFIG2_TWR_LSB) & DDR_CONFIG2_TWR_MASK)
+#define DDR_CONFIG2_CKE_LSB 7
+#define DDR_CONFIG2_CKE_MASK 0x00000080
+#define DDR_CONFIG2_CKE_SET(x) \
+ (((x) << DDR_CONFIG2_CKE_LSB) & DDR_CONFIG2_CKE_MASK)
+#define DDR_CONFIG2_CNTL_OE_EN_LSB 5
+#define DDR_CONFIG2_CNTL_OE_EN_MASK 0x00000020
+#define DDR_CONFIG2_CNTL_OE_EN_SET(x) \
+ (((x) << DDR_CONFIG2_CNTL_OE_EN_LSB) & DDR_CONFIG2_CNTL_OE_EN_MASK)
+#define DDR_CONFIG2_BURST_LENGTH_LSB 0
+#define DDR_CONFIG2_BURST_LENGTH_MASK 0x0000000f
+#define DDR_CONFIG2_BURST_LENGTH_SET(x) \
+ (((x) << DDR_CONFIG2_BURST_LENGTH_LSB) & DDR_CONFIG2_BURST_LENGTH_MASK)
+#define RST_BOOTSTRAP_ADDRESS 0x180600b0
+#define PMU2_SWREGMSB_LSB 22
+#define PMU2_SWREGMSB_MASK 0xffc00000
+#define PMU2_SWREGMSB_SET(x) \
+ (((x) << PMU2_SWREGMSB_LSB) & PMU2_SWREGMSB_MASK)
+#define PMU2_PGM_LSB 21
+#define PMU2_PGM_MASK 0x00200000
+#define PMU2_PGM_SET(x) \
+ (((x) << PMU2_PGM_LSB) & PMU2_PGM_MASK)
+
+#define CPU_DDR_SYNC_MODE DDR_CTL_CONFIG_CPU_DDR_SYNC_SET(0)
+
+/*
+* DDR2 DDR1
+* 0x40c3 25MHz 0x4186 25Mhz
+* 0x4138 40MHz 0x4270 40Mhz
+*/
+#define CFG_DDR2_REFRESH_VAL 0x40c3
+#define CFG_DDR2_CONFIG_VAL DDR_CONFIG_CAS_LATENCY_MSB_SET(0x1) | \
+ DDR_CONFIG_OPEN_PAGE_SET(0x1) | DDR_CONFIG_CAS_LATENCY_SET(0x4) | \
+ DDR_CONFIG_TMRD_SET(0x6) | DDR_CONFIG_TRFC_SET(0x16) | \
+ DDR_CONFIG_TRRD_SET(0x7) | DDR_CONFIG_TRP_SET(0xb) | \
+ DDR_CONFIG_TRCD_SET(0xb) | DDR_CONFIG_TRAS_SET(0)
+#define CFG_DDR2_CONFIG2_VAL DDR_CONFIG2_HALF_WIDTH_LOW_SET(0x1) | \
+ DDR_CONFIG2_SWAP_A26_A27_SET(0x0) | DDR_CONFIG2_GATE_OPEN_LATENCY_SET(0xa) | \
+ DDR_CONFIG2_TWTR_SET(0x16) | DDR_CONFIG2_TRTP_SET(0xa) | \
+ DDR_CONFIG2_TRTW_SET(0xe) | DDR_CONFIG2_TWR_SET(0x2) | \
+ DDR_CONFIG2_CKE_SET(0x1) | DDR_CONFIG2_CNTL_OE_EN_SET(0x1) | \
+ DDR_CONFIG2_BURST_LENGTH_SET(0x8)
+
+#define CFG_DDR2_CONFIG3_VAL 0x0000000e
+#define CFG_DDR2_EXT_MODE_VAL1 0x782
+#define CFG_DDR2_EXT_MODE_VAL2 0x402
+#define CFG_DDR2_MODE_VAL_INIT 0xb53
+#define CFG_DDR2_MODE_VAL 0xa53
+#define CFG_DDR2_TAP_VAL 0x10
+#define CFG_DDR2_EN_TWL_VAL 0x00001e91
+#define CFG_DDR2_RD_DATA_THIS_CYCLE_VAL_16 0xffff
+
+#define CFG_DDR_CTL_CONFIG DDR_CTL_CONFIG_SRAM_TSEL_SET(0x1) | \
+ DDR_CTL_CONFIG_GE0_SRAM_SYNC_SET(0x1) | \
+ DDR_CTL_CONFIG_GE1_SRAM_SYNC_SET(0x1) | \
+ DDR_CTL_CONFIG_USB_SRAM_SYNC_SET(0x1) | \
+ DDR_CTL_CONFIG_PCIE_SRAM_SYNC_SET(0x1) | \
+ DDR_CTL_CONFIG_WMAC_SRAM_SYNC_SET(0x1) | \
+ DDR_CTL_CONFIG_MISC_SRC1_SRAM_SYNC_SET(0x1) | \
+ DDR_CTL_CONFIG_MISC_SRC2_SRAM_SYNC_SET(0x1)
+
+DECLARE_GLOBAL_DATA_PTR;
+
+void qca956x_ddr_init(void)
+{
+ u32 ddr_config, ddr_config2, ddr_config3, mod_val, \
+ mod_val_init, cycle_val, tap_val, ctl_config;
+ void __iomem *ddr_regs = map_physmem(AR71XX_DDR_CTRL_BASE, AR71XX_DDR_CTRL_SIZE,
+ MAP_NOCACHE);
+ void __iomem *srif_regs = map_physmem(QCA956X_SRIF_BASE, QCA956X_SRIF_SIZE,
+ MAP_NOCACHE);
+
+ ddr_config = CFG_DDR2_CONFIG_VAL;
+ ddr_config2 = CFG_DDR2_CONFIG2_VAL;
+ ddr_config3 = CFG_DDR2_CONFIG3_VAL;
+ mod_val_init = CFG_DDR2_MODE_VAL_INIT;
+ mod_val = CFG_DDR2_MODE_VAL;
+ tap_val = CFG_DDR2_TAP_VAL;
+ cycle_val = CFG_DDR2_RD_DATA_THIS_CYCLE_VAL_16;
+ ctl_config = CFG_DDR_CTL_CONFIG | DDR_CTL_CONFIG_PAD_DDR2_SEL_SET(0x1) |
+ DDR_CTL_CONFIG_HALF_WIDTH_SET(0x1) | CPU_DDR_SYNC_MODE;
+
+ writel(0x10, ddr_regs + AR71XX_DDR_REG_CONTROL);
+ udelay(10);
+
+ writel(0x20, ddr_regs + AR71XX_DDR_REG_CONTROL);
+ udelay(10);
+
+ writel(ctl_config, ddr_regs + QCA956X_DDR_REG_CTL_CONF);
+ udelay(10);
+
+ writel(cycle_val, ddr_regs + AR71XX_DDR_REG_RD_CYCLE);
+ udelay(100);
+
+ writel(0x74444444, ddr_regs + QCA956X_DDR_REG_BURST);
+ udelay(100);
+
+ writel(0x44444444, ddr_regs + QCA956X_DDR_REG_BURST2);
+ udelay(100);
+
+ writel(DDR_FSM_WAIT_CTRL_VAL, ddr_regs + QCA956X_DDR_REG_FSM_WAIT_CTRL);
+ udelay(100);
+
+ writel(0xfffff, ddr_regs + QCA956X_DDR_REG_TIMEOUT_MAX);
+ udelay(100);
+
+ writel(ddr_config, ddr_regs + AR71XX_DDR_REG_CONFIG);
+ udelay(100);
+
+ writel(ddr_config2, ddr_regs + AR71XX_DDR_REG_CONFIG2);
+ udelay(100);
+
+ writel(ddr_config3, ddr_regs + QCA956X_DDR_REG_DDR3_CONFIG);
+ udelay(100);
+
+ writel(CFG_DDR2_EN_TWL_VAL, ddr_regs + QCA956X_DDR_REG_DDR2_CONFIG);
+ udelay(100);
+
+ writel(ddr_config2 | 0x80, ddr_regs + AR71XX_DDR_REG_CONFIG2); // CKE Enable
+ udelay(100);
+
+ writel(0x8, ddr_regs + AR71XX_DDR_REG_CONTROL); // Precharge
+ udelay(10);
+
+ writel(0, ddr_regs + QCA956X_DDR_REG_DDR2_EMR2);
+ writel(0x10, ddr_regs + AR71XX_DDR_REG_CONTROL); // EMR2
+ udelay(10);
+
+ writel(0, ddr_regs + QCA956X_DDR_REG_DDR2_EMR3);
+ writel(0x20, ddr_regs + AR71XX_DDR_REG_CONTROL); // EMR3
+ udelay(10);
+
+ // EMR DLL enable, Reduced Driver Impedance control, Differential DQS disabled
+ writel(CFG_DDR2_EXT_MODE_VAL2, ddr_regs + AR71XX_DDR_REG_EMR);
+ udelay(100);
+
+ writel(0x2, ddr_regs + AR71XX_DDR_REG_CONTROL); // EMR write
+ udelay(10);
+
+ writel(mod_val_init, ddr_regs + AR71XX_DDR_REG_MODE);
+ udelay(1000);
+
+ writel(0x1, ddr_regs + AR71XX_DDR_REG_CONTROL); // MR Write
+ udelay(10);
+
+ writel(0x8, ddr_regs + AR71XX_DDR_REG_CONTROL); // Precharge
+ udelay(10);
+
+ writel(0x4, ddr_regs + AR71XX_DDR_REG_CONTROL); // Auto Refresh
+ udelay(10);
+
+ writel(0x4, ddr_regs + AR71XX_DDR_REG_CONTROL); // Auto Refresh
+ udelay(10);
+
+ // Issue MRS to remove DLL out-of-reset
+ writel(mod_val, ddr_regs + AR71XX_DDR_REG_MODE);
+ udelay(100);
+
+ writel(0x1, ddr_regs + AR71XX_DDR_REG_CONTROL); // MR write
+ udelay(100);
+
+ writel(CFG_DDR2_EXT_MODE_VAL1, ddr_regs + AR71XX_DDR_REG_EMR);
+ udelay(100);
+
+ writel(0x2, ddr_regs + AR71XX_DDR_REG_CONTROL); // EMR write
+ udelay(100);
+
+ writel(CFG_DDR2_EXT_MODE_VAL2, ddr_regs + AR71XX_DDR_REG_EMR);
+ udelay(100);
+
+ writel(0x2, ddr_regs + AR71XX_DDR_REG_CONTROL); // EMR write
+ udelay(100);
+
+ writel(CFG_DDR2_REFRESH_VAL, ddr_regs + AR71XX_DDR_REG_REFRESH);
+ udelay(100);
+
+ writel(tap_val, ddr_regs + AR71XX_DDR_REG_TAP_CTRL0);
+ writel(tap_val, ddr_regs + AR71XX_DDR_REG_TAP_CTRL1);
+ writel(tap_val, ddr_regs + QCA956X_DDR_REG_TAP_CTRL2);
+ writel(tap_val, ddr_regs + QCA956X_DDR_REG_TAP_CTRL3);
+
+ writel(0x633c8176, srif_regs + QCA956X_SRIF_PMU1_REG);
+ // Set DDR2 Voltage to 1.8 volts
+ writel(PMU2_SWREGMSB_SET(0x40) | PMU2_PGM_SET(0x1),
+ srif_regs + QCA956X_SRIF_PMU2_REG);
+}
diff --git a/arch/mips/mach-ath79/qca956x/lowlevel_init.S b/arch/mips/mach-ath79/qca956x/lowlevel_init.S
new file mode 100644
index 0000000000..0580e238bc
--- /dev/null
+++ b/arch/mips/mach-ath79/qca956x/lowlevel_init.S
@@ -0,0 +1,79 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2018-1029 Rosy Song <rosysong(a)rosinson.com>
+ * Based on Atheros LSDK/QSDK
+ */
+
+#include <config.h>
+#include <asm/asm.h>
+#include <asm/regdef.h>
+#include <asm/mipsregs.h>
+#include <asm/addrspace.h>
+#include <mach/ar71xx_regs.h>
+
+ .text
+ .set noreorder
+
+LEAF(lowlevel_init)
+ li t0, CKSEG1ADDR(QCA956X_SRIF_BASE)
+ li t1, 0x54486000
+ sw t1, QCA953X_SRIF_BB_DPLL2_REG(t0)
+
+ li t1, 0x2e406000
+ sw t1, QCA956X_SRIF_CPU_DPLL2_REG(t0)
+
+ li t1, 0x54406000
+ sw t1, QCA956X_SRIF_DDR_DPLL2_REG(t0)
+
+ li t1, 0x88586000
+ sw t1, QCA956X_SRIF_PCIE_DPLL2_REG(t0)
+
+init_cpu_pll:
+ li t0, CKSEG1ADDR(AR71XX_PLL_BASE)
+ li t1, 0x00001000
+ sw t1, QCA956X_PLL_CPU_CONFIG_REG(t0)
+ li t1, 0x007c0000
+ sw t1, QCA956X_PLL_CPU_CONFIG1_REG(t0)
+
+init_ddr_pll:
+ li t1, 0x00010000
+ sw t1, QCA956X_PLL_DDR_CONFIG_REG(t0)
+ li t1, 0x00680000
+ sw t1, QCA956X_PLL_DDR_CONFIG1_REG(t0)
+
+init_ahb_pll:
+ li t1, 0x00010000
+ sw t1, QCA956X_PLL_CLK_CTRL_REG(t0)
+
+ddr_pll_dither_unset:
+ li t1, 0x00000000
+ sw t1, QCA956X_PLL_DDR_DIT_FRAC_REG(t0)
+
+ li t1, 0x00000000
+ sw t1, QCA956X_PLL_DDR_DIT2_FRAC_REG(t0)
+
+cpu_pll_dither_unset:
+ li t1, 0x00000000
+ sw t1, QCA956X_PLL_CPU_DIT_FRAC_REG(t0)
+
+ li t1, 0x00000000
+ sw t1, QCA956X_PLL_CPU_DIT2_FRAC_REG(t0)
+
+check_cpu_pll_locked:
+ li t7, KSEG1ADDR(AR71XX_PLL_BASE);
+ lw t8, QCA956X_PLL_CPU_CONFIG_REG(t7);
+ li t9, 0x8000000;
+ and t8, t8, t9;
+ bne zero, t8, check_cpu_pll_locked;
+
+check_ddr_pll_locked:
+ li t7, KSEG1ADDR(AR71XX_PLL_BASE);
+ lw t8, QCA956X_PLL_DDR_CONFIG_REG(t7);
+ li t9, 0x8000000;
+ and t8, t8, t9;
+ bne zero, t8, check_ddr_pll_locked;
+
+ nop
+ jr ra
+ nop
+ END(lowlevel_init)
diff --git a/arch/mips/mach-ath79/qca956x/qca956x-ddr-tap.S b/arch/mips/mach-ath79/qca956x/qca956x-ddr-tap.S
new file mode 100644
index 0000000000..fa5f6c1a76
--- /dev/null
+++ b/arch/mips/mach-ath79/qca956x/qca956x-ddr-tap.S
@@ -0,0 +1,194 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2019 Rosy Song <rosysong(a)rosinson.com>
+ *
+ * Based on QSDK
+ */
+
+#include <config.h>
+#include <asm/asm.h>
+#include <asm/regdef.h>
+#include <asm/mipsregs.h>
+#include <asm/addrspace.h>
+#include <mach/ar71xx_regs.h>
+
+ .text
+ .set noreorder
+
+LEAF(ddr_tap_tuning)
+ li a0, 0xbd001f00
+ sw zero, 0x0(a0) // Place where the tap values are saved and used for SWEEP
+ sw zero, 0x4(a0) // Place where the number of passing taps are saved.
+ sw zero, 0x14(a0) // Place where the last pass tap value is stored
+ li a1, 0xaa55aa55 // Indicates that the First pass tap value is not found
+ sw a1, 0x10(a0) // Place where the First pass tap value is stored
+ nop
+
+ li a0, 0xb8060000 // RESET_BASE_ADDRESS
+ lw a1, 0x1c(a0) // Reading the RST_RESET_ADDRESS
+ li a2, 0x08000000 // Setting the RST_RESET_RTC_RESET
+ or a1, a1, a2
+ sw a1, 0x1c(a0)
+
+ li a3, 0xffffffff
+ xor a2, a2, a3
+ and a1, a1, a2
+ sw a1, 0x1c(a0) // Taking the RTC out of RESET
+ nop
+
+ li a0, 0xb8107000 // RTC_BASE_ADDRESS
+ li a1, 0x1
+ sw a1, 0x0040(a0) // RTC_SYNC_RESET_ADDRESS
+
+ li a2, 0x2
+
+_poll_for_RTC_ON:
+ lw a1, 0x0044(a0) // RTC_SYNC_STATUS_ADDRESS
+ and a1, a2, a1
+ bne a1, a2, _poll_for_RTC_ON
+ nop
+
+_CHANGE_TAPS:
+ li t0, 0xbd001f00 // Read the current value of the TAP for programming
+ lw t1, 0x0(t0)
+ li t2, 0x00000000
+ or t3, t1, t2
+
+ li t0, 0xb8000000 // DDR_BASE_ADDRESS
+ sw t3, 0x1c(t0) // TAP_CONTROL_0_ADDRESS
+ sw t3, 0x20(t0) // TAP_CONTROL_1_ADDRESS
+ sw t3, 0x24(t0) // TAP_CONTROL_2_ADDRESS
+ sw t3, 0x28(t0) // TAP_CONTROL_3_ADDRESS
+
+ li t1, 0x00000010 // Running the test 8 times
+ sw t1, 0x0068(t0) // PERF_COMP_ADDR_1_ADDRESS
+
+ li t1, 0xfa5de83f // 4 Row Address Bits, 4 Column Address Bits, 2 BA bits
+ sw t1, 0x002c(t0) // PERF_MASK_ADDR_0_ADDRESS
+
+ li t1, 0x0000ffff
+ sw t1, 0x0070(t0) // PERF_COMP_AHB_GE0_1_ADDRESS
+
+ li t1, 0x0000ffff
+ sw t1, 0x0040(t0) // PERF_COMP_AHB_GE1_0_ADDRESS
+
+ li t1, 0x0000ffff
+ sw t1, 0x0078(t0) // PERF_COMP_AHB_GE1_1_ADDRESS
+
+ li t1, 0x0000ffff
+ sw t1, 0x0034(t0) // PERF_MASK_AHB_GE0_0_ADDRESS
+
+ li t1, 0x0000ffff
+ sw t1, 0x006c(t0) // PERF_MASK_AHB_GE0_1_ADDRESS
+
+ li t1, 0x0000ffff
+ sw t1, 0x003c(t0) // PERF_MASK_AHB_GE1_0_ADDRESS
+
+ li t1, 0x0000ffff
+ sw t1, 0x0074(t0) // PERF_MASK_AHB_GE1_1_ADDRESS
+
+ li t1, 0x0000ffff
+ sw t1, 0x0038(t0) // PERF_COMP_AHB_GE0_0_ADDRESS
+
+ li t1, 0x00000001
+ sw t1, 0x011c(t0) // DDR_BIST_ADDRESS
+
+ li t2, 0x1
+
+_bist_done_poll:
+ lw t1, 0x0120(t0) // DDR_BIST_STATUS_ADDRESS
+ and t1, t1, t2
+ bne t1, t2, _bist_done_poll
+ nop
+
+ lw t1, 0x0120(t0) // DDR_BIST_STATUS_ADDRESS
+ li t4, 0x000001fe
+ and t2, t1, t4
+ srl t2, t2, 0x1 // no. of Pass Runs
+
+ li t5, 0x00000000
+ sw t5, 0x011c(t0) //DDR_BIST_ADDRESS - Stop the DDR BIST test
+
+ li t5, 0x0001fe00
+ and t5, t5, t1
+ bnez t5, _iterate_tap // This is a redundant compare but nevertheless - Comparing the FAILS
+ nop
+
+ lw t1, 0x0068(t0) // PERF_COMP_ADDR_1_ADDRESS
+ li t3, 0x000001fe
+ and t3, t3, t1
+ srl t3, t3, 0x1 // No. of runs in the config register.
+ bne t3, t2, _iterate_tap
+ nop
+
+pass_tap:
+ li t0, 0xbd001f00
+ lw t1, 0x4(t0)
+ addiu t1, t1, 0x1
+ sw t1, 0x4(t0)
+
+ li t0, 0xbd001f10
+ lw t1, 0x0(t0)
+ li t2, 0xaa55aa55
+ beq t1, t2, _first_pass
+ nop
+
+ li t0, 0xbd001f00
+ lw t1, 0x0(t0)
+ li t0, 0xbd001f10
+ sw t1, 0x4(t0)
+ nop
+ b _iterate_tap
+ nop
+
+_first_pass:
+ li t0, 0xbd001f00
+ lw t1, 0x0(t0)
+ li t0, 0xbd001f10
+ sw t1, 0x0(t0)
+ sw t1, 0x4(t0)
+ nop
+
+_iterate_tap:
+ li t0, 0xbd001f00
+ lw t1, 0x0(t0)
+ li t2, 0x3f
+ beq t1, t2, _STOP_TEST
+ nop
+
+ addiu t1, t1, 0x1
+ sw t1, 0x0(t0)
+ nop
+ b _CHANGE_TAPS
+ nop
+
+_STOP_TEST:
+ li t0, 0xbd001f00
+ lw t1, 0x4(t0)
+ bnez t1, _load_center_tap
+ nop
+
+ li t3, 0x8 // Default Tap to be used
+ b _load_tap_into_reg
+ nop
+
+_load_center_tap:
+ li t0, 0xbd001f10
+ lw t1, 0x0(t0)
+ lw t2, 0x4(t0)
+ add t3, t1, t2
+ srl t3, t3, 0x1
+ li t4, 0x3f
+ and t3, t3, t4
+
+_load_tap_into_reg:
+ li t0, 0xb8000000
+ sw t3, 0x1c(t0) // TAP_CONTROL_0_ADDRESS
+ sw t3, 0x20(t0) // TAP_CONTROL_1_ADDRESS
+ sw t3, 0x24(t0) // TAP_CONTROL_2_ADDRESS
+ sw t3, 0x28(t0) // TAP_CONTROL_3_ADDRESS
+
+ nop
+ jr ra
+ nop
+ END(ddr_tap_tuning)
diff --git a/arch/mips/mach-ath79/reset.c b/arch/mips/mach-ath79/reset.c
index 6a94d886f9..0ab3ab6383 100644
--- a/arch/mips/mach-ath79/reset.c
+++ b/arch/mips/mach-ath79/reset.c
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2015-2016 Wills Wang <wills.wang(a)live.com>
+ * Copyright (C) 2018-2019 Rosy Song <rosysong(a)rosinson.com>
*/
#include <common.h>
@@ -11,6 +12,44 @@
#include <mach/ath79.h>
#include <mach/ar71xx_regs.h>
+/* QCA956X ETH_SGMII_SERDES Registers */
+#define SGMII_SERDES_RES_CALIBRATION_LSB 23
+#define SGMII_SERDES_RES_CALIBRATION_MASK 0x07800000
+#define SGMII_SERDES_RES_CALIBRATION_SET(x) \
+ (((x) << SGMII_SERDES_RES_CALIBRATION_LSB) & SGMII_SERDES_RES_CALIBRATION_MASK)
+#define SGMII_SERDES_CDR_BW_LSB 1
+#define SGMII_SERDES_CDR_BW_MASK 0x00000006
+#define SGMII_SERDES_CDR_BW_SET(x) \
+ (((x) << SGMII_SERDES_CDR_BW_LSB) & SGMII_SERDES_CDR_BW_MASK)
+#define SGMII_SERDES_TX_DR_CTRL_LSB 4
+#define SGMII_SERDES_TX_DR_CTRL_MASK 0x00000070
+#define SGMII_SERDES_TX_DR_CTRL_SET(x) \
+ (((x) << SGMII_SERDES_TX_DR_CTRL_LSB) & SGMII_SERDES_TX_DR_CTRL_MASK)
+#define SGMII_SERDES_PLL_BW_LSB 8
+#define SGMII_SERDES_PLL_BW_MASK 0x00000100
+#define SGMII_SERDES_PLL_BW_SET(x) \
+ (((x) << SGMII_SERDES_PLL_BW_LSB) & SGMII_SERDES_PLL_BW_MASK)
+#define SGMII_SERDES_EN_SIGNAL_DETECT_LSB 16
+#define SGMII_SERDES_EN_SIGNAL_DETECT_MASK 0x00010000
+#define SGMII_SERDES_EN_SIGNAL_DETECT_SET(x) \
+ (((x) << SGMII_SERDES_EN_SIGNAL_DETECT_LSB) & SGMII_SERDES_EN_SIGNAL_DETECT_MASK)
+#define SGMII_SERDES_FIBER_SDO_LSB 17
+#define SGMII_SERDES_FIBER_SDO_MASK 0x00020000
+#define SGMII_SERDES_FIBER_SDO_SET(x) \
+ (((x) << SGMII_SERDES_FIBER_SDO_LSB) & SGMII_SERDES_FIBER_SDO_MASK)
+#define SGMII_SERDES_VCO_REG_LSB 27
+#define SGMII_SERDES_VCO_REG_MASK 0x78000000
+#define SGMII_SERDES_VCO_REG_SET(x) \
+ (((x) << SGMII_SERDES_VCO_REG_LSB) & SGMII_SERDES_VCO_REG_MASK)
+#define SGMII_SERDES_VCO_FAST_LSB 9
+#define SGMII_SERDES_VCO_FAST_MASK 0x00000200
+#define SGMII_SERDES_VCO_FAST_GET(x) \
+ (((x) & SGMII_SERDES_VCO_FAST_MASK) >> SGMII_SERDES_VCO_FAST_LSB)
+#define SGMII_SERDES_VCO_SLOW_LSB 10
+#define SGMII_SERDES_VCO_SLOW_MASK 0x00000400
+#define SGMII_SERDES_VCO_SLOW_GET(x) \
+ (((x) & SGMII_SERDES_VCO_SLOW_MASK) >> SGMII_SERDES_VCO_SLOW_LSB)
+
void _machine_restart(void)
{
void __iomem *base;
@@ -152,6 +191,236 @@ static int eth_init_qca953x(void)
return 0;
}
+static int qca956x_sgmii_cal(void)
+{
+ int i;
+ u32 reg, rev_sgmii_val;
+ u32 vco_fast, vco_slow;
+ u32 start_val = 0, end_val = 0;
+ void __iomem *gregs = map_physmem(AR71XX_MII_BASE, AR71XX_MII_SIZE,
+ MAP_NOCACHE);
+ void __iomem *pregs = map_physmem(AR71XX_PLL_BASE, AR71XX_PLL_SIZE,
+ MAP_NOCACHE);
+ void __iomem *rregs = map_physmem(AR71XX_RESET_BASE, AR71XX_RESET_SIZE,
+ MAP_NOCACHE);
+ const u32 mask = QCA956X_RESET_SGMII_ASSERT | QCA956X_RESET_SGMII;
+
+ writel(BIT(2) | BIT(0), pregs + QCA956X_PLL_ETH_SGMII_SERDES_REG);
+
+ reg = readl(gregs + QCA956X_GMAC_REG_SGMII_SERDES);
+ vco_fast = SGMII_SERDES_VCO_FAST_GET(reg);
+ vco_slow = SGMII_SERDES_VCO_SLOW_GET(reg);
+
+ /* Set resistor calibration from 0000 to 1111 */
+ for (i = 0; i < 0x10; i++) {
+ reg = (readl(gregs + QCA956X_GMAC_REG_SGMII_SERDES) &
+ ~SGMII_SERDES_RES_CALIBRATION_MASK) |
+ SGMII_SERDES_RES_CALIBRATION_SET(i);
+ writel(reg, gregs + QCA956X_GMAC_REG_SGMII_SERDES);
+
+ udelay(50);
+
+ reg = readl(gregs + QCA956X_GMAC_REG_SGMII_SERDES);
+ if (vco_fast != SGMII_SERDES_VCO_FAST_GET(reg) ||
+ vco_slow != SGMII_SERDES_VCO_SLOW_GET(reg)) {
+ if (start_val == 0) {
+ start_val = i;
+ end_val = i;
+ } else {
+ end_val = i;
+ }
+ }
+ vco_fast = SGMII_SERDES_VCO_FAST_GET(reg);
+ vco_slow = SGMII_SERDES_VCO_SLOW_GET(reg);
+ }
+
+ if (start_val == 0)
+ rev_sgmii_val = 0x7;
+ else
+ rev_sgmii_val = (start_val + end_val) >> 1;
+
+ writel((readl(gregs + QCA956X_GMAC_REG_SGMII_SERDES) &
+ ~SGMII_SERDES_RES_CALIBRATION_MASK) |
+ SGMII_SERDES_RES_CALIBRATION_SET(rev_sgmii_val),
+ gregs + QCA956X_GMAC_REG_SGMII_SERDES);
+
+ writel(BIT(2) | BIT(0), pregs + QCA956X_PLL_ETH_SGMII_SERDES_REG);
+
+ reg = readl(gregs + QCA956X_GMAC_REG_SGMII_SERDES);
+ writel(SGMII_SERDES_CDR_BW_SET(3) | SGMII_SERDES_TX_DR_CTRL_SET(1) |
+ SGMII_SERDES_PLL_BW_SET(1) | SGMII_SERDES_EN_SIGNAL_DETECT_SET(1) |
+ SGMII_SERDES_FIBER_SDO_SET(1) | SGMII_SERDES_VCO_REG_SET(3) | reg,
+ gregs + QCA956X_GMAC_REG_SGMII_SERDES);
+
+ setbits_be32(rregs + QCA956X_RESET_REG_RESET_MODULE, mask);
+ mdelay(1);
+ clrbits_be32(rregs + QCA956X_RESET_REG_RESET_MODULE, mask);
+ mdelay(1);
+
+ while (!(readl(gregs + QCA956X_GMAC_REG_SGMII_SERDES) & BIT(15)))
+ /* NOP */;
+
+ return 0;
+}
+
+static int qca956x_sgmii_setup(void)
+{
+ int i;
+ u32 s = 0, reg = 0;
+ u32 _regs[] = {
+ BIT(4), /* HW_RX_125M_N */
+ BIT(2), /* RX_125M_N */
+ BIT(3), /* TX_125M_N */
+ BIT(0), /* RX_CLK_N */
+ BIT(1), /* TX_CLK_N */
+ };
+ void __iomem *gregs = map_physmem(AR71XX_MII_BASE, AR71XX_MII_SIZE,
+ MAP_NOCACHE);
+
+ /* Force sgmii mode */
+ writel(BIT(6) | BIT(15) | BIT(8), gregs + QCA956X_GMAC_REG_MR_AN_CTRL);
+ udelay(10);
+ writel(0x2 | BIT(5) | (0x2 << 6), gregs + QCA956X_GMAC_REG_SGMII_CONFIG);
+
+ /* SGMII reset sequence sugguest by qca systems team. */
+ writel(0, gregs + QCA956X_GMAC_REG_SGMII_RESET);
+ for (i = 0; i < ARRAY_SIZE(_regs); i++) {
+ reg |= _regs[i];
+ writel(reg, gregs + QCA956X_GMAC_REG_SGMII_RESET);
+ }
+
+ writel(readl(gregs + QCA956X_GMAC_REG_MR_AN_CTRL) & ~BIT(15),
+ gregs + QCA956X_GMAC_REG_MR_AN_CTRL);
+
+ /*
+ * WARNING: Across resets SGMII link status goes to weird state.
+ * if 0xb8070058 (SGMII_DEBUG Register) reads other than 0xf or 0x10
+ * for sure we are in bad state.
+ * Issue a PHY RESET in MR_AN_CONTROL_ADDRESS to keep going.
+ */
+ i = 0;
+ s = (readl(gregs + QCA956X_GMAC_REG_SGMII_DEBUG) & 0xff);
+ while (!(s == 0xf || s == 0x10)) {
+ writel(readl(gregs + QCA956X_GMAC_REG_MR_AN_CTRL) | BIT(15),
+ gregs + QCA956X_GMAC_REG_MR_AN_CTRL);
+ udelay(100);
+ writel(readl(gregs + QCA956X_GMAC_REG_MR_AN_CTRL) & ~BIT(15),
+ gregs + QCA956X_GMAC_REG_MR_AN_CTRL);
+ if (i++ == 10)
+ break;
+ s = (readl(gregs + QCA956X_GMAC_REG_SGMII_DEBUG) & 0xff);
+ }
+
+ return 0;
+}
+
+static int qca956x_s17_reset(void)
+{
+ void __iomem *regs = map_physmem(AR71XX_GPIO_BASE, AR71XX_GPIO_SIZE,
+ MAP_NOCACHE);
+ void __iomem *rregs = map_physmem(AR71XX_RESET_BASE, AR71XX_RESET_SIZE,
+ MAP_NOCACHE);
+ const u32 mask = QCA956X_RESET_SGMII_ASSERT | QCA956X_RESET_SGMII |
+ QCA956X_RESET_EXTERNAL | QCA956X_RESET_SGMII_ANALOG |
+ QCA956X_RESET_SWITCH;
+ /* Bits(Reserved in datasheet) should be set to 1 */
+ const u32 mask_r = QCA956X_RESET_SGMII_ASSERT | QCA956X_RESET_SGMII |
+ QCA956X_RESET_EXTERNAL;
+
+ setbits_be32(rregs + QCA956X_RESET_REG_RESET_MODULE, mask);
+ mdelay(1);
+ clrbits_be32(rregs + QCA956X_RESET_REG_RESET_MODULE, mask_r);
+ mdelay(1);
+
+ /* Reset s17 switch(GPIO11) SYS_RST_L */
+ writel(readl(regs + AR71XX_GPIO_REG_OE) & ~BIT(11),
+ regs + AR71XX_GPIO_REG_OE);
+ udelay(100);
+
+ writel(readl(regs + AR71XX_GPIO_REG_OUT) & ~BIT(11),
+ regs + AR71XX_GPIO_REG_OUT);
+ udelay(100);
+ writel(readl(regs + AR71XX_GPIO_REG_OUT) | BIT(11),
+ regs + AR71XX_GPIO_REG_OUT);
+
+ return 0;
+}
+
+static int qca956x_init_mdio(void)
+{
+ u32 reg;
+ void __iomem *regs = map_physmem(AR71XX_GPIO_BASE, AR71XX_GPIO_SIZE,
+ MAP_NOCACHE);
+ void __iomem *rregs = map_physmem(AR71XX_RESET_BASE, AR71XX_RESET_SIZE,
+ MAP_NOCACHE);
+ const u32 mask = QCA956X_RESET_GE0_MDIO | QCA956X_RESET_GE0_MAC |
+ QCA956X_RESET_GE1_MDIO | QCA956X_RESET_GE1_MAC;
+
+ setbits_be32(rregs + QCA956X_RESET_REG_RESET_MODULE, mask);
+ mdelay(1);
+ clrbits_be32(rregs + QCA956X_RESET_REG_RESET_MODULE, mask);
+ mdelay(1);
+
+ /* GPIO4 as MDI */
+ reg = readl(regs + QCA956X_GPIO_REG_IN_ENABLE3);
+ reg &= ~(0xff << 16);
+ reg |= (0x4 << 16);
+ writel(reg, regs + QCA956X_GPIO_REG_IN_ENABLE3);
+
+ /* GPIO4 as MDO */
+ reg = readl(regs + QCA956X_GPIO_REG_OUT_FUNC1);
+ reg &= ~0xff;
+ reg |= 0x20;
+ writel(reg, regs + QCA956X_GPIO_REG_OUT_FUNC1);
+
+ /* Init MDC(GPIO3) / MDIO(GPIO4) */
+ reg = readl(regs + AR71XX_GPIO_REG_OE);
+ reg &= ~BIT(4);
+ writel(reg, regs + AR71XX_GPIO_REG_OE);
+ udelay(100);
+
+ reg = readl(regs + AR71XX_GPIO_REG_OE);
+ reg &= ~BIT(3);
+ writel(reg, regs + AR71XX_GPIO_REG_OE);
+ udelay(100);
+
+ /* GPIO3 as MDI */
+ reg = readl(regs + QCA956X_GPIO_REG_OUT_FUNC0);
+ reg &= ~(0xff << 24);
+ reg |= (0x21 << 24);
+ writel(reg, regs + QCA956X_GPIO_REG_OUT_FUNC0);
+
+ return 0;
+}
+
+static int eth_init_qca956x(void)
+{
+ void __iomem *pregs = map_physmem(AR71XX_PLL_BASE, AR71XX_PLL_SIZE,
+ MAP_NOCACHE);
+ void __iomem *gregs = map_physmem(AR71XX_MII_BASE, AR71XX_MII_SIZE,
+ MAP_NOCACHE);
+
+ qca956x_sgmii_cal();
+ qca956x_s17_reset();
+ qca956x_init_mdio();
+
+ if (ath79_get_bootstrap() & QCA956X_BOOTSTRAP_REF_CLK_40)
+ writel(0x45500, pregs + QCA956X_PLL_SWITCH_CLK_CTRL_REG);
+ else
+ writel(0xc5200, pregs + QCA956X_PLL_SWITCH_CLK_CTRL_REG);
+
+ qca956x_sgmii_setup();
+
+ writel((3 << 16) | (3 << 14) | (1 << 0) | (1 << 6),
+ gregs + QCA956X_GMAC_REG_ETH_CFG);
+
+ writel((1 << 31) | (2 << 28) | (2 << 26) | (1 << 25),
+ pregs + QCA956X_PLL_ETH_XMII_CTRL_REG);
+ mdelay(1);
+
+ return 0;
+}
+
int ath79_eth_reset(void)
{
/*
@@ -164,6 +433,8 @@ int ath79_eth_reset(void)
return eth_init_ar934x();
if (soc_is_qca953x())
return eth_init_qca953x();
+ if (soc_is_qca956x())
+ return eth_init_qca956x();
return -EINVAL;
}
diff --git a/board/qca/ap152/Kconfig b/board/qca/ap152/Kconfig
new file mode 100644
index 0000000000..a3d82780fe
--- /dev/null
+++ b/board/qca/ap152/Kconfig
@@ -0,0 +1,27 @@
+if TARGET_AP152
+
+config SYS_VENDOR
+ default "qca"
+
+config SYS_BOARD
+ default "ap152"
+
+config SYS_CONFIG_NAME
+ default "ap152"
+
+config SYS_TEXT_BASE
+ default 0x9f000000
+
+config SYS_DCACHE_SIZE
+ default 32768
+
+config SYS_DCACHE_LINE_SIZE
+ default 32
+
+config SYS_ICACHE_SIZE
+ default 65536
+
+config SYS_ICACHE_LINE_SIZE
+ default 32
+
+endif
diff --git a/board/qca/ap152/MAINTAINERS b/board/qca/ap152/MAINTAINERS
new file mode 100644
index 0000000000..785ec2766d
--- /dev/null
+++ b/board/qca/ap152/MAINTAINERS
@@ -0,0 +1,6 @@
+AP152 BOARD
+M: Rosy Song <rosysong(a)rosinson.com>
+S: Maintained
+F: board/qca/ap152/
+F: include/configs/ap152.h
+F: configs/ap152_defconfig
diff --git a/board/qca/ap152/Makefile b/board/qca/ap152/Makefile
new file mode 100644
index 0000000000..4270afa129
--- /dev/null
+++ b/board/qca/ap152/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0+
+
+obj-y = ap152.o
diff --git a/board/qca/ap152/ap152.c b/board/qca/ap152/ap152.c
new file mode 100644
index 0000000000..30cd56563b
--- /dev/null
+++ b/board/qca/ap152/ap152.c
@@ -0,0 +1,81 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Rosy Song <rosysong(a)rosinson.com>
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/addrspace.h>
+#include <asm/types.h>
+#include <mach/ar71xx_regs.h>
+#include <mach/ddr.h>
+#include <mach/ath79.h>
+#include <debug_uart.h>
+
+#define RST_RESET_RTC_RESET_LSB 27
+#define RST_RESET_RTC_RESET_MASK 0x08000000
+#define RST_RESET_RTC_RESET_SET(x) \
+ (((x) << RST_RESET_RTC_RESET_LSB) & RST_RESET_RTC_RESET_MASK)
+
+#ifdef CONFIG_DEBUG_UART_BOARD_INIT
+void board_debug_uart_init(void)
+{
+ void __iomem *regs;
+ u32 val;
+
+ regs = map_physmem(AR71XX_GPIO_BASE, AR71XX_GPIO_SIZE,
+ MAP_NOCACHE);
+
+ /* UART : RX18, TX22 done
+ * GPIO18 as input, GPIO22 as output
+ */
+ val = readl(regs + AR71XX_GPIO_REG_OE);
+ val |= QCA956X_GPIO(18);
+ val &= ~QCA956X_GPIO(22);
+ writel(val, regs + AR71XX_GPIO_REG_OE);
+
+ /*
+ * Enable GPIO22 as UART0_SOUT
+ */
+ val = readl(regs + QCA956X_GPIO_REG_OUT_FUNC5);
+ val &= ~QCA956X_GPIO_MUX_MASK(16);
+ val |= QCA956X_GPIO_OUT_MUX_UART0_SOUT << 16;
+ writel(val, regs + QCA956X_GPIO_REG_OUT_FUNC5);
+
+ /*
+ * Enable GPIO18 as UART0_SIN
+ */
+ val = readl(regs + QCA956X_GPIO_REG_IN_ENABLE0);
+ val &= ~QCA956X_GPIO_MUX_MASK(8);
+ val |= QCA956X_GPIO_IN_MUX_UART0_SIN << 8;
+ writel(val, regs + QCA956X_GPIO_REG_IN_ENABLE0);
+
+ /*
+ * Enable GPIO22 output
+ */
+ val = readl(regs + AR71XX_GPIO_REG_OUT);
+ val |= QCA956X_GPIO(22);
+ writel(val, regs + AR71XX_GPIO_REG_OUT);
+}
+#endif
+
+int board_early_init_f(void)
+{
+ u32 reg;
+ void __iomem *rst_regs = map_physmem(AR71XX_RESET_BASE,
+ AR71XX_RESET_SIZE, MAP_NOCACHE);
+
+#ifndef CONFIG_SKIP_LOWLEVEL_INIT
+ /* CPU:775, DDR:650, AHB:258 */
+ qca956x_pll_init();
+ qca956x_ddr_init();
+#endif
+
+ /* Take WMAC out of reset */
+ reg = readl(rst_regs + QCA956X_RESET_REG_RESET_MODULE);
+ reg &= (~RST_RESET_RTC_RESET_SET(1));
+ writel(reg, rst_regs + QCA956X_RESET_REG_RESET_MODULE);
+
+ ath79_eth_reset();
+ return 0;
+}
diff --git a/configs/ap152_defconfig b/configs/ap152_defconfig
new file mode 100644
index 0000000000..383c48b03d
--- /dev/null
+++ b/configs/ap152_defconfig
@@ -0,0 +1,55 @@
+CONFIG_MIPS=y
+CONFIG_SYS_TEXT_BASE=0x9F000000
+CONFIG_SYS_MALLOC_F_LEN=0x800
+CONFIG_DEBUG_UART_BOARD_INIT=y
+CONFIG_DEBUG_UART_BASE=0xb8020000
+CONFIG_DEBUG_UART_CLOCK=25000000
+CONFIG_ARCH_ATH79=y
+CONFIG_TARGET_AP152=y
+CONFIG_DEBUG_UART=y
+CONFIG_BOOTDELAY=3
+CONFIG_USE_BOOTARGS=y
+CONFIG_BOOTARGS="console=ttyS0,115200 root=/dev/mtdblock2 rootfstype=squashfs"
+CONFIG_DISPLAY_CPUINFO=y
+CONFIG_BOARD_EARLY_INIT_F=y
+CONFIG_SYS_PROMPT="ap152 # "
+# CONFIG_CMD_BDI is not set
+# CONFIG_CMD_CONSOLE is not set
+# CONFIG_CMD_ELF is not set
+# CONFIG_CMD_XIMG is not set
+# CONFIG_CMD_EXPORTENV is not set
+# CONFIG_CMD_IMPORTENV is not set
+# CONFIG_CMD_EDITENV is not set
+# CONFIG_CMD_CRC32 is not set
+CONFIG_CMD_MEMTEST=y
+# CONFIG_CMD_FLASH is not set
+CONFIG_CMD_SF=y
+CONFIG_CMD_SPI=y
+CONFIG_CMD_MTDPARTS=y
+CONFIG_MTDIDS_DEFAULT="nor0=spi-flash.0"
+CONFIG_MTDPARTS_DEFAULT="mtdparts=spi-flash.0:256k(u-boot),64k(u-boot-env),6336k(rootfs),1472k(uImage),64k(ART)"
+# CONFIG_ISO_PARTITION is not set
+CONFIG_DEFAULT_DEVICE_TREE="ap152"
+CONFIG_ENV_IS_IN_SPI_FLASH=y
+# CONFIG_NET is not set
+CONFIG_DM_SPI_FLASH=y
+CONFIG_SPI_FLASH=y
+CONFIG_SPI_FLASH_BAR=y
+CONFIG_SPI_FLASH_ATMEL=y
+CONFIG_SPI_FLASH_EON=y
+CONFIG_SPI_FLASH_GIGADEVICE=y
+CONFIG_SPI_FLASH_MACRONIX=y
+CONFIG_SPI_FLASH_SPANSION=y
+CONFIG_SPI_FLASH_STMICRO=y
+CONFIG_SPI_FLASH_SST=y
+CONFIG_SPI_FLASH_WINBOND=y
+CONFIG_SPI_FLASH_DATAFLASH=y
+CONFIG_SPI_FLASH_MTD=y
+CONFIG_PINCTRL=y
+CONFIG_DM_SERIAL=y
+CONFIG_DEBUG_UART_SHIFT=2
+CONFIG_SYS_NS16550=y
+CONFIG_SPI=y
+CONFIG_DM_SPI=y
+CONFIG_ATH79_SPI=y
+CONFIG_LZMA=y
diff --git a/include/configs/ap152.h b/include/configs/ap152.h
new file mode 100644
index 0000000000..bc88506dff
--- /dev/null
+++ b/include/configs/ap152.h
@@ -0,0 +1,54 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2018 Rosy Song <rosysong(a)rosinson.com>
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#define CONFIG_SYS_HZ 1000
+#define CONFIG_SYS_MHZ 375
+#define CONFIG_SYS_MIPS_TIMER_FREQ (CONFIG_SYS_MHZ * 1000000)
+
+#define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE
+
+#define CONFIG_SYS_MALLOC_LEN 0x40000
+#define CONFIG_SYS_BOOTPARAMS_LEN 0x20000
+
+#define CONFIG_SYS_SDRAM_BASE 0x80000000
+#define CONFIG_SYS_LOAD_ADDR 0x81000000
+
+#define CONFIG_SYS_INIT_RAM_ADDR 0xbd000000
+#define CONFIG_SYS_INIT_RAM_SIZE 0x2000
+#define CONFIG_SYS_INIT_SP_ADDR \
+ (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_RAM_SIZE - 1)
+
+/*
+ * Serial Port
+ */
+#define CONFIG_SYS_NS16550_CLK 25000000
+#define CONFIG_SYS_BAUDRATE_TABLE \
+ {9600, 19200, 38400, 57600, 115200}
+
+#define CONFIG_BOOTCOMMAND "sf probe;" \
+ "mtdparts default;" \
+ "bootm 0x9f060000"
+
+#define CONFIG_EXTRA_ENV_SETTINGS \
+ "ipaddr=192.168.1.1\0" \
+ "serverip=192.168.1.10\0" \
+
+#define CONFIG_ENV_SPI_MAX_HZ 25000000
+#define CONFIG_ENV_OFFSET 0x40000
+#define CONFIG_ENV_SECT_SIZE 0x10000
+#define CONFIG_ENV_SIZE 0x10000
+
+/* Miscellaneous configurable options */
+
+/*
+ * Diagnostics
+ */
+#define CONFIG_SYS_MEMTEST_START 0x80100000
+#define CONFIG_SYS_MEMTEST_END 0x83f00000
+
+#endif /* __CONFIG_H */
--
2.17.0
2
1
I am working on an application needing the ability to update to a verified image from the running kernel/application.
We can follow the "normal" verified image boot sequence, where the chain of trust is verified from U-Boot to image to execution, etc, but unsure how to verify a new image after already running.
Is there a way to extract the public key hash from the U-Boot image so that we can compute a hash on an upgrade image and verify a match? Either an existing tool, or some means that is accessibly from a Linux kernel that we could use to grab this information.
I've done a lot of googling, and I have not seen any means to get to this once the image is already booted and running.
Thank you for any guidance you can provide for this.
Jeridiah Welti
2
1