예제 #1
0
static int saa7231_ts2dtl_run_prepare(struct saa7231_stream *stream)
{
    unsigned long run = 0;
    u32 delay;

    u32 reg;
    struct saa7231_dev *saa7231	= stream->saa7231;
    struct saa7231_dtl *dtl		= &stream->dtl;
    struct saa7231_ring *ring	= stream->ring;
    struct saa7231_dmabuf *dmabuf	= ring->dmabuf;

    u32 module			= dtl->module;
    int port			= stream->port_id;
    int ch				= DMACH(port);

    SAA7231_WR(DMAADDR(0, port, dmabuf, 0), SAA7231_BAR0, module, S2D_CHx_B0_B_START_ADDRESS(0));
    SAA7231_WR(DMAADDR(0, port, dmabuf, 1), SAA7231_BAR0, module, S2D_CHx_B1_B_START_ADDRESS(0));

    reg = SAA7231_RD(SAA7231_BAR0, MMU, MMU_DMA_CONFIG(ch));
    reg &= ~0x40;
    SAA7231_WR(reg, SAA7231_BAR0, MMU, MMU_DMA_CONFIG(ch));
    SAA7231_WR((reg | 0x40), SAA7231_BAR0, MMU, MMU_DMA_CONFIG(ch));

    dtl->addr_prev = 0xffffff;

    delay = 1000;
    do {
        if (!run) {
            msleep(10);
            delay--;
        }
        run = SAA7231_RD(SAA7231_BAR0, MMU, MMU_DMA_CONFIG(ch)) & 0x80;
    } while (!run && delay);

    if (!run) {
        dprintk(SAA7231_ERROR, 1, "ERROR, Preload PTA failed");
        return -EINVAL;
    }
#if 0
    reg = SAA7231_RD(SAA7231_BAR0, module, S2D_CHx_CTRL(0));
    SAA7231_WR(reg | 0x1, SAA7231_BAR0, module, S2D_CHx_CTRL(0));
#endif
    return 0;
}
예제 #2
0
static int saa7231_init_ptables(struct saa7231_stream *stream)
{
    struct saa7231_ring *ring	= stream->ring;
    struct saa7231_dmabuf *dmabuf	= ring->dmabuf;
    struct saa7231_dev *saa7231	= dmabuf->saa7231;

    int port = stream->port_id;
    int ch = DMACH(port);

    BUG_ON(!ring);
    BUG_ON(!dmabuf);
    BUG_ON(!saa7231);

    dprintk(SAA7231_DEBUG, 1, "DEBUG: Initializing PORT:%d DMA_CH:%d with %d Buffers",
            port,
            ch,
            TS2D_BUFFERS);

    SAA7231_WR((TS2D_BUFFERS - 1), SAA7231_BAR0, MMU, MMU_DMA_CONFIG(ch));

    SAA7231_WR(PTA_LSB(dmabuf[0].pt_phys), SAA7231_BAR0, MMU, MMU_PTA0_LSB(ch));
    SAA7231_WR(PTA_MSB(dmabuf[0].pt_phys), SAA7231_BAR0, MMU, MMU_PTA0_MSB(ch));
    SAA7231_WR(PTA_LSB(dmabuf[1].pt_phys), SAA7231_BAR0, MMU, MMU_PTA1_LSB(ch));
    SAA7231_WR(PTA_MSB(dmabuf[1].pt_phys), SAA7231_BAR0, MMU, MMU_PTA1_MSB(ch));
    SAA7231_WR(PTA_LSB(dmabuf[2].pt_phys), SAA7231_BAR0, MMU, MMU_PTA2_LSB(ch));
    SAA7231_WR(PTA_MSB(dmabuf[2].pt_phys), SAA7231_BAR0, MMU, MMU_PTA2_MSB(ch));
    SAA7231_WR(PTA_LSB(dmabuf[3].pt_phys), SAA7231_BAR0, MMU, MMU_PTA3_LSB(ch));
    SAA7231_WR(PTA_MSB(dmabuf[3].pt_phys), SAA7231_BAR0, MMU, MMU_PTA3_MSB(ch));
    SAA7231_WR(PTA_LSB(dmabuf[4].pt_phys), SAA7231_BAR0, MMU, MMU_PTA4_LSB(ch));
    SAA7231_WR(PTA_MSB(dmabuf[4].pt_phys), SAA7231_BAR0, MMU, MMU_PTA4_MSB(ch));
    SAA7231_WR(PTA_LSB(dmabuf[5].pt_phys), SAA7231_BAR0, MMU, MMU_PTA5_LSB(ch));
    SAA7231_WR(PTA_MSB(dmabuf[5].pt_phys), SAA7231_BAR0, MMU, MMU_PTA5_MSB(ch));
    SAA7231_WR(PTA_LSB(dmabuf[6].pt_phys), SAA7231_BAR0, MMU, MMU_PTA6_LSB(ch));
    SAA7231_WR(PTA_MSB(dmabuf[6].pt_phys), SAA7231_BAR0, MMU, MMU_PTA6_MSB(ch));
    SAA7231_WR(PTA_LSB(dmabuf[7].pt_phys), SAA7231_BAR0, MMU, MMU_PTA7_LSB(ch));
    SAA7231_WR(PTA_MSB(dmabuf[7].pt_phys), SAA7231_BAR0, MMU, MMU_PTA7_MSB(ch));

    stream->index_w += 8;
    return 0;
}
예제 #3
0
void UnwrappedHardwareScheduler::initDma() {
    //enable DMA channel (it's probably already enabled, but we want to be sure):
    writeBitmasked(dmaBaseMem + DMAENABLE/4, 1 << dmaCh, 1 << dmaCh);
    
    //configure the DMA header to point to our control block:
    dmaHeader = (struct DmaChannelHeader*)(dmaBaseMem + DMACH(dmaCh)/4); //must divide by 4, as dmaBaseMem is uint32_t*
    //abort any previous DMA:
    //dmaHeader->NEXTCONBK = 0; //NEXTCONBK is read-only.
    dmaHeader->CS |= DMA_CS_ABORT; //make sure to disable dma first.
    mitpi::usleep(100); //give time for the abort command to be handled.
    
    dmaHeader->CS = DMA_CS_RESET;
    mitpi::usleep(100);
    
    writeBitmasked(&dmaHeader->CS, DMA_CS_END, DMA_CS_END); //clear the end flag
    dmaHeader->DEBUG = DMA_DEBUG_READ_ERROR | DMA_DEBUG_FIFO_ERROR | DMA_DEBUG_READ_LAST_NOT_SET_ERROR; // clear debug error flags
    uint32_t firstAddr = physToUncached(cbMem.physAddrAtByteOffset(0));
    LOG("platforms::rpi::UnwrappedHardwareScheduler::initDma: starting DMA @ CONBLK_AD=0x%08x\n", firstAddr);
    dmaHeader->CONBLK_AD = firstAddr; //(uint32_t)physCbPage + ((void*)cbArr - virtCbPage); //we have to point it to the PHYSICAL address of the control block (cb1)
    dmaHeader->CS = DMA_CS_PRIORITY(14) | DMA_CS_PANIC_PRIORITY(14) | DMA_CS_DISDEBUG; //high priority (max is 15)
    dmaHeader->CS = DMA_CS_PRIORITY(14) | DMA_CS_PANIC_PRIORITY(14) | DMA_CS_DISDEBUG | DMA_CS_ACTIVE; //activate DMA. 
}
예제 #4
0
static int saa7231_ts2dtl_set_buffer(struct saa7231_stream *stream,
                                     u32 index,
                                     struct saa7231_dmabuf *dmabuf)
{
    struct saa7231_dev *saa7231	= stream->saa7231;
    struct saa7231_dtl *dtl		= &stream->dtl;
    u32 module			= dtl->module;

    int port			= stream->port_id;
    int ch				= DMACH(port);
    int ret;

    switch (index) {
    case 0:
        SAA7231_WR(PTA_LSB(dmabuf->pt_phys), SAA7231_BAR0, MMU, MMU_PTA(LSB, index, ch));
        SAA7231_WR(PTA_MSB(dmabuf->pt_phys), SAA7231_BAR0, MMU, MMU_PTA(MSB, index, ch));
        SAA7231_WR(DMAADDR(0, port, dmabuf, 0), SAA7231_BAR0, module, S2D_CHx_B0_B_START_ADDRESS(0));
        break;
    case 1:
        SAA7231_WR(PTA_LSB(dmabuf->pt_phys), SAA7231_BAR0, MMU, MMU_PTA(LSB, index, ch));
        SAA7231_WR(PTA_MSB(dmabuf->pt_phys), SAA7231_BAR0, MMU, MMU_PTA(MSB, index, ch));
        SAA7231_WR(DMAADDR(0, port, dmabuf, 1), SAA7231_BAR0, module, S2D_CHx_B1_B_START_ADDRESS(0));
        break;
    case 2:
        SAA7231_WR(PTA_LSB(dmabuf->pt_phys), SAA7231_BAR0, MMU, MMU_PTA(LSB, index, ch));
        SAA7231_WR(PTA_MSB(dmabuf->pt_phys), SAA7231_BAR0, MMU, MMU_PTA(MSB, index, ch));
        SAA7231_WR(DMAADDR(0, port, dmabuf, 2), SAA7231_BAR0, module, S2D_CHx_B2_B_START_ADDRESS(0));
        break;
    case 3:
        SAA7231_WR(PTA_LSB(dmabuf->pt_phys), SAA7231_BAR0, MMU, MMU_PTA(LSB, index, ch));
        SAA7231_WR(PTA_MSB(dmabuf->pt_phys), SAA7231_BAR0, MMU, MMU_PTA(MSB, index, ch));
        SAA7231_WR(DMAADDR(0, port, dmabuf, 3), SAA7231_BAR0, module, S2D_CHx_B3_B_START_ADDRESS(0));
        break;
    case 4:
        SAA7231_WR(PTA_LSB(dmabuf->pt_phys), SAA7231_BAR0, MMU, MMU_PTA(LSB, index, ch));
        SAA7231_WR(PTA_MSB(dmabuf->pt_phys), SAA7231_BAR0, MMU, MMU_PTA(MSB, index, ch));
        SAA7231_WR(DMAADDR(0, port, dmabuf, 4), SAA7231_BAR0, module, S2D_CHx_B4_B_START_ADDRESS(0));
        break;
    case 5:
        SAA7231_WR(PTA_LSB(dmabuf->pt_phys), SAA7231_BAR0, MMU, MMU_PTA(LSB, index, ch));
        SAA7231_WR(PTA_MSB(dmabuf->pt_phys), SAA7231_BAR0, MMU, MMU_PTA(MSB, index, ch));
        SAA7231_WR(DMAADDR(0, port, dmabuf, 5), SAA7231_BAR0, module, S2D_CHx_B5_B_START_ADDRESS(0));
        break;
    case 6:
        SAA7231_WR(PTA_LSB(dmabuf->pt_phys), SAA7231_BAR0, MMU, MMU_PTA(LSB, index, ch));
        SAA7231_WR(PTA_MSB(dmabuf->pt_phys), SAA7231_BAR0, MMU, MMU_PTA(MSB, index, ch));
        SAA7231_WR(DMAADDR(0, port, dmabuf, 6), SAA7231_BAR0, module, S2D_CHx_B6_B_START_ADDRESS(0));
        break;
    case 7:
        SAA7231_WR(PTA_LSB(dmabuf->pt_phys), SAA7231_BAR0, MMU, MMU_PTA(LSB, index, ch));
        SAA7231_WR(PTA_MSB(dmabuf->pt_phys), SAA7231_BAR0, MMU, MMU_PTA(MSB, index, ch));
        SAA7231_WR(DMAADDR(0, port, dmabuf, 7), SAA7231_BAR0, module, S2D_CHx_B7_B_START_ADDRESS(0));
        break;
    default:
        dprintk(SAA7231_ERROR, 1, "Invalid Index:%d", index);
        ret = -EINVAL;
        goto exit;
    }
exit:
    return ret;
}