23
23
#include <linux/of_gpio.h>
24
24
#include <linux/pinctrl/consumer.h>
25
25
#include <linux/platform_device.h>
26
+ #include <linux/pm.h>
27
+ #include <linux/pm_runtime.h>
26
28
#include <linux/regulator/consumer.h>
27
29
#include <linux/spinlock.h>
28
30
213
215
#define MSDC_ASYNC_FLAG (0x1 << 1)
214
216
#define MSDC_MMAP_FLAG (0x1 << 2)
215
217
218
+ #define MTK_MMC_AUTOSUSPEND_DELAY 50
216
219
#define CMD_TIMEOUT (HZ/10 * 5) /* 100ms x5 */
217
220
#define DAT_TIMEOUT (HZ * 5) /* 1000ms x5 */
218
221
@@ -255,6 +258,15 @@ struct msdc_dma {
255
258
dma_addr_t bd_addr ; /* the physical address of bd array */
256
259
};
257
260
261
+ struct msdc_save_para {
262
+ u32 msdc_cfg ;
263
+ u32 iocon ;
264
+ u32 sdc_cfg ;
265
+ u32 pad_tune ;
266
+ u32 patch_bit0 ;
267
+ u32 patch_bit1 ;
268
+ };
269
+
258
270
struct msdc_host {
259
271
struct device * dev ;
260
272
struct mmc_host * mmc ; /* mmc structure */
@@ -287,6 +299,7 @@ struct msdc_host {
287
299
u32 sclk ; /* SD/MS bus clock frequency */
288
300
bool ddr ;
289
301
bool vqmmc_enabled ;
302
+ struct msdc_save_para save_para ; /* used when gate HCLK */
290
303
};
291
304
292
305
static void sdr_set_bits (void __iomem * reg , u32 bs )
@@ -678,6 +691,9 @@ static void msdc_request_done(struct msdc_host *host, struct mmc_request *mrq)
678
691
if (mrq -> data )
679
692
msdc_unprepare_data (host , mrq );
680
693
mmc_request_done (host -> mmc , mrq );
694
+
695
+ pm_runtime_mark_last_busy (host -> dev );
696
+ pm_runtime_put_autosuspend (host -> dev );
681
697
}
682
698
683
699
/* returns true if command is fully handled; returns false otherwise */
@@ -832,6 +848,8 @@ static void msdc_ops_request(struct mmc_host *mmc, struct mmc_request *mrq)
832
848
WARN_ON (host -> mrq );
833
849
host -> mrq = mrq ;
834
850
851
+ pm_runtime_get_sync (host -> dev );
852
+
835
853
if (mrq -> data )
836
854
msdc_prepare_data (host , mrq );
837
855
@@ -1146,6 +1164,8 @@ static void msdc_ops_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
1146
1164
int ret ;
1147
1165
u32 ddr = 0 ;
1148
1166
1167
+ pm_runtime_get_sync (host -> dev );
1168
+
1149
1169
if (ios -> timing == MMC_TIMING_UHS_DDR50 ||
1150
1170
ios -> timing == MMC_TIMING_MMC_DDR52 )
1151
1171
ddr = 1 ;
@@ -1160,7 +1180,7 @@ static void msdc_ops_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
1160
1180
ios -> vdd );
1161
1181
if (ret ) {
1162
1182
dev_err (host -> dev , "Failed to set vmmc power!\n" );
1163
- return ;
1183
+ goto end ;
1164
1184
}
1165
1185
}
1166
1186
break ;
@@ -1188,6 +1208,10 @@ static void msdc_ops_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
1188
1208
1189
1209
if (host -> mclk != ios -> clock || host -> ddr != ddr )
1190
1210
msdc_set_mclk (host , ddr , ios -> clock );
1211
+
1212
+ end :
1213
+ pm_runtime_mark_last_busy (host -> dev );
1214
+ pm_runtime_put_autosuspend (host -> dev );
1191
1215
}
1192
1216
1193
1217
static struct mmc_host_ops mt_msdc_ops = {
@@ -1311,12 +1335,18 @@ static int msdc_drv_probe(struct platform_device *pdev)
1311
1335
if (ret )
1312
1336
goto release ;
1313
1337
1338
+ pm_runtime_set_active (host -> dev );
1339
+ pm_runtime_set_autosuspend_delay (host -> dev , MTK_MMC_AUTOSUSPEND_DELAY );
1340
+ pm_runtime_use_autosuspend (host -> dev );
1341
+ pm_runtime_enable (host -> dev );
1314
1342
ret = mmc_add_host (mmc );
1343
+
1315
1344
if (ret )
1316
- goto release ;
1345
+ goto end ;
1317
1346
1318
1347
return 0 ;
1319
-
1348
+ end :
1349
+ pm_runtime_disable (host -> dev );
1320
1350
release :
1321
1351
platform_set_drvdata (pdev , NULL );
1322
1352
msdc_deinit_hw (host );
@@ -1344,11 +1374,15 @@ static int msdc_drv_remove(struct platform_device *pdev)
1344
1374
mmc = platform_get_drvdata (pdev );
1345
1375
host = mmc_priv (mmc );
1346
1376
1377
+ pm_runtime_get_sync (host -> dev );
1378
+
1347
1379
platform_set_drvdata (pdev , NULL );
1348
1380
mmc_remove_host (host -> mmc );
1349
1381
msdc_deinit_hw (host );
1350
1382
msdc_gate_clock (host );
1351
1383
1384
+ pm_runtime_disable (host -> dev );
1385
+ pm_runtime_put_noidle (host -> dev );
1352
1386
dma_free_coherent (& pdev -> dev ,
1353
1387
sizeof (struct mt_gpdma_desc ),
1354
1388
host -> dma .gpd , host -> dma .gpd_addr );
@@ -1360,6 +1394,54 @@ static int msdc_drv_remove(struct platform_device *pdev)
1360
1394
return 0 ;
1361
1395
}
1362
1396
1397
+ #ifdef CONFIG_PM
1398
+ static void msdc_save_reg (struct msdc_host * host )
1399
+ {
1400
+ host -> save_para .msdc_cfg = readl (host -> base + MSDC_CFG );
1401
+ host -> save_para .iocon = readl (host -> base + MSDC_IOCON );
1402
+ host -> save_para .sdc_cfg = readl (host -> base + SDC_CFG );
1403
+ host -> save_para .pad_tune = readl (host -> base + MSDC_PAD_TUNE );
1404
+ host -> save_para .patch_bit0 = readl (host -> base + MSDC_PATCH_BIT );
1405
+ host -> save_para .patch_bit1 = readl (host -> base + MSDC_PATCH_BIT1 );
1406
+ }
1407
+
1408
+ static void msdc_restore_reg (struct msdc_host * host )
1409
+ {
1410
+ writel (host -> save_para .msdc_cfg , host -> base + MSDC_CFG );
1411
+ writel (host -> save_para .iocon , host -> base + MSDC_IOCON );
1412
+ writel (host -> save_para .sdc_cfg , host -> base + SDC_CFG );
1413
+ writel (host -> save_para .pad_tune , host -> base + MSDC_PAD_TUNE );
1414
+ writel (host -> save_para .patch_bit0 , host -> base + MSDC_PATCH_BIT );
1415
+ writel (host -> save_para .patch_bit1 , host -> base + MSDC_PATCH_BIT1 );
1416
+ }
1417
+
1418
+ static int msdc_runtime_suspend (struct device * dev )
1419
+ {
1420
+ struct mmc_host * mmc = dev_get_drvdata (dev );
1421
+ struct msdc_host * host = mmc_priv (mmc );
1422
+
1423
+ msdc_save_reg (host );
1424
+ msdc_gate_clock (host );
1425
+ return 0 ;
1426
+ }
1427
+
1428
+ static int msdc_runtime_resume (struct device * dev )
1429
+ {
1430
+ struct mmc_host * mmc = dev_get_drvdata (dev );
1431
+ struct msdc_host * host = mmc_priv (mmc );
1432
+
1433
+ msdc_ungate_clock (host );
1434
+ msdc_restore_reg (host );
1435
+ return 0 ;
1436
+ }
1437
+ #endif
1438
+
1439
+ static const struct dev_pm_ops msdc_dev_pm_ops = {
1440
+ SET_SYSTEM_SLEEP_PM_OPS (pm_runtime_force_suspend ,
1441
+ pm_runtime_force_resume )
1442
+ SET_RUNTIME_PM_OPS (msdc_runtime_suspend , msdc_runtime_resume , NULL )
1443
+ };
1444
+
1363
1445
static const struct of_device_id msdc_of_ids [] = {
1364
1446
{ .compatible = "mediatek,mt8135-mmc" , },
1365
1447
{}
@@ -1371,6 +1453,7 @@ static struct platform_driver mt_msdc_driver = {
1371
1453
.driver = {
1372
1454
.name = "mtk-msdc" ,
1373
1455
.of_match_table = msdc_of_ids ,
1456
+ .pm = & msdc_dev_pm_ops ,
1374
1457
},
1375
1458
};
1376
1459
0 commit comments