aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/msm/adreno/a3xx_gpu.c49
-rw-r--r--drivers/gpu/drm/msm/hdmi/hdmi.c44
-rw-r--r--drivers/gpu/drm/msm/msm_drv.c112
-rw-r--r--drivers/gpu/drm/msm/msm_drv.h4
4 files changed, 176 insertions, 33 deletions
diff --git a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c
index e6cb2bc40ebe..f20fbde5dc49 100644
--- a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c
@@ -41,8 +41,6 @@ MODULE_PARM_DESC(hang_debug, "Dump registers when hang is detected (can be slow!
41module_param_named(hang_debug, hang_debug, bool, 0600); 41module_param_named(hang_debug, hang_debug, bool, 0600);
42static void a3xx_dump(struct msm_gpu *gpu); 42static void a3xx_dump(struct msm_gpu *gpu);
43 43
44static struct platform_device *a3xx_pdev;
45
46static void a3xx_me_init(struct msm_gpu *gpu) 44static void a3xx_me_init(struct msm_gpu *gpu)
47{ 45{
48 struct msm_ringbuffer *ring = gpu->rb; 46 struct msm_ringbuffer *ring = gpu->rb;
@@ -320,7 +318,6 @@ static void a3xx_destroy(struct msm_gpu *gpu)
320 ocmem_free(OCMEM_GRAPHICS, a3xx_gpu->ocmem_hdl); 318 ocmem_free(OCMEM_GRAPHICS, a3xx_gpu->ocmem_hdl);
321#endif 319#endif
322 320
323 put_device(&a3xx_gpu->pdev->dev);
324 kfree(a3xx_gpu); 321 kfree(a3xx_gpu);
325} 322}
326 323
@@ -473,7 +470,8 @@ struct msm_gpu *a3xx_gpu_init(struct drm_device *dev)
473 struct a3xx_gpu *a3xx_gpu = NULL; 470 struct a3xx_gpu *a3xx_gpu = NULL;
474 struct adreno_gpu *adreno_gpu; 471 struct adreno_gpu *adreno_gpu;
475 struct msm_gpu *gpu; 472 struct msm_gpu *gpu;
476 struct platform_device *pdev = a3xx_pdev; 473 struct msm_drm_private *priv = dev->dev_private;
474 struct platform_device *pdev = priv->gpu_pdev;
477 struct adreno_platform_config *config; 475 struct adreno_platform_config *config;
478 int ret; 476 int ret;
479 477
@@ -494,7 +492,6 @@ struct msm_gpu *a3xx_gpu_init(struct drm_device *dev)
494 adreno_gpu = &a3xx_gpu->base; 492 adreno_gpu = &a3xx_gpu->base;
495 gpu = &adreno_gpu->base; 493 gpu = &adreno_gpu->base;
496 494
497 get_device(&pdev->dev);
498 a3xx_gpu->pdev = pdev; 495 a3xx_gpu->pdev = pdev;
499 496
500 gpu->fast_rate = config->fast_rate; 497 gpu->fast_rate = config->fast_rate;
@@ -556,17 +553,24 @@ fail:
556# include <mach/kgsl.h> 553# include <mach/kgsl.h>
557#endif 554#endif
558 555
559static int a3xx_probe(struct platform_device *pdev) 556static void set_gpu_pdev(struct drm_device *dev,
557 struct platform_device *pdev)
558{
559 struct msm_drm_private *priv = dev->dev_private;
560 priv->gpu_pdev = pdev;
561}
562
563static int a3xx_bind(struct device *dev, struct device *master, void *data)
560{ 564{
561 static struct adreno_platform_config config = {}; 565 static struct adreno_platform_config config = {};
562#ifdef CONFIG_OF 566#ifdef CONFIG_OF
563 struct device_node *child, *node = pdev->dev.of_node; 567 struct device_node *child, *node = dev->of_node;
564 u32 val; 568 u32 val;
565 int ret; 569 int ret;
566 570
567 ret = of_property_read_u32(node, "qcom,chipid", &val); 571 ret = of_property_read_u32(node, "qcom,chipid", &val);
568 if (ret) { 572 if (ret) {
569 dev_err(&pdev->dev, "could not find chipid: %d\n", ret); 573 dev_err(dev, "could not find chipid: %d\n", ret);
570 return ret; 574 return ret;
571 } 575 }
572 576
@@ -582,7 +586,7 @@ static int a3xx_probe(struct platform_device *pdev)
582 for_each_child_of_node(child, pwrlvl) { 586 for_each_child_of_node(child, pwrlvl) {
583 ret = of_property_read_u32(pwrlvl, "qcom,gpu-freq", &val); 587 ret = of_property_read_u32(pwrlvl, "qcom,gpu-freq", &val);
584 if (ret) { 588 if (ret) {
585 dev_err(&pdev->dev, "could not find gpu-freq: %d\n", ret); 589 dev_err(dev, "could not find gpu-freq: %d\n", ret);
586 return ret; 590 return ret;
587 } 591 }
588 config.fast_rate = max(config.fast_rate, val); 592 config.fast_rate = max(config.fast_rate, val);
@@ -592,12 +596,12 @@ static int a3xx_probe(struct platform_device *pdev)
592 } 596 }
593 597
594 if (!config.fast_rate) { 598 if (!config.fast_rate) {
595 dev_err(&pdev->dev, "could not find clk rates\n"); 599 dev_err(dev, "could not find clk rates\n");
596 return -ENXIO; 600 return -ENXIO;
597 } 601 }
598 602
599#else 603#else
600 struct kgsl_device_platform_data *pdata = pdev->dev.platform_data; 604 struct kgsl_device_platform_data *pdata = dev->platform_data;
601 uint32_t version = socinfo_get_version(); 605 uint32_t version = socinfo_get_version();
602 if (cpu_is_apq8064ab()) { 606 if (cpu_is_apq8064ab()) {
603 config.fast_rate = 450000000; 607 config.fast_rate = 450000000;
@@ -643,14 +647,30 @@ static int a3xx_probe(struct platform_device *pdev)
643 config.bus_scale_table = pdata->bus_scale_table; 647 config.bus_scale_table = pdata->bus_scale_table;
644# endif 648# endif
645#endif 649#endif
646 pdev->dev.platform_data = &config; 650 dev->platform_data = &config;
647 a3xx_pdev = pdev; 651 set_gpu_pdev(dev_get_drvdata(master), to_platform_device(dev));
648 return 0; 652 return 0;
649} 653}
650 654
655static void a3xx_unbind(struct device *dev, struct device *master,
656 void *data)
657{
658 set_gpu_pdev(dev_get_drvdata(master), NULL);
659}
660
661static const struct component_ops a3xx_ops = {
662 .bind = a3xx_bind,
663 .unbind = a3xx_unbind,
664};
665
666static int a3xx_probe(struct platform_device *pdev)
667{
668 return component_add(&pdev->dev, &a3xx_ops);
669}
670
651static int a3xx_remove(struct platform_device *pdev) 671static int a3xx_remove(struct platform_device *pdev)
652{ 672{
653 a3xx_pdev = NULL; 673 component_del(&pdev->dev, &a3xx_ops);
654 return 0; 674 return 0;
655} 675}
656 676
@@ -658,7 +678,6 @@ static const struct of_device_id dt_match[] = {
658 { .compatible = "qcom,kgsl-3d0" }, 678 { .compatible = "qcom,kgsl-3d0" },
659 {} 679 {}
660}; 680};
661MODULE_DEVICE_TABLE(of, dt_match);
662 681
663static struct platform_driver a3xx_driver = { 682static struct platform_driver a3xx_driver = {
664 .probe = a3xx_probe, 683 .probe = a3xx_probe,
diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.c b/drivers/gpu/drm/msm/hdmi/hdmi.c
index 6048b6b2a8c7..ae750f6928c1 100644
--- a/drivers/gpu/drm/msm/hdmi/hdmi.c
+++ b/drivers/gpu/drm/msm/hdmi/hdmi.c
@@ -17,8 +17,6 @@
17 17
18#include "hdmi.h" 18#include "hdmi.h"
19 19
20static struct platform_device *hdmi_pdev;
21
22void hdmi_set_mode(struct hdmi *hdmi, bool power_on) 20void hdmi_set_mode(struct hdmi *hdmi, bool power_on)
23{ 21{
24 uint32_t ctrl = 0; 22 uint32_t ctrl = 0;
@@ -68,8 +66,6 @@ void hdmi_destroy(struct kref *kref)
68 hdmi_i2c_destroy(hdmi->i2c); 66 hdmi_i2c_destroy(hdmi->i2c);
69 67
70 platform_set_drvdata(hdmi->pdev, NULL); 68 platform_set_drvdata(hdmi->pdev, NULL);
71
72 put_device(&hdmi->pdev->dev);
73} 69}
74 70
75/* initialize connector */ 71/* initialize connector */
@@ -77,7 +73,7 @@ struct hdmi *hdmi_init(struct drm_device *dev, struct drm_encoder *encoder)
77{ 73{
78 struct hdmi *hdmi = NULL; 74 struct hdmi *hdmi = NULL;
79 struct msm_drm_private *priv = dev->dev_private; 75 struct msm_drm_private *priv = dev->dev_private;
80 struct platform_device *pdev = hdmi_pdev; 76 struct platform_device *pdev = priv->hdmi_pdev;
81 struct hdmi_platform_config *config; 77 struct hdmi_platform_config *config;
82 int i, ret; 78 int i, ret;
83 79
@@ -97,8 +93,6 @@ struct hdmi *hdmi_init(struct drm_device *dev, struct drm_encoder *encoder)
97 93
98 kref_init(&hdmi->refcount); 94 kref_init(&hdmi->refcount);
99 95
100 get_device(&pdev->dev);
101
102 hdmi->dev = dev; 96 hdmi->dev = dev;
103 hdmi->pdev = pdev; 97 hdmi->pdev = pdev;
104 hdmi->config = config; 98 hdmi->config = config;
@@ -255,17 +249,24 @@ fail:
255 249
256#include <linux/of_gpio.h> 250#include <linux/of_gpio.h>
257 251
258static int hdmi_dev_probe(struct platform_device *pdev) 252static void set_hdmi_pdev(struct drm_device *dev,
253 struct platform_device *pdev)
254{
255 struct msm_drm_private *priv = dev->dev_private;
256 priv->hdmi_pdev = pdev;
257}
258
259static int hdmi_bind(struct device *dev, struct device *master, void *data)
259{ 260{
260 static struct hdmi_platform_config config = {}; 261 static struct hdmi_platform_config config = {};
261#ifdef CONFIG_OF 262#ifdef CONFIG_OF
262 struct device_node *of_node = pdev->dev.of_node; 263 struct device_node *of_node = dev->of_node;
263 264
264 int get_gpio(const char *name) 265 int get_gpio(const char *name)
265 { 266 {
266 int gpio = of_get_named_gpio(of_node, name, 0); 267 int gpio = of_get_named_gpio(of_node, name, 0);
267 if (gpio < 0) { 268 if (gpio < 0) {
268 dev_err(&pdev->dev, "failed to get gpio: %s (%d)\n", 269 dev_err(dev, "failed to get gpio: %s (%d)\n",
269 name, gpio); 270 name, gpio);
270 gpio = -1; 271 gpio = -1;
271 } 272 }
@@ -342,14 +343,30 @@ static int hdmi_dev_probe(struct platform_device *pdev)
342 config.mux_sel_gpio = -1; 343 config.mux_sel_gpio = -1;
343 } 344 }
344#endif 345#endif
345 pdev->dev.platform_data = &config; 346 dev->platform_data = &config;
346 hdmi_pdev = pdev; 347 set_hdmi_pdev(dev_get_drvdata(master), to_platform_device(dev));
347 return 0; 348 return 0;
348} 349}
349 350
351static void hdmi_unbind(struct device *dev, struct device *master,
352 void *data)
353{
354 set_hdmi_pdev(dev_get_drvdata(master), NULL);
355}
356
357static const struct component_ops hdmi_ops = {
358 .bind = hdmi_bind,
359 .unbind = hdmi_unbind,
360};
361
362static int hdmi_dev_probe(struct platform_device *pdev)
363{
364 return component_add(&pdev->dev, &hdmi_ops);
365}
366
350static int hdmi_dev_remove(struct platform_device *pdev) 367static int hdmi_dev_remove(struct platform_device *pdev)
351{ 368{
352 hdmi_pdev = NULL; 369 component_del(&pdev->dev, &hdmi_ops);
353 return 0; 370 return 0;
354} 371}
355 372
@@ -357,7 +374,6 @@ static const struct of_device_id dt_match[] = {
357 { .compatible = "qcom,hdmi-tx" }, 374 { .compatible = "qcom,hdmi-tx" },
358 {} 375 {}
359}; 376};
360MODULE_DEVICE_TABLE(of, dt_match);
361 377
362static struct platform_driver hdmi_driver = { 378static struct platform_driver hdmi_driver = {
363 .probe = hdmi_dev_probe, 379 .probe = hdmi_dev_probe,
diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index e913efa4ea0a..7a7421fb02b4 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -56,6 +56,10 @@ static char *vram;
56MODULE_PARM_DESC(vram, "Configure VRAM size (for devices without IOMMU/GPUMMU"); 56MODULE_PARM_DESC(vram, "Configure VRAM size (for devices without IOMMU/GPUMMU");
57module_param(vram, charp, 0); 57module_param(vram, charp, 0);
58 58
59/*
60 * Util/helpers:
61 */
62
59void __iomem *msm_ioremap(struct platform_device *pdev, const char *name, 63void __iomem *msm_ioremap(struct platform_device *pdev, const char *name,
60 const char *dbgname) 64 const char *dbgname)
61{ 65{
@@ -143,6 +147,8 @@ static int msm_unload(struct drm_device *dev)
143 priv->vram.paddr, &attrs); 147 priv->vram.paddr, &attrs);
144 } 148 }
145 149
150 component_unbind_all(dev->dev, dev);
151
146 dev->dev_private = NULL; 152 dev->dev_private = NULL;
147 153
148 kfree(priv); 154 kfree(priv);
@@ -175,6 +181,7 @@ static int msm_load(struct drm_device *dev, unsigned long flags)
175 struct msm_kms *kms; 181 struct msm_kms *kms;
176 int ret; 182 int ret;
177 183
184
178 priv = kzalloc(sizeof(*priv), GFP_KERNEL); 185 priv = kzalloc(sizeof(*priv), GFP_KERNEL);
179 if (!priv) { 186 if (!priv) {
180 dev_err(dev->dev, "failed to allocate private data\n"); 187 dev_err(dev->dev, "failed to allocate private data\n");
@@ -226,6 +233,13 @@ static int msm_load(struct drm_device *dev, unsigned long flags)
226 (uint32_t)(priv->vram.paddr + size)); 233 (uint32_t)(priv->vram.paddr + size));
227 } 234 }
228 235
236 platform_set_drvdata(pdev, dev);
237
238 /* Bind all our sub-components: */
239 ret = component_bind_all(dev->dev, dev);
240 if (ret)
241 return ret;
242
229 switch (get_mdp_ver(pdev)) { 243 switch (get_mdp_ver(pdev)) {
230 case 4: 244 case 4:
231 kms = mdp4_kms_init(dev); 245 kms = mdp4_kms_init(dev);
@@ -281,8 +295,6 @@ static int msm_load(struct drm_device *dev, unsigned long flags)
281 goto fail; 295 goto fail;
282 } 296 }
283 297
284 platform_set_drvdata(pdev, dev);
285
286#ifdef CONFIG_DRM_MSM_FBDEV 298#ifdef CONFIG_DRM_MSM_FBDEV
287 priv->fbdev = msm_fbdev_init(dev); 299 priv->fbdev = msm_fbdev_init(dev);
288#endif 300#endif
@@ -824,18 +836,110 @@ static const struct dev_pm_ops msm_pm_ops = {
824}; 836};
825 837
826/* 838/*
839 * Componentized driver support:
840 */
841
842#ifdef CONFIG_OF
843/* NOTE: the CONFIG_OF case duplicates the same code as exynos or imx
844 * (or probably any other).. so probably some room for some helpers
845 */
846static int compare_of(struct device *dev, void *data)
847{
848 return dev->of_node == data;
849}
850
851static int msm_drm_add_components(struct device *master, struct master *m)
852{
853 struct device_node *np = master->of_node;
854 unsigned i;
855 int ret;
856
857 for (i = 0; ; i++) {
858 struct device_node *node;
859
860 node = of_parse_phandle(np, "connectors", i);
861 if (!node)
862 break;
863
864 ret = component_master_add_child(m, compare_of, node);
865 of_node_put(node);
866
867 if (ret)
868 return ret;
869 }
870 return 0;
871}
872#else
873static int compare_dev(struct device *dev, void *data)
874{
875 return dev == data;
876}
877
878static int msm_drm_add_components(struct device *master, struct master *m)
879{
880 /* For non-DT case, it kinda sucks. We don't actually have a way
881 * to know whether or not we are waiting for certain devices (or if
882 * they are simply not present). But for non-DT we only need to
883 * care about apq8064/apq8060/etc (all mdp4/a3xx):
884 */
885 static const char *devnames[] = {
886 "hdmi_msm.0", "kgsl-3d0.0",
887 };
888 int i;
889
890 DBG("Adding components..");
891
892 for (i = 0; i < ARRAY_SIZE(devnames); i++) {
893 struct device *dev;
894 int ret;
895
896 dev = bus_find_device_by_name(&platform_bus_type,
897 NULL, devnames[i]);
898 if (!dev) {
899 dev_info(master, "still waiting for %s\n", devnames[i]);
900 return -EPROBE_DEFER;
901 }
902
903 ret = component_master_add_child(m, compare_dev, dev);
904 if (ret) {
905 DBG("could not add child: %d", ret);
906 return ret;
907 }
908 }
909
910 return 0;
911}
912#endif
913
914static int msm_drm_bind(struct device *dev)
915{
916 return drm_platform_init(&msm_driver, to_platform_device(dev));
917}
918
919static void msm_drm_unbind(struct device *dev)
920{
921 drm_put_dev(platform_get_drvdata(to_platform_device(dev)));
922}
923
924static const struct component_master_ops msm_drm_ops = {
925 .add_components = msm_drm_add_components,
926 .bind = msm_drm_bind,
927 .unbind = msm_drm_unbind,
928};
929
930/*
827 * Platform driver: 931 * Platform driver:
828 */ 932 */
829 933
830static int msm_pdev_probe(struct platform_device *pdev) 934static int msm_pdev_probe(struct platform_device *pdev)
831{ 935{
832 pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32); 936 pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
833 return drm_platform_init(&msm_driver, pdev); 937 return component_master_add(&pdev->dev, &msm_drm_ops);
834} 938}
835 939
836static int msm_pdev_remove(struct platform_device *pdev) 940static int msm_pdev_remove(struct platform_device *pdev)
837{ 941{
838 drm_put_dev(platform_get_drvdata(pdev)); 942 component_master_del(&pdev->dev, &msm_drm_ops);
839 943
840 return 0; 944 return 0;
841} 945}
diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h
index 3d63269c5b29..9d10ee0b5aac 100644
--- a/drivers/gpu/drm/msm/msm_drv.h
+++ b/drivers/gpu/drm/msm/msm_drv.h
@@ -22,6 +22,7 @@
22#include <linux/clk.h> 22#include <linux/clk.h>
23#include <linux/cpufreq.h> 23#include <linux/cpufreq.h>
24#include <linux/module.h> 24#include <linux/module.h>
25#include <linux/component.h>
25#include <linux/platform_device.h> 26#include <linux/platform_device.h>
26#include <linux/pm.h> 27#include <linux/pm.h>
27#include <linux/pm_runtime.h> 28#include <linux/pm_runtime.h>
@@ -69,6 +70,9 @@ struct msm_drm_private {
69 70
70 struct msm_kms *kms; 71 struct msm_kms *kms;
71 72
73 /* subordinate devices, if present: */
74 struct platform_device *hdmi_pdev, *gpu_pdev;
75
72 /* when we have more than one 'msm_gpu' these need to be an array: */ 76 /* when we have more than one 'msm_gpu' these need to be an array: */
73 struct msm_gpu *gpu; 77 struct msm_gpu *gpu;
74 struct msm_file_private *lastctx; 78 struct msm_file_private *lastctx;