8
8
#include <linux/iommu.h>
9
9
#include <linux/module.h>
10
10
#include <linux/of_device.h>
11
+ #include <linux/pm_runtime.h>
11
12
#include <linux/reset.h>
12
13
14
+ #include <soc/tegra/common.h>
15
+
13
16
#include "drm.h"
14
17
#include "gem.h"
15
18
#include "gr2d.h"
16
19
20
+ enum {
21
+ RST_MC ,
22
+ RST_GR2D ,
23
+ RST_GR2D_MAX ,
24
+ };
25
+
17
26
struct gr2d_soc {
18
27
unsigned int version ;
19
28
};
20
29
21
30
struct gr2d {
22
31
struct tegra_drm_client client ;
23
32
struct host1x_channel * channel ;
24
- struct reset_control * rst ;
25
33
struct clk * clk ;
26
34
35
+ struct reset_control_bulk_data resets [RST_GR2D_MAX ];
36
+ unsigned int nresets ;
37
+
27
38
const struct gr2d_soc * soc ;
28
39
29
40
DECLARE_BITMAP (addr_regs , GR2D_NUM_REGS );
@@ -59,15 +70,22 @@ static int gr2d_init(struct host1x_client *client)
59
70
goto free ;
60
71
}
61
72
73
+ pm_runtime_enable (client -> dev );
74
+ pm_runtime_use_autosuspend (client -> dev );
75
+ pm_runtime_set_autosuspend_delay (client -> dev , 200 );
76
+
62
77
err = tegra_drm_register_client (dev -> dev_private , drm );
63
78
if (err < 0 ) {
64
79
dev_err (client -> dev , "failed to register client: %d\n" , err );
65
- goto detach ;
80
+ goto disable_rpm ;
66
81
}
67
82
68
83
return 0 ;
69
84
70
- detach :
85
+ disable_rpm :
86
+ pm_runtime_dont_use_autosuspend (client -> dev );
87
+ pm_runtime_force_suspend (client -> dev );
88
+
71
89
host1x_client_iommu_detach (client );
72
90
free :
73
91
host1x_syncpt_put (client -> syncpts [0 ]);
@@ -88,10 +106,15 @@ static int gr2d_exit(struct host1x_client *client)
88
106
if (err < 0 )
89
107
return err ;
90
108
109
+ pm_runtime_dont_use_autosuspend (client -> dev );
110
+ pm_runtime_force_suspend (client -> dev );
111
+
91
112
host1x_client_iommu_detach (client );
92
113
host1x_syncpt_put (client -> syncpts [0 ]);
93
114
host1x_channel_put (gr2d -> channel );
94
115
116
+ gr2d -> channel = NULL ;
117
+
95
118
return 0 ;
96
119
}
97
120
@@ -104,17 +127,25 @@ static int gr2d_open_channel(struct tegra_drm_client *client,
104
127
struct tegra_drm_context * context )
105
128
{
106
129
struct gr2d * gr2d = to_gr2d (client );
130
+ int err ;
131
+
132
+ err = pm_runtime_resume_and_get (client -> base .dev );
133
+ if (err )
134
+ return err ;
107
135
108
136
context -> channel = host1x_channel_get (gr2d -> channel );
109
- if (!context -> channel )
137
+ if (!context -> channel ) {
138
+ pm_runtime_put (client -> base .dev );
110
139
return - ENOMEM ;
140
+ }
111
141
112
142
return 0 ;
113
143
}
114
144
115
145
static void gr2d_close_channel (struct tegra_drm_context * context )
116
146
{
117
147
host1x_channel_put (context -> channel );
148
+ pm_runtime_put (context -> client -> base .dev );
118
149
}
119
150
120
151
static int gr2d_is_addr_reg (struct device * dev , u32 class , u32 offset )
@@ -193,6 +224,27 @@ static const u32 gr2d_addr_regs[] = {
193
224
GR2D_VA_BASE_ADDR_SB ,
194
225
};
195
226
227
+ static int gr2d_get_resets (struct device * dev , struct gr2d * gr2d )
228
+ {
229
+ int err ;
230
+
231
+ gr2d -> resets [RST_MC ].id = "mc" ;
232
+ gr2d -> resets [RST_GR2D ].id = "2d" ;
233
+ gr2d -> nresets = RST_GR2D_MAX ;
234
+
235
+ err = devm_reset_control_bulk_get_optional_exclusive_released (
236
+ dev , gr2d -> nresets , gr2d -> resets );
237
+ if (err ) {
238
+ dev_err (dev , "failed to get reset: %d\n" , err );
239
+ return err ;
240
+ }
241
+
242
+ if (WARN_ON (!gr2d -> resets [RST_GR2D ].rstc ))
243
+ return - ENOENT ;
244
+
245
+ return 0 ;
246
+ }
247
+
196
248
static int gr2d_probe (struct platform_device * pdev )
197
249
{
198
250
struct device * dev = & pdev -> dev ;
@@ -205,37 +257,23 @@ static int gr2d_probe(struct platform_device *pdev)
205
257
if (!gr2d )
206
258
return - ENOMEM ;
207
259
260
+ platform_set_drvdata (pdev , gr2d );
261
+
208
262
gr2d -> soc = of_device_get_match_data (dev );
209
263
210
264
syncpts = devm_kzalloc (dev , sizeof (* syncpts ), GFP_KERNEL );
211
265
if (!syncpts )
212
266
return - ENOMEM ;
213
267
214
- gr2d -> rst = devm_reset_control_get (dev , NULL );
215
- if (IS_ERR (gr2d -> rst )) {
216
- dev_err (dev , "cannot get reset\n" );
217
- return PTR_ERR (gr2d -> rst );
218
- }
219
-
220
268
gr2d -> clk = devm_clk_get (dev , NULL );
221
269
if (IS_ERR (gr2d -> clk )) {
222
270
dev_err (dev , "cannot get clock\n" );
223
271
return PTR_ERR (gr2d -> clk );
224
272
}
225
273
226
- err = clk_prepare_enable (gr2d -> clk );
227
- if (err ) {
228
- dev_err (dev , "cannot turn on clock\n" );
274
+ err = gr2d_get_resets (dev , gr2d );
275
+ if (err )
229
276
return err ;
230
- }
231
-
232
- usleep_range (2000 , 4000 );
233
-
234
- err = reset_control_deassert (gr2d -> rst );
235
- if (err < 0 ) {
236
- dev_err (dev , "failed to deassert reset: %d\n" , err );
237
- goto disable_clk ;
238
- }
239
277
240
278
INIT_LIST_HEAD (& gr2d -> client .base .list );
241
279
gr2d -> client .base .ops = & gr2d_client_ops ;
@@ -248,26 +286,21 @@ static int gr2d_probe(struct platform_device *pdev)
248
286
gr2d -> client .version = gr2d -> soc -> version ;
249
287
gr2d -> client .ops = & gr2d_ops ;
250
288
289
+ err = devm_tegra_core_dev_init_opp_table_common (dev );
290
+ if (err )
291
+ return err ;
292
+
251
293
err = host1x_client_register (& gr2d -> client .base );
252
294
if (err < 0 ) {
253
295
dev_err (dev , "failed to register host1x client: %d\n" , err );
254
- goto assert_rst ;
296
+ return err ;
255
297
}
256
298
257
299
/* initialize address register map */
258
300
for (i = 0 ; i < ARRAY_SIZE (gr2d_addr_regs ); i ++ )
259
301
set_bit (gr2d_addr_regs [i ], gr2d -> addr_regs );
260
302
261
- platform_set_drvdata (pdev , gr2d );
262
-
263
303
return 0 ;
264
-
265
- assert_rst :
266
- (void )reset_control_assert (gr2d -> rst );
267
- disable_clk :
268
- clk_disable_unprepare (gr2d -> clk );
269
-
270
- return err ;
271
304
}
272
305
273
306
static int gr2d_remove (struct platform_device * pdev )
@@ -282,21 +315,100 @@ static int gr2d_remove(struct platform_device *pdev)
282
315
return err ;
283
316
}
284
317
285
- err = reset_control_assert (gr2d -> rst );
286
- if (err < 0 )
287
- dev_err (& pdev -> dev , "failed to assert reset: %d\n" , err );
318
+ return 0 ;
319
+ }
288
320
289
- usleep_range (2000 , 4000 );
321
+ static int __maybe_unused gr2d_runtime_suspend (struct device * dev )
322
+ {
323
+ struct gr2d * gr2d = dev_get_drvdata (dev );
324
+ int err ;
325
+
326
+ host1x_channel_stop (gr2d -> channel );
327
+ reset_control_bulk_release (gr2d -> nresets , gr2d -> resets );
328
+
329
+ /*
330
+ * GR2D module shouldn't be reset while hardware is idling, otherwise
331
+ * host1x's cmdproc will stuck on trying to access any G2 register
332
+ * after reset. GR2D module could be either hot-reset or reset after
333
+ * power-gating of the HEG partition. Hence we will put in reset only
334
+ * the memory client part of the module, the HEG GENPD will take care
335
+ * of resetting GR2D module across power-gating.
336
+ *
337
+ * On Tegra20 there is no HEG partition, but it's okay to have
338
+ * undetermined h/w state since userspace is expected to reprogram
339
+ * the state on each job submission anyways.
340
+ */
341
+ err = reset_control_acquire (gr2d -> resets [RST_MC ].rstc );
342
+ if (err ) {
343
+ dev_err (dev , "failed to acquire MC reset: %d\n" , err );
344
+ goto acquire_reset ;
345
+ }
346
+
347
+ err = reset_control_assert (gr2d -> resets [RST_MC ].rstc );
348
+ reset_control_release (gr2d -> resets [RST_MC ].rstc );
349
+ if (err ) {
350
+ dev_err (dev , "failed to assert MC reset: %d\n" , err );
351
+ goto acquire_reset ;
352
+ }
290
353
291
354
clk_disable_unprepare (gr2d -> clk );
292
355
293
356
return 0 ;
357
+
358
+ acquire_reset :
359
+ reset_control_bulk_acquire (gr2d -> nresets , gr2d -> resets );
360
+ reset_control_bulk_deassert (gr2d -> nresets , gr2d -> resets );
361
+
362
+ return err ;
363
+ }
364
+
365
+ static int __maybe_unused gr2d_runtime_resume (struct device * dev )
366
+ {
367
+ struct gr2d * gr2d = dev_get_drvdata (dev );
368
+ int err ;
369
+
370
+ err = reset_control_bulk_acquire (gr2d -> nresets , gr2d -> resets );
371
+ if (err ) {
372
+ dev_err (dev , "failed to acquire reset: %d\n" , err );
373
+ return err ;
374
+ }
375
+
376
+ err = clk_prepare_enable (gr2d -> clk );
377
+ if (err ) {
378
+ dev_err (dev , "failed to enable clock: %d\n" , err );
379
+ goto release_reset ;
380
+ }
381
+
382
+ usleep_range (2000 , 4000 );
383
+
384
+ /* this is a reset array which deasserts both 2D MC and 2D itself */
385
+ err = reset_control_bulk_deassert (gr2d -> nresets , gr2d -> resets );
386
+ if (err ) {
387
+ dev_err (dev , "failed to deassert reset: %d\n" , err );
388
+ goto disable_clk ;
389
+ }
390
+
391
+ return 0 ;
392
+
393
+ disable_clk :
394
+ clk_disable_unprepare (gr2d -> clk );
395
+ release_reset :
396
+ reset_control_bulk_release (gr2d -> nresets , gr2d -> resets );
397
+
398
+ return err ;
294
399
}
295
400
401
+ static const struct dev_pm_ops tegra_gr2d_pm = {
402
+ SET_RUNTIME_PM_OPS (gr2d_runtime_suspend , gr2d_runtime_resume , NULL )
403
+ SET_SYSTEM_SLEEP_PM_OPS (pm_runtime_force_suspend ,
404
+ pm_runtime_force_resume )
405
+ };
406
+
296
407
struct platform_driver tegra_gr2d_driver = {
297
408
.driver = {
298
409
.name = "tegra-gr2d" ,
299
410
.of_match_table = gr2d_match ,
411
+ .pm = & tegra_gr2d_pm ,
300
412
},
301
413
.probe = gr2d_probe ,
302
414
.remove = gr2d_remove ,
0 commit comments