Date:2011-03-05 00:18:59 (9 years 3 months ago)
Author:Lars C.
Commit:184d4914225fec620e05763703c0073aa0d2cfd5
Message:Add OST support

Add support for the OST found on the JZ4750 and later.
Use it instead of the timer clocksource and clockevent for JZ4750 and JZ4760.
Files: arch/mips/jz47xx/Kconfig (2 diffs)
arch/mips/jz47xx/Makefile (1 diff)
arch/mips/jz47xx/jz4750/time.c (1 diff)
arch/mips/jz47xx/jz4760/Makefile (1 diff)
arch/mips/jz47xx/jz4760/time.c (1 diff)
arch/mips/jz47xx/ost.c (1 diff)
arch/mips/jz47xx/ost.h (1 diff)

Change Details

arch/mips/jz47xx/Kconfig
1212
1313config MACH_JZ4750
1414    bool "JZ4750"
15    select JZ47XX_TIMER_CSRC
16    select JZ47XX_TIMER_CEVT
15    select JZ47XX_OST
1716    select JZ47XX_GPIOV2
1817
1918config MACH_JZ4760
2019    bool "JZ4760"
21    select JZ47XX_TIMER_CSRC
22    select JZ47XX_TIMER_CEVT
20    select JZ47XX_OST
2321    select JZ47XX_GPIOV2
2422
2523endchoice
...... 
3735config JZ47XX_TIMER_CEVT
3836    bool
3937
38config JZ47XX_OST
39    bool
40
4041config JZ47XX_GPIOV2
4142    bool
arch/mips/jz47xx/Makefile
99
1010obj-$(CONFIG_JZ47XX_TIMER_CSRC) += timer-csrc.o
1111obj-$(CONFIG_JZ47XX_TIMER_CEVT) += timer-cevt.o
12obj-$(CONFIG_JZ47XX_OST) += ost.o
1213obj-$(CONFIG_JZ47XX_GPIOV2) += gpiov2.o
1314obj-$(CONFIG_DEBUG_FS) += clock-debugfs.o
1415
arch/mips/jz47xx/jz4750/time.c
1717#include <asm/mach-jz47xx/jz4750/irq.h>
1818
1919#include "../timer.h"
20#include "../timer-cevt.h"
20#include "../ost.h"
2121
2222void __init plat_time_init(void)
2323{
2424    jz4740_timer_init();
25    jz47xx_timer_cevt_init(JZ4750_IRQ_TCU1, 0);
25    jz47xx_ost_init(JZ4750_IRQ_TCU0);
2626}
arch/mips/jz47xx/jz4760/Makefile
11
2obj-y += clock.o platform.o time.o gpio.o irq.o
2obj-y += platform.o time.o gpio.o irq.o clock.o
33
44obj-$(CONFIG_JZ4760_LEPUS) += board-lepus.o
55
arch/mips/jz47xx/jz4760/time.c
33#include <asm/mach-jz47xx/jz4760/irq.h>
44
55#include "../timer.h"
6#include "../timer-csrc.h"
7#include "../timer-cevt.h"
6#include "../ost.h"
87
98void __init plat_time_init(void)
109{
1110    jz4740_timer_init();
12    jz47xx_timer_csrc_init(0);
13    jz47xx_timer_cevt_init(JZ4760_IRQ_TCU1, 5);
11    jz47xx_ost_init(JZ4760_IRQ_TCU0);
1412}
arch/mips/jz47xx/ost.c
1/*
2 * Copyright (C) 2011, Lars-Peter Clausen <lars@metafoo.de>
3 * jz47xx OST support
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
9 *
10 * You should have received a copy of the GNU General Public License along
11 * with this program; if not, write to the Free Software Foundation, Inc.,
12 * 675 Mass Ave, Cambridge, MA 02139, USA.
13 *
14 */
15
16#include <linux/interrupt.h>
17#include <linux/kernel.h>
18#include <linux/time.h>
19
20#include <linux/clockchips.h>
21#include <linux/clocksource.h>
22
23#include <asm/mach-jz47xx/base.h>
24
25#include <asm/time.h>
26
27#include "clock.h"
28#include "timer.h"
29
30#define JZ_REG_OST_COMPARE 0x0
31#define JZ_REG_OST_COUNT 0x8
32#define JZ_REG_OST_CTRL 0xC
33
34/* 0: Counter will be set to 0 if it is equal to the compare value
35 * 1: Counter will only be set to 0 when it wraps around */
36#define JZ_OST_CTRL_COUNT_MODE BIT(15)
37
38#define JZ47XX_TIMER_OST 15
39
40static void __iomem *jz47xx_ost_base;
41
42static irqreturn_t jz47xx_ost_clockevent_irq(int irq, void *devid)
43{
44    struct clock_event_device *cd = devid;
45
46    jz4740_timer_irq_full_disable(JZ47XX_TIMER_OST);
47    jz4740_timer_ack_full(JZ47XX_TIMER_OST);
48
49    cd->event_handler(cd);
50
51    return IRQ_HANDLED;
52}
53
54static void jz47xx_ost_clockevent_set_mode(enum clock_event_mode mode,
55    struct clock_event_device *cd)
56{
57    switch (mode) {
58    case CLOCK_EVT_MODE_RESUME:
59        jz4740_timer_irq_full_enable(JZ47XX_TIMER_OST);
60        break;
61    case CLOCK_EVT_MODE_ONESHOT:
62    case CLOCK_EVT_MODE_SHUTDOWN:
63        jz4740_timer_irq_full_disable(JZ47XX_TIMER_OST);
64        break;
65    default:
66        break;
67    }
68}
69
70static int jz47xx_ost_clockevent_set_next(unsigned long evt,
71    struct clock_event_device *cd)
72{
73    uint32_t count = readl(jz47xx_ost_base + JZ_REG_OST_COUNT);
74
75    count += evt;
76    writel(count, jz47xx_ost_base + JZ_REG_OST_COMPARE);
77
78    jz4740_timer_irq_full_enable(JZ47XX_TIMER_OST);
79
80    count = readl(jz47xx_ost_base + JZ_REG_OST_COUNT);
81
82    return 0;
83}
84
85static struct clock_event_device jz47xx_ost_clockevent = {
86    .name = "jz47xx-ost",
87    .features = CLOCK_EVT_FEAT_ONESHOT,
88    .set_next_event = jz47xx_ost_clockevent_set_next,
89    .set_mode = jz47xx_ost_clockevent_set_mode,
90    .rating = 300,
91};
92
93static struct irqaction timer_irqaction = {
94    .handler = jz47xx_ost_clockevent_irq,
95    .flags = IRQF_PERCPU | IRQF_TIMER,
96    .name = "jz47xx-ost",
97    .dev_id = &jz47xx_ost_clockevent,
98};
99
100static cycle_t jz47xx_ost_clocksource_read(struct clocksource *cs)
101{
102    return readl(jz47xx_ost_base + JZ_REG_OST_COUNT);
103}
104
105static struct clocksource jz47xx_ost_clocksource = {
106    .name = "jz47xx-ost",
107    .rating = 300,
108    .read = jz47xx_ost_clocksource_read,
109    .mask = CLOCKSOURCE_MASK(32),
110    .flags = CLOCK_SOURCE_IS_CONTINUOUS,
111};
112
113int __init jz47xx_ost_init(unsigned int irq)
114{
115    unsigned int clk_rate;
116    int ret;
117
118    jz47xx_ost_base = ioremap(JZ47XX_OST_BASE_ADDR, 0x10);
119    if (!jz47xx_ost_base) {
120        printk(KERN_ERR "Failed to ioremap ost mem region\n");
121        return -EBUSY;
122    }
123
124    jz4740_timer_start(JZ47XX_TIMER_OST);
125
126    jz47xx_ost_clockevent.irq = irq;
127
128    clk_rate = jz4740_clock_bdata.ext_rate >> 4;
129
130    clocksource_set_clock(&jz47xx_ost_clocksource, clk_rate);
131    ret = clocksource_register(&jz47xx_ost_clocksource);
132
133    if (ret) {
134        printk(KERN_ERR "Failed to register clocksource: %d\n", ret);
135        return ret;
136    }
137
138    clockevent_set_clock(&jz47xx_ost_clockevent, clk_rate);
139    jz47xx_ost_clockevent.min_delta_ns = clockevent_delta2ns(100, &jz47xx_ost_clockevent);
140    jz47xx_ost_clockevent.max_delta_ns = clockevent_delta2ns(0xffffffff, &jz47xx_ost_clockevent);
141    jz47xx_ost_clockevent.cpumask = cpumask_of(0);
142
143    clockevents_register_device(&jz47xx_ost_clockevent);
144
145    writew(JZ_TIMER_CTRL_PRESCALE_16 | JZ_TIMER_CTRL_SRC_EXT |
146        JZ_OST_CTRL_COUNT_MODE, jz47xx_ost_base + JZ_REG_OST_CTRL);
147
148    setup_irq(irq, &timer_irqaction);
149
150    jz4740_timer_enable(JZ47XX_TIMER_OST);
151
152    return 0;
153}
arch/mips/jz47xx/ost.h
1#ifndef __MIPS_JZ47XX_TIMER_OST_H__
2#define __MIPS_JZ47XX_TIMER_OST_H__
3
4extern int __init jz47xx_ost_init(unsigned int irq);
5
6#endif

Archive Download the corresponding diff file



interactive