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