1
1
// SPDX-License-Identifier: GPL-2.0+
2
2
//
3
3
// Copyright 2013 Freescale Semiconductor, Inc.
4
- // Copyright 2020 NXP
4
+ // Copyright 2020-2025 NXP
5
5
//
6
6
// Freescale DSPI driver
7
7
// This file contains a driver for the Freescale DSPI
62
62
#define SPI_SR_TFIWF BIT(18)
63
63
#define SPI_SR_RFDF BIT(17)
64
64
#define SPI_SR_CMDFFF BIT(16)
65
+ #define SPI_SR_TXRXS BIT(30)
65
66
#define SPI_SR_CLEAR (SPI_SR_TCFQF | \
66
67
SPI_SR_TFUF | SPI_SR_TFFF | \
67
68
SPI_SR_CMDTCF | SPI_SR_SPEF | \
@@ -921,9 +922,20 @@ static int dspi_transfer_one_message(struct spi_controller *ctlr,
921
922
struct spi_transfer * transfer ;
922
923
bool cs = false;
923
924
int status = 0 ;
925
+ u32 val = 0 ;
926
+ bool cs_change = false;
924
927
925
928
message -> actual_length = 0 ;
926
929
930
+ /* Put DSPI in running mode if halted. */
931
+ regmap_read (dspi -> regmap , SPI_MCR , & val );
932
+ if (val & SPI_MCR_HALT ) {
933
+ regmap_update_bits (dspi -> regmap , SPI_MCR , SPI_MCR_HALT , 0 );
934
+ while (regmap_read (dspi -> regmap , SPI_SR , & val ) >= 0 &&
935
+ !(val & SPI_SR_TXRXS ))
936
+ ;
937
+ }
938
+
927
939
list_for_each_entry (transfer , & message -> transfers , transfer_list ) {
928
940
dspi -> cur_transfer = transfer ;
929
941
dspi -> cur_msg = message ;
@@ -953,6 +965,7 @@ static int dspi_transfer_one_message(struct spi_controller *ctlr,
953
965
dspi -> tx_cmd |= SPI_PUSHR_CMD_CONT ;
954
966
}
955
967
968
+ cs_change = transfer -> cs_change ;
956
969
dspi -> tx = transfer -> tx_buf ;
957
970
dspi -> rx = transfer -> rx_buf ;
958
971
dspi -> len = transfer -> len ;
@@ -962,6 +975,8 @@ static int dspi_transfer_one_message(struct spi_controller *ctlr,
962
975
SPI_MCR_CLR_TXF | SPI_MCR_CLR_RXF ,
963
976
SPI_MCR_CLR_TXF | SPI_MCR_CLR_RXF );
964
977
978
+ regmap_write (dspi -> regmap , SPI_SR , SPI_SR_CLEAR );
979
+
965
980
spi_take_timestamp_pre (dspi -> ctlr , dspi -> cur_transfer ,
966
981
dspi -> progress , !dspi -> irq );
967
982
@@ -988,6 +1003,15 @@ static int dspi_transfer_one_message(struct spi_controller *ctlr,
988
1003
dspi_deassert_cs (spi , & cs );
989
1004
}
990
1005
1006
+ if (status || !cs_change ) {
1007
+ /* Put DSPI in stop mode */
1008
+ regmap_update_bits (dspi -> regmap , SPI_MCR ,
1009
+ SPI_MCR_HALT , SPI_MCR_HALT );
1010
+ while (regmap_read (dspi -> regmap , SPI_SR , & val ) >= 0 &&
1011
+ val & SPI_SR_TXRXS )
1012
+ ;
1013
+ }
1014
+
991
1015
message -> status = status ;
992
1016
spi_finalize_current_message (ctlr );
993
1017
@@ -1167,6 +1191,20 @@ static int dspi_resume(struct device *dev)
1167
1191
1168
1192
static SIMPLE_DEV_PM_OPS (dspi_pm , dspi_suspend , dspi_resume ) ;
1169
1193
1194
+ static const struct regmap_range dspi_yes_ranges [] = {
1195
+ regmap_reg_range (SPI_MCR , SPI_MCR ),
1196
+ regmap_reg_range (SPI_TCR , SPI_CTAR (3 )),
1197
+ regmap_reg_range (SPI_SR , SPI_TXFR3 ),
1198
+ regmap_reg_range (SPI_RXFR0 , SPI_RXFR3 ),
1199
+ regmap_reg_range (SPI_CTARE (0 ), SPI_CTARE (3 )),
1200
+ regmap_reg_range (SPI_SREX , SPI_SREX ),
1201
+ };
1202
+
1203
+ static const struct regmap_access_table dspi_access_table = {
1204
+ .yes_ranges = dspi_yes_ranges ,
1205
+ .n_yes_ranges = ARRAY_SIZE (dspi_yes_ranges ),
1206
+ };
1207
+
1170
1208
static const struct regmap_range dspi_volatile_ranges [] = {
1171
1209
regmap_reg_range (SPI_MCR , SPI_TCR ),
1172
1210
regmap_reg_range (SPI_SR , SPI_SR ),
@@ -1184,6 +1222,8 @@ static const struct regmap_config dspi_regmap_config = {
1184
1222
.reg_stride = 4 ,
1185
1223
.max_register = 0x88 ,
1186
1224
.volatile_table = & dspi_volatile_table ,
1225
+ .rd_table = & dspi_access_table ,
1226
+ .wr_table = & dspi_access_table ,
1187
1227
};
1188
1228
1189
1229
static const struct regmap_range dspi_xspi_volatile_ranges [] = {
@@ -1205,6 +1245,8 @@ static const struct regmap_config dspi_xspi_regmap_config[] = {
1205
1245
.reg_stride = 4 ,
1206
1246
.max_register = 0x13c ,
1207
1247
.volatile_table = & dspi_xspi_volatile_table ,
1248
+ .rd_table = & dspi_access_table ,
1249
+ .wr_table = & dspi_access_table ,
1208
1250
},
1209
1251
{
1210
1252
.name = "pushr" ,
@@ -1227,6 +1269,8 @@ static int dspi_init(struct fsl_dspi *dspi)
1227
1269
if (!spi_controller_is_target (dspi -> ctlr ))
1228
1270
mcr |= SPI_MCR_HOST ;
1229
1271
1272
+ mcr |= SPI_MCR_HALT ;
1273
+
1230
1274
regmap_write (dspi -> regmap , SPI_MCR , mcr );
1231
1275
regmap_write (dspi -> regmap , SPI_SR , SPI_SR_CLEAR );
1232
1276
0 commit comments