* [PATCH v6 12/22] sh: Add PCI host bridge driver for SH7751 [not found] ` <1467564402-2649-1-git-send-email-ysato-Rn4VEauK+AKRv+LV9MX5uooqe+aC9MnS@public.gmane.org> @ 2016-07-03 16:46 ` Yoshinori Sato 2016-07-05 15:53 ` Rob Herring [not found] ` <1467564402-2649-13-git-send-email-ysato-Rn4VEauK+AKRv+LV9MX5uooqe+aC9MnS@public.gmane.org> 2016-07-03 16:46 ` [PATCH v5 13/22] sh: irqchip: SH7751 IRQCHIP Driver Yoshinori Sato 1 sibling, 2 replies; 13+ messages in thread From: Yoshinori Sato @ 2016-07-03 16:46 UTC (permalink / raw) To: devicetree-u79uwXL29TY76Z2rM5mHXA, linux-pci-u79uwXL29TY76Z2rM5mHXA, linux-sh-u79uwXL29TY76Z2rM5mHXA, linux-kernel-u79uwXL29TY76Z2rM5mHXA Cc: Yoshinori Sato This is an alternative SH7751 PCI driver. Existing driver (arch/sh/drivers/pci/pci-sh7751) uses SH specific interface. But this driver uses common PCI interface. It is more modern and generic. Signed-off-by: Yoshinori Sato <ysato-Rn4VEauK+AKRv+LV9MX5uooqe+aC9MnS@public.gmane.org> --- .../devicetree/bindings/pci/sh7751-pci.txt | 37 +++ arch/sh/boards/Kconfig | 1 + arch/sh/drivers/Makefile | 2 + drivers/pci/host/Kconfig | 7 + drivers/pci/host/Makefile | 1 + drivers/pci/host/pci-sh7751.c | 327 +++++++++++++++++++++ 6 files changed, 375 insertions(+) create mode 100644 Documentation/devicetree/bindings/pci/sh7751-pci.txt create mode 100644 drivers/pci/host/pci-sh7751.c diff --git a/Documentation/devicetree/bindings/pci/sh7751-pci.txt b/Documentation/devicetree/bindings/pci/sh7751-pci.txt new file mode 100644 index 0000000..2df9af6 --- /dev/null +++ b/Documentation/devicetree/bindings/pci/sh7751-pci.txt @@ -0,0 +1,37 @@ +* Renesas SH7751 PCI host interfaces + +Required properties: + - compatible: "renesas,sh7751-pci" is required. + And board specific compatible if fixup required. + - reg: contain two entries. + first entry: PCI controller register base address and length. + second entry: BUS controller register base address and length. + - #address-cells: set to <2> + - #size-cells: set to <1> + - bus-range: PCI bus numbers covered + - device_type: set to "pci" + - ranges: ranges for the PCI memory and I/O regions. + - interrupt-map-mask and interrupt-map: standard PCI properties + to define the mapping of the PCI interface to interrupt + numbers. + +Example: + pci: pci-controller@fe200000 { + compatible = "renesas,sh7751-pci", "iodata,landisk"; + device_type = "pci"; + bus-range = <0 0>; + #address-cells = <2>; + #size-cells = <1>; + ranges = <0x02000000 0x00000000 0xfd000000 0xfd000000 0x00000000 0x01000000>, + <0x01000000 0x00000000 0xfe240000 0x00000000 0x00000000 0x00040000>; + reg = <0xfe200000 0x0400>, + <0xff800000 0x0030>; + #interrupt-cells = <1>; + interrupt-map-mask = <0x1800 0 7>; + interrupt-map = <0x0000 0 1 &cpldintc 0 0>, + <0x0800 0 1 &cpldintc 1 0>, + <0x1000 0 1 &cpldintc 2 0>, + <0x1800 0 1 &cpldintc 3 0>, + <0x1800 0 2 &cpldintc 0 0>; + }; +}; diff --git a/arch/sh/boards/Kconfig b/arch/sh/boards/Kconfig index b6ff9df..cfde921 100644 --- a/arch/sh/boards/Kconfig +++ b/arch/sh/boards/Kconfig @@ -14,6 +14,7 @@ config SH_DEVICE_TREE select GENERIC_CALIBRATE_DELAY select GENERIC_IOMAP select COMMON_CLK + select SYS_SUPPORTS_PCI help Select Board Described by Device Tree to build a kernel that does not hard-code any board-specific knowledge but instead uses diff --git a/arch/sh/drivers/Makefile b/arch/sh/drivers/Makefile index e13f06b..382e86f 100644 --- a/arch/sh/drivers/Makefile +++ b/arch/sh/drivers/Makefile @@ -4,7 +4,9 @@ obj-y += dma/ +ifndef CONFIG_SH_DEVICE_TREE obj-$(CONFIG_PCI) += pci/ +endif obj-$(CONFIG_SUPERHYWAY) += superhyway/ obj-$(CONFIG_PUSH_SWITCH) += push-switch.o obj-$(CONFIG_HEARTBEAT) += heartbeat.o diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig index 5d2374e..df60505 100644 --- a/drivers/pci/host/Kconfig +++ b/drivers/pci/host/Kconfig @@ -245,4 +245,11 @@ config PCIE_ARMADA_8K Designware hardware and therefore the driver re-uses the Designware core functions to implement the driver. +config PCI_SH7751 + bool "Renesas SH7751 On-Chip PCI controller" + depends on OF && SUPERH + select PCI_HOST_COMMON + help + Say Y here if you want PCI support on SH7751. + endmenu diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile index 9c8698e..4681e49 100644 --- a/drivers/pci/host/Makefile +++ b/drivers/pci/host/Makefile @@ -29,3 +29,4 @@ obj-$(CONFIG_PCIE_QCOM) += pcie-qcom.o obj-$(CONFIG_PCI_HOST_THUNDER_ECAM) += pci-thunder-ecam.o obj-$(CONFIG_PCI_HOST_THUNDER_PEM) += pci-thunder-pem.o obj-$(CONFIG_PCIE_ARMADA_8K) += pcie-armada8k.o +obj-$(CONFIG_PCI_SH7751) += pci-sh7751.o diff --git a/drivers/pci/host/pci-sh7751.c b/drivers/pci/host/pci-sh7751.c new file mode 100644 index 0000000..21601f1 --- /dev/null +++ b/drivers/pci/host/pci-sh7751.c @@ -0,0 +1,327 @@ +/* + * SH7751 PCI driver + * Copyright (C) 2016 Yoshinori Sato + */ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/of_address.h> +#include <linux/of_pci.h> +#include <linux/of_platform.h> +#include <linux/pci.h> +#include <linux/platform_device.h> +#include <linux/io.h> +#include "../ecam.h" + +#define SH7751_PCICONF1 0x4 /* PCI Config Reg 1 */ +#define SH7751_PCICONF4 0x10 /* PCI Config Reg 4 */ +#define SH7751_PCICONF5 0x14 /* PCI Config Reg 5 */ +#define SH7751_PCICONF6 0x18 /* PCI Config Reg 6 */ +#define SH4_PCICR 0x100 /* PCI Control Register */ + #define SH4_PCICR_PREFIX 0xA5000000 /* CR prefix for write */ + #define SH4_PCICR_FTO BIT(10) /* TRDY/IRDY Enable */ + #define SH4_PCICR_TRSB BIT(9) /* Target Read Single */ + #define SH4_PCICR_BSWP BIT(8) /* Target Byte Swap */ + #define SH4_PCICR_PLUP BIT(7) /* Enable PCI Pullup */ + #define SH4_PCICR_ARBM BIT(6) /* PCI Arbitration Mode */ +#define SH4_PCICR_MD (BIT(4) | BIT(5)) /* MD9 and MD10 status */ + #define SH4_PCICR_SERR BIT(3) /* SERR output assert */ + #define SH4_PCICR_INTA BIT(2) /* INTA output assert */ + #define SH4_PCICR_PRST BIT(1) /* PCI Reset Assert */ + #define SH4_PCICR_CFIN BIT(0) /* Central Fun. Init Done */ +#define SH4_PCILSR0 0x104 /* PCI Local Space Register0 */ +#define SH4_PCILSR1 0x108 /* PCI Local Space Register1 */ +#define SH4_PCILAR0 0x10C /* PCI Local Addr Register1 */ +#define SH4_PCILAR1 0x110 /* PCI Local Addr Register1 */ +#define SH4_PCIINTM 0x118 /* PCI Interrupt Mask */ + #define SH4_PCIINTM_TTADIM BIT(14) /* Target-target abort interrupt */ + #define SH4_PCIINTM_TMTOIM BIT(9) /* Target retry timeout */ + #define SH4_PCIINTM_MDEIM BIT(8) /* Master function disable error */ + #define SH4_PCIINTM_APEDIM BIT(7) /* Address parity error detection */ + #define SH4_PCIINTM_SDIM BIT(6) /* SERR detection */ + #define SH4_PCIINTM_DPEITWM BIT(5) /* Data parity error for target write */ + #define SH4_PCIINTM_PEDITRM BIT(4) /* PERR detection for target read */ + #define SH4_PCIINTM_TADIMM BIT(3) /* Target abort for master */ + #define SH4_PCIINTM_MADIMM BIT(2) /* Master abort for master */ + #define SH4_PCIINTM_MWPDIM BIT(1) /* Master write data parity error */ + #define SH4_PCIINTM_MRDPEIM BIT(0) /* Master read data parity error */ +#define SH4_PCIAINTM 0x134 /* Arbiter Int. Mask Register */ +#define SH4_PCIPAR 0x1C0 /* PIO Address Register */ + #define SH4_PCIPAR_CFGEN 0x80000000 /* Configuration Enable */ + #define SH4_PCIPAR_BUSNO 0x00FF0000 /* Config. Bus Number */ + #define SH4_PCIPAR_DEVNO 0x0000FF00 /* Config. Device Number */ + #define SH4_PCIPAR_REGAD 0x000000FC /* Register Address Number */ +#define SH4_PCIPINT 0x1CC /* Power Mgmnt Int. Register */ + #define SH4_PCIPINT_D3 0x00000002 /* D3 Pwr Mgmt. Interrupt */ + #define SH4_PCIPINT_D0 0x00000001 /* D0 Pwr Mgmt. Interrupt */ +#define SH4_PCICLKR 0x1D4 /* Clock Ctrl. Register */ +/* For definitions of BCR, MCR see ... */ +#define SH4_PCIBCR1 0x1E0 /* Memory BCR1 Register */ + #define SH4_PCIMBR0 SH4_PCIBCR1 +#define SH4_PCIBCR2 0x1E4 /* Memory BCR2 Register */ + #define SH4_PCIMBMR0 SH4_PCIBCR2 +#define SH4_PCIWCR1 0x1E8 /* Wait Control 1 Register */ +#define SH4_PCIWCR2 0x1EC /* Wait Control 2 Register */ +#define SH4_PCIWCR3 0x1F0 /* Wait Control 3 Register */ + #define SH4_PCIMBR2 SH4_PCIWCR3 +#define SH4_PCIMCR 0x1F4 /* Memory Control Register */ +#define SH4_PCIPDR 0x220 /* Port IO Data Register */ + +/* Platform Specific Values */ +#define SH7751_VENDOR_ID 0x1054 +#define SH7751_DEVICE_ID 0x3505 +#define SH7751R_DEVICE_ID 0x350e + +/* Memory Control Registers */ +#define SH7751_BCR1 0x0000 /* Memory BCR1 Register */ +#define SH7751_BCR2 0x0004 /* Memory BCR2 Register */ +#define SH7751_BCR3 0x0050 /* Memory BCR3 Register */ +#define SH7751_WCR1 0x0008 /* Wait Control 1 Register */ +#define SH7751_WCR2 0x000C /* Wait Control 2 Register */ +#define SH7751_WCR3 0x0010 /* Wait Control 3 Register */ +#define SH7751_MCR 0x0014 /* Memory Control Register */ + +#define pcic_writel(val, reg) iowrite32(val, pci_reg_base + (reg)) +#define pcic_readl(reg) ioread32(pci_reg_base + (reg)) + +/* + * PCIC fixups + */ + +#define PCIMCR_MRSET 0x40000000 +#define PCIMCR_RFSH 0x00000004 + +static void __init landisk_fixup(void __iomem *pci_reg_base, void __iomem *bcr) +{ + unsigned long bcr1, mcr; + + bcr1 = ioread32(bcr + SH7751_BCR1); + bcr1 |= 0x00080000; /* Enable Bit 19 BREQEN, set PCIC to slave */ + pcic_writel(bcr1, SH4_PCIBCR1); + + mcr = ioread32(bcr + SH7751_MCR); + mcr &= (~PCIMCR_MRSET) & (~PCIMCR_RFSH); + pcic_writel(mcr, SH4_PCIMCR); + + pcic_writel(0x0c000000, PCI_BASE_ADDRESS_1); + pcic_writel(0xd0000000, PCI_BASE_ADDRESS_2); + pcic_writel(0x0c000000, SH4_PCILAR0); + pcic_writel(0x00000000, SH4_PCILAR1); +} + +static void __init r2dplus_fixup(void __iomem *pci_reg_base, void __iomem *bcr) +{ + unsigned long bcr1, mcr; + + bcr1 = ioread32(bcr + SH7751_BCR1); + bcr1 |= 0x40080000; /* Enable Bit 19 BREQEN, set PCIC to slave */ + pcic_writel(bcr1, SH4_PCIBCR1); + + /* Enable all interrupts, so we known what to fix */ + pcic_writel(0x0000c3ff, SH4_PCIINTM); + pcic_writel(0x0000380f, SH4_PCIAINTM); + + pcic_writel(0xfb900047, SH7751_PCICONF1); + pcic_writel(0xab000001, SH7751_PCICONF4); + + mcr = ioread32(bcr + SH7751_MCR); + mcr &= (~PCIMCR_MRSET) & (~PCIMCR_RFSH); + pcic_writel(mcr, SH4_PCIMCR); + + pcic_writel(0x0c000000, SH7751_PCICONF5); + pcic_writel(0xd0000000, SH7751_PCICONF6); + pcic_writel(0x0c000000, SH4_PCILAR0); + pcic_writel(0x00000000, SH4_PCILAR1); +} + +/* + * Direct access to PCI hardware... + */ +#define CONFIG_CMD(bus, devfn, where) \ + (0x80000000 | (bus->number << 16) | (devfn << 8) | (where & ~3)) + +/* + * Functions for accessing PCI configuration space with type 1 accesses + */ +static void __iomem *sh7751_map_bus(struct pci_bus *bus, + unsigned int devfn, int where) +{ + struct pci_config_window *cfg = bus->sysdata; + void __iomem *pci_reg_base = (void __iomem *)cfg->res.start; + + pcic_writel(CONFIG_CMD(bus, devfn, where), SH4_PCIPAR); + return pci_reg_base + SH4_PCIPDR; +} + +static const struct of_device_id fixup_of_match[] = { + { .compatible = "iodata,landisk-pci", .data = landisk_fixup, }, + { .compatible = "renesas,r2dplus-pci", .data = r2dplus_fixup, }, + { }, +}; + +static const struct of_device_id sh7751_pci_of_match[] = { + { .compatible = "renesas,sh7751-pci", }, + { }, +}; +MODULE_DEVICE_TABLE(of, sh7751_pci_of_match); + +static resource_size_t sh7751_align_resource(struct pci_dev *dev, + const struct resource *res, + resource_size_t start, + resource_size_t size, + resource_size_t align) +{ + if (res->flags & IORESOURCE_IO) { + if (start < PCIBIOS_MIN_IO + 0x1000) + start = PCIBIOS_MIN_IO + 0x1000; + + /* + * Put everything into 0x00-0xff region modulo 0x400. + */ + if (start & 0x300) + start = (start + 0x3ff) & ~0x3ff; + } + + return start; +} + +static void __init set_pci_bcr(void __iomem *pci_reg_base, + void __iomem *bcr, + unsigned int area) +{ + unsigned long word; + + word = ioread32(bcr + SH7751_BCR1); + /* check BCR for SDRAM in area */ + if (((word >> area) & 1) == 0) { + pr_info("PCI: Area %d is not configured for SDRAM. BCR1=0x%lx\n", + area, word); + return; + } + pcic_writel(word, SH4_PCIBCR1); + + word = ioread16(bcr + SH7751_BCR2); + /* check BCR2 for 32bit SDRAM interface*/ + if (((word >> (area << 1)) & 0x3) != 0x3) { + pr_info("PCI: Area %d is not 32 bit SDRAM. BCR2=0x%lx\n", + area, word); + return; + } + pcic_writel(word, SH4_PCIBCR2); +} + +static __init int sh7751_cfg_init(struct device *dev, + struct pci_config_window *cfg) +{ + cfg->priv = sh7751_align_resource; + return 0; +} + +static struct pci_ecam_ops ecm_ops __initdata = { + .init = sh7751_cfg_init, + .pci_ops = { + .read = pci_generic_config_read32, + .write = pci_generic_config_write32, + .map_bus = sh7751_map_bus, + } +}; + +static __init int sh7751_pci_probe(struct platform_device *pdev) +{ + struct resource *res; + u32 id; + u32 reg, word; + void __iomem *pci_reg_base; + void __iomem *bcr; + const struct of_device_id *match; + void (*fixup_fn)(void __iomem *pci_reg_base, void __iomem *bcr); + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + pci_reg_base = ioremap(res->start, resource_size(res)); + if (IS_ERR(pci_reg_base)) + return PTR_ERR(pci_reg_base); + + res = platform_get_resource(pdev, IORESOURCE_MEM, 1); + bcr = ioremap(res->start, resource_size(res)); + if (IS_ERR(bcr)) + return PTR_ERR(bcr); + + /* check for SH7751/SH7751R hardware */ + id = pcic_readl(PCI_VENDOR_ID); + if (id != ((SH7751_DEVICE_ID << 16) | SH7751_VENDOR_ID) && + id != ((SH7751R_DEVICE_ID << 16) | SH7751_VENDOR_ID)) { + pr_warn("PCI: This is not an SH7751(R)\n"); + return -ENODEV; + } + dev_info(&pdev->dev, "PCI core found at %pR\n", + pci_reg_base); + + /* Set the BCRs to enable PCI access */ + reg = ioread32(bcr); + reg |= 0x80000; + iowrite32(reg, bcr); + + /* Turn the clocks back on (not done in reset)*/ + pcic_writel(0, SH4_PCICLKR); + /* Clear Powerdown IRQs (not done in reset) */ + word = SH4_PCIPINT_D3 | SH4_PCIPINT_D0; + pcic_writel(word, SH4_PCIPINT); + + /* set the command/status bits to: + * Wait Cycle Control + Parity Enable + Bus Master + + * Mem space enable + */ + word = PCI_COMMAND_WAIT | PCI_COMMAND_PARITY | + PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY; + pcic_writel(word, PCI_COMMAND); + + /* define this host as the host bridge */ + word = PCI_BASE_CLASS_BRIDGE << 24; + pcic_writel(word, PCI_CLASS_REVISION); + + /* Set IO and Mem windows to local address + * Make PCI and local address the same for easy 1 to 1 mapping + */ + word = memory_end - memory_start - 1; + pcic_writel(word, SH4_PCILSR0); + /* Set the values on window 0 PCI config registers */ + word = P2SEGADDR(__pa(memory_start)); + pcic_writel(word, SH4_PCILAR0); + pcic_writel(word, PCI_BASE_ADDRESS_1); + + set_pci_bcr(pci_reg_base, bcr, (__pa(memory_start) >> 27) & 0x07); + + /* configure the wait control registers */ + word = ioread32(bcr + SH7751_WCR1); + pcic_writel(word, SH4_PCIWCR1); + word = ioread32(bcr + SH7751_WCR2); + pcic_writel(word, SH4_PCIWCR2); + word = ioread32(bcr + SH7751_WCR3); + pcic_writel(word, SH4_PCIWCR3); + word = ioread32(bcr + SH7751_MCR); + pcic_writel(word, SH4_PCIMCR); + + match = of_match_node(fixup_of_match, pdev->dev.of_node); + if (match) { + fixup_fn = match->data; + fixup_fn(pci_reg_base, bcr); + } + /* + * SH7751 init done, set central function init complete + * use round robin mode to stop a device starving/overruning + */ + word = SH4_PCICR_PREFIX | SH4_PCICR_CFIN | SH4_PCICR_ARBM; + pcic_writel(word, SH4_PCICR); + + return pci_host_common_probe(pdev, &ecm_ops); +} + +static __refdata struct platform_driver sh7751_pci_driver = { + .driver = { + .name = "sh7751-pci", + .of_match_table = sh7751_pci_of_match, + .suppress_bind_attrs = true, + }, + .probe = sh7751_pci_probe, +}; +builtin_platform_driver(sh7751_pci_driver); -- 2.7.0 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH v6 12/22] sh: Add PCI host bridge driver for SH7751 2016-07-03 16:46 ` [PATCH v6 12/22] sh: Add PCI host bridge driver for SH7751 Yoshinori Sato @ 2016-07-05 15:53 ` Rob Herring 2016-07-06 16:19 ` Yoshinori Sato [not found] ` <1467564402-2649-13-git-send-email-ysato-Rn4VEauK+AKRv+LV9MX5uooqe+aC9MnS@public.gmane.org> 1 sibling, 1 reply; 13+ messages in thread From: Rob Herring @ 2016-07-05 15:53 UTC (permalink / raw) To: Yoshinori Sato; +Cc: devicetree, linux-pci, linux-sh, linux-kernel On Mon, Jul 04, 2016 at 01:46:32AM +0900, Yoshinori Sato wrote: > This is an alternative SH7751 PCI driver. > Existing driver (arch/sh/drivers/pci/pci-sh7751) uses SH specific interface. > But this driver uses common PCI interface. It is more modern and generic. > > Signed-off-by: Yoshinori Sato <ysato@users.sourceforge.jp> > --- > .../devicetree/bindings/pci/sh7751-pci.txt | 37 +++ Please add acks when posting new versions. > arch/sh/boards/Kconfig | 1 + > arch/sh/drivers/Makefile | 2 + > drivers/pci/host/Kconfig | 7 + > drivers/pci/host/Makefile | 1 + > drivers/pci/host/pci-sh7751.c | 327 +++++++++++++++++++++ > 6 files changed, 375 insertions(+) > create mode 100644 Documentation/devicetree/bindings/pci/sh7751-pci.txt > create mode 100644 drivers/pci/host/pci-sh7751.c ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v6 12/22] sh: Add PCI host bridge driver for SH7751 2016-07-05 15:53 ` Rob Herring @ 2016-07-06 16:19 ` Yoshinori Sato 0 siblings, 0 replies; 13+ messages in thread From: Yoshinori Sato @ 2016-07-06 16:19 UTC (permalink / raw) To: Rob Herring; +Cc: devicetree, linux-pci, linux-sh, linux-kernel On Wed, 06 Jul 2016 00:53:06 +0900, Rob Herring wrote: > > On Mon, Jul 04, 2016 at 01:46:32AM +0900, Yoshinori Sato wrote: > > This is an alternative SH7751 PCI driver. > > Existing driver (arch/sh/drivers/pci/pci-sh7751) uses SH specific interface. > > But this driver uses common PCI interface. It is more modern and generic. > > > > Signed-off-by: Yoshinori Sato <ysato@users.sourceforge.jp> > > --- > > .../devicetree/bindings/pci/sh7751-pci.txt | 37 +++ > > Please add acks when posting new versions. > > > arch/sh/boards/Kconfig | 1 + > > arch/sh/drivers/Makefile | 2 + > > drivers/pci/host/Kconfig | 7 + > > drivers/pci/host/Makefile | 1 + > > drivers/pci/host/pci-sh7751.c | 327 +++++++++++++++++++++ > > 6 files changed, 375 insertions(+) > > create mode 100644 Documentation/devicetree/bindings/pci/sh7751-pci.txt > > create mode 100644 drivers/pci/host/pci-sh7751.c Oh. Sorry. I forgot it. -- Yoshinori Sato <ysato@users.sourceforge.jp> ^ permalink raw reply [flat|nested] 13+ messages in thread
[parent not found: <1467564402-2649-13-git-send-email-ysato-Rn4VEauK+AKRv+LV9MX5uooqe+aC9MnS@public.gmane.org>]
* Re: [PATCH v6 12/22] sh: Add PCI host bridge driver for SH7751 [not found] ` <1467564402-2649-13-git-send-email-ysato-Rn4VEauK+AKRv+LV9MX5uooqe+aC9MnS@public.gmane.org> @ 2016-07-22 22:59 ` Bjorn Helgaas 0 siblings, 0 replies; 13+ messages in thread From: Bjorn Helgaas @ 2016-07-22 22:59 UTC (permalink / raw) To: Yoshinori Sato Cc: devicetree-u79uwXL29TY76Z2rM5mHXA, linux-pci-u79uwXL29TY76Z2rM5mHXA, linux-sh-u79uwXL29TY76Z2rM5mHXA, linux-kernel-u79uwXL29TY76Z2rM5mHXA On Mon, Jul 04, 2016 at 01:46:32AM +0900, Yoshinori Sato wrote: > This is an alternative SH7751 PCI driver. > Existing driver (arch/sh/drivers/pci/pci-sh7751) uses SH specific interface. > But this driver uses common PCI interface. It is more modern and generic. I'd like some details here about why we want this new driver. Will the old one be removed? How should a user choose which one to use? > Signed-off-by: Yoshinori Sato <ysato-Rn4VEauK+AKRv+LV9MX5uooqe+aC9MnS@public.gmane.org> > --- > .../devicetree/bindings/pci/sh7751-pci.txt | 37 +++ > arch/sh/boards/Kconfig | 1 + > arch/sh/drivers/Makefile | 2 + > drivers/pci/host/Kconfig | 7 + > drivers/pci/host/Makefile | 1 + > drivers/pci/host/pci-sh7751.c | 327 +++++++++++++++++++++ > 6 files changed, 375 insertions(+) > create mode 100644 Documentation/devicetree/bindings/pci/sh7751-pci.txt > create mode 100644 drivers/pci/host/pci-sh7751.c How do you plan to merge this? It looks like part of a large series, and I've only seen a few pieces of it. The ones you've posted to linux-pci seem mostly OK. I have a few minor comments below, but after you fix those and write some text for the changelogs, I can ack them and you can merge them along with the rest of the series. Bjorn > diff --git a/Documentation/devicetree/bindings/pci/sh7751-pci.txt b/Documentation/devicetree/bindings/pci/sh7751-pci.txt > new file mode 100644 > index 0000000..2df9af6 > --- /dev/null > +++ b/Documentation/devicetree/bindings/pci/sh7751-pci.txt > @@ -0,0 +1,37 @@ > +* Renesas SH7751 PCI host interfaces > + > +Required properties: > + - compatible: "renesas,sh7751-pci" is required. > + And board specific compatible if fixup required. > + - reg: contain two entries. > + first entry: PCI controller register base address and length. > + second entry: BUS controller register base address and length. > + - #address-cells: set to <2> > + - #size-cells: set to <1> > + - bus-range: PCI bus numbers covered > + - device_type: set to "pci" > + - ranges: ranges for the PCI memory and I/O regions. > + - interrupt-map-mask and interrupt-map: standard PCI properties > + to define the mapping of the PCI interface to interrupt > + numbers. > + > +Example: > + pci: pci-controller@fe200000 { > + compatible = "renesas,sh7751-pci", "iodata,landisk"; > + device_type = "pci"; > + bus-range = <0 0>; > + #address-cells = <2>; > + #size-cells = <1>; > + ranges = <0x02000000 0x00000000 0xfd000000 0xfd000000 0x00000000 0x01000000>, > + <0x01000000 0x00000000 0xfe240000 0x00000000 0x00000000 0x00040000>; > + reg = <0xfe200000 0x0400>, > + <0xff800000 0x0030>; > + #interrupt-cells = <1>; > + interrupt-map-mask = <0x1800 0 7>; > + interrupt-map = <0x0000 0 1 &cpldintc 0 0>, > + <0x0800 0 1 &cpldintc 1 0>, > + <0x1000 0 1 &cpldintc 2 0>, > + <0x1800 0 1 &cpldintc 3 0>, > + <0x1800 0 2 &cpldintc 0 0>; > + }; > +}; > diff --git a/arch/sh/boards/Kconfig b/arch/sh/boards/Kconfig > index b6ff9df..cfde921 100644 > --- a/arch/sh/boards/Kconfig > +++ b/arch/sh/boards/Kconfig > @@ -14,6 +14,7 @@ config SH_DEVICE_TREE > select GENERIC_CALIBRATE_DELAY > select GENERIC_IOMAP > select COMMON_CLK > + select SYS_SUPPORTS_PCI > help > Select Board Described by Device Tree to build a kernel that > does not hard-code any board-specific knowledge but instead uses > diff --git a/arch/sh/drivers/Makefile b/arch/sh/drivers/Makefile > index e13f06b..382e86f 100644 > --- a/arch/sh/drivers/Makefile > +++ b/arch/sh/drivers/Makefile > @@ -4,7 +4,9 @@ > > obj-y += dma/ > > +ifndef CONFIG_SH_DEVICE_TREE > obj-$(CONFIG_PCI) += pci/ > +endif > obj-$(CONFIG_SUPERHYWAY) += superhyway/ > obj-$(CONFIG_PUSH_SWITCH) += push-switch.o > obj-$(CONFIG_HEARTBEAT) += heartbeat.o > diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig > index 5d2374e..df60505 100644 > --- a/drivers/pci/host/Kconfig > +++ b/drivers/pci/host/Kconfig > @@ -245,4 +245,11 @@ config PCIE_ARMADA_8K > Designware hardware and therefore the driver re-uses the > Designware core functions to implement the driver. > > +config PCI_SH7751 > + bool "Renesas SH7751 On-Chip PCI controller" > + depends on OF && SUPERH > + select PCI_HOST_COMMON > + help > + Say Y here if you want PCI support on SH7751. > + > endmenu > diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile > index 9c8698e..4681e49 100644 > --- a/drivers/pci/host/Makefile > +++ b/drivers/pci/host/Makefile > @@ -29,3 +29,4 @@ obj-$(CONFIG_PCIE_QCOM) += pcie-qcom.o > obj-$(CONFIG_PCI_HOST_THUNDER_ECAM) += pci-thunder-ecam.o > obj-$(CONFIG_PCI_HOST_THUNDER_PEM) += pci-thunder-pem.o > obj-$(CONFIG_PCIE_ARMADA_8K) += pcie-armada8k.o > +obj-$(CONFIG_PCI_SH7751) += pci-sh7751.o > diff --git a/drivers/pci/host/pci-sh7751.c b/drivers/pci/host/pci-sh7751.c > new file mode 100644 > index 0000000..21601f1 > --- /dev/null > +++ b/drivers/pci/host/pci-sh7751.c > @@ -0,0 +1,327 @@ > +/* > + * SH7751 PCI driver > + * Copyright (C) 2016 Yoshinori Sato > + */ > + > +#include <linux/kernel.h> > +#include <linux/module.h> > +#include <linux/of_address.h> > +#include <linux/of_pci.h> > +#include <linux/of_platform.h> > +#include <linux/pci.h> > +#include <linux/platform_device.h> > +#include <linux/io.h> > +#include "../ecam.h" > + > +#define SH7751_PCICONF1 0x4 /* PCI Config Reg 1 */ > +#define SH7751_PCICONF4 0x10 /* PCI Config Reg 4 */ > +#define SH7751_PCICONF5 0x14 /* PCI Config Reg 5 */ > +#define SH7751_PCICONF6 0x18 /* PCI Config Reg 6 */ > +#define SH4_PCICR 0x100 /* PCI Control Register */ > + #define SH4_PCICR_PREFIX 0xA5000000 /* CR prefix for write */ Follow the indentation style of include/uapi/linux/pci_regs.h, drivers/pci/host/pcie-rcar.c, drivers/pci/host/pci-mvebu.c, etc.: #define SH4_PCICR 0x100 #define SH4_PCICR_PREFIX 0xA5000000 > + #define SH4_PCICR_FTO BIT(10) /* TRDY/IRDY Enable */ > + #define SH4_PCICR_TRSB BIT(9) /* Target Read Single */ > + #define SH4_PCICR_BSWP BIT(8) /* Target Byte Swap */ > + #define SH4_PCICR_PLUP BIT(7) /* Enable PCI Pullup */ The above are unused and can be omitted. > + #define SH4_PCICR_ARBM BIT(6) /* PCI Arbitration Mode */ > +#define SH4_PCICR_MD (BIT(4) | BIT(5)) /* MD9 and MD10 status */ Indentation error (should match other fields above). Also, unused, so can just be omitted. > + #define SH4_PCICR_SERR BIT(3) /* SERR output assert */ > + #define SH4_PCICR_INTA BIT(2) /* INTA output assert */ > + #define SH4_PCICR_PRST BIT(1) /* PCI Reset Assert */ Above are unused. > + #define SH4_PCICR_CFIN BIT(0) /* Central Fun. Init Done */ > +#define SH4_PCILSR0 0x104 /* PCI Local Space Register0 */ > +#define SH4_PCILSR1 0x108 /* PCI Local Space Register1 */ Unused. > +#define SH4_PCILAR0 0x10C /* PCI Local Addr Register1 */ > +#define SH4_PCILAR1 0x110 /* PCI Local Addr Register1 */ > +#define SH4_PCIINTM 0x118 /* PCI Interrupt Mask */ > + #define SH4_PCIINTM_TTADIM BIT(14) /* Target-target abort interrupt */ > + #define SH4_PCIINTM_TMTOIM BIT(9) /* Target retry timeout */ > + #define SH4_PCIINTM_MDEIM BIT(8) /* Master function disable error */ > + #define SH4_PCIINTM_APEDIM BIT(7) /* Address parity error detection */ > + #define SH4_PCIINTM_SDIM BIT(6) /* SERR detection */ > + #define SH4_PCIINTM_DPEITWM BIT(5) /* Data parity error for target write */ > + #define SH4_PCIINTM_PEDITRM BIT(4) /* PERR detection for target read */ > + #define SH4_PCIINTM_TADIMM BIT(3) /* Target abort for master */ > + #define SH4_PCIINTM_MADIMM BIT(2) /* Master abort for master */ > + #define SH4_PCIINTM_MWPDIM BIT(1) /* Master write data parity error */ > + #define SH4_PCIINTM_MRDPEIM BIT(0) /* Master read data parity error */ Field names are unused. You do write 0xc3ff to SH4_PCIINTM, but it's a pain to match that up with these definitions. Either write out the masks here, e.g., "#define SH4_PCIINTM_MRDPEIM 0x00000001", or build up the SH4_PCIINTM from these definitions, or both. > +#define SH4_PCIAINTM 0x134 /* Arbiter Int. Mask Register */ > +#define SH4_PCIPAR 0x1C0 /* PIO Address Register */ > + #define SH4_PCIPAR_CFGEN 0x80000000 /* Configuration Enable */ > + #define SH4_PCIPAR_BUSNO 0x00FF0000 /* Config. Bus Number */ > + #define SH4_PCIPAR_DEVNO 0x0000FF00 /* Config. Device Number */ > + #define SH4_PCIPAR_REGAD 0x000000FC /* Register Address Number */ Field names unused. At least SH4_PCIPAR_CFGEN *could* be used in CONFIG_CMD() below. > +#define SH4_PCIPINT 0x1CC /* Power Mgmnt Int. Register */ > + #define SH4_PCIPINT_D3 0x00000002 /* D3 Pwr Mgmt. Interrupt */ > + #define SH4_PCIPINT_D0 0x00000001 /* D0 Pwr Mgmt. Interrupt */ > +#define SH4_PCICLKR 0x1D4 /* Clock Ctrl. Register */ > +/* For definitions of BCR, MCR see ... */ See ... what? > +#define SH4_PCIBCR1 0x1E0 /* Memory BCR1 Register */ > + #define SH4_PCIMBR0 SH4_PCIBCR1 Unused. > +#define SH4_PCIBCR2 0x1E4 /* Memory BCR2 Register */ > + #define SH4_PCIMBMR0 SH4_PCIBCR2 Unused. > +#define SH4_PCIWCR1 0x1E8 /* Wait Control 1 Register */ > +#define SH4_PCIWCR2 0x1EC /* Wait Control 2 Register */ > +#define SH4_PCIWCR3 0x1F0 /* Wait Control 3 Register */ > + #define SH4_PCIMBR2 SH4_PCIWCR3 Unused. > +#define SH4_PCIMCR 0x1F4 /* Memory Control Register */ > +#define SH4_PCIPDR 0x220 /* Port IO Data Register */ > + > +/* Platform Specific Values */ > +#define SH7751_VENDOR_ID 0x1054 > +#define SH7751_DEVICE_ID 0x3505 > +#define SH7751R_DEVICE_ID 0x350e > + > +/* Memory Control Registers */ > +#define SH7751_BCR1 0x0000 /* Memory BCR1 Register */ > +#define SH7751_BCR2 0x0004 /* Memory BCR2 Register */ > +#define SH7751_BCR3 0x0050 /* Memory BCR3 Register */ Unused. > +#define SH7751_WCR1 0x0008 /* Wait Control 1 Register */ > +#define SH7751_WCR2 0x000C /* Wait Control 2 Register */ > +#define SH7751_WCR3 0x0010 /* Wait Control 3 Register */ > +#define SH7751_MCR 0x0014 /* Memory Control Register */ > + > +#define pcic_writel(val, reg) iowrite32(val, pci_reg_base + (reg)) > +#define pcic_readl(reg) ioread32(pci_reg_base + (reg)) > + > +/* > + * PCIC fixups > + */ > + > +#define PCIMCR_MRSET 0x40000000 > +#define PCIMCR_RFSH 0x00000004 > + > +static void __init landisk_fixup(void __iomem *pci_reg_base, void __iomem *bcr) > +{ > + unsigned long bcr1, mcr; > + > + bcr1 = ioread32(bcr + SH7751_BCR1); > + bcr1 |= 0x00080000; /* Enable Bit 19 BREQEN, set PCIC to slave */ > + pcic_writel(bcr1, SH4_PCIBCR1); > + > + mcr = ioread32(bcr + SH7751_MCR); > + mcr &= (~PCIMCR_MRSET) & (~PCIMCR_RFSH); > + pcic_writel(mcr, SH4_PCIMCR); > + > + pcic_writel(0x0c000000, PCI_BASE_ADDRESS_1); > + pcic_writel(0xd0000000, PCI_BASE_ADDRESS_2); > + pcic_writel(0x0c000000, SH4_PCILAR0); > + pcic_writel(0x00000000, SH4_PCILAR1); > +} > + > +static void __init r2dplus_fixup(void __iomem *pci_reg_base, void __iomem *bcr) > +{ > + unsigned long bcr1, mcr; > + > + bcr1 = ioread32(bcr + SH7751_BCR1); > + bcr1 |= 0x40080000; /* Enable Bit 19 BREQEN, set PCIC to slave */ > + pcic_writel(bcr1, SH4_PCIBCR1); > + > + /* Enable all interrupts, so we known what to fix */ > + pcic_writel(0x0000c3ff, SH4_PCIINTM); > + pcic_writel(0x0000380f, SH4_PCIAINTM); > + > + pcic_writel(0xfb900047, SH7751_PCICONF1); > + pcic_writel(0xab000001, SH7751_PCICONF4); > + > + mcr = ioread32(bcr + SH7751_MCR); > + mcr &= (~PCIMCR_MRSET) & (~PCIMCR_RFSH); > + pcic_writel(mcr, SH4_PCIMCR); > + > + pcic_writel(0x0c000000, SH7751_PCICONF5); > + pcic_writel(0xd0000000, SH7751_PCICONF6); > + pcic_writel(0x0c000000, SH4_PCILAR0); > + pcic_writel(0x00000000, SH4_PCILAR1); > +} > + > +/* > + * Direct access to PCI hardware... > + */ > +#define CONFIG_CMD(bus, devfn, where) \ > + (0x80000000 | (bus->number << 16) | (devfn << 8) | (where & ~3)) > + > +/* > + * Functions for accessing PCI configuration space with type 1 accesses > + */ > +static void __iomem *sh7751_map_bus(struct pci_bus *bus, > + unsigned int devfn, int where) > +{ > + struct pci_config_window *cfg = bus->sysdata; > + void __iomem *pci_reg_base = (void __iomem *)cfg->res.start; > + > + pcic_writel(CONFIG_CMD(bus, devfn, where), SH4_PCIPAR); > + return pci_reg_base + SH4_PCIPDR; > +} > + > +static const struct of_device_id fixup_of_match[] = { > + { .compatible = "iodata,landisk-pci", .data = landisk_fixup, }, > + { .compatible = "renesas,r2dplus-pci", .data = r2dplus_fixup, }, > + { }, > +}; > + > +static const struct of_device_id sh7751_pci_of_match[] = { > + { .compatible = "renesas,sh7751-pci", }, > + { }, > +}; > +MODULE_DEVICE_TABLE(of, sh7751_pci_of_match); > + > +static resource_size_t sh7751_align_resource(struct pci_dev *dev, > + const struct resource *res, > + resource_size_t start, > + resource_size_t size, > + resource_size_t align) > +{ > + if (res->flags & IORESOURCE_IO) { > + if (start < PCIBIOS_MIN_IO + 0x1000) > + start = PCIBIOS_MIN_IO + 0x1000; > + > + /* > + * Put everything into 0x00-0xff region modulo 0x400. > + */ > + if (start & 0x300) > + start = (start + 0x3ff) & ~0x3ff; > + } > + > + return start; > +} > + > +static void __init set_pci_bcr(void __iomem *pci_reg_base, > + void __iomem *bcr, > + unsigned int area) > +{ > + unsigned long word; > + > + word = ioread32(bcr + SH7751_BCR1); > + /* check BCR for SDRAM in area */ > + if (((word >> area) & 1) == 0) { > + pr_info("PCI: Area %d is not configured for SDRAM. BCR1=0x%lx\n", > + area, word); Use dev_info() so we can associate the message with a device and driver. > + return; > + } > + pcic_writel(word, SH4_PCIBCR1); > + > + word = ioread16(bcr + SH7751_BCR2); > + /* check BCR2 for 32bit SDRAM interface*/ > + if (((word >> (area << 1)) & 0x3) != 0x3) { > + pr_info("PCI: Area %d is not 32 bit SDRAM. BCR2=0x%lx\n", > + area, word); dev_info() > + return; > + } > + pcic_writel(word, SH4_PCIBCR2); > +} > + > +static __init int sh7751_cfg_init(struct device *dev, > + struct pci_config_window *cfg) > +{ > + cfg->priv = sh7751_align_resource; > + return 0; > +} > + > +static struct pci_ecam_ops ecm_ops __initdata = { > + .init = sh7751_cfg_init, > + .pci_ops = { > + .read = pci_generic_config_read32, > + .write = pci_generic_config_write32, > + .map_bus = sh7751_map_bus, > + } > +}; > + > +static __init int sh7751_pci_probe(struct platform_device *pdev) > +{ > + struct resource *res; > + u32 id; > + u32 reg, word; > + void __iomem *pci_reg_base; > + void __iomem *bcr; > + const struct of_device_id *match; > + void (*fixup_fn)(void __iomem *pci_reg_base, void __iomem *bcr); > + > + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); > + pci_reg_base = ioremap(res->start, resource_size(res)); > + if (IS_ERR(pci_reg_base)) > + return PTR_ERR(pci_reg_base); > + > + res = platform_get_resource(pdev, IORESOURCE_MEM, 1); > + bcr = ioremap(res->start, resource_size(res)); > + if (IS_ERR(bcr)) > + return PTR_ERR(bcr); > + > + /* check for SH7751/SH7751R hardware */ > + id = pcic_readl(PCI_VENDOR_ID); > + if (id != ((SH7751_DEVICE_ID << 16) | SH7751_VENDOR_ID) && > + id != ((SH7751R_DEVICE_ID << 16) | SH7751_VENDOR_ID)) { > + pr_warn("PCI: This is not an SH7751(R)\n"); dev_warn() > + return -ENODEV; > + } > + dev_info(&pdev->dev, "PCI core found at %pR\n", > + pci_reg_base); > + > + /* Set the BCRs to enable PCI access */ > + reg = ioread32(bcr); > + reg |= 0x80000; > + iowrite32(reg, bcr); > + > + /* Turn the clocks back on (not done in reset)*/ > + pcic_writel(0, SH4_PCICLKR); > + /* Clear Powerdown IRQs (not done in reset) */ > + word = SH4_PCIPINT_D3 | SH4_PCIPINT_D0; > + pcic_writel(word, SH4_PCIPINT); > + > + /* set the command/status bits to: > + * Wait Cycle Control + Parity Enable + Bus Master + > + * Mem space enable > + */ Multi-line comment style is: /* * set the command/... * ... */ > + word = PCI_COMMAND_WAIT | PCI_COMMAND_PARITY | > + PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY; > + pcic_writel(word, PCI_COMMAND); > + > + /* define this host as the host bridge */ > + word = PCI_BASE_CLASS_BRIDGE << 24; > + pcic_writel(word, PCI_CLASS_REVISION); > + > + /* Set IO and Mem windows to local address > + * Make PCI and local address the same for easy 1 to 1 mapping > + */ > + word = memory_end - memory_start - 1; > + pcic_writel(word, SH4_PCILSR0); > + /* Set the values on window 0 PCI config registers */ > + word = P2SEGADDR(__pa(memory_start)); > + pcic_writel(word, SH4_PCILAR0); > + pcic_writel(word, PCI_BASE_ADDRESS_1); > + > + set_pci_bcr(pci_reg_base, bcr, (__pa(memory_start) >> 27) & 0x07); > + > + /* configure the wait control registers */ > + word = ioread32(bcr + SH7751_WCR1); > + pcic_writel(word, SH4_PCIWCR1); > + word = ioread32(bcr + SH7751_WCR2); > + pcic_writel(word, SH4_PCIWCR2); > + word = ioread32(bcr + SH7751_WCR3); > + pcic_writel(word, SH4_PCIWCR3); > + word = ioread32(bcr + SH7751_MCR); > + pcic_writel(word, SH4_PCIMCR); > + > + match = of_match_node(fixup_of_match, pdev->dev.of_node); > + if (match) { > + fixup_fn = match->data; > + fixup_fn(pci_reg_base, bcr); > + } > + /* > + * SH7751 init done, set central function init complete > + * use round robin mode to stop a device starving/overruning > + */ > + word = SH4_PCICR_PREFIX | SH4_PCICR_CFIN | SH4_PCICR_ARBM; > + pcic_writel(word, SH4_PCICR); > + > + return pci_host_common_probe(pdev, &ecm_ops); > +} > + > +static __refdata struct platform_driver sh7751_pci_driver = { > + .driver = { > + .name = "sh7751-pci", > + .of_match_table = sh7751_pci_of_match, > + .suppress_bind_attrs = true, > + }, > + .probe = sh7751_pci_probe, > +}; > +builtin_platform_driver(sh7751_pci_driver); > -- > 2.7.0 > -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH v5 13/22] sh: irqchip: SH7751 IRQCHIP Driver [not found] ` <1467564402-2649-1-git-send-email-ysato-Rn4VEauK+AKRv+LV9MX5uooqe+aC9MnS@public.gmane.org> 2016-07-03 16:46 ` [PATCH v6 12/22] sh: Add PCI host bridge driver for SH7751 Yoshinori Sato @ 2016-07-03 16:46 ` Yoshinori Sato 1 sibling, 0 replies; 13+ messages in thread From: Yoshinori Sato @ 2016-07-03 16:46 UTC (permalink / raw) To: devicetree-u79uwXL29TY76Z2rM5mHXA, linux-sh-u79uwXL29TY76Z2rM5mHXA, linux-kernel-u79uwXL29TY76Z2rM5mHXA Cc: Yoshinori Sato Signed-off-by: Yoshinori Sato <ysato-Rn4VEauK+AKRv+LV9MX5uooqe+aC9MnS@public.gmane.org> Acked-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> --- .../interrupt-controller/renesas,sh7751-intc.txt | 25 ++++ arch/sh/Kconfig | 6 +- arch/sh/boards/Kconfig | 1 + drivers/irqchip/Kconfig | 5 + drivers/irqchip/Makefile | 1 + drivers/irqchip/irq-renesas-sh7751.c | 141 +++++++++++++++++++++ 6 files changed, 176 insertions(+), 3 deletions(-) create mode 100644 Documentation/devicetree/bindings/interrupt-controller/renesas,sh7751-intc.txt create mode 100644 drivers/irqchip/irq-renesas-sh7751.c diff --git a/Documentation/devicetree/bindings/interrupt-controller/renesas,sh7751-intc.txt b/Documentation/devicetree/bindings/interrupt-controller/renesas,sh7751-intc.txt new file mode 100644 index 0000000..2bc6f22f --- /dev/null +++ b/Documentation/devicetree/bindings/interrupt-controller/renesas,sh7751-intc.txt @@ -0,0 +1,25 @@ +DT bindings for the SH7751 interrupt controller + +Required properties: + + - compatible: has to be "renesas,sh7751-intc". + + - reg: Base address and length of interrupt controller register + and extend register. + + - interrupt-controller: Identifies the node as an interrupt controller. + + - #interrupt-cells: has to be <2>: an interrupt index and flags, as defined + in interrupts.txt in this directory. + +Example +------- + + shintc: interrupt-controller@ffd00000 { + compatible = "renesas,sh7751-intc"; + #interrupt-cells = <2>; + #address-cells = <1>; + #size-cells = <1>; + interrupt-controller; + reg = <0xffd00000 14>, <0xfe080000 128>; + }; diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index d06cac1..fee4333 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -29,7 +29,7 @@ config SUPERH select ARCH_WANT_IPC_PARSE_VERSION select HAVE_SYSCALL_TRACEPOINTS select HAVE_REGS_AND_STACK_ACCESS_API - select MAY_HAVE_SPARSE_IRQ + select MAY_HAVE_SPARSE_IRQ if !SH_DEVICE_TREE select IRQ_FORCED_THREADING select RTC_LIB select GENERIC_ATOMIC64 @@ -69,7 +69,7 @@ config SUPERH32 select HAVE_MIXED_BREAKPOINTS_REGS select PERF_EVENTS select ARCH_HIBERNATION_POSSIBLE if MMU - select SPARSE_IRQ + select SPARSE_IRQ if !SH_DEVICE_TREE select HAVE_CC_STACKPROTECTOR config SUPERH64 @@ -863,7 +863,7 @@ config PCI depends on SYS_SUPPORTS_PCI select PCI_DOMAINS select GENERIC_PCI_IOMAP - select NO_GENERIC_PCI_IOPORT_MAP + select NO_GENERIC_PCI_IOPORT_MAP if !SH_DEVICE_TREE help Find out whether you have a PCI motherboard. PCI is the name of a bus system, i.e. the way the CPU talks to the other stuff inside diff --git a/arch/sh/boards/Kconfig b/arch/sh/boards/Kconfig index cfde921..d33ae46 100644 --- a/arch/sh/boards/Kconfig +++ b/arch/sh/boards/Kconfig @@ -15,6 +15,7 @@ config SH_DEVICE_TREE select GENERIC_IOMAP select COMMON_CLK select SYS_SUPPORTS_PCI + select GENERIC_IRQ_CHIP help Select Board Described by Device Tree to build a kernel that does not hard-code any board-specific knowledge but instead uses diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig index fa33c50..fd7f842 100644 --- a/drivers/irqchip/Kconfig +++ b/drivers/irqchip/Kconfig @@ -251,6 +251,11 @@ config LS_SCFG_MSI depends on PCI && PCI_MSI select PCI_MSI_IRQ_DOMAIN +config RENESAS_SH_INTC + def_bool y if SH_DEVICE_TREE + select IRQ_DOMAIN + select IRQ_DOMAIN_HIERARCHY + config PARTITION_PERCPU bool diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile index 38853a1..2ab5735 100644 --- a/drivers/irqchip/Makefile +++ b/drivers/irqchip/Makefile @@ -69,3 +69,4 @@ obj-$(CONFIG_PIC32_EVIC) += irq-pic32-evic.o obj-$(CONFIG_MVEBU_ODMI) += irq-mvebu-odmi.o obj-$(CONFIG_LS_SCFG_MSI) += irq-ls-scfg-msi.o obj-$(CONFIG_EZNPS_GIC) += irq-eznps.o +obj-$(CONFIG_RENESAS_SH_INTC) += irq-renesas-sh7751.o diff --git a/drivers/irqchip/irq-renesas-sh7751.c b/drivers/irqchip/irq-renesas-sh7751.c new file mode 100644 index 0000000..1710978 --- /dev/null +++ b/drivers/irqchip/irq-renesas-sh7751.c @@ -0,0 +1,141 @@ +/* + * SH7751 interrupt contoller driver + * + * Copyright 2016 Yoshinori Sato <ysato-Rn4VEauK+AKRv+LV9MX5uooqe+aC9MnS@public.gmane.org> + */ + +#include <linux/irq.h> +#include <linux/irqchip.h> +#include <linux/of_address.h> +#include <linux/of_irq.h> +#include <linux/of.h> +#include <linux/io.h> + +static struct sh7751_intc_regs { + void *icr; + void *ipr; + void *intpri00; + void *intreq00; + void *intmsk00; + void *intmskclr00; +} sh7751_regs; + +static const unsigned int ipr_table[] = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0 - 7 */ + 0x41, 0xff, 0xff, 0x40, 0xff, 0xff, 0xff, 0xff, /* 8 - 15 */ + 0x03, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x11, /* 16 - 23 */ + 0x11, 0x11, 0x11, 0x13, 0x12, 0x12, 0xff, 0xff, /* 24 - 31 */ + 0x30, 0x33, 0x32, 0x32, 0x32, 0x32, 0x32, 0x21, /* 32 - 39 */ + 0x21, 0x21, 0x21, 0x21, 0x32, 0x32, 0x32, 0x32, /* 40 - 47 */ + 0xff, 0xff, 0xff, 0x40, 0xff, 0xff, 0xff, 0xff, /* 48 - 55 */ + 0xff, 0xff, 0xff, 0x40, 0xff, 0xff, 0xff, 0xff, /* 56 - 63 */ +}; + +static const unsigned int pri_table[] = { + 0, 4, 4, 4, 4, 4, 4, 4, + 8, 32, 32, 32, 12, 32, 32, 32, +}; + +static void sh_disable_irq(struct irq_data *data) +{ + int pos; + unsigned int addr; + unsigned long pri; + int irq = data->irq; + struct sh7751_intc_regs *reg = data->chip_data; + + if (irq < 64) { + if (ipr_table[irq] != 0xff) { + addr = (ipr_table[irq] & 0xf0) >> 2; + pos = (ipr_table[irq] & 0x0f) << 4; + pri = ~(0x000f << pos); + pri &= __raw_readw(reg->ipr + addr); + __raw_writew(pri, reg->ipr + addr); + } + } else { + if (pri_table[irq - 64] < 32) { + pos = pri_table[irq - 64]; + pri = ~(0x000f << pos); + pri &= __raw_readw(reg->intpri00); + __raw_writew(pri, reg->intpri00); + } + } +} + +static void sh_enable_irq(struct irq_data *data) +{ + int pos; + unsigned int addr; + unsigned long pri; + int irq = data->irq; + struct sh7751_intc_regs *reg = data->chip_data; + + if (irq < 64) { + if (ipr_table[irq] != 0xff) { + addr = (ipr_table[irq] & 0xf0) >> 2; + pos = (ipr_table[irq] & 0x0f) * 4; + pri = ~(0x000f << pos); + pri &= __raw_readw(reg->ipr + addr); + pri |= 1 << pos; + __raw_writew(pri, reg->ipr + addr); + } + } else { + if (pri_table[irq - 64] < 32) { + pos = pri_table[irq - 64]; + pri = ~(0x000f << pos); + pri &= __raw_readw(reg->intpri00); + pri |= 1 << pos; + __raw_writew(pri, reg->intpri00); + } + } +} + +static struct irq_chip sh_irq_chip = { + .name = "SH-IPR", + .irq_unmask = sh_enable_irq, + .irq_mask = sh_disable_irq, +}; + +static __init int irq_map(struct irq_domain *h, unsigned int virq, + irq_hw_number_t hw_irq_num) +{ + irq_set_chip_and_handler(virq, &sh_irq_chip, handle_level_irq); + irq_get_irq_data(virq)->chip_data = h->host_data; + irq_modify_status(virq, IRQ_NOREQUEST, IRQ_NOPROBE); + + return 0; +} + +static struct irq_domain_ops irq_ops = { + .map = irq_map, + .xlate = irq_domain_xlate_onecell, +}; + +static int __init sh_intc_7751_init(struct device_node *intc, + struct device_node *parent) +{ + struct irq_domain *domain; + void *intc_baseaddr; + void *intc_baseaddr2; + + intc_baseaddr = of_iomap(intc, 0); + intc_baseaddr2 = of_iomap(intc, 1); + if (!intc_baseaddr || !intc_baseaddr2) + panic("INTC regsiter not defined"); + + sh7751_regs.icr = intc_baseaddr; + sh7751_regs.ipr = intc_baseaddr + 4; + sh7751_regs.intpri00 = intc_baseaddr2; + sh7751_regs.intreq00 = intc_baseaddr2 + 0x20; + sh7751_regs.intmsk00 = intc_baseaddr2 + 0x40; + sh7751_regs.intmskclr00 = intc_baseaddr2 + 0x60; + + domain = irq_domain_add_linear(intc, NR_IRQS, &irq_ops, &sh7751_regs); + if (!domain) + panic("%s: unable to create IRQ domain\n", intc->full_name); + + irq_set_default_host(domain); + return 0; +} + +IRQCHIP_DECLARE(sh_7751_intc, "renesas,sh7751-intc", sh_intc_7751_init); -- 2.7.0 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v5 14/22] sh: SH7751 core dtsi [not found] <1467564402-2649-1-git-send-email-ysato@users.sourceforge.jp> [not found] ` <1467564402-2649-1-git-send-email-ysato-Rn4VEauK+AKRv+LV9MX5uooqe+aC9MnS@public.gmane.org> @ 2016-07-03 16:46 ` Yoshinori Sato 2016-07-03 16:46 ` [PATCH v5 19/22] sh: IO-DATA HDL-U (a.k.a landisk) IRQCHIP driver Yoshinori Sato ` (3 subsequent siblings) 5 siblings, 0 replies; 13+ messages in thread From: Yoshinori Sato @ 2016-07-03 16:46 UTC (permalink / raw) To: devicetree, linux-sh, linux-kernel; +Cc: Yoshinori Sato SH7751 core and internal peripheral define. Signed-off-by: Yoshinori Sato <ysato@users.sourceforge.jp> --- arch/sh/boot/dts/include/dt-bindings | 1 + arch/sh/boot/dts/sh7751.dtsi | 83 ++++++++++++++++++++++ include/dt-bindings/clock/renesas-sh7750.h | 26 +++++++ include/dt-bindings/interrupt-controller/sh_intc.h | 2 + 4 files changed, 112 insertions(+) create mode 120000 arch/sh/boot/dts/include/dt-bindings create mode 100644 arch/sh/boot/dts/sh7751.dtsi create mode 100644 include/dt-bindings/clock/renesas-sh7750.h create mode 100644 include/dt-bindings/interrupt-controller/sh_intc.h diff --git a/arch/sh/boot/dts/include/dt-bindings b/arch/sh/boot/dts/include/dt-bindings new file mode 120000 index 0000000..08c00e4 --- /dev/null +++ b/arch/sh/boot/dts/include/dt-bindings @@ -0,0 +1 @@ +../../../../../include/dt-bindings \ No newline at end of file diff --git a/arch/sh/boot/dts/sh7751.dtsi b/arch/sh/boot/dts/sh7751.dtsi new file mode 100644 index 0000000..713e72e --- /dev/null +++ b/arch/sh/boot/dts/sh7751.dtsi @@ -0,0 +1,83 @@ +/* + * Device Tree Source for the SH7751 + * + * Copyright (C) 2016 Yoshinori Sato + */ + +#include <dt-bindings/interrupt-controller/sh_intc.h> +#include <dt-bindings/clock/renesas-sh7750.h> + +/ { + oclk: oscillator { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <0>; + }; + cpg: clock-controller@ffc00000 { + compatible = "renesas,sh7750-cpg"; + clocks = <&oclk>; + #clock-cells = <1>; + renesas,mult = <12>; + reg = <0xffc00000 32>, <0xfe0a0000 16>; + }; + cpus { + #address-cells = <1>; + #size-cells = <0>; + cpu@0 { + compatible = "renesas,sh4", "renesas,sh"; + clock-frequency = <266666666>; + }; + }; + shintc: interrupt-controller@ffd00000 { + compatible = "renesas,sh7751-intc"; + #interrupt-cells = <2>; + interrupt-controller; + reg = <0xffd00000 14>, <0xfe080000 128>; + + }; + sci0: serial@ffe00000 { + compatible = "renesas,sci"; + reg = <0xffe00000 0x20>; + interrupts = <evt2irq(0x4e0) 0>, + <evt2irq(0x500) 0>, + <evt2irq(0x540) 0>, + <evt2irq(0x520) 0>; + clocks = <&cpg SH7750_CLK_SCI>; + clock-names = "fck"; + status = "disabled"; + }; + sci1: serial@ffe80000 { + compatible = "renesas,scif"; + reg = <0xffe80000 0x100>; + interrupts = <evt2irq(0x700) 0>, + <evt2irq(0x720) 0>, + <evt2irq(0x760) 0>, + <evt2irq(0x740) 0>; + clocks = <&cpg SH7750_CLK_SCIF>; + clock-names = "fck"; + status = "disabled"; + }; + tmu: timer@ffd80000 { + compatible = "renesas,tmu"; + reg = <0xffd80000 12>; + interrupts = <evt2irq(0x400) 0>, + <evt2irq(0x420) 0>, + <evt2irq(0x440) 0>; + clocks = <&cpg SH7750_CLK_TMU0>; + clock-names = "fck"; + renesas,channels-mask = <0x03>; + }; + pci: pci-controller@fe200000 { + compatible = "renesas,sh7751-pci"; + device_type = "pci"; + bus-range = <0 0>; + #address-cells = <2>; + #size-cells = <1>; + ranges = <0x02000000 0x00000000 0xfd000000 0xfd000000 0x00000000 0x01000000>, + <0x01000000 0x00000000 0xfe240000 0x00000000 0x00000000 0x00040000>; + reg = <0xfe200000 0x0400>, <0xff800000 0x0030>; + #interrupt-cells = <1>; + interrupt-map-mask = <0x1800 0 7>; + status = "disabled"; + }; +}; diff --git a/include/dt-bindings/clock/renesas-sh7750.h b/include/dt-bindings/clock/renesas-sh7750.h new file mode 100644 index 0000000..546c0b1 --- /dev/null +++ b/include/dt-bindings/clock/renesas-sh7750.h @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2016 Yoshinori Sato + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ +#ifndef __DT_BINDINGS_CLOCK_RENESAS_SH7750_H__ +#define __DT_BINDINGS_CLOCK_RENESAS_SH7750_H__ + +#define SH7750_CLK_SCI 0 +#define SH7750_CLK_RTC 1 +#define SH7750_CLK_TMU0 2 +#define SH7750_CLK_TMU1 3 +#define SH7750_CLK_TMU2 4 +#define SH7750_CLK_SCIF 5 +#define SH7750_CLK_DMAC 6 +#define SH7750_CLK_UBC 7 +#define SH7750_CLK_SQ 8 +#define SH7750_CLK_INTC 9 +#define SH7750_CLK_TMU3 10 +#define SH7750_CLK_TMU4 11 +#define SH7750_CLK_PCIC 12 + +#endif /* __DT_BINDINGS_CLOCK_RENESAS_CPG_MSSR_H__ */ diff --git a/include/dt-bindings/interrupt-controller/sh_intc.h b/include/dt-bindings/interrupt-controller/sh_intc.h new file mode 100644 index 0000000..8c9dcdc --- /dev/null +++ b/include/dt-bindings/interrupt-controller/sh_intc.h @@ -0,0 +1,2 @@ +#define evt2irq(evt) (((evt) >> 5) - 16) +#define irq2evt(irq) (((irq) + 16) << 5) -- 2.7.0 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v5 19/22] sh: IO-DATA HDL-U (a.k.a landisk) IRQCHIP driver [not found] <1467564402-2649-1-git-send-email-ysato@users.sourceforge.jp> [not found] ` <1467564402-2649-1-git-send-email-ysato-Rn4VEauK+AKRv+LV9MX5uooqe+aC9MnS@public.gmane.org> 2016-07-03 16:46 ` [PATCH v5 14/22] sh: SH7751 core dtsi Yoshinori Sato @ 2016-07-03 16:46 ` Yoshinori Sato 2016-07-11 14:02 ` Rob Herring 2016-07-03 16:46 ` [PATCH v5 20/22] sh: IO-DATA HDL-U (a.k.a landisk) DeviceTree Yoshinori Sato ` (2 subsequent siblings) 5 siblings, 1 reply; 13+ messages in thread From: Yoshinori Sato @ 2016-07-03 16:46 UTC (permalink / raw) To: devicetree, linux-sh, linux-kernel; +Cc: Yoshinori Sato Signed-off-by: Yoshinori Sato <ysato@users.sourceforge.jp> --- .../interrupt-controller/iodata-landisk.txt | 31 ++++++++++ drivers/irqchip/Makefile | 2 +- drivers/irqchip/irq-io-landisk.c | 72 ++++++++++++++++++++++ 3 files changed, 104 insertions(+), 1 deletion(-) create mode 100644 Documentation/devicetree/bindings/interrupt-controller/iodata-landisk.txt create mode 100644 drivers/irqchip/irq-io-landisk.c diff --git a/Documentation/devicetree/bindings/interrupt-controller/iodata-landisk.txt b/Documentation/devicetree/bindings/interrupt-controller/iodata-landisk.txt new file mode 100644 index 0000000..cf461dc --- /dev/null +++ b/Documentation/devicetree/bindings/interrupt-controller/iodata-landisk.txt @@ -0,0 +1,31 @@ +DT bindings for the I/O DATA HDL-U interrupt controller + +Required properties: + + - compatible: has to be "iodata,landisk-intc". + + - reg: Base address and length of interrupt controller register. + + - #interrupt-cells: has to be <1>: an interrupt index. + + - #address-cells: has to be <0> + + - interrupt-map: Interrupt mapping on parent controller. + +Example +------- + + cpldintc: cpld@b0000000 { + compatible = "iodata,landisk-intc"; + #interrupt-cells = <1>; + #address-cells = <0>; + reg = <0xb0000000 8>; + interrupt-map=<0 &shintc evt2irq(0x2a0)>, + <1 &shintc evt2irq(0x2c0)>, + <2 &shintc evt2irq(0x2e0)>, + <3 &shintc evt2irq(0x300)>, + <4 &shintc evt2irq(0x320)>, + <5 &shintc evt2irq(0x340)>, + <6 &shintc evt2irq(0x360)>, + <7 &shintc evt2irq(0x380)>; + }; diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile index 2ab5735..5e225cf 100644 --- a/drivers/irqchip/Makefile +++ b/drivers/irqchip/Makefile @@ -69,4 +69,4 @@ obj-$(CONFIG_PIC32_EVIC) += irq-pic32-evic.o obj-$(CONFIG_MVEBU_ODMI) += irq-mvebu-odmi.o obj-$(CONFIG_LS_SCFG_MSI) += irq-ls-scfg-msi.o obj-$(CONFIG_EZNPS_GIC) += irq-eznps.o -obj-$(CONFIG_RENESAS_SH_INTC) += irq-renesas-sh7751.o +obj-$(CONFIG_RENESAS_SH_INTC) += irq-renesas-sh7751.o irq-io-landisk.o diff --git a/drivers/irqchip/irq-io-landisk.c b/drivers/irqchip/irq-io-landisk.c new file mode 100644 index 0000000..b7f3b41 --- /dev/null +++ b/drivers/irqchip/irq-io-landisk.c @@ -0,0 +1,72 @@ +/* + * IO-DATA LANDISK CPLD IRQ driver + * + * Copyright 2016 Yoshinori Sato <ysato@users.sourceforge.jp> + */ + +#include <linux/init.h> +#include <linux/irq.h> +#include <linux/irqchip.h> +#include <linux/irqdomain.h> +#include <linux/of_address.h> +#include <linux/of_irq.h> +#include <linux/io.h> + +static void landisk_mask_irq(struct irq_data *data) +{ + u8 mask = __raw_readb(data->chip_data + 5); + + mask &= ~(1 << (data->irq - 5)); + __raw_writeb(mask, data->chip_data + 5); +} + +static void landisk_unmask_irq(struct irq_data *data) +{ + u8 mask = __raw_readb(data->chip_data + 5); + + mask |= (1 << (data->irq - 5)); + __raw_writeb(mask, data->chip_data + 5); +} + +static struct irq_chip cpld_irq_chip = { + .name = "LANDISK-CPLD", + .irq_unmask = landisk_unmask_irq, + .irq_mask = landisk_mask_irq, +}; + +static int cpld_map(struct irq_domain *d, unsigned int virq, + irq_hw_number_t hw_irq_num) +{ + irq_set_chip_and_handler(virq, &cpld_irq_chip, + handle_simple_irq); + irq_set_chip_data(virq, d->host_data); + + return 0; +} + +static struct irq_domain_ops irq_ops = { + .xlate = irq_domain_xlate_onecell, + .map = cpld_map, +}; + +static int __init landisk_intc_of_init(struct device_node *intc, + struct device_node *parent) +{ + struct irq_domain *domain, *pdomain; + int num_irqpin; + void *baseaddr; + + baseaddr = of_iomap(intc, 0); + pdomain = irq_find_host(parent); + of_get_property(intc, "interrupt-map", &num_irqpin); + num_irqpin /= sizeof(u32) * 3; + domain = irq_domain_create_hierarchy(pdomain, 0, num_irqpin, + of_node_to_fwnode(intc), + &irq_ops, baseaddr); + if (!domain) + panic("%s: unable to create IRQ domain\n", intc->full_name); + irq_domain_associate_many(domain, 5, 0, 8); + return 0; +} + +IRQCHIP_DECLARE(cpld_intc, "iodata,landisk-intc", landisk_intc_of_init); -- 2.7.0 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH v5 19/22] sh: IO-DATA HDL-U (a.k.a landisk) IRQCHIP driver 2016-07-03 16:46 ` [PATCH v5 19/22] sh: IO-DATA HDL-U (a.k.a landisk) IRQCHIP driver Yoshinori Sato @ 2016-07-11 14:02 ` Rob Herring 0 siblings, 0 replies; 13+ messages in thread From: Rob Herring @ 2016-07-11 14:02 UTC (permalink / raw) To: Yoshinori Sato; +Cc: devicetree, linux-sh, linux-kernel On Mon, Jul 04, 2016 at 01:46:39AM +0900, Yoshinori Sato wrote: > Signed-off-by: Yoshinori Sato <ysato@users.sourceforge.jp> > --- > .../interrupt-controller/iodata-landisk.txt | 31 ++++++++++ > drivers/irqchip/Makefile | 2 +- > drivers/irqchip/irq-io-landisk.c | 72 ++++++++++++++++++++++ > 3 files changed, 104 insertions(+), 1 deletion(-) > create mode 100644 Documentation/devicetree/bindings/interrupt-controller/iodata-landisk.txt > create mode 100644 drivers/irqchip/irq-io-landisk.c > > diff --git a/Documentation/devicetree/bindings/interrupt-controller/iodata-landisk.txt b/Documentation/devicetree/bindings/interrupt-controller/iodata-landisk.txt > new file mode 100644 > index 0000000..cf461dc > --- /dev/null > +++ b/Documentation/devicetree/bindings/interrupt-controller/iodata-landisk.txt > @@ -0,0 +1,31 @@ > +DT bindings for the I/O DATA HDL-U interrupt controller > + > +Required properties: > + > + - compatible: has to be "iodata,landisk-intc". > + > + - reg: Base address and length of interrupt controller register. > + > + - #interrupt-cells: has to be <1>: an interrupt index. > + > + - #address-cells: has to be <0> > + > + - interrupt-map: Interrupt mapping on parent controller. > + > +Example > +------- > + > + cpldintc: cpld@b0000000 { > + compatible = "iodata,landisk-intc"; > + #interrupt-cells = <1>; > + #address-cells = <0>; > + reg = <0xb0000000 8>; > + interrupt-map=<0 &shintc evt2irq(0x2a0)>, What is evt2irq? We only allow simple defines for DT files, not complex macros. Spaces around the '=' also needed. > + <1 &shintc evt2irq(0x2c0)>, > + <2 &shintc evt2irq(0x2e0)>, > + <3 &shintc evt2irq(0x300)>, > + <4 &shintc evt2irq(0x320)>, > + <5 &shintc evt2irq(0x340)>, > + <6 &shintc evt2irq(0x360)>, > + <7 &shintc evt2irq(0x380)>; > + }; ^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH v5 20/22] sh: IO-DATA HDL-U (a.k.a landisk) DeviceTree [not found] <1467564402-2649-1-git-send-email-ysato@users.sourceforge.jp> ` (2 preceding siblings ...) 2016-07-03 16:46 ` [PATCH v5 19/22] sh: IO-DATA HDL-U (a.k.a landisk) IRQCHIP driver Yoshinori Sato @ 2016-07-03 16:46 ` Yoshinori Sato 2016-07-03 19:00 ` Sergei Shtylyov 2016-07-03 16:46 ` [PATCH v5 21/22] sh: Renesas RTS7751R2Dplus (a.k.a R2Dplus) IRQCHIP Driver Yoshinori Sato 2016-07-03 16:46 ` [PATCH v5 22/22] sh: Renesas RTS7751R2Dplus (a,k.a R2Dplus) DeviceTree Yoshinori Sato 5 siblings, 1 reply; 13+ messages in thread From: Yoshinori Sato @ 2016-07-03 16:46 UTC (permalink / raw) To: devicetree, linux-sh, linux-kernel; +Cc: Yoshinori Sato Signed-off-by: Yoshinori Sato <ysato@users.sourceforge.jp> --- arch/sh/boot/dts/Makefile | 2 ++ arch/sh/boot/dts/landisk.dts | 61 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+) create mode 100644 arch/sh/boot/dts/landisk.dts diff --git a/arch/sh/boot/dts/Makefile b/arch/sh/boot/dts/Makefile index 38fdc38..cf5aec4 100644 --- a/arch/sh/boot/dts/Makefile +++ b/arch/sh/boot/dts/Makefile @@ -1,5 +1,7 @@ obj-$(CONFIG_USE_BUILTIN_DTB) += $(patsubst "%",%,$(CONFIG_BUILTIN_DTB_SOURCE)).dtb.o +dtb-y += landisk.dtb + dtstree := $(srctree)/$(src) clean-files := *.dtb.S always := $(dtb-y) diff --git a/arch/sh/boot/dts/landisk.dts b/arch/sh/boot/dts/landisk.dts new file mode 100644 index 0000000..3745ae0 --- /dev/null +++ b/arch/sh/boot/dts/landisk.dts @@ -0,0 +1,61 @@ +/dts-v1/; + +#include "sh7751.dtsi" + +/ { + model = "iodata,HDL-U"; + compatible = "iodata,hdl-u"; + #address-cells = <1>; + #size-cells = <1>; + interrupt-parent = <&shintc>; + chosen { + stdout-path = "serial1:115200n8"; + }; + aliases { + serial0 = &sci0; + serial1 = &sci1; + }; + + memory@0c000000 { + device_type = "memory"; + reg = <0x0c000000 0x4000000>; + }; + + cpldintc: cpld@b0000000 { + compatible = "iodata,landisk-intc"; + #interrupt-cells = <1>; + #address-cells = <0>; + reg = <0xb0000000 8>; + interrupt-map=<0 &shintc evt2irq(0x2a0)>, + <1 &shintc evt2irq(0x2c0)>, + <2 &shintc evt2irq(0x2e0)>, + <3 &shintc evt2irq(0x300)>, + <4 &shintc evt2irq(0x320)>, + <5 &shintc evt2irq(0x340)>, + <6 &shintc evt2irq(0x360)>, + <7 &shintc evt2irq(0x380)>; + }; +}; + +&oclk { + clock-frequency = <22222222>; +}; + +&sci0 { + status = "ok"; +}; + +&sci1 { + status = "ok"; +}; + +&pci { + compatible = "renesas,sh7751-pci", "iodata,landisk-pci"; + interrupt-map-mask = <0x1800 0 7>; + interrupt-map = <0x0000 0 1 &cpldintc 0>, + <0x0800 0 1 &cpldintc 1>, + <0x1000 0 1 &cpldintc 2>, + <0x1000 0 2 &cpldintc 3>, + <0x1000 0 3 &cpldintc 0>; + status = "ok"; +}; -- 2.7.0 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH v5 20/22] sh: IO-DATA HDL-U (a.k.a landisk) DeviceTree 2016-07-03 16:46 ` [PATCH v5 20/22] sh: IO-DATA HDL-U (a.k.a landisk) DeviceTree Yoshinori Sato @ 2016-07-03 19:00 ` Sergei Shtylyov 2016-07-06 16:18 ` Yoshinori Sato 0 siblings, 1 reply; 13+ messages in thread From: Sergei Shtylyov @ 2016-07-03 19:00 UTC (permalink / raw) To: Yoshinori Sato, devicetree, linux-sh, linux-kernel Hello. On 07/03/2016 07:46 PM, Yoshinori Sato wrote: > Signed-off-by: Yoshinori Sato <ysato@users.sourceforge.jp> [...] > diff --git a/arch/sh/boot/dts/landisk.dts b/arch/sh/boot/dts/landisk.dts > new file mode 100644 > index 0000000..3745ae0 > --- /dev/null > +++ b/arch/sh/boot/dts/landisk.dts > @@ -0,0 +1,61 @@ [...] > +&oclk { > + clock-frequency = <22222222>; > +}; > + > +&sci0 { > + status = "ok"; Should be "okay". Sorry for overlooking it. > +}; > + > +&sci1 { > + status = "ok"; Likewise. [...] MBR, Sergei ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v5 20/22] sh: IO-DATA HDL-U (a.k.a landisk) DeviceTree 2016-07-03 19:00 ` Sergei Shtylyov @ 2016-07-06 16:18 ` Yoshinori Sato 0 siblings, 0 replies; 13+ messages in thread From: Yoshinori Sato @ 2016-07-06 16:18 UTC (permalink / raw) To: Sergei Shtylyov; +Cc: devicetree, linux-sh, linux-kernel On Mon, 04 Jul 2016 04:00:59 +0900, Sergei Shtylyov wrote: > > Hello. > > On 07/03/2016 07:46 PM, Yoshinori Sato wrote: > > > Signed-off-by: Yoshinori Sato <ysato@users.sourceforge.jp> > > [...] > > > diff --git a/arch/sh/boot/dts/landisk.dts b/arch/sh/boot/dts/landisk.dts > > new file mode 100644 > > index 0000000..3745ae0 > > --- /dev/null > > +++ b/arch/sh/boot/dts/landisk.dts > > @@ -0,0 +1,61 @@ > [...] > > +&oclk { > > + clock-frequency = <22222222>; > > +}; > > + > > +&sci0 { > > + status = "ok"; > > Should be "okay". Sorry for overlooking it. > > > +}; > > + > > +&sci1 { > > + status = "ok"; > > Likewise. > > [...] > > MBR, Sergei > Updated. Thanks. > -- > To unsubscribe from this list: send the line "unsubscribe linux-sh" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html -- Yoshinori Sato <ysato@users.sourceforge.jp> ^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH v5 21/22] sh: Renesas RTS7751R2Dplus (a.k.a R2Dplus) IRQCHIP Driver [not found] <1467564402-2649-1-git-send-email-ysato@users.sourceforge.jp> ` (3 preceding siblings ...) 2016-07-03 16:46 ` [PATCH v5 20/22] sh: IO-DATA HDL-U (a.k.a landisk) DeviceTree Yoshinori Sato @ 2016-07-03 16:46 ` Yoshinori Sato 2016-07-03 16:46 ` [PATCH v5 22/22] sh: Renesas RTS7751R2Dplus (a,k.a R2Dplus) DeviceTree Yoshinori Sato 5 siblings, 0 replies; 13+ messages in thread From: Yoshinori Sato @ 2016-07-03 16:46 UTC (permalink / raw) To: devicetree, linux-sh, linux-kernel; +Cc: Yoshinori Sato Signed-off-by: Yoshinori Sato <ysato@users.sourceforge.jp> --- .../interrupt-controller/renesas-r2dplus.txt | 38 ++++++++++ drivers/irqchip/Makefile | 2 +- drivers/irqchip/irq-renesas-r2dplus.c | 88 ++++++++++++++++++++++ 3 files changed, 127 insertions(+), 1 deletion(-) create mode 100644 Documentation/devicetree/bindings/interrupt-controller/renesas-r2dplus.txt create mode 100644 drivers/irqchip/irq-renesas-r2dplus.c diff --git a/Documentation/devicetree/bindings/interrupt-controller/renesas-r2dplus.txt b/Documentation/devicetree/bindings/interrupt-controller/renesas-r2dplus.txt new file mode 100644 index 0000000..5b74da4 --- /dev/null +++ b/Documentation/devicetree/bindings/interrupt-controller/renesas-r2dplus.txt @@ -0,0 +1,38 @@ +DT bindings for the Renesas R0P751RLC0011RL (R2Dplus) interrupt controller + +Required properties: + + - compatible: has to be "renesas,r2dplus-intc". + + - reg: Base address and length of interrupt controller register. + + - #interrupt-cells: has to be <1>: an interrupt index. + + - #address-cells: has to be <0> + + - interrupt-map: Interrupt mapping on parent controller. + +Example +------- + + fpgaintc: fpga@a4000000 { + compatible = "renesas,r2dplus-intc"; + #interrupt-cells = <1>; + #address-cells = <0>; + reg = <0xa4000000 0x40>; + interrupt-map=<0 &shintc evt2irq(0x200)>, + <1 &shintc evt2irq(0x220)>, + <2 &shintc evt2irq(0x240)>, + <3 &shintc evt2irq(0x260)>, + <4 &shintc evt2irq(0x280)>, + <5 &shintc evt2irq(0x2a0)>, + <6 &shintc evt2irq(0x2c0)>, + <7 &shintc evt2irq(0x2e0)>, + <8 &shintc evt2irq(0x300)>, + <9 &shintc evt2irq(0x320)>, + <10 &shintc evt2irq(0x340)>, + <11 &shintc evt2irq(0x360)>, + <12 &shintc evt2irq(0x380)>, + <13 &shintc evt2irq(0x3a0)>, + <14 &shintc evt2irq(0x3c0)>, + }; diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile index 5e225cf..1e0f1c3 100644 --- a/drivers/irqchip/Makefile +++ b/drivers/irqchip/Makefile @@ -69,4 +69,4 @@ obj-$(CONFIG_PIC32_EVIC) += irq-pic32-evic.o obj-$(CONFIG_MVEBU_ODMI) += irq-mvebu-odmi.o obj-$(CONFIG_LS_SCFG_MSI) += irq-ls-scfg-msi.o obj-$(CONFIG_EZNPS_GIC) += irq-eznps.o -obj-$(CONFIG_RENESAS_SH_INTC) += irq-renesas-sh7751.o irq-io-landisk.o +obj-$(CONFIG_RENESAS_SH_INTC) += irq-renesas-sh7751.o irq-io-landisk.o irq-renesas-r2dplus.o diff --git a/drivers/irqchip/irq-renesas-r2dplus.c b/drivers/irqchip/irq-renesas-r2dplus.c new file mode 100644 index 0000000..3f80775 --- /dev/null +++ b/drivers/irqchip/irq-renesas-r2dplus.c @@ -0,0 +1,88 @@ +/* + * Renesas RTS7751R2D+ FPGA IRQ driver + * + * Copyright 2016 Yoshinori Sato <ysato@users.sourceforge.jp> + */ + +#include <linux/init.h> +#include <linux/irq.h> +#include <linux/irqchip.h> +#include <linux/irqdomain.h> +#include <linux/of_address.h> +#include <linux/of_irq.h> +#include <linux/io.h> + +static const u16 mask_bit[] = { + BIT(11), + BIT(9), + BIT(8), + BIT(12), + BIT(10), + BIT(6), + BIT(5), + BIT(4), + BIT(7), + BIT(14), + BIT(13), + BIT(0), + BIT(15), +}; + +static void r2dplus_mask_irq(struct irq_data *data) +{ + u16 mask = __raw_readw(data->chip_data); + + mask &= ~mask_bit[data->irq]; + __raw_writew(mask, data->chip_data); +} + +static void r2dplus_unmask_irq(struct irq_data *data) +{ + u16 mask = __raw_readw(data->chip_data); + + mask |= mask_bit[data->irq]; + __raw_writew(mask, data->chip_data); +} + +static struct irq_chip fpga_irq_chip = { + .name = "R2DPLUS-FPGA", + .irq_unmask = r2dplus_unmask_irq, + .irq_mask = r2dplus_mask_irq, +}; + +static int fpga_map(struct irq_domain *d, unsigned int virq, + irq_hw_number_t hw_irq_num) +{ + irq_set_chip_and_handler(virq, &fpga_irq_chip, + handle_simple_irq); + irq_set_chip_data(virq, d->host_data); + + return 0; +} + +static struct irq_domain_ops irq_ops = { + .xlate = irq_domain_xlate_onecell, + .map = fpga_map, +}; + +static int __init r2dplus_intc_of_init(struct device_node *intc, + struct device_node *parent) +{ + struct irq_domain *domain, *pdomain; + int num_irqpin; + void *baseaddr; + + baseaddr = of_iomap(intc, 0); + pdomain = irq_find_host(parent); + of_get_property(intc, "interrupt-map", &num_irqpin); + num_irqpin /= sizeof(u32) * 3; + domain = irq_domain_create_hierarchy(pdomain, 0, num_irqpin, + of_node_to_fwnode(intc), + &irq_ops, baseaddr); + if (!domain) + panic("%s: unable to create IRQ domain\n", intc->full_name); + irq_domain_associate_many(domain, 0, 0, 16); + return 0; +} + +IRQCHIP_DECLARE(cpld_intc, "renesas,r2dplus-intc", r2dplus_intc_of_init); -- 2.7.0 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v5 22/22] sh: Renesas RTS7751R2Dplus (a,k.a R2Dplus) DeviceTree [not found] <1467564402-2649-1-git-send-email-ysato@users.sourceforge.jp> ` (4 preceding siblings ...) 2016-07-03 16:46 ` [PATCH v5 21/22] sh: Renesas RTS7751R2Dplus (a.k.a R2Dplus) IRQCHIP Driver Yoshinori Sato @ 2016-07-03 16:46 ` Yoshinori Sato 5 siblings, 0 replies; 13+ messages in thread From: Yoshinori Sato @ 2016-07-03 16:46 UTC (permalink / raw) To: devicetree, linux-sh, linux-kernel; +Cc: Yoshinori Sato Signed-off-by: Yoshinori Sato <ysato@users.sourceforge.jp> --- arch/sh/boot/dts/Makefile | 1 + arch/sh/boot/dts/r2dplus.dts | 85 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 86 insertions(+) create mode 100644 arch/sh/boot/dts/r2dplus.dts diff --git a/arch/sh/boot/dts/Makefile b/arch/sh/boot/dts/Makefile index cf5aec4..e059ce2b 100644 --- a/arch/sh/boot/dts/Makefile +++ b/arch/sh/boot/dts/Makefile @@ -1,6 +1,7 @@ obj-$(CONFIG_USE_BUILTIN_DTB) += $(patsubst "%",%,$(CONFIG_BUILTIN_DTB_SOURCE)).dtb.o dtb-y += landisk.dtb +otb-y += r2dplus.dtb dtstree := $(srctree)/$(src) clean-files := *.dtb.S diff --git a/arch/sh/boot/dts/r2dplus.dts b/arch/sh/boot/dts/r2dplus.dts new file mode 100644 index 0000000..f9c01f9 --- /dev/null +++ b/arch/sh/boot/dts/r2dplus.dts @@ -0,0 +1,85 @@ +/dts-v1/; + +#include "sh7751.dtsi" + +/ { + model = "renesas,RTS7751R2D+"; + compatible = "renesas,r2dplus"; + #address-cells = <1>; + #size-cells = <1>; + interrupt-parent = <&shintc>; + chosen { + stdout-path = "serial1:115200n8"; + }; + aliases { + serial1 = &sci1; + }; + + memory@0c000000 { + device_type = "memory"; + reg = <0x0c000000 0x4000000>; + }; + + fpgaintc: fpga@a4000000 { + compatible = "renesas,r2dplus-intc"; + #interrupt-cells = <1>; + #address-cells = <0>; + reg = <0xa4000000 0x40>; + interrupt-map=<0 &shintc evt2irq(0x200)>, + <1 &shintc evt2irq(0x220)>, + <2 &shintc evt2irq(0x240)>, + <3 &shintc evt2irq(0x260)>, + <4 &shintc evt2irq(0x280)>, + <5 &shintc evt2irq(0x2a0)>, + <6 &shintc evt2irq(0x2c0)>, + <7 &shintc evt2irq(0x2e0)>, + <8 &shintc evt2irq(0x300)>, + <9 &shintc evt2irq(0x320)>, + <10 &shintc evt2irq(0x340)>, + <11 &shintc evt2irq(0x360)>, + <12 &shintc evt2irq(0x380)>, + <13 &shintc evt2irq(0x3a0)>, + <14 &shintc evt2irq(0x3c0)>; + }; + + ide: ide@b4001000 { + compatible = "ata-generic"; + reg = <0xb4001000 0x10>, <0xb400080c 0x02>; + interrupt-parent = <&fpgaintc>; + interrupts = <1 0>; + reg-shift = <1>; + pio-mode = <0>; + }; + + sm501: display@13e00000 { + compatible = "smi,sm501"; + reg = <0x10000000 0x13dfffff>, <0x13e00000 0x13ffffff>; + interrupt-parent = <&fpgaintc>; + interrupts = <4 0>; + mode = "640x480-16@60"; + edid = [00 ff ff ff ff ff ff 00 04 21 00 00 00 00 00 00 + 01 00 01 04 00 00 00 00 08 00 00 00 00 00 00 00 + 00 00 00 20 00 00 01 40 01 00 01 00 01 00 01 00 + 01 00 01 00 01 00 d6 09 80 a0 20 e0 2d 10 10 60 + a2 00 00 00 00 00 00 00 00 00 00 10 00 00 00 00 + 00 00 00 00 00 00 00 00 00 00 00 00 00 10 00 00 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 fd]; + smi,devices = <1>; + }; +}; + +&oclk { + clock-frequency = <60000000>; +}; + +&sci1 { + status = "ok"; +}; + +&pci { + compatible = "renesas,sh7751-pci", "renesas.r2dplus-pci"; + interrupt-map-mask = <0x1800 0 7>; + interrupt-map = <0x1000 0 1 &fpgaintc 3 0>; + status = "ok"; +}; -- 2.7.0 ^ permalink raw reply related [flat|nested] 13+ messages in thread
end of thread, other threads:[~2016-07-22 22:59 UTC | newest] Thread overview: 13+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- [not found] <1467564402-2649-1-git-send-email-ysato@users.sourceforge.jp> [not found] ` <1467564402-2649-1-git-send-email-ysato-Rn4VEauK+AKRv+LV9MX5uooqe+aC9MnS@public.gmane.org> 2016-07-03 16:46 ` [PATCH v6 12/22] sh: Add PCI host bridge driver for SH7751 Yoshinori Sato 2016-07-05 15:53 ` Rob Herring 2016-07-06 16:19 ` Yoshinori Sato [not found] ` <1467564402-2649-13-git-send-email-ysato-Rn4VEauK+AKRv+LV9MX5uooqe+aC9MnS@public.gmane.org> 2016-07-22 22:59 ` Bjorn Helgaas 2016-07-03 16:46 ` [PATCH v5 13/22] sh: irqchip: SH7751 IRQCHIP Driver Yoshinori Sato 2016-07-03 16:46 ` [PATCH v5 14/22] sh: SH7751 core dtsi Yoshinori Sato 2016-07-03 16:46 ` [PATCH v5 19/22] sh: IO-DATA HDL-U (a.k.a landisk) IRQCHIP driver Yoshinori Sato 2016-07-11 14:02 ` Rob Herring 2016-07-03 16:46 ` [PATCH v5 20/22] sh: IO-DATA HDL-U (a.k.a landisk) DeviceTree Yoshinori Sato 2016-07-03 19:00 ` Sergei Shtylyov 2016-07-06 16:18 ` Yoshinori Sato 2016-07-03 16:46 ` [PATCH v5 21/22] sh: Renesas RTS7751R2Dplus (a.k.a R2Dplus) IRQCHIP Driver Yoshinori Sato 2016-07-03 16:46 ` [PATCH v5 22/22] sh: Renesas RTS7751R2Dplus (a,k.a R2Dplus) DeviceTree Yoshinori Sato
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).