static int histb_pcie_establish_link(struct pcie_port *pp) { struct dw_pcie *pci = to_dw_pcie_from_pp(pp); struct histb_pcie *hipcie = to_histb_pcie(pci); u32 regval; if (dw_pcie_link_up(pci)) { dev_info(pci->dev, "Link already up\n"); return 0; } /* PCIe RC work mode */ regval = histb_pcie_readl(hipcie, PCIE_SYS_CTRL0); regval &= ~PCIE_DEVICE_TYPE_MASK; regval |= PCIE_WM_RC; histb_pcie_writel(hipcie, PCIE_SYS_CTRL0, regval); /* setup root complex */ dw_pcie_setup_rc(pp); /* assert LTSSM enable */ regval = histb_pcie_readl(hipcie, PCIE_SYS_CTRL7); regval |= PCIE_APP_LTSSM_ENABLE; histb_pcie_writel(hipcie, PCIE_SYS_CTRL7, regval); return dw_pcie_wait_for_link(pci); }
static int histb_pcie_host_enable(struct pcie_port *pp) { struct dw_pcie *pci = to_dw_pcie_from_pp(pp); struct histb_pcie *hipcie = to_histb_pcie(pci); struct device *dev = pci->dev; int ret; /* power on PCIe device if have */ if (gpio_is_valid(hipcie->reset_gpio)) gpio_set_value_cansleep(hipcie->reset_gpio, 1); ret = clk_prepare_enable(hipcie->bus_clk); if (ret) { dev_err(dev, "cannot prepare/enable bus clk\n"); goto err_bus_clk; } ret = clk_prepare_enable(hipcie->sys_clk); if (ret) { dev_err(dev, "cannot prepare/enable sys clk\n"); goto err_sys_clk; } ret = clk_prepare_enable(hipcie->pipe_clk); if (ret) { dev_err(dev, "cannot prepare/enable pipe clk\n"); goto err_pipe_clk; } ret = clk_prepare_enable(hipcie->aux_clk); if (ret) { dev_err(dev, "cannot prepare/enable aux clk\n"); goto err_aux_clk; } reset_control_assert(hipcie->soft_reset); reset_control_deassert(hipcie->soft_reset); reset_control_assert(hipcie->sys_reset); reset_control_deassert(hipcie->sys_reset); reset_control_assert(hipcie->bus_reset); reset_control_deassert(hipcie->bus_reset); return 0; err_aux_clk: clk_disable_unprepare(hipcie->aux_clk); err_pipe_clk: clk_disable_unprepare(hipcie->pipe_clk); err_sys_clk: clk_disable_unprepare(hipcie->sys_clk); err_bus_clk: clk_disable_unprepare(hipcie->bus_clk); return ret; }
static void histb_pcie_dbi_r_mode(struct pcie_port *pp, bool enable) { struct dw_pcie *pci = to_dw_pcie_from_pp(pp); struct histb_pcie *hipcie = to_histb_pcie(pci); u32 val; val = histb_pcie_readl(hipcie, PCIE_SYS_CTRL1); if (enable) val |= PCIE_ELBI_SLV_DBI_ENABLE; else val &= ~PCIE_ELBI_SLV_DBI_ENABLE; histb_pcie_writel(hipcie, PCIE_SYS_CTRL1, val); }
static int histb_pcie_link_up(struct dw_pcie *pci) { struct histb_pcie *hipcie = to_histb_pcie(pci); u32 regval; u32 status; regval = histb_pcie_readl(hipcie, PCIE_SYS_STAT0); status = histb_pcie_readl(hipcie, PCIE_SYS_STAT4); status &= PCIE_LTSSM_STATE_MASK; if ((regval & PCIE_XMLH_LINK_UP) && (regval & PCIE_RDLH_LINK_UP) && (status == PCIE_LTSSM_STATE_ACTIVE)) return 1; return 0; }