drm/msm: add headless gpu device for imx5
This patch allows using drm/msm without qcom display hardware. It adds a amd,imageon compatible, which is used instead of qcom,adreno, but does not require a top level msm node. Signed-off-by: Jonathan Marek <jonathan@marek.ca> Signed-off-by: Rob Clark <robdclark@gmail.com>
This commit is contained in:
Родитель
fb42b5354d
Коммит
e6f6d63ed1
|
@ -2,7 +2,7 @@
|
||||||
config DRM_MSM
|
config DRM_MSM
|
||||||
tristate "MSM DRM"
|
tristate "MSM DRM"
|
||||||
depends on DRM
|
depends on DRM
|
||||||
depends on ARCH_QCOM || (ARM && COMPILE_TEST)
|
depends on ARCH_QCOM || SOC_IMX5 || (ARM && COMPILE_TEST)
|
||||||
depends on OF && COMMON_CLK
|
depends on OF && COMMON_CLK
|
||||||
depends on MMU
|
depends on MMU
|
||||||
select QCOM_MDT_LOADER if ARCH_QCOM
|
select QCOM_MDT_LOADER if ARCH_QCOM
|
||||||
|
@ -11,7 +11,7 @@ config DRM_MSM
|
||||||
select DRM_PANEL
|
select DRM_PANEL
|
||||||
select SHMEM
|
select SHMEM
|
||||||
select TMPFS
|
select TMPFS
|
||||||
select QCOM_SCM
|
select QCOM_SCM if ARCH_QCOM
|
||||||
select WANT_DEV_COREDUMP
|
select WANT_DEV_COREDUMP
|
||||||
select SND_SOC_HDMI_CODEC if SND_SOC
|
select SND_SOC_HDMI_CODEC if SND_SOC
|
||||||
select SYNC_FILE
|
select SYNC_FILE
|
||||||
|
|
|
@ -271,7 +271,8 @@ static int find_chipid(struct device *dev, struct adreno_rev *rev)
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
unsigned int r, patch;
|
unsigned int r, patch;
|
||||||
|
|
||||||
if (sscanf(compat, "qcom,adreno-%u.%u", &r, &patch) == 2) {
|
if (sscanf(compat, "qcom,adreno-%u.%u", &r, &patch) == 2 ||
|
||||||
|
sscanf(compat, "amd,imageon-%u.%u", &r, &patch) == 2) {
|
||||||
rev->core = r / 100;
|
rev->core = r / 100;
|
||||||
r %= 100;
|
r %= 100;
|
||||||
rev->major = r / 10;
|
rev->major = r / 10;
|
||||||
|
@ -359,9 +360,37 @@ static const struct component_ops a3xx_ops = {
|
||||||
.unbind = adreno_unbind,
|
.unbind = adreno_unbind,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void adreno_device_register_headless(void)
|
||||||
|
{
|
||||||
|
/* on imx5, we don't have a top-level mdp/dpu node
|
||||||
|
* this creates a dummy node for the driver for that case
|
||||||
|
*/
|
||||||
|
struct platform_device_info dummy_info = {
|
||||||
|
.parent = NULL,
|
||||||
|
.name = "msm",
|
||||||
|
.id = -1,
|
||||||
|
.res = NULL,
|
||||||
|
.num_res = 0,
|
||||||
|
.data = NULL,
|
||||||
|
.size_data = 0,
|
||||||
|
.dma_mask = ~0,
|
||||||
|
};
|
||||||
|
platform_device_register_full(&dummy_info);
|
||||||
|
}
|
||||||
|
|
||||||
static int adreno_probe(struct platform_device *pdev)
|
static int adreno_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
return component_add(&pdev->dev, &a3xx_ops);
|
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = component_add(&pdev->dev, &a3xx_ops);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
if (of_device_is_compatible(pdev->dev.of_node, "amd,imageon"))
|
||||||
|
adreno_device_register_headless();
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int adreno_remove(struct platform_device *pdev)
|
static int adreno_remove(struct platform_device *pdev)
|
||||||
|
@ -373,6 +402,8 @@ static int adreno_remove(struct platform_device *pdev)
|
||||||
static const struct of_device_id dt_match[] = {
|
static const struct of_device_id dt_match[] = {
|
||||||
{ .compatible = "qcom,adreno" },
|
{ .compatible = "qcom,adreno" },
|
||||||
{ .compatible = "qcom,adreno-3xx" },
|
{ .compatible = "qcom,adreno-3xx" },
|
||||||
|
/* for compatibility with imx5 gpu: */
|
||||||
|
{ .compatible = "amd,imageon" },
|
||||||
/* for backwards compat w/ downstream kgsl DT files: */
|
/* for backwards compat w/ downstream kgsl DT files: */
|
||||||
{ .compatible = "qcom,kgsl-3d0" },
|
{ .compatible = "qcom,kgsl-3d0" },
|
||||||
{}
|
{}
|
||||||
|
|
|
@ -235,7 +235,7 @@ int msm_debugfs_init(struct drm_minor *minor)
|
||||||
debugfs_create_file("gpu", S_IRUSR, minor->debugfs_root,
|
debugfs_create_file("gpu", S_IRUSR, minor->debugfs_root,
|
||||||
dev, &msm_gpu_fops);
|
dev, &msm_gpu_fops);
|
||||||
|
|
||||||
if (priv->kms->funcs->debugfs_init) {
|
if (priv->kms && priv->kms->funcs->debugfs_init) {
|
||||||
ret = priv->kms->funcs->debugfs_init(priv->kms, minor);
|
ret = priv->kms->funcs->debugfs_init(priv->kms, minor);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -520,17 +520,13 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv)
|
||||||
priv->kms = kms;
|
priv->kms = kms;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
kms = ERR_PTR(-ENODEV);
|
/* valid only for the dummy headless case, where of_node=NULL */
|
||||||
|
WARN_ON(dev->of_node);
|
||||||
|
kms = NULL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IS_ERR(kms)) {
|
if (IS_ERR(kms)) {
|
||||||
/*
|
|
||||||
* NOTE: once we have GPU support, having no kms should not
|
|
||||||
* be considered fatal.. ideally we would still support gpu
|
|
||||||
* and (for example) use dmabuf/prime to share buffers with
|
|
||||||
* imx drm driver on iMX5
|
|
||||||
*/
|
|
||||||
DRM_DEV_ERROR(dev, "failed to load kms\n");
|
DRM_DEV_ERROR(dev, "failed to load kms\n");
|
||||||
ret = PTR_ERR(kms);
|
ret = PTR_ERR(kms);
|
||||||
priv->kms = NULL;
|
priv->kms = NULL;
|
||||||
|
@ -648,7 +644,7 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv)
|
||||||
drm_mode_config_reset(ddev);
|
drm_mode_config_reset(ddev);
|
||||||
|
|
||||||
#ifdef CONFIG_DRM_FBDEV_EMULATION
|
#ifdef CONFIG_DRM_FBDEV_EMULATION
|
||||||
if (fbdev)
|
if (kms && fbdev)
|
||||||
priv->fbdev = msm_fbdev_init(ddev);
|
priv->fbdev = msm_fbdev_init(ddev);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1332,6 +1328,7 @@ static int add_display_components(struct device *dev,
|
||||||
static const struct of_device_id msm_gpu_match[] = {
|
static const struct of_device_id msm_gpu_match[] = {
|
||||||
{ .compatible = "qcom,adreno" },
|
{ .compatible = "qcom,adreno" },
|
||||||
{ .compatible = "qcom,adreno-3xx" },
|
{ .compatible = "qcom,adreno-3xx" },
|
||||||
|
{ .compatible = "amd,imageon" },
|
||||||
{ .compatible = "qcom,kgsl-3d0" },
|
{ .compatible = "qcom,kgsl-3d0" },
|
||||||
{ },
|
{ },
|
||||||
};
|
};
|
||||||
|
@ -1376,9 +1373,11 @@ static int msm_pdev_probe(struct platform_device *pdev)
|
||||||
struct component_match *match = NULL;
|
struct component_match *match = NULL;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = add_display_components(&pdev->dev, &match);
|
if (get_mdp_ver(pdev)) {
|
||||||
if (ret)
|
ret = add_display_components(&pdev->dev, &match);
|
||||||
return ret;
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
ret = add_gpu_components(&pdev->dev, &match);
|
ret = add_gpu_components(&pdev->dev, &match);
|
||||||
if (ret)
|
if (ret)
|
||||||
|
|
Загрузка…
Ссылка в новой задаче