diff options
Diffstat (limited to 'chip/ish/dma.c')
-rw-r--r-- | chip/ish/dma.c | 193 |
1 files changed, 0 insertions, 193 deletions
diff --git a/chip/ish/dma.c b/chip/ish/dma.c deleted file mode 100644 index a409dc6ad3..0000000000 --- a/chip/ish/dma.c +++ /dev/null @@ -1,193 +0,0 @@ -/* Copyright 2019 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -/* DMA module for ISH */ - -#include "common.h" -#include "console.h" -#include "registers.h" -#include "ish_dma.h" -#include "util.h" - -static int dma_init_called; /* If ish_dma_init is called */ - -static int dma_poll(uint32_t addr, uint32_t expected, uint32_t mask) -{ - int retval = -1; - uint32_t counter = 0; - - /* - * The timeout is approximately 2.2 seconds according to - * value of UINT32_MAX, 120MHZ ISH clock frequency and - * instruction count which is around 4. - */ - while (counter < (UINT32_MAX / 64)) { - /* test condition */ - if ((REG32(addr) & mask) == expected) { - retval = DMA_RC_OK; - break; - } - counter++; - } - - return retval; -} - -void ish_dma_ocp_timeout_disable(void) -{ - uint32_t ctrl = OCP_AGENT_CONTROL; - - OCP_AGENT_CONTROL = ctrl & OCP_RESPONSE_TO_DISABLE; -} - -static inline uint32_t interrupt_lock(void) -{ - uint32_t eflags = 0; - __asm__ volatile("pushfl;" /* save eflag value */ - "popl %0;" - "cli;" - : "=r"(eflags)); /* shut off interrupts */ - return eflags; -} - -static inline void interrupt_unlock(uint32_t eflags) -{ - __asm__ volatile("pushl %0;" /* restore elfag values */ - "popfl;" - : - : "r"(eflags)); -} - -void dma_configure_psize(void) -{ - /* Give chan0 512 bytes for high performance, and chan1 128 bytes. */ - DMA_PSIZE_01 = DMA_PSIZE_UPDATE | - (DMA_PSIZE_CHAN1_SIZE << DMA_PSIZE_CHAN1_OFFSET) | - (DMA_PSIZE_CHAN0_SIZE << DMA_PSIZE_CHAN0_OFFSET); -} - -void ish_dma_init(void) -{ - uint32_t uma_msb; - - ish_dma_ocp_timeout_disable(); - - /* configure DMA partition size */ - dma_configure_psize(); - - /* set DRAM address 32 MSB for DMA transactions on UMA */ - uma_msb = IPC_UMA_RANGE_LOWER_1; - ish_dma_set_msb(PAGING_CHAN, uma_msb, uma_msb); - - dma_init_called = 1; -} - -int ish_dma_copy(uint32_t chan, uint32_t dst, uint32_t src, uint32_t length, - enum dma_mode mode) -{ - uint32_t chan_reg = DMA_REG_BASE + (DMA_CH_REGS_SIZE * chan); - int rc = DMA_RC_OK; - uint32_t eflags; - uint32_t chunk; - - __asm__ volatile("\twbinvd\n"); /* Flush cache before dma start */ - - /* Bringup VNN power rail for accessing SoC fabric */ - PMU_VNN_REQ = (1 << VNN_ID_DMA(chan)); - while (!(PMU_VNN_REQ_ACK & PMU_VNN_REQ_ACK_STATUS)) - continue; - - /* - * shut off interrupts to assure no simultanious - * access to DMA registers - */ - eflags = interrupt_lock(); - - MISC_CHID_CFG_REG = chan; /* Set channel to configure */ - - mode |= NON_SNOOP; - MISC_DMA_CTL_REG(chan) = mode; /* Set transfer direction */ - - DMA_CFG_REG = DMA_ENABLE; /* Enable DMA module */ - DMA_LLP(chan_reg) = 0; /* Linked lists are not used */ - DMA_CTL_LOW(chan_reg) = - 0 /* Set transfer parameters */ | - (DMA_CTL_TT_FC_M2M_DMAC << DMA_CTL_TT_FC_SHIFT) | - (DMA_CTL_ADDR_INC << DMA_CTL_SINC_SHIFT) | - (DMA_CTL_ADDR_INC << DMA_CTL_DINC_SHIFT) | - (SRC_TR_WIDTH << DMA_CTL_SRC_TR_WIDTH_SHIFT) | - (DEST_TR_WIDTH << DMA_CTL_DST_TR_WIDTH_SHIFT) | - (SRC_BURST_SIZE << DMA_CTL_SRC_MSIZE_SHIFT) | - (DEST_BURST_SIZE << DMA_CTL_DEST_MSIZE_SHIFT); - - interrupt_unlock(eflags); - while (length) { - chunk = (length > DMA_MAX_BLOCK_SIZE) ? DMA_MAX_BLOCK_SIZE - : length; - - if (rc != DMA_RC_OK) - break; - - eflags = interrupt_lock(); - MISC_CHID_CFG_REG = chan; /* Set channel to configure */ - DMA_CTL_HIGH(chan_reg) = - chunk; /* Set number of bytes to transfer */ - DMA_DAR(chan_reg) = dst; /* Destination address */ - DMA_SAR(chan_reg) = src; /* Source address */ - DMA_EN_REG = DMA_CH_EN_BIT(chan) | - DMA_CH_EN_WE_BIT(chan); /* Enable the channel */ - interrupt_unlock(eflags); - - rc = ish_wait_for_dma_done( - chan); /* Wait for trans completion */ - - dst += chunk; - src += chunk; - length -= chunk; - } - - /* Mark the DMA VNN power rail as no longer needed */ - PMU_VNN_REQ = (1 << VNN_ID_DMA(chan)); - return rc; -} - -void ish_dma_disable(void) -{ - uint32_t channel; - uint32_t counter; - - /* Disable DMA on per-channel basis. */ - for (channel = 0; channel <= DMA_MAX_CHANNEL; channel++) { - MISC_CHID_CFG_REG = channel; - if (DMA_EN_REG & DMA_CH_EN_BIT(channel)) { - /* Write 0 to channel enable bit ... */ - DMA_EN_REG = DMA_CH_EN_WE_BIT(channel); - - /* Wait till it shuts up. */ - counter = 0; - while ((DMA_EN_REG & DMA_CH_EN_BIT(channel)) && - counter < (UINT32_MAX / 64)) - counter++; - } - } - DMA_CLR_ERR_REG = 0xFFFFFFFF; - DMA_CLR_BLOCK_REG = 0xFFFFFFFF; - - DMA_CFG_REG = 0; /* Disable DMA module */ -} - -int ish_wait_for_dma_done(uint32_t ch) -{ - return dma_poll(DMA_EN_REG_ADDR, 0, DMA_CH_EN_BIT(ch)); -} - -void ish_dma_set_msb(uint32_t chan, uint32_t dst_msb, uint32_t src_msb) -{ - uint32_t eflags = interrupt_lock(); - MISC_CHID_CFG_REG = chan; /* Set channel to configure */ - MISC_SRC_FILLIN_DMA(chan) = src_msb; - MISC_DST_FILLIN_DMA(chan) = dst_msb; - interrupt_unlock(eflags); -} |