1*083a11a3SMarcus Overhagen /* 2*083a11a3SMarcus Overhagen * Copyright (c) 2004-2007 Marcus Overhagen <marcus@overhagen.de> 3*083a11a3SMarcus Overhagen * 4*083a11a3SMarcus Overhagen * Permission is hereby granted, free of charge, to any person 5*083a11a3SMarcus Overhagen * obtaining a copy of this software and associated documentation 6*083a11a3SMarcus Overhagen * files (the "Software"), to deal in the Software without restriction, 7*083a11a3SMarcus Overhagen * including without limitation the rights to use, copy, modify, 8*083a11a3SMarcus Overhagen * merge, publish, distribute, sublicense, and/or sell copies of 9*083a11a3SMarcus Overhagen * the Software, and to permit persons to whom the Software is 10*083a11a3SMarcus Overhagen * furnished to do so, subject to the following conditions: 11*083a11a3SMarcus Overhagen * 12*083a11a3SMarcus Overhagen * The above copyright notice and this permission notice shall be 13*083a11a3SMarcus Overhagen * included in all copies or substantial portions of the Software. 14*083a11a3SMarcus Overhagen * 15*083a11a3SMarcus Overhagen * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16*083a11a3SMarcus Overhagen * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17*083a11a3SMarcus Overhagen * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18*083a11a3SMarcus Overhagen * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 19*083a11a3SMarcus Overhagen * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 20*083a11a3SMarcus Overhagen * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21*083a11a3SMarcus Overhagen * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22*083a11a3SMarcus Overhagen * OTHER DEALINGS IN THE SOFTWARE. 23*083a11a3SMarcus Overhagen */ 24*083a11a3SMarcus Overhagen 25*083a11a3SMarcus Overhagen #include "cx23882.h" 26*083a11a3SMarcus Overhagen #include "util.h" 27*083a11a3SMarcus Overhagen #include <KernelExport.h> 28*083a11a3SMarcus Overhagen #include <ByteOrder.h> 29*083a11a3SMarcus Overhagen #include <Drivers.h> 30*083a11a3SMarcus Overhagen 31*083a11a3SMarcus Overhagen 32*083a11a3SMarcus Overhagen #define TRACE_CX23882 33*083a11a3SMarcus Overhagen #ifdef TRACE_CX23882 34*083a11a3SMarcus Overhagen #define TRACE dprintf 35*083a11a3SMarcus Overhagen #else 36*083a11a3SMarcus Overhagen #define TRACE(a...) 37*083a11a3SMarcus Overhagen #endif 38*083a11a3SMarcus Overhagen 39*083a11a3SMarcus Overhagen // settings for hardware stream sync 40*083a11a3SMarcus Overhagen #define MPEG2_SYNC_BYTE 0x47 41*083a11a3SMarcus Overhagen #define MPEG2_PACKET_SIZE 188 42*083a11a3SMarcus Overhagen #define SYNC_PACKET_COUNT 7 // 0 and 5 don't seem to work 43*083a11a3SMarcus Overhagen 44*083a11a3SMarcus Overhagen // Line size is also used as FIFO size! 45*083a11a3SMarcus Overhagen // BYTES_PER_LINE must be a multiple of 8 and <= 4096 bytes 46*083a11a3SMarcus Overhagen #define PACKETS_PER_LINE 20 47*083a11a3SMarcus Overhagen #define BYTES_PER_LINE (PACKETS_PER_LINE * MPEG2_PACKET_SIZE) 48*083a11a3SMarcus Overhagen 49*083a11a3SMarcus Overhagen #define SRAM_START_ADDRESS 0x180000 50*083a11a3SMarcus Overhagen #define SRAM_BASE_CMDS_TS 0x200 51*083a11a3SMarcus Overhagen #define SRAM_BASE_RISC_PROG 0x400 52*083a11a3SMarcus Overhagen #define SRAM_BASE_RISC_QUEUE 0x800 53*083a11a3SMarcus Overhagen #define SRAM_BASE_CDT 0x900 54*083a11a3SMarcus Overhagen #define SRAM_BASE_FIFO_0 0x1000 55*083a11a3SMarcus Overhagen #define SRAM_BASE_FIFO_1 0x2000 56*083a11a3SMarcus Overhagen 57*083a11a3SMarcus Overhagen // About 64 kByte DMA buffer size 58*083a11a3SMarcus Overhagen #define LINES_PER_BUFFER 16 59*083a11a3SMarcus Overhagen #define DMA_BUFFER_SIZE (LINES_PER_BUFFER * BYTES_PER_LINE) 60*083a11a3SMarcus Overhagen 61*083a11a3SMarcus Overhagen 62*083a11a3SMarcus Overhagen static status_t cx23882_buffers_alloc(cx23882_device *device); 63*083a11a3SMarcus Overhagen static void cx23882_buffers_free(cx23882_device *device); 64*083a11a3SMarcus Overhagen static void cx23882_risc_ram_setup(cx23882_device *device); 65*083a11a3SMarcus Overhagen static void cx23882_sram_setup(cx23882_device *device); 66*083a11a3SMarcus Overhagen static void cx23882_via_sis_fixup(cx23882_device *device); 67*083a11a3SMarcus Overhagen 68*083a11a3SMarcus Overhagen 69*083a11a3SMarcus Overhagen void 70*083a11a3SMarcus Overhagen cx23882_reset(cx23882_device *device) 71*083a11a3SMarcus Overhagen { 72*083a11a3SMarcus Overhagen // software reset (XXX Test) 73*083a11a3SMarcus Overhagen reg_write32(0x38c06c, 1); 74*083a11a3SMarcus Overhagen snooze(200000); 75*083a11a3SMarcus Overhagen 76*083a11a3SMarcus Overhagen // disable RISC controller 77*083a11a3SMarcus Overhagen reg_write32(REG_DEV_CNTRL2, 0); 78*083a11a3SMarcus Overhagen 79*083a11a3SMarcus Overhagen // disable TS interface DMA 80*083a11a3SMarcus Overhagen reg_write32(REG_TS_DMA_CNTRL, 0x0); 81*083a11a3SMarcus Overhagen 82*083a11a3SMarcus Overhagen // disable VIP interface up- & downstram DMA 83*083a11a3SMarcus Overhagen reg_write32(REG_VIP_STREAM_EN, 0x0); 84*083a11a3SMarcus Overhagen 85*083a11a3SMarcus Overhagen // disable host interface up- & downstram DMA 86*083a11a3SMarcus Overhagen reg_write32(REG_HST_STREAM_EN, 0x0); 87*083a11a3SMarcus Overhagen 88*083a11a3SMarcus Overhagen // stop all interrupts 89*083a11a3SMarcus Overhagen reg_write32(REG_PCI_INT_MSK, 0x0); 90*083a11a3SMarcus Overhagen reg_write32(REG_VID_INT_MSK, 0x0); 91*083a11a3SMarcus Overhagen reg_write32(REG_AUD_INT_MSK, 0x0); 92*083a11a3SMarcus Overhagen reg_write32(REG_TS_INT_MSK, 0x0); 93*083a11a3SMarcus Overhagen reg_write32(REG_VIP_INT_MSK, 0x0); 94*083a11a3SMarcus Overhagen reg_write32(REG_HST_INT_MSK, 0x0); 95*083a11a3SMarcus Overhagen reg_write32(REG_DMA_RISC_INT_MSK, 0x0); 96*083a11a3SMarcus Overhagen 97*083a11a3SMarcus Overhagen // clear all pending interrupts 98*083a11a3SMarcus Overhagen reg_write32(REG_PCI_INT_STAT, 0xffffffff); 99*083a11a3SMarcus Overhagen reg_write32(REG_VID_INT_STAT, 0xffffffff); 100*083a11a3SMarcus Overhagen reg_write32(REG_AUD_INT_STAT, 0xffffffff); 101*083a11a3SMarcus Overhagen reg_write32(REG_TS_INT_STAT, 0xffffffff); 102*083a11a3SMarcus Overhagen reg_write32(REG_VIP_INT_STAT, 0xffffffff); 103*083a11a3SMarcus Overhagen reg_write32(REG_HST_INT_STAT, 0xffffffff); 104*083a11a3SMarcus Overhagen reg_write32(REG_DMA_RISC_INT_MSK, 0xffffffff); 105*083a11a3SMarcus Overhagen } 106*083a11a3SMarcus Overhagen 107*083a11a3SMarcus Overhagen 108*083a11a3SMarcus Overhagen status_t 109*083a11a3SMarcus Overhagen cx23882_init(cx23882_device *device) 110*083a11a3SMarcus Overhagen { 111*083a11a3SMarcus Overhagen // assumes that cx23882_reset() has already been called 112*083a11a3SMarcus Overhagen 113*083a11a3SMarcus Overhagen status_t err; 114*083a11a3SMarcus Overhagen 115*083a11a3SMarcus Overhagen if ((err = cx23882_buffers_alloc(device)) < B_OK) { 116*083a11a3SMarcus Overhagen dprintf("cx23882: Error, buffer alloc failed\n"); 117*083a11a3SMarcus Overhagen return err; 118*083a11a3SMarcus Overhagen } 119*083a11a3SMarcus Overhagen 120*083a11a3SMarcus Overhagen device->capture_size = DMA_BUFFER_SIZE; 121*083a11a3SMarcus Overhagen 122*083a11a3SMarcus Overhagen cx23882_via_sis_fixup(device); 123*083a11a3SMarcus Overhagen 124*083a11a3SMarcus Overhagen // Set FIFO thresholds, should be 0 < x <= 7 125*083a11a3SMarcus Overhagen reg_write32(REG_PDMA_STHRSH, PDMA_ISBTHRSH_6 | PDMA_PCITHRSH_6); 126*083a11a3SMarcus Overhagen reg_write32(REG_PDMA_DTHRSH, PDMA_ISBTHRSH_6 | PDMA_PCITHRSH_6); 127*083a11a3SMarcus Overhagen 128*083a11a3SMarcus Overhagen // init risc programm 129*083a11a3SMarcus Overhagen cx23882_risc_ram_setup(device); 130*083a11a3SMarcus Overhagen 131*083a11a3SMarcus Overhagen // init sram 132*083a11a3SMarcus Overhagen cx23882_sram_setup(device); 133*083a11a3SMarcus Overhagen 134*083a11a3SMarcus Overhagen // Reset counter to 0 135*083a11a3SMarcus Overhagen reg_write32(REG_TS_GP_CNT_CNTRL, 0x3); 136*083a11a3SMarcus Overhagen 137*083a11a3SMarcus Overhagen // Line length for RISC DMA 138*083a11a3SMarcus Overhagen reg_write32(REG_TS_LNGTH, BYTES_PER_LINE); 139*083a11a3SMarcus Overhagen 140*083a11a3SMarcus Overhagen // Set serial interface mode 141*083a11a3SMarcus Overhagen reg_write32(REG_TS_GEN_CONTROL, reg_read32(REG_TS_GEN_CONTROL) | TS_GEN_CONTROL_IPB_SMODE); 142*083a11a3SMarcus Overhagen 143*083a11a3SMarcus Overhagen // Setup hardware MPEG2 fec interface 144*083a11a3SMarcus Overhagen reg_write32(REG_HW_SOP_CONTROL, (MPEG2_SYNC_BYTE << 16) | (MPEG2_PACKET_SIZE << 4) | SYNC_PACKET_COUNT); 145*083a11a3SMarcus Overhagen 146*083a11a3SMarcus Overhagen // Setup TSSTOP status, active low, rising and falling edge, single bit width 147*083a11a3SMarcus Overhagen reg_write32(REG_TS_SOP_STATUS, reg_read32(REG_TS_SOP_STATUS) | 0x18000); 148*083a11a3SMarcus Overhagen reg_write32(REG_TS_SOP_STATUS, reg_read32(REG_TS_SOP_STATUS) & ~0x06000); 149*083a11a3SMarcus Overhagen 150*083a11a3SMarcus Overhagen // Enable interrupts for MPEG TS and all errors 151*083a11a3SMarcus Overhagen reg_write32(REG_PCI_INT_MSK, reg_read32(REG_PCI_INT_MSK) | PCI_INT_STAT_TS_INT | 0x00fc00); 152*083a11a3SMarcus Overhagen reg_write32(REG_TS_INT_MSK, reg_read32(REG_TS_INT_MSK) | TS_INT_STAT_TS_RISC1 | TS_INT_STAT_TS_RISC2 | 0x1f1100); 153*083a11a3SMarcus Overhagen 154*083a11a3SMarcus Overhagen TRACE("cx23882_init done\n"); 155*083a11a3SMarcus Overhagen return B_OK; 156*083a11a3SMarcus Overhagen } 157*083a11a3SMarcus Overhagen 158*083a11a3SMarcus Overhagen 159*083a11a3SMarcus Overhagen status_t 160*083a11a3SMarcus Overhagen cx23882_terminate(cx23882_device *device) 161*083a11a3SMarcus Overhagen { 162*083a11a3SMarcus Overhagen cx23882_reset(device); 163*083a11a3SMarcus Overhagen 164*083a11a3SMarcus Overhagen cx23882_buffers_free(device); 165*083a11a3SMarcus Overhagen return B_OK; 166*083a11a3SMarcus Overhagen } 167*083a11a3SMarcus Overhagen 168*083a11a3SMarcus Overhagen 169*083a11a3SMarcus Overhagen status_t 170*083a11a3SMarcus Overhagen cx23882_start_capture(cx23882_device *device) 171*083a11a3SMarcus Overhagen { 172*083a11a3SMarcus Overhagen TRACE("cx23882_start_capture\n"); 173*083a11a3SMarcus Overhagen 174*083a11a3SMarcus Overhagen // start RISC processor and DMA 175*083a11a3SMarcus Overhagen reg_write32(REG_DEV_CNTRL2, reg_read32(REG_DEV_CNTRL2) | DEV_CNTRL2_RUN_RISC); 176*083a11a3SMarcus 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); 177*083a11a3SMarcus Overhagen return B_OK; 178*083a11a3SMarcus Overhagen } 179*083a11a3SMarcus Overhagen 180*083a11a3SMarcus Overhagen 181*083a11a3SMarcus Overhagen status_t 182*083a11a3SMarcus Overhagen cx23882_stop_capture(cx23882_device *device) 183*083a11a3SMarcus Overhagen { 184*083a11a3SMarcus Overhagen TRACE("cx23882_stop_capture\n"); 185*083a11a3SMarcus Overhagen 186*083a11a3SMarcus Overhagen // stop RISC processor and DMA 187*083a11a3SMarcus 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)); 188*083a11a3SMarcus Overhagen reg_write32(REG_DEV_CNTRL2, reg_read32(REG_DEV_CNTRL2) & ~DEV_CNTRL2_RUN_RISC); 189*083a11a3SMarcus Overhagen return B_OK; 190*083a11a3SMarcus Overhagen } 191*083a11a3SMarcus Overhagen 192*083a11a3SMarcus Overhagen 193*083a11a3SMarcus Overhagen static inline void 194*083a11a3SMarcus Overhagen cx23882_mpegts_int(cx23882_device *device) 195*083a11a3SMarcus Overhagen { 196*083a11a3SMarcus Overhagen uint32 mstat = reg_read32(REG_TS_INT_MSTAT); 197*083a11a3SMarcus Overhagen reg_write32(REG_TS_INT_STAT, mstat); 198*083a11a3SMarcus Overhagen 199*083a11a3SMarcus Overhagen // dprintf("cx23882_mpegts_int got 0x%08lx\n", mstat); 200*083a11a3SMarcus Overhagen 201*083a11a3SMarcus Overhagen if (mstat & TS_INT_STAT_OPC_ERR) { 202*083a11a3SMarcus Overhagen dprintf("cx23882_mpegts_int RISC opcode error\n"); 203*083a11a3SMarcus Overhagen reg_write32(REG_PCI_INT_MSK, 0); 204*083a11a3SMarcus Overhagen return; 205*083a11a3SMarcus Overhagen } 206*083a11a3SMarcus Overhagen 207*083a11a3SMarcus Overhagen if ((mstat & (TS_INT_STAT_TS_RISC1 | TS_INT_STAT_TS_RISC2)) == (TS_INT_STAT_TS_RISC1 | TS_INT_STAT_TS_RISC2)) { 208*083a11a3SMarcus Overhagen dprintf("cx23882_mpegts_int both buffers ready\n"); 209*083a11a3SMarcus Overhagen mstat = TS_INT_STAT_TS_RISC1; 210*083a11a3SMarcus Overhagen } 211*083a11a3SMarcus Overhagen 212*083a11a3SMarcus Overhagen if (mstat & TS_INT_STAT_TS_RISC1) { 213*083a11a3SMarcus Overhagen int32 count; 214*083a11a3SMarcus Overhagen // dprintf("cx23882_mpegts_int buffer 1 at %Ld\n", system_time()); 215*083a11a3SMarcus Overhagen device->capture_data = device->dma_buf1_virt; 216*083a11a3SMarcus Overhagen device->capture_end_time = system_time(); 217*083a11a3SMarcus Overhagen get_sem_count(device->capture_sem, &count); 218*083a11a3SMarcus Overhagen if (count <= 0) 219*083a11a3SMarcus Overhagen release_sem_etc(device->capture_sem, 1, B_DO_NOT_RESCHEDULE); 220*083a11a3SMarcus Overhagen } 221*083a11a3SMarcus Overhagen 222*083a11a3SMarcus Overhagen if (mstat & TS_INT_STAT_TS_RISC2) { 223*083a11a3SMarcus Overhagen int32 count; 224*083a11a3SMarcus Overhagen // dprintf("cx23882_mpegts_int buffer 2 at %Ld\n", system_time()); 225*083a11a3SMarcus Overhagen device->capture_data = device->dma_buf2_virt; 226*083a11a3SMarcus Overhagen device->capture_end_time = system_time(); 227*083a11a3SMarcus Overhagen get_sem_count(device->capture_sem, &count); 228*083a11a3SMarcus Overhagen if (count <= 0) 229*083a11a3SMarcus Overhagen release_sem_etc(device->capture_sem, 1, B_DO_NOT_RESCHEDULE); 230*083a11a3SMarcus Overhagen } 231*083a11a3SMarcus Overhagen } 232*083a11a3SMarcus Overhagen 233*083a11a3SMarcus Overhagen 234*083a11a3SMarcus Overhagen int32 235*083a11a3SMarcus Overhagen cx23882_int(void *data) 236*083a11a3SMarcus Overhagen { 237*083a11a3SMarcus Overhagen cx23882_device *device = data; 238*083a11a3SMarcus Overhagen uint32 mstat; 239*083a11a3SMarcus Overhagen uint32 wmstat; 240*083a11a3SMarcus Overhagen 241*083a11a3SMarcus Overhagen mstat = reg_read32(REG_PCI_INT_MSTAT); 242*083a11a3SMarcus Overhagen if (!mstat) 243*083a11a3SMarcus Overhagen return B_UNHANDLED_INTERRUPT; 244*083a11a3SMarcus Overhagen 245*083a11a3SMarcus Overhagen if (mstat & (PCI_INT_STAT_HST_INT | PCI_INT_STAT_VIP_INT | PCI_INT_STAT_AUD_INT | PCI_INT_STAT_VID_INT)) { 246*083a11a3SMarcus Overhagen // serious error, these bits should not be set 247*083a11a3SMarcus Overhagen dprintf("cx23882_int error: msk 0x%08lx, stat 0x%08lx, mstat 0x%08lx\n", reg_read32(REG_PCI_INT_MSK), reg_read32(REG_PCI_INT_STAT), mstat); 248*083a11a3SMarcus Overhagen reg_write32(REG_PCI_INT_MSK, 0); 249*083a11a3SMarcus Overhagen return B_HANDLED_INTERRUPT; 250*083a11a3SMarcus Overhagen } 251*083a11a3SMarcus Overhagen 252*083a11a3SMarcus 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); 253*083a11a3SMarcus Overhagen if (wmstat) 254*083a11a3SMarcus Overhagen reg_write32(REG_PCI_INT_STAT, wmstat); 255*083a11a3SMarcus Overhagen 256*083a11a3SMarcus Overhagen if (wmstat) 257*083a11a3SMarcus Overhagen dprintf("cx23882_int got 0x%08lx\n", wmstat); 258*083a11a3SMarcus Overhagen 259*083a11a3SMarcus Overhagen if (mstat & PCI_INT_STAT_TS_INT) { 260*083a11a3SMarcus Overhagen cx23882_mpegts_int(device); 261*083a11a3SMarcus Overhagen return B_INVOKE_SCHEDULER; 262*083a11a3SMarcus Overhagen } else { 263*083a11a3SMarcus Overhagen return B_HANDLED_INTERRUPT; 264*083a11a3SMarcus Overhagen } 265*083a11a3SMarcus Overhagen } 266*083a11a3SMarcus Overhagen 267*083a11a3SMarcus Overhagen 268*083a11a3SMarcus Overhagen static status_t 269*083a11a3SMarcus Overhagen cx23882_buffers_alloc(cx23882_device *device) 270*083a11a3SMarcus Overhagen { 271*083a11a3SMarcus 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"); 272*083a11a3SMarcus 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"); 273*083a11a3SMarcus Overhagen if (device->dma_buf1_area < B_OK || device->dma_buf2_area < B_OK) { 274*083a11a3SMarcus Overhagen cx23882_buffers_free(device); 275*083a11a3SMarcus Overhagen return B_NO_MEMORY; 276*083a11a3SMarcus Overhagen } 277*083a11a3SMarcus Overhagen return B_OK; 278*083a11a3SMarcus Overhagen } 279*083a11a3SMarcus Overhagen 280*083a11a3SMarcus Overhagen 281*083a11a3SMarcus Overhagen static void 282*083a11a3SMarcus Overhagen cx23882_buffers_free(cx23882_device *device) 283*083a11a3SMarcus Overhagen { 284*083a11a3SMarcus Overhagen if (device->dma_buf1_area >= 0) 285*083a11a3SMarcus Overhagen delete_area(device->dma_buf1_area); 286*083a11a3SMarcus Overhagen if (device->dma_buf2_area >= 0) 287*083a11a3SMarcus Overhagen delete_area(device->dma_buf2_area); 288*083a11a3SMarcus Overhagen device->dma_buf1_area = -1; 289*083a11a3SMarcus Overhagen device->dma_buf2_area = -1; 290*083a11a3SMarcus Overhagen } 291*083a11a3SMarcus Overhagen 292*083a11a3SMarcus Overhagen 293*083a11a3SMarcus Overhagen static void 294*083a11a3SMarcus Overhagen cx23882_sram_setup(cx23882_device *device) 295*083a11a3SMarcus Overhagen { 296*083a11a3SMarcus Overhagen dprintf("cx23882_sram_setup enter\n"); 297*083a11a3SMarcus Overhagen 298*083a11a3SMarcus Overhagen // setup CDT entries for both FIFOs 299*083a11a3SMarcus Overhagen reg_write32(SRAM_START_ADDRESS + SRAM_BASE_CDT, SRAM_START_ADDRESS + SRAM_BASE_FIFO_0); 300*083a11a3SMarcus Overhagen reg_write32(SRAM_START_ADDRESS + SRAM_BASE_CDT + 16, SRAM_START_ADDRESS + SRAM_BASE_FIFO_1); 301*083a11a3SMarcus Overhagen 302*083a11a3SMarcus Overhagen // setup CDMS 303*083a11a3SMarcus Overhagen reg_write32(SRAM_START_ADDRESS + SRAM_BASE_CMDS_TS + 0x00, SRAM_START_ADDRESS + SRAM_BASE_RISC_PROG); 304*083a11a3SMarcus Overhagen reg_write32(SRAM_START_ADDRESS + SRAM_BASE_CMDS_TS + 0x04, SRAM_START_ADDRESS + SRAM_BASE_CDT); 305*083a11a3SMarcus Overhagen reg_write32(SRAM_START_ADDRESS + SRAM_BASE_CMDS_TS + 0x08, (2 * 16) / 8); // FIFO count = 2 306*083a11a3SMarcus Overhagen reg_write32(SRAM_START_ADDRESS + SRAM_BASE_CMDS_TS + 0x0c, SRAM_START_ADDRESS + SRAM_BASE_RISC_QUEUE); 307*083a11a3SMarcus Overhagen reg_write32(SRAM_START_ADDRESS + SRAM_BASE_CMDS_TS + 0x10, 0x80000000 | (0x100 / 4)); 308*083a11a3SMarcus Overhagen 309*083a11a3SMarcus Overhagen // setup DMA registers 310*083a11a3SMarcus Overhagen reg_write32(REG_DMA28_PTR1, SRAM_START_ADDRESS + SRAM_BASE_FIFO_0); 311*083a11a3SMarcus Overhagen reg_write32(REG_DMA28_PTR2, SRAM_START_ADDRESS + SRAM_BASE_CDT); 312*083a11a3SMarcus Overhagen reg_write32(REG_DMA28_CNT1, BYTES_PER_LINE / 8); 313*083a11a3SMarcus Overhagen reg_write32(REG_DMA28_CNT2, (2 * 16) / 8); // FIFO count = 2 314*083a11a3SMarcus Overhagen 315*083a11a3SMarcus Overhagen dprintf("cx23882_sram_setup leave\n"); 316*083a11a3SMarcus Overhagen } 317*083a11a3SMarcus Overhagen 318*083a11a3SMarcus Overhagen 319*083a11a3SMarcus Overhagen static void 320*083a11a3SMarcus Overhagen cx23882_risc_ram_setup(cx23882_device *device) 321*083a11a3SMarcus Overhagen { 322*083a11a3SMarcus Overhagen char *start = (char *)(device->regs) + SRAM_START_ADDRESS + SRAM_BASE_RISC_PROG; 323*083a11a3SMarcus Overhagen volatile uint32 *rp = (volatile uint32 *)start; 324*083a11a3SMarcus Overhagen int i; 325*083a11a3SMarcus Overhagen 326*083a11a3SMarcus Overhagen #define set_opcode(a) (*rp++) = B_HOST_TO_LENDIAN_INT32((a)) 327*083a11a3SMarcus Overhagen 328*083a11a3SMarcus Overhagen dprintf("cx23882_risc_ram_setup enter\n"); 329*083a11a3SMarcus Overhagen 330*083a11a3SMarcus Overhagen // sync 331*083a11a3SMarcus Overhagen set_opcode(RISC_RESYNC | 0); 332*083a11a3SMarcus Overhagen 333*083a11a3SMarcus Overhagen // copy buffer 1 334*083a11a3SMarcus Overhagen for (i = 0; i < LINES_PER_BUFFER; i++) { 335*083a11a3SMarcus Overhagen set_opcode(RISC_WRITE | RISC_SOL | RISC_EOL | BYTES_PER_LINE); 336*083a11a3SMarcus Overhagen set_opcode((unsigned long)device->dma_buf1_phys + i * BYTES_PER_LINE); 337*083a11a3SMarcus Overhagen } 338*083a11a3SMarcus Overhagen 339*083a11a3SMarcus Overhagen // execute IRQ 1 340*083a11a3SMarcus Overhagen set_opcode(RISC_SKIP | RISC_IRQ1 | RISC_SOL | 0); 341*083a11a3SMarcus Overhagen 342*083a11a3SMarcus Overhagen // copy buffer 2 343*083a11a3SMarcus Overhagen for (i = 0; i < LINES_PER_BUFFER; i++) { 344*083a11a3SMarcus Overhagen set_opcode(RISC_WRITE | RISC_SOL | RISC_EOL | BYTES_PER_LINE); 345*083a11a3SMarcus Overhagen set_opcode((unsigned long)device->dma_buf2_phys + i * BYTES_PER_LINE); 346*083a11a3SMarcus Overhagen } 347*083a11a3SMarcus Overhagen 348*083a11a3SMarcus Overhagen // execute IRQ 2 349*083a11a3SMarcus Overhagen set_opcode(RISC_SKIP | RISC_IRQ2 | RISC_SOL | 0); 350*083a11a3SMarcus Overhagen 351*083a11a3SMarcus Overhagen // jmp to start, but skip sync instruction 352*083a11a3SMarcus Overhagen set_opcode(RISC_JUMP | RISC_SRP); 353*083a11a3SMarcus Overhagen set_opcode(SRAM_START_ADDRESS + SRAM_BASE_RISC_PROG + 4); 354*083a11a3SMarcus Overhagen 355*083a11a3SMarcus Overhagen #undef set_opcode 356*083a11a3SMarcus Overhagen 357*083a11a3SMarcus Overhagen dprintf("cx23882_risc_ram_setup leave\n"); 358*083a11a3SMarcus Overhagen } 359*083a11a3SMarcus Overhagen 360*083a11a3SMarcus Overhagen 361*083a11a3SMarcus Overhagen static void 362*083a11a3SMarcus Overhagen cx23882_via_sis_fixup(cx23882_device *device) 363*083a11a3SMarcus Overhagen { 364*083a11a3SMarcus Overhagen uint16 host_vendor; 365*083a11a3SMarcus Overhagen uint32 dev_cntrl1; 366*083a11a3SMarcus Overhagen 367*083a11a3SMarcus Overhagen host_vendor = gPci->read_pci_config(0, 0, 0, PCI_vendor_id, 2); 368*083a11a3SMarcus Overhagen dev_cntrl1 = reg_read32(REG_F2_DEV_CNTRL1); 369*083a11a3SMarcus Overhagen 370*083a11a3SMarcus Overhagen if (host_vendor == PCI_VENDOR_VIA || host_vendor == PCI_VENDOR_SIS) { 371*083a11a3SMarcus Overhagen dprintf("cx23882: enabling VIA/SIS compatibility mode\n"); 372*083a11a3SMarcus Overhagen reg_write32(REG_F2_DEV_CNTRL1, dev_cntrl1 | F2_DEV_CNTRL1_EN_VSFX); 373*083a11a3SMarcus Overhagen } else { 374*083a11a3SMarcus Overhagen dprintf("cx23882: disabling VIA/SIS compatibility mode\n"); 375*083a11a3SMarcus Overhagen reg_write32(REG_F2_DEV_CNTRL1, dev_cntrl1 & ~F2_DEV_CNTRL1_EN_VSFX); 376*083a11a3SMarcus Overhagen } 377*083a11a3SMarcus Overhagen } 378