On 26/03/05 12:09AM, Saif Abrar wrote: > Get the current link-status from PCIE macro. > Extract link-speed and link-width from the link-status > and set in the DLP training control (PCIE_DLP_TCR) register. > > Signed-off-by: Saif Abrar <[email protected]> > Reviewed-by: Cédric Le Goater <[email protected]> > Reviewed-by: Michael S. Tsirkin <[email protected]> > --- > v4: Variables declaration moved to the top of the method pnv_phb4_reg_read(). > v3: Updates for coding guidelines. > > hw/pci-host/pnv_phb4.c | 22 ++++++++++++++++++++-- > 1 file changed, 20 insertions(+), 2 deletions(-) > > diff --git a/hw/pci-host/pnv_phb4.c b/hw/pci-host/pnv_phb4.c > index c35f632e64..a6fa578e85 100644 > --- a/hw/pci-host/pnv_phb4.c > +++ b/hw/pci-host/pnv_phb4.c > @@ -900,6 +900,7 @@ static uint64_t pnv_phb4_reg_read(void *opaque, hwaddr > off, unsigned size) > PCIDevice *pdev = pci_find_device(pci->bus, 0, 0); > uint32_t exp_base = get_exp_offset(pdev); > uint64_t val; > + uint32_t v, lnkstatus; > > if ((off & 0xfffc) == PHB_CONFIG_DATA) { > return pnv_phb4_config_read(phb, off & 0x3, size); > @@ -961,10 +962,27 @@ static uint64_t pnv_phb4_reg_read(void *opaque, hwaddr > off, unsigned size) > val |= PHB_PCIE_SCR_PLW_X16; /* RO bit */ > break; > > - /* Link training always appears trained */ > case PHB_PCIE_DLP_TRAIN_CTL: > - /* TODO: Do something sensible with speed ? */ > + /* Get the current link-status from PCIE */ > + lnkstatus = bswap32(pnv_phb4_rc_config_read(phb, > + exp_base + PCI_EXP_LNKSTA, 4));
nit: s/bswap32/be32_to_cpu/ ? > + > + /* Extract link-speed from the link-status */ > + v = lnkstatus & PCI_EXP_LNKSTA_CLS; > + > + /* Link training always appears trained */ > val |= PHB_PCIE_DLP_INBAND_PRESENCE | PHB_PCIE_DLP_TL_LINKACT; > + > + /* Set the current link-speed at the LINK_SPEED position */ > + val = SETFIELD(PHB_PCIE_DLP_LINK_SPEED, val, v); > + > + /* > + * Extract link-width from the link-status, > + * after shifting the required bitfields. > + */ > + v = (lnkstatus & PCI_EXP_LNKSTA_NLW) >> PCI_EXP_LNKSTA_NLW_SHIFT; > + /* Set the current link-width at the LINK_WIDTH position */ > + val = SETFIELD(PHB_PCIE_DLP_LINK_WIDTH, val, v); v is little-endian, while val is supposed to be big-endian, is it correct ? if so, should v be converted to big-endian before SETFIELDs ? > return val; > > /* - Aditya G
