dmtimer.c (5515B)
1 #include <kernel.h> 2 #include <irq.h> 3 #include <dmtimer.h> 4 5 #define DMT_OVF_ENA_FLAG (1<<1) 6 #define DMT_TCLR_ST (1<<0) 7 #define DMT_TCLR_AR (1<<1) 8 9 #define DMT_1MS_TIOCP_SOFTRESET (1<<1) 10 #define DMT_1MS_TIOCP_SMARTIDLE (2<<3) 11 #define DMT_1MS_TISTAT_RESETDONE (1<<0) 12 13 /* gptimer1, gptimer2, gptimer10 */ 14 struct dm_gpt_1ms { 15 u32 tidr; 16 u32 _pad1[3]; 17 u32 tiocp_1ms_cfg; 18 u32 tistat; 19 u32 tisr; 20 u32 tier; 21 u32 twer; 22 u32 tclr; 23 u32 tcrr; 24 u32 tldr; 25 u32 ttgr; 26 u32 twps; 27 u32 tmar; 28 u32 tcar1; 29 u32 tsicr; 30 u32 tcar2; 31 u32 tpir; 32 u32 tnir; 33 u32 tcvr; 34 u32 tocr; 35 u32 towr; 36 }; 37 38 #define DMT_TIOCP_SOFTRESET (1<<0) 39 #define DMT_TIOCP_SMARTIDLE (2<<2) 40 41 /* gptimer3, gptimer4, gptimer5, gptimer6 42 * gptimer7, gptimer8, gptimer9, gptimer11 43 */ 44 struct dm_gpt { 45 u32 tidr; 46 u32 _pad1[3]; 47 u32 tiocp_cfg; 48 u32 _pad2[4]; 49 u32 irqstatus_raw; 50 u32 irqstatus; 51 u32 irqenable_set; 52 u32 irqenable_clr; 53 u32 irqwakeen; 54 u32 tclr; 55 u32 tcrr; 56 u32 tldr; 57 u32 ttgr; 58 u32 twps; 59 u32 tmar; 60 u32 tcar1; 61 u32 tsicr; 62 u32 tcar2; 63 }; 64 65 #define DMT_1MS (1<<0) 66 #define CM2_CLKSEL (1<<24) 67 68 struct dmtimer { 69 u32 flags; 70 dmtimer_callback_func callback_func; 71 union { 72 u32 *mem; 73 struct dm_gpt_1ms *dmt_1ms; 74 struct dm_gpt *dmt; 75 }; 76 /* L4PER CM2 register */ 77 u32 *cm2r; 78 } dmtimers[] = { 79 { DMT_1MS, NULL, { .mem = (u32*)0x4a318000 }, NULL }, /* GPTIMER1 */ 80 { DMT_1MS, NULL, { .mem = (u32*)0x48032000 }, (u32*)0x4a009438 }, /* GPTIMER2 */ 81 { 0, NULL, { .mem = (u32*)0x48034000 }, (u32*)0x4a009440 }, /* GPTIMER3 */ 82 { 0, NULL, { .mem = (u32*)0x48036000 }, (u32*)0x4a009448 }, /* GPTIMER4 */ 83 84 /* GPTIMER 5 - 8 are not implemented yet */ 85 { 0, NULL, { .mem = (u32*)NULL }, NULL }, /* GPTIMER5 */ 86 { 0, NULL, { .mem = (u32*)NULL }, NULL }, /* GPTIMER6 */ 87 { 0, NULL, { .mem = (u32*)NULL }, NULL }, /* GPTIMER7 */ 88 { 0, NULL, { .mem = (u32*)NULL }, NULL }, /* GPTIMER8 */ 89 90 { 0, NULL, { .mem = (u32*)0x4803e000 }, (u32*)0x4a009450 }, /* GPTIMER9 */ 91 { DMT_1MS, NULL, { .mem = (u32*)0x48086000 }, (u32*)0x4a009428 }, /* GPTIMER10 */ 92 { 0, NULL, { .mem = (u32*)0x48088000 }, (u32*)0x4a009430 } /* GPTIMER11 */ 93 }; 94 95 static void 96 dmtimer_irq_callback(u32 irq_num, struct regs *regs) 97 { 98 u32 val; 99 int id, idx; 100 101 if (irq_num < HW_IRQ(37) || irq_num > HW_IRQ(47)) 102 return; 103 104 idx = irq_num - HW_IRQ(37); 105 id = idx + 1; 106 107 if (dmtimers[idx].mem == NULL) 108 return; 109 110 /* read type of event */ 111 if (dmtimers[idx].flags & DMT_1MS) 112 val = readl(&dmtimers[idx].dmt_1ms->tisr); 113 else 114 val = readl(&dmtimers[idx].dmt->irqstatus); 115 116 if (dmtimers[idx].callback_func) 117 dmtimers[idx].callback_func(id, regs); 118 119 /* clear event by writing 1 to the bits */ 120 if (dmtimers[idx].flags & DMT_1MS) 121 writel(val, &dmtimers[idx].dmt_1ms->tisr); 122 else 123 writel(val, &dmtimers[idx].dmt->irqstatus); 124 } 125 126 static int 127 reset_timer(int id) 128 { 129 u32 val; 130 int idx; 131 132 if (id <= 0 || id > 11) 133 return -EINVAL; 134 135 idx = id - 1; 136 137 /* not implemented yet */ 138 if (dmtimers[idx].mem == NULL) 139 return -ENOSYS; 140 141 if (dmtimers[idx].flags & DMT_1MS) { 142 /* request reset */ 143 writel(DMT_1MS_TIOCP_SOFTRESET, &dmtimers[idx].dmt_1ms->tiocp_1ms_cfg); 144 /* wait until reset is done */ 145 while (!(readl(&dmtimers[idx].dmt_1ms->tistat) & DMT_1MS_TISTAT_RESETDONE)) 146 ; 147 } else { 148 /* request reset */ 149 writel(DMT_TIOCP_SOFTRESET, &dmtimers[idx].dmt->tiocp_cfg); 150 /* wait until reset is done */ 151 while (readl(&dmtimers[idx].dmt->tiocp_cfg) & DMT_TIOCP_SOFTRESET) 152 ; 153 } 154 155 /* enable 32KHz clock */ 156 if (dmtimers[idx].cm2r) { 157 val = readl(dmtimers[idx].cm2r); 158 val |= CM2_CLKSEL; 159 writel(val, dmtimers[idx].cm2r); 160 } 161 162 return 0; 163 } 164 165 int 166 dmtimer_trigger(int id) 167 { 168 int idx; 169 170 if (id <= 0 || id > 11) 171 return -EINVAL; 172 173 idx = id - 1; 174 175 /* not implemented yet */ 176 if (dmtimers[idx].mem == NULL) 177 return -ENOSYS; 178 179 /* manually overflow the timer */ 180 if (dmtimers[idx].flags & DMT_1MS) 181 writel(0xffffffff, &dmtimers[idx].dmt_1ms->tcrr); 182 else 183 writel(0xffffffff, &dmtimers[idx].dmt->tcrr); 184 185 return 0; 186 } 187 188 int 189 dmtimer_register(int id, dmtimer_callback_func func, u32 ms) 190 { 191 int ret, idx; 192 u32 val; 193 194 if (id <= 0 || id > 11 || ms == 0 || func == NULL) 195 return -EINVAL; 196 197 idx = id - 1; 198 199 /* not implemented yet */ 200 if (dmtimers[idx].mem == NULL) 201 return -ENOSYS; 202 203 ret = reset_timer(id); 204 if (ret) 205 return ret; 206 207 ret = irq_register(HW_IRQ(37) + idx, dmtimer_irq_callback); 208 if (ret) 209 return ret; 210 dmtimers[idx].callback_func = func; 211 212 if (dmtimers[idx].flags & DMT_1MS) { 213 /* enable start-idle */ 214 writel(DMT_1MS_TIOCP_SMARTIDLE, &dmtimers[idx].dmt_1ms->tiocp_1ms_cfg); 215 216 /* set milliseconds */ 217 val = 0xffffffff; 218 val -= ms * 32; 219 writel(val, &dmtimers[idx].dmt_1ms->tldr); 220 221 /* writing to TTGR causes TCRR to be loaded from TLDR */ 222 writel(1, &dmtimers[idx].dmt_1ms->ttgr); 223 /* enable overflow interrupt */ 224 writel(DMT_OVF_ENA_FLAG, &dmtimers[idx].dmt_1ms->tier); 225 /* start timer and enable autoreload */ 226 writel(DMT_TCLR_ST | DMT_TCLR_AR, &dmtimers[idx].dmt_1ms->tclr); 227 } else { 228 /* enable start-idle */ 229 writel(DMT_TIOCP_SMARTIDLE, &dmtimers[idx].dmt->tiocp_cfg); 230 231 /* set milliseconds */ 232 val = 0xffffffff; 233 val -= ms * 32; 234 writel(val, &dmtimers[idx].dmt->tldr); 235 236 /* writing to TTGR causes TCRR to be loaded from TLDR */ 237 writel(1, &dmtimers[idx].dmt->ttgr); 238 /* enable overflow interrupt */ 239 writel(DMT_OVF_ENA_FLAG, &dmtimers[idx].dmt->irqenable_set); 240 /* start timer and enable autoreload */ 241 writel(DMT_TCLR_ST | DMT_TCLR_AR, &dmtimers[idx].dmt->tclr); 242 } 243 244 return 0; 245 } 246 247 void 248 dmtimer_init(void) 249 { 250 int i; 251 for (i = 1; i <= 11; i++) 252 reset_timer(i); 253 }