109109 * @rxbuf: Pointer to the RX buffer
110110 * @tx_bytes: Number of bytes left to transfer
111111 * @rx_bytes: Number of bytes requested
112+ * @n_bytes: Number of bytes per word
112113 * @dev_busy: Device busy flag
113114 * @is_decoded_cs: Flag for decoder property set or not
114115 * @tx_fifo_depth: Depth of the TX FIFO
@@ -120,16 +121,24 @@ struct cdns_spi {
120121 struct clk * pclk ;
121122 unsigned int clk_rate ;
122123 u32 speed_hz ;
123- const u8 * txbuf ;
124- u8 * rxbuf ;
124+ const void * txbuf ;
125+ void * rxbuf ;
125126 int tx_bytes ;
126127 int rx_bytes ;
128+ u8 n_bytes ;
127129 u8 dev_busy ;
128130 u32 is_decoded_cs ;
129131 unsigned int tx_fifo_depth ;
130132 struct reset_control * rstc ;
131133};
132134
135+ enum cdns_spi_frame_n_bytes {
136+ CDNS_SPI_N_BYTES_NULL = 0 ,
137+ CDNS_SPI_N_BYTES_U8 = 1 ,
138+ CDNS_SPI_N_BYTES_U16 = 2 ,
139+ CDNS_SPI_N_BYTES_U32 = 4
140+ };
141+
133142/* Macros for the SPI controller read/write */
134143static inline u32 cdns_spi_read (struct cdns_spi * xspi , u32 offset )
135144{
@@ -305,6 +314,78 @@ static int cdns_spi_setup_transfer(struct spi_device *spi,
305314 return 0 ;
306315}
307316
317+ static u8 cdns_spi_n_bytes (struct spi_transfer * transfer )
318+ {
319+ if (transfer -> bits_per_word <= 8 )
320+ return CDNS_SPI_N_BYTES_U8 ;
321+ else if (transfer -> bits_per_word <= 16 )
322+ return CDNS_SPI_N_BYTES_U16 ;
323+ else
324+ return CDNS_SPI_N_BYTES_U32 ;
325+ }
326+
327+ static inline void cdns_spi_reader (struct cdns_spi * xspi )
328+ {
329+ u32 rxw = 0 ;
330+
331+ if (xspi -> rxbuf && !IS_ALIGNED ((uintptr_t )xspi -> rxbuf , xspi -> n_bytes )) {
332+ pr_err ("%s: rxbuf address is not aligned for %d bytes\n" ,
333+ __func__ , xspi -> n_bytes );
334+ return ;
335+ }
336+
337+ rxw = cdns_spi_read (xspi , CDNS_SPI_RXD );
338+ if (xspi -> rxbuf ) {
339+ switch (xspi -> n_bytes ) {
340+ case CDNS_SPI_N_BYTES_U8 :
341+ * (u8 * )xspi -> rxbuf = rxw ;
342+ break ;
343+ case CDNS_SPI_N_BYTES_U16 :
344+ * (u16 * )xspi -> rxbuf = rxw ;
345+ break ;
346+ case CDNS_SPI_N_BYTES_U32 :
347+ * (u32 * )xspi -> rxbuf = rxw ;
348+ break ;
349+ default :
350+ pr_err ("%s invalid n_bytes %d\n" , __func__ ,
351+ xspi -> n_bytes );
352+ return ;
353+ }
354+ xspi -> rxbuf = (u8 * )xspi -> rxbuf + xspi -> n_bytes ;
355+ }
356+ }
357+
358+ static inline void cdns_spi_writer (struct cdns_spi * xspi )
359+ {
360+ u32 txw = 0 ;
361+
362+ if (xspi -> txbuf && !IS_ALIGNED ((uintptr_t )xspi -> txbuf , xspi -> n_bytes )) {
363+ pr_err ("%s: txbuf address is not aligned for %d bytes\n" ,
364+ __func__ , xspi -> n_bytes );
365+ return ;
366+ }
367+
368+ if (xspi -> txbuf ) {
369+ switch (xspi -> n_bytes ) {
370+ case CDNS_SPI_N_BYTES_U8 :
371+ txw = * (u8 * )xspi -> txbuf ;
372+ break ;
373+ case CDNS_SPI_N_BYTES_U16 :
374+ txw = * (u16 * )xspi -> txbuf ;
375+ break ;
376+ case CDNS_SPI_N_BYTES_U32 :
377+ txw = * (u32 * )xspi -> txbuf ;
378+ break ;
379+ default :
380+ pr_err ("%s invalid n_bytes %d\n" , __func__ ,
381+ xspi -> n_bytes );
382+ return ;
383+ }
384+ cdns_spi_write (xspi , CDNS_SPI_TXD , txw );
385+ xspi -> txbuf = (u8 * )xspi -> txbuf + xspi -> n_bytes ;
386+ }
387+ }
388+
308389/**
309390 * cdns_spi_process_fifo - Fills the TX FIFO, and drain the RX FIFO
310391 * @xspi: Pointer to the cdns_spi structure
@@ -321,23 +402,14 @@ static void cdns_spi_process_fifo(struct cdns_spi *xspi, int ntx, int nrx)
321402
322403 while (ntx || nrx ) {
323404 if (nrx ) {
324- u8 data = cdns_spi_read (xspi , CDNS_SPI_RXD );
325-
326- if (xspi -> rxbuf )
327- * xspi -> rxbuf ++ = data ;
328-
405+ cdns_spi_reader (xspi );
329406 nrx -- ;
330407 }
331408
332409 if (ntx ) {
333- if (xspi -> txbuf )
334- cdns_spi_write (xspi , CDNS_SPI_TXD , * xspi -> txbuf ++ );
335- else
336- cdns_spi_write (xspi , CDNS_SPI_TXD , 0 );
337-
410+ cdns_spi_writer (xspi );
338411 ntx -- ;
339412 }
340-
341413 }
342414}
343415
@@ -454,6 +526,10 @@ static int cdns_transfer_one(struct spi_controller *ctlr,
454526 if (cdns_spi_read (xspi , CDNS_SPI_ISR ) & CDNS_SPI_IXR_TXFULL )
455527 udelay (10 );
456528
529+ xspi -> n_bytes = cdns_spi_n_bytes (transfer );
530+ xspi -> tx_bytes = DIV_ROUND_UP (xspi -> tx_bytes , xspi -> n_bytes );
531+ xspi -> rx_bytes = DIV_ROUND_UP (xspi -> rx_bytes , xspi -> n_bytes );
532+
457533 cdns_spi_process_fifo (xspi , xspi -> tx_fifo_depth , 0 );
458534
459535 cdns_spi_write (xspi , CDNS_SPI_IER , CDNS_SPI_IXR_DEFAULT );
@@ -654,6 +730,9 @@ static int cdns_spi_probe(struct platform_device *pdev)
654730 ctlr -> mode_bits = SPI_CPOL | SPI_CPHA ;
655731 ctlr -> bits_per_word_mask = SPI_BPW_MASK (8 );
656732
733+ if (of_device_is_compatible (pdev -> dev .of_node , "cix,sky1-spi-r1p6" ))
734+ ctlr -> bits_per_word_mask |= SPI_BPW_MASK (16 ) | SPI_BPW_MASK (32 );
735+
657736 if (!spi_controller_is_target (ctlr )) {
658737 ctlr -> mode_bits |= SPI_CS_HIGH ;
659738 ctlr -> set_cs = cdns_spi_chipselect ;
@@ -797,6 +876,7 @@ static const struct dev_pm_ops cdns_spi_dev_pm_ops = {
797876
798877static const struct of_device_id cdns_spi_of_match [] = {
799878 { .compatible = "xlnx,zynq-spi-r1p6" },
879+ { .compatible = "cix,sky1-spi-r1p6" },
800880 { .compatible = "cdns,spi-r1p6" },
801881 { /* end of table */ }
802882};
0 commit comments