AU_LINUX_QSDK_NHSS.QSDK.12.0.R6_TARGET_ALL.12.0.06.408.056

-----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1
 
 iEYEABECAAYFAmFdjpIACgkQoUgPZYCpAfHuowCg2absYOq7ngpmVptItgsF9ptc
 Xr8An1fsI6P4Inlkt8XmusFkOCD/673s
 =jIZD
 -----END PGP SIGNATURE-----

Merge AU_LINUX_QSDK_NHSS.QSDK.12.0.R6_TARGET_ALL.12.0.06.408.056 on remote branch

Change-Id: If8eec7fee7447d4fc30450d255848d6041f67bc3
Signed-off-by: Linux Build Service Account <lnxbuild@localhost>
This commit is contained in:
Linux Build Service Account 2021-10-06 10:20:56 -06:00
commit 2cf0f1cd99
55 changed files with 11733 additions and 18 deletions

View file

@ -581,10 +581,14 @@ else
ifdef CONFIG_ARCH_IPQ6018
KBUILD_CFLAGS += $(call cc-option,-fstack-protector)
else
ifdef CONFIG_ARCH_IPQ9574
KBUILD_CFLAGS += $(call cc-option,-fstack-protector)
else
KBUILD_CFLAGS += $(call cc-option, -fno-stack-protector)
endif
endif
endif
endif
KBUILD_CFLAGS += $(call cc-option,-fno-delete-null-pointer-checks)
KBUILD_CFLAGS += -g

View file

@ -469,6 +469,14 @@ config ARCH_IPQ6018
select SYS_GENERIC_BOARD
select QCA_COMMON
config ARCH_IPQ9574
bool "QCA, IPQ9574"
select DM
select DM_SERIAL
select CPU_V7
select SYS_GENERIC_BOARD
select QCA_COMMON
config ARCH_S5PC1XX
bool "Samsung S5PC1XX"
select CPU_V7
@ -860,6 +868,7 @@ source "board/ipq40xx/Kconfig"
source "board/ipq5018/Kconfig"
source "board/ipq6018/Kconfig"
source "board/ipq806x/Kconfig"
source "board/ipq9574/Kconfig"
source "board/ipq807x/Kconfig"
source "board/isee/igep0033/Kconfig"
source "board/maxbcm/Kconfig"

View file

@ -470,6 +470,28 @@ int qca_scm_fuseipq(u32 svc_id, u32 cmd_id, void *buf, size_t len)
return ret;
}
int qca_scm_part_info(void *cmd_buf,
size_t cmd_len)
{
int ret = 0;
if (is_scm_armv8())
{
struct qca_scm_desc desc = {0};
desc.arginfo = QCA_SCM_ARGS(1, SCM_VAL);
/* args[0] has the part info id */
desc.args[0] = * ((unsigned int *)cmd_buf);
ret = scm_call_64(SCM_SVC_BOOT, PART_INFO_CMD, &desc);
}
else
{
ret = scm_call(SCM_SVC_BOOT, PART_INFO_CMD, cmd_buf, cmd_len,
NULL, 0);
}
return ret;
}
int qca_scm_auth_kernel(void *cmd_buf,
size_t cmd_len)
{
@ -638,6 +660,10 @@ int qca_scm_fuseipq(u32 svc_id, u32 cmd_id, void *buf, size_t len)
{
return 0;
}
int qca_scm_part_info(void *cmd_buf, size_t cmd_len)
{
return 0;
}
int qca_scm_auth_kernel(void *cmd_buf,
size_t cmd_len)
{

View file

@ -48,7 +48,7 @@ save_boot_params_ret:
msr cpsr,r0
#if defined (CONFIG_ARCH_IPQ807x) || defined (CONFIG_ARCH_IPQ6018) \
|| defined (CONFIG_ARCH_IPQ5018)
|| defined (CONFIG_ARCH_IPQ5018) || defined (CONFIG_ARCH_IPQ9574)
/* Setup CP15 barrier */
mrc p15, 0, r0, c1, c0, 0 @Read SCTLR to r0
orr r0, r0, #0x20 @set the cp15 barrier enable bit

View file

@ -97,6 +97,16 @@ dtb-$(CONFIG_ARCH_IPQ6018) += ipq6018-cp01-c1.dtb \
ipq6018-db-cp01.dtb \
ipq6018-db-cp02.dtb
dtb-$(CONFIG_ARCH_IPQ9574) += ipq9574-al01-c1.dtb \
ipq9574-al02-c1.dtb \
ipq9574-al02-c2.dtb \
ipq9574-db-al01-c1.dtb \
ipq9574-db-al01-c2.dtb \
ipq9574-db-al01-c3.dtb \
ipq9574-db-al02-c1.dtb \
ipq9574-db-al02-c2.dtb \
ipq9574-db-al02-c3.dtb \
dtb-$(CONFIG_ARCH_ROCKCHIP) += \
rk3288-firefly.dtb \
rk3288-jerry.dtb \

View file

@ -0,0 +1,197 @@
/*
* Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
/dts-v1/;
#include "ipq9574-soc.dtsi"
/ {
machid = <0x8050000>;
config_name = "config@al01-c1";
aliases {
console = "/serial@78B1000";
uart2 = "/serial@78B2000";
usb0 = "/xhci@8a00000";
pci0 = "/pci@28000000";
pci1 = "/pci@10000000";
nand = "/nand-controller@79B0000";
i2c0 = "/i2c@78B8000";
};
console: serial@78B1000 {
status = "ok";
serial_gpio {
blsp1_uart2_rx {
gpio = <34>;
func = <1>;
pull = <GPIO_NO_PULL>;
drvstr = <GPIO_8MA>;
od_en = <GPIO_OD_DISABLE>;
};
blsp1_uart2_tx {
gpio = <35>;
func = <1>;
pull = <GPIO_NO_PULL>;
drvstr = <GPIO_8MA>;
od_en = <GPIO_OD_DISABLE>;
};
};
};
spi {
spi_gpio {
blsp0_spi_clk {
gpio = <11>;
func = <1>;
pull = <GPIO_NO_PULL>;
oe = <GPIO_OE_ENABLE>;
drvstr = <GPIO_8MA>;
};
blsp0_spi_mosi {
gpio = <14>;
func = <1>;
pull = <GPIO_NO_PULL>;
oe = <GPIO_OE_ENABLE>;
drvstr = <GPIO_8MA>;
};
blsp0_spi_miso {
gpio = <13>;
func = <1>;
pull = <GPIO_NO_PULL>;
drvstr = <GPIO_8MA>;
};
blsp0_spi_cs {
gpio = <12>;
func = <1>;
oe = <GPIO_OE_ENABLE>;
drvstr = <GPIO_8MA>;
};
};
};
nand: nand-controller@79B0000 {
status = "okay";
nand_gpio {
qspi_dat3 {
gpio = <0>;
func = <2>;
pull = <GPIO_NO_PULL>;
od_en = <GPIO_OD_DISABLE>;
drvstr = <GPIO_8MA>;
};
qspi_dat2 {
gpio = <1>;
func = <2>;
pull = <GPIO_NO_PULL>;
od_en = <GPIO_OD_DISABLE>;
drvstr = <GPIO_8MA>;
};
qspi_dat1 {
gpio = <2>;
func = <2>;
pull = <GPIO_NO_PULL>;
od_en = <GPIO_OD_DISABLE>;
drvstr = <GPIO_8MA>;
};
qspi_dat0 {
gpio = <3>;
func = <2>;
pull = <GPIO_NO_PULL>;
od_en = <GPIO_OD_DISABLE>;
drvstr = <GPIO_8MA>;
};
qspi_cs_n {
gpio = <4>;
func = <2>;
pull = <GPIO_NO_PULL>;
od_en = <GPIO_OD_DISABLE>;
drvstr = <GPIO_8MA>;
};
qspi_clk {
gpio = <5>;
func = <2>;
pull = <GPIO_NO_PULL>;
od_en = <GPIO_OD_DISABLE>;
drvstr = <GPIO_8MA>;
};
};
};
pci0: pci@28000000 {
status = "ok";
perst_gpio = <23>;
pci_gpio {
pci_rst {
gpio = <23>;
func = <0>;
pull = <GPIO_PULL_UP>;
oe = <GPIO_OD_ENABLE>;
od_en = <GPIO_OD_DISABLE>;
drvstr = <GPIO_8MA>;
};
};
};
pci1: pci@10000000 {
status = "ok";
perst_gpio = <26>;
pci_gpio {
pci_rst {
gpio = <26>;
func = <0>;
pull = <GPIO_PULL_DOWN>;
oe = <GPIO_OD_ENABLE>;
od_en = <GPIO_OD_DISABLE>;
drvstr = <GPIO_8MA>;
};
};
};
ess-switch {
switch_mac_mode0 = <PORT_WRAPPER_PSGMII>;
switch_mac_mode1 = <PORT_WRAPPER_MAX>; /* Unused */
switch_mac_mode2 = <PORT_WRAPPER_USXGMII>;
qca807x_gpio = <60>;
qca807x_gpio_cnt = <1>;
aquantia_gpio = <36>;
aquantia_gpio_cnt = <1>;
aquantia_port = <5>;
aquantia_port_cnt = <1>;
mdc_mdio_gpio = <38 39>;
port_phyinfo {
port@0 {
phy_address = <16>;
phy_type = <QCA807x_PHY_TYPE>;
};
port@1 {
phy_address = <17>;
phy_type = <QCA807x_PHY_TYPE>;
};
port@2 {
phy_address = <18>;
phy_type = <QCA807x_PHY_TYPE>;
};
port@3 {
phy_address = <19>;
phy_type = <QCA807x_PHY_TYPE>;
};
port@4 {
phy_address = <20>;
phy_type = <QCA807x_PHY_TYPE>;
};
port@5 {
phy_address = <0>;
phy_type = <AQ_PHY_TYPE>;
};
};
};
};

View file

@ -0,0 +1,197 @@
/*
* Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
/dts-v1/;
#include "ipq9574-soc.dtsi"
/ {
machid = <0x8050001>;
config_name = "config@al02-c1";
aliases {
console = "/serial@78B1000";
uart2 = "/serial@78B2000";
usb0 = "/xhci@8a00000";
pci2 = "/pci@20000000";
pci3 = "/pci@18000000";
nand = "/nand-controller@79B0000";
i2c0 = "/i2c@78B8000";
};
console: serial@78B1000 {
status = "ok";
serial_gpio {
blsp1_uart2_rx {
gpio = <34>;
func = <1>;
pull = <GPIO_NO_PULL>;
drvstr = <GPIO_8MA>;
od_en = <GPIO_OD_DISABLE>;
};
blsp1_uart2_tx {
gpio = <35>;
func = <1>;
pull = <GPIO_NO_PULL>;
drvstr = <GPIO_8MA>;
od_en = <GPIO_OD_DISABLE>;
};
};
};
spi {
spi_gpio {
blsp0_spi_clk {
gpio = <11>;
func = <1>;
pull = <GPIO_NO_PULL>;
oe = <GPIO_OE_ENABLE>;
drvstr = <GPIO_8MA>;
};
blsp0_spi_mosi {
gpio = <14>;
func = <1>;
pull = <GPIO_NO_PULL>;
oe = <GPIO_OE_ENABLE>;
drvstr = <GPIO_8MA>;
};
blsp0_spi_miso {
gpio = <13>;
func = <1>;
pull = <GPIO_NO_PULL>;
drvstr = <GPIO_8MA>;
};
blsp0_spi_cs {
gpio = <12>;
func = <1>;
oe = <GPIO_OE_ENABLE>;
drvstr = <GPIO_8MA>;
};
};
};
nand: nand-controller@79B0000 {
status = "okay";
nand_gpio {
qspi_dat3 {
gpio = <0>;
func = <2>;
pull = <GPIO_NO_PULL>;
od_en = <GPIO_OD_DISABLE>;
drvstr = <GPIO_8MA>;
};
qspi_dat2 {
gpio = <1>;
func = <2>;
pull = <GPIO_NO_PULL>;
od_en = <GPIO_OD_DISABLE>;
drvstr = <GPIO_8MA>;
};
qspi_dat1 {
gpio = <2>;
func = <2>;
pull = <GPIO_NO_PULL>;
od_en = <GPIO_OD_DISABLE>;
drvstr = <GPIO_8MA>;
};
qspi_dat0 {
gpio = <3>;
func = <2>;
pull = <GPIO_NO_PULL>;
od_en = <GPIO_OD_DISABLE>;
drvstr = <GPIO_8MA>;
};
qspi_cs_n {
gpio = <4>;
func = <2>;
pull = <GPIO_NO_PULL>;
od_en = <GPIO_OD_DISABLE>;
drvstr = <GPIO_8MA>;
};
qspi_clk {
gpio = <5>;
func = <2>;
pull = <GPIO_NO_PULL>;
od_en = <GPIO_OD_DISABLE>;
drvstr = <GPIO_8MA>;
};
};
};
pci2: pci@20000000 {
status = "ok";
perst_gpio = <29>;
pci_gpio {
pci_rst {
gpio = <29>;
func = <0>;
pull = <GPIO_PULL_DOWN>;
oe = <GPIO_OD_ENABLE>;
od_en = <GPIO_OD_DISABLE>;
drvstr = <GPIO_8MA>;
};
};
};
pci3: pci@18000000 {
status = "ok";
perst_gpio = <32>;
pci_gpio {
pci_rst {
gpio = <32>;
func = <0>;
pull = <GPIO_PULL_UP>;
oe = <GPIO_OD_ENABLE>;
od_en = <GPIO_OD_DISABLE>;
drvstr = <GPIO_8MA>;
};
};
};
ess-switch {
switch_mac_mode0 = <PORT_WRAPPER_PSGMII>;
switch_mac_mode1 = <PORT_WRAPPER_USXGMII>;
switch_mac_mode2 = <PORT_WRAPPER_USXGMII>;
qca807x_gpio = <60>;
qca807x_gpio_cnt = <1>;
aquantia_gpio = <36>;
aquantia_gpio_cnt = <1>;
aquantia_port = <4 5>;
aquantia_port_cnt = <2>;
mdc_mdio_gpio = <38 39>;
port_phyinfo {
port@0 {
phy_address = <16>;
phy_type = <QCA807x_PHY_TYPE>;
};
port@1 {
phy_address = <17>;
phy_type = <QCA807x_PHY_TYPE>;
};
port@2 {
phy_address = <18>;
phy_type = <QCA807x_PHY_TYPE>;
};
port@3 {
phy_address = <19>;
phy_type = <QCA807x_PHY_TYPE>;
};
port@4 {
phy_address = <8>;
phy_type = <AQ_PHY_TYPE>;
};
port@5 {
phy_address = <0>;
phy_type = <AQ_PHY_TYPE>;
};
};
};
};

View file

@ -0,0 +1,111 @@
/*
* Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
/dts-v1/;
#include "ipq9574-al02-c1.dts"
/ {
machid = <0x8050101>;
config_name = "config@al02-c2";
aliases {
mmc = "/sdhci@7804000";
};
mmc: sdhci@7804000 {
compatible = "qcom,sdhci-msm";
status = "okay";
mmc_gpio {
emmc_dat7 {
gpio = <0>;
func = <1>;
pull = <GPIO_PULL_UP>;
od_en = <GPIO_OD_DISABLE>;
drvstr = <GPIO_8MA>;
};
emmc_dat6 {
gpio = <1>;
func = <1>;
pull = <GPIO_PULL_UP>;
od_en = <GPIO_OD_DISABLE>;
drvstr = <GPIO_8MA>;
};
emmc_dat5 {
gpio = <2>;
func = <1>;
pull = <GPIO_PULL_UP>;
od_en = <GPIO_OD_DISABLE>;
drvstr = <GPIO_8MA>;
};
emmc_dat4 {
gpio = <3>;
func = <1>;
pull = <GPIO_PULL_UP>;
od_en = <GPIO_OD_DISABLE>;
drvstr = <GPIO_8MA>;
};
emmc_dat3 {
gpio = <6>;
func = <1>;
pull = <GPIO_PULL_UP>;
od_en = <GPIO_OD_DISABLE>;
drvstr = <GPIO_8MA>;
};
emmc_dat2 {
gpio = <7>;
func = <1>;
pull = <GPIO_PULL_UP>;
od_en = <GPIO_OD_DISABLE>;
drvstr = <GPIO_8MA>;
};
emmc_dat1 {
gpio = <8>;
func = <1>;
pull = <GPIO_PULL_UP>;
od_en = <GPIO_OD_DISABLE>;
drvstr = <GPIO_8MA>;
};
emmc_dat0 {
gpio = <9>;
func = <1>;
pull = <GPIO_PULL_UP>;
od_en = <GPIO_OD_DISABLE>;
drvstr = <GPIO_8MA>;
};
emmc_cmd{
gpio = <4>;
func = <1>;
pull = <GPIO_PULL_UP>;
od_en = <GPIO_OD_DISABLE>;
drvstr = <GPIO_8MA>;
};
emmc_clk{
gpio = <5>;
func = <1>;
pull = <GPIO_NO_PULL>;
od_en = <GPIO_OD_DISABLE>;
drvstr = <GPIO_8MA>;
};
emmc_rclk{
gpio = <10>;
func = <1>;
pull = <GPIO_PULL_DOWN>;
od_en = <GPIO_OD_DISABLE>;
drvstr = <GPIO_8MA>;
};
};
};
nand: nand-controller@79B0000 {
status = "disabled";
};
};

View file

@ -0,0 +1,231 @@
/*
* Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
/dts-v1/;
#include "ipq9574-soc.dtsi"
/ {
machid = <0x1050000>;
config_name = "config@db-al01-c1";
aliases {
console = "/serial@78B1000";
uart2 = "/serial@78B2000";
usb0 = "/xhci@8a00000";
pci0 = "/pci@28000000";
pci1 = "/pci@10000000";
pci2 = "/pci@20000000";
pci3 = "/pci@18000000";
nand = "/nand-controller@79B0000";
i2c0 = "/i2c@78B8000";
};
console: serial@78B1000 {
status = "ok";
serial_gpio {
blsp1_uart2_rx {
gpio = <34>;
func = <1>;
pull = <GPIO_NO_PULL>;
drvstr = <GPIO_8MA>;
od_en = <GPIO_OD_DISABLE>;
};
blsp1_uart2_tx {
gpio = <35>;
func = <1>;
pull = <GPIO_NO_PULL>;
drvstr = <GPIO_8MA>;
od_en = <GPIO_OD_DISABLE>;
};
};
};
spi {
spi_gpio {
blsp0_spi_clk {
gpio = <11>;
func = <1>;
pull = <GPIO_NO_PULL>;
oe = <GPIO_OE_ENABLE>;
drvstr = <GPIO_8MA>;
};
blsp0_spi_mosi {
gpio = <14>;
func = <1>;
pull = <GPIO_NO_PULL>;
oe = <GPIO_OE_ENABLE>;
drvstr = <GPIO_8MA>;
};
blsp0_spi_miso {
gpio = <13>;
func = <1>;
pull = <GPIO_NO_PULL>;
drvstr = <GPIO_8MA>;
};
blsp0_spi_cs {
gpio = <12>;
func = <1>;
oe = <GPIO_OE_ENABLE>;
drvstr = <GPIO_8MA>;
};
};
};
nand: nand-controller@79B0000 {
status = "okay";
nand_gpio {
qspi_dat3 {
gpio = <0>;
func = <2>;
pull = <GPIO_NO_PULL>;
od_en = <GPIO_OD_DISABLE>;
drvstr = <GPIO_8MA>;
};
qspi_dat2 {
gpio = <1>;
func = <2>;
pull = <GPIO_NO_PULL>;
od_en = <GPIO_OD_DISABLE>;
drvstr = <GPIO_8MA>;
};
qspi_dat1 {
gpio = <2>;
func = <2>;
pull = <GPIO_NO_PULL>;
od_en = <GPIO_OD_DISABLE>;
drvstr = <GPIO_8MA>;
};
qspi_dat0 {
gpio = <3>;
func = <2>;
pull = <GPIO_NO_PULL>;
od_en = <GPIO_OD_DISABLE>;
drvstr = <GPIO_8MA>;
};
qspi_cs_n {
gpio = <4>;
func = <2>;
pull = <GPIO_NO_PULL>;
od_en = <GPIO_OD_DISABLE>;
drvstr = <GPIO_8MA>;
};
qspi_clk {
gpio = <5>;
func = <2>;
pull = <GPIO_NO_PULL>;
od_en = <GPIO_OD_DISABLE>;
drvstr = <GPIO_8MA>;
};
};
};
pci0: pci@28000000 {
status = "ok";
perst_gpio = <23>;
pci_gpio {
pci_rst {
gpio = <23>;
func = <0>;
pull = <GPIO_PULL_UP>;
oe = <GPIO_OD_ENABLE>;
od_en = <GPIO_OD_DISABLE>;
drvstr = <GPIO_8MA>;
};
};
};
pci1: pci@10000000 {
status = "ok";
perst_gpio = <26>;
pci_gpio {
pci_rst {
gpio = <26>;
func = <0>;
pull = <GPIO_PULL_DOWN>;
oe = <GPIO_OD_ENABLE>;
od_en = <GPIO_OD_DISABLE>;
drvstr = <GPIO_8MA>;
};
};
};
pci2: pci@20000000 {
status = "ok";
perst_gpio = <29>;
pci_gpio {
pci_rst {
gpio = <29>;
func = <0>;
pull = <GPIO_PULL_DOWN>;
oe = <GPIO_OD_ENABLE>;
od_en = <GPIO_OD_DISABLE>;
drvstr = <GPIO_8MA>;
};
};
};
pci3: pci@18000000 {
status = "ok";
perst_gpio = <32>;
pci_gpio {
pci_rst {
gpio = <32>;
func = <0>;
pull = <GPIO_PULL_UP>;
oe = <GPIO_OD_ENABLE>;
od_en = <GPIO_OD_DISABLE>;
drvstr = <GPIO_8MA>;
};
};
};
ess-switch {
switch_mac_mode0 = <PORT_WRAPPER_PSGMII>;
switch_mac_mode1 = <PORT_WRAPPER_USXGMII>;
switch_mac_mode2 = <PORT_WRAPPER_SGMII_PLUS>;
qca807x_gpio = <60>;
qca807x_gpio_cnt = <1>;
aquantia_gpio = <36>;
aquantia_gpio_cnt = <1>;
aquantia_port = <4>;
aquantia_port_cnt = <1>;
qca808x_gpio = <57>;
qca808x_gpio_cnt = <1>;
mdc_mdio_gpio = <38 39>;
port_phyinfo {
port@0 {
phy_address = <16>;
phy_type = <QCA807x_PHY_TYPE>;
};
port@1 {
phy_address = <17>;
phy_type = <QCA807x_PHY_TYPE>;
};
port@2 {
phy_address = <18>;
phy_type = <QCA807x_PHY_TYPE>;
};
port@3 {
phy_address = <19>;
phy_type = <QCA807x_PHY_TYPE>;
};
port@4 {
phy_address = <8>;
phy_type = <AQ_PHY_TYPE>;
};
port@5 {
phy_address = <28>;
phy_type = <QCA808x_PHY_TYPE>;
};
};
};
};

View file

@ -0,0 +1,111 @@
/*
* Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
/dts-v1/;
#include "ipq9574-db-al01-c1.dts"
/ {
machid = <0x1050100>;
config_name = "config@db-al01-c2";
aliases {
mmc = "/sdhci@7804000";
};
mmc: sdhci@7804000 {
compatible = "qcom,sdhci-msm";
status = "okay";
mmc_gpio {
emmc_dat7 {
gpio = <0>;
func = <1>;
pull = <GPIO_PULL_UP>;
od_en = <GPIO_OD_DISABLE>;
drvstr = <GPIO_8MA>;
};
emmc_dat6 {
gpio = <1>;
func = <1>;
pull = <GPIO_PULL_UP>;
od_en = <GPIO_OD_DISABLE>;
drvstr = <GPIO_8MA>;
};
emmc_dat5 {
gpio = <2>;
func = <1>;
pull = <GPIO_PULL_UP>;
od_en = <GPIO_OD_DISABLE>;
drvstr = <GPIO_8MA>;
};
emmc_dat4 {
gpio = <3>;
func = <1>;
pull = <GPIO_PULL_UP>;
od_en = <GPIO_OD_DISABLE>;
drvstr = <GPIO_8MA>;
};
emmc_dat3 {
gpio = <6>;
func = <1>;
pull = <GPIO_PULL_UP>;
od_en = <GPIO_OD_DISABLE>;
drvstr = <GPIO_8MA>;
};
emmc_dat2 {
gpio = <7>;
func = <1>;
pull = <GPIO_PULL_UP>;
od_en = <GPIO_OD_DISABLE>;
drvstr = <GPIO_8MA>;
};
emmc_dat1 {
gpio = <8>;
func = <1>;
pull = <GPIO_PULL_UP>;
od_en = <GPIO_OD_DISABLE>;
drvstr = <GPIO_8MA>;
};
emmc_dat0 {
gpio = <9>;
func = <1>;
pull = <GPIO_PULL_UP>;
od_en = <GPIO_OD_DISABLE>;
drvstr = <GPIO_8MA>;
};
emmc_cmd{
gpio = <4>;
func = <1>;
pull = <GPIO_PULL_UP>;
od_en = <GPIO_OD_DISABLE>;
drvstr = <GPIO_8MA>;
};
emmc_clk{
gpio = <5>;
func = <1>;
pull = <GPIO_NO_PULL>;
od_en = <GPIO_OD_DISABLE>;
drvstr = <GPIO_8MA>;
};
emmc_rclk{
gpio = <10>;
func = <1>;
pull = <GPIO_PULL_DOWN>;
od_en = <GPIO_OD_DISABLE>;
drvstr = <GPIO_8MA>;
};
};
};
nand: nand-controller@79B0000 {
status = "disabled";
};
};

View file

@ -0,0 +1,36 @@
/*
* Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
/dts-v1/;
#include "ipq9574-db-al01-c1.dts"
/ {
machid = <0x1050200>;
config_name = "config@db-al01-c3";
ess-switch {
/* Overriding port6 configuration to support AQ instead
* of QCA808x
*/
/delete-property/qca808x_gpio;
/delete-property/qca808x_gpio_cnt;
switch_mac_mode2 = <PORT_WRAPPER_USXGMII>;
aquantia_port = <4 5>;
aquantia_port_cnt = <2>;
port_phyinfo {
port@5 {
phy_address = <0>;
phy_type = <AQ_PHY_TYPE>;
};
};
};
};

View file

@ -0,0 +1,231 @@
/*
* Copyright (c) 2016-2019, 2021, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
/dts-v1/;
#include "ipq9574-soc.dtsi"
/ {
machid = <0x1050001>;
config_name = "config@db-al02-c1";
aliases {
console = "/serial@78B1000";
uart2 = "/serial@78B2000";
pci0 = "/pci@28000000";
pci1 = "/pci@10000000";
pci2 = "/pci@20000000";
pci3 = "/pci@18000000";
usb0 = "/xhci@8a00000";
nand = "/nand-controller@79B0000";
i2c0 = "/i2c@78B8000";
};
console: serial@78B1000 {
status = "ok";
serial_gpio {
blsp1_uart2_rx {
gpio = <34>;
func = <1>;
pull = <GPIO_NO_PULL>;
drvstr = <GPIO_8MA>;
od_en = <GPIO_OD_DISABLE>;
};
blsp1_uart2_tx {
gpio = <35>;
func = <1>;
pull = <GPIO_NO_PULL>;
drvstr = <GPIO_8MA>;
od_en = <GPIO_OD_DISABLE>;
};
};
};
spi {
spi_gpio {
blsp0_spi_clk {
gpio = <11>;
func = <1>;
pull = <GPIO_NO_PULL>;
oe = <GPIO_OE_ENABLE>;
drvstr = <GPIO_8MA>;
};
blsp0_spi_mosi {
gpio = <14>;
func = <1>;
pull = <GPIO_NO_PULL>;
oe = <GPIO_OE_ENABLE>;
drvstr = <GPIO_8MA>;
};
blsp0_spi_miso {
gpio = <13>;
func = <1>;
pull = <GPIO_NO_PULL>;
drvstr = <GPIO_8MA>;
};
blsp0_spi_cs {
gpio = <12>;
func = <1>;
oe = <GPIO_OE_ENABLE>;
drvstr = <GPIO_8MA>;
};
};
};
nand: nand-controller@79B0000 {
status = "okay";
nand_gpio {
qspi_dat3 {
gpio = <0>;
func = <2>;
pull = <GPIO_NO_PULL>;
od_en = <GPIO_OD_DISABLE>;
drvstr = <GPIO_8MA>;
};
qspi_dat2 {
gpio = <1>;
func = <2>;
pull = <GPIO_NO_PULL>;
od_en = <GPIO_OD_DISABLE>;
drvstr = <GPIO_8MA>;
};
qspi_dat1 {
gpio = <2>;
func = <2>;
pull = <GPIO_NO_PULL>;
od_en = <GPIO_OD_DISABLE>;
drvstr = <GPIO_8MA>;
};
qspi_dat0 {
gpio = <3>;
func = <2>;
pull = <GPIO_NO_PULL>;
od_en = <GPIO_OD_DISABLE>;
drvstr = <GPIO_8MA>;
};
qspi_cs_n {
gpio = <4>;
func = <2>;
pull = <GPIO_NO_PULL>;
od_en = <GPIO_OD_DISABLE>;
drvstr = <GPIO_8MA>;
};
qspi_clk {
gpio = <5>;
func = <2>;
pull = <GPIO_NO_PULL>;
od_en = <GPIO_OD_DISABLE>;
drvstr = <GPIO_8MA>;
};
};
};
pci0: pci@28000000 {
status = "ok";
perst_gpio = <23>;
pci_gpio {
pci_rst {
gpio = <23>;
func = <0>;
pull = <GPIO_PULL_UP>;
oe = <GPIO_OD_ENABLE>;
od_en = <GPIO_OD_DISABLE>;
drvstr = <GPIO_8MA>;
};
};
};
pci1: pci@10000000 {
status = "ok";
perst_gpio = <26>;
pci_gpio {
pci_rst {
gpio = <26>;
func = <0>;
pull = <GPIO_PULL_DOWN>;
oe = <GPIO_OD_ENABLE>;
od_en = <GPIO_OD_DISABLE>;
drvstr = <GPIO_8MA>;
};
};
};
pci2: pci@20000000 {
status = "ok";
perst_gpio = <29>;
pci_gpio {
pci_rst {
gpio = <29>;
func = <0>;
pull = <GPIO_PULL_DOWN>;
oe = <GPIO_OD_ENABLE>;
od_en = <GPIO_OD_DISABLE>;
drvstr = <GPIO_8MA>;
};
};
};
pci3: pci@18000000 {
status = "ok";
perst_gpio = <32>;
pci_gpio {
pci_rst {
gpio = <32>;
func = <0>;
pull = <GPIO_PULL_UP>;
oe = <GPIO_OD_ENABLE>;
od_en = <GPIO_OD_DISABLE>;
drvstr = <GPIO_8MA>;
};
};
};
ess-switch {
switch_mac_mode0 = <PORT_WRAPPER_PSGMII>;
switch_mac_mode1 = <PORT_WRAPPER_SGMII_PLUS>;
switch_mac_mode2 = <PORT_WRAPPER_USXGMII>;
qca807x_gpio = <60>;
qca807x_gpio_cnt = <1>;
qca808x_gpio = <57>;
qca808x_gpio_cnt = <1>;
aquantia_gpio = <36>;
aquantia_gpio_cnt = <1>;
aquantia_port = <5>;
aquantia_port_cnt = <1>;
mdc_mdio_gpio = <38 39>;
port_phyinfo {
port@0 {
phy_address = <16>;
phy_type = <QCA807x_PHY_TYPE>;
};
port@1 {
phy_address = <17>;
phy_type = <QCA807x_PHY_TYPE>;
};
port@2 {
phy_address = <18>;
phy_type = <QCA807x_PHY_TYPE>;
};
port@3 {
phy_address = <19>;
phy_type = <QCA807x_PHY_TYPE>;
};
port@4 {
phy_address = <28>;
phy_type = <QCA808x_PHY_TYPE>;
};
port@5 {
phy_address = <0>;
phy_type = <AQ_PHY_TYPE>;
};
};
};
};

View file

@ -0,0 +1,111 @@
/*
* Copyright (c) 2016-2019, 2021, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
/dts-v1/;
#include "ipq9574-db-al02-c1.dts"
/ {
machid = <0x1050101>;
config_name = "config@db-al02-c2";
aliases {
mmc = "/sdhci@7804000";
};
mmc: sdhci@7804000 {
compatible = "qcom,sdhci-msm";
status = "okay";
mmc_gpio {
emmc_dat7 {
gpio = <0>;
func = <1>;
pull = <GPIO_PULL_UP>;
od_en = <GPIO_OD_DISABLE>;
drvstr = <GPIO_8MA>;
};
emmc_dat6 {
gpio = <1>;
func = <1>;
pull = <GPIO_PULL_UP>;
od_en = <GPIO_OD_DISABLE>;
drvstr = <GPIO_8MA>;
};
emmc_dat5 {
gpio = <2>;
func = <1>;
pull = <GPIO_PULL_UP>;
od_en = <GPIO_OD_DISABLE>;
drvstr = <GPIO_8MA>;
};
emmc_dat4 {
gpio = <3>;
func = <1>;
pull = <GPIO_PULL_UP>;
od_en = <GPIO_OD_DISABLE>;
drvstr = <GPIO_8MA>;
};
emmc_dat3 {
gpio = <6>;
func = <1>;
pull = <GPIO_PULL_UP>;
od_en = <GPIO_OD_DISABLE>;
drvstr = <GPIO_8MA>;
};
emmc_dat2 {
gpio = <7>;
func = <1>;
pull = <GPIO_PULL_UP>;
od_en = <GPIO_OD_DISABLE>;
drvstr = <GPIO_8MA>;
};
emmc_dat1 {
gpio = <8>;
func = <1>;
pull = <GPIO_PULL_UP>;
od_en = <GPIO_OD_DISABLE>;
drvstr = <GPIO_8MA>;
};
emmc_dat0 {
gpio = <9>;
func = <1>;
pull = <GPIO_PULL_UP>;
od_en = <GPIO_OD_DISABLE>;
drvstr = <GPIO_8MA>;
};
emmc_cmd{
gpio = <4>;
func = <1>;
pull = <GPIO_PULL_UP>;
od_en = <GPIO_OD_DISABLE>;
drvstr = <GPIO_8MA>;
};
emmc_clk{
gpio = <5>;
func = <1>;
pull = <GPIO_NO_PULL>;
od_en = <GPIO_OD_DISABLE>;
drvstr = <GPIO_8MA>;
};
emmc_rclk{
gpio = <10>;
func = <1>;
pull = <GPIO_PULL_DOWN>;
od_en = <GPIO_OD_DISABLE>;
drvstr = <GPIO_8MA>;
};
};
};
nand: nand-controller@79B0000 {
status = "disabled";
};
};

View file

@ -0,0 +1,42 @@
/*
* Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
/dts-v1/;
#include "ipq9574-db-al02-c1.dts"
/ {
machid = <0x1050201>;
config_name = "config@db-al02-c3";
aliases {
i2c0 = "/i2c@78B9000";
};
ess-switch {
/* Overriding port5 configuration to support SFP instead
* of QCA808x.
*/
/delete-property/qca808x_gpio;
/delete-property/qca808x_gpio_cnt;
switch_mac_mode1 = <PORT_WRAPPER_10GBASE_R>;
sfp_gpio = <61>;
sfp_gpio_cnt = <1>;
sfp_port = <4>;
sfp_port_cnt = <1>;
port_phyinfo {
port@4 {
/delete-property/phy_address;
phy_type = <SFP_PHY_TYPE>;
};
};
};
};

View file

@ -0,0 +1,112 @@
/*
* Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
/dts-v1/;
#include "ipq9574-soc.dtsi"
/ {
machid = <0xF050000>;
config_name = "config@emulation-fbc";
aliases {
console = "/serial@78AF000";
nand = "/nand-controller@79B0000";
mmc = "/sdhci@7804000";
usb0 = "/xhci@8a00000";
i2c0 = "/i2c@78b6000";
};
timer {
gpt_freq_hz = <240000>;
};
nand: nand-controller@79B0000 {
status = "okay";
nand_gpio {};
};
mmc: sdhci@7804000 {
compatible = "qcom,sdhci-msm";
};
i2c0: i2c@78b6000 {
compatible = "qcom,qup-i2c";
#address-cells = <1>;
#size-cells = <0>;
reg = <0x78b6000 0x600>;
clock-frequency = <400000>;
i2c_gpio {
gpio1 {
gpio = <36>;
func = <2>;
pull = <GPIO_NO_PULL>;
drvstr = <GPIO_8MA>;
oe = <GPIO_OE_ENABLE>;
};
gpio2 {
gpio = <37>;
func = <2>;
pull = <GPIO_NO_PULL>;
drvstr = <GPIO_8MA>;
oe = <GPIO_OE_ENABLE>;
};
};
};
xhci@8a00000 {
qcom,emulation = <1>;
};
pci0: pci@28000000 {
status = "disabled";
perst_gpio = <39>;
pci_gpio {
pci_rst {
};
};
};
pci1: pci@20000000 {
status = "disabled";
perst_gpio = <41>;
pci_gpio {
pci_rst {
};
};
};
pci2: pci@18000000 {
status = "disabled";
perst_gpio = <42>;
pci_gpio {
pci_rst {
};
};
};
pci3: pci@10000000 {
status = "disabled";
perst_gpio = <40>;
pci_gpio {
pci_rst {
};
};
};
ess-switch {
switch_mac_mode0 = <PORT_WRAPPER_SGMII0_RGMII4>;
switch_mac_mode1 = <PORT_WRAPPER_SGMII0_RGMII4>;
switch_mac_mode2 = <PORT_WRAPPER_SGMII0_RGMII4>;
};
};

View file

@ -0,0 +1,277 @@
/*
* Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include "skeleton.dtsi"
#include <dt-bindings/qcom/gpio-ipq9574.h>
#include <dt-bindings/qcom/eth-ipq9574.h>
/ {
serial@78AF000 {
compatible = "qca,ipq-uartdm";
reg = <0x78AF000 0x200>;
id = <2>;
bit_rate = <0xff>;
status = "ok";
m_value = <36>;
n_value = <15625>;
d_value = <15625>;
serial_gpio {
gpio1 {
gpio = <13>;
func = <2>;
pull = <GPIO_NO_PULL>;
drvstr = <GPIO_8MA>;
oe = <GPIO_OE_ENABLE>;
};
gpio2 {
gpio = <14>;
func = <2>;
pull = <GPIO_NO_PULL>;
drvstr = <GPIO_8MA>;
oe = <GPIO_OE_ENABLE>;
};
};
};
serial@78B2000 {
compatible = "qca,ipq-uartdm";
reg = <0x78B2000 0x200>;
id = <2>;
bit_rate = <0xff>;
status = "ok";
m_value = <36>;
n_value = <15625>;
d_value = <15625>;
serial_gpio {
gpio1 {
gpio = <17>;
func = <2>;
pull = <GPIO_NO_PULL>;
drvstr = <GPIO_8MA>;
oe = <GPIO_OE_ENABLE>;
};
gpio2 {
gpio = <18>;
func = <2>;
pull = <GPIO_NO_PULL>;
drvstr = <GPIO_8MA>;
oe = <GPIO_OE_ENABLE>;
};
};
};
serial@78B1000 {
compatible = "qca,ipq-uartdm";
reg = <0x78B1000 0x200>;
id = <2>;
bit_rate = <0xff>;
status = "ok";
m_value = <36>;
n_value = <15625>;
d_value = <15625>;
};
spi {
compatible = "qcom,spi-qup-v2.7.0";
wr_pipe_0 = <12>;
rd_pipe_0 = <13>;
status = "ok";
spi_gpio {
};
};
i2c@78BA000 {
compatible = "qcom,qup-i2c";
#address-cells = <1>;
#size-cells = <0>;
reg = <0x78BA000 0x600>;
clock-frequency = <400000>;
i2c_gpio {
gpio1 {
gpio = <48>;
func = <1>;
pull = <GPIO_PULL_UP>;
drvstr = <GPIO_8MA>;
oe = <GPIO_OE_ENABLE>;
};
gpio2 {
gpio = <49>;
func = <1>;
pull = <GPIO_PULL_UP>;
drvstr = <GPIO_8MA>;
oe = <GPIO_OE_ENABLE>;
};
};
};
i2c@78B9000 {
compatible = "qcom,qup-i2c";
#address-cells = <1>;
#size-cells = <0>;
reg = <0x78B9000 0x600>;
clock-frequency = <400000>;
i2c_gpio {
gpio1 {
gpio = <50>;
func = <2>;
pull = <GPIO_PULL_UP>;
drvstr = <GPIO_8MA>;
oe = <GPIO_OE_ENABLE>;
};
gpio2 {
gpio = <51>;
func = <2>;
pull = <GPIO_PULL_UP>;
drvstr = <GPIO_8MA>;
oe = <GPIO_OE_ENABLE>;
};
};
};
i2c@78B8000 {
compatible = "qcom,qup-i2c";
#address-cells = <1>;
#size-cells = <0>;
reg = <0x78B8000 0x600>;
clock-frequency = <400000>;
i2c_gpio {
gpio1 {
gpio = <15>;
func = <2>;
pull = <GPIO_PULL_UP>;
drvstr = <GPIO_8MA>;
oe = <GPIO_OE_ENABLE>;
};
gpio2 {
gpio = <16>;
func = <2>;
pull = <GPIO_PULL_UP>;
drvstr = <GPIO_8MA>;
oe = <GPIO_OE_ENABLE>;
};
};
};
nand: nand-controller@79B0000 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "qcom,qpic-nand-v2.1.1";
reg = <0x79B0000 0x10000>;
status = "disabled";
};
mmc: sdhci@7804000 {
compatible = "qcom,sdhci-msm";
};
xhci@8a00000 {
compatible = "qca,dwc3-ipq";
#address-cells = <1>;
#size-cells = <1>;
reg = <0x8a00000 0xcd00>;
};
pci0: pci@28000000 {
compatible = "qcom,ipq9574-pcie";
#address-cells = <1>;
#size-cells = <1>;
reg = <0x28000000 0xf1d
0x80000 0x3000
0x28000F20 0xa8
0x28001000 0x1000
0x28300000 0xd00000
0x28100000 0x100000
0x1828000 0x60
0x84000 0x1000>;
reg-names = "pci_dbi", "parf", "elbi","dm_iatu", "axi_bars",
"axi_conf", "pci_rst", "pci_phy";
gen3 = <1>;
lane = <1>;
status = "disabled";
skip_phy_int = <0>;
};
pci1: pci@10000000 {
compatible = "qcom,ipq9574-pcie";
#address-cells = <1>;
#size-cells = <1>;
reg = <0x10000000 0xf1d
0xF8000 0x3000
0x10000F20 0xa8
0x10001000 0x1000
0x10300000 0xd00000
0x10100000 0x100000
0x182B000 0x60
0xFC000 0x1000>;
reg-names = "pci_dbi", "parf", "elbi","dm_iatu", "axi_bars",
"axi_conf", "pci_rst", "pci_phy";
gen3 = <1>;
lane = <1>;
status = "disabled";
skip_phy_int = <0>;
};
pci2: pci@20000000 {
compatible = "qcom,ipq9574-pcie";
#address-cells = <1>;
#size-cells = <1>;
reg = <0x20000000 0xf1d
0x88000 0x3000
0x20000F20 0xa8
0x20001000 0x1000
0x20300000 0xd00000
0x20100000 0x100000
0x1829000 0x60
0x8c000 0x1000>;
reg-names = "pci_dbi", "parf", "elbi","dm_iatu", "axi_bars",
"axi_conf", "pci_rst", "pci_phy";
gen3 = <1>;
lane = <2>;
status = "disabled";
skip_phy_int = <0>;
};
pci3: pci@18000000 {
compatible = "qcom,ipq9574-pcie";
#address-cells = <1>;
#size-cells = <1>;
reg = <0x18000000 0xf1d
0xF0000 0x3000
0x18000F20 0xa8
0x18001000 0x1000
0x18300000 0xd00000
0x18100000 0x100000
0x182A000 0x60
0xF4000 0x1000>;
reg-names = "pci_dbi", "parf", "elbi","dm_iatu", "axi_bars",
"axi_conf", "pci_rst", "pci_phy";
gen3 = <1>;
lane = <2>;
status = "disabled";
skip_phy_int = <0>;
};
timer {
gcnt_cntcv_lo = <0x4a2000>;
gcnt_cntcv_hi = <0x4a2004>;
gpt_freq_hz = <24000000>;
timer_load_val = <0x00FFFFFF 0xFFFFFFFF>;
};
};

View file

@ -0,0 +1,244 @@
/*
* Copyright (c) 2015-2016, 2018, 2021 The Linux Foundation. All rights reserved.
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef IPQ9574_CLK_H
#define IPQ9574_CLK_H
#include <asm/arch-qca-common/uart.h>
/* I2C clocks configuration */
#ifdef CONFIG_IPQ9574_I2C
#define GCC_BLSP1_QUP1_I2C_APPS_CFG_RCGR 0x180201C
#define GCC_BLSP1_QUP1_I2C_APPS_CFG_RCGR_SRC_SEL (1 << 8)
#define GCC_BLSP1_QUP1_I2C_APPS_CFG_RCGR_SRC_DIV (0x1F << 0)
#define GCC_BLSP1_QUP1_I2C_APPS_CMD_RCGR 0x1802018
#define GCC_BLSP1_QUP1_I2C_APPS_CBCR 0x1802024
#define CMD_UPDATE 0x1
#define ROOT_EN 0x2
#define CLK_ENABLE 0x1
void i2c_clock_config(void);
#endif
#define GCC_BLSP1_UART1_BCR 0x1802028
#define GCC_BLSP1_UART2_BCR 0x1803028
#define GCC_BLSP1_UART3_BCR 0x1804028
#define GCC_BLSP1_UART4_BCR 0x1805028
#define GCC_BLSP1_UART5_BCR 0x1806028
#define GCC_BLSP1_UART6_BCR 0x1807028
#define GCC_BLSP1_UART_BCR(id) ((id < 1) ? \
(GCC_BLSP1_UART1_BCR):\
(GCC_BLSP1_UART1_BCR + (0x1000 * id)))
#define GCC_BLSP1_UART_APPS_CMD_RCGR(id) (GCC_BLSP1_UART_BCR(id) + 0x04)
#define GCC_BLSP1_UART_APPS_CFG_RCGR(id) (GCC_BLSP1_UART_BCR(id) + 0x08)
#define GCC_BLSP1_UART_APPS_M(id) (GCC_BLSP1_UART_BCR(id) + 0x0c)
#define GCC_BLSP1_UART_APPS_N(id) (GCC_BLSP1_UART_BCR(id) + 0x10)
#define GCC_BLSP1_UART_APPS_D(id) (GCC_BLSP1_UART_BCR(id) + 0x14)
#define GCC_BLSP1_UART_APPS_CBCR(id) (GCC_BLSP1_UART_BCR(id) + 0x18)
#define GCC_UART_CFG_RCGR_MODE_MASK 0x3000
#define GCC_UART_CFG_RCGR_SRCSEL_MASK 0x0700
#define GCC_UART_CFG_RCGR_SRCDIV_MASK 0x001F
#define GCC_UART_CFG_RCGR_MODE_SHIFT 12
#define GCC_UART_CFG_RCGR_SRCSEL_SHIFT 8
#define GCC_UART_CFG_RCGR_SRCDIV_SHIFT 0
#define UART_RCGR_SRC_SEL 0x1
#define UART_RCGR_SRC_DIV 0x0
#define UART_RCGR_MODE 0x2
#define UART_CMD_RCGR_UPDATE 0x1
#define UART_CBCR_CLK_ENABLE 0x1
#define NOT_2D(two_d) (~two_d)
#define NOT_N_MINUS_M(n,m) (~(n - m))
#define CLOCK_UPDATE_TIMEOUT_US 1000
#define CMD_UPDATE 0x1
#define ROOT_EN 0x2
#define CLK_ENABLE 0x1
/*
* Qpic SPI Nand clock
*/
#define GCC_QPIC_IO_MACRO_CMD_RCGR 0x1832004
#define GCC_QPIC_IO_MACRO_CFG_RCGR 0x1832008
#define GCC_QPIC_IO_MACRO_CBCR 0x183200C
#define GCC_QPIC_AHB_CBCR_ADDR 0x1832010
#define GCC_QPIC_CBCR_ADDR 0x1832014
#define GCC_QPIC_SLEEP_CBCR 0x1832018
#define IO_MACRO_CLK_320_MHZ 320000000
#define IO_MACRO_CLK_266_MHZ 266000000
#define IO_MACRO_CLK_228_MHZ 228000000
#define IO_MACRO_CLK_200_MHZ 200000000
#define IO_MACRO_CLK_100_MHZ 100000000
#define IO_MACRO_CLK_24MHZ 24000000
#define QPIC_IO_MACRO_CLK 0
#define QPIC_CORE_CLK 1
#define XO_CLK_SRC 2
#define GPLL0_CLK_SRC 3
#define FB_CLK_BIT (1 << 4)
#define UPDATE_EN 0x1
/*
* GCC-SDCC
*/
#define GCC_SDCC1_BCR 0x1833000
#define GCC_SDCC1_APPS_CMD_RCGR 0x1833004
#define GCC_SDCC1_APPS_CFG_RCGR 0x1833008
#define GCC_SDCC1_APPS_M 0x183300C
#define GCC_SDCC1_APPS_N 0x1833010
#define GCC_SDCC1_APPS_D 0x1833014
#define GCC_SDCC1_APPS_CBCR 0x183302C
#define GCC_SDCC1_AHB_CBCR 0x1833034
#define SDCC1_M_VAL 0x1
#define SDCC1_N_VAL 0xFC
#define SDCC1_D_VAL 0xFD
#define GCC_SDCC1_APPS_CFG_RCGR_SRC_SEL (2 << 8)
#define GCC_SDCC1_APPS_CFG_RCGR_SRC_DIV (0xB << 0)
/*
* USB
*/
#define GCC_USB_BCR 0x182C000
#define GCC_USB0_MASTER_CMD_RCGR 0x182C004
#define GCC_USB0_MASTER_CFG_RCGR 0x182C008
#define GCC_USB0_AUX_CMD_RCGR 0x182C018
#define GCC_USB0_AUX_CFG_RCGR 0x182C01C
#define GCC_USB0_AUX_M 0x182C020
#define GCC_USB0_AUX_N 0x182C024
#define GCC_USB0_AUX_D 0x182C028
#define GCC_USB0_MOCK_UTMI_CMD_RCGR 0x182C02C
#define GCC_USB0_MOCK_UTMI_CFG_RCGR 0x182C030
#define GCC_USB0_MOCK_UTMI_M 0x182C034
#define GCC_USB0_MOCK_UTMI_N 0x182C038
#define GCC_USB0_MOCK_UTMI_D 0x182C03C
#define GCC_USB0_MASTER_CBCR 0x182C044
#define GCC_USB0_AUX_CBCR 0x182C048
#define GCC_USB0_MOCK_UTMI_CBCR 0x182C04C
#define GCC_USB0_PIPE_CBCR 0x182C054
#define GCC_USB0_SLEEP_CBCR 0x182C058
#define GCC_USB0_PHY_CFG_AHB_CBCR 0x182C05C
#define GCC_USB_0_BOOT_CLOCK_CTL 0x182C060
#define GCC_QUSB2_0_PHY_BCR 0x182C068
#define GCC_USB0_PHY_BCR 0x182C06C
#define GCC_USB3PHY_0_PHY_BCR 0x182C070
#define GCC_USB0_PHY_PIPE_MISC 0x182C074
#define GCC_SNOC_USB_CBCR 0x182E058
#define GCC_ANOC_USB_AXI_CBCR 0x182E084
#define AUX_M 0x0
#define AUX_N 0x0
#define AUX_D 0x0
#define SW_COLLAPSE_ENABLE (1 << 0)
#define SW_OVERRIDE_ENABLE (1 << 2)
#define GCC_USB0_MASTER_CFG_RCGR_SRC_SEL (1 << 8)
#define GCC_USB0_MASTER_CFG_RCGR_SRC_DIV (0x7 << 0)
#define GCC_USB_MOCK_UTMI_SRC_SEL (0 << 8)
#define GCC_USB_MOCK_UTMI_SRC_DIV (0x1 << 0)
#define UTMI_M 0x1
#define UTMI_N 0xFFFE
#define UTMI_D 0xFFFD
#define GCC_USB0_AUX_CFG_MODE_DUAL_EDGE (2 << 12)
#define GCC_USB0_AUX_CFG_SRC_SEL (0 << 8)
#define GCC_USB0_AUX_CFG_SRC_DIV (0 << 0)
/*
* PCIE
*/
#define GCC_PCIE_BASE 0x1828000
#define GCC_PCIE_REG(_offset, _index) (GCC_PCIE_BASE + _offset +\
(_index * 0x1000))
#define GCC_PCIE_BCR 0x0
#define GCC_PCIE_AUX_CMD_RCGR 0x4
#define GCC_PCIE_AUX_CFG_RCGR 0x8
#define GCC_PCIE_AUX_M 0xC
#define GCC_PCIE_AUX_N 0x10
#define GCC_PCIE_AUX_D 0x14
#define GCC_PCIE_AXI_M_CMD_RCGR 0x18
#define GCC_PCIE_AXI_M_CFG_RCGR 0x1C
#define GCC_PCIE_AXI_S_CMD_RCGR 0x20
#define GCC_PCIE_AXI_S_CFG_RCGR 0x24
#define GCC_PCIE_RCHNG_CMD_RCGR 0x28
#define GCC_PCIE_RCHNG_CFG_RCGR 0x2C
#define GCC_PCIE_AHB_CBCR 0x30
#define GCC_PCIE_AUX_CBCR 0x34
#define GCC_PCIE_AXI_M_CBCR 0x38
#define GCC_PCIE_AXI_S_CBCR 0x3C
#define GCC_PCIE_AXI_S_BRIDGE_CBCR 0x40
#define GCC_PCIE_PIPE_CBCR 0x44
#define GCC_PCIE_BOOT_CLOCK_CTL 0x50
#define GCC_PCIE_LINK_DOWN_BCR 0x54
#define GCC_PCIE_MISC_RESET 0x58
#define GCC_PCIEPHY_PHY_BCR 0x5C
#define GCC_PCIE_PHY_BCR 0x60
#define GCC_PCIE_PHY_PIPE_MISC 0x64
#define GCC_SNOC_PCIE0_1LANE_S_CBCR 0x182E048
#define GCC_SNOC_PCIE1_1LANE_S_CBCR 0x182E04C
#define GCC_SNOC_PCIE2_2LANE_S_CBCR 0x182E050
#define GCC_SNOC_PCIE3_2LANE_S_CBCR 0x182E054
#define GCC_ANOC_PCIE0_1LANE_M_CBCR 0x182E07C
#define GCC_ANOC_PCIE2_2LANE_M_CBCR 0x182E080
#define GCC_ANOC_PCIE1_1LANE_M_CBCR 0x182E08C
#define GCC_ANOC_PCIE3_2LANE_M_CBCR 0x182E090
#define GCC_PCIE_AUX_CFG_RCGR_MN_MODE (2 << 12)
#define GCC_PCIE_AUX_CFG_RCGR_SRC_SEL (1 << 8)
#define GCC_PCIE_AUX_CFG_RCGR_SRC_DIV (0x13 << 0)
#define GCC_PCIE_AXI_M_CFG_RCGR_SRC_SEL (2 << 8)
#define GCC_PCIE_AXI_M_CFG_RCGR_SRC_DIV_LANE2 (6 << 0)
#define GCC_PCIE_AXI_M_CFG_RCGR_SRC_DIV_LANE1 (9 << 0)
#define GCC_PCIE_AXI_S_CFG_RCGR_SRC_SEL (2 << 8)
#define GCC_PCIE_AXI_S_CFG_RCGR_SRC_DIV (9 << 0)
#define CMD_UPDATE 0x1
#define ROOT_EN 0x2
#define PIPE_CLK_ENABLE 0x4FF1
#define CLK_DISABLE 0x0
#define NOC_HANDSHAKE_FSM_EN (1 << 15)
#define GCC_PCIE_RCHNG_CFG_RCGR_SRC_SEL (1 << 8)
#define GCC_PCIE_RCHNG_CFG_RCGR_SRC_DIV (0xF << 0)
#define GCC_PCIE_PHY_PIPE_MISC_SRC_SEL (0x1 << 8)
int uart_clock_config(struct ipq_serial_platdata *plat);
#ifdef CONFIG_QPIC_NAND
void qpic_set_clk_rate(unsigned int clk_rate, int blk_type,
int req_clk_src_type);
#endif
#ifdef CONFIG_USB_XHCI_IPQ
void usb_clock_init(int id);
void usb_clock_deinit(void);
#endif
#ifdef CONFIG_QCA_MMC
void emmc_clock_init(void);
void emmc_clock_reset(void);
#endif
#ifdef CONFIG_PCI_IPQ
void pcie_v2_clock_init(int pcie_id);
void pcie_v2_clock_deinit(int pcie_id);
#endif
#endif /*IPQ9574_CLK_H*/

View file

@ -0,0 +1,198 @@
/*
**************************************************************************
* Copyright (c) 2016-2019, 2021, The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
**************************************************************************
*/
#ifndef __EDMA_REGS__
#define __EDMA_REGS__
#define IPQ9574_EDMA_CFG_BASE 0x3ab00000
/*
* IPQ9574 EDMA register offsets
*/
#define IPQ9574_EDMA_REG_MAS_CTRL 0x0
#define IPQ9574_EDMA_REG_PORT_CTRL 0x4
#define IPQ9574_EDMA_REG_RXDESC2FILL_MAP_0 0x14
#define IPQ9574_EDMA_REG_RXDESC2FILL_MAP_1 0x18
#define IPQ9574_EDMA_REG_RXDESC2FILL_MAP_2 0x1c
#define IPQ9574_EDMA_REG_MISC_INT_STAT 0x5c
#define IPQ9574_EDMA_REG_MISC_INT_MASK 0x60
#define IPQ9574_EDMA_REG_TXDESC2CMPL_MAP_0 0x8c
#define IPQ9574_EDMA_REG_TXDESC2CMPL_MAP_1 0x90
#define IPQ9574_EDMA_REG_TXDESC2CMPL_MAP_2 0x94
#define IPQ9574_EDMA_REG_TXDESC2CMPL_MAP_3 0x98
#define IPQ9574_EDMA_REG_TXDESC2CMPL_MAP_4 0x9c
#define IPQ9574_EDMA_REG_TXDESC2CMPL_MAP_5 0xa0
#define IPQ9574_EDMA_REG_TXDESC_BA2(n) (0x1014 + (0x1000 * n))
#define IPQ9574_EDMA_REG_TXDESC_BA(n) (0x1000 + (0x1000 * n))
#define IPQ9574_EDMA_REG_TXDESC_PROD_IDX(n) (0x1004 + (0x1000 * n))
#define IPQ9574_EDMA_REG_TXDESC_CONS_IDX(n) (0x1008 + (0x1000 * n))
#define IPQ9574_EDMA_REG_TXDESC_RING_SIZE(n) (0x100c + (0x1000 * n))
#define IPQ9574_EDMA_REG_TXDESC_CTRL(n) (0x1010 + (0x1000 * n))
#define IPQ9574_EDMA_REG_TXCMPL_BA(n) (0x79000 + (0x1000 * n))
#define IPQ9574_EDMA_REG_TXCMPL_PROD_IDX(n) (0x79004 + (0x1000 * n))
#define IPQ9574_EDMA_REG_TXCMPL_CONS_IDX(n) (0x79008 + (0x1000 * n))
#define IPQ9574_EDMA_REG_TXCMPL_RING_SIZE(n) (0x7900c + (0x1000 * n))
#define IPQ9574_EDMA_REG_TXCMPL_CTRL(n) (0x79014 + (0x1000 * n))
#define IPQ9574_EDMA_REG_TX_INT_STAT(n) (0x99000 + (0x1000 * n))
#define IPQ9574_EDMA_REG_TX_INT_MASK(n) (0x99004 + (0x1000 * n))
#define IPQ9574_EDMA_REG_TX_INT_CTRL(n) (0x9900c + (0x1000 * n))
#define IPQ9574_EDMA_REG_RXFILL_BA(n) (0x29000 + (0x1000 * n))
#define IPQ9574_EDMA_REG_RXFILL_PROD_IDX(n) (0x29004 + (0x1000 * n))
#define IPQ9574_EDMA_REG_RXFILL_CONS_IDX(n) (0x29008 + (0x1000 * n))
#define IPQ9574_EDMA_REG_RXFILL_RING_SIZE(n) (0x2900c + (0x1000 * n))
#define IPQ9574_EDMA_REG_RXFILL_RING_EN(n) (0x2901c + (0x1000 * n))
#define IPQ9574_EDMA_REG_RXFILL_INT_STAT(n) (0x31000 + (0x1000 * n))
#define IPQ9574_EDMA_REG_RXFILL_INT_MASK(n) (0x31004 + (0x1000 * n))
#define IPQ9574_EDMA_REG_RXDESC_BA2(n) (0x39028 + (0x1000 * n))
#define IPQ9574_EDMA_REG_RXDESC_BA(n) (0x39000 + (0x1000 * n))
#define IPQ9574_EDMA_REG_RXDESC_PROD_IDX(n) (0x39004 + (0x1000 * n))
#define IPQ9574_EDMA_REG_RXDESC_CONS_IDX(n) (0x39008 + (0x1000 * n))
#define IPQ9574_EDMA_REG_RXDESC_RING_SIZE(n) (0x3900c + (0x1000 * n))
#define IPQ9574_EDMA_REG_RXDESC_CTRL(n) (0x39018 + (0x1000 * n))
#define IPQ9574_EDMA_REG_RXDESC_INT_STAT(n) (0x59000 + (0x1000 * n))
#define IPQ9574_EDMA_REG_RXDESC_INT_MASK(n) (0x59004 + (0x1000 * n))
#define IPQ9574_EDMA_REG_RX_INT_CTRL(n) (0x5900c + (0x1000 * n))
#define IPQ9574_EDMA_QID2RID_TABLE_MEM(q) (0xb9000 + (0x4 * q))
/*
* EDMA_REG_PORT_CTRL register
*/
#define IPQ9574_EDMA_PORT_CTRL_EN 0x3
/*
* EDMA_REG_TXDESC_PROD_IDX register
*/
#define IPQ9574_EDMA_TXDESC_PROD_IDX_MASK 0xffff
/*
* EDMA_REG_TXDESC_CONS_IDX register
*/
#define IPQ9574_EDMA_TXDESC_CONS_IDX_MASK 0xffff
/*
* EDMA_REG_TXDESC_RING_SIZE register
*/
#define IPQ9574_EDMA_TXDESC_RING_SIZE_MASK 0xffff
/*
* EDMA_REG_TXDESC_CTRL register
*/
#define IPQ9574_EDMA_TXDESC_TX_EN 0x1
/*
* EDMA_REG_TXCMPL_PROD_IDX register
*/
#define IPQ9574_EDMA_TXCMPL_PROD_IDX_MASK 0xffff
/*
* EDMA_REG_TXCMPL_CONS_IDX register
*/
#define IPQ9574_EDMA_TXCMPL_CONS_IDX_MASK 0xffff
/*
* EDMA_REG_TX_INT_CTRL register
*/
#define IPQ9574_EDMA_TX_INT_MASK 0x3
/*
* EDMA_REG_RXFILL_PROD_IDX register
*/
#define IPQ9574_EDMA_RXFILL_PROD_IDX_MASK 0xffff
/*
* EDMA_REG_RXFILL_CONS_IDX register
*/
#define IPQ9574_EDMA_RXFILL_CONS_IDX_MASK 0xffff
/*
* EDMA_REG_RXFILL_RING_SIZE register
*/
#define IPQ9574_EDMA_RXFILL_RING_SIZE_MASK 0xffff
#define IPQ9574_EDMA_RXFILL_BUF_SIZE_MASK 0xffff0000
#define IPQ9574_EDMA_RXFILL_BUF_SIZE_SHIFT 16
/*
* EDMA_REG_RXFILL_RING_EN register
*/
#define IPQ9574_EDMA_RXFILL_RING_EN 0x1
/*
* EDMA_REG_RXFILL_INT_MASK register
*/
#define IPQ9574_EDMA_RXFILL_INT_MASK 0x1
/*
* EDMA_REG_RXDESC_PROD_IDX register
*/
#define IPQ9574_EDMA_RXDESC_PROD_IDX_MASK 0xffff
/*
* EDMA_REG_RXDESC_CONS_IDX register
*/
#define IPQ9574_EDMA_RXDESC_CONS_IDX_MASK 0xffff
/*
* EDMA_REG_RXDESC_RING_SIZE register
*/
#define IPQ9574_EDMA_RXDESC_RING_SIZE_MASK 0xffff
#define IPQ9574_EDMA_RXDESC_PL_OFFSET_MASK 0x1ff
#define IPQ9574_EDMA_RXDESC_PL_OFFSET_SHIFT 16
/*
* EDMA_REG_RXDESC_CTRL register
*/
#define IPQ9574_EDMA_RXDESC_RX_EN 0x1
/*
* EDMA_REG_TX_INT_MASK register
*/
#define IPQ9574_EDMA_TX_INT_MASK_PKT_INT 0x1
#define IPQ9574_EDMA_TX_INT_MASK_UGT_INT 0x2
/*
* EDMA_REG_RXDESC_INT_MASK register
*/
#define IPQ9574_EDMA_RXDESC_INT_MASK_PKT_INT 0x1
#define IPQ9574_EDMA_MASK_INT_DISABLE 0x0
/*
* TXDESC shift values
*/
#define IPQ9574_EDMA_TXDESC_PREHEADER_SHIFT 29
#define IPQ9574_EDMA_TXDESC_DATA_OFFSET_SHIFT 0
#define IPQ9574_EDMA_TXDESC_DATA_OFFSET_MASK 0xfff
#define IPQ9574_EDMA_TXDESC_DATA_LENGTH_SHIFT 0
#define IPQ9574_EDMA_TXDESC_DATA_LENGTH_MASK 0x3ffff
#define IPQ9574_EDMA_PREHDR_DSTINFO_PORTID_IND 0x20
#define IPQ9574_EDMA_PREHDR_PORTNUM_BITS 0x0fff
#define IPQ9574_EDMA_RING_DMA_MASK 0xffffffff
/*
* RXDESC shift values
*/
#define IPQ9574_EDMA_RXDESC_PKT_SIZE_MASK 0x3ffff
#define IPQ9574_EDMA_RXDESC_PKT_SIZE_SHIFT 0
#define IPQ9574_EDMA_RXDESC_RING_INT_STATUS_MASK 0x3
#define IPQ9574_EDMA_TXCMPL_RING_INT_STATUS_MASK 0x3
#define IPQ9574_EDMA_TXCMPL_RETMODE_OPAQUE 0x0
#define IPQ9574_EDMA_RXFILL_RING_INT_STATUS_MASK 0x1
#endif /* __EDMA_REGS__ */

View file

@ -25,6 +25,10 @@
#include <asm/arch-ipq6018/clk.h>
#endif
#ifdef CONFIG_ARCH_IPQ9574
#include <asm/arch-ipq9574/clk.h>
#endif
#ifdef CONFIG_ARCH_IPQ807x
#include <asm/arch-ipq807x/clk.h>
#endif
@ -100,8 +104,12 @@ int set_uuid_bootargs(char *boot_args, char *part_name, int buflen, bool gpt_fla
int get_eth_mac_address(uchar *enetaddr, uint no_of_macs);
void set_ethmac_addr(void);
#ifndef CONFIG_IPQ9574_RUMI
void aquantia_phy_reset_init_done(void);
void aquantia_phy_reset_init(void);
#endif
int bring_sec_core_up(unsigned int cpuid, unsigned int entry, unsigned int arg);
int is_secondary_core_off(unsigned int cpuid);
int smem_read_cpu_count(void);

View file

@ -1,7 +1,7 @@
/*
* Copyright (c) 2008, Google Inc.
* All rights reserved.
* Copyright (c) 2009-2019 The Linux Foundation. All rights reserved.
* Copyright (c) 2009-2020 The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -31,7 +31,8 @@
#define __QPIC_NAND_H
#if defined(CONFIG_IPQ40XX) || defined(CONFIG_IPQ_RUMI) \
|| defined(CONFIG_IPQ6018) || defined(CONFIG_IPQ5018)
|| defined(CONFIG_IPQ6018) || defined(CONFIG_IPQ5018) \
|| defined(CONFIG_IPQ9574)
#define QPIC_EBI2ND_BASE (0x079b0000)
#else
#error "QPIC NAND not supported"

View file

@ -33,6 +33,7 @@
#define SCM_FLAG_COLDBOOT_CPU1 0x1
#define SCM_SVC_ID_SHIFT 0xA
#define IS_CALL_AVAIL_CMD 0x1
#define PART_INFO_CMD 0x22
#ifdef CONFIG_IPQ_BT_SUPPORT
#define SCM_PAS_INIT_IMAGE_CMD 0x1
@ -130,6 +131,7 @@ int qca_scm_dload(u32);
int qca_scm_fuseipq(u32, u32, void *, size_t);
bool is_scm_armv8(void);
int qca_scm_secure_authenticate(void *cmd_buf, size_t cmd_len);
int qca_scm_part_info(void *cmd_buf, size_t cmd_len);
s32 qca_scm_call_atomic_ver2_32(u32 svc, u32 cmd, u32 arg1, u32 arg2);
int qca_scm_auth_kernel(void *cmd_buf, size_t cmd_len);
int is_scm_sec_auth_available(u32 svc_id, u32 cmd_id);

View file

@ -1155,6 +1155,7 @@ extern unsigned int __machine_arch_type;
#define MACH_TYPE_IPQ807x_AP_HK01_C6 0x8010500
#define MACH_TYPE_IPQ807x_AP_HK12_C1 0x8010013
#define MACH_TYPE_IPQ807x_AP_HK10_C2 0x801010E
#define MACH_TYPE_IPQ9574_EMULATION 0xF050000
#ifdef CONFIG_ARCH_EBSA110
# ifdef machine_arch_type

View file

@ -182,7 +182,7 @@ void flush_l3_cache(void);
*/
void save_boot_params_ret(void);
#define isb() __asm__ __volatile__ ("" : : : "memory")
#define isb() __asm__ __volatile__ ("isb" : : : "memory")
#define nop() __asm__ __volatile__("mov\tr0,r0\t@ nop\n\t");

21
board/ipq9574/Kconfig Normal file
View file

@ -0,0 +1,21 @@
if ARCH_IPQ9574
config SYS_CPU
default "ipq9574"
config SYS_BOARD
default "ipq9574"
config SYS_VENDOR
default "qca/arm"
config SYS_CONFIG_NAME
default "ipq9574"
config IPQ9574_QCA_AQUANTIA_PHY
bool "Enable Aquantia PHY support for ipq9574"
config IPQ9574_QCA8075_PHY
bool "Enable Malibu PHY support for ipq9574"
endif

View file

@ -219,7 +219,9 @@ int board_init(void)
printf("WARN: ipq_board_usb_init failed\n");
}
#ifdef CONFIG_IPQ9574_EDMA
aquantia_phy_reset_init();
#endif
disable_audio_clks();
ipq_uboot_fdt_fixup();
/*

View file

@ -35,6 +35,11 @@
#define ELF_HDR_PLUS_PHDR_SIZE sizeof(Elf32_Ehdr) + \
(NO_OF_PROGRAM_HDRS * sizeof(Elf32_Phdr))
#define PRIMARY_PARTITION 1
#define SECONDARY_PARTITION 2
extern int qca_scm_part_info(void *cmd_buf, size_t cmd_len);
unsigned long __stack_chk_guard = 0x000a0dff;
static int debug = 0;
static char mtdids[256];
@ -444,6 +449,9 @@ static int do_boot_signedimg(cmd_tbl_t *cmdtp, int flag, int argc, char *const a
char runcmd[256];
int ret;
unsigned int request;
#ifdef CONFIG_VERSION_ROLLBACK_PARTITION_INFO
int part = PRIMARY_PARTITION;
#endif
#ifdef CONFIG_QCA_MMC
block_dev_desc_t *blk_dev;
disk_partition_t disk_info;
@ -485,6 +493,19 @@ static int do_boot_signedimg(cmd_tbl_t *cmdtp, int flag, int argc, char *const a
request = CONFIG_SYS_LOAD_ADDR;
kernel_img_info.kernel_load_addr = request;
#ifdef CONFIG_VERSION_ROLLBACK_PARTITION_INFO
if (smem_bootconfig_info() == 0){
ret = get_rootfs_active_partition();
if (ret){
part = SECONDARY_PARTITION;
}
}
ret = qca_scm_part_info(&part, sizeof(part));
if (ret) {
printf(" Partition info authentication failed \n");
BUG();
}
#endif
if (ipq_fs_on_nand) {
#ifdef CONFIG_CMD_UBI
/*
@ -628,7 +649,6 @@ static int do_boot_signedimg(cmd_tbl_t *cmdtp, int flag, int argc, char *const a
ret = qca_scm_auth_kernel(&kernel_img_info,
sizeof(kernel_img_info));
if (ret) {
printf("Kernel image authentication failed \n");
BUG();
@ -848,7 +868,9 @@ static int do_bootipq(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
ret = qca_scm_call(SCM_SVC_FUSE, QFPROM_IS_AUTHENTICATE_CMD, &buf, sizeof(char));
#ifdef CONFIG_IPQ9574_EDMA
aquantia_phy_reset_init_done();
#endif
/*
|| if atf is enable in env ,do_boot_signedimg is skip.
|| Note: This features currently support in ipq50XX.

View file

@ -955,6 +955,7 @@ int ft_board_setup(void *blob, bd_t *bd)
{ "qcom,qcom_nand", MTD_DEV_TYPE_NAND, 0 },
{ "qcom,ebi2-nandc-bam-v1.5.0", MTD_DEV_TYPE_NAND, 0 },
{ "qcom,ebi2-nandc-bam-v2.1.1", MTD_DEV_TYPE_NAND, 0 },
{ "qcom,ipq9574-nand", MTD_DEV_TYPE_NAND, 0 },
{ "qcom,ipq8074-nand", MTD_DEV_TYPE_NAND, 0 },
{ "spinand,mt29f", MTD_DEV_TYPE_NAND, 1 },
{ "n25q128a11", MTD_DEV_TYPE_NAND,

View file

@ -0,0 +1,5 @@
ccflags-y += -I$(srctree)/board/qca/arm/ipq9574
cppflags-y += -I$(srctree)/board/qca/arm/ipq9574
obj-y := ipq9574.o
obj-y += clock.o

View file

@ -0,0 +1,359 @@
/*
* Copyright (c) 2015-2016, 2018, 2020 The Linux Foundation. All rights reserved.
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <common.h>
#include <asm/io.h>
#include <asm/arch-ipq9574/clk.h>
#include <asm/errno.h>
#ifdef CONFIG_IPQ9574_I2C
void i2c_clock_config(void)
{
#ifndef CONFIG_IPQ9574_RUMI
int cfg;
/* Configure qup1_i2c_apps_clk_src */
cfg = (GCC_BLSP1_QUP1_I2C_APPS_CFG_RCGR_SRC_SEL |
GCC_BLSP1_QUP1_I2C_APPS_CFG_RCGR_SRC_DIV);
writel(cfg, GCC_BLSP1_QUP1_I2C_APPS_CFG_RCGR);
writel(CMD_UPDATE, GCC_BLSP1_QUP1_I2C_APPS_CMD_RCGR);
mdelay(100);
writel(ROOT_EN, GCC_BLSP1_QUP1_I2C_APPS_CMD_RCGR);
/* Configure CBCR */
writel(CLK_ENABLE, GCC_BLSP1_QUP1_I2C_APPS_CBCR);
#endif
}
#endif
static void uart_configure_mux(u8 id)
{
unsigned long cfg_rcgr;
cfg_rcgr = readl(GCC_BLSP1_UART_APPS_CFG_RCGR(id));
/* Clear mode, src sel, src div */
cfg_rcgr &= ~(GCC_UART_CFG_RCGR_MODE_MASK |
GCC_UART_CFG_RCGR_SRCSEL_MASK |
GCC_UART_CFG_RCGR_SRCDIV_MASK);
cfg_rcgr |= ((UART_RCGR_SRC_SEL << GCC_UART_CFG_RCGR_SRCSEL_SHIFT)
& GCC_UART_CFG_RCGR_SRCSEL_MASK);
cfg_rcgr |= ((UART_RCGR_SRC_DIV << GCC_UART_CFG_RCGR_SRCDIV_SHIFT)
& GCC_UART_CFG_RCGR_SRCDIV_MASK);
cfg_rcgr |= ((UART_RCGR_MODE << GCC_UART_CFG_RCGR_MODE_SHIFT)
& GCC_UART_CFG_RCGR_MODE_MASK);
writel(cfg_rcgr, GCC_BLSP1_UART_APPS_CFG_RCGR(id));
}
static int uart_trigger_update(u8 id)
{
unsigned long cmd_rcgr;
int timeout = 0;
cmd_rcgr = readl(GCC_BLSP1_UART_APPS_CMD_RCGR(id));
cmd_rcgr |= UART_CMD_RCGR_UPDATE;
writel(cmd_rcgr, GCC_BLSP1_UART_APPS_CMD_RCGR(id));
while (readl(GCC_BLSP1_UART_APPS_CMD_RCGR(id)) & UART_CMD_RCGR_UPDATE) {
if (timeout++ >= CLOCK_UPDATE_TIMEOUT_US) {
printf("Timeout waiting for UART clock update\n");
return -ETIMEDOUT;
}
udelay(1);
}
return 0;
}
int uart_clock_config(struct ipq_serial_platdata *plat)
{
unsigned long cbcr_val;
int ret;
uart_configure_mux(plat->port_id);
writel(plat->m_value, GCC_BLSP1_UART_APPS_M(plat->port_id));
writel(NOT_N_MINUS_M(plat->n_value, plat->m_value),
GCC_BLSP1_UART_APPS_N(plat->port_id));
writel(NOT_2D(plat->d_value), GCC_BLSP1_UART_APPS_D(plat->port_id));
ret = uart_trigger_update(plat->port_id);
if (ret)
return ret;
cbcr_val = readl(GCC_BLSP1_UART_APPS_CBCR(plat->port_id));
cbcr_val |= UART_CBCR_CLK_ENABLE;
writel(cbcr_val, GCC_BLSP1_UART_APPS_CBCR(plat->port_id));
return 0;
}
#ifdef CONFIG_QPIC_NAND
void qpic_set_clk_rate(unsigned int clk_rate, int blk_type, int req_clk_src_type)
{
switch (blk_type) {
case QPIC_IO_MACRO_CLK:
/* select the clk source for IO_PAD_MACRO
* clk source wil be either XO = 24MHz. or GPLL0 = 800MHz.
*/
if (req_clk_src_type == XO_CLK_SRC) {
/* default XO clock will enabled
* i.e XO clock = 24MHz.
* so div value will 0.
* Input clock to IO_MACRO will be divided by 4 by default
* by hardware and then taht clock will be go on bus.
* i.e 24/4MHz = 6MHz i.e 6MHz will go onto the bus.
*/
writel(0x0, GCC_QPIC_IO_MACRO_CFG_RCGR);
} else if (req_clk_src_type == GPLL0_CLK_SRC) {
/* selct GPLL0 clock source 800MHz
* so 800/4 = 200MHz.
* Input clock to IO_MACRO will be divided by 4 by default
* by hardware and then that clock will be go on bus.
* i.e 200/4MHz = 50MHz i.e 50MHz will go onto the bus.
*/
if (clk_rate == IO_MACRO_CLK_320_MHZ)
writel(0x104, GCC_QPIC_IO_MACRO_CFG_RCGR);
else if (clk_rate == IO_MACRO_CLK_266_MHZ)
writel(0x105, GCC_QPIC_IO_MACRO_CFG_RCGR);
else if (clk_rate == IO_MACRO_CLK_228_MHZ)
writel(0x106, GCC_QPIC_IO_MACRO_CFG_RCGR);
else if (clk_rate == IO_MACRO_CLK_100_MHZ)
writel(0x10F, GCC_QPIC_IO_MACRO_CFG_RCGR);
else if (clk_rate == IO_MACRO_CLK_200_MHZ)
writel(0x107, GCC_QPIC_IO_MACRO_CFG_RCGR);
} else {
printf("wrong clk src selection requested.\n");
}
/* Enablle update bit to update the new configuration */
writel((UPDATE_EN | readl(GCC_QPIC_IO_MACRO_CMD_RCGR)),
GCC_QPIC_IO_MACRO_CMD_RCGR);
/* Enable the QPIC_IO_MACRO_CLK */
writel(0x1, GCC_QPIC_IO_MACRO_CBCR);
break;
case QPIC_CORE_CLK:
/* To DO if needed for QPIC core clock setting */
break;
default:
printf("wrong qpic block type\n");
break;
}
}
#endif
#ifdef CONFIG_PCI_IPQ
void pcie_v2_clock_init(int pcie_id)
{
#ifndef CONFIG_IPQ9574_RUMI
int cfg, div;
/* Configure pcie_aux_clk_src */
cfg = (GCC_PCIE_AUX_CFG_RCGR_MN_MODE |
GCC_PCIE_AUX_CFG_RCGR_SRC_SEL |
GCC_PCIE_AUX_CFG_RCGR_SRC_DIV);
writel(cfg, GCC_PCIE_REG(GCC_PCIE_AUX_CFG_RCGR, 0));
writel(0x1, GCC_PCIE_REG(GCC_PCIE_AUX_M, 0));
writel(0xFFFC, GCC_PCIE_REG(GCC_PCIE_AUX_N, 0));
writel(0xFFFB, GCC_PCIE_REG(GCC_PCIE_AUX_D, 0));
writel(CMD_UPDATE, GCC_PCIE_REG(GCC_PCIE_AUX_CMD_RCGR, 0));
mdelay(100);
writel(ROOT_EN, GCC_PCIE_REG(GCC_PCIE_AUX_CMD_RCGR, 0));
/* Configure pcie_axi_m__clk_src */
if ((pcie_id == 2) || (pcie_id == 3))
div = GCC_PCIE_AXI_M_CFG_RCGR_SRC_DIV_LANE2;
else
div = GCC_PCIE_AXI_M_CFG_RCGR_SRC_DIV_LANE1;
cfg = (GCC_PCIE_AXI_M_CFG_RCGR_SRC_SEL | div);
writel(cfg, GCC_PCIE_REG(GCC_PCIE_AXI_M_CFG_RCGR, pcie_id));
writel(CMD_UPDATE, GCC_PCIE_REG(GCC_PCIE_AXI_M_CMD_RCGR, pcie_id));
mdelay(100);
writel(ROOT_EN, GCC_PCIE_REG(GCC_PCIE_AXI_M_CMD_RCGR, pcie_id));
/* Configure pcie_axi_s__clk_src */
cfg = (GCC_PCIE_AXI_S_CFG_RCGR_SRC_SEL | GCC_PCIE_AXI_S_CFG_RCGR_SRC_DIV);
writel(cfg, GCC_PCIE_REG(GCC_PCIE_AXI_S_CFG_RCGR, pcie_id));
writel(CMD_UPDATE, GCC_PCIE_REG(GCC_PCIE_AXI_S_CMD_RCGR, pcie_id));
mdelay(100);
writel(ROOT_EN, GCC_PCIE_REG(GCC_PCIE_AXI_S_CMD_RCGR, pcie_id));
/* Configure CBCRs */
writel(CLK_ENABLE, GCC_PCIE_REG(GCC_PCIE_AHB_CBCR, pcie_id));
writel(CLK_ENABLE, GCC_PCIE_REG(GCC_PCIE_AXI_M_CBCR, pcie_id));
writel(CLK_ENABLE, GCC_PCIE_REG(GCC_PCIE_AXI_S_CBCR, pcie_id));
writel(CLK_ENABLE, GCC_SNOC_PCIE0_1LANE_S_CBCR + (0x4 * pcie_id));
switch(pcie_id){
case 0:
writel(CLK_ENABLE, GCC_ANOC_PCIE0_1LANE_M_CBCR);
break;
case 1:
writel(CLK_ENABLE, GCC_ANOC_PCIE1_1LANE_M_CBCR);
break;
case 2:
writel(CLK_ENABLE, GCC_ANOC_PCIE2_2LANE_M_CBCR);
break;
case 3:
writel(CLK_ENABLE, GCC_ANOC_PCIE3_2LANE_M_CBCR);
break;
}
writel(CLK_ENABLE, GCC_PCIE_REG(GCC_PCIE_AXI_S_BRIDGE_CBCR, pcie_id));
writel(PIPE_CLK_ENABLE, GCC_PCIE_REG(GCC_PCIE_PIPE_CBCR, pcie_id));
/* Configure pcie_rchng_clk_src */
cfg = (GCC_PCIE_RCHNG_CFG_RCGR_SRC_SEL
| GCC_PCIE_RCHNG_CFG_RCGR_SRC_DIV);
writel(cfg, GCC_PCIE_REG(GCC_PCIE_RCHNG_CFG_RCGR, pcie_id));
writel(CMD_UPDATE, GCC_PCIE_REG(GCC_PCIE_RCHNG_CMD_RCGR, pcie_id));
mdelay(100);
writel(ROOT_EN, GCC_PCIE_REG(GCC_PCIE_RCHNG_CMD_RCGR, pcie_id));
writel(CLK_ENABLE, GCC_PCIE_REG(GCC_PCIE_AUX_CBCR, pcie_id));
#endif
}
void pcie_v2_clock_deinit(int pcie_id)
{
#ifndef CONFIG_IPQ9574_RUMI
writel(0x0, GCC_PCIE_REG(GCC_PCIE_AUX_CMD_RCGR, 0));
mdelay(100);
writel(0x0, GCC_PCIE_REG(GCC_PCIE_AHB_CBCR, pcie_id));
writel(0x0, GCC_PCIE_REG(GCC_PCIE_AXI_M_CBCR, pcie_id));
writel(0x0, GCC_PCIE_REG(GCC_PCIE_AXI_S_CBCR, pcie_id));
writel(0x0, GCC_PCIE_REG(GCC_PCIE_AUX_CBCR, pcie_id));
writel(0x0, GCC_PCIE_REG(GCC_PCIE_PIPE_CBCR, pcie_id));
writel(0x0, GCC_PCIE_REG(GCC_PCIE_AXI_S_BRIDGE_CBCR, pcie_id));
writel(0x0, GCC_PCIE_REG(GCC_PCIE_RCHNG_CFG_RCGR, pcie_id));
writel(0x0, GCC_PCIE_REG(GCC_PCIE_RCHNG_CMD_RCGR, pcie_id));
writel(0x0, GCC_SNOC_PCIE0_1LANE_S_CBCR + (0x4 * pcie_id));
switch(pcie_id){
case 0:
writel(0x0, GCC_ANOC_PCIE0_1LANE_M_CBCR);
break;
case 1:
writel(0x0, GCC_ANOC_PCIE1_1LANE_M_CBCR);
break;
case 2:
writel(0x0, GCC_ANOC_PCIE2_2LANE_M_CBCR);
break;
case 3:
writel(0x0, GCC_ANOC_PCIE3_2LANE_M_CBCR);
break;
}
#endif
}
#endif
#ifdef CONFIG_USB_XHCI_IPQ
void usb_clock_init(int id)
{
#ifndef CONFIG_IPQ9574_RUMI
int cfg;
/* Configure usb0_master_clk_src */
cfg = (GCC_USB0_MASTER_CFG_RCGR_SRC_SEL |
GCC_USB0_MASTER_CFG_RCGR_SRC_DIV);
writel(cfg, GCC_USB0_MASTER_CFG_RCGR);
writel(CMD_UPDATE, GCC_USB0_MASTER_CMD_RCGR);
mdelay(100);
writel(ROOT_EN, GCC_USB0_MASTER_CMD_RCGR);
/* Configure usb0_mock_utmi_clk_src */
cfg = (GCC_USB_MOCK_UTMI_SRC_SEL |
GCC_USB_MOCK_UTMI_SRC_DIV);
writel(cfg, GCC_USB0_MOCK_UTMI_CFG_RCGR);
writel(UTMI_M, GCC_USB0_MOCK_UTMI_M);
writel(UTMI_N, GCC_USB0_MOCK_UTMI_N);
writel(UTMI_D, GCC_USB0_MOCK_UTMI_D);
writel(CMD_UPDATE, GCC_USB0_MOCK_UTMI_CMD_RCGR);
mdelay(100);
writel(ROOT_EN, GCC_USB0_MOCK_UTMI_CMD_RCGR);
/* Configure usb0_aux_clk_src */
cfg = (GCC_USB0_AUX_CFG_SRC_SEL |
GCC_USB0_AUX_CFG_SRC_DIV);
writel(cfg, GCC_USB0_AUX_CFG_RCGR);
writel(AUX_M, GCC_USB0_AUX_M);
writel(AUX_N, GCC_USB0_AUX_N);
writel(AUX_D, GCC_USB0_AUX_D);
writel(CMD_UPDATE, GCC_USB0_AUX_CMD_RCGR);
mdelay(100);
writel(ROOT_EN, GCC_USB0_AUX_CMD_RCGR);
/* Configure CBCRs */
writel((readl(GCC_USB0_MASTER_CBCR) | CLK_ENABLE),
GCC_USB0_MASTER_CBCR);
writel(CLK_ENABLE, GCC_ANOC_USB_AXI_CBCR);
writel(CLK_ENABLE, GCC_SNOC_USB_CBCR);
writel(CLK_ENABLE, GCC_USB0_MOCK_UTMI_CBCR);
writel(CLK_ENABLE, GCC_USB0_SLEEP_CBCR);
writel(CLK_ENABLE, GCC_USB0_AUX_CBCR);
writel((CLK_ENABLE | NOC_HANDSHAKE_FSM_EN),
GCC_USB0_PHY_CFG_AHB_CBCR);
writel(CLK_ENABLE, GCC_USB0_PIPE_CBCR);
#endif
}
void usb_clock_deinit(void)
{
#ifndef CONFIG_IPQ9574_RUMI
/* Disable clocks */
writel(0x8000, GCC_USB0_PHY_CFG_AHB_CBCR);
writel(0xcff0, GCC_USB0_MASTER_CBCR);
writel(0, GCC_USB0_SLEEP_CBCR);
writel(0, GCC_USB0_MOCK_UTMI_CBCR);
writel(0, GCC_USB0_AUX_CBCR);
writel(0, GCC_ANOC_USB_AXI_CBCR);
writel(0, GCC_SNOC_USB_CBCR);
#endif
}
#endif
#ifdef CONFIG_QCA_MMC
void emmc_clock_init(void)
{
#ifndef CONFIG_IPQ9574_RUMI
int cfg;
/* Configure sdcc1_apps_clk_src */
cfg = (GCC_SDCC1_APPS_CFG_RCGR_SRC_SEL
| GCC_SDCC1_APPS_CFG_RCGR_SRC_DIV);
writel(cfg, GCC_SDCC1_APPS_CFG_RCGR);
writel(SDCC1_M_VAL, GCC_SDCC1_APPS_M);
writel(SDCC1_N_VAL, GCC_SDCC1_APPS_N);
writel(SDCC1_D_VAL, GCC_SDCC1_APPS_D);
writel(CMD_UPDATE, GCC_SDCC1_APPS_CMD_RCGR);
mdelay(100);
writel(ROOT_EN, GCC_SDCC1_APPS_CMD_RCGR);
/* Configure CBCRs */
writel(readl(GCC_SDCC1_APPS_CBCR) | CLK_ENABLE, GCC_SDCC1_APPS_CBCR);
udelay(10);
writel(readl(GCC_SDCC1_AHB_CBCR) | CLK_ENABLE, GCC_SDCC1_AHB_CBCR);
#endif
}
void emmc_clock_reset(void)
{
#ifndef CONFIG_IPQ9574_RUMI
writel(0x1, GCC_SDCC1_BCR);
udelay(10);
writel(0x0, GCC_SDCC1_BCR);
#endif
}
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,389 @@
/*
* Copyright (c) 2016-2021 The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef _IPQ9574_CDP_H_
#define _IPQ9574_CDP_H_
#include <configs/ipq9574.h>
#include <asm/u-boot.h>
#include <asm/arch-qca-common/qca_common.h>
#define CMN_BLK_ADDR 0x0009B780
#define FREQUENCY_MASK 0xfffffdf0
#define INTERNAL_48MHZ_CLOCK 0x7
#define PORT_WRAPPER_MAX 0xFF
/*
* EDMA HW ASSERT and DEASSERT values
*/
#define NSS_CC_EDMA_HW_RESET_ASSERT 0x18000
#define NSS_CC_EDMA_HW_RESET_DEASSERT 0x0
#define NSS_CC_PORT1_RX_CMD_RCGR 0x39B28110
#define NSS_CC_PORT5_RX_CMD_RCGR 0x39B28170
#define NSS_CC_PORT5_TX_CMD_RCGR 0x39B2817C
#define NSS_CC_PORT1_RX_CFG_RCGR 0x39B28114
#define NSS_CC_PORT1_RX_CBCR 0x39B281A0
#define NSS_CC_UNIPHY_PORT1_RX_CBCR 0x39B28904
#define IPQ9574_PPE_BASE_ADDR 0x3a000000
#define IPQ9574_PPE_REG_SIZE 0x1000000
#define GCC_CBCR_CLK_ENABLE 0x1
#define GCC_CMN_BLK_ADDR 0x183A000
#define GCC_CMN_BLK_AHB_CBCR_OFFSET 0x4
#define GCC_CMN_BLK_SYS_CBCR_OFFSET 0x8
#define GCC_UNIPHY_SYS_ADDR 0x1817048
#define GCC_PORT_MAC_ADDR 0x39B2824C
#define NSS_CC_PPE_SWITCH_CFG_ADDR 0x39B2822C
#define NSS_CC_PPE_SWITCH_CBCR 0x39B28230
#define NSS_CC_PPE_SWITCH_CFG_CBCR 0x39B28234
#define NSS_CC_PPE_EDMA_CBCR 0x39B28238
#define NSS_CC_PPE_EDMA_CFG_CBCR 0x39B2823C
#define NSS_CC_CRYPTO_PPE_CBCR 0x39B28240
#define NSS_CC_NSSNOC_PPE_CBCR 0x39B28244
#define NSS_CC_NSSNOC_PPE_CFG_CBCR 0x39B28248
#define NSS_CC_PPE_SWITCH_BTQ_ADDR 0x39B2827C
#define GCC_MDIO_AHB_CBCR_ADDR 0x1817040
#define GCC_MEM_NOC_NSSNOC_CLK 0x01819014
#define GCC_NSSCFG_CLK 0x0181702C
#define GCC_NSSNOC_ATB_CLK 0x01817014
#define GCC_NSSNOC_MEM_NOC_1_CLK 0x01817084
#define GCC_NSSNOC_MEMNOC_CLK 0x01817024
#define GCC_NSSNOC_QOSGEN_REF_CLK 0x0181701C
#define GCC_NSSNOC_TIMEOUT_REF_CLK 0x01817020
#define GCC_NSSNOC_SNOC_CBCR 0x1817028
#define GCC_NSSNOC_SNOC_1_CBCR 0x181707C
#define GCC_MEM_NOC_SNOC_AXI_CBCR 0x1819018
#define NSS_CC_UNIPHY_PORT1_RX_ADDR 0x39B28904
#define NSS_CC_PPE_RESET_ADDR 0x39B28A08
#define NSS_CC_UNIPHY_MISC_RESET 0x39B28A24
#define GCC_UNIPHY0_MISC 0x1817050
#define GCC_UNIPHY1_MISC 0x1817060
#define GCC_UNIPHY2_MISC 0x1817070
#define GCC_PPE_PORT1_MAC_ARES 0x800
#define GCC_PPE_PORT2_MAC_ARES 0x400
#define GCC_PPE_PORT3_MAC_ARES 0x200
#define GCC_PPE_PORT4_MAC_ARES 0x100
#define GCC_PPE_PORT5_MAC_ARES 0x80
#define GCC_PPE_PORT6_MAC_ARES 0x40
#define GCC_PORT1_ARES 0xC00
#define GCC_PORT2_ARES 0x300
#define GCC_PORT3_ARES 0xC0
#define GCC_PORT4_ARES 0x30
#define GCC_PORT5_ARES 0xC
#define GCC_PORT6_ARES 0x3
#define NSS_CC_PORT_SPEED_DIVIDER 0x39B28110
#define NSS_CC_PPE_FREQUENCY_RCGR 0x39B28204
#define GPIO_DRV_2_MA 0x0 << 6
#define GPIO_DRV_4_MA 0x1 << 6
#define GPIO_DRV_6_MA 0x2 << 6
#define GPIO_DRV_8_MA 0x3 << 6
#define GPIO_DRV_10_MA 0x4 << 6
#define GPIO_DRV_12_MA 0x5 << 6
#define GPIO_DRV_14_MA 0x6 << 6
#define GPIO_DRV_16_MA 0x7 << 6
#define GPIO_OE 0x1 << 9
#define GPIO_NO_PULL 0x0
#define GPIO_PULL_DOWN 0x1
#define GPIO_KEEPER 0x2
#define GPIO_PULL_UP 0x3
#define MDC_MDIO_FUNC_SEL 0x1 << 2
#define BLSP1_UART0_BASE 0x078AF000
#define UART_PORT_ID(reg) ((reg - BLSP1_UART0_BASE) / 0x1000)
#define CLOCK_UPDATE_TIMEOUT_US 1000
#define KERNEL_AUTH_CMD 0x1E
#define SCM_CMD_SEC_AUTH 0x1F
#ifdef CONFIG_SMEM_VERSION_C
#define RAM_PART_NAME_LENGTH 16
#define SECONDARY_CORE_STACKSZ (8 * 1024)
#define CPU_POWER_DOWN (1 << 16)
#define ARM_PSCI_TZ_FN_BASE 0x84000000
#define ARM_PSCI_TZ_FN(n) (ARM_PSCI_TZ_FN_BASE + (n))
#define ARM_PSCI_TZ_FN_CPU_OFF ARM_PSCI_TZ_FN(2)
#define ARM_PSCI_TZ_FN_CPU_ON ARM_PSCI_TZ_FN(3)
#define ARM_PSCI_TZ_FN_AFFINITY_INFO ARM_PSCI_TZ_FN(4)
/*
* GCC-QPIC Registers
*/
#define QPIC_CBCR_VAL 0x80004FF1
#define PSCI_RESET_SMC_ID 0x84000009
#define set_mdelay_clearbits_le32(addr, value, delay) \
setbits_le32(addr, value); \
mdelay(delay); \
clrbits_le32(addr, value); \
/* USB Registers */
#define USB30_PHY_1_QUSB2PHY_BASE 0x7B000
#define USB30_PHY_1_USB3PHY_AHB2PHY_BASE 0x7D000
#define USB3_PHY_POWER_DOWN_CONTROL 0x804
#define USB30_1_GUCTL 0x8A0C12C
#define USB30_1_FLADJ 0x8A0C630
#define QSERDES_COM_SYSCLK_EN_SEL 0xac
#define QSERDES_COM_BIAS_EN_CLKBUFLR_EN 0x34
#define QSERDES_COM_CLK_SELECT 0x174
#define QSERDES_COM_BG_TRIM 0x70
#define QSERDES_RX_UCDR_FASTLOCK_FO_GAIN 0x440
#define QSERDES_COM_SVS_MODE_CLK_SEL 0x19c
#define QSERDES_COM_HSCLK_SEL 0x178
#define QSERDES_COM_CMN_CONFIG 0x194
#define QSERDES_COM_PLL_IVCO 0x048
#define QSERDES_COM_SYS_CLK_CTRL 0x3c
#define QSERDES_COM_DEC_START_MODE0 0xd0
#define QSERDES_COM_DIV_FRAC_START1_MODE0 0xdc
#define QSERDES_COM_DIV_FRAC_START2_MODE0 0xe0
#define QSERDES_COM_DIV_FRAC_START3_MODE0 0xe4
#define QSERDES_COM_CP_CTRL_MODE0 0x78
#define QSERDES_COM_PLL_RCTRL_MODE0 0x84
#define QSERDES_COM_PLL_CCTRL_MODE0 0x90
#define QSERDES_COM_INTEGLOOP_GAIN0_MODE0 0x108
#define QSERDES_COM_LOCK_CMP1_MODE0 0x4c
#define QSERDES_COM_LOCK_CMP2_MODE0 0x50
#define QSERDES_COM_LOCK_CMP3_MODE0 0x54
#define QSERDES_COM_CORE_CLK_EN 0x18c
#define QSERDES_COM_LOCK_CMP_CFG 0xcc
#define QSERDES_COM_VCO_TUNE_MAP 0x128
#define QSERDES_COM_BG_TIMER 0x0c
#define QSERDES_COM_SSC_EN_CENTER 0x10
#define QSERDES_COM_SSC_PER1 0x1c
#define QSERDES_COM_SSC_PER2 0x20
#define QSERDES_COM_SSC_ADJ_PER1 0x14
#define QSERDES_COM_SSC_ADJ_PER2 0x18
#define QSERDES_COM_SSC_STEP_SIZE1 0x24
#define QSERDES_COM_SSC_STEP_SIZE2 0x28
#define QSERDES_RX_UCDR_SO_GAIN 0x410
#define QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2 0x4d8
#define QSERDES_RX_RX_EQU_ADAPTOR_CNTRL3 0x4dc
#define QSERDES_RX_RX_EQU_ADAPTOR_CNTRL4 0x4e0
#define QSERDES_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL 0x508
#define QSERDES_RX_RX_OFFSET_ADAPTOR_CNTRL2 0x50c
#define QSERDES_RX_SIGDET_CNTRL 0x514
#define QSERDES_RX_SIGDET_DEGLITCH_CNTRL 0x51c
#define QSERDES_RX_SIGDET_ENABLES 0x510
#define QSERDES_TX_HIGHZ_TRANSCEIVEREN_BIAS_D 0x268
#define QSERDES_TX_RCV_DETECT_LVL_2 0x2ac
#define QSERDES_TX_LANE_MODE 0x294
#define PCS_TXDEEMPH_M6DB_V0 0x824
#define PCS_TXDEEMPH_M3P5DB_V0 0x828
#define PCS_FLL_CNTRL2 0x8c8
#define PCS_FLL_CNTRL1 0x8c4
#define PCS_FLL_CNT_VAL_L 0x8cc
#define PCS_FLL_CNT_VAL_H_TOL 0x8d0
#define PCS_FLL_MAN_CODE 0x8d4
#define PCS_LOCK_DETECT_CONFIG1 0x880
#define PCS_LOCK_DETECT_CONFIG2 0x884
#define PCS_LOCK_DETECT_CONFIG3 0x888
#define PCS_POWER_STATE_CONFIG2 0x864
#define PCS_RXEQTRAINING_WAIT_TIME 0x8b8
#define PCS_RXEQTRAINING_RUN_TIME 0x8bc
#define PCS_LFPS_TX_ECSTART_EQTLOCK 0x8b0
#define PCS_PWRUP_RESET_DLY_TIME_AUXCLK 0x8a0
#define PCS_TSYNC_RSYNC_TIME 0x88c
#define PCS_RCVR_DTCT_DLY_P1U2_L 0x870
#define PCS_RCVR_DTCT_DLY_P1U2_H 0x874
#define PCS_RCVR_DTCT_DLY_U3_L 0x878
#define PCS_RCVR_DTCT_DLY_U3_H 0x87c
#define PCS_RX_SIGDET_LVL 0x9d8
#define USB3_PCS_TXDEEMPH_M6DB_V0 0x824
#define USB3_PCS_TXDEEMPH_M3P5DB_V0 0x828
#define QSERDES_RX_SIGDET_ENABLES 0x510
#define USB3_PHY_START_CONTROL 0x808
#define USB3_PHY_SW_RESET 0x800
#define NOC_HANDSHAKE_FSM_EN (1 << 15)
enum uniphy_clk_type {
NSS_PORT1_RX_CLK_E = 0,
NSS_PORT1_TX_CLK_E,
NSS_PORT2_RX_CLK_E,
NSS_PORT2_TX_CLK_E,
NSS_PORT3_RX_CLK_E,
NSS_PORT3_TX_CLK_E,
NSS_PORT4_RX_CLK_E,
NSS_PORT4_TX_CLK_E,
NSS_PORT5_RX_CLK_E,
NSS_PORT5_TX_CLK_E,
NSS_PORT6_RX_CLK_E,
NSS_PORT6_TX_CLK_E,
UNIPHY0_PORT1_RX_CLK_E,
UNIPHY0_PORT1_TX_CLK_E,
UNIPHY0_PORT2_RX_CLK_E,
UNIPHY0_PORT2_TX_CLK_E,
UNIPHY0_PORT3_RX_CLK_E,
UNIPHY0_PORT3_TX_CLK_E,
UNIPHY0_PORT4_RX_CLK_E,
UNIPHY0_PORT4_TX_CLK_E,
UNIPHY0_PORT5_RX_CLK_E,
UNIPHY0_PORT5_TX_CLK_E,
UNIPHY1_PORT5_RX_CLK_E,
UNIPHY1_PORT5_TX_CLK_E,
UNIPHY2_PORT6_RX_CLK_E,
UNIPHY2_PORT6_TX_CLK_E,
PORT5_RX_SRC_E,
PORT5_TX_SRC_E,
UNIPHYT_CLK_MAX,
};
#ifdef CONFIG_PCI_IPQ
void board_pci_init(int id);
__weak void board_pcie_clock_init(int id) {}
#endif
unsigned int __invoke_psci_fn_smc(unsigned int, unsigned int,
unsigned int, unsigned int);
/*
* Eud register
*/
#define EUD_EUD_EN2 0x7A000
/*
* QFPROM Register for SKU Validation
*/
#define QFPROM_CORR_FEATURE_CONFIG_ROW1_MSB 0xA401C
#define QFPROM_CORR_FEATURE_CONFIG_ROW2_MSB 0xA4024
#define PCIE_0_CLOCK_DISABLE_BIT 2
#define PCIE_1_CLOCK_DISABLE_BIT 3
#define PCIE_2_CLOCK_DISABLE_BIT 4
#define PCIE_3_CLOCK_DISABLE_BIT 5
#define UNIPHY_0_DISABLE_BIT 23
#define UNIPHY_1_DISABLE_BIT 24
#define UNIPHY_2_DISABLE_BIT 25
int ipq_validate_qfrom_fuse(unsigned int reg_add, int pos);
/**
* Number of RAM partition entries which are usable by APPS.
*/
#define RAM_NUM_PART_ENTRIES 32
struct ram_partition_entry
{
char name[RAM_PART_NAME_LENGTH]; /**< Partition name, unused for now */
u64 start_address; /**< Partition start address in RAM */
u64 length; /**< Partition length in RAM in Bytes */
u32 partition_attribute; /**< Partition attribute */
u32 partition_category; /**< Partition category */
u32 partition_domain; /**< Partition domain */
u32 partition_type; /**< Partition type */
u32 num_partitions; /**< Number of partitions on device */
u32 hw_info; /**< hw information such as type and frequency */
u8 highest_bank_bit; /**< Highest bit corresponding to a bank */
u8 reserve0; /**< Reserved for future use */
u8 reserve1; /**< Reserved for future use */
u8 reserve2; /**< Reserved for future use */
u32 reserved5; /**< Reserved for future use */
u64 available_length; /**< Available Partition length in RAM in Bytes */
};
struct usable_ram_partition_table
{
u32 magic1; /**< Magic number to identify valid RAM partition table */
u32 magic2; /**< Magic number to identify valid RAM partition table */
u32 version; /**< Version number to track structure definition changes
and maintain backward compatibilities */
u32 reserved1; /**< Reserved for future use */
u32 num_partitions; /**< Number of RAM partition table entries */
u32 reserved2; /** < Added for 8 bytes alignment of header */
/** RAM partition table entries */
struct ram_partition_entry ram_part_entry[RAM_NUM_PART_ENTRIES];
};
#endif
struct smem_ram_ptn {
char name[16];
unsigned long long start;
unsigned long long size;
/* RAM Partition attribute: READ_ONLY, READWRITE etc. */
unsigned attr;
/* RAM Partition category: EBI0, EBI1, IRAM, IMEM */
unsigned category;
/* RAM Partition domain: APPS, MODEM, APPS & MODEM (SHARED) etc. */
unsigned domain;
/* RAM Partition type: system, bootloader, appsboot, apps etc. */
unsigned type;
/* reserved for future expansion without changing version number */
unsigned reserved2, reserved3, reserved4, reserved5;
} __attribute__ ((__packed__));
struct smem_ram_ptable {
#define _SMEM_RAM_PTABLE_MAGIC_1 0x9DA5E0A8
#define _SMEM_RAM_PTABLE_MAGIC_2 0xAF9EC4E2
unsigned magic[2];
unsigned version;
unsigned reserved1;
unsigned len;
unsigned buf;
struct smem_ram_ptn parts[32];
} __attribute__ ((__packed__));
int smem_ram_ptable_init(struct smem_ram_ptable *smem_ram_ptable);
int smem_ram_ptable_init_v2(struct usable_ram_partition_table *usable_ram_partition_table);
void reset_crashdump(void);
void reset_board(void);
typedef enum {
SMEM_SPINLOCK_ARRAY = 7,
SMEM_AARM_PARTITION_TABLE = 9,
SMEM_HW_SW_BUILD_ID = 137,
SMEM_USABLE_RAM_PARTITION_TABLE = 402,
SMEM_POWER_ON_STATUS_INFO = 403,
SMEM_MACHID_INFO_LOCATION = 425,
SMEM_IMAGE_VERSION_TABLE = 469,
SMEM_BOOT_FLASH_TYPE = 498,
SMEM_BOOT_FLASH_INDEX = 499,
SMEM_BOOT_FLASH_CHIP_SELECT = 500,
SMEM_BOOT_FLASH_BLOCK_SIZE = 501,
SMEM_BOOT_FLASH_DENSITY = 502,
SMEM_BOOT_DUALPARTINFO = 503,
SMEM_PARTITION_TABLE_OFFSET = 504,
SMEM_SPI_FLASH_ADDR_LEN = 505,
SMEM_FIRST_VALID_TYPE = SMEM_SPINLOCK_ARRAY,
SMEM_LAST_VALID_TYPE = SMEM_SPI_FLASH_ADDR_LEN,
SMEM_MAX_SIZE = SMEM_SPI_FLASH_ADDR_LEN + 1,
} smem_mem_type_t;
#define MSM_SDC1_BASE 0x7800000
#define MSM_SDC1_SDHCI_BASE 0x7804000
__weak void qgic_init(void) {}
__weak void handle_noc_err(void) {}
extern const char *rsvd_node;
extern const char *del_node[];
extern const add_node_t add_fdt_node[];
int ipq_get_tz_version(char *version_name, int buf_size);
void ipq_fdt_fixup_socinfo(void *blob);
int ipq_board_usb_init(void);
#endif /* _IPQ9574_CDP_H_ */

View file

@ -267,7 +267,7 @@ static int do_spi_flash_read_write(int argc, char * const argv[])
int ret = 1;
int dev = 0;
loff_t offset, len, maxsize;
unsigned long sram_end = CONFIG_SYS_SDRAM_BASE + gd->ram_size;
u64 sram_end = CONFIG_SYS_SDRAM_BASE + (u64)gd->ram_size;
if (argc < 3)
return -1;

324
configs/ipq9574_defconfig Normal file
View file

@ -0,0 +1,324 @@
CONFIG_ARM=y
CONFIG_HAS_VBAR=y
CONFIG_CPU_V7=y
CONFIG_ARCH_IPQ9574=y
CONFIG_SYS_MALLOC_F_LEN=0x400
CONFIG_SYS_MALLOC_F=y
CONFIG_DM_SERIAL=y
CONFIG_DEFAULT_DEVICE_TREE=""
CONFIG_LOCALVERSION=""
CONFIG_LOCALVERSION_AUTO=y
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_EXPERT=y
CONFIG_SYS_MALLOC_CLEAR_ON_INIT=y
CONFIG_FIT=y
CONFIG_FIT_VERBOSE=y
# CONFIG_FIT_SIGNATURE is not set
CONFIG_SYS_EXTRA_OPTIONS=""
CONFIG_SYS_PROMPT="IPQ9574# "
#
# Commands
#
#
# Info commands
#
CONFIG_CMD_BDI=y
CONFIG_CMD_CONSOLE=y
#
# Boot commands
#
# CONFIG_CMD_BOOTD is not set
CONFIG_CMD_BOOTM=y
CONFIG_CMD_GO=y
# CONFIG_CMD_RUN is not set
# CONFIG_CMD_IMI is not set
# CONFIG_CMD_IMLS is not set
# CONFIG_CMD_XIMG is not set
#
# Environment commands
#
CONFIG_CMD_EXPORTENV=y
CONFIG_CMD_IMPORTENV=y
CONFIG_CMD_EDITENV=y
CONFIG_CMD_SAVEENV=y
CONFIG_CMD_ENV_EXISTS=y
#
# Memory commands
#
CONFIG_CMD_MEMORY=y
CONFIG_CMD_CRC32=y
# CONFIG_LOOPW is not set
# CONFIG_CMD_MEMTEST is not set
# CONFIG_CMD_MX_CYCLIC is not set
# CONFIG_CMD_MEMINFO is not set
#
# Device access commands
#
CONFIG_CMD_DM=y
# CONFIG_CMD_DEMO is not set
CONFIG_CMD_LOADB=y
CONFIG_CMD_LOADS=y
CONFIG_CMD_FLASH=y
# CONFIG_CMD_NAND is not set
# CONFIG_CMD_SF is not set
# CONFIG_CMD_SPI is not set
# CONFIG_CMD_I2C is not set
# CONFIG_CMD_USB is not set
CONFIG_CMD_FPGA=y
#
# Shell scripting commands
#
CONFIG_CMD_ECHO=y
CONFIG_CMD_ITEST=y
CONFIG_CMD_SOURCE=y
CONFIG_CMD_SETEXPR=y
#
# Network commands
#
CONFIG_CMD_NET=y
# CONFIG_CMD_TFTPPUT is not set
# CONFIG_CMD_TFTPSRV is not set
# CONFIG_CMD_RARP is not set
# CONFIG_CMD_DHCP is not set
CONFIG_CMD_NFS=y
# CONFIG_CMD_PING is not set
# CONFIG_CMD_CDP is not set
# CONFIG_CMD_SNTP is not set
# CONFIG_CMD_DNS is not set
# CONFIG_CMD_LINK_LOCAL is not set
#
# Network PHY
#
# CONFIG_QCA8075_PHY is not set
CONFIG_IPQ9574_QCA_AQUANTIA_PHY=y
# CONFIG_QCA8033_PHY is not set
CONFIG_QCA8081_PHY=y
CONFIG_IPQ9574_QCA8075_PHY=y
#
# Misc commands
#
# CONFIG_CMD_TIME is not set
CONFIG_CMD_MISC=y
CONFIG_CMD_PART=y
CONFIG_PARTITION_UUIDS=y
# CONFIG_CMD_TIMER is not set
#
# Boot timing
#
# CONFIG_BOOTSTAGE is not set
CONFIG_BOOTSTAGE_USER_COUNT=20
CONFIG_BOOTSTAGE_STASH_ADDR=0
CONFIG_BOOTSTAGE_STASH_SIZE=4096
#
# Power commands
#
#
# Security commands
#
CONFIG_SUPPORT_OF_CONTROL=y
#
# Device Tree Control
#
CONFIG_OF_CONTROL=y
CONFIG_OF_SEPARATE=y
# CONFIG_OF_EMBED is not set
CONFIG_NET=y
# CONFIG_NET_RANDOM_ETHADDR is not set
# CONFIG_NETCONSOLE is not set
#
# Device Drivers
#
#
# Generic Driver Options
#
CONFIG_DM=y
CONFIG_DM_WARN=y
CONFIG_DM_DEVICE_REMOVE=y
CONFIG_DM_STDIO=y
CONFIG_DM_SEQ_ALIAS=y
# CONFIG_REGMAP is not set
# CONFIG_DEVRES is not set
CONFIG_SIMPLE_BUS=y
# CONFIG_CLK is not set
# CONFIG_CPU is not set
#
# Hardware crypto devices
#
# CONFIG_FSL_CAAM is not set
#
# Demo for driver model
#
# CONFIG_DM_DEMO is not set
#
# DFU support
#
# CONFIG_DFU_TFTP is not set
#
# GPIO Support
#
# CONFIG_LPC32XX_GPIO is not set
# CONFIG_VYBRID_GPIO is not set
#
# I2C support
#
# CONFIG_DM_I2C_COMPAT is not set
# CONFIG_CROS_EC_KEYB is not set
#
# LED Support
#
# CONFIG_LED is not set
#
# Multifunction device drivers
#
# CONFIG_CROS_EC is not set
# CONFIG_FSL_SEC_MON is not set
# CONFIG_PCA9551_LED is not set
# CONFIG_RESET is not set
#
# MMC Host controller Support
#
# CONFIG_DM_MMC is not set
#
# NAND Device Support
#
# CONFIG_NAND_DENALI is not set
# CONFIG_NAND_VF610_NFC is not set
# CONFIG_NAND_PXA3XX is not set
#
# Generic NAND options
#
#
# Serial NAND
#
CONFIG_QPIC_SERIAL=y
#
# SPI Flash Support
#
# CONFIG_SPI_FLASH is not set
# CONFIG_DM_ETH is not set
# CONFIG_PHYLIB is not set
# CONFIG_NETDEVICES is not set
#
# PCI
#
# CONFIG_DM_PCI is not set
CONFIG_PCI_IPQ=y
#
# Pin controllers
#
# CONFIG_PINCTRL is not set
#
# Power
#
# CONFIG_DM_PMIC is not set
# CONFIG_DM_REGULATOR is not set
# CONFIG_RAM is not set
#
# Real Time Clock
#
# CONFIG_DM_RTC is not set
#
# Serial drivers
#
CONFIG_REQUIRE_SERIAL_CONSOLE=y
# CONFIG_DEBUG_UART is not set
#
# Sound support
#
# CONFIG_SOUND is not set
#
# SPI Support
#
# CONFIG_FSL_ESPI is not set
# CONFIG_TI_QSPI is not set
# CONFIG_DM_THERMAL is not set
#
# TPM support
#
#
# USB support
#
CONFIG_USB=y
CONFIG_DM_USB=y
#
# Graphics support
#
# CONFIG_VIDEO_VESA is not set
# CONFIG_VIDEO_LCD_ANX9804 is not set
# CONFIG_VIDEO_LCD_SSD2828 is not set
# CONFIG_DISPLAY_PORT is not set
# CONFIG_VIDEO_TEGRA124 is not set
# CONFIG_VIDEO_BRIDGE is not set
# CONFIG_PHYS_TO_BUS is not set
#
# File systems
#
#
# Library routines
#
# CONFIG_CC_OPTIMIZE_LIBS_FOR_SPEED is not set
CONFIG_HAVE_PRIVATE_LIBGCC=y
CONFIG_USE_PRIVATE_LIBGCC=y
CONFIG_SYS_HZ=1000
# CONFIG_SYS_VSNPRINTF is not set
CONFIG_REGEX=y
# CONFIG_LIB_RAND is not set
# CONFIG_CMD_DHRYSTONE is not set
# CONFIG_RSA is not set
# CONFIG_TPM is not set
#
# Hashing Support
#
# CONFIG_SHA1 is not set
# CONFIG_SHA256 is not set
# CONFIG_SHA_HW_ACCEL is not set
#
# Compression Support
#
# CONFIG_LZ4 is not set
CONFIG_LZMA=y
# CONFIG_ERRNO_STR is not set
# CONFIG_UNIT_TEST is not set

View file

@ -10,6 +10,7 @@ obj-$(CONFIG_ARCH_IPQ806x) += ipq_gpio.o
obj-$(CONFIG_ARCH_IPQ40xx) += ipq_gpio.o
obj-$(CONFIG_ARCH_IPQ5018) += ipq_gpio.o
obj-$(CONFIG_ARCH_IPQ6018) += ipq_gpio.o
obj-$(CONFIG_ARCH_IPQ9574) += ipq_gpio.o
ifndef CONFIG_SPL_BUILD
obj-$(CONFIG_DWAPB_GPIO) += dwapb_gpio.o
obj-$(CONFIG_AXP_GPIO) += axp_gpio.o

View file

@ -47,6 +47,7 @@ struct nand_onfi_para_page onfi_para;
typedef unsigned long addr_t;
static uint32_t hw_ver;
unsigned int qpic_training_offset = 0;
#ifdef CONFIG_QPIC_SERIAL
static struct qpic_serial_nand_params qpic_serial_nand_tbl[] = {
@ -4341,6 +4342,7 @@ static int qpic_execute_serial_training(struct mtd_info *mtd)
}
training_offset = ((loff_t) mtd->erasesize * start_blocks);
qpic_training_offset = training_offset;
start = (training_offset >> chip->phys_erase_shift);
offset = (start << chip->phys_erase_shift);

View file

@ -86,6 +86,9 @@ obj-$(CONFIG_IPQ807X_EDMA) += ipq807x/ipq807x_uniphy.o
obj-$(CONFIG_IPQ6018_EDMA) += ipq6018/ipq6018_edma.o
obj-$(CONFIG_IPQ6018_EDMA) += ipq6018/ipq6018_ppe.o
obj-$(CONFIG_IPQ6018_EDMA) += ipq6018/ipq6018_uniphy.o
obj-$(CONFIG_IPQ9574_EDMA) += ipq9574/ipq9574_ppe.o
obj-$(CONFIG_IPQ9574_EDMA) += ipq9574/ipq9574_uniphy.o
obj-$(CONFIG_IPQ9574_EDMA) += ipq9574/ipq9574_edma.o
obj-$(CONFIG_IPQ5018_GMAC) += ipq5018/ipq5018_gmac.o
obj-$(CONFIG_IPQ5018_GMAC) += ipq5018/ipq5018_uniphy.o
obj-$(CONFIG_IPQ5018_MDIO) += ipq5018/ipq5018_mdio.o
@ -93,7 +96,9 @@ obj-$(CONFIG_IPQ5018_GMAC) += ipq5018/athrs17_phy.o
obj-$(CONFIG_IPQ_MDIO) += ipq_common/ipq_mdio.o
obj-$(CONFIG_GEPHY) += ipq_common/ipq_gephy.o
obj-$(CONFIG_QCA8075_PHY) += ipq_common/ipq_qca8075.o
obj-$(CONFIG_IPQ9574_QCA8075_PHY) += ipq9574/ipq9574_qca8075.o
obj-$(CONFIG_QCA8033_PHY) += ipq_common/ipq_qca8033.o
obj-$(CONFIG_QCA8081_PHY) += ipq_common/ipq_qca8081.o
obj-$(CONFIG_QCA_AQUANTIA_PHY) += ipq807x/ipq807x_aquantia_phy.o
obj-$(CONFIG_IPQ6018_QCA_AQUANTIA_PHY) += ipq6018/ipq6018_aquantia_phy.o
obj-$(CONFIG_IPQ9574_QCA_AQUANTIA_PHY) += ipq9574/ipq9574_aquantia_phy.o

View file

@ -0,0 +1,614 @@
/*
* Copyright (c) 2017-2019, 2021, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#include <common.h>
#include <net.h>
#include <asm-generic/errno.h>
#include <asm/io.h>
#include <malloc.h>
#include <phy.h>
#include <miiphy.h>
#include "ipq_phy.h"
#include "ipq9574_aquantia_phy.h"
#include <crc.h>
#include <mmc.h>
#include <asm/errno.h>
#include <nand.h>
#include <spi_flash.h>
#include <spi.h>
#include <asm/global_data.h>
#include <fdtdec.h>
DECLARE_GLOBAL_DATA_PTR;
typedef struct {
unsigned int image_type;
unsigned int header_vsn_num;
unsigned int image_src;
unsigned char *image_dest_ptr;
unsigned int image_size;
unsigned int code_size;
unsigned char *signature_ptr;
unsigned int signature_size;
unsigned char *cert_chain_ptr;
unsigned int cert_chain_size;
} mbn_header_t;
mbn_header_t *fwimg_header;
static int debug = 0;
#ifdef CONFIG_QCA_MMC
extern qca_mmc mmc_host;
static qca_mmc *host = &mmc_host;
#endif
extern int ipq_mdio_write(int mii_id,
int regnum, u16 value);
extern int ipq_mdio_read(int mii_id,
int regnum, ushort *data);
extern int ipq_sw_mdio_init(const char *);
extern void ipq9574_eth_initialize(void);
static int program_ethphy_fw(unsigned int phy_addr,
uint32_t load_addr,uint32_t file_size );
static qca_smem_flash_info_t *sfi = &qca_smem_flash_info;
u16 aq_phy_reg_write(u32 dev_id, u32 phy_id,
u32 reg_id, u16 reg_val)
{
ipq_mdio_write(phy_id, reg_id, reg_val);
return 0;
}
u16 aq_phy_reg_read(u32 dev_id, u32 phy_id, u32 reg_id)
{
return ipq_mdio_read(phy_id, reg_id, NULL);
}
u8 aq_phy_get_link_status(u32 dev_id, u32 phy_id)
{
u16 phy_data;
uint32_t reg;
reg = AQ_PHY_AUTO_STATUS_REG | AQUANTIA_MII_ADDR_C45;
phy_data = aq_phy_reg_read(dev_id, phy_id, reg);
phy_data = aq_phy_reg_read(dev_id, phy_id, reg);
if (((phy_data >> 2) & 0x1) & PORT_LINK_UP)
return 0;
return 1;
}
u32 aq_phy_get_duplex(u32 dev_id, u32 phy_id, fal_port_duplex_t *duplex)
{
u16 phy_data;
uint32_t reg;
reg = AQ_PHY_LINK_STATUS_REG | AQUANTIA_MII_ADDR_C45;
phy_data = aq_phy_reg_read(dev_id, phy_id, reg);
/*
* Read duplex
*/
phy_data = phy_data & 0x1;
if (phy_data & 0x1)
*duplex = FAL_FULL_DUPLEX;
else
*duplex = FAL_HALF_DUPLEX;
return 0;
}
u32 aq_phy_get_speed(u32 dev_id, u32 phy_id, fal_port_speed_t *speed)
{
u16 phy_data;
uint32_t reg;
reg = AQ_PHY_LINK_STATUS_REG | AQUANTIA_MII_ADDR_C45;
phy_data = aq_phy_reg_read(dev_id, phy_id, reg);
switch ((phy_data >> 1) & 0x7) {
case SPEED_10G:
*speed = FAL_SPEED_10000;
break;
case SPEED_5G:
*speed = FAL_SPEED_5000;
break;
case SPEED_2_5G:
*speed = FAL_SPEED_2500;
break;
case SPEED_1000MBS:
*speed = FAL_SPEED_1000;
break;
case SPEED_100MBS:
*speed = FAL_SPEED_100;
break;
case SPEED_10MBS:
*speed = FAL_SPEED_10;
break;
default:
return -EINVAL;
}
return 0;
}
void aquantia_phy_restart_autoneg(u32 phy_id)
{
u16 phy_data;
phy_data = aq_phy_reg_read(0x0, phy_id, AQUANTIA_REG_ADDRESS(AQUANTIA_MMD_PHY_XS_REGISTERS,
AQUANTIA_PHY_XS_USX_TRANSMIT));
if (!(phy_data & AQUANTIA_PHY_USX_AUTONEG_ENABLE))
aq_phy_reg_write(0x0, phy_id,AQUANTIA_REG_ADDRESS(
AQUANTIA_MMD_PHY_XS_REGISTERS,
AQUANTIA_PHY_XS_USX_TRANSMIT),
phy_data | AQUANTIA_PHY_USX_AUTONEG_ENABLE);
phy_data = aq_phy_reg_read(0x0, phy_id, AQUANTIA_REG_ADDRESS(AQUANTIA_MMD_AUTONEG,
AQUANTIA_AUTONEG_STANDARD_CONTROL1));
phy_data |= AQUANTIA_CTRL_AUTONEGOTIATION_ENABLE;
aq_phy_reg_write(0x0, phy_id, AQUANTIA_REG_ADDRESS(AQUANTIA_MMD_AUTONEG,
AQUANTIA_AUTONEG_STANDARD_CONTROL1),
phy_data | AQUANTIA_CTRL_RESTART_AUTONEGOTIATION);
}
int ipq_qca_aquantia_phy_init(struct phy_ops **ops, u32 phy_id)
{
u16 phy_data;
struct phy_ops *aq_phy_ops;
aq_phy_ops = (struct phy_ops *)malloc(sizeof(struct phy_ops));
if (!aq_phy_ops)
return -ENOMEM;
aq_phy_ops->phy_get_link_status = aq_phy_get_link_status;
aq_phy_ops->phy_get_speed = aq_phy_get_speed;
aq_phy_ops->phy_get_duplex = aq_phy_get_duplex;
*ops = aq_phy_ops;
phy_data = aq_phy_reg_read(0x0, phy_id, AQUANTIA_REG_ADDRESS(AQUANTIA_MMD_PHY_XS_REGISTERS,
AQUANTIA_PHY_XS_USX_TRANSMIT));
phy_data = aq_phy_reg_read(0x0, phy_id, AQUANTIA_REG_ADDRESS(1, QCA_PHY_ID1));
printf ("PHY ID1: 0x%x\n", phy_data);
phy_data = aq_phy_reg_read(0x0, phy_id, AQUANTIA_REG_ADDRESS(1, QCA_PHY_ID2));
printf ("PHY ID2: 0x%x\n", phy_data);
phy_data = aq_phy_reg_read(0x0, phy_id, AQUANTIA_REG_ADDRESS(AQUANTIA_MMD_PHY_XS_REGISTERS,
AQUANTIA_PHY_XS_USX_TRANSMIT));
phy_data |= AQUANTIA_PHY_USX_AUTONEG_ENABLE;
aq_phy_reg_write(0x0, phy_id, AQUANTIA_REG_ADDRESS(AQUANTIA_MMD_PHY_XS_REGISTERS,
AQUANTIA_PHY_XS_USX_TRANSMIT), phy_data);
phy_data = aq_phy_reg_read(0x0, phy_id, AQUANTIA_REG_ADDRESS(AQUANTIA_MMD_AUTONEG,
AQUANTIA_AUTONEG_TRANSMIT_VENDOR_INTR_MASK));
phy_data |= AQUANTIA_INTR_LINK_STATUS_CHANGE;
aq_phy_reg_write(0x0, phy_id, AQUANTIA_REG_ADDRESS(AQUANTIA_MMD_AUTONEG,
AQUANTIA_AUTONEG_TRANSMIT_VENDOR_INTR_MASK), phy_data);
phy_data = aq_phy_reg_read(0x0, phy_id, AQUANTIA_REG_ADDRESS(AQUANTIA_MMD_GLOABLE_REGISTERS,
AQUANTIA_GLOBAL_INTR_STANDARD_MASK));
phy_data |= AQUANTIA_ALL_VENDOR_ALARMS_INTERRUPT_MASK;
aq_phy_reg_write(0x0, phy_id, AQUANTIA_REG_ADDRESS(AQUANTIA_MMD_GLOABLE_REGISTERS,
AQUANTIA_GLOBAL_INTR_STANDARD_MASK), phy_data);
phy_data = aq_phy_reg_read(0x0, phy_id, AQUANTIA_REG_ADDRESS(AQUANTIA_MMD_GLOABLE_REGISTERS,
AQUANTIA_GLOBAL_INTR_VENDOR_MASK));
phy_data |= AQUANTIA_AUTO_AND_ALARMS_INTR_MASK;
aq_phy_reg_write(0x0, phy_id, AQUANTIA_REG_ADDRESS(AQUANTIA_MMD_GLOABLE_REGISTERS,
AQUANTIA_GLOBAL_INTR_VENDOR_MASK), phy_data);
phy_data = aq_phy_reg_read(0x0, phy_id, AQUANTIA_REG_ADDRESS(AQUANTIA_MMD_PHY_XS_REGISTERS,
AQUANTIA_PHY_XS_USX_TRANSMIT));
return 0;
}
static int do_aq_phy_restart(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
unsigned int phy_addr = AQU_PHY_ADDR;
if (argc > 2)
return CMD_RET_USAGE;
if (argc == 2)
phy_addr = simple_strtoul(argv[1], NULL, 16);
aquantia_phy_restart_autoneg(phy_addr);
return 0;
}
int ipq_board_fw_download(unsigned int phy_addr)
{
char runcmd[256];
int ret,i=0;
uint32_t start; /* block number */
uint32_t size; /* no. of blocks */
qca_part_entry_t ethphyfw;
unsigned int *ethphyfw_load_addr = NULL;
struct { char *name; qca_part_entry_t *part; } entries[] = {
{ "0:ETHPHYFW", &ethphyfw },
};
#ifdef CONFIG_QCA_MMC
block_dev_desc_t *blk_dev;
disk_partition_t disk_info;
#endif
/* check the smem info to see which flash used for booting */
if (sfi->flash_type == SMEM_BOOT_SPI_FLASH) {
if (debug) {
printf("Using nor device \n");
}
} else if (sfi->flash_type == SMEM_BOOT_NAND_FLASH) {
if (debug) {
printf("Using nand device 0\n");
}
} else if (sfi->flash_type == SMEM_BOOT_MMC_FLASH) {
if (debug) {
printf("Using MMC device\n");
}
} else if (sfi->flash_type == SMEM_BOOT_QSPI_NAND_FLASH) {
if (debug) {
printf("Using qspi nand device 0\n");
}
} else {
printf("Unsupported BOOT flash type\n");
return -1;
}
ret = smem_getpart(entries[i].name, &start, &size);
if (ret < 0) {
debug("cdp: get part failed for %s\n", entries[i].name);
} else {
qca_set_part_entry(entries[i].name, sfi, entries[i].part, start, size);
}
if ((sfi->flash_type == SMEM_BOOT_NAND_FLASH) ||
(sfi->flash_type == SMEM_BOOT_QSPI_NAND_FLASH) ||
(sfi->flash_type == SMEM_BOOT_SPI_FLASH)) {
ethphyfw_load_addr = (uint *)malloc(AQ_ETHPHYFW_IMAGE_SIZE);
/* We only need memory equivalent to max size ETHPHYFW
* which is currently assumed as 512 KB.
*/
if (ethphyfw_load_addr == NULL) {
printf("ETHPHYFW Loading failed, size = %llu\n",
ethphyfw.size);
return -1;
} else {
memset(ethphyfw_load_addr, 0, AQ_ETHPHYFW_IMAGE_SIZE);
}
}
if ((sfi->flash_type == SMEM_BOOT_NAND_FLASH) ||
(sfi->flash_type == SMEM_BOOT_QSPI_NAND_FLASH)) {
/*
* Kernel is in a separate partition
*/
snprintf(runcmd, sizeof(runcmd),
/* NOR is treated as psuedo NAND */
"nand read 0x%p 0x%llx 0x%llx && ",
ethphyfw_load_addr, ethphyfw.offset, (long long unsigned int) AQ_ETHPHYFW_IMAGE_SIZE);
if (debug)
printf("%s", runcmd);
if (run_command(runcmd, 0) != CMD_RET_SUCCESS) {
free(ethphyfw_load_addr);
return CMD_RET_FAILURE;
}
} else if (sfi->flash_type == SMEM_BOOT_SPI_FLASH) {
snprintf(runcmd, sizeof(runcmd),
"sf probe && " "sf read 0x%p 0x%llx 0x%llx && ",
ethphyfw_load_addr, ethphyfw.offset, (long long unsigned int) AQ_ETHPHYFW_IMAGE_SIZE);
if (debug)
printf("%s", runcmd);
if (run_command(runcmd, 0) != CMD_RET_SUCCESS) {
free(ethphyfw_load_addr);
return CMD_RET_FAILURE;
}
#ifdef CONFIG_QCA_MMC
} else if (sfi->flash_type == SMEM_BOOT_MMC_FLASH ) {
blk_dev = mmc_get_dev(host->dev_num);
ret = get_partition_info_efi_by_name(blk_dev,
"0:ETHPHYFW", &disk_info);
ethphyfw_load_addr = (uint *)malloc(((uint)disk_info.size) *
((uint)disk_info.blksz));
if (ethphyfw_load_addr == NULL) {
printf("ETHPHYFW Loading failed, size = %lu\n",
((long unsigned int)(uint)disk_info.size) * ((uint)disk_info.blksz));
return -1;
} else {
memset(ethphyfw_load_addr, 0,
(((uint)disk_info.size) *
((uint)disk_info.blksz)));
}
if (ret == 0) {
snprintf(runcmd, sizeof(runcmd),
"mmc read 0x%p 0x%X 0x%X",
ethphyfw_load_addr,
(uint)disk_info.start, (uint)disk_info.size);
if (run_command(runcmd, 0) != CMD_RET_SUCCESS) {
free(ethphyfw_load_addr);
return CMD_RET_FAILURE;
}
}
#endif
}
fwimg_header = (mbn_header_t *)(ethphyfw_load_addr);
if (fwimg_header->image_type == 0x13 &&
fwimg_header->header_vsn_num == 0x3) {
program_ethphy_fw(phy_addr,
(uint32_t)(((uint32_t)ethphyfw_load_addr)
+ sizeof(mbn_header_t)),
(uint32_t)(fwimg_header->image_size));
} else {
printf("bad magic on ETHPHYFW partition\n");
free(ethphyfw_load_addr);
return -1;
}
free(ethphyfw_load_addr);
return 0;
}
#define AQ_PHY_IMAGE_HEADER_CONTENT_OFFSET_HHD 0x300
static int program_ethphy_fw(unsigned int phy_addr, uint32_t load_addr, uint32_t file_size)
{
int i;
uint8_t *buf;
uint16_t file_crc;
uint16_t computed_crc;
uint32_t reg1, reg2;
uint16_t recorded_ggp8_val;
uint16_t daisy_chain_dis;
uint32_t primary_header_ptr = 0x00000000;
uint32_t primary_iram_ptr = 0x00000000;
uint32_t primary_dram_ptr = 0x00000000;
uint32_t primary_iram_sz = 0x00000000;
uint32_t primary_dram_sz = 0x00000000;
uint32_t phy_img_hdr_off;
uint32_t byte_sz;
uint32_t dword_sz;
uint32_t byte_ptr;
uint16_t msw = 0;
uint16_t lsw = 0;
uint8_t msb1;
uint8_t msb2;
uint8_t lsb1;
uint8_t lsb2;
uint16_t mailbox_crc;
aq_phy_reg_write(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0x300), 0xdead);
aq_phy_reg_write(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0x301), 0xbeaf);
reg1 = aq_phy_reg_read(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0x300));
reg2 = aq_phy_reg_read(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0x301));
if(reg1 != 0xdead && reg2 != 0xbeaf) {
printf("PHY::Scratchpad Read/Write test fail\n");
return 0;
}
buf = (uint8_t *)load_addr;
file_crc = buf[file_size - 2] << 8 | buf[file_size - 1];
computed_crc = cyg_crc16(buf, file_size - 2);
if (file_crc != computed_crc) {
printf("CRC check failed on phy fw file\n");
return 0;
} else {
printf("CRC check good on phy fw file (0x%04X)\n",computed_crc);
}
daisy_chain_dis = aq_phy_reg_read(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0xc452));
if (!(daisy_chain_dis & 0x1))
aq_phy_reg_write(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0xc452), 0x1);
aq_phy_reg_write(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0xc471), 0x40);
recorded_ggp8_val = aq_phy_reg_read(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0xc447));
if ((recorded_ggp8_val & 0x1f) != phy_addr)
aq_phy_reg_write(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0xc447), phy_addr);
aq_phy_reg_write(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0xc441), 0x4000);
aq_phy_reg_write(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0xc001), 0x41);
primary_header_ptr = (((buf[0x9] & 0x0F) << 8) | buf[0x8]) << 12;
phy_img_hdr_off = AQ_PHY_IMAGE_HEADER_CONTENT_OFFSET_HHD;
primary_iram_ptr = (buf[primary_header_ptr + phy_img_hdr_off + 0x4 + 2] << 16) |
(buf[primary_header_ptr + phy_img_hdr_off + 0x4 + 1] << 8) |
buf[primary_header_ptr + phy_img_hdr_off + 0x4];
primary_iram_sz = (buf[primary_header_ptr + phy_img_hdr_off + 0x7 + 2] << 16) |
(buf[primary_header_ptr + phy_img_hdr_off + 0x7 + 1] << 8) |
buf[primary_header_ptr + phy_img_hdr_off + 0x7];
primary_dram_ptr = (buf[primary_header_ptr + phy_img_hdr_off + 0xA + 2] << 16) |
(buf[primary_header_ptr + phy_img_hdr_off + 0xA + 1] << 8) |
buf[primary_header_ptr + phy_img_hdr_off + 0xA];
primary_dram_sz = (buf[primary_header_ptr + phy_img_hdr_off + 0xD + 2] << 16) |
(buf[primary_header_ptr + phy_img_hdr_off + 0xD + 1] << 8) |
buf[primary_header_ptr + phy_img_hdr_off + 0xD];
primary_iram_ptr += primary_header_ptr;
primary_dram_ptr += primary_header_ptr;
aq_phy_reg_write(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0x200), 0x1000);
aq_phy_reg_write(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0x200), 0x0);
computed_crc = 0;
printf("PHYFW:Loading IRAM...........");
aq_phy_reg_write(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0x202), 0x4000);
aq_phy_reg_write(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0x203), 0x0);
byte_sz = primary_iram_sz;
dword_sz = byte_sz >> 2;
byte_ptr = primary_iram_ptr;
for (i = 0; i < dword_sz; i++) {
lsw = (buf[byte_ptr + 1] << 8) | buf[byte_ptr];
byte_ptr += 2;
msw = (buf[byte_ptr + 1] << 8) | buf[byte_ptr];
byte_ptr += 2;
aq_phy_reg_write(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0x204), msw);
aq_phy_reg_write(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0x205), lsw);
aq_phy_reg_write(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0x200), 0xc000);
msb1 = msw >> 8;
msb2 = msw & 0xFF;
lsb1 = lsw >> 8;
lsb2 = lsw & 0xFF;
computed_crc = cyg_crc16_computed(&msb1, 0x1, computed_crc);
computed_crc = cyg_crc16_computed(&msb2, 0x1, computed_crc);
computed_crc = cyg_crc16_computed(&lsb1, 0x1, computed_crc);
computed_crc = cyg_crc16_computed(&lsb2, 0x1, computed_crc);
}
switch (byte_sz & 0x3) {
case 0x1:
lsw = buf[byte_ptr++];
msw = 0x0000;
break;
case 0x2:
lsw = (buf[byte_ptr + 1] << 8) | buf[byte_ptr];
byte_ptr += 2;
msw = 0x0000;
break;
case 0x3:
lsw = (buf[byte_ptr + 1] << 8) | buf[byte_ptr];
byte_ptr += 2;
msw = buf[byte_ptr++];
break;
}
if (byte_sz & 0x3) {
aq_phy_reg_write(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0x204), msw);
aq_phy_reg_write(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0x205), lsw);
aq_phy_reg_write(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0x200), 0xc000);
msb1 = msw >> 8;
msb2 = msw & 0xFF;
lsb1 = lsw >> 8;
lsb2 = lsw & 0xFF;
computed_crc = cyg_crc16_computed(&msb1, 0x1, computed_crc);
computed_crc = cyg_crc16_computed(&msb2, 0x1, computed_crc);
computed_crc = cyg_crc16_computed(&lsb1, 0x1, computed_crc);
computed_crc = cyg_crc16_computed(&lsb2, 0x1, computed_crc);
}
printf("done.\n");
printf("PHYFW:Loading DRAM..............");
aq_phy_reg_write(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0x202), 0x3ffe);
aq_phy_reg_write(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0x203), 0x0);
byte_sz = primary_dram_sz;
dword_sz = byte_sz >> 2;
byte_ptr = primary_dram_ptr;
for (i = 0; i < dword_sz; i++) {
lsw = (buf[byte_ptr + 1] << 8) | buf[byte_ptr];
byte_ptr += 2;
msw = (buf[byte_ptr + 1] << 8) | buf[byte_ptr];
byte_ptr += 2;
aq_phy_reg_write(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0x204), msw);
aq_phy_reg_write(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0x205), lsw);
aq_phy_reg_write(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0x200), 0xc000);
msb1 = msw >> 8;
msb2 = msw & 0xFF;
lsb1 = lsw >> 8;
lsb2 = lsw & 0xFF;
computed_crc = cyg_crc16_computed(&msb1, 0x1, computed_crc);
computed_crc = cyg_crc16_computed(&msb2, 0x1, computed_crc);
computed_crc = cyg_crc16_computed(&lsb1, 0x1, computed_crc);
computed_crc = cyg_crc16_computed(&lsb2, 0x1, computed_crc);
}
switch (byte_sz & 0x3) {
case 0x1:
lsw = buf[byte_ptr++];
msw = 0x0000;
break;
case 0x2:
lsw = (buf[byte_ptr + 1] << 8) | buf[byte_ptr];
byte_ptr += 2;
msw = 0x0000;
break;
case 0x3:
lsw = (buf[byte_ptr + 1] << 8) | buf[byte_ptr];
byte_ptr += 2;
msw = buf[byte_ptr++];
break;
}
if (byte_sz & 0x3) {
aq_phy_reg_write(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0x204), msw);
aq_phy_reg_write(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0x205), lsw);
aq_phy_reg_write(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0x200), 0xc000);
msb1 = msw >> 8;
msb2 = msw & 0xFF;
lsb1 = lsw >> 8;
lsb2 = lsw & 0xFF;
computed_crc = cyg_crc16_computed(&msb1, 0x1, computed_crc);
computed_crc = cyg_crc16_computed(&msb2, 0x1, computed_crc);
computed_crc = cyg_crc16_computed(&lsb1, 0x1, computed_crc);
computed_crc = cyg_crc16_computed(&lsb2, 0x1, computed_crc);
}
printf("done.\n");
aq_phy_reg_write(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0xc441), 0x2010);
mailbox_crc = aq_phy_reg_read(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0x201));
if (mailbox_crc != computed_crc) {
printf("phy fw image load CRC-16 (0x%X) does not match calculated CRC-16 (0x%X)\n", mailbox_crc, computed_crc);
return 0;
} else
printf("phy fw image load good CRC-16 matches (0x%X)\n", mailbox_crc);
aq_phy_reg_write(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0x0), 0x0);
aq_phy_reg_write(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0xc001), 0x41);
aq_phy_reg_write(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0xc001), 0x8041);
mdelay(100);
aq_phy_reg_write(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0xc001), 0x40);
mdelay(100);
aquantia_phy_restart_autoneg(phy_addr);
return 0;
}
static int do_load_fw(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
unsigned int phy_addr = AQU_PHY_ADDR;
int node, aquantia_port;
if (argc > 2)
return CMD_RET_USAGE;
if (argc == 2)
phy_addr = simple_strtoul(argv[1], NULL, 16);
node = fdt_path_offset(gd->fdt_blob, "/ess-switch");
if (node < 0) {
printf("Error: ess-switch not specified in dts");
return 0;
}
aquantia_port = fdtdec_get_uint(gd->fdt_blob, node, "aquantia_port", -1);
if (aquantia_port < 0) {
printf("Error: aquantia_port not specified in dts");
return 0;
}
aquantia_port = fdtdec_get_uint(gd->fdt_blob, node, "aquantia_gpio", -1);
if (aquantia_port < 0) {
printf("Error: aquantia_gpio not specified in dts");
return 0;
}
miiphy_init();
ipq9574_eth_initialize();
ipq_sw_mdio_init("IPQ MDIO0");
ipq_board_fw_download(phy_addr);
return 0;
}
U_BOOT_CMD(
aq_load_fw, 5, 1, do_load_fw,
"LOAD aq-fw-binary",
""
);
U_BOOT_CMD(
aq_phy_restart, 5, 1, do_aq_phy_restart,
"Restart Aquantia phy",
""
);

View file

@ -0,0 +1,50 @@
/*
* Copyright (c) 2017-2019, 2021, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#define AQ_ETHPHYFW_IMAGE_SIZE 0x80000
#define AQUANTIA_MII_ADDR_C45 (1<<30)
#define AQUANTIA_REG_ADDRESS(dev_ad, reg_num) (AQUANTIA_MII_ADDR_C45 |\
((dev_ad & 0x1f) << 16) | (reg_num & 0xFFFF))
#define AQUANTIA_MMD_PHY_XS_REGISTERS 4
#define AQUANTIA_PHY_XS_USX_TRANSMIT 0xc441
#define AQUANTIA_PHY_USX_AUTONEG_ENABLE 0x8
#define AQUANTIA_MMD_AUTONEG 0x7
#define AQUANTIA_AUTONEG_TRANSMIT_VENDOR_INTR_MASK 0xD401
#define AQUANTIA_INTR_LINK_STATUS_CHANGE 0x0001
#define AQUANTIA_MMD_GLOABLE_REGISTERS 0x1E
#define AQUANTIA_GLOBAL_INTR_STANDARD_MASK 0xff00
#define AQUANTIA_ALL_VENDOR_ALARMS_INTERRUPT_MASK 0x0001
#define AQUANTIA_GLOBAL_INTR_VENDOR_MASK 0xff01
#define AQUANTIA_AUTO_AND_ALARMS_INTR_MASK 0x1001
#define AQUANTIA_AUTONEG_STANDARD_CONTROL1 0
#define AQUANTIA_CTRL_AUTONEGOTIATION_ENABLE 0x1000
#define AQUANTIA_CTRL_RESTART_AUTONEGOTIATION 0x0200
#define AQ_PHY_AUTO_STATUS_REG 0x70001
#define PORT_LINK_DOWN 0
#define PORT_LINK_UP 1
#define AQ_PHY_LINK_STATUS_REG 0x7c800
#define SPEED_5G 5
#define SPEED_2_5G 4
#define SPEED_10G 3
#define SPEED_1000MBS 2
#define SPEED_100MBS 1
#define SPEED_10MBS 0

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,403 @@
/*
**************************************************************************
* Copyright (c) 2016-2019, 2021, The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
**************************************************************************
*/
#ifndef __IPQ9574_EDMA__
#define __IPQ9574_EDMA__
#define IPQ9574_NSS_DP_START_PHY_PORT 1
#define IPQ9574_NSS_DP_MAX_PHY_PORTS 6
#define IPQ9574_EDMA_DEVICE_NODE_NAME "edma"
/* Number of descriptors in each ring is defined with below macro */
#define EDMA_RING_SIZE 128
/* Number of byte in a descriptor is defined with below macros for each of
* the rings respectively */
#define IPQ9574_EDMA_TXDESC_DESC_SIZE (sizeof(struct ipq9574_edma_txdesc_desc))
#define IPQ9574_EDMA_TXCMPL_DESC_SIZE (sizeof(struct ipq9574_edma_txcmpl_desc))
#define IPQ9574_EDMA_RXDESC_DESC_SIZE (sizeof(struct ipq9574_edma_rxdesc_desc))
#define IPQ9574_EDMA_RXFILL_DESC_SIZE (sizeof(struct ipq9574_edma_rxfill_desc))
#define IPQ9574_EDMA_RX_SEC_DESC_SIZE (sizeof(struct ipq9574_edma_rx_sec_desc))
#define IPQ9574_EDMA_TX_SEC_DESC_SIZE (sizeof(struct ipq9574_edma_tx_sec_desc))
#define IPQ9574_EDMA_START_GMACS IPQ9574_NSS_DP_START_PHY_PORT
#define IPQ9574_EDMA_MAX_GMACS IPQ9574_NSS_DP_MAX_PHY_PORTS
#define IPQ9574_EDMA_TX_BUFF_SIZE 1572
#define IPQ9574_EDMA_RX_BUFF_SIZE 2048
/* Max number of rings of each type is defined with below macro */
#define IPQ9574_EDMA_MAX_TXCMPL_RINGS 32 /* Max TxCmpl rings */
#define IPQ9574_EDMA_MAX_RXDESC_RINGS 24 /* Max RxDesc rings */
#define IPQ9574_EDMA_MAX_RXFILL_RINGS 8 /* Max RxFill rings */
#define IPQ9574_EDMA_MAX_TXDESC_RINGS 32 /* Max TxDesc rings */
#define IPQ9574_EDMA_GET_DESC(R, i, type) (&(((type *)((R)->desc))[i]))
#define IPQ9574_EDMA_RXFILL_DESC(R, i) IPQ9574_EDMA_GET_DESC(R, i, struct ipq9574_edma_rxfill_desc)
#define IPQ9574_EDMA_RXDESC_DESC(R, i) IPQ9574_EDMA_GET_DESC(R, i, struct ipq9574_edma_rxdesc_desc)
#define IPQ9574_EDMA_TXDESC_DESC(R, i) IPQ9574_EDMA_GET_DESC(R, i, struct ipq9574_edma_txdesc_desc)
#define IPQ9574_EDMA_TXCMPL_DESC(R, i) IPQ9574_EDMA_GET_DESC(R, i, struct ipq9574_edma_txcmpl_desc)
#define IPQ9574_EDMA_RXPH_SRC_INFO_TYPE_GET(rxph) (((rxph & 0xffff) >> 8) & 0xf0)
#define IPQ9574_EDMA_DEV 1
#define IPQ9574_EDMA_TX_QUEUE 1
#define IPQ9574_EDMA_RX_QUEUE 1
/* Only 1 ring of each type will be used in U-Boot which is defined with
* below macros */
#define IPQ9574_EDMA_TX_DESC_RING_START 23
#define IPQ9574_EDMA_TX_DESC_RING_NOS 1
#define IPQ9574_EDMA_TX_DESC_RING_SIZE \
(IPQ9574_EDMA_TX_DESC_RING_START + IPQ9574_EDMA_TX_DESC_RING_NOS)
#define IPQ9574_EDMA_SEC_TX_DESC_RING_START 31
#define IPQ9574_EDMA_SEC_TX_DESC_RING_NOS 1
#define IPQ9574_EDMA_SEC_TX_DESC_RING_SIZE \
(IPQ9574_EDMA_SEC_TX_DESC_RING_START + IPQ9574_EDMA_SEC_TX_DESC_RING_NOS)
#define IPQ9574_EDMA_TX_CMPL_RING_START 31
#define IPQ9574_EDMA_TX_CMPL_RING_NOS 1
#define IPQ9574_EDMA_TX_CMPL_RING_SIZE \
(IPQ9574_EDMA_TX_CMPL_RING_START + IPQ9574_EDMA_TX_CMPL_RING_NOS)
#define IPQ9574_EDMA_RX_DESC_RING_START 15
#define IPQ9574_EDMA_RX_DESC_RING_NOS 1
#define IPQ9574_EDMA_RX_DESC_RING_SIZE \
(IPQ9574_EDMA_RX_DESC_RING_START + IPQ9574_EDMA_RX_DESC_RING_NOS)
#define IPQ9574_EDMA_SEC_RX_DESC_RING_START 15
#define IPQ9574_EDMA_SEC_RX_DESC_RING_NOS 1
#define IPQ9574_EDMA_SEC_RX_DESC_RING_SIZE \
(IPQ9574_EDMA_SEC_RX_DESC_RING_START + IPQ9574_EDMA_SEC_RX_DESC_RING_NOS)
#define IPQ9574_EDMA_RX_FILL_RING_START 7
#define IPQ9574_EDMA_RX_FILL_RING_NOS 1
#define IPQ9574_EDMA_RX_FILL_RING_SIZE \
(IPQ9574_EDMA_RX_FILL_RING_START + IPQ9574_EDMA_RX_FILL_RING_NOS)
#define NETDEV_TX_BUSY 1
/*
* RxDesc descriptor
*/
struct ipq9574_edma_rxdesc_desc {
uint32_t rdes0;
/* buffer_address_lo */
uint32_t rdes1;
/* valid toggle, more, int_pri, drop_prec, reserved x 3,
* tunnel_type, tunnel_term_ind, cpu_code_valid, known_ind,
* wifi_qos_flag, wifi_qos, buffer_address_hi */
uint32_t rdes2;
/* opaque_lo */
uint32_t rdes3;
/* opaque_hi */
uint32_t rdes4;
/* dst_info, src_info */
uint32_t rdes5;
/* dspcp, pool_id, data_lengh */
uint32_t rdes6;
/* hash_value, hash_flag, l3_csum_status, l4_csum_status,
* data_offset */
uint32_t rdes7;
/* l4_offset, l3_offset, pid, CVLAN flag, SVLAN flag, PPPOE flag
* service_code */
};
/*
* RxFill descriptor
*/
struct ipq9574_edma_rxfill_desc {
uint32_t rdes0;
/* buffer_address_lo */
uint32_t rdes1;
/* buffer_size, reserved x 1, buffer_address_hi */
uint32_t rdes2;
/* opaque_lo */
uint32_t rdes3;
/* opaque_hu */
};
/*
* TxDesc descriptor
*/
struct ipq9574_edma_txdesc_desc {
uint32_t tdes0;
/* buffer_address_lo */
uint32_t tdes1;
/* reserved x 1, more, int_pri, drop_prec, reserved x 4,
* buff_recycling, fake_mac_header,ptp_tag_flag, pri_valid,
* buffer_address_high_bits_tbi, buffer_address_hi */
uint32_t tdes2;
/* opaque_lo */
uint32_t tdes3;
/* opaque_hi */
uint32_t tdes4;
/* dst_info, src_info */
uint32_t tdes5;
/* adv_offload_en, vlan_offload_en, frm_fmt_indication_en,
* edit_offload_en, csum_mode, ip_csum_en, tso_en, pool_id,
* data_lengh */
uint32_t tdes6;
/* mss/hash_value/pip_tag, hash_flag, reserved x 2,
* data_offset */
uint32_t tdes7;
/* l4_offset, l3_offset, reserved, prot_type, l2_type,
* CVLAN flag, SVLAN flag, PPPOE flag, service_code */
};
/*
* TxCmpl descriptor
*/
struct ipq9574_edma_txcmpl_desc {
uint32_t tdes0;
/* buffer_address_lo */
uint32_t tdes1;
/* buffer_size, reserved x 1, buffer_address_hi */
uint32_t tdes2;
/* opaque_lo */
uint32_t tdes3;
/* opaque_hu */
};
/*
* EDMA Rx Secondary Descriptor
*/
struct ipq9574_edma_rx_sec_desc {
uint32_t rx_sec0;
uint32_t rx_sec1;
uint32_t rx_sec2;
uint32_t rx_sec3;
uint32_t rx_sec4;
uint32_t rx_sec5;
uint32_t rx_sec6;
uint32_t rx_sec7;
};
/*
* EDMA Tx Secondary Descriptor
*/
struct ipq9574_edma_tx_sec_desc {
uint32_t tx_sec0;
uint32_t tx_sec1;
uint32_t rx_sec2;
uint32_t rx_sec3;
uint32_t rx_sec4;
uint32_t rx_sec5;
uint32_t rx_sec6;
uint32_t rx_sec7;
};
/*
* secondary Tx descriptor ring
*/
struct ipq9574_edma_sec_txdesc_ring {
uint32_t id; /* TXDESC ring number */
void *desc; /* descriptor ring virtual address */
dma_addr_t dma; /* descriptor ring physical address */
uint16_t count; /* number of descriptors */
};
/*
* Tx descriptor ring
*/
struct ipq9574_edma_txdesc_ring {
uint32_t id; /* TXDESC ring number */
void *desc; /* descriptor ring virtual address */
dma_addr_t dma; /* descriptor ring physical address */
uint16_t count; /* number of descriptors */
};
/*
* TxCmpl ring
*/
struct ipq9574_edma_txcmpl_ring {
uint32_t id; /* TXCMPL ring number */
void *desc; /* descriptor ring virtual address */
dma_addr_t dma; /* descriptor ring physical address */
uint16_t count; /* number of descriptors in the ring */
};
/*
* RxFill ring
*/
struct ipq9574_edma_rxfill_ring {
uint32_t id; /* RXFILL ring number */
void *desc; /* descriptor ring virtual address */
dma_addr_t dma; /* descriptor ring physical address */
uint16_t count; /* number of descriptors in the ring */
};
/*
* secondary RxDesc ring
*/
struct ipq9574_edma_sec_rxdesc_ring {
uint32_t id; /* RXDESC ring number */
void *desc; /* descriptor ring virtual address */
dma_addr_t dma; /* descriptor ring physical address */
uint16_t count; /* number of descriptors in the ring */
};
/*
* RxDesc ring
*/
struct ipq9574_edma_rxdesc_ring {
uint32_t id; /* RXDESC ring number */
struct ipq9574_edma_rxfill_ring *rxfill; /* RXFILL ring used */
void *desc; /* descriptor ring virtual address */
dma_addr_t dma; /* descriptor ring physical address */
uint16_t count; /* number of descriptors in the ring */
};
enum ipq9574_edma_tx {
EDMA_TX_OK = 0, /* Tx success */
EDMA_TX_DESC = 1, /* Not enough descriptors */
EDMA_TX_FAIL = 2, /* Tx failure */
};
/* per core queue related information */
struct queue_per_cpu_info {
u32 tx_mask; /* tx interrupt mask */
u32 rx_mask; /* rx interrupt mask */
u32 tx_status; /* tx interrupt status */
u32 rx_status; /* rx interrupt status */
u32 tx_start; /* tx queue start */
u32 rx_start; /* rx queue start */
struct ipq9574_edma_common_info *c_info; /* edma common info */
};
/* edma hw specific data */
struct ipq9574_edma_hw {
unsigned long __iomem *hw_addr; /* inner register address */
u8 intr_clear_type; /* interrupt clear */
u8 intr_sw_idx_w; /* To do chk type interrupt software index */
u16 rx_buff_size; /* To do chk type Rx buffer size */
u8 rss_type; /* rss protocol type */
uint16_t rx_payload_offset; /* start of the payload offset */
uint32_t flags; /* internal flags */
int active; /* status */
struct ipq9574_edma_txdesc_ring *txdesc_ring; /* Tx Descriptor Ring, SW is producer */
struct ipq9574_edma_sec_txdesc_ring *sec_txdesc_ring; /* secondary Tx Descriptor Ring, SW is producer */
struct ipq9574_edma_txcmpl_ring *txcmpl_ring; /* Tx Completion Ring, SW is consumer */
struct ipq9574_edma_rxdesc_ring *rxdesc_ring; /* Rx Descriptor Ring, SW is consumer */
struct ipq9574_edma_sec_rxdesc_ring *sec_rxdesc_ring; /* secondary Rx Descriptor Ring, SW is consumer */
struct ipq9574_edma_rxfill_ring *rxfill_ring; /* Rx Fill Ring, SW is producer */
uint32_t txdesc_rings; /* Number of TxDesc rings */
uint32_t txdesc_ring_start; /* Id of first TXDESC ring */
uint32_t txdesc_ring_end; /* Id of the last TXDESC ring */
uint32_t sec_txdesc_rings; /* Number of secondary TxDesc rings */
uint32_t sec_txdesc_ring_start; /* Id of first secondary TxDesc ring */
uint32_t sec_txdesc_ring_end; /* Id of last secondary TxDesc ring */
uint32_t txcmpl_rings; /* Number of TxCmpl rings */
uint32_t txcmpl_ring_start; /* Id of first TXCMPL ring */
uint32_t txcmpl_ring_end; /* Id of last TXCMPL ring */
uint32_t rxfill_rings; /* Number of RxFill rings */
uint32_t rxfill_ring_start; /* Id of first RxFill ring */
uint32_t rxfill_ring_end; /* Id of last RxFill ring */
uint32_t rxdesc_rings; /* Number of RxDesc rings */
uint32_t rxdesc_ring_start; /* Id of first RxDesc ring */
uint32_t rxdesc_ring_end; /* Id of last RxDesc ring */
uint32_t sec_rxdesc_rings; /* Number of secondary RxDesc rings */
uint32_t sec_rxdesc_ring_start; /* Id of first secondary RxDesc ring */
uint32_t sec_rxdesc_ring_end; /* Id of last secondary RxDesc ring */
uint32_t tx_intr_mask; /* tx interrupt mask */
uint32_t rx_intr_mask; /* rx interrupt mask */
uint32_t rxfill_intr_mask; /* Rx fill ring interrupt mask */
uint32_t rxdesc_intr_mask; /* Rx Desc ring interrupt mask */
uint32_t txcmpl_intr_mask; /* Tx Cmpl ring interrupt mask */
uint32_t misc_intr_mask; /* misc interrupt interrupt mask */
};
struct ipq9574_edma_common_info {
struct ipq9574_edma_hw hw;
};
#define MAX_PHY 6
struct ipq9574_eth_dev {
u8 *phy_address;
uint no_of_phys;
uint interface;
uint speed;
uint duplex;
uint sw_configured;
uint mac_unit;
uint mac_ps;
int link_printed;
u32 padding;
struct eth_device *dev;
struct ipq9574_edma_common_info *c_info;
struct phy_ops *ops[MAX_PHY];
const char phy_name[MDIO_NAME_LEN];
} __attribute__ ((aligned(8)));
static inline void* ipq9574_alloc_mem(u32 size)
{
void *p = malloc(size);
if (p != NULL)
memset(p, 0, size);
return p;
}
static inline void* ipq9574_alloc_memalign(u32 size)
{
void *p = memalign(CONFIG_SYS_CACHELINE_SIZE, size);
if (p != NULL)
memset(p, 0, size);
return p;
}
static inline void ipq9574_free_mem(void *ptr)
{
if (ptr)
free(ptr);
}
uint32_t ipq9574_edma_reg_read(uint32_t reg_off);
void ipq9574_edma_reg_write(uint32_t reg_off, uint32_t val);
extern int get_eth_mac_address(uchar *enetaddr, uint no_of_macs);
typedef struct {
uint count;
u8 addr[7];
} ipq9574_edma_phy_addr_t;
/* ipq9574 edma Paramaters */
typedef struct {
uint base;
int unit;
uint mac_conn_to_phy;
phy_interface_t phy;
ipq9574_edma_phy_addr_t phy_addr;
char phy_name[MDIO_NAME_LEN];
} ipq9574_edma_board_cfg_t;
extern void ipq9574_ppe_provision_init(void);
extern void ipq9574_port_mac_clock_reset(int port);
extern void ipq9574_speed_clock_set(int port, int clk[4]);
extern void ipq9574_pqsgmii_speed_set(int port, int speed, int status);
extern void ipq9574_uxsgmii_speed_set(int port, int speed, int duplex, int status);
extern void ppe_port_mux_mac_type_set(int port_id, int mode);
extern void ppe_port_bridge_txmac_set(int port, int status);
extern void ipq9574_10g_r_speed_set(int port, int status);
extern int phy_status_get_from_ppe(int port_id);
extern void ipq9574_ppe_acl_set(int rule_id, int rule_type, int pkt_type, int l4_port_no, int l4_port_mask, int permit, int deny);
extern void ppe_uniphy_mode_set(uint32_t uniphy_index, uint32_t mode);
#endif /* ___IPQ9574_EDMA__ */

View file

@ -0,0 +1,977 @@
/*
**************************************************************************
* Copyright (c) 2016-2019, 2021, The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
**************************************************************************
*/
#include <common.h>
#include <asm/global_data.h>
#include "ipq9574_ppe.h"
#include "ipq9574_uniphy.h"
#include <fdtdec.h>
#include "ipq_phy.h"
DECLARE_GLOBAL_DATA_PTR;
#ifdef DEBUG
#define pr_debug(fmt, args...) printf(fmt, ##args);
#else
#define pr_debug(fmt, args...)
#endif
#define pr_info(fmt, args...) printf(fmt, ##args);
extern int is_uniphy_enabled(int uniphy_index);
extern void uniphy_port5_clock_source_set(void);
/*
* ipq9574_ppe_reg_read()
*/
static inline void ipq9574_ppe_reg_read(u32 reg, u32 *val)
{
*val = readl((void *)(IPQ9574_PPE_BASE_ADDR + reg));
}
/*
* ipq9574_ppe_reg_write()
*/
static inline void ipq9574_ppe_reg_write(u32 reg, u32 val)
{
writel(val, (void *)(IPQ9574_PPE_BASE_ADDR + reg));
}
void ppe_ipo_rule_reg_set(union ipo_rule_reg_u *hw_reg, int rule_id)
{
int i;
for (i = 0; i < 3; i++) {
ipq9574_ppe_reg_write(IPO_CSR_BASE_ADDR + IPO_RULE_REG_ADDRESS +
(rule_id * IPO_RULE_REG_INC) + (i * 4), hw_reg->val[i]);
}
}
void ppe_ipo_mask_reg_set(union ipo_mask_reg_u *hw_mask, int rule_id)
{
int i;
for (i = 0; i < 2; i++) {
ipq9574_ppe_reg_write((IPO_CSR_BASE_ADDR + IPO_MASK_REG_ADDRESS +
(rule_id * IPO_MASK_REG_INC) + (i * 4)), hw_mask->val[i]);
}
}
void ppe_ipo_action_set(union ipo_action_u *hw_act, int rule_id)
{
int i;
for (i = 0; i < 5; i++) {
ipq9574_ppe_reg_write((IPE_L2_BASE_ADDR + IPO_ACTION_ADDRESS +
(rule_id * IPO_ACTION_INC) + (i * 4)), hw_act->val[i]);
}
}
void ipq9574_ppe_acl_set(int rule_id, int rule_type, int pkt_type, int l4_port_no, int l4_port_mask, int permit, int deny)
{
union ipo_rule_reg_u hw_reg = {0};
union ipo_mask_reg_u hw_mask = {0};
union ipo_action_u hw_act = {0};
memset(&hw_reg, 0, sizeof(hw_reg));
memset(&hw_mask, 0, sizeof(hw_mask));
memset(&hw_act, 0, sizeof(hw_act));
if (rule_id < MAX_RULE) {
if (rule_type == ADPT_ACL_HPPE_IPV4_DIP_RULE) {
hw_reg.bf.rule_type = ADPT_ACL_HPPE_IPV4_DIP_RULE;
hw_reg.bf.rule_field_0 = l4_port_no;
hw_reg.bf.rule_field_1 = pkt_type<<17;
hw_mask.bf.maskfield_0 = l4_port_mask;
hw_mask.bf.maskfield_1 = 7<<17;
if (permit == 0x0) {
hw_act.bf.dest_info_change_en = 1;
hw_act.bf.fwd_cmd = 0;/*forward*/
hw_reg.bf.pri = 0x1;
}
if (deny == 0x1) {
hw_act.bf.dest_info_change_en = 1;
hw_act.bf.fwd_cmd = 1;/*drop*/
hw_reg.bf.pri = 0x0;
}
hw_reg.bf.src_0 = 0x6;
hw_reg.bf.src_1 = 0x7;
ppe_ipo_rule_reg_set(&hw_reg, rule_id);
ppe_ipo_mask_reg_set(&hw_mask, rule_id);
ppe_ipo_action_set(&hw_act, rule_id);
}
}
}
/*
* ipq9574_ppe_vp_port_tbl_set()
*/
static void ipq9574_ppe_vp_port_tbl_set(int port, int vsi)
{
u32 addr = IPQ9574_PPE_L3_VP_PORT_TBL_ADDR +
(port * IPQ9574_PPE_L3_VP_PORT_TBL_INC);
ipq9574_ppe_reg_write(addr, 0x0);
ipq9574_ppe_reg_write(addr + 0x4 , 1 << 9 | vsi << 10);
ipq9574_ppe_reg_write(addr + 0x8, 0x0);
ipq9574_ppe_reg_write(addr + 0xc, 0x0);
}
/*
* ipq9574_ppe_ucast_queue_map_tbl_queue_id_set()
*/
static void ipq9574_ppe_ucast_queue_map_tbl_queue_id_set(int queue, int port)
{
uint32_t val;
ipq9574_ppe_reg_read(IPQ9574_PPE_QM_UQM_TBL +
(port * IPQ9574_PPE_UCAST_QUEUE_MAP_TBL_INC), &val);
val |= queue << 4;
ipq9574_ppe_reg_write(IPQ9574_PPE_QM_UQM_TBL +
(port * IPQ9574_PPE_UCAST_QUEUE_MAP_TBL_INC), val);
}
/*
* ipq9574_vsi_setup()
*/
static void ipq9574_vsi_setup(int vsi, uint8_t group_mask)
{
uint32_t val = (group_mask << 24 | group_mask << 16 | group_mask << 8
| group_mask);
/* Set mask */
ipq9574_ppe_reg_write(0x063800 + (vsi * 0x10), val);
/* new addr lrn en | station move lrn en */
ipq9574_ppe_reg_write(0x063804 + (vsi * 0x10), 0x9);
}
/*
* ipq9574_gmac_port_enable()
*/
static void ipq9574_gmac_port_enable(int port)
{
ipq9574_ppe_reg_write(IPQ9574_PPE_MAC_ENABLE + (0x200 * port), 0x70);
ipq9574_ppe_reg_write(IPQ9574_PPE_MAC_SPEED + (0x200 * port), 0x2);
ipq9574_ppe_reg_write(IPQ9574_PPE_MAC_MIB_CTL + (0x200 * port), 0x1);
}
void ppe_port_bridge_txmac_set(int port_id, int status)
{
uint32_t reg_value = 0;
ipq9574_ppe_reg_read(IPE_L2_BASE_ADDR + PORT_BRIDGE_CTRL_ADDRESS +
(port_id * PORT_BRIDGE_CTRL_INC), &reg_value);
if (status == 0)
reg_value |= TX_MAC_EN;
else
reg_value &= ~TX_MAC_EN;
ipq9574_ppe_reg_write(IPE_L2_BASE_ADDR + PORT_BRIDGE_CTRL_ADDRESS +
(port_id * PORT_BRIDGE_CTRL_INC), reg_value);
}
/*
* ipq9574_port_mac_clock_reset()
*/
void ipq9574_port_mac_clock_reset(int port)
{
int reg_val, reg_val1;
reg_val = readl(NSS_CC_PPE_RESET_ADDR);
reg_val1 = readl(NSS_CC_UNIPHY_MISC_RESET);
switch(port) {
case 0:
/* Assert */
reg_val |= GCC_PPE_PORT1_MAC_ARES;
reg_val1 |= GCC_PORT1_ARES;
writel(reg_val, NSS_CC_PPE_RESET_ADDR);
writel(reg_val1, NSS_CC_UNIPHY_MISC_RESET);
mdelay(150);
/* De-Assert */
reg_val = readl(NSS_CC_PPE_RESET_ADDR);
reg_val1 = readl(NSS_CC_UNIPHY_MISC_RESET);
reg_val &= ~GCC_PPE_PORT1_MAC_ARES;
reg_val1 &= ~GCC_PORT1_ARES;
break;
case 1:
/* Assert */
reg_val |= GCC_PPE_PORT2_MAC_ARES;
reg_val1 |= GCC_PORT2_ARES;
writel(reg_val, NSS_CC_PPE_RESET_ADDR);
writel(reg_val1, NSS_CC_UNIPHY_MISC_RESET);
mdelay(150);
/* De-Assert */
reg_val = readl(NSS_CC_PPE_RESET_ADDR);
reg_val1 = readl(NSS_CC_UNIPHY_MISC_RESET);
reg_val &= ~GCC_PPE_PORT2_MAC_ARES;
reg_val1 &= ~GCC_PORT2_ARES;
break;
case 2:
/* Assert */
reg_val |= GCC_PPE_PORT3_MAC_ARES;
reg_val1 |= GCC_PORT3_ARES;
writel(reg_val, NSS_CC_PPE_RESET_ADDR);
writel(reg_val1, NSS_CC_UNIPHY_MISC_RESET);
mdelay(150);
/* De-Assert */
reg_val = readl(NSS_CC_PPE_RESET_ADDR);
reg_val1 = readl(NSS_CC_UNIPHY_MISC_RESET);
reg_val &= ~GCC_PPE_PORT3_MAC_ARES;
reg_val1 &= ~GCC_PORT3_ARES;
break;
case 3:
/* Assert */
reg_val |= GCC_PPE_PORT4_MAC_ARES;
reg_val1 |= GCC_PORT4_ARES;
writel(reg_val, NSS_CC_PPE_RESET_ADDR);
writel(reg_val1, NSS_CC_UNIPHY_MISC_RESET);
mdelay(150);
/* De-Assert */
reg_val = readl(NSS_CC_PPE_RESET_ADDR);
reg_val1 = readl(NSS_CC_UNIPHY_MISC_RESET);
reg_val &= ~GCC_PPE_PORT4_MAC_ARES;
reg_val1 &= ~GCC_PORT4_ARES;
break;
case 4:
/* Assert */
reg_val |= GCC_PPE_PORT5_MAC_ARES;
reg_val1 |= GCC_PORT5_ARES;
writel(reg_val, NSS_CC_PPE_RESET_ADDR);
writel(reg_val1, NSS_CC_UNIPHY_MISC_RESET);
mdelay(150);
/* De-Assert */
reg_val = readl(NSS_CC_PPE_RESET_ADDR);
reg_val1 = readl(NSS_CC_UNIPHY_MISC_RESET);
reg_val &= ~GCC_PPE_PORT5_MAC_ARES;
reg_val1 &= ~GCC_PORT5_ARES;
break;
case 5:
/* Assert */
reg_val |= GCC_PPE_PORT6_MAC_ARES;
reg_val1 |= GCC_PORT6_ARES;
writel(reg_val, NSS_CC_PPE_RESET_ADDR);
writel(reg_val1, NSS_CC_UNIPHY_MISC_RESET);
mdelay(150);
/* De-Assert */
reg_val = readl(NSS_CC_PPE_RESET_ADDR);
reg_val1 = readl(NSS_CC_UNIPHY_MISC_RESET);
reg_val &= ~GCC_PPE_PORT6_MAC_ARES;
reg_val1 &= ~GCC_PORT6_ARES;
break;
default:
break;
}
writel(reg_val, NSS_CC_PPE_RESET_ADDR);
writel(reg_val1, NSS_CC_UNIPHY_MISC_RESET);
mdelay(150);
}
void ipq9574_speed_clock_set(int port_id, int clk[4])
{
int i;
int reg_val[6];
for (i = 0; i < 6; i++)
{
reg_val[i] = readl(NSS_CC_PORT1_RX_CMD_RCGR + (i * 0x4) + (port_id * 0x18));
}
reg_val[0] &= ~0x1;
reg_val[1] &= ~0x71f;
reg_val[2] &= ~0x1ff;
reg_val[3] &= ~0x1;
reg_val[4] &= ~0x71f;
reg_val[5] &= ~0x1ff;
reg_val[1] |= clk[0];
reg_val[2] |= clk[1];
reg_val[4] |= clk[2];
reg_val[5] |= clk[3];
/* Port Rx direction speed clock cfg */
writel(reg_val[1], NSS_CC_PORT1_RX_CMD_RCGR + 0x4 + (port_id * 0x18));
writel(reg_val[2], NSS_CC_PORT1_RX_CMD_RCGR + 0x8 + (port_id * 0x18));
writel(reg_val[0] | 0x1 , NSS_CC_PORT1_RX_CMD_RCGR + (port_id * 0x18));
/* Port Tx direction speed clock cfg */
writel(reg_val[4], NSS_CC_PORT1_RX_CMD_RCGR + 0x10 + (port_id * 0x18));
writel(reg_val[5], NSS_CC_PORT1_RX_CMD_RCGR + 0x14 + (port_id * 0x18));
writel(reg_val[3] | 0x1, NSS_CC_PORT1_RX_CMD_RCGR + 0xc + (port_id * 0x18));
}
int phy_status_get_from_ppe(int port_id)
{
uint32_t reg_field = 0;
ipq9574_ppe_reg_read(PORT_PHY_STATUS_ADDRESS, &reg_field);
if (port_id == (PORT5 - PPE_UNIPHY_INSTANCE1))
reg_field >>= PORT_PHY_STATUS_PORT5_1_OFFSET;
else
reg_field >>= PORT_PHY_STATUS_PORT6_OFFSET;
return ((reg_field >> 7) & 0x1) ? 0 : 1;
}
void ppe_xgmac_speed_set(uint32_t port, int speed)
{
uint32_t reg_value = 0;
pr_debug("\nDEBUGGING xgmac_speed_set......... PORTID = %d\n", port);
ipq9574_ppe_reg_read(PPE_SWITCH_NSS_SWITCH_XGMAC0 +
(port * NSS_SWITCH_XGMAC_MAC_TX_CONFIGURATION), &reg_value);
switch(speed) {
case 0:
case 1:
case 2:
reg_value &=~USS;
reg_value |=SS(XGMAC_SPEED_SELECT_1000M);
break;
case 3:
reg_value |=USS;
reg_value |=SS(XGMAC_SPEED_SELECT_10000M);
break;
case 4:
reg_value |=USS;
reg_value |=SS(XGMAC_SPEED_SELECT_2500M);
break;
case 5:
reg_value |=USS;
reg_value |=SS(XGMAC_SPEED_SELECT_5000M);
break;
}
reg_value |=JD;
ipq9574_ppe_reg_write(PPE_SWITCH_NSS_SWITCH_XGMAC0 +
(port * NSS_SWITCH_XGMAC_MAC_TX_CONFIGURATION), reg_value);
pr_debug("NSS_SWITCH_XGMAC_MAC_TX_CONFIGURATION Address = 0x%x -> Value = %u\n",
PPE_SWITCH_NSS_SWITCH_XGMAC0 + (port * NSS_SWITCH_XGMAC_MAC_TX_CONFIGURATION),
reg_value);
}
void ppe_xgmac_10g_r_speed_set(uint32_t port)
{
uint32_t reg_value = 0;
pr_debug("DEBUGGING 10g_r_speed_set......... PORTID = %d\n", port);
ipq9574_ppe_reg_read(PPE_SWITCH_NSS_SWITCH_XGMAC0 +
(port * NSS_SWITCH_XGMAC_MAC_TX_CONFIGURATION), &reg_value);
reg_value |=JD;
ipq9574_ppe_reg_write(PPE_SWITCH_NSS_SWITCH_XGMAC0 +
(port * NSS_SWITCH_XGMAC_MAC_TX_CONFIGURATION), reg_value);
pr_debug("NSS_SWITCH_XGMAC_MAC_TX_CONFIGURATION Address = 0x%x -> Value = %u\n",
PPE_SWITCH_NSS_SWITCH_XGMAC0 + (port * NSS_SWITCH_XGMAC_MAC_TX_CONFIGURATION),
reg_value);
}
void ppe_port_txmac_status_set(uint32_t port)
{
uint32_t reg_value = 0;
pr_debug("DEBUGGING txmac_status_set......... PORTID = %d\n", port);
ipq9574_ppe_reg_read(PPE_SWITCH_NSS_SWITCH_XGMAC0 +
(port * NSS_SWITCH_XGMAC_MAC_TX_CONFIGURATION), &reg_value);
reg_value |=TE;
ipq9574_ppe_reg_write(PPE_SWITCH_NSS_SWITCH_XGMAC0 +
(port * NSS_SWITCH_XGMAC_MAC_TX_CONFIGURATION), reg_value);
pr_debug("NSS_SWITCH_XGMAC_MAC_TX_CONFIGURATION Address = 0x%x -> Value = %u\n",
PPE_SWITCH_NSS_SWITCH_XGMAC0 + (port * NSS_SWITCH_XGMAC_MAC_TX_CONFIGURATION),
reg_value);
}
void ppe_port_rxmac_status_set(uint32_t port)
{
uint32_t reg_value = 0;
pr_debug("DEBUGGING rxmac_status_set......... PORTID = %d\n", port);
ipq9574_ppe_reg_read(PPE_SWITCH_NSS_SWITCH_XGMAC0 +
MAC_RX_CONFIGURATION_ADDRESS +
(port * NSS_SWITCH_XGMAC_MAC_RX_CONFIGURATION), &reg_value);
reg_value |= 0x5ee00c0;
reg_value |=RE;
reg_value |=ACS;
reg_value |=CST;
ipq9574_ppe_reg_write(PPE_SWITCH_NSS_SWITCH_XGMAC0 +
MAC_RX_CONFIGURATION_ADDRESS +
(port * NSS_SWITCH_XGMAC_MAC_RX_CONFIGURATION), reg_value);
pr_debug("NSS_SWITCH_XGMAC_MAC_RX_CONFIGURATION Address = 0x%x -> Value = %u\n",
PPE_SWITCH_NSS_SWITCH_XGMAC0 + MAC_RX_CONFIGURATION_ADDRESS +
(port * NSS_SWITCH_XGMAC_MAC_RX_CONFIGURATION),
reg_value);
}
void ppe_mac_packet_filter_set(uint32_t port)
{
pr_debug("DEBUGGING mac_packet_filter_set......... PORTID = %d\n", port);
ipq9574_ppe_reg_write(PPE_SWITCH_NSS_SWITCH_XGMAC0 +
MAC_PACKET_FILTER_ADDRESS +
(port * MAC_PACKET_FILTER_INC), 0x81);
pr_debug("NSS_SWITCH_XGMAC_MAC_PACKET_FILTER Address = 0x%x -> Value = %u\n",
PPE_SWITCH_NSS_SWITCH_XGMAC0 + MAC_PACKET_FILTER_ADDRESS +
(port * MAC_PACKET_FILTER_ADDRESS),
0x81);
}
void ipq9574_10g_r_speed_set(int port, int status)
{
ppe_xgmac_10g_r_speed_set(port);
ppe_port_bridge_txmac_set(port + 1, status);
ppe_port_txmac_status_set(port);
ppe_port_rxmac_status_set(port);
ppe_mac_packet_filter_set(port);
}
void ipq9574_uxsgmii_speed_set(int port, int speed, int duplex,
int status)
{
uint32_t uniphy_index;
/* Setting the speed only for PORT5 and PORT6 */
if (port == (PORT5 - PPE_UNIPHY_INSTANCE1))
uniphy_index = PPE_UNIPHY_INSTANCE1;
else if (port == (PORT6 - PPE_UNIPHY_INSTANCE1))
uniphy_index = PPE_UNIPHY_INSTANCE2;
else
uniphy_index = PPE_UNIPHY_INSTANCE0;
ppe_uniphy_usxgmii_autoneg_completed(uniphy_index);
ppe_uniphy_usxgmii_speed_set(uniphy_index, speed);
ppe_xgmac_speed_set(port, speed);
ppe_uniphy_usxgmii_duplex_set(uniphy_index, duplex);
ppe_uniphy_usxgmii_port_reset(uniphy_index);
ppe_port_bridge_txmac_set(port + 1, status);
ppe_port_txmac_status_set(port);
ppe_port_rxmac_status_set(port);
ppe_mac_packet_filter_set(port);
}
void ipq9574_pqsgmii_speed_set(int port, int speed, int status)
{
ppe_port_bridge_txmac_set(port + 1, status);
ipq9574_ppe_reg_write(IPQ9574_PPE_MAC_SPEED + (0x200 * port), speed);
ipq9574_ppe_reg_write(IPQ9574_PPE_MAC_ENABLE + (0x200 * port), 0x73);
ipq9574_ppe_reg_write(IPQ9574_PPE_MAC_MIB_CTL + (0x200 * port), 0x5);
}
/*
* ipq9574_ppe_flow_port_map_tbl_port_num_set()
*/
static void ipq9574_ppe_flow_port_map_tbl_port_num_set(int queue, int port)
{
ipq9574_ppe_reg_write(IPQ9574_PPE_L0_FLOW_PORT_MAP_TBL +
queue * IPQ9574_PPE_L0_FLOW_PORT_MAP_TBL_INC, port);
ipq9574_ppe_reg_write(IPQ9574_PPE_L1_FLOW_PORT_MAP_TBL +
port * IPQ9574_PPE_L1_FLOW_PORT_MAP_TBL_INC, port);
}
/*
* ipq9574_ppe_flow_map_tbl_set()
*/
static void ipq9574_ppe_flow_map_tbl_set(int queue, int port)
{
uint32_t val = port | 0x401000; /* c_drr_wt = 1, e_drr_wt = 1 */
ipq9574_ppe_reg_write(IPQ9574_PPE_L0_FLOW_MAP_TBL + queue * IPQ9574_PPE_L0_FLOW_MAP_TBL_INC,
val);
val = port | 0x100400; /* c_drr_wt = 1, e_drr_wt = 1 */
ipq9574_ppe_reg_write(IPQ9574_PPE_L1_FLOW_MAP_TBL + port * IPQ9574_PPE_L1_FLOW_MAP_TBL_INC,
val);
}
/*
* ipq9574_ppe_tdm_configuration
*/
static void ipq9574_ppe_tdm_configuration(void)
{
ipq9574_ppe_reg_write(0xc000, 0x26);
ipq9574_ppe_reg_write(0xc010, 0x34);
ipq9574_ppe_reg_write(0xc020, 0x25);
ipq9574_ppe_reg_write(0xc030, 0x30);
ipq9574_ppe_reg_write(0xc040, 0x21);
ipq9574_ppe_reg_write(0xc050, 0x36);
ipq9574_ppe_reg_write(0xc060, 0x20);
ipq9574_ppe_reg_write(0xc070, 0x35);
ipq9574_ppe_reg_write(0xc080, 0x26);
ipq9574_ppe_reg_write(0xc090, 0x31);
ipq9574_ppe_reg_write(0xc0a0, 0x22);
ipq9574_ppe_reg_write(0xc0b0, 0x36);
ipq9574_ppe_reg_write(0xc0c0, 0x27);
ipq9574_ppe_reg_write(0xc0d0, 0x30);
ipq9574_ppe_reg_write(0xc0e0, 0x25);
ipq9574_ppe_reg_write(0xc0f0, 0x32);
ipq9574_ppe_reg_write(0xc100, 0x26);
ipq9574_ppe_reg_write(0xc110, 0x36);
ipq9574_ppe_reg_write(0xc120, 0x20);
ipq9574_ppe_reg_write(0xc130, 0x37);
ipq9574_ppe_reg_write(0xc140, 0x24);
ipq9574_ppe_reg_write(0xc150, 0x30);
ipq9574_ppe_reg_write(0xc160, 0x23);
ipq9574_ppe_reg_write(0xc170, 0x36);
ipq9574_ppe_reg_write(0xc180, 0x26);
ipq9574_ppe_reg_write(0xc190, 0x34);
ipq9574_ppe_reg_write(0xc1a0, 0x25);
ipq9574_ppe_reg_write(0xc1b0, 0x33);
ipq9574_ppe_reg_write(0xc1c0, 0x20);
ipq9574_ppe_reg_write(0xc1d0, 0x36);
ipq9574_ppe_reg_write(0xc1e0, 0x21);
ipq9574_ppe_reg_write(0xc1f0, 0x35);
ipq9574_ppe_reg_write(0xc200, 0x26);
ipq9574_ppe_reg_write(0xc210, 0x30);
ipq9574_ppe_reg_write(0xc220, 0x27);
ipq9574_ppe_reg_write(0xc230, 0x31);
ipq9574_ppe_reg_write(0xc240, 0x20);
ipq9574_ppe_reg_write(0xc250, 0x36);
ipq9574_ppe_reg_write(0xc260, 0x25);
ipq9574_ppe_reg_write(0xc270, 0x37);
ipq9574_ppe_reg_write(0xc280, 0x26);
ipq9574_ppe_reg_write(0xc290, 0x30);
ipq9574_ppe_reg_write(0xc2a0, 0x22);
ipq9574_ppe_reg_write(0xc2b0, 0x35);
ipq9574_ppe_reg_write(0xc2c0, 0x20);
ipq9574_ppe_reg_write(0xc2d0, 0x36);
ipq9574_ppe_reg_write(0xc2e0, 0x23);
ipq9574_ppe_reg_write(0xc2f0, 0x32);
ipq9574_ppe_reg_write(0xc300, 0x26);
ipq9574_ppe_reg_write(0xc310, 0x30);
ipq9574_ppe_reg_write(0xc320, 0x25);
ipq9574_ppe_reg_write(0xc330, 0x33);
ipq9574_ppe_reg_write(0xc340, 0x20);
ipq9574_ppe_reg_write(0xc350, 0x36);
ipq9574_ppe_reg_write(0xc360, 0x27);
ipq9574_ppe_reg_write(0xc370, 0x35);
ipq9574_ppe_reg_write(0xc380, 0x26);
ipq9574_ppe_reg_write(0xc390, 0x30);
ipq9574_ppe_reg_write(0xc3a0, 0x24);
ipq9574_ppe_reg_write(0xc3b0, 0x37);
ipq9574_ppe_reg_write(0xc3c0, 0x20);
ipq9574_ppe_reg_write(0xc3d0, 0x36);
ipq9574_ppe_reg_write(0xc3e0, 0x25);
ipq9574_ppe_reg_write(0xc3f0, 0x34);
ipq9574_ppe_reg_write(0xc400, 0x26);
ipq9574_ppe_reg_write(0xc410, 0x30);
ipq9574_ppe_reg_write(0xc420, 0x21);
ipq9574_ppe_reg_write(0xc430, 0x35);
ipq9574_ppe_reg_write(0xc440, 0x20);
ipq9574_ppe_reg_write(0xc450, 0x36);
ipq9574_ppe_reg_write(0xc460, 0x22);
ipq9574_ppe_reg_write(0xc470, 0x31);
ipq9574_ppe_reg_write(0xc480, 0x26);
ipq9574_ppe_reg_write(0xc490, 0x30);
ipq9574_ppe_reg_write(0xc4a0, 0x25);
ipq9574_ppe_reg_write(0xc4b0, 0x32);
ipq9574_ppe_reg_write(0xc4c0, 0x20);
ipq9574_ppe_reg_write(0xc4d0, 0x36);
ipq9574_ppe_reg_write(0xc4e0, 0x27);
ipq9574_ppe_reg_write(0xc4f0, 0x35);
ipq9574_ppe_reg_write(0xc500, 0x26);
ipq9574_ppe_reg_write(0xc510, 0x30);
ipq9574_ppe_reg_write(0xc520, 0x23);
ipq9574_ppe_reg_write(0xc530, 0x37);
ipq9574_ppe_reg_write(0xc540, 0x20);
ipq9574_ppe_reg_write(0xc550, 0x36);
ipq9574_ppe_reg_write(0xc560, 0x25);
ipq9574_ppe_reg_write(0xc570, 0x33);
ipq9574_ppe_reg_write(0xc580, 0x26);
ipq9574_ppe_reg_write(0xc590, 0x30);
ipq9574_ppe_reg_write(0xc5a0, 0x24);
ipq9574_ppe_reg_write(0xc5b0, 0x35);
ipq9574_ppe_reg_write(0xc5c0, 0x20);
ipq9574_ppe_reg_write(0xc5d0, 0x36);
ipq9574_ppe_reg_write(0xc5e0, 0x21);
ipq9574_ppe_reg_write(0xc5f0, 0x34);
ipq9574_ppe_reg_write(0xc600, 0x26);
ipq9574_ppe_reg_write(0xc610, 0x30);
ipq9574_ppe_reg_write(0xc620, 0x25);
ipq9574_ppe_reg_write(0xc630, 0x31);
ipq9574_ppe_reg_write(0xc640, 0x20);
ipq9574_ppe_reg_write(0xc650, 0x36);
ipq9574_ppe_reg_write(0xc660, 0x22);
ipq9574_ppe_reg_write(0xc670, 0x35);
ipq9574_ppe_reg_write(0xc680, 0x26);
ipq9574_ppe_reg_write(0xc690, 0x30);
ipq9574_ppe_reg_write(0xc6a0, 0x23);
ipq9574_ppe_reg_write(0xc6b0, 0x32);
ipq9574_ppe_reg_write(0xc6c0, 0x20);
ipq9574_ppe_reg_write(0xc6d0, 0x36);
ipq9574_ppe_reg_write(0xc6e0, 0x25);
ipq9574_ppe_reg_write(0xc6f0, 0x33);
ipq9574_ppe_reg_write(0xc700, 0x26);
ipq9574_ppe_reg_write(0xc710, 0x30);
ipq9574_ppe_reg_write(0xc720, 0x24);
ipq9574_ppe_reg_write(0xc730, 0x35);
ipq9574_ppe_reg_write(0xc740, 0x20);
ipq9574_ppe_reg_write(0xc750, 0x36);
ipq9574_ppe_reg_write(0xc760, 0x2E);
ipq9574_ppe_reg_write(0xc770, 0x03);
ipq9574_ppe_reg_write(0xc780, 0x1A);
ipq9574_ppe_reg_write(0xc790, 0x1C);
ipq9574_ppe_reg_write(0xc7a0, 0x12);
ipq9574_ppe_reg_write(0xc7b0, 0x1);
ipq9574_ppe_reg_write(0xc7c0, 0xE);
ipq9574_ppe_reg_write(0xc7d0, 0x5);
ipq9574_ppe_reg_write(0xc7e0, 0x32);
ipq9574_ppe_reg_write(0xc7f0, 0x31);
ipq9574_ppe_reg_write(0xb000, 0x80000076);
}
/*
* ipq9574_ppe_sched_configuration
*/
static void ipq9574_ppe_sched_configuration(void)
{
ipq9574_ppe_reg_write(0x0047a000, 0x15CF65);
ipq9574_ppe_reg_write(0x0047a010, 0x159F76);
ipq9574_ppe_reg_write(0x0047a020, 0x153F17);
ipq9574_ppe_reg_write(0x0047a030, 0x153F56);
ipq9574_ppe_reg_write(0x0047a040, 0x15BD01);
ipq9574_ppe_reg_write(0x0047a050, 0x15DD65);
ipq9574_ppe_reg_write(0x0047a060, 0x15DE20);
ipq9574_ppe_reg_write(0x0047a070, 0x15DE65);
ipq9574_ppe_reg_write(0x0047a080, 0x159F06);
ipq9574_ppe_reg_write(0x0047a090, 0x15BB52);
ipq9574_ppe_reg_write(0x0047a0a0, 0x15FA60);
ipq9574_ppe_reg_write(0x0047a0b0, 0x15BE56);
ipq9574_ppe_reg_write(0x0047a0c0, 0x159F05);
ipq9574_ppe_reg_write(0x0047a0d0, 0x15DE60);
ipq9574_ppe_reg_write(0x0047a0e0, 0x157E57);
ipq9574_ppe_reg_write(0x0047a0f0, 0x155F65);
ipq9574_ppe_reg_write(0x0047a100, 0x159F76);
ipq9574_ppe_reg_write(0x0047a110, 0x15BE30);
ipq9574_ppe_reg_write(0x0047a120, 0x15BE56);
ipq9574_ppe_reg_write(0x0047a130, 0x15B703);
ipq9574_ppe_reg_write(0x0047a140, 0x15D765);
ipq9574_ppe_reg_write(0x0047a150, 0x15DE40);
ipq9574_ppe_reg_write(0x0047a160, 0x15DE65);
ipq9574_ppe_reg_write(0x0047a170, 0x159F06);
ipq9574_ppe_reg_write(0x0047a180, 0x15AF54);
ipq9574_ppe_reg_write(0x0047a190, 0x15EE60);
ipq9574_ppe_reg_write(0x0047a1a0, 0x15BE16);
ipq9574_ppe_reg_write(0x0047a1b0, 0x159F25);
ipq9574_ppe_reg_write(0x0047a1c0, 0x15DE60);
ipq9574_ppe_reg_write(0x0047a1d0, 0x157E57);
ipq9574_ppe_reg_write(0x0047a1e0, 0x155F05);
ipq9574_ppe_reg_write(0x0047a1f0, 0x159F36);
ipq9574_ppe_reg_write(0x0047a200, 0x15BE50);
ipq9574_ppe_reg_write(0x0047a210, 0x15BE76);
ipq9574_ppe_reg_write(0x0047a220, 0x15BD01);
ipq9574_ppe_reg_write(0x0047a230, 0x15DD65);
ipq9574_ppe_reg_write(0x0047a240, 0x159F06);
ipq9574_ppe_reg_write(0x0047a250, 0x159F75);
ipq9574_ppe_reg_write(0x0047a260, 0x15DE60);
ipq9574_ppe_reg_write(0x0047a270, 0x15FA52);
ipq9574_ppe_reg_write(0x0047a280, 0x15DB05);
ipq9574_ppe_reg_write(0x0047a290, 0x159F76);
ipq9574_ppe_reg_write(0x0047a2a0, 0x159F05);
ipq9574_ppe_reg_write(0x0047a2b0, 0x159F16);
ipq9574_ppe_reg_write(0x0047a2c0, 0x15BE50);
ipq9574_ppe_reg_write(0x0047a2d0, 0x15DE65);
ipq9574_ppe_reg_write(0x0047a2e0, 0x159F06);
ipq9574_ppe_reg_write(0x0047a2f0, 0x159F25);
ipq9574_ppe_reg_write(0x0047a300, 0x159F06);
ipq9574_ppe_reg_write(0x0047a310, 0x15BE50);
ipq9574_ppe_reg_write(0x0047a320, 0x15BE65);
ipq9574_ppe_reg_write(0x0047a330, 0x159F36);
ipq9574_ppe_reg_write(0x0047a340, 0x159F05);
ipq9574_ppe_reg_write(0x0047a350, 0x159F46);
ipq9574_ppe_reg_write(0x0047a360, 0x15BE50);
ipq9574_ppe_reg_write(0x0047a370, 0x157E67);
ipq9574_ppe_reg_write(0x0047a380, 0x157753);
ipq9574_ppe_reg_write(0x0047a390, 0x15F660);
ipq9574_ppe_reg_write(0x0047a3a0, 0x15EE54);
ipq9574_ppe_reg_write(0x00400000, 0x3b);
}
/*
* ipq9574_ppe_c_sp_cfg_tbl_drr_id_set
*/
static void ipq9574_ppe_c_sp_cfg_tbl_drr_id_set(int id)
{
ipq9574_ppe_reg_write(IPQ9574_PPE_L0_C_SP_CFG_TBL + (id * 0x80), id * 2);
ipq9574_ppe_reg_write(IPQ9574_PPE_L1_C_SP_CFG_TBL + (id * 0x80), id * 2);
}
/*
* ipq9574_ppe_e_sp_cfg_tbl_drr_id_set
*/
static void ipq9574_ppe_e_sp_cfg_tbl_drr_id_set(int id)
{
ipq9574_ppe_reg_write(IPQ9574_PPE_L0_E_SP_CFG_TBL + (id * 0x80), id * 2 + 1);
ipq9574_ppe_reg_write(IPQ9574_PPE_L1_E_SP_CFG_TBL + (id * 0x80), id * 2 + 1);
}
static void ppe_port_mux_set(int port_id, int port_type, int mode)
{
uint32_t mux_mac_type = 0;
union port_mux_ctrl_u port_mux_ctrl;
int node;
uint32_t mode1;
pr_debug("\nport id is: %d, port type is %d, mode is %d",
port_id, port_type, mode);
node = fdt_path_offset(gd->fdt_blob, "/ess-switch");
if (port_type == PORT_GMAC_TYPE)
mux_mac_type = IPQ9574_PORT_MUX_MAC_TYPE;
else if (port_type == PORT_XGMAC_TYPE)
mux_mac_type = IPQ9574_PORT_MUX_XMAC_TYPE;
else
printf("\nAttention!!!..Port type configured wrongly..port_id = %d, mode = %d, port_type = %d",
port_id, mode, port_type);
port_mux_ctrl.val = 0;
ipq9574_ppe_reg_read(IPQ9574_PORT_MUX_CTRL, &(port_mux_ctrl.val));
pr_debug("\nBEFORE UPDATE: Port MUX CTRL value is %u", port_mux_ctrl.val);
switch (port_id) {
case PORT1:
port_mux_ctrl.bf.port1_mac_sel = mux_mac_type;
port_mux_ctrl.bf.port1_pcs_sel = 0;
break;
case PORT2:
port_mux_ctrl.bf.port2_mac_sel = mux_mac_type;
port_mux_ctrl.bf.port2_pcs_sel = 0;
break;
case PORT3:
port_mux_ctrl.bf.port3_mac_sel = mux_mac_type;
port_mux_ctrl.bf.port3_pcs_sel = 0;
break;
case PORT4:
port_mux_ctrl.bf.port4_mac_sel = mux_mac_type;
port_mux_ctrl.bf.port4_pcs_sel = 0;
break;
case PORT5:
port_mux_ctrl.bf.port5_mac_sel = mux_mac_type;
/*
* If port 5 is part of uniphy0, then uniphy1 should be
* given as 0xFF (EPORT_WRAPPER_MAX) in DT since uniphy1
* will not be used in that case
*/
mode1 = fdtdec_get_uint(gd->fdt_blob, node, "switch_mac_mode1", -1);
if (mode1 == EPORT_WRAPPER_MAX)
port_mux_ctrl.bf.port5_pcs_sel =
IPQ9574_PORT5_MUX_PCS_UNIPHY0;
else
port_mux_ctrl.bf.port5_pcs_sel =
IPQ9574_PORT5_MUX_PCS_UNIPHY1;
break;
case PORT6:
port_mux_ctrl.bf.port6_mac_sel = mux_mac_type;
port_mux_ctrl.bf.port6_pcs_sel = 0;
break;
default:
break;
}
ipq9574_ppe_reg_write(IPQ9574_PORT_MUX_CTRL, port_mux_ctrl.val);
pr_debug("\nAFTER UPDATE: Port MUX CTRL value is %u", port_mux_ctrl.val);
}
void ppe_port_mux_mac_type_set(int port_id, int mode)
{
uint32_t port_type;
switch(mode)
{
case EPORT_WRAPPER_PSGMII:
case EPORT_WRAPPER_SGMII0_RGMII4:
case EPORT_WRAPPER_SGMII_PLUS:
case EPORT_WRAPPER_SGMII_FIBER:
port_type = PORT_GMAC_TYPE;
break;
case EPORT_WRAPPER_USXGMII:
case EPORT_WRAPPER_10GBASE_R:
port_type = PORT_XGMAC_TYPE;
break;
default:
printf("\nError during port_type set: mode is %d, port_id is: %d",
mode, port_id);
return;
}
ppe_port_mux_set(port_id, port_type, mode);
}
void ipq9574_ppe_interface_mode_init(void)
{
uint32_t mode0, mode1, mode2;
int node;
node = fdt_path_offset(gd->fdt_blob, "/ess-switch");
if (node < 0) {
printf("\nError: ess-switch not specified in dts");
return;
}
mode0 = fdtdec_get_uint(gd->fdt_blob, node, "switch_mac_mode0", -1);
if (mode0 < 0) {
printf("\nError: switch_mac_mode0 not specified in dts");
return;
}
mode1 = fdtdec_get_uint(gd->fdt_blob, node, "switch_mac_mode1", -1);
if (mode1 < 0) {
printf("\nError: switch_mac_mode1 not specified in dts");
return;
}
mode2 = fdtdec_get_uint(gd->fdt_blob, node, "switch_mac_mode2", -1);
if (mode1 < 0) {
printf("\nError: switch_mac_mode2 not specified in dts");
return;
}
ppe_uniphy_mode_set(PPE_UNIPHY_INSTANCE0, mode0);
ppe_uniphy_mode_set(PPE_UNIPHY_INSTANCE1, mode1);
ppe_uniphy_mode_set(PPE_UNIPHY_INSTANCE2, mode2);
/*
*
* Port 1-4 are used mac type as GMAC by default but
* Port5 and Port6 can be used as GMAC or XGMAC.
*/
ppe_port_mux_mac_type_set(PORT1, mode0);
ppe_port_mux_mac_type_set(PORT2, mode0);
ppe_port_mux_mac_type_set(PORT3, mode0);
ppe_port_mux_mac_type_set(PORT4, mode0);
if (mode1 == EPORT_WRAPPER_MAX) {
ppe_port_mux_mac_type_set(PORT5, mode0);
uniphy_port5_clock_source_set();
} else if (is_uniphy_enabled(PPE_UNIPHY_INSTANCE1)) {
ppe_port_mux_mac_type_set(PORT5, mode1);
}
if (is_uniphy_enabled(PPE_UNIPHY_INSTANCE2)) {
ppe_port_mux_mac_type_set(PORT6, mode2);
}
}
/*
* ipq9574_ppe_provision_init()
*/
void ipq9574_ppe_provision_init(void)
{
int i;
uint32_t queue;
/* tdm/sched configuration */
ipq9574_ppe_tdm_configuration();
ipq9574_ppe_sched_configuration();
#ifdef CONFIG_IPQ9574_BRIDGED_MODE
/* Add CPU port 0 to VSI 2 */
ipq9574_ppe_vp_port_tbl_set(0, 2);
/* Add port 1 - 4 to VSI 2 */
ipq9574_ppe_vp_port_tbl_set(1, 2);
ipq9574_ppe_vp_port_tbl_set(2, 2);
ipq9574_ppe_vp_port_tbl_set(3, 2);
ipq9574_ppe_vp_port_tbl_set(4, 2);
ipq9574_ppe_vp_port_tbl_set(5, 2);
ipq9574_ppe_vp_port_tbl_set(6, 2);
#else
ipq9574_ppe_vp_port_tbl_set(1, 2);
ipq9574_ppe_vp_port_tbl_set(2, 3);
ipq9574_ppe_vp_port_tbl_set(3, 4);
ipq9574_ppe_vp_port_tbl_set(4, 5);
#endif
/* Unicast priority map */
ipq9574_ppe_reg_write(IPQ9574_PPE_QM_UPM_TBL, 0);
/* Port0 - 7 unicast queue settings */
for (i = 0; i < 8; i++) {
if (i == 0)
queue = 0;
else
queue = ((i * 0x10) + 0x70);
ipq9574_ppe_ucast_queue_map_tbl_queue_id_set(queue, i);
ipq9574_ppe_flow_port_map_tbl_port_num_set(queue, i);
ipq9574_ppe_flow_map_tbl_set(queue, i);
ipq9574_ppe_c_sp_cfg_tbl_drr_id_set(i);
ipq9574_ppe_e_sp_cfg_tbl_drr_id_set(i);
}
/* sp_cfg_l0 and sp_cfg_l1 configuration */
ipq9574_ppe_reg_write(IPQ9574_PPE_TM_SHP_CFG_L0, 0x12b);
ipq9574_ppe_reg_write(IPQ9574_PPE_TM_SHP_CFG_L1, 0x3f);
/* Port0 multicast queue */
ipq9574_ppe_reg_write(0x409000, 0x00000000);
ipq9574_ppe_reg_write(0x403000, 0x00401000);
/* Port1 - 7 multicast queue */
for (i = 1; i < 8; i++) {
ipq9574_ppe_reg_write(0x409100 + ((i - 1) * 0x40), i);
ipq9574_ppe_reg_write(0x403100 + ((i - 1) * 0x40), 0x401000 | i);
}
/*
* Port0 - Port7 learn enable and isolation port bitmap and TX_EN
* Here please pay attention on bit16 (TX_EN) is not set on port7
*/
for (i = 0; i < 7; i++)
ipq9574_ppe_reg_write(IPQ9574_PPE_PORT_BRIDGE_CTRL_OFFSET + (i * 4),
IPQ9574_PPE_PORT_BRIDGE_CTRL_PROMISC_EN |
IPQ9574_PPE_PORT_BRIDGE_CTRL_TXMAC_EN |
IPQ9574_PPE_PORT_BRIDGE_CTRL_PORT_ISOLATION_BMP |
IPQ9574_PPE_PORT_BRIDGE_CTRL_STATION_LRN_EN |
IPQ9574_PPE_PORT_BRIDGE_CTRL_NEW_ADDR_LRN_EN);
ipq9574_ppe_reg_write(IPQ9574_PPE_PORT_BRIDGE_CTRL_OFFSET + (7 * 4),
IPQ9574_PPE_PORT_BRIDGE_CTRL_PROMISC_EN |
IPQ9574_PPE_PORT_BRIDGE_CTRL_PORT_ISOLATION_BMP |
IPQ9574_PPE_PORT_BRIDGE_CTRL_STATION_LRN_EN |
IPQ9574_PPE_PORT_BRIDGE_CTRL_NEW_ADDR_LRN_EN);
/* Global learning */
ipq9574_ppe_reg_write(0x060038, 0xc0);
#ifdef CONFIG_IPQ9574_BRIDGED_MODE
ipq9574_vsi_setup(2, 0x7f);
#else
ipq9574_vsi_setup(2, 0x03);
ipq9574_vsi_setup(3, 0x05);
ipq9574_vsi_setup(4, 0x09);
ipq9574_vsi_setup(5, 0x11);
#endif
/* Port 0-7 STP */
for (i = 0; i < 8; i++)
ipq9574_ppe_reg_write(IPQ9574_PPE_STP_BASE + (0x4 * i), 0x3);
ipq9574_ppe_interface_mode_init();
/* Port 0-5 disable */
for (i = 0; i < 6; i++) {
ipq9574_gmac_port_enable(i);
ppe_port_bridge_txmac_set(i + 1, 1);
}
/* Allowing DHCP packets */
ipq9574_ppe_acl_set(0, ADPT_ACL_HPPE_IPV4_DIP_RULE, UDP_PKT, 67, 0xffff, 0, 0);
ipq9574_ppe_acl_set(1, ADPT_ACL_HPPE_IPV4_DIP_RULE, UDP_PKT, 68, 0xffff, 0, 0);
/* Dropping all the UDP packets */
ipq9574_ppe_acl_set(2, ADPT_ACL_HPPE_IPV4_DIP_RULE, UDP_PKT, 0, 0, 0, 1);
}

View file

@ -0,0 +1,263 @@
/*
**************************************************************************
* Copyright (c) 2016-2019, 2021, The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
**************************************************************************
*/
#include <common.h>
#include <net.h>
#include <asm-generic/errno.h>
#include <asm/io.h>
#include <malloc.h>
#include <phy.h>
#include <net.h>
#include <miiphy.h>
#define PORT1 1
#define PORT2 2
#define PORT3 3
#define PORT4 4
#define PORT5 5
#define PORT6 6
#define IPQ9574_PORT5_MUX_PCS_UNIPHY0 0x0
#define IPQ9574_PORT5_MUX_PCS_UNIPHY1 0x1
#define PORT_GMAC_TYPE 1
#define PORT_XGMAC_TYPE 2
#define IPQ9574_PORT_MUX_MAC_TYPE 0
#define IPQ9574_PORT_MUX_XMAC_TYPE 1
struct port_mux_ctrl {
uint32_t port1_pcs_sel:1;
uint32_t port2_pcs_sel:1;
uint32_t port3_pcs_sel:1;
uint32_t port4_pcs_sel:1;
uint32_t port5_pcs_sel:1;
uint32_t port6_pcs_sel:1;
uint32_t _reserved0:2;
uint32_t port1_mac_sel:1;
uint32_t port2_mac_sel:1;
uint32_t port3_mac_sel:1;
uint32_t port4_mac_sel:1;
uint32_t port5_mac_sel:1;
uint32_t port6_mac_sel:1;
uint32_t _reserved1:18;
};
union port_mux_ctrl_u {
uint32_t val;
struct port_mux_ctrl bf;
};
enum {
TCP_PKT,
UDP_PKT,
};
#define ADPT_ACL_HPPE_IPV4_DIP_RULE 4
#define MAX_RULE 512
struct ipo_rule_reg {
uint32_t rule_field_0:32;
uint32_t rule_field_1:20;
uint32_t fake_mac_header:1;
uint32_t range_en:1;
uint32_t inverse_en:1;
uint32_t rule_type:4;
uint32_t src_type:2;
uint32_t src_0:3;
uint32_t src_1:5;
uint32_t pri:9;
uint32_t res_chain:1;
uint32_t post_routing_en:1;
uint32_t _reserved0:16;
};
union ipo_rule_reg_u {
uint32_t val[3];
struct ipo_rule_reg bf;
};
struct ipo_mask_reg {
uint32_t maskfield_0:32;
uint32_t maskfield_1:21;
uint32_t _reserved0:11;
};
union ipo_mask_reg_u {
uint32_t val[2];
struct ipo_mask_reg bf;
};
struct ipo_action {
uint32_t dest_info_change_en:1;
uint32_t fwd_cmd:2;
uint32_t _reserved0:29;
uint32_t _reserved1:32;
uint32_t _reserved2:32;
uint32_t _reserved3:32;
uint32_t _reserved4:32;
};
union ipo_action_u {
uint32_t val[5];
struct ipo_action bf;
};
#define IPQ9574_PORT_MUX_CTRL 0x10
#define IPQ9574_PORT_MUX_CTRL_NUM 1
#define IPQ9574_PORT_MUX_CTRL_INC 0x4
#define IPQ9574_PORT_MUX_CTRL_DEFAULT 0x0
#define PORT_PHY_STATUS_ADDRESS 0x44
#define PORT_PHY_STATUS_PORT5_1_OFFSET 8
#define PORT_PHY_STATUS_PORT6_OFFSET 16
#define IPQ9574_PPE_IPE_L3_BASE_ADDR 0x200000
#define IPQ9574_PPE_L3_VP_PORT_TBL_ADDR (IPQ9574_PPE_IPE_L3_BASE_ADDR + 0x4000)
#define IPQ9574_PPE_L3_VP_PORT_TBL_INC 0x10
#define IPQ9574_PPE_QUEUE_MANAGER_BASE_ADDR 0x800000
#define IPQ9574_PPE_UCAST_QUEUE_MAP_TBL_ADDR 0x10000
#define IPQ9574_PPE_UCAST_QUEUE_MAP_TBL_INC 0x10
#define IPQ9574_PPE_QM_UQM_TBL (IPQ9574_PPE_QUEUE_MANAGER_BASE_ADDR +\
IPQ9574_PPE_UCAST_QUEUE_MAP_TBL_ADDR)
#define IPQ9574_PPE_UCAST_PRIORITY_MAP_TBL_ADDR 0x42000
#define IPQ9574_PPE_QM_UPM_TBL (IPQ9574_PPE_QUEUE_MANAGER_BASE_ADDR +\
IPQ9574_PPE_UCAST_PRIORITY_MAP_TBL_ADDR)
#define IPQ9574_PPE_STP_BASE 0x060100
#define IPQ9574_PPE_MAC_ENABLE 0x001000
#define IPQ9574_PPE_MAC_SPEED 0x001004
#define IPQ9574_PPE_MAC_MIB_CTL 0x001034
#define IPQ9574_PPE_TRAFFIC_MANAGER_BASE_ADDR 0x400000
#define IPQ9574_PPE_TM_SHP_CFG_L0_OFFSET 0x00000030
#define IPQ9574_PPE_TM_SHP_CFG_L1_OFFSET 0x00000034
#define IPQ9574_PPE_TM_SHP_CFG_L0 IPQ9574_PPE_TRAFFIC_MANAGER_BASE_ADDR +\
IPQ9574_PPE_TM_SHP_CFG_L0_OFFSET
#define IPQ9574_PPE_TM_SHP_CFG_L1 IPQ9574_PPE_TRAFFIC_MANAGER_BASE_ADDR +\
IPQ9574_PPE_TM_SHP_CFG_L1_OFFSET
#define IPQ9574_PPE_L0_FLOW_PORT_MAP_TBL_ADDR 0x10000
#define IPQ9574_PPE_L0_FLOW_PORT_MAP_TBL_INC 0x10
#define IPQ9574_PPE_L0_FLOW_PORT_MAP_TBL (IPQ9574_PPE_TRAFFIC_MANAGER_BASE_ADDR +\
IPQ9574_PPE_L0_FLOW_PORT_MAP_TBL_ADDR)
#define IPQ9574_PPE_L0_FLOW_MAP_TBL_ADDR 0x2000
#define IPQ9574_PPE_L0_FLOW_MAP_TBL_INC 0x10
#define IPQ9574_PPE_L0_FLOW_MAP_TBL (IPQ9574_PPE_TRAFFIC_MANAGER_BASE_ADDR +\
IPQ9574_PPE_L0_FLOW_MAP_TBL_ADDR)
#define IPQ9574_PPE_L1_FLOW_PORT_MAP_TBL_ADDR 0x46000
#define IPQ9574_PPE_L1_FLOW_PORT_MAP_TBL_INC 0x10
#define IPQ9574_PPE_L1_FLOW_PORT_MAP_TBL (IPQ9574_PPE_TRAFFIC_MANAGER_BASE_ADDR +\
IPQ9574_PPE_L1_FLOW_PORT_MAP_TBL_ADDR)
#define IPQ9574_PPE_L1_FLOW_MAP_TBL_ADDR 0x40000
#define IPQ9574_PPE_L1_FLOW_MAP_TBL_INC 0x10
#define IPQ9574_PPE_L1_FLOW_MAP_TBL (IPQ9574_PPE_TRAFFIC_MANAGER_BASE_ADDR +\
IPQ9574_PPE_L1_FLOW_MAP_TBL_ADDR)
#define IPQ9574_PPE_L0_C_SP_CFG_TBL_ADDR 0x4000
#define IPQ9574_PPE_L0_C_SP_CFG_TBL (IPQ9574_PPE_TRAFFIC_MANAGER_BASE_ADDR +\
IPQ9574_PPE_L0_C_SP_CFG_TBL_ADDR)
#define IPQ9574_PPE_L1_C_SP_CFG_TBL_ADDR 0x42000
#define IPQ9574_PPE_L1_C_SP_CFG_TBL (IPQ9574_PPE_TRAFFIC_MANAGER_BASE_ADDR +\
IPQ9574_PPE_L1_C_SP_CFG_TBL_ADDR)
#define IPQ9574_PPE_L0_E_SP_CFG_TBL_ADDR 0x6000
#define IPQ9574_PPE_L0_E_SP_CFG_TBL (IPQ9574_PPE_TRAFFIC_MANAGER_BASE_ADDR +\
IPQ9574_PPE_L0_E_SP_CFG_TBL_ADDR)
#define IPQ9574_PPE_L1_E_SP_CFG_TBL_ADDR 0x44000
#define IPQ9574_PPE_L1_E_SP_CFG_TBL (IPQ9574_PPE_TRAFFIC_MANAGER_BASE_ADDR +\
IPQ9574_PPE_L1_E_SP_CFG_TBL_ADDR)
#define IPQ9574_PPE_FPGA_GPIO_BASE_ADDR 0x01008000
#define IPQ9574_PPE_MAC_PORT_MUX_OFFSET 0x10
#define IPQ9574_PPE_FPGA_GPIO_OFFSET 0xc000
#define IPQ9574_PPE_FPGA_SCHED_OFFSET 0x47a000
#define IPQ9574_PPE_TDM_CFG_DEPTH_OFFSET 0xb000
#define IPQ9574_PPE_TDM_SCHED_DEPTH_OFFSET 0x400000
#define IPQ9574_PPE_PORT_BRIDGE_CTRL_OFFSET 0x060300
#define IPQ9574_PPE_TDM_CFG_DEPTH_VAL 0x80000064
#define IPQ9574_PPE_MAC_PORT_MUX_OFFSET_VAL 0x15
#define IPQ9574_PPE_TDM_SCHED_DEPTH_VAL 0x32
#define IPQ9574_PPE_TDM_CFG_VALID 0x20
#define IPQ9574_PPE_TDM_CFG_DIR_INGRESS 0x0
#define IPQ9574_PPE_TDM_CFG_DIR_EGRESS 0x10
#define IPQ9574_PPE_PORT_EDMA 0x0
#define IPQ9574_PPE_PORT_QTI1 0x1
#define IPQ9574_PPE_PORT_QTI2 0x2
#define IPQ9574_PPE_PORT_QTI3 0x3
#define IPQ9574_PPE_PORT_QTI4 0x4
#define IPQ9574_PPE_PORT_XGMAC1 0x5
#define IPQ9574_PPE_PORT_XGMAC2 0x6
#define IPQ9574_PPE_PORT_CRYPTO1 0x7
#define IPQ9574_PPE_PORT_BRIDGE_CTRL_PROMISC_EN 0x20000
#define IPQ9574_PPE_PORT_BRIDGE_CTRL_TXMAC_EN 0x10000
#define IPQ9574_PPE_PORT_BRIDGE_CTRL_PORT_ISOLATION_BMP 0x7f00
#define IPQ9574_PPE_PORT_BRIDGE_CTRL_STATION_LRN_EN 0x8
#define IPQ9574_PPE_PORT_BRIDGE_CTRL_NEW_ADDR_LRN_EN 0x1
#define IPQ9574_PPE_PORT_EDMA_BITPOS 0x1
#define IPQ9574_PPE_PORT_QTI1_BITPOS (1 << IPQ9574_PPE_PORT_QTI1)
#define IPQ9574_PPE_PORT_QTI2_BITPOS (1 << IPQ9574_PPE_PORT_QTI2)
#define IPQ9574_PPE_PORT_QTI3_BITPOS (1 << IPQ9574_PPE_PORT_QTI3)
#define IPQ9574_PPE_PORT_QTI4_BITPOS (1 << IPQ9574_PPE_PORT_QTI4)
#define IPQ9574_PPE_PORT_XGMAC1_BITPOS (1 << IPQ9574_PPE_PORT_XGMAC1)
#define IPQ9574_PPE_PORT_XGMAC2_BITPOS (1 << IPQ9574_PPE_PORT_XGMAC2)
#define IPQ9574_PPE_PORT_CRYPTO1_BITPOS (1 << IPQ9574_PPE_PORT_CRYPTO1)
#define PPE_SWITCH_NSS_SWITCH_XGMAC0 0x500000
#define NSS_SWITCH_XGMAC_MAC_TX_CONFIGURATION 0x4000
#define USS (1 << 31)
#define SS(i) (i << 29)
#define JD (1 << 16)
#define TE (1 << 0)
#define NSS_SWITCH_XGMAC_MAC_RX_CONFIGURATION 0x4000
#define MAC_RX_CONFIGURATION_ADDRESS 0x4
#define RE (1 << 0)
#define ACS (1 << 1)
#define CST (1 << 2)
#define MAC_PACKET_FILTER_INC 0x4000
#define MAC_PACKET_FILTER_ADDRESS 0x8
#define XGMAC_SPEED_SELECT_10000M 0
#define XGMAC_SPEED_SELECT_5000M 1
#define XGMAC_SPEED_SELECT_2500M 2
#define XGMAC_SPEED_SELECT_1000M 3
#define IPE_L2_BASE_ADDR 0x060000
#define PORT_BRIDGE_CTRL_ADDRESS 0x300
#define PORT_BRIDGE_CTRL_INC 0x4
#define TX_MAC_EN (1 << 16)
#define IPO_CSR_BASE_ADDR 0x0b0000
#define IPO_RULE_REG_ADDRESS 0x0
#define IPO_RULE_REG_INC 0x10
#define IPO_MASK_REG_ADDRESS 0x2000
#define IPO_MASK_REG_INC 0x10
#define IPO_ACTION_ADDRESS 0x8000
#define IPO_ACTION_INC 0x20

View file

@ -0,0 +1,584 @@
/*
* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <common.h>
#include <asm-generic/errno.h>
#include <asm/io.h>
#include <malloc.h>
#include <net.h>
#include <phy.h>
#include <miiphy.h>
#include "ipq_phy.h"
#include "ipq9574_qca8075.h"
extern int ipq_mdio_write(int mii_id,
int regnum, u16 value);
extern int ipq_mdio_read(int mii_id,
int regnum, ushort *data);
struct phy_ops *ipq9574_qca8075_ops;
static u32 ipq9574_qca8075_id;
static u16 ipq9574_qca8075_phy_reg_write(u32 dev_id, u32 phy_id,
u32 reg_id, u16 reg_val)
{
ipq_mdio_write(phy_id, reg_id, reg_val);
return 0;
}
static u16 ipq9574_qca8075_phy_reg_read(u32 dev_id, u32 phy_id, u32 reg_id)
{
return ipq_mdio_read(phy_id, reg_id, NULL);
}
/*
* phy4 prfer medium
* get phy4 prefer medum, fiber or copper;
*/
static qca8075_phy_medium_t __phy_prefer_medium_get(u32 dev_id,
u32 phy_id)
{
u16 phy_medium;
phy_medium =
ipq9574_qca8075_phy_reg_read(dev_id, phy_id,
QCA8075_PHY_CHIP_CONFIG);
return ((phy_medium & QCA8075_PHY4_PREFER_FIBER) ?
QCA8075_PHY_MEDIUM_FIBER : QCA8075_PHY_MEDIUM_COPPER);
}
/*
* phy4 activer medium
* get phy4 current active medium, fiber or copper;
*/
static qca8075_phy_medium_t __phy_active_medium_get(u32 dev_id,
u32 phy_id)
{
u16 phy_data = 0;
u32 phy_mode;
phy_mode = ipq9574_qca8075_phy_reg_read(dev_id, phy_id,
QCA8075_PHY_CHIP_CONFIG);
phy_mode &= 0x000f;
if (phy_mode == QCA8075_PHY_PSGMII_AMDET) {
phy_data = ipq9574_qca8075_phy_reg_read(dev_id,
phy_id, QCA8075_PHY_SGMII_STATUS);
if ((phy_data & QCA8075_PHY4_AUTO_COPPER_SELECT)) {
return QCA8075_PHY_MEDIUM_COPPER;
} else if ((phy_data & QCA8075_PHY4_AUTO_BX1000_SELECT)) {
/* PHY_MEDIUM_FIBER_BX1000 */
return QCA8075_PHY_MEDIUM_FIBER;
} else if ((phy_data & QCA8075_PHY4_AUTO_FX100_SELECT)) {
/* PHY_MEDIUM_FIBER_FX100 */
return QCA8075_PHY_MEDIUM_FIBER;
}
/* link down */
return __phy_prefer_medium_get(dev_id, phy_id);
} else if ((phy_mode == QCA8075_PHY_PSGMII_BASET) ||
(phy_mode == QCA8075_PHY_SGMII_BASET)) {
return QCA8075_PHY_MEDIUM_COPPER;
} else if ((phy_mode == QCA8075_PHY_PSGMII_BX1000) ||
(phy_mode == QCA8075_PHY_PSGMII_FX100)) {
return QCA8075_PHY_MEDIUM_FIBER;
} else {
return QCA8075_PHY_MEDIUM_COPPER;
}
}
/*
* phy4 copper page or fiber page select
* set phy4 copper or fiber page
*/
static u8 __phy_reg_pages_sel(u32 dev_id, u32 phy_id,
qca8075_phy_reg_pages_t phy_reg_pages)
{
u16 reg_pages;
reg_pages = ipq9574_qca8075_phy_reg_read(dev_id,
phy_id, QCA8075_PHY_CHIP_CONFIG);
if (phy_reg_pages == QCA8075_PHY_COPPER_PAGES) {
reg_pages |= 0x8000;
} else if (phy_reg_pages == QCA8075_PHY_SGBX_PAGES) {
reg_pages &= ~0x8000;
} else
return -EINVAL;
ipq9574_qca8075_phy_reg_write(dev_id, phy_id,
QCA8075_PHY_CHIP_CONFIG, reg_pages);
return 0;
}
/*
* phy4 reg pages selection by active medium
* phy4 reg pages selection
*/
static u32 __phy_reg_pages_sel_by_active_medium(u32 dev_id,
u32 phy_id)
{
qca8075_phy_medium_t phy_medium;
qca8075_phy_reg_pages_t reg_pages;
phy_medium = __phy_active_medium_get(dev_id, phy_id);
if (phy_medium == QCA8075_PHY_MEDIUM_FIBER) {
reg_pages = QCA8075_PHY_SGBX_PAGES;
} else if (phy_medium == QCA8075_PHY_MEDIUM_COPPER) {
reg_pages = QCA8075_PHY_COPPER_PAGES;
} else {
return -1;
}
return __phy_reg_pages_sel(dev_id, phy_id, reg_pages);
}
static u8 ipq9574_qca8075_phy_get_link_status(u32 dev_id, u32 phy_id)
{
u16 phy_data;
if (phy_id == COMBO_PHY_ID)
__phy_reg_pages_sel_by_active_medium(dev_id, phy_id);
phy_data = ipq9574_qca8075_phy_reg_read(dev_id,
phy_id, QCA8075_PHY_SPEC_STATUS);
if (phy_data & QCA8075_STATUS_LINK_PASS)
return 0;
return 1;
}
static u32 ipq9574_qca8075_phy_get_duplex(u32 dev_id, u32 phy_id,
fal_port_duplex_t * duplex)
{
u16 phy_data;
if (phy_id == COMBO_PHY_ID) {
__phy_reg_pages_sel_by_active_medium(dev_id, phy_id);
}
phy_data = ipq9574_qca8075_phy_reg_read(dev_id, phy_id,
QCA8075_PHY_SPEC_STATUS);
/*
* Read duplex
*/
if (phy_data & QCA8075_STATUS_FULL_DUPLEX)
*duplex = FAL_FULL_DUPLEX;
else
*duplex = FAL_HALF_DUPLEX;
return 0;
}
static u32 ipq9574_qca8075_phy_get_speed(u32 dev_id, u32 phy_id,
fal_port_speed_t * speed)
{
u16 phy_data;
if (phy_id == COMBO_PHY_ID) {
__phy_reg_pages_sel_by_active_medium(dev_id, phy_id);
}
phy_data = ipq9574_qca8075_phy_reg_read(dev_id,
phy_id, QCA8075_PHY_SPEC_STATUS);
switch (phy_data & QCA8075_STATUS_SPEED_MASK) {
case QCA8075_STATUS_SPEED_1000MBS:
*speed = FAL_SPEED_1000;
break;
case QCA8075_STATUS_SPEED_100MBS:
*speed = FAL_SPEED_100;
break;
case QCA8075_STATUS_SPEED_10MBS:
*speed = FAL_SPEED_10;
break;
default:
return -EINVAL;
}
return 0;
}
static u32 ipq9574_qca8075_phy_mmd_write(u32 dev_id, u32 phy_id,
u16 mmd_num, u16 reg_id, u16 reg_val)
{
ipq9574_qca8075_phy_reg_write(dev_id, phy_id,
QCA8075_MMD_CTRL_REG, mmd_num);
ipq9574_qca8075_phy_reg_write(dev_id, phy_id,
QCA8075_MMD_DATA_REG, reg_id);
ipq9574_qca8075_phy_reg_write(dev_id, phy_id,
QCA8075_MMD_CTRL_REG,
0x4000 | mmd_num);
ipq9574_qca8075_phy_reg_write(dev_id, phy_id,
QCA8075_MMD_DATA_REG, reg_val);
return 0;
}
static u16 ipq9574_qca8075_phy_mmd_read(u32 dev_id, u32 phy_id,
u16 mmd_num, u16 reg_id)
{
ipq9574_qca8075_phy_reg_write(dev_id, phy_id,
QCA8075_MMD_CTRL_REG, mmd_num);
ipq9574_qca8075_phy_reg_write(dev_id, phy_id,
QCA8075_MMD_DATA_REG, reg_id);
ipq9574_qca8075_phy_reg_write(dev_id, phy_id,
QCA8075_MMD_CTRL_REG,
0x4000 | mmd_num);
return ipq9574_qca8075_phy_reg_read(dev_id, phy_id,
QCA8075_MMD_DATA_REG);
}
/*
* get phy4 medium is 100fx
*/
static u8 __medium_is_fiber_100fx(u32 dev_id, u32 phy_id)
{
u16 phy_data;
phy_data = ipq9574_qca8075_phy_reg_read(dev_id, phy_id,
QCA8075_PHY_SGMII_STATUS);
if (phy_data & QCA8075_PHY4_AUTO_FX100_SELECT) {
return 1;
}
/* Link down */
if ((!(phy_data & QCA8075_PHY4_AUTO_COPPER_SELECT)) &&
(!(phy_data & QCA8075_PHY4_AUTO_BX1000_SELECT)) &&
(!(phy_data & QCA8075_PHY4_AUTO_SGMII_SELECT))) {
phy_data = ipq9574_qca8075_phy_reg_read(dev_id, phy_id,
QCA8075_PHY_CHIP_CONFIG);
if ((phy_data & QCA8075_PHY4_PREFER_FIBER)
&& (!(phy_data & QCA8075_PHY4_FIBER_MODE_1000BX))) {
return 1;
}
}
return 0;
}
/*
* ipq9574_qca8075_phy_set_hibernate - set hibernate status
* set hibernate status
*/
static u32 ipq9574_qca8075_phy_set_hibernate(u32 dev_id, u32 phy_id, u8 enable)
{
u16 phy_data;
ipq9574_qca8075_phy_reg_write(dev_id, phy_id, QCA8075_DEBUG_PORT_ADDRESS,
QCA8075_DEBUG_PHY_HIBERNATION_CTRL);
phy_data = ipq9574_qca8075_phy_reg_read(dev_id, phy_id,
QCA8075_DEBUG_PORT_DATA);
if (enable) {
phy_data |= 0x8000;
} else {
phy_data &= ~0x8000;
}
ipq9574_qca8075_phy_reg_write(dev_id, phy_id, QCA8075_DEBUG_PORT_DATA, phy_data);
return 0;
}
/*
* ipq9574_qca8075_restart_autoneg - restart the phy autoneg
*/
static u32 ipq9574_qca8075_phy_restart_autoneg(u32 dev_id, u32 phy_id)
{
u16 phy_data;
if (phy_id == COMBO_PHY_ID) {
if (__medium_is_fiber_100fx(dev_id, phy_id))
return -1;
__phy_reg_pages_sel_by_active_medium(dev_id, phy_id);
}
phy_data = ipq9574_qca8075_phy_reg_read(dev_id, phy_id, QCA8075_PHY_CONTROL);
phy_data |= QCA8075_CTRL_AUTONEGOTIATION_ENABLE;
ipq9574_qca8075_phy_reg_write(dev_id, phy_id, QCA8075_PHY_CONTROL,
phy_data | QCA8075_CTRL_RESTART_AUTONEGOTIATION);
return 0;
}
/*
* ipq9574_qca8075_phy_get_8023az status
* get 8023az status
*/
static u32 ipq9574_qca8075_phy_get_8023az(u32 dev_id, u32 phy_id, u8 *enable)
{
u16 phy_data;
if (phy_id == COMBO_PHY_ID) {
if (QCA8075_PHY_MEDIUM_COPPER !=
__phy_active_medium_get(dev_id, phy_id))
return -1;
}
*enable = 0;
phy_data = ipq9574_qca8075_phy_mmd_read(dev_id, phy_id, QCA8075_PHY_MMD7_NUM,
QCA8075_PHY_MMD7_ADDR_8023AZ_EEE_CTRL);
if ((phy_data & 0x0004) && (phy_data & 0x0002))
*enable = 1;
return 0;
}
/*
* ipq9574_qca8075_phy_set_powersave - set power saving status
*/
static u32 ipq9574_qca8075_phy_set_powersave(u32 dev_id, u32 phy_id, u8 enable)
{
u16 phy_data;
u8 status = 0;
if (phy_id == COMBO_PHY_ID) {
if (QCA8075_PHY_MEDIUM_COPPER !=
__phy_active_medium_get(dev_id, phy_id))
return -1;
}
if (enable) {
ipq9574_qca8075_phy_get_8023az(dev_id, phy_id, &status);
if (!status) {
phy_data = ipq9574_qca8075_phy_mmd_read(dev_id, phy_id,
QCA8075_PHY_MMD3_NUM,
QCA8075_PHY_MMD3_ADDR_8023AZ_TIMER_CTRL);
phy_data &= ~(1 << 14);
ipq9574_qca8075_phy_mmd_write(dev_id, phy_id,
QCA8075_PHY_MMD3_NUM,
QCA8075_PHY_MMD3_ADDR_8023AZ_TIMER_CTRL,
phy_data);
}
phy_data = ipq9574_qca8075_phy_mmd_read(dev_id, phy_id,
QCA8075_PHY_MMD3_NUM,
QCA8075_PHY_MMD3_ADDR_CLD_CTRL5);
phy_data &= ~(1 << 14);
ipq9574_qca8075_phy_mmd_write(dev_id, phy_id, QCA8075_PHY_MMD3_NUM,
QCA8075_PHY_MMD3_ADDR_CLD_CTRL5,
phy_data);
phy_data = ipq9574_qca8075_phy_mmd_read(dev_id, phy_id,
QCA8075_PHY_MMD3_NUM,
QCA8075_PHY_MMD3_ADDR_CLD_CTRL3);
phy_data &= ~(1 << 15);
ipq9574_qca8075_phy_mmd_write(dev_id, phy_id, QCA8075_PHY_MMD3_NUM,
QCA8075_PHY_MMD3_ADDR_CLD_CTRL3, phy_data);
} else {
phy_data = ipq9574_qca8075_phy_mmd_read(dev_id, phy_id,
QCA8075_PHY_MMD3_NUM,
QCA8075_PHY_MMD3_ADDR_8023AZ_TIMER_CTRL);
phy_data |= (1 << 14);
ipq9574_qca8075_phy_mmd_write(dev_id, phy_id, QCA8075_PHY_MMD3_NUM,
QCA8075_PHY_MMD3_ADDR_8023AZ_TIMER_CTRL,
phy_data);
phy_data = ipq9574_qca8075_phy_mmd_read(dev_id, phy_id,
QCA8075_PHY_MMD3_NUM,
QCA8075_PHY_MMD3_ADDR_CLD_CTRL5);
phy_data |= (1 << 14);
ipq9574_qca8075_phy_mmd_write(dev_id, phy_id, QCA8075_PHY_MMD3_NUM,
QCA8075_PHY_MMD3_ADDR_CLD_CTRL5, phy_data);
phy_data = ipq9574_qca8075_phy_mmd_read(dev_id, phy_id,
QCA8075_PHY_MMD3_NUM,
QCA8075_PHY_MMD3_ADDR_CLD_CTRL3);
phy_data |= (1 << 15);
ipq9574_qca8075_phy_mmd_write(dev_id, phy_id, QCA8075_PHY_MMD3_NUM,
QCA8075_PHY_MMD3_ADDR_CLD_CTRL3, phy_data);
}
ipq9574_qca8075_phy_reg_write(dev_id, phy_id, QCA8075_PHY_CONTROL, 0x9040);
return 0;
}
/*
* ipq9574_qca8075_phy_set_802.3az
*/
static u32 ipq9574_qca8075_phy_set_8023az(u32 dev_id, u32 phy_id, u8 enable)
{
u16 phy_data;
if (phy_id == COMBO_PHY_ID) {
if (QCA8075_PHY_MEDIUM_COPPER !=
__phy_active_medium_get(dev_id, phy_id))
return -1;
}
phy_data = ipq9574_qca8075_phy_mmd_read(dev_id, phy_id, QCA8075_PHY_MMD7_NUM,
QCA8075_PHY_MMD7_ADDR_8023AZ_EEE_CTRL);
if (enable) {
phy_data |= 0x0006;
ipq9574_qca8075_phy_mmd_write(dev_id, phy_id, QCA8075_PHY_MMD7_NUM,
QCA8075_PHY_MMD7_ADDR_8023AZ_EEE_CTRL, phy_data);
if (ipq9574_qca8075_id == QCA8075_PHY_V1_0_5P) {
/*
* Workaround to avoid packet loss and < 10m cable
* 1000M link not stable under az enable
*/
ipq9574_qca8075_phy_mmd_write(dev_id, phy_id,
QCA8075_PHY_MMD3_NUM,
QCA8075_PHY_MMD3_ADDR_8023AZ_TIMER_CTRL,
AZ_TIMER_CTRL_ADJUST_VALUE);
ipq9574_qca8075_phy_mmd_write(dev_id, phy_id,
QCA8075_PHY_MMD3_NUM,
QCA8075_PHY_MMD3_ADDR_8023AZ_CLD_CTRL,
AZ_CLD_CTRL_ADJUST_VALUE);
}
} else {
phy_data &= ~0x0006;
ipq9574_qca8075_phy_mmd_write(dev_id, phy_id, QCA8075_PHY_MMD7_NUM,
QCA8075_PHY_MMD7_ADDR_8023AZ_EEE_CTRL, phy_data);
if (ipq9574_qca8075_id == QCA8075_PHY_V1_0_5P) {
ipq9574_qca8075_phy_mmd_write(dev_id, phy_id,
QCA8075_PHY_MMD3_NUM,
QCA8075_PHY_MMD3_ADDR_8023AZ_TIMER_CTRL,
AZ_TIMER_CTRL_DEFAULT_VALUE);
}
}
ipq9574_qca8075_phy_restart_autoneg(dev_id, phy_id);
return 0;
}
void ipq9574_qca8075_phy_map_ops(struct phy_ops **ops)
{
*ops = ipq9574_qca8075_ops;
}
void ipq9574_qca8075_phy_serdes_reset(u32 phy_id)
{
ipq9574_qca8075_phy_reg_write(0,
phy_id + QCA8075_PHY_PSGMII_ADDR_INC,
QCA8075_MODE_RESET_REG,
QCA8075_MODE_CHANAGE_RESET);
mdelay(100);
ipq9574_qca8075_phy_reg_write(0,
phy_id + QCA8075_PHY_PSGMII_ADDR_INC,
QCA8075_MODE_RESET_REG,
QCA8075_MODE_RESET_DEFAULT_VALUE);
}
static u16 ipq9574_qca8075_phy_interface_get_mode(u32 phy_id)
{
u16 phy_data;
phy_data = ipq9574_qca8075_phy_reg_read(0,
phy_id + QCA8075_PHY_MAX_ADDR_INC,
QCA8075_PHY_CHIP_CONFIG);
phy_data &= 0x000f;
return phy_data;
}
void ipq9574_qca8075_phy_interface_set_mode(u32 phy_id, u32 mode)
{
u16 phy_data;
phy_data = ipq9574_qca8075_phy_interface_get_mode(phy_id);
if (phy_data != mode) {
phy_data = ipq9574_qca8075_phy_reg_read(0,
phy_id + QCA8075_PHY_MAX_ADDR_INC,
QCA8075_PHY_CHIP_CONFIG);
phy_data &= 0xfff0;
ipq9574_qca8075_phy_reg_write(0,
phy_id + QCA8075_PHY_MAX_ADDR_INC,
QCA8075_PHY_CHIP_CONFIG,
phy_data | mode);
ipq9574_qca8075_phy_serdes_reset(phy_id);
}
}
int ipq9574_qca8075_phy_init(struct phy_ops **ops, u32 phy_id)
{
u16 phy_data;
u32 port_id = 0;
u32 first_phy_id;
first_phy_id = phy_id;
ipq9574_qca8075_ops = (struct phy_ops *)malloc(sizeof(struct phy_ops));
if (!ipq9574_qca8075_ops)
return -ENOMEM;
ipq9574_qca8075_ops->phy_get_link_status = ipq9574_qca8075_phy_get_link_status;
ipq9574_qca8075_ops->phy_get_speed = ipq9574_qca8075_phy_get_speed;
ipq9574_qca8075_ops->phy_get_duplex = ipq9574_qca8075_phy_get_duplex;
*ops = ipq9574_qca8075_ops;
ipq9574_qca8075_id = phy_data = ipq9574_qca8075_phy_reg_read(0x0, phy_id, QCA8075_PHY_ID1);
printf ("PHY ID1: 0x%x\n", phy_data);
phy_data = ipq9574_qca8075_phy_reg_read(0x0, phy_id, QCA8075_PHY_ID2);
printf ("PHY ID2: 0x%x\n", phy_data);
ipq9574_qca8075_id = (ipq9574_qca8075_id << 16) | phy_data;
if (ipq9574_qca8075_id == QCA8075_PHY_V1_0_5P) {
phy_data = ipq9574_qca8075_phy_mmd_read(0, PSGMII_ID,
QCA8075_PHY_MMD1_NUM, QCA8075_PSGMII_FIFI_CTRL);
phy_data &= 0xbfff;
ipq9574_qca8075_phy_mmd_write(0, PSGMII_ID, QCA8075_PHY_MMD1_NUM,
QCA8075_PSGMII_FIFI_CTRL, phy_data);
}
/*
* Enable phy power saving function by default
*/
if ((ipq9574_qca8075_id == QCA8075_PHY_V1_0_5P) ||
(ipq9574_qca8075_id == QCA8075_PHY_V1_1_5P) ||
(ipq9574_qca8075_id == QCA8075_PHY_V1_1_2P)) {
for (port_id = 0; port_id < 5; port_id++) {
/*enable phy power saving function by default */
phy_id = first_phy_id + port_id;
ipq9574_qca8075_phy_set_8023az(0x0, phy_id, 0x1);
ipq9574_qca8075_phy_set_powersave(0x0, phy_id, 0x1);
ipq9574_qca8075_phy_set_hibernate(0x0, phy_id, 0x1);
/*
* change malibu control_dac[2:0] of MMD7 0x801A bit[9:7]
* from 111 to 101
*/
phy_data = ipq9574_qca8075_phy_mmd_read(0, phy_id,
QCA8075_PHY_MMD7_NUM, QCA8075_PHY_MMD7_DAC_CTRL);
phy_data &= ~QCA8075_DAC_CTRL_MASK;
phy_data |= QCA8075_DAC_CTRL_VALUE;
ipq9574_qca8075_phy_mmd_write(0, phy_id, QCA8075_PHY_MMD7_NUM,
QCA8075_PHY_MMD7_DAC_CTRL, phy_data);
/* add 10M and 100M link LED behavior for QFN board*/
phy_data = ipq9574_qca8075_phy_mmd_read(0, phy_id, QCA8075_PHY_MMD7_NUM,
QCA8075_PHY_MMD7_LED_1000_CTRL1);
phy_data &= ~QCA8075_LED_1000_CTRL1_100_10_MASK;
phy_data |= QCA8075_LED_1000_CTRL1_100_10_MASK;
ipq9574_qca8075_phy_mmd_write(0 , phy_id, QCA8075_PHY_MMD7_NUM,
QCA8075_PHY_MMD7_LED_1000_CTRL1, phy_data);
}
}
if ((ipq9574_qca8075_id == QCA8075_PHY_V1_1_2P) && (first_phy_id >= 0x3)) {
phy_id = first_phy_id - 0x3;
}
else {
phy_id = first_phy_id;
}
/*
* Enable AZ transmitting ability
*/
ipq9574_qca8075_phy_mmd_write(0, phy_id + 5, QCA8075_PHY_MMD1_NUM,
QCA8075_PSGMII_MODE_CTRL,
QCA8075_PHY_PSGMII_MODE_CTRL_ADJUST_VALUE);
/* adjust psgmii serdes tx amp */
ipq9574_qca8075_phy_reg_write(0, phy_id + 5, QCA8075_PSGMII_TX_DRIVER_1_CTRL,
QCA8075_PHY_PSGMII_REDUCE_SERDES_TX_AMP);
/* to avoid psgmii module goes into hibernation, work with psgmii self test*/
phy_data = ipq9574_qca8075_phy_mmd_read(0, phy_id + 4, QCA8075_PHY_MMD3_NUM, 0x805a);
phy_data &= (~(1 << 1));
ipq9574_qca8075_phy_mmd_write(0, phy_id + 4, QCA8075_PHY_MMD3_NUM, 0x805a, phy_data);
return 0;
}

View file

@ -0,0 +1,491 @@
/*
* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef _QCA8075_PHY_H_
#define _QCA8075_PHY_H_
#define QCA8075_PHY_CONTROL 0
#define QCA8075_PHY_STATUS 1
#define QCA8075_PHY_ID1 2
#define QCA8075_PHY_ID2 3
#define QCA8075_AUTONEG_ADVERT 4
#define QCA8075_LINK_PARTNER_ABILITY 5
#define QCA8075_AUTONEG_EXPANSION 6
#define QCA8075_NEXT_PAGE_TRANSMIT 7
#define QCA8075_LINK_PARTNER_NEXT_PAGE 8
#define QCA8075_1000BASET_CONTROL 9
#define QCA8075_1000BASET_STATUS 10
#define QCA8075_MMD_CTRL_REG 13
#define QCA8075_MMD_DATA_REG 14
#define QCA8075_EXTENDED_STATUS 15
#define QCA8075_PHY_SPEC_CONTROL 16
#define QCA8075_PHY_SPEC_STATUS 17
#define QCA8075_PHY_INTR_MASK 18
#define QCA8075_PHY_INTR_STATUS 19
#define QCA8075_PHY_CDT_CONTROL 22
#define QCA8075_PHY_CDT_STATUS 28
#define QCA8075_DEBUG_PORT_ADDRESS 29
#define QCA8075_DEBUG_PORT_DATA 30
#define COMBO_PHY_ID 4
#define PSGMII_ID 5
#define QCA8075_DEBUG_PHY_HIBERNATION_CTRL 0xb
#define QCA8075_DEBUG_PHY_POWER_SAVING_CTRL 0x29
#define QCA8075_PHY_MMD7_ADDR_8023AZ_EEE_CTRL 0x3c
#define QCA8075_PHY_MMD3_ADDR_REMOTE_LOOPBACK_CTRL 0x805a
#define QCA8075_PHY_MMD3_WOL_MAGIC_MAC_CTRL1 0x804a
#define QCA8075_PHY_MMD3_WOL_MAGIC_MAC_CTRL2 0x804b
#define QCA8075_PHY_MMD3_WOL_MAGIC_MAC_CTRL3 0x804c
#define QCA8075_PHY_MMD3_WOL_CTRL 0x8012
#define QCA8075_PSGMII_FIFI_CTRL 0x6e
#define QCA8075_PSGMII_CALIB_CTRL 0x27
#define QCA8075_PSGMII_MODE_CTRL 0x6d
#define QCA8075_PHY_PSGMII_MODE_CTRL_ADJUST_VALUE 0x220c
#define QCA8075_PHY_MMD7_NUM 7
#define QCA8075_PHY_MMD3_NUM 3
#define QCA8075_PHY_MMD1_NUM 1
#define QCA8075_PHY_SGMII_STATUS 0x1a /* sgmii_status Register */
#define QCA8075_PHY4_AUTO_SGMII_SELECT 0x40
#define QCA8075_PHY4_AUTO_COPPER_SELECT 0x20
#define QCA8075_PHY4_AUTO_BX1000_SELECT 0x10
#define QCA8075_PHY4_AUTO_FX100_SELECT 0x8
#define QCA8075_MODE_RESET_REG 0x0
#define QCA8075_MODE_CHANAGE_RESET 0x0
#define QCA8075_MODE_RESET_DEFAULT_VALUE 0x5f
#define QCA8075_PHY_MAX_ADDR_INC 0x4
#define QCA8075_PHY_PSGMII_ADDR_INC 0x5
#define QCA8075_PHY_CHIP_CONFIG 0x1f /* Chip Configuration Register */
#define BT_BX_SG_REG_SELECT BIT_15
#define BT_BX_SG_REG_SELECT_OFFSET 15
#define BT_BX_SG_REG_SELECT_LEN 1
#define QCA8075_SG_BX_PAGES 0x0
#define QCA8075_SG_COPPER_PAGES 0x1
#define QCA8075_PHY_PSGMII_BASET 0x0
#define QCA8075_PHY_PSGMII_BX1000 0x1
#define QCA8075_PHY_PSGMII_FX100 0x2
#define QCA8075_PHY_PSGMII_AMDET 0x3
#define QCA8075_PHY_SGMII_BASET 0x4
#define QCA8075_PHY4_PREFER_FIBER 0x400
#define PHY4_PREFER_COPPER 0x0
#define PHY4_PREFER_FIBER 0x1
#define QCA8075_PHY4_FIBER_MODE_1000BX 0x100
#define AUTO_100FX_FIBER 0x0
#define AUTO_1000BX_FIBER 0x1
#define QCA8075_PHY_MDIX 0x0020
#define QCA8075_PHY_MDIX_AUTO 0x0060
#define QCA8075_PHY_MDIX_STATUS 0x0040
#define MODE_CFG_QUAL BIT_4
#define MODE_CFG_QUAL_OFFSET 4
#define MODE_CFG_QUAL_LEN 4
#define MODE_CFG BIT_0
#define MODE_CFG_OFFSET 0
#define MODE_CFG_LEN 4
#define QCA8075_PHY_MMD3_ADDR_8023AZ_CLD_CTRL 0x8007
#define QCA8075_PHY_MMD3_ADDR_8023AZ_TIMER_CTRL 0x804e
#define QCA8075_PHY_MMD3_ADDR_CLD_CTRL5 0x8005
#define QCA8075_PHY_MMD3_ADDR_CLD_CTRL3 0x8003
#define AZ_TIMER_CTRL_DEFAULT_VALUE 0x3062
#define AZ_CLD_CTRL_DEFAULT_VALUE 0x83f6
#define AZ_TIMER_CTRL_ADJUST_VALUE 0x7062
#define AZ_CLD_CTRL_ADJUST_VALUE 0x8396
/*debug port */
#define QCA8075_DEBUG_PORT_RGMII_MODE 18
#define QCA8075_DEBUG_PORT_RGMII_MODE_EN 0x0008
#define QCA8075_DEBUG_PORT_RX_DELAY 0
#define QCA8075_DEBUG_PORT_RX_DELAY_EN 0x8000
#define QCA8075_DEBUG_PORT_TX_DELAY 5
#define QCA8075_DEBUG_PORT_TX_DELAY_EN 0x0100
/* PHY Registers Field */
/* Control Register fields offset:0 */
/* bits 6,13: 10=1000, 01=100, 00=10 */
#define QCA8075_CTRL_SPEED_MSB 0x0040
/* Collision test enable */
#define QCA8075_CTRL_COLL_TEST_ENABLE 0x0080
/* FDX =1, half duplex =0 */
#define QCA8075_CTRL_FULL_DUPLEX 0x0100
/* Restart auto negotiation */
#define QCA8075_CTRL_RESTART_AUTONEGOTIATION 0x0200
/* Isolate PHY from MII */
#define QCA8075_CTRL_ISOLATE 0x0400
/* Power down */
#define QCA8075_CTRL_POWER_DOWN 0x0800
/* Auto Neg Enable */
#define QCA8075_CTRL_AUTONEGOTIATION_ENABLE 0x1000
/* Local Loopback Enable */
#define QCA8075_LOCAL_LOOPBACK_ENABLE 0x4000
/* bits 6,13: 10=1000, 01=100, 00=10 */
#define QCA8075_CTRL_SPEED_LSB 0x2000
/* 0 = normal, 1 = loopback */
#define QCA8075_CTRL_LOOPBACK 0x4000
#define QCA8075_CTRL_SOFTWARE_RESET 0x8000
#define QCA8075_CTRL_SPEED_MASK 0x2040
#define QCA8075_CTRL_SPEED_1000 0x0040
#define QCA8075_CTRL_SPEED_100 0x2000
#define QCA8075_CTRL_SPEED_10 0x0000
#define QCA8075_RESET_DONE(phy_control) \
(((phy_control) & (QCA8075_CTRL_SOFTWARE_RESET)) == 0)
/* Status Register fields offset:1 */
/* Extended register capabilities */
#define QCA8075_STATUS_EXTENDED_CAPS 0x0001
/* Jabber Detected */
#define QCA8075_STATUS_JABBER_DETECT 0x0002
/* Link Status 1 = link */
#define QCA8075_STATUS_LINK_STATUS_UP 0x0004
/* Auto Neg Capable */
#define QCA8075_STATUS_AUTONEG_CAPS 0x0008
/* Remote Fault Detect */
#define QCA8075_STATUS_REMOTE_FAULT 0x0010
/* Auto Neg Complete */
#define QCA8075_STATUS_AUTO_NEG_DONE 0x0020
/* Preamble may be suppressed */
#define QCA8075_STATUS_PREAMBLE_SUPPRESS 0x0040
/* Ext. status info in Reg 0x0F */
#define QCA8075_STATUS_EXTENDED_STATUS 0x0100
/* 100T2 Half Duplex Capable */
#define QCA8075_STATUS_100T2_HD_CAPS 0x0200
/* 100T2 Full Duplex Capable */
#define QCA8075_STATUS_100T2_FD_CAPS 0x0400
/* 10T Half Duplex Capable */
#define QCA8075_STATUS_10T_HD_CAPS 0x0800
/* 10T Full Duplex Capable */
#define QCA8075_STATUS_10T_FD_CAPS 0x1000
/* 100X Half Duplex Capable */
#define QCA8075_STATUS_100X_HD_CAPS 0x2000
/* 100X Full Duplex Capable */
#define QCA8075_STATUS_100X_FD_CAPS 0x4000
/* 100T4 Capable */
#define QCA8075_STATUS_100T4_CAPS 0x8000
/* extended status register capabilities */
#define QCA8075_STATUS_1000T_HD_CAPS 0x1000
#define QCA8075_STATUS_1000T_FD_CAPS 0x2000
#define QCA8075_STATUS_1000X_HD_CAPS 0x4000
#define QCA8075_STATUS_1000X_FD_CAPS 0x8000
#define QCA8075_AUTONEG_DONE(ip_phy_status) \
(((ip_phy_status) & (QCA8075_STATUS_AUTO_NEG_DONE)) == \
(QCA8075_STATUS_AUTO_NEG_DONE))
/* PHY identifier1 offset:2 */
//Organizationally Unique Identifier bits 3:18
/* PHY identifier2 offset:3 */
//Organizationally Unique Identifier bits 19:24
/* Auto-Negotiation Advertisement register. offset:4 */
/* indicates IEEE 802.3 CSMA/CD */
#define QCA8075_ADVERTISE_SELECTOR_FIELD 0x0001
/* 10T Half Duplex Capable */
#define QCA8075_ADVERTISE_10HALF 0x0020
/* 10T Full Duplex Capable */
#define QCA8075_ADVERTISE_10FULL 0x0040
/* 100TX Half Duplex Capable */
#define QCA8075_ADVERTISE_100HALF 0x0080
/* 100TX Full Duplex Capable */
#define QCA8075_ADVERTISE_100FULL 0x0100
/* 100T4 Capable */
#define QCA8075_ADVERTISE_100T4 0x0200
/* Pause operation desired */
#define QCA8075_ADVERTISE_PAUSE 0x0400
/* Asymmetric Pause Direction bit */
#define QCA8075_ADVERTISE_ASYM_PAUSE 0x0800
/* Remote Fault detected */
#define QCA8075_ADVERTISE_REMOTE_FAULT 0x2000
/* Next Page ability supported */
#define QCA8075_ADVERTISE_NEXT_PAGE 0x8000
/* 100TX Half Duplex Capable */
#define QCA8075_ADVERTISE_1000HALF 0x0100
/* 100TX Full Duplex Capable */
#define QCA8075_ADVERTISE_1000FULL 0x0200
#define QCA8075_ADVERTISE_ALL \
(QCA8075_ADVERTISE_10HALF | QCA8075_ADVERTISE_10FULL | \
QCA8075_ADVERTISE_100HALF | QCA8075_ADVERTISE_100FULL | \
QCA8075_ADVERTISE_1000FULL)
#define QCA8075_ADVERTISE_MEGA_ALL \
(QCA8075_ADVERTISE_10HALF | QCA8075_ADVERTISE_10FULL | \
QCA8075_ADVERTISE_100HALF | QCA8075_ADVERTISE_100FULL)
#define QCA8075_BX_ADVERTISE_1000FULL 0x0020
#define QCA8075_BX_ADVERTISE_1000HALF 0x0040
#define QCA8075_BX_ADVERTISE_PAUSE 0x0080
#define QCA8075_BX_ADVERTISE_ASYM_PAUSE 0x0100
#define QCA8075_BX_ADVERTISE_ALL \
(QCA8075_BX_ADVERTISE_ASYM_PAUSE | QCA8075_BX_ADVERTISE_PAUSE | \
QCA8075_BX_ADVERTISE_1000HALF | QCA8075_BX_ADVERTISE_1000FULL)
/* Link Partner ability offset:5 */
/* Same as advertise selector */
#define QCA8075_LINK_SLCT 0x001f
/* Can do 10mbps half-duplex */
#define QCA8075_LINK_10BASETX_HALF_DUPLEX 0x0020
/* Can do 10mbps full-duplex */
#define QCA8075_LINK_10BASETX_FULL_DUPLEX 0x0040
/* Can do 100mbps half-duplex */
#define QCA8075_LINK_100BASETX_HALF_DUPLEX 0x0080
/* Can do 100mbps full-duplex */
#define QCA8075_LINK_100BASETX_FULL_DUPLEX 0x0100
/* Can do 1000mbps full-duplex */
#define QCA8075_LINK_1000BASETX_FULL_DUPLEX 0x0800
/* Can do 1000mbps half-duplex */
#define QCA8075_LINK_1000BASETX_HALF_DUPLEX 0x0400
/* 100BASE-T4 */
#define QCA8075_LINK_100BASE4 0x0200
/* PAUSE */
#define QCA8075_LINK_PAUSE 0x0400
/* Asymmetrical PAUSE */
#define QCA8075_LINK_ASYPAUSE 0x0800
/* Link partner faulted */
#define QCA8075_LINK_RFAULT 0x2000
/* Link partner acked us */
#define QCA8075_LINK_LPACK 0x4000
/* Next page bit */
#define QCA8075_LINK_NPAGE 0x8000
/* Auto-Negotiation Expansion Register offset:6 */
/* Next Page Transmit Register offset:7 */
/* Link partner Next Page Register offset:8 */
/* 1000BASE-T Control Register offset:9 */
/* Advertise 1000T HD capability */
#define QCA8075_CTL_1000T_HD_CAPS 0x0100
/* Advertise 1000T FD capability */
#define QCA8075_CTL_1000T_FD_CAPS 0x0200
/* 1=Repeater/switch device port 0=DTE device */
#define QCA8075_CTL_1000T_REPEATER_DTE 0x0400
/* 1=Configure PHY as Master 0=Configure PHY as Slave */
#define QCA8075_CTL_1000T_MS_VALUE 0x0800
/* 1=Master/Slave manual config value 0=Automatic Master/Slave config */
#define QCA8075_CTL_1000T_MS_ENABLE 0x1000
/* Normal Operation */
#define QCA8075_CTL_1000T_TEST_MODE_NORMAL 0x0000
/* Transmit Waveform test */
#define QCA8075_CTL_1000T_TEST_MODE_1 0x2000
/* Master Transmit Jitter test */
#define QCA8075_CTL_1000T_TEST_MODE_2 0x4000
/* Slave Transmit Jitter test */
#define QCA8075_CTL_1000T_TEST_MODE_3 0x6000
/* Transmitter Distortion test */
#define QCA8075_CTL_1000T_TEST_MODE_4 0x8000
#define QCA8075_CTL_1000T_SPEED_MASK 0x0300
#define QCA8075_CTL_1000T_DEFAULT_CAP_MASK 0x0300
/* 1000BASE-T Status Register offset:10 */
/* LP is 1000T HD capable */
#define QCA8075_STATUS_1000T_LP_HD_CAPS 0x0400
/* LP is 1000T FD capable */
#define QCA8075_STATUS_1000T_LP_FD_CAPS 0x0800
/* Remote receiver OK */
#define QCA8075_STATUS_1000T_REMOTE_RX_STATUS 0x1000
/* Local receiver OK */
#define QCA8075_STATUS_1000T_LOCAL_RX_STATUS 0x2000
/* 1=Local TX is Master, 0=Slave */
#define QCA8075_STATUS_1000T_MS_CONFIG_RES 0x4000
#define QCA8075_STATUS_1000T_MS_CONFIG_FAULT 0x8000
/* Master/Slave config fault */
#define QCA8075_STATUS_1000T_REMOTE_RX_STATUS_SHIFT 12
#define QCA8075_STATUS_1000T_LOCAL_RX_STATUS_SHIFT 13
/* Phy Specific Control Register offset:16 */
/* 1=Jabber Function disabled */
#define QCA8075_CTL_JABBER_DISABLE 0x0001
/* 1=Polarity Reversal enabled */
#define QCA8075_CTL_POLARITY_REVERSAL 0x0002
/* 1=SQE Test enabled */
#define QCA8075_CTL_SQE_TEST 0x0004
#define QCA8075_CTL_MAC_POWERDOWN 0x0008
/* 1=CLK125 low, 0=CLK125 toggling
#define QCA8075_CTL_CLK125_DISABLE 0x0010
*/
/* MDI Crossover Mode bits 6:5 */
/* Manual MDI configuration */
#define QCA8075_CTL_MDI_MANUAL_MODE 0x0000
/* Manual MDIX configuration */
#define QCA8075_CTL_MDIX_MANUAL_MODE 0x0020
/* 1000BASE-T: Auto crossover, 100BASE-TX/10BASE-T: MDI Mode */
#define QCA8075_CTL_AUTO_X_1000T 0x0040
/* Auto crossover enabled all speeds */
#define QCA8075_CTL_AUTO_X_MODE 0x0060
/* 1=Enable Extended 10BASE-T distance
* (Lower 10BASE-T RX Threshold)
* 0=Normal 10BASE-T RX Threshold */
#define QCA8075_CTL_10BT_EXT_DIST_ENABLE 0x0080
/* 1=5-Bit interface in 100BASE-TX
* 0=MII interface in 100BASE-TX */
#define QCA8075_CTL_MII_5BIT_ENABLE 0x0100
/* 1=Scrambler disable */
#define QCA8075_CTL_SCRAMBLER_DISABLE 0x0200
/* 1=Force link good */
#define QCA8075_CTL_FORCE_LINK_GOOD 0x0400
/* 1=Assert CRS on Transmit */
#define QCA8075_CTL_ASSERT_CRS_ON_TX 0x0800
#define QCA8075_CTL_POLARITY_REVERSAL_SHIFT 1
#define QCA8075_CTL_AUTO_X_MODE_SHIFT 5
#define QCA8075_CTL_10BT_EXT_DIST_ENABLE_SHIFT 7
/* Phy Specific status fields offset:17 */
/* 1=Speed & Duplex resolved */
#define QCA8075_STATUS_LINK_PASS 0x0400
#define QCA8075_STATUS_RESOVLED 0x0800
/* 1=Duplex 0=Half Duplex */
#define QCA8075_STATUS_FULL_DUPLEX 0x2000
/* Speed, bits 14:15 */
#define QCA8075_STATUS_SPEED 0xC000
#define QCA8075_STATUS_SPEED_MASK 0xC000
/* 00=10Mbs */
#define QCA8075_STATUS_SPEED_10MBS 0x0000
/* 01=100Mbs */
#define QCA8075_STATUS_SPEED_100MBS 0x4000
/* 10=1000Mbs */
#define QCA8075_STATUS_SPEED_1000MBS 0x8000
#define QCA8075_SPEED_DUPLEX_RESOVLED(phy_status) \
(((phy_status) & \
(QCA8075_STATUS_RESOVLED)) == \
(QCA8075_STATUS_RESOVLED))
/*phy debug port1 register offset:29 */
/*phy debug port2 register offset:30 */
/*QCA8075 interrupt flag */
#define QCA8075_INTR_SPEED_CHANGE 0x4000
#define QCA8075_INTR_DUPLEX_CHANGE 0x2000
#define QCA8075_INTR_STATUS_UP_CHANGE 0x0400
#define QCA8075_INTR_STATUS_DOWN_CHANGE 0x0800
#define QCA8075_INTR_BX_FX_STATUS_DOWN_CHANGE 0x0100
#define QCA8075_INTR_BX_FX_STATUS_UP_CHANGE 0x0080
#define QCA8075_INTR_MEDIA_STATUS_CHANGE 0x1000
#define QCA8075_INTR_WOL 0x0001
#define QCA8075_INTR_POE 0x0002
#define QCA8075_PHY_PSGMII_REDUCE_SERDES_TX_AMP 0x8a
#define QCA8075_DAC_CTRL_MASK 0x380
#define QCA8075_PHY_MMD7_DAC_CTRL 0x801a
#define QCA8075_DAC_CTRL_VALUE 0x280
#define QCA8075_PHY_MMD7_NUM 7
#define QCA8075_PSGMII_TX_DRIVER_1_CTRL 0xb
#define QCA8075_PHY_MMD7_LED_1000_CTRL1 0x8076
#define QCA8075_LED_1000_CTRL1_100_10_MASK 0x30
#define RUN_CDT 0x8000
#define CABLE_LENGTH_UNIT 0x0400
#define QCA8075_MAX_TRIES 100
#endif /* _QCA8075_PHY_H_ */

View file

@ -0,0 +1,553 @@
/*
* Copyright (c) 2017-2019, 2021, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#include <common.h>
#include <asm/global_data.h>
#include <net.h>
#include <asm-generic/errno.h>
#include <asm/io.h>
#include <malloc.h>
#include <phy.h>
#include <net.h>
#include <miiphy.h>
#include <asm/arch-ipq9574/edma_regs.h>
#include "ipq9574_edma.h"
#include "ipq9574_uniphy.h"
#include "ipq9574_ppe.h"
#include <fdtdec.h>
#include "ipq_phy.h"
extern int is_uniphy_enabled(int uniphy_index);
DECLARE_GLOBAL_DATA_PTR;
extern int ipq_mdio_write(int mii_id,
int regnum, u16 value);
extern int ipq_mdio_read(int mii_id,
int regnum, ushort *data);
extern void ipq9574_qca8075_phy_serdes_reset(u32 phy_id);
void csr1_write(int phy_id, int addr, int value)
{
int addr_h, addr_l, ahb_h, ahb_l, phy;
phy=phy_id<<(0x10);
addr_h=(addr&0xffffff)>>8;
addr_l=((addr&0xff)<<2)|(0x20<<(0xa));
ahb_l=(addr_l&0xffff)|(0x7A00000|phy);
ahb_h=(0x7A083FC|phy);
writel(addr_h,ahb_h);
writel(value,ahb_l);
}
int csr1_read(int phy_id, int addr )
{
int addr_h ,addr_l,ahb_h, ahb_l, phy;
phy=phy_id<<(0x10);
addr_h=(addr&0xffffff)>>8;
addr_l=((addr&0xff)<<2)|(0x20<<(0xa));
ahb_l=(addr_l&0xffff)|(0x7A00000|phy);
ahb_h=(0x7A083FC|phy);
writel(addr_h, ahb_h);
return readl(ahb_l);
}
static int ppe_uniphy_calibration(uint32_t uniphy_index)
{
int retries = 100, calibration_done = 0;
uint32_t reg_value = 0;
while(calibration_done != UNIPHY_CALIBRATION_DONE) {
mdelay(1);
if (retries-- == 0) {
printf("uniphy callibration time out!\n");
return -1;
}
reg_value = readl(PPE_UNIPHY_BASE + (uniphy_index * PPE_UNIPHY_REG_INC)
+ PPE_UNIPHY_OFFSET_CALIB_4);
calibration_done = (reg_value >> 0x7) & 0x1;
}
return 0;
}
static void ppe_uniphy_reset(enum uniphy_reset_type rst_type, bool enable)
{
uint32_t mode, node;
uint32_t reg_val, reg_val1;
switch(rst_type) {
case UNIPHY0_SOFT_RESET:
node = fdt_path_offset(gd->fdt_blob, "/ess-switch");
if (node < 0) {
printf("\nError: ess-switch not specified in dts");
return;
}
mode = fdtdec_get_uint(gd->fdt_blob, node, "switch_mac_mode1", -1);
if (mode < 0) {
printf("\nError: switch_mac_mode1 not specified in dts");
return;
}
reg_val = readl(GCC_UNIPHY0_MISC);
reg_val1 = readl(NSS_CC_UNIPHY_MISC_RESET);
if (mode == EPORT_WRAPPER_MAX) {
if (enable) {
reg_val |= 0x1;
reg_val1 |= 0xffc000;
} else {
reg_val &= ~0x1;
reg_val1 &= ~0xffc000;
}
} else {
if (enable) {
reg_val |= 0x1;
reg_val1 |= 0xff0000;
} else {
reg_val &= ~0x1;
reg_val1 &= ~0xff0000;
}
}
writel(reg_val, GCC_UNIPHY0_MISC);
writel(reg_val1, NSS_CC_UNIPHY_MISC_RESET);
break;
case UNIPHY0_XPCS_RESET:
reg_val = readl(GCC_UNIPHY0_MISC);
if (enable)
reg_val |= 0x4;
else
reg_val &= ~0x4;
writel(reg_val, GCC_UNIPHY0_MISC);
break;
case UNIPHY1_SOFT_RESET:
reg_val = readl(GCC_UNIPHY0_MISC + GCC_UNIPHY_REG_INC);
reg_val1 = readl(NSS_CC_UNIPHY_MISC_RESET);
if (enable) {
reg_val |= 0x1;
reg_val1 |= 0xC000;
} else {
reg_val &= ~0x1;
reg_val1 &= ~0xC000;
}
writel(reg_val, GCC_UNIPHY0_MISC + GCC_UNIPHY_REG_INC);
writel(reg_val1, NSS_CC_UNIPHY_MISC_RESET);
break;
case UNIPHY1_XPCS_RESET:
reg_val = readl(GCC_UNIPHY0_MISC + GCC_UNIPHY_REG_INC);
if (enable)
reg_val |= 0x4;
else
reg_val &= ~0x4;
writel(reg_val, GCC_UNIPHY0_MISC + GCC_UNIPHY_REG_INC);
break;
case UNIPHY2_SOFT_RESET:
reg_val = readl(GCC_UNIPHY0_MISC + (2 * GCC_UNIPHY_REG_INC));
reg_val1 = readl(NSS_CC_UNIPHY_MISC_RESET);
if (enable) {
reg_val |= 0x1;
reg_val1 |= 0x3000;
} else {
reg_val &= ~0x1;
reg_val1 &= ~0x3000;
}
writel(reg_val, GCC_UNIPHY0_MISC + (2 * GCC_UNIPHY_REG_INC));
writel(reg_val1, NSS_CC_UNIPHY_MISC_RESET);
break;
case UNIPHY2_XPCS_RESET:
reg_val = readl(GCC_UNIPHY0_MISC + (2 * GCC_UNIPHY_REG_INC));
if (enable)
reg_val |= 0x4;
else
reg_val &= ~0x4;
writel(reg_val, GCC_UNIPHY0_MISC + (2 * GCC_UNIPHY_REG_INC));
break;
default:
break;
}
}
static void ppe_uniphy_psgmii_mode_set(uint32_t uniphy_index)
{
if (uniphy_index == 0)
ppe_uniphy_reset(UNIPHY0_XPCS_RESET, true);
else if (uniphy_index == 1)
ppe_uniphy_reset(UNIPHY1_XPCS_RESET, true);
else
ppe_uniphy_reset(UNIPHY2_XPCS_RESET, true);
mdelay(100);
writel(0x220, PPE_UNIPHY_BASE + (uniphy_index * PPE_UNIPHY_REG_INC)
+ PPE_UNIPHY_MODE_CONTROL);
if (uniphy_index == 0) {
ppe_uniphy_reset(UNIPHY0_SOFT_RESET, true);
mdelay(100);
ppe_uniphy_reset(UNIPHY0_SOFT_RESET, false);
} else if (uniphy_index == 1) {
ppe_uniphy_reset(UNIPHY1_SOFT_RESET, true);
mdelay(100);
ppe_uniphy_reset(UNIPHY1_SOFT_RESET, false);
} else {
ppe_uniphy_reset(UNIPHY2_SOFT_RESET, true);
mdelay(100);
ppe_uniphy_reset(UNIPHY2_SOFT_RESET, false);
}
mdelay(100);
ppe_uniphy_calibration(uniphy_index);
ipq9574_qca8075_phy_serdes_reset(0x10);
}
static void ppe_uniphy_qsgmii_mode_set(uint32_t uniphy_index)
{
if (uniphy_index == 0)
ppe_uniphy_reset(UNIPHY0_XPCS_RESET, true);
else if (uniphy_index == 1)
ppe_uniphy_reset(UNIPHY1_XPCS_RESET, true);
else
ppe_uniphy_reset(UNIPHY2_XPCS_RESET, true);
mdelay(100);
writel(0x120, PPE_UNIPHY_BASE + (uniphy_index * PPE_UNIPHY_REG_INC)
+ PPE_UNIPHY_MODE_CONTROL);
if (uniphy_index == 0) {
ppe_uniphy_reset(UNIPHY0_SOFT_RESET, true);
mdelay(100);
ppe_uniphy_reset(UNIPHY0_SOFT_RESET, false);
} else if (uniphy_index == 1) {
ppe_uniphy_reset(UNIPHY1_SOFT_RESET, true);
mdelay(100);
ppe_uniphy_reset(UNIPHY1_SOFT_RESET, false);
} else {
ppe_uniphy_reset(UNIPHY2_SOFT_RESET, true);
mdelay(100);
ppe_uniphy_reset(UNIPHY2_SOFT_RESET, false);
}
mdelay(100);
}
static void ppe_uniphy_sgmii_mode_set(uint32_t uniphy_index, uint32_t mode)
{
writel(UNIPHY_MISC2_REG_SGMII_MODE, PPE_UNIPHY_BASE +
(uniphy_index * PPE_UNIPHY_REG_INC) + UNIPHY_MISC2_REG_OFFSET);
writel(UNIPHY_PLL_RESET_REG_VALUE, PPE_UNIPHY_BASE +
(uniphy_index * PPE_UNIPHY_REG_INC) + UNIPHY_PLL_RESET_REG_OFFSET);
mdelay(500);
writel(UNIPHY_PLL_RESET_REG_DEFAULT_VALUE, PPE_UNIPHY_BASE +
(uniphy_index * PPE_UNIPHY_REG_INC) + UNIPHY_PLL_RESET_REG_OFFSET);
mdelay(500);
if (uniphy_index == 0)
ppe_uniphy_reset(UNIPHY0_XPCS_RESET, true);
else if (uniphy_index == 1)
ppe_uniphy_reset(UNIPHY1_XPCS_RESET, true);
else
ppe_uniphy_reset(UNIPHY2_XPCS_RESET, true);
mdelay(100);
if (uniphy_index == 1) {
writel(0x0, NSS_CC_UNIPHY_PORT1_RX_CBCR + (PORT5 - 1) * 0x8);
writel(0x0, NSS_CC_UNIPHY_PORT1_RX_CBCR + 0x4 + (PORT5 - 1) * 0x8);
writel(0x0, NSS_CC_PORT1_RX_CBCR + (PORT5 - 1) * 0x8);
writel(0x0, NSS_CC_PORT1_RX_CBCR + 0x4 + (PORT5 - 1) * 0x8);
} else if (uniphy_index == 2) {
writel(0x0, NSS_CC_UNIPHY_PORT1_RX_CBCR + (PORT6 - 1) * 0x8);
writel(0x0, NSS_CC_UNIPHY_PORT1_RX_CBCR + 0x4 + (PORT6 - 1) * 8);
writel(0x0, NSS_CC_PORT1_RX_CBCR + (PORT6 - 1) * 0x8);
writel(0x0, NSS_CC_PORT1_RX_CBCR + 0x4 + (PORT6 - 1) * 0x8);
}
switch (mode) {
case EPORT_WRAPPER_SGMII_FIBER:
writel(0x400, PPE_UNIPHY_BASE + (uniphy_index * PPE_UNIPHY_REG_INC)
+ PPE_UNIPHY_MODE_CONTROL);
break;
case EPORT_WRAPPER_SGMII0_RGMII4:
case EPORT_WRAPPER_SGMII1_RGMII4:
case EPORT_WRAPPER_SGMII4_RGMII4:
writel(0x420, PPE_UNIPHY_BASE + (uniphy_index * PPE_UNIPHY_REG_INC)
+ PPE_UNIPHY_MODE_CONTROL);
break;
case EPORT_WRAPPER_SGMII_PLUS:
writel(0x820, PPE_UNIPHY_BASE + (uniphy_index * PPE_UNIPHY_REG_INC)
+ PPE_UNIPHY_MODE_CONTROL);
break;
default:
printf("SGMII Config. wrongly");
break;
}
if (uniphy_index == 0) {
ppe_uniphy_reset(UNIPHY0_SOFT_RESET, true);
mdelay(100);
ppe_uniphy_reset(UNIPHY0_SOFT_RESET, false);
} else if (uniphy_index == 1) {
ppe_uniphy_reset(UNIPHY1_SOFT_RESET, true);
mdelay(100);
ppe_uniphy_reset(UNIPHY1_SOFT_RESET, false);
} else {
ppe_uniphy_reset(UNIPHY2_SOFT_RESET, true);
mdelay(100);
ppe_uniphy_reset(UNIPHY2_SOFT_RESET, false);
}
mdelay(100);
if (uniphy_index == 1) {
writel(0x1, NSS_CC_UNIPHY_PORT1_RX_CBCR + (PORT5 - 1) * 0x8);
writel(0x1, NSS_CC_UNIPHY_PORT1_RX_CBCR + 0x4 + (PORT5 - 1) * 0x8);
writel(0x1, NSS_CC_PORT1_RX_CBCR + (PORT5 - 1) * 0x8);
writel(0x1, NSS_CC_PORT1_RX_CBCR + 0x4 + (PORT5 - 1) * 0x8);
} else if (uniphy_index == 2) {
writel(0x1, NSS_CC_UNIPHY_PORT1_RX_CBCR + (PORT6 - 1) * 0x8);
writel(0x1, NSS_CC_UNIPHY_PORT1_RX_CBCR + 0x4 + (PORT6 - 1) * 8);
writel(0x1, NSS_CC_PORT1_RX_CBCR + (PORT6 - 1) * 0x8);
writel(0x1, NSS_CC_PORT1_RX_CBCR + 0x4 + (PORT6 - 1) * 0x8);
}
ppe_uniphy_calibration(uniphy_index);
}
static int ppe_uniphy_10g_r_linkup(uint32_t uniphy_index)
{
uint32_t reg_value = 0;
uint32_t retries = 100, linkup = 0;
while (linkup != UNIPHY_10GR_LINKUP) {
mdelay(1);
if (retries-- == 0)
return -1;
reg_value = csr1_read(uniphy_index, SR_XS_PCS_KR_STS1_ADDRESS);
linkup = (reg_value >> 12) & UNIPHY_10GR_LINKUP;
}
mdelay(10);
return 0;
}
static void ppe_uniphy_10g_r_mode_set(uint32_t uniphy_index)
{
if (uniphy_index == 0)
ppe_uniphy_reset(UNIPHY0_XPCS_RESET, true);
else if (uniphy_index == 1)
ppe_uniphy_reset(UNIPHY1_XPCS_RESET, true);
else
ppe_uniphy_reset(UNIPHY2_XPCS_RESET, true);
writel(0x1021, PPE_UNIPHY_BASE + (uniphy_index * PPE_UNIPHY_REG_INC)
+ PPE_UNIPHY_MODE_CONTROL);
writel(0x1C0, PPE_UNIPHY_BASE + (uniphy_index * PPE_UNIPHY_REG_INC)
+ UNIPHY_INSTANCE_LINK_DETECT);
if (uniphy_index == 0) {
ppe_uniphy_reset(UNIPHY0_SOFT_RESET, true);
mdelay(100);
ppe_uniphy_reset(UNIPHY0_SOFT_RESET, false);
} else if (uniphy_index == 1) {
ppe_uniphy_reset(UNIPHY1_SOFT_RESET, true);
mdelay(100);
ppe_uniphy_reset(UNIPHY1_SOFT_RESET, false);
} else {
ppe_uniphy_reset(UNIPHY2_SOFT_RESET, true);
mdelay(100);
ppe_uniphy_reset(UNIPHY2_SOFT_RESET, false);
}
mdelay(100);
ppe_uniphy_calibration(uniphy_index);
if (uniphy_index == 0)
ppe_uniphy_reset(UNIPHY0_XPCS_RESET, false);
else if (uniphy_index == 1)
ppe_uniphy_reset(UNIPHY1_XPCS_RESET, false);
else
ppe_uniphy_reset(UNIPHY2_XPCS_RESET, false);
}
static void ppe_uniphy_usxgmii_mode_set(uint32_t uniphy_index)
{
uint32_t reg_value = 0;
writel(UNIPHY_MISC2_REG_VALUE, PPE_UNIPHY_BASE +
(uniphy_index * PPE_UNIPHY_REG_INC) + UNIPHY_MISC2_REG_OFFSET);
writel(UNIPHY_PLL_RESET_REG_VALUE, PPE_UNIPHY_BASE +
(uniphy_index * PPE_UNIPHY_REG_INC) + UNIPHY_PLL_RESET_REG_OFFSET);
mdelay(500);
writel(UNIPHY_PLL_RESET_REG_DEFAULT_VALUE, PPE_UNIPHY_BASE +
(uniphy_index * PPE_UNIPHY_REG_INC) + UNIPHY_PLL_RESET_REG_OFFSET);
mdelay(500);
if (uniphy_index == 0)
ppe_uniphy_reset(UNIPHY0_XPCS_RESET, true);
else if (uniphy_index == 1)
ppe_uniphy_reset(UNIPHY1_XPCS_RESET, true);
else
ppe_uniphy_reset(UNIPHY2_XPCS_RESET, true);
mdelay(100);
writel(0x1021, PPE_UNIPHY_BASE + (uniphy_index * PPE_UNIPHY_REG_INC)
+ PPE_UNIPHY_MODE_CONTROL);
if (uniphy_index == 0) {
ppe_uniphy_reset(UNIPHY0_SOFT_RESET, true);
mdelay(100);
ppe_uniphy_reset(UNIPHY0_SOFT_RESET, false);
} else if (uniphy_index == 1) {
ppe_uniphy_reset(UNIPHY1_SOFT_RESET, true);
mdelay(100);
ppe_uniphy_reset(UNIPHY1_SOFT_RESET, false);
} else {
ppe_uniphy_reset(UNIPHY2_SOFT_RESET, true);
mdelay(100);
ppe_uniphy_reset(UNIPHY2_SOFT_RESET, false);
}
mdelay(100);
ppe_uniphy_calibration(uniphy_index);
if (uniphy_index == 0)
ppe_uniphy_reset(UNIPHY0_XPCS_RESET, false);
else if (uniphy_index == 1)
ppe_uniphy_reset(UNIPHY1_XPCS_RESET, false);
else
ppe_uniphy_reset(UNIPHY2_XPCS_RESET, false);
mdelay(100);
ppe_uniphy_10g_r_linkup(uniphy_index);
reg_value = csr1_read(uniphy_index, VR_XS_PCS_DIG_CTRL1_ADDRESS);
reg_value |= USXG_EN;
csr1_write(uniphy_index, VR_XS_PCS_DIG_CTRL1_ADDRESS, reg_value);
reg_value = csr1_read(uniphy_index, VR_MII_AN_CTRL_ADDRESS);
reg_value |= MII_AN_INTR_EN;
reg_value |= MII_CTRL;
csr1_write(uniphy_index, VR_MII_AN_CTRL_ADDRESS, reg_value);
reg_value = csr1_read(uniphy_index, SR_MII_CTRL_ADDRESS);
reg_value |= AN_ENABLE;
reg_value &= ~SS5;
reg_value |= SS6 | SS13 | DUPLEX_MODE;
csr1_write(uniphy_index, SR_MII_CTRL_ADDRESS, reg_value);
}
void ppe_uniphy_mode_set(uint32_t uniphy_index, uint32_t mode)
{
if (!is_uniphy_enabled(uniphy_index)) {
printf("Uniphy %u is disabled\n", uniphy_index);
return;
}
switch(mode) {
case EPORT_WRAPPER_PSGMII:
ppe_uniphy_psgmii_mode_set(uniphy_index);
break;
case EPORT_WRAPPER_QSGMII:
ppe_uniphy_qsgmii_mode_set(uniphy_index);
break;
case EPORT_WRAPPER_SGMII0_RGMII4:
case EPORT_WRAPPER_SGMII1_RGMII4:
case EPORT_WRAPPER_SGMII4_RGMII4:
case EPORT_WRAPPER_SGMII_PLUS:
case EPORT_WRAPPER_SGMII_FIBER:
ppe_uniphy_sgmii_mode_set(uniphy_index, mode);
break;
case EPORT_WRAPPER_USXGMII:
ppe_uniphy_usxgmii_mode_set(uniphy_index);
break;
case EPORT_WRAPPER_10GBASE_R:
ppe_uniphy_10g_r_mode_set(uniphy_index);
break;
default:
break;
}
}
void ppe_uniphy_usxgmii_autoneg_completed(uint32_t uniphy_index)
{
uint32_t autoneg_complete = 0, retries = 100;
uint32_t reg_value = 0;
while (autoneg_complete != 0x1) {
mdelay(1);
if (retries-- == 0)
{
return;
}
reg_value = csr1_read(uniphy_index, VR_MII_AN_INTR_STS);
autoneg_complete = reg_value & 0x1;
}
reg_value &= ~CL37_ANCMPLT_INTR;
csr1_write(uniphy_index, VR_MII_AN_INTR_STS, reg_value);
}
void ppe_uniphy_usxgmii_speed_set(uint32_t uniphy_index, int speed)
{
uint32_t reg_value = 0;
reg_value = csr1_read(uniphy_index, SR_MII_CTRL_ADDRESS);
reg_value |= DUPLEX_MODE;
switch(speed) {
case 0:
reg_value &=~SS5;
reg_value &=~SS6;
reg_value &=~SS13;
break;
case 1:
reg_value &=~SS5;
reg_value &=~SS6;
reg_value |=SS13;
break;
case 2:
reg_value &=~SS5;
reg_value |=SS6;
reg_value &=~SS13;
break;
case 3:
reg_value &=~SS5;
reg_value |=SS6;
reg_value |=SS13;
break;
case 4:
reg_value |=SS5;
reg_value &=~SS6;
reg_value &=~SS13;
break;
case 5:
reg_value |=SS5;
reg_value &=~SS6;
reg_value |=SS13;
break;
}
csr1_write(uniphy_index, SR_MII_CTRL_ADDRESS, reg_value);
}
void ppe_uniphy_usxgmii_duplex_set(uint32_t uniphy_index, int duplex)
{
uint32_t reg_value = 0;
reg_value = csr1_read(uniphy_index, SR_MII_CTRL_ADDRESS);
if (duplex & 0x1)
reg_value |= DUPLEX_MODE;
else
reg_value &= ~DUPLEX_MODE;
csr1_write(uniphy_index, SR_MII_CTRL_ADDRESS, reg_value);
}
void ppe_uniphy_usxgmii_port_reset(uint32_t uniphy_index)
{
uint32_t reg_value = 0;
reg_value = csr1_read(uniphy_index, VR_XS_PCS_DIG_CTRL1_ADDRESS);
reg_value |= USRA_RST;
csr1_write(uniphy_index, VR_XS_PCS_DIG_CTRL1_ADDRESS, reg_value);
}

View file

@ -0,0 +1,82 @@
/*
* Copyright (c) 2017-2019, 2021, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#define PPE_UNIPHY_INSTANCE0 0
#define PPE_UNIPHY_INSTANCE1 1
#define PPE_UNIPHY_INSTANCE2 2
#define GCC_UNIPHY_REG_INC 0x10
#define PPE_UNIPHY_OFFSET_CALIB_4 0x1E0
#define UNIPHY_CALIBRATION_DONE 0x1
#define PPE_UNIPHY_BASE 0X07A00000
#define PPE_UNIPHY_REG_INC 0x10000
#define PPE_UNIPHY_MODE_CONTROL 0x46C
#define UNIPHY_XPCS_MODE (1 << 12)
#define UNIPHY_SG_PLUS_MODE (1 << 11)
#define UNIPHY_SG_MODE (1 << 10)
#define UNIPHY_CH0_PSGMII_QSGMII (1 << 9)
#define UNIPHY_CH0_QSGMII_SGMII (1 << 8)
#define UNIPHY_CH4_CH1_0_SGMII (1 << 2)
#define UNIPHY_CH1_CH0_SGMII (1 << 1)
#define UNIPHY_CH0_ATHR_CSCO_MODE_25M (1 << 0)
#define UNIPHY_INSTANCE_LINK_DETECT 0x570
#define UNIPHY_MISC2_REG_OFFSET 0x218
#define UNIPHY_MISC2_REG_SGMII_MODE 0x30
#define UNIPHY_MISC2_REG_SGMII_PLUS_MODE 0x50
#define UNIPHY_MISC2_REG_VALUE 0x70
#define UNIPHY_PLL_RESET_REG_OFFSET 0x780
#define UNIPHY_PLL_RESET_REG_VALUE 0x02bf
#define UNIPHY_PLL_RESET_REG_DEFAULT_VALUE 0x02ff
#define SR_XS_PCS_KR_STS1_ADDRESS 0x30020
#define UNIPHY_10GR_LINKUP 0x1
#define VR_XS_PCS_DIG_CTRL1_ADDRESS 0x38000
#define USXG_EN (1 << 9)
#define USRA_RST (1 << 10)
#define VR_MII_AN_CTRL_ADDRESS 0x1f8001
#define MII_AN_INTR_EN (1 << 0)
#define MII_CTRL (1 << 8)
#define SR_MII_CTRL_ADDRESS 0x1f0000
#define AN_ENABLE (1 << 12)
#define SS5 (1 << 5)
#define SS6 (1 << 6)
#define SS13 (1 << 13)
#define DUPLEX_MODE (1 << 8)
#define VR_MII_AN_INTR_STS 0x1f8002
#define CL37_ANCMPLT_INTR (1 << 0)
enum uniphy_reset_type {
UNIPHY0_SOFT_RESET = 0,
UNIPHY0_XPCS_RESET,
UNIPHY1_SOFT_RESET,
UNIPHY1_XPCS_RESET,
UNIPHY2_SOFT_RESET,
UNIPHY2_XPCS_RESET,
UNIPHY_RST_MAX
};
void ppe_uniphy_mode_set(uint32_t uniphy_index, uint32_t mode);
void ppe_uniphy_usxgmii_port_reset(uint32_t uniphy_index);
void ppe_uniphy_usxgmii_duplex_set(uint32_t uniphy_index, int duplex);
void ppe_uniphy_usxgmii_speed_set(uint32_t uniphy_index, int speed);
void ppe_uniphy_usxgmii_autoneg_completed(uint32_t uniphy_index);

View file

@ -18,6 +18,7 @@
#include <net.h>
#define PHY_MAX 6
#define IPQ9574_PHY_MAX 6
#define IPQ6018_PHY_MAX 5
#define MDIO_CTRL_0_REG 0x00090040
#define MDIO_CTRL_0_DIV(x) (x << 0)
@ -43,14 +44,17 @@
#define AQUANTIA_PHY_107 0x03a1b4e2
#define AQUANTIA_PHY_109 0x03a1b502
#define AQUANTIA_PHY_111 0x03a1b610
#define AQUANTIA_PHY_112 0x03a1b660
#define AQUANTIA_PHY_111B0 0x03a1b612
#define AQUANTIA_PHY_112 0x03a1b660
#define AQUANTIA_PHY_112C 0x03a1b792
#define AQUANTIA_PHY_113C_A0 0x31c31C10
#define AQUANTIA_PHY_113C_A1 0x31c31C11
#define AQUANTIA_PHY_113C_B0 0x31c31C12
#define AQUANTIA_PHY_113C_B1 0x31c31C13
#define AQU_PHY_ADDR 0x7
#define QCA_PHY_ID1 0x2
#define QCA_PHY_ID2 0x3
/* Phy preferred medium type */
typedef enum {
QCA8075_PHY_MEDIUM_COPPER = 0,
@ -87,6 +91,31 @@ typedef enum {
FAL_CABLE_STATUS_BUTT = 0xffff,
} fal_cable_status_t;
enum eport_wrapper_cfg {
EPORT_WRAPPER_PSGMII = 0,
EPORT_WRAPPER_PSGMII_RGMII5,
EPORT_WRAPPER_SGMII0_RGMII5,
EPORT_WRAPPER_SGMII1_RGMII5,
EPORT_WRAPPER_PSGMII_RMII0,
EPORT_WRAPPER_PSGMII_RMII1,
EPORT_WRAPPER_PSGMII_RMII0_RMII1,
EPORT_WRAPPER_PSGMII_RGMII4,
EPORT_WRAPPER_SGMII0_RGMII4,
EPORT_WRAPPER_SGMII1_RGMII4,
EPORT_WRAPPER_SGMII4_RGMII4,
EPORT_WRAPPER_QSGMII,
EPORT_WRAPPER_SGMII_PLUS,
EPORT_WRAPPER_USXGMII,
EPORT_WRAPPER_10GBASE_R,
EPORT_WRAPPER_SGMII_CHANNEL0,
EPORT_WRAPPER_SGMII_CHANNEL1,
EPORT_WRAPPER_SGMII_CHANNEL4,
EPORT_WRAPPER_RGMII,
EPORT_WRAPPER_PSGMII_FIBER,
EPORT_WRAPPER_SGMII_FIBER,
EPORT_WRAPPER_MAX = 0xFF
};
enum port_wrapper_cfg {
PORT_WRAPPER_PSGMII = 0,
PORT_WRAPPER_SGMII0_RGMII4,

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014, 2015-2017, 2020 The Linux Foundation. All rights reserved.
* Copyright (c) 2014, 2015-2017, 2020-2021 The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@ -312,6 +312,51 @@ DECLARE_GLOBAL_DATA_PTR;
#define PCIE_0_PCS_PCIE_PRESET_P10_PRE 0xCBC
#define PCIE_0_PCS_PCIE_PRESET_P10_POST 0xCE0
#define PCIE_0_QSERDES_PLL_SSC_EN_CENTER 0x010
#define PCIE_0_QSERDES_PLL_SSC_ADJ_PER1 0x014
#define PCIE_0_QSERDES_PLL_SSC_ADJ_PER2 0x018
#define PCIE_0_QSERDES_TX1_RES_CODE_LANE_OFFSET_TX 0x63C
#define PCIE_0_QSERDES_TX1_RCV_DETECT_LVL_2 0x69C
#define PCIE_0_QSERDES_TX1_HIGHZ_DRVR_EN 0x658
#define PCIE_0_QSERDES_TX1_LANE_MODE_1 0x684
#define PCIE_0_QSERDES_RX1_SIGDET_CNTRL 0x91C
#define PCIE_0_QSERDES_RX1_SIGDET_ENABLES 0x918
#define PCIE_0_QSERDES_RX1_SIGDET_DEGLITCH_CNTRL 0x924
#define PCIE_0_QSERDES_RX1_RX_EQU_ADAPTOR_CNTRL2 0x8EC
#define PCIE_0_QSERDES_RX1_RX_EQU_ADAPTOR_CNTRL3 0x8F0
#define PCIE_0_QSERDES_RX1_RX_EQU_ADAPTOR_CNTRL4 0x8F4
#define PCIE_0_QSERDES_RX1_DFE_EN_TIMER 0x9B4
#define PCIE_0_QSERDES_RX1_UCDR_FO_GAIN 0x808
#define PCIE_0_QSERDES_RX1_UCDR_SO_GAIN 0x814
#define PCIE_0_QSERDES_RX1_UCDR_SO_SATURATION_AND_ENABLE 0x834
#define PCIE_0_QSERDES_RX1_UCDR_PI_CONTROLS 0x844
#define PCIE_0_QSERDES_RX1_RX_EQ_OFFSET_ADAPTOR_CNTRL1 0x910
#define PCIE_0_QSERDES_RX1_RX_OFFSET_ADAPTOR_CNTRL2 0x914
#define PCIE_0_QSERDES_RX1_RX_MODE_10_LOW 0x998
#define PCIE_0_QSERDES_RX1_RX_MODE_10_HIGH 0x99C
#define PCIE_0_QSERDES_RX1_RX_MODE_10_HIGH2 0x9A0
#define PCIE_0_QSERDES_RX1_RX_MODE_10_HIGH3 0x9A4
#define PCIE_0_QSERDES_RX1_RX_MODE_10_HIGH4 0x9A8
#define PCIE_0_QSERDES_RX1_RX_MODE_01_LOW 0x984
#define PCIE_0_QSERDES_RX1_RX_MODE_01_HIGH 0x988
#define PCIE_0_QSERDES_RX1_RX_MODE_01_HIGH2 0x98C
#define PCIE_0_QSERDES_RX1_RX_MODE_01_HIGH3 0x990
#define PCIE_0_QSERDES_RX1_RX_MODE_01_HIGH4 0x994
#define PCIE_0_QSERDES_RX1_RX_MODE_00_LOW 0x970
#define PCIE_0_QSERDES_RX1_RX_MODE_00_HIGH 0x974
#define PCIE_0_QSERDES_RX1_RX_MODE_00_HIGH2 0x978
#define PCIE_0_QSERDES_RX1_RX_MODE_00_HIGH3 0x97C
#define PCIE_0_QSERDES_RX1_RX_MODE_00_HIGH4 0x980
#define PCIE_0_QSERDES_RX1_RX_IDAC_TSETTLE_HIGH 0x8FC
#define PCIE_0_QSERDES_RX1_RX_IDAC_TSETTLE_LOW 0x8F8
#define PCIE_0_QSERDES_RX1_RX_MODE_00_HIGH3 0x97C
#define PCIE_0_PCS_PCIE_OSC_DTCT_CONFIG1 0xC58
#define PCIE_0_PCS_PCIE_OSC_DTCT_CONFIG4 0xC64
#define PCIE_0_PCS_PCIE_INT_AUX_CLK_CONFIG1 0xC50
#define PCIE_0_PCS_PCIE_OSC_DTCT_MODE2_CONFIG6 0xC88
#define PARF_MHI_CLOCK_RESET_CTRL 0x174
#define BYPASS BIT(4)
#define MSTR_AXI_CLK_EN BIT(1)
@ -369,6 +414,182 @@ struct phy_regs {
u32 val;
};
static const struct phy_regs pcie_phy_v2_x2_init_seq_ipq[] = {
{ PCS_COM_POWER_DOWN_CONTROL + 0x800, 0x00000001},
{ PCIE_0_QSERDES_PLL_BIAS_EN_CLKBUFLR_EN, 0x00000018},
{ PCIE_0_QSERDES_PLL_BIAS_EN_CTRL_BY_PSM, 0x00000001},
{ PCIE_0_QSERDES_PLL_CLK_SELECT, 0x00000031},
{ PCIE_0_QSERDES_PLL_PLL_IVCO, 0x0000000F},
{ PCIE_0_QSERDES_PLL_BG_TRIM, 0x0000000F},
/* delay 5ms */
{ PCIE_PHY_DELAY_MS, 0x00000005},
{ PCIE_0_QSERDES_PLL_CMN_CONFIG, 0x00000006},
{ PCIE_0_QSERDES_PLL_LOCK_CMP_EN, 0x00000042},
{ PCIE_0_QSERDES_PLL_RESETSM_CNTRL, 0x00000020},
{ PCIE_0_QSERDES_PLL_SVS_MODE_CLK_SEL, 0x00000001},
{ PCIE_0_QSERDES_PLL_VCO_TUNE_MAP, 0x00000004},
{ PCIE_0_QSERDES_PLL_SVS_MODE_CLK_SEL, 0x00000005},
{ PCIE_0_QSERDES_PLL_VCO_TUNE_TIMER1, 0x000000FF},
{ PCIE_0_QSERDES_PLL_VCO_TUNE_TIMER2, 0x0000003F},
{ PCIE_0_QSERDES_PLL_CORE_CLK_EN, 0x00000030},
{ PCIE_0_QSERDES_PLL_HSCLK_SEL, 0x00000021},
{ PCIE_0_QSERDES_PLL_DEC_START_MODE0, 0x00000068},
{ PCIE_0_QSERDES_PLL_DIV_FRAC_START3_MODE0, 0x00000002},
{ PCIE_0_QSERDES_PLL_DIV_FRAC_START2_MODE0, 0x000000AA},
{ PCIE_0_QSERDES_PLL_DIV_FRAC_START1_MODE0, 0x000000AB},
{ PCIE_0_QSERDES_PLL_LOCK_CMP2_MODE0, 0x00000014},
{ PCIE_0_QSERDES_PLL_LOCK_CMP1_MODE0, 0x000000D4},
{ PCIE_0_QSERDES_PLL_CP_CTRL_MODE0, 0x00000009},
{ PCIE_0_QSERDES_PLL_PLL_RCTRL_MODE0, 0x00000016},
{ PCIE_0_QSERDES_PLL_PLL_CCTRL_MODE0, 0x00000028},
{ PCIE_0_QSERDES_PLL_INTEGLOOP_GAIN1_MODE0, 0x00000000},
{ PCIE_0_QSERDES_PLL_INTEGLOOP_GAIN0_MODE0, 0x000000A0},
{ PCIE_0_QSERDES_PLL_VCO_TUNE2_MODE0, 0x00000002},
{ PCIE_0_QSERDES_PLL_VCO_TUNE1_MODE0, 0x00000024},
{ PCIE_0_QSERDES_PLL_SVS_MODE_CLK_SEL, 0x00000005},
{ PCIE_0_QSERDES_PLL_CORE_CLK_EN, 0x00000000},
{ PCIE_0_QSERDES_PLL_CORECLK_DIV, 0x0000000A},
{ PCIE_0_QSERDES_PLL_CLK_SELECT, 0x00000032},
{ PCIE_0_QSERDES_PLL_SYS_CLK_CTRL, 0x00000002},
{ PCIE_0_QSERDES_PLL_SYSCLK_BUF_ENABLE, 0x00000007},
{ PCIE_0_QSERDES_PLL_SYSCLK_EN_SEL, 0x00000008},
{ PCIE_0_QSERDES_PLL_BG_TIMER, 0x0000000A},
{ PCIE_0_QSERDES_PLL_HSCLK_SEL, 0x00000001},
{ PCIE_0_QSERDES_PLL_DEC_START_MODE1, 0x00000053},
{ PCIE_0_QSERDES_PLL_DIV_FRAC_START3_MODE1, 0x00000005},
{ PCIE_0_QSERDES_PLL_DIV_FRAC_START2_MODE1, 0x00000055},
{ PCIE_0_QSERDES_PLL_DIV_FRAC_START1_MODE1, 0x00000055},
{ PCIE_0_QSERDES_PLL_LOCK_CMP2_MODE1, 0x00000029},
{ PCIE_0_QSERDES_PLL_LOCK_CMP1_MODE1, 0x000000AA},
{ PCIE_0_QSERDES_PLL_CP_CTRL_MODE1, 0x00000009},
{ PCIE_0_QSERDES_PLL_PLL_RCTRL_MODE1, 0x00000016},
{ PCIE_0_QSERDES_PLL_PLL_CCTRL_MODE1, 0x00000028},
{ PCIE_0_QSERDES_PLL_INTEGLOOP_GAIN1_MODE1, 0x00000000},
{ PCIE_0_QSERDES_PLL_INTEGLOOP_GAIN0_MODE1, 0x000000A0},
{ PCIE_0_QSERDES_PLL_VCO_TUNE2_MODE1, 0x00000003},
{ PCIE_0_QSERDES_PLL_VCO_TUNE1_MODE1, 0x000000B4},
{ PCIE_0_QSERDES_PLL_SVS_MODE_CLK_SEL, 0x00000005},
{ PCIE_0_QSERDES_PLL_CORE_CLK_EN, 0x00000000},
{ PCIE_0_QSERDES_PLL_CORECLK_DIV_MODE1, 0x00000008},
/* SSC init */
{ PCIE_0_QSERDES_PLL_SSC_EN_CENTER, 0x00000001},
{ PCIE_0_QSERDES_PLL_SSC_PER1, 0x0000007D},
{ PCIE_0_QSERDES_PLL_SSC_PER2, 0x00000001},
{ PCIE_0_QSERDES_PLL_SSC_ADJ_PER1, 0x00000000},
{ PCIE_0_QSERDES_PLL_SSC_ADJ_PER2, 0x00000000},
{ PCIE_0_QSERDES_PLL_SSC_STEP_SIZE1_MODE0, 0x0000000A},
{ PCIE_0_QSERDES_PLL_SSC_STEP_SIZE2_MODE0, 0x00000005},
{ PCIE_0_QSERDES_PLL_SSC_STEP_SIZE1_MODE1, 0x00000008},
{ PCIE_0_QSERDES_PLL_SSC_STEP_SIZE2_MODE1, 0x00000004},
/*qmp_tx_init*/
{ PCIE_0_QSERDES_TX0_RES_CODE_LANE_OFFSET_TX, 0x00000002},
{ PCIE_0_QSERDES_TX0_RCV_DETECT_LVL_2, 0x00000012},
{ PCIE_0_QSERDES_TX0_HIGHZ_DRVR_EN, 0x00000010},
{ PCIE_0_QSERDES_TX0_LANE_MODE_1, 0x00000006},
/*qmp_rx_init*/
{ PCIE_0_QSERDES_RX0_SIGDET_CNTRL, 0x00000003},
{ PCIE_0_QSERDES_RX0_SIGDET_ENABLES, 0x0000001C},
{ PCIE_0_QSERDES_RX0_SIGDET_DEGLITCH_CNTRL, 0x00000014},
{ PCIE_0_QSERDES_RX0_RX_EQU_ADAPTOR_CNTRL2, 0x00000061},
{ PCIE_0_QSERDES_RX0_RX_EQU_ADAPTOR_CNTRL3, 0x00000004},
{ PCIE_0_QSERDES_RX0_RX_EQU_ADAPTOR_CNTRL4, 0x0000001E},
{ PCIE_0_QSERDES_RX0_DFE_EN_TIMER, 0x00000004},
{ PCIE_0_QSERDES_RX0_UCDR_FO_GAIN, 0x0000000C},
{ PCIE_0_QSERDES_RX0_UCDR_SO_GAIN, 0x00000002},
{ PCIE_0_QSERDES_RX0_UCDR_SO_SATURATION_AND_ENABLE, 0x0000007F},
{ PCIE_0_QSERDES_RX0_UCDR_PI_CONTROLS, 0x00000070},
{ PCIE_0_QSERDES_RX0_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x00000073},
{ PCIE_0_QSERDES_RX0_RX_OFFSET_ADAPTOR_CNTRL2, 0x00000080},
{ PCIE_0_QSERDES_RX0_RX_MODE_10_LOW, 0x00000000},
{ PCIE_0_QSERDES_RX0_RX_MODE_10_HIGH, 0x00000002},
{ PCIE_0_QSERDES_RX0_RX_MODE_10_HIGH2, 0x000000C8},
{ PCIE_0_QSERDES_RX0_RX_MODE_10_HIGH3, 0x00000009},
{ PCIE_0_QSERDES_RX0_RX_MODE_10_HIGH4, 0x000000B1},
{ PCIE_0_QSERDES_RX0_RX_MODE_01_LOW, 0x00000000},
{ PCIE_0_QSERDES_RX0_RX_MODE_01_HIGH, 0x00000002},
{ PCIE_0_QSERDES_RX0_RX_MODE_01_HIGH2, 0x000000C8},
{ PCIE_0_QSERDES_RX0_RX_MODE_01_HIGH3, 0x00000009},
{ PCIE_0_QSERDES_RX0_RX_MODE_01_HIGH4, 0x000000B1},
{ PCIE_0_QSERDES_RX0_RX_MODE_00_LOW, 0x000000F0},
{ PCIE_0_QSERDES_RX0_RX_MODE_00_HIGH, 0x00000002},
{ PCIE_0_QSERDES_RX0_RX_MODE_00_HIGH2, 0x0000002F},
{ PCIE_0_QSERDES_RX0_RX_MODE_00_HIGH3, 0x000000D3},
{ PCIE_0_QSERDES_RX0_RX_MODE_00_HIGH4, 0x00000040},
{ PCIE_0_QSERDES_RX0_RX_IDAC_TSETTLE_HIGH, 0x00000000},
{ PCIE_0_QSERDES_RX0_RX_IDAC_TSETTLE_LOW, 0x000000C0},
/* TX1 & RX1 */
{ PCIE_0_QSERDES_TX1_RES_CODE_LANE_OFFSET_TX, 0x00000002},
{ PCIE_0_QSERDES_TX1_RCV_DETECT_LVL_2 , 0x00000012},
{ PCIE_0_QSERDES_TX1_HIGHZ_DRVR_EN , 0x00000010},
{ PCIE_0_QSERDES_TX1_LANE_MODE_1, 0x00000006},
{ PCIE_0_QSERDES_RX1_SIGDET_CNTRL, 0x00000003},
{ PCIE_0_QSERDES_RX1_SIGDET_ENABLES, 0x0000001C},
{ PCIE_0_QSERDES_RX1_SIGDET_DEGLITCH_CNTRL, 0x00000014},
{ PCIE_0_QSERDES_RX1_RX_EQU_ADAPTOR_CNTRL2, 0x00000061},
{ PCIE_0_QSERDES_RX1_RX_EQU_ADAPTOR_CNTRL3, 0x00000004},
{ PCIE_0_QSERDES_RX1_RX_EQU_ADAPTOR_CNTRL4, 0x0000001E},
{ PCIE_0_QSERDES_RX1_DFE_EN_TIMER, 0x00000004},
{ PCIE_0_QSERDES_RX1_UCDR_FO_GAIN, 0x0000000C},
{ PCIE_0_QSERDES_RX1_UCDR_SO_GAIN, 0x00000002},
{ PCIE_0_QSERDES_RX1_UCDR_SO_SATURATION_AND_ENABLE, 0x0000007F},
{ PCIE_0_QSERDES_RX1_UCDR_PI_CONTROLS, 0x00000070},
{ PCIE_0_QSERDES_RX1_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x00000073},
{ PCIE_0_QSERDES_RX1_RX_OFFSET_ADAPTOR_CNTRL2, 0x00000080},
{ PCIE_0_QSERDES_RX1_RX_MODE_10_LOW, 0x00000000},
{ PCIE_0_QSERDES_RX1_RX_MODE_10_HIGH, 0x00000002},
{ PCIE_0_QSERDES_RX1_RX_MODE_10_HIGH2, 0x000000C8},
{ PCIE_0_QSERDES_RX1_RX_MODE_10_HIGH3, 0x00000009},
{ PCIE_0_QSERDES_RX1_RX_MODE_10_HIGH4, 0x000000B1},
{ PCIE_0_QSERDES_RX1_RX_MODE_01_LOW, 0x00000000},
{ PCIE_0_QSERDES_RX1_RX_MODE_01_HIGH, 0x00000002},
{ PCIE_0_QSERDES_RX1_RX_MODE_01_HIGH2, 0x000000C8},
{ PCIE_0_QSERDES_RX1_RX_MODE_01_HIGH3, 0x00000009},
{ PCIE_0_QSERDES_RX1_RX_MODE_01_HIGH4, 0x000000B1},
{ PCIE_0_QSERDES_RX1_RX_MODE_00_LOW, 0x000000F0},
{ PCIE_0_QSERDES_RX1_RX_MODE_00_HIGH, 0x00000002},
{ PCIE_0_QSERDES_RX1_RX_MODE_00_HIGH2, 0x0000002F},
{ PCIE_0_QSERDES_RX1_RX_MODE_00_HIGH3, 0x000000D3},
{ PCIE_0_QSERDES_RX1_RX_MODE_00_HIGH4, 0x00000040},
{ PCIE_0_QSERDES_RX1_RX_IDAC_TSETTLE_HIGH, 0x00000000},
{ PCIE_0_QSERDES_RX1_RX_IDAC_TSETTLE_LOW, 0x000000C0},
{ PCIE_0_PCS_COM_REFGEN_REQ_CONFIG1 + 0x800, 0x0000000D},
{ PCIE_0_PCS_COM_G12S1_TXDEEMPH_M3P5DB + 0x800, 0x00000010},
{ PCIE_0_PCS_COM_P2U3_WAKEUP_DLY_TIME_AUXCLK_H + 0x800, 0x00000000},
{ PCIE_0_PCS_COM_P2U3_WAKEUP_DLY_TIME_AUXCLK_L + 0x800, 0x00000001},
{ PCIE_0_PCS_PCIE_OSC_DTCT_ACTIONS + 0x804, 0x00000000},
{ PCIE_0_PCS_PCIE_POWER_STATE_CONFIG2 + 0x800, 0x0000001D},
{ PCIE_0_PCS_PCIE_L1P1_WAKEUP_DLY_TIME_AUXCLK_H + 0x804,0x00000000},
{ PCIE_0_PCS_PCIE_L1P1_WAKEUP_DLY_TIME_AUXCLK_L + 0x804,0x00000001},
{ PCIE_0_PCS_PCIE_L1P2_WAKEUP_DLY_TIME_AUXCLK_H + 0x804,0x00000000},
{ PCIE_0_PCS_PCIE_L1P2_WAKEUP_DLY_TIME_AUXCLK_L + 0x804,0x00000001},
{ PCIE_0_PCS_PCIE_EQ_CONFIG1 + 0x804, 0x00000014},
{ PCIE_0_PCS_PCIE_EQ_CONFIG1 + 0x804, 0x00000010},
{ PCIE_0_PCS_PCIE_EQ_CONFIG2 + 0x804, 0x0000000B},
{ PCIE_0_PCS_PCIE_PRESET_P10_PRE + 0x804, 0x00000000},
{ PCIE_0_PCS_PCIE_PRESET_P10_POST + 0x804, 0x00000058},
{ PCIE_0_PCS_PCIE_POWER_STATE_CONFIG4 + 0x800, 0x00000007},
{ PCIE_0_PCS_PCIE_OSC_DTCT_CONFIG1 + 0x804, 0x00000000},
{ PCIE_0_PCS_PCIE_OSC_DTCT_CONFIG2 + 0x804, 0x00000052},
{ PCIE_0_PCS_PCIE_OSC_DTCT_CONFIG4 + 0x804, 0x00000019},
{ PCIE_0_PCS_PCIE_INT_AUX_CLK_CONFIG1 + 0x804, 0x00000000},
{ PCIE_0_PCS_PCIE_OSC_DTCT_MODE2_CONFIG2 + 0x804, 0x00000049},
{ PCIE_0_PCS_PCIE_OSC_DTCT_MODE2_CONFIG4 + 0x804, 0x0000002A},
{ PCIE_0_PCS_PCIE_OSC_DTCT_MODE2_CONFIG5 + 0x804, 0x00000002},
{ PCIE_0_PCS_PCIE_OSC_DTCT_MODE2_CONFIG6 + 0x804, 0x00000003},
{ PCIE_0_QSERDES_PLL_CLK_EP_DIV_MODE0, 0x00000019},
{ PCIE_0_QSERDES_PLL_CLK_EP_DIV_MODE1, 0x00000028},
{ PCIE_0_QSERDES_PLL_CLK_ENABLE1, 0x00000090},
{ PCIE_0_QSERDES_PLL_HSCLK_SEL, 0x00000089},
{ PCIE_0_QSERDES_PLL_CLK_ENABLE1, 0x00000010},
{ PCIE_0_PCS_COM_POWER_DOWN_CONTROL + 0x800, 0x00000003},
{ PCIE_0_PCS_PCIE_ENDPOINT_REFCLK_DRIVE + 0x804, 0x000000C1},
{ PCIE_0_PCS_COM_RX_DCC_CAL_CONFIG + 0x800, 0x00000001},
{ PCIE_0_PCS_COM_RX_SIGDET_LVL + 0x800, 0x000000AA},
{ PCIE_0_PCS_COM_SW_RESET + 0x800, 0x00000000},
{ PCIE_0_PCS_COM_START_CONTROL + 0x800, 0x00000002},
{ PCIE_0_PCS_COM_START_CONTROL + 0x800, 0x00000003},
};
static const struct phy_regs pcie_phy_v2_init_seq_ipq[] = {
#if !defined(CONFIG_IPQ6018)
{ PCS_COM_POWER_DOWN_CONTROL, 0x00000001},
@ -491,6 +712,143 @@ static const struct phy_regs pcie_phy_v2_init_seq_ipq[] = {
{ PCIE_0_PCS_COM_REFGEN_REQ_CONFIG1, 0x0000000D},
{ PCIE_0_PCS_COM_SW_RESET, 0x00000000},
{ PCIE_0_PCS_COM_START_CONTROL, 0x00000003},
#elif defined(CONFIG_IPQ9574)
{ PCS_COM_POWER_DOWN_CONTROL, 0x00000001},
{ PCIE_0_QSERDES_PLL_BIAS_EN_CLKBUFLR_EN, 0x00000018},
{ PCIE_0_QSERDES_PLL_BIAS_EN_CTRL_BY_PSM, 0x00000001},
{ PCIE_0_QSERDES_PLL_CLK_SELECT, 0x00000031},
{ PCIE_0_QSERDES_PLL_PLL_IVCO, 0x0000000F},
{ PCIE_0_QSERDES_PLL_BG_TRIM, 0x0000000F},
/* delay 5ms */
{ PCIE_PHY_DELAY_MS, 0x00000005},
{ PCIE_0_QSERDES_PLL_CMN_CONFIG, 0x00000006},
{ PCIE_0_QSERDES_PLL_LOCK_CMP_EN, 0x00000042},
{ PCIE_0_QSERDES_PLL_RESETSM_CNTRL, 0x00000020},
{ PCIE_0_QSERDES_PLL_SVS_MODE_CLK_SEL, 0x00000001},
{ PCIE_0_QSERDES_PLL_VCO_TUNE_MAP, 0x00000004},
{ PCIE_0_QSERDES_PLL_SVS_MODE_CLK_SEL, 0x00000005},
{ PCIE_0_QSERDES_PLL_VCO_TUNE_TIMER1, 0x000000FF},
{ PCIE_0_QSERDES_PLL_VCO_TUNE_TIMER2, 0x0000003F},
{ PCIE_0_QSERDES_PLL_CORE_CLK_EN, 0x00000030},
{ PCIE_0_QSERDES_PLL_HSCLK_SEL, 0x00000021},
{ PCIE_0_QSERDES_PLL_DEC_START_MODE0, 0x00000068},
{ PCIE_0_QSERDES_PLL_DIV_FRAC_START3_MODE0, 0x00000002},
{ PCIE_0_QSERDES_PLL_DIV_FRAC_START2_MODE0, 0x000000AA},
{ PCIE_0_QSERDES_PLL_DIV_FRAC_START1_MODE0, 0x000000AB},
{ PCIE_0_QSERDES_PLL_LOCK_CMP2_MODE0, 0x00000014},
{ PCIE_0_QSERDES_PLL_LOCK_CMP1_MODE0, 0x000000D4},
{ PCIE_0_QSERDES_PLL_CP_CTRL_MODE0, 0x00000009},
{ PCIE_0_QSERDES_PLL_PLL_RCTRL_MODE0, 0x00000016},
{ PCIE_0_QSERDES_PLL_PLL_CCTRL_MODE0, 0x00000028},
{ PCIE_0_QSERDES_PLL_INTEGLOOP_GAIN1_MODE0, 0x00000000},
{ PCIE_0_QSERDES_PLL_INTEGLOOP_GAIN0_MODE0, 0x000000A0},
{ PCIE_0_QSERDES_PLL_VCO_TUNE2_MODE0, 0x00000002},
{ PCIE_0_QSERDES_PLL_VCO_TUNE1_MODE0, 0x00000024},
{ PCIE_0_QSERDES_PLL_SVS_MODE_CLK_SEL, 0x00000005},
{ PCIE_0_QSERDES_PLL_CORE_CLK_EN, 0x00000020},
{ PCIE_0_QSERDES_PLL_CORECLK_DIV, 0x0000000A},
{ PCIE_0_QSERDES_PLL_CLK_SELECT, 0x00000032},
{ PCIE_0_QSERDES_PLL_SYS_CLK_CTRL, 0x00000002},
{ PCIE_0_QSERDES_PLL_SYSCLK_BUF_ENABLE, 0x00000007},
{ PCIE_0_QSERDES_PLL_SYSCLK_EN_SEL, 0x00000008},
{ PCIE_0_QSERDES_PLL_BG_TIMER, 0x0000000A},
{ PCIE_0_QSERDES_PLL_HSCLK_SEL, 0x00000001},
{ PCIE_0_QSERDES_PLL_DEC_START_MODE1, 0x00000053},
{ PCIE_0_QSERDES_PLL_DIV_FRAC_START3_MODE1, 0x00000005},
{ PCIE_0_QSERDES_PLL_DIV_FRAC_START2_MODE1, 0x00000055},
{ PCIE_0_QSERDES_PLL_DIV_FRAC_START1_MODE1, 0x00000055},
{ PCIE_0_QSERDES_PLL_LOCK_CMP2_MODE1, 0x00000029},
{ PCIE_0_QSERDES_PLL_LOCK_CMP1_MODE1, 0x000000AA},
{ PCIE_0_QSERDES_PLL_CP_CTRL_MODE1, 0x00000009},
{ PCIE_0_QSERDES_PLL_PLL_RCTRL_MODE1, 0x00000016},
{ PCIE_0_QSERDES_PLL_PLL_CCTRL_MODE1, 0x00000028},
{ PCIE_0_QSERDES_PLL_INTEGLOOP_GAIN1_MODE1, 0x00000000},
{ PCIE_0_QSERDES_PLL_INTEGLOOP_GAIN0_MODE1, 0x000000A0},
{ PCIE_0_QSERDES_PLL_VCO_TUNE2_MODE1, 0x00000003},
{ PCIE_0_QSERDES_PLL_VCO_TUNE1_MODE1, 0x000000B4},
{ PCIE_0_QSERDES_PLL_SVS_MODE_CLK_SEL, 0x00000005},
{ PCIE_0_QSERDES_PLL_CORE_CLK_EN, 0x00000000},
{ PCIE_0_QSERDES_PLL_CORECLK_DIV_MODE1, 0x00000008},
/* SSC init */
{ PCIE_0_QSERDES_PLL_SSC_EN_CENTER, 0x00000001},
{ PCIE_0_QSERDES_PLL_SSC_PER1, 0x0000007D},
{ PCIE_0_QSERDES_PLL_SSC_PER2, 0x00000001},
{ PCIE_0_QSERDES_PLL_SSC_ADJ_PER1, 0x00000000},
{ PCIE_0_QSERDES_PLL_SSC_ADJ_PER2, 0x00000000},
{ PCIE_0_QSERDES_PLL_SSC_STEP_SIZE1_MODE0, 0x0000000A},
{ PCIE_0_QSERDES_PLL_SSC_STEP_SIZE2_MODE0, 0x00000005},
{ PCIE_0_QSERDES_PLL_SSC_STEP_SIZE1_MODE1, 0x00000008},
{ PCIE_0_QSERDES_PLL_SSC_STEP_SIZE2_MODE1, 0x00000004},
/*qmp_tx_init*/
{ PCIE_0_QSERDES_TX0_RES_CODE_LANE_OFFSET_TX, 0x00000002},
{ PCIE_0_QSERDES_TX0_RCV_DETECT_LVL_2, 0x00000012},
{ PCIE_0_QSERDES_TX0_HIGHZ_DRVR_EN, 0x00000010},
{ PCIE_0_QSERDES_TX0_LANE_MODE_1, 0x00000006},
/*qmp_rx_init*/
{ PCIE_0_QSERDES_RX0_SIGDET_CNTRL, 0x00000003},
{ PCIE_0_QSERDES_RX0_SIGDET_ENABLES, 0x0000001C},
{ PCIE_0_QSERDES_RX0_SIGDET_DEGLITCH_CNTRL, 0x00000014},
{ PCIE_0_QSERDES_RX0_RX_EQU_ADAPTOR_CNTRL2, 0x00000061},
{ PCIE_0_QSERDES_RX0_RX_EQU_ADAPTOR_CNTRL3, 0x00000004},
{ PCIE_0_QSERDES_RX0_RX_EQU_ADAPTOR_CNTRL4, 0x0000001E},
{ PCIE_0_QSERDES_RX0_DFE_EN_TIMER, 0x00000004},
{ PCIE_0_QSERDES_RX0_UCDR_FO_GAIN, 0x0000000C},
{ PCIE_0_QSERDES_RX0_UCDR_SO_GAIN, 0x00000002},
{ PCIE_0_QSERDES_RX0_UCDR_SO_SATURATION_AND_ENABLE, 0x0000007F},
{ PCIE_0_QSERDES_RX0_UCDR_PI_CONTROLS, 0x00000070},
{ PCIE_0_QSERDES_RX0_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x00000073},
{ PCIE_0_QSERDES_RX0_RX_OFFSET_ADAPTOR_CNTRL2, 0x00000080},
{ PCIE_0_QSERDES_RX0_RX_MODE_10_LOW, 0x00000000},
{ PCIE_0_QSERDES_RX0_RX_MODE_10_HIGH, 0x00000002},
{ PCIE_0_QSERDES_RX0_RX_MODE_10_HIGH2, 0x000000C8},
{ PCIE_0_QSERDES_RX0_RX_MODE_10_HIGH3, 0x00000009},
{ PCIE_0_QSERDES_RX0_RX_MODE_10_HIGH4, 0x000000B1},
{ PCIE_0_QSERDES_RX0_RX_MODE_01_LOW, 0x00000000},
{ PCIE_0_QSERDES_RX0_RX_MODE_01_HIGH, 0x00000002},
{ PCIE_0_QSERDES_RX0_RX_MODE_01_HIGH2, 0x000000C8},
{ PCIE_0_QSERDES_RX0_RX_MODE_01_HIGH3, 0x00000009},
{ PCIE_0_QSERDES_RX0_RX_MODE_01_HIGH4, 0x000000B1},
{ PCIE_0_QSERDES_RX0_RX_MODE_00_LOW, 0x000000F0},
{ PCIE_0_QSERDES_RX0_RX_MODE_00_HIGH, 0x00000002},
{ PCIE_0_QSERDES_RX0_RX_MODE_00_HIGH2, 0x0000002F},
{ PCIE_0_QSERDES_RX0_RX_MODE_00_HIGH3, 0x000000D3},
{ PCIE_0_QSERDES_RX0_RX_MODE_00_HIGH4, 0x00000040},
{ PCIE_0_QSERDES_RX0_RX_IDAC_TSETTLE_HIGH, 0x00000000},
{ PCIE_0_QSERDES_RX0_RX_IDAC_TSETTLE_LOW, 0x000000C0},
{ PCIE_0_PCS_COM_P2U3_WAKEUP_DLY_TIME_AUXCLK_H, 0x00000000},
{ PCIE_0_PCS_COM_P2U3_WAKEUP_DLY_TIME_AUXCLK_L, 0x00000001},
{ PCIE_0_PCS_PCIE_OSC_DTCT_ACTIONS, 0x00000000},
{ PCIE_0_PCS_PCIE_POWER_STATE_CONFIG2, 0x0000000D},
{ PCIE_0_PCS_PCIE_L1P1_WAKEUP_DLY_TIME_AUXCLK_H, 0x00000000},
{ PCIE_0_PCS_PCIE_L1P1_WAKEUP_DLY_TIME_AUXCLK_L, 0x00000001},
{ PCIE_0_PCS_PCIE_L1P2_WAKEUP_DLY_TIME_AUXCLK_H, 0x00000000},
{ PCIE_0_PCS_PCIE_L1P2_WAKEUP_DLY_TIME_AUXCLK_L, 0x00000001},
{ PCIE_0_PCS_PCIE_EQ_CONFIG1, 0x00000014},
{ PCIE_0_PCS_PCIE_EQ_CONFIG1, 0x00000010},
{ PCIE_0_PCS_PCIE_EQ_CONFIG2, 0x0000000B},
{ PCIE_0_PCS_PCIE_PRESET_P10_PRE, 0x00000000},
{ PCIE_0_PCS_PCIE_PRESET_P10_POST, 0x00000058},
{ PCIE_0_PCS_PCIE_POWER_STATE_CONFIG4, 0x00000007},
{ PCIE_0_PCS_PCIE_OSC_DTCT_CONFIG2, 0x00000052},
{ PCIE_0_PCS_PCIE_INT_AUX_CLK_CONFIG1, 0x00000000},
{ PCIE_0_PCS_PCIE_OSC_DTCT_MODE2_CONFIG2, 0x00000050},
{ PCIE_0_PCS_PCIE_OSC_DTCT_MODE2_CONFIG4, 0x0000001A},
{ PCIE_0_PCS_PCIE_OSC_DTCT_MODE2_CONFIG5, 0x00000006},
{ PCIE_0_PCS_PCIE_OSC_DTCT_MODE2_CONFIG6, 0x00000003},
{ PCIE_0_QSERDES_PLL_CLK_EP_DIV_MODE0, 0x00000019},
{ PCIE_0_QSERDES_PLL_CLK_EP_DIV_MODE1, 0x00000028},
{ PCIE_0_QSERDES_PLL_CLK_ENABLE1, 0x00000090},
{ PCIE_0_QSERDES_PLL_HSCLK_SEL, 0x00000089},
{ PCIE_0_QSERDES_PLL_CLK_ENABLE1, 0x00000010},
{ PCIE_0_PCS_COM_POWER_DOWN_CONTROL, 0x00000003},
{ PCIE_0_PCS_PCIE_ENDPOINT_REFCLK_DRIVE, 0x000000C1},
{ PCIE_0_PCS_COM_RX_DCC_CAL_CONFIG, 0x00000001},
{ PCIE_0_PCS_COM_RX_SIGDET_LVL, 0x000000AA},
{ PCIE_0_PCS_COM_REFGEN_REQ_CONFIG1, 0x0000000D},
{ PCIE_0_PCS_COM_G12S1_TXDEEMPH_M3P5DB, 0x00000010},
{ PCIE_0_PCS_COM_SW_RESET, 0x00000000},
{ PCIE_0_PCS_COM_START_CONTROL, 0x00000002},
{ PCIE_0_PCS_COM_START_CONTROL, 0x00000003},
#else
{ PCIE_0_PCS_COM_POWER_DOWN_CONTROL, 0x03 },
{ PCIE_0_QSERDES_PLL_SSC_PER1, 0x7D },
@ -607,6 +965,7 @@ static const struct udevice_id pcie_ver_ids[] = {
{ .compatible = "qcom,ipq807x-pcie", .data = PCIE_V2 },
{ .compatible = "qcom,ipq6018-pcie", .data = PCIE_V2 },
{ .compatible = "qcom,ipq5018-pcie", .data = PCIE_V2 },
{ .compatible = "qcom,ipq9574-pcie", .data = PCIE_V2 },
{ },
};
@ -626,6 +985,7 @@ struct ipq_pcie {
int linkup;
int version;
int skip_phy_init;
int lane;
};
static void ipq_pcie_write_mask(uint32_t addr,
@ -1053,6 +1413,11 @@ void pcie_v0_linkup(struct ipq_pcie *pcie, int id)
}
__weak int ipq_sku_pci_validation(int id)
{
return 0;
}
static int ipq_pcie_parse_dt(const void *fdt, int id,
struct ipq_pcie *pcie)
{
@ -1066,6 +1431,11 @@ static int ipq_pcie_parse_dt(const void *fdt, int id,
return node;
}
if (ipq_sku_pci_validation(id)){
printf("PCI%d is disabled\n", id);
return 1;
}
err = fdt_get_named_resource(fdt, node, "reg", "reg-names", "pci_dbi",
&pcie->pci_dbi);
if (err < 0) {
@ -1138,6 +1508,8 @@ static int ipq_pcie_parse_dt(const void *fdt, int id,
}
pcie->skip_phy_init =
fdtdec_get_int(fdt, node, "skip_phy_int", 0);
pcie->lane = fdtdec_get_int(fdt, node, "lane", 1);
}
rst_gpio = fdtdec_get_int(fdt, node, "perst_gpio", 0);
if (rst_gpio <= 0) {
@ -1337,8 +1709,12 @@ static inline void qca_pcie_write_reg(u32 base, u32 offset, u32 value)
void pcie_phy_v2_init(struct ipq_pcie *pcie)
{
if (!pcie->skip_phy_init) {
const struct phy_regs *regs = pcie_phy_v2_init_seq_ipq;
int i, size = ARRAY_SIZE(pcie_phy_v2_init_seq_ipq);
const struct phy_regs *regs = (pcie->lane == 2)?
pcie_phy_v2_x2_init_seq_ipq :
pcie_phy_v2_init_seq_ipq;
int i, size = (pcie->lane == 2)?
ARRAY_SIZE(pcie_phy_v2_x2_init_seq_ipq) :
ARRAY_SIZE(pcie_phy_v2_init_seq_ipq);
for (i = 0; i < size; i++) {
if (regs[i].reg_offset == PCIE_PHY_DELAY_MS)

View file

@ -13,6 +13,7 @@ obj-$(CONFIG_ARCH_IPQ806x) += qca_uart.o
obj-$(CONFIG_ARCH_IPQ40xx) += qca_uart.o
obj-$(CONFIG_ARCH_IPQ5018) += qca_uart.o
obj-$(CONFIG_ARCH_IPQ6018) += qca_uart.o
obj-$(CONFIG_ARCH_IPQ9574) += qca_uart.o
ifdef CONFIG_DM_SERIAL
obj-y += serial-uclass.o
obj-$(CONFIG_PL01X_SERIAL) += serial_pl01x.o

View file

@ -37,6 +37,7 @@ obj-$(CONFIG_ARCH_IPQ40xx) += qca_qup_spi_bam.o
obj-$(CONFIG_ARCH_IPQ807x) += qca_qup_spi_bam.o
obj-$(CONFIG_ARCH_IPQ6018) += qca_qup_spi_bam.o
obj-$(CONFIG_ARCH_IPQ5018) += qca_qup_spi_bam.o
obj-$(CONFIG_ARCH_IPQ9574) += qca_qup_spi_bam.o
obj-$(CONFIG_ARCH_IPQ806x) += ipq_spi.o
endif

View file

@ -41,6 +41,9 @@ typedef volatile unsigned char vu_char;
#elif defined(CONFIG_IPQ6018)
#include <../board/qca/arm/ipq6018/ipq6018.h>
#elif defined(CONFIG_IPQ9574)
#include <../board/qca/arm/ipq9574/ipq9574.h>
#elif defined(CONFIG_IPQ_RUMI)
#include <../board/qca/arm/ipq807x/ipq807x.h>
#endif
@ -413,7 +416,7 @@ ulong getenv_hex(const char *varname, ulong default_val);
* Return -1 if variable does not exist (default to true)
*/
int getenv_yesno(const char *var);
#if defined(CONFIG_IPQ40XX_ENV) || defined(CONFIG_IPQ807X_ENV) || defined(CONFIG_IPQ806X_ENV) || defined(CONFIG_IPQ5018_ENV) || defined(CONFIG_IPQ6018_ENV)
#if defined(CONFIG_IPQ40XX_ENV) || defined(CONFIG_IPQ807X_ENV) || defined(CONFIG_IPQ806X_ENV) || defined(CONFIG_IPQ5018_ENV) || defined(CONFIG_IPQ6018_ENV) || defined(CONFIG_IPQ9574_ENV)
extern int (*saveenv)(void);
#else
int saveenv (void);

377
include/configs/ipq9574.h Normal file
View file

@ -0,0 +1,377 @@
/*
* Copyright (c) 2016-2018,2020-2021 The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef _IPQ9574_H
#define _IPQ9574_H
#ifndef DO_DEPS_ONLY
#include <generated/asm-offsets.h>
#endif
#define CONFIG_IPQ9574
#define CONFIG_BOARD_EARLY_INIT_F
#define CONFIG_BOARD_LATE_INIT
#define CONFIG_SYS_NO_FLASH
#define CONFIG_SYS_VSNPRINTF
#define CONFIG_IPQ_NO_RELOC
#define CONFIG_SYS_NONCACHED_MEMORY (1 << 20)
#define CONFIG_IPQ9574_UART
#define CONFIG_NR_DRAM_BANKS 1
#define CONFIG_SKIP_LOWLEVEL_INIT
#define CONFIG_SYS_BOOTM_LEN 0x4000000
/* Enable DTB compress */
#define CONFIG_COMPRESSED_DTB_MAX_SIZE 0x40000
#define CONFIG_COMPRESSED_DTB_BASE CONFIG_SYS_TEXT_BASE -\
CONFIG_COMPRESSED_DTB_MAX_SIZE
/*
* Size of malloc() pool
*/
/*
* select serial console configuration
*/
#define CONFIG_CONS_INDEX 1
#define CONFIG_SYS_DEVICE_NULLDEV
/* allow to overwrite serial and ethaddr */
#define CONFIG_BAUDRATE 115200
#define CONFIG_SYS_BAUDRATE_TABLE {4800, 9600, 19200, 38400, 57600,\
115200}
#define CONFIG_SYS_CBSIZE (512 * 2) /* Console I/O Buffer Size */
/*
svc_sp --> --------------
irq_sp --> | |
fiq_sp --> | |
bd --> | |
gd --> | |
pgt --> | |
malloc --> | |
text_base --> |------------|
*/
#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_TEXT_BASE -\
CONFIG_SYS_MALLOC_LEN - CONFIG_ENV_SIZE -\
GENERATED_BD_INFO_SIZE)
#define CONFIG_SYS_MAXARGS 16
#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + \
sizeof(CONFIG_SYS_PROMPT) + 16)
#define TLMM_BASE 0x01000000
#define GPIO_CONFIG_ADDR(x) (TLMM_BASE + (x)*0x1000)
#define GPIO_IN_OUT_ADDR(x) (TLMM_BASE + 0x4 + (x)*0x1000)
#define CONFIG_SYS_SDRAM_BASE 0x40000000
#define CONFIG_SYS_TEXT_BASE 0x4A400000
#define CONFIG_SYS_SDRAM_SIZE 0x10000000
#define CONFIG_MAX_RAM_BANK_SIZE CONFIG_SYS_SDRAM_SIZE
#define CONFIG_SYS_LOAD_ADDR (CONFIG_SYS_SDRAM_BASE + (64 << 20))
#define CONFIG_ROOTFS_LOAD_ADDR (CONFIG_SYS_SDRAM_BASE + (32 << 20))
#define QCA_KERNEL_START_ADDR CONFIG_SYS_SDRAM_BASE
#define QCA_DRAM_KERNEL_SIZE CONFIG_SYS_SDRAM_SIZE
#define QCA_BOOT_PARAMS_ADDR (QCA_KERNEL_START_ADDR + 0x100)
#define CONFIG_OF_COMBINE 1
#define CONFIG_SMEM_VERSION_C
#define CONFIG_QCA_SMEM_BASE 0x4AA00000
#define CONFIG_QCA_SMEM_SIZE 0x100000
#define CONFIG_IPQ_FDT_HIGH 0x48500000
#define CONFIG_IPQ_NO_MACS 6
#define CONFIG_ENV_IS_IN_SPI_FLASH 1
#define CONFIG_ENV_SECT_SIZE (64 * 1024)
#define CONFIG_SMP_CMD_SUPPORT
#ifdef CONFIG_SMP_CMD_SUPPORT
#define NR_CPUS 4
#endif
/*
* IPQ_TFTP_MIN_ADDR: Starting address of Linux HLOS region.
* CONFIG_TZ_END_ADDR: Ending address of Trust Zone and starting
* address of WLAN Area.
* TFTP file can only be written in Linux HLOS region and WLAN AREA.
*/
#define IPQ_TFTP_MIN_ADDR (CONFIG_SYS_SDRAM_BASE + (16 << 20))
#define CONFIG_TZ_END_ADDR 0x4AA00000
#define CONFIG_SYS_SDRAM_END ((long long)CONFIG_SYS_SDRAM_BASE + gd->ram_size)
#define CONFIG_QCA_UBOOT_OFFSET 0xA100000
#define CONFIG_UBOOT_END_ADDR 0x4A500000
#ifndef __ASSEMBLY__
#include <compiler.h>
extern loff_t board_env_offset;
extern loff_t board_env_range;
extern loff_t board_env_size;
#endif
#define CONFIG_IPQ9574_ENV 1
#define CONFIG_ENV_OFFSET board_env_offset
#define CONFIG_ENV_SIZE CONFIG_ENV_SIZE_MAX
#define CONFIG_ENV_RANGE board_env_range
#define CONFIG_ENV_SIZE_MAX (256 << 10) /* 256 KB */
#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE_MAX + (1024 << 10))
#define CONFIG_ENV_IS_IN_NAND 1
/* Allow to overwrite serial and ethaddr */
#define CONFIG_ENV_OVERWRITE
/*
* Block Device & Disk Partition Config
*/
#define HAVE_BLOCK_DEVICE
#define CONFIG_DOS_PARTITION
#define CONFIG_IPQ9574_I2C 1
#ifdef CONFIG_IPQ9574_I2C
#define CONFIG_SYS_I2C_QUP
#define CONFIG_CMD_I2C
#define CONFIG_DM_I2C
#endif
/*
* USB crashdump collection
*/
#define CONFIG_FS_FAT
#define CONFIG_FAT_WRITE
#define CONFIG_CMD_FAT
/*
* USB Support
*/
#define CONFIG_USB_XHCI_IPQ
#ifdef CONFIG_USB_XHCI_IPQ
#define CONFIG_USB_XHCI
#define CONFIG_USB_XHCI_DWC3
#define CONFIG_CMD_USB
#define CONFIG_USB_STORAGE
#define CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS 2
#define CONFIG_USB_MAX_CONTROLLER_COUNT 1
#endif
/*
* PCIE Enable
*/
#define PCI_MAX_DEVICES 4
#if defined(CONFIG_PCI_IPQ)
#define CONFIG_PCI
#define CONFIG_CMD_PCI
#define CONFIG_PCI_SCAN_SHOW
#endif
/*
* NAND Flash Configs
*/
/* CONFIG_QPIC_NAND: QPIC NAND in BAM mode
* CONFIG_IPQ_NAND: QPIC NAND in FIFO/block mode.
* BAM is enabled by default.
*/
#define CONFIG_QPIC_NAND
#define CONFIG_CMD_NAND
#define CONFIG_CMD_NAND_YAFFS
#define CONFIG_SYS_NAND_SELF_INIT
#define CONFIG_SYS_NAND_ONFI_DETECTION
#define CONFIG_QPIC_SERIAL
#ifdef CONFIG_QPIC_SERIAL
#ifdef QSPI_SERIAL_DEBUG /* QSPI DEBUG */
#define qspi_debug(fmt,args...) printf (fmt ,##args)
#else
#define qspi_debug(fmt,args...)
#endif /* QSPI DEBUG */
#define CONFIG_PAGE_SCOPE_MULTI_PAGE_READ
#define CONFIG_QSPI_SERIAL_TRAINING
#endif
/*
* Expose SPI driver as a pseudo NAND driver to make use
* of U-Boot's MTD framework.
*/
#define CONFIG_SYS_MAX_NAND_DEVICE CONFIG_IPQ_MAX_NAND_DEVICE + \
CONFIG_IPQ_MAX_SPI_DEVICE
#define CONFIG_IPQ_MAX_NAND_DEVICE 1
#define CONFIG_IPQ_MAX_SPI_DEVICE 1
#define CONFIG_QPIC_NAND_NAND_INFO_IDX 0
#define CONFIG_IPQ_SPI_NOR_INFO_IDX 1
#define CONFIG_NAND_FLASH_INFO_IDX CONFIG_QPIC_NAND_NAND_INFO_IDX
#define CONFIG_SPI_FLASH_INFO_IDX CONFIG_IPQ_SPI_NOR_INFO_IDX
#define QCA_SPI_NOR_DEVICE "spi0.0"
#define CONFIG_QCA_BAM 1
/*
* SPI Flash Configs
*/
#define CONFIG_QCA_SPI
#define CONFIG_SPI_FLASH
#define CONFIG_CMD_SF
#define CONFIG_SPI_FLASH_STMICRO
#define CONFIG_SPI_FLASH_WINBOND
#define CONFIG_SPI_FLASH_MACRONIX
#define CONFIG_SPI_FLASH_GIGADEVICE
#define CONFIG_SPI_FLASH_SPANSION
#define CONFIG_SF_DEFAULT_BUS 0
#define CONFIG_SF_DEFAULT_CS 0
#define CONFIG_SF_DEFAULT_MODE SPI_MODE_0
#define CONFIG_SF_DEFAULT_SPEED (48 * 1000 * 1000)
#define CONFIG_SPI_FLASH_BAR 1
#define CONFIG_SPI_FLASH_USE_4K_SECTORS
#define CONFIG_IPQ_4B_ADDR_SWITCH_REQD
#define CONFIG_EFI_PARTITION
#define CONFIG_QUP_SPI_USE_DMA 1
/*
* U-Boot Env Configs
*/
#define CONFIG_OF_LIBFDT 1
#define CONFIG_SYS_HUSH_PARSER
#define CONFIG_CMD_XIMG
/* MTEST */
#define CONFIG_CMD_MEMTEST
#define CONFIG_SYS_MEMTEST_START CONFIG_SYS_SDRAM_BASE + 0x1300000
#define CONFIG_SYS_MEMTEST_END CONFIG_SYS_MEMTEST_START + 0x100
/* NSS firmware loaded using bootm */
#define CONFIG_BOOTCOMMAND "bootipq"
#define CONFIG_BOOTARGS "console=ttyMSM0,115200n8"
#define QCA_ROOT_FS_PART_NAME "rootfs"
#define CONFIG_BOOTDELAY 2
#define CONFIG_MTD_DEVICE
#define CONFIG_CMD_MTDPARTS
#define CONFIG_MTD_PARTITIONS
#define NUM_ALT_PARTITION 16
#define CONFIG_CMD_UBI
#define CONFIG_RBTREE
#define CONFIG_CMD_BOOTZ
#define CONFIG_FDT_FIXUP_PARTITIONS
#define CONFIG_OF_BOARD_SETUP
#ifdef CONFIG_OF_BOARD_SETUP
#define DLOAD_DISABLE 0x1
/*
* Below Configs need to be updated after enabling reset_crashdump
* Included now to avoid build failure
*/
#define SET_MAGIC 0x1
#define CLEAR_MAGIC 0x0
#define SCM_CMD_TZ_CONFIG_HW_FOR_RAM_DUMP_ID 0x9
#define SCM_CMD_TZ_FORCE_DLOAD_ID 0x10
#define SCM_CMD_TZ_PSHOLD 0x15
#define BOOT_VERSION 0
#define TZ_VERSION 1
#define RPM_VERSION 3
#endif
#define CONFIG_IPQ9574_EDMA 1
#ifdef CONFIG_IPQ9574_EDMA
#define CONFIG_IPQ9574_BRIDGED_MODE 1
#define CONFIG_NET_RETRY_COUNT 5
#define CONFIG_SYS_RX_ETH_BUFFER 128
#define CONFIG_TFTP_BLOCKSIZE 1280
#define CONFIG_CMD_PING
#define CONFIG_CMD_DHCP
#define CONFIG_MII
#define CONFIG_CMD_MII
#define CONFIG_IPADDR 192.168.10.10
#define CONFIG_NETMASK 255.255.255.0
#define CONFIG_SERVERIP 192.168.10.1
#define CONFIG_CMD_TFTPPUT
#define CONFIG_IPQ_MDIO 1
#define CONFIG_IPQ_ETH_INIT_DEFER
#endif
/*
* CRASH DUMP ENABLE
*/
#define CONFIG_QCA_APPSBL_DLOAD
#define CONFIG_IPQ9574_DMAGIC_ADDR 0x193D100
#ifdef CONFIG_QCA_APPSBL_DLOAD
#define CONFIG_CMD_TFTPPUT
/* We will be uploading very big files */
#undef CONFIG_NET_RETRY_COUNT
#define CONFIG_NET_RETRY_COUNT 500
#define IPQ_TEMP_DUMP_ADDR 0x44000000
#endif
#define CONFIG_QCA_KERNEL_CRASHDUMP_ADDRESS *((unsigned int *)0x08600658)
#define CONFIG_CPU_CONTEXT_DUMP_SIZE 4096
#define TLV_BUF_OFFSET 500 * 1024
#define CONFIG_TLV_DUMP_SIZE 12 * 1024
/* L1 cache line size is 64 bytes, L2 cache line size is 128 bytes
* Cache flush and invalidation based on L1 cache, so the cache line
* size is configured to 64 */
#define CONFIG_SYS_CACHELINE_SIZE 64
#define CONFIG_CMD_CACHE
/*#define CONFIG_SYS_DCACHE_OFF*/
/* Enabling this flag will report any L2 errors.
* By default we are disabling it */
/*#define CONFIG_IPQ_REPORT_L2ERR*/
/*
* MMC configs
*/
#define CONFIG_QCA_MMC
#ifdef CONFIG_QCA_MMC
#define CONFIG_MMC
#define CONFIG_CMD_MMC
#define CONFIG_GENERIC_MMC
#define CONFIG_SDHCI
#define CONFIG_SDHCI_QCA
#define CONFIG_ENV_IS_IN_MMC
#define CONFIG_SYS_MMC_ENV_DEV 0
#define CONFIG_SDHCI_SUPPORT
#define CONFIG_MMC_ADMA
#endif
/*
* Other commands
*/
#define CONFIG_CMD_FLASHWRITE
#define CONFIG_CMD_RUN
#define CONFIG_IPQ_ELF_AUTH
#define IPQ_UBI_VOL_WRITE_SUPPORT
#define CONFIG_IPQ_TZT
#define CONFIG_IPQ_FDT_FIXUP
#define CONFIG_ARMV7_PSCI
#define CONFIG_VERSION_ROLLBACK_PARTITION_INFO
#endif /* _IPQ9574_H */

View file

@ -0,0 +1,47 @@
/*
* Copyright (c) 2019, 2021, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef __DT_BINDINGS_IPQ9574_ETH_H__
#define __DT_BINDINGS_IPQ9574_ETH_H__
/* ESS Switch Mac Modes */
#define PORT_WRAPPER_PSGMII 0
#define PORT_WRAPPER_PSGMII_RGMII5 1
#define PORT_WRAPPER_SGMII0_RGMII5 2
#define PORT_WRAPPER_SGMII1_RGMII5 3
#define PORT_WRAPPER_PSGMII_RMII0 4
#define PORT_WRAPPER_PSGMII_RMII1 5
#define PORT_WRAPPER_PSGMII_RMII0_RMII1 6
#define PORT_WRAPPER_PSGMII_RGMII4 7
#define PORT_WRAPPER_SGMII0_RGMII4 8
#define PORT_WRAPPER_SGMII1_RGMII4 9
#define PORT_WRAPPER_SGMII4_RGMII4 10
#define PORT_WRAPPER_QSGMII 11
#define PORT_WRAPPER_SGMII_PLUS 12
#define PORT_WRAPPER_USXGMII 13
#define PORT_WRAPPER_10GBASE_R 14
#define PORT_WRAPPER_SGMII_CHANNEL0 15
#define PORT_WRAPPER_SGMII_CHANNEL1 16
#define PORT_WRAPPER_SGMII_CHANNEL4 17
#define PORT_WRAPPER_RGMII 18
#define PORT_WRAPPER_PSGMII_FIBER 19
#define PORT_WRAPPER_SGMII_FIBER 20
#define PORT_WRAPPER_MAX 0xFF
/* ETH PHY Types */
#define QCA807x_PHY_TYPE 0x1
#define QCA808x_PHY_TYPE 0x2
#define AQ_PHY_TYPE 0x3
#define QCA8033_PHY_TYPE 0x4
#define SFP_PHY_TYPE 0x5
#endif

View file

@ -0,0 +1,59 @@
/*
* Copyright (c) 2016-2018,2020 The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef __DT_BINDINGS_IPQ9574_GPIO_H__
#define __DT_BINDINGS_IPQ9574_GPIO_H__
/* GPIO TLMM: Direction */
#define GPIO_INPUT 0
#define GPIO_OUTPUT 1
/* GPIO TLMM: Output value */
#define GPIO_OUT_LOW 0
#define GPIO_OUT_HIGH 1
/* GPIO TLMM: Pullup/Pulldown */
#define GPIO_NO_PULL 0
#define GPIO_PULL_DOWN 1
#define GPIO_KEEPER 2
#define GPIO_PULL_UP 3
/* GPIO TLMM: Drive Strength */
#define GPIO_2MA 0
#define GPIO_4MA 1
#define GPIO_6MA 2
#define GPIO_8MA 3
#define GPIO_10MA 4
#define GPIO_12MA 5
#define GPIO_14MA 6
#define GPIO_16MA 7
/* GPIO TLMM: Status */
#define GPIO_OE_DISABLE 0
#define GPIO_OE_ENABLE 1
/* GPIO VM */
#define GPIO_VM_ENABLE 1
#define GPIO_VM_DISABLE 0
/* GPIO OD */
#define GPIO_OD_ENABLE 1
#define GPIO_OD_DISABLE 0
/* GPIO PULLUP RES */
#define GPIO_PULL_RES0 0
#define GPIO_PULL_RES1 1
#define GPIO_PULL_RES2 2
#define GPIO_PULL_RES3 3
#endif

View file

@ -97,6 +97,7 @@ soc_hw_version_ipq40xx = { 0x20050100 };
soc_hw_version_ipq807x = { 0x200D0100, 0x200D0101, 0x200D0102, 0x200D0200 };
soc_hw_version_ipq6018 = { 0x20170100 };
soc_hw_version_ipq5018 = { 0x20180100, 0x20180101 };
soc_hw_version_ipq9574 = { 0x20190100 };
#
# Python 2.6 and earlier did not have OrderedDict use the backport
@ -1162,6 +1163,8 @@ class Pack(object):
soc_hw_versions = soc_hw_version_ipq6018
if ARCH_NAME == "ipq5018" or ARCH_NAME == "ipq5018_64":
soc_hw_versions = soc_hw_version_ipq5018
if ARCH_NAME == "ipq9574" or ARCH_NAME == "ipq9574_64":
soc_hw_versions = soc_hw_version_ipq9574
chip_count = 0
for soc_hw_version in soc_hw_versions:
@ -2085,7 +2088,7 @@ class Pack(object):
else:
part_info = root.find(".//data[@type='" + ftype.upper() + "_PARAMETER']")
if ARCH_NAME in ["ipq6018", "ipq5018", "ipq807x"]:
if ARCH_NAME in ["ipq6018", "ipq5018", "ipq807x", "ipq9574"]:
MODE_APPEND = "_64" if MODE == "64" else ""
if ftype in ["nand-audio", "nand-audio-4k"]:
@ -2131,7 +2134,7 @@ class Pack(object):
part_file = SRC_DIR + "/" + ARCH_NAME + "/flash_partition/" + ftype + "-partition.xml"
part_xml = ET.parse(part_file)
partition = part_xml.find(".//partitions/partition[2]")
partition = part_xml.find(".//partitions/partition[name='0:MIBIB']")
part_fname = partition[8].text
part_fname = os.path.join(self.images_dname, part_fname)
pagesize = int(part_info.find(".//page_size").text)
@ -2277,12 +2280,12 @@ class ArgParser(object):
#Verify Arguments passed by user
# Verify arch type
if ARCH_NAME not in ["ipq40xx", "ipq806x", "ipq807x", "ipq807x_64", "ipq6018", "ipq6018_64", "ipq5018", "ipq5018_64"]:
if ARCH_NAME not in ["ipq40xx", "ipq806x", "ipq807x", "ipq807x_64", "ipq6018", "ipq6018_64", "ipq5018", "ipq5018_64", "ipq9574", "ipq9574_64"]:
raise UsageError("Invalid arch type '%s'" % arch)
if ARCH_NAME == "ipq807x" or ARCH_NAME == "ipq5018":
if ARCH_NAME == "ipq807x" or ARCH_NAME == "ipq5018" or ARCH_NAME == "ipq9574":
MODE = "32"
elif ARCH_NAME == "ipq807x_64" or ARCH_NAME == "ipq5018_64":
elif ARCH_NAME == "ipq807x_64" or ARCH_NAME == "ipq5018_64" or ARCH_NAME == "ipq9574_64":
MODE = "64"
ARCH_NAME = ARCH_NAME[:-3]
@ -2322,7 +2325,7 @@ class ArgParser(object):
print "python pack_hk.py [options] [Value] ..."
print
print "options:"
print " --arch \tARCH_TYPE [ipq40xx/ipq806x/ipq807x/ipq807x_64/ipq6018/ipq6018_64/ipq5018/ipq5018_64]"
print " --arch \tARCH_TYPE [ipq40xx/ipq806x/ipq807x/ipq807x_64/ipq6018/ipq6018_64/ipq5018/ipq5018_64/ipq9574/ipq9574_64]"
print
print " --fltype \tFlash Type [nor/tiny-nor/nand/emmc/norplusnand/norplusemmc/tiny-nor-debug]"
print " \t\tMultiple flashtypes can be passed by a comma separated string"