aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorAndy Gross <andy.gross@ti.com>2012-03-05 11:48:39 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-03-07 16:38:08 -0500
commit5c137797377db64d4cfb429ee8e4a420d9743660 (patch)
tree6a96a8db5ade06a7d7074860fa39701708189e2f /drivers
parent02646fb8b3de95a170f8ac4f0773a4f5e2a1b54c (diff)
staging: drm/omap: Get DMM resources from hwmod
This patch splits the DMM off into a separate sub-device, in order to utilize the platform device information that was created as part of the OMAP hwmod entry for the DMM. The driver probe function queries the iomem resource and IRQ using standard platform_get functions. The OMAP DRM driver now calls the platform_driver_register() function for the subordinate DMM driver inside its probe function. This guarantees the required order for the DMM and ensures the DMM resources are available for use by the DRM driver. Signed-off-by: Andy Gross <andy.gross@ti.com> Signed-off-by: Rob Clark <rob@ti.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/staging/omapdrm/omap_dmm_tiler.c79
-rw-r--r--drivers/staging/omapdrm/omap_dmm_tiler.h11
-rw-r--r--drivers/staging/omapdrm/omap_drv.c6
-rw-r--r--drivers/staging/omapdrm/omap_gem.c8
4 files changed, 68 insertions, 36 deletions
diff --git a/drivers/staging/omapdrm/omap_dmm_tiler.c b/drivers/staging/omapdrm/omap_dmm_tiler.c
index e4c7bb6afce..1ecb6a73d79 100644
--- a/drivers/staging/omapdrm/omap_dmm_tiler.c
+++ b/drivers/staging/omapdrm/omap_dmm_tiler.c
@@ -34,6 +34,8 @@
34#include "omap_dmm_tiler.h" 34#include "omap_dmm_tiler.h"
35#include "omap_dmm_priv.h" 35#include "omap_dmm_priv.h"
36 36
37#define DMM_DRIVER_NAME "dmm"
38
37/* mappings for associating views to luts */ 39/* mappings for associating views to luts */
38static struct tcm *containers[TILFMT_NFORMATS]; 40static struct tcm *containers[TILFMT_NFORMATS];
39static struct dmm *omap_dmm; 41static struct dmm *omap_dmm;
@@ -465,7 +467,12 @@ size_t tiler_vsize(enum tiler_fmt fmt, uint16_t w, uint16_t h)
465 return round_up(geom[fmt].cpp * w, PAGE_SIZE) * h; 467 return round_up(geom[fmt].cpp * w, PAGE_SIZE) * h;
466} 468}
467 469
468int omap_dmm_remove(void) 470bool dmm_is_initialized(void)
471{
472 return omap_dmm ? true : false;
473}
474
475static int omap_dmm_remove(struct platform_device *dev)
469{ 476{
470 struct tiler_block *block, *_block; 477 struct tiler_block *block, *_block;
471 int i; 478 int i;
@@ -499,40 +506,49 @@ int omap_dmm_remove(void)
499 if (omap_dmm->irq != -1) 506 if (omap_dmm->irq != -1)
500 free_irq(omap_dmm->irq, omap_dmm); 507 free_irq(omap_dmm->irq, omap_dmm);
501 508
509 iounmap(omap_dmm->base);
502 kfree(omap_dmm); 510 kfree(omap_dmm);
511 omap_dmm = NULL;
503 } 512 }
504 513
505 return 0; 514 return 0;
506} 515}
507 516
508int omap_dmm_init(struct drm_device *dev) 517static int omap_dmm_probe(struct platform_device *dev)
509{ 518{
510 int ret = -EFAULT, i; 519 int ret = -EFAULT, i;
511 struct tcm_area area = {0}; 520 struct tcm_area area = {0};
512 u32 hwinfo, pat_geom, lut_table_size; 521 u32 hwinfo, pat_geom, lut_table_size;
513 struct omap_drm_platform_data *pdata = dev->dev->platform_data; 522 struct resource *mem;
514
515 if (!pdata || !pdata->dmm_pdata) {
516 dev_err(dev->dev, "dmm platform data not present, skipping\n");
517 return ret;
518 }
519 523
520 omap_dmm = kzalloc(sizeof(*omap_dmm), GFP_KERNEL); 524 omap_dmm = kzalloc(sizeof(*omap_dmm), GFP_KERNEL);
521 if (!omap_dmm) { 525 if (!omap_dmm) {
522 dev_err(dev->dev, "failed to allocate driver data section\n"); 526 dev_err(&dev->dev, "failed to allocate driver data section\n");
523 goto fail; 527 goto fail;
524 } 528 }
525 529
526 /* lookup hwmod data - base address and irq */ 530 /* lookup hwmod data - base address and irq */
527 omap_dmm->base = pdata->dmm_pdata->base; 531 mem = platform_get_resource(dev, IORESOURCE_MEM, 0);
528 omap_dmm->irq = pdata->dmm_pdata->irq; 532 if (!mem) {
529 omap_dmm->dev = dev->dev; 533 dev_err(&dev->dev, "failed to get base address resource\n");
534 goto fail;
535 }
536
537 omap_dmm->base = ioremap(mem->start, SZ_2K);
530 538
531 if (!omap_dmm->base) { 539 if (!omap_dmm->base) {
532 dev_err(dev->dev, "failed to get dmm base address\n"); 540 dev_err(&dev->dev, "failed to get dmm base address\n");
533 goto fail; 541 goto fail;
534 } 542 }
535 543
544 omap_dmm->irq = platform_get_irq(dev, 0);
545 if (omap_dmm->irq < 0) {
546 dev_err(&dev->dev, "failed to get IRQ resource\n");
547 goto fail;
548 }
549
550 omap_dmm->dev = &dev->dev;
551
536 hwinfo = readl(omap_dmm->base + DMM_PAT_HWINFO); 552 hwinfo = readl(omap_dmm->base + DMM_PAT_HWINFO);
537 omap_dmm->num_engines = (hwinfo >> 24) & 0x1F; 553 omap_dmm->num_engines = (hwinfo >> 24) & 0x1F;
538 omap_dmm->num_lut = (hwinfo >> 16) & 0x1F; 554 omap_dmm->num_lut = (hwinfo >> 16) & 0x1F;
@@ -556,7 +572,7 @@ int omap_dmm_init(struct drm_device *dev)
556 "omap_dmm_irq_handler", omap_dmm); 572 "omap_dmm_irq_handler", omap_dmm);
557 573
558 if (ret) { 574 if (ret) {
559 dev_err(dev->dev, "couldn't register IRQ %d, error %d\n", 575 dev_err(&dev->dev, "couldn't register IRQ %d, error %d\n",
560 omap_dmm->irq, ret); 576 omap_dmm->irq, ret);
561 omap_dmm->irq = -1; 577 omap_dmm->irq = -1;
562 goto fail; 578 goto fail;
@@ -575,25 +591,30 @@ int omap_dmm_init(struct drm_device *dev)
575 591
576 omap_dmm->lut = vmalloc(lut_table_size * sizeof(*omap_dmm->lut)); 592 omap_dmm->lut = vmalloc(lut_table_size * sizeof(*omap_dmm->lut));
577 if (!omap_dmm->lut) { 593 if (!omap_dmm->lut) {
578 dev_err(dev->dev, "could not allocate lut table\n"); 594 dev_err(&dev->dev, "could not allocate lut table\n");
579 ret = -ENOMEM; 595 ret = -ENOMEM;
580 goto fail; 596 goto fail;
581 } 597 }
582 598
583 omap_dmm->dummy_page = alloc_page(GFP_KERNEL | __GFP_DMA32); 599 omap_dmm->dummy_page = alloc_page(GFP_KERNEL | __GFP_DMA32);
584 if (!omap_dmm->dummy_page) { 600 if (!omap_dmm->dummy_page) {
585 dev_err(dev->dev, "could not allocate dummy page\n"); 601 dev_err(&dev->dev, "could not allocate dummy page\n");
586 ret = -ENOMEM; 602 ret = -ENOMEM;
587 goto fail; 603 goto fail;
588 } 604 }
605
606 /* set dma mask for device */
607 /* NOTE: this is a workaround for the hwmod not initializing properly */
608 dev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
609
589 omap_dmm->dummy_pa = page_to_phys(omap_dmm->dummy_page); 610 omap_dmm->dummy_pa = page_to_phys(omap_dmm->dummy_page);
590 611
591 /* alloc refill memory */ 612 /* alloc refill memory */
592 omap_dmm->refill_va = dma_alloc_coherent(dev->dev, 613 omap_dmm->refill_va = dma_alloc_coherent(&dev->dev,
593 REFILL_BUFFER_SIZE * omap_dmm->num_engines, 614 REFILL_BUFFER_SIZE * omap_dmm->num_engines,
594 &omap_dmm->refill_pa, GFP_KERNEL); 615 &omap_dmm->refill_pa, GFP_KERNEL);
595 if (!omap_dmm->refill_va) { 616 if (!omap_dmm->refill_va) {
596 dev_err(dev->dev, "could not allocate refill memory\n"); 617 dev_err(&dev->dev, "could not allocate refill memory\n");
597 goto fail; 618 goto fail;
598 } 619 }
599 620
@@ -602,7 +623,7 @@ int omap_dmm_init(struct drm_device *dev)
602 omap_dmm->num_engines * sizeof(struct refill_engine), 623 omap_dmm->num_engines * sizeof(struct refill_engine),
603 GFP_KERNEL); 624 GFP_KERNEL);
604 if (!omap_dmm->engines) { 625 if (!omap_dmm->engines) {
605 dev_err(dev->dev, "could not allocate engines\n"); 626 dev_err(&dev->dev, "could not allocate engines\n");
606 ret = -ENOMEM; 627 ret = -ENOMEM;
607 goto fail; 628 goto fail;
608 } 629 }
@@ -624,7 +645,7 @@ int omap_dmm_init(struct drm_device *dev)
624 omap_dmm->tcm = kzalloc(omap_dmm->num_lut * sizeof(*omap_dmm->tcm), 645 omap_dmm->tcm = kzalloc(omap_dmm->num_lut * sizeof(*omap_dmm->tcm),
625 GFP_KERNEL); 646 GFP_KERNEL);
626 if (!omap_dmm->tcm) { 647 if (!omap_dmm->tcm) {
627 dev_err(dev->dev, "failed to allocate lut ptrs\n"); 648 dev_err(&dev->dev, "failed to allocate lut ptrs\n");
628 ret = -ENOMEM; 649 ret = -ENOMEM;
629 goto fail; 650 goto fail;
630 } 651 }
@@ -636,7 +657,7 @@ int omap_dmm_init(struct drm_device *dev)
636 NULL); 657 NULL);
637 658
638 if (!omap_dmm->tcm[i]) { 659 if (!omap_dmm->tcm[i]) {
639 dev_err(dev->dev, "failed to allocate container\n"); 660 dev_err(&dev->dev, "failed to allocate container\n");
640 ret = -ENOMEM; 661 ret = -ENOMEM;
641 goto fail; 662 goto fail;
642 } 663 }
@@ -676,7 +697,7 @@ int omap_dmm_init(struct drm_device *dev)
676 return 0; 697 return 0;
677 698
678fail: 699fail:
679 omap_dmm_remove(); 700 omap_dmm_remove(dev);
680 return ret; 701 return ret;
681} 702}
682 703
@@ -836,3 +857,17 @@ error:
836 return 0; 857 return 0;
837} 858}
838#endif 859#endif
860
861struct platform_driver omap_dmm_driver = {
862 .probe = omap_dmm_probe,
863 .remove = omap_dmm_remove,
864 .driver = {
865 .owner = THIS_MODULE,
866 .name = DMM_DRIVER_NAME,
867 },
868};
869
870MODULE_LICENSE("GPL v2");
871MODULE_AUTHOR("Andy Gross <andy.gross@ti.com>");
872MODULE_DESCRIPTION("OMAP DMM/Tiler Driver");
873MODULE_ALIAS("platform:" DMM_DRIVER_NAME);
diff --git a/drivers/staging/omapdrm/omap_dmm_tiler.h b/drivers/staging/omapdrm/omap_dmm_tiler.h
index 55ab284b075..7b1052a329e 100644
--- a/drivers/staging/omapdrm/omap_dmm_tiler.h
+++ b/drivers/staging/omapdrm/omap_dmm_tiler.h
@@ -73,10 +73,6 @@ struct tiler_block {
73#define TIL_ADDR(x, orient, a)\ 73#define TIL_ADDR(x, orient, a)\
74 ((u32) (x) | (orient) | ((a) << SHIFT_ACC_MODE)) 74 ((u32) (x) | (orient) | ((a) << SHIFT_ACC_MODE))
75 75
76/* externally accessible functions */
77int omap_dmm_init(struct drm_device *dev);
78int omap_dmm_remove(void);
79
80#ifdef CONFIG_DEBUG_FS 76#ifdef CONFIG_DEBUG_FS
81int tiler_map_show(struct seq_file *s, void *arg); 77int tiler_map_show(struct seq_file *s, void *arg);
82#endif 78#endif
@@ -98,7 +94,9 @@ uint32_t tiler_stride(enum tiler_fmt fmt);
98size_t tiler_size(enum tiler_fmt fmt, uint16_t w, uint16_t h); 94size_t tiler_size(enum tiler_fmt fmt, uint16_t w, uint16_t h);
99size_t tiler_vsize(enum tiler_fmt fmt, uint16_t w, uint16_t h); 95size_t tiler_vsize(enum tiler_fmt fmt, uint16_t w, uint16_t h);
100void tiler_align(enum tiler_fmt fmt, uint16_t *w, uint16_t *h); 96void tiler_align(enum tiler_fmt fmt, uint16_t *w, uint16_t *h);
97bool dmm_is_initialized(void);
101 98
99extern struct platform_driver omap_dmm_driver;
102 100
103/* GEM bo flags -> tiler fmt */ 101/* GEM bo flags -> tiler fmt */
104static inline enum tiler_fmt gem2fmt(uint32_t flags) 102static inline enum tiler_fmt gem2fmt(uint32_t flags)
@@ -128,11 +126,6 @@ static inline bool validfmt(enum tiler_fmt fmt)
128 } 126 }
129} 127}
130 128
131struct omap_dmm_platform_data {
132 void __iomem *base;
133 int irq;
134};
135
136static inline int dmm_is_available(void) 129static inline int dmm_is_available(void)
137{ 130{
138 return cpu_is_omap44xx(); 131 return cpu_is_omap44xx();
diff --git a/drivers/staging/omapdrm/omap_drv.c b/drivers/staging/omapdrm/omap_drv.c
index e2100bb5609..3df5b4c58ec 100644
--- a/drivers/staging/omapdrm/omap_drv.c
+++ b/drivers/staging/omapdrm/omap_drv.c
@@ -21,6 +21,7 @@
21 21
22#include "drm_crtc_helper.h" 22#include "drm_crtc_helper.h"
23#include "drm_fb_helper.h" 23#include "drm_fb_helper.h"
24#include "omap_dmm_tiler.h"
24 25
25#define DRIVER_NAME MODULE_NAME 26#define DRIVER_NAME MODULE_NAME
26#define DRIVER_DESC "OMAP DRM" 27#define DRIVER_DESC "OMAP DRM"
@@ -802,6 +803,9 @@ static void pdev_shutdown(struct platform_device *device)
802static int pdev_probe(struct platform_device *device) 803static int pdev_probe(struct platform_device *device)
803{ 804{
804 DBG("%s", device->name); 805 DBG("%s", device->name);
806 if (platform_driver_register(&omap_dmm_driver))
807 dev_err(&device->dev, "DMM registration failed\n");
808
805 return drm_platform_init(&omap_drm_driver, device); 809 return drm_platform_init(&omap_drm_driver, device);
806} 810}
807 811
@@ -809,6 +813,8 @@ static int pdev_remove(struct platform_device *device)
809{ 813{
810 DBG(""); 814 DBG("");
811 drm_platform_exit(&omap_drm_driver, device); 815 drm_platform_exit(&omap_drm_driver, device);
816
817 platform_driver_unregister(&omap_dmm_driver);
812 return 0; 818 return 0;
813} 819}
814 820
diff --git a/drivers/staging/omapdrm/omap_gem.c b/drivers/staging/omapdrm/omap_gem.c
index 1d734bc95a3..5abd294ab2e 100644
--- a/drivers/staging/omapdrm/omap_gem.c
+++ b/drivers/staging/omapdrm/omap_gem.c
@@ -1238,12 +1238,11 @@ void omap_gem_init(struct drm_device *dev)
1238 const enum tiler_fmt fmts[] = { 1238 const enum tiler_fmt fmts[] = {
1239 TILFMT_8BIT, TILFMT_16BIT, TILFMT_32BIT 1239 TILFMT_8BIT, TILFMT_16BIT, TILFMT_32BIT
1240 }; 1240 };
1241 int i, j, ret; 1241 int i, j;
1242 1242
1243 ret = omap_dmm_init(dev); 1243 if (!dmm_is_initialized()) {
1244 if (ret) {
1245 /* DMM only supported on OMAP4 and later, so this isn't fatal */ 1244 /* DMM only supported on OMAP4 and later, so this isn't fatal */
1246 dev_warn(dev->dev, "omap_dmm_init failed, disabling DMM\n"); 1245 dev_warn(dev->dev, "DMM not available, disable DMM support\n");
1247 return; 1246 return;
1248 } 1247 }
1249 1248
@@ -1293,6 +1292,5 @@ void omap_gem_deinit(struct drm_device *dev)
1293 /* I believe we can rely on there being no more outstanding GEM 1292 /* I believe we can rely on there being no more outstanding GEM
1294 * objects which could depend on usergart/dmm at this point. 1293 * objects which could depend on usergart/dmm at this point.
1295 */ 1294 */
1296 omap_dmm_remove();
1297 kfree(usergart); 1295 kfree(usergart);
1298} 1296}