@@ -262,6 +262,9 @@ struct atmel_qspi_caps {
262262 bool has_ricr ;
263263 bool octal ;
264264 bool has_dma ;
265+ bool has_2xgclk ;
266+ bool has_padcalib ;
267+ bool has_dllon ;
265268};
266269
267270struct atmel_qspi_ops ;
@@ -1027,13 +1030,25 @@ static int atmel_qspi_set_pad_calibration(struct atmel_qspi *aq)
10271030 aq , QSPI_PCALCFG );
10281031
10291032 /* DLL On + start calibration. */
1030- atmel_qspi_write (QSPI_CR_DLLON | QSPI_CR_STPCAL , aq , QSPI_CR );
1033+ if (aq -> caps -> has_dllon )
1034+ atmel_qspi_write (QSPI_CR_DLLON | QSPI_CR_STPCAL , aq , QSPI_CR );
1035+ /* If there is no DLL support only start calibration. */
1036+ else
1037+ atmel_qspi_write (QSPI_CR_STPCAL , aq , QSPI_CR );
10311038
1032- /* Check synchronization status before updating configuration. */
1033- ret = readl_poll_timeout (aq -> regs + QSPI_SR2 , val ,
1034- (val & QSPI_SR2_DLOCK ) &&
1035- !(val & QSPI_SR2_CALBSY ), 40 ,
1036- ATMEL_QSPI_TIMEOUT );
1039+ /*
1040+ * Check DLL clock lock and synchronization status before updating
1041+ * configuration.
1042+ */
1043+ if (aq -> caps -> has_dllon )
1044+ ret = readl_poll_timeout (aq -> regs + QSPI_SR2 , val ,
1045+ (val & QSPI_SR2_DLOCK ) &&
1046+ !(val & QSPI_SR2_CALBSY ), 40 ,
1047+ ATMEL_QSPI_TIMEOUT );
1048+ else
1049+ ret = readl_poll_timeout (aq -> regs + QSPI_SR2 , val ,
1050+ !(val & QSPI_SR2_CALBSY ), 40 ,
1051+ ATMEL_QSPI_TIMEOUT );
10371052
10381053 /* Refresh analogic blocks every 1 ms.*/
10391054 atmel_qspi_write (FIELD_PREP (QSPI_REFRESH_DELAY_COUNTER ,
@@ -1049,23 +1064,28 @@ static int atmel_qspi_set_gclk(struct atmel_qspi *aq)
10491064 int ret ;
10501065
10511066 /* Disable DLL before setting GCLK */
1052- status = atmel_qspi_read (aq , QSPI_SR2 );
1053- if (status & QSPI_SR2_DLOCK ) {
1054- atmel_qspi_write (QSPI_CR_DLLOFF , aq , QSPI_CR );
1067+ if (aq -> caps -> has_dllon ) {
1068+ status = atmel_qspi_read (aq , QSPI_SR2 );
1069+ if (status & QSPI_SR2_DLOCK ) {
1070+ atmel_qspi_write (QSPI_CR_DLLOFF , aq , QSPI_CR );
1071+ ret = readl_poll_timeout (aq -> regs + QSPI_SR2 , val ,
1072+ !(val & QSPI_SR2_DLOCK ), 40 ,
1073+ ATMEL_QSPI_TIMEOUT );
1074+ if (ret )
1075+ return ret ;
1076+ }
10551077
1056- ret = readl_poll_timeout (aq -> regs + QSPI_SR2 , val ,
1057- !(val & QSPI_SR2_DLOCK ), 40 ,
1058- ATMEL_QSPI_TIMEOUT );
1059- if (ret )
1060- return ret ;
1078+ if (aq -> target_max_speed_hz > QSPI_DLLCFG_THRESHOLD_FREQ )
1079+ atmel_qspi_write (QSPI_DLLCFG_RANGE , aq , QSPI_DLLCFG );
1080+ else
1081+ atmel_qspi_write (0 , aq , QSPI_DLLCFG );
10611082 }
10621083
1063- if (aq -> target_max_speed_hz > QSPI_DLLCFG_THRESHOLD_FREQ )
1064- atmel_qspi_write ( QSPI_DLLCFG_RANGE , aq , QSPI_DLLCFG );
1084+ if (aq -> caps -> has_2xgclk )
1085+ ret = clk_set_rate ( aq -> gclk , 2 * aq -> target_max_speed_hz );
10651086 else
1066- atmel_qspi_write ( 0 , aq , QSPI_DLLCFG );
1087+ ret = clk_set_rate ( aq -> gclk , aq -> target_max_speed_hz );
10671088
1068- ret = clk_set_rate (aq -> gclk , aq -> target_max_speed_hz );
10691089 if (ret ) {
10701090 dev_err (& aq -> pdev -> dev , "Failed to set generic clock rate.\n" );
10711091 return ret ;
@@ -1088,11 +1108,16 @@ static int atmel_qspi_sama7g5_init(struct atmel_qspi *aq)
10881108 if (ret )
10891109 return ret ;
10901110
1091- if (aq -> caps -> octal ) {
1111+ /*
1112+ * Check if the SoC supports pad calibration in Octal SPI mode.
1113+ * Proceed only if both the capabilities are true.
1114+ */
1115+ if (aq -> caps -> octal && aq -> caps -> has_padcalib ) {
10921116 ret = atmel_qspi_set_pad_calibration (aq );
10931117 if (ret )
10941118 return ret ;
1095- } else {
1119+ /* Start DLL on only if the SoC supports the same */
1120+ } else if (aq -> caps -> has_dllon ) {
10961121 atmel_qspi_write (QSPI_CR_DLLON , aq , QSPI_CR );
10971122 ret = readl_poll_timeout (aq -> regs + QSPI_SR2 , val ,
10981123 (val & QSPI_SR2_DLOCK ), 40 ,
@@ -1458,19 +1483,19 @@ static int atmel_qspi_sama7g5_suspend(struct atmel_qspi *aq)
14581483
14591484 clk_disable_unprepare (aq -> gclk );
14601485
1461- atmel_qspi_write (QSPI_CR_DLLOFF , aq , QSPI_CR );
1462- ret = readl_poll_timeout (aq -> regs + QSPI_SR2 , val ,
1463- !(val & QSPI_SR2_DLOCK ), 40 ,
1464- ATMEL_QSPI_TIMEOUT );
1465- if (ret )
1466- return ret ;
1467-
1468- ret = readl_poll_timeout (aq -> regs + QSPI_SR2 , val ,
1469- !(val & QSPI_SR2_CALBSY ), 40 ,
1470- ATMEL_QSPI_TIMEOUT );
1471- if (ret )
1472- return ret ;
1486+ if (aq -> caps -> has_dllon ) {
1487+ atmel_qspi_write (QSPI_CR_DLLOFF , aq , QSPI_CR );
1488+ ret = readl_poll_timeout (aq -> regs + QSPI_SR2 , val ,
1489+ !(val & QSPI_SR2_DLOCK ), 40 ,
1490+ ATMEL_QSPI_TIMEOUT );
1491+ if (ret )
1492+ return ret ;
1493+ }
14731494
1495+ if (aq -> caps -> has_padcalib )
1496+ return readl_poll_timeout (aq -> regs + QSPI_SR2 , val ,
1497+ !(val & QSPI_SR2_CALBSY ), 40 ,
1498+ ATMEL_QSPI_TIMEOUT );
14741499 return 0 ;
14751500}
14761501
@@ -1607,12 +1632,15 @@ static const struct atmel_qspi_caps atmel_sama7g5_ospi_caps = {
16071632 .has_gclk = true,
16081633 .octal = true,
16091634 .has_dma = true,
1635+ .has_padcalib = true,
1636+ .has_dllon = true,
16101637};
16111638
16121639static const struct atmel_qspi_caps atmel_sama7g5_qspi_caps = {
16131640 .max_speed_hz = SAMA7G5_QSPI1_SDR_MAX_SPEED_HZ ,
16141641 .has_gclk = true,
16151642 .has_dma = true,
1643+ .has_dllon = true,
16161644};
16171645
16181646static const struct of_device_id atmel_qspi_dt_ids [] = {
0 commit comments