1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * PCM timer handling on ctxfi 4 */ 5 6 #include <linux/slab.h> 7 #include <linux/math64.h> 8 #include <linux/moduleparam.h> 9 #include <sound/core.h> 10 #include <sound/pcm.h> 11 #include "ctatc.h" 12 #include "cthardware.h" 13 #include "cttimer.h" 14 15 static bool use_system_timer; 16 MODULE_PARM_DESC(use_system_timer, "Force to use system-timer"); 17 module_param(use_system_timer, bool, 0444); 18 19 struct ct_timer_ops { 20 void (*init)(struct ct_timer_instance *); 21 void (*prepare)(struct ct_timer_instance *); 22 void (*start)(struct ct_timer_instance *); 23 void (*stop)(struct ct_timer_instance *); 24 void (*free_instance)(struct ct_timer_instance *); 25 void (*interrupt)(struct ct_timer *); 26 void (*free_global)(struct ct_timer *); 27 }; 28 29 /* timer instance -- assigned to each PCM stream */ 30 struct ct_timer_instance { 31 spinlock_t lock; 32 struct ct_timer *timer_base; 33 struct ct_atc_pcm *apcm; 34 struct snd_pcm_substream *substream; 35 struct timer_list timer; 36 struct list_head instance_list; 37 struct list_head running_list; 38 unsigned int position; 39 unsigned int frag_count; 40 unsigned int running:1; 41 unsigned int need_update:1; 42 }; 43 44 /* timer instance manager */ 45 struct ct_timer { 46 spinlock_t lock; /* global timer lock (for xfitimer) */ 47 spinlock_t list_lock; /* lock for instance list */ 48 struct ct_atc *atc; 49 const struct ct_timer_ops *ops; 50 struct list_head instance_head; 51 struct list_head running_head; 52 unsigned int wc; /* current wallclock */ 53 unsigned int irq_handling:1; /* in IRQ handling */ 54 unsigned int reprogram:1; /* need to reprogram the internval */ 55 unsigned int running:1; /* global timer running */ 56 }; 57 58 59 /* 60 * system-timer-based updates 61 */ 62 63 static void ct_systimer_callback(struct timer_list *t) 64 { 65 struct ct_timer_instance *ti = timer_container_of(ti, t, timer); 66 struct snd_pcm_substream *substream = ti->substream; 67 struct snd_pcm_runtime *runtime = substream->runtime; 68 struct ct_atc_pcm *apcm = ti->apcm; 69 unsigned int period_size = runtime->period_size; 70 unsigned int buffer_size = runtime->buffer_size; 71 unsigned int position, dist, interval; 72 73 position = substream->ops->pointer(substream); 74 dist = (position + buffer_size - ti->position) % buffer_size; 75 if (dist >= period_size || 76 position / period_size != ti->position / period_size) { 77 apcm->interrupt(apcm); 78 ti->position = position; 79 } 80 /* Add extra HZ*5/1000 to avoid overrun issue when recording 81 * at 8kHz in 8-bit format or at 88kHz in 24-bit format. */ 82 interval = ((period_size - (position % period_size)) 83 * HZ + (runtime->rate - 1)) / runtime->rate + HZ * 5 / 1000; 84 guard(spinlock_irqsave)(&ti->lock); 85 if (ti->running) 86 mod_timer(&ti->timer, jiffies + interval); 87 } 88 89 static void ct_systimer_init(struct ct_timer_instance *ti) 90 { 91 timer_setup(&ti->timer, ct_systimer_callback, 0); 92 } 93 94 static void ct_systimer_start(struct ct_timer_instance *ti) 95 { 96 struct snd_pcm_runtime *runtime = ti->substream->runtime; 97 98 guard(spinlock_irqsave)(&ti->lock); 99 ti->running = 1; 100 mod_timer(&ti->timer, 101 jiffies + (runtime->period_size * HZ + 102 (runtime->rate - 1)) / runtime->rate); 103 } 104 105 static void ct_systimer_stop(struct ct_timer_instance *ti) 106 { 107 guard(spinlock_irqsave)(&ti->lock); 108 ti->running = 0; 109 timer_delete(&ti->timer); 110 } 111 112 static void ct_systimer_prepare(struct ct_timer_instance *ti) 113 { 114 ct_systimer_stop(ti); 115 timer_delete_sync_try(&ti->timer); 116 } 117 118 #define ct_systimer_free ct_systimer_prepare 119 120 static const struct ct_timer_ops ct_systimer_ops = { 121 .init = ct_systimer_init, 122 .free_instance = ct_systimer_free, 123 .prepare = ct_systimer_prepare, 124 .start = ct_systimer_start, 125 .stop = ct_systimer_stop, 126 }; 127 128 129 /* 130 * Handling multiple streams using a global emu20k1 timer irq 131 */ 132 133 #define CT_TIMER_FREQ 48000 134 #define MIN_TICKS 1 135 #define MAX_TICKS ((1 << 13) - 1) 136 137 static void ct_xfitimer_irq_rearm(struct ct_timer *atimer, int ticks) 138 { 139 struct hw *hw = atimer->atc->hw; 140 if (ticks > MAX_TICKS) 141 ticks = MAX_TICKS; 142 hw->set_timer_tick(hw, ticks); 143 if (!atimer->running) 144 hw->set_timer_irq(hw, 1); 145 atimer->running = 1; 146 } 147 148 static void ct_xfitimer_irq_stop(struct ct_timer *atimer) 149 { 150 if (atimer->running) { 151 struct hw *hw = atimer->atc->hw; 152 hw->set_timer_irq(hw, 0); 153 hw->set_timer_tick(hw, 0); 154 atimer->running = 0; 155 } 156 } 157 158 static inline unsigned int ct_xfitimer_get_wc(struct ct_timer *atimer) 159 { 160 struct hw *hw = atimer->atc->hw; 161 return hw->get_wc(hw); 162 } 163 164 /* 165 * reprogram the timer interval; 166 * checks the running instance list and determines the next timer interval. 167 * also updates the each stream position, returns the number of streams 168 * to call snd_pcm_period_elapsed() appropriately 169 * 170 * call this inside the lock and irq disabled 171 */ 172 static int ct_xfitimer_reprogram(struct ct_timer *atimer, int can_update) 173 { 174 struct ct_timer_instance *ti; 175 unsigned int min_intr = (unsigned int)-1; 176 int updates = 0; 177 unsigned int wc, diff; 178 179 if (list_empty(&atimer->running_head)) { 180 ct_xfitimer_irq_stop(atimer); 181 atimer->reprogram = 0; /* clear flag */ 182 return 0; 183 } 184 185 wc = ct_xfitimer_get_wc(atimer); 186 diff = wc - atimer->wc; 187 atimer->wc = wc; 188 list_for_each_entry(ti, &atimer->running_head, running_list) { 189 if (ti->frag_count > diff) 190 ti->frag_count -= diff; 191 else { 192 unsigned int pos; 193 unsigned int period_size, rate; 194 195 period_size = ti->substream->runtime->period_size; 196 rate = ti->substream->runtime->rate; 197 pos = ti->substream->ops->pointer(ti->substream); 198 if (pos / period_size != ti->position / period_size) { 199 ti->need_update = 1; 200 ti->position = pos; 201 updates++; 202 } 203 pos %= period_size; 204 pos = period_size - pos; 205 ti->frag_count = div_u64((u64)pos * CT_TIMER_FREQ + 206 rate - 1, rate); 207 } 208 if (ti->need_update && !can_update) 209 min_intr = 0; /* pending to the next irq */ 210 if (ti->frag_count < min_intr) 211 min_intr = ti->frag_count; 212 } 213 214 if (min_intr < MIN_TICKS) 215 min_intr = MIN_TICKS; 216 ct_xfitimer_irq_rearm(atimer, min_intr); 217 atimer->reprogram = 0; /* clear flag */ 218 return updates; 219 } 220 221 /* look through the instance list and call period_elapsed if needed */ 222 static void ct_xfitimer_check_period(struct ct_timer *atimer) 223 { 224 struct ct_timer_instance *ti; 225 226 guard(spinlock_irqsave)(&atimer->list_lock); 227 list_for_each_entry(ti, &atimer->instance_head, instance_list) { 228 if (ti->running && ti->need_update) { 229 ti->need_update = 0; 230 ti->apcm->interrupt(ti->apcm); 231 } 232 } 233 } 234 235 /* Handle timer-interrupt */ 236 static void ct_xfitimer_callback(struct ct_timer *atimer) 237 { 238 int update; 239 240 guard(spinlock_irqsave)(&atimer->lock); 241 atimer->irq_handling = 1; 242 do { 243 update = ct_xfitimer_reprogram(atimer, 1); 244 spin_unlock(&atimer->lock); 245 if (update) 246 ct_xfitimer_check_period(atimer); 247 spin_lock(&atimer->lock); 248 } while (atimer->reprogram); 249 atimer->irq_handling = 0; 250 } 251 252 static void ct_xfitimer_prepare(struct ct_timer_instance *ti) 253 { 254 ti->frag_count = ti->substream->runtime->period_size; 255 ti->running = 0; 256 ti->need_update = 0; 257 } 258 259 260 /* start/stop the timer */ 261 static void ct_xfitimer_update(struct ct_timer *atimer) 262 { 263 guard(spinlock_irqsave)(&atimer->lock); 264 if (atimer->irq_handling) { 265 /* reached from IRQ handler; let it handle later */ 266 atimer->reprogram = 1; 267 return; 268 } 269 270 ct_xfitimer_irq_stop(atimer); 271 ct_xfitimer_reprogram(atimer, 0); 272 } 273 274 static void ct_xfitimer_start(struct ct_timer_instance *ti) 275 { 276 struct ct_timer *atimer = ti->timer_base; 277 278 scoped_guard(spinlock_irqsave, &atimer->lock) { 279 if (list_empty(&ti->running_list)) 280 atimer->wc = ct_xfitimer_get_wc(atimer); 281 ti->running = 1; 282 ti->need_update = 0; 283 list_add(&ti->running_list, &atimer->running_head); 284 } 285 ct_xfitimer_update(atimer); 286 } 287 288 static void ct_xfitimer_stop(struct ct_timer_instance *ti) 289 { 290 struct ct_timer *atimer = ti->timer_base; 291 292 scoped_guard(spinlock_irqsave, &atimer->lock) { 293 list_del_init(&ti->running_list); 294 ti->running = 0; 295 } 296 ct_xfitimer_update(atimer); 297 } 298 299 static void ct_xfitimer_free_global(struct ct_timer *atimer) 300 { 301 ct_xfitimer_irq_stop(atimer); 302 } 303 304 static const struct ct_timer_ops ct_xfitimer_ops = { 305 .prepare = ct_xfitimer_prepare, 306 .start = ct_xfitimer_start, 307 .stop = ct_xfitimer_stop, 308 .interrupt = ct_xfitimer_callback, 309 .free_global = ct_xfitimer_free_global, 310 }; 311 312 /* 313 * timer instance 314 */ 315 316 struct ct_timer_instance * 317 ct_timer_instance_new(struct ct_timer *atimer, struct ct_atc_pcm *apcm) 318 { 319 struct ct_timer_instance *ti; 320 321 ti = kzalloc(sizeof(*ti), GFP_KERNEL); 322 if (!ti) 323 return NULL; 324 spin_lock_init(&ti->lock); 325 INIT_LIST_HEAD(&ti->instance_list); 326 INIT_LIST_HEAD(&ti->running_list); 327 ti->timer_base = atimer; 328 ti->apcm = apcm; 329 ti->substream = apcm->substream; 330 if (atimer->ops->init) 331 atimer->ops->init(ti); 332 333 scoped_guard(spinlock_irq, &atimer->list_lock) { 334 list_add(&ti->instance_list, &atimer->instance_head); 335 } 336 337 return ti; 338 } 339 340 void ct_timer_prepare(struct ct_timer_instance *ti) 341 { 342 if (ti->timer_base->ops->prepare) 343 ti->timer_base->ops->prepare(ti); 344 ti->position = 0; 345 ti->running = 0; 346 } 347 348 void ct_timer_start(struct ct_timer_instance *ti) 349 { 350 struct ct_timer *atimer = ti->timer_base; 351 atimer->ops->start(ti); 352 } 353 354 void ct_timer_stop(struct ct_timer_instance *ti) 355 { 356 struct ct_timer *atimer = ti->timer_base; 357 atimer->ops->stop(ti); 358 } 359 360 void ct_timer_instance_free(struct ct_timer_instance *ti) 361 { 362 struct ct_timer *atimer = ti->timer_base; 363 364 atimer->ops->stop(ti); /* to be sure */ 365 if (atimer->ops->free_instance) 366 atimer->ops->free_instance(ti); 367 368 scoped_guard(spinlock_irq, &atimer->list_lock) { 369 list_del(&ti->instance_list); 370 } 371 372 kfree(ti); 373 } 374 375 /* 376 * timer manager 377 */ 378 379 static void ct_timer_interrupt(void *data, unsigned int status) 380 { 381 struct ct_timer *timer = data; 382 383 /* Interval timer interrupt */ 384 if ((status & IT_INT) && timer->ops->interrupt) 385 timer->ops->interrupt(timer); 386 } 387 388 struct ct_timer *ct_timer_new(struct ct_atc *atc) 389 { 390 struct ct_timer *atimer; 391 struct hw *hw; 392 393 atimer = kzalloc(sizeof(*atimer), GFP_KERNEL); 394 if (!atimer) 395 return NULL; 396 spin_lock_init(&atimer->lock); 397 spin_lock_init(&atimer->list_lock); 398 INIT_LIST_HEAD(&atimer->instance_head); 399 INIT_LIST_HEAD(&atimer->running_head); 400 atimer->atc = atc; 401 hw = atc->hw; 402 if (!use_system_timer && hw->set_timer_irq) { 403 dev_info(atc->card->dev, "Use xfi-native timer\n"); 404 atimer->ops = &ct_xfitimer_ops; 405 hw->irq_callback_data = atimer; 406 hw->irq_callback = ct_timer_interrupt; 407 } else { 408 dev_info(atc->card->dev, "Use system timer\n"); 409 atimer->ops = &ct_systimer_ops; 410 } 411 return atimer; 412 } 413 414 void ct_timer_free(struct ct_timer *atimer) 415 { 416 struct hw *hw = atimer->atc->hw; 417 hw->irq_callback = NULL; 418 if (atimer->ops->free_global) 419 atimer->ops->free_global(atimer); 420 kfree(atimer); 421 } 422 423