Commit 01a9259b authored by Bjorn Helgaas's avatar Bjorn Helgaas

Merge branch 'pci/host-rockchip' into next

* pci/host-rockchip:
  PCI: rockchip: Use normal register bank for config accessors
  PCI: rockchip: Use local struct device pointer consistently
  PCI: rockchip: Check for clk_prepare_enable() errors during resume
  MAINTAINERS: Remove Wenrui Li as Rockchip PCIe driver maintainer
  PCI: rockchip: Configure RC's MPS setting
  PCI: rockchip: Reconfigure configuration space header type
  PCI: rockchip: Split out rockchip_pcie_cfg_configuration_accesses()
  PCI: rockchip: Move configuration accesses into rockchip_pcie_cfg_atu()
  PCI: rockchip: Rename rockchip_cfg_atu() to rockchip_pcie_cfg_atu()
  PCI: rockchip: Control vpcie0v9 for system PM
parents 66a63e15 dc8cca5e
...@@ -9943,7 +9943,6 @@ F: drivers/pci/dwc/pcie-kirin.c ...@@ -9943,7 +9943,6 @@ F: drivers/pci/dwc/pcie-kirin.c
PCIE DRIVER FOR ROCKCHIP PCIE DRIVER FOR ROCKCHIP
M: Shawn Lin <shawn.lin@rock-chips.com> M: Shawn Lin <shawn.lin@rock-chips.com>
M: Wenrui Li <wenrui.li@rock-chips.com>
L: linux-pci@vger.kernel.org L: linux-pci@vger.kernel.org
L: linux-rockchip@lists.infradead.org L: linux-rockchip@lists.infradead.org
S: Maintained S: Maintained
......
...@@ -139,6 +139,7 @@ ...@@ -139,6 +139,7 @@
PCIE_CORE_INT_CT | PCIE_CORE_INT_UTC | \ PCIE_CORE_INT_CT | PCIE_CORE_INT_UTC | \
PCIE_CORE_INT_MMVC) PCIE_CORE_INT_MMVC)
#define PCIE_RC_CONFIG_NORMAL_BASE 0x800000
#define PCIE_RC_CONFIG_BASE 0xa00000 #define PCIE_RC_CONFIG_BASE 0xa00000
#define PCIE_RC_CONFIG_RID_CCR (PCIE_RC_CONFIG_BASE + 0x08) #define PCIE_RC_CONFIG_RID_CCR (PCIE_RC_CONFIG_BASE + 0x08)
#define PCIE_RC_CONFIG_SCC_SHIFT 16 #define PCIE_RC_CONFIG_SCC_SHIFT 16
...@@ -146,6 +147,9 @@ ...@@ -146,6 +147,9 @@
#define PCIE_RC_CONFIG_DCR_CSPL_SHIFT 18 #define PCIE_RC_CONFIG_DCR_CSPL_SHIFT 18
#define PCIE_RC_CONFIG_DCR_CSPL_LIMIT 0xff #define PCIE_RC_CONFIG_DCR_CSPL_LIMIT 0xff
#define PCIE_RC_CONFIG_DCR_CPLS_SHIFT 26 #define PCIE_RC_CONFIG_DCR_CPLS_SHIFT 26
#define PCIE_RC_CONFIG_DCSR (PCIE_RC_CONFIG_BASE + 0xc8)
#define PCIE_RC_CONFIG_DCSR_MPS_MASK GENMASK(7, 5)
#define PCIE_RC_CONFIG_DCSR_MPS_256 (0x1 << 5)
#define PCIE_RC_CONFIG_LINK_CAP (PCIE_RC_CONFIG_BASE + 0xcc) #define PCIE_RC_CONFIG_LINK_CAP (PCIE_RC_CONFIG_BASE + 0xcc)
#define PCIE_RC_CONFIG_LINK_CAP_L0S BIT(10) #define PCIE_RC_CONFIG_LINK_CAP_L0S BIT(10)
#define PCIE_RC_CONFIG_LCS (PCIE_RC_CONFIG_BASE + 0xd0) #define PCIE_RC_CONFIG_LCS (PCIE_RC_CONFIG_BASE + 0xd0)
...@@ -175,6 +179,8 @@ ...@@ -175,6 +179,8 @@
#define IB_ROOT_PORT_REG_SIZE_SHIFT 3 #define IB_ROOT_PORT_REG_SIZE_SHIFT 3
#define AXI_WRAPPER_IO_WRITE 0x6 #define AXI_WRAPPER_IO_WRITE 0x6
#define AXI_WRAPPER_MEM_WRITE 0x2 #define AXI_WRAPPER_MEM_WRITE 0x2
#define AXI_WRAPPER_TYPE0_CFG 0xa
#define AXI_WRAPPER_TYPE1_CFG 0xb
#define AXI_WRAPPER_NOR_MSG 0xc #define AXI_WRAPPER_NOR_MSG 0xc
#define MAX_AXI_IB_ROOTPORT_REGION_NUM 3 #define MAX_AXI_IB_ROOTPORT_REGION_NUM 3
...@@ -198,6 +204,7 @@ ...@@ -198,6 +204,7 @@
#define RC_REGION_0_ADDR_TRANS_H 0x00000000 #define RC_REGION_0_ADDR_TRANS_H 0x00000000
#define RC_REGION_0_ADDR_TRANS_L 0x00000000 #define RC_REGION_0_ADDR_TRANS_L 0x00000000
#define RC_REGION_0_PASS_BITS (25 - 1) #define RC_REGION_0_PASS_BITS (25 - 1)
#define RC_REGION_0_TYPE_MASK GENMASK(3, 0)
#define MAX_AXI_WRAPPER_REGION_NUM 33 #define MAX_AXI_WRAPPER_REGION_NUM 33
struct rockchip_pcie { struct rockchip_pcie {
...@@ -295,7 +302,9 @@ static int rockchip_pcie_valid_device(struct rockchip_pcie *rockchip, ...@@ -295,7 +302,9 @@ static int rockchip_pcie_valid_device(struct rockchip_pcie *rockchip,
static int rockchip_pcie_rd_own_conf(struct rockchip_pcie *rockchip, static int rockchip_pcie_rd_own_conf(struct rockchip_pcie *rockchip,
int where, int size, u32 *val) int where, int size, u32 *val)
{ {
void __iomem *addr = rockchip->apb_base + PCIE_RC_CONFIG_BASE + where; void __iomem *addr;
addr = rockchip->apb_base + PCIE_RC_CONFIG_NORMAL_BASE + where;
if (!IS_ALIGNED((uintptr_t)addr, size)) { if (!IS_ALIGNED((uintptr_t)addr, size)) {
*val = 0; *val = 0;
...@@ -319,11 +328,13 @@ static int rockchip_pcie_wr_own_conf(struct rockchip_pcie *rockchip, ...@@ -319,11 +328,13 @@ static int rockchip_pcie_wr_own_conf(struct rockchip_pcie *rockchip,
int where, int size, u32 val) int where, int size, u32 val)
{ {
u32 mask, tmp, offset; u32 mask, tmp, offset;
void __iomem *addr;
offset = where & ~0x3; offset = where & ~0x3;
addr = rockchip->apb_base + PCIE_RC_CONFIG_NORMAL_BASE + offset;
if (size == 4) { if (size == 4) {
writel(val, rockchip->apb_base + PCIE_RC_CONFIG_BASE + offset); writel(val, addr);
return PCIBIOS_SUCCESSFUL; return PCIBIOS_SUCCESSFUL;
} }
...@@ -334,13 +345,33 @@ static int rockchip_pcie_wr_own_conf(struct rockchip_pcie *rockchip, ...@@ -334,13 +345,33 @@ static int rockchip_pcie_wr_own_conf(struct rockchip_pcie *rockchip,
* corrupt RW1C bits in adjacent registers. But the hardware * corrupt RW1C bits in adjacent registers. But the hardware
* doesn't support smaller writes. * doesn't support smaller writes.
*/ */
tmp = readl(rockchip->apb_base + PCIE_RC_CONFIG_BASE + offset) & mask; tmp = readl(addr) & mask;
tmp |= val << ((where & 0x3) * 8); tmp |= val << ((where & 0x3) * 8);
writel(tmp, rockchip->apb_base + PCIE_RC_CONFIG_BASE + offset); writel(tmp, addr);
return PCIBIOS_SUCCESSFUL; return PCIBIOS_SUCCESSFUL;
} }
static void rockchip_pcie_cfg_configuration_accesses(
struct rockchip_pcie *rockchip, u32 type)
{
u32 ob_desc_0;
/* Configuration Accesses for region 0 */
rockchip_pcie_write(rockchip, 0x0, PCIE_RC_BAR_CONF);
rockchip_pcie_write(rockchip,
(RC_REGION_0_ADDR_TRANS_L + RC_REGION_0_PASS_BITS),
PCIE_CORE_OB_REGION_ADDR0);
rockchip_pcie_write(rockchip, RC_REGION_0_ADDR_TRANS_H,
PCIE_CORE_OB_REGION_ADDR1);
ob_desc_0 = rockchip_pcie_read(rockchip, PCIE_CORE_OB_REGION_DESC0);
ob_desc_0 &= ~(RC_REGION_0_TYPE_MASK);
ob_desc_0 |= (type | (0x1 << 23));
rockchip_pcie_write(rockchip, ob_desc_0, PCIE_CORE_OB_REGION_DESC0);
rockchip_pcie_write(rockchip, 0x0, PCIE_CORE_OB_REGION_DESC1);
}
static int rockchip_pcie_rd_other_conf(struct rockchip_pcie *rockchip, static int rockchip_pcie_rd_other_conf(struct rockchip_pcie *rockchip,
struct pci_bus *bus, u32 devfn, struct pci_bus *bus, u32 devfn,
int where, int size, u32 *val) int where, int size, u32 *val)
...@@ -355,6 +386,13 @@ static int rockchip_pcie_rd_other_conf(struct rockchip_pcie *rockchip, ...@@ -355,6 +386,13 @@ static int rockchip_pcie_rd_other_conf(struct rockchip_pcie *rockchip,
return PCIBIOS_BAD_REGISTER_NUMBER; return PCIBIOS_BAD_REGISTER_NUMBER;
} }
if (bus->parent->number == rockchip->root_bus_nr)
rockchip_pcie_cfg_configuration_accesses(rockchip,
AXI_WRAPPER_TYPE0_CFG);
else
rockchip_pcie_cfg_configuration_accesses(rockchip,
AXI_WRAPPER_TYPE1_CFG);
if (size == 4) { if (size == 4) {
*val = readl(rockchip->reg_base + busdev); *val = readl(rockchip->reg_base + busdev);
} else if (size == 2) { } else if (size == 2) {
...@@ -379,6 +417,13 @@ static int rockchip_pcie_wr_other_conf(struct rockchip_pcie *rockchip, ...@@ -379,6 +417,13 @@ static int rockchip_pcie_wr_other_conf(struct rockchip_pcie *rockchip,
if (!IS_ALIGNED(busdev, size)) if (!IS_ALIGNED(busdev, size))
return PCIBIOS_BAD_REGISTER_NUMBER; return PCIBIOS_BAD_REGISTER_NUMBER;
if (bus->parent->number == rockchip->root_bus_nr)
rockchip_pcie_cfg_configuration_accesses(rockchip,
AXI_WRAPPER_TYPE0_CFG);
else
rockchip_pcie_cfg_configuration_accesses(rockchip,
AXI_WRAPPER_TYPE1_CFG);
if (size == 4) if (size == 4)
writel(val, rockchip->reg_base + busdev); writel(val, rockchip->reg_base + busdev);
else if (size == 2) else if (size == 2)
...@@ -664,15 +709,10 @@ static int rockchip_pcie_init_port(struct rockchip_pcie *rockchip) ...@@ -664,15 +709,10 @@ static int rockchip_pcie_init_port(struct rockchip_pcie *rockchip)
rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_LINK_CAP); rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_LINK_CAP);
} }
rockchip_pcie_write(rockchip, 0x0, PCIE_RC_BAR_CONF); status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_DCSR);
status &= ~PCIE_RC_CONFIG_DCSR_MPS_MASK;
rockchip_pcie_write(rockchip, status |= PCIE_RC_CONFIG_DCSR_MPS_256;
(RC_REGION_0_ADDR_TRANS_L + RC_REGION_0_PASS_BITS), rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_DCSR);
PCIE_CORE_OB_REGION_ADDR0);
rockchip_pcie_write(rockchip, RC_REGION_0_ADDR_TRANS_H,
PCIE_CORE_OB_REGION_ADDR1);
rockchip_pcie_write(rockchip, 0x0080000a, PCIE_CORE_OB_REGION_DESC0);
rockchip_pcie_write(rockchip, 0x0, PCIE_CORE_OB_REGION_DESC1);
return 0; return 0;
} }
...@@ -1156,13 +1196,16 @@ static int rockchip_pcie_prog_ib_atu(struct rockchip_pcie *rockchip, ...@@ -1156,13 +1196,16 @@ static int rockchip_pcie_prog_ib_atu(struct rockchip_pcie *rockchip,
return 0; return 0;
} }
static int rockchip_cfg_atu(struct rockchip_pcie *rockchip) static int rockchip_pcie_cfg_atu(struct rockchip_pcie *rockchip)
{ {
struct device *dev = rockchip->dev; struct device *dev = rockchip->dev;
int offset; int offset;
int err; int err;
int reg_no; int reg_no;
rockchip_pcie_cfg_configuration_accesses(rockchip,
AXI_WRAPPER_TYPE0_CFG);
for (reg_no = 0; reg_no < (rockchip->mem_size >> 20); reg_no++) { for (reg_no = 0; reg_no < (rockchip->mem_size >> 20); reg_no++) {
err = rockchip_pcie_prog_ob_atu(rockchip, reg_no + 1, err = rockchip_pcie_prog_ob_atu(rockchip, reg_no + 1,
AXI_WRAPPER_MEM_WRITE, AXI_WRAPPER_MEM_WRITE,
...@@ -1251,6 +1294,9 @@ static int __maybe_unused rockchip_pcie_suspend_noirq(struct device *dev) ...@@ -1251,6 +1294,9 @@ static int __maybe_unused rockchip_pcie_suspend_noirq(struct device *dev)
clk_disable_unprepare(rockchip->aclk_perf_pcie); clk_disable_unprepare(rockchip->aclk_perf_pcie);
clk_disable_unprepare(rockchip->aclk_pcie); clk_disable_unprepare(rockchip->aclk_pcie);
if (!IS_ERR(rockchip->vpcie0v9))
regulator_disable(rockchip->vpcie0v9);
return ret; return ret;
} }
...@@ -1259,24 +1305,54 @@ static int __maybe_unused rockchip_pcie_resume_noirq(struct device *dev) ...@@ -1259,24 +1305,54 @@ static int __maybe_unused rockchip_pcie_resume_noirq(struct device *dev)
struct rockchip_pcie *rockchip = dev_get_drvdata(dev); struct rockchip_pcie *rockchip = dev_get_drvdata(dev);
int err; int err;
clk_prepare_enable(rockchip->clk_pcie_pm); if (!IS_ERR(rockchip->vpcie0v9)) {
clk_prepare_enable(rockchip->hclk_pcie); err = regulator_enable(rockchip->vpcie0v9);
clk_prepare_enable(rockchip->aclk_perf_pcie); if (err) {
clk_prepare_enable(rockchip->aclk_pcie); dev_err(dev, "fail to enable vpcie0v9 regulator\n");
return err;
}
}
err = clk_prepare_enable(rockchip->clk_pcie_pm);
if (err)
goto err_pcie_pm;
err = clk_prepare_enable(rockchip->hclk_pcie);
if (err)
goto err_hclk_pcie;
err = clk_prepare_enable(rockchip->aclk_perf_pcie);
if (err)
goto err_aclk_perf_pcie;
err = clk_prepare_enable(rockchip->aclk_pcie);
if (err)
goto err_aclk_pcie;
err = rockchip_pcie_init_port(rockchip); err = rockchip_pcie_init_port(rockchip);
if (err) if (err)
return err; goto err_pcie_resume;
err = rockchip_cfg_atu(rockchip); err = rockchip_pcie_cfg_atu(rockchip);
if (err) if (err)
return err; goto err_pcie_resume;
/* Need this to enter L1 again */ /* Need this to enter L1 again */
rockchip_pcie_update_txcredit_mui(rockchip); rockchip_pcie_update_txcredit_mui(rockchip);
rockchip_pcie_enable_interrupts(rockchip); rockchip_pcie_enable_interrupts(rockchip);
return 0; return 0;
err_pcie_resume:
clk_disable_unprepare(rockchip->aclk_pcie);
err_aclk_pcie:
clk_disable_unprepare(rockchip->aclk_perf_pcie);
err_aclk_perf_pcie:
clk_disable_unprepare(rockchip->hclk_pcie);
err_hclk_pcie:
clk_disable_unprepare(rockchip->clk_pcie_pm);
err_pcie_pm:
return err;
} }
static int rockchip_pcie_probe(struct platform_device *pdev) static int rockchip_pcie_probe(struct platform_device *pdev)
...@@ -1388,19 +1464,18 @@ static int rockchip_pcie_probe(struct platform_device *pdev) ...@@ -1388,19 +1464,18 @@ static int rockchip_pcie_probe(struct platform_device *pdev)
} }
} }
err = rockchip_cfg_atu(rockchip); err = rockchip_pcie_cfg_atu(rockchip);
if (err) if (err)
goto err_free_res; goto err_free_res;
rockchip->msg_region = devm_ioremap(rockchip->dev, rockchip->msg_region = devm_ioremap(dev, rockchip->msg_bus_addr, SZ_1M);
rockchip->msg_bus_addr, SZ_1M);
if (!rockchip->msg_region) { if (!rockchip->msg_region) {
err = -ENOMEM; err = -ENOMEM;
goto err_free_res; goto err_free_res;
} }
list_splice_init(&res, &bridge->windows); list_splice_init(&res, &bridge->windows);
bridge->dev.parent = &pdev->dev; bridge->dev.parent = dev;
bridge->sysdata = rockchip; bridge->sysdata = rockchip;
bridge->busnr = 0; bridge->busnr = 0;
bridge->ops = &rockchip_pcie_ops; bridge->ops = &rockchip_pcie_ops;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment