diff options
Diffstat (limited to 'chip/mchp/gpspi.c')
-rw-r--r-- | chip/mchp/gpspi.c | 267 |
1 files changed, 0 insertions, 267 deletions
diff --git a/chip/mchp/gpspi.c b/chip/mchp/gpspi.c deleted file mode 100644 index f8b556d389..0000000000 --- a/chip/mchp/gpspi.c +++ /dev/null @@ -1,267 +0,0 @@ -/* Copyright 2017 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. - */ - -/* General Purpose SPI master module for MCHP MEC */ - -#include "common.h" -#include "console.h" -#include "dma.h" -#include "gpio.h" -#include "registers.h" -#include "spi.h" -#include "timer.h" -#include "util.h" -#include "hooks.h" -#include "task.h" -#include "spi_chip.h" -#include "gpspi_chip.h" -#include "tfdp_chip.h" - -#define CPUTS(outstr) cputs(CC_SPI, outstr) -#define CPRINTS(format, args...) cprints(CC_SPI, format, ## args) - -#define SPI_BYTE_TRANSFER_TIMEOUT_US (3 * MSEC) -/* One byte at 12 MHz full duplex = 0.67 us */ -#define SPI_BYTE_TRANSFER_POLL_INTERVAL_US 20 - -/* - * GP-SPI - */ - -/** - * Return zero based GPSPI controller index given hardware port. - * @param hw_port b[7:4]==1 (GPSPI), b[3:0]=0(GPSPI0), 1(GPSPI1) - * @return 0(GPSPI0) or 1(GPSPI1) - */ -static uint8_t gpspi_port_to_ctrl_id(uint8_t hw_port) -{ - return (hw_port & 0x01); -} - -static int gpspi_wait_byte(const int ctrl) -{ - timestamp_t deadline; - - deadline.val = get_time().val + SPI_BYTE_TRANSFER_TIMEOUT_US; - while ((MCHP_SPI_SR(ctrl) & 0x3) != 0x3) { - if (timestamp_expired(deadline, NULL)) - return EC_ERROR_TIMEOUT; - usleep(SPI_BYTE_TRANSFER_POLL_INTERVAL_US); - } - return EC_SUCCESS; -} - -/* NOTE: auto-read must be disabled before calling this routine! */ -static void gpspi_rx_fifo_clean(const int ctrl) -{ - uint8_t dummy = 0; - - /* If ACTIVE and/or RXFF then clean it */ - if ((MCHP_SPI_SR(ctrl) & 0x4) == 0x4) - dummy += MCHP_SPI_RD(ctrl); - - if ((MCHP_SPI_SR(ctrl) & 0x2) == 0x2) - dummy += MCHP_SPI_RD(ctrl); -} -/* - * NOTE: auto-read must be disabled before calling this routine! - */ -#ifndef CONFIG_MCHP_GPSPI_TX_DMA -static int gpspi_tx(const int ctrl, const uint8_t *txdata, int txlen) -{ - int i; - int ret; - uint8_t dummy = 0; - - gpspi_rx_fifo_clean(ctrl); - - ret = EC_SUCCESS; - for (i = 0; i < txlen; ++i) { - MCHP_SPI_TD(ctrl) = txdata[i]; - ret = gpspi_wait_byte(ctrl); - if (ret != EC_SUCCESS) - break; - dummy += MCHP_SPI_RD(ctrl); - } - - return ret; -} -#endif - -int gpspi_transaction_async(const struct spi_device_t *spi_device, - const uint8_t *txdata, int txlen, - uint8_t *rxdata, int rxlen) -{ - int hw_port, ctrl; - int ret = EC_SUCCESS; - int cs_asserted = 0; - const struct dma_option *opdma; -#ifdef CONFIG_MCHP_GPSPI_TX_DMA - dma_chan_t *chan; -#endif - if (spi_device == NULL) - return EC_ERROR_PARAM1; - - hw_port = spi_device->port; - - ctrl = gpspi_port_to_ctrl_id(hw_port); - - /* Disable auto read */ - MCHP_SPI_CR(ctrl) &= ~BIT(5); - - if ((txdata != NULL) && (txdata != 0)) { -#ifdef CONFIG_MCHP_GPSPI_TX_DMA - opdma = spi_dma_option(spi_device, SPI_DMA_OPTION_WR); - if (opdma == NULL) - return EC_ERROR_INVAL; - - gpspi_rx_fifo_clean(ctrl); - - dma_prepare_tx(opdma, txlen, txdata); - - chan = dma_get_channel(opdma->channel); - - gpio_set_level(spi_device->gpio_cs, 0); - cs_asserted = 1; - - dma_go(chan); - ret = dma_wait(opdma->channel); - if (ret == EC_SUCCESS) - ret = gpspi_wait_byte(ctrl); - - dma_disable(opdma->channel); - dma_clear_isr(opdma->channel); - - gpspi_rx_fifo_clean(ctrl); -#else - gpio_set_level(spi_device->gpio_cs, 0); - cs_asserted = 1; - - ret = gpspi_tx(ctrl, txdata, txlen); -#endif - } - - if (ret == EC_SUCCESS) - if ((rxlen != 0) && (rxdata != NULL)) { - ret = EC_ERROR_INVAL; - opdma = spi_dma_option(spi_device, SPI_DMA_OPTION_RD); - if (opdma != NULL) { - if (!cs_asserted) - gpio_set_level(spi_device->gpio_cs, 0); - /* Enable auto read */ - MCHP_SPI_CR(ctrl) |= BIT(5); - dma_start_rx(opdma, rxlen, rxdata); - MCHP_SPI_TD(ctrl) = 0; - ret = EC_SUCCESS; - } - } - - return ret; -} - -int gpspi_transaction_flush(const struct spi_device_t *spi_device) -{ - int ctrl, hw_port; - int ret; - enum dma_channel chan; - const struct dma_option *opdma; - timestamp_t deadline; - - if (spi_device == NULL) - return EC_ERROR_PARAM1; - - hw_port = spi_device->port; - ctrl = gpspi_port_to_ctrl_id(hw_port); - opdma = spi_dma_option(spi_device, SPI_DMA_OPTION_RD); - chan = opdma->channel; - - ret = dma_wait(chan); - - /* Disable auto read */ - MCHP_SPI_CR(ctrl) &= ~BIT(5); - - deadline.val = get_time().val + SPI_BYTE_TRANSFER_TIMEOUT_US; - /* Wait for FIFO empty SPISR_TXBE */ - while ((MCHP_SPI_SR(ctrl) & 0x01) != 0x1) { - if (timestamp_expired(deadline, NULL)) { - ret = EC_ERROR_TIMEOUT; - break; - } - usleep(SPI_BYTE_TRANSFER_POLL_INTERVAL_US); - } - - dma_disable(chan); - dma_clear_isr(chan); - if (MCHP_SPI_SR(ctrl) & 0x2) - hw_port = MCHP_SPI_RD(ctrl); - - gpio_set_level(spi_device->gpio_cs, 1); - - return ret; -} - -int gpspi_transaction_wait(const struct spi_device_t *spi_device) -{ - const struct dma_option *opdma; - - opdma = spi_dma_option(spi_device, SPI_DMA_OPTION_RD); - - return dma_wait(opdma->channel); -} - -/** - * Enable GPSPI controller and MODULE_SPI_MASTER pins - * - * @param hw_port b[7:4]=1 b[3:0]=0(GPSPI0), 1(GPSPI1) - * @param enable - * @return EC_SUCCESS or EC_ERROR_INVAL if port is unrecognized - * @note called from mec1701/spi.c - * - */ -int gpspi_enable(int hw_port, int enable) -{ - uint32_t ctrl; - - if ((hw_port != GPSPI0_PORT) && (hw_port != GPSPI1_PORT)) - return EC_ERROR_INVAL; - - gpio_config_module(MODULE_SPI_MASTER, (enable > 0)); - - ctrl = (uint32_t)hw_port & 0x0f; - - if (enable) { - - if (ctrl) - MCHP_PCR_SLP_DIS_DEV(MCHP_PCR_GPSPI1); - else - MCHP_PCR_SLP_DIS_DEV(MCHP_PCR_GPSPI0); - - /* Set enable bit in SPI_AR */ - MCHP_SPI_AR(ctrl) |= 0x1; - - /* Set SPDIN to 0 -> Full duplex */ - MCHP_SPI_CR(ctrl) &= ~(0x3 << 2); - - /* Set CLKPOL, TCLKPH, RCLKPH to 0 */ - MCHP_SPI_CC(ctrl) &= ~0x7; - - /* Set LSBF to 0 -> MSB first */ - MCHP_SPI_CR(ctrl) &= ~0x1; - } else { - /* soft reset */ - MCHP_SPI_CR(ctrl) |= (1u << 4); - - /* Clear enable bit in SPI_AR */ - MCHP_SPI_AR(ctrl) &= ~0x1; - - if (ctrl) - MCHP_PCR_SLP_EN_DEV(MCHP_PCR_GPSPI1); - else - MCHP_PCR_SLP_EN_DEV(MCHP_PCR_GPSPI0); - } - - return EC_SUCCESS; -} - |