static void spear13xx_pcie_host_init(struct pcie_port *pp) { struct spear13xx_pcie *spear13xx_pcie = to_spear13xx_pcie(pp); spear13xx_pcie_establish_link(spear13xx_pcie); spear13xx_pcie_enable_interrupts(spear13xx_pcie); }
static int spear13xx_pcie_link_up(struct pcie_port *pp) { struct spear13xx_pcie *spear13xx_pcie = to_spear13xx_pcie(pp); struct pcie_app_reg *app_reg = spear13xx_pcie->app_base; if (readl(&app_reg->app_status_1) & XMLH_LINK_UP) return 1; return 0; }
static void spear13xx_pcie_enable_interrupts(struct pcie_port *pp) { struct spear13xx_pcie *spear13xx_pcie = to_spear13xx_pcie(pp); struct pcie_app_reg *app_reg = spear13xx_pcie->app_base; /* Enable MSI interrupt */ if (IS_ENABLED(CONFIG_PCI_MSI)) { dw_pcie_msi_init(pp); writel(readl(&app_reg->int_mask) | MSI_CTRL_INT, &app_reg->int_mask); } }
static irqreturn_t spear13xx_pcie_irq_handler(int irq, void *arg) { struct pcie_port *pp = arg; struct spear13xx_pcie *spear13xx_pcie = to_spear13xx_pcie(pp); struct pcie_app_reg *app_reg = spear13xx_pcie->app_base; unsigned int status; status = readl(&app_reg->int_sts); if (status & MSI_CTRL_INT) { BUG_ON(!IS_ENABLED(CONFIG_PCI_MSI)); dw_handle_msi_irq(pp); } writel(status, &app_reg->int_clr); return IRQ_HANDLED; }
static int spear13xx_pcie_establish_link(struct pcie_port *pp) { u32 val; struct spear13xx_pcie *spear13xx_pcie = to_spear13xx_pcie(pp); struct pcie_app_reg *app_reg = spear13xx_pcie->app_base; u32 exp_cap_off = EXP_CAP_ID_OFFSET; unsigned int retries; if (dw_pcie_link_up(pp)) { dev_err(pp->dev, "link already up\n"); return 0; } dw_pcie_setup_rc(pp); /* * this controller support only 128 bytes read size, however its * default value in capability register is 512 bytes. So force * it to 128 here. */ dw_pcie_cfg_read(pp->dbi_base, exp_cap_off + PCI_EXP_DEVCTL, 4, &val); val &= ~PCI_EXP_DEVCTL_READRQ; dw_pcie_cfg_write(pp->dbi_base, exp_cap_off + PCI_EXP_DEVCTL, 4, val); dw_pcie_cfg_write(pp->dbi_base, PCI_VENDOR_ID, 2, 0x104A); dw_pcie_cfg_write(pp->dbi_base, PCI_DEVICE_ID, 2, 0xCD80); /* * if is_gen1 is set then handle it, so that some buggy card * also works */ if (spear13xx_pcie->is_gen1) { dw_pcie_cfg_read(pp->dbi_base, exp_cap_off + PCI_EXP_LNKCAP, 4, &val); if ((val & PCI_EXP_LNKCAP_SLS) != PCI_EXP_LNKCAP_SLS_2_5GB) { val &= ~((u32)PCI_EXP_LNKCAP_SLS); val |= PCI_EXP_LNKCAP_SLS_2_5GB; dw_pcie_cfg_write(pp->dbi_base, exp_cap_off + PCI_EXP_LNKCAP, 4, val); } dw_pcie_cfg_read(pp->dbi_base, exp_cap_off + PCI_EXP_LNKCTL2, 4, &val); if ((val & PCI_EXP_LNKCAP_SLS) != PCI_EXP_LNKCAP_SLS_2_5GB) { val &= ~((u32)PCI_EXP_LNKCAP_SLS); val |= PCI_EXP_LNKCAP_SLS_2_5GB; dw_pcie_cfg_write(pp->dbi_base, exp_cap_off + PCI_EXP_LNKCTL2, 4, val); } } /* enable ltssm */ writel(DEVICE_TYPE_RC | (1 << MISCTRL_EN_ID) | (1 << APP_LTSSM_ENABLE_ID) | ((u32)1 << REG_TRANSLATION_ENABLE), &app_reg->app_ctrl_0); /* check if the link is up or not */ for (retries = 0; retries < 10; retries++) { if (dw_pcie_link_up(pp)) { dev_info(pp->dev, "link up\n"); return 0; } mdelay(100); } dev_err(pp->dev, "link Fail\n"); return -EINVAL; }