Changeset d2134da in mainline


Ignore:
Timestamp:
2011-10-03T19:18:53Z (12 years ago)
Author:
Jan Vesely <jano.vesely@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
aa5ae788
Parents:
dea75c04
Message:

sb16: Implement DMA channel setup.

Without mode selection for now.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/audio/sb16/dma_controller.c

    rdea75c04 rd2134da  
    3434#include <assert.h>
    3535#include <errno.h>
     36#include <ddi.h>
     37#include <libarch/ddi.h>
    3638
    3739#include "dma_controller.h"
    3840
    39 #define DMA_CONTROLLER_FIRST_BASE 0x0
     41#define DMA_CONTROLLER_FIRST_BASE ((void*)0x0)
    4042typedef struct dma_controller_regs_first {
    4143        uint8_t channel_start0;
     
    5658        uint8_t request; /* Memory to memory transfers, NOT implemented on PCs*/
    5759        uint8_t single_mask;
    58 #define DMA_SINGLE_MASK_CHAN_SELECT_MASK (0x3)
    59 #define DMA_SINGLE_MASK_CHAN_SELECT_SHIFT (0)
    60 #define DMA_SINGLE_MASK_MASK_ON_FLAG (1 << 2)
     60#define DMA_SINGLE_MASK_CHAN_SEL_MASK (0x3)
     61#define DMA_SINGLE_MASK_CHAN_SEL_SHIFT (0)
     62#define DMA_SINGLE_MASK_CHAN_TO_REG(x) \
     63    (((x % 4) & DMA_SINGLE_MASK_CHAN_SEL_MASK) << DMA_SINGLE_MASK_CHAN_SEL_SHIFT)
     64#define DMA_SINGLE_MASK_MASKED_FLAG (1 << 2)
    6165
    6266        uint8_t mode;
     
    8791} dma_controller_regs_first_t;
    8892
    89 #define DMA_CONTROLLER_SECOND_BASE 0xc0
     93#define DMA_CONTROLLER_SECOND_BASE ((void*)0xc0)
    9094/* See dma_controller_regs_first_t for register values */
    9195typedef struct dma_controller_regs_second {
     
    121125} dma_controller_regs_second_t;
    122126
    123 #define DMA_CONTROLLER_PAGE_BASE 0x81
     127#define DMA_CONTROLLER_PAGE_BASE ((void*)0x81)
    124128typedef struct dma_page_regs {
    125129        uint8_t channel2;
     
    141145
    142146typedef struct dma_channel {
    143         uint8_t offset_reg_address;
    144         uint8_t size_reg_address;
    145         uint8_t page_reg_address;
     147        uint8_t *offset_reg_address;
     148        uint8_t *size_reg_address;
     149        uint8_t *page_reg_address;
    146150} dma_channel_t;
    147151
     
    155159dma_controller_t controller_8237 = {
    156160        .channel = {
    157             { 0x00, 0x01, 0x87 }, { 0x02, 0x03, 0x83 },
    158             { 0x04, 0x05, 0x81 }, { 0x06, 0x07, 0x82 },
    159             { 0xc0, 0xc2, 0x8f }, { 0xc4, 0xc6, 0x8b },
    160             { 0xc8, 0xca, 0x89 }, { 0xcc, 0xce, 0x8a } },
     161            { (uint8_t*)0x00, (uint8_t*)0x01, (uint8_t*)0x87 },
     162            { (uint8_t*)0x02, (uint8_t*)0x03, (uint8_t*)0x83 },
     163            { (uint8_t*)0x04, (uint8_t*)0x05, (uint8_t*)0x81 },
     164            { (uint8_t*)0x06, (uint8_t*)0x07, (uint8_t*)0x82 },
     165            { (uint8_t*)0xc0, (uint8_t*)0xc2, (uint8_t*)0x8f },
     166            { (uint8_t*)0xc4, (uint8_t*)0xc6, (uint8_t*)0x8b },
     167            { (uint8_t*)0xc8, (uint8_t*)0xca, (uint8_t*)0x89 },
     168            { (uint8_t*)0xcc, (uint8_t*)0xce, (uint8_t*)0x8a } },
    161169        .page_table = NULL,
    162170        .first = NULL,
     
    166174static inline dma_controller_t *dma_controller_init()
    167175{
    168         return NULL;
     176        int ret = pio_enable(DMA_CONTROLLER_PAGE_BASE, sizeof(dma_page_regs_t),
     177            (void**)&controller_8237.page_table);
     178        if (ret != EOK)
     179                return NULL;
     180
     181        ret = pio_enable(DMA_CONTROLLER_FIRST_BASE,
     182            sizeof(dma_controller_regs_first_t),
     183            (void**)&controller_8237.first);
     184        if (ret != EOK)
     185                return NULL;
     186
     187        ret = pio_enable(DMA_CONTROLLER_SECOND_BASE,
     188            sizeof(dma_controller_regs_second_t),
     189            (void**)&controller_8237.second);
     190        if (ret != EOK)
     191                return NULL;
     192        return &controller_8237;
     193}
     194/*----------------------------------------------------------------------------*/
     195static int dma_setup_channel_8bit(dma_controller_t *controller,
     196    unsigned channel, uint32_t pa, uint16_t size)
     197{
     198        if (channel == 0 || channel > 3)
     199                return ENOTSUP;
     200        assert(controller);
     201        /* Mask DMA request */
     202        uint8_t value = DMA_SINGLE_MASK_CHAN_TO_REG(channel)
     203            | DMA_SINGLE_MASK_MASKED_FLAG;
     204        pio_write_8(&controller->first->single_mask, value);
     205
     206        /* Set address -- reset flip-flop*/
     207        pio_write_8(&controller->first->flip_flop, 1);
     208
     209        /* Low byte */
     210        value = pa & 0xff;
     211        pio_write_8(controller->channel[channel].offset_reg_address, value);
     212
     213        /* High byte */
     214        value = (pa >> 8) & 0xff;
     215        pio_write_8(controller->channel[channel].offset_reg_address, value);
     216
     217        /* Page address - third byte */
     218        value = (pa >> 16) & 0xff;
     219        pio_write_8(controller->channel[channel].offset_reg_address, value);
     220
     221        /* Set size -- reset flip-flop */
     222        pio_write_8(&controller->first->flip_flop, 1);
     223
     224        /* Low byte */
     225        value = size & 0xff;
     226        pio_write_8(controller->channel[channel].offset_reg_address, value);
     227
     228        /* High byte */
     229        value = (size >> 8) & 0xff;
     230        pio_write_8(controller->channel[channel].offset_reg_address, value);
     231
     232        /* Unmask DMA request */
     233        value = DMA_SINGLE_MASK_CHAN_TO_REG(channel);
     234        pio_write_8(&controller->first->single_mask, value);
     235
     236        return EOK;
     237}
     238/*----------------------------------------------------------------------------*/
     239static int dma_setup_channel_16bit(dma_controller_t *controller,
     240    unsigned channel, uintptr_t pa, size_t size)
     241{
     242        if (channel == 4 || channel > 7)
     243                return ENOTSUP;
     244        assert(controller);
     245        /* Mask DMA request */
     246        uint8_t value = DMA_SINGLE_MASK_CHAN_TO_REG(channel)
     247            | DMA_SINGLE_MASK_MASKED_FLAG;
     248        pio_write_8(&controller->second->single_mask, value);
     249
     250        /* Set address -- reset flip-flop*/
     251        pio_write_8(&controller->second->flip_flop, 1);
     252
     253        /* Low byte */
     254        value = pa & 0xff;
     255        pio_write_8(controller->channel[channel].offset_reg_address, value);
     256
     257        /* High byte */
     258        value = (pa >> 8) & 0xff;
     259        pio_write_8(controller->channel[channel].offset_reg_address, value);
     260
     261        /* Page address - third byte */
     262        value = (pa >> 16) & 0xff;
     263        pio_write_8(controller->channel[channel].offset_reg_address, value);
     264
     265        /* Set size -- reset flip-flop */
     266        pio_write_8(&controller->second->flip_flop, 1);
     267
     268        /* Low byte */
     269        value = size & 0xff;
     270        pio_write_8(controller->channel[channel].offset_reg_address, value);
     271
     272        /* High byte */
     273        value = (size >> 8) & 0xff;
     274        pio_write_8(controller->channel[channel].offset_reg_address, value);
     275
     276        /* Unmask DMA request */
     277        value = DMA_SINGLE_MASK_CHAN_TO_REG(channel);
     278        pio_write_8(&controller->second->single_mask, value);
     279
     280        return EOK;
    169281}
    170282/*----------------------------------------------------------------------------*/
     
    173285        static dma_controller_t *controller = NULL;
    174286        if (!controller)
     287                controller = dma_controller_init();
     288        if (!controller)
    175289                return EIO;
    176         return ENOTSUP;
     290        if (channel <= 4)
     291                return dma_setup_channel_8bit(controller, channel, pa, size);
     292        else
     293                return dma_setup_channel_16bit(controller, channel, pa, size);
    177294}
    178295/**
Note: See TracChangeset for help on using the changeset viewer.