Commit da52605e authored by Rongrong Zou's avatar Rongrong Zou

drm/hisilicon/hibmc: Add support for display engine

Add display engine function, crtc/plane is initialized here.
Signed-off-by: default avatarRongrong Zou <zourongrong@gmail.com>
Reviewed-by: default avatarSean Paul <seanpaul@chromium.org>
Reviewed-by: default avatarXinliang Liu <xinliang.liu@linaro.org>
Acked-by: default avatarSean Paul <seanpaul@chromium.org>
parent d1667b86
ccflags-y := -Iinclude/drm ccflags-y := -Iinclude/drm
hibmc-drm-y := hibmc_drm_drv.o hibmc_drm_fbdev.o hibmc_ttm.o hibmc-drm-y := hibmc_drm_drv.o hibmc_drm_de.o hibmc_drm_fbdev.o hibmc_ttm.o
obj-$(CONFIG_DRM_HISI_HIBMC) += hibmc-drm.o obj-$(CONFIG_DRM_HISI_HIBMC) += hibmc-drm.o
This diff is collapsed.
...@@ -19,6 +19,9 @@ ...@@ -19,6 +19,9 @@
#include <linux/console.h> #include <linux/console.h>
#include <linux/module.h> #include <linux/module.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_crtc_helper.h>
#include "hibmc_drm_drv.h" #include "hibmc_drm_drv.h"
#include "hibmc_drm_regs.h" #include "hibmc_drm_regs.h"
...@@ -44,7 +47,8 @@ static void hibmc_disable_vblank(struct drm_device *dev, unsigned int pipe) ...@@ -44,7 +47,8 @@ static void hibmc_disable_vblank(struct drm_device *dev, unsigned int pipe)
} }
static struct drm_driver hibmc_driver = { static struct drm_driver hibmc_driver = {
.driver_features = DRIVER_GEM, .driver_features = DRIVER_GEM | DRIVER_MODESET |
DRIVER_ATOMIC,
.fops = &hibmc_fops, .fops = &hibmc_fops,
.name = "hibmc", .name = "hibmc",
.date = "20160828", .date = "20160828",
...@@ -62,11 +66,31 @@ static struct drm_driver hibmc_driver = { ...@@ -62,11 +66,31 @@ static struct drm_driver hibmc_driver = {
static int hibmc_pm_suspend(struct device *dev) static int hibmc_pm_suspend(struct device *dev)
{ {
struct pci_dev *pdev = to_pci_dev(dev);
struct drm_device *drm_dev = pci_get_drvdata(pdev);
struct hibmc_drm_private *priv = drm_dev->dev_private;
drm_kms_helper_poll_disable(drm_dev);
priv->suspend_state = drm_atomic_helper_suspend(drm_dev);
if (IS_ERR(priv->suspend_state)) {
DRM_ERROR("drm_atomic_helper_suspend failed: %ld\n",
PTR_ERR(priv->suspend_state));
drm_kms_helper_poll_enable(drm_dev);
return PTR_ERR(priv->suspend_state);
}
return 0; return 0;
} }
static int hibmc_pm_resume(struct device *dev) static int hibmc_pm_resume(struct device *dev)
{ {
struct pci_dev *pdev = to_pci_dev(dev);
struct drm_device *drm_dev = pci_get_drvdata(pdev);
struct hibmc_drm_private *priv = drm_dev->dev_private;
drm_atomic_helper_resume(drm_dev, priv->suspend_state);
drm_kms_helper_poll_enable(drm_dev);
return 0; return 0;
} }
...@@ -75,6 +99,41 @@ static const struct dev_pm_ops hibmc_pm_ops = { ...@@ -75,6 +99,41 @@ static const struct dev_pm_ops hibmc_pm_ops = {
hibmc_pm_resume) hibmc_pm_resume)
}; };
static int hibmc_kms_init(struct hibmc_drm_private *priv)
{
int ret;
drm_mode_config_init(priv->dev);
priv->mode_config_initialized = true;
priv->dev->mode_config.min_width = 0;
priv->dev->mode_config.min_height = 0;
priv->dev->mode_config.max_width = 1920;
priv->dev->mode_config.max_height = 1440;
priv->dev->mode_config.fb_base = priv->fb_base;
priv->dev->mode_config.preferred_depth = 24;
priv->dev->mode_config.prefer_shadow = 0;
priv->dev->mode_config.funcs = (void *)&hibmc_mode_funcs;
ret = hibmc_de_init(priv);
if (ret) {
DRM_ERROR("failed to init de: %d\n", ret);
return ret;
}
return 0;
}
static void hibmc_kms_fini(struct hibmc_drm_private *priv)
{
if (priv->mode_config_initialized) {
drm_mode_config_cleanup(priv->dev);
priv->mode_config_initialized = false;
}
}
/* /*
* It can operate in one of three modes: 0, 1 or Sleep. * It can operate in one of three modes: 0, 1 or Sleep.
*/ */
...@@ -203,6 +262,7 @@ static int hibmc_unload(struct drm_device *dev) ...@@ -203,6 +262,7 @@ static int hibmc_unload(struct drm_device *dev)
struct hibmc_drm_private *priv = dev->dev_private; struct hibmc_drm_private *priv = dev->dev_private;
hibmc_fbdev_fini(priv); hibmc_fbdev_fini(priv);
hibmc_kms_fini(priv);
hibmc_mm_fini(priv); hibmc_mm_fini(priv);
dev->dev_private = NULL; dev->dev_private = NULL;
return 0; return 0;
...@@ -229,6 +289,13 @@ static int hibmc_load(struct drm_device *dev) ...@@ -229,6 +289,13 @@ static int hibmc_load(struct drm_device *dev)
if (ret) if (ret)
goto err; goto err;
ret = hibmc_kms_init(priv);
if (ret)
goto err;
/* reset all the states of crtc/plane/encoder/connector */
drm_mode_config_reset(dev);
ret = hibmc_fbdev_init(priv); ret = hibmc_fbdev_init(priv);
if (ret) { if (ret) {
DRM_ERROR("failed to initialize fbdev: %d\n", ret); DRM_ERROR("failed to initialize fbdev: %d\n", ret);
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#define HIBMC_DRM_DRV_H #define HIBMC_DRM_DRV_H
#include <drm/drmP.h> #include <drm/drmP.h>
#include <drm/drm_atomic.h>
#include <drm/drm_fb_helper.h> #include <drm/drm_fb_helper.h>
#include <drm/drm_gem.h> #include <drm/drm_gem.h>
#include <drm/ttm/ttm_bo_driver.h> #include <drm/ttm/ttm_bo_driver.h>
...@@ -44,6 +45,8 @@ struct hibmc_drm_private { ...@@ -44,6 +45,8 @@ struct hibmc_drm_private {
/* drm */ /* drm */
struct drm_device *dev; struct drm_device *dev;
bool mode_config_initialized;
struct drm_atomic_state *suspend_state;
/* ttm */ /* ttm */
struct drm_global_reference mem_global_ref; struct drm_global_reference mem_global_ref;
...@@ -82,6 +85,7 @@ void hibmc_set_power_mode(struct hibmc_drm_private *priv, ...@@ -82,6 +85,7 @@ void hibmc_set_power_mode(struct hibmc_drm_private *priv,
void hibmc_set_current_gate(struct hibmc_drm_private *priv, void hibmc_set_current_gate(struct hibmc_drm_private *priv,
unsigned int gate); unsigned int gate);
int hibmc_de_init(struct hibmc_drm_private *priv);
int hibmc_fbdev_init(struct hibmc_drm_private *priv); int hibmc_fbdev_init(struct hibmc_drm_private *priv);
void hibmc_fbdev_fini(struct hibmc_drm_private *priv); void hibmc_fbdev_fini(struct hibmc_drm_private *priv);
...@@ -103,4 +107,6 @@ int hibmc_dumb_mmap_offset(struct drm_file *file, struct drm_device *dev, ...@@ -103,4 +107,6 @@ int hibmc_dumb_mmap_offset(struct drm_file *file, struct drm_device *dev,
u32 handle, u64 *offset); u32 handle, u64 *offset);
int hibmc_mmap(struct file *filp, struct vm_area_struct *vma); int hibmc_mmap(struct file *filp, struct vm_area_struct *vma);
extern const struct drm_mode_config_funcs hibmc_mode_funcs;
#endif #endif
...@@ -550,3 +550,9 @@ hibmc_user_framebuffer_create(struct drm_device *dev, ...@@ -550,3 +550,9 @@ hibmc_user_framebuffer_create(struct drm_device *dev,
} }
return &hibmc_fb->fb; return &hibmc_fb->fb;
} }
const struct drm_mode_config_funcs hibmc_mode_funcs = {
.atomic_check = drm_atomic_helper_check,
.atomic_commit = drm_atomic_helper_commit,
.fb_create = hibmc_user_framebuffer_create,
};
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment