blob: 9ac8a25e888fc8218dce8aba7468eeca06908ecf [file] [log] [blame]
developer5d148cb2023-06-02 13:08:11 +08001From 80d83b8abe9bc8878ba7a40b4e399b8ea2ff8ad2 Mon Sep 17 00:00:00 2001
2From: Sam Shih <sam.shih@mediatek.com>
3Date: Fri, 2 Jun 2023 13:06:09 +0800
4Subject: [PATCH]
5 [spi-and-storage][999-2301-mtk-sd-Add-subsys-clock-control.patch]
6
7---
8 drivers/mmc/host/mtk-sd.c | 76 +++++++++++++++++++++++++++++----------
9 1 file changed, 58 insertions(+), 18 deletions(-)
10
11diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
12index b25e8567f..ef344a4bd 100644
developer30389d92022-05-10 09:35:17 +080013--- a/drivers/mmc/host/mtk-sd.c
14+++ b/drivers/mmc/host/mtk-sd.c
15@@ -33,6 +33,7 @@
16 #include <linux/mmc/slot-gpio.h>
17
18 #define MAX_BD_NUM 1024
19+#define MSDC_NR_CLOCKS 3
20
21 /*--------------------------------------------------------------------------*/
22 /* Common Definition */
23@@ -419,6 +420,8 @@ struct msdc_host {
24 struct clk *h_clk; /* msdc h_clk */
25 struct clk *bus_clk; /* bus clock which used to access register */
26 struct clk *src_clk_cg; /* msdc source clock control gate */
27+ struct clk *sys_clk_cg; /* msdc subsys clock control gate */
28+ struct clk_bulk_data bulk_clks[MSDC_NR_CLOCKS];
29 u32 mclk; /* mmc subsystem clock frequency */
30 u32 src_clk_freq; /* source clock frequency */
31 unsigned char timing;
developer5d148cb2023-06-02 13:08:11 +080032@@ -745,6 +748,7 @@ static void msdc_set_timeout(struct msdc_host *host, u32 ns, u32 clks)
developer30389d92022-05-10 09:35:17 +080033
34 static void msdc_gate_clock(struct msdc_host *host)
35 {
36+ clk_bulk_disable_unprepare(MSDC_NR_CLOCKS, host->bulk_clks);
37 clk_disable_unprepare(host->src_clk_cg);
38 clk_disable_unprepare(host->src_clk);
39 clk_disable_unprepare(host->bus_clk);
developer5d148cb2023-06-02 13:08:11 +080040@@ -753,10 +757,18 @@ static void msdc_gate_clock(struct msdc_host *host)
developer30389d92022-05-10 09:35:17 +080041
42 static void msdc_ungate_clock(struct msdc_host *host)
43 {
44+ int ret;
45+
46 clk_prepare_enable(host->h_clk);
47 clk_prepare_enable(host->bus_clk);
48 clk_prepare_enable(host->src_clk);
49 clk_prepare_enable(host->src_clk_cg);
50+ ret = clk_bulk_prepare_enable(MSDC_NR_CLOCKS, host->bulk_clks);
51+ if (ret) {
52+ dev_err(host->dev, "Cannot enable pclk/axi/ahb clock gates\n");
53+ return;
54+ }
55+
56 while (!(readl(host->base + MSDC_CFG) & MSDC_CFG_CKSTB))
57 cpu_relax();
58 }
developer5d148cb2023-06-02 13:08:11 +080059@@ -2195,6 +2207,50 @@ static void msdc_of_property_parse(struct platform_device *pdev,
developer30389d92022-05-10 09:35:17 +080060 host->hs400_cmd_resp_sel_rising = false;
61 }
62
63+static int msdc_of_clock_parse(struct platform_device *pdev,
64+ struct msdc_host *host)
65+{
66+ int ret;
67+
68+ host->src_clk = devm_clk_get(&pdev->dev, "source");
69+ if (IS_ERR(host->src_clk))
70+ return PTR_ERR(host->src_clk);
71+
72+ host->h_clk = devm_clk_get(&pdev->dev, "hclk");
73+ if (IS_ERR(host->h_clk))
74+ return PTR_ERR(host->h_clk);
75+
76+ host->bus_clk = devm_clk_get_optional(&pdev->dev, "bus_clk");
77+ if (IS_ERR(host->bus_clk))
78+ host->bus_clk = NULL;
79+
80+
81+ /*source clock control gate is optional clock*/
82+ host->src_clk_cg = devm_clk_get_optional(&pdev->dev, "source_cg");
83+ if (IS_ERR(host->src_clk_cg))
84+ host->src_clk_cg = NULL;
85+
86+ host->sys_clk_cg = devm_clk_get_optional(&pdev->dev, "sys_cg");
87+ if (IS_ERR(host->sys_clk_cg))
88+ host->sys_clk_cg = NULL;
89+
90+ /* If present, always enable for this clock gate */
91+ clk_prepare_enable(host->sys_clk_cg);
92+
93+ host->bulk_clks[0].id = "pclk_cg";
94+ host->bulk_clks[1].id = "axi_cg";
95+ host->bulk_clks[2].id = "ahb_cg";
96+
97+ ret = devm_clk_bulk_get_optional(&pdev->dev, MSDC_NR_CLOCKS,
98+ host->bulk_clks);
99+ if (ret) {
100+ dev_err(&pdev->dev, "Cannot get pclk/axi/ahb clock gates\n");
101+ return ret;
102+ }
103+
104+ return 0;
105+}
106+
107 static int msdc_drv_probe(struct platform_device *pdev)
108 {
109 struct mmc_host *mmc;
developer5d148cb2023-06-02 13:08:11 +0800110@@ -2235,25 +2291,9 @@ static int msdc_drv_probe(struct platform_device *pdev)
developer30389d92022-05-10 09:35:17 +0800111 if (ret)
112 goto host_free;
113
114- host->src_clk = devm_clk_get(&pdev->dev, "source");
115- if (IS_ERR(host->src_clk)) {
116- ret = PTR_ERR(host->src_clk);
117- goto host_free;
118- }
119-
120- host->h_clk = devm_clk_get(&pdev->dev, "hclk");
121- if (IS_ERR(host->h_clk)) {
122- ret = PTR_ERR(host->h_clk);
123+ ret = msdc_of_clock_parse(pdev, host);
124+ if (ret)
125 goto host_free;
126- }
127-
128- host->bus_clk = devm_clk_get(&pdev->dev, "bus_clk");
129- if (IS_ERR(host->bus_clk))
130- host->bus_clk = NULL;
131- /*source clock control gate is optional clock*/
132- host->src_clk_cg = devm_clk_get(&pdev->dev, "source_cg");
133- if (IS_ERR(host->src_clk_cg))
134- host->src_clk_cg = NULL;
135
136 host->reset = devm_reset_control_get_optional_exclusive(&pdev->dev,
137 "hrst");
developer5d148cb2023-06-02 13:08:11 +0800138--
1392.34.1
140