2
skyeye_mach_mcf5272.c - implementation of Coldfire 5272 Processor
3
Copyright (C) 2003 Skyeye Develop Group
4
for help please send mail to <skyeye-developer@lists.sf.linuxforum.net>
6
This program is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2 of the License, or
9
(at your option) any later version.
11
This program is distributed in the hope that it will be useful,
12
but WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
GNU General Public License for more details.
16
You should have received a copy of the GNU General Public License
17
along with this program; if not, write to the Free Software
18
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22
* 12/27/2006 Michael.Kang <blackfin.kang@gmail.com>
29
#include "../common/memory.h"
32
#include "skyeye_uart.h"
34
typedef struct uart_s{
55
typedef struct cs_module_s{
61
typedef struct mcf5272_timer_s{
69
typedef struct mcf5272_dma_s{
73
typedef struct mcf5272_ethernet_s{
91
typedef struct mcf5272_io_s{
93
cs_module_t cs_module[4];
96
unsigned int ideconfig1;
97
unsigned int ideconfig2;
98
unsigned int dmaconfig;
99
unsigned int dmaroute;
101
unsigned int pacnt; /* Port A Control (r/w) */
102
unsigned int paddr; /* Port A Direction (r/w) */
103
unsigned int padat; /* Port A Data (r/w) */
104
unsigned int pbcnt; /* Port B Control (r/w) */
105
unsigned int pbddr; /* Port B Direction (r/w) */
106
unsigned int pbdat; /* Port B Data (r/w) */
107
unsigned int pcddr; /* Port C Direction (r/w) */
108
unsigned int pcdat; /* Port C Data (r/w) */
109
unsigned int pdcnt; /* Port D Control (r/w) */
111
unsigned int iis2_config;
113
unsigned int data_in_ctrl;
120
mcf5272_dma_t dma[4];
121
mcf5272_timer_t timer[4];
124
mcf5272_ethernet_t ether;
127
static mcf5272_io_t mcf5272_io;
129
static char cs_module_write(short size, int offset, unsigned int value);
130
static char cs_module_read(unsigned int *result, short size, int offset);
131
static char timer_write(short size, int offset, unsigned int value);
132
static char timer_read(unsigned int *result, short size, int offset);
133
static char uart_write(short size, int offset, unsigned int value);
134
static char uart_read(unsigned int *result, short size, int offset);
136
static char mcf5272_mbar_write(short size, int offset, unsigned int value){
137
mcf5272_io_t * io = &mcf5272_io;
159
io->ether.ecr = value;
162
io->ether.eir = value;
165
io->ether.eimr = value;
168
io->ether.rdar = value;
171
io->ether.mmfr = value;
174
io->ether.mscr = value;
177
io->ether.rcr = value;
180
io->ether.tcr = value;
183
io->ether.malr = value;
186
io->ether.maur = value;
189
io->ether.htur = value;
192
io->ether.htlr = value;
195
io->ether.erdsr = value;
198
io->ether.etdst = value;
201
io->ether.emrbr = value;
204
if(offset >= 0x20 && offset <= 0x2C){
205
int index = (offset - 0x20) / 4;
206
unsigned int old_value = mcf5272_io.icr[index];
208
/* IPL is changed only when a 1 is written simultaneously to the corresponding PI bit */
209
for(i = 31; i > 0; i = i - 4)
210
if((value >> i) & 0x1)
211
old_value = (value & (0xf << (i - 3))) | (old_value & (~(0xf << (i - 3))));
212
mcf5272_io.icr[index] = old_value;
216
if((offset >= 0x200 && offset <= 0x272))
217
return timer_write(size, offset, value);
218
if((offset >= 0x100 && offset <= 0x13C) || (offset >= 0x140 && offset <= 0x17C))
219
return uart_write(size, offset, value);
223
if(offset >= 0x80 && offset <= 0xAE)
224
return cs_module_write(size, offset, value);
225
if((offset >= 0x140 && offset < 0x154) || (offset >= 0x180 && offset < 0x194))
226
return timer_write(size, offset, value);
227
if((offset >= 0x1C0 && offset <= 0x1FC) || (offset >= 0x200 && offset <= 0x23C))
228
return uart_write(size, offset, value);
230
fprintf(stderr,"Error adress in %s,offset=0x%x,pc=0x%x\n",__FUNCTION__,offset, memory_core.pc);
235
static char mcf5272_mbar2_write(short size, int offset, unsigned int value){
239
mcf5272_io.gpio_out = value;
242
mcf5272_io.gpio_en = value;
245
mcf5272_io.gpio_func = value;
248
mcf5272_io.iis2_config = value;
251
mcf5272_io.data_in_ctrl = value;
254
mcf5272_io.gpio1_out = value;
257
mcf5272_io.gpio1_en = value;
260
mcf5272_io.gpio1_func = value;
262
case 0x16b:/* INT Base*/
263
mcf5272_io.intbase = value;
266
mcf5272_io.pllcr = value;
269
mcf5272_io.ideconfig1 = value;
272
mcf5272_io.ideconfig2 = value;
275
mcf5272_io.dmaroute = value;
278
mcf5272_io.dmaconfig = value;
281
printf("Warning:register is not implemented\n");
285
fprintf(stderr,"Error adress in %s,offset=0x%x\n",__FUNCTION__,offset);
291
static char mcf5272_mbar_read(unsigned int *result, short size, int offset){
292
mcf5272_io_t * io = &mcf5272_io;
308
*result = io->ether.malr;
311
*result = io->ether.maur;
314
if((offset >= 0x100 && offset <= 0x13C) || (offset >= 0x140 && offset <= 0x17C))
315
return uart_read(result, size, offset);
316
if((offset >= 0x200 && offset < 0x270))
317
return timer_read(result, size, offset);
318
if(offset >= 0x20 && offset <= 0x2C){
319
int index = offset - 0x20;
320
return mcf5272_io.icr[index/4];
323
fprintf(stderr,"Error adress in %s,offset=%x\n",__FUNCTION__,offset);
330
static char mcf5272_mbar2_read(unsigned int *result, short size, int offset){
334
*result = mcf5272_io.gpio_out;
337
*result = mcf5272_io.gpio_en;
340
*result = mcf5272_io.gpio_func;
346
*result = mcf5272_io.gpio1_out;
349
*result = mcf5272_io.gpio1_en;
352
*result = mcf5272_io.gpio1_func;
355
*result = mcf5272_io.pllcr;
359
fprintf(stderr,"Error adress in %s,offset=%x\n",__FUNCTION__,offset);
366
/* Interrupts go from 0 -> 9 on the 5307, with the 7 external
367
* autovector only interrupts defined in the autovector interrupt */
370
* +----+----+----+----+----+----+----+----+
371
* | av | xx | xx | int level | int pri |
372
* +----+----+----+----+----+----+----+----+
373
* av -- autovectored, 1=yes
374
* int level -- interrupt level, 0 -> 7
375
* int pri -- interrupt priority 11(high) -> 00 (low) */
376
#define ICR_LEVEL(x) ((mcf5272_io.icr[(31 - x) / 8] >> (4 * (x % 8))) & 0x7)
377
//#define ICR_PRI(icr) ((icr) & 0x02)
378
//#define ICR_AVEC(icr) ((icr) & 0x80)
380
static unsigned int mcf5272_iack_func(unsigned int interrupt_level){
382
unsigned long vector=0;
384
mcf5272_io_t * io = &mcf5272_io;
385
//TRACE("called for interrupt_level=%d\n", interrupt_level);
386
/* Find the _pending_ interrupt with level == interrupt_level */
387
/* INT1_IRQ has highest priority and SWTO_IRQ is lowest priority */
388
for(x = INT1_IRQ; x > SWTO_IRQ; x--) {
389
int icr_avec, icr_level, icr_pri;
390
if(!((io->isr >> x) & 0x1)){
393
icr_level = ICR_LEVEL(x);
395
if(icr_level != interrupt_level) continue;
396
/* see p163 of user manual of 5272 */
397
vector = (32 - x) | (io->pivr & 0xe0);
400
printf("DBG: in %s, vector=%d\n", __FUNCTION__, vector);
405
//ERR("Inside iack_func, but no interrupt is waiting with level %d\n", interrupt_level);
406
fprintf(stderr, "Inside iack_func, but no interrupt is waiting with level %d\n", interrupt_level);
410
static void interrupt_assert(short number){
411
mcf5272_io_t * io = &mcf5272_io;
412
int level = ICR_LEVEL(number);;
415
printf("DBG:Posting interrupt Number=%d, Level=%d\n", number, level);
417
//TRACE("Posting interrupt Number=%d, Vector=%d\n", number, vector);
418
/* Post an interrupt */
419
exception_post(level, &mcf5272_iack_func);
420
io->isr |= 0x1 << number;
424
static void interrupt_withdraw(short number){
425
mcf5272_io_t * io = &mcf5272_io;
426
int icr_level = ICR_LEVEL(number);
428
io->isr &= ~(0x1 << number);
431
printf("DBG:in %s Number=%d, Level=%d\n", __FUNCTION__, number, icr_level);
433
exception_withdraw(icr_level);
438
void mcf5272_io_do_cycle(){
440
for(i = 0; i < TIMER_NUM; i++){
441
//mcf5272_timer_t * timer = &mcf5272_io.timer[i];
442
/* check if timer is enbaled */
443
if(mcf5272_io.timer[i].tmr & 0x1){
444
mcf5272_io.timer[i].tcn++;
445
/* check if reference interrupt is enabled */
446
if((mcf5272_io.timer[i].tcn == mcf5272_io.timer[i].trr) && (mcf5272_io.timer[i].tmr & 0x10))
449
//printf("DBG:tcn=0x%x,trr=0x%x,i=%d\n", mcf5272_io.timer[i].tcn, mcf5272_io.timer[i].trr, i);
450
/* set REF bit in TER */
451
mcf5272_io.timer[i].ter |= 0x2;
452
interrupt_assert(TIMER0_IRQ - i);
454
/* check if in restart mode */
455
if(mcf5272_io.timer[i].tmr & 0x8)
456
mcf5272_io.timer[i].tcn = 0x0;
462
/* UART FIFO full interrupt enabled */
468
if(skyeye_uart_read(-1, &buf, 1, &tv, NULL) > 0){
469
mcf5272_io.uart[0].urb = buf;
470
/* set RXRDY bit in UISR */
471
mcf5272_io.uart[0].uisr |= 0x2;
473
/* set TXRDY bit in UISR */
474
mcf5272_io.uart[0].uisr |= 0x1;
478
/* check if UART Transmitter ready interrupt enabled */
479
if(!(mcf5272_io.isr & UART1_IRQ)){
480
if((mcf5272_io.uart[0].uimr & mcf5272_io.uart[0].uisr))
481
interrupt_assert(UART1_IRQ);
485
static char cs_module_read(unsigned int *result, short size, int offset){
486
int index = offset - 0x80;
488
if(index >= 0 && index <=8){
492
if(index >= 0xc && index <= 0x16){
493
reg_no = (index - 0xc)/ 4;
496
if(index >= 0x18 && index <= 0x22){
497
reg_no = (index - 0x18)/4;
500
if(index >= 0x24 && index <= 0x2e){
501
reg_no = (index - 0x24);
507
*result = mcf5272_io.cs_module[index].csar;
510
*result = mcf5272_io.cs_module[index].csmr;
513
*result = mcf5272_io.cs_module[index].cscr;
517
fprintf(stderr,"Error adress in %s,offset=0x%x\n",__FUNCTION__,offset);
522
static char cs_module_write(short size, int offset, unsigned int value){
523
int index = offset - 0x80;
525
if(index >= 0 && index <=8){
529
if(index >= 0xc && index <= 0x16){
530
reg_no = (index - 0xc)/ 4;
533
if(index >= 0x18 && index <= 0x22){
534
reg_no = (index - 0x18)/4;
537
if(index >= 0x24 && index <= 0x2e){
538
reg_no = (index - 0x24);
544
mcf5272_io.cs_module[index].csar = value;
547
mcf5272_io.cs_module[index].csmr = value;
550
mcf5272_io.cs_module[index].cscr = value;
554
fprintf(stderr,"Error adress in %s,offset=0x%x\n",__FUNCTION__,offset);
559
static char timer_read(unsigned int *result, short size, int offset){
560
int index = (offset - 0x200) / 0x20;
561
offset = offset % 0x20;
563
//printf("DBG: in %s, offset = 0x%x", __FUNCTION__, offset);
566
*result = mcf5272_io.timer[index].tmr;
569
*result = mcf5272_io.timer[index].trr;
572
*result = mcf5272_io.timer[index].tcap;
575
*result = mcf5272_io.timer[index].tcn;
578
/* write one to clear the corresponding bit */
579
*result = mcf5272_io.timer[index].ter;
580
/* clear the corresponding bit in ipr */
581
//mcf5272_io.ipr &= ~(0x1 << 9);
582
interrupt_withdraw(TIMER0_IRQ - index);
585
fprintf(stderr,"Error adress in %s,offset=0x%x\n",__FUNCTION__,offset);
591
static char timer_write(short size, int offset, unsigned int value){
592
int index = (offset - 0x200) / 0x20;
593
offset = offset % 0x20;
594
//printf("DBG: in %s, offset = 0x%x, value=0x%x\n", __FUNCTION__, offset, value);
597
mcf5272_io.timer[index].tmr = value;
600
mcf5272_io.timer[index].trr = value;
603
mcf5272_io.timer[index].tcap = value;
606
mcf5272_io.timer[index].tcn = value;
609
/* write one to clear the corresponding bit */
610
mcf5272_io.timer[index].ter &= ~(value & 0x3);
611
/* clear the corresponding bit in ipr */
612
//mcf5272_io.ipr &= ~(0x1 << 9);
613
interrupt_withdraw(TIMER0_IRQ - index);
616
fprintf(stderr,"Error adress in %s,offset=0x%x\n",__FUNCTION__,offset);
622
static char uart_read(unsigned int *result, short size, int offset){
624
if(offset >= 0x100 && offset <= 0x13C){
626
offset = offset - 0x100;
628
if(offset >= 0x140 && offset <= 0x17C){
630
offset = offset - 0x140;
632
extern struct _memory_core memory_core;
635
printf("DBG: in %s, offset = 0x%x,PC=0x%x\n", __FUNCTION__, offset, memory_core.pc);
639
*result = mcf5272_io.uart[index].umr1;
642
*result = mcf5272_io.uart[index].usr;
645
*result = mcf5272_io.uart[index].urb;
646
/* set FFULL bit in USR is zero */
647
mcf5272_io.uart[index].usr &= ~0x2;
648
/* set RxRDY bit in USR is zero */
649
mcf5272_io.uart[index].usr &= ~0x1;
650
/* check RXIRQ bit in UMR1 */
651
//if(mcf5272_io.uart[index].umr1 & 0x40)
652
mcf5272_io.uart[index].uisr &= ~0x2;
655
*result = mcf5272_io.uart[index].uipcr;
658
*result = mcf5272_io.uart[index].uisr;
659
mcf5272_io.uart[index].uisr = 0x0;
660
interrupt_withdraw(UART1_IRQ - index);
663
*result = mcf5272_io.uart[index].ubg1;
666
*result = mcf5272_io.uart[index].ubg2;
669
*result = mcf5272_io.uart[index].uip;
672
fprintf(stderr,"Error adress in %s,offset=0x%x\n",__FUNCTION__,offset);
678
static char uart_write(short size, int offset, unsigned int value){
681
if(offset >= 0x100 && offset <= 0x13C){
683
offset = offset - 0x100;
685
if(offset >= 0x140 && offset <= 0x17C){
687
offset = offset - 0x140;
691
printf("DBG: in %s, offset = 0x%x, value=0x%x\n", __FUNCTION__, offset, value);
695
mcf5272_io.uart[index].umr1 = value;
698
mcf5272_io.uart[index].ucsr = value;
701
mcf5272_io.uart[index].ucr = value;
702
if((value & 0x3) == 0x1) /* Receiver enable */
705
if(((value >> 2) & 0x3) == 0x1) /* Transmitter enable */
706
/* set TXRDY bit and TXEMP bit in usr */
707
mcf5272_io.uart[index].usr |= 0xc;
709
cmd = (value >> 4) & 0x7;
710
if (cmd == 0x4) /* Reset error status */
711
mcf5272_io.uart[index].usr &= 0xf;
714
mcf5272_io.uart[index].utb = value;
716
skyeye_uart_write(-1, &tmp, 1, NULL);
717
/* set TXRDY bit and TXEMP bit in usr */
718
mcf5272_io.uart[index].usr |= 0xc;
719
/* set TXRDY bit in usr */
720
mcf5272_io.uart[index].uisr |= 0x1;
723
mcf5272_io.uart[index].uacr = value;
726
mcf5272_io.uart[index].uimr = value;
729
mcf5272_io.uart[index].ubg1 = value;
732
mcf5272_io.uart[index].ubg2 = value;
735
mcf5272_io.uart[index].ufpd = value;
738
mcf5272_io.uart[index].uop1 = value;
741
mcf5272_io.uart[index].uop0 = value;
744
fprintf(stderr,"Error adress in %s,offset=0x%x\n",__FUNCTION__,offset);
750
void mcf5272_mach_init(void * state, machine_config_t * mach){
751
struct _memory_core * core = (struct _memory_core *)state;
752
machine_config_t * this_mach = mach;
753
core->mbar_read = mcf5272_mbar_read;
754
core->mbar_write = mcf5272_mbar_write;
755
core->mbar2_read = mcf5272_mbar2_read;
756
core->mbar2_write = mcf5272_mbar2_write;
758
/* fixme, workaround for uClinux */
759
mcf5272_io.pivr = 0x40;
764
this_mach->mach_io_do_cycle = mcf5272_io_do_cycle;
766
this_mach->mach_io_read_byte = mcf5272_io_read_byte;
767
this_mach->mach_io_read_halfword = mcf5272_io_read_halfword;
768
this_mach->mach_io_read_word = mcf5272_io_read_word;
769
this_mach->mach_io_write_byte = mcf5272_io_write_byte;
770
this_mach->mach_io_write_halfword = mcf5272_io_write_halfword;
771
this_mach->mach_io_write_word = mcf5272_io_write_word;
772
this_mach->mach_io_do_cycle = mcf5272_io_do_cycle;
773
this_mach->mach_set_intr = mcf5272_set_int;