/** * struct amd_spi_freq - Matches device speed with values to write in regs * @speed_hz: Device frequency * @enable_val: Value to be written to "enable register" * @spd7_val: Some frequencies requires to have a value written at SPISPEED register
*/ struct amd_spi_freq {
u32 speed_hz;
u32 enable_val;
u32 spd7_val;
};
fin_msg: switch (amd_spi->version) { case AMD_SPI_V1: break; case AMD_SPI_V2: case AMD_HID2_SPI:
amd_spi_clear_chip(amd_spi, spi_get_chipselect(message->spi, 0)); break; default: return -ENODEV;
}
spi_finalize_current_message(host);
return message->status;
}
staticinlinebool amd_is_spi_read_cmd_4b(const u16 op)
{ switch (op) { case AMD_SPI_OP_READ_FAST_4B: case AMD_SPI_OP_READ_1_1_2_4B: case AMD_SPI_OP_READ_1_2_2_4B: case AMD_SPI_OP_READ_1_1_4_4B: case AMD_SPI_OP_READ_1_4_4_4B: returntrue; default: returnfalse;
}
}
staticinlinebool amd_is_spi_read_cmd(const u16 op)
{ switch (op) { case AMD_SPI_OP_READ: case AMD_SPI_OP_READ_FAST: case AMD_SPI_OP_READ_1_1_2: case AMD_SPI_OP_READ_1_2_2: case AMD_SPI_OP_READ_1_1_4: case AMD_SPI_OP_READ_1_4_4: returntrue; default: return amd_is_spi_read_cmd_4b(op);
}
}
staticinlinebool amd_is_spi_write_cmd(const u16 op)
{ switch (op) { case AMD_SPI_OP_PP: case AMD_SPI_OP_PP_RANDOM: returntrue; default: returnfalse;
}
}
/* bus width is number of IO lines used to transmit */ if (op->cmd.buswidth > 1 || op->addr.buswidth > 4) returnfalse;
/* AMD SPI controllers support quad mode only for read operations */ if (amd_is_spi_read_cmd(op->cmd.opcode) || amd_is_spi_write_cmd(op->cmd.opcode)) { if (op->data.buswidth > 4) returnfalse;
/* * HID2 SPI controller supports DMA read up to 4K bytes and * doesn't support 4-byte address commands.
*/ if (amd_spi->version == AMD_HID2_SPI) { if ((amd_is_spi_read_cmd_4b(op->cmd.opcode) ||
amd_is_spi_write_cmd(op->cmd.opcode)) &&
op->data.nbytes > AMD_SPI_HID2_DMA_SIZE) returnfalse;
} elseif (op->data.nbytes > AMD_SPI_MAX_DATA) { returnfalse;
}
} elseif (op->data.buswidth > 1 || op->data.nbytes > AMD_SPI_MAX_DATA) { returnfalse;
}
if (op->max_freq < mem->spi->controller->min_speed_hz) returnfalse;
/* * HID2 SPI controller DMA read mode supports reading up to 4k * bytes in single transaction, where as SPI0 and HID2 SPI * controller index mode supports maximum of 64 bytes in a single * transaction.
*/ if (amd_spi->version == AMD_HID2_SPI && (amd_is_spi_read_cmd(op->cmd.opcode) ||
amd_is_spi_write_cmd(op->cmd.opcode)))
op->data.nbytes = clamp_val(op->data.nbytes, 0, AMD_SPI_HID2_DMA_SIZE); else
op->data.nbytes = clamp_val(op->data.nbytes, 0, AMD_SPI_MAX_DATA);
/* Program max write length in hid2_write_control1 register */
hid_regval = amd_spi_readreg32(amd_spi, AMD_SPI_HID2_WRITE_CNTRL1);
hid_regval = (hid_regval & ~GENMASK(15, 0)) | ((op->data.nbytes) + 3);
amd_spi_writereg32(amd_spi, AMD_SPI_HID2_WRITE_CNTRL1, hid_regval);
/* Set cmd start bit in hid2_cmd_start register to trigger HID basic write operation */
hid_cmd_start = amd_spi_readreg16(amd_spi, AMD_SPI_HID2_CMD_START);
amd_spi_writereg16(amd_spi, AMD_SPI_HID2_CMD_START, (hid_cmd_start | BIT(2)));
/* Check interrupt status of HIDDMA basic write operation in hid2_int_status register */
readw_poll_timeout(amd_spi->io_remap_addr + AMD_SPI_HID2_INT_STATUS, val,
(val & BIT(2)), AMD_SPI_IO_SLEEP_US, AMD_SPI_IO_TIMEOUT_US);
/* Clear the interrupts by writing to hid2_int_status register */
val = amd_spi_readreg16(amd_spi, AMD_SPI_HID2_INT_STATUS);
amd_spi_writereg16(amd_spi, AMD_SPI_HID2_INT_STATUS, val);
}
/* Set the opcode in hid2_read_control0 register */
hid_regval = amd_spi_readreg32(amd_spi, AMD_SPI_HID2_READ_CNTRL0);
hid_regval = (hid_regval & ~GENMASK(7, 0)) | op->cmd.opcode;
/* * Program the address in the hid2_read_control0 register [8:31]. The address should * be written starting from the 8th bit of the register, requiring an 8-bit shift. * Additionally, to convert a 2-byte spinand address to a 3-byte address, another * 8-bit shift is needed. Therefore, a total shift of 16 bits is required.
*/
hid_regval = (hid_regval & ~GENMASK(31, 8)) | (op->addr.val << 16);
amd_spi_writereg32(amd_spi, AMD_SPI_HID2_READ_CNTRL0, hid_regval);
/* Configure dummy clock cycles for fast read, dual, quad I/O commands */
hid_regval = amd_spi_readreg32(amd_spi, AMD_SPI_HID2_READ_CNTRL2); /* Fast read dummy cycle */
hid_regval &= ~GENMASK(4, 0);
/* Set no of preamble bytecount */
hid_regval &= ~GENMASK(27, 24);
amd_spi_writereg32(amd_spi, AMD_SPI_HID2_READ_CNTRL2, hid_regval);
/* * Program the HID2 Input Ring Buffer0. 4k aligned buf_memory_addr[31:12], * buf_size[4:0], end_input_ring[5].
*/
hid_regval = amd_spi->phy_dma_buf | BIT(5) | BIT(0);
amd_spi_writereg32(amd_spi, AMD_SPI_HID2_INPUT_RING_BUF0, hid_regval);
/* Program max read length(no of DWs) in hid2_read_control1 register */
hid_regval = amd_spi_readreg32(amd_spi, AMD_SPI_HID2_READ_CNTRL1);
hid_regval = (hid_regval & ~GENMASK(15, 0)) | ((op->data.nbytes / 4) - 1);
amd_spi_writereg32(amd_spi, AMD_SPI_HID2_READ_CNTRL1, hid_regval);
/* Set cmd start bit in hid2_cmd_start register to trigger HID basic read operation */
hid_cmd_start = amd_spi_readreg16(amd_spi, AMD_SPI_HID2_CMD_START);
amd_spi_writereg16(amd_spi, AMD_SPI_HID2_CMD_START, (hid_cmd_start | BIT(3)));
/* Check interrupt status of HIDDMA basic read operation in hid2_int_status register */
readw_poll_timeout(amd_spi->io_remap_addr + AMD_SPI_HID2_INT_STATUS, val,
(val & BIT(3)), AMD_SPI_IO_SLEEP_US, AMD_SPI_IO_TIMEOUT_US);
/* Clear the interrupts by writing to hid2_int_status register */
val = amd_spi_readreg16(amd_spi, AMD_SPI_HID2_INT_STATUS);
amd_spi_writereg16(amd_spi, AMD_SPI_HID2_INT_STATUS, val);
}
/* * Condition for using HID read mode. Only for reading complete page data, use HID read. * Use index mode otherwise.
*/ if (amd_spi->version == AMD_HID2_SPI && amd_is_spi_read_cmd(op->cmd.opcode)) {
u64 *dma_buf64 = (u64 *)amd_spi->dma_virt_addr;
u8 *dma_buf;
amd_spi_hiddma_read(amd_spi, op);
/* Copy data from DMA buffer */ while (left_data >= 8) {
*buf_64++ = *dma_buf64++;
left_data -= 8;
}
if (amd_is_spi_read_cmd_4b(op->cmd.opcode))
amd_spi_writereg32(amd_spi, AMD_SPI_ADDR32CTRL_REG, val | BIT(0)); else
amd_spi_writereg32(amd_spi, AMD_SPI_ADDR32CTRL_REG, val & ~BIT(0));
}
/* Allocate DMA buffer to use for HID basic read and write operations. For write * operations, the DMA buffer should include the opcode, address bytes and dummy * bytes(if any) in addition to the data bytes. Additionally, the hardware requires * that the buffer address be 4K aligned. So, allocate DMA buffer of size * 2 * AMD_SPI_HID2_DMA_SIZE.
*/
amd_spi->dma_virt_addr = dmam_alloc_coherent(dev, AMD_SPI_HID2_DMA_SIZE * 2,
&amd_spi->phy_dma_buf, GFP_KERNEL); if (!amd_spi->dma_virt_addr) return -ENOMEM;
/* * Enable interrupts and set mask bits in hid2_int_mask register to generate interrupt * properly for HIDDMA basic read and write operations.
*/
hid_regval = amd_spi_readreg32(amd_spi, AMD_SPI_HID2_INT_MASK);
hid_regval = (hid_regval & GENMASK(31, 8)) | BIT(18) | BIT(19);
amd_spi_writereg32(amd_spi, AMD_SPI_HID2_INT_MASK, hid_regval);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.