lzma-loaderでPCIeコントローラ部最低限の初期化をしてVIDとDEVID出すやつ
diff --git a/target/linux/ath79/image/lzma-loader/src/ar71xx_regs.h b/target/linux/ath79/image/lzma-loader/src/ar71xx_regs.h index e7d7683973..e1737f4fb7 100644 --- a/target/linux/ath79/image/lzma-loader/src/ar71xx_regs.h +++ b/target/linux/ath79/image/lzma-loader/src/ar71xx_regs.h @@ -197,7 +197,7 @@ #define AR71XX_ETH1_PLL_SHIFT 19 #define AR724X_PLL_REG_CPU_CONFIG 0x00 -#define AR724X_PLL_REG_PCIE_CONFIG 0x18 +#define AR724X_PLL_REG_PCIE_CONFIG 0x10 #define AR724X_PLL_DIV_SHIFT 0 #define AR724X_PLL_DIV_MASK 0x3ff diff --git a/target/linux/ath79/image/lzma-loader/src/board.c b/target/linux/ath79/image/lzma-loader/src/board.c index afa2d9e4e9..90e91eb1ca 100644 --- a/target/linux/ath79/image/lzma-loader/src/board.c +++ b/target/linux/ath79/image/lzma-loader/src/board.c @@ -211,6 +211,143 @@ static inline void ap5030dn_init(void) { } defined(CONFIG_BOARD_NEC_WR8750N) || \ defined(CONFIG_BOARD_NEC_WR9500N) +#include <stdbool.h> +#include <unistd.h> +#include <linux/pci_regs.h> + +#define PCIBIOS_SUCCESSFUL 0x0 +#define PCIBIOS_BAD_REGISTER_NUMBER 0x87 + +static int ar724x_pci_write(int where, int size, unsigned int val, bool devcfg) +{ + unsigned int reg, _val; + int shift; + + reg = KSEG1ADDR(devcfg ? AR724X_PCI_CFG_BASE : AR724X_PCI_CRP_BASE); + _val = READREG(reg + (where & ~3)); + + switch (size) { + case 1: + shift = ((where & 3) * 8); + _val &= ~(0xff << shift); + _val |= ((val & 0xff) << shift); + break; + case 2: + shift = ((where & 2) * 8); + _val &= ~(0xffff << shift); + _val |= ((val & 0xffff) << shift); + break; + case 4: + _val = val; + break; + default: + return PCIBIOS_BAD_REGISTER_NUMBER; + } + + WRITEREG(reg + (where & ~3), _val); + /* flush write */ + READREG(reg + (where & ~3)); + + return PCIBIOS_SUCCESSFUL; +} + +#define ar724x_pci_crp_write(w, s, v) \ + ar724x_pci_write(w, s, v, false) +#define ar724x_pci_cfg_write(w, s, v) \ + ar724x_pci_write(w, s, v, true) + +static int ar724x_pci_read(int where, int size, unsigned int *val) +{ + unsigned int reg, _val; + + reg = KSEG1ADDR(AR724X_PCI_CFG_BASE); + _val = READREG(reg + (where & ~3)); + + switch (size) { + case 1: + if (where & 1) + _val >>= 8; + if (where & 2) + _val >>= 16; + _val &= 0xff; + break; + case 2: + if (where & 2) + _val >>= 16; + _val &= 0xffff; + break; + case 4: + break; + default: + return PCIBIOS_BAD_REGISTER_NUMBER; + } + + *val = _val; + + return PCIBIOS_SUCCESSFUL; +} + +#define AR724X_PCI_REG_APP 0x0 +#define AR724X_PCI_REG_RESET 0x18 + +#define AR934X_PLL_PCIE_CONFIG_PLL_PWD BIT(30) +#define AR934X_PLL_PCIE_CONFIG_PLL_BYPASS BIT(16) +#define AR724X_PCI_APP_LTSSM_ENABLE BIT(0) +#define AR724X_PCI_RESET_EP_RESET_L BIT(2) +#define AR724X_PCI_RESET_LINK_UP BIT(0) + +#define AR724X_PCI_CMD_INIT (PCI_COMMAND_MEMORY | \ + PCI_COMMAND_MASTER | \ + PCI_COMMAND_INVALIDATE | \ + PCI_COMMAND_PARITY | \ + PCI_COMMAND_SERR | \ + PCI_COMMAND_FAST_BACK) + +static void nec_aterm_pcie_init(void) +{ + unsigned int reg, val; + int i = 0, ret; + + reg = KSEG1ADDR(AR71XX_RESET_BASE); + val = READREG(reg + AR934X_RESET_REG_RESET_MODULE); + val &= ~(AR934X_RESET_PCIE | AR934X_RESET_PCIE_PHY); + WRITEREG(reg + AR934X_RESET_REG_RESET_MODULE, val); + + reg = KSEG1ADDR(AR71XX_PLL_BASE); + val = READREG(reg + AR724X_PLL_REG_PCIE_CONFIG); + val &= ~(AR934X_PLL_PCIE_CONFIG_PLL_PWD | + AR934X_PLL_PCIE_CONFIG_PLL_BYPASS); + WRITEREG(reg + AR724X_PLL_REG_PCIE_CONFIG, val); + + reg = KSEG1ADDR(AR724X_PCI_CTRL_BASE); + val = READREG(reg + AR724X_PCI_REG_RESET); + val |= AR724X_PCI_RESET_EP_RESET_L; + WRITEREG(reg + AR724X_PCI_REG_RESET, val); + + val = READREG(reg + AR724X_PCI_REG_APP); + val |= AR724X_PCI_APP_LTSSM_ENABLE; + WRITEREG(reg + AR724X_PCI_REG_APP, val); + + while (i < 0xffffffff && + !(READREG(reg + AR724X_PCI_REG_RESET) + & AR724X_PCI_RESET_LINK_UP)) + i++; + if (i >= 0xffffffff) { + printf("failed to initialize PCIe\n"); + return; + } + + ar724x_pci_crp_write(PCI_COMMAND, 4, AR724X_PCI_CMD_INIT); + + ret = ar724x_pci_read(PCI_VENDOR_ID, 4, &val); + if (ret) { + printf("failed to read PCIe IDs\n"); + return; + } + printf("PCIe: vendor->%04x, device->%04x\n", + val & 0xffff, val >> 16); +} + #define AR934X_PLL_SWITCH_CLOCK_CONTROL 0x24 static inline void nec_aterm_init(void) @@ -239,6 +376,13 @@ static inline void nec_aterm_init(void) val = READREG(reg + AR934X_RESET_REG_RESET_MODULE); val &= ~(AR934X_RESET_ETH_SWITCH | AR934X_RESET_ETH_SWITCH_ANALOG); WRITEREG(reg + AR934X_RESET_REG_RESET_MODULE, val); + + /* + * initialize PCIe for activation of ath9k chip to + * set default state of the LEDs that connected to + * the GPIO controller on the ath9k (AR938x) chip + */ + nec_aterm_pcie_init(); } #else static inline void nec_aterm_init(void) {}