diff options
Diffstat (limited to 'drivers/gpu/drm/msm/msm_drv.c')
| -rw-r--r-- | drivers/gpu/drm/msm/msm_drv.c | 96 | 
1 files changed, 46 insertions, 50 deletions
diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index 9a5d87db5c23..fcf95680413d 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -52,7 +52,7 @@ module_param(reglog, bool, 0600);  #define reglog 0  #endif -static char *vram; +static char *vram = "16m";  MODULE_PARM_DESC(vram, "Configure VRAM size (for devices without IOMMU/GPUMMU");  module_param(vram, charp, 0); @@ -181,7 +181,6 @@ static int msm_load(struct drm_device *dev, unsigned long flags)  	struct msm_kms *kms;  	int ret; -  	priv = kzalloc(sizeof(*priv), GFP_KERNEL);  	if (!priv) {  		dev_err(dev->dev, "failed to allocate private data\n"); @@ -314,13 +313,15 @@ fail:  static void load_gpu(struct drm_device *dev)  { +	static DEFINE_MUTEX(init_lock);  	struct msm_drm_private *priv = dev->dev_private;  	struct msm_gpu *gpu; +	mutex_lock(&init_lock); +  	if (priv->gpu) -		return; +		goto out; -	mutex_lock(&dev->struct_mutex);  	gpu = a3xx_gpu_init(dev);  	if (IS_ERR(gpu)) {  		dev_warn(dev->dev, "failed to load a3xx gpu\n"); @@ -330,7 +331,9 @@ static void load_gpu(struct drm_device *dev)  	if (gpu) {  		int ret; +		mutex_lock(&dev->struct_mutex);  		gpu->funcs->pm_resume(gpu); +		mutex_unlock(&dev->struct_mutex);  		ret = gpu->funcs->hw_init(gpu);  		if (ret) {  			dev_err(dev->dev, "gpu hw init failed: %d\n", ret); @@ -340,12 +343,12 @@ static void load_gpu(struct drm_device *dev)  			/* give inactive pm a chance to kick in: */  			msm_gpu_retire(gpu);  		} -  	}  	priv->gpu = gpu; -	mutex_unlock(&dev->struct_mutex); +out: +	mutex_unlock(&init_lock);  }  static int msm_open(struct drm_device *dev, struct drm_file *file) @@ -906,25 +909,22 @@ static int compare_of(struct device *dev, void *data)  	return dev->of_node == data;  } -static int msm_drm_add_components(struct device *master, struct master *m) +static int add_components(struct device *dev, struct component_match **matchptr, +		const char *name)  { -	struct device_node *np = master->of_node; +	struct device_node *np = dev->of_node;  	unsigned i; -	int ret;  	for (i = 0; ; i++) {  		struct device_node *node; -		node = of_parse_phandle(np, "connectors", i); +		node = of_parse_phandle(np, name, i);  		if (!node)  			break; -		ret = component_master_add_child(m, compare_of, node); -		of_node_put(node); - -		if (ret) -			return ret; +		component_match_add(dev, matchptr, compare_of, node);  	} +  	return 0;  }  #else @@ -932,9 +932,34 @@ static int compare_dev(struct device *dev, void *data)  {  	return dev == data;  } +#endif -static int msm_drm_add_components(struct device *master, struct master *m) +static int msm_drm_bind(struct device *dev)  { +	return drm_platform_init(&msm_driver, to_platform_device(dev)); +} + +static void msm_drm_unbind(struct device *dev) +{ +	drm_put_dev(platform_get_drvdata(to_platform_device(dev))); +} + +static const struct component_master_ops msm_drm_ops = { +	.bind = msm_drm_bind, +	.unbind = msm_drm_unbind, +}; + +/* + * Platform driver: + */ + +static int msm_pdev_probe(struct platform_device *pdev) +{ +	struct component_match *match = NULL; +#ifdef CONFIG_OF +	add_components(&pdev->dev, &match, "connectors"); +	add_components(&pdev->dev, &match, "gpus"); +#else  	/* For non-DT case, it kinda sucks.  We don't actually have a way  	 * to know whether or not we are waiting for certain devices (or if  	 * they are simply not present).  But for non-DT we only need to @@ -949,50 +974,20 @@ static int msm_drm_add_components(struct device *master, struct master *m)  	for (i = 0; i < ARRAY_SIZE(devnames); i++) {  		struct device *dev; -		int ret;  		dev = bus_find_device_by_name(&platform_bus_type,  				NULL, devnames[i]);  		if (!dev) { -			dev_info(master, "still waiting for %s\n", devnames[i]); +			dev_info(&pdev->dev, "still waiting for %s\n", devnames[i]);  			return -EPROBE_DEFER;  		} -		ret = component_master_add_child(m, compare_dev, dev); -		if (ret) { -			DBG("could not add child: %d", ret); -			return ret; -		} +		component_match_add(&pdev->dev, &match, compare_dev, dev);  	} - -	return 0; -}  #endif -static int msm_drm_bind(struct device *dev) -{ -	return drm_platform_init(&msm_driver, to_platform_device(dev)); -} - -static void msm_drm_unbind(struct device *dev) -{ -	drm_put_dev(platform_get_drvdata(to_platform_device(dev))); -} - -static const struct component_master_ops msm_drm_ops = { -		.add_components = msm_drm_add_components, -		.bind = msm_drm_bind, -		.unbind = msm_drm_unbind, -}; - -/* - * Platform driver: - */ - -static int msm_pdev_probe(struct platform_device *pdev) -{  	pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32); -	return component_master_add(&pdev->dev, &msm_drm_ops); +	return component_master_add_with_match(&pdev->dev, &msm_drm_ops, match);  }  static int msm_pdev_remove(struct platform_device *pdev) @@ -1008,7 +1003,8 @@ static const struct platform_device_id msm_id[] = {  };  static const struct of_device_id dt_match[] = { -	{ .compatible = "qcom,mdss_mdp" }, +	{ .compatible = "qcom,mdp" },      /* mdp4 */ +	{ .compatible = "qcom,mdss_mdp" }, /* mdp5 */  	{}  };  MODULE_DEVICE_TABLE(of, dt_match);  |