dv-mn103tim.c revision 1.1.1.1
1/* This file is part of the program GDB, the GNU debugger. 2 3 Copyright (C) 1998, 2003, 2007, 2008, 2009, 2010, 2011 4 Free Software Foundation, Inc. 5 Contributed by Cygnus Solutions. 6 7 This program is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 3 of the License, or 10 (at your option) any later version. 11 12 This program is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this program. If not, see <http://www.gnu.org/licenses/>. 19 20 */ 21 22#include "sim-main.h" 23#include "hw-main.h" 24#include "sim-assert.h" 25 26/* DEVICE 27 28 29 mn103tim - mn103002 timers (8 and 16 bit) 30 31 32 DESCRIPTION 33 34 Implements the mn103002 8 and 16 bit timers as described in the mn103002 user guide. 35 36 37 PROPERTIES 38 39 reg = <8bit-timers-addr> <8bit-timers-size> <16bit-timers-addr> <16bit-timers-size> 40 41 42 BUGS 43 44 */ 45 46 47/* The timers' register address blocks */ 48 49struct mn103tim_block { 50 unsigned_word base; 51 unsigned_word bound; 52}; 53 54enum { TIMER8_BLOCK, TIMER16_BLOCK, NR_TIMER_BLOCKS }; 55 56enum timer_register_types { 57 FIRST_MODE_REG = 0, 58 TM0MD = FIRST_MODE_REG, 59 TM1MD, 60 TM2MD, 61 TM3MD, 62 TM4MD, 63 TM5MD, 64 TM6MD, 65 LAST_MODE_REG = TM6MD, 66 FIRST_BASE_REG, 67 TM0BR = FIRST_BASE_REG, 68 TM1BR, 69 TM2BR, 70 TM3BR, 71 TM4BR, 72 TM5BR, 73 LAST_BASE_REG = TM5BR, 74 FIRST_COUNTER, 75 TM0BC = FIRST_COUNTER, 76 TM1BC, 77 TM2BC, 78 TM3BC, 79 TM4BC, 80 TM5BC, 81 TM6BC, 82 LAST_COUNTER = TM6BC, 83 TM6MDA, 84 TM6MDB, 85 TM6CA, 86 TM6CB, 87 LAST_TIMER_REG = TM6BC, 88}; 89 90 91/* Don't include timer 6 because it's handled specially. */ 92#define NR_8BIT_TIMERS 4 93#define NR_16BIT_TIMERS 2 94#define NR_REG_TIMERS 6 /* Exclude timer 6 - it's handled specially. */ 95#define NR_TIMERS 7 96 97typedef struct _mn10300_timer_regs { 98 unsigned32 base; 99 unsigned8 mode; 100} mn10300_timer_regs; 101 102typedef struct _mn10300_timer { 103 unsigned32 div_ratio, start; 104 struct hw_event *event; 105} mn10300_timer; 106 107 108struct mn103tim { 109 struct mn103tim_block block[NR_TIMER_BLOCKS]; 110 mn10300_timer_regs reg[NR_REG_TIMERS]; 111 mn10300_timer timer[NR_TIMERS]; 112 113 /* treat timer 6 registers specially. */ 114 unsigned16 tm6md0, tm6md1, tm6bc, tm6ca, tm6cb; 115 unsigned8 tm6mda, tm6mdb; /* compare/capture mode regs for timer 6 */ 116}; 117 118/* output port ID's */ 119 120/* for mn103002 */ 121enum { 122 TIMER0_UFLOW, 123 TIMER1_UFLOW, 124 TIMER2_UFLOW, 125 TIMER3_UFLOW, 126 TIMER4_UFLOW, 127 TIMER5_UFLOW, 128 TIMER6_UFLOW, 129 TIMER6_CMPA, 130 TIMER6_CMPB, 131}; 132 133 134static const struct hw_port_descriptor mn103tim_ports[] = { 135 136 { "timer-0-underflow", TIMER0_UFLOW, 0, output_port, }, 137 { "timer-1-underflow", TIMER1_UFLOW, 0, output_port, }, 138 { "timer-2-underflow", TIMER2_UFLOW, 0, output_port, }, 139 { "timer-3-underflow", TIMER3_UFLOW, 0, output_port, }, 140 { "timer-4-underflow", TIMER4_UFLOW, 0, output_port, }, 141 { "timer-5-underflow", TIMER5_UFLOW, 0, output_port, }, 142 143 { "timer-6-underflow", TIMER6_UFLOW, 0, output_port, }, 144 { "timer-6-compare-a", TIMER6_CMPA, 0, output_port, }, 145 { "timer-6-compare-b", TIMER6_CMPB, 0, output_port, }, 146 147 { NULL, }, 148}; 149 150#define bits2to5_mask 0x3c 151#define bits0to2_mask 0x07 152#define load_mask 0x40 153#define count_mask 0x80 154#define count_and_load_mask (load_mask | count_mask) 155#define clock_mask 0x03 156#define clk_ioclk 0x00 157#define clk_cascaded 0x03 158 159 160/* Finish off the partially created hw device. Attach our local 161 callbacks. Wire up our port names etc */ 162 163static hw_io_read_buffer_method mn103tim_io_read_buffer; 164static hw_io_write_buffer_method mn103tim_io_write_buffer; 165 166static void 167attach_mn103tim_regs (struct hw *me, 168 struct mn103tim *timers) 169{ 170 int i; 171 if (hw_find_property (me, "reg") == NULL) 172 hw_abort (me, "Missing \"reg\" property"); 173 for (i = 0; i < NR_TIMER_BLOCKS; i++) 174 { 175 unsigned_word attach_address; 176 int attach_space; 177 unsigned attach_size; 178 reg_property_spec reg; 179 if (!hw_find_reg_array_property (me, "reg", i, ®)) 180 hw_abort (me, "\"reg\" property must contain three addr/size entries"); 181 hw_unit_address_to_attach_address (hw_parent (me), 182 ®.address, 183 &attach_space, 184 &attach_address, 185 me); 186 timers->block[i].base = attach_address; 187 hw_unit_size_to_attach_size (hw_parent (me), 188 ®.size, 189 &attach_size, me); 190 timers->block[i].bound = attach_address + (attach_size - 1); 191 hw_attach_address (hw_parent (me), 192 0, 193 attach_space, attach_address, attach_size, 194 me); 195 } 196} 197 198static void 199mn103tim_finish (struct hw *me) 200{ 201 struct mn103tim *timers; 202 int i; 203 204 timers = HW_ZALLOC (me, struct mn103tim); 205 set_hw_data (me, timers); 206 set_hw_io_read_buffer (me, mn103tim_io_read_buffer); 207 set_hw_io_write_buffer (me, mn103tim_io_write_buffer); 208 set_hw_ports (me, mn103tim_ports); 209 210 /* Attach ourself to our parent bus */ 211 attach_mn103tim_regs (me, timers); 212 213 /* Initialize the timers */ 214 for ( i=0; i < NR_REG_TIMERS; ++i ) 215 { 216 timers->reg[i].mode = 0x00; 217 timers->reg[i].base = 0; 218 } 219 for ( i=0; i < NR_TIMERS; ++i ) 220 { 221 timers->timer[i].event = NULL; 222 timers->timer[i].div_ratio = 0; 223 timers->timer[i].start = 0; 224 } 225 timers->tm6md0 = 0x00; 226 timers->tm6md1 = 0x00; 227 timers->tm6bc = 0x0000; 228 timers->tm6ca = 0x0000; 229 timers->tm6cb = 0x0000; 230 timers->tm6mda = 0x00; 231 timers->tm6mdb = 0x00; 232} 233 234 235 236/* read and write */ 237 238static int 239decode_addr (struct hw *me, 240 struct mn103tim *timers, 241 unsigned_word address) 242{ 243 unsigned_word offset; 244 offset = address - timers->block[0].base; 245 246 switch (offset) 247 { 248 case 0x00: return TM0MD; 249 case 0x01: return TM1MD; 250 case 0x02: return TM2MD; 251 case 0x03: return TM3MD; 252 case 0x10: return TM0BR; 253 case 0x11: return TM1BR; 254 case 0x12: return TM2BR; 255 case 0x13: return TM3BR; 256 case 0x20: return TM0BC; 257 case 0x21: return TM1BC; 258 case 0x22: return TM2BC; 259 case 0x23: return TM3BC; 260 case 0x80: return TM4MD; 261 case 0x82: return TM5MD; 262 case 0x84: /* fall through */ 263 case 0x85: return TM6MD; 264 case 0x90: return TM4BR; 265 case 0x92: return TM5BR; 266 case 0xa0: return TM4BC; 267 case 0xa2: return TM5BC; 268 case 0xa4: return TM6BC; 269 case 0xb4: return TM6MDA; 270 case 0xb5: return TM6MDB; 271 case 0xc4: return TM6CA; 272 case 0xd4: return TM6CB; 273 default: 274 { 275 hw_abort (me, "bad address"); 276 return -1; 277 } 278 } 279} 280 281static void 282read_mode_reg (struct hw *me, 283 struct mn103tim *timers, 284 int timer_nr, 285 void *dest, 286 unsigned nr_bytes) 287{ 288 unsigned16 val16; 289 unsigned32 val32; 290 291 switch ( nr_bytes ) 292 { 293 case 1: 294 /* Accessing 1 byte is ok for all mode registers. */ 295 if ( timer_nr == 6 ) 296 { 297 *(unsigned8*)dest = timers->tm6md0; 298 } 299 else 300 { 301 *(unsigned8*)dest = timers->reg[timer_nr].mode; 302 } 303 break; 304 305 case 2: 306 if ( timer_nr == 6 ) 307 { 308 *(unsigned16 *)dest = (timers->tm6md0 << 8) | timers->tm6md1; 309 } 310 else if ( timer_nr == 0 || timer_nr == 2 ) 311 { 312 val16 = (timers->reg[timer_nr].mode << 8) 313 | timers->reg[timer_nr+1].mode; 314 *(unsigned16*)dest = val16; 315 } 316 else 317 { 318 hw_abort (me, "bad read size of 2 bytes to TM%dMD.", timer_nr); 319 } 320 break; 321 322 case 4: 323 if ( timer_nr == 0 ) 324 { 325 val32 = (timers->reg[0].mode << 24 ) 326 | (timers->reg[1].mode << 16) 327 | (timers->reg[2].mode << 8) 328 | timers->reg[3].mode; 329 *(unsigned32*)dest = val32; 330 } 331 else 332 { 333 hw_abort (me, "bad read size of 4 bytes to TM%dMD.", timer_nr); 334 } 335 break; 336 337 default: 338 hw_abort (me, "bad read size of %d bytes to TM%dMD.", 339 nr_bytes, timer_nr); 340 } 341} 342 343 344static void 345read_base_reg (struct hw *me, 346 struct mn103tim *timers, 347 int timer_nr, 348 void *dest, 349 unsigned nr_bytes) 350{ 351 unsigned16 val16; 352 unsigned32 val32; 353 354 /* Check nr_bytes: accesses of 1, 2 and 4 bytes allowed depending on timer. */ 355 switch ( nr_bytes ) 356 { 357 case 1: 358 /* Reading 1 byte is ok for all registers. */ 359 if ( timer_nr < NR_8BIT_TIMERS ) 360 { 361 *(unsigned8*)dest = timers->reg[timer_nr].base; 362 } 363 break; 364 365 case 2: 366 if ( timer_nr == 1 || timer_nr == 3 ) 367 { 368 hw_abort (me, "bad read size of 2 bytes to TM%dBR.", timer_nr); 369 } 370 else 371 { 372 if ( timer_nr < NR_8BIT_TIMERS ) 373 { 374 val16 = (timers->reg[timer_nr].base<<8) 375 | timers->reg[timer_nr+1].base; 376 } 377 else 378 { 379 val16 = timers->reg[timer_nr].base; 380 } 381 *(unsigned16*)dest = val16; 382 } 383 break; 384 385 case 4: 386 if ( timer_nr == 0 ) 387 { 388 val32 = (timers->reg[0].base << 24) | (timers->reg[1].base << 16) 389 | (timers->reg[2].base << 8) | timers->reg[3].base; 390 *(unsigned32*)dest = val32; 391 } 392 else if ( timer_nr == 4 ) 393 { 394 val32 = (timers->reg[4].base << 16) | timers->reg[5].base; 395 *(unsigned32*)dest = val32; 396 } 397 else 398 { 399 hw_abort (me, "bad read size of 4 bytes to TM%dBR.", timer_nr); 400 } 401 break; 402 403 default: 404 hw_abort (me, "bad read size must of %d bytes to TM%dBR.", 405 nr_bytes, timer_nr); 406 } 407} 408 409 410static void 411read_counter (struct hw *me, 412 struct mn103tim *timers, 413 int timer_nr, 414 void *dest, 415 unsigned nr_bytes) 416{ 417 unsigned32 val; 418 419 if ( NULL == timers->timer[timer_nr].event ) 420 { 421 /* Timer is not counting, use value in base register. */ 422 if ( timer_nr == 6 ) 423 { 424 val = 0; /* timer 6 is an up counter */ 425 } 426 else 427 { 428 val = timers->reg[timer_nr].base; 429 } 430 } 431 else 432 { 433 if ( timer_nr == 6 ) /* timer 6 is an up counter. */ 434 { 435 val = hw_event_queue_time(me) - timers->timer[timer_nr].start; 436 } 437 else 438 { 439 /* ticks left = start time + div ratio - curr time */ 440 /* Cannot use base register because it can be written during counting and it 441 doesn't affect counter until underflow occurs. */ 442 443 val = timers->timer[timer_nr].start + timers->timer[timer_nr].div_ratio 444 - hw_event_queue_time(me); 445 } 446 } 447 448 switch (nr_bytes) { 449 case 1: 450 *(unsigned8 *)dest = val; 451 break; 452 453 case 2: 454 *(unsigned16 *)dest = val; 455 break; 456 457 case 4: 458 *(unsigned32 *)dest = val; 459 break; 460 461 default: 462 hw_abort(me, "bad read size for reading counter"); 463 } 464 465} 466 467 468static void 469read_special_timer6_reg (struct hw *me, 470 struct mn103tim *timers, 471 int timer_nr, 472 void *dest, 473 unsigned nr_bytes) 474{ 475 unsigned32 val; 476 477 switch (nr_bytes) { 478 case 1: 479 { 480 switch ( timer_nr ) { 481 case TM6MDA: 482 *(unsigned8 *)dest = timers->tm6mda; 483 break; 484 485 case TM6MDB: 486 *(unsigned8 *)dest = timers->tm6mdb; 487 break; 488 489 case TM6CA: 490 *(unsigned8 *)dest = timers->tm6ca; 491 break; 492 493 case TM6CB: 494 *(unsigned8 *)dest = timers->tm6cb; 495 break; 496 497 default: 498 break; 499 } 500 break; 501 } 502 503 case 2: 504 if ( timer_nr == TM6CA ) 505 { 506 *(unsigned16 *)dest = timers->tm6ca; 507 } 508 else if ( timer_nr == TM6CB ) 509 { 510 *(unsigned16 *)dest = timers->tm6cb; 511 } 512 else 513 { 514 hw_abort(me, "bad read size for timer 6 mode A/B register"); 515 } 516 break; 517 518 default: 519 hw_abort(me, "bad read size for timer 6 register"); 520 } 521 522} 523 524 525static unsigned 526mn103tim_io_read_buffer (struct hw *me, 527 void *dest, 528 int space, 529 unsigned_word base, 530 unsigned nr_bytes) 531{ 532 struct mn103tim *timers = hw_data (me); 533 enum timer_register_types timer_reg; 534 535 HW_TRACE ((me, "read 0x%08lx %d", (long) base, (int) nr_bytes)); 536 537 timer_reg = decode_addr (me, timers, base); 538 539 /* It can be either a mode register, a base register, a binary counter, */ 540 /* or a special timer 6 register. Check in that order. */ 541 if ( timer_reg >= FIRST_MODE_REG && timer_reg <= LAST_MODE_REG ) 542 { 543 read_mode_reg(me, timers, timer_reg-FIRST_MODE_REG, dest, nr_bytes); 544 } 545 else if ( timer_reg <= LAST_BASE_REG ) 546 { 547 read_base_reg(me, timers, timer_reg-FIRST_BASE_REG, dest, nr_bytes); 548 } 549 else if ( timer_reg <= LAST_COUNTER ) 550 { 551 read_counter(me, timers, timer_reg-FIRST_COUNTER, dest, nr_bytes); 552 } 553 else if ( timer_reg <= LAST_TIMER_REG ) 554 { 555 read_special_timer6_reg(me, timers, timer_reg, dest, nr_bytes); 556 } 557 else 558 { 559 hw_abort(me, "invalid timer register address."); 560 } 561 562 return nr_bytes; 563} 564 565 566static void 567do_counter_event (struct hw *me, 568 void *data) 569{ 570 struct mn103tim *timers = hw_data(me); 571 long timer_nr = (long) data; 572 int next_timer; 573 574 /* Check if counting is still enabled. */ 575 if ( (timers->reg[timer_nr].mode & count_mask) != 0 ) 576 { 577 /* Generate an interrupt for the timer underflow (TIMERn_UFLOW). */ 578 579 /* Port event occurs on port of last cascaded timer. */ 580 /* This works across timer range from 0 to NR_REG_TIMERS because */ 581 /* the first 16 bit timer (timer 4) is not allowed to be set as */ 582 /* a cascading timer. */ 583 for ( next_timer = timer_nr+1; next_timer < NR_REG_TIMERS; ++next_timer ) 584 { 585 if ( (timers->reg[next_timer].mode & clock_mask) != clk_cascaded ) 586 { 587 break; 588 } 589 } 590 hw_port_event (me, next_timer-1, 1); 591 592 /* Schedule next timeout. */ 593 timers->timer[timer_nr].start = hw_event_queue_time(me); 594 /* FIX: Check if div_ratio has changed and if it's now 0. */ 595 timers->timer[timer_nr].event 596 = hw_event_queue_schedule (me, timers->timer[timer_nr].div_ratio, 597 do_counter_event, (void *)timer_nr); 598 } 599 else 600 { 601 timers->timer[timer_nr].event = NULL; 602 } 603 604} 605 606 607static void 608do_counter6_event (struct hw *me, 609 void *data) 610{ 611 struct mn103tim *timers = hw_data(me); 612 long timer_nr = (long) data; 613 int next_timer; 614 615 /* Check if counting is still enabled. */ 616 if ( (timers->reg[timer_nr].mode & count_mask) != 0 ) 617 { 618 /* Generate an interrupt for the timer underflow (TIMERn_UFLOW). */ 619 hw_port_event (me, timer_nr, 1); 620 621 /* Schedule next timeout. */ 622 timers->timer[timer_nr].start = hw_event_queue_time(me); 623 /* FIX: Check if div_ratio has changed and if it's now 0. */ 624 timers->timer[timer_nr].event 625 = hw_event_queue_schedule (me, timers->timer[timer_nr].div_ratio, 626 do_counter6_event, (void *)timer_nr); 627 } 628 else 629 { 630 timers->timer[timer_nr].event = NULL; 631 } 632 633} 634 635static void 636write_base_reg (struct hw *me, 637 struct mn103tim *timers, 638 int timer_nr, 639 const void *source, 640 unsigned nr_bytes) 641{ 642 unsigned i; 643 const unsigned8 *buf8 = source; 644 const unsigned16 *buf16 = source; 645 646 /* If TMnCNE == 0 (counting is off), writing to the base register 647 (TMnBR) causes a simultaneous write to the counter reg (TMnBC). 648 Else, the TMnBC is reloaded with the value from TMnBR when 649 underflow occurs. Since the counter register is not explicitly 650 maintained, this functionality is handled in read_counter. */ 651 652 /* Check nr_bytes: write of 1, 2 or 4 bytes allowed depending on timer. */ 653 switch ( nr_bytes ) 654 { 655 case 1: 656 /* Storing 1 byte is ok for all registers. */ 657 timers->reg[timer_nr].base = buf8[0]; 658 break; 659 660 case 2: 661 if ( timer_nr == 1 || timer_nr == 3 ) 662 { 663 hw_abort (me, "bad write size of 2 bytes to TM%dBR.", timer_nr); 664 } 665 else 666 { 667 if ( timer_nr < NR_8BIT_TIMERS ) 668 { 669 timers->reg[timer_nr].base = buf8[0]; 670 timers->reg[timer_nr+1].base = buf8[1]; 671 } 672 else 673 { 674 timers->reg[timer_nr].base = buf16[0]; 675 } 676 } 677 break; 678 679 case 4: 680 if ( timer_nr == 0 ) 681 { 682 timers->reg[0].base = buf8[0]; 683 timers->reg[1].base = buf8[1]; 684 timers->reg[2].base = buf8[2]; 685 timers->reg[3].base = buf8[3]; 686 } 687 else if ( timer_nr == 4 ) 688 { 689 timers->reg[4].base = buf16[0]; 690 timers->reg[5].base = buf16[1]; 691 } 692 else 693 { 694 hw_abort (me, "bad write size of 4 bytes to TM%dBR.", timer_nr); 695 } 696 break; 697 698 default: 699 hw_abort (me, "bad write size must of %d bytes to TM%dBR.", 700 nr_bytes, timer_nr); 701 } 702 703} 704 705static void 706write_mode_reg (struct hw *me, 707 struct mn103tim *timers, 708 long timer_nr, 709 const void *source, 710 unsigned nr_bytes) 711 /* for timers 0 to 5 */ 712{ 713 unsigned i; 714 unsigned8 mode_val, next_mode_val; 715 unsigned32 div_ratio; 716 717 if ( nr_bytes != 1 ) 718 { 719 hw_abort (me, "bad write size of %d bytes to TM%ldMD.", nr_bytes, 720 timer_nr); 721 } 722 723 mode_val = *(unsigned8 *)source; 724 timers->reg[timer_nr].mode = mode_val; 725 726 if ( ( mode_val & count_and_load_mask ) == count_and_load_mask ) 727 { 728 hw_abort(me, "Cannot load base reg and start counting simultaneously."); 729 } 730 if ( ( mode_val & bits2to5_mask ) != 0 ) 731 { 732 hw_abort(me, "Cannot write to bits 2 to 5 of mode register"); 733 } 734 735 if ( mode_val & count_mask ) 736 { 737 /* - de-schedule any previous event. */ 738 /* - add new event to queue to start counting. */ 739 /* - assert that counter == base reg? */ 740 741 /* For cascaded timers, */ 742 if ( (mode_val & clock_mask) == clk_cascaded ) 743 { 744 if ( timer_nr == 0 || timer_nr == 4 ) 745 { 746 hw_abort(me, "Timer %ld cannot be cascaded.", timer_nr); 747 } 748 } 749 else 750 { 751 div_ratio = timers->reg[timer_nr].base; 752 753 /* Check for cascading. */ 754 if ( timer_nr < NR_8BIT_TIMERS ) 755 { 756 for ( i = timer_nr + 1; i <= 3; ++i ) 757 { 758 next_mode_val = timers->reg[i].mode; 759 if ( ( next_mode_val & clock_mask ) == clk_cascaded ) 760 { 761 /* Check that CNE is on. */ 762 if ( ( next_mode_val & count_mask ) == 0 ) 763 { 764 hw_abort (me, "cascaded timer not ready for counting"); 765 } 766 ASSERT(timers->timer[i].event == NULL); 767 ASSERT(timers->timer[i].div_ratio == 0); 768 div_ratio = div_ratio 769 | (timers->reg[i].base << (8*(i-timer_nr))); 770 } 771 else 772 { 773 break; 774 } 775 } 776 } 777 else 778 { 779 /* Mode register for a 16 bit timer */ 780 next_mode_val = timers->reg[timer_nr+1].mode; 781 if ( ( next_mode_val & clock_mask ) == clk_cascaded ) 782 { 783 /* Check that CNE is on. */ 784 if ( ( next_mode_val & count_mask ) == 0 ) 785 { 786 hw_abort (me, "cascaded timer not ready for counting"); 787 } 788 ASSERT(timers->timer[timer_nr+1].event == NULL); 789 ASSERT(timers->timer[timer_nr+1].div_ratio == 0); 790 div_ratio = div_ratio | (timers->reg[timer_nr+1].base << 16); 791 } 792 } 793 794 timers->timer[timer_nr].div_ratio = div_ratio; 795 796 if ( NULL != timers->timer[timer_nr].event ) 797 { 798 hw_event_queue_deschedule (me, timers->timer[timer_nr].event); 799 timers->timer[timer_nr].event = NULL; 800 } 801 802 if ( div_ratio > 0 ) 803 { 804 /* Set start time. */ 805 timers->timer[timer_nr].start = hw_event_queue_time(me); 806 timers->timer[timer_nr].event 807 = hw_event_queue_schedule(me, div_ratio, 808 do_counter_event, 809 (void *)(timer_nr)); 810 } 811 } 812 } 813 else 814 { 815 /* Turn off counting */ 816 if ( NULL != timers->timer[timer_nr].event ) 817 { 818 ASSERT((timers->reg[timer_nr].mode & clock_mask) != clk_cascaded); 819 hw_event_queue_deschedule (me, timers->timer[timer_nr].event); 820 timers->timer[timer_nr].event = NULL; 821 } 822 else 823 { 824 if ( (timers->reg[timer_nr].mode & clock_mask) == clk_cascaded ) 825 { 826 ASSERT(timers->timer[timer_nr].event == NULL); 827 } 828 } 829 830 } 831 832} 833 834static void 835write_tm6md (struct hw *me, 836 struct mn103tim *timers, 837 unsigned_word address, 838 const void *source, 839 unsigned nr_bytes) 840{ 841 unsigned8 mode_val0 = 0x00, mode_val1 = 0x00; 842 unsigned32 div_ratio; 843 long timer_nr = 6; 844 845 unsigned_word offset = address - timers->block[0].base; 846 847 if ((offset != 0x84 && nr_bytes > 1) || nr_bytes > 2 ) 848 { 849 hw_abort (me, "Bad write size of %d bytes to TM6MD", nr_bytes); 850 } 851 852 if ( offset == 0x84 ) /* address of TM6MD */ 853 { 854 /* Fill in first byte of mode */ 855 mode_val0 = *(unsigned8 *)source; 856 timers->tm6md0 = mode_val0; 857 858 if ( ( mode_val0 & 0x26 ) != 0 ) 859 { 860 hw_abort(me, "Cannot write to bits 5, 3, and 2 of TM6MD"); 861 } 862 } 863 864 if ( offset == 0x85 || nr_bytes == 2 ) 865 { 866 /* Fill in second byte of mode */ 867 if ( nr_bytes == 2 ) 868 { 869 mode_val1 = *(unsigned8 *)source+1; 870 } 871 else 872 { 873 mode_val1 = *(unsigned8 *)source; 874 } 875 876 timers->tm6md1 = mode_val1; 877 878 if ( ( mode_val1 & count_and_load_mask ) == count_and_load_mask ) 879 { 880 hw_abort(me, "Cannot load base reg and start counting simultaneously."); 881 } 882 if ( ( mode_val1 & bits0to2_mask ) != 0 ) 883 { 884 hw_abort(me, "Cannot write to bits 8 to 10 of TM6MD"); 885 } 886 } 887 888 if ( mode_val1 & count_mask ) 889 { 890 /* - de-schedule any previous event. */ 891 /* - add new event to queue to start counting. */ 892 /* - assert that counter == base reg? */ 893 894 div_ratio = timers->tm6ca; /* binary counter for timer 6 */ 895 timers->timer[timer_nr].div_ratio = div_ratio; 896 if ( NULL != timers->timer[timer_nr].event ) 897 { 898 hw_event_queue_deschedule (me, timers->timer[timer_nr].event); 899 timers->timer[timer_nr].event = NULL; 900 } 901 902 if ( div_ratio > 0 ) 903 { 904 /* Set start time. */ 905 timers->timer[timer_nr].start = hw_event_queue_time(me); 906 timers->timer[timer_nr].event 907 = hw_event_queue_schedule(me, div_ratio, 908 do_counter6_event, 909 (void *)(timer_nr)); 910 } 911 } 912 else 913 { 914 /* Turn off counting */ 915 if ( NULL != timers->timer[timer_nr].event ) 916 { 917 hw_event_queue_deschedule (me, timers->timer[timer_nr].event); 918 timers->timer[timer_nr].event = NULL; 919 } 920 } 921} 922 923 924 925static void 926write_special_timer6_reg (struct hw *me, 927 struct mn103tim *timers, 928 int timer_nr, 929 const void *source, 930 unsigned nr_bytes) 931{ 932 unsigned32 val; 933 934 switch (nr_bytes) { 935 case 1: 936 { 937 switch ( timer_nr ) { 938 case TM6MDA: 939 timers->tm6mda = *(unsigned8 *)source; 940 break; 941 942 case TM6MDB: 943 timers->tm6mdb = *(unsigned8 *)source; 944 break; 945 946 case TM6CA: 947 timers->tm6ca = *(unsigned8 *)source; 948 break; 949 950 case TM6CB: 951 timers->tm6cb = *(unsigned8 *)source; 952 break; 953 954 default: 955 break; 956 } 957 break; 958 } 959 960 case 2: 961 if ( timer_nr == TM6CA ) 962 { 963 timers->tm6ca = *(unsigned16 *)source; 964 } 965 else if ( timer_nr == TM6CB ) 966 { 967 timers->tm6cb = *(unsigned16 *)source; 968 } 969 else 970 { 971 hw_abort(me, "bad read size for timer 6 mode A/B register"); 972 } 973 break; 974 975 default: 976 hw_abort(me, "bad read size for timer 6 register"); 977 } 978 979} 980 981 982static unsigned 983mn103tim_io_write_buffer (struct hw *me, 984 const void *source, 985 int space, 986 unsigned_word base, 987 unsigned nr_bytes) 988{ 989 struct mn103tim *timers = hw_data (me); 990 enum timer_register_types timer_reg; 991 992 HW_TRACE ((me, "write to 0x%08lx length %d with 0x%x", (long) base, 993 (int) nr_bytes, *(unsigned32 *)source)); 994 995 timer_reg = decode_addr (me, timers, base); 996 997 /* It can be either a mode register, a base register, a binary counter, */ 998 /* or a special timer 6 register. Check in that order. */ 999 if ( timer_reg <= LAST_MODE_REG ) 1000 { 1001 if ( timer_reg == 6 ) 1002 { 1003 write_tm6md(me, timers, base, source, nr_bytes); 1004 } 1005 else 1006 { 1007 write_mode_reg(me, timers, timer_reg-FIRST_MODE_REG, 1008 source, nr_bytes); 1009 } 1010 } 1011 else if ( timer_reg <= LAST_BASE_REG ) 1012 { 1013 write_base_reg(me, timers, timer_reg-FIRST_BASE_REG, source, nr_bytes); 1014 } 1015 else if ( timer_reg <= LAST_COUNTER ) 1016 { 1017 hw_abort(me, "cannot write to counter"); 1018 } 1019 else if ( timer_reg <= LAST_TIMER_REG ) 1020 { 1021 write_special_timer6_reg(me, timers, timer_reg, source, nr_bytes); 1022 } 1023 else 1024 { 1025 hw_abort(me, "invalid reg type"); 1026 } 1027 1028 return nr_bytes; 1029} 1030 1031 1032const struct hw_descriptor dv_mn103tim_descriptor[] = { 1033 { "mn103tim", mn103tim_finish, }, 1034 { NULL }, 1035}; 1036