diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-11-25 17:42:56 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-11-25 17:42:56 -0800 |
commit | 2981dcf333b37e3753b5c1b5814418c4de1a8e34 (patch) | |
tree | 7b082d99452fb90fd39dd619cb5c65bd66c979c6 /arch/mips/sgi-ip30/ip30-xtalk.c | |
parent | Merge tag 'm68k-for-v5.5-tag1' of git://git.kernel.org/pub/scm/linux/kernel/git/geert/linux-m68k (diff) | |
parent | MIPS: SGI-IP27: Enable ethernet phy on second Origin 200 module (diff) | |
download | linux-dev-2981dcf333b37e3753b5c1b5814418c4de1a8e34.tar.xz linux-dev-2981dcf333b37e3753b5c1b5814418c4de1a8e34.zip |
Merge tag 'mips_5.5' of git://git.kernel.org/pub/scm/linux/kernel/git/mips/linux
Pull MIPS updates from Paul Burton:
"The main MIPS changes for 5.5:
- Atomics-related code sees some rework & cleanup, most notably
allowing Loongson LL/SC errata workarounds to be more bulletproof &
their correctness to be checked at build time.
- Command line setup code is simplified somewhat, resolving various
corner cases.
- MIPS kernels can now be built with kcov code coverage support.
- We can now build with CONFIG_FORTIFY_SOURCE=y.
- Miscellaneous cleanups.
And some platform specific changes:
- We now disable some broken TLB functionality on certain Ingenic
systems, and JZ4780 systems gain some devicetree nodes to support
more devices.
- Loongson support sees a number of cleanups, and we gain initial
support for Loongson 3A R4 systems.
- We gain support for MediaTek MT7688-based GARDENA Smart Gateway
systems.
- SGI IP27 (Origin 2*) see a number of fixes, cleanups &
simplifications.
- SGI IP30 (Octane) systems are now supported"
* tag 'mips_5.5' of git://git.kernel.org/pub/scm/linux/kernel/git/mips/linux: (107 commits)
MIPS: SGI-IP27: Enable ethernet phy on second Origin 200 module
MIPS: PCI: Fix fake subdevice ID for IOC3
MIPS: Ingenic: Disable abandoned HPTLB function.
MIPS: PCI: remember nasid changed by set interrupt affinity
MIPS: SGI-IP27: Fix crash, when CPUs are disabled via nr_cpus parameter
mips: add support for folded p4d page tables
mips: drop __pXd_offset() macros that duplicate pXd_index() ones
mips: fix build when "48 bits virtual memory" is enabled
MIPS: math-emu: Reuse name array in debugfs_fpuemu()
MIPS: allow building with kcov coverage
MIPS: Loongson64: Drop setup_pcimap
MIPS: Loongson2ef: Convert to early_printk_8250
MIPS: Drop CPU_SUPPORTS_UNCACHED_ACCELERATED
MIPS: Loongson{2ef, 32, 64} convert to generic fw cmdline
MIPS: Drop pmon.h
MIPS: Loongson: Unify LOONGSON3/LOONGSON64 Kconfig usage
MIPS: Loongson: Rename LOONGSON1 to LOONGSON32
MIPS: Loongson: Fix return value of loongson_hwmon_init
MIPS: add support for SGI Octane (IP30)
MIPS: PCI: make phys_to_dma/dma_to_phys for pci-xtalk-bridge common
...
Diffstat (limited to 'arch/mips/sgi-ip30/ip30-xtalk.c')
-rw-r--r-- | arch/mips/sgi-ip30/ip30-xtalk.c | 152 |
1 files changed, 152 insertions, 0 deletions
diff --git a/arch/mips/sgi-ip30/ip30-xtalk.c b/arch/mips/sgi-ip30/ip30-xtalk.c new file mode 100644 index 000000000000..8a2894645529 --- /dev/null +++ b/arch/mips/sgi-ip30/ip30-xtalk.c @@ -0,0 +1,152 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * ip30-xtalk.c - Very basic Crosstalk (XIO) detection support. + * Copyright (C) 2004-2007 Stanislaw Skowronek <skylark@unaligned.org> + * Copyright (C) 2009 Johannes Dickgreber <tanzy@gmx.de> + * Copyright (C) 2007, 2014-2016 Joshua Kinard <kumba@gentoo.org> + */ + +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/platform_device.h> +#include <linux/platform_data/sgi-w1.h> +#include <linux/platform_data/xtalk-bridge.h> + +#include <asm/xtalk/xwidget.h> +#include <asm/pci/bridge.h> + +#define IP30_SWIN_BASE(widget) \ + (0x0000000010000000 | (((unsigned long)(widget)) << 24)) + +#define IP30_RAW_SWIN_BASE(widget) (IO_BASE + IP30_SWIN_BASE(widget)) + +#define IP30_SWIN_SIZE (1 << 24) + +#define IP30_WIDGET_XBOW _AC(0x0, UL) /* XBow is always 0 */ +#define IP30_WIDGET_HEART _AC(0x8, UL) /* HEART is always 8 */ +#define IP30_WIDGET_PCI_BASE _AC(0xf, UL) /* BaseIO PCI is always 15 */ + +#define XTALK_NODEV 0xffffffff + +#define XBOW_REG_LINK_STAT_0 0x114 +#define XBOW_REG_LINK_BLK_SIZE 0x40 +#define XBOW_REG_LINK_ALIVE 0x80000000 + +#define HEART_INTR_ADDR 0x00000080 + +#define xtalk_read __raw_readl + +static void bridge_platform_create(int widget, int masterwid) +{ + struct xtalk_bridge_platform_data *bd; + struct sgi_w1_platform_data *wd; + struct platform_device *pdev; + struct resource w1_res; + + wd = kzalloc(sizeof(*wd), GFP_KERNEL); + if (!wd) + goto no_mem; + + snprintf(wd->dev_id, sizeof(wd->dev_id), "bridge-%012lx", + IP30_SWIN_BASE(widget)); + + memset(&w1_res, 0, sizeof(w1_res)); + w1_res.start = IP30_SWIN_BASE(widget) + + offsetof(struct bridge_regs, b_nic); + w1_res.end = w1_res.start + 3; + w1_res.flags = IORESOURCE_MEM; + + pdev = platform_device_alloc("sgi_w1", PLATFORM_DEVID_AUTO); + if (!pdev) { + kfree(wd); + goto no_mem; + } + platform_device_add_resources(pdev, &w1_res, 1); + platform_device_add_data(pdev, wd, sizeof(*wd)); + platform_device_add(pdev); + + bd = kzalloc(sizeof(*bd), GFP_KERNEL); + if (!bd) + goto no_mem; + pdev = platform_device_alloc("xtalk-bridge", PLATFORM_DEVID_AUTO); + if (!pdev) { + kfree(bd); + goto no_mem; + } + + bd->bridge_addr = IP30_RAW_SWIN_BASE(widget); + bd->intr_addr = HEART_INTR_ADDR; + bd->nasid = 0; + bd->masterwid = masterwid; + + bd->mem.name = "Bridge PCI MEM"; + bd->mem.start = IP30_SWIN_BASE(widget) + BRIDGE_DEVIO0; + bd->mem.end = IP30_SWIN_BASE(widget) + IP30_SWIN_SIZE - 1; + bd->mem.flags = IORESOURCE_MEM; + bd->mem_offset = IP30_SWIN_BASE(widget); + + bd->io.name = "Bridge PCI IO"; + bd->io.start = IP30_SWIN_BASE(widget) + BRIDGE_DEVIO0; + bd->io.end = IP30_SWIN_BASE(widget) + IP30_SWIN_SIZE - 1; + bd->io.flags = IORESOURCE_IO; + bd->io_offset = IP30_SWIN_BASE(widget); + + platform_device_add_data(pdev, bd, sizeof(*bd)); + platform_device_add(pdev); + pr_info("xtalk:%x bridge widget\n", widget); + return; + +no_mem: + pr_warn("xtalk:%x bridge create out of memory\n", widget); +} + +static unsigned int __init xbow_widget_active(s8 wid) +{ + unsigned int link_stat; + + link_stat = xtalk_read((void *)(IP30_RAW_SWIN_BASE(IP30_WIDGET_XBOW) + + XBOW_REG_LINK_STAT_0 + + XBOW_REG_LINK_BLK_SIZE * + (wid - 8))); + + return (link_stat & XBOW_REG_LINK_ALIVE) ? 1 : 0; +} + +static void __init xtalk_init_widget(s8 wid, s8 masterwid) +{ + xwidget_part_num_t partnum; + widgetreg_t widget_id; + + if (!xbow_widget_active(wid)) + return; + + widget_id = xtalk_read((void *)(IP30_RAW_SWIN_BASE(wid) + WIDGET_ID)); + + partnum = XWIDGET_PART_NUM(widget_id); + + switch (partnum) { + case BRIDGE_WIDGET_PART_NUM: + case XBRIDGE_WIDGET_PART_NUM: + bridge_platform_create(wid, masterwid); + break; + default: + pr_info("xtalk:%x unknown widget (0x%x)\n", wid, partnum); + break; + } +} + +static int __init ip30_xtalk_init(void) +{ + int i; + + /* + * Walk widget IDs backwards so that BaseIO is probed first. This + * ensures that the BaseIO IOC3 is always detected as eth0. + */ + for (i = IP30_WIDGET_PCI_BASE; i > IP30_WIDGET_HEART; i--) + xtalk_init_widget(i, IP30_WIDGET_HEART); + + return 0; +} + +arch_initcall(ip30_xtalk_init); |