imx_gpt.c (b01422622b7c7293196fdaf1dbb4f495af44ecf9) | imx_gpt.c (1b914994ea5e995f36fe751f7ed1d8858a87b032) |
---|---|
1/* 2 * IMX GPT Timer 3 * 4 * Copyright (c) 2008 OK Labs 5 * Copyright (c) 2011 NICTA Pty Ltd 6 * Originally written by Hans Jiang 7 * Updated by Peter Chubb 8 * Updated by Jean-Christophe Dubois <jcd@tribudubois.net> 9 * 10 * This code is licensed under GPL version 2 or later. See 11 * the COPYING file in the top-level directory. 12 * 13 */ 14 15#include "qemu/osdep.h" 16#include "hw/irq.h" 17#include "hw/timer/imx_gpt.h" 18#include "migration/vmstate.h" | 1/* 2 * IMX GPT Timer 3 * 4 * Copyright (c) 2008 OK Labs 5 * Copyright (c) 2011 NICTA Pty Ltd 6 * Originally written by Hans Jiang 7 * Updated by Peter Chubb 8 * Updated by Jean-Christophe Dubois <jcd@tribudubois.net> 9 * 10 * This code is licensed under GPL version 2 or later. See 11 * the COPYING file in the top-level directory. 12 * 13 */ 14 15#include "qemu/osdep.h" 16#include "hw/irq.h" 17#include "hw/timer/imx_gpt.h" 18#include "migration/vmstate.h" |
19#include "qemu/main-loop.h" | |
20#include "qemu/module.h" 21#include "qemu/log.h" 22 23#ifndef DEBUG_IMX_GPT 24#define DEBUG_IMX_GPT 0 25#endif 26 27#define DPRINTF(fmt, args...) \ --- 94 unchanged lines hidden (view full) --- 122 CLK_IPG_HIGH, /* 010 ipg_clk_highfreq */ 123 CLK_EXT, /* 011 External clock */ 124 CLK_32k, /* 100 ipg_clk_32k */ 125 CLK_HIGH, /* 101 reference clock */ 126 CLK_NONE, /* 110 not defined */ 127 CLK_NONE, /* 111 not defined */ 128}; 129 | 19#include "qemu/module.h" 20#include "qemu/log.h" 21 22#ifndef DEBUG_IMX_GPT 23#define DEBUG_IMX_GPT 0 24#endif 25 26#define DPRINTF(fmt, args...) \ --- 94 unchanged lines hidden (view full) --- 121 CLK_IPG_HIGH, /* 010 ipg_clk_highfreq */ 122 CLK_EXT, /* 011 External clock */ 123 CLK_32k, /* 100 ipg_clk_32k */ 124 CLK_HIGH, /* 101 reference clock */ 125 CLK_NONE, /* 110 not defined */ 126 CLK_NONE, /* 111 not defined */ 127}; 128 |
129/* Must be called from within ptimer_transaction_begin/commit block */ |
|
130static void imx_gpt_set_freq(IMXGPTState *s) 131{ 132 uint32_t clksrc = extract32(s->cr, GPT_CR_CLKSRC_SHIFT, 3); 133 134 s->freq = imx_ccm_get_clock_frequency(s->ccm, 135 s->clocks[clksrc]) / (1 + s->pr); 136 137 DPRINTF("Setting clksrc %d to frequency %d\n", clksrc, s->freq); --- 24 unchanged lines hidden (view full) --- 162{ 163 if ((count < reg) && (timeout > reg)) { 164 timeout = reg; 165 } 166 167 return timeout; 168} 169 | 130static void imx_gpt_set_freq(IMXGPTState *s) 131{ 132 uint32_t clksrc = extract32(s->cr, GPT_CR_CLKSRC_SHIFT, 3); 133 134 s->freq = imx_ccm_get_clock_frequency(s->ccm, 135 s->clocks[clksrc]) / (1 + s->pr); 136 137 DPRINTF("Setting clksrc %d to frequency %d\n", clksrc, s->freq); --- 24 unchanged lines hidden (view full) --- 162{ 163 if ((count < reg) && (timeout > reg)) { 164 timeout = reg; 165 } 166 167 return timeout; 168} 169 |
170/* Must be called from within ptimer_transaction_begin/commit block */ |
|
170static void imx_gpt_compute_next_timeout(IMXGPTState *s, bool event) 171{ 172 uint32_t timeout = GPT_TIMER_MAX; 173 uint32_t count; 174 long long limit; 175 176 if (!(s->cr & GPT_CR_EN)) { 177 /* if not enabled just return */ --- 130 unchanged lines hidden (view full) --- 308 DPRINTF("(%s) = 0x%08x\n", imx_gpt_reg_name(offset >> 2), reg_value); 309 310 return reg_value; 311} 312 313 314static void imx_gpt_reset_common(IMXGPTState *s, bool is_soft_reset) 315{ | 171static void imx_gpt_compute_next_timeout(IMXGPTState *s, bool event) 172{ 173 uint32_t timeout = GPT_TIMER_MAX; 174 uint32_t count; 175 long long limit; 176 177 if (!(s->cr & GPT_CR_EN)) { 178 /* if not enabled just return */ --- 130 unchanged lines hidden (view full) --- 309 DPRINTF("(%s) = 0x%08x\n", imx_gpt_reg_name(offset >> 2), reg_value); 310 311 return reg_value; 312} 313 314 315static void imx_gpt_reset_common(IMXGPTState *s, bool is_soft_reset) 316{ |
317 ptimer_transaction_begin(s->timer); |
|
316 /* stop timer */ 317 ptimer_stop(s->timer); 318 319 /* Soft reset and hard reset differ only in their handling of the CR 320 * register -- soft reset preserves the values of some bits there. 321 */ 322 if (is_soft_reset) { 323 /* Clear all CR bits except those that are preserved by soft reset. */ --- 21 unchanged lines hidden (view full) --- 345 346 /* reset the limit to GPT_TIMER_MAX */ 347 ptimer_set_limit(s->timer, GPT_TIMER_MAX, 1); 348 349 /* if the timer is still enabled, restart it */ 350 if (s->freq && (s->cr & GPT_CR_EN)) { 351 ptimer_run(s->timer, 1); 352 } | 318 /* stop timer */ 319 ptimer_stop(s->timer); 320 321 /* Soft reset and hard reset differ only in their handling of the CR 322 * register -- soft reset preserves the values of some bits there. 323 */ 324 if (is_soft_reset) { 325 /* Clear all CR bits except those that are preserved by soft reset. */ --- 21 unchanged lines hidden (view full) --- 347 348 /* reset the limit to GPT_TIMER_MAX */ 349 ptimer_set_limit(s->timer, GPT_TIMER_MAX, 1); 350 351 /* if the timer is still enabled, restart it */ 352 if (s->freq && (s->cr & GPT_CR_EN)) { 353 ptimer_run(s->timer, 1); 354 } |
355 ptimer_transaction_commit(s->timer); |
|
353} 354 355static void imx_gpt_soft_reset(DeviceState *dev) 356{ 357 IMXGPTState *s = IMX_GPT(dev); 358 imx_gpt_reset_common(s, true); 359} 360 --- 16 unchanged lines hidden (view full) --- 377 case 0: 378 oldreg = s->cr; 379 s->cr = value & ~0x7c14; 380 if (s->cr & GPT_CR_SWR) { /* force reset */ 381 /* handle the reset */ 382 imx_gpt_soft_reset(DEVICE(s)); 383 } else { 384 /* set our freq, as the source might have changed */ | 356} 357 358static void imx_gpt_soft_reset(DeviceState *dev) 359{ 360 IMXGPTState *s = IMX_GPT(dev); 361 imx_gpt_reset_common(s, true); 362} 363 --- 16 unchanged lines hidden (view full) --- 380 case 0: 381 oldreg = s->cr; 382 s->cr = value & ~0x7c14; 383 if (s->cr & GPT_CR_SWR) { /* force reset */ 384 /* handle the reset */ 385 imx_gpt_soft_reset(DEVICE(s)); 386 } else { 387 /* set our freq, as the source might have changed */ |
388 ptimer_transaction_begin(s->timer); |
|
385 imx_gpt_set_freq(s); 386 387 if ((oldreg ^ s->cr) & GPT_CR_EN) { 388 if (s->cr & GPT_CR_EN) { 389 if (s->cr & GPT_CR_ENMOD) { 390 s->next_timeout = GPT_TIMER_MAX; 391 ptimer_set_count(s->timer, GPT_TIMER_MAX); 392 imx_gpt_compute_next_timeout(s, false); 393 } 394 ptimer_run(s->timer, 1); 395 } else { 396 /* stop timer */ 397 ptimer_stop(s->timer); 398 } 399 } | 389 imx_gpt_set_freq(s); 390 391 if ((oldreg ^ s->cr) & GPT_CR_EN) { 392 if (s->cr & GPT_CR_EN) { 393 if (s->cr & GPT_CR_ENMOD) { 394 s->next_timeout = GPT_TIMER_MAX; 395 ptimer_set_count(s->timer, GPT_TIMER_MAX); 396 imx_gpt_compute_next_timeout(s, false); 397 } 398 ptimer_run(s->timer, 1); 399 } else { 400 /* stop timer */ 401 ptimer_stop(s->timer); 402 } 403 } |
404 ptimer_transaction_commit(s->timer); |
|
400 } 401 break; 402 403 case 1: /* Prescaler */ 404 s->pr = value & 0xfff; | 405 } 406 break; 407 408 case 1: /* Prescaler */ 409 s->pr = value & 0xfff; |
410 ptimer_transaction_begin(s->timer); |
|
405 imx_gpt_set_freq(s); | 411 imx_gpt_set_freq(s); |
412 ptimer_transaction_commit(s->timer); |
|
406 break; 407 408 case 2: /* SR */ 409 s->sr &= ~(value & 0x3f); 410 imx_gpt_update_int(s); 411 break; 412 413 case 3: /* IR -- interrupt register */ 414 s->ir = value & 0x3f; 415 imx_gpt_update_int(s); 416 | 413 break; 414 415 case 2: /* SR */ 416 s->sr &= ~(value & 0x3f); 417 imx_gpt_update_int(s); 418 break; 419 420 case 3: /* IR -- interrupt register */ 421 s->ir = value & 0x3f; 422 imx_gpt_update_int(s); 423 |
424 ptimer_transaction_begin(s->timer); |
|
417 imx_gpt_compute_next_timeout(s, false); | 425 imx_gpt_compute_next_timeout(s, false); |
426 ptimer_transaction_commit(s->timer); |
|
418 419 break; 420 421 case 4: /* OCR1 -- output compare register */ 422 s->ocr1 = value; 423 | 427 428 break; 429 430 case 4: /* OCR1 -- output compare register */ 431 s->ocr1 = value; 432 |
433 ptimer_transaction_begin(s->timer); |
|
424 /* In non-freerun mode, reset count when this register is written */ 425 if (!(s->cr & GPT_CR_FRR)) { 426 s->next_timeout = GPT_TIMER_MAX; 427 ptimer_set_limit(s->timer, GPT_TIMER_MAX, 1); 428 } 429 430 /* compute the new timeout */ 431 imx_gpt_compute_next_timeout(s, false); | 434 /* In non-freerun mode, reset count when this register is written */ 435 if (!(s->cr & GPT_CR_FRR)) { 436 s->next_timeout = GPT_TIMER_MAX; 437 ptimer_set_limit(s->timer, GPT_TIMER_MAX, 1); 438 } 439 440 /* compute the new timeout */ 441 imx_gpt_compute_next_timeout(s, false); |
442 ptimer_transaction_commit(s->timer); |
|
432 433 break; 434 435 case 5: /* OCR2 -- output compare register */ 436 s->ocr2 = value; 437 438 /* compute the new timeout */ | 443 444 break; 445 446 case 5: /* OCR2 -- output compare register */ 447 s->ocr2 = value; 448 449 /* compute the new timeout */ |
450 ptimer_transaction_begin(s->timer); |
|
439 imx_gpt_compute_next_timeout(s, false); | 451 imx_gpt_compute_next_timeout(s, false); |
452 ptimer_transaction_commit(s->timer); |
|
440 441 break; 442 443 case 6: /* OCR3 -- output compare register */ 444 s->ocr3 = value; 445 446 /* compute the new timeout */ | 453 454 break; 455 456 case 6: /* OCR3 -- output compare register */ 457 s->ocr3 = value; 458 459 /* compute the new timeout */ |
460 ptimer_transaction_begin(s->timer); |
|
447 imx_gpt_compute_next_timeout(s, false); | 461 imx_gpt_compute_next_timeout(s, false); |
462 ptimer_transaction_commit(s->timer); |
|
448 449 break; 450 451 default: 452 qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Bad register at offset 0x%" 453 HWADDR_PRIx "\n", TYPE_IMX_GPT, __func__, offset); 454 break; 455 } --- 23 unchanged lines hidden (view full) --- 479 .endianness = DEVICE_NATIVE_ENDIAN, 480}; 481 482 483static void imx_gpt_realize(DeviceState *dev, Error **errp) 484{ 485 IMXGPTState *s = IMX_GPT(dev); 486 SysBusDevice *sbd = SYS_BUS_DEVICE(dev); | 463 464 break; 465 466 default: 467 qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Bad register at offset 0x%" 468 HWADDR_PRIx "\n", TYPE_IMX_GPT, __func__, offset); 469 break; 470 } --- 23 unchanged lines hidden (view full) --- 494 .endianness = DEVICE_NATIVE_ENDIAN, 495}; 496 497 498static void imx_gpt_realize(DeviceState *dev, Error **errp) 499{ 500 IMXGPTState *s = IMX_GPT(dev); 501 SysBusDevice *sbd = SYS_BUS_DEVICE(dev); |
487 QEMUBH *bh; | |
488 489 sysbus_init_irq(sbd, &s->irq); 490 memory_region_init_io(&s->iomem, OBJECT(s), &imx_gpt_ops, s, TYPE_IMX_GPT, 491 0x00001000); 492 sysbus_init_mmio(sbd, &s->iomem); 493 | 502 503 sysbus_init_irq(sbd, &s->irq); 504 memory_region_init_io(&s->iomem, OBJECT(s), &imx_gpt_ops, s, TYPE_IMX_GPT, 505 0x00001000); 506 sysbus_init_mmio(sbd, &s->iomem); 507 |
494 bh = qemu_bh_new(imx_gpt_timeout, s); 495 s->timer = ptimer_init_with_bh(bh, PTIMER_POLICY_DEFAULT); | 508 s->timer = ptimer_init(imx_gpt_timeout, s, PTIMER_POLICY_DEFAULT); |
496} 497 498static void imx_gpt_class_init(ObjectClass *klass, void *data) 499{ 500 DeviceClass *dc = DEVICE_CLASS(klass); 501 502 dc->realize = imx_gpt_realize; 503 dc->reset = imx_gpt_reset; --- 67 unchanged lines hidden --- | 509} 510 511static void imx_gpt_class_init(ObjectClass *klass, void *data) 512{ 513 DeviceClass *dc = DEVICE_CLASS(klass); 514 515 dc->realize = imx_gpt_realize; 516 dc->reset = imx_gpt_reset; --- 67 unchanged lines hidden --- |