On Mon, Oct 21, 2019 at 02:39:19PM +0800, Dilip Kota wrote:It is not device specific.
Add support to PCIe RC controller on Intel Gateway SoCs.Link Control is only 16 bits wide, so "PCI_EXP_LNKSTA_SLC << 16"
PCIe controller is based of Synopsys DesignWare pci core.
Intel PCIe driver requires Upconfig support, fast training
sequence configuration and link speed change. So adding the
respective helper functions in the pcie DesignWare framework.
It also programs hardware autonomous speed during speed
configuration so defining it in pci_regs.h.
+static void intel_pcie_link_setup(struct intel_pcie_port *lpp)
+{
+ u32 val;
+
+ val = pcie_rc_cfg_rd(lpp, PCIE_CAP_OFST + PCI_EXP_LNKCAP);
+ lpp->max_speed = FIELD_GET(PCI_EXP_LNKCAP_SLS, val);
+ lpp->max_width = FIELD_GET(PCI_EXP_LNKCAP_MLW, val);
+
+ val = pcie_rc_cfg_rd(lpp, PCIE_CAP_OFST + PCI_EXP_LNKCTL);
+
+ val &= ~(PCI_EXP_LNKCTL_LD | PCI_EXP_LNKCTL_ASPMC);
+ val |= (PCI_EXP_LNKSTA_SLC << 16) | PCI_EXP_LNKCTL_CCC |
+ PCI_EXP_LNKCTL_RCB;
wouldn't make sense. But I guess you're writing a device-specific
register that is not actually the Link Control as documented in PCIe
r5.0, sec 7.5.3.7, even though the bits are similar?
You are correct, PCI_EXP_LNKCTL_RCB is RO. I will remove it.
Likewise, PCI_EXP_LNKCTL_RCB is RO for Root Ports, but maybe you're
telling the device what it should advertise in its Link Control?
PCIe RC and endpoint device are having the common clock so set the CCC=1.
PCI_EXP_LNKCTL_CCC is RW. But doesn't it depend on the components on
both ends of the link? Do you know what device is at the other end?
I would have assumed that you'd have to start with CCC==0, which
should be most conservative, then set CCC=1 only if you know both ends
have a common clock.
dra7xx_pcie_establish_link() and ks_pcie_set_link_speed() are doing speed configuration for GEN1 and GEN1 &2 respectively.
+ pcie_rc_cfg_wr(lpp, val, PCIE_CAP_OFST + PCI_EXP_LNKCTL);There are other users of of_pci_get_max_link_speed() that look sort of
+}
+
+static void intel_pcie_max_speed_setup(struct intel_pcie_port *lpp)
+{
+ u32 reg, val;
+
+ reg = pcie_rc_cfg_rd(lpp, PCIE_CAP_OFST + PCI_EXP_LNKCTL2);
+ switch (lpp->link_gen) {
+ case PCIE_LINK_SPEED_GEN1:
+ reg &= ~PCI_EXP_LNKCTL2_TLS;
+ reg |= PCI_EXP_LNKCTL2_HASD|
+ PCI_EXP_LNKCTL2_TLS_2_5GT;
+ break;
+ case PCIE_LINK_SPEED_GEN2:
+ reg &= ~PCI_EXP_LNKCTL2_TLS;
+ reg |= PCI_EXP_LNKCTL2_HASD|
+ PCI_EXP_LNKCTL2_TLS_5_0GT;
+ break;
+ case PCIE_LINK_SPEED_GEN3:
+ reg &= ~PCI_EXP_LNKCTL2_TLS;
+ reg |= PCI_EXP_LNKCTL2_HASD|
+ PCI_EXP_LNKCTL2_TLS_8_0GT;
+ break;
+ case PCIE_LINK_SPEED_GEN4:
+ reg &= ~PCI_EXP_LNKCTL2_TLS;
+ reg |= PCI_EXP_LNKCTL2_HASD|
+ PCI_EXP_LNKCTL2_TLS_16_0GT;
+ break;
+ default:
+ /* Use hardware capability */
+ val = pcie_rc_cfg_rd(lpp, PCIE_CAP_OFST + PCI_EXP_LNKCAP);
+ val = FIELD_GET(PCI_EXP_LNKCAP_SLS, val);
+ reg &= ~PCI_EXP_LNKCTL2_HASD;
+ reg |= val;
+ break;
+ }
+
+ pcie_rc_cfg_wr(lpp, reg, PCIE_CAP_OFST + PCI_EXP_LNKCTL2);
+ dw_pcie_link_set_n_fts(&lpp->pci, lpp->n_fts);
similar to this (dra7xx_pcie_establish_link(),
ks_pcie_set_link_speed(), tegra_pcie_prepare_host()). Do these *need*
to be different, or is there something that could be factored out?
i will remove it.
+}Remove extra blank lines here.
+
+
+
Yes, you are correct. Telling not to program an outbound ATU for IO.
+static void intel_pcie_port_logic_setup(struct intel_pcie_port *lpp)This comment doesn't describe the code. Is there supposed to be some
...
+ /* Intel PCIe doesn't configure IO region, so configure
+ * viewport to not to access IO region during register
+ * read write operations.
+ */
code here that configures the viewport? Where do we tell the viewport
not to access IO?
I guess maybe this means something like "tell
dw_pcie_access_other_conf() not to program an outbound ATU for I/O"?
I don't know that structure well enough to write this in a way that
makes sense, but this code doesn't look like it's configuring any
viewports.
Please use usual multi-line comment style, i.e.,Sure, i will correct it.
/*
* Intel PCIe ...
*/
+ pci->num_viewport = data->num_viewport;
+ dev_info(dev, "Intel PCIe Root Complex Port %d init done\n", lpp->id);
+
+ return ret;
+}