Merge tag 'drm-next-2018-12-14' of git://anongit.freedesktop.org/drm/drm
Pull drm updates from Dave Airlie: "Core: - shared fencing staging removal - drop transactional atomic helpers and move helpers to new location - DP/MST atomic cleanup - Leasing cleanups and drop EXPORT_SYMBOL - Convert drivers to atomic helpers and generic fbdev. - removed deprecated obj_ref/unref in favour of get/put - Improve dumb callback documentation - MODESET_LOCK_BEGIN/END helpers panels: - CDTech panels, Banana Pi Panel, DLC1010GIG, - Olimex LCD-O-LinuXino, Samsung S6D16D0, Truly NT35597 WQXGA, - Himax HX8357D, simulated RTSM AEMv8. - GPD Win2 panel - AUO G101EVN010 vgem: - render node support ttm: - move global init out of drivers - fix LRU handling for ghost objects - Support for simultaneous submissions to multiple engines scheduler: - timeout/fault handling changes to help GPU recovery - helpers for hw with preemption support i915: - Scaler/Watermark fixes - DP MST + powerwell fixes - PSR fixes - Break long get/put shmemfs pages - Icelake fixes - Icelake DSI video mode enablement - Engine workaround improvements amdgpu: - freesync support - GPU reset enabled on CI, VI, SOC15 dGPUs - ABM support in DC - KFD support for vega12/polaris12 - SDMA paging queue on vega - More amdkfd code sharing - DCC scanout on GFX9 - DC kerneldoc - Updated SMU firmware for GFX8 chips - XGMI PSP + hive reset support - GPU reset - DC trace support - Powerplay updates for newer Polaris - Cursor plane update fast path - kfd dma-buf support virtio-gpu: - add EDID support vmwgfx: - pageflip with damage support nouveau: - Initial Turing TU104/TU106 modesetting support msm: - a2xx gpu support for apq8060 and imx5 - a2xx gpummu support - mdp4 display support for apq8060 - DPU fixes and cleanups - enhanced profiling support - debug object naming interface - get_iova/page pinning decoupling tegra: - Tegra194 host1x, VIC and display support enabled - Audio over HDMI for Tegra186 and Tegra194 exynos: - DMA/IOMMU refactoring - plane alpha + blend mode support - Color format fixes for mixer driver rcar-du: - R8A7744 and R8A77470 support - R8A77965 LVDS support imx: - fbdev emulation fix - multi-tiled scalling fixes - SPDX identifiers rockchip - dw_hdmi support - dw-mipi-dsi + dual dsi support - mailbox read size fix qxl: - fix cursor pinning vc4: - YUV support (scaling + cursor) v3d: - enable TFU (Texture Formatting Unit) mali-dp: - add support for linear tiled formats sun4i: - Display Engine 3 support - H6 DE3 mixer 0 support - H6 display engine support - dw-hdmi support - H6 HDMI phy support - implicit fence waiting - BGRX8888 support meson: - Overlay plane support - implicit fence waiting - HDMI 1.4 4k modes bridge: - i2c fixes for sii902x" * tag 'drm-next-2018-12-14' of git://anongit.freedesktop.org/drm/drm: (1403 commits) drm/amd/display: Add fast path for cursor plane updates drm/amdgpu: Enable GPU recovery by default for CI drm/amd/display: Fix duplicating scaling/underscan connector state drm/amd/display: Fix unintialized max_bpc state values Revert "drm/amd/display: Set RMX_ASPECT as default" drm/amdgpu: Fix stub function name drm/msm/dpu: Fix clock issue after bind failure drm/msm/dpu: Clean up dpu_media_info.h static inline functions drm/msm/dpu: Further cleanups for static inline functions drm/msm/dpu: Cleanup the debugfs functions drm/msm/dpu: Remove dpu_irq and unused functions drm/msm: Make irq_postinstall optional drm/msm/dpu: Cleanup callers of dpu_hw_blk_init drm/msm/dpu: Remove unused functions drm/msm/dpu: Remove dpu_crtc_is_enabled() drm/msm/dpu: Remove dpu_crtc_get_mixer_height drm/msm/dpu: Remove dpu_dbg drm/msm: dpu: Remove crtc_lock drm/msm: dpu: Remove vblank_requested flag from dpu_crtc drm/msm: dpu: Separate crtc assignment from vblank enable ...
This commit is contained in:
@@ -23,8 +23,10 @@
|
||||
#include "msm_drv.h"
|
||||
#include "msm_debugfs.h"
|
||||
#include "msm_fence.h"
|
||||
#include "msm_gem.h"
|
||||
#include "msm_gpu.h"
|
||||
#include "msm_kms.h"
|
||||
#include "adreno/adreno_gpu.h"
|
||||
|
||||
|
||||
/*
|
||||
@@ -35,9 +37,11 @@
|
||||
* - 1.3.0 - adds GMEM_BASE + NR_RINGS params, SUBMITQUEUE_NEW +
|
||||
* SUBMITQUEUE_CLOSE ioctls, and MSM_INFO_IOVA flag for
|
||||
* MSM_GEM_INFO ioctl.
|
||||
* - 1.4.0 - softpin, MSM_RELOC_BO_DUMP, and GEM_INFO support to set/get
|
||||
* GEM object's debug name
|
||||
*/
|
||||
#define MSM_VERSION_MAJOR 1
|
||||
#define MSM_VERSION_MINOR 3
|
||||
#define MSM_VERSION_MINOR 4
|
||||
#define MSM_VERSION_PATCHLEVEL 0
|
||||
|
||||
static const struct drm_mode_config_funcs mode_config_funcs = {
|
||||
@@ -170,7 +174,7 @@ void __iomem *msm_ioremap(struct platform_device *pdev, const char *name,
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
|
||||
if (!res) {
|
||||
dev_err(&pdev->dev, "failed to get memory resource: %s\n", name);
|
||||
DRM_DEV_ERROR(&pdev->dev, "failed to get memory resource: %s\n", name);
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
@@ -178,7 +182,7 @@ void __iomem *msm_ioremap(struct platform_device *pdev, const char *name,
|
||||
|
||||
ptr = devm_ioremap_nocache(&pdev->dev, res->start, size);
|
||||
if (!ptr) {
|
||||
dev_err(&pdev->dev, "failed to ioremap: %s\n", name);
|
||||
DRM_DEV_ERROR(&pdev->dev, "failed to ioremap: %s\n", name);
|
||||
return ERR_PTR(-ENOMEM);
|
||||
}
|
||||
|
||||
@@ -312,6 +316,7 @@ static int msm_drm_uninit(struct device *dev)
|
||||
if (fbdev && priv->fbdev)
|
||||
msm_fbdev_free(ddev);
|
||||
#endif
|
||||
drm_atomic_helper_shutdown(ddev);
|
||||
drm_mode_config_cleanup(ddev);
|
||||
|
||||
pm_runtime_get_sync(dev);
|
||||
@@ -357,6 +362,14 @@ static int get_mdp_ver(struct platform_device *pdev)
|
||||
|
||||
#include <linux/of_address.h>
|
||||
|
||||
bool msm_use_mmu(struct drm_device *dev)
|
||||
{
|
||||
struct msm_drm_private *priv = dev->dev_private;
|
||||
|
||||
/* a2xx comes with its own MMU */
|
||||
return priv->is_a2xx || iommu_present(&platform_bus_type);
|
||||
}
|
||||
|
||||
static int msm_init_vram(struct drm_device *dev)
|
||||
{
|
||||
struct msm_drm_private *priv = dev->dev_private;
|
||||
@@ -395,7 +408,7 @@ static int msm_init_vram(struct drm_device *dev)
|
||||
* Grab the entire CMA chunk carved out in early startup in
|
||||
* mach-msm:
|
||||
*/
|
||||
} else if (!iommu_present(&platform_bus_type)) {
|
||||
} else if (!msm_use_mmu(dev)) {
|
||||
DRM_INFO("using %s VRAM carveout\n", vram);
|
||||
size = memparse(vram, NULL);
|
||||
}
|
||||
@@ -418,12 +431,12 @@ static int msm_init_vram(struct drm_device *dev)
|
||||
p = dma_alloc_attrs(dev->dev, size,
|
||||
&priv->vram.paddr, GFP_KERNEL, attrs);
|
||||
if (!p) {
|
||||
dev_err(dev->dev, "failed to allocate VRAM\n");
|
||||
DRM_DEV_ERROR(dev->dev, "failed to allocate VRAM\n");
|
||||
priv->vram.paddr = 0;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
dev_info(dev->dev, "VRAM: %08x->%08x\n",
|
||||
DRM_DEV_INFO(dev->dev, "VRAM: %08x->%08x\n",
|
||||
(uint32_t)priv->vram.paddr,
|
||||
(uint32_t)(priv->vram.paddr + size));
|
||||
}
|
||||
@@ -443,7 +456,7 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv)
|
||||
|
||||
ddev = drm_dev_alloc(drv, dev);
|
||||
if (IS_ERR(ddev)) {
|
||||
dev_err(dev, "failed to allocate drm_device\n");
|
||||
DRM_DEV_ERROR(dev, "failed to allocate drm_device\n");
|
||||
return PTR_ERR(ddev);
|
||||
}
|
||||
|
||||
@@ -507,19 +520,16 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv)
|
||||
priv->kms = kms;
|
||||
break;
|
||||
default:
|
||||
kms = ERR_PTR(-ENODEV);
|
||||
/* valid only for the dummy headless case, where of_node=NULL */
|
||||
WARN_ON(dev->of_node);
|
||||
kms = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
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
|
||||
*/
|
||||
dev_err(dev, "failed to load kms\n");
|
||||
DRM_DEV_ERROR(dev, "failed to load kms\n");
|
||||
ret = PTR_ERR(kms);
|
||||
priv->kms = NULL;
|
||||
goto err_msm_uninit;
|
||||
}
|
||||
|
||||
@@ -529,7 +539,7 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv)
|
||||
if (kms) {
|
||||
ret = kms->funcs->hw_init(kms);
|
||||
if (ret) {
|
||||
dev_err(dev, "kms hw init failed: %d\n", ret);
|
||||
DRM_DEV_ERROR(dev, "kms hw init failed: %d\n", ret);
|
||||
goto err_msm_uninit;
|
||||
}
|
||||
}
|
||||
@@ -554,7 +564,7 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv)
|
||||
&priv->disp_thread[i].worker,
|
||||
"crtc_commit:%d", priv->disp_thread[i].crtc_id);
|
||||
if (IS_ERR(priv->disp_thread[i].thread)) {
|
||||
dev_err(dev, "failed to create crtc_commit kthread\n");
|
||||
DRM_DEV_ERROR(dev, "failed to create crtc_commit kthread\n");
|
||||
priv->disp_thread[i].thread = NULL;
|
||||
goto err_msm_uninit;
|
||||
}
|
||||
@@ -574,7 +584,7 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv)
|
||||
&priv->event_thread[i].worker,
|
||||
"crtc_event:%d", priv->event_thread[i].crtc_id);
|
||||
if (IS_ERR(priv->event_thread[i].thread)) {
|
||||
dev_err(dev, "failed to create crtc_event kthread\n");
|
||||
DRM_DEV_ERROR(dev, "failed to create crtc_event kthread\n");
|
||||
priv->event_thread[i].thread = NULL;
|
||||
goto err_msm_uninit;
|
||||
}
|
||||
@@ -595,7 +605,7 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv)
|
||||
|
||||
ret = drm_vblank_init(ddev, priv->num_crtcs);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "failed to initialize vblank\n");
|
||||
DRM_DEV_ERROR(dev, "failed to initialize vblank\n");
|
||||
goto err_msm_uninit;
|
||||
}
|
||||
|
||||
@@ -604,7 +614,7 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv)
|
||||
ret = drm_irq_install(ddev, kms->irq);
|
||||
pm_runtime_put_sync(dev);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "failed to install IRQ handler\n");
|
||||
DRM_DEV_ERROR(dev, "failed to install IRQ handler\n");
|
||||
goto err_msm_uninit;
|
||||
}
|
||||
}
|
||||
@@ -616,7 +626,7 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv)
|
||||
drm_mode_config_reset(ddev);
|
||||
|
||||
#ifdef CONFIG_DRM_FBDEV_EMULATION
|
||||
if (fbdev)
|
||||
if (kms && fbdev)
|
||||
priv->fbdev = msm_fbdev_init(ddev);
|
||||
#endif
|
||||
|
||||
@@ -724,7 +734,11 @@ static int msm_irq_postinstall(struct drm_device *dev)
|
||||
struct msm_drm_private *priv = dev->dev_private;
|
||||
struct msm_kms *kms = priv->kms;
|
||||
BUG_ON(!kms);
|
||||
return kms->funcs->irq_postinstall(kms);
|
||||
|
||||
if (kms->funcs->irq_postinstall)
|
||||
return kms->funcs->irq_postinstall(kms);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void msm_irq_uninstall(struct drm_device *dev)
|
||||
@@ -791,7 +805,7 @@ static int msm_ioctl_gem_new(struct drm_device *dev, void *data,
|
||||
}
|
||||
|
||||
return msm_gem_new_handle(dev, file, args->size,
|
||||
args->flags, &args->handle);
|
||||
args->flags, &args->handle, NULL);
|
||||
}
|
||||
|
||||
static inline ktime_t to_ktime(struct drm_msm_timespec timeout)
|
||||
@@ -849,6 +863,10 @@ static int msm_ioctl_gem_info_iova(struct drm_device *dev,
|
||||
if (!priv->gpu)
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
* Don't pin the memory here - just get an address so that userspace can
|
||||
* be productive
|
||||
*/
|
||||
return msm_gem_get_iova(obj, priv->gpu->aspace, iova);
|
||||
}
|
||||
|
||||
@@ -857,23 +875,66 @@ static int msm_ioctl_gem_info(struct drm_device *dev, void *data,
|
||||
{
|
||||
struct drm_msm_gem_info *args = data;
|
||||
struct drm_gem_object *obj;
|
||||
int ret = 0;
|
||||
struct msm_gem_object *msm_obj;
|
||||
int i, ret = 0;
|
||||
|
||||
if (args->flags & ~MSM_INFO_FLAGS)
|
||||
if (args->pad)
|
||||
return -EINVAL;
|
||||
|
||||
switch (args->info) {
|
||||
case MSM_INFO_GET_OFFSET:
|
||||
case MSM_INFO_GET_IOVA:
|
||||
/* value returned as immediate, not pointer, so len==0: */
|
||||
if (args->len)
|
||||
return -EINVAL;
|
||||
break;
|
||||
case MSM_INFO_SET_NAME:
|
||||
case MSM_INFO_GET_NAME:
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
obj = drm_gem_object_lookup(file, args->handle);
|
||||
if (!obj)
|
||||
return -ENOENT;
|
||||
|
||||
if (args->flags & MSM_INFO_IOVA) {
|
||||
uint64_t iova;
|
||||
msm_obj = to_msm_bo(obj);
|
||||
|
||||
ret = msm_ioctl_gem_info_iova(dev, obj, &iova);
|
||||
if (!ret)
|
||||
args->offset = iova;
|
||||
} else {
|
||||
args->offset = msm_gem_mmap_offset(obj);
|
||||
switch (args->info) {
|
||||
case MSM_INFO_GET_OFFSET:
|
||||
args->value = msm_gem_mmap_offset(obj);
|
||||
break;
|
||||
case MSM_INFO_GET_IOVA:
|
||||
ret = msm_ioctl_gem_info_iova(dev, obj, &args->value);
|
||||
break;
|
||||
case MSM_INFO_SET_NAME:
|
||||
/* length check should leave room for terminating null: */
|
||||
if (args->len >= sizeof(msm_obj->name)) {
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
ret = copy_from_user(msm_obj->name,
|
||||
u64_to_user_ptr(args->value), args->len);
|
||||
msm_obj->name[args->len] = '\0';
|
||||
for (i = 0; i < args->len; i++) {
|
||||
if (!isprint(msm_obj->name[i])) {
|
||||
msm_obj->name[i] = '\0';
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case MSM_INFO_GET_NAME:
|
||||
if (args->value && (args->len < strlen(msm_obj->name))) {
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
args->len = strlen(msm_obj->name);
|
||||
if (args->value) {
|
||||
ret = copy_to_user(u64_to_user_ptr(args->value),
|
||||
msm_obj->name, args->len);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
drm_gem_object_put_unlocked(obj);
|
||||
@@ -1052,18 +1113,15 @@ static int msm_pm_suspend(struct device *dev)
|
||||
{
|
||||
struct drm_device *ddev = dev_get_drvdata(dev);
|
||||
struct msm_drm_private *priv = ddev->dev_private;
|
||||
struct msm_kms *kms = priv->kms;
|
||||
|
||||
/* TODO: Use atomic helper suspend/resume */
|
||||
if (kms && kms->funcs && kms->funcs->pm_suspend)
|
||||
return kms->funcs->pm_suspend(dev);
|
||||
|
||||
drm_kms_helper_poll_disable(ddev);
|
||||
if (WARN_ON(priv->pm_state))
|
||||
drm_atomic_state_put(priv->pm_state);
|
||||
|
||||
priv->pm_state = drm_atomic_helper_suspend(ddev);
|
||||
if (IS_ERR(priv->pm_state)) {
|
||||
drm_kms_helper_poll_enable(ddev);
|
||||
return PTR_ERR(priv->pm_state);
|
||||
int ret = PTR_ERR(priv->pm_state);
|
||||
DRM_ERROR("Failed to suspend dpu, %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -1073,16 +1131,16 @@ static int msm_pm_resume(struct device *dev)
|
||||
{
|
||||
struct drm_device *ddev = dev_get_drvdata(dev);
|
||||
struct msm_drm_private *priv = ddev->dev_private;
|
||||
struct msm_kms *kms = priv->kms;
|
||||
int ret;
|
||||
|
||||
/* TODO: Use atomic helper suspend/resume */
|
||||
if (kms && kms->funcs && kms->funcs->pm_resume)
|
||||
return kms->funcs->pm_resume(dev);
|
||||
if (WARN_ON(!priv->pm_state))
|
||||
return -ENOENT;
|
||||
|
||||
drm_atomic_helper_resume(ddev, priv->pm_state);
|
||||
drm_kms_helper_poll_enable(ddev);
|
||||
ret = drm_atomic_helper_resume(ddev, priv->pm_state);
|
||||
if (!ret)
|
||||
priv->pm_state = NULL;
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1167,7 +1225,7 @@ static int add_components_mdp(struct device *mdp_dev,
|
||||
|
||||
ret = of_graph_parse_endpoint(ep_node, &ep);
|
||||
if (ret) {
|
||||
dev_err(mdp_dev, "unable to parse port endpoint\n");
|
||||
DRM_DEV_ERROR(mdp_dev, "unable to parse port endpoint\n");
|
||||
of_node_put(ep_node);
|
||||
return ret;
|
||||
}
|
||||
@@ -1189,8 +1247,10 @@ static int add_components_mdp(struct device *mdp_dev,
|
||||
if (!intf)
|
||||
continue;
|
||||
|
||||
drm_of_component_match_add(master_dev, matchptr, compare_of,
|
||||
intf);
|
||||
if (of_device_is_available(intf))
|
||||
drm_of_component_match_add(master_dev, matchptr,
|
||||
compare_of, intf);
|
||||
|
||||
of_node_put(intf);
|
||||
}
|
||||
|
||||
@@ -1218,13 +1278,13 @@ static int add_display_components(struct device *dev,
|
||||
of_device_is_compatible(dev->of_node, "qcom,sdm845-mdss")) {
|
||||
ret = of_platform_populate(dev->of_node, NULL, NULL, dev);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to populate children devices\n");
|
||||
DRM_DEV_ERROR(dev, "failed to populate children devices\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
mdp_dev = device_find_child(dev, NULL, compare_name_mdp);
|
||||
if (!mdp_dev) {
|
||||
dev_err(dev, "failed to find MDSS MDP node\n");
|
||||
DRM_DEV_ERROR(dev, "failed to find MDSS MDP node\n");
|
||||
of_platform_depopulate(dev);
|
||||
return -ENODEV;
|
||||
}
|
||||
@@ -1254,6 +1314,7 @@ static int add_display_components(struct device *dev,
|
||||
static const struct of_device_id msm_gpu_match[] = {
|
||||
{ .compatible = "qcom,adreno" },
|
||||
{ .compatible = "qcom,adreno-3xx" },
|
||||
{ .compatible = "amd,imageon" },
|
||||
{ .compatible = "qcom,kgsl-3d0" },
|
||||
{ },
|
||||
};
|
||||
@@ -1298,9 +1359,11 @@ static int msm_pdev_probe(struct platform_device *pdev)
|
||||
struct component_match *match = NULL;
|
||||
int ret;
|
||||
|
||||
ret = add_display_components(&pdev->dev, &match);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (get_mdp_ver(pdev)) {
|
||||
ret = add_display_components(&pdev->dev, &match);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = add_gpu_components(&pdev->dev, &match);
|
||||
if (ret)
|
||||
|
Reference in New Issue
Block a user