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) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) //
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3) // Copyright (c) 2006-2009 Simtec Electronics
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4) //	http://armlinux.simtec.co.uk/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5) //	Ben Dooks <ben@simtec.co.uk>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) //
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) // S3C24XX CPU Frequency scaling - IO timing for S3C2410/S3C2440/S3C2442
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/cpufreq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/seq_file.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/io.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) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include "map.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include "regs-clock.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include <linux/soc/samsung/s3c-cpufreq-core.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #include "regs-mem-s3c24xx.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #define print_ns(x) ((x) / 10), ((x) % 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27)  * s3c2410_print_timing - print bank timing data for debug purposes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28)  * @pfx: The prefix to put on the output
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29)  * @timings: The timing inforamtion to print.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) static void s3c2410_print_timing(const char *pfx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 				 struct s3c_iotimings *timings)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 	struct s3c2410_iobank_timing *bt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 	int bank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 	for (bank = 0; bank < MAX_BANKS; bank++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 		bt = timings->bank[bank].io_2410;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 		if (!bt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 		printk(KERN_DEBUG "%s %d: Tacs=%d.%d, Tcos=%d.%d, Tacc=%d.%d, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 		       "Tcoh=%d.%d, Tcah=%d.%d\n", pfx, bank,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 		       print_ns(bt->tacs),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 		       print_ns(bt->tcos),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 		       print_ns(bt->tacc),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 		       print_ns(bt->tcoh),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 		       print_ns(bt->tcah));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53)  * bank_reg - convert bank number to pointer to the control register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54)  * @bank: The IO bank number.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) static inline void __iomem *bank_reg(unsigned int bank)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	return S3C2410_BANKCON0 + (bank << 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62)  * bank_is_io - test whether bank is used for IO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63)  * @bankcon: The bank control register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65)  * This is a simplistic test to see if any BANKCON[x] is not an IO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66)  * bank. It currently does not take into account whether BWSCON has
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67)  * an illegal width-setting in it, or if the pin connected to nCS[x]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68)  * is actually being handled as a chip-select.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) static inline int bank_is_io(unsigned long bankcon)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	return !(bankcon & S3C2410_BANKCON_SDRAM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76)  * to_div - convert cycle time to divisor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77)  * @cyc: The cycle time, in 10ths of nanoseconds.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78)  * @hclk_tns: The cycle time for HCLK, in 10ths of nanoseconds.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80)  * Convert the given cycle time into the divisor to use to obtain it from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81)  * HCLK.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) static inline unsigned int to_div(unsigned int cyc, unsigned int hclk_tns)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	if (cyc == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	return DIV_ROUND_UP(cyc, hclk_tns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92)  * calc_0124 - calculate divisor control for divisors that do /0, /1. /2 and /4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93)  * @cyc: The cycle time, in 10ths of nanoseconds.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94)  * @hclk_tns: The cycle time for HCLK, in 10ths of nanoseconds.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95)  * @v: Pointer to register to alter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96)  * @shift: The shift to get to the control bits.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98)  * Calculate the divisor, and turn it into the correct control bits to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99)  * set in the result, @v.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) static unsigned int calc_0124(unsigned int cyc, unsigned long hclk_tns,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 			      unsigned long *v, int shift)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 	unsigned int div = to_div(cyc, hclk_tns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	unsigned long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	s3c_freq_iodbg("%s: cyc=%d, hclk=%lu, shift=%d => div %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 		       __func__, cyc, hclk_tns, shift, div);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	switch (div) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 		val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 		val = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 		val = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 		val = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 	*v |= val << shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) static int calc_tacp(unsigned int cyc, unsigned long hclk, unsigned long *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 	/* Currently no support for Tacp calculations. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)  * calc_tacc - calculate divisor control for tacc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)  * @cyc: The cycle time, in 10ths of nanoseconds.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)  * @nwait_en: IS nWAIT enabled for this bank.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)  * @hclk_tns: The cycle time for HCLK, in 10ths of nanoseconds.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)  * @v: Pointer to register to alter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)  * Calculate the divisor control for tACC, taking into account whether
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)  * the bank has nWAIT enabled. The result is used to modify the value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)  * pointed to by @v.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) static int calc_tacc(unsigned int cyc, int nwait_en,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 		     unsigned long hclk_tns, unsigned long *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	unsigned int div = to_div(cyc, hclk_tns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	unsigned long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	s3c_freq_iodbg("%s: cyc=%u, nwait=%d, hclk=%lu => div=%u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 		       __func__, cyc, nwait_en, hclk_tns, div);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	/* if nWait enabled on an bank, Tacc must be at-least 4 cycles. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 	if (nwait_en && div < 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 		div = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 	switch (div) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 		val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 	case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 		val = div - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 	case 5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	case 6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 		val = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 	case 7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	case 8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 		val = 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 	case 9:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 	case 10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 		val = 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 	case 11:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 	case 12:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 	case 13:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 	case 14:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 		val = 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 	*v |= val << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)  * s3c2410_calc_bank - calculate bank timing information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)  * @cfg: The configuration we need to calculate for.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)  * @bt: The bank timing information.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)  * Given the cycle timine for a bank @bt, calculate the new BANKCON
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)  * setting for the @cfg timing. This updates the timing information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)  * ready for the cpu frequency change.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) static int s3c2410_calc_bank(struct s3c_cpufreq_config *cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 			     struct s3c2410_iobank_timing *bt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 	unsigned long hclk = cfg->freq.hclk_tns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 	unsigned long res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 	res  = bt->bankcon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 	res &= (S3C2410_BANKCON_SDRAM | S3C2410_BANKCON_PMC16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 	/* tacp: 2,3,4,5 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 	/* tcah: 0,1,2,4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 	/* tcoh: 0,1,2,4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 	/* tacc: 1,2,3,4,6,7,10,14 (>4 for nwait) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 	/* tcos: 0,1,2,4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 	/* tacs: 0,1,2,4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 	ret  = calc_0124(bt->tacs, hclk, &res, S3C2410_BANKCON_Tacs_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 	ret |= calc_0124(bt->tcos, hclk, &res, S3C2410_BANKCON_Tcos_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 	ret |= calc_0124(bt->tcah, hclk, &res, S3C2410_BANKCON_Tcah_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 	ret |= calc_0124(bt->tcoh, hclk, &res, S3C2410_BANKCON_Tcoh_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 	ret |= calc_tacp(bt->tacp, hclk, &res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 	ret |= calc_tacc(bt->tacc, bt->nwait_en, hclk, &res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 	bt->bankcon = res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) static const unsigned int tacc_tab[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 	[0]	= 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 	[1]	= 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 	[2]	= 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 	[3]	= 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 	[4]	= 6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 	[5]	= 9,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 	[6]	= 10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 	[7]	= 14,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) };
^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)  * get_tacc - turn tACC value into cycle time
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)  * @hclk_tns: The cycle time for HCLK, in 10ths of nanoseconds.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)  * @val: The bank timing register value, shifed down.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) static unsigned int get_tacc(unsigned long hclk_tns,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 			     unsigned long val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 	val &= 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 	return hclk_tns * tacc_tab[val];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)  * get_0124 - turn 0/1/2/4 divider into cycle time
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)  * @hclk_tns: The cycle time for HCLK, in 10ths of nanoseconds.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)  * @val: The bank timing register value, shifed down.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) static unsigned int get_0124(unsigned long hclk_tns,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 			     unsigned long val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 	val &= 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 	return hclk_tns * ((val == 3) ? 4 : val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)  * s3c2410_iotiming_getbank - turn BANKCON into cycle time information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)  * @cfg: The frequency configuration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)  * @bt: The bank timing to fill in (uses cached BANKCON)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)  * Given the BANKCON setting in @bt and the current frequency settings
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)  * in @cfg, update the cycle timing information.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) static void s3c2410_iotiming_getbank(struct s3c_cpufreq_config *cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 				     struct s3c2410_iobank_timing *bt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 	unsigned long bankcon = bt->bankcon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 	unsigned long hclk = cfg->freq.hclk_tns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 	bt->tcah = get_0124(hclk, bankcon >> S3C2410_BANKCON_Tcah_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 	bt->tcoh = get_0124(hclk, bankcon >> S3C2410_BANKCON_Tcoh_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 	bt->tcos = get_0124(hclk, bankcon >> S3C2410_BANKCON_Tcos_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 	bt->tacs = get_0124(hclk, bankcon >> S3C2410_BANKCON_Tacs_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 	bt->tacc = get_tacc(hclk, bankcon >> S3C2410_BANKCON_Tacc_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)  * s3c2410_iotiming_debugfs - debugfs show io bank timing information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)  * @seq: The seq_file to write output to using seq_printf().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)  * @cfg: The current configuration.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)  * @iob: The IO bank information to decode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) void s3c2410_iotiming_debugfs(struct seq_file *seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 			      struct s3c_cpufreq_config *cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 			      union s3c_iobank *iob)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 	struct s3c2410_iobank_timing *bt = iob->io_2410;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 	unsigned long bankcon = bt->bankcon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 	unsigned long hclk = cfg->freq.hclk_tns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 	unsigned int tacs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 	unsigned int tcos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 	unsigned int tacc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 	unsigned int tcoh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 	unsigned int tcah;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 	seq_printf(seq, "BANKCON=0x%08lx\n", bankcon);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 	tcah = get_0124(hclk, bankcon >> S3C2410_BANKCON_Tcah_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 	tcoh = get_0124(hclk, bankcon >> S3C2410_BANKCON_Tcoh_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 	tcos = get_0124(hclk, bankcon >> S3C2410_BANKCON_Tcos_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 	tacs = get_0124(hclk, bankcon >> S3C2410_BANKCON_Tacs_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 	tacc = get_tacc(hclk, bankcon >> S3C2410_BANKCON_Tacc_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 	seq_printf(seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 		   "\tRead: Tacs=%d.%d, Tcos=%d.%d, Tacc=%d.%d, Tcoh=%d.%d, Tcah=%d.%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 		   print_ns(bt->tacs),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 		   print_ns(bt->tcos),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 		   print_ns(bt->tacc),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 		   print_ns(bt->tcoh),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 		   print_ns(bt->tcah));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 	seq_printf(seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 		   "\t Set: Tacs=%d.%d, Tcos=%d.%d, Tacc=%d.%d, Tcoh=%d.%d, Tcah=%d.%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 		   print_ns(tacs),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 		   print_ns(tcos),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 		   print_ns(tacc),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 		   print_ns(tcoh),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 		   print_ns(tcah));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)  * s3c2410_iotiming_calc - Calculate bank timing for frequency change.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)  * @cfg: The frequency configuration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)  * @iot: The IO timing information to fill out.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)  * Calculate the new values for the banks in @iot based on the new
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)  * frequency information in @cfg. This is then used by s3c2410_iotiming_set()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)  * to update the timing when necessary.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) int s3c2410_iotiming_calc(struct s3c_cpufreq_config *cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 			  struct s3c_iotimings *iot)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 	struct s3c2410_iobank_timing *bt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 	unsigned long bankcon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 	int bank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 	for (bank = 0; bank < MAX_BANKS; bank++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 		bankcon = __raw_readl(bank_reg(bank));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 		bt = iot->bank[bank].io_2410;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 		if (!bt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 		bt->bankcon = bankcon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 		ret = s3c2410_calc_bank(cfg, bt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 		if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 			printk(KERN_ERR "%s: cannot calculate bank %d io\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 			       __func__, bank);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 			goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 		s3c_freq_iodbg("%s: bank %d: con=%08lx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 			       __func__, bank, bt->bankcon);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)  err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)  * s3c2410_iotiming_set - set the IO timings from the given setup.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392)  * @cfg: The frequency configuration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)  * @iot: The IO timing information to use.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)  * Set all the currently used IO bank timing information generated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396)  * by s3c2410_iotiming_calc() once the core has validated that all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)  * the new values are within permitted bounds.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) void s3c2410_iotiming_set(struct s3c_cpufreq_config *cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 			  struct s3c_iotimings *iot)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 	struct s3c2410_iobank_timing *bt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 	int bank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 	/* set the io timings from the specifier */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 	for (bank = 0; bank < MAX_BANKS; bank++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 		bt = iot->bank[bank].io_2410;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 		if (!bt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 		__raw_writel(bt->bankcon, bank_reg(bank));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)  * s3c2410_iotiming_get - Get the timing information from current registers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418)  * @cfg: The frequency configuration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419)  * @timings: The IO timing information to fill out.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)  * Calculate the @timings timing information from the current frequency
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)  * information in @cfg, and the new frequency configuration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)  * through all the IO banks, reading the state and then updating @iot
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424)  * as necessary.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)  * This is used at the moment on initialisation to get the current
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)  * configuration so that boards do not have to carry their own setup
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428)  * if the timings are correct on initialisation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) int s3c2410_iotiming_get(struct s3c_cpufreq_config *cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 			 struct s3c_iotimings *timings)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 	struct s3c2410_iobank_timing *bt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 	unsigned long bankcon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 	unsigned long bwscon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 	int bank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 	bwscon = __raw_readl(S3C2410_BWSCON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 	/* look through all banks to see what is currently set. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 	for (bank = 0; bank < MAX_BANKS; bank++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 		bankcon = __raw_readl(bank_reg(bank));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 		if (!bank_is_io(bankcon))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 		s3c_freq_iodbg("%s: bank %d: con %08lx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 			       __func__, bank, bankcon);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 		bt = kzalloc(sizeof(*bt), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 		if (!bt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 			return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 		/* find out in nWait is enabled for bank. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 		if (bank != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 			unsigned long tmp  = S3C2410_BWSCON_GET(bwscon, bank);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 			if (tmp & S3C2410_BWSCON_WS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 				bt->nwait_en = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 		timings->bank[bank].io_2410 = bt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 		bt->bankcon = bankcon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 		s3c2410_iotiming_getbank(cfg, bt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 	s3c2410_print_timing("get", timings);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) }