diff options
Diffstat (limited to 'drivers/media/dvb/b2c2/flexcop-dma.c')
-rw-r--r-- | drivers/media/dvb/b2c2/flexcop-dma.c | 165 |
1 files changed, 111 insertions, 54 deletions
diff --git a/drivers/media/dvb/b2c2/flexcop-dma.c b/drivers/media/dvb/b2c2/flexcop-dma.c index 8d2706075360..cf4ed1df6086 100644 --- a/drivers/media/dvb/b2c2/flexcop-dma.c +++ b/drivers/media/dvb/b2c2/flexcop-dma.c | |||
@@ -37,22 +37,90 @@ void flexcop_dma_free(struct flexcop_dma *dma) | |||
37 | } | 37 | } |
38 | EXPORT_SYMBOL(flexcop_dma_free); | 38 | EXPORT_SYMBOL(flexcop_dma_free); |
39 | 39 | ||
40 | int flexcop_dma_control_timer_irq(struct flexcop_device *fc, flexcop_dma_index_t no, int onoff) | 40 | int flexcop_dma_config(struct flexcop_device *fc, |
41 | struct flexcop_dma *dma, | ||
42 | flexcop_dma_index_t dma_idx) | ||
41 | { | 43 | { |
42 | flexcop_ibi_value v = fc->read_ibi_reg(fc,ctrl_208); | 44 | flexcop_ibi_value v0x0,v0x4,v0xc; |
45 | v0x0.raw = v0x4.raw = v0xc.raw = 0; | ||
43 | 46 | ||
44 | if (no & FC_DMA_1) | 47 | v0x0.dma_0x0.dma_address0 = dma->dma_addr0 >> 2; |
45 | v.ctrl_208.DMA1_Timer_Enable_sig = onoff; | 48 | v0xc.dma_0xc.dma_address1 = dma->dma_addr1 >> 2; |
49 | v0x4.dma_0x4_write.dma_addr_size = dma->size / 4; | ||
46 | 50 | ||
47 | if (no & FC_DMA_2) | 51 | if ((dma_idx & FC_DMA_1) == dma_idx) { |
48 | v.ctrl_208.DMA2_Timer_Enable_sig = onoff; | 52 | fc->write_ibi_reg(fc,dma1_000,v0x0); |
53 | fc->write_ibi_reg(fc,dma1_004,v0x4); | ||
54 | fc->write_ibi_reg(fc,dma1_00c,v0xc); | ||
55 | } else if ((dma_idx & FC_DMA_2) == dma_idx) { | ||
56 | fc->write_ibi_reg(fc,dma2_010,v0x0); | ||
57 | fc->write_ibi_reg(fc,dma2_014,v0x4); | ||
58 | fc->write_ibi_reg(fc,dma2_01c,v0xc); | ||
59 | } else { | ||
60 | err("either DMA1 or DMA2 can be configured at the within one flexcop_dma_config call."); | ||
61 | return -EINVAL; | ||
62 | } | ||
49 | 63 | ||
50 | fc->write_ibi_reg(fc,ctrl_208,v); | ||
51 | return 0; | 64 | return 0; |
52 | } | 65 | } |
53 | EXPORT_SYMBOL(flexcop_dma_control_timer_irq); | 66 | EXPORT_SYMBOL(flexcop_dma_config); |
67 | |||
68 | /* start the DMA transfers, but not the DMA IRQs */ | ||
69 | int flexcop_dma_xfer_control(struct flexcop_device *fc, | ||
70 | flexcop_dma_index_t dma_idx, | ||
71 | flexcop_dma_addr_index_t index, | ||
72 | int onoff) | ||
73 | { | ||
74 | flexcop_ibi_value v0x0,v0xc; | ||
75 | flexcop_ibi_register r0x0,r0xc; | ||
76 | |||
77 | if ((dma_idx & FC_DMA_1) == dma_idx) { | ||
78 | r0x0 = dma1_000; | ||
79 | r0xc = dma1_00c; | ||
80 | } else if ((dma_idx & FC_DMA_2) == dma_idx) { | ||
81 | r0x0 = dma2_010; | ||
82 | r0xc = dma2_01c; | ||
83 | } else { | ||
84 | err("either transfer DMA1 or DMA2 can be started within one flexcop_dma_xfer_control call."); | ||
85 | return -EINVAL; | ||
86 | } | ||
87 | |||
88 | v0x0 = fc->read_ibi_reg(fc,r0x0); | ||
89 | v0xc = fc->read_ibi_reg(fc,r0xc); | ||
90 | |||
91 | deb_rdump("reg: %03x: %x\n",r0x0,v0x0.raw); | ||
92 | deb_rdump("reg: %03x: %x\n",r0xc,v0xc.raw); | ||
93 | |||
94 | if (index & FC_DMA_SUBADDR_0) | ||
95 | v0x0.dma_0x0.dma_0start = onoff; | ||
96 | |||
97 | if (index & FC_DMA_SUBADDR_1) | ||
98 | v0xc.dma_0xc.dma_1start = onoff; | ||
99 | |||
100 | fc->write_ibi_reg(fc,r0x0,v0x0); | ||
101 | fc->write_ibi_reg(fc,r0xc,v0xc); | ||
102 | |||
103 | deb_rdump("reg: %03x: %x\n",r0x0,v0x0.raw); | ||
104 | deb_rdump("reg: %03x: %x\n",r0xc,v0xc.raw); | ||
105 | return 0; | ||
106 | } | ||
107 | EXPORT_SYMBOL(flexcop_dma_xfer_control); | ||
108 | |||
109 | static int flexcop_dma_remap(struct flexcop_device *fc, | ||
110 | flexcop_dma_index_t dma_idx, | ||
111 | int onoff) | ||
112 | { | ||
113 | flexcop_ibi_register r = (dma_idx & FC_DMA_1) ? dma1_00c : dma2_01c; | ||
114 | flexcop_ibi_value v = fc->read_ibi_reg(fc,r); | ||
115 | deb_info("%s\n",__FUNCTION__); | ||
116 | v.dma_0xc.remap_enable = onoff; | ||
117 | fc->write_ibi_reg(fc,r,v); | ||
118 | return 0; | ||
119 | } | ||
54 | 120 | ||
55 | int flexcop_dma_control_size_irq(struct flexcop_device *fc, flexcop_dma_index_t no, int onoff) | 121 | int flexcop_dma_control_size_irq(struct flexcop_device *fc, |
122 | flexcop_dma_index_t no, | ||
123 | int onoff) | ||
56 | { | 124 | { |
57 | flexcop_ibi_value v = fc->read_ibi_reg(fc,ctrl_208); | 125 | flexcop_ibi_value v = fc->read_ibi_reg(fc,ctrl_208); |
58 | 126 | ||
@@ -67,75 +135,64 @@ int flexcop_dma_control_size_irq(struct flexcop_device *fc, flexcop_dma_index_t | |||
67 | } | 135 | } |
68 | EXPORT_SYMBOL(flexcop_dma_control_size_irq); | 136 | EXPORT_SYMBOL(flexcop_dma_control_size_irq); |
69 | 137 | ||
70 | int flexcop_dma_control_packet_irq(struct flexcop_device *fc, flexcop_dma_index_t no, int onoff) | 138 | int flexcop_dma_control_timer_irq(struct flexcop_device *fc, |
139 | flexcop_dma_index_t no, | ||
140 | int onoff) | ||
71 | { | 141 | { |
72 | flexcop_ibi_value v = fc->read_ibi_reg(fc,ctrl_208); | 142 | flexcop_ibi_value v = fc->read_ibi_reg(fc,ctrl_208); |
73 | 143 | ||
74 | if (no & FC_DMA_1) | 144 | if (no & FC_DMA_1) |
75 | v.ctrl_208.DMA1_Size_IRQ_Enable_sig = onoff; | 145 | v.ctrl_208.DMA1_Timer_Enable_sig = onoff; |
76 | 146 | ||
77 | if (no & FC_DMA_2) | 147 | if (no & FC_DMA_2) |
78 | v.ctrl_208.DMA2_Size_IRQ_Enable_sig = onoff; | 148 | v.ctrl_208.DMA2_Timer_Enable_sig = onoff; |
79 | 149 | ||
80 | fc->write_ibi_reg(fc,ctrl_208,v); | 150 | fc->write_ibi_reg(fc,ctrl_208,v); |
81 | return 0; | 151 | return 0; |
82 | } | 152 | } |
83 | EXPORT_SYMBOL(flexcop_dma_control_packet_irq); | 153 | EXPORT_SYMBOL(flexcop_dma_control_timer_irq); |
84 | 154 | ||
85 | int flexcop_dma_config(struct flexcop_device *fc, struct flexcop_dma *dma, flexcop_dma_index_t dma_idx,flexcop_dma_addr_index_t index) | 155 | /* 1 cycles = 1.97 msec */ |
156 | int flexcop_dma_config_timer(struct flexcop_device *fc, | ||
157 | flexcop_dma_index_t dma_idx, | ||
158 | u8 cycles) | ||
86 | { | 159 | { |
160 | flexcop_ibi_register r = (dma_idx & FC_DMA_1) ? dma1_004 : dma2_014; | ||
161 | flexcop_ibi_value v = fc->read_ibi_reg(fc,r); | ||
87 | 162 | ||
88 | flexcop_ibi_value v0x0,v0x4,v0xc; | 163 | flexcop_dma_remap(fc,dma_idx,0); |
89 | v0x0.raw = v0x4.raw = v0xc.raw = 0; | ||
90 | |||
91 | v0x0.dma_0x0.dma_address0 = dma->dma_addr0 >> 2; | ||
92 | v0xc.dma_0xc.dma_address1 = dma->dma_addr1 >> 2; | ||
93 | v0x4.dma_0x4_write.dma_addr_size = dma->size / 4; | ||
94 | |||
95 | if (index & FC_DMA_SUBADDR_0) | ||
96 | v0x0.dma_0x0.dma_0start = 1; | ||
97 | |||
98 | if (index & FC_DMA_SUBADDR_1) | ||
99 | v0xc.dma_0xc.dma_1start = 1; | ||
100 | |||
101 | if (dma_idx & FC_DMA_1) { | ||
102 | fc->write_ibi_reg(fc,dma1_000,v0x0); | ||
103 | fc->write_ibi_reg(fc,dma1_004,v0x4); | ||
104 | fc->write_ibi_reg(fc,dma1_00c,v0xc); | ||
105 | } else { /* (dma_idx & FC_DMA_2) */ | ||
106 | fc->write_ibi_reg(fc,dma2_010,v0x0); | ||
107 | fc->write_ibi_reg(fc,dma2_014,v0x4); | ||
108 | fc->write_ibi_reg(fc,dma2_01c,v0xc); | ||
109 | } | ||
110 | |||
111 | return 0; | ||
112 | } | ||
113 | EXPORT_SYMBOL(flexcop_dma_config); | ||
114 | 164 | ||
115 | static int flexcop_dma_remap(struct flexcop_device *fc, flexcop_dma_index_t dma_idx, int onoff) | 165 | deb_info("%s\n",__FUNCTION__); |
116 | { | 166 | v.dma_0x4_write.dmatimer = cycles; |
117 | flexcop_ibi_register r = (dma_idx & FC_DMA_1) ? dma1_00c : dma2_01c; | ||
118 | flexcop_ibi_value v = fc->read_ibi_reg(fc,r); | ||
119 | v.dma_0xc.remap_enable = onoff; | ||
120 | fc->write_ibi_reg(fc,r,v); | 167 | fc->write_ibi_reg(fc,r,v); |
121 | return 0; | 168 | return 0; |
122 | } | 169 | } |
170 | EXPORT_SYMBOL(flexcop_dma_config_timer); | ||
123 | 171 | ||
124 | /* 1 cycles = 1.97 msec */ | 172 | /* packet IRQ does not exist in FCII or FCIIb - according to data book and tests */ |
125 | int flexcop_dma_config_timer(struct flexcop_device *fc, flexcop_dma_index_t dma_idx, u8 cycles) | 173 | int flexcop_dma_control_packet_irq(struct flexcop_device *fc, |
174 | flexcop_dma_index_t no, | ||
175 | int onoff) | ||
126 | { | 176 | { |
127 | flexcop_ibi_register r = (dma_idx & FC_DMA_1) ? dma1_004 : dma2_014; | 177 | flexcop_ibi_value v = fc->read_ibi_reg(fc,ctrl_208); |
128 | flexcop_ibi_value v = fc->read_ibi_reg(fc,r); | ||
129 | 178 | ||
130 | flexcop_dma_remap(fc,dma_idx,0); | 179 | deb_rdump("reg: %03x: %x\n",ctrl_208,v.raw); |
180 | if (no & FC_DMA_1) | ||
181 | v.ctrl_208.DMA1_Size_IRQ_Enable_sig = onoff; | ||
182 | |||
183 | if (no & FC_DMA_2) | ||
184 | v.ctrl_208.DMA2_Size_IRQ_Enable_sig = onoff; | ||
185 | |||
186 | fc->write_ibi_reg(fc,ctrl_208,v); | ||
187 | deb_rdump("reg: %03x: %x\n",ctrl_208,v.raw); | ||
131 | 188 | ||
132 | v.dma_0x4_write.dmatimer = cycles >> 1; | ||
133 | fc->write_ibi_reg(fc,r,v); | ||
134 | return 0; | 189 | return 0; |
135 | } | 190 | } |
136 | EXPORT_SYMBOL(flexcop_dma_config_timer); | 191 | EXPORT_SYMBOL(flexcop_dma_control_packet_irq); |
137 | 192 | ||
138 | int flexcop_dma_config_packet_count(struct flexcop_device *fc, flexcop_dma_index_t dma_idx, u8 packets) | 193 | int flexcop_dma_config_packet_count(struct flexcop_device *fc, |
194 | flexcop_dma_index_t dma_idx, | ||
195 | u8 packets) | ||
139 | { | 196 | { |
140 | flexcop_ibi_register r = (dma_idx & FC_DMA_1) ? dma1_004 : dma2_014; | 197 | flexcop_ibi_register r = (dma_idx & FC_DMA_1) ? dma1_004 : dma2_014; |
141 | flexcop_ibi_value v = fc->read_ibi_reg(fc,r); | 198 | flexcop_ibi_value v = fc->read_ibi_reg(fc,r); |