aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/clocksource/timer-milbeaut.c62
1 files changed, 39 insertions, 23 deletions
diff --git a/drivers/clocksource/timer-milbeaut.c b/drivers/clocksource/timer-milbeaut.c
index f4780619dbaf..fa9fb4eacade 100644
--- a/drivers/clocksource/timer-milbeaut.c
+++ b/drivers/clocksource/timer-milbeaut.c
@@ -26,8 +26,8 @@
26#define MLB_TMR_TMCSR_CSL_DIV2 0 26#define MLB_TMR_TMCSR_CSL_DIV2 0
27#define MLB_TMR_DIV_CNT 2 27#define MLB_TMR_DIV_CNT 2
28 28
29#define MLB_TMR_SRC_CH (1) 29#define MLB_TMR_SRC_CH 1
30#define MLB_TMR_EVT_CH (0) 30#define MLB_TMR_EVT_CH 0
31 31
32#define MLB_TMR_SRC_CH_OFS (MLB_TMR_REGSZPCH * MLB_TMR_SRC_CH) 32#define MLB_TMR_SRC_CH_OFS (MLB_TMR_REGSZPCH * MLB_TMR_SRC_CH)
33#define MLB_TMR_EVT_CH_OFS (MLB_TMR_REGSZPCH * MLB_TMR_EVT_CH) 33#define MLB_TMR_EVT_CH_OFS (MLB_TMR_REGSZPCH * MLB_TMR_EVT_CH)
@@ -43,6 +43,8 @@
43#define MLB_TMR_EVT_TMRLR2_OFS (MLB_TMR_EVT_CH_OFS + MLB_TMR_TMRLR2_OFS) 43#define MLB_TMR_EVT_TMRLR2_OFS (MLB_TMR_EVT_CH_OFS + MLB_TMR_TMRLR2_OFS)
44 44
45#define MLB_TIMER_RATING 500 45#define MLB_TIMER_RATING 500
46#define MLB_TIMER_ONESHOT 0
47#define MLB_TIMER_PERIODIC 1
46 48
47static irqreturn_t mlb_timer_interrupt(int irq, void *dev_id) 49static irqreturn_t mlb_timer_interrupt(int irq, void *dev_id)
48{ 50{
@@ -59,38 +61,53 @@ static irqreturn_t mlb_timer_interrupt(int irq, void *dev_id)
59 return IRQ_HANDLED; 61 return IRQ_HANDLED;
60} 62}
61 63
62static int mlb_set_state_periodic(struct clock_event_device *clk) 64static void mlb_evt_timer_start(struct timer_of *to, bool periodic)
63{ 65{
64 struct timer_of *to = to_timer_of(clk);
65 u32 val = MLB_TMR_TMCSR_CSL_DIV2; 66 u32 val = MLB_TMR_TMCSR_CSL_DIV2;
66 67
68 val |= MLB_TMR_TMCSR_CNTE | MLB_TMR_TMCSR_TRG | MLB_TMR_TMCSR_INTE;
69 if (periodic)
70 val |= MLB_TMR_TMCSR_RELD;
67 writel_relaxed(val, timer_of_base(to) + MLB_TMR_EVT_TMCSR_OFS); 71 writel_relaxed(val, timer_of_base(to) + MLB_TMR_EVT_TMCSR_OFS);
72}
73
74static void mlb_evt_timer_stop(struct timer_of *to)
75{
76 u32 val = readl_relaxed(timer_of_base(to) + MLB_TMR_EVT_TMCSR_OFS);
68 77
69 writel_relaxed(to->of_clk.period, timer_of_base(to) + 78 val &= ~MLB_TMR_TMCSR_CNTE;
70 MLB_TMR_EVT_TMRLR1_OFS);
71 val |= MLB_TMR_TMCSR_RELD | MLB_TMR_TMCSR_CNTE |
72 MLB_TMR_TMCSR_TRG | MLB_TMR_TMCSR_INTE;
73 writel_relaxed(val, timer_of_base(to) + MLB_TMR_EVT_TMCSR_OFS); 79 writel_relaxed(val, timer_of_base(to) + MLB_TMR_EVT_TMCSR_OFS);
80}
81
82static void mlb_evt_timer_register_count(struct timer_of *to, unsigned long cnt)
83{
84 writel_relaxed(cnt, timer_of_base(to) + MLB_TMR_EVT_TMRLR1_OFS);
85}
86
87static int mlb_set_state_periodic(struct clock_event_device *clk)
88{
89 struct timer_of *to = to_timer_of(clk);
90
91 mlb_evt_timer_stop(to);
92 mlb_evt_timer_register_count(to, to->of_clk.period);
93 mlb_evt_timer_start(to, MLB_TIMER_PERIODIC);
74 return 0; 94 return 0;
75} 95}
76 96
77static int mlb_set_state_oneshot(struct clock_event_device *clk) 97static int mlb_set_state_oneshot(struct clock_event_device *clk)
78{ 98{
79 struct timer_of *to = to_timer_of(clk); 99 struct timer_of *to = to_timer_of(clk);
80 u32 val = MLB_TMR_TMCSR_CSL_DIV2;
81 100
82 writel_relaxed(val, timer_of_base(to) + MLB_TMR_EVT_TMCSR_OFS); 101 mlb_evt_timer_stop(to);
83 val |= MLB_TMR_TMCSR_CNTE | MLB_TMR_TMCSR_TRG | MLB_TMR_TMCSR_INTE; 102 mlb_evt_timer_start(to, MLB_TIMER_ONESHOT);
84 writel_relaxed(val, timer_of_base(to) + MLB_TMR_EVT_TMCSR_OFS);
85 return 0; 103 return 0;
86} 104}
87 105
88static int mlb_set_state_shutdown(struct clock_event_device *clk) 106static int mlb_set_state_shutdown(struct clock_event_device *clk)
89{ 107{
90 struct timer_of *to = to_timer_of(clk); 108 struct timer_of *to = to_timer_of(clk);
91 u32 val = MLB_TMR_TMCSR_CSL_DIV2;
92 109
93 writel_relaxed(val, timer_of_base(to) + MLB_TMR_EVT_TMCSR_OFS); 110 mlb_evt_timer_stop(to);
94 return 0; 111 return 0;
95} 112}
96 113
@@ -99,22 +116,21 @@ static int mlb_clkevt_next_event(unsigned long event,
99{ 116{
100 struct timer_of *to = to_timer_of(clk); 117 struct timer_of *to = to_timer_of(clk);
101 118
102 writel_relaxed(event, timer_of_base(to) + MLB_TMR_EVT_TMRLR1_OFS); 119 mlb_evt_timer_stop(to);
103 writel_relaxed(MLB_TMR_TMCSR_CSL_DIV2 | 120 mlb_evt_timer_register_count(to, event);
104 MLB_TMR_TMCSR_CNTE | MLB_TMR_TMCSR_INTE | 121 mlb_evt_timer_start(to, MLB_TIMER_ONESHOT);
105 MLB_TMR_TMCSR_TRG, timer_of_base(to) +
106 MLB_TMR_EVT_TMCSR_OFS);
107 return 0; 122 return 0;
108} 123}
109 124
110static int mlb_config_clock_source(struct timer_of *to) 125static int mlb_config_clock_source(struct timer_of *to)
111{ 126{
112 writel_relaxed(0, timer_of_base(to) + MLB_TMR_SRC_TMCSR_OFS); 127 u32 val = MLB_TMR_TMCSR_CSL_DIV2;
113 writel_relaxed(~0, timer_of_base(to) + MLB_TMR_SRC_TMR_OFS); 128
129 writel_relaxed(val, timer_of_base(to) + MLB_TMR_SRC_TMCSR_OFS);
114 writel_relaxed(~0, timer_of_base(to) + MLB_TMR_SRC_TMRLR1_OFS); 130 writel_relaxed(~0, timer_of_base(to) + MLB_TMR_SRC_TMRLR1_OFS);
115 writel_relaxed(~0, timer_of_base(to) + MLB_TMR_SRC_TMRLR2_OFS); 131 writel_relaxed(~0, timer_of_base(to) + MLB_TMR_SRC_TMRLR2_OFS);
116 writel_relaxed(BIT(4) | BIT(1) | BIT(0), timer_of_base(to) + 132 val |= MLB_TMR_TMCSR_RELD | MLB_TMR_TMCSR_CNTE | MLB_TMR_TMCSR_TRG;
117 MLB_TMR_SRC_TMCSR_OFS); 133 writel_relaxed(val, timer_of_base(to) + MLB_TMR_SRC_TMCSR_OFS);
118 return 0; 134 return 0;
119} 135}
120 136