/* * IMG SPFI controller driver * * Copyright (C) 2007,2008,2013 Imagination Technologies Ltd. * Copyright (C) 2014 Google, Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, * version 2, as published by the Free Software Foundation. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define SPFI_DEVICE_PARAMETER(x) (0x00 + 0x4 * (x)) #define SPFI_DEVICE_PARAMETER_BITCLK_SHIFT 24 #define SPFI_DEVICE_PARAMETER_BITCLK_MASK 0xff #define SPFI_DEVICE_PARAMETER_CSSETUP_SHIFT 16 #define SPFI_DEVICE_PARAMETER_CSSETUP_MASK 0xff #define SPFI_DEVICE_PARAMETER_CSHOLD_SHIFT 8 #define SPFI_DEVICE_PARAMETER_CSHOLD_MASK 0xff #define SPFI_DEVICE_PARAMETER_CSDELAY_SHIFT 0 #define SPFI_DEVICE_PARAMETER_CSDELAY_MASK 0xff #define SPFI_CONTROL 0x14 #define SPFI_CONTROL_CONTINUE BIT(12) #define SPFI_CONTROL_SOFT_RESET BIT(11) #define SPFI_CONTROL_SEND_DMA BIT(10) #define SPFI_CONTROL_GET_DMA BIT(9) #define SPFI_CONTROL_SE BIT(8) #define SPFI_CONTROL_TMODE_SHIFT 5 #define SPFI_CONTROL_TMODE_MASK 0x7 #define SPFI_CONTROL_TMODE_SINGLE 0 #define SPFI_CONTROL_TMODE_DUAL 1 #define SPFI_CONTROL_TMODE_QUAD 2 #define SPFI_CONTROL_SPFI_EN BIT(0) #define SPFI_TRANSACTION 0x18 #define SPFI_TRANSACTION_TSIZE_SHIFT 16 #define SPFI_TRANSACTION_TSIZE_MASK 0xffff #define SPFI_PORT_STATE 0x1c #define SPFI_PORT_STATE_DEV_SEL_SHIFT 20 #define SPFI_PORT_STATE_DEV_SEL_MASK 0x7 #define SPFI_PORT_STATE_CK_POL(x) BIT(19 - (x)) #define SPFI_PORT_STATE_CK_PHASE(x) BIT(14 - (x)) #define SPFI_TX_32BIT_VALID_DATA 0x20 #define SPFI_TX_8BIT_VALID_DATA 0x24 #define SPFI_RX_32BIT_VALID_DATA 0x28 #define SPFI_RX_8BIT_VALID_DATA 0x2c #define SPFI_INTERRUPT_STATUS 0x30 #define SPFI_INTERRUPT_ENABLE 0x34 #define SPFI_INTERRUPT_CLEAR 0x38 #define SPFI_INTERRUPT_IACCESS BIT(12) #define SPFI_INTERRUPT_GDEX8BIT BIT(11) #define SPFI_INTERRUPT_ALLDONETRIG BIT(9) #define SPFI_INTERRUPT_GDFUL BIT(8) #define SPFI_INTERRUPT_GDHF BIT(7) #define SPFI_INTERRUPT_GDEX32BIT BIT(6) #define SPFI_INTERRUPT_GDTRIG BIT(5) #define SPFI_INTERRUPT_SDFUL BIT(3) #define SPFI_INTERRUPT_SDHF BIT(2) #define SPFI_INTERRUPT_SDE BIT(1) #define SPFI_INTERRUPT_SDTRIG BIT(0) /* * There are four parallel FIFOs of 16 bytes each. The word buffer * (*_32BIT_VALID_DATA) accesses all four FIFOs at once, resulting in an * effective FIFO size of 64 bytes. The byte buffer (*_8BIT_VALID_DATA) * accesses only a single FIFO, resulting in an effective FIFO size of * 16 bytes. */ #define SPFI_32BIT_FIFO_SIZE 64 #define SPFI_8BIT_FIFO_SIZE 16 struct img_spfi { struct device *dev; struct spi_master *master; spinlock_t lock; void __iomem *regs; phys_addr_t phys; int irq; struct clk *spfi_clk; struct clk *sys_clk; struct dma_chan *rx_ch; struct dma_chan *tx_ch; bool tx_dma_busy; bool rx_dma_busy; }; struct img_spfi_device_data { bool gpio_requested; }; static inline u32 spfi_readl(struct img_spfi *spfi, u32 reg) { return readl(spfi->regs + reg); } static inline void spfi_writel(struct img_spfi *spfi, u32 val, u32 reg) { writel(val, spfi->regs + reg); } static inline void spfi_start(struct img_spfi *spfi) { u32 val; val = spfi_readl(spfi, SPFI_CONTROL); val |= SPFI_CONTROL_SPFI_EN; spfi_writel(spfi, val, SPFI_CONTROL); } static inline void spfi_reset(struct img_spfi *spfi) { spfi_writel(spfi, SPFI_CONTROL_SOFT_RESET, SPFI_CONTROL); spfi_writel(spfi, 0, SPFI_CONTROL); } static int spfi_wait_all_done(struct img_spfi *spfi) { unsigned long timeout = jiffies + msecs_to_jiffies(50); while (time_before(jiffies, timeout)) { u32 status = spfi_readl(spfi, SPFI_INTERRUPT_STATUS); if (status & SPFI_INTERRUPT_ALLDONETRIG) { spfi_writel(spfi, SPFI_INTERRUPT_ALLDONETRIG, SPFI_INTERRUPT_CLEAR); return 0; } cpu_relax(); } dev_err(spfi->dev, "Timed out waiting for transaction to complete\n"); spfi_reset(spfi); return -ETIMEDOUT; } static unsigned int spfi_pio_write32(struct img_spfi *spfi, const u32 *buf, unsigned int max) { unsigned int count = 0; u32 status; while (count < max / 4) { spfi_writel(spfi, SPFI_INTERRUPT_SDFUL, SPFI_INTERRUPT_CLEAR); status = spfi_readl(spfi, SPFI_INTERRUPT_STATUS); if (status & SPFI_INTERRUPT_SDFUL) break; spfi_writel(spfi, buf[count], SPFI_TX_32BIT_VALID_DATA); count++; } return count * 4; } static unsigned int spfi_pio_write8(struct img_spfi *spfi, const u8 *buf, unsigned int max) { unsigned int count = 0; u32 status; while (count < max) { spfi_writel(spfi, SPFI_INTERRUPT_SDFUL, SPFI_INTERRUPT_CLEAR); status = spfi_readl(spfi, SPFI_INTERRUPT_STATUS); if (status & SPFI_INTERRUPT_SDFUL) break; spfi_writel(spfi, buf[count], SPFI_TX_8BIT_VALID_DATA); count++; } return count; } static unsigned int spfi_pio_read32(struct img_spfi *spfi, u32 *buf, unsigned int max) { unsigned int count = 0; u32 status; while (count < max / 4) { spfi_writel(spfi, SPFI_INTERRUPT_GDEX32BIT, SPFI_INT
heat_template_version: 2015-10-15

description: >
  Returns an IP from a network mapped list of IPs This version is for IPv6
  addresses. The ip_address_uri output will have brackets for use in URLs.

parameters:
  StorageMgmtNetName:
    description: Name of the storage MGMT network
    default: storage_mgmt
    type: string
  PortName:
    description: Name of the port
    default: ''
    type: string
  ControlPlaneIP: # Here for compatability with noop.yaml
    description: IP address on the control plane
    default: ''
    type: string
  IPPool:
    default: {}
    description: A network mapped list of IPs
    type: json
  NodeIndex:
    default: 0
    description: Index of the IP to get from Pool
    type: number
  StorageMgmtNetCidr:
    default: 'fd00:fd00:fd00:4000::/64'
    description: Cidr for the storage MGMT network.
    type: string

outputs:
  ip_address:
    description: storage MGMT network IP
    value: {get_param: [IPPool, {get_param: StorageMgmtNetName}, {get_param: NodeIndex}]}
  ip_address_uri:
    description: storage MGMT network IP (for compatibility with storage_mgmt_v6.yaml)
    value:
          list_join:
          - ''
          - - '['
            - {get_param: [IPPool, {get_param: StorageMgmtNetName}, {get_param: NodeIndex}]}
            - ']'
  ip_subnet:
    description: IP/Subnet CIDR for the storage MGMT network IP
    value:
      list_join:
      - ''
      - - {get_param: [IPPool, {get_param: StorageMgmtNetName}, {get_param: NodeIndex}]}
        - '