From a07e1c8167f0b71759ad44b42f1250bbe821f366 Mon Sep 17 00:00:00 2001 From: Sergio Paracuellos Date: Wed, 29 May 2019 09:58:07 +0200 Subject: [PATCH] staging: mt7621-pci: use perst gpio instead of builtin perst Some boards need gpio instead of builtin perst. Use gpio for all of them which was the approach of the original code. Signed-off-by: Sergio Paracuellos --- drivers/staging/mt7621-dts/mt7621.dtsi | 3 +- drivers/staging/mt7621-pci/pci-mt7621.c | 122 ++++++++++++++++---------------- 2 files changed, 64 insertions(+), 61 deletions(-) diff --git a/drivers/staging/mt7621-dts/mt7621.dtsi b/drivers/staging/mt7621-dts/mt7621.dtsi index 280ec33..aed2458 100644 --- a/drivers/staging/mt7621-dts/mt7621.dtsi +++ b/drivers/staging/mt7621-dts/mt7621.dtsi @@ -1,5 +1,5 @@ #include - +#include / { #address-cells = <1>; #size-cells = <1>; @@ -468,6 +468,7 @@ #address-cells = <3>; #size-cells = <2>; + perst-gpio = <&gpio 19 GPIO_ACTIVE_HIGH>; pinctrl-names = "default"; pinctrl-0 = <&pcie_pins>; diff --git a/drivers/staging/mt7621-pci/pci-mt7621.c b/drivers/staging/mt7621-pci/pci-mt7621.c index 03d919a..b13920a 100644 --- a/drivers/staging/mt7621-pci/pci-mt7621.c +++ b/drivers/staging/mt7621-pci/pci-mt7621.c @@ -17,6 +17,7 @@ #include #include +#include #include #include #include @@ -35,6 +36,7 @@ /* sysctl */ #define MT7621_CHIP_REV_ID 0x0c +#define MT7621_GPIO_MODE 0x60 #define CHIP_REV_MT7621_E2 0x0101 /* MediaTek specific configuration registers */ @@ -81,7 +83,6 @@ #define PCIE_BAR_ENABLE BIT(0) #define PCIE_PORT_INT_EN(x) BIT(20 + (x)) #define PCIE_PORT_CLK_EN(x) BIT(24 + (x)) -#define PCIE_PORT_PERST(x) BIT(1 + (x)) #define PCIE_PORT_LINKUP BIT(0) #define PCIE_CLK_GEN_EN BIT(31) @@ -90,6 +91,10 @@ #define PCIE_CLK_GEN1_EN (BIT(27) | BIT(25)) #define MEMORY_BASE 0x0 +#define PERST_MODE_MASK GENMASK(11, 10) +#define PERST_MODE_GPIO BIT(10) +#define PERST_DELAY_US 1000 + /** * struct mt7621_pcie_port - PCIe port information * @base: I/O mapped register base @@ -119,6 +124,7 @@ struct mt7621_pcie_port { * @offset: IO / Memory offset * @dev: Pointer to PCIe device * @ports: pointer to PCIe port information + * @perst: gpio reset * @rst: pointer to pcie reset */ struct mt7621_pcie { @@ -132,6 +138,7 @@ struct mt7621_pcie { resource_size_t io; } offset; struct list_head ports; + struct gpio_desc *perst; struct reset_control *rst; }; @@ -198,6 +205,18 @@ static void write_config(struct mt7621_pcie *pcie, unsigned int dev, pcie_write(pcie, val, RALINK_PCI_CONFIG_DATA); } +static void mt7621_perst_gpio_pcie_assert(struct mt7621_pcie *pcie) +{ + gpiod_set_value(pcie->perst, 0); + mdelay(PERST_DELAY_US); +} + +static void mt7621_perst_gpio_pcie_deassert(struct mt7621_pcie *pcie) +{ + gpiod_set_value(pcie->perst, 1); + mdelay(PERST_DELAY_US); +} + static inline void mt7621_control_assert(struct mt7621_pcie_port *port) { u32 chip_rev_id = rt_sysc_r32(MT7621_CHIP_REV_ID); @@ -344,6 +363,12 @@ static int mt7621_pcie_parse_dt(struct mt7621_pcie *pcie) struct resource regs; int err; + pcie->perst = devm_gpiod_get(dev, "perst", GPIOD_OUT_HIGH); + if (IS_ERR(pcie->perst)) { + dev_err(dev, "failed to get gpio perst\n"); + return -EPROBE_DEFER; + } + err = of_address_to_resource(node, 0, ®s); if (err) { dev_err(dev, "missing \"reg\" property\n"); @@ -384,56 +409,41 @@ static int mt7621_pcie_init_port(struct mt7621_pcie_port *port) struct mt7621_pcie *pcie = port->pcie; struct device *dev = pcie->dev; u32 slot = port->slot; - u32 val = 0; int err; - /* - * Any MT7621 Ralink pcie controller that doesn't have 0x0101 at - * the end of the chip_id has inverted PCI resets. - */ - mt7621_reset_port(port); - - val = read_config(pcie, slot, PCIE_FTS_NUM); - dev_info(dev, "Port %d N_FTS = %x\n", (unsigned int)val, slot); - err = phy_init(port->phy); if (err) { dev_err(dev, "failed to initialize port%d phy\n", slot); - goto err_phy_init; + return err; } err = phy_power_on(port->phy); if (err) { dev_err(dev, "failed to power on port%d phy\n", slot); - goto err_phy_on; - } - - if ((pcie_port_read(port, RALINK_PCI_STATUS) & PCIE_PORT_LINKUP) == 0) { - dev_err(dev, "pcie%d no card, disable it (RST & CLK)\n", slot); - mt7621_control_assert(port); - port->enabled = false; - err = -ENODEV; - goto err_no_link_up; + return err; } port->enabled = true; return 0; - -err_no_link_up: - phy_power_off(port->phy); -err_phy_on: - phy_exit(port->phy); -err_phy_init: - return err; } static void mt7621_pcie_init_ports(struct mt7621_pcie *pcie) { struct device *dev = pcie->dev; struct mt7621_pcie_port *port, *tmp; + u32 val = 0; int err; + list_for_each_entry(port, &pcie->ports, list) + mt7621_control_assert(port); + + rt_sysc_m32(PERST_MODE_MASK, PERST_MODE_GPIO, MT7621_GPIO_MODE); + mt7621_perst_gpio_pcie_assert(pcie); + + list_for_each_entry(port, &pcie->ports, list) + mt7621_control_deassert(port); + list_for_each_entry_safe(port, tmp, &pcie->ports, list) { u32 slot = port->slot; @@ -441,7 +451,10 @@ static void mt7621_pcie_init_ports(struct mt7621_pcie *pcie) if (err) { dev_err(dev, "Initiating port %d failed\n", slot); list_del(&port->list); - } + } else { + val = read_config(pcie, slot, PCIE_FTS_NUM); + dev_info(dev, "Port %d N_FTS = %x\n", slot, (unsigned int)val); + } } reset_control_assert(pcie->rst); @@ -451,37 +464,32 @@ static void mt7621_pcie_init_ports(struct mt7621_pcie *pcie) rt_sysc_m32(PCIE_CLK_GEN_DIS, PCIE_CLK_GEN_EN, RALINK_PCIE_CLK_GEN); msleep(50); reset_control_deassert(pcie->rst); + + mt7621_perst_gpio_pcie_deassert(pcie); + + list_for_each_entry(port, &pcie->ports, list) { + u32 slot = port->slot; + + if ((pcie_port_read(port, RALINK_PCI_STATUS) & PCIE_PORT_LINKUP) == 0) { + dev_err(dev, "pcie%d no card, disable it (RST & CLK)\n", slot); + phy_power_off(port->phy); + mt7621_control_assert(port); + port->enabled = false; + } else { + /* enable pcie interrupt */ + val = pcie_read(pcie, RALINK_PCI_PCIMSK_ADDR); + val |= PCIE_PORT_INT_EN(slot); + pcie_write(pcie, val, RALINK_PCI_PCIMSK_ADDR); + } + } } -static int mt7621_pcie_enable_port(struct mt7621_pcie_port *port) +static void mt7621_pcie_enable_port(struct mt7621_pcie_port *port) { struct mt7621_pcie *pcie = port->pcie; u32 slot = port->slot; u32 offset = MT7621_PCIE_OFFSET + (slot * MT7621_NEXT_PORT); u32 val; - int err; - - /* assert port PERST_N */ - val = pcie_read(pcie, RALINK_PCI_PCICFG_ADDR); - val |= PCIE_PORT_PERST(slot); - pcie_write(pcie, val, RALINK_PCI_PCICFG_ADDR); - - /* de-assert port PERST_N */ - val = pcie_read(pcie, RALINK_PCI_PCICFG_ADDR); - val &= ~PCIE_PORT_PERST(slot); - pcie_write(pcie, val, RALINK_PCI_PCICFG_ADDR); - - /* 100ms timeout value should be enough for Gen1 training */ - err = readl_poll_timeout(port->base + RALINK_PCI_STATUS, - val, !!(val & PCIE_PORT_LINKUP), - 20, 100 * USEC_PER_MSEC); - if (err) - return -ETIMEDOUT; - - /* enable pcie interrupt */ - val = pcie_read(pcie, RALINK_PCI_PCIMSK_ADDR); - val |= PCIE_PORT_INT_EN(slot); - pcie_write(pcie, val, RALINK_PCI_PCIMSK_ADDR); /* map 2G DDR region */ pcie_write(pcie, PCIE_BAR_MAP_MAX | PCIE_BAR_ENABLE, @@ -492,8 +500,6 @@ static int mt7621_pcie_enable_port(struct mt7621_pcie_port *port) /* configure class code and revision ID */ pcie_write(pcie, PCIE_CLASS_CODE | PCIE_REVISION_ID, offset + RALINK_PCI_CLASS); - - return 0; } static void mt7621_pcie_enable_ports(struct mt7621_pcie *pcie) @@ -506,11 +512,7 @@ static void mt7621_pcie_enable_ports(struct mt7621_pcie *pcie) list_for_each_entry(port, &pcie->ports, list) { if (port->enabled) { - if (mt7621_pcie_enable_port(port)) { - dev_err(dev, "de-assert port %d PERST_N\n", - port->slot); - continue; - } + mt7621_pcie_enable_port(port); dev_info(dev, "PCIE%d enabled\n", slot); num_slots_enabled++; } -- 2.7.4