Merge "ipq806x: Add PCIE entries for AP148 board"

This commit is contained in:
Linux Build Service Account 2017-12-07 00:15:32 -08:00 committed by Gerrit - the friendly Code Review server
commit 3db4cdde4d
9 changed files with 300 additions and 15 deletions

View file

@ -25,6 +25,8 @@
nand = "/nand@1A600000";
gmac_gpio = "/gmac1_gpio";
i2c0 = "/i2c@16380000";
pci0 = "/pci@1b500000";
pci1 = "/pci@1b700000";
};
serial@16340000 {
@ -65,4 +67,29 @@
phy_name = "IPQ MDIO2";
};
};
pci@1b500000 {
pci_gpio {
gpio3 {
gpio = <3>;
func = <1>;
pull = <GPIO_PULL_UP>;
drvstr = <GPIO_12MA>;
oe = <GPIO_OE_ENABLE>;
};
};
};
pci@1b700000 {
pci_gpio {
gpio48 {
gpio = <48>;
func = <1>;
pull = <GPIO_PULL_UP>;
drvstr = <GPIO_12MA>;
oe = <GPIO_OE_ENABLE>;
};
};
};
};

View file

@ -408,6 +408,36 @@
clock-frequency = <24000>;
};
pci@1b500000 {
compatible = "qcom,ipq806x-pcie";
#address-cells = <1>;
#size-cells = <1>;
reg = <0x1b500000 0xf1d
0x1b600000 0x2000
0x1b502000 0xa8
0x08000000 0x08000000
0x0ff00000 0x100000
0x009022DC 0x40>;
reg-names = "pci_dbi", "parf", "elbi", "axi_bars",
"axi_conf", "pci_rst";
perst_gpio = <3>;
};
pci@1b700000 {
compatible = "qcom,ipq806x-pcie";
#address-cells = <1>;
#size-cells = <1>;
reg = <0x1b700000 0xf1d
0x1b800000 0x2000
0x1b702000 0xa8
0x2E000000 0x04000000
0x31f00000 0x100000
0x00903A9C 0x40>;
reg-names = "pci_dbi", "parf", "elbi", "axi_bars",
"axi_conf", "pci_rst";
perst_gpio = <48>;
};
spi {
spi0 {
mosi_miso_clk {

View file

@ -73,11 +73,49 @@
#define emmc_clk_ns_mask (BM(BIT_POS_23, BIT_POS_16) | BM(BIT_POS_6, BIT_POS_0))
#define emmc_en_mask BIT(11)
#define PCIE_0_ACLK_CTL 0x9022C0
#define PCIE_1_ACLK_CTL 0x903a80
#define PCIE_2_ACLK_CTL 0x903ac0
#define PCIE_0_PCLK_CTL 0x9022D0
#define PCIE_1_PCLK_CTL 0x903A90
#define PCIE_2_PCLK_CTL 0x903AD0
#define PCIE_0_HCLK_CTL 0x9022CC
#define PCIE_1_HCLK_CTL 0x903A8C
#define PCIE_2_HCLK_CTL 0x903ACC
#define PCIE_0_AUX_CLK_CTL 0x9022C8
#define PCIE_1_AUX_CLK_CTL 0x903A88
#define PCIE_2_AUX_CLK_CTL 0x903AC8
#define PCIE_0_ALT_REF_CLK_NS 0x903860
#define PCIE_1_ALT_REF_CLK_NS 0x903AA0
#define PCIE_2_ALT_REF_CLK_NS 0x903AE0
#define PCIE_0_ALT_REF_CLK_ACR 0x901344
#define PCIE_1_ALT_REF_CLK_ACR 0x901354
#define PCIE_2_ALT_REF_CLK_ACR 0x90135C
#define PCIE_0_ACLK_FS 0x9022C4
#define PCIE_0_PCLK_FS 0x9022D4
#define PCIE_1_ACLK_FS 0x903A84
#define PCIE_1_PCLK_FS 0x903A94
#define PCIE_2_ACLK_FS 0x903AC4
#define PCIE_2_PCLK_FS 0x903AD4
#define PCIE20_0_PARF_PHY_REFCLK 0x1B60004C
#define PCIE20_1_PARF_PHY_REFCLK 0x1B80004C
#define PCIE20_2_PARF_PHY_REFCLK 0x1BA0004C
typedef struct {
unsigned int aclk_ctl;
unsigned int pclk_ctl;
unsigned int hclk_ctl;
unsigned int aux_clk_ctl;
unsigned int alt_ref_clk_ns;
unsigned int alt_ref_clk_acr;
unsigned int aclk_fs;
unsigned int pclk_fs;
unsigned int parf_phy_refclk;
} pci_clk_offset_t;
void i2c_clock_config(void);
/* Uart specific clock settings */
void uart_pll_vote_clk_enable(void);
void uart_clock_config(unsigned int gsbi_port, unsigned int m, unsigned int n,
unsigned int d);

View file

@ -73,6 +73,7 @@ typedef struct {
#endif
void board_pci_init(int id);
__weak void board_pcie_clock_init(int id) {}
__weak void aquantia_phy_reset(void) {}
/* Board specific parameters */

View file

@ -72,6 +72,48 @@ int dump_entries_s = dump_entries_n;
extern int ipq_spi_init(u16);
pci_clk_offset_t pcie_0_clk = {
.aclk_ctl = PCIE_0_ACLK_CTL,
.pclk_ctl = PCIE_0_PCLK_CTL,
.hclk_ctl = PCIE_0_HCLK_CTL,
.aux_clk_ctl = PCIE_0_AUX_CLK_CTL,
.alt_ref_clk_ns = PCIE_0_ALT_REF_CLK_NS,
.alt_ref_clk_acr = PCIE_0_ALT_REF_CLK_ACR,
.aclk_fs = PCIE_0_ACLK_FS,
.pclk_fs = PCIE_0_PCLK_FS,
.parf_phy_refclk = PCIE20_0_PARF_PHY_REFCLK
};
pci_clk_offset_t pcie_1_clk = {
.aclk_ctl = PCIE_1_ACLK_CTL,
.pclk_ctl = PCIE_1_PCLK_CTL,
.hclk_ctl = PCIE_1_HCLK_CTL,
.aux_clk_ctl = PCIE_1_AUX_CLK_CTL,
.alt_ref_clk_ns = PCIE_1_ALT_REF_CLK_NS,
.alt_ref_clk_acr = PCIE_1_ALT_REF_CLK_ACR,
.aclk_fs = PCIE_1_ACLK_FS,
.pclk_fs = PCIE_1_PCLK_FS,
.parf_phy_refclk = PCIE20_1_PARF_PHY_REFCLK
};
pci_clk_offset_t pcie_2_clk = {
.aclk_ctl = PCIE_2_ACLK_CTL,
.pclk_ctl = PCIE_2_PCLK_CTL,
.hclk_ctl = PCIE_2_HCLK_CTL,
.aux_clk_ctl = PCIE_2_AUX_CLK_CTL,
.alt_ref_clk_ns = PCIE_2_ALT_REF_CLK_NS,
.alt_ref_clk_acr = PCIE_2_ALT_REF_CLK_ACR,
.aclk_fs = PCIE_2_ACLK_FS,
.pclk_fs = PCIE_2_PCLK_FS,
.parf_phy_refclk = PCIE20_2_PARF_PHY_REFCLK
};
enum pcie_id {
PCIE_0,
PCIE_1,
PCIE_2,
};
unsigned long timer_read_counter(void)
{
return 0;
@ -315,6 +357,38 @@ void qca_serial_init(struct ipq_serial_platdata *plat)
GSBI_CTRL_REG(gsbi_base));
}
void board_pcie_clock_init(int id)
{
switch(id) {
case PCIE_0:
pcie_clock_config(&pcie_0_clk);
break;
case PCIE_1:
pcie_clock_config(&pcie_1_clk);
break;
case PCIE_2:
pcie_clock_config(&pcie_2_clk);
break;
}
}
void board_pci_init(int id)
{
int node, gpio_node;
char name[16];
sprintf(name, "pci%d", id);
node = fdt_path_offset(gd->fdt_blob, name);
if (node < 0) {
printf("Could not find PCI in device tree\n");
return;
}
gpio_node = fdt_subnode_offset(gd->fdt_blob, node, "pci_gpio");
if (gpio_node >= 0)
qca_gpio_init(gpio_node);
return;
}
void ipq_fdt_fixup_socinfo(void *blob)
{

View file

@ -117,4 +117,6 @@ extern const char *del_node[];
extern const add_node_t add_node[];
void reset_crashdump(void);
void ipq_fdt_fixup_socinfo(void *blob);
void board_pci_init(int id);
void board_pcie_clock_init(int id);
#endif /* _IPQ806X_H_ */

View file

@ -435,8 +435,7 @@ void nand_clock_config(void)
}
#endif
#ifdef CONFIG_IPQ806X_PCI
void pcie_clock_shutdown(clk_offset_t *pci_clk)
void pcie_clock_shutdown(pci_clk_offset_t *pci_clk)
{
/* PCIE_ALT_REF_CLK_NS */
writel(0x0, pci_clk->alt_ref_clk_ns);
@ -457,7 +456,7 @@ void pcie_clock_shutdown(clk_offset_t *pci_clk)
writel(0x0, pci_clk->aux_clk_ctl);
}
void pcie_clock_config(clk_offset_t *pci_clk)
void pcie_clock_config(pci_clk_offset_t *pci_clk)
{
/* PCIE_ALT_REF_CLK_NS */
writel(0x0A59, pci_clk->alt_ref_clk_ns);
@ -481,7 +480,6 @@ void pcie_clock_config(clk_offset_t *pci_clk)
/* PCIE_AUX_CLK_CTL */
writel(0x10, pci_clk->aux_clk_ctl);
}
#endif /* CONFIG_IPQ806X_PCI */
#ifdef CONFIG_QCA_MMC
void emmc_pll_vote_clk_enable(void)

View file

@ -159,6 +159,29 @@ DECLARE_GLOBAL_DATA_PTR;
#define PCIE_USB3_PCS_SW_RESET 0x800
#define PCIE_USB3_PCS_START_CONTROL 0x808
#define PCIE20_PARF_PHY_CTRL 0x40
#define PHY_CTRL_PHY_TX0_TERM_OFFSET_MASK (0x1f << 16)
#define PHY_CTRL_PHY_TX0_TERM_OFFSET(x) (x << 16)
#define PCIE20_PARF_PHY_REFCLK 0x4C
#define REF_SSP_EN BIT(16)
#define REF_USE_PAD BIT(12)
#define PCIE20_PARF_PCS_DEEMPH 0x34
#define PCIE20_PARF_PCS_DEEMPH_TX_DEEMPH_GEN1(x) (x << 16)
#define PCIE20_PARF_PCS_DEEMPH_TX_DEEMPH_GEN2_3_5DB(x) (x << 8)
#define PCIE20_PARF_PCS_DEEMPH_TX_DEEMPH_GEN2_6DB(x) (x << 0)
#define PCIE20_PARF_PCS_SWING 0x38
#define PCIE20_PARF_PCS_SWING_TX_SWING_FULL(x) (x << 8)
#define PCIE20_PARF_PCS_SWING_TX_SWING_LOW(x) (x << 0)
#define PCIE20_PARF_CONFIG_BITS 0x50
#define PCIE_SFAB_AXI_S5_FCLK_CTL 0x00902154
#define PCIE20_ELBI_SYS_CTRL 0x04
static unsigned int local_buses[] = { 0, 0 };
struct pci_controller pci_hose[PCI_MAX_DEVICES];
static int phy_initialised;
@ -196,6 +219,24 @@ struct ipq_pcie {
int version;
};
static void ipq_pcie_write_mask(uint32_t addr,
uint32_t clear_mask, uint32_t set_mask)
{
uint32_t val;
val = (readl(addr) & ~clear_mask) | set_mask;
writel(val, addr);
}
static void ipq_pcie_parf_reset(uint32_t addr, int domain, int assert)
{
if (assert)
ipq_pcie_write_mask(addr, 0, domain);
else
ipq_pcie_write_mask(addr, domain, 0);
}
void ipq_pcie_config_cfgtype(uint32_t phyaddr)
{
uint32_t bdf, cfgtype;
@ -455,18 +496,88 @@ void pcie_linkup(struct ipq_pcie *pcie)
}
ipq_pcie_config_controller(pcie);
}
void pcie_v0_linkup(struct ipq_pcie *pcie, int id)
{
int j;
uint32_t val;
/* assert PCIe PARF reset while powering the core */
ipq_pcie_parf_reset(pcie->pci_rst.start, BIT(6), 0);
ipq_pcie_parf_reset(pcie->pci_rst.start, BIT(2), 1);
board_pcie_clock_init(id);
/*
* de-assert PCIe PARF reset;
* wait 1us before accessing PARF registers
*/
ipq_pcie_parf_reset(pcie->pci_rst.start, BIT(2), 0);
udelay(1);
/* enable PCIe clocks and resets */
val = (readl(pcie->parf.start + PCIE20_PARF_PHY_CTRL) & ~BIT(0));
writel(val, pcie->parf.start + PCIE20_PARF_PHY_CTRL);
ipq_pcie_write_mask(pcie->parf.start + PCIE20_PARF_PHY_CTRL,
PHY_CTRL_PHY_TX0_TERM_OFFSET_MASK,
PHY_CTRL_PHY_TX0_TERM_OFFSET(0));
/* PARF programming */
writel(PCIE20_PARF_PCS_DEEMPH_TX_DEEMPH_GEN1(0x18) |
PCIE20_PARF_PCS_DEEMPH_TX_DEEMPH_GEN2_3_5DB(0x18) |
PCIE20_PARF_PCS_DEEMPH_TX_DEEMPH_GEN2_6DB(0x22),
pcie->parf.start + PCIE20_PARF_PCS_DEEMPH);
writel(PCIE20_PARF_PCS_SWING_TX_SWING_FULL(0x78) |
PCIE20_PARF_PCS_SWING_TX_SWING_LOW(0x78),
pcie->parf.start + PCIE20_PARF_PCS_SWING);
writel((4<<24), pcie->parf.start + PCIE20_PARF_CONFIG_BITS);
ipq_pcie_write_mask(pcie->parf.start + PCIE20_PARF_PHY_REFCLK,
REF_USE_PAD, REF_SSP_EN);
/* enable access to PCIe slave port on system fabric */
if (id == 0) {
writel(BIT(4), PCIE_SFAB_AXI_S5_FCLK_CTL);
}
udelay(1);
/* de-assert PICe PHY, Core, POR and AXI clk domain resets */
ipq_pcie_parf_reset(pcie->pci_rst.start, BIT(5), 0);
ipq_pcie_parf_reset(pcie->pci_rst.start, BIT(4), 0);
ipq_pcie_parf_reset(pcie->pci_rst.start, BIT(3), 0);
ipq_pcie_parf_reset(pcie->pci_rst.start, BIT(0), 0);
/* enable link training */
ipq_pcie_write_mask( pcie->elbi.start + PCIE20_ELBI_SYS_CTRL, 0,
BIT(0));
udelay(500);
for (j = 0; j < 10; j++) {
val = readl(pcie->pci_dbi.start +
PCIE_0_TYPE0_LINK_CONTROL_LINK_STATUS_REG_1);
if (val & BIT(29)) {
printf("PCI%d Link Intialized\n", id);
pcie->linkup = 1;
break;
}
udelay(10000);
}
ipq_pcie_config_controller(pcie);
}
static int ipq_pcie_parse_dt(const void *fdt, int id,
struct ipq_pcie *pcie)
{
int err, rst_gpio, node;
char name[16];
if (id == 0) {
node = fdt_path_offset(fdt, "pci0");
} else if (id == 1) {
node = fdt_path_offset(fdt, "pci1");
} else {
printf("PCI is not defined in the device tree\n");
return -1;
sprintf(name, "pci%d", id);
node = fdt_path_offset(fdt, name);
if (node < 0) {
printf("PCI%d is not defined in the device tree\n", id);
return node;
}
err = fdt_get_named_resource(fdt, node, "reg", "reg-names", "pci_dbi",
@ -703,6 +814,9 @@ static int pci_ipq_ofdata_to_platdata(int id, struct ipq_pcie *pcie)
board_pci_init(id);
switch(pcie->version) {
case PCIE_V0:
pcie_v0_linkup(pcie, id);
break;
case PCIE_V1:
pci_controller_init_v1(pcie);
pcie_linkup(pcie);

View file

@ -142,14 +142,15 @@
/*
* PCI Configs
*/
#undef CONFIG_IPQ806X_PCI
#ifdef CONFIG_IPQ806X_PCI
#define CONFIG_PCI_IPQ
#define PCI_MAX_DEVICES 3
#ifdef CONFIG_PCI_IPQ
#define CONFIG_PCI
#define CONFIG_CMD_PCI
#define CONFIG_PCI_SCAN_SHOW
#endif
/*
* MMC Configs
*/