#include <linux/resource.h>
#include <linux/signal.h>
#include <linux/types.h>
+#include <linux/busfreq-imx6.h>
#include "pcie-designware.h"
return 0;
}
-static int imx6_pcie_assert_core_reset(struct pcie_port *pp)
-{
- struct imx6_pcie *imx6_pcie = to_imx6_pcie(pp);
-
- regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1,
- IMX6Q_GPR1_PCIE_TEST_PD, 1 << 18);
- regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
- IMX6Q_GPR12_PCIE_CTL_2, 1 << 10);
- regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1,
- IMX6Q_GPR1_PCIE_REF_CLK_EN, 0 << 16);
-
- gpio_set_value(imx6_pcie->reset_gpio, 0);
- msleep(100);
- gpio_set_value(imx6_pcie->reset_gpio, 1);
-
- return 0;
-}
-
static int imx6_pcie_deassert_core_reset(struct pcie_port *pp)
{
struct imx6_pcie *imx6_pcie = to_imx6_pcie(pp);
IMX6Q_GPR1_PCIE_TEST_PD, 0 << 18);
regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1,
IMX6Q_GPR1_PCIE_REF_CLK_EN, 1 << 16);
+ request_bus_freq(BUS_FREQ_HIGH);
ret = clk_prepare_enable(imx6_pcie->sata_ref_100m);
if (ret) {
/* allow the clocks to stabilize */
usleep_range(200, 500);
+ gpio_set_value(imx6_pcie->reset_gpio, 0);
+ msleep(100);
+ gpio_set_value(imx6_pcie->reset_gpio, 1);
+
return 0;
err_pcie_axi:
err_pcie_ref:
clk_disable_unprepare(imx6_pcie->sata_ref_100m);
err_sata_ref:
+ release_bus_freq(BUS_FREQ_HIGH);
return ret;
}
int count = 0;
struct imx6_pcie *imx6_pcie = to_imx6_pcie(pp);
- imx6_pcie_assert_core_reset(pp);
-
imx6_pcie_init_phy(pp);
imx6_pcie_deassert_core_reset(pp);
dw_pcie_writel_rc(pp, 0, dbi_base + PCIE_ATU_UPPER_TARGET);
}
-static void dw_pcie_prog_viewport_mem_outbound(struct pcie_port *pp)
-{
- u32 val;
- void __iomem *dbi_base = pp->dbi_base;
-
- /* Program viewport 0 : OUTBOUND : MEM */
- val = PCIE_ATU_REGION_OUTBOUND | PCIE_ATU_REGION_INDEX0;
- dw_pcie_writel_rc(pp, val, dbi_base + PCIE_ATU_VIEWPORT);
- dw_pcie_writel_rc(pp, PCIE_ATU_TYPE_MEM, dbi_base + PCIE_ATU_CR1);
- val = PCIE_ATU_ENABLE;
- dw_pcie_writel_rc(pp, val, dbi_base + PCIE_ATU_CR2);
- dw_pcie_writel_rc(pp, pp->mem_base, dbi_base + PCIE_ATU_LOWER_BASE);
- dw_pcie_writel_rc(pp, (pp->mem_base >> 32),
- dbi_base + PCIE_ATU_UPPER_BASE);
- dw_pcie_writel_rc(pp, pp->mem_base + pp->config.mem_size - 1,
- dbi_base + PCIE_ATU_LIMIT);
- dw_pcie_writel_rc(pp, pp->config.mem_bus_addr,
- dbi_base + PCIE_ATU_LOWER_TARGET);
- dw_pcie_writel_rc(pp, upper_32_bits(pp->config.mem_bus_addr),
- dbi_base + PCIE_ATU_UPPER_TARGET);
-}
-
-static void dw_pcie_prog_viewport_io_outbound(struct pcie_port *pp)
-{
- u32 val;
- void __iomem *dbi_base = pp->dbi_base;
-
- /* Program viewport 1 : OUTBOUND : IO */
- val = PCIE_ATU_REGION_OUTBOUND | PCIE_ATU_REGION_INDEX1;
- dw_pcie_writel_rc(pp, val, dbi_base + PCIE_ATU_VIEWPORT);
- dw_pcie_writel_rc(pp, PCIE_ATU_TYPE_IO, dbi_base + PCIE_ATU_CR1);
- val = PCIE_ATU_ENABLE;
- dw_pcie_writel_rc(pp, val, dbi_base + PCIE_ATU_CR2);
- dw_pcie_writel_rc(pp, pp->io_base, dbi_base + PCIE_ATU_LOWER_BASE);
- dw_pcie_writel_rc(pp, (pp->io_base >> 32),
- dbi_base + PCIE_ATU_UPPER_BASE);
- dw_pcie_writel_rc(pp, pp->io_base + pp->config.io_size - 1,
- dbi_base + PCIE_ATU_LIMIT);
- dw_pcie_writel_rc(pp, pp->config.io_bus_addr,
- dbi_base + PCIE_ATU_LOWER_TARGET);
- dw_pcie_writel_rc(pp, upper_32_bits(pp->config.io_bus_addr),
- dbi_base + PCIE_ATU_UPPER_TARGET);
-}
-
static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus,
u32 devfn, int where, int size, u32 *val)
{
if (bus->parent->number == pp->root_bus_nr) {
dw_pcie_prog_viewport_cfg0(pp, busdev);
ret = cfg_read(pp->va_cfg0_base + address, where, size, val);
- dw_pcie_prog_viewport_mem_outbound(pp);
} else {
dw_pcie_prog_viewport_cfg1(pp, busdev);
ret = cfg_read(pp->va_cfg1_base + address, where, size, val);
- dw_pcie_prog_viewport_io_outbound(pp);
}
return ret;
if (bus->parent->number == pp->root_bus_nr) {
dw_pcie_prog_viewport_cfg0(pp, busdev);
ret = cfg_write(pp->va_cfg0_base + address, where, size, val);
- dw_pcie_prog_viewport_mem_outbound(pp);
} else {
dw_pcie_prog_viewport_cfg1(pp, busdev);
ret = cfg_write(pp->va_cfg1_base + address, where, size, val);
- dw_pcie_prog_viewport_io_outbound(pp);
}
return ret;
{
struct pcie_port *pp = sys_to_pcie(dev->bus->sysdata);
- return pp->irq;
+ switch (pin) {
+ case 1: return pp->irq;
+ case 2: return pp->irq - 1;
+ case 3: return pp->irq - 2;
+ case 4: return pp->irq - 3;
+ default: return -1;
+ }
}
static void dw_pcie_add_bus(struct pci_bus *bus)