Hi Greg, On Wed, May 29, 2019 at 9:11 AM Greg Ungerer <gerg@xxxxxxxxxx> wrote: > > Hi Sergio, > > On 27/5/19 6:02 pm, Sergio Paracuellos wrote: > > On Mon, May 27, 2019 at 9:29 AM Greg Ungerer <gerg@xxxxxxxxxx> wrote: > >> On 27/5/19 4:35 pm, Sergio Paracuellos wrote: > >>> On Mon, May 27, 2019 at 6:37 AM Greg Ungerer <gerg@xxxxxxxxxx> wrote: > >>>> On 24/5/19 3:35 pm, Sergio Paracuellos wrote: > >>>>> On Fri, May 24, 2019 at 2:35 AM Greg Ungerer <gerg@xxxxxxxxxx> wrote: > >>>>>> On 23/5/19 3:26 pm, Sergio Paracuellos wrote: > >>>>>>> On Thu, May 23, 2019 at 4:11 AM Greg Ungerer <gerg@xxxxxxxxxx> wrote: > >>>>>>>> On 22/5/19 4:27 pm, Sergio Paracuellos wrote: > >>>>>>>> [snip] > >>>>>>>>> There are some big changes between 4.20 and 5.x. One is the use of PERST_N > >>>>>>>>> instead of using gpio. This PERT_N stuff is used now on enable ports > >>>>>>>>> assuming the > >>>>>>>>> link of PCI is properly detected after enabling the phy. And it seems > >>>>>>>>> it is not according to > >>>>>>>>> your dmesg traces. The previous 4.20 code used gpio before this was done. > >>>>>>>>> > >>>>>>>>> This code is the one I am referring: > >>>>>>>>> > >>>>>>>>> /* Use GPIO control instead of PERST_N */ > >>>>>>>>> *(unsigned int *)(0xbe000620) |= BIT(19) | BIT(8) | BIT(7); // set DATA > >>>>>>>>> mdelay(1000); > >>>>>>>> > >>>>>>>> I have been looking closely at those, wondering why the old code > >>>>>>>> drove that PERST line as a GPIO instead of using the built-in behavior. > >>>>>>>> (I have ignored bits 7 and 8 here since they are control of UART 3) > >>>>>>> > >>>>>>> Yes, this was also at first one of my big concerns so I tried to change into > >>>>>>> to use builtin behaviour (which is much more cleaner) and when the > >>>>>>> code was tested > >>>>>>> it worked. It seems it is not valid for every board. > >>>>>>> > >>>>>>>> > >>>>>>>> > >>>>>>>>> I assume reset lines on your device tree are properly set up which is > >>>>>>>>> other of the big changes here: use > >>>>>>>>> reset lines instead of that hardcoding stuff. Also, the > >>>>>>>>> mt7621_reset_port routine is also using msleep(100) > >>>>>>>>> but maybe you can try a bigger value and change it into a mdelay, to > >>>>>>>>> see if that changes anything. > >>>>>>>> > >>>>>>>> I see the reset line configuration in the pcie section of mt7621.dtsi, > >>>>>>>> is there any others absolutely required here? I couldn't see the > >>>>>>>> gbpc1.dts devicetree do anything else with pcie - othe than enable it. > >>>>>>>> My device tree for the EX15 is similar in that regard. > >>>>>>>> > >>>>>>>> I tried a couple of things with interesting results. > >>>>>>>> > >>>>>>>> 1. I made sure that the PERST_N line is set for PCIe operation (not GPIO). > >>>>>>>> I forced it with: > >>>>>>>> > >>>>>>>> *(unsigned int *)(0xbe000060) &= ~(0x3 << 10); > >>>>>>>> > >>>>>>>> I checked bits 10 and 11 at kernel PCI init and they were 00 anyway. > >>>>>>>> So PERST_N was definitely in PCIe reset mode. No change in behavior, > >>>>>>>> > >>>>>>>> > >>>>>>>> 2. I forced a GPIO style reset of that PERST line (using GPIO19) and got > >>>>>>>> the following result on kernel boot: > >>>>>>>> > >>>>>>>> mt7621-pci 1e140000.pcie: Port 454043648 N_FTS = 0 > >>>>>>>> mt7621-pci-phy 1e149000.pcie-phy: Xtal is 40MHz > >>>>>>>> mt7621-pci 1e140000.pcie: Port 454043648 N_FTS = 1 > >>>>>>>> mt7621-pci 1e140000.pcie: pcie1 no card, disable it (RST & CLK) > >>>>>>>> mt7621-pci 1e140000.pcie: Initiating port 1 failed > >>>>>>>> mt7621-pci 1e140000.pcie: Port 454043648 N_FTS = 2 > >>>>>>>> mt7621-pci-phy 1e14a000.pcie-phy: Xtal is 40MHz > >>>>>>>> mt7621-pci 1e140000.pcie: pcie2 no card, disable it (RST & CLK) > >>>>>>>> mt7621-pci 1e140000.pcie: Initiating port 2 failed > >>>>>>>> mt7621-pci 1e140000.pcie: de-assert port 0 PERST_N > >>>>>>> > >>>>>>> This line seems to be the problem. When ports are init, (and with your > >>>>>>> changes seems the are > >>>>>>> init properly), the ports with pcie link are stored into a list to be > >>>>>>> enabled afterwards. This code is > >>>>>>> located into 'mt7621_pcie_enable_ports' which call simple > >>>>>>> 'mt7621_pcie_enable_port' to enable each port > >>>>>>> on the list. In this process it uses the PERS_N built-in register > >>>>>>> deasserting and asserting it. If enabling fails > >>>>>>> (and this is ypour case now) the port is removed from the list and it > >>>>>>> is not properly set up. You should try to > >>>>>>> comment this code: > >>>>>>> > >>>>>>> /* 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; > >>>>>>> > >>>>>>> because on enabling, it seems it is getting ETIMEOUT and hence the > >>>>>>> message ' mt7621-pci 1e140000.pcie: de-assert port 0 PERST_N'. > >>>>>>> Commenting > >>>>>>> this code should end up into a properly configured pci? > >>>>>> > >>>>>> No, unfortunately it doesn't. It does show PCIE0 enabled now though: > >>>>> > >>>>> That is a surprise :( > >>>>> > >>>>>> > >>>>>> mt7621-pci 1e140000.pcie: Port 454043648 N_FTS = 0 > >>>>>> mt7621-pci-phy 1e149000.pcie-phy: Xtal is 40MHz > >>>>>> mt7621-pci 1e140000.pcie: Port 454043648 N_FTS = 1 > >>>>>> mt7621-pci 1e140000.pcie: pcie1 no card, disable it (RST & CLK) > >>>>>> mt7621-pci 1e140000.pcie: Initiating port 1 failed > >>>>>> mt7621-pci 1e140000.pcie: Port 454043648 N_FTS = 2 > >>>>>> mt7621-pci-phy 1e14a000.pcie-phy: Xtal is 40MHz > >>>>>> mt7621-pci 1e140000.pcie: pcie2 no card, disable it (RST & CLK) > >>>>>> mt7621-pci 1e140000.pcie: Initiating port 2 failed > >>>>>> mt7621-pci 1e140000.pcie: PCIE0 enabled > >>>>>> mt7621-pci 1e140000.pcie: PCI coherence region base: 0x60000000, mask/settings: 0xf0000002 > >>>>>> mt7621-pci 1e140000.pcie: PCI host bridge to bus 0000:00 > >>>>>> pci_bus 0000:00: root bus resource [io 0xffffffff] > >>>>>> pci_bus 0000:00: root bus resource [mem 0x60000000-0x6fffffff] > >>>>>> pci_bus 0000:00: root bus resource [bus 00-ff] > >>>>> > >>>>> > >>>>>> > >>>>>> And again no devices are found on the PCI bus. > >>>>>> (System did still boot too). > >>>>> > >>>>> Looking to your original trace of linux-4.20 working the init traces > >>>>> are pretty much the same... I don't really know what could be > >>>>> happening there. Root resources > >>>>> are correct, virtual bridge seems to be detected, the next should be > >>>>> to reconfigure resources of > >>>>> the bridge and this is done by the pci kernel apis. > >>>>> > >>>>> Can you check that "mt7621_pcie_init_virtual_bridges" is getting link > >>>>> up and configuring bridges > >>>>> correctly? > >>>> > >>>> Yes, it does get link there. It sees pcie_link_status as 0x1, so its getting > >>>> through that. > >>>> > >>>> I threw a bit of trace in to see where we end up losing the ability to > >>>> read correct config data from slot 0 (my only valid slot). It gets to > >>>> the "err_no_link_up:" label for port/slot 2 still being able to read config > >>>> space, but then after executing the phy_power_off() and phy_exit() > >>>> calls for that port/slot we can no longer read config for slot 0. > >>> > >>> Mmmm. I see. So phy instances for port 0 and 2 are different instances > >>> of the phy, so it should not > >>> have problems for the power_off function. Looking again to the version > >>> which is in the 5.0 linux (but not in the last changes of > >>> staging where no child nodes are being used) I can see the phy_exit > >>> function is disabling the clock using PCIE_PORT_CLK_EN which is > >>> defined as: > >>> > >>> #define PCIE_PORT_CLK_EN(x) BIT(24 + (x)) > >>> > >>> On probe function index is being set to 0 for the port 2 also, instead > >>> of 2 (which is the correct value). Just try to comment this line: > >>> > >>> rt_sysc_m32(PCIE_PORT_CLK_EN(instance->index), 0, RALINK_CLKCFG1); > >>> > >>> Does this enough to get the pci enumeration being done correctly? > >> > >> Yes, just that (and the gpio based reset hack) is enough to enumerate the bus. > > > > Ok, so this is problem shouldn't be present in the current staging and > > linux tree at master where the > > device tree is not using child nodes, which is the way to go. > > I cloned the staging tree from git.kernel.org and tried that. > It didn't work any better, I had to patch pci-mt7621.c and > pci-mt8721-phy.c in the same ways to get an almost working result. That's weird. I'll check that. > > > > I think we should add a gpio reset line in the device tree and use it > > properly with > > the gpio descriptor api. Maybe this is better for all the boards > > instead of use the builtin stuff. > > Would seem to be the best approach. > > > >>>> If I comment out the code in phy_power_off() and phy_exit() so they > >>>> return doing nothing then I get further: > >>>> > >>>> mt7621-pci 1e140000.pcie: Port 454043648 N_FTS = 0 > >>>> mt7621-pci-phy 1e149000.pcie-phy: Xtal is 40MHz > >>>> mt7621-pci 1e140000.pcie: Port 454043648 N_FTS = 1 > >>>> mt7621-pci 1e140000.pcie: pcie1 no card, disable it (RST & CLK) > >>>> mt7621-pci 1e140000.pcie: Initiating port 1 failed > >>>> mt7621-pci 1e140000.pcie: Port 454043648 N_FTS = 2 > >>>> mt7621-pci-phy 1e14a000.pcie-phy: Xtal is 40MHz > >>>> mt7621-pci 1e140000.pcie: pcie2 no card, disable it (RST & CLK) > >>>> mt7621-pci 1e140000.pcie: Initiating port 2 failed > >>>> mt7621-pci 1e140000.pcie: PCIE0 enabled > >>>> mt7621-pci 1e140000.pcie: PCI coherence region base: 0x60000000, mask/settings: 0xf0000002 > >>>> mt7621-pci 1e140000.pcie: PCI host bridge to bus 0000:00 > >>>> pci_bus 0000:00: root bus resource [io 0xffffffff] > >>>> pci_bus 0000:00: root bus resource [mem 0x60000000-0x6fffffff] > >>>> pci_bus 0000:00: root bus resource [bus 00-ff] > >>>> pci 0000:00:00.0: bridge configuration invalid ([bus 00-00]), reconfiguring > >>>> pci 0000:00:00.0: PCI bridge to [bus 01-ff] > >>>> pci 0000:00:00.0: BAR 0: no space for [mem size 0x80000000] > >>>> pci 0000:00:00.0: BAR 0: failed to assign [mem size 0x80000000] > >>>> pci 0000:00:00.0: BAR 8: assigned [mem 0x60000000-0x601fffff] > >>>> pci 0000:00:00.0: BAR 9: assigned [mem 0x60200000-0x602fffff pref] > >>>> pci 0000:00:00.0: BAR 1: assigned [mem 0x60300000-0x6030ffff] > >>>> pci 0000:00:00.0: BAR 7: no space for [io size 0x1000] > >>>> pci 0000:00:00.0: BAR 7: failed to assign [io size 0x1000] > >>>> pci 0000:01:00.0: BAR 0: assigned [mem 0x60000000-0x601fffff 64bit] > >>>> pci 0000:01:00.0: BAR 6: assigned [mem 0x60200000-0x6020ffff pref] > >>>> pci 0000:00:00.0: PCI bridge to [bus 01] > >>>> pci 0000:00:00.0: bridge window [mem 0x60000000-0x601fffff] > >>>> pci 0000:00:00.0: bridge window [mem 0x60200000-0x602fffff pref] > >>>> pcieport 0000:00:00.0: of_irq_parse_pci: failed with rc=-22 > >>>> pcieport 0000:00:00.0: enabling device (0004 -> 0006) > >>>> > >>>> > >>>> So devices found, but interrupt setup failed for some reason. > >>>> I have an atheros PCIe WIFI device on that bus which is detected, but > >>>> the interrupt failure means it still doesn't actually work. > >>> > >>> Nothing has changed about interrupts from linux 4.20 version to this. > >>> It is returning -EINVAL > >>> for some reason. Irq is set using "of_irq_parse_and_map_pci" function. > >> > >> Not sure either why this would be different. > >> I'll dig into that tomorrow too. > > > > Thanks, let me know any advance on this, please. > > I suspect that the bus or devices stop reading/writing valid data > at some point in this initialization process. What I see is that > dumping /sys/bus/pci/devices/0000:01:00.0/config on a running > system shows: > > 00000000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ > 00000010: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ > 00000020: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ > ... > > But if I replace the PCI code again with that from 4.20 then > I get a valid dump of the wifi card config space: > > 00000000: 8c 16 3c 00 06 00 10 00 00 00 80 02 00 00 00 00 ..<............. > 00000010: 04 00 00 60 00 00 00 00 00 00 00 00 00 00 00 00 ...`............ > 00000020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ > I have added gpio consumer stuff and reorder a bit the code to be more similar to 4.20. I attach the patch. I have not try it to compile it, because my normal environment is in another computer and I am in the middle of moving from my current house and don't have access to it, sorry. So, please try this and let's see what happens. > Regards > Greg Hope this helps. Best regards, Sergio Paracuellos > > > >> Regards > >> Greg > > > > Best regards, > > Sergio Paracuellos > > > >> > >> > >>>> Regards > >>>> Greg > >>> > >>> Best regards, > >>> Sergio Paracuellos > >>>> > >>>> > >>>>>> I'll keep digging. > >>>>> > >>>>> Thanks, really appreciate it. > >>>>> > >>>>>> > >>>>>> Thanks > >>>>>> Greg > >>>>> > >>>>> Best regards, > >>>>> Sergio Paracuellos > >>>>> > >>>>>> > >>>>>> > >>>>>>> > >>>>>>>> mt7621-pci 1e140000.pcie: PCI coherence region base: 0x60000000, mask/settings: 0xf0000002 > >>>>>>>> mt7621-pci 1e140000.pcie: PCI host bridge to bus 0000:00 > >>>>>>>> pci_bus 0000:00: root bus resource [io 0xffffffff] > >>>>>>>> pci_bus 0000:00: root bus resource [mem 0x60000000-0x6fffffff] > >>>>>>>> pci_bus 0000:00: root bus resource [bus 00-ff] > >>>>>>>> > >>>>>>>> And the system continued on to fully boot. So it looks like it thinks > >>>>>>>> pcie0 is active. Better, but the PCI bus probe didn't find any of the > >>>>>>>> devices it should have. > >>>>>>> > >>>>>>> Yes, that seems what is happening because of my explanation above. > >>>>>>> > >>>>>>>> > >>>>>>>> I inserted the quick hack code to do this at the top of mt7621_pcie_init_ports() > >>>>>>>> and it looked like this: > >>>>>>>> > >>>>>>>> /* Force PERST PCIe line into GPIO mode */ > >>>>>>>> *(unsigned int *)(0xbe000060) &= ~(0x3 << 10); > >>>>>>>> *(unsigned int *)(0xbe000060) |= BIT(10); > >>>>>>>> mdelay(100); > >>>>>>>> > >>>>>>>> *(unsigned int *)(0xbe000600) |= BIT(19); // use GPIO19 (PERST_N/) > >>>>>>>> mdelay(100); > >>>>>>>> *(unsigned int *)(0xbe000620) &= ~(BIT(19)); // clear DATA > >>>>>>>> mdelay(1000); > >>>>>>>> > >>>>>>>> /* Use GPIO control instead of PERST_N */ > >>>>>>>> *(unsigned int *)(0xbe000620) |= BIT(19); // set DATA > >>>>>>>> mdelay(1000); > >>>>>>>> > >>>>>>>> > >>>>>>> > >>>>>>> I really hate the gpio way of doing this. If this works we have to > >>>>>>> think in how to achieve this in a cleaner way :)) > >>>>>>> > >>>>>>>> Regards > >>>>>>>> Greg > >>>>>>> > >>>>>>> Thanks for your effort in this. > >>>>>>> > >>>>>>> Best regards, > >>>>>>> Sergio Paracuellos > >>>>>>>> > >>>>>>>> > >>>>>>>>> Other big change is to use the new phy driver but I think the problem > >>>>>>>>> seems to be related with resets. > >>>>>>>>> > >>>>>>>>>> > >>>>>>>>>> Regards > >>>>>>>>>> Greg > >>>>>>>>> > >>>>>>>>> Please, don't hesitate to ask me whatever you need to. > >>>>>>>>> > >>>>>>>>> Hope this helps. > >>>>>>>>> > >>>>>>>>> Best regards, > >>>>>>>>> Sergio Paracuellos > >>>>>>>>> > >>>>>>> > >>>>> > >>> > >
From b7d26e7cca7d354d83fc217ab04a179019e1ad47 Mon Sep 17 00:00:00 2001 From: Sergio Paracuellos <sergio.paracuellos@xxxxxxxxx> 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 <sergio.paracuellos@xxxxxxxxx> --- drivers/staging/mt7621-dts/mt7621.dtsi | 3 +- drivers/staging/mt7621-pci/pci-mt7621.c | 98 ++++++++++++++++----------------- 2 files changed, 51 insertions(+), 50 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 <dt-bindings/interrupt-controller/mips-gic.h> - +#include <dt-bindings/gpio/gpio.h> / { #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..8464985 100644 --- a/drivers/staging/mt7621-pci/pci-mt7621.c +++ b/drivers/staging/mt7621-pci/pci-mt7621.c @@ -17,6 +17,7 @@ #include <linux/bitops.h> #include <linux/delay.h> +#include <linux/gpio/consumer.h> #include <linux/iopoll.h> #include <linux/module.h> #include <linux/of.h> @@ -75,13 +76,13 @@ #define RALINK_PCI_STATUS 0x0050 /* Some definition values */ +#define RALINK_PCI_IO_MAP_BASE 0x1e160000 #define PCIE_REVISION_ID BIT(0) #define PCIE_CLASS_CODE (0x60400 << 8) #define PCIE_BAR_MAP_MAX GENMASK(30, 16) #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,8 @@ #define PCIE_CLK_GEN1_EN (BIT(27) | BIT(25)) #define MEMORY_BASE 0x0 +#define PERST_DELAY_US 1000 + /** * struct mt7621_pcie_port - PCIe port information * @base: I/O mapped register base @@ -119,6 +122,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 +136,7 @@ struct mt7621_pcie { resource_size_t io; } offset; struct list_head ports; + struct gpio_desc *perst; struct reset_control *rst; }; @@ -198,6 +203,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 +361,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 PTR_ERR(pcie->perst); + } + err = of_address_to_resource(node, 0, ®s); if (err) { dev_err(dev, "missing \"reg\" property\n"); @@ -384,7 +407,6 @@ 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; /* @@ -393,47 +415,32 @@ static int mt7621_pcie_init_port(struct mt7621_pcie_port *port) */ 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; + mt7621_perst_gpio_pcie_assert(pcie); + list_for_each_entry_safe(port, tmp, &pcie->ports, list) { u32 slot = port->slot; @@ -441,7 +448,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", (unsigned int)val, slot); + } } reset_control_assert(pcie->rst); @@ -451,32 +461,25 @@ 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) { + 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); + phy_power_off(port->phy); + port->enabled = false; + } + } } -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); @@ -492,8 +495,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 +507,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++; } @@ -665,6 +662,9 @@ static int mt7621_pci_probe(struct platform_device *pdev) return 0; } + pcie_write(pcie, 0xffffffff, RALINK_PCI_MEMBASE); + pcie_write(pcie, RALINK_PCI_IO_MAP_BASE, RALINK_PCI_IOBASE); + mt7621_pcie_enable_ports(pcie); err = mt7621_pci_parse_request_of_pci_ranges(pcie); -- 2.7.4
_______________________________________________ devel mailing list devel@xxxxxxxxxxxxxxxxxxxxxx http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel