Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^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) };