1 /*-
2 * Copyright (c) 2015 Michal Meloun
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27 #include <sys/param.h>
28 #include <sys/systm.h>
29 #include <sys/bus.h>
30 #include <sys/clock.h>
31 #include <sys/kernel.h>
32 #include <sys/limits.h>
33 #include <sys/lock.h>
34
35 #include <sys/module.h>
36 #include <sys/resource.h>
37 #include <sys/sx.h>
38 #include <sys/rman.h>
39
40 #include <machine/bus.h>
41 #include <machine/resource.h>
42
43 #include <dev/clk/clk.h>
44 #include <dev/hwreset/hwreset.h>
45 #include <dev/drm2/drmP.h>
46 #include <dev/drm2/drm_crtc_helper.h>
47 #include <dev/drm2/drm_fb_helper.h>
48 #include <dev/fdt/simplebus.h>
49 #include <dev/ofw/ofw_bus.h>
50 #include <dev/ofw/ofw_bus_subr.h>
51
52 #include <arm/nvidia/drm2/tegra_drm.h>
53
54 #include "fb_if.h"
55 #include "tegra_drm_if.h"
56
57 #define WR4(_sc, _r, _v) bus_rite_4((_sc)->mem_res, (_r), (_v))
58 #define RD4(_sc, _r) bus_read_4((_sc)->mem_res, (_r))
59
60 #define LOCK(_sc) sx_xlock(&(_sc)->lock)
61 #define UNLOCK(_sc) sx_xunlock(&(_sc)->lock)
62 #define SLEEP(_sc, timeout) sx_sleep(sc, &sc->lock, 0, "host1x", timeout);
63 #define LOCK_INIT(_sc) sx_init(&_sc->lock, "host1x")
64 #define LOCK_DESTROY(_sc) sx_destroy(&_sc->lock)
65 #define ASSERT_LOCKED(_sc) sx_assert(&_sc->lock, SA_LOCKED)
66 #define ASSERT_UNLOCKED(_sc) sx_assert(&_sc->lock, SA_UNLOCKED)
67
68 static struct ofw_compat_data compat_data[] = {
69 {"nvidia,tegra124-host1x", 1},
70 {NULL, 0}
71 };
72
73 #define DRIVER_NAME "tegra"
74 #define DRIVER_DESC "NVIDIA Tegra TK1"
75 #define DRIVER_DATE "20151101"
76 #define DRIVER_MAJOR 0
77 #define DRIVER_MINOR 0
78 #define DRIVER_PATCHLEVEL 0
79
80 struct client_info;
81 TAILQ_HEAD(client_list, client_info);
82 typedef struct client_list client_list_t;
83
84 struct client_info {
85 TAILQ_ENTRY(client_info) list_e;
86 device_t client;
87 int activated;
88 };
89
90 struct host1x_softc {
91 struct simplebus_softc simplebus_sc; /* must be first */
92 device_t dev;
93 struct sx lock;
94 int attach_done;
95
96 struct resource *mem_res;
97 struct resource *syncpt_irq_res;
98 void *syncpt_irq_h;
99 struct resource *gen_irq_res;
100 void *gen_irq_h;
101
102 clk_t clk;
103 hwreset_t reset;
104 struct intr_config_hook irq_hook;
105
106 int drm_inited;
107 client_list_t clients;
108
109 struct tegra_drm *tegra_drm;
110 };
111
112 static void
host1x_output_poll_changed(struct drm_device * drm_dev)113 host1x_output_poll_changed(struct drm_device *drm_dev)
114 {
115 struct tegra_drm *drm;
116
117 drm = container_of(drm_dev, struct tegra_drm, drm_dev);
118 if (drm->fb != NULL)
119 drm_fb_helper_hotplug_event(&drm->fb->fb_helper);
120 }
121
122 static const struct drm_mode_config_funcs mode_config_funcs = {
123 .fb_create = tegra_drm_fb_create,
124 .output_poll_changed = host1x_output_poll_changed,
125 };
126
127 static int
host1x_drm_init(struct host1x_softc * sc)128 host1x_drm_init(struct host1x_softc *sc)
129 {
130 struct client_info *entry;
131 int rv;
132
133 LOCK(sc);
134
135 TAILQ_FOREACH(entry, &sc->clients, list_e) {
136 if (entry->activated)
137 continue;
138 rv = TEGRA_DRM_INIT_CLIENT(entry->client, sc->dev,
139 sc->tegra_drm);
140 if (rv != 0) {
141 device_printf(sc->dev,
142 "Cannot init DRM client %s: %d\n",
143 device_get_name(entry->client), rv);
144 return (rv);
145 }
146 entry->activated = 1;
147 }
148 UNLOCK(sc);
149
150 return (0);
151 }
152
153 static int
host1x_drm_exit(struct host1x_softc * sc)154 host1x_drm_exit(struct host1x_softc *sc)
155 {
156 struct client_info *entry;
157 int rv;
158 #ifdef FREEBSD_NOTYET
159 struct drm_device *dev, *tmp;
160 #endif
161 LOCK(sc);
162 if (!sc->drm_inited) {
163 UNLOCK(sc);
164 return (0);
165 }
166 TAILQ_FOREACH_REVERSE(entry, &sc->clients, client_list, list_e) {
167 if (!entry->activated)
168 continue;
169 rv = TEGRA_DRM_EXIT_CLIENT(entry->client, sc->dev,
170 sc->tegra_drm);
171 if (rv != 0) {
172 device_printf(sc->dev,
173 "Cannot exit DRM client %s: %d\n",
174 device_get_name(entry->client), rv);
175 }
176 entry->activated = 0;
177 }
178
179 #ifdef FREEBSD_NOTYET
180 list_for_each_entry_safe(dev, tmp, &driver->device_list, driver_item)
181 drm_put_dev(dev);
182 #endif
183 sc->drm_inited = 0;
184 UNLOCK(sc);
185
186 return (0);
187 }
188
189 static int
host1x_drm_load(struct drm_device * drm_dev,unsigned long flags)190 host1x_drm_load(struct drm_device *drm_dev, unsigned long flags)
191 {
192 struct host1x_softc *sc;
193 int rv;
194
195 sc = device_get_softc(drm_dev->dev);
196
197 drm_mode_config_init(drm_dev);
198 drm_dev->mode_config.min_width = 32;
199 drm_dev->mode_config.min_height = 32;
200 drm_dev->mode_config.max_width = 4096;
201 drm_dev->mode_config.max_height = 4096;
202 drm_dev->mode_config.funcs = &mode_config_funcs;
203
204 rv = host1x_drm_init(sc);
205 if (rv != 0)
206 goto fail_host1x;
207
208 drm_dev->irq_enabled = true;
209 drm_dev->max_vblank_count = 0xffffffff;
210 drm_dev->vblank_disable_allowed = true;
211
212 rv = drm_vblank_init(drm_dev, drm_dev->mode_config.num_crtc);
213 if (rv != 0)
214 goto fail_vblank;
215
216 drm_mode_config_reset(drm_dev);
217
218 rv = tegra_drm_fb_init(drm_dev);
219 if (rv != 0)
220 goto fail_fb;
221 drm_kms_helper_poll_init(drm_dev);
222
223 return (0);
224
225 fail_fb:
226 tegra_drm_fb_destroy(drm_dev);
227 drm_vblank_cleanup(drm_dev);
228 fail_vblank:
229 host1x_drm_exit(sc);
230 fail_host1x:
231 drm_mode_config_cleanup(drm_dev);
232
233 return (rv);
234 }
235
236 static int
host1x_drm_unload(struct drm_device * drm_dev)237 host1x_drm_unload(struct drm_device *drm_dev)
238 {
239 struct host1x_softc *sc;
240 int rv;
241
242 sc = device_get_softc(drm_dev->dev);
243
244 drm_kms_helper_poll_fini(drm_dev);
245 tegra_drm_fb_destroy(drm_dev);
246 drm_mode_config_cleanup(drm_dev);
247
248 rv = host1x_drm_exit(sc);
249 if (rv < 0)
250 return (rv);
251 return (0);
252 }
253
254 static int
host1x_drm_open(struct drm_device * drm_dev,struct drm_file * filp)255 host1x_drm_open(struct drm_device *drm_dev, struct drm_file *filp)
256 {
257
258 return (0);
259 }
260
261 static void
tegra_drm_preclose(struct drm_device * drm,struct drm_file * file)262 tegra_drm_preclose(struct drm_device *drm, struct drm_file *file)
263 {
264 struct drm_crtc *crtc;
265
266 list_for_each_entry(crtc, &drm->mode_config.crtc_list, head)
267 tegra_dc_cancel_page_flip(crtc, file);
268 }
269
270 static void
host1x_drm_lastclose(struct drm_device * drm_dev)271 host1x_drm_lastclose(struct drm_device *drm_dev)
272 {
273
274 struct tegra_drm *drm;
275
276 drm = container_of(drm_dev, struct tegra_drm, drm_dev);
277 if (drm->fb != NULL)
278 drm_fb_helper_restore_fbdev_mode(&drm->fb->fb_helper);
279 }
280
281 static int
host1x_drm_enable_vblank(struct drm_device * drm_dev,int pipe)282 host1x_drm_enable_vblank(struct drm_device *drm_dev, int pipe)
283 {
284 struct drm_crtc *crtc;
285
286 list_for_each_entry(crtc, &drm_dev->mode_config.crtc_list, head) {
287 if (pipe == tegra_dc_get_pipe(crtc)) {
288 tegra_dc_enable_vblank(crtc);
289 return (0);
290 }
291 }
292 return (-ENODEV);
293 }
294
295 static void
host1x_drm_disable_vblank(struct drm_device * drm_dev,int pipe)296 host1x_drm_disable_vblank(struct drm_device *drm_dev, int pipe)
297 {
298 struct drm_crtc *crtc;
299
300 list_for_each_entry(crtc, &drm_dev->mode_config.crtc_list, head) {
301 if (pipe == tegra_dc_get_pipe(crtc)) {
302 tegra_dc_disable_vblank(crtc);
303 return;
304 }
305 }
306 }
307
308 static struct drm_ioctl_desc host1x_drm_ioctls[] = {
309 };
310
311 struct drm_driver tegra_drm_driver = {
312 .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME,
313 .load = host1x_drm_load,
314 .unload = host1x_drm_unload,
315 .open = host1x_drm_open,
316 .preclose = tegra_drm_preclose,
317 .lastclose = host1x_drm_lastclose,
318
319 .get_vblank_counter = drm_vblank_count,
320 .enable_vblank = host1x_drm_enable_vblank,
321 .disable_vblank = host1x_drm_disable_vblank,
322
323 /* Fields filled by tegra_bo_driver_register()
324 .gem_free_object
325 .gem_pager_ops
326 .dumb_create
327 .dumb_map_offset
328 .dumb_destroy
329 */
330 .ioctls = host1x_drm_ioctls,
331 .num_ioctls = nitems(host1x_drm_ioctls),
332
333 .name = DRIVER_NAME,
334 .desc = DRIVER_DESC,
335 .date = DRIVER_DATE,
336 .major = DRIVER_MAJOR,
337 .minor = DRIVER_MINOR,
338 .patchlevel = DRIVER_PATCHLEVEL,
339 };
340
341 /*
342 * ----------------- Device methods -------------------------
343 */
344 static void
host1x_irq_hook(void * arg)345 host1x_irq_hook(void *arg)
346 {
347 struct host1x_softc *sc;
348 int rv;
349
350 sc = arg;
351 config_intrhook_disestablish(&sc->irq_hook);
352
353 tegra_bo_driver_register(&tegra_drm_driver);
354 rv = drm_get_platform_dev(sc->dev, &sc->tegra_drm->drm_dev,
355 &tegra_drm_driver);
356 if (rv != 0) {
357 device_printf(sc->dev, "drm_get_platform_dev(): %d\n", rv);
358 return;
359 }
360
361 sc->drm_inited = 1;
362 }
363
364 static struct fb_info *
host1x_fb_helper_getinfo(device_t dev)365 host1x_fb_helper_getinfo(device_t dev)
366 {
367 struct host1x_softc *sc;
368
369 sc = device_get_softc(dev);
370 if (sc->tegra_drm == NULL)
371 return (NULL);
372 return (tegra_drm_fb_getinfo(&sc->tegra_drm->drm_dev));
373 }
374
375 static int
host1x_register_client(device_t dev,device_t client)376 host1x_register_client(device_t dev, device_t client)
377 {
378 struct host1x_softc *sc;
379 struct client_info *entry;
380
381 sc = device_get_softc(dev);
382
383 entry = malloc(sizeof(struct client_info), M_DEVBUF, M_WAITOK | M_ZERO);
384 entry->client = client;
385 entry->activated = 0;
386
387 LOCK(sc);
388 TAILQ_INSERT_TAIL(&sc->clients, entry, list_e);
389 UNLOCK(sc);
390
391 return (0);
392 }
393
394 static int
host1x_deregister_client(device_t dev,device_t client)395 host1x_deregister_client(device_t dev, device_t client)
396 {
397 struct host1x_softc *sc;
398 struct client_info *entry;
399
400 sc = device_get_softc(dev);
401
402 LOCK(sc);
403 TAILQ_FOREACH(entry, &sc->clients, list_e) {
404 if (entry->client == client) {
405 if (entry->activated)
406 panic("Tegra DRM: Attempt to deregister "
407 "activated client");
408 TAILQ_REMOVE(&sc->clients, entry, list_e);
409 free(entry, M_DEVBUF);
410 UNLOCK(sc);
411 return (0);
412 }
413 }
414 UNLOCK(sc);
415
416 return (0);
417 }
418
419 static void
host1x_gen_intr(void * arg)420 host1x_gen_intr(void *arg)
421 {
422 struct host1x_softc *sc;
423
424 sc = (struct host1x_softc *)arg;
425 LOCK(sc);
426 UNLOCK(sc);
427 }
428
429 static void
host1x_syncpt_intr(void * arg)430 host1x_syncpt_intr(void *arg)
431 {
432 struct host1x_softc *sc;
433
434 sc = (struct host1x_softc *)arg;
435 LOCK(sc);
436 UNLOCK(sc);
437 }
438
439 static void
host1x_new_pass(device_t dev)440 host1x_new_pass(device_t dev)
441 {
442 struct host1x_softc *sc;
443 int rv, rid;
444 phandle_t node;
445
446 /*
447 * We attach during BUS_PASS_BUS (because we must overcome simplebus),
448 * but some of our FDT resources are not ready until BUS_PASS_DEFAULT
449 */
450 sc = device_get_softc(dev);
451 if (sc->attach_done || bus_get_pass() < BUS_PASS_DEFAULT) {
452 bus_generic_new_pass(dev);
453 return;
454 }
455
456 sc->attach_done = 1;
457 node = ofw_bus_get_node(dev);
458
459 /* Allocate our IRQ resource. */
460 rid = 0;
461 sc->syncpt_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
462 RF_ACTIVE);
463 if (sc->syncpt_irq_res == NULL) {
464 device_printf(dev, "Cannot allocate interrupt.\n");
465 rv = ENXIO;
466 goto fail;
467 }
468 rid = 1;
469 sc->gen_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
470 RF_ACTIVE);
471 if (sc->gen_irq_res == NULL) {
472 device_printf(dev, "Cannot allocate interrupt.\n");
473 rv = ENXIO;
474 goto fail;
475 }
476
477 /* FDT resources */
478 rv = hwreset_get_by_ofw_name(sc->dev, 0, "host1x", &sc->reset);
479 if (rv != 0) {
480 device_printf(dev, "Cannot get fuse reset\n");
481 goto fail;
482 }
483 rv = clk_get_by_ofw_index(sc->dev, 0, 0, &sc->clk);
484 if (rv != 0) {
485 device_printf(dev, "Cannot get i2c clock: %d\n", rv);
486 goto fail;
487 }
488
489 rv = clk_enable(sc->clk);
490 if (rv != 0) {
491 device_printf(dev, "Cannot enable clock: %d\n", rv);
492 goto fail;
493 }
494 rv = hwreset_deassert(sc->reset);
495 if (rv != 0) {
496 device_printf(sc->dev, "Cannot clear reset\n");
497 goto fail;
498 }
499
500 /* Setup interrupts */
501 rv = bus_setup_intr(dev, sc->gen_irq_res,
502 INTR_TYPE_MISC | INTR_MPSAFE, NULL, host1x_gen_intr,
503 sc, &sc->gen_irq_h);
504 if (rv) {
505 device_printf(dev, "Cannot setup gen interrupt.\n");
506 goto fail;
507 }
508
509 rv = bus_setup_intr(dev, sc->syncpt_irq_res,
510 INTR_TYPE_MISC | INTR_MPSAFE, NULL, host1x_syncpt_intr,
511 sc, &sc->syncpt_irq_h);
512 if (rv) {
513 device_printf(dev, "Cannot setup syncpt interrupt.\n");
514 goto fail;
515 }
516
517 simplebus_init(dev, 0);
518 for (node = OF_child(node); node > 0; node = OF_peer(node))
519 simplebus_add_device(dev, node, 0, NULL, -1, NULL);
520
521 sc->irq_hook.ich_func = host1x_irq_hook;
522 sc->irq_hook.ich_arg = sc;
523 config_intrhook_establish(&sc->irq_hook);
524 bus_generic_new_pass(dev);
525 return;
526
527 fail:
528 device_detach(dev);
529 return;
530 }
531
532 static int
host1x_probe(device_t dev)533 host1x_probe(device_t dev)
534 {
535
536 if (!ofw_bus_status_okay(dev))
537 return (ENXIO);
538
539 if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0)
540 return (ENXIO);
541
542 return (BUS_PROBE_DEFAULT);
543 }
544
545 static int
host1x_attach(device_t dev)546 host1x_attach(device_t dev)
547 {
548 int rv, rid;
549 struct host1x_softc *sc;
550
551 sc = device_get_softc(dev);
552 sc->tegra_drm = malloc(sizeof(struct tegra_drm), DRM_MEM_DRIVER,
553 M_WAITOK | M_ZERO);
554
555 /* crosslink together all worlds */
556 sc->dev = dev;
557 sc->tegra_drm->drm_dev.dev_private = &sc->tegra_drm;
558 sc->tegra_drm->drm_dev.dev = dev;
559
560 TAILQ_INIT(&sc->clients);
561
562 LOCK_INIT(sc);
563
564 /* Get the memory resource for the register mapping. */
565 rid = 0;
566 sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
567 RF_ACTIVE);
568 if (sc->mem_res == NULL) {
569 device_printf(dev, "Cannot map registers.\n");
570 rv = ENXIO;
571 goto fail;
572 }
573
574 return (bus_generic_attach(dev));
575
576 fail:
577 if (sc->tegra_drm != NULL)
578 free(sc->tegra_drm, DRM_MEM_DRIVER);
579 if (sc->mem_res != NULL)
580 bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->mem_res);
581 LOCK_DESTROY(sc);
582 return (rv);
583 }
584
585 static int
host1x_detach(device_t dev)586 host1x_detach(device_t dev)
587 {
588 struct host1x_softc *sc;
589 int error;
590
591 error = bus_generic_detach(dev);
592 if (error != 0)
593 return (error);
594
595 sc = device_get_softc(dev);
596
597 host1x_drm_exit(sc);
598
599 if (sc->gen_irq_h != NULL)
600 bus_teardown_intr(dev, sc->gen_irq_res, sc->gen_irq_h);
601 if (sc->tegra_drm != NULL)
602 free(sc->tegra_drm, DRM_MEM_DRIVER);
603 if (sc->clk != NULL)
604 clk_release(sc->clk);
605 if (sc->reset != NULL)
606 hwreset_release(sc->reset);
607 if (sc->syncpt_irq_h != NULL)
608 bus_teardown_intr(dev, sc->syncpt_irq_res, sc->syncpt_irq_h);
609 if (sc->gen_irq_res != NULL)
610 bus_release_resource(dev, SYS_RES_IRQ, 1, sc->gen_irq_res);
611 if (sc->syncpt_irq_res != NULL)
612 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->syncpt_irq_res);
613 if (sc->mem_res != NULL)
614 bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->mem_res);
615 LOCK_DESTROY(sc);
616 return (0);
617 }
618
619 static device_method_t host1x_methods[] = {
620 /* Device interface */
621 DEVMETHOD(device_probe, host1x_probe),
622 DEVMETHOD(device_attach, host1x_attach),
623 DEVMETHOD(device_detach, host1x_detach),
624
625 /* Bus interface */
626 DEVMETHOD(bus_new_pass, host1x_new_pass),
627
628 /* Framebuffer service methods */
629 DEVMETHOD(fb_getinfo, host1x_fb_helper_getinfo),
630
631 /* tegra drm interface */
632 DEVMETHOD(tegra_drm_register_client, host1x_register_client),
633 DEVMETHOD(tegra_drm_deregister_client, host1x_deregister_client),
634
635 DEVMETHOD_END
636 };
637
638 DEFINE_CLASS_1(host1x, host1x_driver, host1x_methods,
639 sizeof(struct host1x_softc), simplebus_driver);
640 EARLY_DRIVER_MODULE(host1x, simplebus, host1x_driver, 0, 0, BUS_PASS_BUS);
641
642 /* Bindings for fbd device. */
643 extern driver_t fbd_driver;
644 DRIVER_MODULE(fbd, host1x, fbd_driver, 0, 0);
645