1515#include <linux/parser.h>
1616#include <linux/suspend.h>
1717
18+ #include <linux/clk.h>
1819#include <linux/clk/at91_pmc.h>
1920#include <linux/platform_data/atmel.h>
2021
@@ -60,13 +61,61 @@ struct at91_pm_sfrbu_regs {
6061 } pswbu ;
6162};
6263
64+ /*
65+ * enum at91_pm_eth_clk: Ethernet clock indexes
66+ * @AT91_PM_ETH_PCLK: pclk index
67+ * @AT91_PM_ETH_HCLK: hclk index
68+ * @AT91_PM_ETH_MAX_CLK: max index
69+ */
70+ enum at91_pm_eth_clk {
71+ AT91_PM_ETH_PCLK ,
72+ AT91_PM_ETH_HCLK ,
73+ AT91_PM_ETH_MAX_CLK ,
74+ };
75+
76+ /*
77+ * enum at91_pm_eth: Ethernet controller indexes
78+ * @AT91_PM_G_ETH: gigabit Ethernet controller index
79+ * @AT91_PM_E_ETH: megabit Ethernet controller index
80+ * @AT91_PM_MAX_ETH: max index
81+ */
82+ enum at91_pm_eth {
83+ AT91_PM_G_ETH ,
84+ AT91_PM_E_ETH ,
85+ AT91_PM_MAX_ETH ,
86+ };
87+
88+ /*
89+ * @np: Ethernet device node
90+ * @clks: Ethernet clocks
91+ * @modes: power management mode that this quirk applies to
92+ * @dns_modes: do not suspend modes: stop suspending if Ethernet is configured
93+ * as wakeup source but buggy and no other wakeup source is
94+ * available
95+ */
96+ struct at91_pm_quirk_eth {
97+ struct device_node * np ;
98+ struct clk_bulk_data clks [AT91_PM_ETH_MAX_CLK ];
99+ u32 modes ;
100+ u32 dns_modes ;
101+ };
102+
103+ /*
104+ * struct at91_pm_quirks: AT91 specific quirks
105+ * @eth: Ethernet quirks
106+ */
107+ struct at91_pm_quirks {
108+ struct at91_pm_quirk_eth eth [AT91_PM_MAX_ETH ];
109+ };
110+
63111/*
64112 * struct at91_soc_pm - AT91 SoC power management data structure
65113 * @config_shdwc_ws: wakeup sources configuration function for SHDWC
66114 * @config_pmc_ws: wakeup srouces configuration function for PMC
67115 * @ws_ids: wakup sources of_device_id array
68116 * @shdwc_np: pointer to shdwc node
69117 * @bu: backup unit mapped data (for backup mode)
118+ * @quirks: PM quirks
70119 * @data: PM data to be used on last phase of suspend
71120 * @sfrbu_regs: SFRBU registers mapping
72121 * @memcs: memory chip select
@@ -77,6 +126,7 @@ struct at91_soc_pm {
77126 const struct of_device_id * ws_ids ;
78127 struct device_node * shdwc_np ;
79128 struct at91_pm_bu * bu ;
129+ struct at91_pm_quirks quirks ;
80130 struct at91_pm_data data ;
81131 struct at91_pm_sfrbu_regs sfrbu_regs ;
82132 void * memcs ;
@@ -86,10 +136,12 @@ struct at91_soc_pm {
86136 * enum at91_pm_iomaps: IOs that needs to be mapped for different PM modes
87137 * @AT91_PM_IOMAP_SHDWC: SHDWC controller
88138 * @AT91_PM_IOMAP_SFRBU: SFRBU controller
139+ * @AT91_PM_IOMAP_ETHC: Ethernet controller
89140 */
90141enum at91_pm_iomaps {
91142 AT91_PM_IOMAP_SHDWC ,
92143 AT91_PM_IOMAP_SFRBU ,
144+ AT91_PM_IOMAP_ETHC ,
93145};
94146
95147#define AT91_PM_IOMAP (name ) BIT(AT91_PM_IOMAP_##name)
@@ -343,6 +395,115 @@ static int at91_sam9x60_config_pmc_ws(void __iomem *pmc, u32 mode, u32 polarity)
343395 return 0 ;
344396}
345397
398+ static bool at91_pm_eth_quirk_is_valid (int index )
399+ {
400+ struct platform_device * pdev ;
401+ bool ret = true;
402+
403+ /* Interface NA in DT. */
404+ if (!soc_pm .quirks .eth [index ].np )
405+ return false;
406+
407+ /* No quirks for this interface and current suspend mode. */
408+ if (!(soc_pm .quirks .eth [index ].modes & BIT (soc_pm .data .mode )))
409+ return false;
410+
411+ /* Driver not probed. */
412+ pdev = of_find_device_by_node (soc_pm .quirks .eth [index ].np );
413+ if (!pdev )
414+ return false;
415+
416+ /* No quirks if device isn't a wakeup source. */
417+ if (!device_may_wakeup (& pdev -> dev ))
418+ ret = false;
419+
420+ put_device (& pdev -> dev );
421+ return ret ;
422+ }
423+
424+ static int at91_pm_config_quirks (bool suspend )
425+ {
426+ struct wakeup_source * ws ;
427+ int i , j , ret , tmp ;
428+
429+ /*
430+ * Ethernet IPs who's device_node pointers are stored into
431+ * soc_pm.quirks.eth[].np cannot handle WoL packets while in ULP0, ULP1
432+ * or both due to a hardware bug. If they receive WoL packets while in
433+ * ULP0 or ULP1 IPs could stop working or the whole system could stop
434+ * working. We cannot handle this scenario in the ethernet driver itself
435+ * as the driver is common to multiple vendors and also we only know
436+ * here, in this file, if we suspend to ULP0 or ULP1 mode. Thus handle
437+ * these scenarios here, as quirks.
438+ */
439+ for (i = 0 ; i < AT91_PM_MAX_ETH ; i ++ ) {
440+ if (!at91_pm_eth_quirk_is_valid (i ))
441+ continue ;
442+
443+ /*
444+ * For modes in dns_modes mask the system blocks if quirk is not
445+ * applied but if applied the interface doesn't act at WoL
446+ * events. Thus take care to avoid suspending if this interface
447+ * is the only configured wakeup source.
448+ */
449+ if (suspend &&
450+ soc_pm .quirks .eth [i ].dns_modes & BIT (soc_pm .data .mode )) {
451+ int ws_count = 0 ;
452+
453+ for_each_wakeup_source (ws ) {
454+ ws_count ++ ;
455+ if (ws_count > 1 )
456+ break ;
457+ }
458+
459+ /*
460+ * Checking ws == 1 is good for all SAMA5 based platforms
461+ * even when both G_ETH and E_ETH are available as dsn_modes
462+ * is populated only on G_ETH interface.
463+ */
464+ if (ws_count == 1 ) {
465+ pr_err ("AT91: PM: Ethernet cannot resume from WoL!" );
466+ ret = - EPERM ;
467+ goto clk_unconfigure ;
468+ }
469+ }
470+
471+ if (suspend ) {
472+ clk_bulk_disable_unprepare (AT91_PM_ETH_MAX_CLK ,
473+ soc_pm .quirks .eth [i ].clks );
474+ } else {
475+ ret = clk_bulk_prepare_enable (AT91_PM_ETH_MAX_CLK ,
476+ soc_pm .quirks .eth [i ].clks );
477+ if (ret )
478+ goto clk_unconfigure ;
479+ }
480+ }
481+
482+ return 0 ;
483+
484+ clk_unconfigure :
485+ /*
486+ * In case of resume we reach this point if clk_prepare_enable() failed.
487+ * we don't want to revert the previous clk_prepare_enable() for the
488+ * other IP.
489+ */
490+ if (suspend ) {
491+ for (j = i - 1 ; j <= 0 ; j -- ) {
492+ if (!at91_pm_eth_quirk_is_valid (i ))
493+ continue ;
494+
495+ tmp = clk_bulk_prepare_enable (AT91_PM_ETH_MAX_CLK ,
496+ soc_pm .quirks .eth [i ].clks );
497+ if (tmp ) {
498+ pr_err ("AT91: PM: failed to enable %s clock\n" ,
499+ i == AT91_PM_ETH_PCLK ? "pclk" : "hclk" );
500+ }
501+ }
502+ }
503+
504+ return ret ;
505+ }
506+
346507/*
347508 * Called after processes are frozen, but before we shutdown devices.
348509 */
@@ -514,6 +675,12 @@ static void at91_pm_suspend(suspend_state_t state)
514675 */
515676static int at91_pm_enter (suspend_state_t state )
516677{
678+ int ret ;
679+
680+ ret = at91_pm_config_quirks (true);
681+ if (ret )
682+ return ret ;
683+
517684#ifdef CONFIG_PINCTRL_AT91
518685 /*
519686 * FIXME: this is needed to communicate between the pinctrl driver and
@@ -551,6 +718,7 @@ static int at91_pm_enter(suspend_state_t state)
551718#ifdef CONFIG_PINCTRL_AT91
552719 at91_pinctrl_gpio_resume ();
553720#endif
721+ at91_pm_config_quirks (false);
554722 return 0 ;
555723}
556724
@@ -948,6 +1116,20 @@ static const struct of_device_id atmel_shdwc_ids[] = {
9481116 { /* sentinel. */ }
9491117};
9501118
1119+ static const struct of_device_id gmac_ids [] __initconst = {
1120+ { .compatible = "atmel,sama5d3-gem" },
1121+ { .compatible = "atmel,sama5d2-gem" },
1122+ { .compatible = "atmel,sama5d29-gem" },
1123+ { .compatible = "microchip,sama7g5-gem" },
1124+ { },
1125+ };
1126+
1127+ static const struct of_device_id emac_ids [] __initconst = {
1128+ { .compatible = "atmel,sama5d3-macb" },
1129+ { .compatible = "microchip,sama7g5-emac" },
1130+ { },
1131+ };
1132+
9511133/*
9521134 * Replaces _mode_to_replace with a supported mode that doesn't depend
9531135 * on controller pointed by _map_bitmask
@@ -1001,8 +1183,30 @@ static const struct of_device_id atmel_shdwc_ids[] = {
10011183 (soc_pm.data.standby_mode)); \
10021184 } while (0)
10031185
1186+ static int __init at91_pm_get_eth_clks (struct device_node * np ,
1187+ struct clk_bulk_data * clks )
1188+ {
1189+ clks [AT91_PM_ETH_PCLK ].clk = of_clk_get_by_name (np , "pclk" );
1190+ if (IS_ERR (clks [AT91_PM_ETH_PCLK ].clk ))
1191+ return PTR_ERR (clks [AT91_PM_ETH_PCLK ].clk );
1192+
1193+ clks [AT91_PM_ETH_HCLK ].clk = of_clk_get_by_name (np , "hclk" );
1194+ if (IS_ERR (clks [AT91_PM_ETH_HCLK ].clk ))
1195+ return PTR_ERR (clks [AT91_PM_ETH_HCLK ].clk );
1196+
1197+ return 0 ;
1198+ }
1199+
1200+ static int __init at91_pm_eth_clks_empty (struct clk_bulk_data * clks )
1201+ {
1202+ return IS_ERR (clks [AT91_PM_ETH_PCLK ].clk ) ||
1203+ IS_ERR (clks [AT91_PM_ETH_HCLK ].clk );
1204+ }
1205+
10041206static void __init at91_pm_modes_init (const u32 * maps , int len )
10051207{
1208+ struct at91_pm_quirk_eth * gmac = & soc_pm .quirks .eth [AT91_PM_G_ETH ];
1209+ struct at91_pm_quirk_eth * emac = & soc_pm .quirks .eth [AT91_PM_E_ETH ];
10061210 struct device_node * np ;
10071211 int ret ;
10081212
@@ -1042,6 +1246,40 @@ static void __init at91_pm_modes_init(const u32 *maps, int len)
10421246 }
10431247 }
10441248
1249+ if ((at91_is_pm_mode_active (AT91_PM_ULP1 ) ||
1250+ at91_is_pm_mode_active (AT91_PM_ULP0 )) &&
1251+ (maps [soc_pm .data .standby_mode ] & AT91_PM_IOMAP (ETHC ) ||
1252+ maps [soc_pm .data .suspend_mode ] & AT91_PM_IOMAP (ETHC ))) {
1253+ np = of_find_matching_node (NULL , gmac_ids );
1254+ if (!np ) {
1255+ np = of_find_matching_node (NULL , emac_ids );
1256+ if (np )
1257+ goto get_emac_clks ;
1258+ AT91_PM_REPLACE_MODES (maps , ETHC );
1259+ goto unmap_unused_nodes ;
1260+ } else {
1261+ gmac -> np = np ;
1262+ at91_pm_get_eth_clks (np , gmac -> clks );
1263+ }
1264+
1265+ np = of_find_matching_node (NULL , emac_ids );
1266+ if (!np ) {
1267+ if (at91_pm_eth_clks_empty (gmac -> clks ))
1268+ AT91_PM_REPLACE_MODES (maps , ETHC );
1269+ } else {
1270+ get_emac_clks :
1271+ emac -> np = np ;
1272+ ret = at91_pm_get_eth_clks (np , emac -> clks );
1273+ if (ret && at91_pm_eth_clks_empty (gmac -> clks )) {
1274+ of_node_put (gmac -> np );
1275+ of_node_put (emac -> np );
1276+ gmac -> np = NULL ;
1277+ emac -> np = NULL ;
1278+ }
1279+ }
1280+ }
1281+
1282+ unmap_unused_nodes :
10451283 /* Unmap all unnecessary. */
10461284 if (soc_pm .data .shdwc &&
10471285 !(maps [soc_pm .data .standby_mode ] & AT91_PM_IOMAP (SHDWC ) ||
@@ -1277,17 +1515,27 @@ void __init sama5_pm_init(void)
12771515 static const int modes [] __initconst = {
12781516 AT91_PM_STANDBY , AT91_PM_ULP0 , AT91_PM_ULP0_FAST ,
12791517 };
1518+ static const u32 iomaps [] __initconst = {
1519+ [AT91_PM_ULP0 ] = AT91_PM_IOMAP (ETHC ),
1520+ };
12801521 int ret ;
12811522
12821523 if (!IS_ENABLED (CONFIG_SOC_SAMA5 ))
12831524 return ;
12841525
12851526 at91_pm_modes_validate (modes , ARRAY_SIZE (modes ));
1527+ at91_pm_modes_init (iomaps , ARRAY_SIZE (iomaps ));
12861528 ret = at91_dt_ramc (false);
12871529 if (ret )
12881530 return ;
12891531
12901532 at91_pm_init (NULL );
1533+
1534+ /* Quirks applies to ULP0 and ULP1 modes. */
1535+ soc_pm .quirks .eth [AT91_PM_G_ETH ].modes = BIT (AT91_PM_ULP0 ) |
1536+ BIT (AT91_PM_ULP1 );
1537+ /* Do not suspend in ULP0 if GETH is the only wakeup source. */
1538+ soc_pm .quirks .eth [AT91_PM_G_ETH ].dns_modes = BIT (AT91_PM_ULP0 );
12911539}
12921540
12931541void __init sama5d2_pm_init (void )
@@ -1297,7 +1545,9 @@ void __init sama5d2_pm_init(void)
12971545 AT91_PM_BACKUP ,
12981546 };
12991547 static const u32 iomaps [] __initconst = {
1300- [AT91_PM_ULP1 ] = AT91_PM_IOMAP (SHDWC ),
1548+ [AT91_PM_ULP0 ] = AT91_PM_IOMAP (ETHC ),
1549+ [AT91_PM_ULP1 ] = AT91_PM_IOMAP (SHDWC ) |
1550+ AT91_PM_IOMAP (ETHC ),
13011551 [AT91_PM_BACKUP ] = AT91_PM_IOMAP (SHDWC ) |
13021552 AT91_PM_IOMAP (SFRBU ),
13031553 };
@@ -1322,6 +1572,12 @@ void __init sama5d2_pm_init(void)
13221572 soc_pm .sfrbu_regs .pswbu .ctrl = BIT (0 );
13231573 soc_pm .sfrbu_regs .pswbu .softsw = BIT (1 );
13241574 soc_pm .sfrbu_regs .pswbu .state = BIT (3 );
1575+
1576+ /* Quirk applies to ULP0 and ULP1 modes. */
1577+ soc_pm .quirks .eth [AT91_PM_G_ETH ].modes = BIT (AT91_PM_ULP0 ) |
1578+ BIT (AT91_PM_ULP1 );
1579+ /* Do not suspend in ULP0 if GETH is the only wakeup source. */
1580+ soc_pm .quirks .eth [AT91_PM_G_ETH ].dns_modes = BIT (AT91_PM_ULP0 );
13251581}
13261582
13271583void __init sama7_pm_init (void )
@@ -1333,7 +1589,8 @@ void __init sama7_pm_init(void)
13331589 [AT91_PM_ULP0 ] = AT91_PM_IOMAP (SFRBU ) |
13341590 AT91_PM_IOMAP (SHDWC ),
13351591 [AT91_PM_ULP1 ] = AT91_PM_IOMAP (SFRBU ) |
1336- AT91_PM_IOMAP (SHDWC ),
1592+ AT91_PM_IOMAP (SHDWC ) |
1593+ AT91_PM_IOMAP (ETHC ),
13371594 [AT91_PM_BACKUP ] = AT91_PM_IOMAP (SFRBU ) |
13381595 AT91_PM_IOMAP (SHDWC ),
13391596 };
@@ -1358,6 +1615,10 @@ void __init sama7_pm_init(void)
13581615 soc_pm .sfrbu_regs .pswbu .ctrl = BIT (0 );
13591616 soc_pm .sfrbu_regs .pswbu .softsw = BIT (1 );
13601617 soc_pm .sfrbu_regs .pswbu .state = BIT (2 );
1618+
1619+ /* Quirks applies to ULP1 for both Ethernet interfaces. */
1620+ soc_pm .quirks .eth [AT91_PM_E_ETH ].modes = BIT (AT91_PM_ULP1 );
1621+ soc_pm .quirks .eth [AT91_PM_G_ETH ].modes = BIT (AT91_PM_ULP1 );
13611622}
13621623
13631624static int __init at91_pm_modes_select (char * str )
0 commit comments