@@ -82,9 +82,10 @@ struct aspeed_spi_data {
8282 u32 hdiv_max ;
8383 u32 min_window_size ;
8484
85- u32 (* segment_start )(struct aspeed_spi * aspi , u32 reg );
86- u32 (* segment_end )(struct aspeed_spi * aspi , u32 reg );
87- u32 (* segment_reg )(struct aspeed_spi * aspi , u32 start , u32 end );
85+ phys_addr_t (* segment_start )(struct aspeed_spi * aspi , u32 reg );
86+ phys_addr_t (* segment_end )(struct aspeed_spi * aspi , u32 reg );
87+ u32 (* segment_reg )(struct aspeed_spi * aspi , phys_addr_t start ,
88+ phys_addr_t end );
8889 int (* adjust_window )(struct aspeed_spi * aspi );
8990 u32 (* get_clk_div )(struct aspeed_spi_chip * chip , u32 hz );
9091 int (* calibrate )(struct aspeed_spi_chip * chip , u32 hdiv ,
@@ -97,7 +98,7 @@ struct aspeed_spi {
9798 const struct aspeed_spi_data * data ;
9899
99100 void __iomem * regs ;
100- u32 ahb_base_phy ;
101+ phys_addr_t ahb_base_phy ;
101102 u32 ahb_window_size ;
102103 u32 num_cs ;
103104 struct device * dev ;
@@ -263,11 +264,15 @@ static ssize_t aspeed_spi_write_user(struct aspeed_spi_chip *chip,
263264 const struct spi_mem_op * op )
264265{
265266 int ret ;
267+ int io_mode = aspeed_spi_get_io_mode (op );
266268
267269 aspeed_spi_start_user (chip );
268270 ret = aspeed_spi_send_cmd_addr (chip , op -> addr .nbytes , op -> addr .val , op -> cmd .opcode );
269271 if (ret < 0 )
270272 goto stop_user ;
273+
274+ aspeed_spi_set_io_mode (chip , io_mode );
275+
271276 aspeed_spi_write_to_ahb (chip -> ahb_base , op -> data .buf .out , op -> data .nbytes );
272277stop_user :
273278 aspeed_spi_stop_user (chip );
@@ -480,9 +485,9 @@ static int aspeed_spi_chip_set_default_window(struct aspeed_spi *aspi)
480485 /* Assign the minimum window size to each CS */
481486 for (cs = 0 ; cs < aspi -> num_cs ; cs ++ ) {
482487 aspi -> chips [cs ].ahb_window_size = aspi -> data -> min_window_size ;
483- dev_dbg (aspi -> dev , "CE%d default window [ 0x%.8x - 0x%.8x ]" ,
484- cs , aspi -> ahb_base_phy + aspi -> data -> min_window_size * cs ,
485- aspi -> ahb_base_phy + aspi -> data -> min_window_size * cs - 1 );
488+ dev_dbg (aspi -> dev , "CE%d default window [ 0x%.9llx - 0x%.9llx ]" ,
489+ cs , ( u64 )( aspi -> ahb_base_phy + aspi -> data -> min_window_size * cs ) ,
490+ ( u64 )( aspi -> ahb_base_phy + aspi -> data -> min_window_size * cs - 1 ) );
486491 }
487492
488493 /* Close unused CS */
@@ -926,17 +931,18 @@ static void aspeed_spi_remove(struct platform_device *pdev)
926931 * The address range is encoded with absolute addresses in the overall
927932 * mapping window.
928933 */
929- static u32 aspeed_spi_segment_start (struct aspeed_spi * aspi , u32 reg )
934+ static phys_addr_t aspeed_spi_segment_start (struct aspeed_spi * aspi , u32 reg )
930935{
931936 return ((reg >> 16 ) & 0xFF ) << 23 ;
932937}
933938
934- static u32 aspeed_spi_segment_end (struct aspeed_spi * aspi , u32 reg )
939+ static phys_addr_t aspeed_spi_segment_end (struct aspeed_spi * aspi , u32 reg )
935940{
936941 return ((reg >> 24 ) & 0xFF ) << 23 ;
937942}
938943
939- static u32 aspeed_spi_segment_reg (struct aspeed_spi * aspi , u32 start , u32 end )
944+ static u32 aspeed_spi_segment_reg (struct aspeed_spi * aspi ,
945+ phys_addr_t start , phys_addr_t end )
940946{
941947 return (((start >> 23 ) & 0xFF ) << 16 ) | (((end >> 23 ) & 0xFF ) << 24 );
942948}
@@ -948,16 +954,16 @@ static u32 aspeed_spi_segment_reg(struct aspeed_spi *aspi, u32 start, u32 end)
948954
949955#define AST2600_SEG_ADDR_MASK 0x0ff00000
950956
951- static u32 aspeed_spi_segment_ast2600_start (struct aspeed_spi * aspi ,
952- u32 reg )
957+ static phys_addr_t aspeed_spi_segment_ast2600_start (struct aspeed_spi * aspi ,
958+ u32 reg )
953959{
954960 u32 start_offset = (reg << 16 ) & AST2600_SEG_ADDR_MASK ;
955961
956962 return aspi -> ahb_base_phy + start_offset ;
957963}
958964
959- static u32 aspeed_spi_segment_ast2600_end (struct aspeed_spi * aspi ,
960- u32 reg )
965+ static phys_addr_t aspeed_spi_segment_ast2600_end (struct aspeed_spi * aspi ,
966+ u32 reg )
961967{
962968 u32 end_offset = reg & AST2600_SEG_ADDR_MASK ;
963969
@@ -969,7 +975,7 @@ static u32 aspeed_spi_segment_ast2600_end(struct aspeed_spi *aspi,
969975}
970976
971977static u32 aspeed_spi_segment_ast2600_reg (struct aspeed_spi * aspi ,
972- u32 start , u32 end )
978+ phys_addr_t start , phys_addr_t end )
973979{
974980 /* disable zero size segments */
975981 if (start == end )
@@ -979,6 +985,41 @@ static u32 aspeed_spi_segment_ast2600_reg(struct aspeed_spi *aspi,
979985 ((end - 1 ) & AST2600_SEG_ADDR_MASK );
980986}
981987
988+ /* The Segment Registers of the AST2700 use a 64KB unit. */
989+ #define AST2700_SEG_ADDR_MASK 0x7fff0000
990+
991+ static phys_addr_t aspeed_spi_segment_ast2700_start (struct aspeed_spi * aspi ,
992+ u32 reg )
993+ {
994+ u64 start_offset = (reg << 16 ) & AST2700_SEG_ADDR_MASK ;
995+
996+ if (!start_offset )
997+ return aspi -> ahb_base_phy ;
998+
999+ return aspi -> ahb_base_phy + start_offset ;
1000+ }
1001+
1002+ static phys_addr_t aspeed_spi_segment_ast2700_end (struct aspeed_spi * aspi ,
1003+ u32 reg )
1004+ {
1005+ u64 end_offset = reg & AST2700_SEG_ADDR_MASK ;
1006+
1007+ if (!end_offset )
1008+ return aspi -> ahb_base_phy ;
1009+
1010+ return aspi -> ahb_base_phy + end_offset ;
1011+ }
1012+
1013+ static u32 aspeed_spi_segment_ast2700_reg (struct aspeed_spi * aspi ,
1014+ phys_addr_t start , phys_addr_t end )
1015+ {
1016+ if (start == end )
1017+ return 0 ;
1018+
1019+ return (u32 )(((start & AST2700_SEG_ADDR_MASK ) >> 16 ) |
1020+ (end & AST2700_SEG_ADDR_MASK ));
1021+ }
1022+
9821023/*
9831024 * Read timing compensation sequences
9841025 */
@@ -1505,13 +1546,49 @@ static const struct aspeed_spi_data ast2600_spi_data = {
15051546 .adjust_window = aspeed_adjust_window_ast2600 ,
15061547};
15071548
1549+ static const struct aspeed_spi_data ast2700_fmc_data = {
1550+ .max_cs = 3 ,
1551+ .hastype = false,
1552+ .mode_bits = SPI_RX_QUAD | SPI_TX_QUAD ,
1553+ .we0 = 16 ,
1554+ .ctl0 = CE0_CTRL_REG ,
1555+ .timing = CE0_TIMING_COMPENSATION_REG ,
1556+ .hclk_mask = 0xf0fff0ff ,
1557+ .hdiv_max = 2 ,
1558+ .min_window_size = 0x10000 ,
1559+ .get_clk_div = aspeed_get_clk_div_ast2600 ,
1560+ .calibrate = aspeed_spi_ast2600_calibrate ,
1561+ .segment_start = aspeed_spi_segment_ast2700_start ,
1562+ .segment_end = aspeed_spi_segment_ast2700_end ,
1563+ .segment_reg = aspeed_spi_segment_ast2700_reg ,
1564+ };
1565+
1566+ static const struct aspeed_spi_data ast2700_spi_data = {
1567+ .max_cs = 2 ,
1568+ .hastype = false,
1569+ .mode_bits = SPI_RX_QUAD | SPI_TX_QUAD ,
1570+ .we0 = 16 ,
1571+ .ctl0 = CE0_CTRL_REG ,
1572+ .timing = CE0_TIMING_COMPENSATION_REG ,
1573+ .hclk_mask = 0xf0fff0ff ,
1574+ .hdiv_max = 2 ,
1575+ .min_window_size = 0x10000 ,
1576+ .get_clk_div = aspeed_get_clk_div_ast2600 ,
1577+ .calibrate = aspeed_spi_ast2600_calibrate ,
1578+ .segment_start = aspeed_spi_segment_ast2700_start ,
1579+ .segment_end = aspeed_spi_segment_ast2700_end ,
1580+ .segment_reg = aspeed_spi_segment_ast2700_reg ,
1581+ };
1582+
15081583static const struct of_device_id aspeed_spi_matches [] = {
15091584 { .compatible = "aspeed,ast2400-fmc" , .data = & ast2400_fmc_data },
15101585 { .compatible = "aspeed,ast2400-spi" , .data = & ast2400_spi_data },
15111586 { .compatible = "aspeed,ast2500-fmc" , .data = & ast2500_fmc_data },
15121587 { .compatible = "aspeed,ast2500-spi" , .data = & ast2500_spi_data },
15131588 { .compatible = "aspeed,ast2600-fmc" , .data = & ast2600_fmc_data },
15141589 { .compatible = "aspeed,ast2600-spi" , .data = & ast2600_spi_data },
1590+ { .compatible = "aspeed,ast2700-fmc" , .data = & ast2700_fmc_data },
1591+ { .compatible = "aspeed,ast2700-spi" , .data = & ast2700_spi_data },
15151592 { }
15161593};
15171594MODULE_DEVICE_TABLE (of , aspeed_spi_matches );
0 commit comments