Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 160942
b: refs/heads/master
c: e6d197a
h: refs/heads/master
v: v3
  • Loading branch information
Ben Dooks authored and Ben Dooks committed Jul 30, 2009
1 parent d7c7a62 commit 6b1807c
Show file tree
Hide file tree
Showing 11 changed files with 318 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: dfff4e95d749c414af3f7350835139103408a50d
refs/heads/master: e6d197a6954c8a9ff85727c31ca61fc1da78628a
6 changes: 6 additions & 0 deletions trunk/arch/arm/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
2 changes: 2 additions & 0 deletions trunk/arch/arm/mach-s3c2410/cpu-freq.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 2 additions & 0 deletions trunk/arch/arm/mach-s3c2412/cpu-freq.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
1 change: 1 addition & 0 deletions trunk/arch/arm/plat-s3c24xx/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
199 changes: 199 additions & 0 deletions trunk/arch/arm/plat-s3c24xx/cpu-freq-debugfs.c
Original file line number Diff line number Diff line change
@@ -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 <ben@simtec.co.uk>
*
* 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 <linux/init.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/cpufreq.h>
#include <linux/debugfs.h>
#include <linux/seq_file.h>
#include <linux/err.h>

#include <plat/cpu-freq-core.h>

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);

12 changes: 12 additions & 0 deletions trunk/arch/arm/plat-s3c24xx/cpu-freq.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
24 changes: 24 additions & 0 deletions trunk/arch/arm/plat-s3c24xx/include/plat/cpu-freq-core.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@

#include <plat/cpu-freq.h>

struct seq_file;

#define MAX_BANKS (8)
#define S3C2412_MAX_IO (8)

Expand Down Expand Up @@ -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);
Expand All @@ -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 *);
Expand Down
45 changes: 45 additions & 0 deletions trunk/arch/arm/plat-s3c24xx/s3c2410-iotiming.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/cpufreq.h>
#include <linux/seq_file.h>
#include <linux/io.h>

#include <mach/map.h>
Expand Down Expand Up @@ -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
Expand Down
Loading

0 comments on commit 6b1807c

Please sign in to comment.