static void sdma_event_enable(struct sdma_channel *sdmac, unsigned int event) { struct sdma_engine *sdma = sdmac->sdma; int channel = sdmac->channel; u32 val; u32 chnenbl = chnenbl_ofs(sdma, event); val = __raw_readl(sdma->regs + chnenbl); val |= (1 << channel); __raw_writel(val, sdma->regs + chnenbl); }
static void sdma_event_disable(struct sdma_channel *sdmac, unsigned int event) { struct sdma_engine *sdma = sdmac->sdma; int channel = sdmac->channel; u32 chnenbl = chnenbl_ofs(sdma, event); u32 val; val = readl_relaxed(sdma->regs + chnenbl); val &= ~(1 << channel); writel_relaxed(val, sdma->regs + chnenbl); }
static int __init sdma_init(struct sdma_engine *sdma) { int i, ret; dma_addr_t ccb_phys; switch (sdma->version) { case 1: sdma->num_events = 32; break; case 2: sdma->num_events = 48; break; default: dev_err(sdma->dev, "Unknown version %d. aborting\n", sdma->version); return -ENODEV; } clk_enable(sdma->clk); /* Be sure SDMA has not started yet */ __raw_writel(0, sdma->regs + SDMA_H_C0PTR); sdma->channel_control = dma_alloc_coherent(NULL, MAX_DMA_CHANNELS * sizeof (struct sdma_channel_control) + sizeof(struct sdma_context_data), &ccb_phys, GFP_KERNEL); if (!sdma->channel_control) { ret = -ENOMEM; goto err_dma_alloc; } sdma->context = (void *)sdma->channel_control + MAX_DMA_CHANNELS * sizeof (struct sdma_channel_control); sdma->context_phys = ccb_phys + MAX_DMA_CHANNELS * sizeof (struct sdma_channel_control); /* Zero-out the CCB structures array just allocated */ memset(sdma->channel_control, 0, MAX_DMA_CHANNELS * sizeof (struct sdma_channel_control)); /* disable all channels */ for (i = 0; i < sdma->num_events; i++) __raw_writel(0, sdma->regs + chnenbl_ofs(sdma, i)); /* All channels have priority 0 */ for (i = 0; i < MAX_DMA_CHANNELS; i++) __raw_writel(0, sdma->regs + SDMA_CHNPRI_0 + i * 4); ret = sdma_request_channel(&sdma->channel[0]); if (ret) goto err_dma_alloc; sdma_config_ownership(&sdma->channel[0], false, true, false); /* Set Command Channel (Channel Zero) */ __raw_writel(0x4050, sdma->regs + SDMA_CHN0ADDR); /* Set bits of CONFIG register but with static context switching */ /* FIXME: Check whether to set ACR bit depending on clock ratios */ __raw_writel(0, sdma->regs + SDMA_H_CONFIG); __raw_writel(ccb_phys, sdma->regs + SDMA_H_C0PTR); /* Set bits of CONFIG register with given context switching mode */ __raw_writel(SDMA_H_CONFIG_CSM, sdma->regs + SDMA_H_CONFIG); /* Initializes channel's priorities */ sdma_set_channel_priority(&sdma->channel[0], 7); clk_disable(sdma->clk); return 0; err_dma_alloc: clk_disable(sdma->clk); dev_err(sdma->dev, "initialisation failed with %d\n", ret); return ret; }