diff options
Diffstat (limited to 'chip/stm32/spi.c')
-rw-r--r-- | chip/stm32/spi.c | 747 |
1 files changed, 0 insertions, 747 deletions
diff --git a/chip/stm32/spi.c b/chip/stm32/spi.c deleted file mode 100644 index 3dbbbc4fa9..0000000000 --- a/chip/stm32/spi.c +++ /dev/null @@ -1,747 +0,0 @@ -/* - * Copyright 2013 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. - * - * SPI driver for Chrome EC. - * - * This uses DMA to handle transmission and reception. - */ - -#include "chipset.h" -#include "clock.h" -#include "console.h" -#include "dma.h" -#include "gpio.h" -#include "hooks.h" -#include "link_defs.h" -#include "registers.h" -#include "spi.h" -#include "stm32-dma.h" -#include "system.h" -#include "timer.h" -#include "util.h" - -/* Console output macros */ -#define CPUTS(outstr) cputs(CC_SPI, outstr) -#define CPRINTS(format, args...) cprints(CC_SPI, format, ## args) -#define CPRINTF(format, args...) cprintf(CC_SPI, format, ## args) - -/* SPI FIFO registers */ -#ifdef CHIP_FAMILY_STM32H7 -#define SPI_TXDR REG8(&STM32_SPI1_REGS->txdr) -#define SPI_RXDR REG8(&STM32_SPI1_REGS->rxdr) -#else -#define SPI_TXDR STM32_SPI1_REGS->dr -#define SPI_RXDR STM32_SPI1_REGS->dr -#endif - -/* DMA channel option */ -static const struct dma_option dma_tx_option = { - STM32_DMAC_SPI1_TX, (void *)&SPI_TXDR, - STM32_DMA_CCR_MSIZE_8_BIT | STM32_DMA_CCR_PSIZE_8_BIT -#ifdef CHIP_FAMILY_STM32F4 - | STM32_DMA_CCR_CHANNEL(STM32_SPI1_TX_REQ_CH) -#endif -}; - -static const struct dma_option dma_rx_option = { - STM32_DMAC_SPI1_RX, (void *)&SPI_RXDR, - STM32_DMA_CCR_MSIZE_8_BIT | STM32_DMA_CCR_PSIZE_8_BIT -#ifdef CHIP_FAMILY_STM32F4 - | STM32_DMA_CCR_CHANNEL(STM32_SPI1_RX_REQ_CH) -#endif -}; - -/* - * Timeout to wait for SPI request packet - * - * This affects the slowest SPI clock we can support. A delay of 8192 us - * permits a 512-byte request at 500 KHz, assuming the master starts sending - * bytes as soon as it asserts chip select. That's as slow as we would - * practically want to run the SPI interface, since running it slower - * significantly impacts firmware update times. - */ -#define SPI_CMD_RX_TIMEOUT_US 8192 - -#ifdef CONFIG_SPI_PROTOCOL_V2 -/* - * Offset of output parameters needs to account for pad and framing bytes and - * one last past-end byte at the end so any additional bytes clocked out by - * the AP will have a known and identifiable value. - */ -#define SPI_PROTO2_OFFSET (EC_PROTO2_RESPONSE_HEADER_BYTES + 2) -#define SPI_PROTO2_OVERHEAD (SPI_PROTO2_OFFSET + \ - EC_PROTO2_RESPONSE_TRAILER_BYTES + 1) -#endif /* defined(CONFIG_SPI_PROTOCOL_V2) */ -/* - * Max data size for a version 3 request/response packet. This is big enough - * to handle a request/response header, flash write offset/size, and 512 bytes - * of flash data. - */ -#define SPI_MAX_REQUEST_SIZE 0x220 -#define SPI_MAX_RESPONSE_SIZE 0x220 - -/* - * The AP blindly clocks back bytes over the SPI interface looking for a - * framing byte. So this preamble must always precede the actual response - * packet. Search for "spi-frame-header" in U-boot to see how that's - * implemented. - * - * The preamble must be 32-bit aligned so that the response buffer is also - * 32-bit aligned. - */ -static const uint8_t out_preamble[4] = { - EC_SPI_PROCESSING, - EC_SPI_PROCESSING, - EC_SPI_PROCESSING, - EC_SPI_FRAME_START, /* This is the byte which matters */ -}; - -/* - * Space allocation of the past-end status byte (EC_SPI_PAST_END) in the out_msg - * buffer. This seems to be dynamic because the F0 family needs to send it 4 - * times in order to make sure it actually stays at the repeating byte after DMA - * ends. - * - * See crosbug.com/p/31390 - */ -#if defined(CHIP_FAMILY_STM32F0) || defined(CHIP_FAMILY_STM32L4) -#define EC_SPI_PAST_END_LENGTH 4 -#else -#define EC_SPI_PAST_END_LENGTH 1 -#endif - -/* - * Our input and output buffers. These must be large enough for our largest - * message, including protocol overhead, and must be 32-bit aligned. - */ -static uint8_t out_msg[SPI_MAX_RESPONSE_SIZE + sizeof(out_preamble) + - EC_SPI_PAST_END_LENGTH] __aligned(4) __uncached; -static uint8_t in_msg[SPI_MAX_REQUEST_SIZE] __aligned(4) __uncached; -static uint8_t enabled; -#ifdef CONFIG_SPI_PROTOCOL_V2 -static struct host_cmd_handler_args args; -#endif -static struct host_packet spi_packet; - -/* - * This is set if SPI NSS raises to high while EC is still processing a - * command. - */ -static int setup_transaction_later; - -enum spi_state { - /* SPI not enabled (initial state, and when chipset is off) */ - SPI_STATE_DISABLED = 0, - - /* Setting up receive DMA */ - SPI_STATE_PREPARE_RX, - - /* Ready to receive next request */ - SPI_STATE_READY_TO_RX, - - /* Receiving request */ - SPI_STATE_RECEIVING, - - /* Processing request */ - SPI_STATE_PROCESSING, - - /* Sending response */ - SPI_STATE_SENDING, - - /* - * Received bad data - transaction started before we were ready, or - * packet header from host didn't parse properly. Ignoring received - * data. - */ - SPI_STATE_RX_BAD, -} state; - -/** - * Wait until we have received a certain number of bytes - * - * Watch the DMA receive channel until it has the required number of bytes, - * or a timeout occurs - * - * We keep an eye on the NSS line - if this goes high then the transaction is - * over so there is no point in trying to receive the bytes. - * - * @param rxdma RX DMA channel to watch - * @param needed Number of bytes that are needed - * @param nss GPIO signal for NSS control line - * @return 0 if bytes received, -1 if we hit a timeout or NSS went high - */ -static int wait_for_bytes(dma_chan_t *rxdma, int needed, - enum gpio_signal nss) -{ - timestamp_t deadline; - - ASSERT(needed <= sizeof(in_msg)); - deadline.val = 0; - while (1) { - if (dma_bytes_done(rxdma, sizeof(in_msg)) >= needed) - return 0; - if (gpio_get_level(nss)) - return -1; - if (!deadline.val) { - deadline = get_time(); - deadline.val += SPI_CMD_RX_TIMEOUT_US; - } - if (timestamp_expired(deadline, NULL)) - return -1; - } -} - -#ifdef CONFIG_SPI_PROTOCOL_V2 -/** - * Send a reply on a given port. - * - * The format of a reply is as per the command interface, with a number of - * preamble bytes before it. - * - * The format of a reply is a sequence of bytes: - * - * <hdr> <status> <len> <msg bytes> <sum> [<preamble byte>...] - * - * The hdr byte is just a tag to indicate that the real message follows. It - * signals the end of any preamble required by the interface. - * - * The length is the entire packet size, including the header, length bytes, - * message payload, checksum, and postamble byte. - * - * The preamble is at least 2 bytes, but can be longer if the STM takes ages - * to react to the incoming message. Since we send our first byte as the AP - * sends us the command, we clearly can't send anything sensible for that - * byte. The second byte must be written to the output register just when the - * command byte is ready (I think), so we can't do anything there either. - * Any processing we do may increase this delay. That's the reason for the - * preamble. - * - * It is interesting to note that it seems to be possible to run the SPI - * interface faster than the CPU clock with this approach. - * - * We keep an eye on the NSS line - if this goes high then the transaction is - * over so there is no point in trying to send the reply. - * - * @param txdma TX DMA channel to send on - * @param status Status result to send - * @param msg_ptr Message payload to send, which normally starts - * SPI_PROTO2_OFFSET bytes into out_msg - * @param msg_len Number of message bytes to send - */ -static void reply(dma_chan_t *txdma, - enum ec_status status, char *msg_ptr, int msg_len) -{ - char *msg = out_msg; - int need_copy = msg_ptr != msg + SPI_PROTO2_OFFSET; - int sum, i; - - ASSERT(msg_len + SPI_PROTO2_OVERHEAD <= sizeof(out_msg)); - - /* Add our header bytes - the first one might not actually be sent */ - msg[0] = EC_SPI_PROCESSING; - msg[1] = EC_SPI_FRAME_START; - msg[2] = status; - msg[3] = msg_len & 0xff; - - /* - * Calculate the checksum; includes the status and message length bytes - * but not the pad and framing bytes since those are stripped by the AP - * driver. - */ - sum = status + msg_len; - for (i = 0; i < msg_len; i++) { - int ch = msg_ptr[i]; - sum += ch; - if (need_copy) - msg[i + SPI_PROTO2_OFFSET] = ch; - } - - /* Add the checksum and get ready to send */ - msg[SPI_PROTO2_OFFSET + msg_len] = sum & 0xff; - msg[SPI_PROTO2_OFFSET + msg_len + 1] = EC_SPI_PAST_END; - dma_prepare_tx(&dma_tx_option, msg_len + SPI_PROTO2_OVERHEAD, msg); - - /* Kick off the DMA to send the data */ - dma_go(txdma); -} -#endif /* defined(CONFIG_SPI_PROTOCOL_V2) */ - -/** - * Sends a byte over SPI without DMA - * - * This is mostly used when we want to relay status bytes to the AP while we're - * receiving the message and we're thinking about it. - * - * @note It may be sent 0, 1, or >1 times, depending on whether the host clocks - * the bus or not. Basically, the EC is saying "if you ask me what my status is, - * you'll get this value. But you're not required to ask, or you can ask - * multiple times." - * - * @param byte status byte to send, one of the EC_SPI_* #defines from - * ec_commands.h - */ -static void tx_status(uint8_t byte) -{ - stm32_spi_regs_t *spi __attribute__((unused)) = STM32_SPI1_REGS; - - SPI_TXDR = byte; -#if defined(CHIP_FAMILY_STM32F0) || defined(CHIP_FAMILY_STM32L4) - /* It sends the byte 4 times in order to be sure it bypassed the FIFO - * from the STM32F0 line. - */ - spi->dr = byte; - spi->dr = byte; - spi->dr = byte; -#elif defined(CHIP_FAMILY_STM32H7) - spi->udrdr = byte; -#endif -} - -/** - * Get ready to receive a message from the master. - * - * Set up our RX DMA and disable our TX DMA. Set up the data output so that - * we will send preamble bytes. - */ -static void setup_for_transaction(void) -{ - stm32_spi_regs_t *spi __attribute__((unused)) = STM32_SPI1_REGS; - volatile uint8_t unused __attribute__((unused)); - - /* clear this as soon as possible */ - setup_transaction_later = 0; - -#ifndef CHIP_FAMILY_STM32H7 /* H7 is not ready to set status here */ - /* Not ready to receive yet */ - tx_status(EC_SPI_NOT_READY); -#endif - - /* We are no longer actively processing a transaction */ - state = SPI_STATE_PREPARE_RX; - - /* Stop sending response, if any */ - dma_disable(STM32_DMAC_SPI1_TX); - - /* - * Read unused bytes in case there are some pending; this prevents the - * receive DMA from getting that byte right when we start it. - */ - unused = SPI_RXDR; -#if defined(CHIP_FAMILY_STM32F0) || defined(CHIP_FAMILY_STM32L4) - /* 4 Bytes makes sure the RX FIFO on the F0 is empty as well. */ - unused = spi->dr; - unused = spi->dr; - unused = spi->dr; -#endif - - /* Start DMA */ - dma_start_rx(&dma_rx_option, sizeof(in_msg), in_msg); - - /* Ready to receive */ - state = SPI_STATE_READY_TO_RX; - tx_status(EC_SPI_OLD_READY); - -#ifdef CHIP_FAMILY_STM32H7 - spi->cr1 |= STM32_SPI_CR1_SPE; -#endif -} - -/* Forward declaration */ -static void spi_init(void); - -/* - * If a setup_for_transaction() was postponed, call it now. - * Note that setup_for_transaction() cancels Tx DMA. - */ -static void check_setup_transaction_later(void) -{ - if (setup_transaction_later) { - spi_init(); /* Fix for bug chrome-os-partner:31390 */ - /* - * 'state' is set to SPI_STATE_READY_TO_RX. Somehow AP - * de-asserted the SPI NSS during the handler was running. - * Thus, the pending result will be dropped anyway. - */ - } -} - -#ifdef CONFIG_SPI_PROTOCOL_V2 -/** - * Called for V2 protocol to indicate that a command has completed - * - * Some commands can continue for a while. This function is called by - * host_command when it completes. - * - */ -static void spi_send_response(struct host_cmd_handler_args *args) -{ - enum ec_status result = args->result; - dma_chan_t *txdma; - - /* - * If we're not processing, then the AP has already terminated the - * transaction, and won't be listening for a response. - */ - if (state != SPI_STATE_PROCESSING) - return; - - /* state == SPI_STATE_PROCESSING */ - - if (args->response_size > args->response_max) - result = EC_RES_INVALID_RESPONSE; - - /* Transmit the reply */ - txdma = dma_get_channel(STM32_DMAC_SPI1_TX); - reply(txdma, result, args->response, args->response_size); - - /* - * Before the state is set to SENDING, any CS de-assertion would - * set setup_transaction_later to 1. - */ - state = SPI_STATE_SENDING; - check_setup_transaction_later(); -} -#endif /* defined(CONFIG_SPI_PROTOCOL_V2) */ - -/** - * Called to send a response back to the host. - * - * Some commands can continue for a while. This function is called by - * host_command when it completes. - * - */ -static void spi_send_response_packet(struct host_packet *pkt) -{ - dma_chan_t *txdma; - - /* - * If we're not processing, then the AP has already terminated the - * transaction, and won't be listening for a response. - */ - if (state != SPI_STATE_PROCESSING) - return; - - /* state == SPI_STATE_PROCESSING */ - - /* Append our past-end byte, which we reserved space for. */ - ((uint8_t *)pkt->response)[pkt->response_size + 0] = EC_SPI_PAST_END; -#if defined(CHIP_FAMILY_STM32F0) || defined(CHIP_FAMILY_STM32L4) - /* Make sure we are going to be outputting it properly when the DMA - * ends due to the TX FIFO bug on the F0. See crosbug.com/p/31390 - */ - ((uint8_t *)pkt->response)[pkt->response_size + 1] = EC_SPI_PAST_END; - ((uint8_t *)pkt->response)[pkt->response_size + 2] = EC_SPI_PAST_END; - ((uint8_t *)pkt->response)[pkt->response_size + 3] = EC_SPI_PAST_END; -#endif - - /* Transmit the reply */ - txdma = dma_get_channel(STM32_DMAC_SPI1_TX); - dma_prepare_tx(&dma_tx_option, sizeof(out_preamble) + pkt->response_size - + EC_SPI_PAST_END_LENGTH, out_msg); - dma_go(txdma); -#ifdef CHIP_FAMILY_STM32H7 - /* clear any previous underrun */ - STM32_SPI1_REGS->ifcr = STM32_SPI_SR_UDR; -#endif /* CHIP_FAMILY_STM32H7 */ - - /* - * Before the state is set to SENDING, any CS de-assertion would - * set setup_transaction_later to 1. - */ - state = SPI_STATE_SENDING; - check_setup_transaction_later(); -} - -/** - * Handle an event on the NSS pin - * - * A falling edge of NSS indicates that the master is starting a new - * transaction. A rising edge indicates that we have finished. - * - * @param signal GPIO signal for the NSS pin - */ -void spi_event(enum gpio_signal signal) -{ - dma_chan_t *rxdma; - uint16_t i; - - /* If not enabled, ignore glitches on NSS */ - if (!enabled) - return; - - /* Check chip select. If it's high, the AP ended a transaction. */ - if (gpio_get_level(GPIO_SPI1_NSS)) { - enable_sleep(SLEEP_MASK_SPI); - - /* - * If the buffer is still used by the host command, postpone - * the DMA rx setup. - */ - if (state == SPI_STATE_PROCESSING) { - setup_transaction_later = 1; - return; - } - - /* Set up for the next transaction */ - spi_init(); /* Fix for bug chrome-os-partner:31390 */ - return; - } - disable_sleep(SLEEP_MASK_SPI); - - /* Chip select is low = asserted */ - if (state != SPI_STATE_READY_TO_RX) { - /* - * AP started a transaction but we weren't ready for it. - * Tell AP we weren't ready, and ignore the received data. - */ - CPRINTS("SPI not ready"); - tx_status(EC_SPI_NOT_READY); - state = SPI_STATE_RX_BAD; - return; - } - - /* We're now inside a transaction */ - state = SPI_STATE_RECEIVING; - tx_status(EC_SPI_RECEIVING); - rxdma = dma_get_channel(STM32_DMAC_SPI1_RX); - - /* Wait for version, command, length bytes */ - if (wait_for_bytes(rxdma, 3, GPIO_SPI1_NSS)) - goto spi_event_error; - - if (in_msg[0] == EC_HOST_REQUEST_VERSION) { - /* Protocol version 3 */ - struct ec_host_request *r = (struct ec_host_request *)in_msg; - int pkt_size; - - /* Wait for the rest of the command header */ - if (wait_for_bytes(rxdma, sizeof(*r), GPIO_SPI1_NSS)) - goto spi_event_error; - - /* - * Check how big the packet should be. We can't just wait to - * see how much data the host sends, because it will keep - * sending extra data until we respond. - */ - pkt_size = host_request_expected_size(r); - if (pkt_size == 0 || pkt_size > sizeof(in_msg)) - goto spi_event_error; - - /* Wait for the packet data */ - if (wait_for_bytes(rxdma, pkt_size, GPIO_SPI1_NSS)) - goto spi_event_error; - - spi_packet.send_response = spi_send_response_packet; - - spi_packet.request = in_msg; - spi_packet.request_temp = NULL; - spi_packet.request_max = sizeof(in_msg); - spi_packet.request_size = pkt_size; - - /* Response must start with the preamble */ - memcpy(out_msg, out_preamble, sizeof(out_preamble)); - spi_packet.response = out_msg + sizeof(out_preamble); - /* Reserve space for the preamble and trailing past-end byte */ - spi_packet.response_max = sizeof(out_msg) - - sizeof(out_preamble) - EC_SPI_PAST_END_LENGTH; - spi_packet.response_size = 0; - - spi_packet.driver_result = EC_RES_SUCCESS; - - /* Move to processing state */ - state = SPI_STATE_PROCESSING; - tx_status(EC_SPI_PROCESSING); - - host_packet_receive(&spi_packet); - return; - - } else if (in_msg[0] >= EC_CMD_VERSION0) { -#ifdef CONFIG_SPI_PROTOCOL_V2 - /* - * Protocol version 2 - * - * TODO(crosbug.com/p/20257): Remove once kernel supports - * version 3. - */ - -#ifdef CHIP_FAMILY_STM32F0 - CPRINTS("WARNING: Protocol version 2 is not supported on the F0" - " line due to crosbug.com/p/31390"); -#endif - - args.version = in_msg[0] - EC_CMD_VERSION0; - args.command = in_msg[1]; - args.params_size = in_msg[2]; - - /* Wait for parameters */ - if (wait_for_bytes(rxdma, 3 + args.params_size, GPIO_SPI1_NSS)) - goto spi_event_error; - - /* - * Params are not 32-bit aligned in protocol version 2. As a - * workaround, move them to the beginning of the input buffer - * so they are aligned. - */ - if (args.params_size) - memmove(in_msg, in_msg + 3, args.params_size); - - args.params = in_msg; - args.send_response = spi_send_response; - - /* Allow room for the header bytes */ - args.response = out_msg + SPI_PROTO2_OFFSET; - args.response_max = sizeof(out_msg) - SPI_PROTO2_OVERHEAD; - args.response_size = 0; - args.result = EC_RES_SUCCESS; - - /* Move to processing state */ - state = SPI_STATE_PROCESSING; - tx_status(EC_SPI_PROCESSING); - - host_command_received(&args); - return; -#else /* !defined(CONFIG_SPI_PROTOCOL_V2) */ - /* Protocol version 2 is deprecated. */ - CPRINTS("ERROR: Protocol V2 is not supported!"); -#endif /* defined(CONFIG_SPI_PROTOCOL_V2) */ - } - - spi_event_error: - /* Error, timeout, or protocol we can't handle. Ignore data. */ - tx_status(EC_SPI_RX_BAD_DATA); - state = SPI_STATE_RX_BAD; - CPRINTS("SPI rx bad data"); - - CPRINTF("in_msg=["); - for (i = 0; i < dma_bytes_done(rxdma, sizeof(in_msg)); i++) - CPRINTF("%02x ", in_msg[i]); - CPRINTF("]\n"); -} - -static void spi_chipset_startup(void) -{ - /* Enable pullup and interrupts on NSS */ - gpio_set_flags(GPIO_SPI1_NSS, GPIO_INT_BOTH | GPIO_PULL_UP); - - /* Set SPI pins to alternate function */ - gpio_config_module(MODULE_SPI, 1); - - /* Set up for next transaction */ - setup_for_transaction(); - - enabled = 1; -} -#ifdef CONFIG_CHIPSET_RESUME_INIT_HOOK -DECLARE_HOOK(HOOK_CHIPSET_RESUME_INIT, spi_chipset_startup, HOOK_PRIO_DEFAULT); -#else -DECLARE_HOOK(HOOK_CHIPSET_RESUME, spi_chipset_startup, HOOK_PRIO_DEFAULT); -#endif - -static void spi_chipset_shutdown(void) -{ - enabled = 0; - state = SPI_STATE_DISABLED; - - /* Disable pullup and interrupts on NSS */ - gpio_set_flags(GPIO_SPI1_NSS, GPIO_INPUT); - - /* Set SPI pins to inputs so we don't leak power when AP is off */ - gpio_config_module(MODULE_SPI, 0); - - /* Allow deep sleep when AP off */ - enable_sleep(SLEEP_MASK_SPI); -} -#ifdef CONFIG_CHIPSET_RESUME_INIT_HOOK -DECLARE_HOOK(HOOK_CHIPSET_SUSPEND_COMPLETE, spi_chipset_shutdown, - HOOK_PRIO_DEFAULT); -#else -DECLARE_HOOK(HOOK_CHIPSET_SUSPEND, spi_chipset_shutdown, HOOK_PRIO_DEFAULT); -#endif - -static void spi_init(void) -{ - stm32_spi_regs_t *spi = STM32_SPI1_REGS; - uint8_t was_enabled = enabled; - - /* Reset the SPI Peripheral to clear any existing weird states. */ - /* Fix for bug chrome-os-partner:31390 */ - enabled = 0; - state = SPI_STATE_DISABLED; - STM32_RCC_APB2RSTR |= STM32_RCC_PB2_SPI1; - STM32_RCC_APB2RSTR &= ~STM32_RCC_PB2_SPI1; - - /* 40 MHz pin speed */ - STM32_GPIO_OSPEEDR(GPIO_A) |= 0xff00; - - /* Enable clocks to SPI1 module */ - STM32_RCC_APB2ENR |= STM32_RCC_PB2_SPI1; - - /* Delay 1 APB clock cycle after the clock is enabled */ - clock_wait_bus_cycles(BUS_APB, 1); - - /* - * Select the right DMA request for the variants using it. - * This is not required for STM32F4 since the channel (aka request) is - * set directly in the respective dma_option. In fact, it would be - * overridden in dma-stm32f4::prepare_stream(). - */ -#ifdef CHIP_FAMILY_STM32L4 - dma_select_channel(STM32_DMAC_SPI1_TX, 1); - dma_select_channel(STM32_DMAC_SPI1_RX, 1); -#elif defined(CHIP_FAMILY_STM32H7) - dma_select_channel(STM32_DMAC_SPI1_TX, DMAMUX1_REQ_SPI1_TX); - dma_select_channel(STM32_DMAC_SPI1_RX, DMAMUX1_REQ_SPI1_RX); -#endif - /* - * Enable rx/tx DMA and get ready to receive our first transaction and - * "disable" FIFO by setting event to happen after only 1 byte - */ -#ifdef CHIP_FAMILY_STM32H7 - spi->cfg2 = 0; - spi->cfg1 = STM32_SPI_CFG1_DATASIZE(8) | STM32_SPI_CFG1_FTHLV(4) | - STM32_SPI_CFG1_CRCSIZE(8) | - STM32_SPI_CFG1_TXDMAEN | STM32_SPI_CFG1_RXDMAEN | - STM32_SPI_CFG1_UDRCFG_CONST | - STM32_SPI_CFG1_UDRDET_BEGIN_FRM; - spi->cr1 = 0; -#else /* !CHIP_FAMILY_STM32H7 */ - spi->cr2 = STM32_SPI_CR2_RXDMAEN | STM32_SPI_CR2_TXDMAEN | - STM32_SPI_CR2_FRXTH | STM32_SPI_CR2_DATASIZE(8); - - /* Enable the SPI peripheral */ - spi->cr1 |= STM32_SPI_CR1_SPE; -#endif /* !CHIP_FAMILY_STM32H7 */ - - gpio_enable_interrupt(GPIO_SPI1_NSS); - - /* - * If we were already enabled or chipset is already on, - * prepare for transaction - */ - if (was_enabled || chipset_in_state(CHIPSET_STATE_ON)) - spi_chipset_startup(); -} -DECLARE_HOOK(HOOK_INIT, spi_init, HOOK_PRIO_INIT_SPI); - -/** - * Get protocol information - */ -enum ec_status spi_get_protocol_info(struct host_cmd_handler_args *args) -{ - struct ec_response_get_protocol_info *r = args->response; - - memset(r, 0, sizeof(*r)); -#ifdef CONFIG_SPI_PROTOCOL_V2 - r->protocol_versions |= BIT(2); -#endif - r->protocol_versions |= BIT(3); - r->max_request_packet_size = SPI_MAX_REQUEST_SIZE; - r->max_response_packet_size = SPI_MAX_RESPONSE_SIZE; - r->flags = EC_PROTOCOL_INFO_IN_PROGRESS_SUPPORTED; - - args->response_size = sizeof(*r); - - return EC_RES_SUCCESS; -} |