Armada DRM driver
Subsystems (3)
v4 cover Armada DRM driver
Quite a number of things has changed since the last revision in the core code - notably the move to use drm_plane for overlay, and the limited and restricted use of dma_buf so that gem objects can be passed to the GALCORE code and libbmm contiguous video frames can be imported into DRM.
As I thought, this does require quite a number of new system calls, but the case which I care more about (vlc) doesn't pass rendered frames directly to the X server by physical address, it's not something I'm particularly concerned about - for vlc and the "normal" Xv protocol we can cache four DRM gem objects with their framebuffers pre-prepared meaning we just copy the frame and call the DRM set_plane function.
What the loss of the create_phys() interface does mean is that the modified gstreamer gstbmmxvimagesink plugin will not work; it will need to be updated. I do *not* intend to support the hacky bidirectional Xv SHM hack which Marvell came up with there!
I've left out the TDA998x changes and the final patch which depends on those changes which add the HDMI output for the cubox, so this series will be lacking the final parts of connector support. It is probable that the patch from the previous series can be trivially applied to this (or easily adapted if not.)
Other changes:
- the crtc exports a few attributes now for setting the colour transform mode. (CCIR601/709 to Computer vs "Studio" RGB). An automatic mode for these settings provided depending on selected resolution.
- overlay has working brightness/contrast/saturation settings, but not hue - not worked that bit out yet.
- hardware ARGB cursor support only in this version.
- backend ops are now called variants, because the structure started to contain other stuff other than just function pointers. Armada510 backend moved to a separate file.
- features requiring the SPU_ADV_REG (only present on Armada 510) can be disabled by the variant structure - such as interlace and ARGB cursor.
- use of page_alloc() reduced down to 8K, enough to store the hardware cursor. This is all that that allocation was really used for anyway.
- now uses a common kfifo queue to free used framebuffers at the appropriate time, both from the crtc code and the drm_plane code, rather than having this logic in several places. kfifo is a weird API and there's a note in the driver about that.
- framebuffers now carry their configuration with them, to save having the pixel format decode scattered in several places in the driver.
- power down FIFOs and RAMs not being used, and keep them powered down where possible.
- minimum framebuffer size added, moved out from the X server driver.
- maximum horizontal resolution dropped to 1920 to avoid a potential problem with V scaling (the RAM is apparantly 1920 pixels by 3 lines.)
- protection preventing various gem objects being used in unexpected ways added - eg, you can't create a framebuffer from a cursor gem object or an imported object which is non-contiguous.
- full range of colorkey modes for video supported (hey, it's just drm plane properties!)
- loads of smaller cleanups, and a number of checkpatch fixes.
Things left to do, in no particular order:
- Creation of planar YUV formatted framebuffers - I suspect the planar YUV formats are not supported for graphic framebuffers even though Marvell document the register settings. (Where do you program the base addresses of the U and V planes?) Not a high priority as Vmeta produces UYVY encoded frames and it's more efficient to keep the native format.
- Gamma support if anyone cares. Again, not high priority.
- Resolution of the clocking conundrum.
- Resolution of the DT specification conundrum (super-device?)
- Specification of DRM connectors (DT but how?), their configuration, what they're connected to and what fixed format(s) they support.
- CMA or no CMA - I've added a comment pointing out additional concerns about how to get the physical address from CMA. I think for most platforms this driver will be used on, the device address and physical address will be the same, but _conceptually_ they have never been the same in the kernel.
- DCON support... I have no use for this, and the information in my documentation is pretty damned poor, so much so that I'm reluctant to try prodding around with it, especially as some of it is self-contradictory. Anyone who really cares about this can look at the issues there.
Stuff omitted:
- the DRM refcounting bug fix which breaks the i915 driver (but without it, booting with this driver results in a leaked refcount on the framebuffer thanks what I consider to be a bug in the DRM crtc code.) So don't boot this without something reporting itself as being connected with a valid mode.
RFC PATCH 1/3 DRM: Armada: Add Armada DRM driver
This patch adds support for the pair of LCD controllers on the Marvell Armada 510 SoCs. This driver supports:
- multiple contiguous scanout buffers for video and graphics
- shm backed cacheable buffer objects for X pixmaps for Vivante GPU acceleration
- dual lcd0 and lcd1 crt operation
- video overlay on each LCD crt
- page flipping of the main scanout buffers
Included in this commit is the core driver with no output support; output support is platform and encoder driver dependent.
--- drivers/gpu/drm/Kconfig | 2 + drivers/gpu/drm/Makefile | 1 + drivers/gpu/drm/armada/Kconfig | 15 + drivers/gpu/drm/armada/Makefile | 7 + drivers/gpu/drm/armada/armada_510.c | 86 +++ drivers/gpu/drm/armada/armada_crtc.c | 861 +++++++++++++++++++++++++++++++ drivers/gpu/drm/armada/armada_crtc.h | 74 +++ drivers/gpu/drm/armada/armada_debugfs.c | 187 +++++++ drivers/gpu/drm/armada/armada_drm.h | 112 ++++ drivers/gpu/drm/armada/armada_drv.c | 381 ++++++++++++++ drivers/gpu/drm/armada/armada_fb.c | 155 ++++++ drivers/gpu/drm/armada/armada_fb.h | 24 + drivers/gpu/drm/armada/armada_fbdev.c | 206 ++++++++ drivers/gpu/drm/armada/armada_gem.c | 541 +++++++++++++++++++ drivers/gpu/drm/armada/armada_gem.h | 48 ++ drivers/gpu/drm/armada/armada_hw.h | 316 +++++++++++ drivers/gpu/drm/armada/armada_ioctl.h | 45 ++ drivers/gpu/drm/armada/armada_ioctlP.h | 18 + drivers/gpu/drm/armada/armada_output.c | 159 ++++++ drivers/gpu/drm/armada/armada_output.h | 39 ++ drivers/gpu/drm/armada/armada_overlay.c | 478 +++++++++++++++++ drivers/gpu/drm/armada/armada_slave.c | 139 +++++ drivers/gpu/drm/armada/armada_slave.h | 26 + drivers/gpu/drm/armada/drm_helper.h | 31 ++ 24 files changed, 3951 insertions(+), 0 deletions(-) create mode 100644 drivers/gpu/drm/armada/Kconfig create mode 100644 drivers/gpu/drm/armada/Makefile create mode 100644 drivers/gpu/drm/armada/armada_510.c create mode 100644 drivers/gpu/drm/armada/armada_crtc.c create mode 100644 drivers/gpu/drm/armada/armada_crtc.h create mode 100644 drivers/gpu/drm/armada/armada_debugfs.c create mode 100644 drivers/gpu/drm/armada/armada_drm.h create mode 100644 drivers/gpu/drm/armada/armada_drv.c create mode 100644 drivers/gpu/drm/armada/armada_fb.c create mode 100644 drivers/gpu/drm/armada/armada_fb.h create mode 100644 drivers/gpu/drm/armada/armada_fbdev.c create mode 100644 drivers/gpu/drm/armada/armada_gem.c create mode 100644 drivers/gpu/drm/armada/armada_gem.h create mode 100644 drivers/gpu/drm/armada/armada_hw.h create mode 100644 drivers/gpu/drm/armada/armada_ioctl.h create mode 100644 drivers/gpu/drm/armada/armada_ioctlP.h create mode 100644 drivers/gpu/drm/armada/armada_output.c create mode 100644 drivers/gpu/drm/armada/armada_output.h create mode 100644 drivers/gpu/drm/armada/armada_overlay.c create mode 100644 drivers/gpu/drm/armada/armada_slave.c create mode 100644 drivers/gpu/drm/armada/armada_slave.h create mode 100644 drivers/gpu/drm/armada/drm_helper.h
drivers/gpu/drm/Kconfig +2 -0
@@ -213,6 +213,8 @@ source "drivers/gpu/drm/mgag200/Kconfig" source "drivers/gpu/drm/cirrus/Kconfig" +source "drivers/gpu/drm/armada/Kconfig" + source "drivers/gpu/drm/shmobile/Kconfig" source "drivers/gpu/drm/tegra/Kconfig"
drivers/gpu/drm/Makefile +1 -0
@@ -48,6 +48,7 @@ obj-$(CONFIG_DRM_EXYNOS) +=exynos/ obj-$(CONFIG_DRM_GMA500) += gma500/ obj-$(CONFIG_DRM_UDL) += udl/ obj-$(CONFIG_DRM_AST) += ast/ +obj-$(CONFIG_DRM_ARMADA) += armada/ obj-$(CONFIG_DRM_SHMOBILE) +=shmobile/ obj-$(CONFIG_DRM_TEGRA) += tegra/ obj-$(CONFIG_DRM_OMAP) += omapdrm/
drivers/gpu/drm/armada/Kconfig new file +15 -0
@@ -0,0 +1,15 @@ +config DRM_ARMADA + tristate "DRM support for Marvell Armada SoCs" + depends on DRM && HAVE_CLK + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + select DRM_KMS_HELPER + help + Support the "LCD" controllers found on the Marvell Armada 510 + devices. There are two controllers on the device, each controller + supports graphics and video overlays. + + This driver provides no built-in acceleration; acceleration is + performed by other IP found on the SoC. This driver provides + kernel mode setting and buffer management to userspace.
drivers/gpu/drm/armada/Makefile new file +7 -0
@@ -0,0 +1,7 @@ +armada-y := armada_crtc.o armada_drv.o armada_fb.o armada_fbdev.o \ + armada_gem.o armada_output.o armada_overlay.o \ + armada_slave.o +armada-y += armada_510.o +armada-$(CONFIG_DEBUG_FS) += armada_debugfs.o + +obj-$(CONFIG_DRM_ARMADA) := armada.o
drivers/gpu/drm/armada/armada_510.c new file +86 -0
86 lines not on this page · raw message
drivers/gpu/drm/armada/armada_crtc.c new file +861 -0
861 lines not on this page · raw message
drivers/gpu/drm/armada/armada_crtc.h new file +74 -0
74 lines not on this page · raw message
drivers/gpu/drm/armada/armada_debugfs.c new file +187 -0
187 lines not on this page · raw message
drivers/gpu/drm/armada/armada_drm.h new file +112 -0
112 lines not on this page · raw message
drivers/gpu/drm/armada/armada_drv.c new file +381 -0
381 lines not on this page · raw message
drivers/gpu/drm/armada/armada_fb.c new file +155 -0
155 lines not on this page · raw message
drivers/gpu/drm/armada/armada_fb.h new file +24 -0
@@ -0,0 +1,24 @@ +/* +* Copyright (C) 2012 Russell King +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 as +* published by the Free Software Foundation. +*/ +#ifndef ARMADA_FB_H +#define ARMADA_FB_H + +struct armada_framebuffer { +struct drm_framebuffer fb; +struct armada_gem_object *obj; +uint8_t fmt; +uint8_t mod; +}; +#define drm_fb_to_armada_fb (dfb) \ + container_of(dfb, struct armada_framebuffer, fb) +#define drm_fb_obj (fb) drm_fb_to_armada_fb(fb)->obj + +struct armada_framebuffer *armada_framebuffer_create (struct drm_device *, +struct drm_mode_fb_cmd2 *,struct armada_gem_object *); + +#endif
drivers/gpu/drm/armada/armada_fbdev.c new file +206 -0
206 lines not on this page · raw message
drivers/gpu/drm/armada/armada_gem.c new file +541 -0
541 lines not on this page · raw message
drivers/gpu/drm/armada/armada_gem.h new file +48 -0
48 lines not on this page · raw message
drivers/gpu/drm/armada/armada_hw.h new file +316 -0
288 lines not on this page · raw message
drivers/gpu/drm/armada/armada_ioctl.h new file +45 -0
45 lines not on this page · raw message
drivers/gpu/drm/armada/armada_ioctlP.h new file +18 -0
Lines of this file are not shown. View the raw message.
drivers/gpu/drm/armada/armada_output.c new file +159 -0
159 lines not on this page · raw message
drivers/gpu/drm/armada/armada_output.h new file +39 -0
Lines of this file are not shown. View the raw message.
drivers/gpu/drm/armada/armada_overlay.c new file +478 -0
478 lines not on this page · raw message
drivers/gpu/drm/armada/armada_slave.c new file +139 -0
139 lines not on this page · raw message
drivers/gpu/drm/armada/armada_slave.h new file +26 -0
Lines of this file are not shown. View the raw message.
drivers/gpu/drm/armada/drm_helper.h new file +31 -0
Lines of this file are not shown. View the raw message.
The rest of this diff is not shown. View the raw message.
Signature · 1 line
1.7.4.4
Part of the diff is not shown here. View the raw message.
Re: [PATCH RFC 1/3] DRM: Armada: Add Armada DRM driver
Quoted 9 lines · Russell King
This patch adds support for the pair of LCD controllers on the Marvell Armada 510 SoCs. This driver supports:
- multiple contiguous scanout buffers for video and graphics
- shm backed cacheable buffer objects for X pixmaps for Vivante GPU acceleration
- dual lcd0 and lcd1 crt operation
- video overlay on each LCD crt
- page flipping of the main scanout buffers
Quoted 4 lines
Included in this commit is the core driver with no output support; output support is platform and encoder driver dependent.
Signed-off-by Russell King <[email protected]>
Upfront disclaimer: I have no clue about ARM/DT integration issues, so I don't have any opinion/comments on those.
I've spotted a few other things though, see below. With those addressed this patch is
Cheers, Daniel
Quoted 1 line
---
[snip]
Quoted 22 lines
drivers/gpu/drm/armada/armada_crtc.c new file +22
-0+static uint32_t armada_drm_crtc_calculate_csc (struct armada_crtc *dcrtc) +{ +struct drm_display_mode *adj = &dcrtc->crtc.mode; +uint32_t val =0 ; + +if (dcrtc->csc_yuv_mode ==CSC_YUV_CCIR709 ) + val |=CFG_CSC_YUV_CCIR709 ; +if (dcrtc->csc_rgb_mode ==CSC_RGB_STUDIO ) + val |=CFG_CSC_RGB_STUDIO ; + +/* +* In auto mode, set the colorimetry, based upon the HDMI spec. +* 1280x720p, 1920x1080p and 1920x1080i use ITU709, others use +* ITU601. It may be more appropriate to set this depending on +* the source - but what if the graphic frame is YUV and the +* video frame is RGB? +*/ +if ((adj->hdisplay ==1280 && adj->vdisplay ==720 && + !(adj->flags &DRM_MODE_FLAG_INTERLACE )) || + (adj->hdisplay ==1920 && adj->vdisplay ==1080 )) { +if (dcrtc->csc_yuv_mode ==CSC_AUTO ) + val |=CFG_CSC_YUV_CCIR709 ;
drivers/gpu/drm/armada/armada_crtc.c line 450
Quoted 10 lines
drivers/gpu/drm/armada/armada_crtc.c new file +10
-0+ } + +/* +* We assume we're connected to a TV-like device, so the YUV->RGB +* conversion should produce a limited range. We should set this +* depending on the connectors attached to this CRTC, and what +* kind of device they report being connected. +*/ +if (dcrtc->csc_rgb_mode ==CSC_AUTO ) + val |=CFG_CSC_RGB_STUDIO ;
In the intel driver we check whether it's an cea mode with drm_match_cea_mode, e.g. in intel_hdmi.c:
if (intel_hdmi->color_range_auto) {
/* See CEA-861-E - 5.1 Default Encoding Parameters */
if (intel_hdmi->has_hdmi_sink &&
drm_match_cea_mode(adjusted_mode) > 1)
intel_hdmi->color_range = HDMI_COLOR_RANGE_16_235;
else
intel_hdmi->color_range = 0;
}(The color_range gets then propageted to the right place since different platforms have different ways to do that in intel hw).
Quoted 4 lines
drivers/gpu/drm/armada/armada_crtc.c new file +4
-0+ +return val; +} +
[snip]
Quoted 41 lines
drivers/gpu/drm/armada/armada_fb.c new file +41
-0+struct armada_framebuffer *armada_framebuffer_create (struct drm_device *dev, +struct drm_mode_fb_cmd2 *mode,struct armada_gem_object *obj) +{ +struct armada_framebuffer *dfb; +uint8_t format, config; +int ret; + +switch (mode->pixel_format) { +#define FMT (drm, fmt, mod) \ + case DRM_FORMAT_##drm: \ + format = CFG_##fmt; \ + config = mod; \ + break +FMT (RGB565 ,565 ,CFG_SWAPRB ); +FMT (BGR565 ,565 ,0 ); +FMT (ARGB1555 ,1555 ,CFG_SWAPRB ); +FMT (ABGR1555 ,1555 ,0 ); + FMT(RGB888, 888PACK, CFG_SWAPRB); + FMT(BGR888, 888PACK, 0); +FMT (XRGB8888 ,X888 ,CFG_SWAPRB ); +FMT (XBGR8888 ,X888 ,0 ); +FMT (ARGB8888 ,8888 ,CFG_SWAPRB ); +FMT (ABGR8888 ,8888 ,0 ); + FMT(YUYV, 422PACK, CFG_YUV2RGB | CFG_SWAPYU | CFG_SWAPUV); + FMT(UYVY, 422PACK, CFG_YUV2RGB); + FMT(VYUY, 422PACK, CFG_YUV2RGB | CFG_SWAPUV); + FMT(YVYU, 422PACK, CFG_YUV2RGB | CFG_SWAPYU); +FMT (YUV422 ,422 ,CFG_YUV2RGB |CFG_SWAPUV ); +FMT (YVU422 ,422 ,CFG_YUV2RGB ); +FMT (YUV420 ,420 ,CFG_YUV2RGB |CFG_SWAPUV ); +FMT (YVU420 ,420 ,CFG_YUV2RGB ); +FMT (C8 ,PSEUDO8 ,0 ); +#undef FMT +default : +return ERR_PTR (-EINVAL ); + } + + dfb =kzalloc (sizeof (*dfb),GFP_KERNEL ); +if (!dfb) { +DRM_ERROR ("failed to allocate Armada fb object\n" ); +return ERR_PTR (-ENOMEM );
drivers/gpu/drm/armada/armada_fb.c line 87
Quoted 10 lines
drivers/gpu/drm/armada/armada_fb.c new file +10
-0+ } + + dfb->fmt = format; + dfb->mod = config; + + ret =drm_framebuffer_init (dev, &dfb->fb, &armada_fb_funcs); +if (ret) { +kfree (dfb); +return ERR_PTR (ret); + }
drm_framebuffer_init publishes the fb object to the world, hence initialization of all invariant state _must_ be done beforehand. This is a new requirement since the kms locking rework. So all the below should be moved above.
Quoted 12 lines
drivers/gpu/drm/armada/armada_fb.c new file +12
-0+ +drm_helper_mode_fill_fb_struct (&dfb->fb, mode); + +/* +* Take a reference on our object - the caller is expected +* to drop their reference to it. +*/ +drm_gem_object_reference (&obj->obj); + dfb->obj = obj; + +return dfb; +}
[snip]
Quoted 34 lines
drivers/gpu/drm/armada/armada_fbdev.c new file +34
-0+static int armada_fb_create (struct drm_fb_helper *fbh, +struct drm_fb_helper_surface_size *sizes) +{ +struct drm_device *dev = fbh->dev; +struct drm_mode_fb_cmd2 mode; +struct armada_framebuffer *dfb; +struct armada_gem_object *obj; +struct fb_info *info; +int size, ret; +void *ptr; + +memset (&mode,0 ,sizeof (mode)); + mode.width = sizes->surface_width; + mode.height = sizes->surface_height; + mode.pitches[0 ] =armada_pitch (mode.width, sizes->surface_bpp); + mode.pixel_format =drm_mode_legacy_fb_format (sizes->surface_bpp, + sizes->surface_depth); + + size = mode.pitches[0 ] * mode.height; + obj =armada_gem_alloc_private_object (dev, size); +if (!obj) { +DRM_ERROR ("failed to allocate fb memory\n" ); +return -ENOMEM ; + } + + ret =armada_gem_linear_back (dev, obj); +if (ret) { +drm_gem_object_unreference_unlocked (&obj->obj); +return ret; + } + + ptr =armada_gem_map_object (dev, obj); +if (!ptr) { +drm_gem_object_unreference_unlocked (&obj->obj);
drivers/gpu/drm/armada/armada_fbdev.c line 78
Quoted 10 lines
drivers/gpu/drm/armada/armada_fbdev.c new file +10
-0+return -ENOMEM ; + } + + dfb =armada_framebuffer_create (dev, &mode, obj); +if (IS_ERR (dfb)) { + ret =PTR_ERR (dfb); + goto err_fbcreate; + } + +mutex_lock (&dev->struct_mutex);
I don't understand what exactly the dev->struct_mutex protects here, I think it can be dropped.
I'm just trying to reduce proliferation of that lock as much as possible, since it's deeply interwoven with the legacy drm dragons ...
Quoted 45 lines
drivers/gpu/drm/armada/armada_fbdev.c new file +45
-0+ + info =framebuffer_alloc (0 , dev->dev); +if (!info) { + ret = -ENOMEM ; + goto err_fballoc; + } + + ret =fb_alloc_cmap (&info->cmap,256 ,0 ); +if (ret) { + ret = -ENOMEM ; + goto err_fbcmap; + } + +strlcpy (info->fix.id,"armada-drmfb" ,sizeof (info->fix.id)); + info->par = fbh; + info->flags =FBINFO_DEFAULT |FBINFO_CAN_FORCE_OUTPUT ; + info->fbops = &armada_fb_ops; + info->fix.smem_start = obj->phys_addr; + info->fix.smem_len = obj->obj.size; + info->screen_size = obj->obj.size; + info->screen_base = ptr; + fbh->fb = &dfb->fb; + fbh->fbdev = info; +drm_fb_helper_fill_fix (info, dfb->fb.pitches[0 ], dfb->fb.depth); +drm_fb_helper_fill_var (info, fbh, sizes->fb_width, sizes->fb_height); + +DRM_DEBUG_KMS ("allocated %dx%d %dbpp fb: 0x%08x\n" , + dfb->fb.width, dfb->fb.height, + dfb->fb.bits_per_pixel, obj->phys_addr); + +/* Reference is now held by the framebuffer object */ +drm_gem_object_unreference (&obj->obj); +mutex_unlock (&dev->struct_mutex); + +return 0 ; + + err_fbcmap: +framebuffer_release (info); + err_fballoc: +mutex_unlock (&dev->struct_mutex); + dfb->fb.funcs->destroy (&dfb->fb); + err_fbcreate: +drm_gem_object_unreference_unlocked (&obj->obj); +return ret; +}
[snip]
Quoted 11 lines
drivers/gpu/drm/armada/armada_gem.c new file +11
-0+static int armada_gem_vm_fault (struct vm_area_struct *vma,struct vm_fault *vmf) +{ +struct armada_gem_object *obj =drm_to_armada_gem (vma->vm_private_data); +unsigned long addr = (unsigned long )vmf->virtual_address; +unsigned long pfn = obj->phys_addr >>PAGE_SHIFT ; +int ret; + + pfn += (addr - vma->vm_start) >>PAGE_SHIFT ; + ret =vm_insert_pfn (vma, addr, pfn); + +switch (ret) {
drivers/gpu/drm/armada/armada_gem.c line 37
Quoted 10 lines
drivers/gpu/drm/armada/armada_gem.c new file +10
-0+case -EIO : +case -EAGAIN : +set_need_resched (); +case 0 : +case -ERESTARTSYS : +case -EINTR : +return VM_FAULT_NOPAGE ; +case -ENOMEM : +return VM_FAULT_OOM ; +default :
You don't handle -EBUSY from vm_insert_pfn here. This can happen when mulitple threads concurrently fault on the same address. See
commit e79e0fe380847493266fba557217e2773c61bd1b
Author: Dmitry Rogozhkin <[email protected]> Date: Wed Oct 3 17:15:26 2012 +0300
drm/i915: EBUSY status handling added to i915_gem_fault().
Quoted 3 lines
drivers/gpu/drm/armada/armada_gem.c new file +3
-0+return VM_FAULT_SIGBUS ; + } +}
[snip]
Quoted 7 lines
drivers/gpu/drm/armada/drm_helper.h new file +1
-0@@ -0,0 +1,31 @@ +/*
drivers/gpu/drm/armada/drm_helper.h line 11
Quoted 10 lines
drivers/gpu/drm/armada/drm_helper.h new file +10
-0+* Copyright (C) 2012 Russell King +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 as +* published by the Free Software Foundation. +*/ +#ifndef DRM_HELPER_H +#define DRM_HELPER_H + +/* Useful helpers I wish the DRM core would provide */
With the addition of variants for connectors/planes and rolling it out in drm_crtc.c this sounds like a nice up-front patch. I agree that this doesn't really belong in drivers ;-)
Quoted 23 lines
drivers/gpu/drm/armada/drm_helper.h new file +20
-0+ +#include <drm/drmP.h> + +static inline struct drm_crtc *drm_crtc_find (struct drm_device *dev, +uint32_t id) +{ +struct drm_mode_object *mo; + mo =drm_mode_object_find (dev, id,DRM_MODE_OBJECT_CRTC ); +return mo ?obj_to_crtc (mo) :NULL ; +} + +static inline struct drm_encoder *drm_encoder_find (struct drm_device *dev, +uint32_t id) +{ +struct drm_mode_object *mo; + mo =drm_mode_object_find (dev, id,DRM_MODE_OBJECT_ENCODER ); +return mo ?obj_to_encoder (mo) :NULL ; +} + +#endif Signature · 1 line
1.7.4.4
Signature · 3 lines
Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch
Re: [PATCH RFC 1/3] DRM: Armada: Add Armada DRM driver
Quoted 46 lines · Daniel Vetter
Quoted 22 lines · Russell King
drivers/gpu/drm/armada/armada_crtc.c new file +22
-0+static uint32_t armada_drm_crtc_calculate_csc (struct armada_crtc *dcrtc) +{ +struct drm_display_mode *adj = &dcrtc->crtc.mode; +uint32_t val =0 ; + +if (dcrtc->csc_yuv_mode ==CSC_YUV_CCIR709 ) + val |=CFG_CSC_YUV_CCIR709 ; +if (dcrtc->csc_rgb_mode ==CSC_RGB_STUDIO ) + val |=CFG_CSC_RGB_STUDIO ; + +/* +* In auto mode, set the colorimetry, based upon the HDMI spec. +* 1280x720p, 1920x1080p and 1920x1080i use ITU709, others use +* ITU601. It may be more appropriate to set this depending on +* the source - but what if the graphic frame is YUV and the +* video frame is RGB? +*/ +if ((adj->hdisplay ==1280 && adj->vdisplay ==720 && + !(adj->flags &DRM_MODE_FLAG_INTERLACE )) || + (adj->hdisplay ==1920 && adj->vdisplay ==1080 )) { +if (dcrtc->csc_yuv_mode ==CSC_AUTO ) + val |=CFG_CSC_YUV_CCIR709 ;drivers/gpu/drm/armada/armada_crtc.c line 450
Quoted 10 lines
drivers/gpu/drm/armada/armada_crtc.c new file +10
-0+ } + +/* +* We assume we're connected to a TV-like device, so the YUV->RGB +* conversion should produce a limited range. We should set this +* depending on the connectors attached to this CRTC, and what +* kind of device they report being connected. +*/ +if (dcrtc->csc_rgb_mode ==CSC_AUTO ) + val |=CFG_CSC_RGB_STUDIO ;In the intel driver we check whether it's an cea mode with
drm_match_cea_mode, e.g. inintel_hdmi.c:if (intel_hdmi->color_range_auto) { /* See CEA-861-E - 5.1 Default Encoding Parameters */ if (intel_hdmi->has_hdmi_sink && drm_match_cea_mode(adjusted_mode) > 1) intel_hdmi->color_range = HDMI_COLOR_RANGE_16_235; else intel_hdmi->color_range = 0; }
Quoted 2 lines
(The
color_rangegets then propageted to the right place since different platforms have different ways to do that in intel hw).
Unfortunately, this disagrees with the HDMI v1.3a specification:
| Default Colorimetry | | ... | | 480p, 480i, 576p, 576i, 240p and 288p | | The default colorimetry for all 480-line, 576-line, 240-line, and 288-line | video formats described in CEA-861-D is based on SMPTE 170M. | | 1080i, 1080p and 720p | | The default colorimetry for high-definition video formats (1080i, 1080p and | 720p) described in CEA-861-D is based on ITU-R BT.709-5.
As the HDMI spec refers to the CEA-861 specs, the HDMI spec overrides CEA when dealing with HDMI specifics.
So, according to the HDMI specification, the default is that it's only 1080i, 1080p and 720p which are 709, the others are 601. This does not correspond with "drm_match_cea_mode(adjusted_mode) > 1".
Unfortunately, given DRM's structure, there's no way for the CRTC layer to really know what its driving, and this setting is at the CRTC layer, not the output layer. It may be that you have the CRTC duplicated between two different display devices with different characteristics, which means you have to "choose" one - or just not bother. I've chosen the latter because it's a simpler solution, and is in no way any more correct than any other solution.
This is also why these are exported to userspace via properties, so if userspace knows better, it can deal with those issues.
Quoted 48 lines
Quoted 48 lines
drivers/gpu/drm/armada/armada_fb.c new file +48
-0+struct armada_framebuffer *armada_framebuffer_create (struct drm_device *dev, +struct drm_mode_fb_cmd2 *mode,struct armada_gem_object *obj) +{ +struct armada_framebuffer *dfb; +uint8_t format, config; +int ret; + +switch (mode->pixel_format) { +#define FMT (drm, fmt, mod) \ + case DRM_FORMAT_##drm: \ + format = CFG_##fmt; \ + config = mod; \ + break +FMT (RGB565 ,565 ,CFG_SWAPRB ); +FMT (BGR565 ,565 ,0 ); +FMT (ARGB1555 ,1555 ,CFG_SWAPRB ); +FMT (ABGR1555 ,1555 ,0 ); + FMT(RGB888, 888PACK, CFG_SWAPRB); + FMT(BGR888, 888PACK, 0); +FMT (XRGB8888 ,X888 ,CFG_SWAPRB ); +FMT (XBGR8888 ,X888 ,0 ); +FMT (ARGB8888 ,8888 ,CFG_SWAPRB ); +FMT (ABGR8888 ,8888 ,0 ); + FMT(YUYV, 422PACK, CFG_YUV2RGB | CFG_SWAPYU | CFG_SWAPUV); + FMT(UYVY, 422PACK, CFG_YUV2RGB); + FMT(VYUY, 422PACK, CFG_YUV2RGB | CFG_SWAPUV); + FMT(YVYU, 422PACK, CFG_YUV2RGB | CFG_SWAPYU); +FMT (YUV422 ,422 ,CFG_YUV2RGB |CFG_SWAPUV ); +FMT (YVU422 ,422 ,CFG_YUV2RGB ); +FMT (YUV420 ,420 ,CFG_YUV2RGB |CFG_SWAPUV ); +FMT (YVU420 ,420 ,CFG_YUV2RGB ); +FMT (C8 ,PSEUDO8 ,0 ); +#undef FMT +default : +return ERR_PTR (-EINVAL ); + } + + dfb =kzalloc (sizeof (*dfb),GFP_KERNEL ); +if (!dfb) { +DRM_ERROR ("failed to allocate Armada fb object\n" ); +return ERR_PTR (-ENOMEM ); + } + + dfb->fmt = format; + dfb->mod = config; + + ret =drm_framebuffer_init (dev, &dfb->fb, &armada_fb_funcs); +if (ret) {
Quoted 8 lines
drivers/gpu/drm/armada/armada_fb.c line 87
Quoted 3 lines
drivers/gpu/drm/armada/armada_fb.c new file +3
-0+kfree (dfb); +return ERR_PTR (ret); + }
drm_framebuffer_initpublishes the fb object to the world, hence initialization of all invariant state _must_ be done beforehand. This is a new requirement since the kms locking rework. So all the below should be moved above.
The constant rewriting of DRM is a right pain in the arse. I'm dealing with v3.9 here, and v3.9 only... However, it doesn't harm moving the below so I'll do that. When v3.10 comes along, that's the kernel I'll care about, and not v3.10-rcwhatever.
Quoted 63 lines
Quoted 12 lines
drivers/gpu/drm/armada/armada_fb.c new file +12
-0+ +drm_helper_mode_fill_fb_struct (&dfb->fb, mode); + +/* +* Take a reference on our object - the caller is expected +* to drop their reference to it. +*/ +drm_gem_object_reference (&obj->obj); + dfb->obj = obj; + +return dfb; +}[snip]
Quoted 34 lines
drivers/gpu/drm/armada/armada_fbdev.c new file +34
-0+static int armada_fb_create (struct drm_fb_helper *fbh, +struct drm_fb_helper_surface_size *sizes) +{ +struct drm_device *dev = fbh->dev; +struct drm_mode_fb_cmd2 mode; +struct armada_framebuffer *dfb; +struct armada_gem_object *obj; +struct fb_info *info; +int size, ret; +void *ptr; + +memset (&mode,0 ,sizeof (mode)); + mode.width = sizes->surface_width; + mode.height = sizes->surface_height; + mode.pitches[0 ] =armada_pitch (mode.width, sizes->surface_bpp); + mode.pixel_format =drm_mode_legacy_fb_format (sizes->surface_bpp, + sizes->surface_depth); + + size = mode.pitches[0 ] * mode.height; + obj =armada_gem_alloc_private_object (dev, size); +if (!obj) { +DRM_ERROR ("failed to allocate fb memory\n" ); +return -ENOMEM ; + } + + ret =armada_gem_linear_back (dev, obj); +if (ret) { +drm_gem_object_unreference_unlocked (&obj->obj); +return ret; + } + + ptr =armada_gem_map_object (dev, obj); +if (!ptr) { +drm_gem_object_unreference_unlocked (&obj->obj);drivers/gpu/drm/armada/armada_fbdev.c line 78
Quoted 10 lines
drivers/gpu/drm/armada/armada_fbdev.c new file +10
-0+return -ENOMEM ; + } + + dfb =armada_framebuffer_create (dev, &mode, obj); +if (IS_ERR (dfb)) { + ret =PTR_ERR (dfb); + goto err_fbcreate; + } + +mutex_lock (&dev->struct_mutex);I don't understand what exactly the
dev->struct_mutexprotects here, I think it can be dropped.
Quoted 2 lines
I'm just trying to reduce proliferation of that lock as much as possible, since it's deeply interwoven with the legacy drm dragons ...
Bear in mind much of this was written when I had very little clue as to what DRM required, so there's lots of stuff which was worked out from the i915 driver - if the i915 driver did something like that, then I initially copied that pattern.
You may wish to ask the exact same question of the i915 driver which still takes that lock over a similar section of code.
Quoted 25 lines
Quoted 11 lines
drivers/gpu/drm/armada/armada_gem.c new file +11
-0+static int armada_gem_vm_fault (struct vm_area_struct *vma,struct vm_fault *vmf) +{ +struct armada_gem_object *obj =drm_to_armada_gem (vma->vm_private_data); +unsigned long addr = (unsigned long )vmf->virtual_address; +unsigned long pfn = obj->phys_addr >>PAGE_SHIFT ; +int ret; + + pfn += (addr - vma->vm_start) >>PAGE_SHIFT ; + ret =vm_insert_pfn (vma, addr, pfn); + +switch (ret) {drivers/gpu/drm/armada/armada_gem.c line 37
Quoted 10 lines
drivers/gpu/drm/armada/armada_gem.c new file +10
-0+case -EIO : +case -EAGAIN : +set_need_resched (); +case 0 : +case -ERESTARTSYS : +case -EINTR : +return VM_FAULT_NOPAGE ; +case -ENOMEM : +return VM_FAULT_OOM ; +default :You don't handle
-EBUSYfromvm_insert_pfnhere. This can happen when mulitple threads concurrently fault on the same address. See
Quoted 5 lines
commit
e79e0fe380847493266fba557217e2773c61bd1bAuthor: Dmitry Rogozhkin <[email protected]> Date: Wed Oct 3 17:15:26 2012 +0300drm/i915: EBUSY status handling added to
i915_gem_fault().
Ok.
Quoted 20 lines
Quoted 4 lines
drivers/gpu/drm/armada/armada_gem.c new file +3
-0+return VM_FAULT_SIGBUS ; + } +}[snip]
Quoted 13 lines
drivers/gpu/drm/armada/drm_helper.h new file +7
-0@@ -0,0 +1,31 @@ +/* +* Copyright (C) 2012 Russell King +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 as +* published by the Free Software Foundation. +*/
Quoted 8 lines
drivers/gpu/drm/armada/drm_helper.h line 11
Quoted 4 lines
drivers/gpu/drm/armada/drm_helper.h new file +4
-0+#ifndef DRM_HELPER_H +#define DRM_HELPER_H + +/* Useful helpers I wish the DRM core would provide */ With the addition of variants for connectors/planes and rolling it out in
drm_crtc.cthis sounds like a nice up-front patch. I agree that this doesn't really belong in drivers ;-)
If DRM people want to take this and do that, then that's fine, but otherwise I have more than enough on my plate that moving those and then fixing up all the DRM drivers is way beyond what I'm prepared to do. (Consider that it has been more than two weeks between this posting and the previous posting...)
In any case, I disagree with the idea that they should find their way into drm_crtc.c - they're small enough to go into a header file as inline functions as I've shown in this patch. Do we really need the overhead of function calls for this, especially when these may be used in various fast paths?
However, at least I've taken the time to _think_ about what I'm doing and realise that there _is_ scope here for the DRM core to improve, rather than burying this stuff deep inside my driver like everyone else has. That's no reason to penalise patches from the "good guys" who think about what they're doing while accepting drivers from people who don't (like everyone else who's submitted a DRM driver recently without doing this.)
Re: [PATCH RFC 1/3] DRM: Armada: Add Armada DRM driver
Quoted 66 lines · Russell King - ARM Linux
Quoted 46 lines · Daniel Vetter
Quoted 22 lines · Russell King
drivers/gpu/drm/armada/armada_crtc.c new file +22
-0+static uint32_t armada_drm_crtc_calculate_csc (struct armada_crtc *dcrtc) +{ +struct drm_display_mode *adj = &dcrtc->crtc.mode; +uint32_t val =0 ; + +if (dcrtc->csc_yuv_mode ==CSC_YUV_CCIR709 ) + val |=CFG_CSC_YUV_CCIR709 ; +if (dcrtc->csc_rgb_mode ==CSC_RGB_STUDIO ) + val |=CFG_CSC_RGB_STUDIO ; + +/* +* In auto mode, set the colorimetry, based upon the HDMI spec. +* 1280x720p, 1920x1080p and 1920x1080i use ITU709, others use +* ITU601. It may be more appropriate to set this depending on +* the source - but what if the graphic frame is YUV and the +* video frame is RGB? +*/ +if ((adj->hdisplay ==1280 && adj->vdisplay ==720 && + !(adj->flags &DRM_MODE_FLAG_INTERLACE )) || + (adj->hdisplay ==1920 && adj->vdisplay ==1080 )) { +if (dcrtc->csc_yuv_mode ==CSC_AUTO ) + val |=CFG_CSC_YUV_CCIR709 ;drivers/gpu/drm/armada/armada_crtc.c line 450
Quoted 10 lines
drivers/gpu/drm/armada/armada_crtc.c new file +10
-0+ } + +/* +* We assume we're connected to a TV-like device, so the YUV->RGB +* conversion should produce a limited range. We should set this +* depending on the connectors attached to this CRTC, and what +* kind of device they report being connected. +*/ +if (dcrtc->csc_rgb_mode ==CSC_AUTO ) + val |=CFG_CSC_RGB_STUDIO ;In the intel driver we check whether it's an cea mode with
drm_match_cea_mode, e.g. inintel_hdmi.c:if (intel_hdmi->color_range_auto) { /* See CEA-861-E - 5.1 Default Encoding Parameters */ if (intel_hdmi->has_hdmi_sink && drm_match_cea_mode(adjusted_mode) > 1) intel_hdmi->color_range = HDMI_COLOR_RANGE_16_235; else intel_hdmi->color_range = 0; }Quoted 2 lines
(The
color_rangegets then propageted to the right place since different platforms have different ways to do that in intel hw).Unfortunately, this disagrees with the HDMI v1.3a specification:
| Default Colorimetry | | ... | | 480p, 480i, 576p, 576i, 240p and 288p | | The default colorimetry for all 480-line, 576-line, 240-line, and 288-line | video formats described in CEA-861-D is based on SMPTE 170M. | | 1080i, 1080p and 720p | | The default colorimetry for high-definition video formats (1080i, 1080p and | 720p) described in CEA-861-D is based on ITU-R BT.709-5.
Quoted 6 lines
As the HDMI spec refers to the CEA-861 specs, the HDMI spec overrides CEA when dealing with HDMI specifics.
So, according to the HDMI specification, the default is that it's only 1080i, 1080p and 720p which are 709, the others are 601. This does not correspond with "
drm_match_cea_mode(adjusted_mode)> 1".
Hm, sounds like we need to improve stuff a bit, maybe add a common cea helper to the drm core with a bool is_hdmi to decide whether it's palin CEA or HDMI-CEA. Ville (who's written the current code and the match cea mode helper) can you please take a look?
Quoted 10 lines
Unfortunately, given DRM's structure, there's no way for the CRTC layer to really know what its driving, and this setting is at the CRTC layer, not the output layer. It may be that you have the CRTC duplicated between two different display devices with different characteristics, which means you have to "choose" one - or just not bother. I've chosen the latter because it's a simpler solution, and is in no way any more correct than any other solution.
This is also why these are exported to userspace via properties, so if userspace knows better, it can deal with those issues.
Yeah, allowing userspace to overwrite the default selection makes lots of sense, we expose similar properties.
Quoted 57 lines
Quoted 48 lines
Quoted 48 lines
drivers/gpu/drm/armada/armada_fb.c new file +48
-0+struct armada_framebuffer *armada_framebuffer_create (struct drm_device *dev, +struct drm_mode_fb_cmd2 *mode,struct armada_gem_object *obj) +{ +struct armada_framebuffer *dfb; +uint8_t format, config; +int ret; + +switch (mode->pixel_format) { +#define FMT (drm, fmt, mod) \ + case DRM_FORMAT_##drm: \ + format = CFG_##fmt; \ + config = mod; \ + break +FMT (RGB565 ,565 ,CFG_SWAPRB ); +FMT (BGR565 ,565 ,0 ); +FMT (ARGB1555 ,1555 ,CFG_SWAPRB ); +FMT (ABGR1555 ,1555 ,0 ); + FMT(RGB888, 888PACK, CFG_SWAPRB); + FMT(BGR888, 888PACK, 0); +FMT (XRGB8888 ,X888 ,CFG_SWAPRB ); +FMT (XBGR8888 ,X888 ,0 ); +FMT (ARGB8888 ,8888 ,CFG_SWAPRB ); +FMT (ABGR8888 ,8888 ,0 ); + FMT(YUYV, 422PACK, CFG_YUV2RGB | CFG_SWAPYU | CFG_SWAPUV); + FMT(UYVY, 422PACK, CFG_YUV2RGB); + FMT(VYUY, 422PACK, CFG_YUV2RGB | CFG_SWAPUV); + FMT(YVYU, 422PACK, CFG_YUV2RGB | CFG_SWAPYU); +FMT (YUV422 ,422 ,CFG_YUV2RGB |CFG_SWAPUV ); +FMT (YVU422 ,422 ,CFG_YUV2RGB ); +FMT (YUV420 ,420 ,CFG_YUV2RGB |CFG_SWAPUV ); +FMT (YVU420 ,420 ,CFG_YUV2RGB ); +FMT (C8 ,PSEUDO8 ,0 ); +#undef FMT +default : +return ERR_PTR (-EINVAL ); + } + + dfb =kzalloc (sizeof (*dfb),GFP_KERNEL ); +if (!dfb) { +DRM_ERROR ("failed to allocate Armada fb object\n" ); +return ERR_PTR (-ENOMEM ); + } + + dfb->fmt = format; + dfb->mod = config; + + ret =drm_framebuffer_init (dev, &dfb->fb, &armada_fb_funcs); +if (ret) {Quoted 8 lines
drivers/gpu/drm/armada/armada_fb.c line 87
Quoted 3 lines
drivers/gpu/drm/armada/armada_fb.c new file +3
-0+kfree (dfb); +return ERR_PTR (ret); + }
drm_framebuffer_initpublishes the fb object to the world, hence initialization of all invariant state _must_ be done beforehand. This is a new requirement since the kms locking rework. So all the below should be moved above.
Quoted 4 lines
The constant rewriting of DRM is a right pain in the arse. I'm dealing with v3.9 here, and v3.9 only... However, it doesn't harm moving the below so I'll do that. When v3.10 comes along, that's the kernel I'll care about, and not v3.10-rcwhatever.
On the upside thus far we've used every reorg to also massively improve the docs. So hopefully just diffing the kerneldoc stuff in the future should be good enough to figure out what needs to be updated.
Quoted 63 lines
Quoted 63 lines
Quoted 12 lines
drivers/gpu/drm/armada/armada_fb.c new file +12
-0+ +drm_helper_mode_fill_fb_struct (&dfb->fb, mode); + +/* +* Take a reference on our object - the caller is expected +* to drop their reference to it. +*/ +drm_gem_object_reference (&obj->obj); + dfb->obj = obj; + +return dfb; +}[snip]
Quoted 34 lines
drivers/gpu/drm/armada/armada_fbdev.c new file +34
-0+static int armada_fb_create (struct drm_fb_helper *fbh, +struct drm_fb_helper_surface_size *sizes) +{ +struct drm_device *dev = fbh->dev; +struct drm_mode_fb_cmd2 mode; +struct armada_framebuffer *dfb; +struct armada_gem_object *obj; +struct fb_info *info; +int size, ret; +void *ptr; + +memset (&mode,0 ,sizeof (mode)); + mode.width = sizes->surface_width; + mode.height = sizes->surface_height; + mode.pitches[0 ] =armada_pitch (mode.width, sizes->surface_bpp); + mode.pixel_format =drm_mode_legacy_fb_format (sizes->surface_bpp, + sizes->surface_depth); + + size = mode.pitches[0 ] * mode.height; + obj =armada_gem_alloc_private_object (dev, size); +if (!obj) { +DRM_ERROR ("failed to allocate fb memory\n" ); +return -ENOMEM ; + } + + ret =armada_gem_linear_back (dev, obj); +if (ret) { +drm_gem_object_unreference_unlocked (&obj->obj); +return ret; + } + + ptr =armada_gem_map_object (dev, obj); +if (!ptr) { +drm_gem_object_unreference_unlocked (&obj->obj);drivers/gpu/drm/armada/armada_fbdev.c line 78
Quoted 10 lines
drivers/gpu/drm/armada/armada_fbdev.c new file +10
-0+return -ENOMEM ; + } + + dfb =armada_framebuffer_create (dev, &mode, obj); +if (IS_ERR (dfb)) { + ret =PTR_ERR (dfb); + goto err_fbcreate; + } + +mutex_lock (&dev->struct_mutex);I don't understand what exactly the
dev->struct_mutexprotects here, I think it can be dropped.
Quoted 7 lines
Quoted 2 lines
I'm just trying to reduce proliferation of that lock as much as possible, since it's deeply interwoven with the legacy drm dragons ...
Bear in mind much of this was written when I had very little clue as to what DRM required, so there's lots of stuff which was worked out from the i915 driver - if the i915 driver did something like that, then I initially copied that pattern.
Well, in i915.ko we need that locking to keep a bunch of asserts happy. But it shouldn't really be needed for us either. The reason I've asked whether you really need it is that the drm driver load sequence is laden with historical baggage and locking with dev->struct_mutex even more so. Hence I like to double-check these places for whether we really need it or whether it's just cargo-cult locking.
I'm ok if you keep this, just wanted to raise awereness of the historical dragons a bit..
Quoted 2 lines
You may wish to ask the exact same question of the i915 driver which still takes that lock over a similar section of code.
Oh, a full overhaul of the drm driver load sequence is on my todo list somewhere, including checking all the locking around it. But there's a few other things that need to be done first.
Quoted 68 lines
Quoted 25 lines
Quoted 11 lines
drivers/gpu/drm/armada/armada_gem.c new file +11
-0+static int armada_gem_vm_fault (struct vm_area_struct *vma,struct vm_fault *vmf) +{ +struct armada_gem_object *obj =drm_to_armada_gem (vma->vm_private_data); +unsigned long addr = (unsigned long )vmf->virtual_address; +unsigned long pfn = obj->phys_addr >>PAGE_SHIFT ; +int ret; + + pfn += (addr - vma->vm_start) >>PAGE_SHIFT ; + ret =vm_insert_pfn (vma, addr, pfn); + +switch (ret) {drivers/gpu/drm/armada/armada_gem.c line 37
Quoted 10 lines
drivers/gpu/drm/armada/armada_gem.c new file +10
-0+case -EIO : +case -EAGAIN : +set_need_resched (); +case 0 : +case -ERESTARTSYS : +case -EINTR : +return VM_FAULT_NOPAGE ; +case -ENOMEM : +return VM_FAULT_OOM ; +default :You don't handle
-EBUSYfromvm_insert_pfnhere. This can happen when mulitple threads concurrently fault on the same address. SeeQuoted 5 lines
commit
e79e0fe380847493266fba557217e2773c61bd1bAuthor: Dmitry Rogozhkin <[email protected]> Date: Wed Oct 3 17:15:26 2012 +0300drm/i915: EBUSY status handling added to
i915_gem_fault().Ok.
Quoted 20 lines
Quoted 4 lines
drivers/gpu/drm/armada/armada_gem.c new file +3
-0+return VM_FAULT_SIGBUS ; + } +}[snip]
Quoted 13 lines
drivers/gpu/drm/armada/drm_helper.h new file +7
-0@@ -0,0 +1,31 @@ +/* +* Copyright (C) 2012 Russell King +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 as +* published by the Free Software Foundation. +*/ Quoted 8 lines
drivers/gpu/drm/armada/drm_helper.h line 11
Quoted 4 lines
drivers/gpu/drm/armada/drm_helper.h new file +4
-0+#ifndef DRM_HELPER_H +#define DRM_HELPER_H + +/* Useful helpers I wish the DRM core would provide */ With the addition of variants for connectors/planes and rolling it out in
drm_crtc.cthis sounds like a nice up-front patch. I agree that this doesn't really belong in drivers ;-)If DRM people want to take this and do that, then that's fine, but otherwise I have more than enough on my plate that moving those and then fixing up all the DRM drivers is way beyond what I'm prepared to do. (Consider that it has been more than two weeks between this posting and the previous posting...)
Quoted 5 lines
In any case, I disagree with the idea that they should find their way into
drm_crtc.c- they're small enough to go into a header file as inline functions as I've shown in this patch. Do we really need the overhead of function calls for this, especially when these may be used in various fast paths?
Oh, my comment about drm_crtc.c was to use them in that file since there's a few places which do exactly that. Of cours the code itself should be static inline functions in a header file.
Quoted 7 lines
However, at least I've taken the time to _think_ about what I'm doing and realise that there _is_ scope here for the DRM core to improve, rather than burying this stuff deep inside my driver like everyone else has. That's no reason to penalise patches from the "good guys" who think about what they're doing while accepting drivers from people who don't (like everyone else who's submitted a DRM driver recently without doing this.)
Iirc we've had:
- omapdrm/gma500: extracted the gem helpers
- tilcdc: Rob Clark refactored the drm property code to allow plane/crtc properties
- tegra: Created the infoframe helpers (although partially outside the drm subsystem to also use it with fbdevs, but still)
- rcar/shmob: Laurent created tons of kerneldoc/DocBook patches for the modesetting stuff while writing his drm drivers. Most of what we have now is from him.
On top of that we have all the ongoing refactoring and extracting of driver logic into drm helpers by the established drivers. As drm/i915 maintainer I volunteer tons of that stuff myself for ongoing drm/i915 feature work.
So on a quick look it's only the exynos guys that bail here, and since you've participated a bit in the discussion around their dma-buf sync proposal patches that's not necessarily due to lack of effort from their side.
The drm subsystem simply accumulated technical debt for years (hardware abstraction layer shared with *BSDs and out-of-tree driver just ain't no good) and imo it's fair to distribute efforts to fix that. Especially since you've already spotted another opportunity here.
Cheers, Daniel
--
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
Re: [PATCH RFC 1/3] DRM: Armada: Add Armada DRM driver
Quoted 54 lines · Daniel Vetter
Quoted 52 lines · Russell King - ARM Linux
Quoted 46 lines · Daniel Vetter
Quoted 22 lines · Russell King
drivers/gpu/drm/armada/armada_crtc.c new file +22
-0+static uint32_t armada_drm_crtc_calculate_csc (struct armada_crtc *dcrtc) +{ +struct drm_display_mode *adj = &dcrtc->crtc.mode; +uint32_t val =0 ; + +if (dcrtc->csc_yuv_mode ==CSC_YUV_CCIR709 ) + val |=CFG_CSC_YUV_CCIR709 ; +if (dcrtc->csc_rgb_mode ==CSC_RGB_STUDIO ) + val |=CFG_CSC_RGB_STUDIO ; + +/* +* In auto mode, set the colorimetry, based upon the HDMI spec. +* 1280x720p, 1920x1080p and 1920x1080i use ITU709, others use +* ITU601. It may be more appropriate to set this depending on +* the source - but what if the graphic frame is YUV and the +* video frame is RGB? +*/ +if ((adj->hdisplay ==1280 && adj->vdisplay ==720 && + !(adj->flags &DRM_MODE_FLAG_INTERLACE )) || + (adj->hdisplay ==1920 && adj->vdisplay ==1080 )) { +if (dcrtc->csc_yuv_mode ==CSC_AUTO ) + val |=CFG_CSC_YUV_CCIR709 ;drivers/gpu/drm/armada/armada_crtc.c line 450
Quoted 10 lines
drivers/gpu/drm/armada/armada_crtc.c new file +10
-0+ } + +/* +* We assume we're connected to a TV-like device, so the YUV->RGB +* conversion should produce a limited range. We should set this +* depending on the connectors attached to this CRTC, and what +* kind of device they report being connected. +*/ +if (dcrtc->csc_rgb_mode ==CSC_AUTO ) + val |=CFG_CSC_RGB_STUDIO ;In the intel driver we check whether it's an cea mode with
drm_match_cea_mode, e.g. inintel_hdmi.c:if (intel_hdmi->color_range_auto) { /* See CEA-861-E - 5.1 Default Encoding Parameters */ if (intel_hdmi->has_hdmi_sink && drm_match_cea_mode(adjusted_mode) > 1) intel_hdmi->color_range = HDMI_COLOR_RANGE_16_235; else intel_hdmi->color_range = 0; }Quoted 2 lines
(The
color_rangegets then propageted to the right place since different platforms have different ways to do that in intel hw).Unfortunately, this disagrees with the HDMI v1.3a specification:
Quoted 13 lines
Quoted 5 lines
| Default Colorimetry | | ... | | 480p, 480i, 576p, 576i, 240p and 288pQuoted 8 lines
| | The default colorimetry for all 480-line, 576-line, 240-line, and 288-line | video formats described in CEA-861-D is based on SMPTE 170M. | | 1080i, 1080p and 720p | | The default colorimetry for high-definition video formats (1080i, 1080p and | 720p) described in CEA-861-D is based on ITU-R BT.709-5.
I think this was pretty much copy pasted from CEA-861-D which is very vague.
CEA-861-E is a bit better, and more clearly states that if the sink can receive YCbCr, then the source should use it by default for CE formats, and the default colorimetry depends on whether it's SD or HD. It also states that when transmitting IT or CE formats as RGB, the color space is the one defined in the EDID. CEA-861-D only made that statement for IT formats, and left the RGB CE format case out in the cold.
Quoted 6 lines
Quoted 6 lines
As the HDMI spec refers to the CEA-861 specs, the HDMI spec overrides CEA when dealing with HDMI specifics.
So, according to the HDMI specification, the default is that it's only 1080i, 1080p and 720p which are 709, the others are 601. This does not correspond with "
drm_match_cea_mode(adjusted_mode)> 1".
We're mixing our apples and oranges here. The logic in i915 has to do with the default RGB quantization range only.
Quoted 4 lines
Hm, sounds like we need to improve stuff a bit, maybe add a common cea helper to the drm core with a bool
is_hdmito decide whether it's palin CEA or HDMI-CEA. Ville (who's written the current code and the match cea mode helper) can you please take a look?
Currently i915 only outputs RGB, so based on CEA-861-E setting C=00 is the right thing to do. So I think the only thing we could improve is to use YCbCr for CE formats by default, but first we need to implement YCbCr output support :P
Oh and the other thing someone should do is fix the intel Xv code to use BT.709 CSC matrix for HD content. I believe that code is hardcoded for BT.601 currently, which may explain the last weirdness reported in that CEA bug or ours.
Quoted 8 lines
Quoted 8 lines
Unfortunately, given DRM's structure, there's no way for the CRTC layer to really know what its driving, and this setting is at the CRTC layer, not the output layer. It may be that you have the CRTC duplicated between two different display devices with different characteristics, which means you have to "choose" one - or just not bother. I've chosen the latter because it's a simpler solution, and is in no way any more correct than any other solution.
Quoted 5 lines
Quoted 2 lines
This is also why these are exported to userspace via properties, so if userspace knows better, it can deal with those issues.
Yeah, allowing userspace to overwrite the default selection makes lots of sense, we expose similar properties.
We really should start documenting properties in some ABI document, and actually designing them properly. Too many ad-hoc things in most of the the drivers.
Signature · 2 lines
Ville Syrj?l? Intel OTC
Re: [PATCH RFC 1/3] DRM: Armada: Add Armada DRM driver
Quoted 20 lines · Ville Syrjälä
Quoted 15 lines · Daniel Vetter
Quoted 5 lines · Russell King - ARM Linux
| Default Colorimetry | | ... | | 480p, 480i, 576p, 576i, 240p and 288pQuoted 8 lines
| | The default colorimetry for all 480-line, 576-line, 240-line, and 288-line | video formats described in CEA-861-D is based on SMPTE 170M. | | 1080i, 1080p and 720p | | The default colorimetry for high-definition video formats (1080i, 1080p and | 720p) described in CEA-861-D is based on ITU-R BT.709-5.I think this was pretty much copy pasted from CEA-861-D which is very vague.
Quoted 6 lines
CEA-861-E is a bit better, and more clearly states that if the sink can receive YCbCr, then the source should use it by default for CE formats, and the default colorimetry depends on whether it's SD or HD. It also states that when transmitting IT or CE formats as RGB, the color space is the one defined in the EDID. CEA-861-D only made that statement for IT formats, and left the RGB CE format case out in the cold.
Actually, what I'm doing there is probably wrong when you consider what is going on:
Overlay (YUV) -> YUV->RGB colorspace conversion
|
vGraphic (RGB) -----------(colorkey)--------------------> HDMI
These bits control the YUV->RGB colorspace conversion. The "is it 601 or 709 colorspace" question applies more to the colorspace of the overlay image. As far as I can tell, that is unspecified within our normal video playback programs - there's provision to communicate that information (they certainly don't seem to look for any kind of Xv attribute).
The "is it computer or studio RGB" question (I think - I can't say because the documentation is hellishly poor, and you now have as much information on this as I do) refers to the colorspace of the RGB side.
So, maybe I should move the YUV colorspace setting to be a drm_plane property? But then how do we know what format it is supposed to be? Do we just pick one and hope it's right? Do we try to autodetect it from the size of the drm_plane framebuffer? What if something downscales a HD YUV framebuffer to something smaller because the display is smaller?
What I can say is that I've watched many hours of content with my driver and at 720p output resolution, I prefer it converting the YUV between 709 to studio RGB - otherwise the blacks are too black and I find that I have to adjust the brightness/contrast to bring the black levels up compared to a standard TV broadcast.
Quoted 4 lines
Oh and the other thing someone should do is fix the intel Xv code to use BT.709 CSC matrix for HD content. I believe that code is hardcoded for BT.601 currently, which may explain the last weirdness reported in that CEA bug or ours.
How do you propose to switch between the two?
Re: [PATCH RFC 1/3] DRM: Armada: Add Armada DRM driver
Quoted 47 lines · Russell King - ARM Linux
Quoted 20 lines · Ville Syrjälä
Quoted 15 lines · Daniel Vetter
Quoted 5 lines · Russell King - ARM Linux
| Default Colorimetry | | ... | | 480p, 480i, 576p, 576i, 240p and 288pQuoted 8 lines
| | The default colorimetry for all 480-line, 576-line, 240-line, and 288-line | video formats described in CEA-861-D is based on SMPTE 170M. | | 1080i, 1080p and 720p | | The default colorimetry for high-definition video formats (1080i, 1080p and | 720p) described in CEA-861-D is based on ITU-R BT.709-5.I think this was pretty much copy pasted from CEA-861-D which is very vague.
Quoted 6 lines
CEA-861-E is a bit better, and more clearly states that if the sink can receive YCbCr, then the source should use it by default for CE formats, and the default colorimetry depends on whether it's SD or HD. It also states that when transmitting IT or CE formats as RGB, the color space is the one defined in the EDID. CEA-861-D only made that statement for IT formats, and left the RGB CE format case out in the cold.
Actually, what I'm doing there is probably wrong when you consider what is going on:
Overlay (YUV) ->
YUV->RGBcolorspace conversion| vGraphic (RGB) -----------(colorkey)--------------------> HDMI
These bits control the
YUV->RGBcolorspace conversion. The "is it 601 or 709 colorspace" question applies more to the colorspace of the overlay image. As far as I can tell, that is unspecified within our normal video playback programs - there's provision to communicate that information (they certainly don't seem to look for any kind of Xv attribute).The "is it computer or studio RGB" question (I think - I can't say because the documentation is hellishly poor, and you now have as much information on this as I do) refers to the colorspace of the RGB side.
Quoted 6 lines
So, maybe I should move the YUV colorspace setting to be a
drm_planeproperty? But then how do we know what format it is supposed to be? Do we just pick one and hope it's right? Do we try to autodetect it from the size of thedrm_planeframebuffer? What if something downscales a HD YUV framebuffer to something smaller because the display is smaller?
Yes a plane property would be the right thing to use here. I'm not sure we need any automagic default in the kernel for this stuff. I'm thinking we just default to BT.601 (or something else if the hardware is really weird and doesn't do BT.601) and let userspace override if it wants.
My plan for such a property has thus far been an enum called "csc matrix" (or something vaguely similar) and the values could just be something like "BT.601", "BT.709" etc.
Calling the property "csc matrix" has one downside though; What if the hardware CSC is fully programmable and we want to push an actual matrix from userspace. That property might also like to be called "csc matrix", so maybe we want try to come up with a better name for this first guy. Or maybe it should be "csc matrix" = "custom" + "csc matrix custom" = <actual matrix>. There's also the question of the format of the coefficients in the custom matrix. We may need some HW specifics there...
Quoted 6 lines
What I can say is that I've watched many hours of content with my driver and at 720p output resolution, I prefer it converting the YUV between 709 to studio RGB - otherwise the blacks are too black and I find that I have to adjust the brightness/contrast to bring the black levels up compared to a standard TV broadcast.
Quoted 6 lines
Quoted 4 lines
Oh and the other thing someone should do is fix the intel Xv code to use BT.709 CSC matrix for HD content. I believe that code is hardcoded for BT.601 currently, which may explain the last weirdness reported in that CEA bug or ours.
How do you propose to switch between the two?
An Xv port attribute should do. Google found me XV_COLORSPACE, which seems to be the name the radeon folks picked for it.
Signature · 2 lines
Ville Syrjälä Intel OTC
Dave Airlie
maintainerRe: [PATCH RFC 1/3] DRM: Armada: Add Armada DRM driver
In reply to Russell King - ARM LinuxQuoted 141 lines · Russell King - ARM Linux
Quoted 46 lines · Daniel Vetter
Quoted 22 lines · Russell King
drivers/gpu/drm/armada/armada_crtc.c new file +22
-0+static uint32_t armada_drm_crtc_calculate_csc (struct armada_crtc *dcrtc) +{ +struct drm_display_mode *adj = &dcrtc->crtc.mode; +uint32_t val =0 ; + +if (dcrtc->csc_yuv_mode ==CSC_YUV_CCIR709 ) + val |=CFG_CSC_YUV_CCIR709 ; +if (dcrtc->csc_rgb_mode ==CSC_RGB_STUDIO ) + val |=CFG_CSC_RGB_STUDIO ; + +/* +* In auto mode, set the colorimetry, based upon the HDMI spec. +* 1280x720p, 1920x1080p and 1920x1080i use ITU709, others use +* ITU601. It may be more appropriate to set this depending on +* the source - but what if the graphic frame is YUV and the +* video frame is RGB? +*/ +if ((adj->hdisplay ==1280 && adj->vdisplay ==720 && + !(adj->flags &DRM_MODE_FLAG_INTERLACE )) || + (adj->hdisplay ==1920 && adj->vdisplay ==1080 )) { +if (dcrtc->csc_yuv_mode ==CSC_AUTO ) + val |=CFG_CSC_YUV_CCIR709 ;drivers/gpu/drm/armada/armada_crtc.c line 450
Quoted 10 lines
drivers/gpu/drm/armada/armada_crtc.c new file +10
-0+ } + +/* +* We assume we're connected to a TV-like device, so the YUV->RGB +* conversion should produce a limited range. We should set this +* depending on the connectors attached to this CRTC, and what +* kind of device they report being connected. +*/ +if (dcrtc->csc_rgb_mode ==CSC_AUTO ) + val |=CFG_CSC_RGB_STUDIO ;In the intel driver we check whether it's an cea mode with
drm_match_cea_mode, e.g. inintel_hdmi.c:if (intel_hdmi->color_range_auto) { /* See CEA-861-E - 5.1 Default Encoding Parameters */ if (intel_hdmi->has_hdmi_sink && drm_match_cea_mode(adjusted_mode) > 1) intel_hdmi->color_range = HDMI_COLOR_RANGE_16_235; else intel_hdmi->color_range = 0; }Quoted 2 lines
(The
color_rangegets then propageted to the right place since different platforms have different ways to do that in intel hw).Unfortunately, this disagrees with the HDMI v1.3a specification:
| Default Colorimetry | | ... | | 480p, 480i, 576p, 576i, 240p and 288p | | The default colorimetry for all 480-line, 576-line, 240-line, and 288-line | video formats described in CEA-861-D is based on SMPTE 170M. | | 1080i, 1080p and 720p | | The default colorimetry for high-definition video formats (1080i, 1080p and | 720p) described in CEA-861-D is based on ITU-R BT.709-5.As the HDMI spec refers to the CEA-861 specs, the HDMI spec overrides CEA when dealing with HDMI specifics.
So, according to the HDMI specification, the default is that it's only 1080i, 1080p and 720p which are 709, the others are 601. This does not correspond with "
drm_match_cea_mode(adjusted_mode)> 1".Unfortunately, given DRM's structure, there's no way for the CRTC layer to really know what its driving, and this setting is at the CRTC layer, not the output layer. It may be that you have the CRTC duplicated between two different display devices with different characteristics, which means you have to "choose" one - or just not bother. I've chosen the latter because it's a simpler solution, and is in no way any more correct than any other solution.
This is also why these are exported to userspace via properties, so if userspace knows better, it can deal with those issues.
Quoted 48 lines
Quoted 48 lines
drivers/gpu/drm/armada/armada_fb.c new file +48
-0+struct armada_framebuffer *armada_framebuffer_create (struct drm_device *dev, +struct drm_mode_fb_cmd2 *mode,struct armada_gem_object *obj) +{ +struct armada_framebuffer *dfb; +uint8_t format, config; +int ret; + +switch (mode->pixel_format) { +#define FMT (drm, fmt, mod) \ + case DRM_FORMAT_##drm: \ + format = CFG_##fmt; \ + config = mod; \ + break +FMT (RGB565 ,565 ,CFG_SWAPRB ); +FMT (BGR565 ,565 ,0 ); +FMT (ARGB1555 ,1555 ,CFG_SWAPRB ); +FMT (ABGR1555 ,1555 ,0 ); + FMT(RGB888, 888PACK, CFG_SWAPRB); + FMT(BGR888, 888PACK, 0); +FMT (XRGB8888 ,X888 ,CFG_SWAPRB ); +FMT (XBGR8888 ,X888 ,0 ); +FMT (ARGB8888 ,8888 ,CFG_SWAPRB ); +FMT (ABGR8888 ,8888 ,0 ); + FMT(YUYV, 422PACK, CFG_YUV2RGB | CFG_SWAPYU | CFG_SWAPUV); + FMT(UYVY, 422PACK, CFG_YUV2RGB); + FMT(VYUY, 422PACK, CFG_YUV2RGB | CFG_SWAPUV); + FMT(YVYU, 422PACK, CFG_YUV2RGB | CFG_SWAPYU); +FMT (YUV422 ,422 ,CFG_YUV2RGB |CFG_SWAPUV ); +FMT (YVU422 ,422 ,CFG_YUV2RGB ); +FMT (YUV420 ,420 ,CFG_YUV2RGB |CFG_SWAPUV ); +FMT (YVU420 ,420 ,CFG_YUV2RGB ); +FMT (C8 ,PSEUDO8 ,0 ); +#undef FMT +default : +return ERR_PTR (-EINVAL ); + } + + dfb =kzalloc (sizeof (*dfb),GFP_KERNEL ); +if (!dfb) { +DRM_ERROR ("failed to allocate Armada fb object\n" ); +return ERR_PTR (-ENOMEM ); + } + + dfb->fmt = format; + dfb->mod = config; + + ret =drm_framebuffer_init (dev, &dfb->fb, &armada_fb_funcs); +if (ret) {Quoted 8 lines
drivers/gpu/drm/armada/armada_fb.c line 87
Quoted 3 lines
drivers/gpu/drm/armada/armada_fb.c new file +3
-0+kfree (dfb); +return ERR_PTR (ret); + }
drm_framebuffer_initpublishes the fb object to the world, hence initialization of all invariant state _must_ be done beforehand. This is a new requirement since the kms locking rework. So all the below should be moved above.
Quoted 5 lines
The constant rewriting of DRM is a right pain in the arse. I'm dealing with v3.9 here, and v3.9 only... However, it doesn't harm moving the below so I'll do that. When v3.10 comes along, that's the kernel I'll care about, and not v3.10-rcwhatever.
OMG I'm working in a subsystem where stuff is being developed, with only a few resources! I know my full time job isn't maintaining a 500,000 line subsystem,
and the sub maintainers and developers do a great job refactoring where required.
lots of other driver authors have made substantial changes to the drm core as they've written drivers, you spot one bit of refactoring and its a major shortcoming
of the entire subsystem and development community.
how about instead of writing:
"However, at least I've taken the time to _think_ about what I'm doing and realise that there _is_ scope here for the DRM core to improve, rather than burying this stuff deep inside my driver like everyone else has. That's no reason to penalise patches from the "good guys" who think"
you go with
"I noticed this piece of functionality could be refactored, here is a patch adding them to
the core, does anyone think its a good idea?"
As Daniel pointed out every driver submitted has refactored things, even exynos did a
lot of work to be the first ARM driver we shipped, the DRM core doesn't write itself and
I fully expect driver authors to be the ones that tell me what needs refactoring, since
they are on the pointy end, but to state that you are the only person ever to think about
things is frankly being a dick.
Lets try for less dick, and more productive in future. Dave.
Re: [PATCH RFC 1/3] DRM: Armada: Add Armada DRM driver
Quoted 32 lines · Dave Airlie
OMG I'm working in a subsystem where stuff is being developed, with only a few resources! I know my full time job isn't maintaining a 500,000 line subsystem,
and the sub maintainers and developers do a great job refactoring where required.lots of other driver authors have made substantial changes to the drm core as they've written drivers, you spot one bit of refactoring and its a major shortcoming
of the entire subsystem and development community.how about instead of writing:
"However, at least I've taken the time to _think_ about what I'm doing and realise that there _is_ scope here for the DRM core to improve, rather than burying this stuff deep inside my driver like everyone else has. That's no reason to penalise patches from the "good guys" who think"you go with
"I noticed this piece of functionality could be refactored, here is a patch adding them to
the core, does anyone think its a good idea?"As Daniel pointed out every driver submitted has refactored things, even exynos did a
lot of work to be the first ARM driver we shipped, the DRM core doesn't write itself and
I fully expect driver authors to be the ones that tell me what needs refactoring, since
they are on the pointy end, but to state that you are the only person ever to think about
things is frankly being a dick.
Quoted 1 line
Lets try for less dick, and more productive in future.
And you can stick your dick back where you got it from David. Really, your response is totally uncalled for.
Let's try realising that I only have very limited time to put into this and unlike the other submitters who have been _paid_ to get their code sorted, this is being done purely for free - which means it's really low priority. As you should already realise because I've stated already that I *really* don't care whether it gets into mainline or not.
I am *NOT* planning on spending any time on this during the next week as I have *paid* work to do, and probably not next weekend nor the following week either. So the next time that I'm likely to do anything on this is in a fortnight or longer.
If you want stuff to be refactored in DRM, you need to find someone with more time to do it.
And before you continue making a mountain out of a molehill, as you seem to like doing, the "let's make it a core thing" is REALLY BLOODY SIMPLE. All it takes is for the header file to go into include/drm. It's now available to anyone who wants to use that - and all that's left is to sort out all those drivers *WHICH I CANT TEST* to use that stuff.
And, frankly, when I was going to post this latest RFC, I gave serious consideration to quite simply not posting it to dri-devel and copying you or any other person listed as a maintainer for DRM, and only posting it to the people interested in it on the ARM side, because I'd already given up hope of it ever being merged into mainline.
Your totally over the top and rediculous response just confirms that.
Further postings will now omit you and dri-devel.
Dave Airlie
maintainerRe: [PATCH RFC 1/3] DRM: Armada: Add Armada DRM driver
Quoted 35 lines · Russell King - ARM Linux
Quoted 32 lines · Dave Airlie
OMG I'm working in a subsystem where stuff is being developed, with only a few resources! I know my full time job isn't maintaining a 500,000 line subsystem,
and the sub maintainers and developers do a great job refactoring where required.lots of other driver authors have made substantial changes to the drm core as they've written drivers, you spot one bit of refactoring and its a major shortcoming
of the entire subsystem and development community.how about instead of writing:
"However, at least I've taken the time to _think_ about what I'm doing and realise that there _is_ scope here for the DRM core to improve, rather than burying this stuff deep inside my driver like everyone else has. That's no reason to penalise patches from the "good guys" who think"you go with
"I noticed this piece of functionality could be refactored, here is a patch adding them to
the core, does anyone think its a good idea?"As Daniel pointed out every driver submitted has refactored things, even exynos did a
lot of work to be the first ARM driver we shipped, the DRM core doesn't write itself and
I fully expect driver authors to be the ones that tell me what needs refactoring, since
they are on the pointy end, but to state that you are the only person ever to think about
things is frankly being a dick.Quoted 1 line
Lets try for less dick, and more productive in future.
Quoted 8 lines
And you can stick your dick back where you got it from David. Really, your response is totally uncalled for.
Let's try realising that I only have very limited time to put into this and unlike the other submitters who have been _paid_ to get their code sorted, this is being done purely for free - which means it's really low priority. As you should already realise because I've stated already that I *really* don't care whether it gets into mainline or not.
Really not every driver maintainer is paid to submit their drivers, if you'd any clue
you'd understand that you aren't special. We currently have a number of non-paid maintainer drivers being submitted and worked on, via for one, gma500 is maintain
in spare time, the tegra driver isn't purely a work of paid dedication, I maintain
5 drivers currently, and I certainly don't do all of that in my day job. Keeping attitude off
this list is what I do, I don't care if you don't appreciate the work put in by other developers
to the drm subsystem, but I do and I won't have someone come in here saying "you guys
suck" when clearly they've no historical perspective and as such are plainly trolling.
Yes the DRM has growing pains, yes there is a lots of legacy shit in the way of making
things clean, yes writing a driver for SoC is more painful than necessary, but overall
its a majorly moving target, 5 years ago DRM/KMS hadn't considered ARM, now its probably most of what we have to consider.
Quoted 2 lines
If you want stuff to be refactored in DRM, you need to find someone with more time to do it.
I pointed out I didn't want stuff refactored, I wanted a driver author to suggest
possible refactorings with a patch to add the interfaces, and suggest its a good idea.
Split the patch, one to add the additions to the core without changing anything, then just
have your driver use them. If other driver writes want to use them they'll figure it out, and maybe someone else will go around and clean up the other drivers.
I'm really hoping the OLPC guys pick up this work and care enough to merge it, if not,
its a bit of a waste.
Dave.
Re: [PATCH RFC 1/3] DRM: Armada: Add Armada DRM driver
In reply to Dave AirlieQuoted 10 lines · Dave Airlie
how about instead of writing:
"However, at least I've taken the timeto_think_about what I'm doing and realise thatthere_is_scope here for the DRM core to improve, rather than burying this stuff deep inside my driver like everyone else has. That's no reason to penalise patches from the "good guys" who think"you go with
"I noticed this piece of functionality could be refactored, here is a patch adding them to
the core, does anyone think its a good idea?"
Dave,
at least on this point I do share Russell's impression. I've sent bunch of patches improving TDA998x and DRM+DT:
- TDA998x irq handling - ignored
- TDA998x sync fix - ignored
- Fix drm I2C slave encoder probing
I am aware that this is not an easy job nor one you get much appreciation for. But, back when TDA998x driver was published, all my comments were basically answered with "Oh, I know. Maybe someday somebody will fix it".
I am not being paid for any of this, but have a strong intrinsic motivation here. But I am loosing interest in sending fixes for DRM stuff because my (personal) impression is the same Russell
has: Depending on who sends patches, they get merged independent of how broken they are - others are discussed to death.
Sebastian
Re: [PATCH RFC 1/3] DRM: Armada: Add Armada DRM driver
Quoted 20 lines · Sebastian Hesselbarth
Quoted 10 lines · Dave Airlie
how about instead of writing:
"However, at least I've taken the timeto_think_about what I'm doing and realise thatthere_is_scope here for the DRM core to improve, rather than burying this stuff deep inside my driver like everyone else has. That's no reason to penalise patches from the "good guys" who think"you go with
"I noticed this piece of functionality could be refactored, here is a patch adding them to
the core, does anyone think its a good idea?"Dave,
at least on this point I do share Russell's impression. I've sent bunch of patches improving TDA998x and DRM+DT:
- TDA998x irq handling - ignored
- TDA998x sync fix - ignored
- Fix drm I2C slave encoder probing
Quoted 4 lines
I am aware that this is not an easy job nor one you get much appreciation for. But, back when TDA998x driver was published, all my comments were basically answered with "Oh, I know. Maybe someday somebody will fix it".
I guess part of the problem here is that in the arm world we don't (yet) have many full-blown drivers and not many people to fix up stuff or chime in with good review. And sometimes that just means that someone puts down his foot and says "this is how we do it" - at least for drm/i915 I sometimes have to do that to unblock a massive bikeshed-fest.
Quoted 5 lines
I am not being paid for any of this, but have a strong intrinsic motivation here. But I am loosing interest in sending fixes for DRM stuff because my (personal) impression is the same Russell
has: Depending on who sends patches, they get merged independent of how broken they are - others are discussed to death.
Hm, we run fairly extensive QA for drm/i915, and thus far the drm core stuff hasn't really blown up badly for us. So can you please point at examples where crap was merged and shouldn't have been?
Wrt to bikeshed to death I know that drm folks are a bit prone to that (me included), but recently I haven't spotted a case where this happened. ARM stuff excluded ofc since I don't follow that too closely. There's also that Dave is sometimes a bit swamped, but pinging him on irc about lost patches works well (at least for stuff I care about).
Cheers, Daniel
Signature · 3 lines
Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch
Re: [PATCH RFC 1/3] DRM: Armada: Add Armada DRM driver
Quoted 24 lines · Daniel Vetter
Quoted 10 lines · Sebastian Hesselbarth
at least on this point I do share Russell's impression. I've sent bunch of patches improving TDA998x and DRM+DT:
- TDA998x irq handling - ignored
- TDA998x sync fix - ignored
- Fix drm I2C slave encoder probingI am aware that this is not an easy job nor one you get much appreciation for. But, back when TDA998x driver was published, all my comments were basically answered with "Oh, I know. Maybe someday somebody will fix it".
I guess part of the problem here is that in the arm world we don't (yet) have many full-blown drivers and not many people to fix up stuff or chime in with good review. And sometimes that just means that someone puts down his foot and says "this is how we do it" - at least for drm/i915 I sometimes have to do that to unblock a massive bikeshed-fest.
Quoted 5 lines
I am not being paid for any of this, but have a strong intrinsic motivation here. But I am loosing interest in sending fixes for DRM stuff because my (personal) impression is the same Russell
has: Depending on who sends patches, they get merged independent of how broken they are - others are discussed to death.
Quoted 3 lines
Hm, we run fairly extensive QA for drm/i915, and thus far the drm core stuff hasn't really blown up badly for us. So can you please point at examples where crap was merged and shouldn't have been?
Don't get me wrong, "broken" above didn't mean it doesn't work at all, but with SoC graphic drivers arising, requirements shift from "some known implementations" to "you never know what will be combined with e.g. a specific CRTC". So from that latter point-of-view, I consider TDA998x for example as broken. It may work with tilcdc in some modes, but as Darren Etheridge stated, it breaks as soon as you touch TDA998x driver. At least for that, I confirmed the timings of Russell's driver and the fixes posted with a scope and a bunch of modes and monitors/tv.
For the timing fix of TDA998x, Darren now is trying to also confirm every single sync line of tilcdc and I really like to see his Tested-by on the patch - just because Russell's driver and the CuBox are the only testbeds I have on this.
Quoted 5 lines
Wrt to bikeshed to death I know that drm folks are a bit prone to that (me included), but recently I haven't spotted a case where this happened. ARM stuff excluded ofc since I don't follow that too closely. There's also that Dave is sometimes a bit swamped, but pinging him on irc about lost patches works well (at least for stuff I care about).
Hmm, I understand that it is _very_ time consuming work on your side. But for me - with limited insight of DRM core - it is not a good starter to make the API DT aware. The DRM API documentation _is_ limited wrt intentions of the way it is done.
Of course, I share the idea of true, full-blown of_drm_something helpers. But the DT patch, is not an improvement but a real fix as in "make DRM not break on some platforms". From that on, I can start digging into DRM API and improve DT support here and there.
So for the three patches I mentioned above, they are all minor improvements of the API. Minor, because I cannot ever sent _the_ single perfect patch just because I don't know the API well enough, yet.
Just based on my personal experience: TDA998x driver got merged the way it is _although_ I addressed some concerns - the fixes are not merged _although_ I provided experimental results. This is of course
disappointing for me, but I am sure it will work out soon and I will
get back to happily send improvements for the platforms I can test on.
Sebastian
Dave Airlie
maintainerRe: [PATCH RFC 1/3] DRM: Armada: Add Armada DRM driver
Quoted 9 lines
Of course, I share the idea of true, full-blown
of_drm_somethinghelpers. But the DT patch, is not an improvement but a real fix as in "make DRM not break on some platforms". From that on, I can start digging into DRM API and improve DT support here and there.So for the three patches I mentioned above, they are all minor improvements of the API. Minor, because I cannot ever sent _the_ single perfect patch just because I don't know the API well enough, yet.
Quoted 5 lines
Just based on my personal experience: TDA998x driver got merged the way it is _although_ I addressed some concerns - the fixes are not merged _although_ I provided experimental results. This is of course disappointing for me, but I am sure it will work out soon and I will get back to happily send improvements for the platforms I can test on.
To be honest I've no idea what those tda998x patches could fix or break, so they go on my no ideas list and I hope if they get reposted someone will tell me what they do.
I could probably be more motivated towards poking other people to review stuff, but I mostly hope in vain that the ARM people will cross review things for other ARM chips, I had a bit of that happening for a while at the start, but it seems to have died off. Now I'm mostly relying on Rob to have some clue what I'm merging is sane.
My current priority for merging stuff is:
core patches that affect all platforms,
core patches that affect x86
drivers that I maintain by default
core patches that affect ARM
misc ARM drivers that fall through cracks.
Maybe I can persuade Rob to become a sub maintainer for all of the SoC drivers but I suspect he'd try and hurt me in real life.
I'll take another look at the tda patches but I may still have no idea what they are doing.
Dave.
Re: [PATCH RFC 1/3] DRM: Armada: Add Armada DRM driver
Quoted 15 lines · Dave Airlie
Quoted 9 lines
Of course, I share the idea of true, full-blown
of_drm_somethinghelpers. But the DT patch, is not an improvement but a real fix as in "make DRM not break on some platforms". From that on, I can start digging into DRM API and improve DT support here and there.So for the three patches I mentioned above, they are all minor improvements of the API. Minor, because I cannot ever sent _the_ single perfect patch just because I don't know the API well enough, yet.
Quoted 5 lines
Just based on my personal experience: TDA998x driver got merged the way it is _although_ I addressed some concerns - the fixes are not merged _although_ I provided experimental results. This is of course disappointing for me, but I am sure it will work out soon and I will get back to happily send improvements for the platforms I can test on.
Quoted 3 lines
To be honest I've no idea what those tda998x patches could fix or break, so they go on my no ideas list and I hope if they get reposted someone will tell me what they do.
IIRC, a few of those patches were breaking things on tilcdc, which someone needs to get to the bottom of.. and for that I'm relying a bit on Darren as he is the one with both hw to test with tilcdc plus an hdmi tester. And I think understands the issue better than I do at this point.
Quoted 13 lines
I could probably be more motivated towards poking other people to review stuff, but I mostly hope in vain that the ARM people will cross review things for other ARM chips, I had a bit of that happening for a while at the start, but it seems to have died off. Now I'm mostly relying on Rob to have some clue what I'm merging is sane.
My current priority for merging stuff is:
core patches that affect all platforms,
core patches that affect x86
drivers that I maintain by default
core patches that affect ARM
misc ARM drivers that fall through cracks.
Quoted 2 lines
Maybe I can persuade Rob to become a sub maintainer for all of the SoC drivers but I suspect he'd try and hurt me in real life.
/me runs :-P
well, anyways, I do at least try to review arm patches. Things sometimes do fall on the floor when I'm busy in other areas.
BR,
-R
Quoted 8 lines
I'll take another look at the tda patches but I may still have no idea what they are doing.
Dave.
_______________________________________________
dri-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH RFC 1/3] DRM: Armada: Add Armada DRM driver
In reply to Sebastian HesselbarthQuoted 15 lines · Sebastian Hesselbarth
Quoted 5 lines · Dave Airlie
how about instead of writing:
"However, at least I've taken the timeto_think_about what I'm doing and realise thatthere_is_scope here for the DRM core to improve,Quoted 7 lines
rather than burying this stuff deep inside my driver like everyone else has. That's no reason to penalise patches from the "good guys" who think"
you go with
"I noticed this piece of functionality could be refactored, here is a patch adding them to
the core, does anyone think its a good idea?"
Quoted 6 lines
Dave,
at least on this point I do share Russell's impression. I've sent bunch of patches improving TDA998x and DRM+DT:
- TDA998x irq handling - ignored
- TDA998x sync fix - ignored
At least the sync fix, looks like I missed it (it probably is a good idea to CC me if you want me to look at it). Looks like there was some follow-up discussion on both patches, unless I missed seeing a newer version of those patches.
Sometimes if you think a patch has been ignored/forgotten, it doesn't hurt to ping on mailing list or #dri-devel.. a lot of us are working not just on kernel (the relatively small part in the whole linux graphics stack), but also mesa and/or x11. Some times things end up several pages down in the mail folder. It's not because we are all sitting on a beach drinking margaritas, or because we don't like you. It is just because we are busy and missed it.
Last few months I've been pretty buried in r/e + gallium driver for new gpu, so I wasn't always checking dri-devel list every day. At least now I am in drm-driver mode again ;-)
Quoted 6 lines
- Fix drm I2C slave encoder probing
I am aware that this is not an easy job nor one you get much appreciation for. But, back when TDA998x driver was published, all my comments were basically answered with "Oh, I know. Maybe someday somebody will fix it".
If you have a better idea about how to make the slave encoder probing better (and/or more generic to support stuff other than i2c), please send RFC patch. (And if you already did this, please send updated version, see previous point about sometimes missing patches.)
BR,
-R
Quoted 13 lines
I am not being paid for any of this, but have a strong intrinsic motivation here. But I am loosing interest in sending fixes for DRM stuff because my (personal) impression is the same Russell
has: Depending on who sends patches, they get merged independent of how broken they are - others are discussed to death.Sebastian
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Re: [PATCH RFC 1/3] DRM: Armada: Add Armada DRM driver
Quoted 9 lines · Rob Clark
Quoted 2 lines · Sebastian Hesselbarth
- TDA998x irq handling - ignored
- TDA998x sync fix - ignoredAt least the sync fix, looks like I missed it (it probably is a good idea to CC me if you want me to look at it). Looks like there was some follow-up discussion on both patches, unless I missed seeing a newer version of those patches.
Yeah, I will update the patch for current mainline linux as it was based on some of Russell's RFC patches.
Quoted 11 lines
Sometimes if you think a patch has been ignored/forgotten, it doesn't hurt to ping on mailing list or #dri-devel.. a lot of us are working not just on kernel (the relatively small part in the whole linux graphics stack), but also mesa and/or x11. Some times things end up several pages down in the mail folder. It's not because we are all sitting on a beach drinking margaritas, or because we don't like you. It is just because we are busy and missed it.
Last few months I've been pretty buried in r/e + gallium driver for new gpu, so I wasn't always checking dri-devel list every day. At least now I am in drm-driver mode again ;-)
It is ok, I don't blame anyone here. Darren wants to test it on tilcdc. I also found a datasheet for TDA9983b which is kind of compatible but has more information about register layout in it. IIRC digikey also has it.
Quoted 6 lines
Quoted 2 lines
- Fix drm I2C slave encoder probing
If you have a better idea about how to make the slave encoder probing better (and/or more generic to support stuff other than i2c), please send RFC patch. (And if you already did this, please send updated version, see previous point about sometimes missing patches.)
Also, will send an updated fix.
Sebastian
Re: [PATCH RFC 1/3] DRM: Armada: Add Armada DRM driver
In reply to Russell KingQuoted 9 lines · Russell King
This patch adds support for the pair of LCD controllers on the Marvell Armada 510 SoCs. This driver supports:
- multiple contiguous scanout buffers for video and graphics
- shm backed cacheable buffer objects for X pixmaps for Vivante GPU acceleration
- dual lcd0 and lcd1 crt operation
- video overlay on each LCD crt
- page flipping of the main scanout buffers
Quoted 4 lines
Included in this commit is the core driver with no output support; output support is platform and encoder driver dependent.
Signed-off-by Russell King <[email protected]>
Found one more ...
[snip]
Quoted 54 lines
drivers/gpu/drm/armada/armada_gem.c new file +54
-0+int +armada_gem_linear_back (struct drm_device *dev,struct armada_gem_object *obj) +{ +struct armada_private *priv = dev->dev_private; +size_t size = obj->obj.size; + +if (obj->page || obj->linear) +return 0 ; + +/* +* If it is a small allocation (typically cursor, which will +* be 32x64 or 64x32 ARGB pixels) try to get it from the system. +* Framebuffers will never be this small (our minimum size for +* framebuffers is larger than this anyway.) Such objects are +* only accessed by the CPU so we don't need any special handing +* here. +*/ +if (size <=8192 ) { +unsigned int order =get_order (size); +struct page *p =alloc_pages (GFP_KERNEL , order); + +if (p) { + obj->addr =page_address (p); + obj->phys_addr =page_to_phys (p); + obj->page = p; + +memset (obj->addr,0 ,PAGE_ALIGN (size)); + } + } + +/* +* We could grab something from CMA if it's enabled, but that +* involves building in a problem: +* +* CMA's interface uses dma_alloc_coherent(), which provides us +* with an CPU virtual address and a device address. +* +* The CPU virtual address may be either an address in the kernel +* direct mapped region (for example, as it would be on x86) or +* it may be remapped into another part of kernel memory space +* (eg, as it would be on ARM.) This means virt_to_phys() on the +* returned virtual address is invalid depending on the architecture +* implementation. +* +* The device address may also not be a physical address; it may +* be that there is some kind of remapping between the device and +* system RAM, which makes the use of the device address also +* unsafe to re-use as a physical address. +* +* This makes DRM usage of dma_alloc_coherent() in a generic way +* at best very questionable and unsafe. +*/ + +/* Otherwise, grab it from our linear allocation */
drivers/gpu/drm/armada/armada_gem.c line 142
Quoted 10 lines
drivers/gpu/drm/armada/armada_gem.c new file +10
-0+if (!obj->page) { +struct drm_mm_node *free; +unsigned align =min_t (unsigned, size,SZ_2M ); +void __iomem *ptr; + +mutex_lock (&dev->struct_mutex); + free =drm_mm_search_free (&priv->linear, size, align,0 ); +if (free) + obj->linear =drm_mm_get_block (free, size, align); +mutex_unlock (&dev->struct_mutex);
The two-stage search_free+get_block drm_mm interface is something I'd like to remove since it' complicates the interface for no gain. And the preallocation trick for atomic contexts is pretty racy as-is. Can you please convert this over to the insert_node interfaces which take a preallocate drm_mm_node?
Thanks, Daniel
Signature · 3 lines
Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch
Re: [PATCH RFC 1/3] DRM: Armada: Add Armada DRM driver
Quoted 12 lines · Daniel Vetter
drivers/gpu/drm/armada/armada_gem.c line 142
Quoted 5 lines · Russell King
drivers/gpu/drm/armada/armada_gem.c new file +5
-0+mutex_lock (&dev->struct_mutex); + free =drm_mm_search_free (&priv->linear, size, align,0 ); +if (free) + obj->linear =drm_mm_get_block (free, size, align); +mutex_unlock (&dev->struct_mutex);The two-stage search_free+get_block
drm_mminterface is something I'd like to remove since it' complicates the interface for no gain. And the preallocation trick for atomic contexts is pretty racy as-is. Can you please convert this over to theinsert_nodeinterfaces which take a preallocatedrm_mm_node?
Yes and no. This is only racy if it is callable from atomic contexts, which the above isn't, because it takes a mutex, and the above is the only place which allocations against that pool are done. Mutexes can't be taken in atomic contexts. Plus it's using the non-atomic drm_mm_* interfaces.
However, the insert_node interfaces appear not to solve any kind of race. All they do is allow the kmalloc to be moved out of this region into the user of this code sequence, while offering no additional locking or safety. So the mutex lock around a call to drm_mm_insert_node*() is still required.
As the kmalloc() happens beneath the mutex lock, another thread can't race with an allocation in the above code anyway. The *only* reason I'll change this is that it is nicer to the system not to hold locks while allocating memory.
Re: [PATCH RFC 1/3] DRM: Armada: Add Armada DRM driver
Quoted 26 lines · Russell King - ARM Linux
Quoted 12 lines · Daniel Vetter
drivers/gpu/drm/armada/armada_gem.c line 142
Quoted 5 lines · Russell King
drivers/gpu/drm/armada/armada_gem.c new file +5
-0+mutex_lock (&dev->struct_mutex); + free =drm_mm_search_free (&priv->linear, size, align,0 ); +if (free) + obj->linear =drm_mm_get_block (free, size, align); +mutex_unlock (&dev->struct_mutex);The two-stage search_free+get_block
drm_mminterface is something I'd like to remove since it' complicates the interface for no gain. And the preallocation trick for atomic contexts is pretty racy as-is. Can you please convert this over to theinsert_nodeinterfaces which take a preallocatedrm_mm_node?Yes and no. This is only racy if it is callable from atomic contexts, which the above isn't, because it takes a mutex, and the above is the only place which allocations against that pool are done. Mutexes can't be taken in atomic contexts. Plus it's using the non-atomic drm_mm_* interfaces.
However, the
insert_nodeinterfaces appear not to solve any kind of race. All they do is allow the kmalloc to be moved out of this region into the user of this code sequence, while offering no additional locking or safety. So the mutex lock around a call to drm_mm_insert_node*() is still required.
Quoted 4 lines
As the
kmalloc()happens beneath the mutex lock, another thread can't race with an allocation in the above code anyway. The *only* reason I'll change this is that it is nicer to the system not to hold locks while allocating memory.
Err. There's bugs here in the other drivers such as i915 which follow your suggestion. The problem is this:
Every time they allocate using drm_mm_insert_node(), they kmalloc a new struct drm_mm_node for this function to fill in and attach.
When they've done with the allocation, they call drm_mm_put_block(). This places the node onto the mm's unused_nodes list provided we don't already have MM_UNUSED_TARGET nodes on that list.
So, we end up filling up the unused nodes list to MM_UNUSED_TARGET, at which point we then start freeing any further nodes - and with no way to pull these off that list, they all just sit there not being used.
The only function which takes nodes off that list is drm_mm_kmalloc(), which is declared statically, and so isn't available to drivers.
Are drivers which use the drm_mm_insert_node() function expected to also use drm_mm_remove_node(), kfreeing the node after that call, rather than using drm_mm_put_block() ?
Either way, I think someone needs to fix the other drivers and Cc those patches to Stable...
Re: [PATCH RFC 1/3] DRM: Armada: Add Armada DRM driver
Right, so, incrementally, the changes are (this may not entirely apply to the version I've posted because I have several patches on top of that.)
I've also added locking to the calls to drm_mm_dump_table() as otherwise these walk those lists without holding any locks what so ever, which could mean that a block is removed while we're walking the list.
drivers/gpu/drm/armada/armada_debugfs.c | 17 ++++++++++-- drivers/gpu/drm/armada/armada_fb.c | 43 ++++++++++++++++++------------- drivers/gpu/drm/armada/armada_fbdev.c | 20 ++++++-------- drivers/gpu/drm/armada/armada_gem.c | 29 +++++++++++++++------ 4 files changed, 68 insertions(+), 41 deletions(-)
drivers/gpu/drm/armada/armada_debugfs.c +14 -3
@@ -23,16 +23,27 @@ static int armada_debugfs_gem_offs_show(struct seq_file *m, void *data)struct drm_info_node *node = m->private;struct drm_device *dev = node->minor->dev;struct drm_gem_mm *mm = dev->mm_private; +int ret; + +mutex_lock (&dev->struct_mutex); + ret =drm_mm_dump_table (m, &mm->offset_manager); +mutex_unlock (&dev->struct_mutex); -return drm_mm_dump_table (m, &mm->offset_manager); +return ret; }static int armada_debugfs_gem_linear_show (struct seq_file *m,void *data) {struct drm_info_node *node = m->private; -struct armada_private *priv = node->minor->dev->dev_private; +struct drm_device *dev = node->minor->dev; +struct armada_private *priv = dev->dev_private; +int ret; -return drm_mm_dump_table (m, &priv->linear); +mutex_lock (&dev->struct_mutex); + ret =drm_mm_dump_table (m, &priv->linear); +mutex_unlock (&dev->struct_mutex); + +return ret; }static int armada_debugfs_reg_show (struct seq_file *m,void *data)
drivers/gpu/drm/armada/armada_fb.c +25 -18
84 lines not on this page · raw message
drivers/gpu/drm/armada/armada_fbdev.c +8 -12
@@ -70,12 +70,15 @@ static int armada_fb_create(struct drm_fb_helper *fbh, } dfb =armada_framebuffer_create (dev, &mode, obj); -if (IS_ERR (dfb)) { - ret =PTR_ERR (dfb); - goto err_fbcreate; - } -mutex_lock (&dev->struct_mutex); +/* +* A reference is now held by the framebuffer object if +* successful, otherwise this drops the ref for the error path. +*/ +drm_gem_object_unreference_unlocked (&obj->obj); + +if (IS_ERR (dfb)) +return PTR_ERR (dfb); info =framebuffer_alloc (0 , dev->dev);if (!info) {
@@ -106,19 +109,12 @@ static int armada_fb_create(struct drm_fb_helper *fbh, dfb->fb.width, dfb->fb.height, dfb->fb.bits_per_pixel, obj->phys_addr); -/* Reference is now held by the framebuffer object */ -drm_gem_object_unreference (&obj->obj); -mutex_unlock (&dev->struct_mutex); -return 0 ; err_fbcmap:framebuffer_release (info); err_fballoc: -mutex_unlock (&dev->struct_mutex); dfb->fb.funcs->destroy (&dfb->fb); - err_fbcreate: -drm_gem_object_unreference_unlocked (&obj->obj);return ret; }
drivers/gpu/drm/armada/armada_gem.c +21 -8
@@ -31,6 +31,7 @@ static int armada_gem_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)case 0 :case -ERESTARTSYS :case -EINTR : +case -EBUSY :return VM_FAULT_NOPAGE ;case -ENOMEM :return VM_FAULT_OOM ;
@@ -50,6 +51,7 @@ static size_t roundup_gem_size(size_t size)return roundup (size,PAGE_SIZE ); } +/* dev->struct_mutex is held here */ void armada_gem_free_object (struct drm_gem_object *obj) {struct armada_gem_object *dobj =drm_to_armada_gem (obj);
@@ -65,7 +67,8 @@ void armada_gem_free_object(struct drm_gem_object *obj)__free_pages (dobj->page, order); }else if (dobj->linear) {/* linear backed memory */ -drm_mm_put_block (dobj->linear); +drm_mm_remove_node (dobj->linear); +kfree (dobj->linear);if (dobj->addr)iounmap (dobj->addr); }
@@ -137,22 +140,32 @@ armada_gem_linear_back(struct drm_device *dev, struct armada_gem_object *obj)/* Otherwise, grab it from our linear allocation */ if (!obj->page) { -struct drm_mm_node *free; +struct drm_mm_node *node;unsigned align =min_t (unsigned, size,SZ_2M );void __iomem *ptr; +int ret; + + node =kzalloc (sizeof (*node),GFP_KERNEL ); +if (!node) +return -ENOSPC ;mutex_lock (&dev->struct_mutex); - free =drm_mm_search_free (&priv->linear, size, align,0 ); -if (free) - obj->linear =drm_mm_get_block (free, size, align); + ret =drm_mm_insert_node (&priv->linear, node, size, align);mutex_unlock (&dev->struct_mutex); -if (!obj->linear) -return -ENOSPC ; +if (ret) { +kfree (node); +return ret; + } + + obj->linear = node;/* Ensure that the memory we're returning is cleared. */ ptr =ioremap_wc (obj->linear->start, size);if (!ptr) { -drm_mm_put_block (obj->linear); +mutex_lock (&dev->struct_mutex); +drm_mm_remove_node (obj->linear); +mutex_unlock (&dev->struct_mutex); +kfree (obj->linear); obj->linear =NULL ;return -ENOMEM ; }
Re: [PATCH RFC 1/3] DRM: Armada: Add Armada DRM driver
In reply to Russell King - ARM LinuxQuoted 35 lines · Russell King - ARM Linux
Quoted 26 lines · Russell King - ARM Linux
Quoted 7 lines · Daniel Vetter
drivers/gpu/drm/armada/armada_gem.c line 142
Quoted 5 lines · Russell King
drivers/gpu/drm/armada/armada_gem.c new file +5
-0+mutex_lock (&dev->struct_mutex); + free =drm_mm_search_free (&priv->linear, size, align,0 ); +if (free) + obj->linear =drm_mm_get_block (free, size, align); +mutex_unlock (&dev->struct_mutex);Quoted 5 lines
The two-stage search_free+get_block
drm_mminterface is something I'd like to remove since it' complicates the interface for no gain. And the preallocation trick for atomic contexts is pretty racy as-is. Can you please convert this over to theinsert_nodeinterfaces which take a preallocatedrm_mm_node?Yes and no. This is only racy if it is callable from atomic contexts, which the above isn't, because it takes a mutex, and the above is the only place which allocations against that pool are done. Mutexes can't be taken in atomic contexts. Plus it's using the non-atomic drm_mm_* interfaces.
However, the
insert_nodeinterfaces appear not to solve any kind of race. All they do is allow the kmalloc to be moved out of this region into the user of this code sequence, while offering no additional locking or safety. So the mutex lock around a call to drm_mm_insert_node*() is still required.Quoted 4 lines
As the
kmalloc()happens beneath the mutex lock, another thread can't race with an allocation in the above code anyway. The *only* reason I'll change this is that it is nicer to the system not to hold locks while allocating memory.Err. There's bugs here in the other drivers such as i915 which follow your suggestion. The problem is this:
Quoted 6 lines
Every time they allocate using
drm_mm_insert_node(), they kmalloc a new structdrm_mm_nodefor this function to fill in and attach.When they've done with the allocation, they call
drm_mm_put_block(). This places the node onto the mm'sunused_nodeslist provided we don't already haveMM_UNUSED_TARGETnodes on that list.
Yeah, for drivers that never use the atomic alloc stuff it's pointless waste of memory.
Quoted 11 lines
So, we end up filling up the unused nodes list to
MM_UNUSED_TARGET, at which point we then start freeing any further nodes - and with no way to pull these off that list, they all just sit there not being used.The only function which takes nodes off that list is
drm_mm_kmalloc(), which is declared statically, and so isn't available to drivers.Are drivers which use the
drm_mm_insert_node()function expected to also usedrm_mm_remove_node(), kfreeing the node after that call, rather than usingdrm_mm_put_block()?
Yeah, with the insert_node interface deallocing the node is the driver's responsibility.
Quoted 2 lines
Either way, I think someone needs to fix the other drivers and Cc those patches to Stable...
Yeah, I think it's time that I move that item up my todo list a lot. And also add some decent kerneldoc to the drm_mm stuff. -Daniel
--
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
RFC PATCH 2/3 DRM: Armada: Add support for ARGB 32x64 or 64x32 hardware cursors
In reply to Russell King - ARM LinuxThis patch adds ARGB hardware cursor support to the DRM driver for the Marvell Armada SoCs. ARGB cursors are supported at either 32x64 or 64x32 resolutions.
--- drivers/gpu/drm/armada/armada_510.c | 1 + drivers/gpu/drm/armada/armada_crtc.c | 244 +++++++++++++++++++++++++++++++++- drivers/gpu/drm/armada/armada_crtc.h | 9 ++ drivers/gpu/drm/armada/armada_drm.h | 1 + drivers/gpu/drm/armada/armada_hw.h | 6 +- 5 files changed, 255 insertions(+), 6 deletions(-)
drivers/gpu/drm/armada/armada_510.c +1 -0
@@ -80,6 +80,7 @@ static int armada510_crtc_compute_clock(struct armada_crtc *dcrtc,const struct armada_variant armada510_ops = { .has_spu_adv_reg = true, + .spu_adv_reg =ADV_HWC32ENABLE |ADV_HWC32ARGB |ADV_HWC32BLEND , .init = armada510_init, .crtc_init = armada510_crtc_init, .crtc_compute_clock = armada510_crtc_compute_clock,
drivers/gpu/drm/armada/armada_crtc.c +240 -4
289 lines not on this page · raw message
drivers/gpu/drm/armada/armada_crtc.h +9 -0
@@ -44,11 +44,20 @@ struct armada_crtc {uint32_t spu_adv_reg; } v[2 ];bool interlaced; +bool cursor_update;uint8_t csc_yuv_mode;uint8_t csc_rgb_mode;struct drm_plane *plane; +struct armada_gem_object *cursor_obj; +int cursor_x; +int cursor_y; +uint32_t cursor_hw_pos; +uint32_t cursor_hw_sz; +uint32_t cursor_w; +uint32_t cursor_h; +int dpms;uint32_t cfg_dumb_ctrl;uint32_t dumb_ctrl;
drivers/gpu/drm/armada/armada_drm.h +1 -0
@@ -60,6 +60,7 @@ struct armada_private;struct armada_variant {bool has_spu_adv_reg; +uint32_t spu_adv_reg;int (*init)(struct armada_private *,struct device *);int (*crtc_init)(struct armada_crtc *); int (*crtc_compute_clock)(struct armada_crtc *,
drivers/gpu/drm/armada/armada_hw.h +4 -2
@@ -168,8 +168,10 @@ enum {SRAM_READ =0 <<14 ,SRAM_WRITE =2 <<14 ,SRAM_INIT =3 <<14 , -SRAM_HWC32_RAMR =0xc <<8 , -SRAM_HWC32_RAMG =0xd <<8 , +SRAM_HWC32_RAM1 =0xc <<8 , +SRAM_HWC32_RAM2 =0xd <<8 , +SRAM_HWC32_RAMR =SRAM_HWC32_RAM1 , +SRAM_HWC32_RAMG =SRAM_HWC32_RAM2 ,SRAM_HWC32_RAMB =0xe <<8 ,SRAM_HWC32_TRAN =0xf <<8 , SRAM_HWC = 0xf << 8,
Signature · 1 line
1.7.4.4
RFC PATCH 3/3 DRM: Armada: support for dma_buf import into gem
In reply to Russell King - ARM LinuxSupport importing certain dma_bufs back into gem - notably those which are either contiguous or are our own exports which do not use dma_map_sg().
--- drivers/gpu/drm/armada/armada_drv.c | 4 +- drivers/gpu/drm/armada/armada_fb.c | 6 +++ drivers/gpu/drm/armada/armada_gem.c | 81 ++++++++++++++++++++++++++++++++++- drivers/gpu/drm/armada/armada_gem.h | 4 ++ 4 files changed, 92 insertions(+), 3 deletions(-)
drivers/gpu/drm/armada/armada_drv.c +2 -2
@@ -311,9 +311,9 @@ static struct drm_driver armada_drm_driver = { .gem_init_object = NULL, .gem_free_object = armada_gem_free_object, .prime_handle_to_fd = drm_gem_prime_handle_to_fd, - .prime_fd_to_handle = NULL, + .prime_fd_to_handle = drm_gem_prime_fd_to_handle, .gem_prime_export = armada_gem_prime_export, - .gem_prime_import = NULL, + .gem_prime_import = armada_gem_prime_import, .dumb_create = armada_gem_dumb_create, .dumb_map_offset = armada_gem_dumb_map_offset, .dumb_destroy = armada_gem_dumb_destroy,
drivers/gpu/drm/armada/armada_fb.c +6 -0
@@ -120,6 +120,12 @@ static struct drm_framebuffer *armada_fb_create(struct drm_device *dev,return ERR_PTR (-ENOENT ); } +if (obj->obj.import_attach && !obj->sgt) { + ret =armada_gem_map_import (obj); +if (ret) + goto unref; + } +/* Framebuffer objects must have a valid device address for scanout */ if (obj->dev_addr ==DMA_ERROR_CODE ) { ret = -EINVAL ;
drivers/gpu/drm/armada/armada_gem.c +80 -1
97 lines not on this page · raw message
drivers/gpu/drm/armada/armada_gem.h +4 -0
@@ -16,6 +16,7 @@ struct armada_gem_object {resource_size_t dev_addr;struct drm_mm_node *linear;/* for linear backed */ struct page *page;/* for page backed */ +struct sg_table *sgt;/* for imported */ void (*update)(void *);void *update_data; };
@@ -37,6 +38,9 @@ int armada_gem_dumb_destroy(struct drm_file *, struct drm_device *, uint32_t);struct dma_buf *armada_gem_prime_export (struct drm_device *dev,struct drm_gem_object *obj,int flags); +struct drm_gem_object *armada_gem_prime_import (struct drm_device *, +struct dma_buf *); +int armada_gem_map_import (struct armada_gem_object *);static inline struct armada_gem_object *armada_gem_object_lookup (struct drm_device *dev,struct drm_file *dfile,unsigned handle)
Signature · 1 line
1.7.4.4