aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/msm/msm_drv.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/msm/msm_drv.c')
-rw-r--r--drivers/gpu/drm/msm/msm_drv.c112
1 files changed, 108 insertions, 4 deletions
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}