1b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto/*
2b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto * Toshiba RBTX4939 setup routines.
3b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto * Based on linux/arch/mips/txx9/rbtx4938/setup.c,
4b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto *	    and RBTX49xx patch from CELF patch archive.
5b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto *
6b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto * Copyright (C) 2000-2001,2005-2007 Toshiba Corporation
7b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the
8b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto * terms of the GNU General Public License version 2. This program is
9b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto * licensed "as is" without any warranty of any kind, whether express
10b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto * or implied.
11b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto */
12b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto#include <linux/init.h>
13b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto#include <linux/kernel.h>
14b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto#include <linux/types.h>
155a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h>
16cae39d1386dba405de0fbda32e224a1535d38a07Paul Gortmaker#include <linux/export.h>
17b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto#include <linux/platform_device.h>
18b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto#include <linux/leds.h>
191ba5a1767416cfa4fa37096e160e764c56e1460aAtsushi Nemoto#include <linux/interrupt.h>
201ba5a1767416cfa4fa37096e160e764c56e1460aAtsushi Nemoto#include <linux/smc91x.h>
21cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto#include <linux/mtd/mtd.h>
22cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto#include <linux/mtd/partitions.h>
23cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto#include <linux/mtd/map.h>
24b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto#include <asm/reboot.h>
25b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto#include <asm/txx9/generic.h>
26b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto#include <asm/txx9/pci.h>
27b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto#include <asm/txx9/rbtx4939.h>
28b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto
29b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemotostatic void rbtx4939_machine_restart(char *command)
30b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto{
31b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	local_irq_disable();
32b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	writeb(1, rbtx4939_reseten_addr);
33b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	writeb(1, rbtx4939_softreset_addr);
34b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	while (1)
35b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto		;
36b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto}
37b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto
38b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemotostatic void __init rbtx4939_time_init(void)
39b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto{
40b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	tx4939_time_init(0);
41b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto}
42b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto
431ba5a1767416cfa4fa37096e160e764c56e1460aAtsushi Nemoto#if defined(__BIG_ENDIAN) && \
441ba5a1767416cfa4fa37096e160e764c56e1460aAtsushi Nemoto	(defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE))
451ba5a1767416cfa4fa37096e160e764c56e1460aAtsushi Nemoto#define HAVE_RBTX4939_IOSWAB
461ba5a1767416cfa4fa37096e160e764c56e1460aAtsushi Nemoto#define IS_CE1_ADDR(addr) \
471ba5a1767416cfa4fa37096e160e764c56e1460aAtsushi Nemoto	((((unsigned long)(addr) - IO_BASE) & 0xfff00000) == TXX9_CE(1))
481ba5a1767416cfa4fa37096e160e764c56e1460aAtsushi Nemotostatic u16 rbtx4939_ioswabw(volatile u16 *a, u16 x)
491ba5a1767416cfa4fa37096e160e764c56e1460aAtsushi Nemoto{
501ba5a1767416cfa4fa37096e160e764c56e1460aAtsushi Nemoto	return IS_CE1_ADDR(a) ? x : le16_to_cpu(x);
511ba5a1767416cfa4fa37096e160e764c56e1460aAtsushi Nemoto}
521ba5a1767416cfa4fa37096e160e764c56e1460aAtsushi Nemotostatic u16 rbtx4939_mem_ioswabw(volatile u16 *a, u16 x)
531ba5a1767416cfa4fa37096e160e764c56e1460aAtsushi Nemoto{
541ba5a1767416cfa4fa37096e160e764c56e1460aAtsushi Nemoto	return !IS_CE1_ADDR(a) ? x : le16_to_cpu(x);
551ba5a1767416cfa4fa37096e160e764c56e1460aAtsushi Nemoto}
561ba5a1767416cfa4fa37096e160e764c56e1460aAtsushi Nemoto#endif /* __BIG_ENDIAN && CONFIG_SMC91X */
571ba5a1767416cfa4fa37096e160e764c56e1460aAtsushi Nemoto
58b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemotostatic void __init rbtx4939_pci_setup(void)
59b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto{
60b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto#ifdef CONFIG_PCI
61b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	int extarb = !(__raw_readq(&tx4939_ccfgptr->ccfg) & TX4939_CCFG_PCIARB);
62b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	struct pci_controller *c = &txx9_primary_pcic;
63b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto
64b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	register_pci_controller(c);
65b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto
66b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	tx4939_report_pciclk();
67b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	tx4927_pcic_setup(tx4939_pcicptr, c, extarb);
68b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	if (!(__raw_readq(&tx4939_ccfgptr->pcfg) & TX4939_PCFG_ATA1MODE) &&
69b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	    (__raw_readq(&tx4939_ccfgptr->pcfg) &
70b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	     (TX4939_PCFG_ET0MODE | TX4939_PCFG_ET1MODE))) {
71b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto		tx4939_report_pci1clk();
72b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto
73b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto		/* mem:64K(max), io:64K(max) (enough for ETH0,ETH1) */
74b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto		c = txx9_alloc_pci_controller(NULL, 0, 0x10000, 0, 0x10000);
75b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto		register_pci_controller(c);
76b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto		tx4927_pcic_setup(tx4939_pcic1ptr, c, 0);
77b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	}
78b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto
79b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	tx4939_setup_pcierr_irq();
80b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto#endif /* CONFIG_PCI */
81b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto}
82b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto
83b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemotostatic unsigned long long default_ebccr[] __initdata = {
84b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	0x01c0000000007608ULL, /* 64M ROM */
85b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	0x017f000000007049ULL, /* 1M IOC */
86b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	0x0180000000408608ULL, /* ISA */
87b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	0,
88b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto};
89b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto
90b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemotostatic void __init rbtx4939_ebusc_setup(void)
91b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto{
92b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	int i;
93b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	unsigned int sp;
94b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto
95b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	/* use user-configured speed */
96b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	sp = TX4939_EBUSC_CR(0) & 0x30;
97b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	default_ebccr[0] |= sp;
98b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	default_ebccr[1] |= sp;
99b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	default_ebccr[2] |= sp;
100b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	/* initialise by myself */
101b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	for (i = 0; i < ARRAY_SIZE(default_ebccr); i++) {
102b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto		if (default_ebccr[i])
103b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto			____raw_writeq(default_ebccr[i],
104b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto				       &tx4939_ebuscptr->cr[i]);
105b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto		else
106b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto			____raw_writeq(____raw_readq(&tx4939_ebuscptr->cr[i])
107b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto				       & ~8,
108b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto				       &tx4939_ebuscptr->cr[i]);
109b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	}
110b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto}
111b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto
112b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemotostatic void __init rbtx4939_update_ioc_pen(void)
113b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto{
114b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	__u64 pcfg = ____raw_readq(&tx4939_ccfgptr->pcfg);
115b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	__u64 ccfg = ____raw_readq(&tx4939_ccfgptr->ccfg);
116b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	__u8 pe1 = readb(rbtx4939_pe1_addr);
117b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	__u8 pe2 = readb(rbtx4939_pe2_addr);
118b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	__u8 pe3 = readb(rbtx4939_pe3_addr);
119b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	if (pcfg & TX4939_PCFG_ATA0MODE)
120b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto		pe1 |= RBTX4939_PE1_ATA(0);
121b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	else
122b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto		pe1 &= ~RBTX4939_PE1_ATA(0);
123b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	if (pcfg & TX4939_PCFG_ATA1MODE) {
124b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto		pe1 |= RBTX4939_PE1_ATA(1);
125b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto		pe1 &= ~(RBTX4939_PE1_RMII(0) | RBTX4939_PE1_RMII(1));
126b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	} else {
127b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto		pe1 &= ~RBTX4939_PE1_ATA(1);
128b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto		if (pcfg & TX4939_PCFG_ET0MODE)
129b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto			pe1 |= RBTX4939_PE1_RMII(0);
130b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto		else
131b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto			pe1 &= ~RBTX4939_PE1_RMII(0);
132b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto		if (pcfg & TX4939_PCFG_ET1MODE)
133b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto			pe1 |= RBTX4939_PE1_RMII(1);
134b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto		else
135b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto			pe1 &= ~RBTX4939_PE1_RMII(1);
136b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	}
137b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	if (ccfg & TX4939_CCFG_PTSEL)
138b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto		pe3 &= ~(RBTX4939_PE3_VP | RBTX4939_PE3_VP_P |
139b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto			 RBTX4939_PE3_VP_S);
140b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	else {
141b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto		__u64 vmode = pcfg &
142b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto			(TX4939_PCFG_VSSMODE | TX4939_PCFG_VPSMODE);
143b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto		if (vmode == 0)
144b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto			pe3 &= ~(RBTX4939_PE3_VP | RBTX4939_PE3_VP_P |
145b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto				 RBTX4939_PE3_VP_S);
146b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto		else if (vmode == TX4939_PCFG_VPSMODE) {
147b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto			pe3 |= RBTX4939_PE3_VP_P;
148b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto			pe3 &= ~(RBTX4939_PE3_VP | RBTX4939_PE3_VP_S);
149b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto		} else if (vmode == TX4939_PCFG_VSSMODE) {
150b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto			pe3 |= RBTX4939_PE3_VP | RBTX4939_PE3_VP_S;
151b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto			pe3 &= ~RBTX4939_PE3_VP_P;
152b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto		} else {
153b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto			pe3 |= RBTX4939_PE3_VP | RBTX4939_PE3_VP_P;
154b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto			pe3 &= ~RBTX4939_PE3_VP_S;
155b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto		}
156b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	}
157b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	if (pcfg & TX4939_PCFG_SPIMODE) {
158b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto		if (pcfg & TX4939_PCFG_SIO2MODE_GPIO)
159b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto			pe2 &= ~(RBTX4939_PE2_SIO2 | RBTX4939_PE2_SIO0);
160b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto		else {
161b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto			if (pcfg & TX4939_PCFG_SIO2MODE_SIO2) {
162b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto				pe2 |= RBTX4939_PE2_SIO2;
163b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto				pe2 &= ~RBTX4939_PE2_SIO0;
164b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto			} else {
165b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto				pe2 |= RBTX4939_PE2_SIO0;
166b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto				pe2 &= ~RBTX4939_PE2_SIO2;
167b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto			}
168b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto		}
169b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto		if (pcfg & TX4939_PCFG_SIO3MODE)
170b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto			pe2 |= RBTX4939_PE2_SIO3;
171b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto		else
172b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto			pe2 &= ~RBTX4939_PE2_SIO3;
173b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto		pe2 &= ~RBTX4939_PE2_SPI;
174b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	} else {
175b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto		pe2 |= RBTX4939_PE2_SPI;
176b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto		pe2 &= ~(RBTX4939_PE2_SIO3 | RBTX4939_PE2_SIO2 |
177b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto			 RBTX4939_PE2_SIO0);
178b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	}
179b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	if ((pcfg & TX4939_PCFG_I2SMODE_MASK) == TX4939_PCFG_I2SMODE_GPIO)
180b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto		pe2 |= RBTX4939_PE2_GPIO;
181b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	else
182b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto		pe2 &= ~RBTX4939_PE2_GPIO;
183b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	writeb(pe1, rbtx4939_pe1_addr);
184b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	writeb(pe2, rbtx4939_pe2_addr);
185b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	writeb(pe3, rbtx4939_pe3_addr);
186b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto}
187b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto
188b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto#define RBTX4939_MAX_7SEGLEDS	8
189b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto
190b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto#if defined(CONFIG_LEDS_CLASS) || defined(CONFIG_LEDS_CLASS_MODULE)
191b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemotostatic u8 led_val[RBTX4939_MAX_7SEGLEDS];
192b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemotostruct rbtx4939_led_data {
193b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	struct led_classdev cdev;
194b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	char name[32];
195b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	unsigned int num;
196b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto};
197b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto
198b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto/* Use "dot" in 7seg LEDs */
199b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemotostatic void rbtx4939_led_brightness_set(struct led_classdev *led_cdev,
200b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto					enum led_brightness value)
201b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto{
202b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	struct rbtx4939_led_data *led_dat =
203b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto		container_of(led_cdev, struct rbtx4939_led_data, cdev);
204b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	unsigned int num = led_dat->num;
205b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	unsigned long flags;
206b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto
207b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	local_irq_save(flags);
208b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	led_val[num] = (led_val[num] & 0x7f) | (value ? 0x80 : 0);
209b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	writeb(led_val[num], rbtx4939_7seg_addr(num / 4, num % 4));
210b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	local_irq_restore(flags);
211b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto}
212b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto
213b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemotostatic int __init rbtx4939_led_probe(struct platform_device *pdev)
214b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto{
215b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	struct rbtx4939_led_data *leds_data;
216b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	int i;
217b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	static char *default_triggers[] __initdata = {
218b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto		"heartbeat",
219b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto		"ide-disk",
220b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto		"nand-disk",
221b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	};
222b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto
223b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	leds_data = kzalloc(sizeof(*leds_data) * RBTX4939_MAX_7SEGLEDS,
224b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto			    GFP_KERNEL);
225b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	if (!leds_data)
226b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto		return -ENOMEM;
227b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	for (i = 0; i < RBTX4939_MAX_7SEGLEDS; i++) {
228b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto		int rc;
229b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto		struct rbtx4939_led_data *led_dat = &leds_data[i];
230b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto
231b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto		led_dat->num = i;
232b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto		led_dat->cdev.brightness_set = rbtx4939_led_brightness_set;
233b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto		sprintf(led_dat->name, "rbtx4939:amber:%u", i);
234b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto		led_dat->cdev.name = led_dat->name;
235b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto		if (i < ARRAY_SIZE(default_triggers))
236b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto			led_dat->cdev.default_trigger = default_triggers[i];
237b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto		rc = led_classdev_register(&pdev->dev, &led_dat->cdev);
238b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto		if (rc < 0)
239b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto			return rc;
240b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto		led_dat->cdev.brightness_set(&led_dat->cdev, 0);
241b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	}
242b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	return 0;
243b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto
244b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto}
245b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto
246b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemotostatic struct platform_driver rbtx4939_led_driver = {
247b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	.driver  = {
248b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto		.name = "rbtx4939-led",
249b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto		.owner = THIS_MODULE,
250b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	},
251b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto};
252b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto
253b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemotostatic void __init rbtx4939_led_setup(void)
254b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto{
255b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	platform_device_register_simple("rbtx4939-led", -1, NULL, 0);
256b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	platform_driver_probe(&rbtx4939_led_driver, rbtx4939_led_probe);
257b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto}
258b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto#else
259b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemotostatic inline void rbtx4939_led_setup(void)
260b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto{
261b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto}
262b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto#endif
263b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto
264bc89b2bdefa5f56133d0b19a220880d4ada62560Atsushi Nemotostatic void __rbtx4939_7segled_putc(unsigned int pos, unsigned char val)
265bc89b2bdefa5f56133d0b19a220880d4ada62560Atsushi Nemoto{
266bc89b2bdefa5f56133d0b19a220880d4ada62560Atsushi Nemoto#if defined(CONFIG_LEDS_CLASS) || defined(CONFIG_LEDS_CLASS_MODULE)
267bc89b2bdefa5f56133d0b19a220880d4ada62560Atsushi Nemoto	unsigned long flags;
268bc89b2bdefa5f56133d0b19a220880d4ada62560Atsushi Nemoto	local_irq_save(flags);
269bc89b2bdefa5f56133d0b19a220880d4ada62560Atsushi Nemoto	/* bit7: reserved for LED class */
270bc89b2bdefa5f56133d0b19a220880d4ada62560Atsushi Nemoto	led_val[pos] = (led_val[pos] & 0x80) | (val & 0x7f);
271bc89b2bdefa5f56133d0b19a220880d4ada62560Atsushi Nemoto	val = led_val[pos];
272bc89b2bdefa5f56133d0b19a220880d4ada62560Atsushi Nemoto	local_irq_restore(flags);
273bc89b2bdefa5f56133d0b19a220880d4ada62560Atsushi Nemoto#endif
274bc89b2bdefa5f56133d0b19a220880d4ada62560Atsushi Nemoto	writeb(val, rbtx4939_7seg_addr(pos / 4, pos % 4));
275bc89b2bdefa5f56133d0b19a220880d4ada62560Atsushi Nemoto}
276bc89b2bdefa5f56133d0b19a220880d4ada62560Atsushi Nemoto
277bc89b2bdefa5f56133d0b19a220880d4ada62560Atsushi Nemotostatic void rbtx4939_7segled_putc(unsigned int pos, unsigned char val)
278bc89b2bdefa5f56133d0b19a220880d4ada62560Atsushi Nemoto{
279bc89b2bdefa5f56133d0b19a220880d4ada62560Atsushi Nemoto	/* convert from map_to_seg7() notation */
280bc89b2bdefa5f56133d0b19a220880d4ada62560Atsushi Nemoto	val = (val & 0x88) |
281bc89b2bdefa5f56133d0b19a220880d4ada62560Atsushi Nemoto		((val & 0x40) >> 6) |
282bc89b2bdefa5f56133d0b19a220880d4ada62560Atsushi Nemoto		((val & 0x20) >> 4) |
283bc89b2bdefa5f56133d0b19a220880d4ada62560Atsushi Nemoto		((val & 0x10) >> 2) |
284bc89b2bdefa5f56133d0b19a220880d4ada62560Atsushi Nemoto		((val & 0x04) << 2) |
285bc89b2bdefa5f56133d0b19a220880d4ada62560Atsushi Nemoto		((val & 0x02) << 4) |
286bc89b2bdefa5f56133d0b19a220880d4ada62560Atsushi Nemoto		((val & 0x01) << 6);
287bc89b2bdefa5f56133d0b19a220880d4ada62560Atsushi Nemoto	__rbtx4939_7segled_putc(pos, val);
288bc89b2bdefa5f56133d0b19a220880d4ada62560Atsushi Nemoto}
289bc89b2bdefa5f56133d0b19a220880d4ada62560Atsushi Nemoto
290cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto#if defined(CONFIG_MTD_RBTX4939) || defined(CONFIG_MTD_RBTX4939_MODULE)
291cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto/* special mapping for boot rom */
292cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemotostatic unsigned long rbtx4939_flash_fixup_ofs(unsigned long ofs)
293cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto{
294cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto	u8 bdipsw = readb(rbtx4939_bdipsw_addr) & 0x0f;
295cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto	unsigned char shift;
296cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto
297cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto	if (bdipsw & 8) {
298cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto		/* BOOT Mode: USER ROM1 / USER ROM2 */
299cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto		shift = bdipsw & 3;
300cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto		/* rotate A[23:22] */
301cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto		return (ofs & ~0xc00000) | ((((ofs >> 22) + shift) & 3) << 22);
302cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto	}
303cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto#ifdef __BIG_ENDIAN
304cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto	if (bdipsw == 0)
305cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto		/* BOOT Mode: Monitor ROM */
306cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto		ofs ^= 0x400000;	/* swap A[22] */
307cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto#endif
308cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto	return ofs;
309cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto}
310cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto
311cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemotostatic map_word rbtx4939_flash_read16(struct map_info *map, unsigned long ofs)
312cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto{
313cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto	map_word r;
314cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto
315cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto	ofs = rbtx4939_flash_fixup_ofs(ofs);
316cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto	r.x[0] = __raw_readw(map->virt + ofs);
317cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto	return r;
318cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto}
319cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto
320cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemotostatic void rbtx4939_flash_write16(struct map_info *map, const map_word datum,
321cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto				   unsigned long ofs)
322cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto{
323cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto	ofs = rbtx4939_flash_fixup_ofs(ofs);
324cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto	__raw_writew(datum.x[0], map->virt + ofs);
325cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto	mb();	/* see inline_map_write() in mtd/map.h */
326cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto}
327cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto
328cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemotostatic void rbtx4939_flash_copy_from(struct map_info *map, void *to,
329cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto				     unsigned long from, ssize_t len)
330cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto{
331cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto	u8 bdipsw = readb(rbtx4939_bdipsw_addr) & 0x0f;
332cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto	unsigned char shift;
333cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto	ssize_t curlen;
334cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto
335cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto	from += (unsigned long)map->virt;
336cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto	if (bdipsw & 8) {
337cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto		/* BOOT Mode: USER ROM1 / USER ROM2 */
338cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto		shift = bdipsw & 3;
339cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto		while (len) {
340cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto			curlen = min_t(unsigned long, len,
341cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto				     0x400000 -	(from & (0x400000 - 1)));
342cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto			memcpy(to,
343cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto			       (void *)((from & ~0xc00000) |
344cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto					((((from >> 22) + shift) & 3) << 22)),
345cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto			       curlen);
346cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto			len -= curlen;
347cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto			from += curlen;
348cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto			to += curlen;
349cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto		}
350cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto		return;
351cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto	}
352cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto#ifdef __BIG_ENDIAN
353cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto	if (bdipsw == 0) {
354cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto		/* BOOT Mode: Monitor ROM */
355cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto		while (len) {
356cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto			curlen = min_t(unsigned long, len,
357cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto				     0x400000 - (from & (0x400000 - 1)));
358cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto			memcpy(to, (void *)(from ^ 0x400000), curlen);
359cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto			len -= curlen;
360cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto			from += curlen;
361cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto			to += curlen;
362cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto		}
363cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto		return;
364cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto	}
365cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto#endif
366cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto	memcpy(to, (void *)from, len);
367cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto}
368cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto
369cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemotostatic void rbtx4939_flash_map_init(struct map_info *map)
370cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto{
371cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto	map->read = rbtx4939_flash_read16;
372cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto	map->write = rbtx4939_flash_write16;
373cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto	map->copy_from = rbtx4939_flash_copy_from;
374cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto}
375cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto
376cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemotostatic void __init rbtx4939_mtd_init(void)
377cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto{
378cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto	static struct {
379cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto		struct platform_device dev;
380cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto		struct resource res;
381cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto		struct rbtx4939_flash_data data;
382cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto	} pdevs[4];
383cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto	int i;
384cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto	static char names[4][8];
385cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto	static struct mtd_partition parts[4];
386cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto	struct rbtx4939_flash_data *boot_pdata = &pdevs[0].data;
387cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto	u8 bdipsw = readb(rbtx4939_bdipsw_addr) & 0x0f;
388cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto
389cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto	if (bdipsw & 8) {
390cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto		/* BOOT Mode: USER ROM1 / USER ROM2 */
391cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto		boot_pdata->nr_parts = 4;
392cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto		for (i = 0; i < boot_pdata->nr_parts; i++) {
393cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto			sprintf(names[i], "img%d", 4 - i);
394cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto			parts[i].name = names[i];
395cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto			parts[i].size = 0x400000;
396cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto			parts[i].offset = MTDPART_OFS_NXTBLK;
397cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto		}
398cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto	} else if (bdipsw == 0) {
399cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto		/* BOOT Mode: Monitor ROM */
400cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto		boot_pdata->nr_parts = 2;
401cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto		strcpy(names[0], "big");
402cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto		strcpy(names[1], "little");
403cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto		for (i = 0; i < boot_pdata->nr_parts; i++) {
404cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto			parts[i].name = names[i];
405cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto			parts[i].size = 0x400000;
406cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto			parts[i].offset = MTDPART_OFS_NXTBLK;
407cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto		}
408cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto	} else {
409cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto		/* BOOT Mode: ROM Emulator */
410cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto		boot_pdata->nr_parts = 2;
411cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto		parts[0].name = "boot";
412cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto		parts[0].offset = 0xc00000;
413cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto		parts[0].size = 0x400000;
414cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto		parts[1].name = "user";
415cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto		parts[1].offset = 0;
416cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto		parts[1].size = 0xc00000;
417cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto	}
418cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto	boot_pdata->parts = parts;
419cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto	boot_pdata->map_init = rbtx4939_flash_map_init;
420cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto
421cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto	for (i = 0; i < ARRAY_SIZE(pdevs); i++) {
422cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto		struct resource *r = &pdevs[i].res;
423cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto		struct platform_device *dev = &pdevs[i].dev;
424cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto
425cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto		r->start = 0x1f000000 - i * 0x1000000;
426cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto		r->end = r->start + 0x1000000 - 1;
427cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto		r->flags = IORESOURCE_MEM;
428cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto		pdevs[i].data.width = 2;
429cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto		dev->num_resources = 1;
430cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto		dev->resource = r;
431cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto		dev->id = i;
432cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto		dev->name = "rbtx4939-flash";
433cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto		dev->dev.platform_data = &pdevs[i].data;
434cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto		platform_device_register(dev);
435cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto	}
436cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto}
437cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto#else
438cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemotostatic void __init rbtx4939_mtd_init(void)
439cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto{
440cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto}
441cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto#endif
442cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto
443b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemotostatic void __init rbtx4939_arch_init(void)
444b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto{
445b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	rbtx4939_pci_setup();
446b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto}
447b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto
448b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemotostatic void __init rbtx4939_device_init(void)
449b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto{
4501ba5a1767416cfa4fa37096e160e764c56e1460aAtsushi Nemoto	unsigned long smc_addr = RBTX4939_ETHER_ADDR - IO_BASE;
4511ba5a1767416cfa4fa37096e160e764c56e1460aAtsushi Nemoto	struct resource smc_res[] = {
4521ba5a1767416cfa4fa37096e160e764c56e1460aAtsushi Nemoto		{
4531ba5a1767416cfa4fa37096e160e764c56e1460aAtsushi Nemoto			.start	= smc_addr,
4541ba5a1767416cfa4fa37096e160e764c56e1460aAtsushi Nemoto			.end	= smc_addr + 0x10 - 1,
4551ba5a1767416cfa4fa37096e160e764c56e1460aAtsushi Nemoto			.flags	= IORESOURCE_MEM,
4561ba5a1767416cfa4fa37096e160e764c56e1460aAtsushi Nemoto		}, {
4571ba5a1767416cfa4fa37096e160e764c56e1460aAtsushi Nemoto			.start	= RBTX4939_IRQ_ETHER,
4581ba5a1767416cfa4fa37096e160e764c56e1460aAtsushi Nemoto			/* override default irq flag defined in smc91x.h */
4591ba5a1767416cfa4fa37096e160e764c56e1460aAtsushi Nemoto			.flags	= IORESOURCE_IRQ | IRQF_TRIGGER_LOW,
4601ba5a1767416cfa4fa37096e160e764c56e1460aAtsushi Nemoto		},
4611ba5a1767416cfa4fa37096e160e764c56e1460aAtsushi Nemoto	};
4621ba5a1767416cfa4fa37096e160e764c56e1460aAtsushi Nemoto	struct smc91x_platdata smc_pdata = {
4631ba5a1767416cfa4fa37096e160e764c56e1460aAtsushi Nemoto		.flags = SMC91X_USE_16BIT,
4641ba5a1767416cfa4fa37096e160e764c56e1460aAtsushi Nemoto	};
4651ba5a1767416cfa4fa37096e160e764c56e1460aAtsushi Nemoto	struct platform_device *pdev;
466b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto#if defined(CONFIG_TC35815) || defined(CONFIG_TC35815_MODULE)
467b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	int i, j;
468b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	unsigned char ethaddr[2][6];
4699cc4581528233e2a4eb8720621c1e2f613d7c38aAtsushi Nemoto	u8 bdipsw = readb(rbtx4939_bdipsw_addr) & 0x0f;
4709cc4581528233e2a4eb8720621c1e2f613d7c38aAtsushi Nemoto
471b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	for (i = 0; i < 2; i++) {
472b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto		unsigned long area = CKSEG1 + 0x1fff0000 + (i * 0x10);
4739cc4581528233e2a4eb8720621c1e2f613d7c38aAtsushi Nemoto		if (bdipsw == 0)
4749cc4581528233e2a4eb8720621c1e2f613d7c38aAtsushi Nemoto			memcpy(ethaddr[i], (void *)area, 6);
4759cc4581528233e2a4eb8720621c1e2f613d7c38aAtsushi Nemoto		else {
476b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto			u16 buf[3];
4779cc4581528233e2a4eb8720621c1e2f613d7c38aAtsushi Nemoto			if (bdipsw & 8)
4789cc4581528233e2a4eb8720621c1e2f613d7c38aAtsushi Nemoto				area -= 0x03000000;
4799cc4581528233e2a4eb8720621c1e2f613d7c38aAtsushi Nemoto			else
4809cc4581528233e2a4eb8720621c1e2f613d7c38aAtsushi Nemoto				area -= 0x01000000;
481b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto			for (j = 0; j < 3; j++)
482b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto				buf[j] = le16_to_cpup((u16 *)(area + j * 2));
483b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto			memcpy(ethaddr[i], buf, 6);
4849cc4581528233e2a4eb8720621c1e2f613d7c38aAtsushi Nemoto		}
485b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	}
486b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	tx4939_ethaddr_init(ethaddr[0], ethaddr[1]);
487b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto#endif
4881ba5a1767416cfa4fa37096e160e764c56e1460aAtsushi Nemoto	pdev = platform_device_alloc("smc91x", -1);
4891ba5a1767416cfa4fa37096e160e764c56e1460aAtsushi Nemoto	if (!pdev ||
4901ba5a1767416cfa4fa37096e160e764c56e1460aAtsushi Nemoto	    platform_device_add_resources(pdev, smc_res, ARRAY_SIZE(smc_res)) ||
4911ba5a1767416cfa4fa37096e160e764c56e1460aAtsushi Nemoto	    platform_device_add_data(pdev, &smc_pdata, sizeof(smc_pdata)) ||
4921ba5a1767416cfa4fa37096e160e764c56e1460aAtsushi Nemoto	    platform_device_add(pdev))
4931ba5a1767416cfa4fa37096e160e764c56e1460aAtsushi Nemoto		platform_device_put(pdev);
494cbf77c1bd9c79d1742976862d0b2bebaff1ea14dAtsushi Nemoto	rbtx4939_mtd_init();
495a591f5d35e89be90c04830d7de01c276af68aeb7Atsushi Nemoto	/* TC58DVM82A1FT: tDH=10ns, tWP=tRP=tREADID=35ns */
496a591f5d35e89be90c04830d7de01c276af68aeb7Atsushi Nemoto	tx4939_ndfmc_init(10, 35,
497a591f5d35e89be90c04830d7de01c276af68aeb7Atsushi Nemoto			  (1 << 1) | (1 << 2),
498a591f5d35e89be90c04830d7de01c276af68aeb7Atsushi Nemoto			  (1 << 2)); /* ch1:8bit, ch2:16bit */
499b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	rbtx4939_led_setup();
500b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	tx4939_wdt_init();
5014bacc68766b11c191ee1567f54103f109c002f4fAtsushi Nemoto	tx4939_ata_init();
50265655b5a94f6fc7e6450e3e07f2687c523c71c08Atsushi Nemoto	tx4939_rtc_init();
503f48c8c958a2d39f13dace880d15a6e711aafe577Atsushi Nemoto	tx4939_dmac_init(0, 2);
504742cd5867b2ef7ce865d7ab67574c4e3aa1fb155Atsushi Nemoto	tx4939_aclc_init();
505742cd5867b2ef7ce865d7ab67574c4e3aa1fb155Atsushi Nemoto	platform_device_register_simple("txx9aclc-generic", -1, NULL, 0);
506c3b28ae260d99a5364a31210a36a3246bd9647f7Atsushi Nemoto	tx4939_sramc_init();
507923e3819005e60449ed6c9c8a86fd8e5cd9e6d77Atsushi Nemoto	tx4939_rng_init();
508b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto}
509b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto
510b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemotostatic void __init rbtx4939_setup(void)
511b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto{
512bc89b2bdefa5f56133d0b19a220880d4ada62560Atsushi Nemoto	int i;
513bc89b2bdefa5f56133d0b19a220880d4ada62560Atsushi Nemoto
514b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	rbtx4939_ebusc_setup();
515b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	/* always enable ATA0 */
516b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	txx9_set64(&tx4939_ccfgptr->pcfg, TX4939_PCFG_ATA0MODE);
517b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	if (txx9_master_clock == 0)
518b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto		txx9_master_clock = 20000000;
519b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	tx4939_setup();
5203e6e92183118d26d856e8efb549987164d1b49b4Atsushi Nemoto	rbtx4939_update_ioc_pen();
5211ba5a1767416cfa4fa37096e160e764c56e1460aAtsushi Nemoto#ifdef HAVE_RBTX4939_IOSWAB
5221ba5a1767416cfa4fa37096e160e764c56e1460aAtsushi Nemoto	ioswabw = rbtx4939_ioswabw;
5231ba5a1767416cfa4fa37096e160e764c56e1460aAtsushi Nemoto	__mem_ioswabw = rbtx4939_mem_ioswabw;
5241ba5a1767416cfa4fa37096e160e764c56e1460aAtsushi Nemoto#endif
525b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto
526b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	_machine_restart = rbtx4939_machine_restart;
527b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto
528bc89b2bdefa5f56133d0b19a220880d4ada62560Atsushi Nemoto	txx9_7segled_init(RBTX4939_MAX_7SEGLEDS, rbtx4939_7segled_putc);
529bc89b2bdefa5f56133d0b19a220880d4ada62560Atsushi Nemoto	for (i = 0; i < RBTX4939_MAX_7SEGLEDS; i++)
530bc89b2bdefa5f56133d0b19a220880d4ada62560Atsushi Nemoto		txx9_7segled_putc(i, '-');
531b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	pr_info("RBTX4939 (Rev %02x) --- FPGA(Rev %02x) DIPSW:%02x,%02x\n",
532b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto		readb(rbtx4939_board_rev_addr), readb(rbtx4939_ioc_rev_addr),
533b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto		readb(rbtx4939_udipsw_addr), readb(rbtx4939_bdipsw_addr));
534b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto
535b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto#ifdef CONFIG_PCI
536b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	txx9_alloc_pci_controller(&txx9_primary_pcic, 0, 0, 0, 0);
537b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	txx9_board_pcibios_setup = tx4927_pcibios_setup;
538b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto#else
539b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	set_io_port_base(RBTX4939_ETHER_BASE);
540b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto#endif
541b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto
542b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	tx4939_sio_init(TX4939_SCLK0(txx9_master_clock), 0);
543b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto}
544b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto
545b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemotostruct txx9_board_vec rbtx4939_vec __initdata = {
546dfe99b9c4ef62fa6ea20fa06b6f5c9819039c52dAtsushi Nemoto	.system = "Toshiba RBTX4939",
547b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	.prom_init = rbtx4939_prom_init,
548b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	.mem_setup = rbtx4939_setup,
549b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	.irq_setup = rbtx4939_irq_setup,
550b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	.time_init = rbtx4939_time_init,
551b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	.device_init = rbtx4939_device_init,
552b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	.arch_init = rbtx4939_arch_init,
553b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto#ifdef CONFIG_PCI
554b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto	.pci_map_irq = tx4939_pci_map_irq,
555b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto#endif
556b27311e1cace4e296ace786c886d22f7a8ec78d6Atsushi Nemoto};
557