4848/* CEx Address Decoding Range Register */
4949#define CE0_SEGMENT_ADDR_REG 0x30
5050
51+ #define FULL_DUPLEX_RX_DATA 0x1e4
52+
5153/* CEx Read timing compensation register */
5254#define CE0_TIMING_COMPENSATION_REG 0x94
5355
@@ -81,6 +83,7 @@ struct aspeed_spi_data {
8183 u32 hclk_mask ;
8284 u32 hdiv_max ;
8385 u32 min_window_size ;
86+ bool full_duplex ;
8487
8588 phys_addr_t (* segment_start )(struct aspeed_spi * aspi , u32 reg );
8689 phys_addr_t (* segment_end )(struct aspeed_spi * aspi , u32 reg );
@@ -105,6 +108,7 @@ struct aspeed_spi {
105108
106109 struct clk * clk ;
107110 u32 clk_freq ;
111+ u8 cs_change ;
108112
109113 struct aspeed_spi_chip chips [ASPEED_SPI_MAX_NUM_CS ];
110114};
@@ -280,7 +284,8 @@ static ssize_t aspeed_spi_write_user(struct aspeed_spi_chip *chip,
280284}
281285
282286/* support for 1-1-1, 1-1-2 or 1-1-4 */
283- static bool aspeed_spi_supports_op (struct spi_mem * mem , const struct spi_mem_op * op )
287+ static bool aspeed_spi_supports_mem_op (struct spi_mem * mem ,
288+ const struct spi_mem_op * op )
284289{
285290 if (op -> cmd .buswidth > 1 )
286291 return false;
@@ -305,7 +310,8 @@ static bool aspeed_spi_supports_op(struct spi_mem *mem, const struct spi_mem_op
305310
306311static const struct aspeed_spi_data ast2400_spi_data ;
307312
308- static int do_aspeed_spi_exec_op (struct spi_mem * mem , const struct spi_mem_op * op )
313+ static int do_aspeed_spi_exec_mem_op (struct spi_mem * mem ,
314+ const struct spi_mem_op * op )
309315{
310316 struct aspeed_spi * aspi = spi_controller_get_devdata (mem -> spi -> controller );
311317 struct aspeed_spi_chip * chip = & aspi -> chips [spi_get_chipselect (mem -> spi , 0 )];
@@ -367,11 +373,12 @@ static int do_aspeed_spi_exec_op(struct spi_mem *mem, const struct spi_mem_op *o
367373 return ret ;
368374}
369375
370- static int aspeed_spi_exec_op (struct spi_mem * mem , const struct spi_mem_op * op )
376+ static int aspeed_spi_exec_mem_op (struct spi_mem * mem ,
377+ const struct spi_mem_op * op )
371378{
372379 int ret ;
373380
374- ret = do_aspeed_spi_exec_op (mem , op );
381+ ret = do_aspeed_spi_exec_mem_op (mem , op );
375382 if (ret )
376383 dev_err (& mem -> spi -> dev , "operation failed: %d\n" , ret );
377384 return ret ;
@@ -773,8 +780,8 @@ static ssize_t aspeed_spi_dirmap_read(struct spi_mem_dirmap_desc *desc,
773780}
774781
775782static const struct spi_controller_mem_ops aspeed_spi_mem_ops = {
776- .supports_op = aspeed_spi_supports_op ,
777- .exec_op = aspeed_spi_exec_op ,
783+ .supports_op = aspeed_spi_supports_mem_op ,
784+ .exec_op = aspeed_spi_exec_mem_op ,
778785 .get_name = aspeed_spi_get_name ,
779786 .dirmap_create = aspeed_spi_dirmap_create ,
780787 .dirmap_read = aspeed_spi_dirmap_read ,
@@ -843,6 +850,110 @@ static void aspeed_spi_enable(struct aspeed_spi *aspi, bool enable)
843850 aspeed_spi_chip_enable (aspi , cs , enable );
844851}
845852
853+ static int aspeed_spi_user_prepare_msg (struct spi_controller * ctlr ,
854+ struct spi_message * msg )
855+ {
856+ struct aspeed_spi * aspi =
857+ (struct aspeed_spi * )spi_controller_get_devdata (ctlr );
858+ const struct aspeed_spi_data * data = aspi -> data ;
859+ struct spi_device * spi = msg -> spi ;
860+ u32 cs = spi_get_chipselect (spi , 0 );
861+ struct aspeed_spi_chip * chip = & aspi -> chips [cs ];
862+ u32 ctrl_val ;
863+ u32 clk_div = data -> get_clk_div (chip , spi -> max_speed_hz );
864+
865+ ctrl_val = chip -> ctl_val [ASPEED_SPI_BASE ];
866+ ctrl_val &= ~CTRL_IO_MODE_MASK & data -> hclk_mask ;
867+ ctrl_val |= clk_div ;
868+ chip -> ctl_val [ASPEED_SPI_BASE ] = ctrl_val ;
869+
870+ if (aspi -> cs_change == 0 )
871+ aspeed_spi_start_user (chip );
872+
873+ return 0 ;
874+ }
875+
876+ static int aspeed_spi_user_unprepare_msg (struct spi_controller * ctlr ,
877+ struct spi_message * msg )
878+ {
879+ struct aspeed_spi * aspi =
880+ (struct aspeed_spi * )spi_controller_get_devdata (ctlr );
881+ struct spi_device * spi = msg -> spi ;
882+ u32 cs = spi_get_chipselect (spi , 0 );
883+ struct aspeed_spi_chip * chip = & aspi -> chips [cs ];
884+
885+ if (aspi -> cs_change == 0 )
886+ aspeed_spi_stop_user (chip );
887+
888+ return 0 ;
889+ }
890+
891+ static void aspeed_spi_user_transfer_tx (struct aspeed_spi * aspi ,
892+ struct spi_device * spi ,
893+ const u8 * tx_buf , u8 * rx_buf ,
894+ void * dst , u32 len )
895+ {
896+ const struct aspeed_spi_data * data = aspi -> data ;
897+ bool full_duplex_transfer = data -> full_duplex && tx_buf == rx_buf ;
898+ u32 i ;
899+
900+ if (full_duplex_transfer &&
901+ !!(spi -> mode & (SPI_TX_DUAL | SPI_TX_QUAD |
902+ SPI_RX_DUAL | SPI_RX_QUAD ))) {
903+ dev_err (aspi -> dev ,
904+ "full duplex is only supported for single IO mode\n" );
905+ return ;
906+ }
907+
908+ for (i = 0 ; i < len ; i ++ ) {
909+ writeb (tx_buf [i ], dst );
910+ if (full_duplex_transfer )
911+ rx_buf [i ] = readb (aspi -> regs + FULL_DUPLEX_RX_DATA );
912+ }
913+ }
914+
915+ static int aspeed_spi_user_transfer (struct spi_controller * ctlr ,
916+ struct spi_device * spi ,
917+ struct spi_transfer * xfer )
918+ {
919+ struct aspeed_spi * aspi =
920+ (struct aspeed_spi * )spi_controller_get_devdata (ctlr );
921+ u32 cs = spi_get_chipselect (spi , 0 );
922+ struct aspeed_spi_chip * chip = & aspi -> chips [cs ];
923+ void __iomem * ahb_base = aspi -> chips [cs ].ahb_base ;
924+ const u8 * tx_buf = xfer -> tx_buf ;
925+ u8 * rx_buf = xfer -> rx_buf ;
926+
927+ dev_dbg (aspi -> dev ,
928+ "[cs%d] xfer: width %d, len %u, tx %p, rx %p\n" ,
929+ cs , xfer -> bits_per_word , xfer -> len ,
930+ tx_buf , rx_buf );
931+
932+ if (tx_buf ) {
933+ if (spi -> mode & SPI_TX_DUAL )
934+ aspeed_spi_set_io_mode (chip , CTRL_IO_DUAL_DATA );
935+ else if (spi -> mode & SPI_TX_QUAD )
936+ aspeed_spi_set_io_mode (chip , CTRL_IO_QUAD_DATA );
937+
938+ aspeed_spi_user_transfer_tx (aspi , spi , tx_buf , rx_buf ,
939+ (void * )ahb_base , xfer -> len );
940+ }
941+
942+ if (rx_buf && rx_buf != tx_buf ) {
943+ if (spi -> mode & SPI_RX_DUAL )
944+ aspeed_spi_set_io_mode (chip , CTRL_IO_DUAL_DATA );
945+ else if (spi -> mode & SPI_RX_QUAD )
946+ aspeed_spi_set_io_mode (chip , CTRL_IO_QUAD_DATA );
947+
948+ ioread8_rep (ahb_base , rx_buf , xfer -> len );
949+ }
950+
951+ xfer -> error = 0 ;
952+ aspi -> cs_change = xfer -> cs_change ;
953+
954+ return 0 ;
955+ }
956+
846957static int aspeed_spi_probe (struct platform_device * pdev )
847958{
848959 struct device * dev = & pdev -> dev ;
@@ -899,6 +1010,9 @@ static int aspeed_spi_probe(struct platform_device *pdev)
8991010 ctlr -> cleanup = aspeed_spi_cleanup ;
9001011 ctlr -> num_chipselect = of_get_available_child_count (dev -> of_node );
9011012 ctlr -> dev .of_node = dev -> of_node ;
1013+ ctlr -> prepare_message = aspeed_spi_user_prepare_msg ;
1014+ ctlr -> unprepare_message = aspeed_spi_user_unprepare_msg ;
1015+ ctlr -> transfer_one = aspeed_spi_user_transfer ;
9021016
9031017 aspi -> num_cs = ctlr -> num_chipselect ;
9041018
@@ -1455,6 +1569,7 @@ static const struct aspeed_spi_data ast2400_fmc_data = {
14551569 .hclk_mask = 0xfffff0ff ,
14561570 .hdiv_max = 1 ,
14571571 .min_window_size = 0x800000 ,
1572+ .full_duplex = false,
14581573 .calibrate = aspeed_spi_calibrate ,
14591574 .get_clk_div = aspeed_get_clk_div_ast2400 ,
14601575 .segment_start = aspeed_spi_segment_start ,
@@ -1471,6 +1586,7 @@ static const struct aspeed_spi_data ast2400_spi_data = {
14711586 .timing = 0x14 ,
14721587 .hclk_mask = 0xfffff0ff ,
14731588 .hdiv_max = 1 ,
1589+ .full_duplex = false,
14741590 .get_clk_div = aspeed_get_clk_div_ast2400 ,
14751591 .calibrate = aspeed_spi_calibrate ,
14761592 /* No segment registers */
@@ -1485,6 +1601,7 @@ static const struct aspeed_spi_data ast2500_fmc_data = {
14851601 .hclk_mask = 0xffffd0ff ,
14861602 .hdiv_max = 1 ,
14871603 .min_window_size = 0x800000 ,
1604+ .full_duplex = false,
14881605 .get_clk_div = aspeed_get_clk_div_ast2500 ,
14891606 .calibrate = aspeed_spi_calibrate ,
14901607 .segment_start = aspeed_spi_segment_start ,
@@ -1502,6 +1619,7 @@ static const struct aspeed_spi_data ast2500_spi_data = {
15021619 .hclk_mask = 0xffffd0ff ,
15031620 .hdiv_max = 1 ,
15041621 .min_window_size = 0x800000 ,
1622+ .full_duplex = false,
15051623 .get_clk_div = aspeed_get_clk_div_ast2500 ,
15061624 .calibrate = aspeed_spi_calibrate ,
15071625 .segment_start = aspeed_spi_segment_start ,
@@ -1520,6 +1638,7 @@ static const struct aspeed_spi_data ast2600_fmc_data = {
15201638 .hclk_mask = 0xf0fff0ff ,
15211639 .hdiv_max = 2 ,
15221640 .min_window_size = 0x200000 ,
1641+ .full_duplex = false,
15231642 .get_clk_div = aspeed_get_clk_div_ast2600 ,
15241643 .calibrate = aspeed_spi_ast2600_calibrate ,
15251644 .segment_start = aspeed_spi_segment_ast2600_start ,
@@ -1538,6 +1657,7 @@ static const struct aspeed_spi_data ast2600_spi_data = {
15381657 .hclk_mask = 0xf0fff0ff ,
15391658 .hdiv_max = 2 ,
15401659 .min_window_size = 0x200000 ,
1660+ .full_duplex = false,
15411661 .get_clk_div = aspeed_get_clk_div_ast2600 ,
15421662 .calibrate = aspeed_spi_ast2600_calibrate ,
15431663 .segment_start = aspeed_spi_segment_ast2600_start ,
@@ -1556,6 +1676,7 @@ static const struct aspeed_spi_data ast2700_fmc_data = {
15561676 .hclk_mask = 0xf0fff0ff ,
15571677 .hdiv_max = 2 ,
15581678 .min_window_size = 0x10000 ,
1679+ .full_duplex = true,
15591680 .get_clk_div = aspeed_get_clk_div_ast2600 ,
15601681 .calibrate = aspeed_spi_ast2600_calibrate ,
15611682 .segment_start = aspeed_spi_segment_ast2700_start ,
@@ -1573,6 +1694,7 @@ static const struct aspeed_spi_data ast2700_spi_data = {
15731694 .hclk_mask = 0xf0fff0ff ,
15741695 .hdiv_max = 2 ,
15751696 .min_window_size = 0x10000 ,
1697+ .full_duplex = true,
15761698 .get_clk_div = aspeed_get_clk_div_ast2600 ,
15771699 .calibrate = aspeed_spi_ast2600_calibrate ,
15781700 .segment_start = aspeed_spi_segment_ast2700_start ,
0 commit comments