aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>2014-02-11 17:46:48 -0500
committerLaurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>2014-04-16 06:03:10 -0400
commit2cda3ac49d5744432e9ebffb8ba47bef6eca053d (patch)
tree1869cd0f7a392e8cfdb0e09dd06becba4e3008c3
parentf5ec9b194a93c05e2ccdb3e90d9061cfedc806d9 (diff)
clocksource: sh_cmt: Split static information from sh_cmt_device
Create a new sh_cmt_info structure to hold static information about the device model and reference that structure from the sh_cmt_device structure. Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
-rw-r--r--drivers/clocksource/sh_cmt.c192
1 files changed, 122 insertions, 70 deletions
diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c
index f94db327ac7c..879b8c2ae556 100644
--- a/drivers/clocksource/sh_cmt.c
+++ b/drivers/clocksource/sh_cmt.c
@@ -37,6 +37,52 @@
37 37
38struct sh_cmt_device; 38struct sh_cmt_device;
39 39
40/*
41 * The CMT comes in 5 different identified flavours, depending not only on the
42 * SoC but also on the particular instance. The following table lists the main
43 * characteristics of those flavours.
44 *
45 * 16B 32B 32B-F 48B 48B-2
46 * -----------------------------------------------------------------------------
47 * Channels 2 1/4 1 6 2/8
48 * Control Width 16 16 16 16 32
49 * Counter Width 16 32 32 32/48 32/48
50 * Shared Start/Stop Y Y Y Y N
51 *
52 * The 48-bit gen2 version has a per-channel start/stop register located in the
53 * channel registers block. All other versions have a shared start/stop register
54 * located in the global space.
55 *
56 * Note that CMT0 on r8a73a4, r8a7790 and r8a7791, while implementing 32-bit
57 * channels only, is a 48-bit gen2 CMT with the 48-bit channels unavailable.
58 */
59
60enum sh_cmt_model {
61 SH_CMT_16BIT,
62 SH_CMT_32BIT,
63 SH_CMT_32BIT_FAST,
64 SH_CMT_48BIT,
65 SH_CMT_48BIT_GEN2,
66};
67
68struct sh_cmt_info {
69 enum sh_cmt_model model;
70
71 unsigned long width; /* 16 or 32 bit version of hardware block */
72 unsigned long overflow_bit;
73 unsigned long clear_bits;
74
75 /* callbacks for CMSTR and CMCSR access */
76 unsigned long (*read_control)(void __iomem *base, unsigned long offs);
77 void (*write_control)(void __iomem *base, unsigned long offs,
78 unsigned long value);
79
80 /* callbacks for CMCNT and CMCOR access */
81 unsigned long (*read_count)(void __iomem *base, unsigned long offs);
82 void (*write_count)(void __iomem *base, unsigned long offs,
83 unsigned long value);
84};
85
40struct sh_cmt_channel { 86struct sh_cmt_channel {
41 struct sh_cmt_device *cmt; 87 struct sh_cmt_device *cmt;
42 unsigned int index; 88 unsigned int index;
@@ -58,49 +104,16 @@ struct sh_cmt_channel {
58struct sh_cmt_device { 104struct sh_cmt_device {
59 struct platform_device *pdev; 105 struct platform_device *pdev;
60 106
107 const struct sh_cmt_info *info;
108
61 void __iomem *mapbase_ch; 109 void __iomem *mapbase_ch;
62 void __iomem *mapbase; 110 void __iomem *mapbase;
63 struct clk *clk; 111 struct clk *clk;
64 112
65 struct sh_cmt_channel *channels; 113 struct sh_cmt_channel *channels;
66 unsigned int num_channels; 114 unsigned int num_channels;
67
68 unsigned long width; /* 16 or 32 bit version of hardware block */
69 unsigned long overflow_bit;
70 unsigned long clear_bits;
71
72 /* callbacks for CMSTR and CMCSR access */
73 unsigned long (*read_control)(void __iomem *base, unsigned long offs);
74 void (*write_control)(void __iomem *base, unsigned long offs,
75 unsigned long value);
76
77 /* callbacks for CMCNT and CMCOR access */
78 unsigned long (*read_count)(void __iomem *base, unsigned long offs);
79 void (*write_count)(void __iomem *base, unsigned long offs,
80 unsigned long value);
81}; 115};
82 116
83/* Examples of supported CMT timer register layouts and I/O access widths:
84 *
85 * "16-bit counter and 16-bit control" as found on sh7263:
86 * CMSTR 0xfffec000 16-bit
87 * CMCSR 0xfffec002 16-bit
88 * CMCNT 0xfffec004 16-bit
89 * CMCOR 0xfffec006 16-bit
90 *
91 * "32-bit counter and 16-bit control" as found on sh7372, sh73a0, r8a7740:
92 * CMSTR 0xffca0000 16-bit
93 * CMCSR 0xffca0060 16-bit
94 * CMCNT 0xffca0064 32-bit
95 * CMCOR 0xffca0068 32-bit
96 *
97 * "32-bit counter and 32-bit control" as found on r8a73a4 and r8a7790:
98 * CMSTR 0xffca0500 32-bit
99 * CMCSR 0xffca0510 32-bit
100 * CMCNT 0xffca0514 32-bit
101 * CMCOR 0xffca0518 32-bit
102 */
103
104static unsigned long sh_cmt_read16(void __iomem *base, unsigned long offs) 117static unsigned long sh_cmt_read16(void __iomem *base, unsigned long offs)
105{ 118{
106 return ioread16(base + (offs << 1)); 119 return ioread16(base + (offs << 1));
@@ -123,47 +136,100 @@ static void sh_cmt_write32(void __iomem *base, unsigned long offs,
123 iowrite32(value, base + (offs << 2)); 136 iowrite32(value, base + (offs << 2));
124} 137}
125 138
139static const struct sh_cmt_info sh_cmt_info[] = {
140 [SH_CMT_16BIT] = {
141 .model = SH_CMT_16BIT,
142 .width = 16,
143 .overflow_bit = 0x80,
144 .clear_bits = ~0x80,
145 .read_control = sh_cmt_read16,
146 .write_control = sh_cmt_write16,
147 .read_count = sh_cmt_read16,
148 .write_count = sh_cmt_write16,
149 },
150 [SH_CMT_32BIT] = {
151 .model = SH_CMT_32BIT,
152 .width = 32,
153 .overflow_bit = 0x8000,
154 .clear_bits = ~0xc000,
155 .read_control = sh_cmt_read16,
156 .write_control = sh_cmt_write16,
157 .read_count = sh_cmt_read32,
158 .write_count = sh_cmt_write32,
159 },
160 [SH_CMT_32BIT_FAST] = {
161 .model = SH_CMT_32BIT_FAST,
162 .width = 32,
163 .overflow_bit = 0x8000,
164 .clear_bits = ~0xc000,
165 .read_control = sh_cmt_read16,
166 .write_control = sh_cmt_write16,
167 .read_count = sh_cmt_read32,
168 .write_count = sh_cmt_write32,
169 },
170 [SH_CMT_48BIT] = {
171 .model = SH_CMT_48BIT,
172 .width = 32,
173 .overflow_bit = 0x8000,
174 .clear_bits = ~0xc000,
175 .read_control = sh_cmt_read32,
176 .write_control = sh_cmt_write32,
177 .read_count = sh_cmt_read32,
178 .write_count = sh_cmt_write32,
179 },
180 [SH_CMT_48BIT_GEN2] = {
181 .model = SH_CMT_48BIT_GEN2,
182 .width = 32,
183 .overflow_bit = 0x8000,
184 .clear_bits = ~0xc000,
185 .read_control = sh_cmt_read32,
186 .write_control = sh_cmt_write32,
187 .read_count = sh_cmt_read32,
188 .write_count = sh_cmt_write32,
189 },
190};
191
126#define CMCSR 0 /* channel register */ 192#define CMCSR 0 /* channel register */
127#define CMCNT 1 /* channel register */ 193#define CMCNT 1 /* channel register */
128#define CMCOR 2 /* channel register */ 194#define CMCOR 2 /* channel register */
129 195
130static inline unsigned long sh_cmt_read_cmstr(struct sh_cmt_channel *ch) 196static inline unsigned long sh_cmt_read_cmstr(struct sh_cmt_channel *ch)
131{ 197{
132 return ch->cmt->read_control(ch->cmt->mapbase, 0); 198 return ch->cmt->info->read_control(ch->cmt->mapbase, 0);
133} 199}
134 200
135static inline unsigned long sh_cmt_read_cmcsr(struct sh_cmt_channel *ch) 201static inline unsigned long sh_cmt_read_cmcsr(struct sh_cmt_channel *ch)
136{ 202{
137 return ch->cmt->read_control(ch->base, CMCSR); 203 return ch->cmt->info->read_control(ch->base, CMCSR);
138} 204}
139 205
140static inline unsigned long sh_cmt_read_cmcnt(struct sh_cmt_channel *ch) 206static inline unsigned long sh_cmt_read_cmcnt(struct sh_cmt_channel *ch)
141{ 207{
142 return ch->cmt->read_count(ch->base, CMCNT); 208 return ch->cmt->info->read_count(ch->base, CMCNT);
143} 209}
144 210
145static inline void sh_cmt_write_cmstr(struct sh_cmt_channel *ch, 211static inline void sh_cmt_write_cmstr(struct sh_cmt_channel *ch,
146 unsigned long value) 212 unsigned long value)
147{ 213{
148 ch->cmt->write_control(ch->cmt->mapbase, 0, value); 214 ch->cmt->info->write_control(ch->cmt->mapbase, 0, value);
149} 215}
150 216
151static inline void sh_cmt_write_cmcsr(struct sh_cmt_channel *ch, 217static inline void sh_cmt_write_cmcsr(struct sh_cmt_channel *ch,
152 unsigned long value) 218 unsigned long value)
153{ 219{
154 ch->cmt->write_control(ch->base, CMCSR, value); 220 ch->cmt->info->write_control(ch->base, CMCSR, value);
155} 221}
156 222
157static inline void sh_cmt_write_cmcnt(struct sh_cmt_channel *ch, 223static inline void sh_cmt_write_cmcnt(struct sh_cmt_channel *ch,
158 unsigned long value) 224 unsigned long value)
159{ 225{
160 ch->cmt->write_count(ch->base, CMCNT, value); 226 ch->cmt->info->write_count(ch->base, CMCNT, value);
161} 227}
162 228
163static inline void sh_cmt_write_cmcor(struct sh_cmt_channel *ch, 229static inline void sh_cmt_write_cmcor(struct sh_cmt_channel *ch,
164 unsigned long value) 230 unsigned long value)
165{ 231{
166 ch->cmt->write_count(ch->base, CMCOR, value); 232 ch->cmt->info->write_count(ch->base, CMCOR, value);
167} 233}
168 234
169static unsigned long sh_cmt_get_counter(struct sh_cmt_channel *ch, 235static unsigned long sh_cmt_get_counter(struct sh_cmt_channel *ch,
@@ -172,7 +238,7 @@ static unsigned long sh_cmt_get_counter(struct sh_cmt_channel *ch,
172 unsigned long v1, v2, v3; 238 unsigned long v1, v2, v3;
173 int o1, o2; 239 int o1, o2;
174 240
175 o1 = sh_cmt_read_cmcsr(ch) & ch->cmt->overflow_bit; 241 o1 = sh_cmt_read_cmcsr(ch) & ch->cmt->info->overflow_bit;
176 242
177 /* Make sure the timer value is stable. Stolen from acpi_pm.c */ 243 /* Make sure the timer value is stable. Stolen from acpi_pm.c */
178 do { 244 do {
@@ -180,7 +246,7 @@ static unsigned long sh_cmt_get_counter(struct sh_cmt_channel *ch,
180 v1 = sh_cmt_read_cmcnt(ch); 246 v1 = sh_cmt_read_cmcnt(ch);
181 v2 = sh_cmt_read_cmcnt(ch); 247 v2 = sh_cmt_read_cmcnt(ch);
182 v3 = sh_cmt_read_cmcnt(ch); 248 v3 = sh_cmt_read_cmcnt(ch);
183 o1 = sh_cmt_read_cmcsr(ch) & ch->cmt->overflow_bit; 249 o1 = sh_cmt_read_cmcsr(ch) & ch->cmt->info->overflow_bit;
184 } while (unlikely((o1 != o2) || (v1 > v2 && v1 < v3) 250 } while (unlikely((o1 != o2) || (v1 > v2 && v1 < v3)
185 || (v2 > v3 && v2 < v1) || (v3 > v1 && v3 < v2))); 251 || (v2 > v3 && v2 < v1) || (v3 > v1 && v3 < v2)));
186 252
@@ -227,7 +293,7 @@ static int sh_cmt_enable(struct sh_cmt_channel *ch, unsigned long *rate)
227 sh_cmt_start_stop_ch(ch, 0); 293 sh_cmt_start_stop_ch(ch, 0);
228 294
229 /* configure channel, periodic mode and maximum timeout */ 295 /* configure channel, periodic mode and maximum timeout */
230 if (ch->cmt->width == 16) { 296 if (ch->cmt->info->width == 16) {
231 *rate = clk_get_rate(ch->cmt->clk) / 512; 297 *rate = clk_get_rate(ch->cmt->clk) / 512;
232 sh_cmt_write_cmcsr(ch, 0x43); 298 sh_cmt_write_cmcsr(ch, 0x43);
233 } else { 299 } else {
@@ -405,7 +471,8 @@ static irqreturn_t sh_cmt_interrupt(int irq, void *dev_id)
405 struct sh_cmt_channel *ch = dev_id; 471 struct sh_cmt_channel *ch = dev_id;
406 472
407 /* clear flags */ 473 /* clear flags */
408 sh_cmt_write_cmcsr(ch, sh_cmt_read_cmcsr(ch) & ch->cmt->clear_bits); 474 sh_cmt_write_cmcsr(ch, sh_cmt_read_cmcsr(ch) &
475 ch->cmt->info->clear_bits);
409 476
410 /* update clock source counter to begin with if enabled 477 /* update clock source counter to begin with if enabled
411 * the wrap flag should be cleared by the timer specific 478 * the wrap flag should be cleared by the timer specific
@@ -719,10 +786,10 @@ static int sh_cmt_setup_channel(struct sh_cmt_channel *ch, unsigned int index,
719 return irq; 786 return irq;
720 } 787 }
721 788
722 if (cmt->width == (sizeof(ch->max_match_value) * 8)) 789 if (cmt->info->width == (sizeof(ch->max_match_value) * 8))
723 ch->max_match_value = ~0; 790 ch->max_match_value = ~0;
724 else 791 else
725 ch->max_match_value = (1 << cmt->width) - 1; 792 ch->max_match_value = (1 << cmt->info->width) - 1;
726 793
727 ch->match_value = ch->max_match_value; 794 ch->match_value = ch->max_match_value;
728 raw_spin_lock_init(&ch->lock); 795 raw_spin_lock_init(&ch->lock);
@@ -800,28 +867,13 @@ static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev)
800 if (ret < 0) 867 if (ret < 0)
801 goto err3; 868 goto err3;
802 869
803 if (res2 && (resource_size(res2) == 4)) { 870 /* identify the model based on the resources */
804 /* assume both CMSTR and CMCSR to be 32-bit */ 871 if (resource_size(res) == 6)
805 cmt->read_control = sh_cmt_read32; 872 cmt->info = &sh_cmt_info[SH_CMT_16BIT];
806 cmt->write_control = sh_cmt_write32; 873 else if (res2 && (resource_size(res2) == 4))
807 } else { 874 cmt->info = &sh_cmt_info[SH_CMT_48BIT_GEN2];
808 cmt->read_control = sh_cmt_read16; 875 else
809 cmt->write_control = sh_cmt_write16; 876 cmt->info = &sh_cmt_info[SH_CMT_32BIT];
810 }
811
812 if (resource_size(res) == 6) {
813 cmt->width = 16;
814 cmt->read_count = sh_cmt_read16;
815 cmt->write_count = sh_cmt_write16;
816 cmt->overflow_bit = 0x80;
817 cmt->clear_bits = ~0x80;
818 } else {
819 cmt->width = 32;
820 cmt->read_count = sh_cmt_read32;
821 cmt->write_count = sh_cmt_write32;
822 cmt->overflow_bit = 0x8000;
823 cmt->clear_bits = ~0xc000;
824 }
825 877
826 cmt->channels = kzalloc(sizeof(*cmt->channels), GFP_KERNEL); 878 cmt->channels = kzalloc(sizeof(*cmt->channels), GFP_KERNEL);
827 if (cmt->channels == NULL) { 879 if (cmt->channels == NULL) {