Re: 回复:[PATCH 5/6] MIPS: Loongson: Add PCI support for 7A1000

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 03/09/2020 04:47 PM, Jiaxun Yang wrote:

  ---- 在 星期一, 2020-03-09 16:23:25 Tiezhu Yang <yangtiezhu@xxxxxxxxxxx> 撰写 ----
  > Add PCI support for 7A1000 to detect PCI device.
  >
  > Co-developed-by: Jianmin Lv <lvjianmin@xxxxxxxxxxx>
  > Signed-off-by: Jianmin Lv <lvjianmin@xxxxxxxxxxx>
  > Signed-off-by: Tiezhu Yang <yangtiezhu@xxxxxxxxxxx>
  > ---
  >  arch/mips/include/asm/mach-loongson64/pci.h |   1 +
  >  arch/mips/loongson64/pci.c                  |  12 ++-
  >  arch/mips/pci/Makefile                      |   2 +-
  >  arch/mips/pci/ops-loongson3-ls7a.c          | 132 ++++++++++++++++++++++++++++
  >  4 files changed, 143 insertions(+), 4 deletions(-)
  >  create mode 100644 arch/mips/pci/ops-loongson3-ls7a.c
  >
  > diff --git a/arch/mips/include/asm/mach-loongson64/pci.h b/arch/mips/include/asm/mach-loongson64/pci.h
  > index 8b59d64..42c9744 100644
  > --- a/arch/mips/include/asm/mach-loongson64/pci.h
  > +++ b/arch/mips/include/asm/mach-loongson64/pci.h
  > @@ -8,6 +8,7 @@
  >  #define __ASM_MACH_LOONGSON64_PCI_H_
  >
  >  extern struct pci_ops loongson_pci_ops;
  > +extern struct pci_ops loongson_ls7a_pci_ops;
  >
  >  /* this is an offset from mips_io_port_base */
  >  #define LOONGSON_PCI_IO_START    0x00004000UL
  > diff --git a/arch/mips/loongson64/pci.c b/arch/mips/loongson64/pci.c
  > index e84ae20..b79368f 100644
  > --- a/arch/mips/loongson64/pci.c
  > +++ b/arch/mips/loongson64/pci.c
  > @@ -23,8 +23,8 @@ static struct resource loongson_pci_io_resource = {
  >      .flags    = IORESOURCE_IO,
  >  };
  >
  > -static struct pci_controller  loongson_pci_controller = {
  > -    .pci_ops    = &loongson_pci_ops,
  > +static struct pci_controller loongson_pci_controller = {
  > +    .pci_ops    = NULL,
  >      .io_resource    = &loongson_pci_io_resource,
  >      .mem_resource    = &loongson_pci_mem_resource,
  >      .mem_offset    = 0x00000000UL,
  > @@ -36,6 +36,11 @@ extern int sbx00_acpi_init(void);
  >
  >  static int __init pcibios_init(void)
  >  {
  > +    if (strstr(eboard->name, "780E"))
  > +        loongson_pci_controller.pci_ops = &loongson_pci_ops;
  > +
  > +    if (strstr(eboard->name, "7A1000"))
  > +        loongson_pci_controller.pci_ops = &loongson_ls7a_pci_ops;

Please do not check PCH type everywhere.

Yes, you are right.


  >
  >      loongson_pci_controller.io_map_base = mips_io_port_base;
  >      loongson_pci_mem_resource.start = loongson_sysconf.pci_mem_start_addr;
  > @@ -43,7 +48,8 @@ static int __init pcibios_init(void)
  >
  >      register_pci_controller(&loongson_pci_controller);
  >
  > -    sbx00_acpi_init();
  > +    if (strstr(eboard->name, "780E"))
  > +        sbx00_acpi_init();
  >
  >      return 0;
  >  }
  > diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile
  > index 342ce10..7256bb1 100644
  > --- a/arch/mips/pci/Makefile
  > +++ b/arch/mips/pci/Makefile
  > @@ -35,7 +35,7 @@ obj-$(CONFIG_LASAT)        += pci-lasat.o
  >  obj-$(CONFIG_MIPS_COBALT)    += fixup-cobalt.o
  >  obj-$(CONFIG_LEMOTE_FULOONG2E)    += fixup-fuloong2e.o ops-loongson2.o
  >  obj-$(CONFIG_LEMOTE_MACH2F)    += fixup-lemote2f.o ops-loongson2.o
  > -obj-$(CONFIG_MACH_LOONGSON64)    += fixup-loongson3.o ops-loongson3.o
  > +obj-$(CONFIG_MACH_LOONGSON64)    += fixup-loongson3.o ops-loongson3.o ops-loongson3-ls7a.o
  >  obj-$(CONFIG_MIPS_MALTA)    += fixup-malta.o pci-malta.o
  >  obj-$(CONFIG_PMC_MSP7120_GW)    += fixup-pmcmsp.o ops-pmcmsp.o
  >  obj-$(CONFIG_PMC_MSP7120_EVAL)    += fixup-pmcmsp.o ops-pmcmsp.o
  > diff --git a/arch/mips/pci/ops-loongson3-ls7a.c b/arch/mips/pci/ops-loongson3-ls7a.c
  > new file mode 100644
  > index 0000000..4ed6c40
  > --- /dev/null
  > +++ b/arch/mips/pci/ops-loongson3-ls7a.c
  > @@ -0,0 +1,132 @@
  > +// SPDX-License-Identifier: GPL-2.0
  > +/*
  > + * Copyright (C) 2020 Loongson Technology Corporation Limited
  > + *
  > + * Author: Jianmin Lv <lvjianmin@xxxxxxxxxxx>
  > + * Author: Tiezhu Yang <yangtiezhu@xxxxxxxxxxx>
  > + */
  > +
  > +#include <linux/types.h>
  > +#include <linux/pci.h>
  > +#include <linux/kernel.h>
  > +
  > +#include <asm/mips-boards/bonito64.h>

Why we need this?

I will check it, if it is useless, I will remove it.


  > +
  > +#include <loongson.h>
  > +
  > +#define PCI_ACCESS_READ 0
  > +#define PCI_ACCESS_WRITE 1
  > +
  > +#define HT1LO_PCICFG_BASE 0x1a000000
  > +#define HT1LO_PCICFG_BASE_TP1 0x1b000000
  > +
  > +#define HT1LO_PCICFG_BASE_EXT 0xefe00000000
  > +#define HT1LO_PCICFG_BASE_TP1_EXT 0xefe10000000
  > +
  > +static int ls7a_pci_config_access(unsigned char access_type,
  > +        struct pci_bus *bus, unsigned int devfn,
  > +        int where, u32 *data)
  > +{
  > +    u_int64_t addr;
  > +    void *addrp;
  > +    unsigned char busnum = bus->number;
  > +    int device = PCI_SLOT(devfn);
  > +    int function = PCI_FUNC(devfn);
  > +    int reg = where & ~3;
  > +
  > +    if (where >= PCI_CFG_SPACE_EXP_SIZE)
  > +        return PCIBIOS_DEVICE_NOT_FOUND;
  > +
  > +    if (busnum == 0 && device > 23)
  > +        return PCIBIOS_DEVICE_NOT_FOUND;
  > +
  > +    if (where < PCI_CFG_SPACE_SIZE) { /* standard config */
  > +        addr = (busnum << 16) | (device << 11) | (function << 8) | reg;
  > +        if (busnum == 0) {
  > +            addr = HT1LO_PCICFG_BASE | addr;
  > +            addrp = (void *)TO_UNCAC(addr);
  > +        } else {
  > +            addr = HT1LO_PCICFG_BASE_TP1 | addr;
  > +            addrp = (void *)TO_UNCAC(addr);
  > +        }
  > +    } else { /* extended config */
  > +        reg = (reg & 0xff) | ((reg & 0xf00) << 16);
  > +        addr = (busnum << 16) | (device << 11) | (function << 8) | reg;
  > +        if (busnum == 0) {
  > +            addr = HT1LO_PCICFG_BASE_EXT | addr;
  > +            addrp = (void *)TO_UNCAC(addr);
  > +        } else {
  > +            addr = HT1LO_PCICFG_BASE_TP1_EXT | addr;
  > +            addrp = (void *)TO_UNCAC(addr);
  > +        }
  > +    }
  > +
  > +    if (access_type == PCI_ACCESS_WRITE)
  > +        *(unsigned int *)addrp = cpu_to_le32(*data);
  > +    else {
  > +        *data = le32_to_cpu(*(unsigned int *)addrp);
  > +        if (busnum == 0 &&
  > +            reg == PCI_CLASS_REVISION && *data == 0x06000001)
  > +            *data = (PCI_CLASS_BRIDGE_PCI << 16) | (*data & 0xffff);

It should be a part of quirk. Not a part of accessing.

  > +
  > +        if (*data == 0xffffffff) {
  > +            *data = -1;
  > +            return PCIBIOS_DEVICE_NOT_FOUND;
  > +        }
  > +    }
  > +
  > +    return PCIBIOS_SUCCESSFUL;
  > +}
  > +
  > +static int ls7a_pci_pcibios_read(struct pci_bus *bus, unsigned int devfn,
  > +                 int where, int size, u32 *val)
  > +{
  > +    int ret;
  > +    u32 data = 0;
  > +
  > +    ret = ls7a_pci_config_access(PCI_ACCESS_READ, bus, devfn, where, &data);
  > +    if (ret != PCIBIOS_SUCCESSFUL)
  > +        return ret;
  > +
  > +    if (size == 1)
  > +        *val = (data >> ((where & 3) << 3)) & 0xff;
  > +    else if (size == 2)
  > +        *val = (data >> ((where & 3) << 3)) & 0xffff;
  > +    else
  > +        *val = data;

That  loggic seems identical with RS780E one, can we reuse them?

OK, I will do it.

Thanks,

Tiezhu Yang


+
  > +    return PCIBIOS_SUCCESSFUL;
  > +}
  > +
  > +static int ls7a_pci_pcibios_write(struct pci_bus *bus, unsigned int devfn,
  > +                  int where, int size, u32 val)
  > +{
  > +    int ret;
  > +    u32 data = 0;
  > +
  > +    if (size == 4)
  > +        data = val;
  > +    else {
  > +        ret = ls7a_pci_config_access(PCI_ACCESS_READ, bus,
  > +                        devfn, where, &data);
  > +        if (ret != PCIBIOS_SUCCESSFUL)
  > +            return ret;
  > +
  > +        if (size == 1)
  > +            data = (data & ~(0xff << ((where & 3) << 3))) |
  > +                (val << ((where & 3) << 3));
  > +        else if (size == 2)
  > +            data = (data & ~(0xffff << ((where & 3) << 3))) |
  > +                (val << ((where & 3) << 3));
  > +    }
  > +
  > +    ret = ls7a_pci_config_access(PCI_ACCESS_WRITE, bus,
  > +                    devfn, where, &data);
  > +
  > +    return ret;
  > +}
  > +
  > +struct pci_ops loongson_ls7a_pci_ops = {
  > +    .read = ls7a_pci_pcibios_read,
  > +    .write = ls7a_pci_pcibios_write
  > +};
  > --
  > 2.1.0
  >
  >




[Index of Archives]     [DMA Engine]     [Linux Coverity]     [Linux USB]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Greybus]

  Powered by Linux