From b0e66522f4d86713b0450255210e26c4f11ee86b Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Thu, 30 Jul 2009 23:23:20 +0100 Subject: ARM: S3C24XX: Add BWSCON per-bank information. Add definitions and an accessor macro to deal with reading bus information from S3C2410_BWSCON for any given numbered bank. Signed-off-by: Ben Dooks Signed-off-by: Ben Dooks --- arch/arm/mach-s3c2410/include/mach/regs-mem.h | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'arch/arm/mach-s3c2410') diff --git a/arch/arm/mach-s3c2410/include/mach/regs-mem.h b/arch/arm/mach-s3c2410/include/mach/regs-mem.h index 57759804e2f..7f7c5294796 100644 --- a/arch/arm/mach-s3c2410/include/mach/regs-mem.h +++ b/arch/arm/mach-s3c2410/include/mach/regs-mem.h @@ -73,6 +73,16 @@ #define S3C2410_BWSCON_WS7 (1<<30) #define S3C2410_BWSCON_ST7 (1<<31) +/* accesor functions for getting BANK(n) configuration. (n != 0) */ + +#define S3C2410_BWSCON_GET(_bwscon, _bank) (((_bwscon) >> ((_bank) * 4)) & 0xf) + +#define S3C2410_BWSCON_DW8 (0) +#define S3C2410_BWSCON_DW16 (1) +#define S3C2410_BWSCON_DW32 (2) +#define S3C2410_BWSCON_WS (1 << 2) +#define S3C2410_BWSCON_ST (1 << 3) + /* memory set (rom, ram) */ #define S3C2410_BANKCON0 S3C2410_MEMREG(0x0004) #define S3C2410_BANKCON1 S3C2410_MEMREG(0x0008) -- cgit v1.2.3 From a24c091db988551e2c350cfde9eb80ab6e791ffb Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Thu, 30 Jul 2009 23:23:27 +0100 Subject: ARM: S3C2410: CPUFREQ: Add core support. Add core support for frequency scaling on the S3C2410 SoC. Signed-off-by: Ben Dooks Signed-off-by: Ben Dooks --- arch/arm/mach-s3c2410/Kconfig | 11 ++ arch/arm/mach-s3c2410/Makefile | 1 + arch/arm/mach-s3c2410/cpu-freq.c | 157 ++++++++++++++++++++++++++ arch/arm/plat-s3c24xx/Kconfig | 7 ++ arch/arm/plat-s3c24xx/Makefile | 1 + arch/arm/plat-s3c24xx/s3c2410-cpufreq-utils.c | 64 +++++++++++ 6 files changed, 241 insertions(+) create mode 100644 arch/arm/mach-s3c2410/cpu-freq.c create mode 100644 arch/arm/plat-s3c24xx/s3c2410-cpufreq-utils.c (limited to 'arch/arm/mach-s3c2410') diff --git a/arch/arm/mach-s3c2410/Kconfig b/arch/arm/mach-s3c2410/Kconfig index 41bb65d5b91..a7f70e18ccb 100644 --- a/arch/arm/mach-s3c2410/Kconfig +++ b/arch/arm/mach-s3c2410/Kconfig @@ -12,6 +12,7 @@ config CPU_S3C2410 select S3C2410_GPIO select CPU_LLSERIAL_S3C2410 select S3C2410_PM if PM + select S3C2410_CPUFREQ if CPU_FREQ_S3C24XX help Support for S3C2410 and S3C2410A family from the S3C24XX line of Samsung Mobile CPUs. @@ -45,6 +46,15 @@ config MACH_BAST_IDE Internal node for machines with an BAST style IDE interface +# cpu frequency scaling support + +config S3C2410_CPUFREQ + bool + depends on CPU_FREQ_S3C24XX && CPU_S3C2410 + select S3C2410_CPUFREQ_UTILS + help + CPU Frequency scaling support for S3C2410 + menu "S3C2410 Machines" config ARCH_SMDK2410 @@ -79,6 +89,7 @@ config MACH_N30 config ARCH_BAST bool "Simtec Electronics BAST (EB2410ITX)" select CPU_S3C2410 + select S3C2410_IOTIMING if S3C2410_CPUFREQ select PM_SIMTEC if PM select SIMTEC_NOR select MACH_BAST_IDE diff --git a/arch/arm/mach-s3c2410/Makefile b/arch/arm/mach-s3c2410/Makefile index fca02f82711..cc25eb0eb2c 100644 --- a/arch/arm/mach-s3c2410/Makefile +++ b/arch/arm/mach-s3c2410/Makefile @@ -15,6 +15,7 @@ obj-$(CONFIG_CPU_S3C2410_DMA) += dma.o obj-$(CONFIG_CPU_S3C2410_DMA) += dma.o obj-$(CONFIG_S3C2410_PM) += pm.o sleep.o obj-$(CONFIG_S3C2410_GPIO) += gpio.o +obj-$(CONFIG_S3C2410_CPUFREQ) += cpu-freq.o # Machine support diff --git a/arch/arm/mach-s3c2410/cpu-freq.c b/arch/arm/mach-s3c2410/cpu-freq.c new file mode 100644 index 00000000000..f2cbdbab0df --- /dev/null +++ b/arch/arm/mach-s3c2410/cpu-freq.c @@ -0,0 +1,157 @@ +/* linux/arch/arm/mach-s3c2410/cpu-freq.c + * + * Copyright (c) 2006,2008 Simtec Electronics + * http://armlinux.simtec.co.uk/ + * Ben Dooks + * + * S3C2410 CPU Frequency scaling + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include +#include +#include + +/* Note, 2410A has an extra mode for 1:4:4 ratio, bit 2 of CLKDIV */ + +static void s3c2410_cpufreq_setdivs(struct s3c_cpufreq_config *cfg) +{ + u32 clkdiv = 0; + + if (cfg->divs.h_divisor == 2) + clkdiv |= S3C2410_CLKDIVN_HDIVN; + + if (cfg->divs.p_divisor != cfg->divs.h_divisor) + clkdiv |= S3C2410_CLKDIVN_PDIVN; + + __raw_writel(clkdiv, S3C2410_CLKDIVN); +} + +static int s3c2410_cpufreq_calcdivs(struct s3c_cpufreq_config *cfg) +{ + unsigned long hclk, fclk, pclk; + unsigned int hdiv, pdiv; + unsigned long hclk_max; + + fclk = cfg->freq.fclk; + hclk_max = cfg->max.hclk; + + cfg->freq.armclk = fclk; + + s3c_freq_dbg("%s: fclk is %lu, max hclk %lu\n", + __func__, fclk, hclk_max); + + hdiv = (fclk > cfg->max.hclk) ? 2 : 1; + hclk = fclk / hdiv; + + if (hclk > cfg->max.hclk) { + s3c_freq_dbg("%s: hclk too big\n", __func__); + return -EINVAL; + } + + pdiv = (hclk > cfg->max.pclk) ? 2 : 1; + pclk = hclk / pdiv; + + if (pclk > cfg->max.pclk) { + s3c_freq_dbg("%s: pclk too big\n", __func__); + return -EINVAL; + } + + pdiv *= hdiv; + + /* record the result */ + cfg->divs.p_divisor = pdiv; + cfg->divs.h_divisor = hdiv; + + return 0 ; +} + +static struct s3c_cpufreq_info s3c2410_cpufreq_info = { + .max = { + .fclk = 200000000, + .hclk = 100000000, + .pclk = 50000000, + }, + + /* transition latency is about 5ms worst-case, so + * set 10ms to be sure */ + .latency = 10000000, + + .locktime_m = 150, + .locktime_u = 150, + .locktime_bits = 12, + + .need_pll = 1, + + .name = "s3c2410", + .calc_iotiming = s3c2410_iotiming_calc, + .set_iotiming = s3c2410_iotiming_set, + .get_iotiming = s3c2410_iotiming_get, + .resume_clocks = s3c2410_setup_clocks, + + .set_fvco = s3c2410_set_fvco, + .set_refresh = s3c2410_cpufreq_setrefresh, + .set_divs = s3c2410_cpufreq_setdivs, + .calc_divs = s3c2410_cpufreq_calcdivs, +}; + +static int s3c2410_cpufreq_add(struct sys_device *sysdev) +{ + return s3c_cpufreq_register(&s3c2410_cpufreq_info); +} + +static struct sysdev_driver s3c2410_cpufreq_driver = { + .add = s3c2410_cpufreq_add, +}; + +static int __init s3c2410_cpufreq_init(void) +{ + return sysdev_driver_register(&s3c2410_sysclass, + &s3c2410_cpufreq_driver); +} + +arch_initcall(s3c2410_cpufreq_init); + +static int s3c2410a_cpufreq_add(struct sys_device *sysdev) +{ + /* alter the maximum freq settings for S3C2410A. If a board knows + * it only has a maximum of 200, then it should register its own + * limits. */ + + s3c2410_cpufreq_info.max.fclk = 266000000; + s3c2410_cpufreq_info.max.hclk = 133000000; + s3c2410_cpufreq_info.max.pclk = 66500000; + s3c2410_cpufreq_info.name = "s3c2410a"; + + return s3c2410_cpufreq_add(sysdev); +} + +static struct sysdev_driver s3c2410a_cpufreq_driver = { + .add = s3c2410a_cpufreq_add, +}; + +static int __init s3c2410a_cpufreq_init(void) +{ + return sysdev_driver_register(&s3c2410a_sysclass, + &s3c2410a_cpufreq_driver); +} + +arch_initcall(s3c2410a_cpufreq_init); diff --git a/arch/arm/plat-s3c24xx/Kconfig b/arch/arm/plat-s3c24xx/Kconfig index d82d30c2f05..a547c79ed6c 100644 --- a/arch/arm/plat-s3c24xx/Kconfig +++ b/arch/arm/plat-s3c24xx/Kconfig @@ -116,6 +116,13 @@ config S3C2410_IOTIMING Internal node to select io timing code that is common to the s3c2410 and s3c2440/s3c2442 cpu frequency support. +config S3C2410_CPUFREQ_UTILS + bool + depends on CPU_FREQ_S3C24XX + help + Internal node to select timing code that is common to the s3c2410 + and s3c2440/s3c244 cpu frequency support. + config MACH_SMDK bool help diff --git a/arch/arm/plat-s3c24xx/Makefile b/arch/arm/plat-s3c24xx/Makefile index 6f9afd13ab4..b28fe9cb0e5 100644 --- a/arch/arm/plat-s3c24xx/Makefile +++ b/arch/arm/plat-s3c24xx/Makefile @@ -36,6 +36,7 @@ obj-$(CONFIG_S3C2410_CLOCK) += s3c2410-clock.o obj-$(CONFIG_S3C2410_DMA) += dma.o obj-$(CONFIG_S3C24XX_ADC) += adc.o obj-$(CONFIG_S3C2410_IOTIMING) += s3c2410-iotiming.o +obj-$(CONFIG_S3C2410_CPUFREQ_UTILS) += s3c2410-cpufreq-utils.o # device specific setup and/or initialisation obj-$(CONFIG_ARCH_S3C2410) += setup-i2c.o diff --git a/arch/arm/plat-s3c24xx/s3c2410-cpufreq-utils.c b/arch/arm/plat-s3c24xx/s3c2410-cpufreq-utils.c new file mode 100644 index 00000000000..43ea80190d8 --- /dev/null +++ b/arch/arm/plat-s3c24xx/s3c2410-cpufreq-utils.c @@ -0,0 +1,64 @@ +/* linux/arch/arm/plat-s3c24xx/s3c2410-cpufreq-utils.c + * + * Copyright (c) 2009 Simtec Electronics + * http://armlinux.simtec.co.uk/ + * Ben Dooks + * + * S3C24XX CPU Frequency scaling - utils for S3C2410/S3C2440/S3C2442 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#include +#include +#include +#include + +#include +#include +#include + +#include + +/** + * s3c2410_cpufreq_setrefresh - set SDRAM refresh value + * @cfg: The frequency configuration + * + * Set the SDRAM refresh value appropriately for the configured + * frequency. + */ +void s3c2410_cpufreq_setrefresh(struct s3c_cpufreq_config *cfg) +{ + struct s3c_cpufreq_board *board = cfg->board; + unsigned long refresh; + unsigned long refval; + + /* Reduce both the refresh time (in ns) and the frequency (in MHz) + * down to ensure that we do not overflow 32 bit numbers. + * + * This should work for HCLK up to 133MHz and refresh period up + * to 30usec. + */ + + refresh = (cfg->freq.hclk / 100) * (board->refresh / 10); + refresh = DIV_ROUND_UP(refresh, (1000 * 1000)); /* apply scale */ + refresh = (1 << 11) + 1 - refresh; + + s3c_freq_dbg("%s: refresh value %lu\n", __func__, refresh); + + refval = __raw_readl(S3C2410_REFRESH); + refval &= ~((1 << 12) - 1); + refval |= refresh; + __raw_writel(refval, S3C2410_REFRESH); +} + +/** + * s3c2410_set_fvco - set the PLL value + * @cfg: The frequency configuration + */ +void s3c2410_set_fvco(struct s3c_cpufreq_config *cfg) +{ + __raw_writel(cfg->pll.index, S3C2410_MPLLCON); +} -- cgit v1.2.3 From 438a09e1eb01c3f0d4cddde97ed9caae652f910b Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Thu, 30 Jul 2009 23:23:28 +0100 Subject: ARM: S3C2410: CPUFREQ: Add PLL table Add PLL table for the S3C2410 SoC. Signed-off-by: Ben Dooks Signed-off-by: Ben Dooks --- arch/arm/mach-s3c2410/Kconfig | 7 ++++ arch/arm/mach-s3c2410/Makefile | 1 + arch/arm/mach-s3c2410/pll.c | 95 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 103 insertions(+) create mode 100644 arch/arm/mach-s3c2410/pll.c (limited to 'arch/arm/mach-s3c2410') diff --git a/arch/arm/mach-s3c2410/Kconfig b/arch/arm/mach-s3c2410/Kconfig index a7f70e18ccb..d8c023d4df3 100644 --- a/arch/arm/mach-s3c2410/Kconfig +++ b/arch/arm/mach-s3c2410/Kconfig @@ -55,6 +55,13 @@ config S3C2410_CPUFREQ help CPU Frequency scaling support for S3C2410 +config S3C2410_PLLTABLE + bool + depends on S3C2410_CPUFREQ && CPU_FREQ_S3C24XX_PLL + default y + help + Select the PLL table for the S3C2410 + menu "S3C2410 Machines" config ARCH_SMDK2410 diff --git a/arch/arm/mach-s3c2410/Makefile b/arch/arm/mach-s3c2410/Makefile index cc25eb0eb2c..2ab5ba4b266 100644 --- a/arch/arm/mach-s3c2410/Makefile +++ b/arch/arm/mach-s3c2410/Makefile @@ -16,6 +16,7 @@ obj-$(CONFIG_CPU_S3C2410_DMA) += dma.o obj-$(CONFIG_S3C2410_PM) += pm.o sleep.o obj-$(CONFIG_S3C2410_GPIO) += gpio.o obj-$(CONFIG_S3C2410_CPUFREQ) += cpu-freq.o +obj-$(CONFIG_S3C2410_PLLTABLE) += pll.o # Machine support diff --git a/arch/arm/mach-s3c2410/pll.c b/arch/arm/mach-s3c2410/pll.c new file mode 100644 index 00000000000..f178c2fd9d8 --- /dev/null +++ b/arch/arm/mach-s3c2410/pll.c @@ -0,0 +1,95 @@ +/* arch/arm/mach-s3c2410/pll.c + * + * Copyright (c) 2006,2007 Simtec Electronics + * http://armlinux.simtec.co.uk/ + * Ben Dooks + * Vincent Sanders + * + * S3C2410 CPU PLL tables + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +static struct cpufreq_frequency_table pll_vals_12MHz[] = { + { .frequency = 34000000, .index = PLLVAL(82, 2, 3), }, + { .frequency = 45000000, .index = PLLVAL(82, 1, 3), }, + { .frequency = 51000000, .index = PLLVAL(161, 3, 3), }, + { .frequency = 48000000, .index = PLLVAL(120, 2, 3), }, + { .frequency = 56000000, .index = PLLVAL(142, 2, 3), }, + { .frequency = 68000000, .index = PLLVAL(82, 2, 2), }, + { .frequency = 79000000, .index = PLLVAL(71, 1, 2), }, + { .frequency = 85000000, .index = PLLVAL(105, 2, 2), }, + { .frequency = 90000000, .index = PLLVAL(112, 2, 2), }, + { .frequency = 101000000, .index = PLLVAL(127, 2, 2), }, + { .frequency = 113000000, .index = PLLVAL(105, 1, 2), }, + { .frequency = 118000000, .index = PLLVAL(150, 2, 2), }, + { .frequency = 124000000, .index = PLLVAL(116, 1, 2), }, + { .frequency = 135000000, .index = PLLVAL(82, 2, 1), }, + { .frequency = 147000000, .index = PLLVAL(90, 2, 1), }, + { .frequency = 152000000, .index = PLLVAL(68, 1, 1), }, + { .frequency = 158000000, .index = PLLVAL(71, 1, 1), }, + { .frequency = 170000000, .index = PLLVAL(77, 1, 1), }, + { .frequency = 180000000, .index = PLLVAL(82, 1, 1), }, + { .frequency = 186000000, .index = PLLVAL(85, 1, 1), }, + { .frequency = 192000000, .index = PLLVAL(88, 1, 1), }, + { .frequency = 203000000, .index = PLLVAL(161, 3, 1), }, + + /* 2410A extras */ + + { .frequency = 210000000, .index = PLLVAL(132, 2, 1), }, + { .frequency = 226000000, .index = PLLVAL(105, 1, 1), }, + { .frequency = 266000000, .index = PLLVAL(125, 1, 1), }, + { .frequency = 268000000, .index = PLLVAL(126, 1, 1), }, + { .frequency = 270000000, .index = PLLVAL(127, 1, 1), }, +}; + +static int s3c2410_plls_add(struct sys_device *dev) +{ + return s3c_plltab_register(pll_vals_12MHz, ARRAY_SIZE(pll_vals_12MHz)); +} + +static struct sysdev_driver s3c2410_plls_drv = { + .add = s3c2410_plls_add, +}; + +static int __init s3c2410_pll_init(void) +{ + return sysdev_driver_register(&s3c2410_sysclass, &s3c2410_plls_drv); + +} + +arch_initcall(s3c2410_pll_init); + +static struct sysdev_driver s3c2410a_plls_drv = { + .add = s3c2410_plls_add, +}; + +static int __init s3c2410a_pll_init(void) +{ + return sysdev_driver_register(&s3c2410a_sysclass, &s3c2410a_plls_drv); +} + +arch_initcall(s3c2410a_pll_init); -- cgit v1.2.3 From 25400036867fa7a135fca17810555400d176acaa Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Thu, 30 Jul 2009 23:23:36 +0100 Subject: ARM: S3C2412: Update memory register mapping and definitions Update the mapping of the memory controler registers and add the missing definitions of the register block for the SSMC. The register contents definitions can be found in the pl093 header. Signed-off-by: Ben Dooks Signed-off-by: Ben Dooks --- arch/arm/mach-s3c2410/include/mach/map.h | 7 +++++++ .../mach-s3c2410/include/mach/regs-s3c2412-mem.h | 23 ++++++++++++++++++++-- arch/arm/mach-s3c2412/s3c2412.c | 12 +++++++++++ 3 files changed, 40 insertions(+), 2 deletions(-) (limited to 'arch/arm/mach-s3c2410') diff --git a/arch/arm/mach-s3c2410/include/mach/map.h b/arch/arm/mach-s3c2410/include/mach/map.h index e99b212cb1c..11cce097550 100644 --- a/arch/arm/mach-s3c2410/include/mach/map.h +++ b/arch/arm/mach-s3c2410/include/mach/map.h @@ -67,6 +67,13 @@ #define S3C2443_PA_HSMMC (0x4A800000) #define S3C2443_SZ_HSMMC (256) +/* S3C2412 memory and IO controls */ +#define S3C2412_PA_SSMC (0x4F000000) +#define S3C2412_VA_SSMC S3C_ADDR_CPU(0x00000000) + +#define S3C2412_PA_EBI (0x48800000) +#define S3C2412_VA_EBI S3C_ADDR_CPU(0x00010000) + /* physical addresses of all the chip-select areas */ #define S3C2410_CS0 (0x00000000) diff --git a/arch/arm/mach-s3c2410/include/mach/regs-s3c2412-mem.h b/arch/arm/mach-s3c2410/include/mach/regs-s3c2412-mem.h index a4bf2712317..fb635251509 100644 --- a/arch/arm/mach-s3c2410/include/mach/regs-s3c2412-mem.h +++ b/arch/arm/mach-s3c2410/include/mach/regs-s3c2412-mem.h @@ -14,9 +14,11 @@ #ifndef __ASM_ARM_REGS_S3C2412_MEM #define __ASM_ARM_REGS_S3C2412_MEM -#ifndef S3C2412_MEMREG #define S3C2412_MEMREG(x) (S3C24XX_VA_MEMCTRL + (x)) -#endif +#define S3C2412_EBIREG(x) (S3C2412_VA_EBI + (x)) + +#define S3C2412_SSMCREG(x) (S3C2412_VA_SSMC + (x)) +#define S3C2412_SSMC(x, o) (S3C2412_SSMCREG((x * 0x20) + (o))) #define S3C2412_BANKCFG S3C2412_MEMREG(0x00) #define S3C2412_BANKCON1 S3C2412_MEMREG(0x04) @@ -26,4 +28,21 @@ #define S3C2412_REFRESH S3C2412_MEMREG(0x10) #define S3C2412_TIMEOUT S3C2412_MEMREG(0x14) +/* EBI control registers */ + +#define S3C2412_EBI_PR S3C2412_EBIREG(0x00) +#define S3C2412_EBI_BANKCFG S3C2412_EBIREG(0x04) + +/* SSMC control registers */ + +#define S3C2412_SSMC_BANK(x) S3C2412_SSMC(x, 0x00) +#define S3C2412_SMIDCYR(x) S3C2412_SSMC(x, 0x00) +#define S3C2412_SMBWSTRD(x) S3C2412_SSMC(x, 0x04) +#define S3C2412_SMBWSTWRR(x) S3C2412_SSMC(x, 0x08) +#define S3C2412_SMBWSTOENR(x) S3C2412_SSMC(x, 0x0C) +#define S3C2412_SMBWSTWENR(x) S3C2412_SSMC(x, 0x10) +#define S3C2412_SMBCR(x) S3C2412_SSMC(x, 0x14) +#define S3C2412_SMBSR(x) S3C2412_SSMC(x, 0x18) +#define S3C2412_SMBWSTBRDR(x) S3C2412_SSMC(x, 0x1C) + #endif /* __ASM_ARM_REGS_S3C2412_MEM */ diff --git a/arch/arm/mach-s3c2412/s3c2412.c b/arch/arm/mach-s3c2412/s3c2412.c index 5b5aba69ec3..bef39f77729 100644 --- a/arch/arm/mach-s3c2412/s3c2412.c +++ b/arch/arm/mach-s3c2412/s3c2412.c @@ -69,6 +69,18 @@ static struct map_desc s3c2412_iodesc[] __initdata = { IODESC_ENT(CLKPWR), IODESC_ENT(TIMER), IODESC_ENT(WATCHDOG), + { + .virtual = (unsigned long)S3C2412_VA_SSMC, + .pfn = __phys_to_pfn(S3C2412_PA_SSMC), + .length = SZ_1M, + .type = MT_DEVICE, + }, + { + .virtual = (unsigned long)S3C2412_VA_EBI, + .pfn = __phys_to_pfn(S3C2412_PA_EBI), + .length = SZ_1M, + .type = MT_DEVICE, + }, }; /* uart registration process */ -- cgit v1.2.3 From f0176794b6abc2e5239c07a58cf11b6f43d0f185 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Thu, 30 Jul 2009 23:23:38 +0100 Subject: ARM: S3C2410: Add S3C2410A sysdev. Add a sysdev S3C2410A sysdev to allow the differentiation of the S3C2410A from the S3C2410. This is needed for the CPUFREQ code to enable the extra features and update cpu specific information. Signed-off-by: Ben Dooks Signed-off-by: Ben Dooks --- arch/arm/mach-s3c2410/dma.c | 11 +++++++++++ arch/arm/mach-s3c2410/irq.c | 15 ++++++++++++++- arch/arm/mach-s3c2410/pm.c | 12 ++++++++++++ arch/arm/mach-s3c2410/s3c2410.c | 20 ++++++++++++++++++++ arch/arm/plat-s3c/include/plat/cpu.h | 1 + arch/arm/plat-s3c24xx/cpu.c | 2 +- arch/arm/plat-s3c24xx/include/plat/s3c2410.h | 1 + 7 files changed, 60 insertions(+), 2 deletions(-) (limited to 'arch/arm/mach-s3c2410') diff --git a/arch/arm/mach-s3c2410/dma.c b/arch/arm/mach-s3c2410/dma.c index dbf96e60d99..63b753f56c6 100644 --- a/arch/arm/mach-s3c2410/dma.c +++ b/arch/arm/mach-s3c2410/dma.c @@ -164,6 +164,17 @@ static int __init s3c2410_dma_drvinit(void) } arch_initcall(s3c2410_dma_drvinit); + +static struct sysdev_driver s3c2410a_dma_driver = { + .add = s3c2410_dma_add, +}; + +static int __init s3c2410a_dma_drvinit(void) +{ + return sysdev_driver_register(&s3c2410a_sysclass, &s3c2410a_dma_driver); +} + +arch_initcall(s3c2410a_dma_drvinit); #endif #if defined(CONFIG_CPU_S3C2442) diff --git a/arch/arm/mach-s3c2410/irq.c b/arch/arm/mach-s3c2410/irq.c index 92150399563..5e2f3533205 100644 --- a/arch/arm/mach-s3c2410/irq.c +++ b/arch/arm/mach-s3c2410/irq.c @@ -39,9 +39,22 @@ static struct sysdev_driver s3c2410_irq_driver = { .resume = s3c24xx_irq_resume, }; -static int s3c2410_irq_init(void) +static int __init s3c2410_irq_init(void) { return sysdev_driver_register(&s3c2410_sysclass, &s3c2410_irq_driver); } arch_initcall(s3c2410_irq_init); + +static struct sysdev_driver s3c2410a_irq_driver = { + .add = s3c2410_irq_add, + .suspend = s3c24xx_irq_suspend, + .resume = s3c24xx_irq_resume, +}; + +static int __init s3c2410a_irq_init(void) +{ + return sysdev_driver_register(&s3c2410a_sysclass, &s3c2410a_irq_driver); +} + +arch_initcall(s3c2410a_irq_init); diff --git a/arch/arm/mach-s3c2410/pm.c b/arch/arm/mach-s3c2410/pm.c index 143e08a599d..966119c8efe 100644 --- a/arch/arm/mach-s3c2410/pm.c +++ b/arch/arm/mach-s3c2410/pm.c @@ -119,6 +119,18 @@ static int __init s3c2410_pm_drvinit(void) } arch_initcall(s3c2410_pm_drvinit); + +static struct sysdev_driver s3c2410a_pm_driver = { + .add = s3c2410_pm_add, + .resume = s3c2410_pm_resume, +}; + +static int __init s3c2410a_pm_drvinit(void) +{ + return sysdev_driver_register(&s3c2410a_sysclass, &s3c2410a_pm_driver); +} + +arch_initcall(s3c2410a_pm_drvinit); #endif #if defined(CONFIG_CPU_S3C2440) diff --git a/arch/arm/mach-s3c2410/s3c2410.c b/arch/arm/mach-s3c2410/s3c2410.c index feb141b1f91..e5724a22c35 100644 --- a/arch/arm/mach-s3c2410/s3c2410.c +++ b/arch/arm/mach-s3c2410/s3c2410.c @@ -116,6 +116,13 @@ struct sysdev_class s3c2410_sysclass = { .name = "s3c2410-core", }; +/* Note, we would have liked to name this s3c2410-core, but we cannot + * register two sysdev_class with the same name. + */ +struct sysdev_class s3c2410a_sysclass = { + .name = "s3c2410a-core", +}; + static struct sys_device s3c2410_sysdev = { .cls = &s3c2410_sysclass, }; @@ -133,9 +140,22 @@ static int __init s3c2410_core_init(void) core_initcall(s3c2410_core_init); +static int __init s3c2410a_core_init(void) +{ + return sysdev_class_register(&s3c2410a_sysclass); +} + +core_initcall(s3c2410a_core_init); + int __init s3c2410_init(void) { printk("S3C2410: Initialising architecture\n"); return sysdev_register(&s3c2410_sysdev); } + +int __init s3c2410a_init(void) +{ + s3c2410_sysdev.cls = &s3c2410a_sysclass; + return s3c2410_init(); +} diff --git a/arch/arm/plat-s3c/include/plat/cpu.h b/arch/arm/plat-s3c/include/plat/cpu.h index be541cbba07..fbc3d498e02 100644 --- a/arch/arm/plat-s3c/include/plat/cpu.h +++ b/arch/arm/plat-s3c/include/plat/cpu.h @@ -65,6 +65,7 @@ extern struct sys_timer s3c24xx_timer; /* system device classes */ extern struct sysdev_class s3c2410_sysclass; +extern struct sysdev_class s3c2410a_sysclass; extern struct sysdev_class s3c2412_sysclass; extern struct sysdev_class s3c2440_sysclass; extern struct sysdev_class s3c2442_sysclass; diff --git a/arch/arm/plat-s3c24xx/cpu.c b/arch/arm/plat-s3c24xx/cpu.c index 1932b7e0da1..5447e60f393 100644 --- a/arch/arm/plat-s3c24xx/cpu.c +++ b/arch/arm/plat-s3c24xx/cpu.c @@ -81,7 +81,7 @@ static struct cpu_table cpu_ids[] __initdata = { .map_io = s3c2410_map_io, .init_clocks = s3c2410_init_clocks, .init_uarts = s3c2410_init_uarts, - .init = s3c2410_init, + .init = s3c2410a_init, .name = name_s3c2410a }, { diff --git a/arch/arm/plat-s3c24xx/include/plat/s3c2410.h b/arch/arm/plat-s3c24xx/include/plat/s3c2410.h index a9ac9e29759..b6deeef8f66 100644 --- a/arch/arm/plat-s3c24xx/include/plat/s3c2410.h +++ b/arch/arm/plat-s3c24xx/include/plat/s3c2410.h @@ -14,6 +14,7 @@ #ifdef CONFIG_CPU_S3C2410 extern int s3c2410_init(void); +extern int s3c2410a_init(void); extern void s3c2410_map_io(void); -- cgit v1.2.3 From ca0b4901d8faaf98cf254e25cd2784bcb21e46d5 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Thu, 30 Jul 2009 23:23:39 +0100 Subject: ARM: BAST: CPUFREQ: Add board support Add board support for CPUFREQ with the Simtec BAST board registering the necessary information with the core. Signed-off-by: Ben Dooks Signed-off-by: Ben Dooks --- arch/arm/mach-s3c2410/mach-bast.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'arch/arm/mach-s3c2410') diff --git a/arch/arm/mach-s3c2410/mach-bast.c b/arch/arm/mach-s3c2410/mach-bast.c index ce3baba2cd7..d8a26ea92f2 100644 --- a/arch/arm/mach-s3c2410/mach-bast.c +++ b/arch/arm/mach-s3c2410/mach-bast.c @@ -59,6 +59,7 @@ #include #include #include +#include #include "usb-simtec.h" #include "nor-simtec.h" @@ -570,6 +571,12 @@ static struct clk *bast_clocks[] __initdata = { &s3c24xx_uclk, }; +static struct s3c_cpufreq_board __initdata bast_cpufreq = { + .refresh = 7800, /* 7.8usec */ + .auto_io = 1, + .need_io = 1, +}; + static void __init bast_map_io(void) { /* initialise the clocks */ @@ -608,6 +615,8 @@ static void __init bast_init(void) usb_simtec_init(); nor_simtec_init(); + + s3c_cpufreq_setboard(&bast_cpufreq); } MACHINE_START(BAST, "Simtec-BAST") -- cgit v1.2.3 From ad78759529be38d6aa062233b980095cf74aa7f0 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Thu, 30 Jul 2009 23:23:40 +0100 Subject: ARM: S3C2410: Add armclk for cpufreq support Add armclk for use with the cpufreq support and anything else that may want it. This clock is just a direct descendant of fclk. Signed-off-by: Ben Dooks Signed-off-by: Ben Dooks --- arch/arm/mach-s3c2410/s3c2410.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'arch/arm/mach-s3c2410') diff --git a/arch/arm/mach-s3c2410/s3c2410.c b/arch/arm/mach-s3c2410/s3c2410.c index e5724a22c35..91ba42f688a 100644 --- a/arch/arm/mach-s3c2410/s3c2410.c +++ b/arch/arm/mach-s3c2410/s3c2410.c @@ -105,11 +105,20 @@ void __init_or_cpufreq s3c2410_setup_clocks(void) s3c24xx_setup_clocks(fclk, hclk, pclk); } +/* fake ARMCLK for use with cpufreq, etc. */ + +static struct clk s3c2410_armclk = { + .name = "armclk", + .parent = &clk_f, + .id = -1, +}; + void __init s3c2410_init_clocks(int xtal) { s3c24xx_register_baseclocks(xtal); s3c2410_setup_clocks(); s3c2410_baseclk_add(); + s3c24xx_register_clock(&s3c2410_armclk); } struct sysdev_class s3c2410_sysclass = { -- cgit v1.2.3 From e6d197a6954c8a9ff85727c31ca61fc1da78628a Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Thu, 30 Jul 2009 23:23:42 +0100 Subject: ARM: S3C: CPUFREQ: Add debugfs support for cpufreq Add debugfs support for the cpufreq driver to allow information about the system state to be exported to the user. Signed-off-by: Ben Dooks Signed-off-by: Ben Dooks --- arch/arm/Kconfig | 6 + arch/arm/mach-s3c2410/cpu-freq.c | 2 + arch/arm/mach-s3c2412/cpu-freq.c | 2 + arch/arm/plat-s3c24xx/Makefile | 1 + arch/arm/plat-s3c24xx/cpu-freq-debugfs.c | 199 +++++++++++++++++++++ arch/arm/plat-s3c24xx/cpu-freq.c | 12 ++ arch/arm/plat-s3c24xx/include/plat/cpu-freq-core.h | 24 +++ arch/arm/plat-s3c24xx/s3c2410-iotiming.c | 45 +++++ arch/arm/plat-s3c24xx/s3c2412-iotiming.c | 24 +++ arch/arm/plat-s3c24xx/s3c2440-cpufreq.c | 2 + 10 files changed, 317 insertions(+) create mode 100644 arch/arm/plat-s3c24xx/cpu-freq-debugfs.c (limited to 'arch/arm/mach-s3c2410') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index c7a83efef0b..f07a4ba281b 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1329,6 +1329,12 @@ config CPU_FREQ_S3C24XX_IODEBUG help Enable s3c_freq_iodbg for the Samsung S3C CPUfreq core +config CPU_FREQ_S3C24XX_DEBUGFS + bool "Export debugfs for CPUFreq" + depends on CPU_FREQ_S3C24XX && DEBUG_FS + help + Export status information via debugfs. + endif source "drivers/cpuidle/Kconfig" diff --git a/arch/arm/mach-s3c2410/cpu-freq.c b/arch/arm/mach-s3c2410/cpu-freq.c index f2cbdbab0df..9d1186877d0 100644 --- a/arch/arm/mach-s3c2410/cpu-freq.c +++ b/arch/arm/mach-s3c2410/cpu-freq.c @@ -111,6 +111,8 @@ static struct s3c_cpufreq_info s3c2410_cpufreq_info = { .set_refresh = s3c2410_cpufreq_setrefresh, .set_divs = s3c2410_cpufreq_setdivs, .calc_divs = s3c2410_cpufreq_calcdivs, + + .debug_io_show = s3c_cpufreq_debugfs_call(s3c2410_iotiming_debugfs), }; static int s3c2410_cpufreq_add(struct sys_device *sysdev) diff --git a/arch/arm/mach-s3c2412/cpu-freq.c b/arch/arm/mach-s3c2412/cpu-freq.c index 21a66178d9b..eb3ea172133 100644 --- a/arch/arm/mach-s3c2412/cpu-freq.c +++ b/arch/arm/mach-s3c2412/cpu-freq.c @@ -190,6 +190,8 @@ static struct s3c_cpufreq_info s3c2412_cpufreq_info = { .get_iotiming = s3c2412_iotiming_get, .resume_clocks = s3c2412_setup_clocks, + + .debug_io_show = s3c_cpufreq_debugfs_call(s3c2412_iotiming_debugfs), }; static int s3c2412_cpufreq_add(struct sys_device *sysdev) diff --git a/arch/arm/plat-s3c24xx/Makefile b/arch/arm/plat-s3c24xx/Makefile index 8759c070fd9..f3493751580 100644 --- a/arch/arm/plat-s3c24xx/Makefile +++ b/arch/arm/plat-s3c24xx/Makefile @@ -21,6 +21,7 @@ obj-y += clock.o obj-$(CONFIG_S3C24XX_DCLK) += clock-dclk.o obj-$(CONFIG_CPU_FREQ_S3C24XX) += cpu-freq.o +obj-$(CONFIG_CPU_FREQ_S3C24XX_DEBUGFS) += cpu-freq-debugfs.o # Architecture dependant builds diff --git a/arch/arm/plat-s3c24xx/cpu-freq-debugfs.c b/arch/arm/plat-s3c24xx/cpu-freq-debugfs.c new file mode 100644 index 00000000000..a9276667c2f --- /dev/null +++ b/arch/arm/plat-s3c24xx/cpu-freq-debugfs.c @@ -0,0 +1,199 @@ +/* linux/arch/arm/plat-s3c24xx/cpu-freq-debugfs.c + * + * Copyright (c) 2009 Simtec Electronics + * http://armlinux.simtec.co.uk/ + * Ben Dooks + * + * S3C24XX CPU Frequency scaling - debugfs status support + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +static struct dentry *dbgfs_root; +static struct dentry *dbgfs_file_io; +static struct dentry *dbgfs_file_info; +static struct dentry *dbgfs_file_board; + +#define print_ns(x) ((x) / 10), ((x) % 10) + +static void show_max(struct seq_file *seq, struct s3c_freq *f) +{ + seq_printf(seq, "MAX: F=%lu, H=%lu, P=%lu, A=%lu\n", + f->fclk, f->hclk, f->pclk, f->armclk); +} + +static int board_show(struct seq_file *seq, void *p) +{ + struct s3c_cpufreq_config *cfg; + struct s3c_cpufreq_board *brd; + + cfg = s3c_cpufreq_getconfig(); + if (!cfg) { + seq_printf(seq, "no configuration registered\n"); + return 0; + } + + brd = cfg->board; + if (!brd) { + seq_printf(seq, "no board definition set?\n"); + return 0; + } + + seq_printf(seq, "SDRAM refresh %u ns\n", brd->refresh); + seq_printf(seq, "auto_io=%u\n", brd->auto_io); + seq_printf(seq, "need_io=%u\n", brd->need_io); + + show_max(seq, &brd->max); + + + return 0; +} + +static int fops_board_open(struct inode *inode, struct file *file) +{ + return single_open(file, board_show, NULL); +} + +static const struct file_operations fops_board = { + .open = fops_board_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .owner = THIS_MODULE, +}; + +static int info_show(struct seq_file *seq, void *p) +{ + struct s3c_cpufreq_config *cfg; + + cfg = s3c_cpufreq_getconfig(); + if (!cfg) { + seq_printf(seq, "no configuration registered\n"); + return 0; + } + + seq_printf(seq, " FCLK %ld Hz\n", cfg->freq.fclk); + seq_printf(seq, " HCLK %ld Hz (%lu.%lu ns)\n", + cfg->freq.hclk, print_ns(cfg->freq.hclk_tns)); + seq_printf(seq, " PCLK %ld Hz\n", cfg->freq.hclk); + seq_printf(seq, "ARMCLK %ld Hz\n", cfg->freq.armclk); + seq_printf(seq, "\n"); + + show_max(seq, &cfg->max); + + seq_printf(seq, "Divisors: P=%d, H=%d, A=%d, dvs=%s\n", + cfg->divs.h_divisor, cfg->divs.p_divisor, + cfg->divs.arm_divisor, cfg->divs.dvs ? "on" : "off"); + seq_printf(seq, "\n"); + + seq_printf(seq, "lock_pll=%u\n", cfg->lock_pll); + + return 0; +} + +static int fops_info_open(struct inode *inode, struct file *file) +{ + return single_open(file, info_show, NULL); +} + +static const struct file_operations fops_info = { + .open = fops_info_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .owner = THIS_MODULE, +}; + +static int io_show(struct seq_file *seq, void *p) +{ + void (*show_bank)(struct seq_file *, struct s3c_cpufreq_config *, union s3c_iobank *); + struct s3c_cpufreq_config *cfg; + struct s3c_iotimings *iot; + union s3c_iobank *iob; + int bank; + + cfg = s3c_cpufreq_getconfig(); + if (!cfg) { + seq_printf(seq, "no configuration registered\n"); + return 0; + } + + show_bank = cfg->info->debug_io_show; + if (!show_bank) { + seq_printf(seq, "no code to show bank timing\n"); + return 0; + } + + iot = s3c_cpufreq_getiotimings(); + if (!iot) { + seq_printf(seq, "no io timings registered\n"); + return 0; + } + + seq_printf(seq, "hclk period is %lu.%lu ns\n", print_ns(cfg->freq.hclk_tns)); + + for (bank = 0; bank < MAX_BANKS; bank++) { + iob = &iot->bank[bank]; + + seq_printf(seq, "bank %d: ", bank); + + if (!iob->io_2410) { + seq_printf(seq, "nothing set\n"); + continue; + } + + show_bank(seq, cfg, iob); + } + + return 0; +} + +static int fops_io_open(struct inode *inode, struct file *file) +{ + return single_open(file, io_show, NULL); +} + +static const struct file_operations fops_io = { + .open = fops_io_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .owner = THIS_MODULE, +}; + + +static int __init s3c_freq_debugfs_init(void) +{ + dbgfs_root = debugfs_create_dir("s3c-cpufreq", NULL); + if (IS_ERR(dbgfs_root)) { + printk(KERN_ERR "%s: error creating debugfs root\n", __func__); + return PTR_ERR(dbgfs_root); + } + + dbgfs_file_io = debugfs_create_file("io-timing", S_IRUGO, dbgfs_root, + NULL, &fops_io); + + dbgfs_file_info = debugfs_create_file("info", S_IRUGO, dbgfs_root, + NULL, &fops_info); + + dbgfs_file_board = debugfs_create_file("board", S_IRUGO, dbgfs_root, + NULL, &fops_board); + + return 0; +} + +late_initcall(s3c_freq_debugfs_init); + diff --git a/arch/arm/plat-s3c24xx/cpu-freq.c b/arch/arm/plat-s3c24xx/cpu-freq.c index 40ff7e2569d..4f1b789a117 100644 --- a/arch/arm/plat-s3c24xx/cpu-freq.c +++ b/arch/arm/plat-s3c24xx/cpu-freq.c @@ -50,6 +50,18 @@ static struct clk *clk_hclk; static struct clk *clk_pclk; static struct clk *clk_arm; +#ifdef CONFIG_CPU_FREQ_S3C24XX_DEBUGFS +struct s3c_cpufreq_config *s3c_cpufreq_getconfig(void) +{ + return &cpu_cur; +} + +struct s3c_iotimings *s3c_cpufreq_getiotimings(void) +{ + return &s3c24xx_iotiming; +} +#endif /* CONFIG_CPU_FREQ_S3C24XX_DEBUGFS */ + static void s3c_cpufreq_getcur(struct s3c_cpufreq_config *cfg) { unsigned long fclk, pclk, hclk, armclk; diff --git a/arch/arm/plat-s3c24xx/include/plat/cpu-freq-core.h b/arch/arm/plat-s3c24xx/include/plat/cpu-freq-core.h index f02b3c06c1e..efeb025affc 100644 --- a/arch/arm/plat-s3c24xx/include/plat/cpu-freq-core.h +++ b/arch/arm/plat-s3c24xx/include/plat/cpu-freq-core.h @@ -13,6 +13,8 @@ #include +struct seq_file; + #define MAX_BANKS (8) #define S3C2412_MAX_IO (8) @@ -181,6 +183,10 @@ struct s3c_cpufreq_info { struct cpufreq_frequency_table *t, size_t table_size); + void (*debug_io_show)(struct seq_file *seq, + struct s3c_cpufreq_config *cfg, + union s3c_iobank *iob); + void (*set_refresh)(struct s3c_cpufreq_config *cfg); void (*set_fvco)(struct s3c_cpufreq_config *cfg); void (*set_divs)(struct s3c_cpufreq_config *cfg); @@ -191,6 +197,24 @@ extern int s3c_cpufreq_register(struct s3c_cpufreq_info *info); extern int s3c_plltab_register(struct cpufreq_frequency_table *plls, unsigned int plls_no); +/* exports and utilities for debugfs */ +extern struct s3c_cpufreq_config *s3c_cpufreq_getconfig(void); +extern struct s3c_iotimings *s3c_cpufreq_getiotimings(void); + +extern void s3c2410_iotiming_debugfs(struct seq_file *seq, + struct s3c_cpufreq_config *cfg, + union s3c_iobank *iob); + +extern void s3c2412_iotiming_debugfs(struct seq_file *seq, + struct s3c_cpufreq_config *cfg, + union s3c_iobank *iob); + +#ifdef CONFIG_CPU_FREQ_S3C24XX_DEBUGFS +#define s3c_cpufreq_debugfs_call(x) x +#else +#define s3c_cpufreq_debugfs_call(x) NULL +#endif + /* Useful utility functions. */ extern struct clk *s3c_cpufreq_clk_get(struct device *, const char *); diff --git a/arch/arm/plat-s3c24xx/s3c2410-iotiming.c b/arch/arm/plat-s3c24xx/s3c2410-iotiming.c index 26fe2129cf2..d0a3a145cd4 100644 --- a/arch/arm/plat-s3c24xx/s3c2410-iotiming.c +++ b/arch/arm/plat-s3c24xx/s3c2410-iotiming.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -303,6 +304,50 @@ void s3c2410_iotiming_getbank(struct s3c_cpufreq_config *cfg, bt->tacc = get_tacc(hclk, bankcon >> S3C2410_BANKCON_Tacc_SHIFT); } +/** + * s3c2410_iotiming_debugfs - debugfs show io bank timing information + * @seq: The seq_file to write output to using seq_printf(). + * @cfg: The current configuration. + * @iob: The IO bank information to decode. + */ +void s3c2410_iotiming_debugfs(struct seq_file *seq, + struct s3c_cpufreq_config *cfg, + union s3c_iobank *iob) +{ + struct s3c2410_iobank_timing *bt = iob->io_2410; + unsigned long bankcon = bt->bankcon; + unsigned long hclk = cfg->freq.hclk_tns; + unsigned int tacs; + unsigned int tcos; + unsigned int tacc; + unsigned int tcoh; + unsigned int tcah; + + seq_printf(seq, "BANKCON=0x%08lx\n", bankcon); + + tcah = get_0124(hclk, bankcon >> S3C2410_BANKCON_Tcah_SHIFT); + tcoh = get_0124(hclk, bankcon >> S3C2410_BANKCON_Tcoh_SHIFT); + tcos = get_0124(hclk, bankcon >> S3C2410_BANKCON_Tcos_SHIFT); + tacs = get_0124(hclk, bankcon >> S3C2410_BANKCON_Tacs_SHIFT); + tacc = get_tacc(hclk, bankcon >> S3C2410_BANKCON_Tacc_SHIFT); + + seq_printf(seq, + "\tRead: Tacs=%d.%d, Tcos=%d.%d, Tacc=%d.%d, Tcoh=%d.%d, Tcah=%d.%d\n", + print_ns(bt->tacs), + print_ns(bt->tcos), + print_ns(bt->tacc), + print_ns(bt->tcoh), + print_ns(bt->tcah)); + + seq_printf(seq, + "\t Set: Tacs=%d.%d, Tcos=%d.%d, Tacc=%d.%d, Tcoh=%d.%d, Tcah=%d.%d\n", + print_ns(tacs), + print_ns(tcos), + print_ns(tacc), + print_ns(tcoh), + print_ns(tcah)); +} + /** * s3c2410_iotiming_calc - Calculate bank timing for frequency change. * @cfg: The frequency configuration diff --git a/arch/arm/plat-s3c24xx/s3c2412-iotiming.c b/arch/arm/plat-s3c24xx/s3c2412-iotiming.c index a3648cba0eb..fd45e47facb 100644 --- a/arch/arm/plat-s3c24xx/s3c2412-iotiming.c +++ b/arch/arm/plat-s3c24xx/s3c2412-iotiming.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -108,6 +109,29 @@ static int s3c2412_calc_bank(struct s3c_cpufreq_config *cfg, return err; } +/** + * s3c2412_iotiming_debugfs - debugfs show io bank timing information + * @seq: The seq_file to write output to using seq_printf(). + * @cfg: The current configuration. + * @iob: The IO bank information to decode. +*/ +void s3c2412_iotiming_debugfs(struct seq_file *seq, + struct s3c_cpufreq_config *cfg, + union s3c_iobank *iob) +{ + struct s3c2412_iobank_timing *bt = iob->io_2412; + + seq_printf(seq, + "\tRead: idcy=%d.%d wstrd=%d.%d wstwr=%d,%d" + "wstoen=%d.%d wstwen=%d.%d wstbrd=%d.%d\n", + print_ns(bt->idcy), + print_ns(bt->wstrd), + print_ns(bt->wstwr), + print_ns(bt->wstoen), + print_ns(bt->wstwen), + print_ns(bt->wstbrd)); +} + /** * s3c2412_iotiming_calc - calculate all the bank divisor settings. * @cfg: The current frequency configuration. diff --git a/arch/arm/plat-s3c24xx/s3c2440-cpufreq.c b/arch/arm/plat-s3c24xx/s3c2440-cpufreq.c index c177a20319e..ae2e6c604f2 100644 --- a/arch/arm/plat-s3c24xx/s3c2440-cpufreq.c +++ b/arch/arm/plat-s3c24xx/s3c2440-cpufreq.c @@ -266,6 +266,8 @@ struct s3c_cpufreq_info s3c2440_cpufreq_info = { .calc_freqtable = s3c2440_cpufreq_calctable, .resume_clocks = s3c244x_setup_clocks, + + .debug_io_show = s3c_cpufreq_debugfs_call(s3c2410_iotiming_debugfs), }; static int s3c2440_cpufreq_add(struct sys_device *sysdev) -- cgit v1.2.3