/** * md_mic_dma_chan_init_attr - Set channel attributes like owner and endianness * @chan: The DMA channel handle */ void md_mic_dma_chan_init_attr(struct mic_dma_device *dma_dev, struct md_mic_dma_chan *chan) { uint32_t dcr; CHECK_CHAN(chan); dcr = mic_sbox_read_mmio(dma_dev->mm_sbox, SBOX_DCR); dcr = chan_to_dcr_mask(dcr, chan, dma_dev); mic_sbox_write_mmio(dma_dev->mm_sbox, SBOX_DCR, dcr); }
/** * md_mic_dma_enable_chan - Enable/disable the DMA channel * @chan_num: The DMA channel * @enable: enable/disable * * Must set desc ring and update head pointer only * after disabling the channel */ void md_mic_dma_enable_chan(struct mic_dma_device *dma_dev, uint32_t chan_num, bool enable) { uint32_t dcr = mic_sbox_read_mmio(dma_dev->mm_sbox, SBOX_DCR); /* * There is a separate bit for every channel. * Look up sboxDcrReg. */ if (enable) { dcr |= 2 << (chan_num << 1); } else { dcr &= ~(2 << (chan_num << 1)); } mic_sbox_write_mmio(dma_dev->mm_sbox, SBOX_DCR, dcr); }
/** * md_mic_dma_print_debug - Print channel debug information * @chan: The DMA channel handle * @sbuf: Print to an sbuf if not NULL else prints to console */ void md_mic_dma_print_debug(struct mic_dma_device *dma_dev, struct md_mic_dma_chan *chan) { uint32_t dcr; uint32_t dcar; uint32_t dtpr; uint32_t dhpr; uint32_t drar_lo; uint32_t drar_hi; uint32_t dstat; uint32_t chan_num = chan->ch_num; dcr = mic_sbox_read_mmio(dma_dev->mm_sbox, SBOX_DCR); dcar = md_mic_dma_read_mmio(dma_dev, chan_num, REG_DCAR); dtpr = md_mic_dma_read_mmio(dma_dev, chan_num, REG_DTPR); dhpr = md_mic_dma_read_mmio(dma_dev, chan_num, REG_DHPR); drar_lo = md_mic_dma_read_mmio(dma_dev, chan_num, REG_DRAR_LO); drar_hi = md_mic_dma_read_mmio(dma_dev, chan_num, REG_DRAR_HI); dstat = md_mic_dma_read_mmio(dma_dev, chan_num, REG_DSTAT); pr_debug(PR_PREFIX "Chan_Num 0x%x DCR 0x%x DCAR 0x%x DTPR 0x%x" "DHPR 0x%x DRAR_HI 0x%x DRAR_LO 0x%x DSTAT 0x%x\n", chan_num, dcr, dcar, dtpr, dhpr, drar_hi, drar_lo, dstat); pr_debug(PR_PREFIX "DCR 0x%x\n", dcr); }
static int mic_dma_reg_show(struct seq_file *m, void *v) { int i, j, chan_num, size, dtpr; struct mic_dma_ctx_t *dma_ctx = m->private; struct mic_dma_device *dma_dev = &dma_ctx->dma_dev; struct dma_channel *curr_chan; union md_mic_dma_desc desc; seq_printf(m, "========================================" "=======================================\n"); seq_printf(m, "SBOX_DCR: %#x\n", mic_sbox_read_mmio(dma_dev->mm_sbox, SBOX_DCR)); seq_printf(m, "DMA Channel Registers\n"); seq_printf(m, "========================================" "=======================================\n"); seq_printf(m, "%-10s| %-10s %-10s %-10s %-10s %-10s %-10s" #ifdef CONFIG_MK1OM " %-10s %-11s %-14s %-10s" #endif "\n", "Channel", "DCAR", "DTPR", "DHPR", "DRAR_HI", "DRAR_LO", #ifdef CONFIG_MK1OM "DSTATWB_LO", "DSTATWB_HI", "DSTAT_CHERR", "DSTAT_CHERRMSK", #endif "DSTAT"); seq_printf(m, "========================================" "=======================================\n"); #ifdef _MIC_SCIF_ for (i = 0; i < MAX_NUM_DMA_CHAN; i++) { #else for (i = first_dma_chan(); i <= last_dma_chan(); i++) { #endif curr_chan = &dma_ctx->dma_channels[i]; chan_num = curr_chan->ch_num; seq_printf(m, "%-10i| %-#10x %-#10x %-#10x %-#10x" " %-#10x" #ifdef CONFIG_MK1OM " %-#10x %-#11x %-#10x %-#14x" #endif " %-#10x\n", chan_num, md_mic_dma_read_mmio(dma_dev, chan_num, REG_DCAR), md_mic_dma_read_mmio(dma_dev, chan_num, REG_DTPR), md_mic_dma_read_mmio(dma_dev, chan_num, REG_DHPR), md_mic_dma_read_mmio(dma_dev, chan_num, REG_DRAR_HI), md_mic_dma_read_mmio(dma_dev, chan_num, REG_DRAR_LO), #ifdef CONFIG_MK1OM md_mic_dma_read_mmio(dma_dev, chan_num, REG_DSTATWB_LO), md_mic_dma_read_mmio(dma_dev, chan_num, REG_DSTATWB_HI), md_mic_dma_read_mmio(dma_dev, chan_num, REG_DCHERR), md_mic_dma_read_mmio(dma_dev, chan_num, REG_DCHERRMSK), #endif md_mic_dma_read_mmio(dma_dev, chan_num, REG_DSTAT)); } seq_printf(m, "\nDMA Channel Descriptor Rings\n"); seq_printf(m, "========================================" "=======================================\n"); for (i = first_dma_chan(); i <= last_dma_chan(); i++) { curr_chan = &dma_ctx->dma_channels[i]; chan_num = curr_chan->ch_num; dtpr = md_mic_dma_read_mmio(dma_dev, chan_num, REG_DTPR); seq_printf(m, "Channel %i: [", chan_num); size = ((int) md_mic_dma_read_mmio(dma_dev, chan_num, REG_DHPR) - dtpr) % curr_chan->chan->num_desc_in_ring; /* * In KNC B0, empty condition is tail = head -1 */ if (mic_hw_family(dma_ctx->device_num) == FAMILY_KNC && mic_hw_stepping(dma_ctx->device_num) >= KNC_B0_STEP) size -= 1; for (j = 0; j < size; j++) { desc = curr_chan->desc_ring[(j+dtpr) % curr_chan->chan->num_desc_in_ring]; switch (desc.desc.nop.type){ case NOP: seq_printf(m," {Type: NOP, 0x%#llx" " %#llx} ", desc.qwords.qw0, desc.qwords.qw1); case MEMCOPY: seq_printf(m," {Type: MEMCOPY, SAP:" " 0x%#llx, DAP: %#llx, length: %#llx} ", (uint64_t) desc.desc.memcopy.sap, (uint64_t) desc.desc.memcopy.dap, (uint64_t) desc.desc.memcopy.length); break; case STATUS: seq_printf(m," {Type: STATUS, data:" " 0x%#llx, DAP: %#llx, intr: %lli} ", (uint64_t) desc.desc.status.data, (uint64_t) desc.desc.status.dap, (uint64_t) desc.desc.status.intr); break; case GENERAL: seq_printf(m," {Type: GENERAL, " "DAP: %#llx, dword: %#llx} ", (uint64_t) desc.desc.general.dap, (uint64_t) desc.desc.general.data); break; case KEYNONCECNT: seq_printf(m," {Type: KEYNONCECNT, sel: " "%lli, h: %lli, index: %lli, cs: %lli," " value: %#llx} ", (uint64_t) desc.desc.keynoncecnt.sel, (uint64_t) desc.desc.keynoncecnt.h, (uint64_t) desc.desc.keynoncecnt.index, (uint64_t) desc.desc.keynoncecnt.cs, (uint64_t) desc.desc.keynoncecnt.data); break; case KEY: seq_printf(m," {Type: KEY, dest_ind" "ex: %lli, ski: %lli, skap: %#llx ", (uint64_t) desc.desc.key.di, (uint64_t) desc.desc.key.ski, (uint64_t) desc.desc.key.skap); break; default: seq_printf(m," {Uknown Type=%lli ," "%#llx %#llx} ",(uint64_t) desc.desc.nop.type, (uint64_t) desc.qwords.qw0, (uint64_t) desc.qwords.qw1); } } seq_printf(m, "]\n"); if (mic_hw_family(dma_ctx->device_num) == FAMILY_KNC && mic_hw_stepping(dma_ctx->device_num) >= KNC_B0_STEP && curr_chan->chan->dstat_wb_loc) seq_printf(m, "DSTAT_WB = 0x%x\n", *((uint32_t*)curr_chan->chan->dstat_wb_loc)); } return 0; } static int mic_dma_reg_open(struct inode *inode, struct file *file) { return single_open(file, mic_dma_reg_show, PDE_DATA(inode)); } static const struct file_operations mic_dma_reg_fops = { .owner = THIS_MODULE, .open = mic_dma_reg_open, .read = seq_read, .llseek = seq_lseek, .release = single_release }; static void mic_dma_proc_init(struct mic_dma_ctx_t *dma_ctx) { char name[64]; snprintf(name, 63, "%s%d", proc_dma_ring, dma_ctx->device_num); proc_create_data(name, S_IFREG | S_IRUGO, NULL, &mic_dma_ring_fops, dma_ctx); snprintf(name, 63, "%s%d", proc_dma_reg, dma_ctx->device_num); proc_create_data(name, S_IFREG | S_IRUGO, NULL, &mic_dma_reg_fops, dma_ctx); }