1083a11a3SMarcus Overhagen /*
2083a11a3SMarcus Overhagen * Copyright (c) 2004-2007 Marcus Overhagen <marcus@overhagen.de>
3083a11a3SMarcus Overhagen *
4083a11a3SMarcus Overhagen * Permission is hereby granted, free of charge, to any person
5083a11a3SMarcus Overhagen * obtaining a copy of this software and associated documentation
6083a11a3SMarcus Overhagen * files (the "Software"), to deal in the Software without restriction,
7083a11a3SMarcus Overhagen * including without limitation the rights to use, copy, modify,
8083a11a3SMarcus Overhagen * merge, publish, distribute, sublicense, and/or sell copies of
9083a11a3SMarcus Overhagen * the Software, and to permit persons to whom the Software is
10083a11a3SMarcus Overhagen * furnished to do so, subject to the following conditions:
11083a11a3SMarcus Overhagen *
12083a11a3SMarcus Overhagen * The above copyright notice and this permission notice shall be
13083a11a3SMarcus Overhagen * included in all copies or substantial portions of the Software.
14083a11a3SMarcus Overhagen *
15083a11a3SMarcus Overhagen * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16083a11a3SMarcus Overhagen * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17083a11a3SMarcus Overhagen * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18083a11a3SMarcus Overhagen * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19083a11a3SMarcus Overhagen * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20083a11a3SMarcus Overhagen * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21083a11a3SMarcus Overhagen * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22083a11a3SMarcus Overhagen * OTHER DEALINGS IN THE SOFTWARE.
23083a11a3SMarcus Overhagen */
24083a11a3SMarcus Overhagen
25083a11a3SMarcus Overhagen #include "cx23882.h"
26083a11a3SMarcus Overhagen #include "util.h"
27083a11a3SMarcus Overhagen #include <KernelExport.h>
28083a11a3SMarcus Overhagen #include <ByteOrder.h>
29083a11a3SMarcus Overhagen #include <Drivers.h>
30083a11a3SMarcus Overhagen
31083a11a3SMarcus Overhagen
32083a11a3SMarcus Overhagen #define TRACE_CX23882
33083a11a3SMarcus Overhagen #ifdef TRACE_CX23882
34083a11a3SMarcus Overhagen #define TRACE dprintf
35083a11a3SMarcus Overhagen #else
36083a11a3SMarcus Overhagen #define TRACE(a...)
37083a11a3SMarcus Overhagen #endif
38083a11a3SMarcus Overhagen
39083a11a3SMarcus Overhagen // settings for hardware stream sync
40083a11a3SMarcus Overhagen #define MPEG2_SYNC_BYTE 0x47
41083a11a3SMarcus Overhagen #define MPEG2_PACKET_SIZE 188
42083a11a3SMarcus Overhagen #define SYNC_PACKET_COUNT 7 // 0 and 5 don't seem to work
43083a11a3SMarcus Overhagen
44083a11a3SMarcus Overhagen // Line size is also used as FIFO size!
45083a11a3SMarcus Overhagen // BYTES_PER_LINE must be a multiple of 8 and <= 4096 bytes
46083a11a3SMarcus Overhagen #define PACKETS_PER_LINE 20
47083a11a3SMarcus Overhagen #define BYTES_PER_LINE (PACKETS_PER_LINE * MPEG2_PACKET_SIZE)
48083a11a3SMarcus Overhagen
49083a11a3SMarcus Overhagen #define SRAM_START_ADDRESS 0x180000
50083a11a3SMarcus Overhagen #define SRAM_BASE_CMDS_TS 0x200
51083a11a3SMarcus Overhagen #define SRAM_BASE_RISC_PROG 0x400
52083a11a3SMarcus Overhagen #define SRAM_BASE_RISC_QUEUE 0x800
53083a11a3SMarcus Overhagen #define SRAM_BASE_CDT 0x900
54083a11a3SMarcus Overhagen #define SRAM_BASE_FIFO_0 0x1000
55083a11a3SMarcus Overhagen #define SRAM_BASE_FIFO_1 0x2000
56083a11a3SMarcus Overhagen
57083a11a3SMarcus Overhagen // About 64 kByte DMA buffer size
58083a11a3SMarcus Overhagen #define LINES_PER_BUFFER 16
59083a11a3SMarcus Overhagen #define DMA_BUFFER_SIZE (LINES_PER_BUFFER * BYTES_PER_LINE)
60083a11a3SMarcus Overhagen
61083a11a3SMarcus Overhagen
62083a11a3SMarcus Overhagen static status_t cx23882_buffers_alloc(cx23882_device *device);
63083a11a3SMarcus Overhagen static void cx23882_buffers_free(cx23882_device *device);
64083a11a3SMarcus Overhagen static void cx23882_risc_ram_setup(cx23882_device *device);
65083a11a3SMarcus Overhagen static void cx23882_sram_setup(cx23882_device *device);
66083a11a3SMarcus Overhagen static void cx23882_via_sis_fixup(cx23882_device *device);
67083a11a3SMarcus Overhagen
68083a11a3SMarcus Overhagen
69083a11a3SMarcus Overhagen void
cx23882_reset(cx23882_device * device)70083a11a3SMarcus Overhagen cx23882_reset(cx23882_device *device)
71083a11a3SMarcus Overhagen {
72083a11a3SMarcus Overhagen // software reset (XXX Test)
73083a11a3SMarcus Overhagen reg_write32(0x38c06c, 1);
74083a11a3SMarcus Overhagen snooze(200000);
75083a11a3SMarcus Overhagen
76083a11a3SMarcus Overhagen // disable RISC controller
77083a11a3SMarcus Overhagen reg_write32(REG_DEV_CNTRL2, 0);
78083a11a3SMarcus Overhagen
79083a11a3SMarcus Overhagen // disable TS interface DMA
80083a11a3SMarcus Overhagen reg_write32(REG_TS_DMA_CNTRL, 0x0);
81083a11a3SMarcus Overhagen
82083a11a3SMarcus Overhagen // disable VIP interface up- & downstram DMA
83083a11a3SMarcus Overhagen reg_write32(REG_VIP_STREAM_EN, 0x0);
84083a11a3SMarcus Overhagen
85083a11a3SMarcus Overhagen // disable host interface up- & downstram DMA
86083a11a3SMarcus Overhagen reg_write32(REG_HST_STREAM_EN, 0x0);
87083a11a3SMarcus Overhagen
88083a11a3SMarcus Overhagen // stop all interrupts
89083a11a3SMarcus Overhagen reg_write32(REG_PCI_INT_MSK, 0x0);
90083a11a3SMarcus Overhagen reg_write32(REG_VID_INT_MSK, 0x0);
91083a11a3SMarcus Overhagen reg_write32(REG_AUD_INT_MSK, 0x0);
92083a11a3SMarcus Overhagen reg_write32(REG_TS_INT_MSK, 0x0);
93083a11a3SMarcus Overhagen reg_write32(REG_VIP_INT_MSK, 0x0);
94083a11a3SMarcus Overhagen reg_write32(REG_HST_INT_MSK, 0x0);
95083a11a3SMarcus Overhagen reg_write32(REG_DMA_RISC_INT_MSK, 0x0);
96083a11a3SMarcus Overhagen
97083a11a3SMarcus Overhagen // clear all pending interrupts
98083a11a3SMarcus Overhagen reg_write32(REG_PCI_INT_STAT, 0xffffffff);
99083a11a3SMarcus Overhagen reg_write32(REG_VID_INT_STAT, 0xffffffff);
100083a11a3SMarcus Overhagen reg_write32(REG_AUD_INT_STAT, 0xffffffff);
101083a11a3SMarcus Overhagen reg_write32(REG_TS_INT_STAT, 0xffffffff);
102083a11a3SMarcus Overhagen reg_write32(REG_VIP_INT_STAT, 0xffffffff);
103083a11a3SMarcus Overhagen reg_write32(REG_HST_INT_STAT, 0xffffffff);
104083a11a3SMarcus Overhagen reg_write32(REG_DMA_RISC_INT_MSK, 0xffffffff);
105083a11a3SMarcus Overhagen }
106083a11a3SMarcus Overhagen
107083a11a3SMarcus Overhagen
108083a11a3SMarcus Overhagen status_t
cx23882_init(cx23882_device * device)109083a11a3SMarcus Overhagen cx23882_init(cx23882_device *device)
110083a11a3SMarcus Overhagen {
111083a11a3SMarcus Overhagen // assumes that cx23882_reset() has already been called
112083a11a3SMarcus Overhagen
113083a11a3SMarcus Overhagen status_t err;
114083a11a3SMarcus Overhagen
115083a11a3SMarcus Overhagen if ((err = cx23882_buffers_alloc(device)) < B_OK) {
116083a11a3SMarcus Overhagen dprintf("cx23882: Error, buffer alloc failed\n");
117083a11a3SMarcus Overhagen return err;
118083a11a3SMarcus Overhagen }
119083a11a3SMarcus Overhagen
120083a11a3SMarcus Overhagen device->capture_size = DMA_BUFFER_SIZE;
121083a11a3SMarcus Overhagen
122083a11a3SMarcus Overhagen cx23882_via_sis_fixup(device);
123083a11a3SMarcus Overhagen
124083a11a3SMarcus Overhagen // Set FIFO thresholds, should be 0 < x <= 7
125083a11a3SMarcus Overhagen reg_write32(REG_PDMA_STHRSH, PDMA_ISBTHRSH_6 | PDMA_PCITHRSH_6);
126083a11a3SMarcus Overhagen reg_write32(REG_PDMA_DTHRSH, PDMA_ISBTHRSH_6 | PDMA_PCITHRSH_6);
127083a11a3SMarcus Overhagen
128083a11a3SMarcus Overhagen // init risc programm
129083a11a3SMarcus Overhagen cx23882_risc_ram_setup(device);
130083a11a3SMarcus Overhagen
131083a11a3SMarcus Overhagen // init sram
132083a11a3SMarcus Overhagen cx23882_sram_setup(device);
133083a11a3SMarcus Overhagen
134083a11a3SMarcus Overhagen // Reset counter to 0
135083a11a3SMarcus Overhagen reg_write32(REG_TS_GP_CNT_CNTRL, 0x3);
136083a11a3SMarcus Overhagen
137083a11a3SMarcus Overhagen // Line length for RISC DMA
138083a11a3SMarcus Overhagen reg_write32(REG_TS_LNGTH, BYTES_PER_LINE);
139083a11a3SMarcus Overhagen
140083a11a3SMarcus Overhagen // Set serial interface mode
141083a11a3SMarcus Overhagen reg_write32(REG_TS_GEN_CONTROL, reg_read32(REG_TS_GEN_CONTROL) | TS_GEN_CONTROL_IPB_SMODE);
142083a11a3SMarcus Overhagen
143083a11a3SMarcus Overhagen // Setup hardware MPEG2 fec interface
144083a11a3SMarcus Overhagen reg_write32(REG_HW_SOP_CONTROL, (MPEG2_SYNC_BYTE << 16) | (MPEG2_PACKET_SIZE << 4) | SYNC_PACKET_COUNT);
145083a11a3SMarcus Overhagen
146083a11a3SMarcus Overhagen // Setup TSSTOP status, active low, rising and falling edge, single bit width
147083a11a3SMarcus Overhagen reg_write32(REG_TS_SOP_STATUS, reg_read32(REG_TS_SOP_STATUS) | 0x18000);
148083a11a3SMarcus Overhagen reg_write32(REG_TS_SOP_STATUS, reg_read32(REG_TS_SOP_STATUS) & ~0x06000);
149083a11a3SMarcus Overhagen
150083a11a3SMarcus Overhagen // Enable interrupts for MPEG TS and all errors
151083a11a3SMarcus Overhagen reg_write32(REG_PCI_INT_MSK, reg_read32(REG_PCI_INT_MSK) | PCI_INT_STAT_TS_INT | 0x00fc00);
152083a11a3SMarcus Overhagen reg_write32(REG_TS_INT_MSK, reg_read32(REG_TS_INT_MSK) | TS_INT_STAT_TS_RISC1 | TS_INT_STAT_TS_RISC2 | 0x1f1100);
153083a11a3SMarcus Overhagen
154083a11a3SMarcus Overhagen TRACE("cx23882_init done\n");
155083a11a3SMarcus Overhagen return B_OK;
156083a11a3SMarcus Overhagen }
157083a11a3SMarcus Overhagen
158083a11a3SMarcus Overhagen
159083a11a3SMarcus Overhagen status_t
cx23882_terminate(cx23882_device * device)160083a11a3SMarcus Overhagen cx23882_terminate(cx23882_device *device)
161083a11a3SMarcus Overhagen {
162083a11a3SMarcus Overhagen cx23882_reset(device);
163083a11a3SMarcus Overhagen
164083a11a3SMarcus Overhagen cx23882_buffers_free(device);
165083a11a3SMarcus Overhagen return B_OK;
166083a11a3SMarcus Overhagen }
167083a11a3SMarcus Overhagen
168083a11a3SMarcus Overhagen
169083a11a3SMarcus Overhagen status_t
cx23882_start_capture(cx23882_device * device)170083a11a3SMarcus Overhagen cx23882_start_capture(cx23882_device *device)
171083a11a3SMarcus Overhagen {
172083a11a3SMarcus Overhagen TRACE("cx23882_start_capture\n");
173083a11a3SMarcus Overhagen
174083a11a3SMarcus Overhagen // start RISC processor and DMA
175083a11a3SMarcus Overhagen reg_write32(REG_DEV_CNTRL2, reg_read32(REG_DEV_CNTRL2) | DEV_CNTRL2_RUN_RISC);
176083a11a3SMarcus Overhagen reg_write32(REG_TS_DMA_CNTRL, reg_read32(REG_TS_DMA_CNTRL) | TS_DMA_CNTRL_TS_FIFO_EN | TS_DMA_CNTRL_TS_RISC_EN);
177083a11a3SMarcus Overhagen return B_OK;
178083a11a3SMarcus Overhagen }
179083a11a3SMarcus Overhagen
180083a11a3SMarcus Overhagen
181083a11a3SMarcus Overhagen status_t
cx23882_stop_capture(cx23882_device * device)182083a11a3SMarcus Overhagen cx23882_stop_capture(cx23882_device *device)
183083a11a3SMarcus Overhagen {
184083a11a3SMarcus Overhagen TRACE("cx23882_stop_capture\n");
185083a11a3SMarcus Overhagen
186083a11a3SMarcus Overhagen // stop RISC processor and DMA
187083a11a3SMarcus Overhagen reg_write32(REG_TS_DMA_CNTRL, reg_read32(REG_TS_DMA_CNTRL) & ~(TS_DMA_CNTRL_TS_FIFO_EN | TS_DMA_CNTRL_TS_RISC_EN));
188083a11a3SMarcus Overhagen reg_write32(REG_DEV_CNTRL2, reg_read32(REG_DEV_CNTRL2) & ~DEV_CNTRL2_RUN_RISC);
189083a11a3SMarcus Overhagen return B_OK;
190083a11a3SMarcus Overhagen }
191083a11a3SMarcus Overhagen
192083a11a3SMarcus Overhagen
193083a11a3SMarcus Overhagen static inline void
cx23882_mpegts_int(cx23882_device * device)194083a11a3SMarcus Overhagen cx23882_mpegts_int(cx23882_device *device)
195083a11a3SMarcus Overhagen {
196083a11a3SMarcus Overhagen uint32 mstat = reg_read32(REG_TS_INT_MSTAT);
197083a11a3SMarcus Overhagen reg_write32(REG_TS_INT_STAT, mstat);
198083a11a3SMarcus Overhagen
199083a11a3SMarcus Overhagen // dprintf("cx23882_mpegts_int got 0x%08lx\n", mstat);
200083a11a3SMarcus Overhagen
201083a11a3SMarcus Overhagen if (mstat & TS_INT_STAT_OPC_ERR) {
202083a11a3SMarcus Overhagen dprintf("cx23882_mpegts_int RISC opcode error\n");
203083a11a3SMarcus Overhagen reg_write32(REG_PCI_INT_MSK, 0);
204083a11a3SMarcus Overhagen return;
205083a11a3SMarcus Overhagen }
206083a11a3SMarcus Overhagen
207083a11a3SMarcus Overhagen if ((mstat & (TS_INT_STAT_TS_RISC1 | TS_INT_STAT_TS_RISC2)) == (TS_INT_STAT_TS_RISC1 | TS_INT_STAT_TS_RISC2)) {
208083a11a3SMarcus Overhagen dprintf("cx23882_mpegts_int both buffers ready\n");
209083a11a3SMarcus Overhagen mstat = TS_INT_STAT_TS_RISC1;
210083a11a3SMarcus Overhagen }
211083a11a3SMarcus Overhagen
212083a11a3SMarcus Overhagen if (mstat & TS_INT_STAT_TS_RISC1) {
213083a11a3SMarcus Overhagen int32 count;
214*425ac1b6SAlexander von Gluck IV // dprintf("cx23882_mpegts_int buffer 1 at %lld\n", system_time());
215083a11a3SMarcus Overhagen device->capture_data = device->dma_buf1_virt;
216083a11a3SMarcus Overhagen device->capture_end_time = system_time();
217083a11a3SMarcus Overhagen get_sem_count(device->capture_sem, &count);
218083a11a3SMarcus Overhagen if (count <= 0)
219083a11a3SMarcus Overhagen release_sem_etc(device->capture_sem, 1, B_DO_NOT_RESCHEDULE);
220083a11a3SMarcus Overhagen }
221083a11a3SMarcus Overhagen
222083a11a3SMarcus Overhagen if (mstat & TS_INT_STAT_TS_RISC2) {
223083a11a3SMarcus Overhagen int32 count;
224*425ac1b6SAlexander von Gluck IV // dprintf("cx23882_mpegts_int buffer 2 at %lld\n", system_time());
225083a11a3SMarcus Overhagen device->capture_data = device->dma_buf2_virt;
226083a11a3SMarcus Overhagen device->capture_end_time = system_time();
227083a11a3SMarcus Overhagen get_sem_count(device->capture_sem, &count);
228083a11a3SMarcus Overhagen if (count <= 0)
229083a11a3SMarcus Overhagen release_sem_etc(device->capture_sem, 1, B_DO_NOT_RESCHEDULE);
230083a11a3SMarcus Overhagen }
231083a11a3SMarcus Overhagen }
232083a11a3SMarcus Overhagen
233083a11a3SMarcus Overhagen
234083a11a3SMarcus Overhagen int32
cx23882_int(void * data)235083a11a3SMarcus Overhagen cx23882_int(void *data)
236083a11a3SMarcus Overhagen {
237083a11a3SMarcus Overhagen cx23882_device *device = data;
238083a11a3SMarcus Overhagen uint32 mstat;
239083a11a3SMarcus Overhagen uint32 wmstat;
240083a11a3SMarcus Overhagen
241083a11a3SMarcus Overhagen mstat = reg_read32(REG_PCI_INT_MSTAT);
242083a11a3SMarcus Overhagen if (!mstat)
243083a11a3SMarcus Overhagen return B_UNHANDLED_INTERRUPT;
244083a11a3SMarcus Overhagen
245083a11a3SMarcus Overhagen if (mstat & (PCI_INT_STAT_HST_INT | PCI_INT_STAT_VIP_INT | PCI_INT_STAT_AUD_INT | PCI_INT_STAT_VID_INT)) {
246083a11a3SMarcus Overhagen // serious error, these bits should not be set
2476849e7ccSJérôme Duval dprintf("cx23882_int error: msk 0x%08" B_PRIx32 ", stat 0x%08" B_PRIx32
2486849e7ccSJérôme Duval ", mstat 0x%08" B_PRIx32 "\n", reg_read32(REG_PCI_INT_MSK),
2496849e7ccSJérôme Duval reg_read32(REG_PCI_INT_STAT), mstat);
250083a11a3SMarcus Overhagen reg_write32(REG_PCI_INT_MSK, 0);
251083a11a3SMarcus Overhagen return B_HANDLED_INTERRUPT;
252083a11a3SMarcus Overhagen }
253083a11a3SMarcus Overhagen
254083a11a3SMarcus Overhagen wmstat = mstat & ~(PCI_INT_STAT_HST_INT | PCI_INT_STAT_VIP_INT | PCI_INT_STAT_TS_INT | PCI_INT_STAT_AUD_INT | PCI_INT_STAT_VID_INT);
255083a11a3SMarcus Overhagen if (wmstat)
256083a11a3SMarcus Overhagen reg_write32(REG_PCI_INT_STAT, wmstat);
257083a11a3SMarcus Overhagen
258083a11a3SMarcus Overhagen if (wmstat)
2596849e7ccSJérôme Duval dprintf("cx23882_int got 0x%08" B_PRIx32 "\n", wmstat);
260083a11a3SMarcus Overhagen
261083a11a3SMarcus Overhagen if (mstat & PCI_INT_STAT_TS_INT) {
262083a11a3SMarcus Overhagen cx23882_mpegts_int(device);
263083a11a3SMarcus Overhagen return B_INVOKE_SCHEDULER;
264083a11a3SMarcus Overhagen } else {
265083a11a3SMarcus Overhagen return B_HANDLED_INTERRUPT;
266083a11a3SMarcus Overhagen }
267083a11a3SMarcus Overhagen }
268083a11a3SMarcus Overhagen
269083a11a3SMarcus Overhagen
270083a11a3SMarcus Overhagen static status_t
cx23882_buffers_alloc(cx23882_device * device)271083a11a3SMarcus Overhagen cx23882_buffers_alloc(cx23882_device *device)
272083a11a3SMarcus Overhagen {
273083a11a3SMarcus Overhagen device->dma_buf1_area = alloc_mem(&device->dma_buf1_virt, &device->dma_buf1_phys, DMA_BUFFER_SIZE, B_READ_AREA, "cx23882 dma buf 1");
274083a11a3SMarcus Overhagen device->dma_buf2_area = alloc_mem(&device->dma_buf2_virt, &device->dma_buf2_phys, DMA_BUFFER_SIZE, B_READ_AREA, "cx23882 dma buf 2");
275083a11a3SMarcus Overhagen if (device->dma_buf1_area < B_OK || device->dma_buf2_area < B_OK) {
276083a11a3SMarcus Overhagen cx23882_buffers_free(device);
277083a11a3SMarcus Overhagen return B_NO_MEMORY;
278083a11a3SMarcus Overhagen }
279083a11a3SMarcus Overhagen return B_OK;
280083a11a3SMarcus Overhagen }
281083a11a3SMarcus Overhagen
282083a11a3SMarcus Overhagen
283083a11a3SMarcus Overhagen static void
cx23882_buffers_free(cx23882_device * device)284083a11a3SMarcus Overhagen cx23882_buffers_free(cx23882_device *device)
285083a11a3SMarcus Overhagen {
286083a11a3SMarcus Overhagen if (device->dma_buf1_area >= 0)
287083a11a3SMarcus Overhagen delete_area(device->dma_buf1_area);
288083a11a3SMarcus Overhagen if (device->dma_buf2_area >= 0)
289083a11a3SMarcus Overhagen delete_area(device->dma_buf2_area);
290083a11a3SMarcus Overhagen device->dma_buf1_area = -1;
291083a11a3SMarcus Overhagen device->dma_buf2_area = -1;
292083a11a3SMarcus Overhagen }
293083a11a3SMarcus Overhagen
294083a11a3SMarcus Overhagen
295083a11a3SMarcus Overhagen static void
cx23882_sram_setup(cx23882_device * device)296083a11a3SMarcus Overhagen cx23882_sram_setup(cx23882_device *device)
297083a11a3SMarcus Overhagen {
298083a11a3SMarcus Overhagen dprintf("cx23882_sram_setup enter\n");
299083a11a3SMarcus Overhagen
300083a11a3SMarcus Overhagen // setup CDT entries for both FIFOs
301083a11a3SMarcus Overhagen reg_write32(SRAM_START_ADDRESS + SRAM_BASE_CDT, SRAM_START_ADDRESS + SRAM_BASE_FIFO_0);
302083a11a3SMarcus Overhagen reg_write32(SRAM_START_ADDRESS + SRAM_BASE_CDT + 16, SRAM_START_ADDRESS + SRAM_BASE_FIFO_1);
303083a11a3SMarcus Overhagen
304083a11a3SMarcus Overhagen // setup CDMS
305083a11a3SMarcus Overhagen reg_write32(SRAM_START_ADDRESS + SRAM_BASE_CMDS_TS + 0x00, SRAM_START_ADDRESS + SRAM_BASE_RISC_PROG);
306083a11a3SMarcus Overhagen reg_write32(SRAM_START_ADDRESS + SRAM_BASE_CMDS_TS + 0x04, SRAM_START_ADDRESS + SRAM_BASE_CDT);
307083a11a3SMarcus Overhagen reg_write32(SRAM_START_ADDRESS + SRAM_BASE_CMDS_TS + 0x08, (2 * 16) / 8); // FIFO count = 2
308083a11a3SMarcus Overhagen reg_write32(SRAM_START_ADDRESS + SRAM_BASE_CMDS_TS + 0x0c, SRAM_START_ADDRESS + SRAM_BASE_RISC_QUEUE);
309083a11a3SMarcus Overhagen reg_write32(SRAM_START_ADDRESS + SRAM_BASE_CMDS_TS + 0x10, 0x80000000 | (0x100 / 4));
310083a11a3SMarcus Overhagen
311083a11a3SMarcus Overhagen // setup DMA registers
312083a11a3SMarcus Overhagen reg_write32(REG_DMA28_PTR1, SRAM_START_ADDRESS + SRAM_BASE_FIFO_0);
313083a11a3SMarcus Overhagen reg_write32(REG_DMA28_PTR2, SRAM_START_ADDRESS + SRAM_BASE_CDT);
314083a11a3SMarcus Overhagen reg_write32(REG_DMA28_CNT1, BYTES_PER_LINE / 8);
315083a11a3SMarcus Overhagen reg_write32(REG_DMA28_CNT2, (2 * 16) / 8); // FIFO count = 2
316083a11a3SMarcus Overhagen
317083a11a3SMarcus Overhagen dprintf("cx23882_sram_setup leave\n");
318083a11a3SMarcus Overhagen }
319083a11a3SMarcus Overhagen
320083a11a3SMarcus Overhagen
321083a11a3SMarcus Overhagen static void
cx23882_risc_ram_setup(cx23882_device * device)322083a11a3SMarcus Overhagen cx23882_risc_ram_setup(cx23882_device *device)
323083a11a3SMarcus Overhagen {
324083a11a3SMarcus Overhagen char *start = (char *)(device->regs) + SRAM_START_ADDRESS + SRAM_BASE_RISC_PROG;
325083a11a3SMarcus Overhagen volatile uint32 *rp = (volatile uint32 *)start;
326083a11a3SMarcus Overhagen int i;
327083a11a3SMarcus Overhagen
328083a11a3SMarcus Overhagen #define set_opcode(a) (*rp++) = B_HOST_TO_LENDIAN_INT32((a))
329083a11a3SMarcus Overhagen
330083a11a3SMarcus Overhagen dprintf("cx23882_risc_ram_setup enter\n");
331083a11a3SMarcus Overhagen
332083a11a3SMarcus Overhagen // sync
333083a11a3SMarcus Overhagen set_opcode(RISC_RESYNC | 0);
334083a11a3SMarcus Overhagen
335083a11a3SMarcus Overhagen // copy buffer 1
336083a11a3SMarcus Overhagen for (i = 0; i < LINES_PER_BUFFER; i++) {
337083a11a3SMarcus Overhagen set_opcode(RISC_WRITE | RISC_SOL | RISC_EOL | BYTES_PER_LINE);
338083a11a3SMarcus Overhagen set_opcode((unsigned long)device->dma_buf1_phys + i * BYTES_PER_LINE);
339083a11a3SMarcus Overhagen }
340083a11a3SMarcus Overhagen
341083a11a3SMarcus Overhagen // execute IRQ 1
342083a11a3SMarcus Overhagen set_opcode(RISC_SKIP | RISC_IRQ1 | RISC_SOL | 0);
343083a11a3SMarcus Overhagen
344083a11a3SMarcus Overhagen // copy buffer 2
345083a11a3SMarcus Overhagen for (i = 0; i < LINES_PER_BUFFER; i++) {
346083a11a3SMarcus Overhagen set_opcode(RISC_WRITE | RISC_SOL | RISC_EOL | BYTES_PER_LINE);
347083a11a3SMarcus Overhagen set_opcode((unsigned long)device->dma_buf2_phys + i * BYTES_PER_LINE);
348083a11a3SMarcus Overhagen }
349083a11a3SMarcus Overhagen
350083a11a3SMarcus Overhagen // execute IRQ 2
351083a11a3SMarcus Overhagen set_opcode(RISC_SKIP | RISC_IRQ2 | RISC_SOL | 0);
352083a11a3SMarcus Overhagen
353083a11a3SMarcus Overhagen // jmp to start, but skip sync instruction
354083a11a3SMarcus Overhagen set_opcode(RISC_JUMP | RISC_SRP);
355083a11a3SMarcus Overhagen set_opcode(SRAM_START_ADDRESS + SRAM_BASE_RISC_PROG + 4);
356083a11a3SMarcus Overhagen
357083a11a3SMarcus Overhagen #undef set_opcode
358083a11a3SMarcus Overhagen
359083a11a3SMarcus Overhagen dprintf("cx23882_risc_ram_setup leave\n");
360083a11a3SMarcus Overhagen }
361083a11a3SMarcus Overhagen
362083a11a3SMarcus Overhagen
363083a11a3SMarcus Overhagen static void
cx23882_via_sis_fixup(cx23882_device * device)364083a11a3SMarcus Overhagen cx23882_via_sis_fixup(cx23882_device *device)
365083a11a3SMarcus Overhagen {
366083a11a3SMarcus Overhagen uint16 host_vendor;
367083a11a3SMarcus Overhagen uint32 dev_cntrl1;
368083a11a3SMarcus Overhagen
369083a11a3SMarcus Overhagen host_vendor = gPci->read_pci_config(0, 0, 0, PCI_vendor_id, 2);
370083a11a3SMarcus Overhagen dev_cntrl1 = reg_read32(REG_F2_DEV_CNTRL1);
371083a11a3SMarcus Overhagen
372083a11a3SMarcus Overhagen if (host_vendor == PCI_VENDOR_VIA || host_vendor == PCI_VENDOR_SIS) {
373083a11a3SMarcus Overhagen dprintf("cx23882: enabling VIA/SIS compatibility mode\n");
374083a11a3SMarcus Overhagen reg_write32(REG_F2_DEV_CNTRL1, dev_cntrl1 | F2_DEV_CNTRL1_EN_VSFX);
375083a11a3SMarcus Overhagen } else {
376083a11a3SMarcus Overhagen dprintf("cx23882: disabling VIA/SIS compatibility mode\n");
377083a11a3SMarcus Overhagen reg_write32(REG_F2_DEV_CNTRL1, dev_cntrl1 & ~F2_DEV_CNTRL1_EN_VSFX);
378083a11a3SMarcus Overhagen }
379083a11a3SMarcus Overhagen }
380