^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) }