diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2020-01-30 19:04:01 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2020-01-30 19:04:01 +0300 |
commit | 9f68e3655aae6d49d6ba05dd263f99f33c2567af (patch) | |
tree | 42c2c4579c4acbbb456695326af4f4ad8f402813 /drivers/gpu/drm/gma500 | |
parent | 4cadc60d6bcfee9c626d4b55e9dc1475d21ad3bb (diff) | |
parent | d47c7f06268082bc0082a15297a07c0da59b0fc4 (diff) | |
download | linux-9f68e3655aae6d49d6ba05dd263f99f33c2567af.tar.xz |
Merge tag 'drm-next-2020-01-30' of git://anongit.freedesktop.org/drm/drm
Pull drm updates from Davbe Airlie:
"This is the main pull request for graphics for 5.6. Usual selection of
changes all over.
I've got one outstanding vmwgfx pull that touches mm so kept it
separate until after all of this lands. I'll try and get it to you
soon after this, but it might be early next week (nothing wrong with
code, just my schedule is messy)
This also hits a lot of fbdev drivers with some cleanups.
Other notables:
- vulkan timeline semaphore support added to syncobjs
- nouveau turing secureboot/graphics support
- Displayport MST display stream compression support
Detailed summary:
uapi:
- dma-buf heaps added (and fixed)
- command line add support for panel oreientation
- command line allow overriding penguin count
drm:
- mipi dsi definition updates
- lockdep annotations for dma_resv
- remove dma-buf kmap/kunmap support
- constify fb_ops in all fbdev drivers
- MST fix for daisy chained hotplug-
- CTA-861-G modes with VIC >= 193 added
- fix drm_panel_of_backlight export
- LVDS decoder support
- more device based logging support
- scanline alighment for dumb buffers
- MST DSC helpers
scheduler:
- documentation fixes
- job distribution improvements
panel:
- Logic PD type 28 panel support
- Jimax8729d MIPI-DSI
- igenic JZ4770
- generic DSI devicetree bindings
- sony acx424AKP panel
- Leadtek LTK500HD1829
- xinpeng XPP055C272
- AUO B116XAK01
- GiantPlus GPM940B0
- BOE NV140FHM-N49
- Satoz SAT050AT40H12R2
- Sharp LS020B1DD01D panels.
ttm:
- use blocking WW lock
i915:
- hw/uapi state separation
- Lock annotation improvements
- selftest improvements
- ICL/TGL DSI VDSC support
- VBT parsing improvments
- Display refactoring
- DSI updates + fixes
- HDCP 2.2 for CFL
- CML PCI ID fixes
- GLK+ fbc fix
- PSR fixes
- GEN/GT refactor improvments
- DP MST fixes
- switch context id alloc to xarray
- workaround updates
- LMEM debugfs support
- tiled monitor fixes
- ICL+ clock gating programming removed
- DP MST disable sequence fixed
- LMEM discontiguous object maps
- prefaulting for discontiguous objects
- use LMEM for dumb buffers if possible
- add LMEM mmap support
amdgpu:
- enable sync object timelines for vulkan
- MST atomic routines
- enable MST DSC support
- add DMCUB display microengine support
- DC OEM i2c support
- Renoir DC fixes
- Initial HDCP 2.x support
- BACO support for Arcturus
- Use BACO for runtime PM power save
- gfxoff on navi10
- gfx10 golden updates and fixes
- DCN support on POWER
- GFXOFF for raven1 refresh
- MM engine idle handlers cleanup
- 10bpc EDP panel fixes
- renoir watermark fixes
- SR-IOV fixes
- Arcturus VCN fixes
- GDDR6 training fixes
- freesync fixes
- Pollock support
amdkfd:
- unify more codepath with amdgpu
- use KIQ to setup HIQ rather than MMIO
radeon:
- fix vma fault handler race
- PPC DMA fix
- register check fixes for r100/r200
nouveau:
- mmap_sem vs dma_resv fix
- rewrite the ACR secure boot code for Turing
- TU10x graphics engine support (TU11x pending)
- Page kind mapping for turing
- 10-bit LUT support
- GP10B Tegra fixes
- HD audio regression fix
hisilicon/hibmc:
- use generic fbdev code and helpers
rockchip:
- dsi/px30 support
virtio:
- fb damage support
- static some functions
vc4:
- use dma_resv lock wrappers
msm:
- use dma_resv lock wrappers
- sc7180 display + DSI support
- a618 support
- UBWC support improvements
vmwgfx:
- updates + new logging uapi
exynos:
- enable/disable callback cleanups
etnaviv:
- use dma_resv lock wrappers
atmel-hlcdc:
- clock fixes
mediatek:
- cmdq support
- non-smooth cursor fixes
- ctm property support
sun4i:
- suspend support
- A64 mipi dsi support
rcar-du:
- Color management module support
- LVDS encoder dual-link support
- R8A77980 support
analogic:
- add support for an6345
ast:
- atomic modeset support
- primary plane garbage fix
arcgpu:
- fixes for fourcc handling
tegra:
- minor fixes and improvments
mcde:
- vblank support
meson:
- OSD1 plane AFBC commit
gma500:
- add pageflip support
- reomve global drm_dev
komeda:
- tweak debugfs output
- d32 support
- runtime PM suppotr
udl:
- use generic shmem helpers
- cleanup and fixes"
* tag 'drm-next-2020-01-30' of git://anongit.freedesktop.org/drm/drm: (1998 commits)
drm/nouveau/fb/gp102-: allow module to load even when scrubber binary is missing
drm/nouveau/acr: return error when registering LSF if ACR not supported
drm/nouveau/disp/gv100-: not all channel types support reporting error codes
drm/nouveau/disp/nv50-: prevent oops when no channel method map provided
drm/nouveau: support synchronous pushbuf submission
drm/nouveau: signal pending fences when channel has been killed
drm/nouveau: reject attempts to submit to dead channels
drm/nouveau: zero vma pointer even if we only unreference it rather than free
drm/nouveau: Add HD-audio component notifier support
drm/nouveau: fix build error without CONFIG_IOMMU_API
drm/nouveau/kms/nv04: remove set but not used variable 'width'
drm/nouveau/kms/nv50: remove set but not unused variable 'nv_connector'
drm/nouveau/mmu: fix comptag memory leak
drm/nouveau/gr/gp10b: Use gp100_grctx and gp100_gr_zbc
drm/nouveau/pmu/gm20b,gp10b: Fix Falcon bootstrapping
drm/exynos: Rename Exynos to lowercase
drm/exynos: change callback names
drm/mst: Don't do atomic checks over disabled managers
drm/amdgpu: add the lost mutex_init back
drm/amd/display: skip opp blank or unblank if test pattern enabled
...
Diffstat (limited to 'drivers/gpu/drm/gma500')
-rw-r--r-- | drivers/gpu/drm/gma500/accel_2d.c | 19 | ||||
-rw-r--r-- | drivers/gpu/drm/gma500/cdv_intel_display.c | 8 | ||||
-rw-r--r-- | drivers/gpu/drm/gma500/cdv_intel_dp.c | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/gma500/framebuffer.c | 135 | ||||
-rw-r--r-- | drivers/gpu/drm/gma500/framebuffer.h | 15 | ||||
-rw-r--r-- | drivers/gpu/drm/gma500/gma_display.c | 48 | ||||
-rw-r--r-- | drivers/gpu/drm/gma500/gma_display.h | 6 | ||||
-rw-r--r-- | drivers/gpu/drm/gma500/mdfld_intel_display.c | 23 | ||||
-rw-r--r-- | drivers/gpu/drm/gma500/oaktrail_hdmi.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/gma500/oaktrail_lvds.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/gma500/psb_drv.c | 44 | ||||
-rw-r--r-- | drivers/gpu/drm/gma500/psb_drv.h | 8 | ||||
-rw-r--r-- | drivers/gpu/drm/gma500/psb_intel_display.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/gma500/psb_intel_drv.h | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/gma500/psb_irq.c | 23 | ||||
-rw-r--r-- | drivers/gpu/drm/gma500/tc35876x-dsi-lvds.c | 88 |
16 files changed, 231 insertions, 198 deletions
diff --git a/drivers/gpu/drm/gma500/accel_2d.c b/drivers/gpu/drm/gma500/accel_2d.c index 45ad5ffedc93..adc0507545bf 100644 --- a/drivers/gpu/drm/gma500/accel_2d.c +++ b/drivers/gpu/drm/gma500/accel_2d.c @@ -21,9 +21,9 @@ #include <drm/drm.h> #include <drm/drm_crtc.h> +#include <drm/drm_fb_helper.h> #include <drm/drm_fourcc.h> -#include "framebuffer.h" #include "psb_drv.h" #include "psb_reg.h" @@ -226,11 +226,10 @@ static int psb_accel_2d_copy(struct drm_psb_private *dev_priv, static void psbfb_copyarea_accel(struct fb_info *info, const struct fb_copyarea *a) { - struct psb_fbdev *fbdev = info->par; - struct psb_framebuffer *psbfb = &fbdev->pfb; - struct drm_device *dev = psbfb->base.dev; - struct drm_framebuffer *fb = fbdev->psb_fb_helper.fb; - struct drm_psb_private *dev_priv = dev->dev_private; + struct drm_fb_helper *fb_helper = info->par; + struct drm_framebuffer *fb = fb_helper->fb; + struct drm_device *dev; + struct drm_psb_private *dev_priv; uint32_t offset; uint32_t stride; uint32_t src_format; @@ -239,6 +238,8 @@ static void psbfb_copyarea_accel(struct fb_info *info, if (!fb) return; + dev = fb->dev; + dev_priv = dev->dev_private; offset = to_gtt_range(fb->obj[0])->offset; stride = fb->pitches[0]; @@ -309,9 +310,9 @@ void psbfb_copyarea(struct fb_info *info, */ int psbfb_sync(struct fb_info *info) { - struct psb_fbdev *fbdev = info->par; - struct psb_framebuffer *psbfb = &fbdev->pfb; - struct drm_device *dev = psbfb->base.dev; + struct drm_fb_helper *fb_helper = info->par; + struct drm_framebuffer *fb = fb_helper->fb; + struct drm_device *dev = fb->dev; struct drm_psb_private *dev_priv = dev->dev_private; unsigned long _end = jiffies + HZ; int busy = 0; diff --git a/drivers/gpu/drm/gma500/cdv_intel_display.c b/drivers/gpu/drm/gma500/cdv_intel_display.c index 8b784947ed3b..1ed854f498b7 100644 --- a/drivers/gpu/drm/gma500/cdv_intel_display.c +++ b/drivers/gpu/drm/gma500/cdv_intel_display.c @@ -582,8 +582,8 @@ static int cdv_intel_crtc_mode_set(struct drm_crtc *crtc, struct gma_clock_t clock; u32 dpll = 0, dspcntr, pipeconf; bool ok; - bool is_crt = false, is_lvds = false, is_tv = false; - bool is_hdmi = false, is_dp = false; + bool is_lvds = false, is_tv = false; + bool is_dp = false; struct drm_mode_config *mode_config = &dev->mode_config; struct drm_connector *connector; const struct gma_limit_t *limit; @@ -607,10 +607,7 @@ static int cdv_intel_crtc_mode_set(struct drm_crtc *crtc, is_tv = true; break; case INTEL_OUTPUT_ANALOG: - is_crt = true; - break; case INTEL_OUTPUT_HDMI: - is_hdmi = true; break; case INTEL_OUTPUT_DISPLAYPORT: is_dp = true; @@ -979,6 +976,7 @@ const struct drm_crtc_funcs cdv_intel_crtc_funcs = { .gamma_set = gma_crtc_gamma_set, .set_config = gma_crtc_set_config, .destroy = gma_crtc_destroy, + .page_flip = gma_crtc_page_flip, }; const struct gma_clock_funcs cdv_clock_funcs = { diff --git a/drivers/gpu/drm/gma500/cdv_intel_dp.c b/drivers/gpu/drm/gma500/cdv_intel_dp.c index 570b59520fd1..5772b2dce0d6 100644 --- a/drivers/gpu/drm/gma500/cdv_intel_dp.c +++ b/drivers/gpu/drm/gma500/cdv_intel_dp.c @@ -1594,7 +1594,6 @@ cdv_intel_dp_complete_link_train(struct gma_encoder *encoder) { struct drm_device *dev = encoder->base.dev; struct cdv_intel_dp *intel_dp = encoder->dev_priv; - bool channel_eq = false; int tries, cr_tries; u32 reg; uint32_t DP = intel_dp->DP; @@ -1602,7 +1601,6 @@ cdv_intel_dp_complete_link_train(struct gma_encoder *encoder) /* channel equalization */ tries = 0; cr_tries = 0; - channel_eq = false; DRM_DEBUG_KMS("\n"); reg = DP | DP_LINK_TRAIN_PAT_2; @@ -1648,7 +1646,6 @@ cdv_intel_dp_complete_link_train(struct gma_encoder *encoder) if (cdv_intel_channel_eq_ok(encoder)) { DRM_DEBUG_KMS("PT2 train is done\n"); - channel_eq = true; break; } diff --git a/drivers/gpu/drm/gma500/framebuffer.c b/drivers/gpu/drm/gma500/framebuffer.c index 218f3bb15276..1459076d1980 100644 --- a/drivers/gpu/drm/gma500/framebuffer.c +++ b/drivers/gpu/drm/gma500/framebuffer.c @@ -40,8 +40,8 @@ static int psbfb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue, unsigned transp, struct fb_info *info) { - struct psb_fbdev *fbdev = info->par; - struct drm_framebuffer *fb = fbdev->psb_fb_helper.fb; + struct drm_fb_helper *fb_helper = info->par; + struct drm_framebuffer *fb = fb_helper->fb; uint32_t v; if (!fb) @@ -77,10 +77,10 @@ static int psbfb_setcolreg(unsigned regno, unsigned red, unsigned green, static int psbfb_pan(struct fb_var_screeninfo *var, struct fb_info *info) { - struct psb_fbdev *fbdev = info->par; - struct psb_framebuffer *psbfb = &fbdev->pfb; - struct drm_device *dev = psbfb->base.dev; - struct gtt_range *gtt = to_gtt_range(psbfb->base.obj[0]); + struct drm_fb_helper *fb_helper = info->par; + struct drm_framebuffer *fb = fb_helper->fb; + struct drm_device *dev = fb->dev; + struct gtt_range *gtt = to_gtt_range(fb->obj[0]); /* * We have to poke our nose in here. The core fb code assumes @@ -99,10 +99,10 @@ static int psbfb_pan(struct fb_var_screeninfo *var, struct fb_info *info) static vm_fault_t psbfb_vm_fault(struct vm_fault *vmf) { struct vm_area_struct *vma = vmf->vma; - struct psb_framebuffer *psbfb = vma->vm_private_data; - struct drm_device *dev = psbfb->base.dev; + struct drm_framebuffer *fb = vma->vm_private_data; + struct drm_device *dev = fb->dev; struct drm_psb_private *dev_priv = dev->dev_private; - struct gtt_range *gtt = to_gtt_range(psbfb->base.obj[0]); + struct gtt_range *gtt = to_gtt_range(fb->obj[0]); int page_num; int i; unsigned long address; @@ -145,23 +145,21 @@ static const struct vm_operations_struct psbfb_vm_ops = { static int psbfb_mmap(struct fb_info *info, struct vm_area_struct *vma) { - struct psb_fbdev *fbdev = info->par; - struct psb_framebuffer *psbfb = &fbdev->pfb; + struct drm_fb_helper *fb_helper = info->par; + struct drm_framebuffer *fb = fb_helper->fb; if (vma->vm_pgoff != 0) return -EINVAL; if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) return -EINVAL; - if (!psbfb->addr_space) - psbfb->addr_space = vma->vm_file->f_mapping; /* * If this is a GEM object then info->screen_base is the virtual * kernel remapping of the object. FIXME: Review if this is * suitable for our mmap work */ vma->vm_ops = &psbfb_vm_ops; - vma->vm_private_data = (void *)psbfb; + vma->vm_private_data = (void *)fb; vma->vm_flags |= VM_IO | VM_MIXEDMAP | VM_DONTEXPAND | VM_DONTDUMP; return 0; } @@ -209,9 +207,9 @@ static struct fb_ops psbfb_unaccel_ops = { * 0 on success or an error code if we fail. */ static int psb_framebuffer_init(struct drm_device *dev, - struct psb_framebuffer *fb, + struct drm_framebuffer *fb, const struct drm_mode_fb_cmd2 *mode_cmd, - struct gtt_range *gt) + struct drm_gem_object *obj) { const struct drm_format_info *info; int ret; @@ -227,9 +225,9 @@ static int psb_framebuffer_init(struct drm_device *dev, if (mode_cmd->pitches[0] & 63) return -EINVAL; - drm_helper_mode_fill_fb_struct(dev, &fb->base, mode_cmd); - fb->base.obj[0] = >->gem; - ret = drm_framebuffer_init(dev, &fb->base, &psb_fb_funcs); + drm_helper_mode_fill_fb_struct(dev, fb, mode_cmd); + fb->obj[0] = obj; + ret = drm_framebuffer_init(dev, fb, &psb_fb_funcs); if (ret) { dev_err(dev->dev, "framebuffer init failed: %d\n", ret); return ret; @@ -252,21 +250,21 @@ static int psb_framebuffer_init(struct drm_device *dev, static struct drm_framebuffer *psb_framebuffer_create (struct drm_device *dev, const struct drm_mode_fb_cmd2 *mode_cmd, - struct gtt_range *gt) + struct drm_gem_object *obj) { - struct psb_framebuffer *fb; + struct drm_framebuffer *fb; int ret; fb = kzalloc(sizeof(*fb), GFP_KERNEL); if (!fb) return ERR_PTR(-ENOMEM); - ret = psb_framebuffer_init(dev, fb, mode_cmd, gt); + ret = psb_framebuffer_init(dev, fb, mode_cmd, obj); if (ret) { kfree(fb); return ERR_PTR(ret); } - return &fb->base; + return fb; } /** @@ -300,14 +298,13 @@ static struct gtt_range *psbfb_alloc(struct drm_device *dev, int aligned_size) * * Create a framebuffer to the specifications provided */ -static int psbfb_create(struct psb_fbdev *fbdev, +static int psbfb_create(struct drm_fb_helper *fb_helper, struct drm_fb_helper_surface_size *sizes) { - struct drm_device *dev = fbdev->psb_fb_helper.dev; + struct drm_device *dev = fb_helper->dev; struct drm_psb_private *dev_priv = dev->dev_private; struct fb_info *info; struct drm_framebuffer *fb; - struct psb_framebuffer *psbfb = &fbdev->pfb; struct drm_mode_fb_cmd2 mode_cmd; int size; int ret; @@ -372,7 +369,7 @@ static int psbfb_create(struct psb_fbdev *fbdev, memset(dev_priv->vram_addr + backing->offset, 0, size); - info = drm_fb_helper_alloc_fbi(&fbdev->psb_fb_helper); + info = drm_fb_helper_alloc_fbi(fb_helper); if (IS_ERR(info)) { ret = PTR_ERR(info); goto out; @@ -380,14 +377,13 @@ static int psbfb_create(struct psb_fbdev *fbdev, mode_cmd.pixel_format = drm_mode_legacy_fb_format(bpp, depth); - ret = psb_framebuffer_init(dev, psbfb, &mode_cmd, backing); - if (ret) + fb = psb_framebuffer_create(dev, &mode_cmd, &backing->gem); + if (IS_ERR(fb)) { + ret = PTR_ERR(fb); goto out; + } - fb = &psbfb->base; - psbfb->fbdev = info; - - fbdev->psb_fb_helper.fb = fb; + fb_helper->fb = fb; if (dev_priv->ops->accel_2d && pitch_lines > 8) /* 2D engine */ info->fbops = &psbfb_ops; @@ -411,15 +407,14 @@ static int psbfb_create(struct psb_fbdev *fbdev, info->apertures->ranges[0].size = dev_priv->gtt.stolen_size; } - drm_fb_helper_fill_info(info, &fbdev->psb_fb_helper, sizes); + drm_fb_helper_fill_info(info, fb_helper, sizes); info->fix.mmio_start = pci_resource_start(dev->pdev, 0); info->fix.mmio_len = pci_resource_len(dev->pdev, 0); /* Use default scratch pixmap (info->pixmap.flags = FB_PIXMAP_SYSTEM) */ - dev_dbg(dev->dev, "allocated %dx%d fb\n", - psbfb->base.width, psbfb->base.height); + dev_dbg(dev->dev, "allocated %dx%d fb\n", fb->width, fb->height); return 0; out: @@ -439,7 +434,6 @@ static struct drm_framebuffer *psb_user_framebuffer_create (struct drm_device *dev, struct drm_file *filp, const struct drm_mode_fb_cmd2 *cmd) { - struct gtt_range *r; struct drm_gem_object *obj; /* @@ -451,17 +445,15 @@ static struct drm_framebuffer *psb_user_framebuffer_create return ERR_PTR(-ENOENT); /* Let the core code do all the work */ - r = container_of(obj, struct gtt_range, gem); - return psb_framebuffer_create(dev, cmd, r); + return psb_framebuffer_create(dev, cmd, obj); } -static int psbfb_probe(struct drm_fb_helper *helper, +static int psbfb_probe(struct drm_fb_helper *fb_helper, struct drm_fb_helper_surface_size *sizes) { - struct psb_fbdev *psb_fbdev = - container_of(helper, struct psb_fbdev, psb_fb_helper); - struct drm_device *dev = psb_fbdev->psb_fb_helper.dev; + struct drm_device *dev = fb_helper->dev; struct drm_psb_private *dev_priv = dev->dev_private; + unsigned int fb_size; int bytespp; bytespp = sizes->surface_bpp / 8; @@ -471,72 +463,77 @@ static int psbfb_probe(struct drm_fb_helper *helper, /* If the mode will not fit in 32bit then switch to 16bit to get a console on full resolution. The X mode setting server will allocate its own 32bit GEM framebuffer */ - if (ALIGN(sizes->fb_width * bytespp, 64) * sizes->fb_height > - dev_priv->vram_stolen_size) { + fb_size = ALIGN(sizes->surface_width * bytespp, 64) * + sizes->surface_height; + fb_size = ALIGN(fb_size, PAGE_SIZE); + + if (fb_size > dev_priv->vram_stolen_size) { sizes->surface_bpp = 16; sizes->surface_depth = 16; } - return psbfb_create(psb_fbdev, sizes); + return psbfb_create(fb_helper, sizes); } static const struct drm_fb_helper_funcs psb_fb_helper_funcs = { .fb_probe = psbfb_probe, }; -static int psb_fbdev_destroy(struct drm_device *dev, struct psb_fbdev *fbdev) +static int psb_fbdev_destroy(struct drm_device *dev, + struct drm_fb_helper *fb_helper) { - struct psb_framebuffer *psbfb = &fbdev->pfb; + struct drm_framebuffer *fb = fb_helper->fb; + + drm_fb_helper_unregister_fbi(fb_helper); - drm_fb_helper_unregister_fbi(&fbdev->psb_fb_helper); + drm_fb_helper_fini(fb_helper); + drm_framebuffer_unregister_private(fb); + drm_framebuffer_cleanup(fb); - drm_fb_helper_fini(&fbdev->psb_fb_helper); - drm_framebuffer_unregister_private(&psbfb->base); - drm_framebuffer_cleanup(&psbfb->base); + if (fb->obj[0]) + drm_gem_object_put_unlocked(fb->obj[0]); + kfree(fb); - if (psbfb->base.obj[0]) - drm_gem_object_put_unlocked(psbfb->base.obj[0]); return 0; } int psb_fbdev_init(struct drm_device *dev) { - struct psb_fbdev *fbdev; + struct drm_fb_helper *fb_helper; struct drm_psb_private *dev_priv = dev->dev_private; int ret; - fbdev = kzalloc(sizeof(struct psb_fbdev), GFP_KERNEL); - if (!fbdev) { + fb_helper = kzalloc(sizeof(*fb_helper), GFP_KERNEL); + if (!fb_helper) { dev_err(dev->dev, "no memory\n"); return -ENOMEM; } - dev_priv->fbdev = fbdev; + dev_priv->fb_helper = fb_helper; - drm_fb_helper_prepare(dev, &fbdev->psb_fb_helper, &psb_fb_helper_funcs); + drm_fb_helper_prepare(dev, fb_helper, &psb_fb_helper_funcs); - ret = drm_fb_helper_init(dev, &fbdev->psb_fb_helper, - INTELFB_CONN_LIMIT); + ret = drm_fb_helper_init(dev, fb_helper, INTELFB_CONN_LIMIT); if (ret) goto free; - ret = drm_fb_helper_single_add_all_connectors(&fbdev->psb_fb_helper); + ret = drm_fb_helper_single_add_all_connectors(fb_helper); if (ret) goto fini; /* disable all the possible outputs/crtcs before entering KMS mode */ drm_helper_disable_unused_functions(dev); - ret = drm_fb_helper_initial_config(&fbdev->psb_fb_helper, 32); + ret = drm_fb_helper_initial_config(fb_helper, 32); if (ret) goto fini; return 0; fini: - drm_fb_helper_fini(&fbdev->psb_fb_helper); + drm_fb_helper_fini(fb_helper); free: - kfree(fbdev); + kfree(fb_helper); return ret; } @@ -544,12 +541,12 @@ static void psb_fbdev_fini(struct drm_device *dev) { struct drm_psb_private *dev_priv = dev->dev_private; - if (!dev_priv->fbdev) + if (!dev_priv->fb_helper) return; - psb_fbdev_destroy(dev, dev_priv->fbdev); - kfree(dev_priv->fbdev); - dev_priv->fbdev = NULL; + psb_fbdev_destroy(dev, dev_priv->fb_helper); + kfree(dev_priv->fb_helper); + dev_priv->fb_helper = NULL; } static const struct drm_mode_config_funcs psb_mode_funcs = { diff --git a/drivers/gpu/drm/gma500/framebuffer.h b/drivers/gpu/drm/gma500/framebuffer.h index ae8a02639fd9..2fbba4b48841 100644 --- a/drivers/gpu/drm/gma500/framebuffer.h +++ b/drivers/gpu/drm/gma500/framebuffer.h @@ -9,23 +9,8 @@ #ifndef _FRAMEBUFFER_H_ #define _FRAMEBUFFER_H_ -#include <drm/drm_fb_helper.h> - #include "psb_drv.h" -struct psb_framebuffer { - struct drm_framebuffer base; - struct address_space *addr_space; - struct fb_info *fbdev; -}; - -struct psb_fbdev { - struct drm_fb_helper psb_fb_helper; /* must be first */ - struct psb_framebuffer pfb; -}; - -#define to_psb_fb(x) container_of(x, struct psb_framebuffer, base) - extern int gma_connector_clones(struct drm_device *dev, int type_mask); #endif diff --git a/drivers/gpu/drm/gma500/gma_display.c b/drivers/gpu/drm/gma500/gma_display.c index e20ccb5d10fd..17f136985d21 100644 --- a/drivers/gpu/drm/gma500/gma_display.c +++ b/drivers/gpu/drm/gma500/gma_display.c @@ -255,6 +255,8 @@ void gma_crtc_dpms(struct drm_crtc *crtc, int mode) /* Give the overlay scaler a chance to enable * if it's on this pipe */ /* psb_intel_crtc_dpms_video(crtc, true); TODO */ + + drm_crtc_vblank_on(crtc); break; case DRM_MODE_DPMS_OFF: if (!gma_crtc->active) @@ -501,6 +503,52 @@ void gma_crtc_destroy(struct drm_crtc *crtc) kfree(gma_crtc); } +int gma_crtc_page_flip(struct drm_crtc *crtc, + struct drm_framebuffer *fb, + struct drm_pending_vblank_event *event, + uint32_t page_flip_flags, + struct drm_modeset_acquire_ctx *ctx) +{ + struct gma_crtc *gma_crtc = to_gma_crtc(crtc); + struct drm_framebuffer *current_fb = crtc->primary->fb; + struct drm_framebuffer *old_fb = crtc->primary->old_fb; + const struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; + struct drm_device *dev = crtc->dev; + unsigned long flags; + int ret; + + if (!crtc_funcs->mode_set_base) + return -EINVAL; + + /* Using mode_set_base requires the new fb to be set already. */ + crtc->primary->fb = fb; + + if (event) { + spin_lock_irqsave(&dev->event_lock, flags); + + WARN_ON(drm_crtc_vblank_get(crtc) != 0); + + gma_crtc->page_flip_event = event; + + /* Call this locked if we want an event at vblank interrupt. */ + ret = crtc_funcs->mode_set_base(crtc, crtc->x, crtc->y, old_fb); + if (ret) { + gma_crtc->page_flip_event = NULL; + drm_crtc_vblank_put(crtc); + } + + spin_unlock_irqrestore(&dev->event_lock, flags); + } else { + ret = crtc_funcs->mode_set_base(crtc, crtc->x, crtc->y, old_fb); + } + + /* Restore previous fb in case of failure. */ + if (ret) + crtc->primary->fb = current_fb; + + return ret; +} + int gma_crtc_set_config(struct drm_mode_set *set, struct drm_modeset_acquire_ctx *ctx) { diff --git a/drivers/gpu/drm/gma500/gma_display.h b/drivers/gpu/drm/gma500/gma_display.h index fdbd7ecaa59c..7bd6c1ee8b21 100644 --- a/drivers/gpu/drm/gma500/gma_display.h +++ b/drivers/gpu/drm/gma500/gma_display.h @@ -11,6 +11,7 @@ #define _GMA_DISPLAY_H_ #include <linux/pm_runtime.h> +#include <drm/drm_vblank.h> struct drm_encoder; struct drm_mode_set; @@ -71,6 +72,11 @@ extern void gma_crtc_prepare(struct drm_crtc *crtc); extern void gma_crtc_commit(struct drm_crtc *crtc); extern void gma_crtc_disable(struct drm_crtc *crtc); extern void gma_crtc_destroy(struct drm_crtc *crtc); +extern int gma_crtc_page_flip(struct drm_crtc *crtc, + struct drm_framebuffer *fb, + struct drm_pending_vblank_event *event, + uint32_t page_flip_flags, + struct drm_modeset_acquire_ctx *ctx); extern int gma_crtc_set_config(struct drm_mode_set *set, struct drm_modeset_acquire_ctx *ctx); diff --git a/drivers/gpu/drm/gma500/mdfld_intel_display.c b/drivers/gpu/drm/gma500/mdfld_intel_display.c index b8bfb96008b8..4fff110c4921 100644 --- a/drivers/gpu/drm/gma500/mdfld_intel_display.c +++ b/drivers/gpu/drm/gma500/mdfld_intel_display.c @@ -113,27 +113,6 @@ static int psb_intel_panel_fitter_pipe(struct drm_device *dev) return (pfit_control >> 29) & 0x3; } -static struct drm_device globle_dev; - -void mdfld__intel_plane_set_alpha(int enable) -{ - struct drm_device *dev = &globle_dev; - int dspcntr_reg = DSPACNTR; - u32 dspcntr; - - dspcntr = REG_READ(dspcntr_reg); - - if (enable) { - dspcntr &= ~DISPPLANE_32BPP_NO_ALPHA; - dspcntr |= DISPPLANE_32BPP; - } else { - dspcntr &= ~DISPPLANE_32BPP; - dspcntr |= DISPPLANE_32BPP_NO_ALPHA; - } - - REG_WRITE(dspcntr_reg, dspcntr); -} - static int check_fb(struct drm_framebuffer *fb) { if (!fb) @@ -164,8 +143,6 @@ static int mdfld__intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, u32 dspcntr; int ret; - memcpy(&globle_dev, dev, sizeof(struct drm_device)); - dev_dbg(dev->dev, "pipe = 0x%x.\n", pipe); /* no fb bound */ diff --git a/drivers/gpu/drm/gma500/oaktrail_hdmi.c b/drivers/gpu/drm/gma500/oaktrail_hdmi.c index f4c520893ceb..f4370232767d 100644 --- a/drivers/gpu/drm/gma500/oaktrail_hdmi.c +++ b/drivers/gpu/drm/gma500/oaktrail_hdmi.c @@ -159,9 +159,7 @@ static void oaktrail_hdmi_audio_disable(struct drm_device *dev) static unsigned int htotal_calculate(struct drm_display_mode *mode) { - u32 htotal, new_crtc_htotal; - - htotal = (mode->crtc_hdisplay - 1) | ((mode->crtc_htotal - 1) << 16); + u32 new_crtc_htotal; /* * 1024 x 768 new_crtc_htotal = 0x1024; diff --git a/drivers/gpu/drm/gma500/oaktrail_lvds.c b/drivers/gpu/drm/gma500/oaktrail_lvds.c index 7390403ea1b7..582e09597500 100644 --- a/drivers/gpu/drm/gma500/oaktrail_lvds.c +++ b/drivers/gpu/drm/gma500/oaktrail_lvds.c @@ -117,6 +117,7 @@ static void oaktrail_lvds_mode_set(struct drm_encoder *encoder, if (!connector) { DRM_ERROR("Couldn't find connector when setting mode"); + gma_power_end(dev); return; } diff --git a/drivers/gpu/drm/gma500/psb_drv.c b/drivers/gpu/drm/gma500/psb_drv.c index 0900052fc484..6956c8e7501c 100644 --- a/drivers/gpu/drm/gma500/psb_drv.c +++ b/drivers/gpu/drm/gma500/psb_drv.c @@ -19,10 +19,10 @@ #include <drm/drm.h> #include <drm/drm_drv.h> +#include <drm/drm_fb_helper.h> #include <drm/drm_file.h> #include <drm/drm_ioctl.h> #include <drm/drm_irq.h> -#include <drm/drm_pci.h> #include <drm/drm_pciids.h> #include <drm/drm_vblank.h> @@ -426,14 +426,48 @@ static long psb_unlocked_ioctl(struct file *filp, unsigned int cmd, static int psb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { - return drm_get_pci_dev(pdev, ent, &driver); -} + struct drm_device *dev; + int ret; + + ret = pci_enable_device(pdev); + if (ret) + return ret; + + dev = drm_dev_alloc(&driver, &pdev->dev); + if (IS_ERR(dev)) { + ret = PTR_ERR(dev); + goto err_pci_disable_device; + } + + dev->pdev = pdev; + pci_set_drvdata(pdev, dev); + + ret = psb_driver_load(dev, ent->driver_data); + if (ret) + goto err_drm_dev_put; + ret = drm_dev_register(dev, ent->driver_data); + if (ret) + goto err_psb_driver_unload; + + return 0; + +err_psb_driver_unload: + psb_driver_unload(dev); +err_drm_dev_put: + drm_dev_put(dev); +err_pci_disable_device: + pci_disable_device(pdev); + return ret; +} static void psb_pci_remove(struct pci_dev *pdev) { struct drm_device *dev = pci_get_drvdata(pdev); - drm_put_dev(dev); + + drm_dev_unregister(dev); + psb_driver_unload(dev); + drm_dev_put(dev); } static const struct dev_pm_ops psb_pm_ops = { @@ -466,8 +500,6 @@ static const struct file_operations psb_gem_fops = { static struct drm_driver driver = { .driver_features = DRIVER_MODESET | DRIVER_GEM, - .load = psb_driver_load, - .unload = psb_driver_unload, .lastclose = drm_fb_helper_lastclose, .num_ioctls = ARRAY_SIZE(psb_ioctls), diff --git a/drivers/gpu/drm/gma500/psb_drv.h b/drivers/gpu/drm/gma500/psb_drv.h index 9b3c03f4a38d..3d4ef3071d45 100644 --- a/drivers/gpu/drm/gma500/psb_drv.h +++ b/drivers/gpu/drm/gma500/psb_drv.h @@ -229,6 +229,8 @@ enum { #define KSEL_BYPASS_25 6 #define KSEL_BYPASS_83_100 7 +struct drm_fb_helper; + struct opregion_header; struct opregion_acpi; struct opregion_swsci; @@ -432,7 +434,7 @@ struct drm_psb_private { struct pci_dev *lpc_pdev; /* Currently only used by mrst */ const struct psb_ops *ops; const struct psb_offset *regmap; - + struct child_device_config *child_dev; int child_dev_num; @@ -540,7 +542,7 @@ struct drm_psb_private { /* Oaktrail HDMI state */ struct oaktrail_hdmi_dev *hdmi_priv; - + /* Register state */ struct psb_save_area regs; @@ -572,7 +574,7 @@ struct drm_psb_private { uint32_t blc_adj1; uint32_t blc_adj2; - void *fbdev; + struct drm_fb_helper *fb_helper; /* 2D acceleration */ spinlock_t lock_2d; diff --git a/drivers/gpu/drm/gma500/psb_intel_display.c b/drivers/gpu/drm/gma500/psb_intel_display.c index 4256410535f0..fed3b563e62e 100644 --- a/drivers/gpu/drm/gma500/psb_intel_display.c +++ b/drivers/gpu/drm/gma500/psb_intel_display.c @@ -432,6 +432,7 @@ const struct drm_crtc_funcs psb_intel_crtc_funcs = { .gamma_set = gma_crtc_gamma_set, .set_config = gma_crtc_set_config, .destroy = gma_crtc_destroy, + .page_flip = gma_crtc_page_flip, }; const struct gma_clock_funcs psb_clock_funcs = { diff --git a/drivers/gpu/drm/gma500/psb_intel_drv.h b/drivers/gpu/drm/gma500/psb_intel_drv.h index cdf10333d1c2..16c6136f778b 100644 --- a/drivers/gpu/drm/gma500/psb_intel_drv.h +++ b/drivers/gpu/drm/gma500/psb_intel_drv.h @@ -12,6 +12,7 @@ #include <drm/drm_crtc_helper.h> #include <drm/drm_encoder.h> #include <drm/drm_probe_helper.h> +#include <drm/drm_vblank.h> #include <linux/gpio.h> #include "gma_display.h" @@ -182,6 +183,8 @@ struct gma_crtc { struct psb_intel_crtc_state *crtc_state; const struct gma_clock_funcs *clock_funcs; + + struct drm_pending_vblank_event *page_flip_event; }; #define to_gma_crtc(x) \ diff --git a/drivers/gpu/drm/gma500/psb_irq.c b/drivers/gpu/drm/gma500/psb_irq.c index e6265fb85626..91f90016dba9 100644 --- a/drivers/gpu/drm/gma500/psb_irq.c +++ b/drivers/gpu/drm/gma500/psb_irq.c @@ -165,11 +165,23 @@ static void mid_pipe_event_handler(struct drm_device *dev, int pipe) "%s, can't clear status bits for pipe %d, its value = 0x%x.\n", __func__, pipe, PSB_RVDC32(pipe_stat_reg)); - if (pipe_stat_val & PIPE_VBLANK_STATUS) - drm_handle_vblank(dev, pipe); + if (pipe_stat_val & PIPE_VBLANK_STATUS || + (IS_MFLD(dev) && pipe_stat_val & PIPE_TE_STATUS)) { + struct drm_crtc *crtc = drm_crtc_from_index(dev, pipe); + struct gma_crtc *gma_crtc = to_gma_crtc(crtc); + unsigned long flags; - if (pipe_stat_val & PIPE_TE_STATUS) drm_handle_vblank(dev, pipe); + + spin_lock_irqsave(&dev->event_lock, flags); + if (gma_crtc->page_flip_event) { + drm_crtc_send_vblank_event(crtc, + gma_crtc->page_flip_event); + gma_crtc->page_flip_event = NULL; + drm_crtc_vblank_put(crtc); + } + spin_unlock_irqrestore(&dev->event_lock, flags); + } } /* @@ -194,7 +206,6 @@ static void psb_sgx_interrupt(struct drm_device *dev, u32 stat_1, u32 stat_2) { struct drm_psb_private *dev_priv = dev->dev_private; u32 val, addr; - int error = false; if (stat_1 & _PSB_CE_TWOD_COMPLETE) val = PSB_RSGX32(PSB_CR_2D_BLIT_STATUS); @@ -229,7 +240,6 @@ static void psb_sgx_interrupt(struct drm_device *dev, u32 stat_1, u32 stat_2) DRM_ERROR("\tMMU failing address is 0x%08x.\n", (unsigned int)addr); - error = true; } } @@ -460,12 +470,11 @@ void psb_irq_turn_off_dpst(struct drm_device *dev) { struct drm_psb_private *dev_priv = (struct drm_psb_private *) dev->dev_private; - u32 hist_reg; u32 pwm_reg; if (gma_power_begin(dev, false)) { PSB_WVDC32(0x00000000, HISTOGRAM_INT_CONTROL); - hist_reg = PSB_RVDC32(HISTOGRAM_INT_CONTROL); + PSB_RVDC32(HISTOGRAM_INT_CONTROL); psb_disable_pipestat(dev_priv, 0, PIPE_DPST_EVENT_ENABLE); diff --git a/drivers/gpu/drm/gma500/tc35876x-dsi-lvds.c b/drivers/gpu/drm/gma500/tc35876x-dsi-lvds.c index 7de3ce637c7f..9e8224456ea2 100644 --- a/drivers/gpu/drm/gma500/tc35876x-dsi-lvds.c +++ b/drivers/gpu/drm/gma500/tc35876x-dsi-lvds.c @@ -25,7 +25,7 @@ #include <linux/delay.h> #include <linux/kernel.h> #include <linux/module.h> -#include <linux/platform_data/tc35876x.h> +#include <linux/gpio/consumer.h> #include <asm/intel_scu_ipc.h> @@ -36,6 +36,11 @@ static struct i2c_client *tc35876x_client; static struct i2c_client *cmi_lcd_i2c_client; +/* Panel GPIOs */ +static struct gpio_desc *bridge_reset; +static struct gpio_desc *bridge_bl_enable; +static struct gpio_desc *backlight_voltage; + #define FLD_MASK(start, end) (((1 << ((start) - (end) + 1)) - 1) << (end)) #define FLD_VAL(val, start, end) (((val) << (end)) & FLD_MASK(start, end)) @@ -316,27 +321,23 @@ static int tc35876x_regr(struct i2c_client *client, u16 reg, u32 *value) void tc35876x_set_bridge_reset_state(struct drm_device *dev, int state) { - struct tc35876x_platform_data *pdata; - if (WARN(!tc35876x_client, "%s called before probe", __func__)) return; dev_dbg(&tc35876x_client->dev, "%s: state %d\n", __func__, state); - pdata = dev_get_platdata(&tc35876x_client->dev); - - if (pdata->gpio_bridge_reset == -1) + if (!bridge_reset) return; if (state) { - gpio_set_value_cansleep(pdata->gpio_bridge_reset, 0); + gpiod_set_value_cansleep(bridge_reset, 0); mdelay(10); } else { /* Pull MIPI Bridge reset pin to Low */ - gpio_set_value_cansleep(pdata->gpio_bridge_reset, 0); + gpiod_set_value_cansleep(bridge_reset, 0); mdelay(20); /* Pull MIPI Bridge reset pin to High */ - gpio_set_value_cansleep(pdata->gpio_bridge_reset, 1); + gpiod_set_value_cansleep(bridge_reset, 1); mdelay(40); } } @@ -510,25 +511,20 @@ void tc35876x_brightness_control(struct drm_device *dev, int level) void tc35876x_toshiba_bridge_panel_off(struct drm_device *dev) { - struct tc35876x_platform_data *pdata; - if (WARN(!tc35876x_client, "%s called before probe", __func__)) return; dev_dbg(&tc35876x_client->dev, "%s\n", __func__); - pdata = dev_get_platdata(&tc35876x_client->dev); - - if (pdata->gpio_panel_bl_en != -1) - gpio_set_value_cansleep(pdata->gpio_panel_bl_en, 0); + if (bridge_bl_enable) + gpiod_set_value_cansleep(bridge_bl_enable, 0); - if (pdata->gpio_panel_vadd != -1) - gpio_set_value_cansleep(pdata->gpio_panel_vadd, 0); + if (backlight_voltage) + gpiod_set_value_cansleep(backlight_voltage, 0); } void tc35876x_toshiba_bridge_panel_on(struct drm_device *dev) { - struct tc35876x_platform_data *pdata; struct drm_psb_private *dev_priv = dev->dev_private; if (WARN(!tc35876x_client, "%s called before probe", __func__)) @@ -536,10 +532,8 @@ void tc35876x_toshiba_bridge_panel_on(struct drm_device *dev) dev_dbg(&tc35876x_client->dev, "%s\n", __func__); - pdata = dev_get_platdata(&tc35876x_client->dev); - - if (pdata->gpio_panel_vadd != -1) { - gpio_set_value_cansleep(pdata->gpio_panel_vadd, 1); + if (backlight_voltage) { + gpiod_set_value_cansleep(backlight_voltage, 1); msleep(260); } @@ -571,8 +565,8 @@ void tc35876x_toshiba_bridge_panel_on(struct drm_device *dev) "i2c write failed (%d)\n", ret); } - if (pdata->gpio_panel_bl_en != -1) - gpio_set_value_cansleep(pdata->gpio_panel_bl_en, 1); + if (bridge_bl_enable) + gpiod_set_value_cansleep(bridge_bl_enable, 1); tc35876x_brightness_control(dev, dev_priv->brightness_adjusted); } @@ -635,8 +629,6 @@ static int tc35876x_get_panel_info(struct drm_device *dev, int pipe, static int tc35876x_bridge_probe(struct i2c_client *client, const struct i2c_device_id *id) { - struct tc35876x_platform_data *pdata; - dev_info(&client->dev, "%s\n", __func__); if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { @@ -645,26 +637,23 @@ static int tc35876x_bridge_probe(struct i2c_client *client, return -ENODEV; } - pdata = dev_get_platdata(&client->dev); - if (!pdata) { - dev_err(&client->dev, "%s: no platform data\n", __func__); - return -ENODEV; - } + bridge_reset = devm_gpiod_get_optional(&client->dev, "bridge-reset", GPIOD_OUT_LOW); + if (IS_ERR(bridge_reset)) + return PTR_ERR(bridge_reset); + if (bridge_reset) + gpiod_set_consumer_name(bridge_reset, "tc35876x bridge reset"); - if (pdata->gpio_bridge_reset != -1) { - gpio_request(pdata->gpio_bridge_reset, "tc35876x bridge reset"); - gpio_direction_output(pdata->gpio_bridge_reset, 0); - } - - if (pdata->gpio_panel_bl_en != -1) { - gpio_request(pdata->gpio_panel_bl_en, "tc35876x panel bl en"); - gpio_direction_output(pdata->gpio_panel_bl_en, 0); - } + bridge_bl_enable = devm_gpiod_get_optional(&client->dev, "bl-en", GPIOD_OUT_LOW); + if (IS_ERR(bridge_bl_enable)) + return PTR_ERR(bridge_bl_enable); + if (bridge_bl_enable) + gpiod_set_consumer_name(bridge_bl_enable, "tc35876x panel bl en"); - if (pdata->gpio_panel_vadd != -1) { - gpio_request(pdata->gpio_panel_vadd, "tc35876x panel vadd"); - gpio_direction_output(pdata->gpio_panel_vadd, 0); - } + backlight_voltage = devm_gpiod_get_optional(&client->dev, "vadd", GPIOD_OUT_LOW); + if (IS_ERR(backlight_voltage)) + return PTR_ERR(backlight_voltage); + if (backlight_voltage) + gpiod_set_consumer_name(backlight_voltage, "tc35876x panel vadd"); tc35876x_client = client; @@ -673,19 +662,8 @@ static int tc35876x_bridge_probe(struct i2c_client *client, static int tc35876x_bridge_remove(struct i2c_client *client) { - struct tc35876x_platform_data *pdata = dev_get_platdata(&client->dev); - dev_dbg(&client->dev, "%s\n", __func__); - if (pdata->gpio_bridge_reset != -1) - gpio_free(pdata->gpio_bridge_reset); - - if (pdata->gpio_panel_bl_en != -1) - gpio_free(pdata->gpio_panel_bl_en); - - if (pdata->gpio_panel_vadd != -1) - gpio_free(pdata->gpio_panel_vadd); - tc35876x_client = NULL; return 0; |