aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/txx9
diff options
context:
space:
mode:
authorWe-unite <3205135446@qq.com>2025-03-08 22:04:20 +0800
committerWe-unite <3205135446@qq.com>2025-03-08 22:04:20 +0800
commita07bb8fd1299070229f0e8f3dcb57ffd5ef9870a (patch)
tree84f21bd0bf7071bc5fc7dd989e77d7ceb5476682 /arch/mips/txx9
downloadohosKernel-a07bb8fd1299070229f0e8f3dcb57ffd5ef9870a.tar.gz
ohosKernel-a07bb8fd1299070229f0e8f3dcb57ffd5ef9870a.zip
Initial commit: OpenHarmony-v4.0-ReleaseOpenHarmony-v4.0-Release
Diffstat (limited to 'arch/mips/txx9')
-rw-r--r--arch/mips/txx9/Kconfig128
-rw-r--r--arch/mips/txx9/Makefile18
-rw-r--r--arch/mips/txx9/Platform7
-rw-r--r--arch/mips/txx9/generic/7segled.c123
-rw-r--r--arch/mips/txx9/generic/Makefile14
-rw-r--r--arch/mips/txx9/generic/irq_tx3927.c25
-rw-r--r--arch/mips/txx9/generic/irq_tx4927.c49
-rw-r--r--arch/mips/txx9/generic/irq_tx4938.c37
-rw-r--r--arch/mips/txx9/generic/irq_tx4939.c216
-rw-r--r--arch/mips/txx9/generic/mem_tx4927.c75
-rw-r--r--arch/mips/txx9/generic/pci.c432
-rw-r--r--arch/mips/txx9/generic/setup.c965
-rw-r--r--arch/mips/txx9/generic/setup_tx3927.c136
-rw-r--r--arch/mips/txx9/generic/setup_tx4927.c337
-rw-r--r--arch/mips/txx9/generic/setup_tx4938.c485
-rw-r--r--arch/mips/txx9/generic/setup_tx4939.c568
-rw-r--r--arch/mips/txx9/generic/smsc_fdc37m81x.c169
-rw-r--r--arch/mips/txx9/generic/spi_eeprom.c104
-rw-r--r--arch/mips/txx9/jmr3927/Makefile6
-rw-r--r--arch/mips/txx9/jmr3927/irq.c128
-rw-r--r--arch/mips/txx9/jmr3927/prom.c52
-rw-r--r--arch/mips/txx9/jmr3927/setup.c223
-rw-r--r--arch/mips/txx9/rbtx4927/Makefile2
-rw-r--r--arch/mips/txx9/rbtx4927/irq.c198
-rw-r--r--arch/mips/txx9/rbtx4927/prom.c42
-rw-r--r--arch/mips/txx9/rbtx4927/setup.c380
-rw-r--r--arch/mips/txx9/rbtx4938/Makefile2
-rw-r--r--arch/mips/txx9/rbtx4938/irq.c157
-rw-r--r--arch/mips/txx9/rbtx4938/prom.c22
-rw-r--r--arch/mips/txx9/rbtx4938/setup.c372
-rw-r--r--arch/mips/txx9/rbtx4939/Makefile2
-rw-r--r--arch/mips/txx9/rbtx4939/irq.c95
-rw-r--r--arch/mips/txx9/rbtx4939/prom.c29
-rw-r--r--arch/mips/txx9/rbtx4939/setup.c554
34 files changed, 6152 insertions, 0 deletions
diff --git a/arch/mips/txx9/Kconfig b/arch/mips/txx9/Kconfig
new file mode 100644
index 000000000..85c4c121c
--- /dev/null
+++ b/arch/mips/txx9/Kconfig
@@ -0,0 +1,128 @@
1# SPDX-License-Identifier: GPL-2.0
2config MACH_TX39XX
3 bool
4 select MACH_TXX9
5 select SYS_HAS_CPU_TX39XX
6
7config MACH_TX49XX
8 bool
9 select MACH_TXX9
10 select CEVT_R4K
11 select CSRC_R4K
12 select IRQ_MIPS_CPU
13 select SYS_HAS_CPU_TX49XX
14 select SYS_SUPPORTS_64BIT_KERNEL
15
16config MACH_TXX9
17 bool
18 select DMA_NONCOHERENT
19 select SWAP_IO_SPACE
20 select SYS_HAS_EARLY_PRINTK
21 select SYS_SUPPORTS_32BIT_KERNEL
22 select SYS_SUPPORTS_LITTLE_ENDIAN
23 select SYS_SUPPORTS_BIG_ENDIAN
24 select COMMON_CLK
25
26config TOSHIBA_JMR3927
27 bool "Toshiba JMR-TX3927 board"
28 depends on MACH_TX39XX
29 select SOC_TX3927
30
31config TOSHIBA_RBTX4927
32 bool "Toshiba RBTX49[23]7 board"
33 depends on MACH_TX49XX
34 select SOC_TX4927
35 # TX4937 is subset of TX4938
36 select SOC_TX4938
37 help
38 This Toshiba board is based on the TX4927 processor. Say Y here to
39 support this machine type
40
41config TOSHIBA_RBTX4938
42 bool "Toshiba RBTX4938 board"
43 depends on MACH_TX49XX
44 select SOC_TX4938
45 help
46 This Toshiba board is based on the TX4938 processor. Say Y here to
47 support this machine type
48
49config TOSHIBA_RBTX4939
50 bool "Toshiba RBTX4939 board"
51 depends on MACH_TX49XX
52 select SOC_TX4939
53 select TXX9_7SEGLED
54 help
55 This Toshiba board is based on the TX4939 processor. Say Y here to
56 support this machine type
57
58config SOC_TX3927
59 bool
60 select CEVT_TXX9
61 imply HAS_TXX9_SERIAL
62 select HAVE_PCI
63 select IRQ_TXX9
64 select GPIO_TXX9
65
66config SOC_TX4927
67 bool
68 select CEVT_TXX9
69 imply HAS_TXX9_SERIAL
70 select HAVE_PCI
71 select IRQ_TXX9
72 select PCI_TX4927
73 select GPIO_TXX9
74 imply HAS_TXX9_ACLC
75
76config SOC_TX4938
77 bool
78 select CEVT_TXX9
79 imply HAS_TXX9_SERIAL
80 select HAVE_PCI
81 select IRQ_TXX9
82 select PCI_TX4927
83 select GPIO_TXX9
84 imply HAS_TXX9_ACLC
85
86config SOC_TX4939
87 bool
88 select CEVT_TXX9
89 imply HAS_TXX9_SERIAL
90 select HAVE_PCI
91 select PCI_TX4927
92 imply HAS_TXX9_ACLC
93
94config TXX9_7SEGLED
95 bool
96
97config TOSHIBA_FPCIB0
98 bool "FPCIB0 Backplane Support"
99 depends on PCI && MACH_TXX9
100 select I8259
101
102config PICMG_PCI_BACKPLANE_DEFAULT
103 bool "Support for PICMG PCI Backplane"
104 depends on PCI && MACH_TXX9
105 default y if !TOSHIBA_FPCIB0
106
107if TOSHIBA_RBTX4938
108
109comment "Multiplex Pin Select"
110choice
111 prompt "PIO[58:61]"
112 default TOSHIBA_RBTX4938_MPLEX_PIO58_61
113
114config TOSHIBA_RBTX4938_MPLEX_PIO58_61
115 bool "PIO"
116config TOSHIBA_RBTX4938_MPLEX_NAND
117 bool "NAND"
118config TOSHIBA_RBTX4938_MPLEX_ATA
119 bool "ATA"
120config TOSHIBA_RBTX4938_MPLEX_KEEP
121 bool "Keep firmware settings"
122
123endchoice
124
125endif
126
127config PCI_TX4927
128 bool
diff --git a/arch/mips/txx9/Makefile b/arch/mips/txx9/Makefile
new file mode 100644
index 000000000..195295937
--- /dev/null
+++ b/arch/mips/txx9/Makefile
@@ -0,0 +1,18 @@
1# SPDX-License-Identifier: GPL-2.0
2#
3# Common TXx9
4#
5obj-$(CONFIG_MACH_TX39XX) += generic/
6obj-$(CONFIG_MACH_TX49XX) += generic/
7
8#
9# Toshiba JMR-TX3927 board
10#
11obj-$(CONFIG_TOSHIBA_JMR3927) += jmr3927/
12
13#
14# Toshiba RBTX49XX boards
15#
16obj-$(CONFIG_TOSHIBA_RBTX4927) += rbtx4927/
17obj-$(CONFIG_TOSHIBA_RBTX4938) += rbtx4938/
18obj-$(CONFIG_TOSHIBA_RBTX4939) += rbtx4939/
diff --git a/arch/mips/txx9/Platform b/arch/mips/txx9/Platform
new file mode 100644
index 000000000..7f4429ba2
--- /dev/null
+++ b/arch/mips/txx9/Platform
@@ -0,0 +1,7 @@
1cflags-$(CONFIG_MACH_TX39XX) += \
2 -I$(srctree)/arch/mips/include/asm/mach-tx39xx
3cflags-$(CONFIG_MACH_TX49XX) += \
4 -I$(srctree)/arch/mips/include/asm/mach-tx49xx
5
6load-$(CONFIG_MACH_TX39XX) += 0xffffffff80050000
7load-$(CONFIG_MACH_TX49XX) += 0xffffffff80100000
diff --git a/arch/mips/txx9/generic/7segled.c b/arch/mips/txx9/generic/7segled.c
new file mode 100644
index 000000000..2203c2548
--- /dev/null
+++ b/arch/mips/txx9/generic/7segled.c
@@ -0,0 +1,123 @@
1/*
2 * 7 Segment LED routines
3 * Based on RBTX49xx patch from CELF patch archive.
4 *
5 * This file is subject to the terms and conditions of the GNU General Public
6 * License. See the file "COPYING" in the main directory of this archive
7 * for more details.
8 *
9 * (C) Copyright TOSHIBA CORPORATION 2005-2007
10 * All Rights Reserved.
11 */
12#include <linux/device.h>
13#include <linux/slab.h>
14#include <linux/map_to_7segment.h>
15#include <asm/txx9/generic.h>
16
17static unsigned int tx_7segled_num;
18static void (*tx_7segled_putc)(unsigned int pos, unsigned char val);
19
20void __init txx9_7segled_init(unsigned int num,
21 void (*putc)(unsigned int pos, unsigned char val))
22{
23 tx_7segled_num = num;
24 tx_7segled_putc = putc;
25}
26
27static SEG7_CONVERSION_MAP(txx9_seg7map, MAP_ASCII7SEG_ALPHANUM_LC);
28
29int txx9_7segled_putc(unsigned int pos, char c)
30{
31 if (pos >= tx_7segled_num)
32 return -EINVAL;
33 c = map_to_seg7(&txx9_seg7map, c);
34 if (c < 0)
35 return c;
36 tx_7segled_putc(pos, c);
37 return 0;
38}
39
40static ssize_t ascii_store(struct device *dev,
41 struct device_attribute *attr,
42 const char *buf, size_t size)
43{
44 unsigned int ch = dev->id;
45 txx9_7segled_putc(ch, buf[0]);
46 return size;
47}
48
49static ssize_t raw_store(struct device *dev,
50 struct device_attribute *attr,
51 const char *buf, size_t size)
52{
53 unsigned int ch = dev->id;
54 tx_7segled_putc(ch, buf[0]);
55 return size;
56}
57
58static DEVICE_ATTR_WO(ascii);
59static DEVICE_ATTR_WO(raw);
60
61static ssize_t map_seg7_show(struct device *dev,
62 struct device_attribute *attr,
63 char *buf)
64{
65 memcpy(buf, &txx9_seg7map, sizeof(txx9_seg7map));
66 return sizeof(txx9_seg7map);
67}
68
69static ssize_t map_seg7_store(struct device *dev,
70 struct device_attribute *attr,
71 const char *buf, size_t size)
72{
73 if (size != sizeof(txx9_seg7map))
74 return -EINVAL;
75 memcpy(&txx9_seg7map, buf, size);
76 return size;
77}
78
79static DEVICE_ATTR(map_seg7, 0600, map_seg7_show, map_seg7_store);
80
81static struct bus_type tx_7segled_subsys = {
82 .name = "7segled",
83 .dev_name = "7segled",
84};
85
86static void tx_7segled_release(struct device *dev)
87{
88 kfree(dev);
89}
90
91static int __init tx_7segled_init_sysfs(void)
92{
93 int error, i;
94 if (!tx_7segled_num)
95 return -ENODEV;
96 error = subsys_system_register(&tx_7segled_subsys, NULL);
97 if (error)
98 return error;
99 error = device_create_file(tx_7segled_subsys.dev_root, &dev_attr_map_seg7);
100 if (error)
101 return error;
102 for (i = 0; i < tx_7segled_num; i++) {
103 struct device *dev;
104 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
105 if (!dev) {
106 error = -ENODEV;
107 break;
108 }
109 dev->id = i;
110 dev->bus = &tx_7segled_subsys;
111 dev->release = &tx_7segled_release;
112 error = device_register(dev);
113 if (error) {
114 put_device(dev);
115 return error;
116 }
117 device_create_file(dev, &dev_attr_ascii);
118 device_create_file(dev, &dev_attr_raw);
119 }
120 return error;
121}
122
123device_initcall(tx_7segled_init_sysfs);
diff --git a/arch/mips/txx9/generic/Makefile b/arch/mips/txx9/generic/Makefile
new file mode 100644
index 000000000..6d00580fc
--- /dev/null
+++ b/arch/mips/txx9/generic/Makefile
@@ -0,0 +1,14 @@
1# SPDX-License-Identifier: GPL-2.0
2#
3# Makefile for common code for TXx9 based systems
4#
5
6obj-y += setup.o
7obj-$(CONFIG_PCI) += pci.o
8obj-$(CONFIG_SOC_TX3927) += setup_tx3927.o irq_tx3927.o
9obj-$(CONFIG_SOC_TX4927) += mem_tx4927.o setup_tx4927.o irq_tx4927.o
10obj-$(CONFIG_SOC_TX4938) += mem_tx4927.o setup_tx4938.o irq_tx4938.o
11obj-$(CONFIG_SOC_TX4939) += setup_tx4939.o irq_tx4939.o
12obj-$(CONFIG_TOSHIBA_FPCIB0) += smsc_fdc37m81x.o
13obj-$(CONFIG_SPI) += spi_eeprom.o
14obj-$(CONFIG_TXX9_7SEGLED) += 7segled.o
diff --git a/arch/mips/txx9/generic/irq_tx3927.c b/arch/mips/txx9/generic/irq_tx3927.c
new file mode 100644
index 000000000..c683f593e
--- /dev/null
+++ b/arch/mips/txx9/generic/irq_tx3927.c
@@ -0,0 +1,25 @@
1/*
2 * Common tx3927 irq handler
3 *
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file "COPYING" in the main directory of this archive
6 * for more details.
7 *
8 * Copyright 2001 MontaVista Software Inc.
9 * Copyright (C) 2000-2001 Toshiba Corporation
10 */
11#include <linux/init.h>
12#include <asm/txx9irq.h>
13#include <asm/txx9/tx3927.h>
14
15void __init tx3927_irq_init(void)
16{
17 int i;
18
19 txx9_irq_init(TX3927_IRC_REG);
20 /* raise priority for timers, sio */
21 for (i = 0; i < TX3927_NR_TMR; i++)
22 txx9_irq_set_pri(TX3927_IR_TMR(i), 6);
23 for (i = 0; i < TX3927_NR_SIO; i++)
24 txx9_irq_set_pri(TX3927_IR_SIO(i), 7);
25}
diff --git a/arch/mips/txx9/generic/irq_tx4927.c b/arch/mips/txx9/generic/irq_tx4927.c
new file mode 100644
index 000000000..ed8e702d4
--- /dev/null
+++ b/arch/mips/txx9/generic/irq_tx4927.c
@@ -0,0 +1,49 @@
1/*
2 * Common tx4927 irq handler
3 *
4 * Author: MontaVista Software, Inc.
5 * source@mvista.com
6 *
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 *
11 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
12 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
14 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
15 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
16 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
17 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
18 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
19 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
20 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
21 *
22 * You should have received a copy of the GNU General Public License along
23 * with this program; if not, write to the Free Software Foundation, Inc.,
24 * 675 Mass Ave, Cambridge, MA 02139, USA.
25 */
26#include <linux/init.h>
27#include <linux/interrupt.h>
28#include <linux/irq.h>
29#include <asm/irq_cpu.h>
30#include <asm/txx9/tx4927.h>
31
32void __init tx4927_irq_init(void)
33{
34 int i;
35
36 mips_cpu_irq_init();
37 txx9_irq_init(TX4927_IRC_REG & 0xfffffffffULL);
38 irq_set_chained_handler(MIPS_CPU_IRQ_BASE + TX4927_IRC_INT,
39 handle_simple_irq);
40 /* raise priority for errors, timers, SIO */
41 txx9_irq_set_pri(TX4927_IR_ECCERR, 7);
42 txx9_irq_set_pri(TX4927_IR_WTOERR, 7);
43 txx9_irq_set_pri(TX4927_IR_PCIERR, 7);
44 txx9_irq_set_pri(TX4927_IR_PCIPME, 7);
45 for (i = 0; i < TX4927_NUM_IR_TMR; i++)
46 txx9_irq_set_pri(TX4927_IR_TMR(i), 6);
47 for (i = 0; i < TX4927_NUM_IR_SIO; i++)
48 txx9_irq_set_pri(TX4927_IR_SIO(i), 5);
49}
diff --git a/arch/mips/txx9/generic/irq_tx4938.c b/arch/mips/txx9/generic/irq_tx4938.c
new file mode 100644
index 000000000..aace85653
--- /dev/null
+++ b/arch/mips/txx9/generic/irq_tx4938.c
@@ -0,0 +1,37 @@
1/*
2 * linux/arch/mips/tx4938/common/irq.c
3 *
4 * Common tx4938 irq handler
5 * Copyright (C) 2000-2001 Toshiba Corporation
6 *
7 * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the
8 * terms of the GNU General Public License version 2. This program is
9 * licensed "as is" without any warranty of any kind, whether express
10 * or implied.
11 *
12 * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com)
13 */
14#include <linux/init.h>
15#include <linux/interrupt.h>
16#include <linux/irq.h>
17#include <asm/irq_cpu.h>
18#include <asm/txx9/tx4938.h>
19
20void __init tx4938_irq_init(void)
21{
22 int i;
23
24 mips_cpu_irq_init();
25 txx9_irq_init(TX4938_IRC_REG & 0xfffffffffULL);
26 irq_set_chained_handler(MIPS_CPU_IRQ_BASE + TX4938_IRC_INT,
27 handle_simple_irq);
28 /* raise priority for errors, timers, SIO */
29 txx9_irq_set_pri(TX4938_IR_ECCERR, 7);
30 txx9_irq_set_pri(TX4938_IR_WTOERR, 7);
31 txx9_irq_set_pri(TX4938_IR_PCIERR, 7);
32 txx9_irq_set_pri(TX4938_IR_PCIPME, 7);
33 for (i = 0; i < TX4938_NUM_IR_TMR; i++)
34 txx9_irq_set_pri(TX4938_IR_TMR(i), 6);
35 for (i = 0; i < TX4938_NUM_IR_SIO; i++)
36 txx9_irq_set_pri(TX4938_IR_SIO(i), 5);
37}
diff --git a/arch/mips/txx9/generic/irq_tx4939.c b/arch/mips/txx9/generic/irq_tx4939.c
new file mode 100644
index 000000000..0d7267e81
--- /dev/null
+++ b/arch/mips/txx9/generic/irq_tx4939.c
@@ -0,0 +1,216 @@
1/*
2 * TX4939 irq routines
3 * Based on linux/arch/mips/kernel/irq_txx9.c,
4 * and RBTX49xx patch from CELF patch archive.
5 *
6 * Copyright 2001, 2003-2005 MontaVista Software Inc.
7 * Author: MontaVista Software, Inc.
8 * ahennessy@mvista.com
9 * source@mvista.com
10 * Copyright (C) 2000-2001,2005-2007 Toshiba Corporation
11 *
12 * This file is subject to the terms and conditions of the GNU General Public
13 * License. See the file "COPYING" in the main directory of this archive
14 * for more details.
15 */
16/*
17 * TX4939 defines 64 IRQs.
18 * Similer to irq_txx9.c but different register layouts.
19 */
20#include <linux/init.h>
21#include <linux/interrupt.h>
22#include <linux/irq.h>
23#include <linux/types.h>
24#include <asm/irq_cpu.h>
25#include <asm/txx9irq.h>
26#include <asm/txx9/tx4939.h>
27
28/* IRCER : Int. Control Enable */
29#define TXx9_IRCER_ICE 0x00000001
30
31/* IRCR : Int. Control */
32#define TXx9_IRCR_LOW 0x00000000
33#define TXx9_IRCR_HIGH 0x00000001
34#define TXx9_IRCR_DOWN 0x00000002
35#define TXx9_IRCR_UP 0x00000003
36#define TXx9_IRCR_EDGE(cr) ((cr) & 0x00000002)
37
38/* IRSCR : Int. Status Control */
39#define TXx9_IRSCR_EIClrE 0x00000100
40#define TXx9_IRSCR_EIClr_MASK 0x0000000f
41
42/* IRCSR : Int. Current Status */
43#define TXx9_IRCSR_IF 0x00010000
44
45#define irc_dlevel 0
46#define irc_elevel 1
47
48static struct {
49 unsigned char level;
50 unsigned char mode;
51} tx4939irq[TX4939_NUM_IR] __read_mostly;
52
53static void tx4939_irq_unmask(struct irq_data *d)
54{
55 unsigned int irq_nr = d->irq - TXX9_IRQ_BASE;
56 u32 __iomem *lvlp;
57 int ofs;
58 if (irq_nr < 32) {
59 irq_nr--;
60 lvlp = &tx4939_ircptr->lvl[(irq_nr % 16) / 2].r;
61 } else {
62 irq_nr -= 32;
63 lvlp = &tx4939_ircptr->lvl[8 + (irq_nr % 16) / 2].r;
64 }
65 ofs = (irq_nr & 16) + (irq_nr & 1) * 8;
66 __raw_writel((__raw_readl(lvlp) & ~(0xff << ofs))
67 | (tx4939irq[irq_nr].level << ofs),
68 lvlp);
69}
70
71static inline void tx4939_irq_mask(struct irq_data *d)
72{
73 unsigned int irq_nr = d->irq - TXX9_IRQ_BASE;
74 u32 __iomem *lvlp;
75 int ofs;
76 if (irq_nr < 32) {
77 irq_nr--;
78 lvlp = &tx4939_ircptr->lvl[(irq_nr % 16) / 2].r;
79 } else {
80 irq_nr -= 32;
81 lvlp = &tx4939_ircptr->lvl[8 + (irq_nr % 16) / 2].r;
82 }
83 ofs = (irq_nr & 16) + (irq_nr & 1) * 8;
84 __raw_writel((__raw_readl(lvlp) & ~(0xff << ofs))
85 | (irc_dlevel << ofs),
86 lvlp);
87 mmiowb();
88}
89
90static void tx4939_irq_mask_ack(struct irq_data *d)
91{
92 unsigned int irq_nr = d->irq - TXX9_IRQ_BASE;
93
94 tx4939_irq_mask(d);
95 if (TXx9_IRCR_EDGE(tx4939irq[irq_nr].mode)) {
96 irq_nr--;
97 /* clear edge detection */
98 __raw_writel((TXx9_IRSCR_EIClrE | (irq_nr & 0xf))
99 << (irq_nr & 0x10),
100 &tx4939_ircptr->edc.r);
101 }
102}
103
104static int tx4939_irq_set_type(struct irq_data *d, unsigned int flow_type)
105{
106 unsigned int irq_nr = d->irq - TXX9_IRQ_BASE;
107 u32 cr;
108 u32 __iomem *crp;
109 int ofs;
110 int mode;
111
112 if (flow_type & IRQF_TRIGGER_PROBE)
113 return 0;
114 switch (flow_type & IRQF_TRIGGER_MASK) {
115 case IRQF_TRIGGER_RISING:
116 mode = TXx9_IRCR_UP;
117 break;
118 case IRQF_TRIGGER_FALLING:
119 mode = TXx9_IRCR_DOWN;
120 break;
121 case IRQF_TRIGGER_HIGH:
122 mode = TXx9_IRCR_HIGH;
123 break;
124 case IRQF_TRIGGER_LOW:
125 mode = TXx9_IRCR_LOW;
126 break;
127 default:
128 return -EINVAL;
129 }
130 if (irq_nr < 32) {
131 irq_nr--;
132 crp = &tx4939_ircptr->dm[(irq_nr & 8) >> 3].r;
133 } else {
134 irq_nr -= 32;
135 crp = &tx4939_ircptr->dm2[((irq_nr & 8) >> 3)].r;
136 }
137 ofs = (((irq_nr & 16) >> 1) | (irq_nr & (8 - 1))) * 2;
138 cr = __raw_readl(crp);
139 cr &= ~(0x3 << ofs);
140 cr |= (mode & 0x3) << ofs;
141 __raw_writel(cr, crp);
142 tx4939irq[irq_nr].mode = mode;
143 return 0;
144}
145
146static struct irq_chip tx4939_irq_chip = {
147 .name = "TX4939",
148 .irq_ack = tx4939_irq_mask_ack,
149 .irq_mask = tx4939_irq_mask,
150 .irq_mask_ack = tx4939_irq_mask_ack,
151 .irq_unmask = tx4939_irq_unmask,
152 .irq_set_type = tx4939_irq_set_type,
153};
154
155static int tx4939_irq_set_pri(int irc_irq, int new_pri)
156{
157 int old_pri;
158
159 if ((unsigned int)irc_irq >= TX4939_NUM_IR)
160 return 0;
161 old_pri = tx4939irq[irc_irq].level;
162 tx4939irq[irc_irq].level = new_pri;
163 return old_pri;
164}
165
166void __init tx4939_irq_init(void)
167{
168 int i;
169
170 mips_cpu_irq_init();
171 /* disable interrupt control */
172 __raw_writel(0, &tx4939_ircptr->den.r);
173 __raw_writel(0, &tx4939_ircptr->maskint.r);
174 __raw_writel(0, &tx4939_ircptr->maskext.r);
175 /* irq_base + 0 is not used */
176 for (i = 1; i < TX4939_NUM_IR; i++) {
177 tx4939irq[i].level = 4; /* middle level */
178 tx4939irq[i].mode = TXx9_IRCR_LOW;
179 irq_set_chip_and_handler(TXX9_IRQ_BASE + i, &tx4939_irq_chip,
180 handle_level_irq);
181 }
182
183 /* mask all IRC interrupts */
184 __raw_writel(0, &tx4939_ircptr->msk.r);
185 for (i = 0; i < 16; i++)
186 __raw_writel(0, &tx4939_ircptr->lvl[i].r);
187 /* setup IRC interrupt mode (Low Active) */
188 for (i = 0; i < 2; i++)
189 __raw_writel(0, &tx4939_ircptr->dm[i].r);
190 for (i = 0; i < 2; i++)
191 __raw_writel(0, &tx4939_ircptr->dm2[i].r);
192 /* enable interrupt control */
193 __raw_writel(TXx9_IRCER_ICE, &tx4939_ircptr->den.r);
194 __raw_writel(irc_elevel, &tx4939_ircptr->msk.r);
195
196 irq_set_chained_handler(MIPS_CPU_IRQ_BASE + TX4939_IRC_INT,
197 handle_simple_irq);
198
199 /* raise priority for errors, timers, sio */
200 tx4939_irq_set_pri(TX4939_IR_WTOERR, 7);
201 tx4939_irq_set_pri(TX4939_IR_PCIERR, 7);
202 tx4939_irq_set_pri(TX4939_IR_PCIPME, 7);
203 for (i = 0; i < TX4939_NUM_IR_TMR; i++)
204 tx4939_irq_set_pri(TX4939_IR_TMR(i), 6);
205 for (i = 0; i < TX4939_NUM_IR_SIO; i++)
206 tx4939_irq_set_pri(TX4939_IR_SIO(i), 5);
207}
208
209int tx4939_irq(void)
210{
211 u32 csr = __raw_readl(&tx4939_ircptr->cs.r);
212
213 if (likely(!(csr & TXx9_IRCSR_IF)))
214 return TXX9_IRQ_BASE + (csr & (TX4939_NUM_IR - 1));
215 return -1;
216}
diff --git a/arch/mips/txx9/generic/mem_tx4927.c b/arch/mips/txx9/generic/mem_tx4927.c
new file mode 100644
index 000000000..deea2ceae
--- /dev/null
+++ b/arch/mips/txx9/generic/mem_tx4927.c
@@ -0,0 +1,75 @@
1/*
2 * common tx4927 memory interface
3 *
4 * Author: MontaVista Software, Inc.
5 * source@mvista.com
6 *
7 * Copyright 2001-2002 MontaVista Software Inc.
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2 of the License, or (at your
12 * option) any later version.
13 *
14 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
15 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
16 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
19 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
20 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
22 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
23 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 *
25 * You should have received a copy of the GNU General Public License along
26 * with this program; if not, write to the Free Software Foundation, Inc.,
27 * 675 Mass Ave, Cambridge, MA 02139, USA.
28 */
29
30#include <linux/init.h>
31#include <linux/types.h>
32#include <linux/io.h>
33#include <asm/txx9/tx4927.h>
34
35static unsigned int __init tx4927_process_sdccr(u64 __iomem *addr)
36{
37 u64 val;
38 unsigned int sdccr_ce;
39 unsigned int sdccr_bs;
40 unsigned int sdccr_rs;
41 unsigned int sdccr_cs;
42 unsigned int sdccr_mw;
43 unsigned int bs = 0;
44 unsigned int rs = 0;
45 unsigned int cs = 0;
46 unsigned int mw = 0;
47
48 val = __raw_readq(addr);
49
50 /* MVMCP -- need #defs for these bits masks */
51 sdccr_ce = ((val & (1 << 10)) >> 10);
52 sdccr_bs = ((val & (1 << 8)) >> 8);
53 sdccr_rs = ((val & (3 << 5)) >> 5);
54 sdccr_cs = ((val & (7 << 2)) >> 2);
55 sdccr_mw = ((val & (1 << 0)) >> 0);
56
57 if (sdccr_ce) {
58 bs = 2 << sdccr_bs;
59 rs = 2048 << sdccr_rs;
60 cs = 256 << sdccr_cs;
61 mw = 8 >> sdccr_mw;
62 }
63
64 return rs * cs * mw * bs;
65}
66
67unsigned int __init tx4927_get_mem_size(void)
68{
69 unsigned int total = 0;
70 int i;
71
72 for (i = 0; i < ARRAY_SIZE(tx4927_sdramcptr->cr); i++)
73 total += tx4927_process_sdccr(&tx4927_sdramcptr->cr[i]);
74 return total;
75}
diff --git a/arch/mips/txx9/generic/pci.c b/arch/mips/txx9/generic/pci.c
new file mode 100644
index 000000000..fb998726b
--- /dev/null
+++ b/arch/mips/txx9/generic/pci.c
@@ -0,0 +1,432 @@
1/*
2 * linux/arch/mips/txx9/pci.c
3 *
4 * Based on linux/arch/mips/txx9/rbtx4927/setup.c,
5 * linux/arch/mips/txx9/rbtx4938/setup.c,
6 * and RBTX49xx patch from CELF patch archive.
7 *
8 * Copyright 2001-2005 MontaVista Software Inc.
9 * Copyright (C) 1996, 97, 2001, 04 Ralf Baechle (ralf@linux-mips.org)
10 * (C) Copyright TOSHIBA CORPORATION 2000-2001, 2004-2007
11 *
12 * This file is subject to the terms and conditions of the GNU General Public
13 * License. See the file "COPYING" in the main directory of this archive
14 * for more details.
15 */
16#include <linux/delay.h>
17#include <linux/jiffies.h>
18#include <linux/io.h>
19#include <asm/txx9/generic.h>
20#include <asm/txx9/pci.h>
21#ifdef CONFIG_TOSHIBA_FPCIB0
22#include <linux/interrupt.h>
23#include <linux/slab.h>
24#include <asm/i8259.h>
25#include <asm/txx9/smsc_fdc37m81x.h>
26#endif
27
28static int __init
29early_read_config_word(struct pci_controller *hose,
30 int top_bus, int bus, int devfn, int offset, u16 *value)
31{
32 struct pci_bus fake_bus;
33
34 fake_bus.number = bus;
35 fake_bus.sysdata = hose;
36 fake_bus.ops = hose->pci_ops;
37
38 if (bus != top_bus)
39 /* Fake a parent bus structure. */
40 fake_bus.parent = &fake_bus;
41 else
42 fake_bus.parent = NULL;
43
44 return pci_bus_read_config_word(&fake_bus, devfn, offset, value);
45}
46
47int __init txx9_pci66_check(struct pci_controller *hose, int top_bus,
48 int current_bus)
49{
50 u32 pci_devfn;
51 unsigned short vid;
52 int cap66 = -1;
53 u16 stat;
54
55 /* It seems SLC90E66 needs some time after PCI reset... */
56 mdelay(80);
57
58 pr_info("PCI: Checking 66MHz capabilities...\n");
59
60 for (pci_devfn = 0; pci_devfn < 0xff; pci_devfn++) {
61 if (PCI_FUNC(pci_devfn))
62 continue;
63 if (early_read_config_word(hose, top_bus, current_bus,
64 pci_devfn, PCI_VENDOR_ID, &vid) !=
65 PCIBIOS_SUCCESSFUL)
66 continue;
67 if (vid == 0xffff)
68 continue;
69
70 /* check 66MHz capability */
71 if (cap66 < 0)
72 cap66 = 1;
73 if (cap66) {
74 early_read_config_word(hose, top_bus, current_bus,
75 pci_devfn, PCI_STATUS, &stat);
76 if (!(stat & PCI_STATUS_66MHZ)) {
77 pr_debug("PCI: %02x:%02x not 66MHz capable.\n",
78 current_bus, pci_devfn);
79 cap66 = 0;
80 break;
81 }
82 }
83 }
84 return cap66 > 0;
85}
86
87static struct resource primary_pci_mem_res[2] = {
88 { .name = "PCI MEM" },
89 { .name = "PCI MMIO" },
90};
91static struct resource primary_pci_io_res = { .name = "PCI IO" };
92struct pci_controller txx9_primary_pcic = {
93 .mem_resource = &primary_pci_mem_res[0],
94 .io_resource = &primary_pci_io_res,
95};
96
97#ifdef CONFIG_64BIT
98int txx9_pci_mem_high __initdata = 1;
99#else
100int txx9_pci_mem_high __initdata;
101#endif
102
103/*
104 * allocate pci_controller and resources.
105 * mem_base, io_base: physical address. 0 for auto assignment.
106 * mem_size and io_size means max size on auto assignment.
107 * pcic must be &txx9_primary_pcic or NULL.
108 */
109struct pci_controller *__init
110txx9_alloc_pci_controller(struct pci_controller *pcic,
111 unsigned long mem_base, unsigned long mem_size,
112 unsigned long io_base, unsigned long io_size)
113{
114 struct pcic {
115 struct pci_controller c;
116 struct resource r_mem[2];
117 struct resource r_io;
118 } *new = NULL;
119 int min_size = 0x10000;
120
121 if (!pcic) {
122 new = kzalloc(sizeof(*new), GFP_KERNEL);
123 if (!new)
124 return NULL;
125 new->r_mem[0].name = "PCI mem";
126 new->r_mem[1].name = "PCI mmio";
127 new->r_io.name = "PCI io";
128 new->c.mem_resource = new->r_mem;
129 new->c.io_resource = &new->r_io;
130 pcic = &new->c;
131 } else
132 BUG_ON(pcic != &txx9_primary_pcic);
133 pcic->io_resource->flags = IORESOURCE_IO;
134
135 /*
136 * for auto assignment, first search a (big) region for PCI
137 * MEM, then search a region for PCI IO.
138 */
139 if (mem_base) {
140 pcic->mem_resource[0].start = mem_base;
141 pcic->mem_resource[0].end = mem_base + mem_size - 1;
142 if (request_resource(&iomem_resource, &pcic->mem_resource[0]))
143 goto free_and_exit;
144 } else {
145 unsigned long min = 0, max = 0x20000000; /* low 512MB */
146 if (!mem_size) {
147 /* default size for auto assignment */
148 if (txx9_pci_mem_high)
149 mem_size = 0x20000000; /* mem:512M(max) */
150 else
151 mem_size = 0x08000000; /* mem:128M(max) */
152 }
153 if (txx9_pci_mem_high) {
154 min = 0x20000000;
155 max = 0xe0000000;
156 }
157 /* search free region for PCI MEM */
158 for (; mem_size >= min_size; mem_size /= 2) {
159 if (allocate_resource(&iomem_resource,
160 &pcic->mem_resource[0],
161 mem_size, min, max,
162 mem_size, NULL, NULL) == 0)
163 break;
164 }
165 if (mem_size < min_size)
166 goto free_and_exit;
167 }
168
169 pcic->mem_resource[1].flags = IORESOURCE_MEM | IORESOURCE_BUSY;
170 if (io_base) {
171 pcic->mem_resource[1].start = io_base;
172 pcic->mem_resource[1].end = io_base + io_size - 1;
173 if (request_resource(&iomem_resource, &pcic->mem_resource[1]))
174 goto release_and_exit;
175 } else {
176 if (!io_size)
177 /* default size for auto assignment */
178 io_size = 0x01000000; /* io:16M(max) */
179 /* search free region for PCI IO in low 512MB */
180 for (; io_size >= min_size; io_size /= 2) {
181 if (allocate_resource(&iomem_resource,
182 &pcic->mem_resource[1],
183 io_size, 0, 0x20000000,
184 io_size, NULL, NULL) == 0)
185 break;
186 }
187 if (io_size < min_size)
188 goto release_and_exit;
189 io_base = pcic->mem_resource[1].start;
190 }
191
192 pcic->mem_resource[0].flags = IORESOURCE_MEM;
193 if (pcic == &txx9_primary_pcic &&
194 mips_io_port_base == (unsigned long)-1) {
195 /* map ioport 0 to PCI I/O space address 0 */
196 set_io_port_base(IO_BASE + pcic->mem_resource[1].start);
197 pcic->io_resource->start = 0;
198 pcic->io_offset = 0; /* busaddr == ioaddr */
199 pcic->io_map_base = IO_BASE + pcic->mem_resource[1].start;
200 } else {
201 /* physaddr to ioaddr */
202 pcic->io_resource->start =
203 io_base - (mips_io_port_base - IO_BASE);
204 pcic->io_offset = io_base - (mips_io_port_base - IO_BASE);
205 pcic->io_map_base = mips_io_port_base;
206 }
207 pcic->io_resource->end = pcic->io_resource->start + io_size - 1;
208
209 pcic->mem_offset = 0; /* busaddr == physaddr */
210
211 pr_info("PCI: IO %pR MEM %pR\n", &pcic->mem_resource[1],
212 &pcic->mem_resource[0]);
213
214 /* register_pci_controller() will request MEM resource */
215 release_resource(&pcic->mem_resource[0]);
216 return pcic;
217 release_and_exit:
218 release_resource(&pcic->mem_resource[0]);
219 free_and_exit:
220 kfree(new);
221 pr_err("PCI: Failed to allocate resources.\n");
222 return NULL;
223}
224
225static int __init
226txx9_arch_pci_init(void)
227{
228 PCIBIOS_MIN_IO = 0x8000; /* reseve legacy I/O space */
229 return 0;
230}
231arch_initcall(txx9_arch_pci_init);
232
233/* IRQ/IDSEL mapping */
234int txx9_pci_option =
235#ifdef CONFIG_PICMG_PCI_BACKPLANE_DEFAULT
236 TXX9_PCI_OPT_PICMG |
237#endif
238 TXX9_PCI_OPT_CLK_AUTO;
239
240enum txx9_pci_err_action txx9_pci_err_action = TXX9_PCI_ERR_REPORT;
241
242#ifdef CONFIG_TOSHIBA_FPCIB0
243static irqreturn_t i8259_interrupt(int irq, void *dev_id)
244{
245 int isairq;
246
247 isairq = i8259_irq();
248 if (unlikely(isairq <= I8259A_IRQ_BASE))
249 return IRQ_NONE;
250 generic_handle_irq(isairq);
251 return IRQ_HANDLED;
252}
253
254static int txx9_i8259_irq_setup(int irq)
255{
256 int err;
257
258 init_i8259_irqs();
259 err = request_irq(irq, &i8259_interrupt, IRQF_SHARED,
260 "cascade(i8259)", (void *)(long)irq);
261 if (!err)
262 pr_info("PCI-ISA bridge PIC (irq %d)\n", irq);
263 return err;
264}
265
266static void __ref quirk_slc90e66_bridge(struct pci_dev *dev)
267{
268 int irq; /* PCI/ISA Bridge interrupt */
269 u8 reg_64;
270 u32 reg_b0;
271 u8 reg_e1;
272 irq = pcibios_map_irq(dev, PCI_SLOT(dev->devfn), 1); /* INTA */
273 if (!irq)
274 return;
275 txx9_i8259_irq_setup(irq);
276 pci_read_config_byte(dev, 0x64, &reg_64);
277 pci_read_config_dword(dev, 0xb0, &reg_b0);
278 pci_read_config_byte(dev, 0xe1, &reg_e1);
279 /* serial irq control */
280 reg_64 = 0xd0;
281 /* serial irq pin */
282 reg_b0 |= 0x00010000;
283 /* ide irq on isa14 */
284 reg_e1 &= 0xf0;
285 reg_e1 |= 0x0d;
286 pci_write_config_byte(dev, 0x64, reg_64);
287 pci_write_config_dword(dev, 0xb0, reg_b0);
288 pci_write_config_byte(dev, 0xe1, reg_e1);
289
290 smsc_fdc37m81x_init(0x3f0);
291 smsc_fdc37m81x_config_beg();
292 smsc_fdc37m81x_config_set(SMSC_FDC37M81X_DNUM,
293 SMSC_FDC37M81X_KBD);
294 smsc_fdc37m81x_config_set(SMSC_FDC37M81X_INT, 1);
295 smsc_fdc37m81x_config_set(SMSC_FDC37M81X_INT2, 12);
296 smsc_fdc37m81x_config_set(SMSC_FDC37M81X_ACTIVE,
297 1);
298 smsc_fdc37m81x_config_end();
299}
300
301static void quirk_slc90e66_ide(struct pci_dev *dev)
302{
303 unsigned char dat;
304 int regs[2] = {0x41, 0x43};
305 int i;
306
307 /* SMSC SLC90E66 IDE uses irq 14, 15 (default) */
308 pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 14);
309 pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &dat);
310 pr_info("PCI: %s: IRQ %02x", pci_name(dev), dat);
311 /* enable SMSC SLC90E66 IDE */
312 for (i = 0; i < ARRAY_SIZE(regs); i++) {
313 pci_read_config_byte(dev, regs[i], &dat);
314 pci_write_config_byte(dev, regs[i], dat | 0x80);
315 pci_read_config_byte(dev, regs[i], &dat);
316 pr_cont(" IDETIM%d %02x", i, dat);
317 }
318 pci_read_config_byte(dev, 0x5c, &dat);
319 /*
320 * !!! DO NOT REMOVE THIS COMMENT IT IS REQUIRED BY SMSC !!!
321 *
322 * This line of code is intended to provide the user with a work
323 * around solution to the anomalies cited in SMSC's anomaly sheet
324 * entitled, "SLC90E66 Functional Rev.J_0.1 Anomalies"".
325 *
326 * !!! DO NOT REMOVE THIS COMMENT IT IS REQUIRED BY SMSC !!!
327 */
328 dat |= 0x01;
329 pci_write_config_byte(dev, 0x5c, dat);
330 pci_read_config_byte(dev, 0x5c, &dat);
331 pr_cont(" REG5C %02x\n", dat);
332}
333#endif /* CONFIG_TOSHIBA_FPCIB0 */
334
335static void tc35815_fixup(struct pci_dev *dev)
336{
337 /* This device may have PM registers but not they are not supported. */
338 if (dev->pm_cap) {
339 dev_info(&dev->dev, "PM disabled\n");
340 dev->pm_cap = 0;
341 }
342}
343
344static void final_fixup(struct pci_dev *dev)
345{
346 unsigned char bist;
347
348 /* Do build-in self test */
349 if (pci_read_config_byte(dev, PCI_BIST, &bist) == PCIBIOS_SUCCESSFUL &&
350 (bist & PCI_BIST_CAPABLE)) {
351 unsigned long timeout;
352 pci_set_power_state(dev, PCI_D0);
353 pr_info("PCI: %s BIST...", pci_name(dev));
354 pci_write_config_byte(dev, PCI_BIST, PCI_BIST_START);
355 timeout = jiffies + HZ * 2; /* timeout after 2 sec */
356 do {
357 pci_read_config_byte(dev, PCI_BIST, &bist);
358 if (time_after(jiffies, timeout))
359 break;
360 } while (bist & PCI_BIST_START);
361 if (bist & (PCI_BIST_CODE_MASK | PCI_BIST_START))
362 pr_cont("failed. (0x%x)\n", bist);
363 else
364 pr_cont("OK.\n");
365 }
366}
367
368#ifdef CONFIG_TOSHIBA_FPCIB0
369#define PCI_DEVICE_ID_EFAR_SLC90E66_0 0x9460
370DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_EFAR, PCI_DEVICE_ID_EFAR_SLC90E66_0,
371 quirk_slc90e66_bridge);
372DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_EFAR, PCI_DEVICE_ID_EFAR_SLC90E66_1,
373 quirk_slc90e66_ide);
374DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_EFAR, PCI_DEVICE_ID_EFAR_SLC90E66_1,
375 quirk_slc90e66_ide);
376#endif
377DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_TOSHIBA_2,
378 PCI_DEVICE_ID_TOSHIBA_TC35815_NWU, tc35815_fixup);
379DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_TOSHIBA_2,
380 PCI_DEVICE_ID_TOSHIBA_TC35815_TX4939, tc35815_fixup);
381DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, final_fixup);
382DECLARE_PCI_FIXUP_RESUME(PCI_ANY_ID, PCI_ANY_ID, final_fixup);
383
384int pcibios_plat_dev_init(struct pci_dev *dev)
385{
386 return 0;
387}
388
389static int (*txx9_pci_map_irq)(const struct pci_dev *dev, u8 slot, u8 pin);
390int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
391{
392 return txx9_pci_map_irq(dev, slot, pin);
393}
394
395char * (*txx9_board_pcibios_setup)(char *str) __initdata;
396
397char *__init txx9_pcibios_setup(char *str)
398{
399 if (txx9_board_pcibios_setup && !txx9_board_pcibios_setup(str))
400 return NULL;
401 if (!strcmp(str, "picmg")) {
402 /* PICMG compliant backplane (TOSHIBA JMB-PICMG-ATX
403 (5V or 3.3V), JMB-PICMG-L2 (5V only), etc.) */
404 txx9_pci_option |= TXX9_PCI_OPT_PICMG;
405 return NULL;
406 } else if (!strcmp(str, "nopicmg")) {
407 /* non-PICMG compliant backplane (TOSHIBA
408 RBHBK4100,RBHBK4200, Interface PCM-PCM05, etc.) */
409 txx9_pci_option &= ~TXX9_PCI_OPT_PICMG;
410 return NULL;
411 } else if (!strncmp(str, "clk=", 4)) {
412 char *val = str + 4;
413 txx9_pci_option &= ~TXX9_PCI_OPT_CLK_MASK;
414 if (strcmp(val, "33") == 0)
415 txx9_pci_option |= TXX9_PCI_OPT_CLK_33;
416 else if (strcmp(val, "66") == 0)
417 txx9_pci_option |= TXX9_PCI_OPT_CLK_66;
418 else /* "auto" */
419 txx9_pci_option |= TXX9_PCI_OPT_CLK_AUTO;
420 return NULL;
421 } else if (!strncmp(str, "err=", 4)) {
422 if (!strcmp(str + 4, "panic"))
423 txx9_pci_err_action = TXX9_PCI_ERR_PANIC;
424 else if (!strcmp(str + 4, "ignore"))
425 txx9_pci_err_action = TXX9_PCI_ERR_IGNORE;
426 return NULL;
427 }
428
429 txx9_pci_map_irq = txx9_board_vec->pci_map_irq;
430
431 return str;
432}
diff --git a/arch/mips/txx9/generic/setup.c b/arch/mips/txx9/generic/setup.c
new file mode 100644
index 000000000..6d0fd0e05
--- /dev/null
+++ b/arch/mips/txx9/generic/setup.c
@@ -0,0 +1,965 @@
1/*
2 * Based on linux/arch/mips/txx9/rbtx4938/setup.c,
3 * and RBTX49xx patch from CELF patch archive.
4 *
5 * 2003-2005 (c) MontaVista Software, Inc.
6 * (C) Copyright TOSHIBA CORPORATION 2000-2001, 2004-2007
7 *
8 * This file is subject to the terms and conditions of the GNU General Public
9 * License. See the file "COPYING" in the main directory of this archive
10 * for more details.
11 */
12#include <linux/init.h>
13#include <linux/kernel.h>
14#include <linux/types.h>
15#include <linux/interrupt.h>
16#include <linux/string.h>
17#include <linux/export.h>
18#include <linux/clk-provider.h>
19#include <linux/clkdev.h>
20#include <linux/err.h>
21#include <linux/gpio/driver.h>
22#include <linux/platform_device.h>
23#include <linux/platform_data/txx9/ndfmc.h>
24#include <linux/serial_core.h>
25#include <linux/mtd/physmap.h>
26#include <linux/leds.h>
27#include <linux/device.h>
28#include <linux/slab.h>
29#include <linux/io.h>
30#include <linux/irq.h>
31#include <asm/bootinfo.h>
32#include <asm/idle.h>
33#include <asm/time.h>
34#include <asm/reboot.h>
35#include <asm/r4kcache.h>
36#include <asm/setup.h>
37#include <asm/txx9/generic.h>
38#include <asm/txx9/pci.h>
39#include <asm/txx9tmr.h>
40#include <asm/txx9/dmac.h>
41#ifdef CONFIG_CPU_TX49XX
42#include <asm/txx9/tx4938.h>
43#endif
44
45/* EBUSC settings of TX4927, etc. */
46struct resource txx9_ce_res[8];
47static char txx9_ce_res_name[8][4]; /* "CEn" */
48
49/* pcode, internal register */
50unsigned int txx9_pcode;
51char txx9_pcode_str[8];
52static struct resource txx9_reg_res = {
53 .name = txx9_pcode_str,
54 .flags = IORESOURCE_MEM,
55};
56void __init
57txx9_reg_res_init(unsigned int pcode, unsigned long base, unsigned long size)
58{
59 int i;
60
61 for (i = 0; i < ARRAY_SIZE(txx9_ce_res); i++) {
62 sprintf(txx9_ce_res_name[i], "CE%d", i);
63 txx9_ce_res[i].flags = IORESOURCE_MEM;
64 txx9_ce_res[i].name = txx9_ce_res_name[i];
65 }
66
67 txx9_pcode = pcode;
68 sprintf(txx9_pcode_str, "TX%x", pcode);
69 if (base) {
70 txx9_reg_res.start = base & 0xfffffffffULL;
71 txx9_reg_res.end = (base & 0xfffffffffULL) + (size - 1);
72 request_resource(&iomem_resource, &txx9_reg_res);
73 }
74}
75
76/* clocks */
77unsigned int txx9_master_clock;
78unsigned int txx9_cpu_clock;
79unsigned int txx9_gbus_clock;
80
81#ifdef CONFIG_CPU_TX39XX
82/* don't enable by default - see errata */
83int txx9_ccfg_toeon __initdata;
84#else
85int txx9_ccfg_toeon __initdata = 1;
86#endif
87
88#define BOARD_VEC(board) extern struct txx9_board_vec board;
89#include <asm/txx9/boards.h>
90#undef BOARD_VEC
91
92struct txx9_board_vec *txx9_board_vec __initdata;
93static char txx9_system_type[32];
94
95static struct txx9_board_vec *board_vecs[] __initdata = {
96#define BOARD_VEC(board) &board,
97#include <asm/txx9/boards.h>
98#undef BOARD_VEC
99};
100
101static struct txx9_board_vec *__init find_board_byname(const char *name)
102{
103 int i;
104
105 /* search board_vecs table */
106 for (i = 0; i < ARRAY_SIZE(board_vecs); i++) {
107 if (strstr(board_vecs[i]->system, name))
108 return board_vecs[i];
109 }
110 return NULL;
111}
112
113static void __init prom_init_cmdline(void)
114{
115 int argc;
116 int *argv32;
117 int i; /* Always ignore the "-c" at argv[0] */
118
119 if (fw_arg0 >= CKSEG0 || fw_arg1 < CKSEG0) {
120 /*
121 * argc is not a valid number, or argv32 is not a valid
122 * pointer
123 */
124 argc = 0;
125 argv32 = NULL;
126 } else {
127 argc = (int)fw_arg0;
128 argv32 = (int *)fw_arg1;
129 }
130
131 arcs_cmdline[0] = '\0';
132
133 for (i = 1; i < argc; i++) {
134 char *str = (char *)(long)argv32[i];
135 if (i != 1)
136 strcat(arcs_cmdline, " ");
137 if (strchr(str, ' ')) {
138 strcat(arcs_cmdline, "\"");
139 strcat(arcs_cmdline, str);
140 strcat(arcs_cmdline, "\"");
141 } else
142 strcat(arcs_cmdline, str);
143 }
144}
145
146static int txx9_ic_disable __initdata;
147static int txx9_dc_disable __initdata;
148
149#if defined(CONFIG_CPU_TX49XX)
150/* flush all cache on very early stage (before 4k_cache_init) */
151static void __init early_flush_dcache(void)
152{
153 unsigned int conf = read_c0_config();
154 unsigned int dc_size = 1 << (12 + ((conf & CONF_DC) >> 6));
155 unsigned int linesz = 32;
156 unsigned long addr, end;
157
158 end = INDEX_BASE + dc_size / 4;
159 /* 4way, waybit=0 */
160 for (addr = INDEX_BASE; addr < end; addr += linesz) {
161 cache_op(Index_Writeback_Inv_D, addr | 0);
162 cache_op(Index_Writeback_Inv_D, addr | 1);
163 cache_op(Index_Writeback_Inv_D, addr | 2);
164 cache_op(Index_Writeback_Inv_D, addr | 3);
165 }
166}
167
168static void __init txx9_cache_fixup(void)
169{
170 unsigned int conf;
171
172 conf = read_c0_config();
173 /* flush and disable */
174 if (txx9_ic_disable) {
175 conf |= TX49_CONF_IC;
176 write_c0_config(conf);
177 }
178 if (txx9_dc_disable) {
179 early_flush_dcache();
180 conf |= TX49_CONF_DC;
181 write_c0_config(conf);
182 }
183
184 /* enable cache */
185 conf = read_c0_config();
186 if (!txx9_ic_disable)
187 conf &= ~TX49_CONF_IC;
188 if (!txx9_dc_disable)
189 conf &= ~TX49_CONF_DC;
190 write_c0_config(conf);
191
192 if (conf & TX49_CONF_IC)
193 pr_info("TX49XX I-Cache disabled.\n");
194 if (conf & TX49_CONF_DC)
195 pr_info("TX49XX D-Cache disabled.\n");
196}
197#elif defined(CONFIG_CPU_TX39XX)
198/* flush all cache on very early stage (before tx39_cache_init) */
199static void __init early_flush_dcache(void)
200{
201 unsigned int conf = read_c0_config();
202 unsigned int dc_size = 1 << (10 + ((conf & TX39_CONF_DCS_MASK) >>
203 TX39_CONF_DCS_SHIFT));
204 unsigned int linesz = 16;
205 unsigned long addr, end;
206
207 end = INDEX_BASE + dc_size / 2;
208 /* 2way, waybit=0 */
209 for (addr = INDEX_BASE; addr < end; addr += linesz) {
210 cache_op(Index_Writeback_Inv_D, addr | 0);
211 cache_op(Index_Writeback_Inv_D, addr | 1);
212 }
213}
214
215static void __init txx9_cache_fixup(void)
216{
217 unsigned int conf;
218
219 conf = read_c0_config();
220 /* flush and disable */
221 if (txx9_ic_disable) {
222 conf &= ~TX39_CONF_ICE;
223 write_c0_config(conf);
224 }
225 if (txx9_dc_disable) {
226 early_flush_dcache();
227 conf &= ~TX39_CONF_DCE;
228 write_c0_config(conf);
229 }
230
231 /* enable cache */
232 conf = read_c0_config();
233 if (!txx9_ic_disable)
234 conf |= TX39_CONF_ICE;
235 if (!txx9_dc_disable)
236 conf |= TX39_CONF_DCE;
237 write_c0_config(conf);
238
239 if (!(conf & TX39_CONF_ICE))
240 pr_info("TX39XX I-Cache disabled.\n");
241 if (!(conf & TX39_CONF_DCE))
242 pr_info("TX39XX D-Cache disabled.\n");
243}
244#else
245static inline void txx9_cache_fixup(void)
246{
247}
248#endif
249
250static void __init preprocess_cmdline(void)
251{
252 static char cmdline[COMMAND_LINE_SIZE] __initdata;
253 char *s;
254
255 strcpy(cmdline, arcs_cmdline);
256 s = cmdline;
257 arcs_cmdline[0] = '\0';
258 while (s && *s) {
259 char *str = strsep(&s, " ");
260 if (strncmp(str, "board=", 6) == 0) {
261 txx9_board_vec = find_board_byname(str + 6);
262 continue;
263 } else if (strncmp(str, "masterclk=", 10) == 0) {
264 unsigned int val;
265 if (kstrtouint(str + 10, 10, &val) == 0)
266 txx9_master_clock = val;
267 continue;
268 } else if (strcmp(str, "icdisable") == 0) {
269 txx9_ic_disable = 1;
270 continue;
271 } else if (strcmp(str, "dcdisable") == 0) {
272 txx9_dc_disable = 1;
273 continue;
274 } else if (strcmp(str, "toeoff") == 0) {
275 txx9_ccfg_toeon = 0;
276 continue;
277 } else if (strcmp(str, "toeon") == 0) {
278 txx9_ccfg_toeon = 1;
279 continue;
280 }
281 if (arcs_cmdline[0])
282 strcat(arcs_cmdline, " ");
283 strcat(arcs_cmdline, str);
284 }
285
286 txx9_cache_fixup();
287}
288
289static void __init select_board(void)
290{
291 const char *envstr;
292
293 /* first, determine by "board=" argument in preprocess_cmdline() */
294 if (txx9_board_vec)
295 return;
296 /* next, determine by "board" envvar */
297 envstr = prom_getenv("board");
298 if (envstr) {
299 txx9_board_vec = find_board_byname(envstr);
300 if (txx9_board_vec)
301 return;
302 }
303
304 /* select "default" board */
305#ifdef CONFIG_TOSHIBA_JMR3927
306 txx9_board_vec = &jmr3927_vec;
307#endif
308#ifdef CONFIG_CPU_TX49XX
309 switch (TX4938_REV_PCODE()) {
310#ifdef CONFIG_TOSHIBA_RBTX4927
311 case 0x4927:
312 txx9_board_vec = &rbtx4927_vec;
313 break;
314 case 0x4937:
315 txx9_board_vec = &rbtx4937_vec;
316 break;
317#endif
318#ifdef CONFIG_TOSHIBA_RBTX4938
319 case 0x4938:
320 txx9_board_vec = &rbtx4938_vec;
321 break;
322#endif
323#ifdef CONFIG_TOSHIBA_RBTX4939
324 case 0x4939:
325 txx9_board_vec = &rbtx4939_vec;
326 break;
327#endif
328 }
329#endif
330}
331
332void __init prom_init(void)
333{
334 prom_init_cmdline();
335 preprocess_cmdline();
336 select_board();
337
338 strcpy(txx9_system_type, txx9_board_vec->system);
339
340 txx9_board_vec->prom_init();
341}
342
343void __init prom_free_prom_memory(void)
344{
345}
346
347const char *get_system_type(void)
348{
349 return txx9_system_type;
350}
351
352const char *__init prom_getenv(const char *name)
353{
354 const s32 *str;
355
356 if (fw_arg2 < CKSEG0)
357 return NULL;
358
359 str = (const s32 *)fw_arg2;
360 /* YAMON style ("name", "value" pairs) */
361 while (str[0] && str[1]) {
362 if (!strcmp((const char *)(unsigned long)str[0], name))
363 return (const char *)(unsigned long)str[1];
364 str += 2;
365 }
366 return NULL;
367}
368
369static void __noreturn txx9_machine_halt(void)
370{
371 local_irq_disable();
372 clear_c0_status(ST0_IM);
373 while (1) {
374 if (cpu_wait) {
375 (*cpu_wait)();
376 if (cpu_has_counter) {
377 /*
378 * Clear counter interrupt while it
379 * breaks WAIT instruction even if
380 * masked.
381 */
382 write_c0_compare(0);
383 }
384 }
385 }
386}
387
388/* Watchdog support */
389void __init txx9_wdt_init(unsigned long base)
390{
391 struct resource res = {
392 .start = base,
393 .end = base + 0x100 - 1,
394 .flags = IORESOURCE_MEM,
395 };
396 platform_device_register_simple("txx9wdt", -1, &res, 1);
397}
398
399void txx9_wdt_now(unsigned long base)
400{
401 struct txx9_tmr_reg __iomem *tmrptr =
402 ioremap(base, sizeof(struct txx9_tmr_reg));
403 /* disable watch dog timer */
404 __raw_writel(TXx9_TMWTMR_WDIS | TXx9_TMWTMR_TWC, &tmrptr->wtmr);
405 __raw_writel(0, &tmrptr->tcr);
406 /* kick watchdog */
407 __raw_writel(TXx9_TMWTMR_TWIE, &tmrptr->wtmr);
408 __raw_writel(1, &tmrptr->cpra); /* immediate */
409 __raw_writel(TXx9_TMTCR_TCE | TXx9_TMTCR_CCDE | TXx9_TMTCR_TMODE_WDOG,
410 &tmrptr->tcr);
411}
412
413/* SPI support */
414void __init txx9_spi_init(int busid, unsigned long base, int irq)
415{
416 struct resource res[] = {
417 {
418 .start = base,
419 .end = base + 0x20 - 1,
420 .flags = IORESOURCE_MEM,
421 }, {
422 .start = irq,
423 .flags = IORESOURCE_IRQ,
424 },
425 };
426 platform_device_register_simple("spi_txx9", busid,
427 res, ARRAY_SIZE(res));
428}
429
430void __init txx9_ethaddr_init(unsigned int id, unsigned char *ethaddr)
431{
432 struct platform_device *pdev =
433 platform_device_alloc("tc35815-mac", id);
434 if (!pdev ||
435 platform_device_add_data(pdev, ethaddr, 6) ||
436 platform_device_add(pdev))
437 platform_device_put(pdev);
438}
439
440void __init txx9_sio_init(unsigned long baseaddr, int irq,
441 unsigned int line, unsigned int sclk, int nocts)
442{
443#ifdef CONFIG_SERIAL_TXX9
444 struct uart_port req;
445
446 memset(&req, 0, sizeof(req));
447 req.line = line;
448 req.iotype = UPIO_MEM;
449 req.membase = ioremap(baseaddr, 0x24);
450 req.mapbase = baseaddr;
451 req.irq = irq;
452 if (!nocts)
453 req.flags |= UPF_BUGGY_UART /*HAVE_CTS_LINE*/;
454 if (sclk) {
455 req.flags |= UPF_MAGIC_MULTIPLIER /*USE_SCLK*/;
456 req.uartclk = sclk;
457 } else
458 req.uartclk = TXX9_IMCLK;
459 early_serial_txx9_setup(&req);
460#endif /* CONFIG_SERIAL_TXX9 */
461}
462
463#ifdef CONFIG_EARLY_PRINTK
464static void null_prom_putchar(char c)
465{
466}
467void (*txx9_prom_putchar)(char c) = null_prom_putchar;
468
469void prom_putchar(char c)
470{
471 txx9_prom_putchar(c);
472}
473
474static void __iomem *early_txx9_sio_port;
475
476static void early_txx9_sio_putchar(char c)
477{
478#define TXX9_SICISR 0x0c
479#define TXX9_SITFIFO 0x1c
480#define TXX9_SICISR_TXALS 0x00000002
481 while (!(__raw_readl(early_txx9_sio_port + TXX9_SICISR) &
482 TXX9_SICISR_TXALS))
483 ;
484 __raw_writel(c, early_txx9_sio_port + TXX9_SITFIFO);
485}
486
487void __init txx9_sio_putchar_init(unsigned long baseaddr)
488{
489 early_txx9_sio_port = ioremap(baseaddr, 0x24);
490 txx9_prom_putchar = early_txx9_sio_putchar;
491}
492#endif /* CONFIG_EARLY_PRINTK */
493
494/* wrappers */
495void __init plat_mem_setup(void)
496{
497 ioport_resource.start = 0;
498 ioport_resource.end = ~0UL; /* no limit */
499 iomem_resource.start = 0;
500 iomem_resource.end = ~0UL; /* no limit */
501
502 /* fallback restart/halt routines */
503 _machine_restart = (void (*)(char *))txx9_machine_halt;
504 _machine_halt = txx9_machine_halt;
505 pm_power_off = txx9_machine_halt;
506
507#ifdef CONFIG_PCI
508 pcibios_plat_setup = txx9_pcibios_setup;
509#endif
510 txx9_board_vec->mem_setup();
511}
512
513void __init arch_init_irq(void)
514{
515 txx9_board_vec->irq_setup();
516}
517
518void __init plat_time_init(void)
519{
520#ifdef CONFIG_CPU_TX49XX
521 mips_hpt_frequency = txx9_cpu_clock / 2;
522#endif
523 txx9_board_vec->time_init();
524}
525
526static void txx9_clk_init(void)
527{
528 struct clk_hw *hw;
529 int error;
530
531 hw = clk_hw_register_fixed_rate(NULL, "gbus", NULL, 0, txx9_gbus_clock);
532 if (IS_ERR(hw)) {
533 error = PTR_ERR(hw);
534 goto fail;
535 }
536
537 hw = clk_hw_register_fixed_factor(NULL, "imbus", "gbus", 0, 1, 2);
538 error = clk_hw_register_clkdev(hw, "imbus_clk", NULL);
539 if (error)
540 goto fail;
541
542#ifdef CONFIG_CPU_TX49XX
543 if (TX4938_REV_PCODE() == 0x4938) {
544 hw = clk_hw_register_fixed_factor(NULL, "spi", "gbus", 0, 1, 4);
545 error = clk_hw_register_clkdev(hw, "spi-baseclk", NULL);
546 if (error)
547 goto fail;
548 }
549#endif
550
551 return;
552
553fail:
554 pr_err("Failed to register clocks: %d\n", error);
555}
556
557static int __init _txx9_arch_init(void)
558{
559 txx9_clk_init();
560
561 if (txx9_board_vec->arch_init)
562 txx9_board_vec->arch_init();
563 return 0;
564}
565arch_initcall(_txx9_arch_init);
566
567static int __init _txx9_device_init(void)
568{
569 if (txx9_board_vec->device_init)
570 txx9_board_vec->device_init();
571 return 0;
572}
573device_initcall(_txx9_device_init);
574
575int (*txx9_irq_dispatch)(int pending);
576asmlinkage void plat_irq_dispatch(void)
577{
578 int pending = read_c0_status() & read_c0_cause() & ST0_IM;
579 int irq = txx9_irq_dispatch(pending);
580
581 if (likely(irq >= 0))
582 do_IRQ(irq);
583 else
584 spurious_interrupt();
585}
586
587/* see include/asm-mips/mach-tx39xx/mangle-port.h, for example. */
588#ifdef NEEDS_TXX9_SWIZZLE_ADDR_B
589static unsigned long __swizzle_addr_none(unsigned long port)
590{
591 return port;
592}
593unsigned long (*__swizzle_addr_b)(unsigned long port) = __swizzle_addr_none;
594EXPORT_SYMBOL(__swizzle_addr_b);
595#endif
596
597#ifdef NEEDS_TXX9_IOSWABW
598static u16 ioswabw_default(volatile u16 *a, u16 x)
599{
600 return le16_to_cpu(x);
601}
602static u16 __mem_ioswabw_default(volatile u16 *a, u16 x)
603{
604 return x;
605}
606u16 (*ioswabw)(volatile u16 *a, u16 x) = ioswabw_default;
607EXPORT_SYMBOL(ioswabw);
608u16 (*__mem_ioswabw)(volatile u16 *a, u16 x) = __mem_ioswabw_default;
609EXPORT_SYMBOL(__mem_ioswabw);
610#endif
611
612void __init txx9_physmap_flash_init(int no, unsigned long addr,
613 unsigned long size,
614 const struct physmap_flash_data *pdata)
615{
616#if IS_ENABLED(CONFIG_MTD_PHYSMAP)
617 struct resource res = {
618 .start = addr,
619 .end = addr + size - 1,
620 .flags = IORESOURCE_MEM,
621 };
622 struct platform_device *pdev;
623 static struct mtd_partition parts[2];
624 struct physmap_flash_data pdata_part;
625
626 /* If this area contained boot area, make separate partition */
627 if (pdata->nr_parts == 0 && !pdata->parts &&
628 addr < 0x1fc00000 && addr + size > 0x1fc00000 &&
629 !parts[0].name) {
630 parts[0].name = "boot";
631 parts[0].offset = 0x1fc00000 - addr;
632 parts[0].size = addr + size - 0x1fc00000;
633 parts[1].name = "user";
634 parts[1].offset = 0;
635 parts[1].size = 0x1fc00000 - addr;
636 pdata_part = *pdata;
637 pdata_part.nr_parts = ARRAY_SIZE(parts);
638 pdata_part.parts = parts;
639 pdata = &pdata_part;
640 }
641
642 pdev = platform_device_alloc("physmap-flash", no);
643 if (!pdev ||
644 platform_device_add_resources(pdev, &res, 1) ||
645 platform_device_add_data(pdev, pdata, sizeof(*pdata)) ||
646 platform_device_add(pdev))
647 platform_device_put(pdev);
648#endif
649}
650
651void __init txx9_ndfmc_init(unsigned long baseaddr,
652 const struct txx9ndfmc_platform_data *pdata)
653{
654#if IS_ENABLED(CONFIG_MTD_NAND_TXX9NDFMC)
655 struct resource res = {
656 .start = baseaddr,
657 .end = baseaddr + 0x1000 - 1,
658 .flags = IORESOURCE_MEM,
659 };
660 struct platform_device *pdev = platform_device_alloc("txx9ndfmc", -1);
661
662 if (!pdev ||
663 platform_device_add_resources(pdev, &res, 1) ||
664 platform_device_add_data(pdev, pdata, sizeof(*pdata)) ||
665 platform_device_add(pdev))
666 platform_device_put(pdev);
667#endif
668}
669
670#if IS_ENABLED(CONFIG_LEDS_GPIO)
671static DEFINE_SPINLOCK(txx9_iocled_lock);
672
673#define TXX9_IOCLED_MAXLEDS 8
674
675struct txx9_iocled_data {
676 struct gpio_chip chip;
677 u8 cur_val;
678 void __iomem *mmioaddr;
679 struct gpio_led_platform_data pdata;
680 struct gpio_led leds[TXX9_IOCLED_MAXLEDS];
681 char names[TXX9_IOCLED_MAXLEDS][32];
682};
683
684static int txx9_iocled_get(struct gpio_chip *chip, unsigned int offset)
685{
686 struct txx9_iocled_data *data = gpiochip_get_data(chip);
687 return !!(data->cur_val & (1 << offset));
688}
689
690static void txx9_iocled_set(struct gpio_chip *chip, unsigned int offset,
691 int value)
692{
693 struct txx9_iocled_data *data = gpiochip_get_data(chip);
694 unsigned long flags;
695 spin_lock_irqsave(&txx9_iocled_lock, flags);
696 if (value)
697 data->cur_val |= 1 << offset;
698 else
699 data->cur_val &= ~(1 << offset);
700 writeb(data->cur_val, data->mmioaddr);
701 mmiowb();
702 spin_unlock_irqrestore(&txx9_iocled_lock, flags);
703}
704
705static int txx9_iocled_dir_in(struct gpio_chip *chip, unsigned int offset)
706{
707 return 0;
708}
709
710static int txx9_iocled_dir_out(struct gpio_chip *chip, unsigned int offset,
711 int value)
712{
713 txx9_iocled_set(chip, offset, value);
714 return 0;
715}
716
717void __init txx9_iocled_init(unsigned long baseaddr,
718 int basenum, unsigned int num, int lowactive,
719 const char *color, char **deftriggers)
720{
721 struct txx9_iocled_data *iocled;
722 struct platform_device *pdev;
723 int i;
724 static char *default_triggers[] __initdata = {
725 "heartbeat",
726 "disk-activity",
727 "nand-disk",
728 NULL,
729 };
730
731 if (!deftriggers)
732 deftriggers = default_triggers;
733 iocled = kzalloc(sizeof(*iocled), GFP_KERNEL);
734 if (!iocled)
735 return;
736 iocled->mmioaddr = ioremap(baseaddr, 1);
737 if (!iocled->mmioaddr)
738 goto out_free;
739 iocled->chip.get = txx9_iocled_get;
740 iocled->chip.set = txx9_iocled_set;
741 iocled->chip.direction_input = txx9_iocled_dir_in;
742 iocled->chip.direction_output = txx9_iocled_dir_out;
743 iocled->chip.label = "iocled";
744 iocled->chip.base = basenum;
745 iocled->chip.ngpio = num;
746 if (gpiochip_add_data(&iocled->chip, iocled))
747 goto out_unmap;
748 if (basenum < 0)
749 basenum = iocled->chip.base;
750
751 pdev = platform_device_alloc("leds-gpio", basenum);
752 if (!pdev)
753 goto out_gpio;
754 iocled->pdata.num_leds = num;
755 iocled->pdata.leds = iocled->leds;
756 for (i = 0; i < num; i++) {
757 struct gpio_led *led = &iocled->leds[i];
758 snprintf(iocled->names[i], sizeof(iocled->names[i]),
759 "iocled:%s:%u", color, i);
760 led->name = iocled->names[i];
761 led->gpio = basenum + i;
762 led->active_low = lowactive;
763 if (deftriggers && *deftriggers)
764 led->default_trigger = *deftriggers++;
765 }
766 pdev->dev.platform_data = &iocled->pdata;
767 if (platform_device_add(pdev))
768 goto out_pdev;
769 return;
770
771out_pdev:
772 platform_device_put(pdev);
773out_gpio:
774 gpiochip_remove(&iocled->chip);
775out_unmap:
776 iounmap(iocled->mmioaddr);
777out_free:
778 kfree(iocled);
779}
780#else /* CONFIG_LEDS_GPIO */
781void __init txx9_iocled_init(unsigned long baseaddr,
782 int basenum, unsigned int num, int lowactive,
783 const char *color, char **deftriggers)
784{
785}
786#endif /* CONFIG_LEDS_GPIO */
787
788void __init txx9_dmac_init(int id, unsigned long baseaddr, int irq,
789 const struct txx9dmac_platform_data *pdata)
790{
791#if IS_ENABLED(CONFIG_TXX9_DMAC)
792 struct resource res[] = {
793 {
794 .start = baseaddr,
795 .end = baseaddr + 0x800 - 1,
796 .flags = IORESOURCE_MEM,
797#ifndef CONFIG_MACH_TX49XX
798 }, {
799 .start = irq,
800 .flags = IORESOURCE_IRQ,
801#endif
802 }
803 };
804#ifdef CONFIG_MACH_TX49XX
805 struct resource chan_res[] = {
806 {
807 .flags = IORESOURCE_IRQ,
808 }
809 };
810#endif
811 struct platform_device *pdev = platform_device_alloc("txx9dmac", id);
812 struct txx9dmac_chan_platform_data cpdata;
813 int i;
814
815 if (!pdev ||
816 platform_device_add_resources(pdev, res, ARRAY_SIZE(res)) ||
817 platform_device_add_data(pdev, pdata, sizeof(*pdata)) ||
818 platform_device_add(pdev)) {
819 platform_device_put(pdev);
820 return;
821 }
822 memset(&cpdata, 0, sizeof(cpdata));
823 cpdata.dmac_dev = pdev;
824 for (i = 0; i < TXX9_DMA_MAX_NR_CHANNELS; i++) {
825#ifdef CONFIG_MACH_TX49XX
826 chan_res[0].start = irq + i;
827#endif
828 pdev = platform_device_alloc("txx9dmac-chan",
829 id * TXX9_DMA_MAX_NR_CHANNELS + i);
830 if (!pdev ||
831#ifdef CONFIG_MACH_TX49XX
832 platform_device_add_resources(pdev, chan_res,
833 ARRAY_SIZE(chan_res)) ||
834#endif
835 platform_device_add_data(pdev, &cpdata, sizeof(cpdata)) ||
836 platform_device_add(pdev))
837 platform_device_put(pdev);
838 }
839#endif
840}
841
842void __init txx9_aclc_init(unsigned long baseaddr, int irq,
843 unsigned int dmac_id,
844 unsigned int dma_chan_out,
845 unsigned int dma_chan_in)
846{
847#if IS_ENABLED(CONFIG_SND_SOC_TXX9ACLC)
848 unsigned int dma_base = dmac_id * TXX9_DMA_MAX_NR_CHANNELS;
849 struct resource res[] = {
850 {
851 .start = baseaddr,
852 .end = baseaddr + 0x100 - 1,
853 .flags = IORESOURCE_MEM,
854 }, {
855 .start = irq,
856 .flags = IORESOURCE_IRQ,
857 }, {
858 .name = "txx9dmac-chan",
859 .start = dma_base + dma_chan_out,
860 .flags = IORESOURCE_DMA,
861 }, {
862 .name = "txx9dmac-chan",
863 .start = dma_base + dma_chan_in,
864 .flags = IORESOURCE_DMA,
865 }
866 };
867 struct platform_device *pdev =
868 platform_device_alloc("txx9aclc-ac97", -1);
869
870 if (!pdev ||
871 platform_device_add_resources(pdev, res, ARRAY_SIZE(res)) ||
872 platform_device_add(pdev))
873 platform_device_put(pdev);
874#endif
875}
876
877static struct bus_type txx9_sramc_subsys = {
878 .name = "txx9_sram",
879 .dev_name = "txx9_sram",
880};
881
882struct txx9_sramc_dev {
883 struct device dev;
884 struct bin_attribute bindata_attr;
885 void __iomem *base;
886};
887
888static ssize_t txx9_sram_read(struct file *filp, struct kobject *kobj,
889 struct bin_attribute *bin_attr,
890 char *buf, loff_t pos, size_t size)
891{
892 struct txx9_sramc_dev *dev = bin_attr->private;
893 size_t ramsize = bin_attr->size;
894
895 if (pos >= ramsize)
896 return 0;
897 if (pos + size > ramsize)
898 size = ramsize - pos;
899 memcpy_fromio(buf, dev->base + pos, size);
900 return size;
901}
902
903static ssize_t txx9_sram_write(struct file *filp, struct kobject *kobj,
904 struct bin_attribute *bin_attr,
905 char *buf, loff_t pos, size_t size)
906{
907 struct txx9_sramc_dev *dev = bin_attr->private;
908 size_t ramsize = bin_attr->size;
909
910 if (pos >= ramsize)
911 return 0;
912 if (pos + size > ramsize)
913 size = ramsize - pos;
914 memcpy_toio(dev->base + pos, buf, size);
915 return size;
916}
917
918static void txx9_device_release(struct device *dev)
919{
920 struct txx9_sramc_dev *tdev;
921
922 tdev = container_of(dev, struct txx9_sramc_dev, dev);
923 kfree(tdev);
924}
925
926void __init txx9_sramc_init(struct resource *r)
927{
928 struct txx9_sramc_dev *dev;
929 size_t size;
930 int err;
931
932 err = subsys_system_register(&txx9_sramc_subsys, NULL);
933 if (err)
934 return;
935 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
936 if (!dev)
937 return;
938 size = resource_size(r);
939 dev->base = ioremap(r->start, size);
940 if (!dev->base) {
941 kfree(dev);
942 return;
943 }
944 dev->dev.release = &txx9_device_release;
945 dev->dev.bus = &txx9_sramc_subsys;
946 sysfs_bin_attr_init(&dev->bindata_attr);
947 dev->bindata_attr.attr.name = "bindata";
948 dev->bindata_attr.attr.mode = S_IRUSR | S_IWUSR;
949 dev->bindata_attr.read = txx9_sram_read;
950 dev->bindata_attr.write = txx9_sram_write;
951 dev->bindata_attr.size = size;
952 dev->bindata_attr.private = dev;
953 err = device_register(&dev->dev);
954 if (err)
955 goto exit_put;
956 err = sysfs_create_bin_file(&dev->dev.kobj, &dev->bindata_attr);
957 if (err) {
958 iounmap(dev->base);
959 device_unregister(&dev->dev);
960 }
961 return;
962exit_put:
963 iounmap(dev->base);
964 put_device(&dev->dev);
965}
diff --git a/arch/mips/txx9/generic/setup_tx3927.c b/arch/mips/txx9/generic/setup_tx3927.c
new file mode 100644
index 000000000..33f7a7253
--- /dev/null
+++ b/arch/mips/txx9/generic/setup_tx3927.c
@@ -0,0 +1,136 @@
1/*
2 * TX3927 setup routines
3 * Based on linux/arch/mips/txx9/jmr3927/setup.c
4 *
5 * Copyright 2001 MontaVista Software Inc.
6 * Copyright (C) 2000-2001 Toshiba Corporation
7 * Copyright (C) 2007 Ralf Baechle (ralf@linux-mips.org)
8 *
9 * This file is subject to the terms and conditions of the GNU General Public
10 * License. See the file "COPYING" in the main directory of this archive
11 * for more details.
12 */
13#include <linux/init.h>
14#include <linux/ioport.h>
15#include <linux/delay.h>
16#include <linux/param.h>
17#include <linux/io.h>
18#include <linux/mtd/physmap.h>
19#include <asm/mipsregs.h>
20#include <asm/txx9irq.h>
21#include <asm/txx9tmr.h>
22#include <asm/txx9pio.h>
23#include <asm/txx9/generic.h>
24#include <asm/txx9/tx3927.h>
25
26void __init tx3927_wdt_init(void)
27{
28 txx9_wdt_init(TX3927_TMR_REG(2));
29}
30
31void __init tx3927_setup(void)
32{
33 int i;
34 unsigned int conf;
35
36 txx9_reg_res_init(TX3927_REV_PCODE(), TX3927_REG_BASE,
37 TX3927_REG_SIZE);
38
39 /* SDRAMC,ROMC are configured by PROM */
40 for (i = 0; i < 8; i++) {
41 if (!(tx3927_romcptr->cr[i] & 0x8))
42 continue; /* disabled */
43 txx9_ce_res[i].start = (unsigned long)TX3927_ROMC_BA(i);
44 txx9_ce_res[i].end =
45 txx9_ce_res[i].start + TX3927_ROMC_SIZE(i) - 1;
46 request_resource(&iomem_resource, &txx9_ce_res[i]);
47 }
48
49 /* clocks */
50 txx9_gbus_clock = txx9_cpu_clock / 2;
51 /* change default value to udelay/mdelay take reasonable time */
52 loops_per_jiffy = txx9_cpu_clock / HZ / 2;
53
54 /* CCFG */
55 /* enable Timeout BusError */
56 if (txx9_ccfg_toeon)
57 tx3927_ccfgptr->ccfg |= TX3927_CCFG_TOE;
58
59 /* clear BusErrorOnWrite flag */
60 tx3927_ccfgptr->ccfg &= ~TX3927_CCFG_BEOW;
61 if (read_c0_conf() & TX39_CONF_WBON)
62 /* Disable PCI snoop */
63 tx3927_ccfgptr->ccfg &= ~TX3927_CCFG_PSNP;
64 else
65 /* Enable PCI SNOOP - with write through only */
66 tx3927_ccfgptr->ccfg |= TX3927_CCFG_PSNP;
67 /* do reset on watchdog */
68 tx3927_ccfgptr->ccfg |= TX3927_CCFG_WR;
69
70 pr_info("TX3927 -- CRIR:%08lx CCFG:%08lx PCFG:%08lx\n",
71 tx3927_ccfgptr->crir, tx3927_ccfgptr->ccfg,
72 tx3927_ccfgptr->pcfg);
73
74 /* TMR */
75 for (i = 0; i < TX3927_NR_TMR; i++)
76 txx9_tmr_init(TX3927_TMR_REG(i));
77
78 /* DMA */
79 tx3927_dmaptr->mcr = 0;
80 for (i = 0; i < ARRAY_SIZE(tx3927_dmaptr->ch); i++) {
81 /* reset channel */
82 tx3927_dmaptr->ch[i].ccr = TX3927_DMA_CCR_CHRST;
83 tx3927_dmaptr->ch[i].ccr = 0;
84 }
85 /* enable DMA */
86#ifdef __BIG_ENDIAN
87 tx3927_dmaptr->mcr = TX3927_DMA_MCR_MSTEN;
88#else
89 tx3927_dmaptr->mcr = TX3927_DMA_MCR_MSTEN | TX3927_DMA_MCR_LE;
90#endif
91
92 /* PIO */
93 __raw_writel(0, &tx3927_pioptr->maskcpu);
94 __raw_writel(0, &tx3927_pioptr->maskext);
95
96 conf = read_c0_conf();
97 if (conf & TX39_CONF_DCE) {
98 if (!(conf & TX39_CONF_WBON))
99 pr_info("TX3927 D-Cache WriteThrough.\n");
100 else if (!(conf & TX39_CONF_CWFON))
101 pr_info("TX3927 D-Cache WriteBack.\n");
102 else
103 pr_info("TX3927 D-Cache WriteBack (CWF) .\n");
104 }
105}
106
107void __init tx3927_time_init(unsigned int evt_tmrnr, unsigned int src_tmrnr)
108{
109 txx9_clockevent_init(TX3927_TMR_REG(evt_tmrnr),
110 TXX9_IRQ_BASE + TX3927_IR_TMR(evt_tmrnr),
111 TXX9_IMCLK);
112 txx9_clocksource_init(TX3927_TMR_REG(src_tmrnr), TXX9_IMCLK);
113}
114
115void __init tx3927_sio_init(unsigned int sclk, unsigned int cts_mask)
116{
117 int i;
118
119 for (i = 0; i < 2; i++)
120 txx9_sio_init(TX3927_SIO_REG(i),
121 TXX9_IRQ_BASE + TX3927_IR_SIO(i),
122 i, sclk, (1 << i) & cts_mask);
123}
124
125void __init tx3927_mtd_init(int ch)
126{
127 struct physmap_flash_data pdata = {
128 .width = TX3927_ROMC_WIDTH(ch) / 8,
129 };
130 unsigned long start = txx9_ce_res[ch].start;
131 unsigned long size = txx9_ce_res[ch].end - start + 1;
132
133 if (!(tx3927_romcptr->cr[ch] & 0x8))
134 return; /* disabled */
135 txx9_physmap_flash_init(ch, start, size, &pdata);
136}
diff --git a/arch/mips/txx9/generic/setup_tx4927.c b/arch/mips/txx9/generic/setup_tx4927.c
new file mode 100644
index 000000000..46e9c4101
--- /dev/null
+++ b/arch/mips/txx9/generic/setup_tx4927.c
@@ -0,0 +1,337 @@
1/*
2 * TX4927 setup routines
3 * Based on linux/arch/mips/txx9/rbtx4938/setup.c,
4 * and RBTX49xx patch from CELF patch archive.
5 *
6 * 2003-2005 (c) MontaVista Software, Inc.
7 * (C) Copyright TOSHIBA CORPORATION 2000-2001, 2004-2007
8 *
9 * This file is subject to the terms and conditions of the GNU General Public
10 * License. See the file "COPYING" in the main directory of this archive
11 * for more details.
12 */
13#include <linux/init.h>
14#include <linux/ioport.h>
15#include <linux/delay.h>
16#include <linux/param.h>
17#include <linux/ptrace.h>
18#include <linux/mtd/physmap.h>
19#include <asm/reboot.h>
20#include <asm/traps.h>
21#include <asm/txx9irq.h>
22#include <asm/txx9tmr.h>
23#include <asm/txx9pio.h>
24#include <asm/txx9/generic.h>
25#include <asm/txx9/dmac.h>
26#include <asm/txx9/tx4927.h>
27
28static void __init tx4927_wdr_init(void)
29{
30 /* report watchdog reset status */
31 if (____raw_readq(&tx4927_ccfgptr->ccfg) & TX4927_CCFG_WDRST)
32 pr_warn("Watchdog reset detected at 0x%lx\n",
33 read_c0_errorepc());
34 /* clear WatchDogReset (W1C) */
35 tx4927_ccfg_set(TX4927_CCFG_WDRST);
36 /* do reset on watchdog */
37 tx4927_ccfg_set(TX4927_CCFG_WR);
38}
39
40void __init tx4927_wdt_init(void)
41{
42 txx9_wdt_init(TX4927_TMR_REG(2) & 0xfffffffffULL);
43}
44
45static void tx4927_machine_restart(char *command)
46{
47 local_irq_disable();
48 pr_emerg("Rebooting (with %s watchdog reset)...\n",
49 (____raw_readq(&tx4927_ccfgptr->ccfg) & TX4927_CCFG_WDREXEN) ?
50 "external" : "internal");
51 /* clear watchdog status */
52 tx4927_ccfg_set(TX4927_CCFG_WDRST); /* W1C */
53 txx9_wdt_now(TX4927_TMR_REG(2) & 0xfffffffffULL);
54 while (!(____raw_readq(&tx4927_ccfgptr->ccfg) & TX4927_CCFG_WDRST))
55 ;
56 mdelay(10);
57 if (____raw_readq(&tx4927_ccfgptr->ccfg) & TX4927_CCFG_WDREXEN) {
58 pr_emerg("Rebooting (with internal watchdog reset)...\n");
59 /* External WDRST failed. Do internal watchdog reset */
60 tx4927_ccfg_clear(TX4927_CCFG_WDREXEN);
61 }
62 /* fallback */
63 (*_machine_halt)();
64}
65
66void show_registers(struct pt_regs *regs);
67static int tx4927_be_handler(struct pt_regs *regs, int is_fixup)
68{
69 int data = regs->cp0_cause & 4;
70 console_verbose();
71 pr_err("%cBE exception at %#lx\n", data ? 'D' : 'I', regs->cp0_epc);
72 pr_err("ccfg:%llx, toea:%llx\n",
73 (unsigned long long)____raw_readq(&tx4927_ccfgptr->ccfg),
74 (unsigned long long)____raw_readq(&tx4927_ccfgptr->toea));
75#ifdef CONFIG_PCI
76 tx4927_report_pcic_status();
77#endif
78 show_registers(regs);
79 panic("BusError!");
80}
81static void __init tx4927_be_init(void)
82{
83 board_be_handler = tx4927_be_handler;
84}
85
86static struct resource tx4927_sdram_resource[4];
87
88void __init tx4927_setup(void)
89{
90 int i;
91 __u32 divmode;
92 unsigned int cpuclk = 0;
93 u64 ccfg;
94
95 txx9_reg_res_init(TX4927_REV_PCODE(), TX4927_REG_BASE,
96 TX4927_REG_SIZE);
97 set_c0_config(TX49_CONF_CWFON);
98
99 /* SDRAMC,EBUSC are configured by PROM */
100 for (i = 0; i < 8; i++) {
101 if (!(TX4927_EBUSC_CR(i) & 0x8))
102 continue; /* disabled */
103 txx9_ce_res[i].start = (unsigned long)TX4927_EBUSC_BA(i);
104 txx9_ce_res[i].end =
105 txx9_ce_res[i].start + TX4927_EBUSC_SIZE(i) - 1;
106 request_resource(&iomem_resource, &txx9_ce_res[i]);
107 }
108
109 /* clocks */
110 ccfg = ____raw_readq(&tx4927_ccfgptr->ccfg);
111 if (txx9_master_clock) {
112 /* calculate gbus_clock and cpu_clock from master_clock */
113 divmode = (__u32)ccfg & TX4927_CCFG_DIVMODE_MASK;
114 switch (divmode) {
115 case TX4927_CCFG_DIVMODE_8:
116 case TX4927_CCFG_DIVMODE_10:
117 case TX4927_CCFG_DIVMODE_12:
118 case TX4927_CCFG_DIVMODE_16:
119 txx9_gbus_clock = txx9_master_clock * 4; break;
120 default:
121 txx9_gbus_clock = txx9_master_clock;
122 }
123 switch (divmode) {
124 case TX4927_CCFG_DIVMODE_2:
125 case TX4927_CCFG_DIVMODE_8:
126 cpuclk = txx9_gbus_clock * 2; break;
127 case TX4927_CCFG_DIVMODE_2_5:
128 case TX4927_CCFG_DIVMODE_10:
129 cpuclk = txx9_gbus_clock * 5 / 2; break;
130 case TX4927_CCFG_DIVMODE_3:
131 case TX4927_CCFG_DIVMODE_12:
132 cpuclk = txx9_gbus_clock * 3; break;
133 case TX4927_CCFG_DIVMODE_4:
134 case TX4927_CCFG_DIVMODE_16:
135 cpuclk = txx9_gbus_clock * 4; break;
136 }
137 txx9_cpu_clock = cpuclk;
138 } else {
139 if (txx9_cpu_clock == 0)
140 txx9_cpu_clock = 200000000; /* 200MHz */
141 /* calculate gbus_clock and master_clock from cpu_clock */
142 cpuclk = txx9_cpu_clock;
143 divmode = (__u32)ccfg & TX4927_CCFG_DIVMODE_MASK;
144 switch (divmode) {
145 case TX4927_CCFG_DIVMODE_2:
146 case TX4927_CCFG_DIVMODE_8:
147 txx9_gbus_clock = cpuclk / 2; break;
148 case TX4927_CCFG_DIVMODE_2_5:
149 case TX4927_CCFG_DIVMODE_10:
150 txx9_gbus_clock = cpuclk * 2 / 5; break;
151 case TX4927_CCFG_DIVMODE_3:
152 case TX4927_CCFG_DIVMODE_12:
153 txx9_gbus_clock = cpuclk / 3; break;
154 case TX4927_CCFG_DIVMODE_4:
155 case TX4927_CCFG_DIVMODE_16:
156 txx9_gbus_clock = cpuclk / 4; break;
157 }
158 switch (divmode) {
159 case TX4927_CCFG_DIVMODE_8:
160 case TX4927_CCFG_DIVMODE_10:
161 case TX4927_CCFG_DIVMODE_12:
162 case TX4927_CCFG_DIVMODE_16:
163 txx9_master_clock = txx9_gbus_clock / 4; break;
164 default:
165 txx9_master_clock = txx9_gbus_clock;
166 }
167 }
168 /* change default value to udelay/mdelay take reasonable time */
169 loops_per_jiffy = txx9_cpu_clock / HZ / 2;
170
171 /* CCFG */
172 tx4927_wdr_init();
173 /* clear BusErrorOnWrite flag (W1C) */
174 tx4927_ccfg_set(TX4927_CCFG_BEOW);
175 /* enable Timeout BusError */
176 if (txx9_ccfg_toeon)
177 tx4927_ccfg_set(TX4927_CCFG_TOE);
178
179 /* DMA selection */
180 txx9_clear64(&tx4927_ccfgptr->pcfg, TX4927_PCFG_DMASEL_ALL);
181
182 /* Use external clock for external arbiter */
183 if (!(____raw_readq(&tx4927_ccfgptr->ccfg) & TX4927_CCFG_PCIARB))
184 txx9_clear64(&tx4927_ccfgptr->pcfg, TX4927_PCFG_PCICLKEN_ALL);
185
186 pr_info("%s -- %dMHz(M%dMHz) CRIR:%08x CCFG:%llx PCFG:%llx\n",
187 txx9_pcode_str, (cpuclk + 500000) / 1000000,
188 (txx9_master_clock + 500000) / 1000000,
189 (__u32)____raw_readq(&tx4927_ccfgptr->crir),
190 ____raw_readq(&tx4927_ccfgptr->ccfg),
191 ____raw_readq(&tx4927_ccfgptr->pcfg));
192
193 pr_info("%s SDRAMC --", txx9_pcode_str);
194 for (i = 0; i < 4; i++) {
195 __u64 cr = TX4927_SDRAMC_CR(i);
196 unsigned long base, size;
197 if (!((__u32)cr & 0x00000400))
198 continue; /* disabled */
199 base = (unsigned long)(cr >> 49) << 21;
200 size = (((unsigned long)(cr >> 33) & 0x7fff) + 1) << 21;
201 pr_cont(" CR%d:%016llx", i, cr);
202 tx4927_sdram_resource[i].name = "SDRAM";
203 tx4927_sdram_resource[i].start = base;
204 tx4927_sdram_resource[i].end = base + size - 1;
205 tx4927_sdram_resource[i].flags = IORESOURCE_MEM;
206 request_resource(&iomem_resource, &tx4927_sdram_resource[i]);
207 }
208 pr_cont(" TR:%09llx\n", ____raw_readq(&tx4927_sdramcptr->tr));
209
210 /* TMR */
211 /* disable all timers */
212 for (i = 0; i < TX4927_NR_TMR; i++)
213 txx9_tmr_init(TX4927_TMR_REG(i) & 0xfffffffffULL);
214
215 /* PIO */
216 __raw_writel(0, &tx4927_pioptr->maskcpu);
217 __raw_writel(0, &tx4927_pioptr->maskext);
218
219 _machine_restart = tx4927_machine_restart;
220 board_be_init = tx4927_be_init;
221}
222
223void __init tx4927_time_init(unsigned int tmrnr)
224{
225 if (____raw_readq(&tx4927_ccfgptr->ccfg) & TX4927_CCFG_TINTDIS)
226 txx9_clockevent_init(TX4927_TMR_REG(tmrnr) & 0xfffffffffULL,
227 TXX9_IRQ_BASE + TX4927_IR_TMR(tmrnr),
228 TXX9_IMCLK);
229}
230
231void __init tx4927_sio_init(unsigned int sclk, unsigned int cts_mask)
232{
233 int i;
234
235 for (i = 0; i < 2; i++)
236 txx9_sio_init(TX4927_SIO_REG(i) & 0xfffffffffULL,
237 TXX9_IRQ_BASE + TX4927_IR_SIO(i),
238 i, sclk, (1 << i) & cts_mask);
239}
240
241void __init tx4927_mtd_init(int ch)
242{
243 struct physmap_flash_data pdata = {
244 .width = TX4927_EBUSC_WIDTH(ch) / 8,
245 };
246 unsigned long start = txx9_ce_res[ch].start;
247 unsigned long size = txx9_ce_res[ch].end - start + 1;
248
249 if (!(TX4927_EBUSC_CR(ch) & 0x8))
250 return; /* disabled */
251 txx9_physmap_flash_init(ch, start, size, &pdata);
252}
253
254void __init tx4927_dmac_init(int memcpy_chan)
255{
256 struct txx9dmac_platform_data plat_data = {
257 .memcpy_chan = memcpy_chan,
258 .have_64bit_regs = true,
259 };
260
261 txx9_dmac_init(0, TX4927_DMA_REG & 0xfffffffffULL,
262 TXX9_IRQ_BASE + TX4927_IR_DMA(0), &plat_data);
263}
264
265void __init tx4927_aclc_init(unsigned int dma_chan_out,
266 unsigned int dma_chan_in)
267{
268 u64 pcfg = __raw_readq(&tx4927_ccfgptr->pcfg);
269 __u64 dmasel_mask = 0, dmasel = 0;
270 unsigned long flags;
271
272 if (!(pcfg & TX4927_PCFG_SEL2))
273 return;
274 /* setup DMASEL (playback:ACLC ch0, capture:ACLC ch1) */
275 switch (dma_chan_out) {
276 case 0:
277 dmasel_mask |= TX4927_PCFG_DMASEL0_MASK;
278 dmasel |= TX4927_PCFG_DMASEL0_ACL0;
279 break;
280 case 2:
281 dmasel_mask |= TX4927_PCFG_DMASEL2_MASK;
282 dmasel |= TX4927_PCFG_DMASEL2_ACL0;
283 break;
284 default:
285 return;
286 }
287 switch (dma_chan_in) {
288 case 1:
289 dmasel_mask |= TX4927_PCFG_DMASEL1_MASK;
290 dmasel |= TX4927_PCFG_DMASEL1_ACL1;
291 break;
292 case 3:
293 dmasel_mask |= TX4927_PCFG_DMASEL3_MASK;
294 dmasel |= TX4927_PCFG_DMASEL3_ACL1;
295 break;
296 default:
297 return;
298 }
299 local_irq_save(flags);
300 txx9_clear64(&tx4927_ccfgptr->pcfg, dmasel_mask);
301 txx9_set64(&tx4927_ccfgptr->pcfg, dmasel);
302 local_irq_restore(flags);
303 txx9_aclc_init(TX4927_ACLC_REG & 0xfffffffffULL,
304 TXX9_IRQ_BASE + TX4927_IR_ACLC,
305 0, dma_chan_out, dma_chan_in);
306}
307
308static void __init tx4927_stop_unused_modules(void)
309{
310 __u64 pcfg, rst = 0, ckd = 0;
311 char buf[128];
312
313 buf[0] = '\0';
314 local_irq_disable();
315 pcfg = ____raw_readq(&tx4927_ccfgptr->pcfg);
316 if (!(pcfg & TX4927_PCFG_SEL2)) {
317 rst |= TX4927_CLKCTR_ACLRST;
318 ckd |= TX4927_CLKCTR_ACLCKD;
319 strcat(buf, " ACLC");
320 }
321 if (rst | ckd) {
322 txx9_set64(&tx4927_ccfgptr->clkctr, rst);
323 txx9_set64(&tx4927_ccfgptr->clkctr, ckd);
324 }
325 local_irq_enable();
326 if (buf[0])
327 pr_info("%s: stop%s\n", txx9_pcode_str, buf);
328}
329
330static int __init tx4927_late_init(void)
331{
332 if (txx9_pcode != 0x4927)
333 return -ENODEV;
334 tx4927_stop_unused_modules();
335 return 0;
336}
337late_initcall(tx4927_late_init);
diff --git a/arch/mips/txx9/generic/setup_tx4938.c b/arch/mips/txx9/generic/setup_tx4938.c
new file mode 100644
index 000000000..17395d5d1
--- /dev/null
+++ b/arch/mips/txx9/generic/setup_tx4938.c
@@ -0,0 +1,485 @@
1/*
2 * TX4938/4937 setup routines
3 * Based on linux/arch/mips/txx9/rbtx4938/setup.c,
4 * and RBTX49xx patch from CELF patch archive.
5 *
6 * 2003-2005 (c) MontaVista Software, Inc.
7 * (C) Copyright TOSHIBA CORPORATION 2000-2001, 2004-2007
8 *
9 * This file is subject to the terms and conditions of the GNU General Public
10 * License. See the file "COPYING" in the main directory of this archive
11 * for more details.
12 */
13#include <linux/init.h>
14#include <linux/ioport.h>
15#include <linux/delay.h>
16#include <linux/param.h>
17#include <linux/ptrace.h>
18#include <linux/mtd/physmap.h>
19#include <linux/platform_device.h>
20#include <linux/platform_data/txx9/ndfmc.h>
21#include <asm/reboot.h>
22#include <asm/traps.h>
23#include <asm/txx9irq.h>
24#include <asm/txx9tmr.h>
25#include <asm/txx9pio.h>
26#include <asm/txx9/generic.h>
27#include <asm/txx9/dmac.h>
28#include <asm/txx9/tx4938.h>
29
30static void __init tx4938_wdr_init(void)
31{
32 /* report watchdog reset status */
33 if (____raw_readq(&tx4938_ccfgptr->ccfg) & TX4938_CCFG_WDRST)
34 pr_warn("Watchdog reset detected at 0x%lx\n",
35 read_c0_errorepc());
36 /* clear WatchDogReset (W1C) */
37 tx4938_ccfg_set(TX4938_CCFG_WDRST);
38 /* do reset on watchdog */
39 tx4938_ccfg_set(TX4938_CCFG_WR);
40}
41
42void __init tx4938_wdt_init(void)
43{
44 txx9_wdt_init(TX4938_TMR_REG(2) & 0xfffffffffULL);
45}
46
47static void tx4938_machine_restart(char *command)
48{
49 local_irq_disable();
50 pr_emerg("Rebooting (with %s watchdog reset)...\n",
51 (____raw_readq(&tx4938_ccfgptr->ccfg) & TX4938_CCFG_WDREXEN) ?
52 "external" : "internal");
53 /* clear watchdog status */
54 tx4938_ccfg_set(TX4938_CCFG_WDRST); /* W1C */
55 txx9_wdt_now(TX4938_TMR_REG(2) & 0xfffffffffULL);
56 while (!(____raw_readq(&tx4938_ccfgptr->ccfg) & TX4938_CCFG_WDRST))
57 ;
58 mdelay(10);
59 if (____raw_readq(&tx4938_ccfgptr->ccfg) & TX4938_CCFG_WDREXEN) {
60 pr_emerg("Rebooting (with internal watchdog reset)...\n");
61 /* External WDRST failed. Do internal watchdog reset */
62 tx4938_ccfg_clear(TX4938_CCFG_WDREXEN);
63 }
64 /* fallback */
65 (*_machine_halt)();
66}
67
68void show_registers(struct pt_regs *regs);
69static int tx4938_be_handler(struct pt_regs *regs, int is_fixup)
70{
71 int data = regs->cp0_cause & 4;
72 console_verbose();
73 pr_err("%cBE exception at %#lx\n", data ? 'D' : 'I', regs->cp0_epc);
74 pr_err("ccfg:%llx, toea:%llx\n",
75 (unsigned long long)____raw_readq(&tx4938_ccfgptr->ccfg),
76 (unsigned long long)____raw_readq(&tx4938_ccfgptr->toea));
77#ifdef CONFIG_PCI
78 tx4927_report_pcic_status();
79#endif
80 show_registers(regs);
81 panic("BusError!");
82}
83static void __init tx4938_be_init(void)
84{
85 board_be_handler = tx4938_be_handler;
86}
87
88static struct resource tx4938_sdram_resource[4];
89static struct resource tx4938_sram_resource;
90
91#define TX4938_SRAM_SIZE 0x800
92
93void __init tx4938_setup(void)
94{
95 int i;
96 __u32 divmode;
97 unsigned int cpuclk = 0;
98 u64 ccfg;
99
100 txx9_reg_res_init(TX4938_REV_PCODE(), TX4938_REG_BASE,
101 TX4938_REG_SIZE);
102 set_c0_config(TX49_CONF_CWFON);
103
104 /* SDRAMC,EBUSC are configured by PROM */
105 for (i = 0; i < 8; i++) {
106 if (!(TX4938_EBUSC_CR(i) & 0x8))
107 continue; /* disabled */
108 txx9_ce_res[i].start = (unsigned long)TX4938_EBUSC_BA(i);
109 txx9_ce_res[i].end =
110 txx9_ce_res[i].start + TX4938_EBUSC_SIZE(i) - 1;
111 request_resource(&iomem_resource, &txx9_ce_res[i]);
112 }
113
114 /* clocks */
115 ccfg = ____raw_readq(&tx4938_ccfgptr->ccfg);
116 if (txx9_master_clock) {
117 /* calculate gbus_clock and cpu_clock from master_clock */
118 divmode = (__u32)ccfg & TX4938_CCFG_DIVMODE_MASK;
119 switch (divmode) {
120 case TX4938_CCFG_DIVMODE_8:
121 case TX4938_CCFG_DIVMODE_10:
122 case TX4938_CCFG_DIVMODE_12:
123 case TX4938_CCFG_DIVMODE_16:
124 case TX4938_CCFG_DIVMODE_18:
125 txx9_gbus_clock = txx9_master_clock * 4; break;
126 default:
127 txx9_gbus_clock = txx9_master_clock;
128 }
129 switch (divmode) {
130 case TX4938_CCFG_DIVMODE_2:
131 case TX4938_CCFG_DIVMODE_8:
132 cpuclk = txx9_gbus_clock * 2; break;
133 case TX4938_CCFG_DIVMODE_2_5:
134 case TX4938_CCFG_DIVMODE_10:
135 cpuclk = txx9_gbus_clock * 5 / 2; break;
136 case TX4938_CCFG_DIVMODE_3:
137 case TX4938_CCFG_DIVMODE_12:
138 cpuclk = txx9_gbus_clock * 3; break;
139 case TX4938_CCFG_DIVMODE_4:
140 case TX4938_CCFG_DIVMODE_16:
141 cpuclk = txx9_gbus_clock * 4; break;
142 case TX4938_CCFG_DIVMODE_4_5:
143 case TX4938_CCFG_DIVMODE_18:
144 cpuclk = txx9_gbus_clock * 9 / 2; break;
145 }
146 txx9_cpu_clock = cpuclk;
147 } else {
148 if (txx9_cpu_clock == 0)
149 txx9_cpu_clock = 300000000; /* 300MHz */
150 /* calculate gbus_clock and master_clock from cpu_clock */
151 cpuclk = txx9_cpu_clock;
152 divmode = (__u32)ccfg & TX4938_CCFG_DIVMODE_MASK;
153 switch (divmode) {
154 case TX4938_CCFG_DIVMODE_2:
155 case TX4938_CCFG_DIVMODE_8:
156 txx9_gbus_clock = cpuclk / 2; break;
157 case TX4938_CCFG_DIVMODE_2_5:
158 case TX4938_CCFG_DIVMODE_10:
159 txx9_gbus_clock = cpuclk * 2 / 5; break;
160 case TX4938_CCFG_DIVMODE_3:
161 case TX4938_CCFG_DIVMODE_12:
162 txx9_gbus_clock = cpuclk / 3; break;
163 case TX4938_CCFG_DIVMODE_4:
164 case TX4938_CCFG_DIVMODE_16:
165 txx9_gbus_clock = cpuclk / 4; break;
166 case TX4938_CCFG_DIVMODE_4_5:
167 case TX4938_CCFG_DIVMODE_18:
168 txx9_gbus_clock = cpuclk * 2 / 9; break;
169 }
170 switch (divmode) {
171 case TX4938_CCFG_DIVMODE_8:
172 case TX4938_CCFG_DIVMODE_10:
173 case TX4938_CCFG_DIVMODE_12:
174 case TX4938_CCFG_DIVMODE_16:
175 case TX4938_CCFG_DIVMODE_18:
176 txx9_master_clock = txx9_gbus_clock / 4; break;
177 default:
178 txx9_master_clock = txx9_gbus_clock;
179 }
180 }
181 /* change default value to udelay/mdelay take reasonable time */
182 loops_per_jiffy = txx9_cpu_clock / HZ / 2;
183
184 /* CCFG */
185 tx4938_wdr_init();
186 /* clear BusErrorOnWrite flag (W1C) */
187 tx4938_ccfg_set(TX4938_CCFG_BEOW);
188 /* enable Timeout BusError */
189 if (txx9_ccfg_toeon)
190 tx4938_ccfg_set(TX4938_CCFG_TOE);
191
192 /* DMA selection */
193 txx9_clear64(&tx4938_ccfgptr->pcfg, TX4938_PCFG_DMASEL_ALL);
194
195 /* Use external clock for external arbiter */
196 if (!(____raw_readq(&tx4938_ccfgptr->ccfg) & TX4938_CCFG_PCIARB))
197 txx9_clear64(&tx4938_ccfgptr->pcfg, TX4938_PCFG_PCICLKEN_ALL);
198
199 pr_info("%s -- %dMHz(M%dMHz) CRIR:%08x CCFG:%llx PCFG:%llx\n",
200 txx9_pcode_str, (cpuclk + 500000) / 1000000,
201 (txx9_master_clock + 500000) / 1000000,
202 (__u32)____raw_readq(&tx4938_ccfgptr->crir),
203 ____raw_readq(&tx4938_ccfgptr->ccfg),
204 ____raw_readq(&tx4938_ccfgptr->pcfg));
205
206 pr_info("%s SDRAMC --", txx9_pcode_str);
207 for (i = 0; i < 4; i++) {
208 __u64 cr = TX4938_SDRAMC_CR(i);
209 unsigned long base, size;
210 if (!((__u32)cr & 0x00000400))
211 continue; /* disabled */
212 base = (unsigned long)(cr >> 49) << 21;
213 size = (((unsigned long)(cr >> 33) & 0x7fff) + 1) << 21;
214 pr_cont(" CR%d:%016llx", i, cr);
215 tx4938_sdram_resource[i].name = "SDRAM";
216 tx4938_sdram_resource[i].start = base;
217 tx4938_sdram_resource[i].end = base + size - 1;
218 tx4938_sdram_resource[i].flags = IORESOURCE_MEM;
219 request_resource(&iomem_resource, &tx4938_sdram_resource[i]);
220 }
221 pr_cont(" TR:%09llx\n", ____raw_readq(&tx4938_sdramcptr->tr));
222
223 /* SRAM */
224 if (txx9_pcode == 0x4938 && ____raw_readq(&tx4938_sramcptr->cr) & 1) {
225 unsigned int size = TX4938_SRAM_SIZE;
226 tx4938_sram_resource.name = "SRAM";
227 tx4938_sram_resource.start =
228 (____raw_readq(&tx4938_sramcptr->cr) >> (39-11))
229 & ~(size - 1);
230 tx4938_sram_resource.end =
231 tx4938_sram_resource.start + TX4938_SRAM_SIZE - 1;
232 tx4938_sram_resource.flags = IORESOURCE_MEM;
233 request_resource(&iomem_resource, &tx4938_sram_resource);
234 }
235
236 /* TMR */
237 /* disable all timers */
238 for (i = 0; i < TX4938_NR_TMR; i++)
239 txx9_tmr_init(TX4938_TMR_REG(i) & 0xfffffffffULL);
240
241 /* PIO */
242 __raw_writel(0, &tx4938_pioptr->maskcpu);
243 __raw_writel(0, &tx4938_pioptr->maskext);
244
245 if (txx9_pcode == 0x4938) {
246 __u64 pcfg = ____raw_readq(&tx4938_ccfgptr->pcfg);
247 /* set PCIC1 reset */
248 txx9_set64(&tx4938_ccfgptr->clkctr, TX4938_CLKCTR_PCIC1RST);
249 if (pcfg & (TX4938_PCFG_ETH0_SEL | TX4938_PCFG_ETH1_SEL)) {
250 mdelay(1); /* at least 128 cpu clock */
251 /* clear PCIC1 reset */
252 txx9_clear64(&tx4938_ccfgptr->clkctr,
253 TX4938_CLKCTR_PCIC1RST);
254 } else {
255 pr_info("%s: stop PCIC1\n", txx9_pcode_str);
256 /* stop PCIC1 */
257 txx9_set64(&tx4938_ccfgptr->clkctr,
258 TX4938_CLKCTR_PCIC1CKD);
259 }
260 if (!(pcfg & TX4938_PCFG_ETH0_SEL)) {
261 pr_info("%s: stop ETH0\n", txx9_pcode_str);
262 txx9_set64(&tx4938_ccfgptr->clkctr,
263 TX4938_CLKCTR_ETH0RST);
264 txx9_set64(&tx4938_ccfgptr->clkctr,
265 TX4938_CLKCTR_ETH0CKD);
266 }
267 if (!(pcfg & TX4938_PCFG_ETH1_SEL)) {
268 pr_info("%s: stop ETH1\n", txx9_pcode_str);
269 txx9_set64(&tx4938_ccfgptr->clkctr,
270 TX4938_CLKCTR_ETH1RST);
271 txx9_set64(&tx4938_ccfgptr->clkctr,
272 TX4938_CLKCTR_ETH1CKD);
273 }
274 }
275
276 _machine_restart = tx4938_machine_restart;
277 board_be_init = tx4938_be_init;
278}
279
280void __init tx4938_time_init(unsigned int tmrnr)
281{
282 if (____raw_readq(&tx4938_ccfgptr->ccfg) & TX4938_CCFG_TINTDIS)
283 txx9_clockevent_init(TX4938_TMR_REG(tmrnr) & 0xfffffffffULL,
284 TXX9_IRQ_BASE + TX4938_IR_TMR(tmrnr),
285 TXX9_IMCLK);
286}
287
288void __init tx4938_sio_init(unsigned int sclk, unsigned int cts_mask)
289{
290 int i;
291 unsigned int ch_mask = 0;
292
293 if (__raw_readq(&tx4938_ccfgptr->pcfg) & TX4938_PCFG_ETH0_SEL)
294 ch_mask |= 1 << 1; /* disable SIO1 by PCFG setting */
295 for (i = 0; i < 2; i++) {
296 if ((1 << i) & ch_mask)
297 continue;
298 txx9_sio_init(TX4938_SIO_REG(i) & 0xfffffffffULL,
299 TXX9_IRQ_BASE + TX4938_IR_SIO(i),
300 i, sclk, (1 << i) & cts_mask);
301 }
302}
303
304void __init tx4938_spi_init(int busid)
305{
306 txx9_spi_init(busid, TX4938_SPI_REG & 0xfffffffffULL,
307 TXX9_IRQ_BASE + TX4938_IR_SPI);
308}
309
310void __init tx4938_ethaddr_init(unsigned char *addr0, unsigned char *addr1)
311{
312 u64 pcfg = __raw_readq(&tx4938_ccfgptr->pcfg);
313
314 if (addr0 && (pcfg & TX4938_PCFG_ETH0_SEL))
315 txx9_ethaddr_init(TXX9_IRQ_BASE + TX4938_IR_ETH0, addr0);
316 if (addr1 && (pcfg & TX4938_PCFG_ETH1_SEL))
317 txx9_ethaddr_init(TXX9_IRQ_BASE + TX4938_IR_ETH1, addr1);
318}
319
320void __init tx4938_mtd_init(int ch)
321{
322 struct physmap_flash_data pdata = {
323 .width = TX4938_EBUSC_WIDTH(ch) / 8,
324 };
325 unsigned long start = txx9_ce_res[ch].start;
326 unsigned long size = txx9_ce_res[ch].end - start + 1;
327
328 if (!(TX4938_EBUSC_CR(ch) & 0x8))
329 return; /* disabled */
330 txx9_physmap_flash_init(ch, start, size, &pdata);
331}
332
333void __init tx4938_ata_init(unsigned int irq, unsigned int shift, int tune)
334{
335 struct platform_device *pdev;
336 struct resource res[] = {
337 {
338 /* .start and .end are filled in later */
339 .flags = IORESOURCE_MEM,
340 }, {
341 .start = irq,
342 .flags = IORESOURCE_IRQ,
343 },
344 };
345 struct tx4938ide_platform_info pdata = {
346 .ioport_shift = shift,
347 /*
348 * The IDE driver should not change bus timings if other ISA
349 * devices existed.
350 */
351 .gbus_clock = tune ? txx9_gbus_clock : 0,
352 };
353 u64 ebccr;
354 int i;
355
356 if ((__raw_readq(&tx4938_ccfgptr->pcfg) &
357 (TX4938_PCFG_ATA_SEL | TX4938_PCFG_NDF_SEL))
358 != TX4938_PCFG_ATA_SEL)
359 return;
360 for (i = 0; i < 8; i++) {
361 /* check EBCCRn.ISA, EBCCRn.BSZ, EBCCRn.ME */
362 ebccr = __raw_readq(&tx4938_ebuscptr->cr[i]);
363 if ((ebccr & 0x00f00008) == 0x00e00008)
364 break;
365 }
366 if (i == 8)
367 return;
368 pdata.ebus_ch = i;
369 res[0].start = ((ebccr >> 48) << 20) + 0x10000;
370 res[0].end = res[0].start + 0x20000 - 1;
371 pdev = platform_device_alloc("tx4938ide", -1);
372 if (!pdev ||
373 platform_device_add_resources(pdev, res, ARRAY_SIZE(res)) ||
374 platform_device_add_data(pdev, &pdata, sizeof(pdata)) ||
375 platform_device_add(pdev))
376 platform_device_put(pdev);
377}
378
379void __init tx4938_ndfmc_init(unsigned int hold, unsigned int spw)
380{
381 struct txx9ndfmc_platform_data plat_data = {
382 .shift = 1,
383 .gbus_clock = txx9_gbus_clock,
384 .hold = hold,
385 .spw = spw,
386 .ch_mask = 1,
387 };
388 unsigned long baseaddr = TX4938_NDFMC_REG & 0xfffffffffULL;
389
390#ifdef __BIG_ENDIAN
391 baseaddr += 4;
392#endif
393 if ((__raw_readq(&tx4938_ccfgptr->pcfg) &
394 (TX4938_PCFG_ATA_SEL|TX4938_PCFG_ISA_SEL|TX4938_PCFG_NDF_SEL)) ==
395 TX4938_PCFG_NDF_SEL)
396 txx9_ndfmc_init(baseaddr, &plat_data);
397}
398
399void __init tx4938_dmac_init(int memcpy_chan0, int memcpy_chan1)
400{
401 struct txx9dmac_platform_data plat_data = {
402 .have_64bit_regs = true,
403 };
404 int i;
405
406 for (i = 0; i < 2; i++) {
407 plat_data.memcpy_chan = i ? memcpy_chan1 : memcpy_chan0;
408 txx9_dmac_init(i, TX4938_DMA_REG(i) & 0xfffffffffULL,
409 TXX9_IRQ_BASE + TX4938_IR_DMA(i, 0),
410 &plat_data);
411 }
412}
413
414void __init tx4938_aclc_init(void)
415{
416 u64 pcfg = __raw_readq(&tx4938_ccfgptr->pcfg);
417
418 if ((pcfg & TX4938_PCFG_SEL2) &&
419 !(pcfg & TX4938_PCFG_ETH0_SEL))
420 txx9_aclc_init(TX4938_ACLC_REG & 0xfffffffffULL,
421 TXX9_IRQ_BASE + TX4938_IR_ACLC,
422 1, 0, 1);
423}
424
425void __init tx4938_sramc_init(void)
426{
427 if (tx4938_sram_resource.start)
428 txx9_sramc_init(&tx4938_sram_resource);
429}
430
431static void __init tx4938_stop_unused_modules(void)
432{
433 __u64 pcfg, rst = 0, ckd = 0;
434 char buf[128];
435
436 buf[0] = '\0';
437 local_irq_disable();
438 pcfg = ____raw_readq(&tx4938_ccfgptr->pcfg);
439 switch (txx9_pcode) {
440 case 0x4937:
441 if (!(pcfg & TX4938_PCFG_SEL2)) {
442 rst |= TX4938_CLKCTR_ACLRST;
443 ckd |= TX4938_CLKCTR_ACLCKD;
444 strcat(buf, " ACLC");
445 }
446 break;
447 case 0x4938:
448 if (!(pcfg & TX4938_PCFG_SEL2) ||
449 (pcfg & TX4938_PCFG_ETH0_SEL)) {
450 rst |= TX4938_CLKCTR_ACLRST;
451 ckd |= TX4938_CLKCTR_ACLCKD;
452 strcat(buf, " ACLC");
453 }
454 if ((pcfg &
455 (TX4938_PCFG_ATA_SEL | TX4938_PCFG_ISA_SEL |
456 TX4938_PCFG_NDF_SEL))
457 != TX4938_PCFG_NDF_SEL) {
458 rst |= TX4938_CLKCTR_NDFRST;
459 ckd |= TX4938_CLKCTR_NDFCKD;
460 strcat(buf, " NDFMC");
461 }
462 if (!(pcfg & TX4938_PCFG_SPI_SEL)) {
463 rst |= TX4938_CLKCTR_SPIRST;
464 ckd |= TX4938_CLKCTR_SPICKD;
465 strcat(buf, " SPI");
466 }
467 break;
468 }
469 if (rst | ckd) {
470 txx9_set64(&tx4938_ccfgptr->clkctr, rst);
471 txx9_set64(&tx4938_ccfgptr->clkctr, ckd);
472 }
473 local_irq_enable();
474 if (buf[0])
475 pr_info("%s: stop%s\n", txx9_pcode_str, buf);
476}
477
478static int __init tx4938_late_init(void)
479{
480 if (txx9_pcode != 0x4937 && txx9_pcode != 0x4938)
481 return -ENODEV;
482 tx4938_stop_unused_modules();
483 return 0;
484}
485late_initcall(tx4938_late_init);
diff --git a/arch/mips/txx9/generic/setup_tx4939.c b/arch/mips/txx9/generic/setup_tx4939.c
new file mode 100644
index 000000000..bf8a3cdab
--- /dev/null
+++ b/arch/mips/txx9/generic/setup_tx4939.c
@@ -0,0 +1,568 @@
1/*
2 * TX4939 setup routines
3 * Based on linux/arch/mips/txx9/generic/setup_tx4938.c,
4 * and RBTX49xx patch from CELF patch archive.
5 *
6 * 2003-2005 (c) MontaVista Software, Inc.
7 * (C) Copyright TOSHIBA CORPORATION 2000-2001, 2004-2007
8 *
9 * This file is subject to the terms and conditions of the GNU General Public
10 * License. See the file "COPYING" in the main directory of this archive
11 * for more details.
12 */
13#include <linux/init.h>
14#include <linux/ioport.h>
15#include <linux/delay.h>
16#include <linux/netdevice.h>
17#include <linux/notifier.h>
18#include <linux/device.h>
19#include <linux/ethtool.h>
20#include <linux/param.h>
21#include <linux/ptrace.h>
22#include <linux/mtd/physmap.h>
23#include <linux/platform_device.h>
24#include <linux/platform_data/txx9/ndfmc.h>
25#include <asm/reboot.h>
26#include <asm/traps.h>
27#include <asm/txx9irq.h>
28#include <asm/txx9tmr.h>
29#include <asm/txx9/generic.h>
30#include <asm/txx9/dmac.h>
31#include <asm/txx9/tx4939.h>
32
33static void __init tx4939_wdr_init(void)
34{
35 /* report watchdog reset status */
36 if (____raw_readq(&tx4939_ccfgptr->ccfg) & TX4939_CCFG_WDRST)
37 pr_warn("Watchdog reset detected at 0x%lx\n",
38 read_c0_errorepc());
39 /* clear WatchDogReset (W1C) */
40 tx4939_ccfg_set(TX4939_CCFG_WDRST);
41 /* do reset on watchdog */
42 tx4939_ccfg_set(TX4939_CCFG_WR);
43}
44
45void __init tx4939_wdt_init(void)
46{
47 txx9_wdt_init(TX4939_TMR_REG(2) & 0xfffffffffULL);
48}
49
50static void tx4939_machine_restart(char *command)
51{
52 local_irq_disable();
53 pr_emerg("Rebooting (with %s watchdog reset)...\n",
54 (____raw_readq(&tx4939_ccfgptr->ccfg) & TX4939_CCFG_WDREXEN) ?
55 "external" : "internal");
56 /* clear watchdog status */
57 tx4939_ccfg_set(TX4939_CCFG_WDRST); /* W1C */
58 txx9_wdt_now(TX4939_TMR_REG(2) & 0xfffffffffULL);
59 while (!(____raw_readq(&tx4939_ccfgptr->ccfg) & TX4939_CCFG_WDRST))
60 ;
61 mdelay(10);
62 if (____raw_readq(&tx4939_ccfgptr->ccfg) & TX4939_CCFG_WDREXEN) {
63 pr_emerg("Rebooting (with internal watchdog reset)...\n");
64 /* External WDRST failed. Do internal watchdog reset */
65 tx4939_ccfg_clear(TX4939_CCFG_WDREXEN);
66 }
67 /* fallback */
68 (*_machine_halt)();
69}
70
71void show_registers(struct pt_regs *regs);
72static int tx4939_be_handler(struct pt_regs *regs, int is_fixup)
73{
74 int data = regs->cp0_cause & 4;
75 console_verbose();
76 pr_err("%cBE exception at %#lx\n",
77 data ? 'D' : 'I', regs->cp0_epc);
78 pr_err("ccfg:%llx, toea:%llx\n",
79 (unsigned long long)____raw_readq(&tx4939_ccfgptr->ccfg),
80 (unsigned long long)____raw_readq(&tx4939_ccfgptr->toea));
81#ifdef CONFIG_PCI
82 tx4927_report_pcic_status();
83#endif
84 show_registers(regs);
85 panic("BusError!");
86}
87static void __init tx4939_be_init(void)
88{
89 board_be_handler = tx4939_be_handler;
90}
91
92static struct resource tx4939_sdram_resource[4];
93static struct resource tx4939_sram_resource;
94#define TX4939_SRAM_SIZE 0x800
95
96void __init tx4939_setup(void)
97{
98 int i;
99 __u32 divmode;
100 __u64 pcfg;
101 unsigned int cpuclk = 0;
102
103 txx9_reg_res_init(TX4939_REV_PCODE(), TX4939_REG_BASE,
104 TX4939_REG_SIZE);
105 set_c0_config(TX49_CONF_CWFON);
106
107 /* SDRAMC,EBUSC are configured by PROM */
108 for (i = 0; i < 4; i++) {
109 if (!(TX4939_EBUSC_CR(i) & 0x8))
110 continue; /* disabled */
111 txx9_ce_res[i].start = (unsigned long)TX4939_EBUSC_BA(i);
112 txx9_ce_res[i].end =
113 txx9_ce_res[i].start + TX4939_EBUSC_SIZE(i) - 1;
114 request_resource(&iomem_resource, &txx9_ce_res[i]);
115 }
116
117 /* clocks */
118 if (txx9_master_clock) {
119 /* calculate cpu_clock from master_clock */
120 divmode = (__u32)____raw_readq(&tx4939_ccfgptr->ccfg) &
121 TX4939_CCFG_MULCLK_MASK;
122 cpuclk = txx9_master_clock * 20 / 2;
123 switch (divmode) {
124 case TX4939_CCFG_MULCLK_8:
125 cpuclk = cpuclk / 3 * 4 /* / 6 * 8 */; break;
126 case TX4939_CCFG_MULCLK_9:
127 cpuclk = cpuclk / 2 * 3 /* / 6 * 9 */; break;
128 case TX4939_CCFG_MULCLK_10:
129 cpuclk = cpuclk / 3 * 5 /* / 6 * 10 */; break;
130 case TX4939_CCFG_MULCLK_11:
131 cpuclk = cpuclk / 6 * 11; break;
132 case TX4939_CCFG_MULCLK_12:
133 cpuclk = cpuclk * 2 /* / 6 * 12 */; break;
134 case TX4939_CCFG_MULCLK_13:
135 cpuclk = cpuclk / 6 * 13; break;
136 case TX4939_CCFG_MULCLK_14:
137 cpuclk = cpuclk / 3 * 7 /* / 6 * 14 */; break;
138 case TX4939_CCFG_MULCLK_15:
139 cpuclk = cpuclk / 2 * 5 /* / 6 * 15 */; break;
140 }
141 txx9_cpu_clock = cpuclk;
142 } else {
143 if (txx9_cpu_clock == 0)
144 txx9_cpu_clock = 400000000; /* 400MHz */
145 /* calculate master_clock from cpu_clock */
146 cpuclk = txx9_cpu_clock;
147 divmode = (__u32)____raw_readq(&tx4939_ccfgptr->ccfg) &
148 TX4939_CCFG_MULCLK_MASK;
149 switch (divmode) {
150 case TX4939_CCFG_MULCLK_8:
151 txx9_master_clock = cpuclk * 6 / 8; break;
152 case TX4939_CCFG_MULCLK_9:
153 txx9_master_clock = cpuclk * 6 / 9; break;
154 case TX4939_CCFG_MULCLK_10:
155 txx9_master_clock = cpuclk * 6 / 10; break;
156 case TX4939_CCFG_MULCLK_11:
157 txx9_master_clock = cpuclk * 6 / 11; break;
158 case TX4939_CCFG_MULCLK_12:
159 txx9_master_clock = cpuclk * 6 / 12; break;
160 case TX4939_CCFG_MULCLK_13:
161 txx9_master_clock = cpuclk * 6 / 13; break;
162 case TX4939_CCFG_MULCLK_14:
163 txx9_master_clock = cpuclk * 6 / 14; break;
164 case TX4939_CCFG_MULCLK_15:
165 txx9_master_clock = cpuclk * 6 / 15; break;
166 }
167 txx9_master_clock /= 10; /* * 2 / 20 */
168 }
169 /* calculate gbus_clock from cpu_clock */
170 divmode = (__u32)____raw_readq(&tx4939_ccfgptr->ccfg) &
171 TX4939_CCFG_YDIVMODE_MASK;
172 txx9_gbus_clock = txx9_cpu_clock;
173 switch (divmode) {
174 case TX4939_CCFG_YDIVMODE_2:
175 txx9_gbus_clock /= 2; break;
176 case TX4939_CCFG_YDIVMODE_3:
177 txx9_gbus_clock /= 3; break;
178 case TX4939_CCFG_YDIVMODE_5:
179 txx9_gbus_clock /= 5; break;
180 case TX4939_CCFG_YDIVMODE_6:
181 txx9_gbus_clock /= 6; break;
182 }
183 /* change default value to udelay/mdelay take reasonable time */
184 loops_per_jiffy = txx9_cpu_clock / HZ / 2;
185
186 /* CCFG */
187 tx4939_wdr_init();
188 /* clear BusErrorOnWrite flag (W1C) */
189 tx4939_ccfg_set(TX4939_CCFG_WDRST | TX4939_CCFG_BEOW);
190 /* enable Timeout BusError */
191 if (txx9_ccfg_toeon)
192 tx4939_ccfg_set(TX4939_CCFG_TOE);
193
194 /* DMA selection */
195 txx9_clear64(&tx4939_ccfgptr->pcfg, TX4939_PCFG_DMASEL_ALL);
196
197 /* Use external clock for external arbiter */
198 if (!(____raw_readq(&tx4939_ccfgptr->ccfg) & TX4939_CCFG_PCIARB))
199 txx9_clear64(&tx4939_ccfgptr->pcfg, TX4939_PCFG_PCICLKEN_ALL);
200
201 pr_info("%s -- %dMHz(M%dMHz,G%dMHz) CRIR:%08x CCFG:%llx PCFG:%llx\n",
202 txx9_pcode_str,
203 (cpuclk + 500000) / 1000000,
204 (txx9_master_clock + 500000) / 1000000,
205 (txx9_gbus_clock + 500000) / 1000000,
206 (__u32)____raw_readq(&tx4939_ccfgptr->crir),
207 ____raw_readq(&tx4939_ccfgptr->ccfg),
208 ____raw_readq(&tx4939_ccfgptr->pcfg));
209
210 pr_info("%s DDRC -- EN:%08x", txx9_pcode_str,
211 (__u32)____raw_readq(&tx4939_ddrcptr->winen));
212 for (i = 0; i < 4; i++) {
213 __u64 win = ____raw_readq(&tx4939_ddrcptr->win[i]);
214 if (!((__u32)____raw_readq(&tx4939_ddrcptr->winen) & (1 << i)))
215 continue; /* disabled */
216 pr_cont(" #%d:%016llx", i, win);
217 tx4939_sdram_resource[i].name = "DDR SDRAM";
218 tx4939_sdram_resource[i].start =
219 (unsigned long)(win >> 48) << 20;
220 tx4939_sdram_resource[i].end =
221 ((((unsigned long)(win >> 32) & 0xffff) + 1) <<
222 20) - 1;
223 tx4939_sdram_resource[i].flags = IORESOURCE_MEM;
224 request_resource(&iomem_resource, &tx4939_sdram_resource[i]);
225 }
226 pr_cont("\n");
227
228 /* SRAM */
229 if (____raw_readq(&tx4939_sramcptr->cr) & 1) {
230 unsigned int size = TX4939_SRAM_SIZE;
231 tx4939_sram_resource.name = "SRAM";
232 tx4939_sram_resource.start =
233 (____raw_readq(&tx4939_sramcptr->cr) >> (39-11))
234 & ~(size - 1);
235 tx4939_sram_resource.end =
236 tx4939_sram_resource.start + TX4939_SRAM_SIZE - 1;
237 tx4939_sram_resource.flags = IORESOURCE_MEM;
238 request_resource(&iomem_resource, &tx4939_sram_resource);
239 }
240
241 /* TMR */
242 /* disable all timers */
243 for (i = 0; i < TX4939_NR_TMR; i++)
244 txx9_tmr_init(TX4939_TMR_REG(i) & 0xfffffffffULL);
245
246 /* set PCIC1 reset (required to prevent hangup on BIST) */
247 txx9_set64(&tx4939_ccfgptr->clkctr, TX4939_CLKCTR_PCI1RST);
248 pcfg = ____raw_readq(&tx4939_ccfgptr->pcfg);
249 if (pcfg & (TX4939_PCFG_ET0MODE | TX4939_PCFG_ET1MODE)) {
250 mdelay(1); /* at least 128 cpu clock */
251 /* clear PCIC1 reset */
252 txx9_clear64(&tx4939_ccfgptr->clkctr, TX4939_CLKCTR_PCI1RST);
253 } else {
254 pr_info("%s: stop PCIC1\n", txx9_pcode_str);
255 /* stop PCIC1 */
256 txx9_set64(&tx4939_ccfgptr->clkctr, TX4939_CLKCTR_PCI1CKD);
257 }
258 if (!(pcfg & TX4939_PCFG_ET0MODE)) {
259 pr_info("%s: stop ETH0\n", txx9_pcode_str);
260 txx9_set64(&tx4939_ccfgptr->clkctr, TX4939_CLKCTR_ETH0RST);
261 txx9_set64(&tx4939_ccfgptr->clkctr, TX4939_CLKCTR_ETH0CKD);
262 }
263 if (!(pcfg & TX4939_PCFG_ET1MODE)) {
264 pr_info("%s: stop ETH1\n", txx9_pcode_str);
265 txx9_set64(&tx4939_ccfgptr->clkctr, TX4939_CLKCTR_ETH1RST);
266 txx9_set64(&tx4939_ccfgptr->clkctr, TX4939_CLKCTR_ETH1CKD);
267 }
268
269 _machine_restart = tx4939_machine_restart;
270 board_be_init = tx4939_be_init;
271}
272
273void __init tx4939_time_init(unsigned int tmrnr)
274{
275 if (____raw_readq(&tx4939_ccfgptr->ccfg) & TX4939_CCFG_TINTDIS)
276 txx9_clockevent_init(TX4939_TMR_REG(tmrnr) & 0xfffffffffULL,
277 TXX9_IRQ_BASE + TX4939_IR_TMR(tmrnr),
278 TXX9_IMCLK);
279}
280
281void __init tx4939_sio_init(unsigned int sclk, unsigned int cts_mask)
282{
283 int i;
284 unsigned int ch_mask = 0;
285 __u64 pcfg = __raw_readq(&tx4939_ccfgptr->pcfg);
286
287 cts_mask |= ~1; /* only SIO0 have RTS/CTS */
288 if ((pcfg & TX4939_PCFG_SIO2MODE_MASK) != TX4939_PCFG_SIO2MODE_SIO0)
289 cts_mask |= 1 << 0; /* disable SIO0 RTS/CTS by PCFG setting */
290 if ((pcfg & TX4939_PCFG_SIO2MODE_MASK) != TX4939_PCFG_SIO2MODE_SIO2)
291 ch_mask |= 1 << 2; /* disable SIO2 by PCFG setting */
292 if (pcfg & TX4939_PCFG_SIO3MODE)
293 ch_mask |= 1 << 3; /* disable SIO3 by PCFG setting */
294 for (i = 0; i < 4; i++) {
295 if ((1 << i) & ch_mask)
296 continue;
297 txx9_sio_init(TX4939_SIO_REG(i) & 0xfffffffffULL,
298 TXX9_IRQ_BASE + TX4939_IR_SIO(i),
299 i, sclk, (1 << i) & cts_mask);
300 }
301}
302
303#if IS_ENABLED(CONFIG_TC35815)
304static u32 tx4939_get_eth_speed(struct net_device *dev)
305{
306 struct ethtool_link_ksettings cmd;
307
308 if (__ethtool_get_link_ksettings(dev, &cmd))
309 return 100; /* default 100Mbps */
310
311 return cmd.base.speed;
312}
313
314static int tx4939_netdev_event(struct notifier_block *this,
315 unsigned long event,
316 void *ptr)
317{
318 struct net_device *dev = netdev_notifier_info_to_dev(ptr);
319
320 if (event == NETDEV_CHANGE && netif_carrier_ok(dev)) {
321 __u64 bit = 0;
322 if (dev->irq == TXX9_IRQ_BASE + TX4939_IR_ETH(0))
323 bit = TX4939_PCFG_SPEED0;
324 else if (dev->irq == TXX9_IRQ_BASE + TX4939_IR_ETH(1))
325 bit = TX4939_PCFG_SPEED1;
326 if (bit) {
327 if (tx4939_get_eth_speed(dev) == 100)
328 txx9_set64(&tx4939_ccfgptr->pcfg, bit);
329 else
330 txx9_clear64(&tx4939_ccfgptr->pcfg, bit);
331 }
332 }
333 return NOTIFY_DONE;
334}
335
336static struct notifier_block tx4939_netdev_notifier = {
337 .notifier_call = tx4939_netdev_event,
338 .priority = 1,
339};
340
341void __init tx4939_ethaddr_init(unsigned char *addr0, unsigned char *addr1)
342{
343 u64 pcfg = __raw_readq(&tx4939_ccfgptr->pcfg);
344
345 if (addr0 && (pcfg & TX4939_PCFG_ET0MODE))
346 txx9_ethaddr_init(TXX9_IRQ_BASE + TX4939_IR_ETH(0), addr0);
347 if (addr1 && (pcfg & TX4939_PCFG_ET1MODE))
348 txx9_ethaddr_init(TXX9_IRQ_BASE + TX4939_IR_ETH(1), addr1);
349 register_netdevice_notifier(&tx4939_netdev_notifier);
350}
351#else
352void __init tx4939_ethaddr_init(unsigned char *addr0, unsigned char *addr1)
353{
354}
355#endif
356
357void __init tx4939_mtd_init(int ch)
358{
359 struct physmap_flash_data pdata = {
360 .width = TX4939_EBUSC_WIDTH(ch) / 8,
361 };
362 unsigned long start = txx9_ce_res[ch].start;
363 unsigned long size = txx9_ce_res[ch].end - start + 1;
364
365 if (!(TX4939_EBUSC_CR(ch) & 0x8))
366 return; /* disabled */
367 txx9_physmap_flash_init(ch, start, size, &pdata);
368}
369
370#define TX4939_ATA_REG_PHYS(ch) (TX4939_ATA_REG(ch) & 0xfffffffffULL)
371void __init tx4939_ata_init(void)
372{
373 static struct resource ata0_res[] = {
374 {
375 .start = TX4939_ATA_REG_PHYS(0),
376 .end = TX4939_ATA_REG_PHYS(0) + 0x1000 - 1,
377 .flags = IORESOURCE_MEM,
378 }, {
379 .start = TXX9_IRQ_BASE + TX4939_IR_ATA(0),
380 .flags = IORESOURCE_IRQ,
381 },
382 };
383 static struct resource ata1_res[] = {
384 {
385 .start = TX4939_ATA_REG_PHYS(1),
386 .end = TX4939_ATA_REG_PHYS(1) + 0x1000 - 1,
387 .flags = IORESOURCE_MEM,
388 }, {
389 .start = TXX9_IRQ_BASE + TX4939_IR_ATA(1),
390 .flags = IORESOURCE_IRQ,
391 },
392 };
393 static struct platform_device ata0_dev = {
394 .name = "tx4939ide",
395 .id = 0,
396 .num_resources = ARRAY_SIZE(ata0_res),
397 .resource = ata0_res,
398 };
399 static struct platform_device ata1_dev = {
400 .name = "tx4939ide",
401 .id = 1,
402 .num_resources = ARRAY_SIZE(ata1_res),
403 .resource = ata1_res,
404 };
405 __u64 pcfg = __raw_readq(&tx4939_ccfgptr->pcfg);
406
407 if (pcfg & TX4939_PCFG_ATA0MODE)
408 platform_device_register(&ata0_dev);
409 if ((pcfg & (TX4939_PCFG_ATA1MODE |
410 TX4939_PCFG_ET1MODE |
411 TX4939_PCFG_ET0MODE)) == TX4939_PCFG_ATA1MODE)
412 platform_device_register(&ata1_dev);
413}
414
415void __init tx4939_rtc_init(void)
416{
417 static struct resource res[] = {
418 {
419 .start = TX4939_RTC_REG & 0xfffffffffULL,
420 .end = (TX4939_RTC_REG & 0xfffffffffULL) + 0x100 - 1,
421 .flags = IORESOURCE_MEM,
422 }, {
423 .start = TXX9_IRQ_BASE + TX4939_IR_RTC,
424 .flags = IORESOURCE_IRQ,
425 },
426 };
427 static struct platform_device rtc_dev = {
428 .name = "tx4939rtc",
429 .id = -1,
430 .num_resources = ARRAY_SIZE(res),
431 .resource = res,
432 };
433
434 platform_device_register(&rtc_dev);
435}
436
437void __init tx4939_ndfmc_init(unsigned int hold, unsigned int spw,
438 unsigned char ch_mask, unsigned char wide_mask)
439{
440 struct txx9ndfmc_platform_data plat_data = {
441 .shift = 1,
442 .gbus_clock = txx9_gbus_clock,
443 .hold = hold,
444 .spw = spw,
445 .flags = NDFMC_PLAT_FLAG_NO_RSTR | NDFMC_PLAT_FLAG_HOLDADD |
446 NDFMC_PLAT_FLAG_DUMMYWRITE,
447 .ch_mask = ch_mask,
448 .wide_mask = wide_mask,
449 };
450 txx9_ndfmc_init(TX4939_NDFMC_REG & 0xfffffffffULL, &plat_data);
451}
452
453void __init tx4939_dmac_init(int memcpy_chan0, int memcpy_chan1)
454{
455 struct txx9dmac_platform_data plat_data = {
456 .have_64bit_regs = true,
457 };
458 int i;
459
460 for (i = 0; i < 2; i++) {
461 plat_data.memcpy_chan = i ? memcpy_chan1 : memcpy_chan0;
462 txx9_dmac_init(i, TX4939_DMA_REG(i) & 0xfffffffffULL,
463 TXX9_IRQ_BASE + TX4939_IR_DMA(i, 0),
464 &plat_data);
465 }
466}
467
468void __init tx4939_aclc_init(void)
469{
470 u64 pcfg = __raw_readq(&tx4939_ccfgptr->pcfg);
471
472 if ((pcfg & TX4939_PCFG_I2SMODE_MASK) == TX4939_PCFG_I2SMODE_ACLC)
473 txx9_aclc_init(TX4939_ACLC_REG & 0xfffffffffULL,
474 TXX9_IRQ_BASE + TX4939_IR_ACLC, 1, 0, 1);
475}
476
477void __init tx4939_sramc_init(void)
478{
479 if (tx4939_sram_resource.start)
480 txx9_sramc_init(&tx4939_sram_resource);
481}
482
483void __init tx4939_rng_init(void)
484{
485 static struct resource res = {
486 .start = TX4939_RNG_REG & 0xfffffffffULL,
487 .end = (TX4939_RNG_REG & 0xfffffffffULL) + 0x30 - 1,
488 .flags = IORESOURCE_MEM,
489 };
490 static struct platform_device pdev = {
491 .name = "tx4939-rng",
492 .id = -1,
493 .num_resources = 1,
494 .resource = &res,
495 };
496
497 platform_device_register(&pdev);
498}
499
500static void __init tx4939_stop_unused_modules(void)
501{
502 __u64 pcfg, rst = 0, ckd = 0;
503 char buf[128];
504
505 buf[0] = '\0';
506 local_irq_disable();
507 pcfg = ____raw_readq(&tx4939_ccfgptr->pcfg);
508 if ((pcfg & TX4939_PCFG_I2SMODE_MASK) !=
509 TX4939_PCFG_I2SMODE_ACLC) {
510 rst |= TX4939_CLKCTR_ACLRST;
511 ckd |= TX4939_CLKCTR_ACLCKD;
512 strcat(buf, " ACLC");
513 }
514 if ((pcfg & TX4939_PCFG_I2SMODE_MASK) !=
515 TX4939_PCFG_I2SMODE_I2S &&
516 (pcfg & TX4939_PCFG_I2SMODE_MASK) !=
517 TX4939_PCFG_I2SMODE_I2S_ALT) {
518 rst |= TX4939_CLKCTR_I2SRST;
519 ckd |= TX4939_CLKCTR_I2SCKD;
520 strcat(buf, " I2S");
521 }
522 if (!(pcfg & TX4939_PCFG_ATA0MODE)) {
523 rst |= TX4939_CLKCTR_ATA0RST;
524 ckd |= TX4939_CLKCTR_ATA0CKD;
525 strcat(buf, " ATA0");
526 }
527 if (!(pcfg & TX4939_PCFG_ATA1MODE)) {
528 rst |= TX4939_CLKCTR_ATA1RST;
529 ckd |= TX4939_CLKCTR_ATA1CKD;
530 strcat(buf, " ATA1");
531 }
532 if (pcfg & TX4939_PCFG_SPIMODE) {
533 rst |= TX4939_CLKCTR_SPIRST;
534 ckd |= TX4939_CLKCTR_SPICKD;
535 strcat(buf, " SPI");
536 }
537 if (!(pcfg & (TX4939_PCFG_VSSMODE | TX4939_PCFG_VPSMODE))) {
538 rst |= TX4939_CLKCTR_VPCRST;
539 ckd |= TX4939_CLKCTR_VPCCKD;
540 strcat(buf, " VPC");
541 }
542 if ((pcfg & TX4939_PCFG_SIO2MODE_MASK) != TX4939_PCFG_SIO2MODE_SIO2) {
543 rst |= TX4939_CLKCTR_SIO2RST;
544 ckd |= TX4939_CLKCTR_SIO2CKD;
545 strcat(buf, " SIO2");
546 }
547 if (pcfg & TX4939_PCFG_SIO3MODE) {
548 rst |= TX4939_CLKCTR_SIO3RST;
549 ckd |= TX4939_CLKCTR_SIO3CKD;
550 strcat(buf, " SIO3");
551 }
552 if (rst | ckd) {
553 txx9_set64(&tx4939_ccfgptr->clkctr, rst);
554 txx9_set64(&tx4939_ccfgptr->clkctr, ckd);
555 }
556 local_irq_enable();
557 if (buf[0])
558 pr_info("%s: stop%s\n", txx9_pcode_str, buf);
559}
560
561static int __init tx4939_late_init(void)
562{
563 if (txx9_pcode != 0x4939)
564 return -ENODEV;
565 tx4939_stop_unused_modules();
566 return 0;
567}
568late_initcall(tx4939_late_init);
diff --git a/arch/mips/txx9/generic/smsc_fdc37m81x.c b/arch/mips/txx9/generic/smsc_fdc37m81x.c
new file mode 100644
index 000000000..40f4098d3
--- /dev/null
+++ b/arch/mips/txx9/generic/smsc_fdc37m81x.c
@@ -0,0 +1,169 @@
1/*
2 * Interface for smsc fdc48m81x Super IO chip
3 *
4 * Author: MontaVista Software, Inc. source@mvista.com
5 *
6 * 2001-2003 (c) MontaVista Software, Inc. This file is licensed under
7 * the terms of the GNU General Public License version 2. This program
8 * is licensed "as is" without any warranty of any kind, whether express
9 * or implied.
10 *
11 * Copyright 2004 (c) MontaVista Software, Inc.
12 */
13#include <linux/init.h>
14#include <linux/types.h>
15#include <asm/io.h>
16#include <asm/txx9/smsc_fdc37m81x.h>
17
18/* Common Registers */
19#define SMSC_FDC37M81X_CONFIG_INDEX 0x00
20#define SMSC_FDC37M81X_CONFIG_DATA 0x01
21#define SMSC_FDC37M81X_CONF 0x02
22#define SMSC_FDC37M81X_INDEX 0x03
23#define SMSC_FDC37M81X_DNUM 0x07
24#define SMSC_FDC37M81X_DID 0x20
25#define SMSC_FDC37M81X_DREV 0x21
26#define SMSC_FDC37M81X_PCNT 0x22
27#define SMSC_FDC37M81X_PMGT 0x23
28#define SMSC_FDC37M81X_OSC 0x24
29#define SMSC_FDC37M81X_CONFPA0 0x26
30#define SMSC_FDC37M81X_CONFPA1 0x27
31#define SMSC_FDC37M81X_TEST4 0x2B
32#define SMSC_FDC37M81X_TEST5 0x2C
33#define SMSC_FDC37M81X_TEST1 0x2D
34#define SMSC_FDC37M81X_TEST2 0x2E
35#define SMSC_FDC37M81X_TEST3 0x2F
36
37/* Logical device numbers */
38#define SMSC_FDC37M81X_FDD 0x00
39#define SMSC_FDC37M81X_SERIAL1 0x04
40#define SMSC_FDC37M81X_SERIAL2 0x05
41#define SMSC_FDC37M81X_KBD 0x07
42
43/* Logical device Config Registers */
44#define SMSC_FDC37M81X_ACTIVE 0x30
45#define SMSC_FDC37M81X_BASEADDR0 0x60
46#define SMSC_FDC37M81X_BASEADDR1 0x61
47#define SMSC_FDC37M81X_INT 0x70
48#define SMSC_FDC37M81X_INT2 0x72
49#define SMSC_FDC37M81X_MODE 0xF0
50
51/* Chip Config Values */
52#define SMSC_FDC37M81X_CONFIG_ENTER 0x55
53#define SMSC_FDC37M81X_CONFIG_EXIT 0xaa
54#define SMSC_FDC37M81X_CHIP_ID 0x4d
55
56static unsigned long g_smsc_fdc37m81x_base;
57
58static inline unsigned char smsc_fdc37m81x_rd(unsigned char index)
59{
60 outb(index, g_smsc_fdc37m81x_base + SMSC_FDC37M81X_CONFIG_INDEX);
61
62 return inb(g_smsc_fdc37m81x_base + SMSC_FDC37M81X_CONFIG_DATA);
63}
64
65static inline void smsc_dc37m81x_wr(unsigned char index, unsigned char data)
66{
67 outb(index, g_smsc_fdc37m81x_base + SMSC_FDC37M81X_CONFIG_INDEX);
68 outb(data, g_smsc_fdc37m81x_base + SMSC_FDC37M81X_CONFIG_DATA);
69}
70
71void smsc_fdc37m81x_config_beg(void)
72{
73 if (g_smsc_fdc37m81x_base) {
74 outb(SMSC_FDC37M81X_CONFIG_ENTER,
75 g_smsc_fdc37m81x_base + SMSC_FDC37M81X_CONFIG_INDEX);
76 }
77}
78
79void smsc_fdc37m81x_config_end(void)
80{
81 if (g_smsc_fdc37m81x_base)
82 outb(SMSC_FDC37M81X_CONFIG_EXIT,
83 g_smsc_fdc37m81x_base + SMSC_FDC37M81X_CONFIG_INDEX);
84}
85
86u8 smsc_fdc37m81x_config_get(u8 reg)
87{
88 u8 val = 0;
89
90 if (g_smsc_fdc37m81x_base)
91 val = smsc_fdc37m81x_rd(reg);
92
93 return val;
94}
95
96void smsc_fdc37m81x_config_set(u8 reg, u8 val)
97{
98 if (g_smsc_fdc37m81x_base)
99 smsc_dc37m81x_wr(reg, val);
100}
101
102unsigned long __init smsc_fdc37m81x_init(unsigned long port)
103{
104 const int field = sizeof(unsigned long) * 2;
105 u8 chip_id;
106
107 if (g_smsc_fdc37m81x_base)
108 pr_warn("%s: stepping on old base=0x%0*lx\n", __func__, field,
109 g_smsc_fdc37m81x_base);
110
111 g_smsc_fdc37m81x_base = port;
112
113 smsc_fdc37m81x_config_beg();
114
115 chip_id = smsc_fdc37m81x_rd(SMSC_FDC37M81X_DID);
116 if (chip_id == SMSC_FDC37M81X_CHIP_ID)
117 smsc_fdc37m81x_config_end();
118 else {
119 pr_warn("%s: unknown chip id 0x%02x\n", __func__, chip_id);
120 g_smsc_fdc37m81x_base = 0;
121 }
122
123 return g_smsc_fdc37m81x_base;
124}
125
126#ifdef DEBUG
127static void smsc_fdc37m81x_config_dump_one(const char *key, u8 dev, u8 reg)
128{
129 pr_info("%s: dev=0x%02x reg=0x%02x val=0x%02x\n", key, dev, reg,
130 smsc_fdc37m81x_rd(reg));
131}
132
133void smsc_fdc37m81x_config_dump(void)
134{
135 u8 orig;
136 const char *fname = __func__;
137
138 smsc_fdc37m81x_config_beg();
139
140 orig = smsc_fdc37m81x_rd(SMSC_FDC37M81X_DNUM);
141
142 pr_info("%s: common\n", fname);
143 smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_NONE,
144 SMSC_FDC37M81X_DNUM);
145 smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_NONE,
146 SMSC_FDC37M81X_DID);
147 smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_NONE,
148 SMSC_FDC37M81X_DREV);
149 smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_NONE,
150 SMSC_FDC37M81X_PCNT);
151 smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_NONE,
152 SMSC_FDC37M81X_PMGT);
153
154 pr_info("%s: keyboard\n", fname);
155 smsc_dc37m81x_wr(SMSC_FDC37M81X_DNUM, SMSC_FDC37M81X_KBD);
156 smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_KBD,
157 SMSC_FDC37M81X_ACTIVE);
158 smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_KBD,
159 SMSC_FDC37M81X_INT);
160 smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_KBD,
161 SMSC_FDC37M81X_INT2);
162 smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_KBD,
163 SMSC_FDC37M81X_LDCR_F0);
164
165 smsc_dc37m81x_wr(SMSC_FDC37M81X_DNUM, orig);
166
167 smsc_fdc37m81x_config_end();
168}
169#endif
diff --git a/arch/mips/txx9/generic/spi_eeprom.c b/arch/mips/txx9/generic/spi_eeprom.c
new file mode 100644
index 000000000..d833dd2c9
--- /dev/null
+++ b/arch/mips/txx9/generic/spi_eeprom.c
@@ -0,0 +1,104 @@
1/*
2 * spi_eeprom.c
3 * Copyright (C) 2000-2001 Toshiba Corporation
4 *
5 * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the
6 * terms of the GNU General Public License version 2. This program is
7 * licensed "as is" without any warranty of any kind, whether express
8 * or implied.
9 *
10 * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com)
11 */
12#include <linux/init.h>
13#include <linux/slab.h>
14#include <linux/export.h>
15#include <linux/device.h>
16#include <linux/spi/spi.h>
17#include <linux/spi/eeprom.h>
18#include <asm/txx9/spi.h>
19
20#define AT250X0_PAGE_SIZE 8
21
22/* register board information for at25 driver */
23int __init spi_eeprom_register(int busid, int chipid, int size)
24{
25 struct spi_board_info info = {
26 .modalias = "at25",
27 .max_speed_hz = 1500000, /* 1.5Mbps */
28 .bus_num = busid,
29 .chip_select = chipid,
30 /* Mode 0: High-Active, Sample-Then-Shift */
31 };
32 struct spi_eeprom *eeprom;
33 eeprom = kzalloc(sizeof(*eeprom), GFP_KERNEL);
34 if (!eeprom)
35 return -ENOMEM;
36 strcpy(eeprom->name, "at250x0");
37 eeprom->byte_len = size;
38 eeprom->page_size = AT250X0_PAGE_SIZE;
39 eeprom->flags = EE_ADDR1;
40 info.platform_data = eeprom;
41 return spi_register_board_info(&info, 1);
42}
43
44/* simple temporary spi driver to provide early access to seeprom. */
45
46static struct read_param {
47 int busid;
48 int chipid;
49 int address;
50 unsigned char *buf;
51 int len;
52} *read_param;
53
54static int __init early_seeprom_probe(struct spi_device *spi)
55{
56 int stat = 0;
57 u8 cmd[2];
58 int len = read_param->len;
59 char *buf = read_param->buf;
60 int address = read_param->address;
61
62 dev_info(&spi->dev, "spiclk %u KHz.\n",
63 (spi->max_speed_hz + 500) / 1000);
64 if (read_param->busid != spi->master->bus_num ||
65 read_param->chipid != spi->chip_select)
66 return -ENODEV;
67 while (len > 0) {
68 /* spi_write_then_read can only work with small chunk */
69 int c = len < AT250X0_PAGE_SIZE ? len : AT250X0_PAGE_SIZE;
70 cmd[0] = 0x03; /* AT25_READ */
71 cmd[1] = address;
72 stat = spi_write_then_read(spi, cmd, sizeof(cmd), buf, c);
73 buf += c;
74 len -= c;
75 address += c;
76 }
77 return stat;
78}
79
80static struct spi_driver early_seeprom_driver __initdata = {
81 .driver = {
82 .name = "at25",
83 },
84 .probe = early_seeprom_probe,
85};
86
87int __init spi_eeprom_read(int busid, int chipid, int address,
88 unsigned char *buf, int len)
89{
90 int ret;
91 struct read_param param = {
92 .busid = busid,
93 .chipid = chipid,
94 .address = address,
95 .buf = buf,
96 .len = len
97 };
98
99 read_param = &param;
100 ret = spi_register_driver(&early_seeprom_driver);
101 if (!ret)
102 spi_unregister_driver(&early_seeprom_driver);
103 return ret;
104}
diff --git a/arch/mips/txx9/jmr3927/Makefile b/arch/mips/txx9/jmr3927/Makefile
new file mode 100644
index 000000000..4bda0615d
--- /dev/null
+++ b/arch/mips/txx9/jmr3927/Makefile
@@ -0,0 +1,6 @@
1# SPDX-License-Identifier: GPL-2.0-only
2#
3# Makefile for TOSHIBA JMR-TX3927 board
4#
5
6obj-y += prom.o irq.o setup.o
diff --git a/arch/mips/txx9/jmr3927/irq.c b/arch/mips/txx9/jmr3927/irq.c
new file mode 100644
index 000000000..c22c859a2
--- /dev/null
+++ b/arch/mips/txx9/jmr3927/irq.c
@@ -0,0 +1,128 @@
1/*
2 * Copyright 2001 MontaVista Software Inc.
3 * Author: MontaVista Software, Inc.
4 * ahennessy@mvista.com
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 *
10 * Copyright (C) 2000-2001 Toshiba Corporation
11 *
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 2 of the License, or (at your
15 * option) any later version.
16 *
17 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
20 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
24 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * You should have received a copy of the GNU General Public License along
29 * with this program; if not, write to the Free Software Foundation, Inc.,
30 * 675 Mass Ave, Cambridge, MA 02139, USA.
31 */
32#include <linux/init.h>
33#include <linux/types.h>
34#include <linux/interrupt.h>
35#include <linux/irq.h>
36
37#include <asm/io.h>
38#include <asm/mipsregs.h>
39#include <asm/txx9/generic.h>
40#include <asm/txx9/jmr3927.h>
41
42#if JMR3927_IRQ_END > NR_IRQS
43#error JMR3927_IRQ_END > NR_IRQS
44#endif
45
46/*
47 * CP0_STATUS is a thread's resource (saved/restored on context switch).
48 * So disable_irq/enable_irq MUST handle IOC/IRC registers.
49 */
50static void mask_irq_ioc(struct irq_data *d)
51{
52 /* 0: mask */
53 unsigned int irq_nr = d->irq - JMR3927_IRQ_IOC;
54 unsigned char imask = jmr3927_ioc_reg_in(JMR3927_IOC_INTM_ADDR);
55 unsigned int bit = 1 << irq_nr;
56 jmr3927_ioc_reg_out(imask & ~bit, JMR3927_IOC_INTM_ADDR);
57 /* flush write buffer */
58 (void)jmr3927_ioc_reg_in(JMR3927_IOC_REV_ADDR);
59}
60static void unmask_irq_ioc(struct irq_data *d)
61{
62 /* 0: mask */
63 unsigned int irq_nr = d->irq - JMR3927_IRQ_IOC;
64 unsigned char imask = jmr3927_ioc_reg_in(JMR3927_IOC_INTM_ADDR);
65 unsigned int bit = 1 << irq_nr;
66 jmr3927_ioc_reg_out(imask | bit, JMR3927_IOC_INTM_ADDR);
67 /* flush write buffer */
68 (void)jmr3927_ioc_reg_in(JMR3927_IOC_REV_ADDR);
69}
70
71static int jmr3927_ioc_irqroute(void)
72{
73 unsigned char istat = jmr3927_ioc_reg_in(JMR3927_IOC_INTS2_ADDR);
74 int i;
75
76 for (i = 0; i < JMR3927_NR_IRQ_IOC; i++) {
77 if (istat & (1 << i))
78 return JMR3927_IRQ_IOC + i;
79 }
80 return -1;
81}
82
83static int jmr3927_irq_dispatch(int pending)
84{
85 int irq;
86
87 if ((pending & CAUSEF_IP7) == 0)
88 return -1;
89 irq = (pending >> CAUSEB_IP2) & 0x0f;
90 irq += JMR3927_IRQ_IRC;
91 if (irq == JMR3927_IRQ_IOCINT)
92 irq = jmr3927_ioc_irqroute();
93 return irq;
94}
95
96static struct irq_chip jmr3927_irq_ioc = {
97 .name = "jmr3927_ioc",
98 .irq_mask = mask_irq_ioc,
99 .irq_unmask = unmask_irq_ioc,
100};
101
102void __init jmr3927_irq_setup(void)
103{
104 int i;
105
106 txx9_irq_dispatch = jmr3927_irq_dispatch;
107 /* Now, interrupt control disabled, */
108 /* all IRC interrupts are masked, */
109 /* all IRC interrupt mode are Low Active. */
110
111 /* mask all IOC interrupts */
112 jmr3927_ioc_reg_out(0, JMR3927_IOC_INTM_ADDR);
113 /* setup IOC interrupt mode (SOFT:High Active, Others:Low Active) */
114 jmr3927_ioc_reg_out(JMR3927_IOC_INTF_SOFT, JMR3927_IOC_INTP_ADDR);
115
116 /* clear PCI Soft interrupts */
117 jmr3927_ioc_reg_out(0, JMR3927_IOC_INTS1_ADDR);
118 /* clear PCI Reset interrupts */
119 jmr3927_ioc_reg_out(0, JMR3927_IOC_RESET_ADDR);
120
121 tx3927_irq_init();
122 for (i = JMR3927_IRQ_IOC; i < JMR3927_IRQ_IOC + JMR3927_NR_IRQ_IOC; i++)
123 irq_set_chip_and_handler(i, &jmr3927_irq_ioc,
124 handle_level_irq);
125
126 /* setup IOC interrupt 1 (PCI, MODEM) */
127 irq_set_chained_handler(JMR3927_IRQ_IOCINT, handle_simple_irq);
128}
diff --git a/arch/mips/txx9/jmr3927/prom.c b/arch/mips/txx9/jmr3927/prom.c
new file mode 100644
index 000000000..53c68de54
--- /dev/null
+++ b/arch/mips/txx9/jmr3927/prom.c
@@ -0,0 +1,52 @@
1/*
2 * BRIEF MODULE DESCRIPTION
3 * PROM library initialisation code, assuming a version of
4 * pmon is the boot code.
5 *
6 * Copyright 2001 MontaVista Software Inc.
7 * Author: MontaVista Software, Inc.
8 * ahennessy@mvista.com
9 *
10 * Based on arch/mips/au1000/common/prom.c
11 *
12 * This file was derived from Carsten Langgaard's
13 * arch/mips/mips-boards/xx files.
14 *
15 * Carsten Langgaard, carstenl@mips.com
16 * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved.
17 *
18 * This program is free software; you can redistribute it and/or modify it
19 * under the terms of the GNU General Public License as published by the
20 * Free Software Foundation; either version 2 of the License, or (at your
21 * option) any later version.
22 *
23 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
24 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
25 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
26 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
27 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
28 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
29 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
30 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
32 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 *
34 * You should have received a copy of the GNU General Public License along
35 * with this program; if not, write to the Free Software Foundation, Inc.,
36 * 675 Mass Ave, Cambridge, MA 02139, USA.
37 */
38#include <linux/init.h>
39#include <linux/kernel.h>
40#include <linux/memblock.h>
41#include <asm/txx9/generic.h>
42#include <asm/txx9/jmr3927.h>
43
44void __init jmr3927_prom_init(void)
45{
46 /* CCFG */
47 if ((tx3927_ccfgptr->ccfg & TX3927_CCFG_TLBOFF) == 0)
48 pr_err("TX3927 TLB off\n");
49
50 memblock_add(0, JMR3927_SDRAM_SIZE);
51 txx9_sio_putchar_init(TX3927_SIO_REG(1));
52}
diff --git a/arch/mips/txx9/jmr3927/setup.c b/arch/mips/txx9/jmr3927/setup.c
new file mode 100644
index 000000000..613943886
--- /dev/null
+++ b/arch/mips/txx9/jmr3927/setup.c
@@ -0,0 +1,223 @@
1/*
2 * This program is free software; you can redistribute it and/or modify it
3 * under the terms of the GNU General Public License as published by the
4 * Free Software Foundation; either version 2 of the License, or (at your
5 * option) any later version.
6 *
7 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
8 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
9 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
10 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
11 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
12 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
13 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
14 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
15 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
16 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 675 Mass Ave, Cambridge, MA 02139, USA.
21 *
22 * Copyright 2001 MontaVista Software Inc.
23 * Author: MontaVista Software, Inc.
24 * ahennessy@mvista.com
25 *
26 * Copyright (C) 2000-2001 Toshiba Corporation
27 * Copyright (C) 2007 Ralf Baechle (ralf@linux-mips.org)
28 */
29
30#include <linux/init.h>
31#include <linux/kernel.h>
32#include <linux/types.h>
33#include <linux/ioport.h>
34#include <linux/delay.h>
35#include <linux/platform_device.h>
36#include <linux/gpio.h>
37#include <asm/reboot.h>
38#include <asm/txx9pio.h>
39#include <asm/txx9/generic.h>
40#include <asm/txx9/pci.h>
41#include <asm/txx9/jmr3927.h>
42#include <asm/mipsregs.h>
43
44static void jmr3927_machine_restart(char *command)
45{
46 local_irq_disable();
47#if 1 /* Resetting PCI bus */
48 jmr3927_ioc_reg_out(0, JMR3927_IOC_RESET_ADDR);
49 jmr3927_ioc_reg_out(JMR3927_IOC_RESET_PCI, JMR3927_IOC_RESET_ADDR);
50 (void)jmr3927_ioc_reg_in(JMR3927_IOC_RESET_ADDR); /* flush WB */
51 mdelay(1);
52 jmr3927_ioc_reg_out(0, JMR3927_IOC_RESET_ADDR);
53#endif
54 jmr3927_ioc_reg_out(JMR3927_IOC_RESET_CPU, JMR3927_IOC_RESET_ADDR);
55 /* fallback */
56 (*_machine_halt)();
57}
58
59static void __init jmr3927_time_init(void)
60{
61 tx3927_time_init(0, 1);
62}
63
64#define DO_WRITE_THROUGH
65
66static void jmr3927_board_init(void);
67
68static void __init jmr3927_mem_setup(void)
69{
70 set_io_port_base(JMR3927_PORT_BASE + JMR3927_PCIIO);
71
72 _machine_restart = jmr3927_machine_restart;
73
74 /* cache setup */
75 {
76 unsigned int conf;
77#ifdef DO_WRITE_THROUGH
78 int mips_config_cwfon = 0;
79 int mips_config_wbon = 0;
80#else
81 int mips_config_cwfon = 1;
82 int mips_config_wbon = 1;
83#endif
84
85 conf = read_c0_conf();
86 conf &= ~(TX39_CONF_WBON | TX39_CONF_CWFON);
87 conf |= mips_config_wbon ? TX39_CONF_WBON : 0;
88 conf |= mips_config_cwfon ? TX39_CONF_CWFON : 0;
89
90 write_c0_conf(conf);
91 write_c0_cache(0);
92 }
93
94 /* initialize board */
95 jmr3927_board_init();
96
97 tx3927_sio_init(0, 1 << 1); /* ch1: noCTS */
98}
99
100static void __init jmr3927_pci_setup(void)
101{
102#ifdef CONFIG_PCI
103 int extarb = !(tx3927_ccfgptr->ccfg & TX3927_CCFG_PCIXARB);
104 struct pci_controller *c;
105
106 c = txx9_alloc_pci_controller(&txx9_primary_pcic,
107 JMR3927_PCIMEM, JMR3927_PCIMEM_SIZE,
108 JMR3927_PCIIO, JMR3927_PCIIO_SIZE);
109 register_pci_controller(c);
110 if (!extarb) {
111 /* Reset PCI Bus */
112 jmr3927_ioc_reg_out(0, JMR3927_IOC_RESET_ADDR);
113 udelay(100);
114 jmr3927_ioc_reg_out(JMR3927_IOC_RESET_PCI,
115 JMR3927_IOC_RESET_ADDR);
116 udelay(100);
117 jmr3927_ioc_reg_out(0, JMR3927_IOC_RESET_ADDR);
118 }
119 tx3927_pcic_setup(c, JMR3927_SDRAM_SIZE, extarb);
120 tx3927_setup_pcierr_irq();
121#endif /* CONFIG_PCI */
122}
123
124static void __init jmr3927_board_init(void)
125{
126 txx9_cpu_clock = JMR3927_CORECLK;
127 /* SDRAMC are configured by PROM */
128
129 /* ROMC */
130 tx3927_romcptr->cr[1] = JMR3927_ROMCE1 | 0x00030048;
131 tx3927_romcptr->cr[2] = JMR3927_ROMCE2 | 0x000064c8;
132 tx3927_romcptr->cr[3] = JMR3927_ROMCE3 | 0x0003f698;
133 tx3927_romcptr->cr[5] = JMR3927_ROMCE5 | 0x0000f218;
134
135 /* Pin selection */
136 tx3927_ccfgptr->pcfg &= ~TX3927_PCFG_SELALL;
137 tx3927_ccfgptr->pcfg |=
138 TX3927_PCFG_SELSIOC(0) | TX3927_PCFG_SELSIO_ALL |
139 (TX3927_PCFG_SELDMA_ALL & ~TX3927_PCFG_SELDMA(1));
140
141 tx3927_setup();
142
143 /* PIO[15:12] connected to LEDs */
144 __raw_writel(0x0000f000, &tx3927_pioptr->dir);
145
146 jmr3927_pci_setup();
147
148 /* SIO0 DTR on */
149 jmr3927_ioc_reg_out(0, JMR3927_IOC_DTR_ADDR);
150
151 jmr3927_led_set(0);
152
153 pr_info("JMR-TX3927 (Rev %d) --- IOC(Rev %d) DIPSW:%d,%d,%d,%d\n",
154 jmr3927_ioc_reg_in(JMR3927_IOC_BREV_ADDR) & JMR3927_REV_MASK,
155 jmr3927_ioc_reg_in(JMR3927_IOC_REV_ADDR) & JMR3927_REV_MASK,
156 jmr3927_dipsw1(), jmr3927_dipsw2(),
157 jmr3927_dipsw3(), jmr3927_dipsw4());
158}
159
160/* This trick makes rtc-ds1742 driver usable as is. */
161static unsigned long jmr3927_swizzle_addr_b(unsigned long port)
162{
163 if ((port & 0xffff0000) != JMR3927_IOC_NVRAMB_ADDR)
164 return port;
165 port = (port & 0xffff0000) | (port & 0x7fff << 1);
166#ifdef __BIG_ENDIAN
167 return port;
168#else
169 return port | 1;
170#endif
171}
172
173static void __init jmr3927_rtc_init(void)
174{
175 static struct resource __initdata res = {
176 .start = JMR3927_IOC_NVRAMB_ADDR - IO_BASE,
177 .end = JMR3927_IOC_NVRAMB_ADDR - IO_BASE + 0x800 - 1,
178 .flags = IORESOURCE_MEM,
179 };
180 platform_device_register_simple("rtc-ds1742", -1, &res, 1);
181}
182
183static void __init jmr3927_mtd_init(void)
184{
185 int i;
186
187 for (i = 0; i < 2; i++)
188 tx3927_mtd_init(i);
189}
190
191static void __init jmr3927_device_init(void)
192{
193 unsigned long iocled_base = JMR3927_IOC_LED_ADDR - IO_BASE;
194#ifdef __LITTLE_ENDIAN
195 iocled_base |= 1;
196#endif
197 __swizzle_addr_b = jmr3927_swizzle_addr_b;
198 jmr3927_rtc_init();
199 tx3927_wdt_init();
200 jmr3927_mtd_init();
201 txx9_iocled_init(iocled_base, -1, 8, 1, "green", NULL);
202}
203
204static void __init jmr3927_arch_init(void)
205{
206 txx9_gpio_init(TX3927_PIO_REG, 0, 16);
207
208 gpio_request(11, "dipsw1");
209 gpio_request(10, "dipsw2");
210}
211
212struct txx9_board_vec jmr3927_vec __initdata = {
213 .system = "Toshiba JMR_TX3927",
214 .prom_init = jmr3927_prom_init,
215 .mem_setup = jmr3927_mem_setup,
216 .irq_setup = jmr3927_irq_setup,
217 .time_init = jmr3927_time_init,
218 .device_init = jmr3927_device_init,
219 .arch_init = jmr3927_arch_init,
220#ifdef CONFIG_PCI
221 .pci_map_irq = jmr3927_pci_map_irq,
222#endif
223};
diff --git a/arch/mips/txx9/rbtx4927/Makefile b/arch/mips/txx9/rbtx4927/Makefile
new file mode 100644
index 000000000..08a02aebd
--- /dev/null
+++ b/arch/mips/txx9/rbtx4927/Makefile
@@ -0,0 +1,2 @@
1# SPDX-License-Identifier: GPL-2.0-only
2obj-y += prom.o setup.o irq.o
diff --git a/arch/mips/txx9/rbtx4927/irq.c b/arch/mips/txx9/rbtx4927/irq.c
new file mode 100644
index 000000000..3f48292c9
--- /dev/null
+++ b/arch/mips/txx9/rbtx4927/irq.c
@@ -0,0 +1,198 @@
1/*
2 * Toshiba RBTX4927 specific interrupt handlers
3 *
4 * Author: MontaVista Software, Inc.
5 * source@mvista.com
6 *
7 * Copyright 2001-2002 MontaVista Software Inc.
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2 of the License, or (at your
12 * option) any later version.
13 *
14 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
15 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
16 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
19 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
20 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
22 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
23 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 *
25 * You should have received a copy of the GNU General Public License along
26 * with this program; if not, write to the Free Software Foundation, Inc.,
27 * 675 Mass Ave, Cambridge, MA 02139, USA.
28 */
29/*
30 * I8259A_IRQ_BASE+00
31 * I8259A_IRQ_BASE+01 PS2/Keyboard
32 * I8259A_IRQ_BASE+02 Cascade RBTX4927-ISA (irqs 8-15)
33 * I8259A_IRQ_BASE+03
34 * I8259A_IRQ_BASE+04
35 * I8259A_IRQ_BASE+05
36 * I8259A_IRQ_BASE+06
37 * I8259A_IRQ_BASE+07
38 * I8259A_IRQ_BASE+08
39 * I8259A_IRQ_BASE+09
40 * I8259A_IRQ_BASE+10
41 * I8259A_IRQ_BASE+11
42 * I8259A_IRQ_BASE+12 PS2/Mouse (not supported at this time)
43 * I8259A_IRQ_BASE+13
44 * I8259A_IRQ_BASE+14 IDE
45 * I8259A_IRQ_BASE+15
46 *
47 * MIPS_CPU_IRQ_BASE+00 Software 0
48 * MIPS_CPU_IRQ_BASE+01 Software 1
49 * MIPS_CPU_IRQ_BASE+02 Cascade TX4927-CP0
50 * MIPS_CPU_IRQ_BASE+03 Multiplexed -- do not use
51 * MIPS_CPU_IRQ_BASE+04 Multiplexed -- do not use
52 * MIPS_CPU_IRQ_BASE+05 Multiplexed -- do not use
53 * MIPS_CPU_IRQ_BASE+06 Multiplexed -- do not use
54 * MIPS_CPU_IRQ_BASE+07 CPU TIMER
55 *
56 * TXX9_IRQ_BASE+00
57 * TXX9_IRQ_BASE+01
58 * TXX9_IRQ_BASE+02
59 * TXX9_IRQ_BASE+03 Cascade RBTX4927-IOC
60 * TXX9_IRQ_BASE+04
61 * TXX9_IRQ_BASE+05 RBTX4927 RTL-8019AS ethernet
62 * TXX9_IRQ_BASE+06
63 * TXX9_IRQ_BASE+07
64 * TXX9_IRQ_BASE+08 TX4927 SerialIO Channel 0
65 * TXX9_IRQ_BASE+09 TX4927 SerialIO Channel 1
66 * TXX9_IRQ_BASE+10
67 * TXX9_IRQ_BASE+11
68 * TXX9_IRQ_BASE+12
69 * TXX9_IRQ_BASE+13
70 * TXX9_IRQ_BASE+14
71 * TXX9_IRQ_BASE+15
72 * TXX9_IRQ_BASE+16 TX4927 PCI PCI-C
73 * TXX9_IRQ_BASE+17
74 * TXX9_IRQ_BASE+18
75 * TXX9_IRQ_BASE+19
76 * TXX9_IRQ_BASE+20
77 * TXX9_IRQ_BASE+21
78 * TXX9_IRQ_BASE+22 TX4927 PCI PCI-ERR
79 * TXX9_IRQ_BASE+23 TX4927 PCI PCI-PMA (not used)
80 * TXX9_IRQ_BASE+24
81 * TXX9_IRQ_BASE+25
82 * TXX9_IRQ_BASE+26
83 * TXX9_IRQ_BASE+27
84 * TXX9_IRQ_BASE+28
85 * TXX9_IRQ_BASE+29
86 * TXX9_IRQ_BASE+30
87 * TXX9_IRQ_BASE+31
88 *
89 * RBTX4927_IRQ_IOC+00 FPCIB0 PCI-D (SouthBridge)
90 * RBTX4927_IRQ_IOC+01 FPCIB0 PCI-C (SouthBridge)
91 * RBTX4927_IRQ_IOC+02 FPCIB0 PCI-B (SouthBridge/IDE/pin=1,INTR)
92 * RBTX4927_IRQ_IOC+03 FPCIB0 PCI-A (SouthBridge/USB/pin=4)
93 * RBTX4927_IRQ_IOC+04
94 * RBTX4927_IRQ_IOC+05
95 * RBTX4927_IRQ_IOC+06
96 * RBTX4927_IRQ_IOC+07
97 *
98 * NOTES:
99 * SouthBridge/INTR is mapped to SouthBridge/A=PCI-B/#58
100 * SouthBridge/ISA/pin=0 no pci irq used by this device
101 * SouthBridge/IDE/pin=1 no pci irq used by this device, using INTR
102 * via ISA IRQ14
103 * SouthBridge/USB/pin=4 using pci irq SouthBridge/D=PCI-A=#59
104 * SouthBridge/PMC/pin=0 no pci irq used by this device
105 * SuperIO/PS2/Keyboard, using INTR via ISA IRQ1
106 * SuperIO/PS2/Mouse, using INTR via ISA IRQ12 (mouse not currently supported)
107 * JP7 is not bus master -- do NOT use -- only 4 pci bus master's
108 * allowed -- SouthBridge, JP4, JP5, JP6
109 */
110
111#include <linux/init.h>
112#include <linux/types.h>
113#include <linux/interrupt.h>
114#include <linux/irq.h>
115#include <asm/io.h>
116#include <asm/mipsregs.h>
117#include <asm/txx9/generic.h>
118#include <asm/txx9/rbtx4927.h>
119
120static int toshiba_rbtx4927_irq_nested(int sw_irq)
121{
122 u8 level3;
123
124 level3 = readb(rbtx4927_imstat_addr) & 0x1f;
125 if (unlikely(!level3))
126 return -1;
127 return RBTX4927_IRQ_IOC + __fls8(level3);
128}
129
130static void toshiba_rbtx4927_irq_ioc_enable(struct irq_data *d)
131{
132 unsigned char v;
133
134 v = readb(rbtx4927_imask_addr);
135 v |= (1 << (d->irq - RBTX4927_IRQ_IOC));
136 writeb(v, rbtx4927_imask_addr);
137}
138
139static void toshiba_rbtx4927_irq_ioc_disable(struct irq_data *d)
140{
141 unsigned char v;
142
143 v = readb(rbtx4927_imask_addr);
144 v &= ~(1 << (d->irq - RBTX4927_IRQ_IOC));
145 writeb(v, rbtx4927_imask_addr);
146 mmiowb();
147}
148
149#define TOSHIBA_RBTX4927_IOC_NAME "RBTX4927-IOC"
150static struct irq_chip toshiba_rbtx4927_irq_ioc_type = {
151 .name = TOSHIBA_RBTX4927_IOC_NAME,
152 .irq_mask = toshiba_rbtx4927_irq_ioc_disable,
153 .irq_unmask = toshiba_rbtx4927_irq_ioc_enable,
154};
155
156static void __init toshiba_rbtx4927_irq_ioc_init(void)
157{
158 int i;
159
160 /* mask all IOC interrupts */
161 writeb(0, rbtx4927_imask_addr);
162 /* clear SoftInt interrupts */
163 writeb(0, rbtx4927_softint_addr);
164
165 for (i = RBTX4927_IRQ_IOC;
166 i < RBTX4927_IRQ_IOC + RBTX4927_NR_IRQ_IOC; i++)
167 irq_set_chip_and_handler(i, &toshiba_rbtx4927_irq_ioc_type,
168 handle_level_irq);
169 irq_set_chained_handler(RBTX4927_IRQ_IOCINT, handle_simple_irq);
170}
171
172static int rbtx4927_irq_dispatch(int pending)
173{
174 int irq;
175
176 if (pending & STATUSF_IP7) /* cpu timer */
177 irq = MIPS_CPU_IRQ_BASE + 7;
178 else if (pending & STATUSF_IP2) { /* tx4927 pic */
179 irq = txx9_irq();
180 if (irq == RBTX4927_IRQ_IOCINT)
181 irq = toshiba_rbtx4927_irq_nested(irq);
182 } else if (pending & STATUSF_IP0) /* user line 0 */
183 irq = MIPS_CPU_IRQ_BASE + 0;
184 else if (pending & STATUSF_IP1) /* user line 1 */
185 irq = MIPS_CPU_IRQ_BASE + 1;
186 else
187 irq = -1;
188 return irq;
189}
190
191void __init rbtx4927_irq_setup(void)
192{
193 txx9_irq_dispatch = rbtx4927_irq_dispatch;
194 tx4927_irq_init();
195 toshiba_rbtx4927_irq_ioc_init();
196 /* Onboard 10M Ether: High Active */
197 irq_set_irq_type(RBTX4927_RTL_8019_IRQ, IRQF_TRIGGER_HIGH);
198}
diff --git a/arch/mips/txx9/rbtx4927/prom.c b/arch/mips/txx9/rbtx4927/prom.c
new file mode 100644
index 000000000..9b4acff82
--- /dev/null
+++ b/arch/mips/txx9/rbtx4927/prom.c
@@ -0,0 +1,42 @@
1/*
2 * rbtx4927 specific prom routines
3 *
4 * Author: MontaVista Software, Inc.
5 * source@mvista.com
6 *
7 * Copyright 2001-2002 MontaVista Software Inc.
8 *
9 * Copyright (C) 2004 MontaVista Software Inc.
10 * Author: Manish Lachwani, mlachwani@mvista.com
11 *
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 2 of the License, or (at your
15 * option) any later version.
16 *
17 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
22 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
23 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
25 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
26 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * You should have received a copy of the GNU General Public License along
29 * with this program; if not, write to the Free Software Foundation, Inc.,
30 * 675 Mass Ave, Cambridge, MA 02139, USA.
31 */
32
33#include <linux/init.h>
34#include <linux/memblock.h>
35#include <asm/txx9/generic.h>
36#include <asm/txx9/rbtx4927.h>
37
38void __init rbtx4927_prom_init(void)
39{
40 memblock_add(0, tx4927_get_mem_size());
41 txx9_sio_putchar_init(TX4927_SIO_REG(0) & 0xfffffffffULL);
42}
diff --git a/arch/mips/txx9/rbtx4927/setup.c b/arch/mips/txx9/rbtx4927/setup.c
new file mode 100644
index 000000000..31955c1d5
--- /dev/null
+++ b/arch/mips/txx9/rbtx4927/setup.c
@@ -0,0 +1,380 @@
1/*
2 * Toshiba rbtx4927 specific setup
3 *
4 * Author: MontaVista Software, Inc.
5 * source@mvista.com
6 *
7 * Copyright 2001-2002 MontaVista Software Inc.
8 *
9 * Copyright (C) 1996, 97, 2001, 04 Ralf Baechle (ralf@linux-mips.org)
10 * Copyright (C) 2000 RidgeRun, Inc.
11 * Author: RidgeRun, Inc.
12 * glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com
13 *
14 * Copyright 2001 MontaVista Software Inc.
15 * Author: jsun@mvista.com or jsun@junsun.net
16 *
17 * Copyright 2002 MontaVista Software Inc.
18 * Author: Michael Pruznick, michael_pruznick@mvista.com
19 *
20 * Copyright (C) 2000-2001 Toshiba Corporation
21 *
22 * Copyright (C) 2004 MontaVista Software Inc.
23 * Author: Manish Lachwani, mlachwani@mvista.com
24 *
25 * This program is free software; you can redistribute it and/or modify it
26 * under the terms of the GNU General Public License as published by the
27 * Free Software Foundation; either version 2 of the License, or (at your
28 * option) any later version.
29 *
30 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
31 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
32 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
33 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
34 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
35 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
36 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
37 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
38 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
39 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40 *
41 * You should have received a copy of the GNU General Public License along
42 * with this program; if not, write to the Free Software Foundation, Inc.,
43 * 675 Mass Ave, Cambridge, MA 02139, USA.
44 */
45#include <linux/init.h>
46#include <linux/kernel.h>
47#include <linux/types.h>
48#include <linux/ioport.h>
49#include <linux/platform_device.h>
50#include <linux/delay.h>
51#include <linux/gpio.h>
52#include <linux/leds.h>
53#include <asm/io.h>
54#include <asm/reboot.h>
55#include <asm/txx9pio.h>
56#include <asm/txx9/generic.h>
57#include <asm/txx9/pci.h>
58#include <asm/txx9/rbtx4927.h>
59#include <asm/txx9/tx4938.h> /* for TX4937 */
60
61#ifdef CONFIG_PCI
62static void __init tx4927_pci_setup(void)
63{
64 int extarb = !(__raw_readq(&tx4927_ccfgptr->ccfg) & TX4927_CCFG_PCIARB);
65 struct pci_controller *c = &txx9_primary_pcic;
66
67 register_pci_controller(c);
68
69 if (__raw_readq(&tx4927_ccfgptr->ccfg) & TX4927_CCFG_PCI66)
70 txx9_pci_option =
71 (txx9_pci_option & ~TXX9_PCI_OPT_CLK_MASK) |
72 TXX9_PCI_OPT_CLK_66; /* already configured */
73
74 /* Reset PCI Bus */
75 writeb(1, rbtx4927_pcireset_addr);
76 /* Reset PCIC */
77 txx9_set64(&tx4927_ccfgptr->clkctr, TX4927_CLKCTR_PCIRST);
78 if ((txx9_pci_option & TXX9_PCI_OPT_CLK_MASK) ==
79 TXX9_PCI_OPT_CLK_66)
80 tx4927_pciclk66_setup();
81 mdelay(10);
82 /* clear PCIC reset */
83 txx9_clear64(&tx4927_ccfgptr->clkctr, TX4927_CLKCTR_PCIRST);
84 writeb(0, rbtx4927_pcireset_addr);
85 iob();
86
87 tx4927_report_pciclk();
88 tx4927_pcic_setup(tx4927_pcicptr, c, extarb);
89 if ((txx9_pci_option & TXX9_PCI_OPT_CLK_MASK) ==
90 TXX9_PCI_OPT_CLK_AUTO &&
91 txx9_pci66_check(c, 0, 0)) {
92 /* Reset PCI Bus */
93 writeb(1, rbtx4927_pcireset_addr);
94 /* Reset PCIC */
95 txx9_set64(&tx4927_ccfgptr->clkctr, TX4927_CLKCTR_PCIRST);
96 tx4927_pciclk66_setup();
97 mdelay(10);
98 /* clear PCIC reset */
99 txx9_clear64(&tx4927_ccfgptr->clkctr, TX4927_CLKCTR_PCIRST);
100 writeb(0, rbtx4927_pcireset_addr);
101 iob();
102 /* Reinitialize PCIC */
103 tx4927_report_pciclk();
104 tx4927_pcic_setup(tx4927_pcicptr, c, extarb);
105 }
106 tx4927_setup_pcierr_irq();
107}
108
109static void __init tx4937_pci_setup(void)
110{
111 int extarb = !(__raw_readq(&tx4938_ccfgptr->ccfg) & TX4938_CCFG_PCIARB);
112 struct pci_controller *c = &txx9_primary_pcic;
113
114 register_pci_controller(c);
115
116 if (__raw_readq(&tx4938_ccfgptr->ccfg) & TX4938_CCFG_PCI66)
117 txx9_pci_option =
118 (txx9_pci_option & ~TXX9_PCI_OPT_CLK_MASK) |
119 TXX9_PCI_OPT_CLK_66; /* already configured */
120
121 /* Reset PCI Bus */
122 writeb(1, rbtx4927_pcireset_addr);
123 /* Reset PCIC */
124 txx9_set64(&tx4938_ccfgptr->clkctr, TX4938_CLKCTR_PCIRST);
125 if ((txx9_pci_option & TXX9_PCI_OPT_CLK_MASK) ==
126 TXX9_PCI_OPT_CLK_66)
127 tx4938_pciclk66_setup();
128 mdelay(10);
129 /* clear PCIC reset */
130 txx9_clear64(&tx4938_ccfgptr->clkctr, TX4938_CLKCTR_PCIRST);
131 writeb(0, rbtx4927_pcireset_addr);
132 iob();
133
134 tx4938_report_pciclk();
135 tx4927_pcic_setup(tx4938_pcicptr, c, extarb);
136 if ((txx9_pci_option & TXX9_PCI_OPT_CLK_MASK) ==
137 TXX9_PCI_OPT_CLK_AUTO &&
138 txx9_pci66_check(c, 0, 0)) {
139 /* Reset PCI Bus */
140 writeb(1, rbtx4927_pcireset_addr);
141 /* Reset PCIC */
142 txx9_set64(&tx4938_ccfgptr->clkctr, TX4938_CLKCTR_PCIRST);
143 tx4938_pciclk66_setup();
144 mdelay(10);
145 /* clear PCIC reset */
146 txx9_clear64(&tx4938_ccfgptr->clkctr, TX4938_CLKCTR_PCIRST);
147 writeb(0, rbtx4927_pcireset_addr);
148 iob();
149 /* Reinitialize PCIC */
150 tx4938_report_pciclk();
151 tx4927_pcic_setup(tx4938_pcicptr, c, extarb);
152 }
153 tx4938_setup_pcierr_irq();
154}
155#else
156static inline void tx4927_pci_setup(void) {}
157static inline void tx4937_pci_setup(void) {}
158#endif /* CONFIG_PCI */
159
160static void __init rbtx4927_gpio_init(void)
161{
162 /* TX4927-SIO DTR on (PIO[15]) */
163 gpio_request(15, "sio-dtr");
164 gpio_direction_output(15, 1);
165
166 tx4927_sio_init(0, 0);
167}
168
169static void __init rbtx4927_arch_init(void)
170{
171 txx9_gpio_init(TX4927_PIO_REG & 0xfffffffffULL, 0, TX4927_NUM_PIO);
172
173 rbtx4927_gpio_init();
174
175 tx4927_pci_setup();
176}
177
178static void __init rbtx4937_arch_init(void)
179{
180 txx9_gpio_init(TX4938_PIO_REG & 0xfffffffffULL, 0, TX4938_NUM_PIO);
181
182 rbtx4927_gpio_init();
183
184 tx4937_pci_setup();
185}
186
187static void toshiba_rbtx4927_restart(char *command)
188{
189 /* enable the s/w reset register */
190 writeb(1, rbtx4927_softresetlock_addr);
191
192 /* wait for enable to be seen */
193 while (!(readb(rbtx4927_softresetlock_addr) & 1))
194 ;
195
196 /* do a s/w reset */
197 writeb(1, rbtx4927_softreset_addr);
198
199 /* fallback */
200 (*_machine_halt)();
201}
202
203static void __init rbtx4927_clock_init(void);
204static void __init rbtx4937_clock_init(void);
205
206static void __init rbtx4927_mem_setup(void)
207{
208 if (TX4927_REV_PCODE() == 0x4927) {
209 rbtx4927_clock_init();
210 tx4927_setup();
211 } else {
212 rbtx4937_clock_init();
213 tx4938_setup();
214 }
215
216 _machine_restart = toshiba_rbtx4927_restart;
217
218#ifdef CONFIG_PCI
219 txx9_alloc_pci_controller(&txx9_primary_pcic,
220 RBTX4927_PCIMEM, RBTX4927_PCIMEM_SIZE,
221 RBTX4927_PCIIO, RBTX4927_PCIIO_SIZE);
222 txx9_board_pcibios_setup = tx4927_pcibios_setup;
223#else
224 set_io_port_base(KSEG1 + RBTX4927_ISA_IO_OFFSET);
225#endif
226}
227
228static void __init rbtx4927_clock_init(void)
229{
230 /*
231 * ASSUMPTION: PCIDIVMODE is configured for PCI 33MHz or 66MHz.
232 *
233 * For TX4927:
234 * PCIDIVMODE[12:11]'s initial value is given by S9[4:3] (ON:0, OFF:1).
235 * CPU 166MHz: PCI 66MHz : PCIDIVMODE: 00 (1/2.5)
236 * CPU 200MHz: PCI 66MHz : PCIDIVMODE: 01 (1/3)
237 * CPU 166MHz: PCI 33MHz : PCIDIVMODE: 10 (1/5)
238 * CPU 200MHz: PCI 33MHz : PCIDIVMODE: 11 (1/6)
239 * i.e. S9[3]: ON (83MHz), OFF (100MHz)
240 */
241 switch ((unsigned long)__raw_readq(&tx4927_ccfgptr->ccfg) &
242 TX4927_CCFG_PCIDIVMODE_MASK) {
243 case TX4927_CCFG_PCIDIVMODE_2_5:
244 case TX4927_CCFG_PCIDIVMODE_5:
245 txx9_cpu_clock = 166666666; /* 166MHz */
246 break;
247 default:
248 txx9_cpu_clock = 200000000; /* 200MHz */
249 }
250}
251
252static void __init rbtx4937_clock_init(void)
253{
254 /*
255 * ASSUMPTION: PCIDIVMODE is configured for PCI 33MHz or 66MHz.
256 *
257 * For TX4937:
258 * PCIDIVMODE[12:11]'s initial value is given by S1[5:4] (ON:0, OFF:1)
259 * PCIDIVMODE[10] is 0.
260 * CPU 266MHz: PCI 33MHz : PCIDIVMODE: 000 (1/8)
261 * CPU 266MHz: PCI 66MHz : PCIDIVMODE: 001 (1/4)
262 * CPU 300MHz: PCI 33MHz : PCIDIVMODE: 010 (1/9)
263 * CPU 300MHz: PCI 66MHz : PCIDIVMODE: 011 (1/4.5)
264 * CPU 333MHz: PCI 33MHz : PCIDIVMODE: 100 (1/10)
265 * CPU 333MHz: PCI 66MHz : PCIDIVMODE: 101 (1/5)
266 */
267 switch ((unsigned long)__raw_readq(&tx4938_ccfgptr->ccfg) &
268 TX4938_CCFG_PCIDIVMODE_MASK) {
269 case TX4938_CCFG_PCIDIVMODE_8:
270 case TX4938_CCFG_PCIDIVMODE_4:
271 txx9_cpu_clock = 266666666; /* 266MHz */
272 break;
273 case TX4938_CCFG_PCIDIVMODE_9:
274 case TX4938_CCFG_PCIDIVMODE_4_5:
275 txx9_cpu_clock = 300000000; /* 300MHz */
276 break;
277 default:
278 txx9_cpu_clock = 333333333; /* 333MHz */
279 }
280}
281
282static void __init rbtx4927_time_init(void)
283{
284 tx4927_time_init(0);
285}
286
287static void __init toshiba_rbtx4927_rtc_init(void)
288{
289 struct resource res = {
290 .start = RBTX4927_BRAMRTC_BASE - IO_BASE,
291 .end = RBTX4927_BRAMRTC_BASE - IO_BASE + 0x800 - 1,
292 .flags = IORESOURCE_MEM,
293 };
294 platform_device_register_simple("rtc-ds1742", -1, &res, 1);
295}
296
297static void __init rbtx4927_ne_init(void)
298{
299 struct resource res[] = {
300 {
301 .start = RBTX4927_RTL_8019_BASE,
302 .end = RBTX4927_RTL_8019_BASE + 0x20 - 1,
303 .flags = IORESOURCE_IO,
304 }, {
305 .start = RBTX4927_RTL_8019_IRQ,
306 .flags = IORESOURCE_IRQ,
307 }
308 };
309 platform_device_register_simple("ne", -1, res, ARRAY_SIZE(res));
310}
311
312static void __init rbtx4927_mtd_init(void)
313{
314 int i;
315
316 for (i = 0; i < 2; i++)
317 tx4927_mtd_init(i);
318}
319
320static void __init rbtx4927_gpioled_init(void)
321{
322 static const struct gpio_led leds[] = {
323 { .name = "gpioled:green:0", .gpio = 0, .active_low = 1, },
324 { .name = "gpioled:green:1", .gpio = 1, .active_low = 1, },
325 };
326 static struct gpio_led_platform_data pdata = {
327 .num_leds = ARRAY_SIZE(leds),
328 .leds = leds,
329 };
330 struct platform_device *pdev = platform_device_alloc("leds-gpio", 0);
331
332 if (!pdev)
333 return;
334 pdev->dev.platform_data = &pdata;
335 if (platform_device_add(pdev))
336 platform_device_put(pdev);
337}
338
339static void __init rbtx4927_device_init(void)
340{
341 toshiba_rbtx4927_rtc_init();
342 rbtx4927_ne_init();
343 tx4927_wdt_init();
344 rbtx4927_mtd_init();
345 if (TX4927_REV_PCODE() == 0x4927) {
346 tx4927_dmac_init(2);
347 tx4927_aclc_init(0, 1);
348 } else {
349 tx4938_dmac_init(0, 2);
350 tx4938_aclc_init();
351 }
352 platform_device_register_simple("txx9aclc-generic", -1, NULL, 0);
353 txx9_iocled_init(RBTX4927_LED_ADDR - IO_BASE, -1, 3, 1, "green", NULL);
354 rbtx4927_gpioled_init();
355}
356
357struct txx9_board_vec rbtx4927_vec __initdata = {
358 .system = "Toshiba RBTX4927",
359 .prom_init = rbtx4927_prom_init,
360 .mem_setup = rbtx4927_mem_setup,
361 .irq_setup = rbtx4927_irq_setup,
362 .time_init = rbtx4927_time_init,
363 .device_init = rbtx4927_device_init,
364 .arch_init = rbtx4927_arch_init,
365#ifdef CONFIG_PCI
366 .pci_map_irq = rbtx4927_pci_map_irq,
367#endif
368};
369struct txx9_board_vec rbtx4937_vec __initdata = {
370 .system = "Toshiba RBTX4937",
371 .prom_init = rbtx4927_prom_init,
372 .mem_setup = rbtx4927_mem_setup,
373 .irq_setup = rbtx4927_irq_setup,
374 .time_init = rbtx4927_time_init,
375 .device_init = rbtx4927_device_init,
376 .arch_init = rbtx4937_arch_init,
377#ifdef CONFIG_PCI
378 .pci_map_irq = rbtx4927_pci_map_irq,
379#endif
380};
diff --git a/arch/mips/txx9/rbtx4938/Makefile b/arch/mips/txx9/rbtx4938/Makefile
new file mode 100644
index 000000000..08a02aebd
--- /dev/null
+++ b/arch/mips/txx9/rbtx4938/Makefile
@@ -0,0 +1,2 @@
1# SPDX-License-Identifier: GPL-2.0-only
2obj-y += prom.o setup.o irq.o
diff --git a/arch/mips/txx9/rbtx4938/irq.c b/arch/mips/txx9/rbtx4938/irq.c
new file mode 100644
index 000000000..58cd7a927
--- /dev/null
+++ b/arch/mips/txx9/rbtx4938/irq.c
@@ -0,0 +1,157 @@
1/*
2 * Toshiba RBTX4938 specific interrupt handlers
3 * Copyright (C) 2000-2001 Toshiba Corporation
4 *
5 * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the
6 * terms of the GNU General Public License version 2. This program is
7 * licensed "as is" without any warranty of any kind, whether express
8 * or implied.
9 *
10 * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com)
11 */
12
13/*
14 * MIPS_CPU_IRQ_BASE+00 Software 0
15 * MIPS_CPU_IRQ_BASE+01 Software 1
16 * MIPS_CPU_IRQ_BASE+02 Cascade TX4938-CP0
17 * MIPS_CPU_IRQ_BASE+03 Multiplexed -- do not use
18 * MIPS_CPU_IRQ_BASE+04 Multiplexed -- do not use
19 * MIPS_CPU_IRQ_BASE+05 Multiplexed -- do not use
20 * MIPS_CPU_IRQ_BASE+06 Multiplexed -- do not use
21 * MIPS_CPU_IRQ_BASE+07 CPU TIMER
22 *
23 * TXX9_IRQ_BASE+00
24 * TXX9_IRQ_BASE+01
25 * TXX9_IRQ_BASE+02 Cascade RBTX4938-IOC
26 * TXX9_IRQ_BASE+03 RBTX4938 RTL-8019AS Ethernet
27 * TXX9_IRQ_BASE+04
28 * TXX9_IRQ_BASE+05 TX4938 ETH1
29 * TXX9_IRQ_BASE+06 TX4938 ETH0
30 * TXX9_IRQ_BASE+07
31 * TXX9_IRQ_BASE+08 TX4938 SIO 0
32 * TXX9_IRQ_BASE+09 TX4938 SIO 1
33 * TXX9_IRQ_BASE+10 TX4938 DMA0
34 * TXX9_IRQ_BASE+11 TX4938 DMA1
35 * TXX9_IRQ_BASE+12 TX4938 DMA2
36 * TXX9_IRQ_BASE+13 TX4938 DMA3
37 * TXX9_IRQ_BASE+14
38 * TXX9_IRQ_BASE+15
39 * TXX9_IRQ_BASE+16 TX4938 PCIC
40 * TXX9_IRQ_BASE+17 TX4938 TMR0
41 * TXX9_IRQ_BASE+18 TX4938 TMR1
42 * TXX9_IRQ_BASE+19 TX4938 TMR2
43 * TXX9_IRQ_BASE+20
44 * TXX9_IRQ_BASE+21
45 * TXX9_IRQ_BASE+22 TX4938 PCIERR
46 * TXX9_IRQ_BASE+23
47 * TXX9_IRQ_BASE+24
48 * TXX9_IRQ_BASE+25
49 * TXX9_IRQ_BASE+26
50 * TXX9_IRQ_BASE+27
51 * TXX9_IRQ_BASE+28
52 * TXX9_IRQ_BASE+29
53 * TXX9_IRQ_BASE+30
54 * TXX9_IRQ_BASE+31 TX4938 SPI
55 *
56 * RBTX4938_IRQ_IOC+00 PCI-D
57 * RBTX4938_IRQ_IOC+01 PCI-C
58 * RBTX4938_IRQ_IOC+02 PCI-B
59 * RBTX4938_IRQ_IOC+03 PCI-A
60 * RBTX4938_IRQ_IOC+04 RTC
61 * RBTX4938_IRQ_IOC+05 ATA
62 * RBTX4938_IRQ_IOC+06 MODEM
63 * RBTX4938_IRQ_IOC+07 SWINT
64 */
65#include <linux/init.h>
66#include <linux/interrupt.h>
67#include <linux/irq.h>
68#include <asm/mipsregs.h>
69#include <asm/txx9/generic.h>
70#include <asm/txx9/rbtx4938.h>
71
72static int toshiba_rbtx4938_irq_nested(int sw_irq)
73{
74 u8 level3;
75
76 level3 = readb(rbtx4938_imstat_addr);
77 if (unlikely(!level3))
78 return -1;
79 /* must use fls so onboard ATA has priority */
80 return RBTX4938_IRQ_IOC + __fls8(level3);
81}
82
83static void toshiba_rbtx4938_irq_ioc_enable(struct irq_data *d)
84{
85 unsigned char v;
86
87 v = readb(rbtx4938_imask_addr);
88 v |= (1 << (d->irq - RBTX4938_IRQ_IOC));
89 writeb(v, rbtx4938_imask_addr);
90 mmiowb();
91}
92
93static void toshiba_rbtx4938_irq_ioc_disable(struct irq_data *d)
94{
95 unsigned char v;
96
97 v = readb(rbtx4938_imask_addr);
98 v &= ~(1 << (d->irq - RBTX4938_IRQ_IOC));
99 writeb(v, rbtx4938_imask_addr);
100 mmiowb();
101}
102
103#define TOSHIBA_RBTX4938_IOC_NAME "RBTX4938-IOC"
104static struct irq_chip toshiba_rbtx4938_irq_ioc_type = {
105 .name = TOSHIBA_RBTX4938_IOC_NAME,
106 .irq_mask = toshiba_rbtx4938_irq_ioc_disable,
107 .irq_unmask = toshiba_rbtx4938_irq_ioc_enable,
108};
109
110static int rbtx4938_irq_dispatch(int pending)
111{
112 int irq;
113
114 if (pending & STATUSF_IP7)
115 irq = MIPS_CPU_IRQ_BASE + 7;
116 else if (pending & STATUSF_IP2) {
117 irq = txx9_irq();
118 if (irq == RBTX4938_IRQ_IOCINT)
119 irq = toshiba_rbtx4938_irq_nested(irq);
120 } else if (pending & STATUSF_IP1)
121 irq = MIPS_CPU_IRQ_BASE + 0;
122 else if (pending & STATUSF_IP0)
123 irq = MIPS_CPU_IRQ_BASE + 1;
124 else
125 irq = -1;
126 return irq;
127}
128
129static void __init toshiba_rbtx4938_irq_ioc_init(void)
130{
131 int i;
132
133 for (i = RBTX4938_IRQ_IOC;
134 i < RBTX4938_IRQ_IOC + RBTX4938_NR_IRQ_IOC; i++)
135 irq_set_chip_and_handler(i, &toshiba_rbtx4938_irq_ioc_type,
136 handle_level_irq);
137
138 irq_set_chained_handler(RBTX4938_IRQ_IOCINT, handle_simple_irq);
139}
140
141void __init rbtx4938_irq_setup(void)
142{
143 txx9_irq_dispatch = rbtx4938_irq_dispatch;
144 /* Now, interrupt control disabled, */
145 /* all IRC interrupts are masked, */
146 /* all IRC interrupt mode are Low Active. */
147
148 /* mask all IOC interrupts */
149 writeb(0, rbtx4938_imask_addr);
150
151 /* clear SoftInt interrupts */
152 writeb(0, rbtx4938_softint_addr);
153 tx4938_irq_init();
154 toshiba_rbtx4938_irq_ioc_init();
155 /* Onboard 10M Ether: High Active */
156 irq_set_irq_type(RBTX4938_IRQ_ETHER, IRQF_TRIGGER_HIGH);
157}
diff --git a/arch/mips/txx9/rbtx4938/prom.c b/arch/mips/txx9/rbtx4938/prom.c
new file mode 100644
index 000000000..0de84716a
--- /dev/null
+++ b/arch/mips/txx9/rbtx4938/prom.c
@@ -0,0 +1,22 @@
1/*
2 * rbtx4938 specific prom routines
3 * Copyright (C) 2000-2001 Toshiba Corporation
4 *
5 * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the
6 * terms of the GNU General Public License version 2. This program is
7 * licensed "as is" without any warranty of any kind, whether express
8 * or implied.
9 *
10 * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com)
11 */
12
13#include <linux/init.h>
14#include <linux/memblock.h>
15#include <asm/txx9/generic.h>
16#include <asm/txx9/rbtx4938.h>
17
18void __init rbtx4938_prom_init(void)
19{
20 memblock_add(0, tx4938_get_mem_size());
21 txx9_sio_putchar_init(TX4938_SIO_REG(0) & 0xfffffffffULL);
22}
diff --git a/arch/mips/txx9/rbtx4938/setup.c b/arch/mips/txx9/rbtx4938/setup.c
new file mode 100644
index 000000000..e68eb2e7c
--- /dev/null
+++ b/arch/mips/txx9/rbtx4938/setup.c
@@ -0,0 +1,372 @@
1/*
2 * Setup pointers to hardware-dependent routines.
3 * Copyright (C) 2000-2001 Toshiba Corporation
4 *
5 * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the
6 * terms of the GNU General Public License version 2. This program is
7 * licensed "as is" without any warranty of any kind, whether express
8 * or implied.
9 *
10 * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com)
11 */
12#include <linux/init.h>
13#include <linux/types.h>
14#include <linux/ioport.h>
15#include <linux/delay.h>
16#include <linux/platform_device.h>
17#include <linux/gpio/driver.h>
18#include <linux/gpio.h>
19#include <linux/mtd/physmap.h>
20
21#include <asm/reboot.h>
22#include <asm/io.h>
23#include <asm/txx9/generic.h>
24#include <asm/txx9/pci.h>
25#include <asm/txx9/rbtx4938.h>
26#include <linux/spi/spi.h>
27#include <asm/txx9/spi.h>
28#include <asm/txx9pio.h>
29
30static void rbtx4938_machine_restart(char *command)
31{
32 local_irq_disable();
33 writeb(1, rbtx4938_softresetlock_addr);
34 writeb(1, rbtx4938_sfvol_addr);
35 writeb(1, rbtx4938_softreset_addr);
36 /* fallback */
37 (*_machine_halt)();
38}
39
40static void __init rbtx4938_pci_setup(void)
41{
42#ifdef CONFIG_PCI
43 int extarb = !(__raw_readq(&tx4938_ccfgptr->ccfg) & TX4938_CCFG_PCIARB);
44 struct pci_controller *c = &txx9_primary_pcic;
45
46 register_pci_controller(c);
47
48 if (__raw_readq(&tx4938_ccfgptr->ccfg) & TX4938_CCFG_PCI66)
49 txx9_pci_option =
50 (txx9_pci_option & ~TXX9_PCI_OPT_CLK_MASK) |
51 TXX9_PCI_OPT_CLK_66; /* already configured */
52
53 /* Reset PCI Bus */
54 writeb(0, rbtx4938_pcireset_addr);
55 /* Reset PCIC */
56 txx9_set64(&tx4938_ccfgptr->clkctr, TX4938_CLKCTR_PCIRST);
57 if ((txx9_pci_option & TXX9_PCI_OPT_CLK_MASK) ==
58 TXX9_PCI_OPT_CLK_66)
59 tx4938_pciclk66_setup();
60 mdelay(10);
61 /* clear PCIC reset */
62 txx9_clear64(&tx4938_ccfgptr->clkctr, TX4938_CLKCTR_PCIRST);
63 writeb(1, rbtx4938_pcireset_addr);
64 iob();
65
66 tx4938_report_pciclk();
67 tx4927_pcic_setup(tx4938_pcicptr, c, extarb);
68 if ((txx9_pci_option & TXX9_PCI_OPT_CLK_MASK) ==
69 TXX9_PCI_OPT_CLK_AUTO &&
70 txx9_pci66_check(c, 0, 0)) {
71 /* Reset PCI Bus */
72 writeb(0, rbtx4938_pcireset_addr);
73 /* Reset PCIC */
74 txx9_set64(&tx4938_ccfgptr->clkctr, TX4938_CLKCTR_PCIRST);
75 tx4938_pciclk66_setup();
76 mdelay(10);
77 /* clear PCIC reset */
78 txx9_clear64(&tx4938_ccfgptr->clkctr, TX4938_CLKCTR_PCIRST);
79 writeb(1, rbtx4938_pcireset_addr);
80 iob();
81 /* Reinitialize PCIC */
82 tx4938_report_pciclk();
83 tx4927_pcic_setup(tx4938_pcicptr, c, extarb);
84 }
85
86 if (__raw_readq(&tx4938_ccfgptr->pcfg) &
87 (TX4938_PCFG_ETH0_SEL|TX4938_PCFG_ETH1_SEL)) {
88 /* Reset PCIC1 */
89 txx9_set64(&tx4938_ccfgptr->clkctr, TX4938_CLKCTR_PCIC1RST);
90 /* PCI1DMD==0 => PCI1CLK==GBUSCLK/2 => PCI66 */
91 if (!(__raw_readq(&tx4938_ccfgptr->ccfg)
92 & TX4938_CCFG_PCI1DMD))
93 tx4938_ccfg_set(TX4938_CCFG_PCI1_66);
94 mdelay(10);
95 /* clear PCIC1 reset */
96 txx9_clear64(&tx4938_ccfgptr->clkctr, TX4938_CLKCTR_PCIC1RST);
97 tx4938_report_pci1clk();
98
99 /* mem:64K(max), io:64K(max) (enough for ETH0,ETH1) */
100 c = txx9_alloc_pci_controller(NULL, 0, 0x10000, 0, 0x10000);
101 register_pci_controller(c);
102 tx4927_pcic_setup(tx4938_pcic1ptr, c, 0);
103 }
104 tx4938_setup_pcierr_irq();
105#endif /* CONFIG_PCI */
106}
107
108/* SPI support */
109
110/* chip select for SPI devices */
111#define SEEPROM1_CS 7 /* PIO7 */
112#define SEEPROM2_CS 0 /* IOC */
113#define SEEPROM3_CS 1 /* IOC */
114#define SRTC_CS 2 /* IOC */
115#define SPI_BUSNO 0
116
117static int __init rbtx4938_ethaddr_init(void)
118{
119#ifdef CONFIG_PCI
120 unsigned char dat[17];
121 unsigned char sum;
122 int i;
123
124 /* 0-3: "MAC\0", 4-9:eth0, 10-15:eth1, 16:sum */
125 if (spi_eeprom_read(SPI_BUSNO, SEEPROM1_CS, 0, dat, sizeof(dat))) {
126 pr_err("seeprom: read error.\n");
127 return -ENODEV;
128 } else {
129 if (strcmp(dat, "MAC") != 0)
130 pr_warn("seeprom: bad signature.\n");
131 for (i = 0, sum = 0; i < sizeof(dat); i++)
132 sum += dat[i];
133 if (sum)
134 pr_warn("seeprom: bad checksum.\n");
135 }
136 tx4938_ethaddr_init(&dat[4], &dat[4 + 6]);
137#endif /* CONFIG_PCI */
138 return 0;
139}
140
141static void __init rbtx4938_spi_setup(void)
142{
143 /* set SPI_SEL */
144 txx9_set64(&tx4938_ccfgptr->pcfg, TX4938_PCFG_SPI_SEL);
145}
146
147static struct resource rbtx4938_fpga_resource;
148
149static void __init rbtx4938_time_init(void)
150{
151 tx4938_time_init(0);
152}
153
154static void __init rbtx4938_mem_setup(void)
155{
156 unsigned long long pcfg;
157
158 if (txx9_master_clock == 0)
159 txx9_master_clock = 25000000; /* 25MHz */
160
161 tx4938_setup();
162
163#ifdef CONFIG_PCI
164 txx9_alloc_pci_controller(&txx9_primary_pcic, 0, 0, 0, 0);
165 txx9_board_pcibios_setup = tx4927_pcibios_setup;
166#else
167 set_io_port_base(RBTX4938_ETHER_BASE);
168#endif
169
170 tx4938_sio_init(7372800, 0);
171
172#ifdef CONFIG_TOSHIBA_RBTX4938_MPLEX_PIO58_61
173 pr_info("PIOSEL: disabling both ATA and NAND selection\n");
174 txx9_clear64(&tx4938_ccfgptr->pcfg,
175 TX4938_PCFG_NDF_SEL | TX4938_PCFG_ATA_SEL);
176#endif
177
178#ifdef CONFIG_TOSHIBA_RBTX4938_MPLEX_NAND
179 pr_info("PIOSEL: enabling NAND selection\n");
180 txx9_set64(&tx4938_ccfgptr->pcfg, TX4938_PCFG_NDF_SEL);
181 txx9_clear64(&tx4938_ccfgptr->pcfg, TX4938_PCFG_ATA_SEL);
182#endif
183
184#ifdef CONFIG_TOSHIBA_RBTX4938_MPLEX_ATA
185 pr_info("PIOSEL: enabling ATA selection\n");
186 txx9_set64(&tx4938_ccfgptr->pcfg, TX4938_PCFG_ATA_SEL);
187 txx9_clear64(&tx4938_ccfgptr->pcfg, TX4938_PCFG_NDF_SEL);
188#endif
189
190#ifdef CONFIG_TOSHIBA_RBTX4938_MPLEX_KEEP
191 pcfg = ____raw_readq(&tx4938_ccfgptr->pcfg);
192 pr_info("PIOSEL: NAND %s, ATA %s\n",
193 (pcfg & TX4938_PCFG_NDF_SEL) ? "enabled" : "disabled",
194 (pcfg & TX4938_PCFG_ATA_SEL) ? "enabled" : "disabled");
195#endif
196
197 rbtx4938_spi_setup();
198 pcfg = ____raw_readq(&tx4938_ccfgptr->pcfg); /* updated */
199 /* fixup piosel */
200 if ((pcfg & (TX4938_PCFG_ATA_SEL | TX4938_PCFG_NDF_SEL)) ==
201 TX4938_PCFG_ATA_SEL)
202 writeb((readb(rbtx4938_piosel_addr) & 0x03) | 0x04,
203 rbtx4938_piosel_addr);
204 else if ((pcfg & (TX4938_PCFG_ATA_SEL | TX4938_PCFG_NDF_SEL)) ==
205 TX4938_PCFG_NDF_SEL)
206 writeb((readb(rbtx4938_piosel_addr) & 0x03) | 0x08,
207 rbtx4938_piosel_addr);
208 else
209 writeb(readb(rbtx4938_piosel_addr) & ~(0x08 | 0x04),
210 rbtx4938_piosel_addr);
211
212 rbtx4938_fpga_resource.name = "FPGA Registers";
213 rbtx4938_fpga_resource.start = CPHYSADDR(RBTX4938_FPGA_REG_ADDR);
214 rbtx4938_fpga_resource.end = CPHYSADDR(RBTX4938_FPGA_REG_ADDR) + 0xffff;
215 rbtx4938_fpga_resource.flags = IORESOURCE_MEM | IORESOURCE_BUSY;
216 if (request_resource(&txx9_ce_res[2], &rbtx4938_fpga_resource))
217 pr_err("request resource for fpga failed\n");
218
219 _machine_restart = rbtx4938_machine_restart;
220
221 writeb(0xff, rbtx4938_led_addr);
222 pr_info("RBTX4938 --- FPGA(Rev %02x) DIPSW:%02x,%02x\n",
223 readb(rbtx4938_fpga_rev_addr),
224 readb(rbtx4938_dipsw_addr), readb(rbtx4938_bdipsw_addr));
225}
226
227static void __init rbtx4938_ne_init(void)
228{
229 struct resource res[] = {
230 {
231 .start = RBTX4938_RTL_8019_BASE,
232 .end = RBTX4938_RTL_8019_BASE + 0x20 - 1,
233 .flags = IORESOURCE_IO,
234 }, {
235 .start = RBTX4938_RTL_8019_IRQ,
236 .flags = IORESOURCE_IRQ,
237 }
238 };
239 platform_device_register_simple("ne", -1, res, ARRAY_SIZE(res));
240}
241
242static DEFINE_SPINLOCK(rbtx4938_spi_gpio_lock);
243
244static void rbtx4938_spi_gpio_set(struct gpio_chip *chip, unsigned int offset,
245 int value)
246{
247 u8 val;
248 unsigned long flags;
249 spin_lock_irqsave(&rbtx4938_spi_gpio_lock, flags);
250 val = readb(rbtx4938_spics_addr);
251 if (value)
252 val |= 1 << offset;
253 else
254 val &= ~(1 << offset);
255 writeb(val, rbtx4938_spics_addr);
256 mmiowb();
257 spin_unlock_irqrestore(&rbtx4938_spi_gpio_lock, flags);
258}
259
260static int rbtx4938_spi_gpio_dir_out(struct gpio_chip *chip,
261 unsigned int offset, int value)
262{
263 rbtx4938_spi_gpio_set(chip, offset, value);
264 return 0;
265}
266
267static struct gpio_chip rbtx4938_spi_gpio_chip = {
268 .set = rbtx4938_spi_gpio_set,
269 .direction_output = rbtx4938_spi_gpio_dir_out,
270 .label = "RBTX4938-SPICS",
271 .base = 16,
272 .ngpio = 3,
273};
274
275static int __init rbtx4938_spi_init(void)
276{
277 struct spi_board_info srtc_info = {
278 .modalias = "rtc-rs5c348",
279 .max_speed_hz = 1000000, /* 1.0Mbps @ Vdd 2.0V */
280 .bus_num = 0,
281 .chip_select = 16 + SRTC_CS,
282 /* Mode 1 (High-Active, Shift-Then-Sample), High Avtive CS */
283 .mode = SPI_MODE_1 | SPI_CS_HIGH,
284 };
285 spi_register_board_info(&srtc_info, 1);
286 spi_eeprom_register(SPI_BUSNO, SEEPROM1_CS, 128);
287 spi_eeprom_register(SPI_BUSNO, 16 + SEEPROM2_CS, 128);
288 spi_eeprom_register(SPI_BUSNO, 16 + SEEPROM3_CS, 128);
289 gpio_request(16 + SRTC_CS, "rtc-rs5c348");
290 gpio_direction_output(16 + SRTC_CS, 0);
291 gpio_request(SEEPROM1_CS, "seeprom1");
292 gpio_direction_output(SEEPROM1_CS, 1);
293 gpio_request(16 + SEEPROM2_CS, "seeprom2");
294 gpio_direction_output(16 + SEEPROM2_CS, 1);
295 gpio_request(16 + SEEPROM3_CS, "seeprom3");
296 gpio_direction_output(16 + SEEPROM3_CS, 1);
297 tx4938_spi_init(SPI_BUSNO);
298 return 0;
299}
300
301static void __init rbtx4938_mtd_init(void)
302{
303 struct physmap_flash_data pdata = {
304 .width = 4,
305 };
306
307 switch (readb(rbtx4938_bdipsw_addr) & 7) {
308 case 0:
309 /* Boot */
310 txx9_physmap_flash_init(0, 0x1fc00000, 0x400000, &pdata);
311 /* System */
312 txx9_physmap_flash_init(1, 0x1e000000, 0x1000000, &pdata);
313 break;
314 case 1:
315 /* System */
316 txx9_physmap_flash_init(0, 0x1f000000, 0x1000000, &pdata);
317 /* Boot */
318 txx9_physmap_flash_init(1, 0x1ec00000, 0x400000, &pdata);
319 break;
320 case 2:
321 /* Ext */
322 txx9_physmap_flash_init(0, 0x1f000000, 0x1000000, &pdata);
323 /* System */
324 txx9_physmap_flash_init(1, 0x1e000000, 0x1000000, &pdata);
325 /* Boot */
326 txx9_physmap_flash_init(2, 0x1dc00000, 0x400000, &pdata);
327 break;
328 case 3:
329 /* Boot */
330 txx9_physmap_flash_init(1, 0x1bc00000, 0x400000, &pdata);
331 /* System */
332 txx9_physmap_flash_init(2, 0x1a000000, 0x1000000, &pdata);
333 break;
334 }
335}
336
337static void __init rbtx4938_arch_init(void)
338{
339 txx9_gpio_init(TX4938_PIO_REG & 0xfffffffffULL, 0, TX4938_NUM_PIO);
340 gpiochip_add_data(&rbtx4938_spi_gpio_chip, NULL);
341 rbtx4938_pci_setup();
342 rbtx4938_spi_init();
343}
344
345static void __init rbtx4938_device_init(void)
346{
347 rbtx4938_ethaddr_init();
348 rbtx4938_ne_init();
349 tx4938_wdt_init();
350 rbtx4938_mtd_init();
351 /* TC58DVM82A1FT: tDH=10ns, tWP=tRP=tREADID=35ns */
352 tx4938_ndfmc_init(10, 35);
353 tx4938_ata_init(RBTX4938_IRQ_IOC_ATA, 0, 1);
354 tx4938_dmac_init(0, 2);
355 tx4938_aclc_init();
356 platform_device_register_simple("txx9aclc-generic", -1, NULL, 0);
357 tx4938_sramc_init();
358 txx9_iocled_init(RBTX4938_LED_ADDR - IO_BASE, -1, 8, 1, "green", NULL);
359}
360
361struct txx9_board_vec rbtx4938_vec __initdata = {
362 .system = "Toshiba RBTX4938",
363 .prom_init = rbtx4938_prom_init,
364 .mem_setup = rbtx4938_mem_setup,
365 .irq_setup = rbtx4938_irq_setup,
366 .time_init = rbtx4938_time_init,
367 .device_init = rbtx4938_device_init,
368 .arch_init = rbtx4938_arch_init,
369#ifdef CONFIG_PCI
370 .pci_map_irq = rbtx4938_pci_map_irq,
371#endif
372};
diff --git a/arch/mips/txx9/rbtx4939/Makefile b/arch/mips/txx9/rbtx4939/Makefile
new file mode 100644
index 000000000..840496e7a
--- /dev/null
+++ b/arch/mips/txx9/rbtx4939/Makefile
@@ -0,0 +1,2 @@
1# SPDX-License-Identifier: GPL-2.0-only
2obj-y += irq.o setup.o prom.o
diff --git a/arch/mips/txx9/rbtx4939/irq.c b/arch/mips/txx9/rbtx4939/irq.c
new file mode 100644
index 000000000..69a80616f
--- /dev/null
+++ b/arch/mips/txx9/rbtx4939/irq.c
@@ -0,0 +1,95 @@
1/*
2 * Toshiba RBTX4939 interrupt routines
3 * Based on linux/arch/mips/txx9/rbtx4938/irq.c,
4 * and RBTX49xx patch from CELF patch archive.
5 *
6 * Copyright (C) 2000-2001,2005-2006 Toshiba Corporation
7 * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the
8 * terms of the GNU General Public License version 2. This program is
9 * licensed "as is" without any warranty of any kind, whether express
10 * or implied.
11 */
12#include <linux/init.h>
13#include <linux/interrupt.h>
14#include <linux/irq.h>
15#include <asm/mipsregs.h>
16#include <asm/txx9/rbtx4939.h>
17
18/*
19 * RBTX4939 IOC controller definition
20 */
21
22static void rbtx4939_ioc_irq_unmask(struct irq_data *d)
23{
24 int ioc_nr = d->irq - RBTX4939_IRQ_IOC;
25
26 writeb(readb(rbtx4939_ien_addr) | (1 << ioc_nr), rbtx4939_ien_addr);
27}
28
29static void rbtx4939_ioc_irq_mask(struct irq_data *d)
30{
31 int ioc_nr = d->irq - RBTX4939_IRQ_IOC;
32
33 writeb(readb(rbtx4939_ien_addr) & ~(1 << ioc_nr), rbtx4939_ien_addr);
34 mmiowb();
35}
36
37static struct irq_chip rbtx4939_ioc_irq_chip = {
38 .name = "IOC",
39 .irq_mask = rbtx4939_ioc_irq_mask,
40 .irq_unmask = rbtx4939_ioc_irq_unmask,
41};
42
43
44static inline int rbtx4939_ioc_irqroute(void)
45{
46 unsigned char istat = readb(rbtx4939_ifac2_addr);
47
48 if (unlikely(istat == 0))
49 return -1;
50 return RBTX4939_IRQ_IOC + __fls8(istat);
51}
52
53static int rbtx4939_irq_dispatch(int pending)
54{
55 int irq;
56
57 if (pending & CAUSEF_IP7)
58 return MIPS_CPU_IRQ_BASE + 7;
59 irq = tx4939_irq();
60 if (likely(irq >= 0)) {
61 /* redirect IOC interrupts */
62 switch (irq) {
63 case RBTX4939_IRQ_IOCINT:
64 irq = rbtx4939_ioc_irqroute();
65 break;
66 }
67 } else if (pending & CAUSEF_IP0)
68 irq = MIPS_CPU_IRQ_BASE + 0;
69 else if (pending & CAUSEF_IP1)
70 irq = MIPS_CPU_IRQ_BASE + 1;
71 else
72 irq = -1;
73 return irq;
74}
75
76void __init rbtx4939_irq_setup(void)
77{
78 int i;
79
80 /* mask all IOC interrupts */
81 writeb(0, rbtx4939_ien_addr);
82
83 /* clear SoftInt interrupts */
84 writeb(0, rbtx4939_softint_addr);
85
86 txx9_irq_dispatch = rbtx4939_irq_dispatch;
87
88 tx4939_irq_init();
89 for (i = RBTX4939_IRQ_IOC;
90 i < RBTX4939_IRQ_IOC + RBTX4939_NR_IRQ_IOC; i++)
91 irq_set_chip_and_handler(i, &rbtx4939_ioc_irq_chip,
92 handle_level_irq);
93
94 irq_set_chained_handler(RBTX4939_IRQ_IOCINT, handle_simple_irq);
95}
diff --git a/arch/mips/txx9/rbtx4939/prom.c b/arch/mips/txx9/rbtx4939/prom.c
new file mode 100644
index 000000000..ba25ba1bd
--- /dev/null
+++ b/arch/mips/txx9/rbtx4939/prom.c
@@ -0,0 +1,29 @@
1/*
2 * rbtx4939 specific prom routines
3 *
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file "COPYING" in the main directory of this archive
6 * for more details.
7 */
8
9#include <linux/init.h>
10#include <linux/memblock.h>
11#include <asm/txx9/generic.h>
12#include <asm/txx9/rbtx4939.h>
13
14void __init rbtx4939_prom_init(void)
15{
16 unsigned long start, size;
17 u64 win;
18 int i;
19
20 for (i = 0; i < 4; i++) {
21 if (!((__u32)____raw_readq(&tx4939_ddrcptr->winen) & (1 << i)))
22 continue;
23 win = ____raw_readq(&tx4939_ddrcptr->win[i]);
24 start = (unsigned long)(win >> 48);
25 size = (((unsigned long)(win >> 32) & 0xffff) + 1) - start;
26 memblock_add(start << 20, size << 20);
27 }
28 txx9_sio_putchar_init(TX4939_SIO_REG(0) & 0xfffffffffULL);
29}
diff --git a/arch/mips/txx9/rbtx4939/setup.c b/arch/mips/txx9/rbtx4939/setup.c
new file mode 100644
index 000000000..ef29a9c2f
--- /dev/null
+++ b/arch/mips/txx9/rbtx4939/setup.c
@@ -0,0 +1,554 @@
1/*
2 * Toshiba RBTX4939 setup routines.
3 * Based on linux/arch/mips/txx9/rbtx4938/setup.c,
4 * and RBTX49xx patch from CELF patch archive.
5 *
6 * Copyright (C) 2000-2001,2005-2007 Toshiba Corporation
7 * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the
8 * terms of the GNU General Public License version 2. This program is
9 * licensed "as is" without any warranty of any kind, whether express
10 * or implied.
11 */
12#include <linux/init.h>
13#include <linux/kernel.h>
14#include <linux/types.h>
15#include <linux/slab.h>
16#include <linux/export.h>
17#include <linux/platform_device.h>
18#include <linux/leds.h>
19#include <linux/interrupt.h>
20#include <linux/smc91x.h>
21#include <linux/mtd/mtd.h>
22#include <linux/mtd/partitions.h>
23#include <linux/mtd/map.h>
24#include <asm/reboot.h>
25#include <asm/txx9/generic.h>
26#include <asm/txx9/pci.h>
27#include <asm/txx9/rbtx4939.h>
28
29static void rbtx4939_machine_restart(char *command)
30{
31 local_irq_disable();
32 writeb(1, rbtx4939_reseten_addr);
33 writeb(1, rbtx4939_softreset_addr);
34 while (1)
35 ;
36}
37
38static void __init rbtx4939_time_init(void)
39{
40 tx4939_time_init(0);
41}
42
43#if defined(__BIG_ENDIAN) && IS_ENABLED(CONFIG_SMC91X)
44#define HAVE_RBTX4939_IOSWAB
45#define IS_CE1_ADDR(addr) \
46 ((((unsigned long)(addr) - IO_BASE) & 0xfff00000) == TXX9_CE(1))
47static u16 rbtx4939_ioswabw(volatile u16 *a, u16 x)
48{
49 return IS_CE1_ADDR(a) ? x : le16_to_cpu(x);
50}
51static u16 rbtx4939_mem_ioswabw(volatile u16 *a, u16 x)
52{
53 return !IS_CE1_ADDR(a) ? x : le16_to_cpu(x);
54}
55#endif /* __BIG_ENDIAN && CONFIG_SMC91X */
56
57static void __init rbtx4939_pci_setup(void)
58{
59#ifdef CONFIG_PCI
60 int extarb = !(__raw_readq(&tx4939_ccfgptr->ccfg) & TX4939_CCFG_PCIARB);
61 struct pci_controller *c = &txx9_primary_pcic;
62
63 register_pci_controller(c);
64
65 tx4939_report_pciclk();
66 tx4927_pcic_setup(tx4939_pcicptr, c, extarb);
67 if (!(__raw_readq(&tx4939_ccfgptr->pcfg) & TX4939_PCFG_ATA1MODE) &&
68 (__raw_readq(&tx4939_ccfgptr->pcfg) &
69 (TX4939_PCFG_ET0MODE | TX4939_PCFG_ET1MODE))) {
70 tx4939_report_pci1clk();
71
72 /* mem:64K(max), io:64K(max) (enough for ETH0,ETH1) */
73 c = txx9_alloc_pci_controller(NULL, 0, 0x10000, 0, 0x10000);
74 register_pci_controller(c);
75 tx4927_pcic_setup(tx4939_pcic1ptr, c, 0);
76 }
77
78 tx4939_setup_pcierr_irq();
79#endif /* CONFIG_PCI */
80}
81
82static unsigned long long default_ebccr[] __initdata = {
83 0x01c0000000007608ULL, /* 64M ROM */
84 0x017f000000007049ULL, /* 1M IOC */
85 0x0180000000408608ULL, /* ISA */
86 0,
87};
88
89static void __init rbtx4939_ebusc_setup(void)
90{
91 int i;
92 unsigned int sp;
93
94 /* use user-configured speed */
95 sp = TX4939_EBUSC_CR(0) & 0x30;
96 default_ebccr[0] |= sp;
97 default_ebccr[1] |= sp;
98 default_ebccr[2] |= sp;
99 /* initialise by myself */
100 for (i = 0; i < ARRAY_SIZE(default_ebccr); i++) {
101 if (default_ebccr[i])
102 ____raw_writeq(default_ebccr[i],
103 &tx4939_ebuscptr->cr[i]);
104 else
105 ____raw_writeq(____raw_readq(&tx4939_ebuscptr->cr[i])
106 & ~8,
107 &tx4939_ebuscptr->cr[i]);
108 }
109}
110
111static void __init rbtx4939_update_ioc_pen(void)
112{
113 __u64 pcfg = ____raw_readq(&tx4939_ccfgptr->pcfg);
114 __u64 ccfg = ____raw_readq(&tx4939_ccfgptr->ccfg);
115 __u8 pe1 = readb(rbtx4939_pe1_addr);
116 __u8 pe2 = readb(rbtx4939_pe2_addr);
117 __u8 pe3 = readb(rbtx4939_pe3_addr);
118 if (pcfg & TX4939_PCFG_ATA0MODE)
119 pe1 |= RBTX4939_PE1_ATA(0);
120 else
121 pe1 &= ~RBTX4939_PE1_ATA(0);
122 if (pcfg & TX4939_PCFG_ATA1MODE) {
123 pe1 |= RBTX4939_PE1_ATA(1);
124 pe1 &= ~(RBTX4939_PE1_RMII(0) | RBTX4939_PE1_RMII(1));
125 } else {
126 pe1 &= ~RBTX4939_PE1_ATA(1);
127 if (pcfg & TX4939_PCFG_ET0MODE)
128 pe1 |= RBTX4939_PE1_RMII(0);
129 else
130 pe1 &= ~RBTX4939_PE1_RMII(0);
131 if (pcfg & TX4939_PCFG_ET1MODE)
132 pe1 |= RBTX4939_PE1_RMII(1);
133 else
134 pe1 &= ~RBTX4939_PE1_RMII(1);
135 }
136 if (ccfg & TX4939_CCFG_PTSEL)
137 pe3 &= ~(RBTX4939_PE3_VP | RBTX4939_PE3_VP_P |
138 RBTX4939_PE3_VP_S);
139 else {
140 __u64 vmode = pcfg &
141 (TX4939_PCFG_VSSMODE | TX4939_PCFG_VPSMODE);
142 if (vmode == 0)
143 pe3 &= ~(RBTX4939_PE3_VP | RBTX4939_PE3_VP_P |
144 RBTX4939_PE3_VP_S);
145 else if (vmode == TX4939_PCFG_VPSMODE) {
146 pe3 |= RBTX4939_PE3_VP_P;
147 pe3 &= ~(RBTX4939_PE3_VP | RBTX4939_PE3_VP_S);
148 } else if (vmode == TX4939_PCFG_VSSMODE) {
149 pe3 |= RBTX4939_PE3_VP | RBTX4939_PE3_VP_S;
150 pe3 &= ~RBTX4939_PE3_VP_P;
151 } else {
152 pe3 |= RBTX4939_PE3_VP | RBTX4939_PE3_VP_P;
153 pe3 &= ~RBTX4939_PE3_VP_S;
154 }
155 }
156 if (pcfg & TX4939_PCFG_SPIMODE) {
157 if (pcfg & TX4939_PCFG_SIO2MODE_GPIO)
158 pe2 &= ~(RBTX4939_PE2_SIO2 | RBTX4939_PE2_SIO0);
159 else {
160 if (pcfg & TX4939_PCFG_SIO2MODE_SIO2) {
161 pe2 |= RBTX4939_PE2_SIO2;
162 pe2 &= ~RBTX4939_PE2_SIO0;
163 } else {
164 pe2 |= RBTX4939_PE2_SIO0;
165 pe2 &= ~RBTX4939_PE2_SIO2;
166 }
167 }
168 if (pcfg & TX4939_PCFG_SIO3MODE)
169 pe2 |= RBTX4939_PE2_SIO3;
170 else
171 pe2 &= ~RBTX4939_PE2_SIO3;
172 pe2 &= ~RBTX4939_PE2_SPI;
173 } else {
174 pe2 |= RBTX4939_PE2_SPI;
175 pe2 &= ~(RBTX4939_PE2_SIO3 | RBTX4939_PE2_SIO2 |
176 RBTX4939_PE2_SIO0);
177 }
178 if ((pcfg & TX4939_PCFG_I2SMODE_MASK) == TX4939_PCFG_I2SMODE_GPIO)
179 pe2 |= RBTX4939_PE2_GPIO;
180 else
181 pe2 &= ~RBTX4939_PE2_GPIO;
182 writeb(pe1, rbtx4939_pe1_addr);
183 writeb(pe2, rbtx4939_pe2_addr);
184 writeb(pe3, rbtx4939_pe3_addr);
185}
186
187#define RBTX4939_MAX_7SEGLEDS 8
188
189#if IS_BUILTIN(CONFIG_LEDS_CLASS)
190static u8 led_val[RBTX4939_MAX_7SEGLEDS];
191struct rbtx4939_led_data {
192 struct led_classdev cdev;
193 char name[32];
194 unsigned int num;
195};
196
197/* Use "dot" in 7seg LEDs */
198static void rbtx4939_led_brightness_set(struct led_classdev *led_cdev,
199 enum led_brightness value)
200{
201 struct rbtx4939_led_data *led_dat =
202 container_of(led_cdev, struct rbtx4939_led_data, cdev);
203 unsigned int num = led_dat->num;
204 unsigned long flags;
205
206 local_irq_save(flags);
207 led_val[num] = (led_val[num] & 0x7f) | (value ? 0x80 : 0);
208 writeb(led_val[num], rbtx4939_7seg_addr(num / 4, num % 4));
209 local_irq_restore(flags);
210}
211
212static int __init rbtx4939_led_probe(struct platform_device *pdev)
213{
214 struct rbtx4939_led_data *leds_data;
215 int i;
216 static char *default_triggers[] __initdata = {
217 "heartbeat",
218 "disk-activity",
219 "nand-disk",
220 };
221
222 leds_data = kcalloc(RBTX4939_MAX_7SEGLEDS, sizeof(*leds_data),
223 GFP_KERNEL);
224 if (!leds_data)
225 return -ENOMEM;
226 for (i = 0; i < RBTX4939_MAX_7SEGLEDS; i++) {
227 int rc;
228 struct rbtx4939_led_data *led_dat = &leds_data[i];
229
230 led_dat->num = i;
231 led_dat->cdev.brightness_set = rbtx4939_led_brightness_set;
232 sprintf(led_dat->name, "rbtx4939:amber:%u", i);
233 led_dat->cdev.name = led_dat->name;
234 if (i < ARRAY_SIZE(default_triggers))
235 led_dat->cdev.default_trigger = default_triggers[i];
236 rc = led_classdev_register(&pdev->dev, &led_dat->cdev);
237 if (rc < 0)
238 return rc;
239 led_dat->cdev.brightness_set(&led_dat->cdev, 0);
240 }
241 return 0;
242
243}
244
245static struct platform_driver rbtx4939_led_driver = {
246 .driver = {
247 .name = "rbtx4939-led",
248 },
249};
250
251static void __init rbtx4939_led_setup(void)
252{
253 platform_device_register_simple("rbtx4939-led", -1, NULL, 0);
254 platform_driver_probe(&rbtx4939_led_driver, rbtx4939_led_probe);
255}
256#else
257static inline void rbtx4939_led_setup(void)
258{
259}
260#endif
261
262static void __rbtx4939_7segled_putc(unsigned int pos, unsigned char val)
263{
264#if IS_BUILTIN(CONFIG_LEDS_CLASS)
265 unsigned long flags;
266 local_irq_save(flags);
267 /* bit7: reserved for LED class */
268 led_val[pos] = (led_val[pos] & 0x80) | (val & 0x7f);
269 val = led_val[pos];
270 local_irq_restore(flags);
271#endif
272 writeb(val, rbtx4939_7seg_addr(pos / 4, pos % 4));
273}
274
275static void rbtx4939_7segled_putc(unsigned int pos, unsigned char val)
276{
277 /* convert from map_to_seg7() notation */
278 val = (val & 0x88) |
279 ((val & 0x40) >> 6) |
280 ((val & 0x20) >> 4) |
281 ((val & 0x10) >> 2) |
282 ((val & 0x04) << 2) |
283 ((val & 0x02) << 4) |
284 ((val & 0x01) << 6);
285 __rbtx4939_7segled_putc(pos, val);
286}
287
288#if IS_ENABLED(CONFIG_MTD_RBTX4939)
289/* special mapping for boot rom */
290static unsigned long rbtx4939_flash_fixup_ofs(unsigned long ofs)
291{
292 u8 bdipsw = readb(rbtx4939_bdipsw_addr) & 0x0f;
293 unsigned char shift;
294
295 if (bdipsw & 8) {
296 /* BOOT Mode: USER ROM1 / USER ROM2 */
297 shift = bdipsw & 3;
298 /* rotate A[23:22] */
299 return (ofs & ~0xc00000) | ((((ofs >> 22) + shift) & 3) << 22);
300 }
301#ifdef __BIG_ENDIAN
302 if (bdipsw == 0)
303 /* BOOT Mode: Monitor ROM */
304 ofs ^= 0x400000; /* swap A[22] */
305#endif
306 return ofs;
307}
308
309static map_word rbtx4939_flash_read16(struct map_info *map, unsigned long ofs)
310{
311 map_word r;
312
313 ofs = rbtx4939_flash_fixup_ofs(ofs);
314 r.x[0] = __raw_readw(map->virt + ofs);
315 return r;
316}
317
318static void rbtx4939_flash_write16(struct map_info *map, const map_word datum,
319 unsigned long ofs)
320{
321 ofs = rbtx4939_flash_fixup_ofs(ofs);
322 __raw_writew(datum.x[0], map->virt + ofs);
323 mb(); /* see inline_map_write() in mtd/map.h */
324}
325
326static void rbtx4939_flash_copy_from(struct map_info *map, void *to,
327 unsigned long from, ssize_t len)
328{
329 u8 bdipsw = readb(rbtx4939_bdipsw_addr) & 0x0f;
330 unsigned char shift;
331 ssize_t curlen;
332
333 from += (unsigned long)map->virt;
334 if (bdipsw & 8) {
335 /* BOOT Mode: USER ROM1 / USER ROM2 */
336 shift = bdipsw & 3;
337 while (len) {
338 curlen = min_t(unsigned long, len,
339 0x400000 - (from & (0x400000 - 1)));
340 memcpy(to,
341 (void *)((from & ~0xc00000) |
342 ((((from >> 22) + shift) & 3) << 22)),
343 curlen);
344 len -= curlen;
345 from += curlen;
346 to += curlen;
347 }
348 return;
349 }
350#ifdef __BIG_ENDIAN
351 if (bdipsw == 0) {
352 /* BOOT Mode: Monitor ROM */
353 while (len) {
354 curlen = min_t(unsigned long, len,
355 0x400000 - (from & (0x400000 - 1)));
356 memcpy(to, (void *)(from ^ 0x400000), curlen);
357 len -= curlen;
358 from += curlen;
359 to += curlen;
360 }
361 return;
362 }
363#endif
364 memcpy(to, (void *)from, len);
365}
366
367static void rbtx4939_flash_map_init(struct map_info *map)
368{
369 map->read = rbtx4939_flash_read16;
370 map->write = rbtx4939_flash_write16;
371 map->copy_from = rbtx4939_flash_copy_from;
372}
373
374static void __init rbtx4939_mtd_init(void)
375{
376 static struct {
377 struct platform_device dev;
378 struct resource res;
379 struct rbtx4939_flash_data data;
380 } pdevs[4];
381 int i;
382 static char names[4][8];
383 static struct mtd_partition parts[4];
384 struct rbtx4939_flash_data *boot_pdata = &pdevs[0].data;
385 u8 bdipsw = readb(rbtx4939_bdipsw_addr) & 0x0f;
386
387 if (bdipsw & 8) {
388 /* BOOT Mode: USER ROM1 / USER ROM2 */
389 boot_pdata->nr_parts = 4;
390 for (i = 0; i < boot_pdata->nr_parts; i++) {
391 sprintf(names[i], "img%d", 4 - i);
392 parts[i].name = names[i];
393 parts[i].size = 0x400000;
394 parts[i].offset = MTDPART_OFS_NXTBLK;
395 }
396 } else if (bdipsw == 0) {
397 /* BOOT Mode: Monitor ROM */
398 boot_pdata->nr_parts = 2;
399 strcpy(names[0], "big");
400 strcpy(names[1], "little");
401 for (i = 0; i < boot_pdata->nr_parts; i++) {
402 parts[i].name = names[i];
403 parts[i].size = 0x400000;
404 parts[i].offset = MTDPART_OFS_NXTBLK;
405 }
406 } else {
407 /* BOOT Mode: ROM Emulator */
408 boot_pdata->nr_parts = 2;
409 parts[0].name = "boot";
410 parts[0].offset = 0xc00000;
411 parts[0].size = 0x400000;
412 parts[1].name = "user";
413 parts[1].offset = 0;
414 parts[1].size = 0xc00000;
415 }
416 boot_pdata->parts = parts;
417 boot_pdata->map_init = rbtx4939_flash_map_init;
418
419 for (i = 0; i < ARRAY_SIZE(pdevs); i++) {
420 struct resource *r = &pdevs[i].res;
421 struct platform_device *dev = &pdevs[i].dev;
422
423 r->start = 0x1f000000 - i * 0x1000000;
424 r->end = r->start + 0x1000000 - 1;
425 r->flags = IORESOURCE_MEM;
426 pdevs[i].data.width = 2;
427 dev->num_resources = 1;
428 dev->resource = r;
429 dev->id = i;
430 dev->name = "rbtx4939-flash";
431 dev->dev.platform_data = &pdevs[i].data;
432 platform_device_register(dev);
433 }
434}
435#else
436static void __init rbtx4939_mtd_init(void)
437{
438}
439#endif
440
441static void __init rbtx4939_arch_init(void)
442{
443 rbtx4939_pci_setup();
444}
445
446static void __init rbtx4939_device_init(void)
447{
448 unsigned long smc_addr = RBTX4939_ETHER_ADDR - IO_BASE;
449 struct resource smc_res[] = {
450 {
451 .start = smc_addr,
452 .end = smc_addr + 0x10 - 1,
453 .flags = IORESOURCE_MEM,
454 }, {
455 .start = RBTX4939_IRQ_ETHER,
456 /* override default irq flag defined in smc91x.h */
457 .flags = IORESOURCE_IRQ | IRQF_TRIGGER_LOW,
458 },
459 };
460 struct smc91x_platdata smc_pdata = {
461 .flags = SMC91X_USE_16BIT,
462 };
463 struct platform_device *pdev;
464#if IS_ENABLED(CONFIG_TC35815)
465 int i, j;
466 unsigned char ethaddr[2][6];
467 u8 bdipsw = readb(rbtx4939_bdipsw_addr) & 0x0f;
468
469 for (i = 0; i < 2; i++) {
470 unsigned long area = CKSEG1 + 0x1fff0000 + (i * 0x10);
471 if (bdipsw == 0)
472 memcpy(ethaddr[i], (void *)area, 6);
473 else {
474 u16 buf[3];
475 if (bdipsw & 8)
476 area -= 0x03000000;
477 else
478 area -= 0x01000000;
479 for (j = 0; j < 3; j++)
480 buf[j] = le16_to_cpup((u16 *)(area + j * 2));
481 memcpy(ethaddr[i], buf, 6);
482 }
483 }
484 tx4939_ethaddr_init(ethaddr[0], ethaddr[1]);
485#endif
486 pdev = platform_device_alloc("smc91x", -1);
487 if (!pdev ||
488 platform_device_add_resources(pdev, smc_res, ARRAY_SIZE(smc_res)) ||
489 platform_device_add_data(pdev, &smc_pdata, sizeof(smc_pdata)) ||
490 platform_device_add(pdev))
491 platform_device_put(pdev);
492 rbtx4939_mtd_init();
493 /* TC58DVM82A1FT: tDH=10ns, tWP=tRP=tREADID=35ns */
494 tx4939_ndfmc_init(10, 35,
495 (1 << 1) | (1 << 2),
496 (1 << 2)); /* ch1:8bit, ch2:16bit */
497 rbtx4939_led_setup();
498 tx4939_wdt_init();
499 tx4939_ata_init();
500 tx4939_rtc_init();
501 tx4939_dmac_init(0, 2);
502 tx4939_aclc_init();
503 platform_device_register_simple("txx9aclc-generic", -1, NULL, 0);
504 tx4939_sramc_init();
505 tx4939_rng_init();
506}
507
508static void __init rbtx4939_setup(void)
509{
510 int i;
511
512 rbtx4939_ebusc_setup();
513 /* always enable ATA0 */
514 txx9_set64(&tx4939_ccfgptr->pcfg, TX4939_PCFG_ATA0MODE);
515 if (txx9_master_clock == 0)
516 txx9_master_clock = 20000000;
517 tx4939_setup();
518 rbtx4939_update_ioc_pen();
519#ifdef HAVE_RBTX4939_IOSWAB
520 ioswabw = rbtx4939_ioswabw;
521 __mem_ioswabw = rbtx4939_mem_ioswabw;
522#endif
523
524 _machine_restart = rbtx4939_machine_restart;
525
526 txx9_7segled_init(RBTX4939_MAX_7SEGLEDS, rbtx4939_7segled_putc);
527 for (i = 0; i < RBTX4939_MAX_7SEGLEDS; i++)
528 txx9_7segled_putc(i, '-');
529 pr_info("RBTX4939 (Rev %02x) --- FPGA(Rev %02x) DIPSW:%02x,%02x\n",
530 readb(rbtx4939_board_rev_addr), readb(rbtx4939_ioc_rev_addr),
531 readb(rbtx4939_udipsw_addr), readb(rbtx4939_bdipsw_addr));
532
533#ifdef CONFIG_PCI
534 txx9_alloc_pci_controller(&txx9_primary_pcic, 0, 0, 0, 0);
535 txx9_board_pcibios_setup = tx4927_pcibios_setup;
536#else
537 set_io_port_base(RBTX4939_ETHER_BASE);
538#endif
539
540 tx4939_sio_init(TX4939_SCLK0(txx9_master_clock), 0);
541}
542
543struct txx9_board_vec rbtx4939_vec __initdata = {
544 .system = "Toshiba RBTX4939",
545 .prom_init = rbtx4939_prom_init,
546 .mem_setup = rbtx4939_setup,
547 .irq_setup = rbtx4939_irq_setup,
548 .time_init = rbtx4939_time_init,
549 .device_init = rbtx4939_device_init,
550 .arch_init = rbtx4939_arch_init,
551#ifdef CONFIG_PCI
552 .pci_map_irq = tx4939_pci_map_irq,
553#endif
554};