Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
8327 maxcodehac 1
#include "pxa255_DMA.h"
2
#include "mem.h"
3
 
4
#define REG_DAR 	0
5
#define REG_SAR 	1
6
#define REG_TAR 	2
7
#define REG_CR		3
8
#define REG_CSR		4
9
 
10
 
11
static void pxa255dmaPrvChannelRegWrite(_UNUSED_ Pxa255dma* dma, UInt8 channel, UInt8 reg, UInt32 val){
12
 
13
	if(val){	//we start with zeros, so non-zero writes are all we care about
14
 
15
		const char* regs[] = {"DADDR", "SADDR", "TADDR", "CR", "CSR"};
16
 
17
		err_str("dma: writes unimpl!");
18
	//	err_str("PXA255 dma engine: writes unimpl! (writing 0x");
19
	//	err_hex(val);
20
	//	err_str(" to channel ");
21
	//	err_dec(channel);
22
	//	err_str(" reg ");
23
	//	err_str(regs[reg]);
24
	//	err_str(". Halting.\r\n");
25
		while(1);
26
	}
27
}
28
 
29
static UInt32 pxa255dmaPrvChannelRegRead(_UNUSED_ Pxa255dma* dma, _UNUSED_ UInt8 channel, _UNUSED_ UInt8 reg){
30
 
31
 
32
	return 0;
33
}
34
 
35
static Boolean pxa255dmaPrvMemAccessF(void* userData, UInt32 pa, UInt8 size, Boolean write, void* buf){
36
 
37
	Pxa255dma* dma = userData;
38
	UInt8 reg, set;
39
	UInt32 val = 0;
40
 
41
	if(size != 4) {
42
		err_str(__FILE__ ": Unexpected ");
43
	//	err_str(write ? "write" : "read");
44
	//	err_str(" of ");
45
	//	err_dec(size);
46
	//	err_str(" bytes to 0x");
47
	//	err_hex(pa);
48
	//	err_str("\r\n");
49
		return true;		//we do not support non-word accesses
50
	}
51
 
52
	pa = (pa - PXA255_DMA_BASE) >> 2;
53
 
54
	if(write){
55
		val = *(UInt32*)buf;
56
 
57
		switch(pa >> 6){		//weird, but quick way to avoide repeated if-then-elses. this is faster
58
			case 0:
59
				if(pa < 16){
60
					reg = REG_CSR;
61
					set = pa;
62
					pxa255dmaPrvChannelRegWrite(dma, set, reg, val);
63
				}
64
				break;
65
 
66
			case 1:
67
				pa -= 64;
68
				if(pa < 40) dma->CMR[pa] = val;
69
				break;
70
 
71
			case 2:
72
				pa -= 128;
73
				set = pa >> 2;
74
				reg = pa & 3;
75
				pxa255dmaPrvChannelRegWrite(dma, set, reg, val);
76
				break;
77
		}
78
	}
79
	else{
80
		switch(pa >> 6){		//weird, but quick way to avoide repeated if-then-elses. this is faster
81
			case 0:
82
				if(pa < 16){
83
					reg = REG_CSR;
84
					set = pa;
85
					val = pxa255dmaPrvChannelRegRead(dma, set, reg);
86
				}
87
				break;
88
 
89
			case 1:
90
				pa -= 64;
91
				if(pa < 40) val = dma->CMR[pa];
92
				break;
93
 
94
			case 2:
95
				pa -= 128;
96
				set = pa >> 2;
97
				reg = pa & 3;
98
				val = pxa255dmaPrvChannelRegRead(dma, set, reg);
99
				break;
100
		}
101
 
102
		*(UInt32*)buf = val;
103
	}
104
 
105
	return true;
106
}
107
 
108
 
109
Boolean pxa255dmaInit(Pxa255dma* dma, ArmMem* physMem, Pxa255ic* ic){
110
 
111
	__mem_zero(dma, sizeof(Pxa255dma));
112
	dma->ic = ic;
113
	dma->mem = physMem;
114
 
115
	return memRegionAdd(physMem, PXA255_DMA_BASE, PXA255_DMA_SIZE, pxa255dmaPrvMemAccessF, dma);
116
}