1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) 2013 Avionic Design GmbH
4 * Copyright (C) 2013 NVIDIA Corporation
8 #include <linux/delay.h>
9 #include <linux/host1x.h>
10 #include <linux/iommu.h>
11 #include <linux/module.h>
13 #include <linux/platform_device.h>
14 #include <linux/pm_domain.h>
15 #include <linux/pm_opp.h>
16 #include <linux/pm_runtime.h>
17 #include <linux/reset.h>
19 #include <soc/tegra/common.h>
20 #include <soc/tegra/pmc.h>
36 unsigned int num_clocks
;
37 unsigned int num_resets
;
41 struct tegra_drm_client client
;
42 struct host1x_channel
*channel
;
44 const struct gr3d_soc
*soc
;
45 struct clk_bulk_data
*clocks
;
47 struct reset_control_bulk_data resets
[RST_GR3D_MAX
];
49 struct dev_pm_domain_list
*pd_list
;
51 DECLARE_BITMAP(addr_regs
, GR3D_NUM_REGS
);
54 static inline struct gr3d
*to_gr3d(struct tegra_drm_client
*client
)
56 return container_of(client
, struct gr3d
, client
);
59 static int gr3d_init(struct host1x_client
*client
)
61 struct tegra_drm_client
*drm
= host1x_to_drm_client(client
);
62 struct drm_device
*dev
= dev_get_drvdata(client
->host
);
63 unsigned long flags
= HOST1X_SYNCPT_HAS_BASE
;
64 struct gr3d
*gr3d
= to_gr3d(drm
);
67 gr3d
->channel
= host1x_channel_request(client
);
71 client
->syncpts
[0] = host1x_syncpt_request(client
, flags
);
72 if (!client
->syncpts
[0]) {
74 dev_err(client
->dev
, "failed to request syncpoint: %d\n", err
);
78 err
= host1x_client_iommu_attach(client
);
80 dev_err(client
->dev
, "failed to attach to domain: %d\n", err
);
84 err
= tegra_drm_register_client(dev
->dev_private
, drm
);
86 dev_err(client
->dev
, "failed to register client: %d\n", err
);
93 host1x_client_iommu_detach(client
);
95 host1x_syncpt_put(client
->syncpts
[0]);
97 host1x_channel_put(gr3d
->channel
);
101 static int gr3d_exit(struct host1x_client
*client
)
103 struct tegra_drm_client
*drm
= host1x_to_drm_client(client
);
104 struct drm_device
*dev
= dev_get_drvdata(client
->host
);
105 struct gr3d
*gr3d
= to_gr3d(drm
);
108 err
= tegra_drm_unregister_client(dev
->dev_private
, drm
);
112 pm_runtime_dont_use_autosuspend(client
->dev
);
113 pm_runtime_force_suspend(client
->dev
);
115 host1x_client_iommu_detach(client
);
116 host1x_syncpt_put(client
->syncpts
[0]);
117 host1x_channel_put(gr3d
->channel
);
119 gr3d
->channel
= NULL
;
124 static const struct host1x_client_ops gr3d_client_ops
= {
129 static int gr3d_open_channel(struct tegra_drm_client
*client
,
130 struct tegra_drm_context
*context
)
132 struct gr3d
*gr3d
= to_gr3d(client
);
134 context
->channel
= host1x_channel_get(gr3d
->channel
);
135 if (!context
->channel
)
141 static void gr3d_close_channel(struct tegra_drm_context
*context
)
143 host1x_channel_put(context
->channel
);
146 static int gr3d_is_addr_reg(struct device
*dev
, u32
class, u32 offset
)
148 struct gr3d
*gr3d
= dev_get_drvdata(dev
);
151 case HOST1X_CLASS_HOST1X
:
157 case HOST1X_CLASS_GR3D
:
158 if (offset
>= GR3D_NUM_REGS
)
161 if (test_bit(offset
, gr3d
->addr_regs
))
170 static const struct tegra_drm_client_ops gr3d_ops
= {
171 .open_channel
= gr3d_open_channel
,
172 .close_channel
= gr3d_close_channel
,
173 .is_addr_reg
= gr3d_is_addr_reg
,
174 .submit
= tegra_drm_submit
,
177 static const struct gr3d_soc tegra20_gr3d_soc
= {
183 static const struct gr3d_soc tegra30_gr3d_soc
= {
189 static const struct gr3d_soc tegra114_gr3d_soc
= {
195 static const struct of_device_id tegra_gr3d_match
[] = {
196 { .compatible
= "nvidia,tegra114-gr3d", .data
= &tegra114_gr3d_soc
},
197 { .compatible
= "nvidia,tegra30-gr3d", .data
= &tegra30_gr3d_soc
},
198 { .compatible
= "nvidia,tegra20-gr3d", .data
= &tegra20_gr3d_soc
},
201 MODULE_DEVICE_TABLE(of
, tegra_gr3d_match
);
203 static const u32 gr3d_addr_regs
[] = {
204 GR3D_IDX_ATTRIBUTE( 0),
205 GR3D_IDX_ATTRIBUTE( 1),
206 GR3D_IDX_ATTRIBUTE( 2),
207 GR3D_IDX_ATTRIBUTE( 3),
208 GR3D_IDX_ATTRIBUTE( 4),
209 GR3D_IDX_ATTRIBUTE( 5),
210 GR3D_IDX_ATTRIBUTE( 6),
211 GR3D_IDX_ATTRIBUTE( 7),
212 GR3D_IDX_ATTRIBUTE( 8),
213 GR3D_IDX_ATTRIBUTE( 9),
214 GR3D_IDX_ATTRIBUTE(10),
215 GR3D_IDX_ATTRIBUTE(11),
216 GR3D_IDX_ATTRIBUTE(12),
217 GR3D_IDX_ATTRIBUTE(13),
218 GR3D_IDX_ATTRIBUTE(14),
219 GR3D_IDX_ATTRIBUTE(15),
224 GR3D_TEX_TEX_ADDR( 0),
225 GR3D_TEX_TEX_ADDR( 1),
226 GR3D_TEX_TEX_ADDR( 2),
227 GR3D_TEX_TEX_ADDR( 3),
228 GR3D_TEX_TEX_ADDR( 4),
229 GR3D_TEX_TEX_ADDR( 5),
230 GR3D_TEX_TEX_ADDR( 6),
231 GR3D_TEX_TEX_ADDR( 7),
232 GR3D_TEX_TEX_ADDR( 8),
233 GR3D_TEX_TEX_ADDR( 9),
234 GR3D_TEX_TEX_ADDR(10),
235 GR3D_TEX_TEX_ADDR(11),
236 GR3D_TEX_TEX_ADDR(12),
237 GR3D_TEX_TEX_ADDR(13),
238 GR3D_TEX_TEX_ADDR(14),
239 GR3D_TEX_TEX_ADDR(15),
240 GR3D_DW_MEMORY_OUTPUT_ADDRESS
,
241 GR3D_GLOBAL_SURFADDR( 0),
242 GR3D_GLOBAL_SURFADDR( 1),
243 GR3D_GLOBAL_SURFADDR( 2),
244 GR3D_GLOBAL_SURFADDR( 3),
245 GR3D_GLOBAL_SURFADDR( 4),
246 GR3D_GLOBAL_SURFADDR( 5),
247 GR3D_GLOBAL_SURFADDR( 6),
248 GR3D_GLOBAL_SURFADDR( 7),
249 GR3D_GLOBAL_SURFADDR( 8),
250 GR3D_GLOBAL_SURFADDR( 9),
251 GR3D_GLOBAL_SURFADDR(10),
252 GR3D_GLOBAL_SURFADDR(11),
253 GR3D_GLOBAL_SURFADDR(12),
254 GR3D_GLOBAL_SURFADDR(13),
255 GR3D_GLOBAL_SURFADDR(14),
256 GR3D_GLOBAL_SURFADDR(15),
257 GR3D_GLOBAL_SPILLSURFADDR
,
258 GR3D_GLOBAL_SURFOVERADDR( 0),
259 GR3D_GLOBAL_SURFOVERADDR( 1),
260 GR3D_GLOBAL_SURFOVERADDR( 2),
261 GR3D_GLOBAL_SURFOVERADDR( 3),
262 GR3D_GLOBAL_SURFOVERADDR( 4),
263 GR3D_GLOBAL_SURFOVERADDR( 5),
264 GR3D_GLOBAL_SURFOVERADDR( 6),
265 GR3D_GLOBAL_SURFOVERADDR( 7),
266 GR3D_GLOBAL_SURFOVERADDR( 8),
267 GR3D_GLOBAL_SURFOVERADDR( 9),
268 GR3D_GLOBAL_SURFOVERADDR(10),
269 GR3D_GLOBAL_SURFOVERADDR(11),
270 GR3D_GLOBAL_SURFOVERADDR(12),
271 GR3D_GLOBAL_SURFOVERADDR(13),
272 GR3D_GLOBAL_SURFOVERADDR(14),
273 GR3D_GLOBAL_SURFOVERADDR(15),
274 GR3D_GLOBAL_SAMP01SURFADDR( 0),
275 GR3D_GLOBAL_SAMP01SURFADDR( 1),
276 GR3D_GLOBAL_SAMP01SURFADDR( 2),
277 GR3D_GLOBAL_SAMP01SURFADDR( 3),
278 GR3D_GLOBAL_SAMP01SURFADDR( 4),
279 GR3D_GLOBAL_SAMP01SURFADDR( 5),
280 GR3D_GLOBAL_SAMP01SURFADDR( 6),
281 GR3D_GLOBAL_SAMP01SURFADDR( 7),
282 GR3D_GLOBAL_SAMP01SURFADDR( 8),
283 GR3D_GLOBAL_SAMP01SURFADDR( 9),
284 GR3D_GLOBAL_SAMP01SURFADDR(10),
285 GR3D_GLOBAL_SAMP01SURFADDR(11),
286 GR3D_GLOBAL_SAMP01SURFADDR(12),
287 GR3D_GLOBAL_SAMP01SURFADDR(13),
288 GR3D_GLOBAL_SAMP01SURFADDR(14),
289 GR3D_GLOBAL_SAMP01SURFADDR(15),
290 GR3D_GLOBAL_SAMP23SURFADDR( 0),
291 GR3D_GLOBAL_SAMP23SURFADDR( 1),
292 GR3D_GLOBAL_SAMP23SURFADDR( 2),
293 GR3D_GLOBAL_SAMP23SURFADDR( 3),
294 GR3D_GLOBAL_SAMP23SURFADDR( 4),
295 GR3D_GLOBAL_SAMP23SURFADDR( 5),
296 GR3D_GLOBAL_SAMP23SURFADDR( 6),
297 GR3D_GLOBAL_SAMP23SURFADDR( 7),
298 GR3D_GLOBAL_SAMP23SURFADDR( 8),
299 GR3D_GLOBAL_SAMP23SURFADDR( 9),
300 GR3D_GLOBAL_SAMP23SURFADDR(10),
301 GR3D_GLOBAL_SAMP23SURFADDR(11),
302 GR3D_GLOBAL_SAMP23SURFADDR(12),
303 GR3D_GLOBAL_SAMP23SURFADDR(13),
304 GR3D_GLOBAL_SAMP23SURFADDR(14),
305 GR3D_GLOBAL_SAMP23SURFADDR(15),
308 static int gr3d_power_up_legacy_domain(struct device
*dev
, const char *name
,
311 struct gr3d
*gr3d
= dev_get_drvdata(dev
);
312 struct reset_control
*reset
;
318 * Tegra20 device-tree doesn't specify 3d clock name and there is only
319 * one clock for Tegra20. Tegra30+ device-trees always specified names
322 if (gr3d
->nclocks
== 1) {
323 if (id
== TEGRA_POWERGATE_3D1
)
326 clk
= gr3d
->clocks
[0].clk
;
328 for (i
= 0; i
< gr3d
->nclocks
; i
++) {
329 if (WARN_ON(!gr3d
->clocks
[i
].id
))
332 if (!strcmp(gr3d
->clocks
[i
].id
, name
)) {
333 clk
= gr3d
->clocks
[i
].clk
;
338 if (WARN_ON(i
== gr3d
->nclocks
))
343 * We use array of resets, which includes MC resets, and MC
344 * reset shouldn't be asserted while hardware is gated because
345 * MC flushing will fail for gated hardware. Hence for legacy
346 * PD we request the individual reset separately.
348 reset
= reset_control_get_exclusive_released(dev
, name
);
350 return PTR_ERR(reset
);
352 err
= reset_control_acquire(reset
);
354 dev_err(dev
, "failed to acquire %s reset: %d\n", name
, err
);
356 err
= tegra_powergate_sequence_power_up(id
, clk
, reset
);
357 reset_control_release(reset
);
360 reset_control_put(reset
);
365 * tegra_powergate_sequence_power_up() leaves clocks enabled,
366 * while GENPD not. Hence keep clock-enable balanced.
368 clk_disable_unprepare(clk
);
373 static int gr3d_init_power(struct device
*dev
, struct gr3d
*gr3d
)
375 struct dev_pm_domain_attach_data pd_data
= {
376 .pd_names
= (const char *[]) { "3d0", "3d1" },
378 .pd_flags
= PD_FLAG_REQUIRED_OPP
,
382 err
= of_count_phandle_with_args(dev
->of_node
, "power-domains",
383 "#power-domain-cells");
389 * Older device-trees don't use GENPD. In this case we should
390 * toggle power domain manually.
392 err
= gr3d_power_up_legacy_domain(dev
, "3d",
397 err
= gr3d_power_up_legacy_domain(dev
, "3d2",
398 TEGRA_POWERGATE_3D1
);
406 * The PM domain core automatically attaches a single power domain,
407 * otherwise it skips attaching completely. We have a single domain
408 * on Tegra20 and two domains on Tegra30+.
413 err
= devm_pm_domain_attach_list(dev
, &pd_data
, &gr3d
->pd_list
);
420 static int gr3d_get_clocks(struct device
*dev
, struct gr3d
*gr3d
)
424 err
= devm_clk_bulk_get_all(dev
, &gr3d
->clocks
);
426 dev_err(dev
, "failed to get clock: %d\n", err
);
431 if (gr3d
->nclocks
!= gr3d
->soc
->num_clocks
) {
432 dev_err(dev
, "invalid number of clocks: %u\n", gr3d
->nclocks
);
439 static int gr3d_get_resets(struct device
*dev
, struct gr3d
*gr3d
)
443 gr3d
->resets
[RST_MC
].id
= "mc";
444 gr3d
->resets
[RST_MC2
].id
= "mc2";
445 gr3d
->resets
[RST_GR3D
].id
= "3d";
446 gr3d
->resets
[RST_GR3D2
].id
= "3d2";
447 gr3d
->nresets
= gr3d
->soc
->num_resets
;
449 err
= devm_reset_control_bulk_get_optional_exclusive_released(
450 dev
, gr3d
->nresets
, gr3d
->resets
);
452 dev_err(dev
, "failed to get reset: %d\n", err
);
456 if (WARN_ON(!gr3d
->resets
[RST_GR3D
].rstc
) ||
457 WARN_ON(!gr3d
->resets
[RST_GR3D2
].rstc
&& gr3d
->nresets
== 4))
463 static int gr3d_probe(struct platform_device
*pdev
)
465 struct host1x_syncpt
**syncpts
;
470 gr3d
= devm_kzalloc(&pdev
->dev
, sizeof(*gr3d
), GFP_KERNEL
);
474 platform_set_drvdata(pdev
, gr3d
);
476 gr3d
->soc
= of_device_get_match_data(&pdev
->dev
);
478 syncpts
= devm_kzalloc(&pdev
->dev
, sizeof(*syncpts
), GFP_KERNEL
);
482 err
= gr3d_get_clocks(&pdev
->dev
, gr3d
);
486 err
= gr3d_get_resets(&pdev
->dev
, gr3d
);
490 err
= gr3d_init_power(&pdev
->dev
, gr3d
);
494 INIT_LIST_HEAD(&gr3d
->client
.base
.list
);
495 gr3d
->client
.base
.ops
= &gr3d_client_ops
;
496 gr3d
->client
.base
.dev
= &pdev
->dev
;
497 gr3d
->client
.base
.class = HOST1X_CLASS_GR3D
;
498 gr3d
->client
.base
.syncpts
= syncpts
;
499 gr3d
->client
.base
.num_syncpts
= 1;
501 INIT_LIST_HEAD(&gr3d
->client
.list
);
502 gr3d
->client
.version
= gr3d
->soc
->version
;
503 gr3d
->client
.ops
= &gr3d_ops
;
505 err
= devm_tegra_core_dev_init_opp_table_common(&pdev
->dev
);
509 err
= host1x_client_register(&gr3d
->client
.base
);
511 dev_err(&pdev
->dev
, "failed to register host1x client: %d\n",
516 /* initialize address register map */
517 for (i
= 0; i
< ARRAY_SIZE(gr3d_addr_regs
); i
++)
518 set_bit(gr3d_addr_regs
[i
], gr3d
->addr_regs
);
523 static void gr3d_remove(struct platform_device
*pdev
)
525 struct gr3d
*gr3d
= platform_get_drvdata(pdev
);
527 pm_runtime_disable(&pdev
->dev
);
528 host1x_client_unregister(&gr3d
->client
.base
);
531 static int __maybe_unused
gr3d_runtime_suspend(struct device
*dev
)
533 struct gr3d
*gr3d
= dev_get_drvdata(dev
);
536 host1x_channel_stop(gr3d
->channel
);
538 err
= reset_control_bulk_assert(gr3d
->nresets
, gr3d
->resets
);
540 dev_err(dev
, "failed to assert reset: %d\n", err
);
544 usleep_range(10, 20);
547 * Older device-trees don't specify MC resets and power-gating can't
548 * be done safely in that case. Hence we will keep the power ungated
549 * for older DTBs. For newer DTBs, GENPD will perform the power-gating.
552 clk_bulk_disable_unprepare(gr3d
->nclocks
, gr3d
->clocks
);
553 reset_control_bulk_release(gr3d
->nresets
, gr3d
->resets
);
558 static int __maybe_unused
gr3d_runtime_resume(struct device
*dev
)
560 struct gr3d
*gr3d
= dev_get_drvdata(dev
);
563 err
= reset_control_bulk_acquire(gr3d
->nresets
, gr3d
->resets
);
565 dev_err(dev
, "failed to acquire reset: %d\n", err
);
569 err
= clk_bulk_prepare_enable(gr3d
->nclocks
, gr3d
->clocks
);
571 dev_err(dev
, "failed to enable clock: %d\n", err
);
575 err
= reset_control_bulk_deassert(gr3d
->nresets
, gr3d
->resets
);
577 dev_err(dev
, "failed to deassert reset: %d\n", err
);
581 pm_runtime_enable(dev
);
582 pm_runtime_use_autosuspend(dev
);
583 pm_runtime_set_autosuspend_delay(dev
, 500);
588 clk_bulk_disable_unprepare(gr3d
->nclocks
, gr3d
->clocks
);
590 reset_control_bulk_release(gr3d
->nresets
, gr3d
->resets
);
595 static const struct dev_pm_ops tegra_gr3d_pm
= {
596 SET_RUNTIME_PM_OPS(gr3d_runtime_suspend
, gr3d_runtime_resume
, NULL
)
597 SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend
,
598 pm_runtime_force_resume
)
601 struct platform_driver tegra_gr3d_driver
= {
603 .name
= "tegra-gr3d",
604 .of_match_table
= tegra_gr3d_match
,
605 .pm
= &tegra_gr3d_pm
,
608 .remove
= gr3d_remove
,