Re: [PATCH] drm/i915: Convert timers to use timer_setup()
On Mon, 2017-10-16 at 15:55 -0700, Kees Cook wrote: > In preparation for unconditionally passing the struct timer_list pointer to > all timer callbacks, switch to using the new timer_setup() and from_timer() > to pass the timer pointer explicitly. > > Cc: Daniel Vetter > Cc: Jani Nikula > Cc: David Airlie > Cc: Chris Wilson > Cc: Joonas Lahtinen > Cc: Tvrtko Ursulin > Cc: Oscar Mateo > Cc: intel-...@lists.freedesktop.org > Cc: dri-devel@lists.freedesktop.org > Signed-off-by: Kees Cook > Reviewed-by: Joonas Lahtinen # for > mock_engine Reviewed-by: Joonas Lahtinen For some reason our CI didn't pick this up even though it was correctly sent to the mailing list, so I will re-send with my refreshed R-b for our CI and then we can merge this. Regards, Joonas -- Joonas Lahtinen Open Source Technology Center Intel Corporation ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[Bug 196615] amdgpu - resume from suspend is no longer working on rx480
https://bugzilla.kernel.org/show_bug.cgi?id=196615 --- Comment #27 from klavkala...@gmail.com --- Alex, I'm sorry for being pushy, but is anything being done about this? The next LTS kernel is closing in on release and suspend/resume is still not working. Linux 4.12.13 is still the last kernel with it working. If there is anything I can help with to solve this, like testing, info etc. just ask. -- You are receiving this mail because: You are watching the assignee of the bug. ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v5] drm/i915: Replace *_reference/unreference() or *_ref/unref with _get/put()
On Tue, Oct 17, 2017 at 12:15 AM, Sean Paul wrote: > On Sat, Oct 14, 2017 at 2:36 PM, Harsha Sharma > wrote: >> Replace instances of drm_framebuffer_reference/unreference() with >> *_get/put() suffixes and drm_dev_unref with *_put() suffix >> because get/put is shorter and consistent with the >> kernel use of *_get/put suffixes. >> Done with following coccinelle semantic patch >> >> @@ >> expression ex; >> @@ >> >> ( >> -drm_framebuffer_unreference(ex); >> +drm_framebuffer_put(ex); >> | >> -drm_dev_unref(ex); >> +drm_dev_put(ex); >> | >> -drm_framebuffer_reference(ex); >> +drm_framebuffer_get(ex); >> ) >> > > When I run this spatch on drm-tip, I get a bunch more changes than > this (below). Are you just running it on i915_pci? Hi, Yes you are right. But Daniel asked me to make the changes just for drm_dev_put in this patch . Sorry if I misinterpreted him. Please let me know if I need to sent another patch for all these changes. Thanks a lot. Regards, Harsha Sharma > > Sean > > > diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c > index 09d97e0990b7..2f106cca46b4 100644 > --- a/drivers/gpu/drm/i915/i915_pci.c > +++ b/drivers/gpu/drm/i915/i915_pci.c > @@ -510,7 +510,7 @@ static void i915_pci_remove(struct pci_dev *pdev) > struct drm_device *dev = pci_get_drvdata(pdev); > > i915_driver_unload(dev); > - drm_dev_unref(dev); > + drm_dev_put(dev); > } > > static int i915_pci_probe(struct pci_dev *pdev, const struct > pci_device_id *ent) > diff --git a/drivers/gpu/drm/i915/intel_display.c > b/drivers/gpu/drm/i915/intel_display.c > index 5c7828c52d12..db755b9a5efd 100644 > --- a/drivers/gpu/drm/i915/intel_display.c > +++ b/drivers/gpu/drm/i915/intel_display.c > @@ -2856,7 +2856,7 @@ intel_find_initial_plane_obj(struct intel_crtc > *intel_crtc, > > if (intel_plane_ggtt_offset(state) == plane_config->base) { > fb = c->primary->fb; > - drm_framebuffer_reference(fb); > + drm_framebuffer_get(fb); > goto valid_fb; > } > } > @@ -2887,7 +2887,7 @@ intel_find_initial_plane_obj(struct intel_crtc > *intel_crtc, > intel_crtc->pipe, PTR_ERR(intel_state->vma)); > > intel_state->vma = NULL; > - drm_framebuffer_unreference(fb); > + drm_framebuffer_put(fb); > return; > } > > @@ -2908,7 +2908,7 @@ intel_find_initial_plane_obj(struct intel_crtc > *intel_crtc, > if (i915_gem_object_is_tiled(obj)) > dev_priv->preserve_bios_swizzle = true; > > - drm_framebuffer_reference(fb); > + drm_framebuffer_get(fb); > primary->fb = primary->state->fb = fb; > primary->crtc = primary->state->crtc = &intel_crtc->base; > > @@ -9847,7 +9847,7 @@ mode_fits_in_fbdev(struct drm_device *dev, > if (obj->base.size < mode->vdisplay * fb->pitches[0]) > return NULL; > > - drm_framebuffer_reference(fb); > + drm_framebuffer_get(fb); > return fb; > #else > return NULL; > @@ -10028,7 +10028,7 @@ int intel_get_load_detect_pipe(struct > drm_connector *connector, > if (ret) > goto fail; > > - drm_framebuffer_unreference(fb); > + drm_framebuffer_put(fb); > > ret = drm_atomic_set_mode_for_crtc(&crtc_state->base, mode); > if (ret) > diff --git a/drivers/gpu/drm/i915/intel_fbdev.c > b/drivers/gpu/drm/i915/intel_fbdev.c > index 262e75c00dd2..e34334a1fbf9 100644 > --- a/drivers/gpu/drm/i915/intel_fbdev.c > +++ b/drivers/gpu/drm/i915/intel_fbdev.c > @@ -189,7 +189,7 @@ static int intelfb_create(struct drm_fb_helper *helper, > " releasing it\n", > intel_fb->base.width, intel_fb->base.height, > sizes->fb_width, sizes->fb_height); > - drm_framebuffer_unreference(&intel_fb->base); > + drm_framebuffer_put(&intel_fb->base); > intel_fb = ifbdev->fb = NULL; > } > if (!intel_fb || WARN_ON(!intel_fb->obj)) { > @@ -624,7 +624,7 @@ static bool intel_fbdev_init_bios(struct drm_device *dev, > ifbdev->preferred_bpp = fb->base.format->cpp[0] * 8; > ifbdev->fb = fb; > > - drm_framebuffer_reference(&ifbdev->fb->base); > + drm_framebuffer_get(&ifbdev->fb->base); > > /* Final pass to check if any active pipes don't have fbs */ > for_each_crtc(dev, crtc) { > diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_dmabuf.c > b/drivers/gpu/drm/i915/selftests/i915_gem_dmabuf.c > index 89dc25a5a53b..a7055b12e53c 100644 > --- a/drivers/gpu/drm/i915/selftests/i915_gem_dmabuf.c > +++ b/drivers/gpu/drm/i915/selftests/i915_gem_dmabuf.c > @@ -389,7 +389,7 @@ int i915_gem_dmabuf_mock_selftests(void) > > err = i915_subtests(tests, i915); > > - drm_dev_unref(&i915->drm); > + drm_dev_put(&i915->drm); > return err; > } > > diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_evict.c > b/drivers/gpu/drm/i915/selftests/i915_gem_evict.c > index 5ea373221f49..75764fdb90da 100644 > --- a/drivers/gpu/drm/i915/selftests/i915_gem_evict.c > +++ b/drivers/gpu/drm/i915/selftests/i915_gem_evict.c > @@ -345,6 +345,6 @@ int i915_gem_evict_mock_selftests(void) > err = i915_subtests(tests, i915); > mutex_unlock(&i915->drm.struct_mutex); > > - drm_dev_unref(&i915->drm); > + drm_dev_put(&i915->drm); >
Re: drm_kms_helper cycle detected build error in next
* Daniel Vetter [171016 02:18]: > On Mon, Oct 16, 2017 at 05:15:50PM +1000, Dave Airlie wrote: > > On 16 October 2017 at 16:53, Tomi Valkeinen wrote: > > > > > > Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. > > > Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki > > > > > > On 13/10/17 18:09, Tony Lindgren wrote: > > > > > >>> Looks like today's next build fails if omapdrm is enabled as modules > > >>> with: > > >>> > > >>> depmod: ERROR: Cycle detected: drm_kms_helper -> drm -> drm_kms_helper > > >>> depmod: ERROR: Found 2 modules in dependency cycles! > > >>> make: *** [Makefile:1261: _modinst_post] Error 1 > > >> > > >> Making CONFIG_DRM=y and CONFIG_DRM_KMS_HELPER=y instead of > > >> lodable modules makes it build. > > > > > > The same happens even after disabling omapdrm, so it's somewhere in the > > > common code. > > > > > > Interestingly, my depmod crashes when encountering this. > > > > There is a fix for this in drm-misc, I should probably pull it over. > > > > If I haven't been sent a pull tomorrow, I'll grab it. > > You're too much ahead for a pull request on your Monday, but you'll get it > asap :-) Meanwhile, can you guys provide few more clues which patch to pick for the rest of us? Something like patch subject line, commit id in drm-misc or something along those lines would be nice.. Regards, Tony ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [linux-sunxi] Re: [PATCH 5/7] drm/sun4i: backend: Offset layer buffer address by DRAM starting address
在 2017-10-16 16:00,Maxime Ripard 写道: Hi, I've applied all the other patches. On Sat, Oct 14, 2017 at 12:02:50PM +0800, Chen-Yu Tsai wrote: The display backend, as well as other peripherals that have a DRAM clock gate and access DRAM directly, bypassing the system bus, address the DRAM starting from 0x0, while physical addresses the system uses starts from 0x4000 (or 0x2000 in A80's case). Correct the address configured into the backend layer registers by PHYS_OFFSET to account for this. However, I'm a bit confused at this. The driver has been working so far, which it wouldn't have been able to if the address was wrong. How was this problem noticed, and how can that fix not be an issue in itself? On devices with <=1GiB (0x4000) DRAM, the DRAM access will just wrap back and no problem would be seen. Thanks! Maxime -- Maxime Ripard, Free Electrons Embedded Linux and Kernel engineering http://free-electrons.com ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[RFC v2 8/8] drm: mediatek: Fix drm_of_find_panel_or_bridge conversion
The port value should be 1 instead of 0; fixes DSI initialization on MT8173 "Elm". Fixes: ebc944613567 ("drm: convert drivers to use drm_of_find_panel_or_bridge") Signed-off-by: Ulrich Hecht --- drivers/gpu/drm/mediatek/mtk_dsi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c index 7e5e24c..e5ec581 100644 --- a/drivers/gpu/drm/mediatek/mtk_dsi.c +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c @@ -1105,7 +1105,7 @@ static int mtk_dsi_probe(struct platform_device *pdev) dsi->host.ops = &mtk_dsi_ops; dsi->host.dev = dev; - ret = drm_of_find_panel_or_bridge(dev->of_node, 0, 0, + ret = drm_of_find_panel_or_bridge(dev->of_node, 1, 0, &dsi->panel, &dsi->bridge); if (ret) return ret; -- 2.7.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH] of: overlay: move resolve phandles into of_overlay_apply()
On 10/16/17 13:46, Rob Herring wrote: > On Tue, Oct 10, 2017 at 8:02 PM, wrote: >> From: Frank Rowand >> >> Move more code into of_overlay_apply() so that it does not have >> to be duplicated by each caller of of_overlay_apply(). >> >> The test in of_resolve_phandles() that the overlay tree is detached is >> temporarily disabled so that old style overlay unittests do not fail. >> >> Signed-off-by: Frank Rowand >> --- >> >> This patch applies on top of the series: "[PATCH 00/12] of: overlay: clean >> up device tree overlay code". >> >> While reviewing "[PATCH 09/12] of: overlay: avoid race condition between >> applying multiple overlays", Rob asked if of_resolve_phandles() could be >> moved into of_overlay_apply(). This patch is what is involved in doing so. > > Looks fine. Can you squash this into patch 9 and resend the series (or > at least 9-12). The rest all looks fine to me. > > Rob > Thanks, I'll do that. -Frank ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 2/8] video: fbdev: au1200fb: Return an error code if a memory allocation fails
'ret' is known to be 0 at this point. In case of memory allocation error in 'framebuffer_alloc()', return -ENOMEM instead. Signed-off-by: Christophe JAILLET --- drivers/video/fbdev/au1200fb.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/video/fbdev/au1200fb.c b/drivers/video/fbdev/au1200fb.c index a5facc2ad90b..7fa41026984d 100644 --- a/drivers/video/fbdev/au1200fb.c +++ b/drivers/video/fbdev/au1200fb.c @@ -1680,8 +1680,10 @@ static int au1200fb_drv_probe(struct platform_device *dev) fbi = framebuffer_alloc(sizeof(struct au1200fb_device), &dev->dev); - if (!fbi) + if (!fbi) { + ret = -ENOMEM; goto failed; + } _au1200fb_infos[plane] = fbi; fbdev = fbi->par; -- 2.11.0 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 5/8] video: fbdev: au1200fb: Fix error handling path
Rewrite the exit path based on 'au1200fb_drv_remove()'. We can safely iterate for all already handled planes. Even if not completely initialized, the functions that are called will silently accept the 'fb_info' structure that is passed. As soon as we find a NULL in the '_au1200fb_infos' array, we know that we have released all what we needed to release. So we can 'break'. Signed-off-by: Christophe JAILLET --- drivers/video/fbdev/au1200fb.c | 12 ++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/video/fbdev/au1200fb.c b/drivers/video/fbdev/au1200fb.c index 0d8ed0ef9183..e531543bc707 100644 --- a/drivers/video/fbdev/au1200fb.c +++ b/drivers/video/fbdev/au1200fb.c @@ -1760,11 +1760,19 @@ static int au1200fb_drv_probe(struct platform_device *dev) return 0; failed: - /* NOTE: This only does the current plane/window that failed; others are still active */ - if (fbi) { + for (plane = 0; plane < device_count; ++plane) { + fbi = _au1200fb_infos[plane]; + if (!fbi) + break; + + /* Clean up all probe data */ + unregister_framebuffer(fbi); if (fbi->cmap.len != 0) fb_dealloc_cmap(&fbi->cmap); kfree(fbi->pseudo_palette); + + framebuffer_release(fbi); + _au1200fb_infos[plane] = NULL; } return ret; } -- 2.11.0 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2 09/12] of: overlay: avoid race condition between applying multiple overlays
From: Frank Rowand The process of applying an overlay consists of: - unflatten an overlay FDT (flattened device tree) into an EDT (expanded device tree) - fixup the phandle values in the overlay EDT to fit in a range above the phandle values in the live device tree - create the overlay changeset to reflect the contents of the overlay EDT - apply the overlay changeset, to modify the live device tree, potentially changing the maximum phandle value in the live device tree There is currently no protection against two overlay applies concurrently determining what range of phandle values are in use in the live device tree, and subsequently changing that range. Add a mutex to prevent multiple overlay applies from occurring simultaneously. Move of_resolve_phandles() into of_overlay_apply() so that it does not have to be duplicated by each caller of of_overlay_apply(). The test in of_resolve_phandles() that the overlay tree is detached is temporarily disabled so that old style overlay unittests do not fail. Signed-off-by: Frank Rowand --- drivers/gpu/drm/tilcdc/tilcdc_slave_compat.c | 6 -- drivers/of/of_private.h | 12 +++ drivers/of/overlay.c | 32 drivers/of/resolver.c| 7 ++ drivers/of/unittest.c| 22 +-- include/linux/of.h | 3 --- 6 files changed, 67 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/tilcdc/tilcdc_slave_compat.c b/drivers/gpu/drm/tilcdc/tilcdc_slave_compat.c index 7a7be0515bfd..54025af534d4 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_slave_compat.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_slave_compat.c @@ -145,7 +145,6 @@ static struct device_node * __init tilcdc_get_overlay(struct kfree_table *kft) __dtb_tilcdc_slave_compat_begin; static void *overlay_data; struct device_node *overlay; - int ret; if (!size) { pr_warn("%s: No overlay data\n", __func__); @@ -164,11 +163,6 @@ static struct device_node * __init tilcdc_get_overlay(struct kfree_table *kft) } of_node_set_flag(overlay, OF_DETACHED); - ret = of_resolve_phandles(overlay); - if (ret) { - pr_err("%s: Failed to resolve phandles: %d\n", __func__, ret); - return NULL; - } return overlay; } diff --git a/drivers/of/of_private.h b/drivers/of/of_private.h index b66e8a812147..03772bdbd94b 100644 --- a/drivers/of/of_private.h +++ b/drivers/of/of_private.h @@ -59,6 +59,18 @@ static inline int of_property_notify(int action, struct device_node *np, } #endif /* CONFIG_OF_DYNAMIC */ +#if defined(CONFIG_OF_RESOLVE) +int of_resolve_phandles(struct device_node *tree); +#endif + +#if defined(CONFIG_OF_OVERLAY) +void of_overlay_mutex_lock(void); +void of_overlay_mutex_unlock(void); +#else +static inline void of_overlay_mutex_lock(void) {}; +static inline void of_overlay_mutex_unlock(void) {}; +#endif + #if defined(CONFIG_OF_UNITTEST) && defined(CONFIG_OF_OVERLAY) extern void __init unittest_unflatten_overlay_base(void); #else diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c index a0d3222febdc..b1082c6f7b2c 100644 --- a/drivers/of/overlay.c +++ b/drivers/of/overlay.c @@ -71,6 +71,28 @@ static int build_changeset_next_level(struct overlay_changeset *ovcs, const struct device_node *overlay_node, bool is_symbols_node); +/* + * of_resolve_phandles() finds the largest phandle in the live tree. + * of_overlay_apply() may add a larger phandle to the live tree. + * Do not allow race between two overlays being applied simultaneously: + *mutex_lock(&of_overlay_phandle_mutex) + *of_resolve_phandles() + *of_overlay_apply() + *mutex_unlock(&of_overlay_phandle_mutex) + */ +static DEFINE_MUTEX(of_overlay_phandle_mutex); + +void of_overlay_mutex_lock(void) +{ + mutex_lock(&of_overlay_phandle_mutex); +} + +void of_overlay_mutex_unlock(void) +{ + mutex_unlock(&of_overlay_phandle_mutex); +} + + static LIST_HEAD(ovcs_list); static DEFINE_IDR(ovcs_idr); @@ -615,6 +637,12 @@ int of_overlay_apply(struct device_node *tree, int *ovcs_id) goto out; } + of_overlay_mutex_lock(); + + ret = of_resolve_phandles(tree); + if (ret) + goto err_overlay_unlock; + mutex_lock(&of_mutex); ret = init_overlay_changeset(ovcs, tree); @@ -660,9 +688,13 @@ int of_overlay_apply(struct device_node *tree, int *ovcs_id) } mutex_unlock(&of_mutex); + of_overlay_mutex_unlock(); goto out; +err_overlay_unlock: + of_overlay_mutex_unlock(); + err_free_overlay_changeset: free_overlay_changeset(ovcs); diff --git a/drivers/of/resolver.c b/drivers/of/resolver.c index 99309cb7d372..8a0f52cfe160 100644 --- a/drivers/of/resolver.c +++ b/drivers/of/re
[RFC v2 7/8] drm/mediatek: Add DRM-based framebuffer device
Add fbdev support to the Mediatek DRM driver. Signed-off-by: CK Hu Signed-off-by: YT Shen Signed-off-by: Philipp Zabel Signed-off-by: Daniel Kurtz [uli: Forward-ported from chromeos-3.18 vendor kernel.] Signed-off-by: Ulrich Hecht --- drivers/gpu/drm/mediatek/Makefile| 2 + drivers/gpu/drm/mediatek/mtk_drm_drv.c | 8 ++ drivers/gpu/drm/mediatek/mtk_drm_drv.h | 4 +- drivers/gpu/drm/mediatek/mtk_drm_fb.c| 13 +++ drivers/gpu/drm/mediatek/mtk_drm_fb.h| 3 + drivers/gpu/drm/mediatek/mtk_drm_fbdev.c | 181 +++ drivers/gpu/drm/mediatek/mtk_drm_fbdev.h | 32 ++ 7 files changed, 242 insertions(+), 1 deletion(-) create mode 100644 drivers/gpu/drm/mediatek/mtk_drm_fbdev.c create mode 100644 drivers/gpu/drm/mediatek/mtk_drm_fbdev.h diff --git a/drivers/gpu/drm/mediatek/Makefile b/drivers/gpu/drm/mediatek/Makefile index e37b55a..8306fb5 100644 --- a/drivers/gpu/drm/mediatek/Makefile +++ b/drivers/gpu/drm/mediatek/Makefile @@ -12,6 +12,8 @@ mediatek-drm-y := mtk_disp_color.o \ mtk_mipi_tx.o \ mtk_dpi.o +mediatek-drm-$(CONFIG_DRM_FBDEV_EMULATION) += mtk_drm_fbdev.o + obj-$(CONFIG_DRM_MEDIATEK) += mediatek-drm.o mediatek-drm-hdmi-objs := mtk_cec.o \ diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c index ce99921..636b8db 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c @@ -30,6 +30,7 @@ #include "mtk_drm_ddp_comp.h" #include "mtk_drm_drv.h" #include "mtk_drm_fb.h" +#include "mtk_drm_fbdev.h" #include "mtk_drm_gem.h" #define DRIVER_NAME "mediatek" @@ -257,8 +258,14 @@ static int mtk_drm_kms_init(struct drm_device *drm) drm_kms_helper_poll_init(drm); drm_mode_config_reset(drm); + ret = mtk_fbdev_init(drm); + if (ret) + goto err_kms_helper_poll_fini; + return 0; +err_kms_helper_poll_fini: + drm_kms_helper_poll_fini(drm); err_component_unbind: component_unbind_all(drm->dev, drm); err_config_cleanup: @@ -269,6 +276,7 @@ static int mtk_drm_kms_init(struct drm_device *drm) static void mtk_drm_kms_deinit(struct drm_device *drm) { + mtk_fbdev_fini(drm); drm_kms_helper_poll_fini(drm); component_unbind_all(drm->dev, drm); diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.h b/drivers/gpu/drm/mediatek/mtk_drm_drv.h index c3378c4..4edc002 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.h +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.h @@ -14,6 +14,7 @@ #ifndef MTK_DRM_DRV_H #define MTK_DRM_DRV_H +#include #include #include "mtk_drm_ddp_comp.h" @@ -24,7 +25,6 @@ struct device; struct device_node; struct drm_crtc; struct drm_device; -struct drm_fb_helper; struct drm_property; struct regmap; @@ -56,6 +56,8 @@ struct mtk_drm_private { } commit; struct drm_atomic_state *suspend_state; + struct drm_fb_helper fb_helper; + struct drm_gem_object *fbdev_bo; }; extern struct platform_driver mtk_ddp_driver; diff --git a/drivers/gpu/drm/mediatek/mtk_drm_fb.c b/drivers/gpu/drm/mediatek/mtk_drm_fb.c index 0d8d506..ac8561d 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_fb.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_fb.c @@ -96,6 +96,19 @@ static struct mtk_drm_fb *mtk_drm_framebuffer_init(struct drm_device *dev, return mtk_fb; } +struct drm_framebuffer *mtk_drm_framebuffer_create(struct drm_device *dev, + const struct drm_mode_fb_cmd2 *mode, + struct drm_gem_object *obj) +{ + struct mtk_drm_fb *mtk_fb; + + mtk_fb = mtk_drm_framebuffer_init(dev, mode, obj); + if (IS_ERR(mtk_fb)) + return ERR_CAST(mtk_fb); + + return &mtk_fb->base; +} + /* * Wait for any exclusive fence in fb's gem object's reservation object. * diff --git a/drivers/gpu/drm/mediatek/mtk_drm_fb.h b/drivers/gpu/drm/mediatek/mtk_drm_fb.h index 9b2ae34..9ee1ac2 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_fb.h +++ b/drivers/gpu/drm/mediatek/mtk_drm_fb.h @@ -19,5 +19,8 @@ int mtk_fb_wait(struct drm_framebuffer *fb); struct drm_framebuffer *mtk_drm_mode_fb_create(struct drm_device *dev, struct drm_file *file, const struct drm_mode_fb_cmd2 *cmd); +struct drm_framebuffer *mtk_drm_framebuffer_create(struct drm_device *dev, + const struct drm_mode_fb_cmd2 *mode, + struct drm_gem_object *obj); #endif /* MTK_DRM_FB_H */ diff --git a/drivers/gpu/drm/mediatek/mtk_drm_fbdev.c b/drivers/gpu/drm/mediatek/mtk_drm_fbdev.c new file mode 100644 index 000..9193647 --- /dev/null +++ b/drivers/gpu/drm/mediatek/mtk_drm_fbdev.c @@ -0,0 +1,181 @@ +/* + * Copyright (c) 2016 MediaTek Inc. + * + * 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
[RFC v2 6/8] hack: mediatek: get mmsys to register as both DRM and clock device
"mediatek,mt8173-mmsys" is the compatible string for both a clock controller and a DRM device. The assumption seems to be that all compatible strings trigger, and that mmsys will be registered as two devices. This does work in the 3.18 vendor kernel, but it is not what happens in mainline: only the clock portion is probed. This hack probes the clocks from mtk_drm_probe(), and has all drivers that need these clocks defer instead of fail. Fixes DRM initialization on Acer Chromebook R13. Signed-off-by: Ulrich Hecht --- drivers/clk/mediatek/clk-mt8173.c | 4 ++-- drivers/gpu/drm/mediatek/mtk_dpi.c | 5 +++-- drivers/gpu/drm/mediatek/mtk_drm_ddp.c | 5 +++-- drivers/gpu/drm/mediatek/mtk_drm_drv.c | 7 +++ drivers/gpu/drm/mediatek/mtk_hdmi.c| 5 +++-- 5 files changed, 18 insertions(+), 8 deletions(-) diff --git a/drivers/clk/mediatek/clk-mt8173.c b/drivers/clk/mediatek/clk-mt8173.c index 96c292c..9339d2c 100644 --- a/drivers/clk/mediatek/clk-mt8173.c +++ b/drivers/clk/mediatek/clk-mt8173.c @@ -1152,7 +1152,7 @@ static void __init mtk_imgsys_init(struct device_node *node) } CLK_OF_DECLARE(mtk_imgsys, "mediatek,mt8173-imgsys", mtk_imgsys_init); -static void __init mtk_mmsys_init(struct device_node *node) +/*static*/ void /*__init*/ mtk_mmsys_init(struct device_node *node) { struct clk_onecell_data *clk_data; int r; @@ -1167,7 +1167,7 @@ static void __init mtk_mmsys_init(struct device_node *node) pr_err("%s(): could not register clock provider: %d\n", __func__, r); } -CLK_OF_DECLARE(mtk_mmsys, "mediatek,mt8173-mmsys", mtk_mmsys_init); +//CLK_OF_DECLARE(mtk_mmsys, "mediatek,mt8173-mmsys", mtk_mmsys_init); static void __init mtk_vdecsys_init(struct device_node *node) { diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c index e80a603..ed999891 100644 --- a/drivers/gpu/drm/mediatek/mtk_dpi.c +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c @@ -682,8 +682,9 @@ static int mtk_dpi_probe(struct platform_device *pdev) dpi->engine_clk = devm_clk_get(dev, "engine"); if (IS_ERR(dpi->engine_clk)) { ret = PTR_ERR(dpi->engine_clk); - dev_err(dev, "Failed to get engine clock: %d\n", ret); - return ret; + dev_err(dev, "Failed to get engine clock: %d, deferring\n", ret); + return -EPROBE_DEFER; + //return ret; } dpi->pixel_clk = devm_clk_get(dev, "pixel"); diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp.c index 8130f3d..465ee60 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp.c @@ -382,8 +382,9 @@ static int mtk_ddp_probe(struct platform_device *pdev) ddp->clk = devm_clk_get(dev, NULL); if (IS_ERR(ddp->clk)) { - dev_err(dev, "Failed to get clock\n"); - return PTR_ERR(ddp->clk); + dev_err(dev, "Failed to get clock, deferring\n"); + return -EPROBE_DEFER; + //return PTR_ERR(ddp->clk); } regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c index a2ca90f..ce99921 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c @@ -381,6 +381,8 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = { { } }; +static int hack_mmsys_inited; +void mtk_mmsys_init(struct device_node *node); static int mtk_drm_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -391,6 +393,11 @@ static int mtk_drm_probe(struct platform_device *pdev) int ret; int i; + if (!hack_mmsys_inited) { + mtk_mmsys_init(dev->of_node); + hack_mmsys_inited = 1; + } + private = devm_kzalloc(dev, sizeof(*private), GFP_KERNEL); if (!private) return -ENOMEM; diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c b/drivers/gpu/drm/mediatek/mtk_hdmi.c index 690c675..715c0e0 100644 --- a/drivers/gpu/drm/mediatek/mtk_hdmi.c +++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c @@ -1441,8 +1441,9 @@ static int mtk_hdmi_dt_parse_pdata(struct mtk_hdmi *hdmi, ret = mtk_hdmi_get_all_clk(hdmi, np); if (ret) { - dev_err(dev, "Failed to get clocks: %d\n", ret); - return ret; + dev_err(dev, "Failed to get clocks: %d, deferring\n", ret); + return -EPROBE_DEFER; + //return ret; } /* The CEC module handles HDMI hotplug detection */ -- 2.7.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[RFC v2 4/8] drm/bridge: Analogix ANX7688 HDMI -> DP bridge driver
Ported from chromeos-3.18. Signed-off-by: Ulrich Hecht --- drivers/gpu/drm/bridge/Kconfig| 9 ++ drivers/gpu/drm/bridge/Makefile | 1 + drivers/gpu/drm/bridge/analogix-anx7688.c | 233 ++ 3 files changed, 243 insertions(+) create mode 100644 drivers/gpu/drm/bridge/analogix-anx7688.c diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig index a1c0d95..712ac0a 100644 --- a/drivers/gpu/drm/bridge/Kconfig +++ b/drivers/gpu/drm/bridge/Kconfig @@ -38,6 +38,15 @@ config DRM_PARADE_PS8640 The PS8640 is a high-performance and low-power MIPI DSI to eDP converter +config DRM_ANALOGIX_ANX7688 + tristate "Analogix ANX7688 bridge" + depends on DRM + select DRM_KMS_HELPER + ---help--- + ANX7688 is a transmitter to support DisplayPort over USB-C for + smartphone and tablets. + This driver only supports the HDMI to DP component of the chip. + config DRM_ANALOGIX_ANX78XX tristate "Analogix ANX78XX bridge" select DRM_KMS_HELPER diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile index 6be8a9d..9cbf788 100644 --- a/drivers/gpu/drm/bridge/Makefile +++ b/drivers/gpu/drm/bridge/Makefile @@ -1,6 +1,7 @@ ccflags-y := -Iinclude/drm obj-$(CONFIG_DRM_PARADE_PS8640) += parade-ps8640.o +obj-$(CONFIG_DRM_ANALOGIX_ANX7688) += analogix-anx7688.o obj-$(CONFIG_DRM_ANALOGIX_ANX78XX) += analogix-anx78xx.o obj-$(CONFIG_DRM_GENERIC_GPIO_MUX) += generic-gpio-mux.o obj-$(CONFIG_DRM_DUMB_VGA_DAC) += dumb-vga-dac.o diff --git a/drivers/gpu/drm/bridge/analogix-anx7688.c b/drivers/gpu/drm/bridge/analogix-anx7688.c new file mode 100644 index 000..cc995c8 --- /dev/null +++ b/drivers/gpu/drm/bridge/analogix-anx7688.c @@ -0,0 +1,233 @@ +/* + * ANX7688 HDMI->DP bridge driver + * + * Copyright (C) 2016 Google, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include + +/* Register addresses */ +#define VENDOR_ID_REG 0x00 +#define DEVICE_ID_REG 0x02 + +#define FW_VERSION_REG 0x80 + +#define DP_BANDWIDTH_REG 0x85 +#define DP_LANE_COUNT_REG 0x86 + +#define VENDOR_ID 0x1f29 +#define DEVICE_ID 0x7688 + +/* First supported firmware version (0.85) */ +#define MINIMUM_FW_VERSION 0x0085 + +struct anx7688 { + struct drm_bridge bridge; + struct i2c_client *client; + + bool filter; +}; + +static int anx7688_read(struct i2c_client *client, u8 reg, u8 *data, + u16 data_len) +{ + int ret; + struct i2c_msg msgs[] = { + { +.addr = client->addr, +.flags = 0, +.len = 1, +.buf = ®, +}, + { +.addr = client->addr, +.flags = I2C_M_RD, +.len = data_len, +.buf = data, +} + }; + + ret = i2c_transfer(client->adapter, msgs, 2); + + if (ret == 2) + return 0; + if (ret < 0) + return ret; + else + return -EIO; +} + +static inline struct anx7688 *bridge_to_anx7688(struct drm_bridge *bridge) +{ + return container_of(bridge, struct anx7688, bridge); +} + +static bool anx7688_bridge_mode_fixup(struct drm_bridge *bridge, + const struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode) +{ + struct anx7688 *anx7688 = bridge_to_anx7688(bridge); + u8 regs[2]; + u8 dpbw, lanecount; + int totalbw, requiredbw; + int ret; + + if (!anx7688->filter) + return true; + + /* Read both regs 0x85 (bandwidth) and 0x86 (lane count). */ + ret = anx7688_read(anx7688->client, DP_BANDWIDTH_REG, regs, 2); + if (ret < 0) { + dev_err(&anx7688->client->dev, + "Failed to read bandwidth/lane count\n"); + return false; + } + dpbw = regs[0]; + lanecount = regs[1]; + + /* Maximum 0x19 bandwidth (6.75 Gbps Turbo mode), 2 lanes */ + if (dpbw > 0x19 || lanecount > 2) { + dev_err(&anx7688->client->dev, + "Invalid bandwidth/lane count (%02x/%d)\n", + dpbw, lanecount); + return false; + } + + /* Compute available bandwidth (kHz) */ + totalbw = dpbw * lanecount * 27 * 8 / 10; + + /* Required bandwidth (8 bpc, kHz) */ + requiredbw =
[PATCH 150/156] drm/etnaviv: Convert timers to use timer_setup()
In preparation for unconditionally passing the struct timer_list pointer to all timer callbacks, switch to using the new timer_setup() and from_timer() to pass the timer pointer explicitly. Cc: Lucas Stach Cc: Russell King Cc: Christian Gmeiner Cc: David Airlie Cc: etna...@lists.freedesktop.org Cc: dri-devel@lists.freedesktop.org Signed-off-by: Kees Cook --- drivers/gpu/drm/etnaviv/etnaviv_gpu.c | 7 +++ 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c index 8197e1d6ed11..e19cbe05da2a 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c @@ -968,9 +968,9 @@ static void hangcheck_timer_reset(struct etnaviv_gpu *gpu) round_jiffies_up(jiffies + DRM_ETNAVIV_HANGCHECK_JIFFIES)); } -static void hangcheck_handler(unsigned long data) +static void hangcheck_handler(struct timer_list *t) { - struct etnaviv_gpu *gpu = (struct etnaviv_gpu *)data; + struct etnaviv_gpu *gpu = from_timer(gpu, t, hangcheck_timer); u32 fence = gpu->completed_fence; bool progress = false; @@ -1765,8 +1765,7 @@ static int etnaviv_gpu_bind(struct device *dev, struct device *master, INIT_WORK(&gpu->recover_work, recover_worker); init_waitqueue_head(&gpu->fence_event); - setup_deferrable_timer(&gpu->hangcheck_timer, hangcheck_handler, - (unsigned long)gpu); + timer_setup(&gpu->hangcheck_timer, hangcheck_handler, TIMER_DEFERRABLE); priv->gpu[priv->num_gpus++] = gpu; -- 2.7.4 -- Kees Cook Pixel Security ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2 06/12] of: overlay: detect cases where device tree may become corrupt
From: Frank Rowand When an attempt to apply an overlay changeset fails, an effort is made to revert any partial application of the changeset. When an attempt to remove an overlay changeset fails, an effort is made to re-apply any partial reversion of the changeset. The existing code does not check for failure to recover a failed overlay changeset application or overlay changeset revert. Add the missing checks and flag the devicetree as corrupt if the state of the devicetree can not be determined. Improve and expand the returned errors to more fully reflect the result of the effort to undo the partial effects of a failed attempt to apply or remove an overlay changeset. If the device tree might be corrupt, do not allow further attempts to apply or remove an overlay changeset. When creating an overlay changeset from an overlay device tree, add some additional warnings if the state of the overlay device tree is not as expected. Signed-off-by: Frank Rowand --- drivers/gpu/drm/tilcdc/tilcdc_slave_compat.c | 5 +- drivers/of/dynamic.c | 135 +++--- drivers/of/of_private.h | 8 +- drivers/of/overlay.c | 253 ++- drivers/of/unittest.c| 57 +++--- include/linux/of.h | 10 +- 6 files changed, 372 insertions(+), 96 deletions(-) diff --git a/drivers/gpu/drm/tilcdc/tilcdc_slave_compat.c b/drivers/gpu/drm/tilcdc/tilcdc_slave_compat.c index 5f5b7ba35f1d..7a7be0515bfd 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_slave_compat.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_slave_compat.c @@ -204,7 +204,7 @@ static void __init tilcdc_convert_slave_node(void) /* For all memory needed for the overlay tree. This memory can be freed after the overlay has been applied. */ struct kfree_table kft; - int ret; + int ovcs_id, ret; if (kfree_table_init(&kft)) return; @@ -247,7 +247,8 @@ static void __init tilcdc_convert_slave_node(void) tilcdc_node_disable(slave); - ret = of_overlay_apply(overlay); + ovcs_id = 0; + ret = of_overlay_apply(overlay, &ovcs_id); if (ret) pr_err("%s: Applying overlay changeset failed: %d\n", __func__, ret); diff --git a/drivers/of/dynamic.c b/drivers/of/dynamic.c index 124510d56421..c1026efd6f9e 100644 --- a/drivers/of/dynamic.c +++ b/drivers/of/dynamic.c @@ -508,11 +508,12 @@ static void __of_changeset_entry_invert(struct of_changeset_entry *ce, } } -static void __of_changeset_entry_notify(struct of_changeset_entry *ce, bool revert) +static int __of_changeset_entry_notify(struct of_changeset_entry *ce, + bool revert) { struct of_reconfig_data rd; struct of_changeset_entry ce_inverted; - int ret; + int ret = 0; if (revert) { __of_changeset_entry_invert(ce, &ce_inverted); @@ -534,11 +535,12 @@ static void __of_changeset_entry_notify(struct of_changeset_entry *ce, bool reve default: pr_err("invalid devicetree changeset action: %i\n", (int)ce->action); - return; + ret = -EINVAL; } if (ret) pr_err("changeset notifier error @%pOF\n", ce->np); + return ret; } static int __of_changeset_entry_apply(struct of_changeset_entry *ce) @@ -672,32 +674,82 @@ void of_changeset_destroy(struct of_changeset *ocs) } EXPORT_SYMBOL_GPL(of_changeset_destroy); -int __of_changeset_apply(struct of_changeset *ocs) +/* + * Apply the changeset entries in @ocs. + * If apply fails, an attempt is made to revert the entries that were + * successfully applied. + * + * If multiple revert errors occur then only the final revert error is reported. + * + * Returns 0 on success, a negative error value in case of an error. + * If a revert error occurs, it is returned in *ret_revert. + */ +int __of_changeset_apply_entries(struct of_changeset *ocs, int *ret_revert) { struct of_changeset_entry *ce; - int ret; + int ret, ret_tmp; - /* perform the rest of the work */ pr_debug("changeset: applying...\n"); list_for_each_entry(ce, &ocs->entries, node) { ret = __of_changeset_entry_apply(ce); if (ret) { pr_err("Error applying changeset (%d)\n", ret); - list_for_each_entry_continue_reverse(ce, &ocs->entries, node) - __of_changeset_entry_revert(ce); + list_for_each_entry_continue_reverse(ce, &ocs->entries, +node) { + ret_tmp = __of_changeset_entry_revert(ce); + if (ret_tmp) + *ret_revert = ret_tmp; + }
[RFC v2 0/8] Acer Chromebook R13 support
Hi! This is a new revision of the Acer Chromebook R13 support series. It does not offer anything new in terms of functionality, but eliminates three out of four ugly hacks and adds a few minor cleanups; see below for details. Thanks to Robin Murphy and CK Hu for their comments and suggestions! I'm still looking for advice on how to implement the dual-role mmsys device correctly; see "hack: mediatek: get mmsys to register as both DRM and clock device" for details on this. Like the previous revision, you can find this series at https://github.com/uli/kernel/tree/elm-working, which also contains a config file and several ancillary bits that are required to build a kernel partition for the Chromebook. Instructions on how to do so (and various other things that have to be done to get it running on your device) are available at https://www.elinux.org/User:Uli/Acer_Chromebook_R13_GPU_test_system (These instructions have been written for the vendor kernel, but apply to mainline as well, except that you won't need any extra patches.) CU Uli Changes since RFC v1: - cmdq: remove obsolete driver; not currently used anyway - dt: remove CD GPIO from mmc1, does not seem to be correct - mmc: remove mtk-sd.c revert hack (works fine without the CD pin) - dsi: fix port number for drm_of_find_panel_or_bridge(), remove hack - fbdev: add missing Signed-off-bys - iommu: remove io-pgtable sanity check hack, has been properly fixed - minor style fixes Ulrich Hecht (8): drm/bridge: GPIO-controlled display multiplexer driver platform/chrome: ChromeOS firmware interface driver drm/bridge: Parade PS8640 MIPI DSI -> eDP converter driver drm/bridge: Analogix ANX7688 HDMI -> DP bridge driver arm64: dts: mediatek: Add Elm Rev. 3 device tree hack: mediatek: get mmsys to register as both DRM and clock device drm/mediatek: Add DRM-based framebuffer device drm: mediatek: Fix drm_of_find_panel_or_bridge conversion arch/arm64/boot/dts/mediatek/Makefile|1 + arch/arm64/boot/dts/mediatek/mt8173-elm-rev3.dts | 21 + arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi | 210 arch/arm64/boot/dts/mediatek/mt8173-oak.dtsi | 1013 drivers/clk/mediatek/clk-mt8173.c|4 +- drivers/gpu/drm/bridge/Kconfig | 32 + drivers/gpu/drm/bridge/Makefile |5 + drivers/gpu/drm/bridge/analogix-anx7688.c| 233 + drivers/gpu/drm/bridge/generic-gpio-mux.c| 316 +++ drivers/gpu/drm/bridge/parade-ps8640.c | 1104 ++ drivers/gpu/drm/mediatek/Makefile|2 + drivers/gpu/drm/mediatek/mtk_dpi.c |5 +- drivers/gpu/drm/mediatek/mtk_drm_ddp.c |5 +- drivers/gpu/drm/mediatek/mtk_drm_drv.c | 15 + drivers/gpu/drm/mediatek/mtk_drm_drv.h |4 +- drivers/gpu/drm/mediatek/mtk_drm_fb.c| 13 + drivers/gpu/drm/mediatek/mtk_drm_fb.h|3 + drivers/gpu/drm/mediatek/mtk_drm_fbdev.c | 181 drivers/gpu/drm/mediatek/mtk_drm_fbdev.h | 32 + drivers/gpu/drm/mediatek/mtk_dsi.c |2 +- drivers/gpu/drm/mediatek/mtk_hdmi.c |5 +- drivers/platform/chrome/Kconfig | 18 + drivers/platform/chrome/Makefile |2 + drivers/platform/chrome/chromeos.c | 120 +++ drivers/platform/chrome/chromeos.h | 61 ++ drivers/platform/chrome/chromeos_arm.c | 264 ++ drivers/platform/chrome/elog.h | 186 include/linux/chromeos_platform.h| 27 + 28 files changed, 3874 insertions(+), 10 deletions(-) create mode 100644 arch/arm64/boot/dts/mediatek/mt8173-elm-rev3.dts create mode 100644 arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi create mode 100644 arch/arm64/boot/dts/mediatek/mt8173-oak.dtsi create mode 100644 drivers/gpu/drm/bridge/analogix-anx7688.c create mode 100644 drivers/gpu/drm/bridge/generic-gpio-mux.c create mode 100644 drivers/gpu/drm/bridge/parade-ps8640.c create mode 100644 drivers/gpu/drm/mediatek/mtk_drm_fbdev.c create mode 100644 drivers/gpu/drm/mediatek/mtk_drm_fbdev.h create mode 100644 drivers/platform/chrome/chromeos.c create mode 100644 drivers/platform/chrome/chromeos.h create mode 100644 drivers/platform/chrome/chromeos_arm.c create mode 100644 drivers/platform/chrome/elog.h create mode 100644 include/linux/chromeos_platform.h -- 2.7.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 7/8] video: fbdev: au1200fb: Propagate an error code
We should propagate the error code returned by 'fb_alloc_cmap()' instead of returning -EFAULT. Signed-off-by: Christophe JAILLET --- drivers/video/fbdev/au1200fb.c | 7 --- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/video/fbdev/au1200fb.c b/drivers/video/fbdev/au1200fb.c index 970ce761ff89..687ea2a8f810 100644 --- a/drivers/video/fbdev/au1200fb.c +++ b/drivers/video/fbdev/au1200fb.c @@ -1518,7 +1518,7 @@ static irqreturn_t au1200fb_handle_irq(int irq, void* dev_id) static int au1200fb_init_fbinfo(struct au1200fb_device *fbdev) { struct fb_info *fbi = fbdev->fb_info; - int bpp; + int bpp, ret; fbi->fbops = &au1200fb_fb_ops; @@ -1550,10 +1550,11 @@ static int au1200fb_init_fbinfo(struct au1200fb_device *fbdev) return -ENOMEM; } - if (fb_alloc_cmap(&fbi->cmap, AU1200_LCD_NBR_PALETTE_ENTRIES, 0) < 0) { + ret = fb_alloc_cmap(&fbi->cmap, AU1200_LCD_NBR_PALETTE_ENTRIES, 0); + if (ret < 0) { print_err("Fail to allocate colormap (%d entries)", AU1200_LCD_NBR_PALETTE_ENTRIES); - return -EFAULT; + return ret; } strncpy(fbi->fix.id, "AU1200", sizeof(fbi->fix.id)); -- 2.11.0 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH] drm/i915: Convert timers to use timer_setup()
In preparation for unconditionally passing the struct timer_list pointer to all timer callbacks, switch to using the new timer_setup() and from_timer() to pass the timer pointer explicitly. Cc: Daniel Vetter Cc: Jani Nikula Cc: David Airlie Cc: Chris Wilson Cc: Joonas Lahtinen Cc: Tvrtko Ursulin Cc: Oscar Mateo Cc: intel-...@lists.freedesktop.org Cc: dri-devel@lists.freedesktop.org Signed-off-by: Kees Cook Reviewed-by: Joonas Lahtinen # for mock_engine --- This patch includes additional timers since the last time it was sent. --- drivers/gpu/drm/i915/i915_sw_fence.c | 8 +++- drivers/gpu/drm/i915/intel_breadcrumbs.c | 18 -- drivers/gpu/drm/i915/selftests/mock_engine.c | 8 +++- 3 files changed, 14 insertions(+), 20 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_sw_fence.c b/drivers/gpu/drm/i915/i915_sw_fence.c index ca33cc08cb07..e8ca67a129d2 100644 --- a/drivers/gpu/drm/i915/i915_sw_fence.c +++ b/drivers/gpu/drm/i915/i915_sw_fence.c @@ -369,9 +369,9 @@ struct i915_sw_dma_fence_cb { struct irq_work work; }; -static void timer_i915_sw_fence_wake(unsigned long data) +static void timer_i915_sw_fence_wake(struct timer_list *t) { - struct i915_sw_dma_fence_cb *cb = (struct i915_sw_dma_fence_cb *)data; + struct i915_sw_dma_fence_cb *cb = from_timer(cb, t, timer); struct i915_sw_fence *fence; fence = xchg(&cb->fence, NULL); @@ -434,9 +434,7 @@ int i915_sw_fence_await_dma_fence(struct i915_sw_fence *fence, i915_sw_fence_await(fence); cb->dma = NULL; - __setup_timer(&cb->timer, - timer_i915_sw_fence_wake, (unsigned long)cb, - TIMER_IRQSAFE); + timer_setup(&cb->timer, timer_i915_sw_fence_wake, TIMER_IRQSAFE); init_irq_work(&cb->work, irq_i915_sw_fence_work); if (timeout) { cb->dma = dma_fence_get(dma); diff --git a/drivers/gpu/drm/i915/intel_breadcrumbs.c b/drivers/gpu/drm/i915/intel_breadcrumbs.c index 29c62d481cef..48e1ba01ccf8 100644 --- a/drivers/gpu/drm/i915/intel_breadcrumbs.c +++ b/drivers/gpu/drm/i915/intel_breadcrumbs.c @@ -74,9 +74,10 @@ static noinline void missed_breadcrumb(struct intel_engine_cs *engine) set_bit(engine->id, &engine->i915->gpu_error.missed_irq_rings); } -static void intel_breadcrumbs_hangcheck(unsigned long data) +static void intel_breadcrumbs_hangcheck(struct timer_list *t) { - struct intel_engine_cs *engine = (struct intel_engine_cs *)data; + struct intel_engine_cs *engine = from_timer(engine, t, + breadcrumbs.hangcheck); struct intel_breadcrumbs *b = &engine->breadcrumbs; if (!b->irq_armed) @@ -108,9 +109,10 @@ static void intel_breadcrumbs_hangcheck(unsigned long data) } } -static void intel_breadcrumbs_fake_irq(unsigned long data) +static void intel_breadcrumbs_fake_irq(struct timer_list *t) { - struct intel_engine_cs *engine = (struct intel_engine_cs *)data; + struct intel_engine_cs *engine = from_timer(engine, t, + breadcrumbs.fake_irq); struct intel_breadcrumbs *b = &engine->breadcrumbs; /* The timer persists in case we cannot enable interrupts, @@ -787,12 +789,8 @@ int intel_engine_init_breadcrumbs(struct intel_engine_cs *engine) spin_lock_init(&b->rb_lock); spin_lock_init(&b->irq_lock); - setup_timer(&b->fake_irq, - intel_breadcrumbs_fake_irq, - (unsigned long)engine); - setup_timer(&b->hangcheck, - intel_breadcrumbs_hangcheck, - (unsigned long)engine); + timer_setup(&b->fake_irq, intel_breadcrumbs_fake_irq, 0); + timer_setup(&b->hangcheck, intel_breadcrumbs_hangcheck, 0); /* Spawn a thread to provide a common bottom-half for all signals. * As this is an asynchronous interface we cannot steal the current diff --git a/drivers/gpu/drm/i915/selftests/mock_engine.c b/drivers/gpu/drm/i915/selftests/mock_engine.c index fc0fd7498689..331c2b09869e 100644 --- a/drivers/gpu/drm/i915/selftests/mock_engine.c +++ b/drivers/gpu/drm/i915/selftests/mock_engine.c @@ -32,9 +32,9 @@ static struct mock_request *first_request(struct mock_engine *engine) link); } -static void hw_delay_complete(unsigned long data) +static void hw_delay_complete(struct timer_list *t) { - struct mock_engine *engine = (typeof(engine))data; + struct mock_engine *engine = from_timer(engine, t, hw_delay); struct mock_request *request; spin_lock(&engine->hw_lock); @@ -161,9 +161,7 @@ struct intel_engine_cs *mock_engine(struct drm_i915_private *i915, /* fake hw queue */ spin_lock_init(&engine->hw_lock); - setup_timer(&engine->hw_delay, - hw_delay_complete, - (unsigned long)engin
[PATCH 4/8] video: fbdev: au1200fb: Fix error handling path
'au1200fb_drv_probe()' can not fail after a succesful call to 'request_irq()'. So there is no point to call 'free_irq()' in the error handling path. Moreover, the hard coded AU1200_LCD_INT looks boggus since commit 1630d85a8312 ("au1200fb: fix hardcoded IRQ") So, remove it. Signed-off-by: Christophe JAILLET --- drivers/video/fbdev/au1200fb.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/video/fbdev/au1200fb.c b/drivers/video/fbdev/au1200fb.c index cf54168d44dc..0d8ed0ef9183 100644 --- a/drivers/video/fbdev/au1200fb.c +++ b/drivers/video/fbdev/au1200fb.c @@ -1766,8 +1766,6 @@ static int au1200fb_drv_probe(struct platform_device *dev) fb_dealloc_cmap(&fbi->cmap); kfree(fbi->pseudo_palette); } - if (plane == 0) - free_irq(AU1200_LCD_INT, (void*)dev); return ret; } -- 2.11.0 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 6/8] video: fbdev: au1200fb: Remove some dead code
There is no need to shut gcc up. It should not complain. Axe 'fbdev', it is never used in this function. Signed-off-by: Christophe JAILLET --- drivers/video/fbdev/au1200fb.c | 6 -- 1 file changed, 6 deletions(-) diff --git a/drivers/video/fbdev/au1200fb.c b/drivers/video/fbdev/au1200fb.c index e531543bc707..970ce761ff89 100644 --- a/drivers/video/fbdev/au1200fb.c +++ b/drivers/video/fbdev/au1200fb.c @@ -1667,10 +1667,6 @@ static int au1200fb_drv_probe(struct platform_device *dev) printk(DRIVER_NAME ": Panel %d %s\n", panel_index, panel->name); printk(DRIVER_NAME ": Win %d %s\n", window_index, win->name); - /* shut gcc up */ - ret = 0; - fbdev = NULL; - for (plane = 0; plane < device_count; ++plane) { bpp = winbpp(win->w[plane].mode_winctrl1); if (win->w[plane].xres == 0) @@ -1780,7 +1776,6 @@ static int au1200fb_drv_probe(struct platform_device *dev) static int au1200fb_drv_remove(struct platform_device *dev) { struct au1200fb_platdata *pd = platform_get_drvdata(dev); - struct au1200fb_device *fbdev; struct fb_info *fbi; int plane; @@ -1789,7 +1784,6 @@ static int au1200fb_drv_remove(struct platform_device *dev) for (plane = 0; plane < device_count; ++plane) { fbi = _au1200fb_infos[plane]; - fbdev = fbi->par; /* Clean up all probe data */ unregister_framebuffer(fbi); -- 2.11.0 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[RFC v2 2/8] platform/chrome: ChromeOS firmware interface driver
Ported from chromeos-3.18 kernel. Signed-off-by: Ulrich Hecht --- drivers/platform/chrome/Kconfig| 18 +++ drivers/platform/chrome/Makefile | 2 + drivers/platform/chrome/chromeos.c | 120 +++ drivers/platform/chrome/chromeos.h | 61 drivers/platform/chrome/chromeos_arm.c | 264 + drivers/platform/chrome/elog.h | 186 +++ include/linux/chromeos_platform.h | 27 7 files changed, 678 insertions(+) create mode 100644 drivers/platform/chrome/chromeos.c create mode 100644 drivers/platform/chrome/chromeos.h create mode 100644 drivers/platform/chrome/chromeos_arm.c create mode 100644 drivers/platform/chrome/elog.h create mode 100644 include/linux/chromeos_platform.h diff --git a/drivers/platform/chrome/Kconfig b/drivers/platform/chrome/Kconfig index 0ad6e29..f8b1876 100644 --- a/drivers/platform/chrome/Kconfig +++ b/drivers/platform/chrome/Kconfig @@ -14,6 +14,24 @@ menuconfig CHROME_PLATFORMS if CHROME_PLATFORMS +config CHROMEOS + bool + depends on CHROMEOS_OF_FIRMWARE || (NVRAM && ACPI_CHROMEOS) + + ---help--- + Provides abstracted interfaces to the firmware features provided on + ChromeOS devices. It depends on a lowlevel driver to implement the + firmware interface on the platform. + +config CHROMEOS_OF_FIRMWARE + bool "ChromeOS firmware interface driver" + depends on OF + select CHROMEOS + ---help--- + This driver provides an interface to ChromeOS firmware. + + Say Y here if you are building for a ChromeOS device. + config CHROMEOS_LAPTOP tristate "Chrome OS Laptop" depends on I2C && DMI && X86 diff --git a/drivers/platform/chrome/Makefile b/drivers/platform/chrome/Makefile index 66c345c..f10a7b6 100644 --- a/drivers/platform/chrome/Makefile +++ b/drivers/platform/chrome/Makefile @@ -1,4 +1,6 @@ +obj-$(CONFIG_CHROMEOS) += chromeos.o +obj-$(CONFIG_CHROMEOS_OF_FIRMWARE) += chromeos_arm.o obj-$(CONFIG_CHROMEOS_LAPTOP) += chromeos_laptop.o obj-$(CONFIG_CHROMEOS_PSTORE) += chromeos_pstore.o cros_ec_devs-objs := cros_ec_dev.o cros_ec_sysfs.o \ diff --git a/drivers/platform/chrome/chromeos.c b/drivers/platform/chrome/chromeos.c new file mode 100644 index 000..8b01630 --- /dev/null +++ b/drivers/platform/chrome/chromeos.c @@ -0,0 +1,120 @@ +/* + * ChromeOS platform support code. Glue layer between higher level functions + * and per-platform firmware interfaces. + * + * Copyright (C) 2010 The Chromium OS Authors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include "chromeos.h" + +static struct chromeos_vbc *chromeos_vbc_ptr; + +static int vbc_read(u8 *buf, int buf_size); +static int vbc_write_byte(unsigned offset, u8 value); + +/* the following defines are copied from + * vboot_reference:firmware/lib/vboot_nvstorage.c. + */ +#define RECOVERY_OFFSET 2 +#define VBNV_RECOVERY_RW_INVALID_OS 0x43 + +int chromeos_set_need_recovery(void) +{ + if (!chromeos_legacy_set_need_recovery()) + return 0; + + return vbc_write_byte(RECOVERY_OFFSET, VBNV_RECOVERY_RW_INVALID_OS); +} +EXPORT_SYMBOL(chromeos_set_need_recovery); + +/* + * Lifted from vboot_reference:firmware/lib/vboot_nvstorage.c and formatted. + * + * Return CRC-8 of the data, using x^8 + x^2 + x + 1 polynomial. A table-based + * algorithm would be faster, but for only 15 bytes isn't worth the code size. + */ +static u8 crc8(const u8 *data, int len) +{ + unsigned crc = 0; + int i, j; + + for (j = len; j; j--, data++) { + crc ^= (*data << 8); + for (i = 8; i; i--) { + if (crc & 0x8000) + crc ^= (0x1070 << 3); + crc <<= 1; + } + } + return (u8)(crc >> 8); +} + +static int vbc_write_byte(unsigned offset, u8 value) +{ + u8 buf[MAX_VBOOT_CONTEXT_BUFFER_SIZE]; + ssize_t size; + + if (!chromeos_vbc_ptr) + return -ENOSYS; + + size = vbc_read(buf, sizeof(buf)); + if (size <= 0) + return -EINVAL; + + if (offset >= (size - 1)) +
[RFC v2 5/8] arm64: dts: mediatek: Add Elm Rev. 3 device tree
Signed-off-by: Ulrich Hecht --- arch/arm64/boot/dts/mediatek/Makefile|1 + arch/arm64/boot/dts/mediatek/mt8173-elm-rev3.dts | 21 + arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi | 210 + arch/arm64/boot/dts/mediatek/mt8173-oak.dtsi | 1013 ++ 4 files changed, 1245 insertions(+) create mode 100644 arch/arm64/boot/dts/mediatek/mt8173-elm-rev3.dts create mode 100644 arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi create mode 100644 arch/arm64/boot/dts/mediatek/mt8173-oak.dtsi diff --git a/arch/arm64/boot/dts/mediatek/Makefile b/arch/arm64/boot/dts/mediatek/Makefile index 151723b..0521e29 100644 --- a/arch/arm64/boot/dts/mediatek/Makefile +++ b/arch/arm64/boot/dts/mediatek/Makefile @@ -4,6 +4,7 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += mt6795-evb.dtb dtb-$(CONFIG_ARCH_MEDIATEK) += mt6797-evb.dtb dtb-$(CONFIG_ARCH_MEDIATEK) += mt7622-rfb1.dtb dtb-$(CONFIG_ARCH_MEDIATEK) += mt8173-evb.dtb +dtb-$(CONFIG_ARCH_MEDIATEK) += mt8173-elm-rev3.dtb always := $(dtb-y) subdir-y := $(dts-dirs) diff --git a/arch/arm64/boot/dts/mediatek/mt8173-elm-rev3.dts b/arch/arm64/boot/dts/mediatek/mt8173-elm-rev3.dts new file mode 100644 index 000..68d4095 --- /dev/null +++ b/arch/arm64/boot/dts/mediatek/mt8173-elm-rev3.dts @@ -0,0 +1,21 @@ +/* + * Copyright 2016 MediaTek Inc. + * Author: Eddie Huang + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/dts-v1/; +#include "mt8173-elm.dtsi" + +/ { + model = "Mediatek Elm rev3 board"; + compatible = "google,elm-rev3", "google,elm", "mediatek,mt8173"; +}; diff --git a/arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi b/arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi new file mode 100644 index 000..850037f --- /dev/null +++ b/arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi @@ -0,0 +1,210 @@ +/* + * Copyright 2016 MediaTek Inc. + * Author: Eddie Huang + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include "mt8173-oak.dtsi" + +/ { + hdmicon: connector { + compatible = "hdmi-connector"; + label = "hdmi"; + type = "a"; + + port { + hdmi_connector_in: endpoint { + remote-endpoint = <&hdmi_mux_out_hdmi>; + }; + }; + }; + + hdmi_mux: hdmi_mux { + compatible = "gpio-display-mux"; + status = "okay"; + detect-gpios = <&pio 36 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&hdmi_mux_pins>; + ddc-i2c-bus = <&hdmiddc0>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { /* input */ + reg = <0>; + + hdmi_mux_in: endpoint { + remote-endpoint = <&hdmi0_out>; + }; + }; + + port@1 { /* output */ + reg = <1>; + + #address-cells = <1>; + #size-cells = <0>; + + hdmi_mux_out_anx: endpoint@0 { + reg = <0>; + remote-endpoint = <&anx7688_in>; + }; + + hdmi_mux_out_hdmi: endpoint@1 { + reg = <1>; + remote-endpoint = <&hdmi_connector_in>; + }; + }; + }; + }; + + sound: sound { + compatible = "mediatek,mt8173-rt5650"; + mediatek,audio-codec = <&rt5650 &hdmi0>; + mediatek,mclk = <1>; + mediatek,platform = <&afe>; + pinctrl-names = "default"; + pinctrl-0 = <&aud_i2s2>; + codec-capture { + sound-dai = <&rt5650 1>; + }; + }; +}; + +&aud_i2s2 { + pins1 { + pinmux =
[PATCH v2 11/12] of: overlay: remove a dependency on device node full_name
From: Frank Rowand The "%pOF" printf format was recently added to print the full name of a device tree node, with the intent of changing the node full_name field to contain only the node name instead of the full path of the node. dup_and_fixup_symbol_prop() duplicates a property from the "/__symbols__" node of an overlay device tree. The value of each duplicated property must be fixed up to include the full path of a node in the live device tree. The current code uses the node's full_name for that purpose. Update the code to use the "%pOF" printf format to determine the node's full path. Signed-off-by: Frank Rowand --- drivers/of/base.c | 2 +- drivers/of/of_private.h | 2 ++ drivers/of/overlay.c| 90 ++--- 3 files changed, 59 insertions(+), 35 deletions(-) diff --git a/drivers/of/base.c b/drivers/of/base.c index 260d33c0f26c..6f91fa67e5bb 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -760,7 +760,7 @@ struct device_node *of_get_child_by_name(const struct device_node *node, } EXPORT_SYMBOL(of_get_child_by_name); -static struct device_node *__of_find_node_by_path(struct device_node *parent, +struct device_node *__of_find_node_by_path(struct device_node *parent, const char *path) { struct device_node *child; diff --git a/drivers/of/of_private.h b/drivers/of/of_private.h index 03772bdbd94b..267edb1b50df 100644 --- a/drivers/of/of_private.h +++ b/drivers/of/of_private.h @@ -93,6 +93,8 @@ extern void *__unflatten_device_tree(const void *blob, struct property *__of_prop_dup(const struct property *prop, gfp_t allocflags); __printf(2, 3) struct device_node *__of_node_dup(const struct device_node *np, const char *fmt, ...); +struct device_node *__of_find_node_by_path(struct device_node *parent, + const char *path); struct device_node *__of_find_node_by_full_path(struct device_node *node, const char *path); diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c index 912c222ff011..a257474c9223 100644 --- a/drivers/of/overlay.c +++ b/drivers/of/overlay.c @@ -37,6 +37,7 @@ struct fragment { /** * struct overlay_changeset * @ovcs_list: list on which we are located + * @overlay_tree: expanded device tree that contains the fragment nodes * @count: count of fragment structures * @fragments: fragment nodes in the overlay expanded device tree * @symbols_fragment: last element of @fragments[] is the __symbols__ node @@ -45,6 +46,7 @@ struct fragment { struct overlay_changeset { int id; struct list_head ovcs_list; + struct device_node *overlay_tree; int count; struct fragment *fragments; bool symbols_fragment; @@ -145,12 +147,13 @@ static int overlay_notify(struct overlay_changeset *ovcs, } /* - * The properties in the "/__symbols__" node are "symbols". + * The values of properties in the "/__symbols__" node are paths in + * the ovcs->overlay_tree. When duplicating the properties, the paths + * need to be adjusted to be the correct path for the live device tree. * - * The value of properties in the "/__symbols__" node is the path of a - * node in the subtree of a fragment node's "__overlay__" node, for - * example "/fragment@0/__overlay__/symbol_path_tail". Symbol_path_tail - * can be a single node or it may be a multi-node path. + * The paths refer to a node in the subtree of a fragment node's "__overlay__" + * node, for example "/fragment@0/__overlay__/symbol_path_tail", + * where symbol_path_tail can be a single node or it may be a multi-node path. * * The duplicated property value will be modified by replacing the * "/fragment_name/__overlay/" portion of the value with the target @@ -160,59 +163,76 @@ static struct property *dup_and_fixup_symbol_prop( struct overlay_changeset *ovcs, const struct property *prop) { struct fragment *fragment; - struct property *new; - const char *overlay_name; - char *symbol_path_tail; - char *symbol_path; + struct property *new_prop; + struct device_node *fragment_node; + struct device_node *overlay_node; + const char *path; + const char *path_tail; const char *target_path; int k; - int symbol_path_tail_len; int overlay_name_len; + int path_len; + int path_tail_len; int target_path_len; if (!prop->value) return NULL; - symbol_path = prop->value; + if (strnlen(prop->value, prop->length) >= prop->length) + return NULL; + path = prop->value; + path_len = strlen(path); - new = kzalloc(sizeof(*new), GFP_KERNEL); - if (!new) + if (path_len < 1) return NULL; + fragment_node = __of_find_node_by_path(ovcs->overlay_tree, path
[RFC v2 3/8] drm/bridge: Parade PS8640 MIPI DSI -> eDP converter driver
Ported from chromeos-3.18 kernel. Signed-off-by: Ulrich Hecht --- drivers/gpu/drm/bridge/Kconfig | 12 + drivers/gpu/drm/bridge/Makefile|3 + drivers/gpu/drm/bridge/parade-ps8640.c | 1104 3 files changed, 1119 insertions(+) create mode 100644 drivers/gpu/drm/bridge/parade-ps8640.c diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig index 966f4eb..a1c0d95 100644 --- a/drivers/gpu/drm/bridge/Kconfig +++ b/drivers/gpu/drm/bridge/Kconfig @@ -26,6 +26,18 @@ config DRM_GENERIC_GPIO_MUX is active, reports it as a GPIO, and the driver redirects calls to the appropriate downstream bridge (if any). +config DRM_PARADE_PS8640 + tristate "Parade PS8640 MIPI DSI to eDP Converter" + depends on DRM + depends on OF + select DRM_KMS_HELPER + select DRM_MIPI_DSI + select DRM_PANEL + ---help--- + Choose this option if you have PS8640 for display + The PS8640 is a high-performance and low-power + MIPI DSI to eDP converter + config DRM_ANALOGIX_ANX78XX tristate "Analogix ANX78XX bridge" select DRM_KMS_HELPER diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile index 2d5652e..6be8a9d 100644 --- a/drivers/gpu/drm/bridge/Makefile +++ b/drivers/gpu/drm/bridge/Makefile @@ -1,3 +1,6 @@ +ccflags-y := -Iinclude/drm + +obj-$(CONFIG_DRM_PARADE_PS8640) += parade-ps8640.o obj-$(CONFIG_DRM_ANALOGIX_ANX78XX) += analogix-anx78xx.o obj-$(CONFIG_DRM_GENERIC_GPIO_MUX) += generic-gpio-mux.o obj-$(CONFIG_DRM_DUMB_VGA_DAC) += dumb-vga-dac.o diff --git a/drivers/gpu/drm/bridge/parade-ps8640.c b/drivers/gpu/drm/bridge/parade-ps8640.c new file mode 100644 index 000..8489f6c --- /dev/null +++ b/drivers/gpu/drm/bridge/parade-ps8640.c @@ -0,0 +1,1104 @@ +/* + * Copyright (c) 2016 MediaTek Inc. + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#define PAGE1_VSTART 0x6b +#define PAGE2_SPI_CFG3 0x82 +#define I2C_TO_SPI_RESET 0x20 +#define PAGE2_ROMADD_BYTE1 0x8e +#define PAGE2_ROMADD_BYTE2 0x8f +#define PAGE2_SWSPI_WDATA 0x90 +#define PAGE2_SWSPI_RDATA 0x91 +#define PAGE2_SWSPI_LEN0x92 +#define PAGE2_SWSPI_CTL0x93 +#define TRIGGER_NO_READBACK0x05 +#define TRIGGER_READBACK 0x01 +#define PAGE2_SPI_STATUS 0x9e +#define SPI_READY 0x0c +#define PAGE2_GPIO_L 0xa6 +#define PAGE2_GPIO_H 0xa7 +#define PS_GPIO9 BIT(1) +#define PAGE2_IROM_CTRL0xb0 +#define IROM_ENABLE0xc0 +#define IROM_DISABLE 0x80 +#define PAGE2_SW_RESET 0xbc +#define SPI_SW_RESET BIT(7) +#define MPU_SW_RESET BIT(6) +#define PAGE2_ENCTLSPI_WR 0xda +#define PAGE2_I2C_BYPASS 0xea +#define I2C_BYPASS_EN 0xd0 +#define PAGE2_MCS_EN 0xf3 +#define MCS_EN BIT(0) +#define PAGE3_SET_ADD 0xfe +#define PAGE3_SET_VAL 0xff +#define VDO_CTL_ADD0x13 +#define VDO_DIS0x18 +#define VDO_EN 0x1c +#define PAGE4_REV_L0xf0 +#define PAGE4_REV_H0xf1 +#define PAGE4_CHIP_L 0xf2 +#define PAGE4_CHIP_H 0xf3 + +/* Firmware */ +#define SPI_MAX_RETRY_CNT 8 +#define PS_FW_NAME "ps864x_fw.bin" + +#define FW_CHIP_ID_OFFSET 0 +#define FW_VERSION_OFFSET 2 +#define EDID_I2C_ADDR 0x50 + +#define WRITE_STATUS_REG_CMD 0x01 +#define READ_STATUS_REG_CMD0x05 +#define BUSY BIT(0) +#define CLEAR_ALL_PROTECT 0x00 +#define BLK_PROTECT_BITS 0x0c +#define STATUS_REG_PROTECT BIT(7) +#define WRITE_ENABLE_CMD 0x06 +#define CHIP_ERASE_CMD 0xc7 +#define MAX_DEVS 0x8 +struct ps8640_info { + u8 family_id; + u8 variant_id; + u16 version; +}; + +struct ps8640 { + struct drm_connector connector; + struct drm_bridge bridge; + struct edid *edid; + struct mipi_dsi_device dsi; + struct i2c_client *page[MAX_DEVS]; + struct i2c_client *ddc_i2c; + struct regulator *v33; + struct regulator *v12; + struct drm_panel *panel; + struct gpio_desc *gpio_rst_n; + struct gpio_desc *gpio_slp_n; + struct gp
[PATCH v2 04/12] of: overlay: rename identifiers in dup_and_fixup_symbol_prop()
From: Frank Rowand More renaming of identifiers to better reflect what they do. Signed-off-by: Frank Rowand --- drivers/of/overlay.c | 24 ++-- 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c index 397ef10d1f26..c350742ed2a2 100644 --- a/drivers/of/overlay.c +++ b/drivers/of/overlay.c @@ -90,17 +90,29 @@ static int overlay_notify(struct overlay_changeset *ovcs, return 0; } +/* + * The properties in the "/__symbols__" node are "symbols". + * + * The value of properties in the "/__symbols__" node is the path of a + * node in the subtree of a fragment node's "__overlay__" node, for + * example "/fragment@0/__overlay__/symbol_path_tail". Symbol_path_tail + * can be a single node or it may be a multi-node path. + * + * The duplicated property value will be modified by replacing the + * "/fragment_name/__overlay/" portion of the value with the target + * path from the fragment node. + */ static struct property *dup_and_fixup_symbol_prop( struct overlay_changeset *ovcs, const struct property *prop) { struct fragment *fragment; struct property *new; const char *overlay_name; - char *label_path; + char *symbol_path_tail; char *symbol_path; const char *target_path; int k; - int label_path_len; + int symbol_path_tail_len; int overlay_name_len; int target_path_len; @@ -126,18 +138,18 @@ static struct property *dup_and_fixup_symbol_prop( target_path = fragment->target->full_name; target_path_len = strlen(target_path); - label_path = symbol_path + overlay_name_len; - label_path_len = strlen(label_path); + symbol_path_tail = symbol_path + overlay_name_len; + symbol_path_tail_len = strlen(symbol_path_tail); new->name = kstrdup(prop->name, GFP_KERNEL); - new->length = target_path_len + label_path_len + 1; + new->length = target_path_len + symbol_path_tail_len + 1; new->value = kzalloc(new->length, GFP_KERNEL); if (!new->name || !new->value) goto err_free; strcpy(new->value, target_path); - strcpy(new->value + target_path_len, label_path); + strcpy(new->value + target_path_len, symbol_path_tail); of_property_set_flag(new, OF_DYNAMIC); -- Frank Rowand ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 0/8] video: fbdev: au1200fb: Fix error handling path of 'au1200fb_drv_probe()'
This patch serie tries to fix several issues found in the error handling code of 'au1200fb_drv_probe()'. The 5 first patches fixes various issues (double free, missing error code, un-released resources on error, incorrect IRQ releasing and incomplete error handling path) The 3 last patches are just cleanups. I've spilt the serie in 8 steps that look logical to me. They could also be merged together if preferred. These patches are provided as-is and ARE NOT even compile-tested (sorry in advance if a patch is broken) because I don't have a cross compiler for MIPS and won't install one. This serie already goes further that the fixes I usually provide, so please excuse me if I missed something or if it is somehow broken and/or incomplete. --- V1 previously posted is patch 3/8 of this serie Christophe JAILLET (8): video: fbdev: au1200fb: Fix a potential double free video: fbdev: au1200fb: Return an error code if a memory allocation fails video: fbdev: au1200fb: Release some resources if a memory allocation fails video: fbdev: au1200fb: Fix error handling path video: fbdev: au1200fb: Fix error handling path video: fbdev: au1200fb: Remove some dead code video: fbdev: au1200fb: Propagate an error code video: fbdev: au1200fb: Style clean up drivers/video/fbdev/au1200fb.c | 43 ++ 1 file changed, 23 insertions(+), 20 deletions(-) -- 2.11.0 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 3/8] video: fbdev: au1200fb: Release some resources if a memory allocation fails
We should go through the error handling code instead of returning -ENOMEM directly. Signed-off-by: Christophe JAILLET --- drivers/video/fbdev/au1200fb.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/video/fbdev/au1200fb.c b/drivers/video/fbdev/au1200fb.c index 7fa41026984d..cf54168d44dc 100644 --- a/drivers/video/fbdev/au1200fb.c +++ b/drivers/video/fbdev/au1200fb.c @@ -1702,7 +1702,8 @@ static int au1200fb_drv_probe(struct platform_device *dev) if (!fbdev->fb_mem) { print_err("fail to allocate frambuffer (size: %dK))", fbdev->fb_len / 1024); - return -ENOMEM; + ret = -ENOMEM; + goto failed; } /* -- 2.11.0 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 8/8] video: fbdev: au1200fb: Style clean up
Style clean-up. Signed-off-by: Christophe JAILLET --- drivers/video/fbdev/au1200fb.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/video/fbdev/au1200fb.c b/drivers/video/fbdev/au1200fb.c index 687ea2a8f810..87d5a62bf6ca 100644 --- a/drivers/video/fbdev/au1200fb.c +++ b/drivers/video/fbdev/au1200fb.c @@ -1546,14 +1546,13 @@ static int au1200fb_init_fbinfo(struct au1200fb_device *fbdev) } fbi->pseudo_palette = kcalloc(16, sizeof(u32), GFP_KERNEL); - if (!fbi->pseudo_palette) { + if (!fbi->pseudo_palette) return -ENOMEM; - } ret = fb_alloc_cmap(&fbi->cmap, AU1200_LCD_NBR_PALETTE_ENTRIES, 0); if (ret < 0) { print_err("Fail to allocate colormap (%d entries)", - AU1200_LCD_NBR_PALETTE_ENTRIES); + AU1200_LCD_NBR_PALETTE_ENTRIES); return ret; } @@ -1717,7 +1716,8 @@ static int au1200fb_drv_probe(struct platform_device *dev) print_dbg("phys=0x%08x, size=%dK", fbdev->fb_phys, fbdev->fb_len / 1024); /* Init FB data */ - if ((ret = au1200fb_init_fbinfo(fbdev)) < 0) + ret = au1200fb_init_fbinfo(fbdev); + if (ret < 0) goto failed; /* Register new framebuffer */ -- 2.11.0 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[RFC v2 1/8] drm/bridge: GPIO-controlled display multiplexer driver
Ported from chromeos-3.18 kernel. Signed-off-by: Ulrich Hecht --- drivers/gpu/drm/bridge/Kconfig| 11 ++ drivers/gpu/drm/bridge/Makefile | 1 + drivers/gpu/drm/bridge/generic-gpio-mux.c | 316 ++ 3 files changed, 328 insertions(+) create mode 100644 drivers/gpu/drm/bridge/generic-gpio-mux.c diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig index adf9ae0..966f4eb 100644 --- a/drivers/gpu/drm/bridge/Kconfig +++ b/drivers/gpu/drm/bridge/Kconfig @@ -15,6 +15,17 @@ config DRM_PANEL_BRIDGE menu "Display Interface Bridges" depends on DRM && DRM_BRIDGE +config DRM_GENERIC_GPIO_MUX + tristate "Generic GPIO-controlled mux" + depends on DRM + depends on OF + select DRM_KMS_HELPER + ---help--- + This bridge driver models a GPIO-controlled display mux with one + input, 2 outputs (e.g. an HDMI mux). The hardware decides which output + is active, reports it as a GPIO, and the driver redirects calls to the + appropriate downstream bridge (if any). + config DRM_ANALOGIX_ANX78XX tristate "Analogix ANX78XX bridge" select DRM_KMS_HELPER diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile index defcf1e..2d5652e 100644 --- a/drivers/gpu/drm/bridge/Makefile +++ b/drivers/gpu/drm/bridge/Makefile @@ -1,4 +1,5 @@ obj-$(CONFIG_DRM_ANALOGIX_ANX78XX) += analogix-anx78xx.o +obj-$(CONFIG_DRM_GENERIC_GPIO_MUX) += generic-gpio-mux.o obj-$(CONFIG_DRM_DUMB_VGA_DAC) += dumb-vga-dac.o obj-$(CONFIG_DRM_LVDS_ENCODER) += lvds-encoder.o obj-$(CONFIG_DRM_MEGACHIPS_STDP_GE_B850V3_FW) += megachips-stdp-ge-b850v3-fw.o diff --git a/drivers/gpu/drm/bridge/generic-gpio-mux.c b/drivers/gpu/drm/bridge/generic-gpio-mux.c new file mode 100644 index 000..744804b --- /dev/null +++ b/drivers/gpu/drm/bridge/generic-gpio-mux.c @@ -0,0 +1,316 @@ +/* + * ANX7688 HDMI->DP bridge driver + * + * Copyright (C) 2016 Google, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct gpio_display_mux { + struct device *dev; + + struct gpio_desc *gpiod_detect; + int detect_irq; + + struct drm_bridge bridge; + + struct drm_bridge *next[2]; +}; + +static inline struct gpio_display_mux *bridge_to_gpio_display_mux( + struct drm_bridge *bridge) +{ + return container_of(bridge, struct gpio_display_mux, bridge); +} + +static irqreturn_t gpio_display_mux_det_threaded_handler(int unused, void *data) +{ + struct gpio_display_mux *gpio_display_mux = data; + int active = gpiod_get_value(gpio_display_mux->gpiod_detect); + + dev_dbg(gpio_display_mux->dev, "Interrupt %d!\n", active); + + if (gpio_display_mux->bridge.dev) + drm_kms_helper_hotplug_event(gpio_display_mux->bridge.dev); + + return IRQ_HANDLED; +} + +static int gpio_display_mux_attach(struct drm_bridge *bridge) +{ + struct gpio_display_mux *gpio_display_mux = + bridge_to_gpio_display_mux(bridge); + struct drm_bridge *next; + int i; + + for (i = 0; i < ARRAY_SIZE(gpio_display_mux->next); i++) { + next = gpio_display_mux->next[i]; + if (next) + next->encoder = bridge->encoder; + } + + return 0; +} + +static bool gpio_display_mux_mode_fixup(struct drm_bridge *bridge, + const struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode) +{ + struct gpio_display_mux *gpio_display_mux = + bridge_to_gpio_display_mux(bridge); + int active; + struct drm_bridge *next; + + active = gpiod_get_value(gpio_display_mux->gpiod_detect); + next = gpio_display_mux->next[active]; + + if (next && next->funcs->mode_fixup) + return next->funcs->mode_fixup(next, mode, adjusted_mode); + else + return true; +} + +static void gpio_display_mux_mode_set(struct drm_bridge *bridge, + struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode) +{ + struct gpio_display_mux *gpio_display_mux = + bridge_to_gpio_display_mux(bridge); + int active; + struct drm_bridge *next; + + active = gpiod_get_value(gpio_display_mux->gpiod_detect); + next = gpio_display_mux->n
[PATCH v2 10/12] of: overlay: simplify applying symbols from an overlay
From: Frank Rowand The code to apply symbols from an overlay to the live device tree was implemented with the intent to be minimally intrusive on the existing code. After recent restructuring of the overlay apply code, it is easier to disintangle the code that applies the symbols, and to make the overlay changeset creation code more straight forward and understandable. Remove the extra complexity, and make the code more obvious. Signed-off-by: Frank Rowand --- drivers/of/overlay.c | 91 +--- 1 file changed, 65 insertions(+), 26 deletions(-) diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c index b1082c6f7b2c..912c222ff011 100644 --- a/drivers/of/overlay.c +++ b/drivers/of/overlay.c @@ -32,21 +32,22 @@ struct fragment { struct device_node *target; struct device_node *overlay; - bool is_symbols_node; }; /** * struct overlay_changeset - * @ovcs_list: list on which we are located - * @count: count of @fragments structures - * @fragments: info about fragment nodes in overlay expanded device tree - * @cset: changeset to apply fragments to live device tree + * @ovcs_list: list on which we are located + * @count: count of fragment structures + * @fragments: fragment nodes in the overlay expanded device tree + * @symbols_fragment: last element of @fragments[] is the __symbols__ node + * @cset: changeset to apply fragments to live device tree */ struct overlay_changeset { int id; struct list_head ovcs_list; int count; struct fragment *fragments; + bool symbols_fragment; struct of_changeset cset; }; @@ -68,8 +69,7 @@ static int devicetree_corrupt(void) static int build_changeset_next_level(struct overlay_changeset *ovcs, struct device_node *target_node, - const struct device_node *overlay_node, - bool is_symbols_node); + const struct device_node *overlay_node); /* * of_resolve_phandles() finds the largest phandle in the live tree. @@ -221,7 +221,7 @@ static struct property *dup_and_fixup_symbol_prop( * @ovcs: overlay changeset * @target_node: where to place @overlay_prop in live tree * @overlay_prop: property to add or update, from overlay tree - * is_symbols_node:1 if @target_node is "/__symbols__" + * @is_symbols_prop: 1 if @overlay_prop is from node "/__symbols__" * * If @overlay_prop does not already exist in @target_node, add changeset entry * to add @overlay_prop in @target_node, else add changeset entry to update @@ -237,7 +237,7 @@ static struct property *dup_and_fixup_symbol_prop( static int add_changeset_property(struct overlay_changeset *ovcs, struct device_node *target_node, struct property *overlay_prop, - bool is_symbols_node) + bool is_symbols_prop) { struct property *new_prop = NULL, *prop; @@ -248,7 +248,7 @@ static int add_changeset_property(struct overlay_changeset *ovcs, !of_prop_cmp(overlay_prop->name, "linux,phandle")) return 0; - if (is_symbols_node) { + if (is_symbols_prop) { if (prop) return -EINVAL; new_prop = dup_and_fixup_symbol_prop(ovcs, overlay_prop); @@ -321,13 +321,13 @@ static int add_changeset_node(struct overlay_changeset *ovcs, if (ret) return ret; - return build_changeset_next_level(ovcs, tchild, node, 0); + return build_changeset_next_level(ovcs, tchild, node); } if (node->phandle && tchild->phandle) ret = -EINVAL; else - ret = build_changeset_next_level(ovcs, tchild, node, 0); + ret = build_changeset_next_level(ovcs, tchild, node); of_node_put(tchild); return ret; @@ -338,7 +338,6 @@ static int add_changeset_node(struct overlay_changeset *ovcs, * @ovcs: overlay changeset * @target_node: where to place @overlay_node in live tree * @overlay_node: node from within an overlay device tree fragment - * @is_symbols_node: @overlay_node is node "/__symbols__" * * Add the properties (if any) and nodes (if any) from @overlay_node to the * @ovcs->cset changeset. If an added node has child nodes, they will @@ -351,16 +350,14 @@ static int add_changeset_node(struct overlay_changeset *ovcs, */ static int build_changeset_next_level(struct overlay_changeset *ovcs, struct device_node *target_node, - const struct device_node *overlay_node, - bool is_symbols_node) + const struct device_node *overlay_node) { struct device_node *child; struct property *prop; int ret; for_each_property_of_node(overlay_node, prop) { - ret = add_cha
[PATCH v2 03/12] of: overlay: rename identifiers to more reflect what they do
From: Frank Rowand This patch is aimed primarily at drivers/of/overlay.c, but those changes also have a small impact in a few other files. overlay.c is difficult to read and maintain. Improve readability: - Rename functions, types and variables to better reflect what they do and to be consistent with names in other places, such as the device tree overlay FDT (flattened device tree), and make the algorithms more clear - Use the same names consistently throughout the file - Update comments for name changes - Fix incorrect comments This patch is intended to not introduce any functional change. Signed-off-by: Frank Rowand --- Documentation/devicetree/overlay-notes.txt | 12 +- drivers/gpu/drm/tilcdc/tilcdc_slave_compat.c | 5 +- drivers/of/dynamic.c | 2 +- drivers/of/overlay.c | 506 ++- drivers/of/unittest.c| 20 +- include/linux/of.h | 12 +- 6 files changed, 294 insertions(+), 263 deletions(-) diff --git a/Documentation/devicetree/overlay-notes.txt b/Documentation/devicetree/overlay-notes.txt index eb7f2685fda1..c4aa0adf13ec 100644 --- a/Documentation/devicetree/overlay-notes.txt +++ b/Documentation/devicetree/overlay-notes.txt @@ -87,15 +87,15 @@ Overlay in-kernel API The API is quite easy to use. -1. Call of_overlay_create() to create and apply an overlay. The return value -is a cookie identifying this overlay. +1. Call of_overlay_apply() to create and apply an overlay changeset. The return +value is an error or a cookie identifying this overlay. -2. Call of_overlay_destroy() to remove and cleanup the overlay previously -created via the call to of_overlay_create(). Removal of an overlay that -is stacked by another will not be permitted. +2. Call of_overlay_remove() to remove and cleanup the overlay changeset +previously created via the call to of_overlay_apply(). Removal of an overlay +changeset that is stacked by another will not be permitted. Finally, if you need to remove all overlays in one-go, just call -of_overlay_destroy_all() which will remove every single one in the correct +of_overlay_remove_all() which will remove every single one in the correct order. Overlay DTS Format diff --git a/drivers/gpu/drm/tilcdc/tilcdc_slave_compat.c b/drivers/gpu/drm/tilcdc/tilcdc_slave_compat.c index 623a9140493c..5f5b7ba35f1d 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_slave_compat.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_slave_compat.c @@ -247,9 +247,10 @@ static void __init tilcdc_convert_slave_node(void) tilcdc_node_disable(slave); - ret = of_overlay_create(overlay); + ret = of_overlay_apply(overlay); if (ret) - pr_err("%s: Creating overlay failed: %d\n", __func__, ret); + pr_err("%s: Applying overlay changeset failed: %d\n", + __func__, ret); else pr_info("%s: ti,tilcdc,slave node successfully converted\n", __func__); diff --git a/drivers/of/dynamic.c b/drivers/of/dynamic.c index 301b6db2b48d..124510d56421 100644 --- a/drivers/of/dynamic.c +++ b/drivers/of/dynamic.c @@ -775,7 +775,7 @@ int of_changeset_revert(struct of_changeset *ocs) EXPORT_SYMBOL_GPL(of_changeset_revert); /** - * of_changeset_action - Perform a changeset action + * of_changeset_action - Add an action to the tail of the changeset list * * @ocs: changeset pointer * @action:action to perform diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c index 8e0c7eb4858c..397ef10d1f26 100644 --- a/drivers/of/overlay.c +++ b/drivers/of/overlay.c @@ -25,67 +25,63 @@ #include "of_private.h" /** - * struct of_overlay_info - Holds a single overlay info + * struct fragment - info about fragment nodes in overlay expanded device tree * @target:target of the overlay operation - * @overlay: pointer to the overlay contents node - * - * Holds a single overlay state, including all the overlay logs & - * records. + * @overlay: pointer to the __overlay__ node */ -struct of_overlay_info { +struct fragment { struct device_node *target; struct device_node *overlay; bool is_symbols_node; }; /** - * struct of_overlay - Holds a complete overlay transaction - * @node: List on which we are located - * @count: Count of ovinfo structures - * @ovinfo_tab:Overlay info table (count sized) - * @cset: Changeset to be used - * - * Holds a complete overlay transaction + * struct overlay_changeset + * @ovcs_list: list on which we are located + * @count: count of @fragments structures + * @fragments: info about fragment nodes in overlay expanded device tree + * @cset: changeset to apply fragments to live device tree */ -struct of_overlay { +struct overlay_changeset { int id; - struct list_head node; + struct list_head ovcs_list; int count; - struct of_overl
[PATCH v2 05/12] of: overlay: minor restructuring
From: Frank Rowand Continue improving the readability of overlay.c. The previous patches renamed identifiers. This patch is split out from the previous patches to make the previous patches easier to review. Changes are: - minor code restructuring - some initialization of an overlay changeset occurred outside of init_overlay_changeset(), move that into init_overlay_changeset() - consolidate freeing an overlay changeset into free_overlay_changeset() This patch is intended to not introduce any functional change. Signed-off-by: Frank Rowand --- drivers/of/overlay.c | 205 +++ 1 file changed, 92 insertions(+), 113 deletions(-) diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c index c350742ed2a2..0f92a5c26748 100644 --- a/drivers/of/overlay.c +++ b/drivers/of/overlay.c @@ -55,6 +55,9 @@ static int build_changeset_next_level(struct overlay_changeset *ovcs, const struct device_node *overlay_node, bool is_symbols_node); +static LIST_HEAD(ovcs_list); +static DEFINE_IDR(ovcs_idr); + static BLOCKING_NOTIFIER_HEAD(overlay_notify_chain); int of_overlay_notifier_register(struct notifier_block *nb) @@ -160,8 +163,6 @@ static struct property *dup_and_fixup_symbol_prop( kfree(new->value); kfree(new); return NULL; - - } /** @@ -249,13 +250,7 @@ static int add_changeset_node(struct overlay_changeset *ovcs, if (!of_node_cmp(node_kbasename, kbasename(tchild->full_name))) break; - if (tchild) { - if (node->phandle) - return -EINVAL; - - ret = build_changeset_next_level(ovcs, tchild, node, 0); - of_node_put(tchild); - } else { + if (!tchild) { tchild = __of_node_dup(node, "%pOF/%s", target_node, node_kbasename); if (!tchild) @@ -267,11 +262,15 @@ static int add_changeset_node(struct overlay_changeset *ovcs, if (ret) return ret; - ret = build_changeset_next_level(ovcs, tchild, node, 0); - if (ret) - return ret; + return build_changeset_next_level(ovcs, tchild, node, 0); } + if (node->phandle) + return -EINVAL; + + ret = build_changeset_next_level(ovcs, tchild, node, 0); + of_node_put(tchild); + return ret; } @@ -385,41 +384,6 @@ static struct device_node *find_target_node(struct device_node *info_node) } /** - * of_fill_overlay_info() - Fill an overlay info structure - * @ov Overlay to fill - * @info_node: Device node containing the overlay - * @ovinfo:Pointer to the overlay info structure to fill - * - * Fills an overlay info structure with the overlay information - * from a device node. This device node must have a target property - * which contains a phandle of the overlay target node, and an - * __overlay__ child node which has the overlay contents. - * Both ovinfo->target & ovinfo->overlay have their references taken. - * - * Returns 0 on success, or a negative error value. - */ -static int of_fill_overlay_info(struct of_overlay *ov, - struct device_node *info_node, struct of_overlay_info *ovinfo) -{ - ovinfo->overlay = of_get_child_by_name(info_node, "__overlay__"); - if (!ovinfo->overlay) - goto err_fail; - - ovinfo->target = find_target_node(info_node); - if (!ovinfo->target) - goto err_fail; - - return 0; - -err_fail: - of_node_put(ovinfo->target); - of_node_put(ovinfo->overlay); - - memset(ovinfo, 0, sizeof(*ovinfo)); - return -EINVAL; -} - -/** * init_overlay_changeset() - initialize overlay changeset from overlay tree * @ovcs Overlay changeset to build * @tree: Contains all the overlay fragments and overlay fixup nodes @@ -429,32 +393,61 @@ static int of_fill_overlay_info(struct of_overlay *ov, * nodes and the __symbols__ node. Any other top level node will be ignored. * * Returns 0 on success, -ENOMEM if memory allocation failure, -EINVAL if error - * detected in @tree, or -ENODEV if no valid nodes found. + * detected in @tree, or -ENOSPC if idr_alloc() error. */ static int init_overlay_changeset(struct overlay_changeset *ovcs, struct device_node *tree) { - struct device_node *node; + struct device_node *node, *overlay_node; struct fragment *fragment; struct fragment *fragments; int cnt, ret; + INIT_LIST_HEAD(&ovcs->ovcs_list); + + of_changeset_init(&ovcs->cset); + + ovcs->id = idr_alloc(&ovcs_idr, ovcs, 1, 0, GFP_KERNEL); + if (ovcs->id <= 0) + return ovcs->id; + cnt = 0; - for_each_child_of_node(tree, node) - cnt++; - if (of_get_child_by_name(tree, "__symbols__"))
[PATCH v2 02/12] of: overlay.c: Convert comparisons to zero or NULL to logical expressions
From: Frank Rowand Use normal shorthand for comparing a variable to zero. For variable "XXX": convert (XXX == 0) to (!XXX) convert (XXX != 0) to (XXX) Signed-off-by: Frank Rowand --- drivers/of/overlay.c | 36 ++-- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c index 26f63f10f4b0..8e0c7eb4858c 100644 --- a/drivers/of/overlay.c +++ b/drivers/of/overlay.c @@ -168,9 +168,9 @@ static int of_overlay_apply_single_property(struct of_overlay *ov, tprop = of_find_property(target, prop->name, NULL); - if (of_prop_cmp(prop->name, "name") == 0 || - of_prop_cmp(prop->name, "phandle") == 0 || - of_prop_cmp(prop->name, "linux,phandle") == 0) + if (!of_prop_cmp(prop->name, "name") || + !of_prop_cmp(prop->name, "phandle") || + !of_prop_cmp(prop->name, "linux,phandle")) return 0; if (is_symbols_node) { @@ -181,10 +181,10 @@ static int of_overlay_apply_single_property(struct of_overlay *ov, propn = __of_prop_dup(prop, GFP_KERNEL); } - if (propn == NULL) + if (!propn) return -ENOMEM; - if (tprop == NULL) + if (!tprop) return of_changeset_add_property(&ov->cset, target, propn); return of_changeset_update_property(&ov->cset, target, propn); @@ -205,14 +205,14 @@ static int of_overlay_apply_single_device_node(struct of_overlay *ov, int ret = 0; cname = kbasename(child->full_name); - if (cname == NULL) + if (!cname) return -ENOMEM; for_each_child_of_node(target, tchild) if (!of_node_cmp(cname, kbasename(tchild->full_name))) break; - if (tchild != NULL) { + if (tchild) { if (child->phandle) return -EINVAL; @@ -270,7 +270,7 @@ static int of_overlay_apply_one(struct of_overlay *ov, for_each_child_of_node(overlay, child) { ret = of_overlay_apply_single_device_node(ov, target, child); - if (ret != 0) { + if (ret) { pr_err("Failed to apply single node @%pOF/%s\n", target, child->name); of_node_put(child); @@ -299,7 +299,7 @@ static int of_overlay_apply(struct of_overlay *ov) err = of_overlay_apply_one(ov, ovinfo->target, ovinfo->overlay, ovinfo->is_symbols_node); - if (err != 0) { + if (err) { pr_err("apply failed '%pOF'\n", ovinfo->target); return err; } @@ -322,11 +322,11 @@ static struct device_node *find_target_node(struct device_node *info_node) int ret; ret = of_property_read_u32(info_node, "target", &val); - if (ret == 0) + if (!ret) return of_find_node_by_phandle(val); ret = of_property_read_string(info_node, "target-path", &path); - if (ret == 0) + if (!ret) return of_find_node_by_path(path); pr_err("Failed to find target for node %p (%s)\n", @@ -353,11 +353,11 @@ static int of_fill_overlay_info(struct of_overlay *ov, struct device_node *info_node, struct of_overlay_info *ovinfo) { ovinfo->overlay = of_get_child_by_name(info_node, "__overlay__"); - if (ovinfo->overlay == NULL) + if (!ovinfo->overlay) goto err_fail; ovinfo->target = find_target_node(info_node); - if (ovinfo->target == NULL) + if (!ovinfo->target) goto err_fail; return 0; @@ -397,13 +397,13 @@ static int of_build_overlay_info(struct of_overlay *ov, cnt++; ovinfo = kcalloc(cnt, sizeof(*ovinfo), GFP_KERNEL); - if (ovinfo == NULL) + if (!ovinfo) return -ENOMEM; cnt = 0; for_each_child_of_node(tree, node) { err = of_fill_overlay_info(ov, node, &ovinfo[cnt]); - if (err == 0) + if (!err) cnt++; } @@ -421,7 +421,7 @@ static int of_build_overlay_info(struct of_overlay *ov, cnt++; } - if (cnt == 0) { + if (!cnt) { kfree(ovinfo); return -ENODEV; } @@ -477,7 +477,7 @@ int of_overlay_create(struct device_node *tree) int err, id; ov = kzalloc(sizeof(*ov), GFP_KERNEL); - if (ov == NULL) + if (!ov) return -ENOMEM; ov->id = -1; @@ -628,7 +628,7 @@ int of_overlay_destroy(int id) mutex_lock(&of_mutex); ov = idr_find(&ov_idr, id); - if (ov == NULL) { + if (!ov) { err = -ENODEV; pr_err("destroy: Could not find overlay #%d\n", id);
[PATCH v2 08/12] of: overlay: loosen overly strict phandle clash check
From: Frank Rowand When an overlay contains a node that already exists in the live device tree, the overlay node is not allowed to change the phandle of the existing node. The existing check refused to allow an overlay node to set the node phandle even when the existing node did not have a phandle. Relax the check to allow an overlay node to set the phandle value if the existing node does not have a phandle. Signed-off-by: Frank Rowand --- drivers/of/overlay.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c index 015d8b112f60..a0d3222febdc 100644 --- a/drivers/of/overlay.c +++ b/drivers/of/overlay.c @@ -302,10 +302,10 @@ static int add_changeset_node(struct overlay_changeset *ovcs, return build_changeset_next_level(ovcs, tchild, node, 0); } - if (node->phandle) - return -EINVAL; - - ret = build_changeset_next_level(ovcs, tchild, node, 0); + if (node->phandle && tchild->phandle) + ret = -EINVAL; + else + ret = build_changeset_next_level(ovcs, tchild, node, 0); of_node_put(tchild); return ret; -- Frank Rowand ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 1/8] video: fbdev: au1200fb: Fix a potential double free
If 'fb_alloc_cmap()' fails, 'fbi->pseudo_palette' is freed and an error code is returned by 'au1200fb_init_fbinfo()'. The only caller, 'au1200fb_drv_probe()' goes to an error handling path where resources allocated in 'fb_alloc_cmap()' are freed. This leads to a double free of 'fbi->pseudo_palette'. Fix it by letting the caller free all resources in case of failure in 'au1200fb_init_fbinfo()'. Signed-off-by: Christophe JAILLET --- drivers/video/fbdev/au1200fb.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/video/fbdev/au1200fb.c b/drivers/video/fbdev/au1200fb.c index 5f04b4096c42..a5facc2ad90b 100644 --- a/drivers/video/fbdev/au1200fb.c +++ b/drivers/video/fbdev/au1200fb.c @@ -1553,7 +1553,6 @@ static int au1200fb_init_fbinfo(struct au1200fb_device *fbdev) if (fb_alloc_cmap(&fbi->cmap, AU1200_LCD_NBR_PALETTE_ENTRIES, 0) < 0) { print_err("Fail to allocate colormap (%d entries)", AU1200_LCD_NBR_PALETTE_ENTRIES); - kfree(fbi->pseudo_palette); return -EFAULT; } -- 2.11.0 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2 01/12] of: overlay.c: Remove comments that state the obvious, to reduce clutter
From: Frank Rowand Follows recommendations in Documentation/process/coding-style.rst, section 8, Commenting. Some in function comments are promoted to function header comments. Signed-off-by: Frank Rowand --- drivers/of/overlay.c | 53 1 file changed, 24 insertions(+), 29 deletions(-) diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c index 8ecfee31ab6d..26f63f10f4b0 100644 --- a/drivers/of/overlay.c +++ b/drivers/of/overlay.c @@ -143,7 +143,6 @@ static struct property *dup_and_fixup_symbol_prop(struct of_overlay *ov, strcpy(new->value, target_path); strcpy(new->value + target_path_len, label_path); - /* mark the property as dynamic */ of_property_set_flag(new, OF_DYNAMIC); return new; @@ -157,23 +156,24 @@ static struct property *dup_and_fixup_symbol_prop(struct of_overlay *ov, } +/* + * Some special properties are not updated (no error returned). + * Update of property in symbols node is not allowed. + */ static int of_overlay_apply_single_property(struct of_overlay *ov, struct device_node *target, struct property *prop, bool is_symbols_node) { struct property *propn = NULL, *tprop; - /* NOTE: Multiple changes of single properties not supported */ tprop = of_find_property(target, prop->name, NULL); - /* special properties are not meant to be updated (silent NOP) */ if (of_prop_cmp(prop->name, "name") == 0 || of_prop_cmp(prop->name, "phandle") == 0 || of_prop_cmp(prop->name, "linux,phandle") == 0) return 0; if (is_symbols_node) { - /* changing a property in __symbols__ node not allowed */ if (tprop) return -EINVAL; propn = dup_and_fixup_symbol_prop(ov, prop); @@ -184,14 +184,19 @@ static int of_overlay_apply_single_property(struct of_overlay *ov, if (propn == NULL) return -ENOMEM; - /* not found? add */ if (tprop == NULL) return of_changeset_add_property(&ov->cset, target, propn); - /* found? update */ return of_changeset_update_property(&ov->cset, target, propn); } +/* + * NOTE: Multiple mods of created nodes not supported. + * + * Return + * -ENOMEM if memory allocation fails + * -EINVAL if existing node has a phandle and overlay node has a phandle + */ static int of_overlay_apply_single_device_node(struct of_overlay *ov, struct device_node *target, struct device_node *child) { @@ -203,13 +208,11 @@ static int of_overlay_apply_single_device_node(struct of_overlay *ov, if (cname == NULL) return -ENOMEM; - /* NOTE: Multiple mods of created nodes not supported */ for_each_child_of_node(target, tchild) if (!of_node_cmp(cname, kbasename(tchild->full_name))) break; if (tchild != NULL) { - /* new overlay phandle value conflicts with existing value */ if (child->phandle) return -EINVAL; @@ -217,12 +220,10 @@ static int of_overlay_apply_single_device_node(struct of_overlay *ov, ret = of_overlay_apply_one(ov, tchild, child, 0); of_node_put(tchild); } else { - /* create empty tree as a target */ tchild = __of_node_dup(child, "%pOF/%s", target, cname); if (!tchild) return -ENOMEM; - /* point to parent */ tchild->parent = target; ret = of_changeset_attach_node(&ov->cset, tchild); @@ -243,6 +244,8 @@ static int of_overlay_apply_single_device_node(struct of_overlay *ov, * Note that the in case of an error the target node is left * in a inconsistent state. Error recovery should be performed * by using the changeset. + * + * Do not allow symbols node to have any children. */ static int of_overlay_apply_one(struct of_overlay *ov, struct device_node *target, const struct device_node *overlay, @@ -262,7 +265,6 @@ static int of_overlay_apply_one(struct of_overlay *ov, } } - /* do not allow symbols node to have any children */ if (is_symbols_node) return 0; @@ -292,7 +294,6 @@ static int of_overlay_apply(struct of_overlay *ov) { int i, err; - /* first we apply the overlays atomically */ for (i = 0; i < ov->count; i++) { struct of_overlay_info *ovinfo = &ov->ovinfo_tab[i]; @@ -309,10 +310,10 @@ static int of_overlay_apply(struct of_overlay *ov) /* * Find the target node using a number of different strategies - * in order of preference + * in order of preference: * - * "target" property containing the phandle of the target - * "target-path" property containing the path of the target + * 1) "targe
[Bug 102820] [bisected][DC] commit ebbf7337e2daacacef3e01114e6be68a2a4f11b4 prevents X11 from starting
https://bugs.freedesktop.org/show_bug.cgi?id=102820 --- Comment #11 from dwagner --- (In reply to Alex Deucher from comment #9) > Harry or Jordan can verify, but I think it means the board maker did not > validate the HDMI connector for 6Ghz timings. The asic may support it, but > the board has to be validated to make sure the physical connector supports > it and the traces are not too long, etc. Some boards only support 4k@60 > over DP. This is the manufacturers page advertising my graphics board: http://www.xfxforce.com/en-us/products/amd-radeon-rx-400-series/rx-460-4gb-heatsink-rx-460p4hfg5- It couldn't be more affirmative regarding support of HDMI 2.0b and high refresh rates for 4k modes... (And practical experience during the last months also tells me: Yes, HDMI 4k @ 60Hz output is stable - even when using a 4m length HDMI cable. > The driver drops the higher bandwidth modes for HDMI connectors if the board > does not support them. I have looked if there are any firmware upgrades for this card or any hints from others regarding lack of 4k 60 Hz support, but found neither. (I only found unofficial firmware that switches on shader units the manufacturer keeps dormant, but I am not using that.) -- You are receiving this mail because: You are the assignee for the bug.___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2 00/12] of: overlay: clean up device tree overlay code
From: Frank Rowand I have found the device tree overlay code to be difficult to read and maintain. This patch series attempts to improve that situation. The cleanup includes some changes visible to users of overlays. The only in kernel user of overlays is fixed up for those changes. The in kernel user is: drivers/gpu/drm/tilcdc/tilcdc_slave_compat.c Following the cleanup patches are a set of patches to fix various issues. The first five patches are intended to not make any functional changes, and are segrated to ease review. Frank Rowand (12): of: overlay.c: Remove comments that state the obvious, to reduce clutter of: overlay.c: Convert comparisons to zero or NULL to logical expressions of: overlay: rename identifiers to more reflect what they do of: overlay: rename identifiers in dup_and_fixup_symbol_prop() of: overlay: minor restructuring of: overlay: detect cases where device tree may become corrupt of: overlay: expand check of whether overlay changeset can be removed of: overlay: loosen overly strict phandle clash check of: overlay: avoid race condition between applying multiple overlays of: overlay: simplify applying symbols from an overlay of: overlay: remove a dependency on device node full_name of: overlay: remove unneeded check for NULL kbasename() Documentation/devicetree/overlay-notes.txt | 12 +- drivers/gpu/drm/tilcdc/tilcdc_slave_compat.c | 14 +- drivers/of/base.c|2 +- drivers/of/dynamic.c | 137 +++- drivers/of/of_private.h | 22 +- drivers/of/overlay.c | 1034 -- drivers/of/resolver.c|7 + drivers/of/unittest.c| 81 +- include/linux/of.h | 17 +- 9 files changed, 869 insertions(+), 457 deletions(-) -- Frank Rowand ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 4/9] drm/panel: simple: add support for overriding the pixel clock polarity
Hi, On Mon, 16 Oct 2017 17:13:29 -0500 Rob Herring wrote: > On Wed, Oct 11, 2017 at 6:23 AM, Lothar Waßmann > wrote: > > The Ka-Ro electronics MB7 baseboard has an on-board LCD->LVDS > > converter that requires a fixed pixelclk polarity, no matter what the > > panel's display_mode specifies. Add an option to override the pixelclk > > polarity defined in the panel's display_mode via DTB. > > Wouldn't you know the polarity required based on the type of LVDS > converter chip in front of the panel? Or is that not being described > because it is "transparent". > Exactly the latter. Lothar Waßmann ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v2 09/12] of: overlay: avoid race condition between applying multiple overlays
On 10/16/17 18:17, frowand.l...@gmail.com wrote: > From: Frank Rowand > > The process of applying an overlay consists of: > - unflatten an overlay FDT (flattened device tree) into an > EDT (expanded device tree) > - fixup the phandle values in the overlay EDT to fit in a > range above the phandle values in the live device tree > - create the overlay changeset to reflect the contents of > the overlay EDT > - apply the overlay changeset, to modify the live device tree, > potentially changing the maximum phandle value in the live > device tree > > There is currently no protection against two overlay applies > concurrently determining what range of phandle values are in use > in the live device tree, and subsequently changing that range. > Add a mutex to prevent multiple overlay applies from occurring > simultaneously. > > Move of_resolve_phandles() into of_overlay_apply() so that it does not > have to be duplicated by each caller of of_overlay_apply(). > > The test in of_resolve_phandles() that the overlay tree is detached is > temporarily disabled so that old style overlay unittests do not fail. > > Signed-off-by: Frank Rowand > --- Brown paper bag time. Changes from version 1: squash "[PATCH] of: overlay: move resolve phandles into of_overlay_apply()" into "[PATCH 09/12] of: overlay: avoid race condition between applying multiple overlays" > drivers/gpu/drm/tilcdc/tilcdc_slave_compat.c | 6 -- > drivers/of/of_private.h | 12 +++ > drivers/of/overlay.c | 32 > > drivers/of/resolver.c| 7 ++ > drivers/of/unittest.c| 22 +-- > include/linux/of.h | 3 --- > 6 files changed, 67 insertions(+), 15 deletions(-) > < snip > ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2 12/12] of: overlay: remove unneeded check for NULL kbasename()
From: Frank Rowand kbasename() will not return NULL if passed a valid string. If the parameter passed to kbasename() in this case is already NULL then the devicetree has been corrupted. Signed-off-by: Frank Rowand --- drivers/of/overlay.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c index a257474c9223..dc7657329aea 100644 --- a/drivers/of/overlay.c +++ b/drivers/of/overlay.c @@ -322,8 +322,6 @@ static int add_changeset_node(struct overlay_changeset *ovcs, int ret = 0; node_kbasename = kbasename(node->full_name); - if (!node_kbasename) - return -ENOMEM; for_each_child_of_node(target_node, tchild) if (!of_node_cmp(node_kbasename, kbasename(tchild->full_name))) -- Frank Rowand ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v2 00/12] of: overlay: clean up device tree overlay code
On 10/16/17 18:17, frowand.l...@gmail.com wrote: > From: Frank Rowand > > I have found the device tree overlay code to be difficult to read and > maintain. This patch series attempts to improve that situation. > > The cleanup includes some changes visible to users of overlays. The > only in kernel user of overlays is fixed up for those changes. The > in kernel user is: > >drivers/gpu/drm/tilcdc/tilcdc_slave_compat.c > > Following the cleanup patches are a set of patches to fix various > issues. > > The first five patches are intended to not make any functional > changes, and are segrated to ease review. > > Frank Rowand (12): > of: overlay.c: Remove comments that state the obvious, to reduce > clutter > of: overlay.c: Convert comparisons to zero or NULL to logical > expressions > of: overlay: rename identifiers to more reflect what they do > of: overlay: rename identifiers in dup_and_fixup_symbol_prop() > of: overlay: minor restructuring > of: overlay: detect cases where device tree may become corrupt > of: overlay: expand check of whether overlay changeset can be removed > of: overlay: loosen overly strict phandle clash check > of: overlay: avoid race condition between applying multiple overlays > of: overlay: simplify applying symbols from an overlay > of: overlay: remove a dependency on device node full_name > of: overlay: remove unneeded check for NULL kbasename() > > Documentation/devicetree/overlay-notes.txt | 12 +- > drivers/gpu/drm/tilcdc/tilcdc_slave_compat.c | 14 +- > drivers/of/base.c|2 +- > drivers/of/dynamic.c | 137 +++- > drivers/of/of_private.h | 22 +- > drivers/of/overlay.c | 1034 > -- > drivers/of/resolver.c|7 + > drivers/of/unittest.c| 81 +- > include/linux/of.h | 17 +- > 9 files changed, 869 insertions(+), 457 deletions(-) > Brown paper bag time. Changes from version 1: squash "[PATCH] of: overlay: move resolve phandles into of_overlay_apply()" into "[PATCH 09/12] of: overlay: avoid race condition between applying multiple overlays" ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2 07/12] of: overlay: expand check of whether overlay changeset can be removed
From: Frank Rowand The test of whether it is safe to remove an overlay changeset looked at whether any node in the overlay changeset was in a subtree rooted at any more recently applied overlay changeset node. The test failed to determine whether any node in the overlay changeset was the root of a subtree that contained a more recently applied overlay changeset node. Add this additional check to the test. The test is still lacking any check for any phandle dependencies. Signed-off-by: Frank Rowand --- drivers/of/overlay.c | 20 +--- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c index c7526186b1c8..015d8b112f60 100644 --- a/drivers/of/overlay.c +++ b/drivers/of/overlay.c @@ -698,13 +698,13 @@ static int find_node(struct device_node *tree, struct device_node *np) } /* - * Is @remove_ce_np a child of or the same as any + * Is @remove_ce_node a child of, a parent of, or the same as any * node in an overlay changeset more topmost than @remove_ovcs? * * Returns 1 if found, else 0 */ -static int node_in_later_cs(struct overlay_changeset *remove_ovcs, - struct device_node *remove_ce_np) +static int node_overlaps_later_cs(struct overlay_changeset *remove_ovcs, + struct device_node *remove_ce_node) { struct overlay_changeset *ovcs; struct of_changeset_entry *ce; @@ -714,10 +714,16 @@ static int node_in_later_cs(struct overlay_changeset *remove_ovcs, break; list_for_each_entry(ce, &ovcs->cset.entries, node) { - if (find_node(ce->np, remove_ce_np)) { - pr_err("%s: #%d clashes #%d @%pOF\n", + if (find_node(ce->np, remove_ce_node)) { + pr_err("%s: #%d overlaps with #%d @%pOF\n", __func__, remove_ovcs->id, ovcs->id, - remove_ce_np); + remove_ce_node); + return 1; + } + if (find_node(remove_ce_node, ce->np)) { + pr_err("%s: #%d overlaps with #%d @%pOF\n", + __func__, remove_ovcs->id, ovcs->id, + remove_ce_node); return 1; } } @@ -741,7 +747,7 @@ static int overlay_removal_is_ok(struct overlay_changeset *remove_ovcs) struct of_changeset_entry *remove_ce; list_for_each_entry(remove_ce, &remove_ovcs->cset.entries, node) { - if (node_in_later_cs(remove_ovcs, remove_ce->np)) { + if (node_overlaps_later_cs(remove_ovcs, remove_ce->np)) { pr_err("overlay #%d is not topmost\n", remove_ovcs->id); return 0; } -- Frank Rowand ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v2 09/11] drm/exynos/hdmi: quirk for support mode timings conversion
2017년 09월 29일 19:05에 Andrzej Hajda 이(가) 쓴 글: > MIXER in SoCs prior to Exynos5420 supports only 4 video modes: > 720x480, 720x576, 1280x720, 1920x1080. Support for other modes > can be enabled by manipulating timings of HDMI. To do it > adjusted_mode should contain actual mode set on crtc. > With this patch it is possible to enable 1024x768 and 1280x1024 > modes in MIXER. > > Suggested-by: Daniel Drake > Signed-off-by: Andrzej Hajda > Reviewed-by: Tobias Jakobi > --- > drivers/gpu/drm/exynos/exynos_hdmi.c | 15 +-- > 1 file changed, 13 insertions(+), 2 deletions(-) > > diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c > b/drivers/gpu/drm/exynos/exynos_hdmi.c > index 7225b6521148..4b081f6cfdcb 100644 > --- a/drivers/gpu/drm/exynos/exynos_hdmi.c > +++ b/drivers/gpu/drm/exynos/exynos_hdmi.c > @@ -1239,6 +1239,17 @@ static void hdmi_v13_mode_apply(struct hdmi_context > *hdata) > static void hdmi_v14_mode_apply(struct hdmi_context *hdata) > { > struct drm_display_mode *m = &hdata->encoder.crtc->state->mode; > + struct drm_display_mode *am = > &hdata->encoder.crtc->state->adjusted_mode; > + int hquirk = 0; > + > + /* > + * In case video mode coming from CRTC differs from requested one HDMI > + * sometimes is able to almost properly perform conversion - only > + * first line is distorted. > + */ > + if ((m->vdisplay != am->vdisplay) && > + (m->hdisplay == 1280 || m->hdisplay == 1024)) > + hquirk = 258; Andrzej, The distorted value couldn't be described logically? Just I wonder why the difference happens. Thanks, Inki Dae > > hdmi_reg_writev(hdata, HDMI_H_BLANK_0, 2, m->htotal - m->hdisplay); > hdmi_reg_writev(hdata, HDMI_V_LINE_0, 2, m->vtotal); > @@ -1332,8 +1343,8 @@ static void hdmi_v14_mode_apply(struct hdmi_context > *hdata) > hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_6_0, 2, 0x); > > hdmi_reg_writev(hdata, HDMI_TG_H_FSZ_L, 2, m->htotal); > - hdmi_reg_writev(hdata, HDMI_TG_HACT_ST_L, 2, m->htotal - m->hdisplay); > - hdmi_reg_writev(hdata, HDMI_TG_HACT_SZ_L, 2, m->hdisplay); > + hdmi_reg_writev(hdata, HDMI_TG_HACT_ST_L, 2, m->htotal - m->hdisplay - > hquirk); > + hdmi_reg_writev(hdata, HDMI_TG_HACT_SZ_L, 2, m->hdisplay + hquirk); > hdmi_reg_writev(hdata, HDMI_TG_V_FSZ_L, 2, m->vtotal); > if (hdata->drv_data == &exynos5433_hdmi_driver_data) > hdmi_reg_writeb(hdata, HDMI_TG_DECON_EN, 1); > ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[Bug 102820] [bisected][DC] commit ebbf7337e2daacacef3e01114e6be68a2a4f11b4 prevents X11 from starting
https://bugs.freedesktop.org/show_bug.cgi?id=102820 --- Comment #12 from dwagner --- Notice that the trailing dash in above link is part of the link, without it the page is not found: http://www.xfxforce.com/en-us/products/amd-radeon-rx-400-series/rx-460-4gb-heatsink-rx-460p4hfg5- -- You are receiving this mail because: You are the assignee for the bug.___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v2 10/11] drm/exynos/mixer: enable support for 1024x768 and 1280x1024 modes
2017년 09월 29일 19:05에 Andrzej Hajda 이(가) 쓴 글: > Since HDMI can handle these modes despite of MIXER limitations let's > enable them. > > Signed-off-by: Andrzej Hajda > Reviewed-by: Tobias Jakobi > --- > drivers/gpu/drm/exynos/exynos_mixer.c | 3 +++ > 1 file changed, 3 insertions(+) > > diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c > b/drivers/gpu/drm/exynos/exynos_mixer.c > index 8baa93f80106..85d33137cfd8 100644 > --- a/drivers/gpu/drm/exynos/exynos_mixer.c > +++ b/drivers/gpu/drm/exynos/exynos_mixer.c > @@ -1014,6 +1014,9 @@ static int mixer_mode_valid(struct exynos_drm_crtc > *crtc, > (w >= 1664 && w <= 1920 && h >= 936 && h <= 1080)) > return MODE_OK; > > + if ((w == 1024 && h == 768) || (w == 1280 && h == 1024)) > + return MODE_OK; mixer_mode_valid function is common to all Exynos SoC managed by Exynos DRM driver. So is it valid for all of them? Thanks, Inki Dae > + > return MODE_BAD; > } > > ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v2 09/11] drm/exynos/hdmi: quirk for support mode timings conversion
On 17.10.2017 09:38, Inki Dae wrote: > > 2017년 09월 29일 19:05에 Andrzej Hajda 이(가) 쓴 글: >> MIXER in SoCs prior to Exynos5420 supports only 4 video modes: >> 720x480, 720x576, 1280x720, 1920x1080. Support for other modes >> can be enabled by manipulating timings of HDMI. To do it >> adjusted_mode should contain actual mode set on crtc. >> With this patch it is possible to enable 1024x768 and 1280x1024 >> modes in MIXER. >> >> Suggested-by: Daniel Drake >> Signed-off-by: Andrzej Hajda >> Reviewed-by: Tobias Jakobi >> --- >> drivers/gpu/drm/exynos/exynos_hdmi.c | 15 +-- >> 1 file changed, 13 insertions(+), 2 deletions(-) >> >> diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c >> b/drivers/gpu/drm/exynos/exynos_hdmi.c >> index 7225b6521148..4b081f6cfdcb 100644 >> --- a/drivers/gpu/drm/exynos/exynos_hdmi.c >> +++ b/drivers/gpu/drm/exynos/exynos_hdmi.c >> @@ -1239,6 +1239,17 @@ static void hdmi_v13_mode_apply(struct hdmi_context >> *hdata) >> static void hdmi_v14_mode_apply(struct hdmi_context *hdata) >> { >> struct drm_display_mode *m = &hdata->encoder.crtc->state->mode; >> +struct drm_display_mode *am = >> &hdata->encoder.crtc->state->adjusted_mode; >> +int hquirk = 0; >> + >> +/* >> + * In case video mode coming from CRTC differs from requested one HDMI >> + * sometimes is able to almost properly perform conversion - only >> + * first line is distorted. >> + */ >> +if ((m->vdisplay != am->vdisplay) && >> +(m->hdisplay == 1280 || m->hdisplay == 1024)) >> +hquirk = 258; > Andrzej, > > The distorted value couldn't be described logically? Just I wonder why the > difference happens. Without low level documentation of the IP one could only guess what happens there. In case of 1024x768 one can reason as follows: - mixer sends image in format 1280x720, so it sends 1280 - 1024 = 256 pixels too much, so if we trim it in HDMI by 256 it should display it correctly, - but another quirk few lines later suppress 2 pixels from hsync_(start,end), so to balance it we should add these pixels here, so finally we have 256 + 2 = 258. This explanation seems quite reasonable, except it does not work for 1280x1024 mode. Regards Andrzej > > Thanks, > Inki Dae > >> >> hdmi_reg_writev(hdata, HDMI_H_BLANK_0, 2, m->htotal - m->hdisplay); >> hdmi_reg_writev(hdata, HDMI_V_LINE_0, 2, m->vtotal); >> @@ -1332,8 +1343,8 @@ static void hdmi_v14_mode_apply(struct hdmi_context >> *hdata) >> hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_6_0, 2, 0x); >> >> hdmi_reg_writev(hdata, HDMI_TG_H_FSZ_L, 2, m->htotal); >> -hdmi_reg_writev(hdata, HDMI_TG_HACT_ST_L, 2, m->htotal - m->hdisplay); >> -hdmi_reg_writev(hdata, HDMI_TG_HACT_SZ_L, 2, m->hdisplay); >> +hdmi_reg_writev(hdata, HDMI_TG_HACT_ST_L, 2, m->htotal - m->hdisplay - >> hquirk); >> +hdmi_reg_writev(hdata, HDMI_TG_HACT_SZ_L, 2, m->hdisplay + hquirk); >> hdmi_reg_writev(hdata, HDMI_TG_V_FSZ_L, 2, m->vtotal); >> if (hdata->drv_data == &exynos5433_hdmi_driver_data) >> hdmi_reg_writeb(hdata, HDMI_TG_DECON_EN, 1); >> > ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 2/4] dt-bindings: display: amlogic, meson-dw-hdmi: Add optional HDMI 5V regulator
On reference boards and derivatives, the HDMI Logic is powered by an external 5V regulator. This regulator was set by the Vendor U-Boot, add optional support for it. Signed-off-by: Neil Armstrong --- Documentation/devicetree/bindings/display/amlogic,meson-dw-hdmi.txt | 4 1 file changed, 4 insertions(+) diff --git a/Documentation/devicetree/bindings/display/amlogic,meson-dw-hdmi.txt b/Documentation/devicetree/bindings/display/amlogic,meson-dw-hdmi.txt index 7f040ed..bf4a180 100644 --- a/Documentation/devicetree/bindings/display/amlogic,meson-dw-hdmi.txt +++ b/Documentation/devicetree/bindings/display/amlogic,meson-dw-hdmi.txt @@ -48,6 +48,10 @@ Required properties: Documentation/devicetree/bindings/reset/reset.txt, the reset-names should be "hdmitx_apb", "hdmitx", "hdmitx_phy" +Optional properties: +- hdmi-supply: Optional phandle to an external 5V regulator to power the HDMI + logic, as described in the file ../regulator/regulator.txt + Required nodes: The connections to the HDMI ports are modeled using the OF graph -- 2.7.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 0/4] drm/meson: power domain init related fixes
On the Amlogic Gx SoCs (GXBB, GXL & GXM), the VPU power domain is initialized by the vendor U-Boot code, but running mainline U-boot has been possible on these SoCs. But lacking such init made the system lock at kernel boot. A PM Power Domain driver has been pushed at [1] to solve the main issue. The following patches : - updates the DT bindings accordingly - adds support for missing regulators and registers init Neil Armstrong (4): dt-bindings: display: amlogic,meson-vpu: Add optional power domain property dt-bindings: display: amlogic,meson-dw-hdmi: Add optional HDMI 5V regulator drm/meson: dw_hdmi: Add support for an optional external 5V regulator drm/meson: Add missing VPU init .../devicetree/bindings/display/amlogic,meson-dw-hdmi.txt | 4 .../devicetree/bindings/display/amlogic,meson-vpu.txt | 4 drivers/gpu/drm/meson/meson_drv.c | 9 + drivers/gpu/drm/meson/meson_dw_hdmi.c | 13 + drivers/gpu/drm/meson/meson_registers.h | 4 5 files changed, 34 insertions(+) -- 2.7.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 1/4] dt-bindings: display: amlogic, meson-vpu: Add optional power domain property
The Video Processing Unit power domain was setup by the Vendor U-Boot, add support for an optional Power Domain phandle to setup it from the kernel. Signed-off-by: Neil Armstrong --- Documentation/devicetree/bindings/display/amlogic,meson-vpu.txt | 4 1 file changed, 4 insertions(+) diff --git a/Documentation/devicetree/bindings/display/amlogic,meson-vpu.txt b/Documentation/devicetree/bindings/display/amlogic,meson-vpu.txt index 00f74ba..057b813 100644 --- a/Documentation/devicetree/bindings/display/amlogic,meson-vpu.txt +++ b/Documentation/devicetree/bindings/display/amlogic,meson-vpu.txt @@ -64,6 +64,10 @@ Required properties: - reg-names: should contain the names of the previous memory regions - interrupts: should contain the VENC Vsync interrupt number +Optional properties: +- power-domains: Optional phandle to associated power domain as described in + the file ../power/power_domain.txt + Required nodes: The connections to the VPU output video ports are modeled using the OF graph -- 2.7.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 3/4] drm/meson: dw_hdmi: Add support for an optional external 5V regulator
On reference boards and derivatives, the HDMI Logic is powered by an external 5V regulator. This regulator was set by the Vendor U-Boot, add optional support for it. Signed-off-by: Neil Armstrong --- drivers/gpu/drm/meson/meson_dw_hdmi.c | 13 + 1 file changed, 13 insertions(+) diff --git a/drivers/gpu/drm/meson/meson_dw_hdmi.c b/drivers/gpu/drm/meson/meson_dw_hdmi.c index cef4144..17de3af 100644 --- a/drivers/gpu/drm/meson/meson_dw_hdmi.c +++ b/drivers/gpu/drm/meson/meson_dw_hdmi.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -137,6 +138,7 @@ struct meson_dw_hdmi { struct reset_control *hdmitx_phy; struct clk *hdmi_pclk; struct clk *venci_clk; + struct regulator *hdmi_supply; u32 irq_stat; }; #define encoder_to_meson_dw_hdmi(x) \ @@ -751,6 +753,17 @@ static int meson_dw_hdmi_bind(struct device *dev, struct device *master, dw_plat_data = &meson_dw_hdmi->dw_plat_data; encoder = &meson_dw_hdmi->encoder; + meson_dw_hdmi->hdmi_supply = devm_regulator_get_optional(dev, "hdmi"); + if (IS_ERR(meson_dw_hdmi->hdmi_supply)) { + if (PTR_ERR(meson_dw_hdmi->hdmi_supply) == -EPROBE_DEFER) + return -EPROBE_DEFER; + meson_dw_hdmi->hdmi_supply = NULL; + } else { + ret = regulator_enable(meson_dw_hdmi->hdmi_supply); + if (ret) + return ret; + } + meson_dw_hdmi->hdmitx_apb = devm_reset_control_get_exclusive(dev, "hdmitx_apb"); if (IS_ERR(meson_dw_hdmi->hdmitx_apb)) { -- 2.7.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 4/4] drm/meson: Add missing VPU init
The VPU init misses these configurations values. Signed-off-by: Neil Armstrong --- drivers/gpu/drm/meson/meson_drv.c | 9 + drivers/gpu/drm/meson/meson_registers.h | 4 2 files changed, 13 insertions(+) diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c index 7742c7d..19a0d8d 100644 --- a/drivers/gpu/drm/meson/meson_drv.c +++ b/drivers/gpu/drm/meson/meson_drv.c @@ -150,6 +150,14 @@ static struct regmap_config meson_regmap_config = { .max_register = 0x1000, }; +static void meson_vpu_init(struct meson_drm *priv) +{ + writel_relaxed(0x21, priv->io_base + _REG(VPU_RDARB_MODE_L1C1)); + writel_relaxed(0x1, priv->io_base + _REG(VPU_RDARB_MODE_L1C2)); + writel_relaxed(0x90, priv->io_base + _REG(VPU_RDARB_MODE_L2C1)); + writel_relaxed(0x2, priv->io_base + _REG(VPU_WRARB_MODE_L2C1)); +} + static int meson_drv_bind_master(struct device *dev, bool has_components) { struct platform_device *pdev = to_platform_device(dev); @@ -221,6 +229,7 @@ static int meson_drv_bind_master(struct device *dev, bool has_components) /* Hardware Initialization */ + meson_vpu_init(priv); meson_venc_init(priv); meson_vpp_init(priv); meson_viu_init(priv); diff --git a/drivers/gpu/drm/meson/meson_registers.h b/drivers/gpu/drm/meson/meson_registers.h index 2847381..bca8714 100644 --- a/drivers/gpu/drm/meson/meson_registers.h +++ b/drivers/gpu/drm/meson/meson_registers.h @@ -1363,6 +1363,10 @@ #define VPU_PROT3_STAT_1 0x277a #define VPU_PROT3_STAT_2 0x277b #define VPU_PROT3_REQ_ONOFF 0x277c +#define VPU_RDARB_MODE_L1C1 0x2790 +#define VPU_RDARB_MODE_L1C2 0x2799 +#define VPU_RDARB_MODE_L2C1 0x279d +#define VPU_WRARB_MODE_L2C1 0x27a2 /* osd super scale */ #define OSDSR_HV_SIZEIN 0x3130 -- 2.7.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v2 10/11] drm/exynos/mixer: enable support for 1024x768 and 1280x1024 modes
On 17.10.2017 09:48, Inki Dae wrote: > > 2017년 09월 29일 19:05에 Andrzej Hajda 이(가) 쓴 글: >> Since HDMI can handle these modes despite of MIXER limitations let's >> enable them. >> >> Signed-off-by: Andrzej Hajda >> Reviewed-by: Tobias Jakobi >> --- >> drivers/gpu/drm/exynos/exynos_mixer.c | 3 +++ >> 1 file changed, 3 insertions(+) >> >> diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c >> b/drivers/gpu/drm/exynos/exynos_mixer.c >> index 8baa93f80106..85d33137cfd8 100644 >> --- a/drivers/gpu/drm/exynos/exynos_mixer.c >> +++ b/drivers/gpu/drm/exynos/exynos_mixer.c >> @@ -1014,6 +1014,9 @@ static int mixer_mode_valid(struct exynos_drm_crtc >> *crtc, >> (w >= 1664 && w <= 1920 && h >= 936 && h <= 1080)) >> return MODE_OK; >> >> +if ((w == 1024 && h == 768) || (w == 1280 && h == 1024)) >> +return MODE_OK; > mixer_mode_valid function is common to all Exynos SoC managed by Exynos DRM > driver. > So is it valid for all of them? It is valid for all SoCs having mixer, it was tested on Odroid U3(Exynos4412) and XU3 (Exynos5422). Regards Andrzej > > Thanks, > Inki Dae > > > >> + >> return MODE_BAD; >> } >> >> > ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[RFC PATCH v3 0/5] rockchip: kevin: Enable edp display
Make edp display works on chromebook kevin(at least for boot animation). Also solve some issues i meet during the bringup. Changes in v3: Assign orphan pwms to dummy pwmchip instead of adding device link in the customer driver. Changes in v2: Use device link to correct the suspend/resume and shutdown ordering, instead of converting rockchip spi's suspend/resume PM callbacks to late suspend/resume PM callbacks. Jeffy Chen (4): arm64: dts: rockchip: Enable edp disaplay on kevin drm/rockchip: Fix error handling path in rockchip_dp_bind() pwm: Add dummy pwmchip for orphan pwms drm/rockchip: Add device links for master and components Tomasz Figa (1): drm/bridge/analogix: Do not use device's drvdata arch/arm64/boot/dts/rockchip/rk3399-gru-kevin.dts | 29 arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi | 16 + drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 50 ++--- drivers/gpu/drm/exynos/exynos_dp.c | 26 --- drivers/gpu/drm/rockchip/analogix_dp-rockchip.c| 57 +-- drivers/gpu/drm/rockchip/rockchip_drm_drv.c| 24 ++- drivers/pwm/core.c | 84 -- include/drm/bridge/analogix_dp.h | 19 ++--- 8 files changed, 226 insertions(+), 79 deletions(-) -- 2.11.0 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[RFC PATCH v3 3/5] drm/bridge/analogix: Do not use device's drvdata
From: Tomasz Figa The driver that instantiates the bridge should own the drvdata, as all driver model callbacks (probe, remove, shutdown, PM ops, etc.) are also owned by its driver struct. Moreover, storing two different pointer types in driver data depending on driver initialization status is barely a good practice and in fact has led to many bugs in this driver. Let's clean up this mess and change Analogix entry points to simply accept some opaque struct pointer, adjusting their users at the same time to avoid breaking the compilation. Signed-off-by: Tomasz Figa Signed-off-by: Jeffy Chen Reviewed-by: Andrzej Hajda --- Changes in v3: None Changes in v2: None drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 50 +- drivers/gpu/drm/exynos/exynos_dp.c | 26 ++- drivers/gpu/drm/rockchip/analogix_dp-rockchip.c| 47 +++- include/drm/bridge/analogix_dp.h | 19 4 files changed, 73 insertions(+), 69 deletions(-) diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c index 5dd3f1cd074a..74d274b6d31d 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c @@ -98,17 +98,15 @@ static int analogix_dp_detect_hpd(struct analogix_dp_device *dp) return 0; } -int analogix_dp_psr_supported(struct device *dev) +int analogix_dp_psr_supported(struct analogix_dp_device *dp) { - struct analogix_dp_device *dp = dev_get_drvdata(dev); return dp->psr_support; } EXPORT_SYMBOL_GPL(analogix_dp_psr_supported); -int analogix_dp_enable_psr(struct device *dev) +int analogix_dp_enable_psr(struct analogix_dp_device *dp) { - struct analogix_dp_device *dp = dev_get_drvdata(dev); struct edp_vsc_psr psr_vsc; if (!dp->psr_support) @@ -129,9 +127,8 @@ int analogix_dp_enable_psr(struct device *dev) } EXPORT_SYMBOL_GPL(analogix_dp_enable_psr); -int analogix_dp_disable_psr(struct device *dev) +int analogix_dp_disable_psr(struct analogix_dp_device *dp) { - struct analogix_dp_device *dp = dev_get_drvdata(dev); struct edp_vsc_psr psr_vsc; int ret; @@ -1281,8 +1278,9 @@ static ssize_t analogix_dpaux_transfer(struct drm_dp_aux *aux, return analogix_dp_transfer(dp, msg); } -int analogix_dp_bind(struct device *dev, struct drm_device *drm_dev, -struct analogix_dp_plat_data *plat_data) +struct analogix_dp_device * +analogix_dp_bind(struct device *dev, struct drm_device *drm_dev, +struct analogix_dp_plat_data *plat_data) { struct platform_device *pdev = to_platform_device(dev); struct analogix_dp_device *dp; @@ -1292,14 +1290,12 @@ int analogix_dp_bind(struct device *dev, struct drm_device *drm_dev, if (!plat_data) { dev_err(dev, "Invalided input plat_data\n"); - return -EINVAL; + return ERR_PTR(-EINVAL); } dp = devm_kzalloc(dev, sizeof(struct analogix_dp_device), GFP_KERNEL); if (!dp) - return -ENOMEM; - - dev_set_drvdata(dev, dp); + return ERR_PTR(-ENOMEM); dp->dev = &pdev->dev; dp->dpms_mode = DRM_MODE_DPMS_OFF; @@ -1316,7 +1312,7 @@ int analogix_dp_bind(struct device *dev, struct drm_device *drm_dev, ret = analogix_dp_dt_parse_pdata(dp); if (ret) - return ret; + return ERR_PTR(ret); dp->phy = devm_phy_get(dp->dev, "dp"); if (IS_ERR(dp->phy)) { @@ -1330,14 +1326,14 @@ int analogix_dp_bind(struct device *dev, struct drm_device *drm_dev, if (ret == -ENOSYS || ret == -ENODEV) dp->phy = NULL; else - return ret; + return ERR_PTR(ret); } } dp->clock = devm_clk_get(&pdev->dev, "dp"); if (IS_ERR(dp->clock)) { dev_err(&pdev->dev, "failed to get clock\n"); - return PTR_ERR(dp->clock); + return ERR_CAST(dp->clock); } clk_prepare_enable(dp->clock); @@ -1346,7 +1342,7 @@ int analogix_dp_bind(struct device *dev, struct drm_device *drm_dev, dp->reg_base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(dp->reg_base)) - return PTR_ERR(dp->reg_base); + return ERR_CAST(dp->reg_base); dp->force_hpd = of_property_read_bool(dev->of_node, "force-hpd"); @@ -1367,7 +1363,7 @@ int analogix_dp_bind(struct device *dev, struct drm_device *drm_dev, "hpd_gpio"); if (ret) { dev_err(&pdev->dev, "failed to get hpd gpio\n"); - return ret; + return ERR_PTR(ret); }
[RFC PATCH v3 5/5] drm/rockchip: Add device links for master and components
Since we are trying to access components' resources in the master's suspend/resume PM callbacks(e.g. panel), add device links to correct the suspend/resume and shutdown ordering. Signed-off-by: Jeffy Chen --- Changes in v3: None Changes in v2: Use device link to correct the suspend/resume and shutdown ordering, instead of converting rockchip spi's suspend/resume PM callbacks to late suspend/resume PM callbacks. drivers/gpu/drm/rockchip/rockchip_drm_drv.c | 24 +--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c index 76d63de5921d..af18967f699b 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c @@ -337,6 +337,8 @@ static struct component_match *rockchip_drm_match_add(struct device *dev) if (!d) break; + + device_link_add(dev, d, DL_FLAG_STATELESS); component_match_add(dev, &match, compare_dev, d); } while (true); } @@ -406,6 +408,7 @@ static int rockchip_drm_platform_of_probe(struct device *dev) static int rockchip_drm_platform_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; + struct device_link *link; struct component_match *match = NULL; int ret; @@ -414,16 +417,31 @@ static int rockchip_drm_platform_probe(struct platform_device *pdev) return ret; match = rockchip_drm_match_add(dev); - if (IS_ERR(match)) - return PTR_ERR(match); + if (IS_ERR(match)) { + ret = PTR_ERR(match); + goto err_cleanup_dev_links; + } - return component_master_add_with_match(dev, &rockchip_drm_ops, match); + ret = component_master_add_with_match(dev, &rockchip_drm_ops, match); + if (ret < 0) + goto err_cleanup_dev_links; + + return 0; +err_cleanup_dev_links: + list_for_each_entry(link, &dev->links.consumers, s_node) + device_link_del(link); + return ret; } static int rockchip_drm_platform_remove(struct platform_device *pdev) { + struct device_link *link; + component_master_del(&pdev->dev, &rockchip_drm_ops); + list_for_each_entry(link, &pdev->dev.links.consumers, s_node) + device_link_del(link); + return 0; } -- 2.11.0 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[RFC PATCH v3 2/5] drm/rockchip: Fix error handling path in rockchip_dp_bind()
Add missing error handling in rockchip_dp_bind(). Fixes: 9e32e16e9e98 ("drm: rockchip: dp: add rockchip platform dp driver") Signed-off-by: Jeffy Chen --- Changes in v3: None Changes in v2: None drivers/gpu/drm/rockchip/analogix_dp-rockchip.c | 14 -- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c index 4d3f6ad0abdd..cb8941e8bcdd 100644 --- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c +++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c @@ -371,7 +371,7 @@ static int rockchip_dp_bind(struct device *dev, struct device *master, ret = rockchip_dp_drm_create_encoder(dp); if (ret) { DRM_ERROR("failed to create drm encoder\n"); - return ret; + goto err_deinit_dp; } dp->plat_data.encoder = &dp->encoder; @@ -387,7 +387,17 @@ static int rockchip_dp_bind(struct device *dev, struct device *master, rockchip_drm_psr_register(&dp->encoder, analogix_dp_psr_set); - return analogix_dp_bind(dev, dp->drm_dev, &dp->plat_data); + ret = analogix_dp_bind(dev, dp->drm_dev, &dp->plat_data); + if (ret < 0) + goto err_unreg_psr; + return 0; + +err_unreg_psr: + rockchip_drm_psr_unregister(&dp->encoder); + rockchip_dp_drm_encoder_destroy(&dp->encoder); +err_deinit_dp: + clk_disable_unprepare(dp->pclk); + return ret; } static void rockchip_dp_unbind(struct device *dev, struct device *master, -- 2.11.0 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: linux-next: manual merge of the drm-intel tree with the drm-intel-fixes tree
On Mon, Oct 16, 2017 at 1:35 PM, Mark Brown wrote: > Hi all, > > Today's linux-next merge of the drm-intel tree got a conflict in: > > drivers/gpu/drm/i915/i915_gem.c > > between commit: > > b85577b72837e ("drm/i915: Order two completing nop_submit_request") > > from the drm-intel-fixes tree and commit: > > 5d031f4e1618b ("drm/i915: Stop asserting on set-wedged vs > nop_submit_request ordering") > > from the drm-intel tree. > > I fixed it up (see below) and can carry the fix as necessary. This > is now fixed as far as linux-next is concerned, but any non trivial > conflicts should be mentioned to your upstream maintainer when your tree > is submitted for merging. You may also want to consider cooperating > with the maintainer of the conflicting tree to minimise any particularly > complex conflicts. This merge seems fine, but it seems there was another merge against the akpm tree that introduced a build error by reintroducing the spin_lock_irqsave() without restoring the local variable: drivers/gpu/drm/i915/i915_gem.c: In function 'nop_submit_request': drivers/gpu/drm/i915/i915_gem.c:3092:54: error: 'flags' undeclared (first use in this function); did you mean 'class'? I'll send my local build fix, which may or may not be the intended behavior but gets it to compile. Arnd ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [RESEND PATCH v2 2/5] backlight: pwm_bl: Add device link for pwm_bl and pwm
Hi Brian, On 10/17/2017 07:57 AM, Brian Norris wrote: This is going to be a*lot* of churn throughout the tree, if we expect all resource consumers to do this. I think we'd want some kind of agreement from the PM maintainers and (larger) subsystem owners before going down this route... And in the PWM case, pwm_get() already has the device pointer. Why can't we just instrument it instead? according to pwm_bl driver, we may need to take care of pwm_request() too: pb->pwm = devm_pwm_get(&pdev->dev, NULL); if (IS_ERR(pb->pwm) && PTR_ERR(pb->pwm) != -EPROBE_DEFER && !node) { dev_err(&pdev->dev, "unable to request PWM, trying legacy API\n"); pb->legacy = true; pb->pwm = pwm_request(data->pwm_id, "pwm-backlight"); } and maybe also *of_pwm_get... maybe we can add a dummy pwm chip for those orphan pwms? Brian ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [GIT PULL] tilcdc changes for 4.15
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki On 10/16/17 12:18, Daniel Vetter wrote: > On Sat, Oct 14, 2017 at 05:52:32PM +0300, Jyri Sarha wrote: >> Hi Dave, >> Please pull the accumulated minor tilcdc changes and fixed for >> v4.15. These small patches have been accumulated over a period of >> several Linux releases. > > Why are patches stuck for several releases? Another candidate for drm-misc > where you just get the pull request train provided for you? > -Daniel > Well, I simply missed the v4.14 release and the pushing of the three first patches were delayed by one release. Sorry about that. I was quite busy at the time. The only patches that were delayed for several releases were my own, which I simply was not confident about in the earlier releases. Best regards, Jyri >> >> Best regards and thanks, >> Jyri >> >> The following changes since commit ebec44a2456fbe5fe18aae88f6010f6878f0cb4a: >> >> BackMerge tag 'v4.14-rc3' into drm-next (2017-10-03 09:35:04 +1000) >> >> are available in the git repository at: >> >> >> https://github.com/jsarha/linux tags/tilcdc-4.15 >> >> for you to fetch changes up to 44cd3939c111b78a9fc6e3136fb0f9b6f475f68a: >> >> drm/tilcdc: Remove redundant OF_DETACHED flag setting (2017-10-13 >> 15:25:11 +0300) >> >> >> tilcdc changes for v4.15 >> >> >> Arvind Yadav (2): >> drm/tilcdc: tilcdc_panel: make of_device_ids const. >> drm/tilcdc: tilcdc_tfp410: make of_device_ids const. >> >> Cihangir Akturk (1): >> drm/tilcdc: switch to drm_*{get,put} helpers >> >> Jyri Sarha (4): >> drm/tilcdc: Turn raster off in crtc reset, if it was on in the HW >> drm/tilcdc: Remove WARN_ON(!drm_modeset_is_locked(&crtc->mutex)) >> checks >> drm/tilcdc: Use tilcdc_crtc_shutdown() in tilcdc_crtc_destroy() >> drm/tilcdc: Precalculate total frametime in tilcdc_crtc_set_mode() >> >> Stephen Boyd (1): >> drm/tilcdc: Remove redundant OF_DETACHED flag setting >> >> drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 57 >> ++-- >> drivers/gpu/drm/tilcdc/tilcdc_panel.c| 2 +- >> drivers/gpu/drm/tilcdc/tilcdc_slave_compat.c | 1 - >> drivers/gpu/drm/tilcdc/tilcdc_tfp410.c | 4 +- >> 4 files changed, 47 insertions(+), 17 deletions(-) >> >> Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. >> Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki >> >> > ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH] linux-next: drm/i916: fix nop_submit_request mismerge
A mismerge in linux-next caused a build failure: drivers/gpu/drm/i915/i915_gem.c: In function 'nop_submit_request': drivers/gpu/drm/i915/i915_gem.c:3092:54: error: 'flags' undeclared (first use in this function); did you mean 'class'? This is the fixup I used to get a clean build on top of today's tree. I don't know which of the versions is the one we want, so this may just as well be wrong. Fixes: 05724bd054c3 ("Merge branch 'akpm/master'") Signed-off-by: Arnd Bergmann --- drivers/gpu/drm/i915/i915_gem.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index b4b62f427a99..ee2aee869dc6 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -3087,6 +3087,8 @@ void i915_gem_reset_finish(struct drm_i915_private *dev_priv) static void nop_submit_request(struct drm_i915_gem_request *request) { + unsigned long flags; + dma_fence_set_error(&request->fence, -EIO); spin_lock_irqsave(&request->engine->timeline->lock, flags); -- 2.9.0 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: linux-next: manual merge of the drm-intel tree with the drm-intel-fixes tree
On Tue, Oct 17, 2017 at 10:11:53AM +0200, Arnd Bergmann wrote: > This merge seems fine, but it seems there was another merge > against the akpm tree that introduced a build error by reintroducing > the spin_lock_irqsave() without restoring the local variable: > drivers/gpu/drm/i915/i915_gem.c: In function 'nop_submit_request': > drivers/gpu/drm/i915/i915_gem.c:3092:54: error: 'flags' undeclared > (first use in this function); did you mean 'class'? > I'll send my local build fix, which may or may not be the intended > behavior but gets it to compile. Bother, that was actually an automated merge git did. signature.asc Description: PGP signature ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 00/12] of: overlay: clean up device tree overlay code
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki On 10/05/17 11:33, Jyri Sarha wrote: > On 10/05/17 09:53, Tomi Valkeinen wrote: >> On 04/10/17 17:56, Rob Herring wrote: >>> On Mon, Oct 2, 2017 at 10:53 PM, wrote: From: Frank Rowand I have found the device tree overlay code to be difficult to read and maintain. This patch series attempts to improve that situation. The cleanup includes some changes visible to users of overlays. The only in kernel user of overlays is fixed up for those changes. The in kernel user is: drivers/gpu/drm/tilcdc/tilcdc_slave_compat.c >>> >>> At what point can we remove this? I'm assuming at some point users >>> will need to update their dtb's for other reasons and this becomes >>> obsolete. >> >> To be honest, I have no idea, or how to find that out. >> > > I think the first approach could be setting the DRM_TILCDC_SLAVE_COMPAT > default to n and listen if there is any reports about breakage. > After giving it more thought. Maybe we can drop the DRM_TILCDC_SLAVE_COMPAT in v4.16. 2017 LTS is out already, so there should be plenty of time for whoever is still using the legacy DTBs to get rid of them. >> Do we need to get rid of it? Afaik, we haven't do much (or any?) >> maintenance on tilcdc_slave_compat.c since it was written, so from our >> perspective it's been a minimal burden. Is it creating burden for others? >> >> Is the approach done with tilcdc_slave_compat.c something that's not >> recommended? I'm sure similar situations happen with other drivers too, >> and I think it's a good idea to have a recommended way of keeping >> compatibility. >> > > For tilcdc I would say that we soon need a similar mechanism to get rid > off tilcdc internal panel driver and to start using generic panel > drivers instead. That is, if we want to keep the kernel compatible with > old devicetree blobs. > Actually for tilcdc this is not that bad. The messy tilcdc slave mechanism has been gotten rid of. The rest of tilcdc specific legacy drivers - the tilcdc legacy panel support and the tilcdc legacy tfp410 driver - do not have any external dependencies and they can basically remain there for ever for backward compatibility. But in general, a generic mechanism to translate legacy DTBs to follow a new binding would be a handy tool in keeping the drivers clean while keeping up the support for legacy DTBs. Best regards, Jyri ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [RFC v2 7/8] drm/mediatek: Add DRM-based framebuffer device
Hi Ulrich, On Mon, 2017-10-16 at 17:31 +0200, Ulrich Hecht wrote: > Add fbdev support to the Mediatek DRM driver. > > Signed-off-by: CK Hu > Signed-off-by: YT Shen > Signed-off-by: Philipp Zabel > Signed-off-by: Daniel Kurtz > [uli: Forward-ported from chromeos-3.18 vendor kernel.] > Signed-off-by: Ulrich Hecht > --- > drivers/gpu/drm/mediatek/Makefile| 2 + > drivers/gpu/drm/mediatek/mtk_drm_drv.c | 8 ++ > drivers/gpu/drm/mediatek/mtk_drm_drv.h | 4 +- > drivers/gpu/drm/mediatek/mtk_drm_fb.c| 13 +++ > drivers/gpu/drm/mediatek/mtk_drm_fb.h| 3 + > drivers/gpu/drm/mediatek/mtk_drm_fbdev.c | 181 > +++ > drivers/gpu/drm/mediatek/mtk_drm_fbdev.h | 32 ++ > 7 files changed, 242 insertions(+), 1 deletion(-) > create mode 100644 drivers/gpu/drm/mediatek/mtk_drm_fbdev.c > create mode 100644 drivers/gpu/drm/mediatek/mtk_drm_fbdev.h > > diff --git a/drivers/gpu/drm/mediatek/Makefile > b/drivers/gpu/drm/mediatek/Makefile > index e37b55a..8306fb5 100644 > --- a/drivers/gpu/drm/mediatek/Makefile > +++ b/drivers/gpu/drm/mediatek/Makefile > @@ -12,6 +12,8 @@ mediatek-drm-y := mtk_disp_color.o \ > mtk_mipi_tx.o \ > mtk_dpi.o > > +mediatek-drm-$(CONFIG_DRM_FBDEV_EMULATION) += mtk_drm_fbdev.o > + > obj-$(CONFIG_DRM_MEDIATEK) += mediatek-drm.o > > mediatek-drm-hdmi-objs := mtk_cec.o \ > diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c > b/drivers/gpu/drm/mediatek/mtk_drm_drv.c > index ce99921..636b8db 100644 > --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c > +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c > @@ -30,6 +30,7 @@ > #include "mtk_drm_ddp_comp.h" > #include "mtk_drm_drv.h" > #include "mtk_drm_fb.h" > +#include "mtk_drm_fbdev.h" > #include "mtk_drm_gem.h" > > #define DRIVER_NAME "mediatek" > @@ -257,8 +258,14 @@ static int mtk_drm_kms_init(struct drm_device *drm) > drm_kms_helper_poll_init(drm); > drm_mode_config_reset(drm); > > + ret = mtk_fbdev_init(drm); > + if (ret) > + goto err_kms_helper_poll_fini; > + > return 0; > > +err_kms_helper_poll_fini: > + drm_kms_helper_poll_fini(drm); > err_component_unbind: > component_unbind_all(drm->dev, drm); > err_config_cleanup: > @@ -269,6 +276,7 @@ static int mtk_drm_kms_init(struct drm_device *drm) > > static void mtk_drm_kms_deinit(struct drm_device *drm) > { > + mtk_fbdev_fini(drm); > drm_kms_helper_poll_fini(drm); > > component_unbind_all(drm->dev, drm); > diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.h > b/drivers/gpu/drm/mediatek/mtk_drm_drv.h > index c3378c4..4edc002 100644 > --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.h > +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.h > @@ -14,6 +14,7 @@ > #ifndef MTK_DRM_DRV_H > #define MTK_DRM_DRV_H > > +#include > #include > #include "mtk_drm_ddp_comp.h" > > @@ -24,7 +25,6 @@ struct device; > struct device_node; > struct drm_crtc; > struct drm_device; > -struct drm_fb_helper; > struct drm_property; > struct regmap; > > @@ -56,6 +56,8 @@ struct mtk_drm_private { > } commit; > > struct drm_atomic_state *suspend_state; > + struct drm_fb_helper fb_helper; > + struct drm_gem_object *fbdev_bo; > }; > > extern struct platform_driver mtk_ddp_driver; > diff --git a/drivers/gpu/drm/mediatek/mtk_drm_fb.c > b/drivers/gpu/drm/mediatek/mtk_drm_fb.c > index 0d8d506..ac8561d 100644 > --- a/drivers/gpu/drm/mediatek/mtk_drm_fb.c > +++ b/drivers/gpu/drm/mediatek/mtk_drm_fb.c > @@ -96,6 +96,19 @@ static struct mtk_drm_fb *mtk_drm_framebuffer_init(struct > drm_device *dev, > return mtk_fb; > } > > +struct drm_framebuffer *mtk_drm_framebuffer_create(struct drm_device *dev, > + const struct drm_mode_fb_cmd2 *mode, > + struct drm_gem_object *obj) > +{ > + struct mtk_drm_fb *mtk_fb; > + > + mtk_fb = mtk_drm_framebuffer_init(dev, mode, obj); > + if (IS_ERR(mtk_fb)) > + return ERR_CAST(mtk_fb); > + > + return &mtk_fb->base; > +} > + > /* > * Wait for any exclusive fence in fb's gem object's reservation object. > * > diff --git a/drivers/gpu/drm/mediatek/mtk_drm_fb.h > b/drivers/gpu/drm/mediatek/mtk_drm_fb.h > index 9b2ae34..9ee1ac2 100644 > --- a/drivers/gpu/drm/mediatek/mtk_drm_fb.h > +++ b/drivers/gpu/drm/mediatek/mtk_drm_fb.h > @@ -19,5 +19,8 @@ int mtk_fb_wait(struct drm_framebuffer *fb); > struct drm_framebuffer *mtk_drm_mode_fb_create(struct drm_device *dev, > struct drm_file *file, > const struct drm_mode_fb_cmd2 > *cmd); > +struct drm_framebuffer *mtk_drm_framebuffer_create(struct drm_device *dev, > + const struct drm_mode_fb_cmd2 *mode, > + struct drm_gem_object *obj); > > #endif /* MTK_DRM_FB_H */ > diff --git a/drivers/gpu/drm/mediatek/mtk_drm_fbdev.c > b/drivers/gpu/drm/mediatek/mtk_drm_fbdev.c > new file mode 100644 > in
[PATCH 02/23] drm/sun4i: Realign Makefile padding and reorder it
Some options were not padded as they should, and the order in the Makefile was chaotic. Fix that. Signed-off-by: Maxime Ripard --- drivers/gpu/drm/sun4i/Makefile | 28 ++-- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/sun4i/Makefile b/drivers/gpu/drm/sun4i/Makefile index 43c753cafc88..af18b70ba5ed 100644 --- a/drivers/gpu/drm/sun4i/Makefile +++ b/drivers/gpu/drm/sun4i/Makefile @@ -1,24 +1,24 @@ -sun4i-drm-y += sun4i_drv.o -sun4i-drm-y += sun4i_framebuffer.o +sun4i-backend-y+= sun4i_backend.o sun4i_layer.o -sun4i-drm-hdmi-y += sun4i_hdmi_enc.o -sun4i-drm-hdmi-y += sun4i_hdmi_i2c.o -sun4i-drm-hdmi-y += sun4i_hdmi_ddc_clk.o -sun4i-drm-hdmi-y += sun4i_hdmi_tmds_clk.o +sun4i-drm-y+= sun4i_drv.o +sun4i-drm-y+= sun4i_framebuffer.o -sun4i-tcon-y += sun4i_tcon.o -sun4i-tcon-y += sun4i_rgb.o -sun4i-tcon-y += sun4i_dotclock.o -sun4i-tcon-y += sun4i_crtc.o +sun4i-drm-hdmi-y += sun4i_hdmi_enc.o +sun4i-drm-hdmi-y += sun4i_hdmi_i2c.o +sun4i-drm-hdmi-y += sun4i_hdmi_ddc_clk.o +sun4i-drm-hdmi-y += sun4i_hdmi_tmds_clk.o -sun4i-backend-y += sun4i_backend.o sun4i_layer.o +sun4i-tcon-y += sun4i_tcon.o +sun4i-tcon-y += sun4i_rgb.o +sun4i-tcon-y += sun4i_dotclock.o +sun4i-tcon-y += sun4i_crtc.o -sun8i-mixer-y += sun8i_mixer.o sun8i_layer.o +sun8i-mixer-y += sun8i_mixer.o sun8i_layer.o obj-$(CONFIG_DRM_SUN4I)+= sun4i-drm.o sun4i-tcon.o obj-$(CONFIG_DRM_SUN4I)+= sun6i_drc.o obj-$(CONFIG_DRM_SUN4I)+= sun4i_tv.o -obj-$(CONFIG_DRM_SUN4I_BACKEND)+= sun4i-backend.o +obj-$(CONFIG_DRM_SUN4I_BACKEND)+= sun4i-backend.o obj-$(CONFIG_DRM_SUN4I_HDMI) += sun4i-drm-hdmi.o -obj-$(CONFIG_DRM_SUN8I_MIXER) += sun8i-mixer.o +obj-$(CONFIG_DRM_SUN8I_MIXER) += sun8i-mixer.o -- git-series 0.9.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 01/23] drm/sun4i: Implement endpoint parsing using kfifo
The commit da82b8785eeb ("drm/sun4i: add components in breadth first traversal order") implemented a breadth first traversal of our device tree nodes graph. However, it was relying on the kernel linked lists, and those are not really safe for addition. Indeed, in a single pipeline stage, your first stage (ie, the mixer or fronted) will be queued, and it will be the final iteration of that list as far as list_for_each_entry_safe is concerned. Then, during that final iteration, we'll queue another element (the TCON or the backend) that list_for_each_entry_safe will not account for, and we will leave the loop without having iterated over all the elements. And since we won't have built our components list properly, the DRM driver will be left non-functional. We can instead use a kfifo to queue and enqueue components in-order, as was the original intention. This also has the benefit of removing any dynamic allocation, making the error handling path simpler too. The only thing we're losing is the ability to tell whether an element has already been queued, but that was only needed to remove spurious logs, and therefore purely cosmetic. This means that this commit effectively reverses e8afb7b67fba ("drm/sun4i: don't add components that are already in the queue"). Fixes: da82b8785eeb ("drm/sun4i: add components in breadth first traversal order") Signed-off-by: Maxime Ripard --- drivers/gpu/drm/sun4i/sun4i_drv.c | 71 +--- 1 file changed, 13 insertions(+), 58 deletions(-) diff --git a/drivers/gpu/drm/sun4i/sun4i_drv.c b/drivers/gpu/drm/sun4i/sun4i_drv.c index b5879d4620d8..a27efad9bc76 100644 --- a/drivers/gpu/drm/sun4i/sun4i_drv.c +++ b/drivers/gpu/drm/sun4i/sun4i_drv.c @@ -11,6 +11,7 @@ */ #include +#include #include #include @@ -222,29 +223,15 @@ static int compare_of(struct device *dev, void *data) * matching system handles this for us. */ struct endpoint_list { - struct device_node *node; - struct list_head list; + DECLARE_KFIFO(fifo, struct device_node *, 16); }; -static bool node_is_in_list(struct list_head *endpoints, - struct device_node *node) -{ - struct endpoint_list *endpoint; - - list_for_each_entry(endpoint, endpoints, list) - if (endpoint->node == node) - return true; - - return false; -} - static int sun4i_drv_add_endpoints(struct device *dev, - struct list_head *endpoints, + struct endpoint_list *list, struct component_match **match, struct device_node *node) { struct device_node *port, *ep, *remote; - struct endpoint_list *endpoint; int count = 0; /* @@ -304,19 +291,7 @@ static int sun4i_drv_add_endpoints(struct device *dev, } } - /* skip downstream node if it is already in the queue */ - if (node_is_in_list(endpoints, remote)) - continue; - - /* Add downstream nodes to the queue */ - endpoint = kzalloc(sizeof(*endpoint), GFP_KERNEL); - if (!endpoint) { - of_node_put(remote); - return -ENOMEM; - } - - endpoint->node = remote; - list_add_tail(&endpoint->list, endpoints); + kfifo_put(&list->fifo, remote); } return count; @@ -325,10 +300,11 @@ static int sun4i_drv_add_endpoints(struct device *dev, static int sun4i_drv_probe(struct platform_device *pdev) { struct component_match *match = NULL; - struct device_node *np = pdev->dev.of_node; - struct endpoint_list *endpoint, *endpoint_temp; + struct device_node *np = pdev->dev.of_node, *endpoint; + struct endpoint_list list; int i, ret, count = 0; - LIST_HEAD(endpoints); + + INIT_KFIFO(list.fifo); for (i = 0;; i++) { struct device_node *pipeline = of_parse_phandle(np, @@ -337,31 +313,19 @@ static int sun4i_drv_probe(struct platform_device *pdev) if (!pipeline) break; - endpoint = kzalloc(sizeof(*endpoint), GFP_KERNEL); - if (!endpoint) { - ret = -ENOMEM; - goto err_free_endpoints; - } - - endpoint->node = pipeline; - list_add_tail(&endpoint->list, &endpoints); + kfifo_put(&list.fifo, pipeline); } - list_for_each_entry_safe(endpoint, endpoint_temp, &endpoints, list) { + while (kfifo_get(&list.fifo, &endpoint)) { /* process this endpoint */ - ret = sun4i_drv_add_endpoints(&pdev->dev, &endpoints, &match, - endpoint->node); + ret = sun4i_
[PATCH 03/23] drm/sun4i: tcon: Make tcon_set_mux mode argument const
The drm_display_mode pointer can be mark const, so let's do it. Signed-off-by: Maxime Ripard --- drivers/gpu/drm/sun4i/sun4i_tcon.c | 6 +++--- drivers/gpu/drm/sun4i/sun4i_tcon.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c b/drivers/gpu/drm/sun4i/sun4i_tcon.c index 68751b999877..54e1796d2953 100644 --- a/drivers/gpu/drm/sun4i/sun4i_tcon.c +++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c @@ -134,7 +134,7 @@ static struct sun4i_tcon *sun4i_get_tcon0(struct drm_device *drm) } void sun4i_tcon_set_mux(struct sun4i_tcon *tcon, int channel, - struct drm_encoder *encoder) + const struct drm_encoder *encoder) { int ret = -ENOTSUPP; @@ -783,7 +783,7 @@ static int sun4i_tcon_remove(struct platform_device *pdev) /* platform specific TCON muxing callbacks */ static int sun5i_a13_tcon_set_mux(struct sun4i_tcon *tcon, - struct drm_encoder *encoder) + const struct drm_encoder *encoder) { u32 val; @@ -799,7 +799,7 @@ static int sun5i_a13_tcon_set_mux(struct sun4i_tcon *tcon, } static int sun6i_tcon_set_mux(struct sun4i_tcon *tcon, - struct drm_encoder *encoder) + const struct drm_encoder *encoder) { struct sun4i_tcon *tcon0 = sun4i_get_tcon0(encoder->dev); u32 shift; diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.h b/drivers/gpu/drm/sun4i/sun4i_tcon.h index d9e1357cc8ae..d81c6e20efe6 100644 --- a/drivers/gpu/drm/sun4i/sun4i_tcon.h +++ b/drivers/gpu/drm/sun4i/sun4i_tcon.h @@ -152,7 +152,7 @@ struct sun4i_tcon_quirks { boolneeds_de_be_mux; /* sun6i needs mux to select backend */ /* callback to handle tcon muxing options */ - int (*set_mux)(struct sun4i_tcon *, struct drm_encoder *); + int (*set_mux)(struct sun4i_tcon *, const struct drm_encoder *); }; struct sun4i_tcon { -- git-series 0.9.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 17/23] arm: dts: sun8i: a83t: Add display pipeline
The display pipeline on the A83T is mainly composed of the mixers and TCONs, plus various encoders. Let's add the mixers and TCONs to the DTSI. Signed-off-by: Maxime Ripard --- arch/arm/boot/dts/sun8i-a83t.dtsi | 80 - 1 file changed, 80 insertions(+) diff --git a/arch/arm/boot/dts/sun8i-a83t.dtsi b/arch/arm/boot/dts/sun8i-a83t.dtsi index ce6e887c8938..57feeb6fee8b 100644 --- a/arch/arm/boot/dts/sun8i-a83t.dtsi +++ b/arch/arm/boot/dts/sun8i-a83t.dtsi @@ -151,6 +151,12 @@ }; }; + de: display-engine { + compatible = "allwinner,sun8i-a83t-display-engine"; + allwinner,pipelines = <&mixer0>; + status = "disabled"; + }; + memory { reg = <0x4000 0x8000>; device_type = "memory"; @@ -162,6 +168,46 @@ #size-cells = <1>; ranges; + display_clocks: clock@100 { + compatible = "allwinner,sun8i-a83t-de2-clk"; + reg = <0x0100 0x10>; + clocks = <&ccu CLK_PLL_DE>, +<&ccu CLK_BUS_DE>; + clock-names = "mod", + "bus"; + resets = <&ccu RST_BUS_DE>; + #clock-cells = <1>; + #reset-cells = <1>; + }; + + mixer0: mixer@110 { + compatible = "allwinner,sun8i-a83t-de2-mixer"; + reg = <0x0110 0x10>; + clocks = <&display_clocks 0>, +<&display_clocks 6>; + clock-names = "bus", + "mod"; + resets = <&display_clocks 0>; + assigned-clocks = <&display_clocks 6>; + assigned-clock-rates = <15000>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + mixer0_out: port@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + + mixer0_out_tcon0: endpoint@0 { + reg = <0>; + remote-endpoint = <&tcon0_in_mixer0>; + }; + }; + }; + }; + syscon: syscon@1c0 { compatible = "allwinner,sun8i-a83t-system-controller", "syscon"; @@ -177,6 +223,40 @@ #dma-cells = <1>; }; + tcon0: lcd-controller@1c0c000 { + compatible = "allwinner,sun8i-a83t-tcon"; + reg = <0x01c0c000 0x1000>; + interrupts = ; + clocks = <&ccu CLK_BUS_TCON0>, <&ccu CLK_TCON0>; + clock-names = "ahb", "tcon-ch0"; + clock-output-names = "tcon-pixel-clock"; + resets = <&ccu RST_BUS_TCON0>, <&ccu RST_BUS_LVDS>; + reset-names = "lcd", "lvds"; + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + tcon0_in: port@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + + tcon0_in_mixer0: endpoint@0 { + reg = <0>; + remote-endpoint = <&mixer0_out_tcon0>; + }; + }; + + tcon0_out: port@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + }; + }; + }; + mmc0: mmc@1c0f000 { compatible = "allwinner,sun8i-a83t-mmc", "allwinner,sun7i-a20-mmc"; -- git-series 0.9.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 15/23] drm/sun4i: Add LVDS support
The TCON supports the LVDS interface to output to a panel or a bridge. Let's add support for it. Signed-off-by: Maxime Ripard --- drivers/gpu/drm/sun4i/Makefile | 1 +- drivers/gpu/drm/sun4i/sun4i_lvds.c | 183 - drivers/gpu/drm/sun4i/sun4i_lvds.h | 18 +++- drivers/gpu/drm/sun4i/sun4i_tcon.c | 193 +- drivers/gpu/drm/sun4i/sun4i_tcon.h | 25 - 5 files changed, 419 insertions(+), 1 deletion(-) create mode 100644 drivers/gpu/drm/sun4i/sun4i_lvds.c create mode 100644 drivers/gpu/drm/sun4i/sun4i_lvds.h diff --git a/drivers/gpu/drm/sun4i/Makefile b/drivers/gpu/drm/sun4i/Makefile index cfba2c07519c..6fee15d016ef 100644 --- a/drivers/gpu/drm/sun4i/Makefile +++ b/drivers/gpu/drm/sun4i/Makefile @@ -10,6 +10,7 @@ sun4i-drm-hdmi-y += sun4i_hdmi_tmds_clk.o sun4i-tcon-y += sun4i_tcon.o sun4i-tcon-y += sun4i_rgb.o +sun4i-tcon-y += sun4i_lvds.o sun4i-tcon-y += sun4i_dotclock.o sun4i-tcon-y += sun4i_crtc.o diff --git a/drivers/gpu/drm/sun4i/sun4i_lvds.c b/drivers/gpu/drm/sun4i/sun4i_lvds.c new file mode 100644 index ..635a3f505ecb --- /dev/null +++ b/drivers/gpu/drm/sun4i/sun4i_lvds.c @@ -0,0 +1,183 @@ +/* + * Copyright (C) 2015 NextThing Co + * Copyright (C) 2015-2017 Free Electrons + * + * Maxime Ripard + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + */ + +#include + +#include +#include +#include +#include +#include + +#include "sun4i_crtc.h" +#include "sun4i_tcon.h" +#include "sun4i_lvds.h" + +struct sun4i_lvds { + struct drm_connectorconnector; + struct drm_encoder encoder; + + struct sun4i_tcon *tcon; +}; + +static inline struct sun4i_lvds * +drm_connector_to_sun4i_lvds(struct drm_connector *connector) +{ + return container_of(connector, struct sun4i_lvds, + connector); +} + +static inline struct sun4i_lvds * +drm_encoder_to_sun4i_lvds(struct drm_encoder *encoder) +{ + return container_of(encoder, struct sun4i_lvds, + encoder); +} + +static int sun4i_lvds_get_modes(struct drm_connector *connector) +{ + struct sun4i_lvds *lvds = + drm_connector_to_sun4i_lvds(connector); + struct sun4i_tcon *tcon = lvds->tcon; + + return drm_panel_get_modes(tcon->panel); +} + +static struct drm_connector_helper_funcs sun4i_lvds_con_helper_funcs = { + .get_modes = sun4i_lvds_get_modes, +}; + +static void +sun4i_lvds_connector_destroy(struct drm_connector *connector) +{ + struct sun4i_lvds *lvds = drm_connector_to_sun4i_lvds(connector); + struct sun4i_tcon *tcon = lvds->tcon; + + drm_panel_detach(tcon->panel); + drm_connector_cleanup(connector); +} + +static const struct drm_connector_funcs sun4i_lvds_con_funcs = { + .fill_modes = drm_helper_probe_single_connector_modes, + .destroy= sun4i_lvds_connector_destroy, + .reset = drm_atomic_helper_connector_reset, + .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, + .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, +}; + +static void sun4i_lvds_encoder_enable(struct drm_encoder *encoder) +{ + struct sun4i_lvds *lvds = drm_encoder_to_sun4i_lvds(encoder); + struct sun4i_tcon *tcon = lvds->tcon; + + DRM_DEBUG_DRIVER("Enabling LVDS output\n"); + + if (!IS_ERR(tcon->panel)) { + drm_panel_prepare(tcon->panel); + drm_panel_enable(tcon->panel); + } +} + +static void sun4i_lvds_encoder_disable(struct drm_encoder *encoder) +{ + struct sun4i_lvds *lvds = drm_encoder_to_sun4i_lvds(encoder); + struct sun4i_tcon *tcon = lvds->tcon; + + DRM_DEBUG_DRIVER("Disabling LVDS output\n"); + + if (!IS_ERR(tcon->panel)) { + drm_panel_disable(tcon->panel); + drm_panel_unprepare(tcon->panel); + } +} + +static const struct drm_encoder_helper_funcs sun4i_lvds_enc_helper_funcs = { + .disable= sun4i_lvds_encoder_disable, + .enable = sun4i_lvds_encoder_enable, +}; + +static const struct drm_encoder_funcs sun4i_lvds_enc_funcs = { + .destroy= drm_encoder_cleanup, +}; + +int sun4i_lvds_init(struct drm_device *drm, struct sun4i_tcon *tcon) +{ + struct drm_encoder *encoder; + struct drm_bridge *bridge; + struct sun4i_lvds *lvds; + int ret; + + lvds = devm_kzalloc(drm->dev, sizeof(*lvds), GFP_KERNEL); + if (!lvds) + return -ENOMEM; + lvds->tcon = tcon; + encoder = &lvds->encoder; + + ret = drm_of_find_panel_or_bridge(tcon->
[PATCH 09/23] drm/panel: lvds: Add support for the power-supply property
A significant number of panels need to power up a regulator in order to operate properly. Add support for the power-supply property to enable and disable such a regulator whenever needed. Signed-off-by: Maxime Ripard --- drivers/gpu/drm/panel/panel-lvds.c | 23 +++ 1 file changed, 23 insertions(+) diff --git a/drivers/gpu/drm/panel/panel-lvds.c b/drivers/gpu/drm/panel/panel-lvds.c index e2d57c01200b..57e38a9e7ab4 100644 --- a/drivers/gpu/drm/panel/panel-lvds.c +++ b/drivers/gpu/drm/panel/panel-lvds.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -39,6 +40,7 @@ struct panel_lvds { bool data_mirror; struct backlight_device *backlight; + struct regulator *supply; struct gpio_desc *enable_gpio; struct gpio_desc *reset_gpio; @@ -69,6 +71,9 @@ static int panel_lvds_unprepare(struct drm_panel *panel) if (lvds->enable_gpio) gpiod_set_value_cansleep(lvds->enable_gpio, 0); + if (lvds->supply) + regulator_disable(lvds->supply); + return 0; } @@ -76,6 +81,17 @@ static int panel_lvds_prepare(struct drm_panel *panel) { struct panel_lvds *lvds = to_panel_lvds(panel); + if (lvds->supply) { + int err; + + err = regulator_enable(lvds->supply); + if (err < 0) { + dev_err(lvds->dev, "failed to enable supply: %d\n", + err); + return err; + } + } + if (lvds->enable_gpio) gpiod_set_value_cansleep(lvds->enable_gpio, 1); @@ -196,6 +212,13 @@ static int panel_lvds_probe(struct platform_device *pdev) if (ret < 0) return ret; + lvds->supply = devm_regulator_get_optional(lvds->dev, "power"); + if (IS_ERR(lvds->supply)) { + ret = PTR_ERR(lvds->supply); + dev_err(lvds->dev, "failed to request regulator: %d\n", ret); + return ret; + } + /* Get GPIOs and backlight controller. */ lvds->enable_gpio = devm_gpiod_get_optional(lvds->dev, "enable", GPIOD_OUT_LOW); -- git-series 0.9.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 08/23] dt-bindings: panel: lvds: Document power-supply property
The power-supply property is used be a vast majority of panels, including panel-simple. Let's document it as a common property Signed-off-by: Maxime Ripard --- Documentation/devicetree/bindings/display/panel/panel-common.txt | 6 ++ Documentation/devicetree/bindings/display/panel/panel-lvds.txt | 1 + 2 files changed, 7 insertions(+) diff --git a/Documentation/devicetree/bindings/display/panel/panel-common.txt b/Documentation/devicetree/bindings/display/panel/panel-common.txt index ec52c472c845..125ea68052af 100644 --- a/Documentation/devicetree/bindings/display/panel/panel-common.txt +++ b/Documentation/devicetree/bindings/display/panel/panel-common.txt @@ -78,6 +78,12 @@ used for panels that implement compatible control signals. while active. Active high reset signals can be supported by inverting the GPIO specifier polarity flag. +Power +- + +- power-supply: many display panels need an additional power supply in + order to be fully powered-up. For such panels, power-supply contains + a phandle to the regulator powering the panel. Backlight - diff --git a/Documentation/devicetree/bindings/display/panel/panel-lvds.txt b/Documentation/devicetree/bindings/display/panel/panel-lvds.txt index b938269f841e..250850a2150b 100644 --- a/Documentation/devicetree/bindings/display/panel/panel-lvds.txt +++ b/Documentation/devicetree/bindings/display/panel/panel-lvds.txt @@ -32,6 +32,7 @@ Optional properties: - label: See panel-common.txt. - gpios: See panel-common.txt. - backlight: See panel-common.txt. +- power-supply: See panel-common.txt. - data-mirror: If set, reverse the bit order described in the data mappings below on all data lanes, transmitting bits for slots 6 to 0 instead of 0 to 6. -- git-series 0.9.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 07/23] drm/sun4i: tcon: Move out the tcon0 common setup
Some channel0 setup has to be done, no matter what the output interface is (RGB, CPU, LVDS). Move that code into a common function in order to avoid duplication. Signed-off-by: Maxime Ripard --- drivers/gpu/drm/sun4i/sun4i_tcon.c | 26 -- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c b/drivers/gpu/drm/sun4i/sun4i_tcon.c index 7ecd4f7c8411..f69bcdf11cb8 100644 --- a/drivers/gpu/drm/sun4i/sun4i_tcon.c +++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c @@ -158,15 +158,26 @@ static int sun4i_tcon_get_clk_delay(const struct drm_display_mode *mode, return delay; } -static void sun4i_tcon0_mode_set(struct sun4i_tcon *tcon, -struct drm_display_mode *mode) +static void sun4i_tcon0_mode_set_common(struct sun4i_tcon *tcon, + const struct drm_display_mode *mode) +{ + /* Configure the dot clock */ + clk_set_rate(tcon->dclk, mode->crtc_clock * 1000); + + /* Set the resolution */ + regmap_write(tcon->regs, SUN4I_TCON0_BASIC0_REG, +SUN4I_TCON0_BASIC0_X(mode->crtc_hdisplay) | +SUN4I_TCON0_BASIC0_Y(mode->crtc_vdisplay)); +} + +static void sun4i_tcon0_mode_set_rgb(struct sun4i_tcon *tcon, +const struct drm_display_mode *mode) { unsigned int bp, hsync, vsync; u8 clk_delay; u32 val = 0; - /* Configure the dot clock */ - clk_set_rate(tcon->dclk, mode->crtc_clock * 1000); + sun4i_tcon0_mode_set_common(tcon, mode); /* Adjust clock delay */ clk_delay = sun4i_tcon_get_clk_delay(mode, 0); @@ -174,11 +185,6 @@ static void sun4i_tcon0_mode_set(struct sun4i_tcon *tcon, SUN4I_TCON0_CTL_CLK_DELAY_MASK, SUN4I_TCON0_CTL_CLK_DELAY(clk_delay)); - /* Set the resolution */ - regmap_write(tcon->regs, SUN4I_TCON0_BASIC0_REG, -SUN4I_TCON0_BASIC0_X(mode->crtc_hdisplay) | -SUN4I_TCON0_BASIC0_Y(mode->crtc_vdisplay)); - /* * This is called a backporch in the register documentation, * but it really is the back porch + hsync @@ -329,7 +335,7 @@ void sun4i_tcon_mode_set(struct sun4i_tcon *tcon, { switch (encoder->encoder_type) { case DRM_MODE_ENCODER_NONE: - sun4i_tcon0_mode_set(tcon, mode); + sun4i_tcon0_mode_set_rgb(tcon, mode); sun4i_tcon_set_mux(tcon, 0, encoder); break; case DRM_MODE_ENCODER_TVDAC: -- git-series 0.9.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 06/23] drm/sun4i: tcon: Don't rely on encoders to set the TCON mode
Just like we did for the TCON enable and disable, for historical reasons we used to rely on the encoders calling the TCON mode_set function, while the CRTC has a callback for that. Let's implement it in order to reduce the boilerplate code. Signed-off-by: Maxime Ripard --- drivers/gpu/drm/sun4i/sun4i_crtc.c | 10 +++- drivers/gpu/drm/sun4i/sun4i_hdmi_ddc_clk.c | 1 +- drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c | 7 +- drivers/gpu/drm/sun4i/sun4i_hdmi_tmds_clk.c | 1 +- drivers/gpu/drm/sun4i/sun4i_rgb.c | 15 +--- drivers/gpu/drm/sun4i/sun4i_tcon.c | 31 +- drivers/gpu/drm/sun4i/sun4i_tcon.h | 11 ++-- drivers/gpu/drm/sun4i/sun4i_tv.c| 6 + 8 files changed, 37 insertions(+), 45 deletions(-) diff --git a/drivers/gpu/drm/sun4i/sun4i_crtc.c b/drivers/gpu/drm/sun4i/sun4i_crtc.c index e86baa3746af..5decae0069d0 100644 --- a/drivers/gpu/drm/sun4i/sun4i_crtc.c +++ b/drivers/gpu/drm/sun4i/sun4i_crtc.c @@ -115,11 +115,21 @@ static void sun4i_crtc_atomic_enable(struct drm_crtc *crtc, sun4i_tcon_set_status(scrtc->tcon, encoder, true); } +static void sun4i_crtc_mode_set_nofb(struct drm_crtc *crtc) +{ + struct drm_display_mode *mode = &crtc->state->adjusted_mode; + struct drm_encoder *encoder = sun4i_crtc_get_encoder(crtc); + struct sun4i_crtc *scrtc = drm_crtc_to_sun4i_crtc(crtc); + + sun4i_tcon_mode_set(scrtc->tcon, encoder, mode); +} + static const struct drm_crtc_helper_funcs sun4i_crtc_helper_funcs = { .atomic_begin = sun4i_crtc_atomic_begin, .atomic_flush = sun4i_crtc_atomic_flush, .atomic_enable = sun4i_crtc_atomic_enable, .atomic_disable = sun4i_crtc_atomic_disable, + .mode_set_nofb = sun4i_crtc_mode_set_nofb, }; static int sun4i_crtc_enable_vblank(struct drm_crtc *crtc) diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_ddc_clk.c b/drivers/gpu/drm/sun4i/sun4i_hdmi_ddc_clk.c index 04f85b1cf922..e826da34e919 100644 --- a/drivers/gpu/drm/sun4i/sun4i_hdmi_ddc_clk.c +++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_ddc_clk.c @@ -13,7 +13,6 @@ #include #include -#include "sun4i_tcon.h" #include "sun4i_hdmi.h" struct sun4i_ddc { diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c index 482bf03d55c1..d2eb0a60e568 100644 --- a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c +++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c @@ -30,7 +30,6 @@ #include "sun4i_crtc.h" #include "sun4i_drv.h" #include "sun4i_hdmi.h" -#include "sun4i_tcon.h" static inline struct sun4i_hdmi * drm_encoder_to_sun4i_hdmi(struct drm_encoder *encoder) @@ -120,15 +119,9 @@ static void sun4i_hdmi_mode_set(struct drm_encoder *encoder, struct drm_display_mode *adjusted_mode) { struct sun4i_hdmi *hdmi = drm_encoder_to_sun4i_hdmi(encoder); - struct sun4i_crtc *crtc = drm_crtc_to_sun4i_crtc(encoder->crtc); - struct sun4i_tcon *tcon = crtc->tcon; unsigned int x, y; u32 val; - sun4i_tcon1_mode_set(tcon, mode); - sun4i_tcon_set_mux(tcon, 1, encoder); - - clk_set_rate(tcon->sclk1, mode->crtc_clock * 1000); clk_set_rate(hdmi->mod_clk, mode->crtc_clock * 1000); clk_set_rate(hdmi->tmds_clk, mode->crtc_clock * 1000); diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_tmds_clk.c b/drivers/gpu/drm/sun4i/sun4i_hdmi_tmds_clk.c index 1b6b37aefc38..dc332ea56f6c 100644 --- a/drivers/gpu/drm/sun4i/sun4i_hdmi_tmds_clk.c +++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_tmds_clk.c @@ -12,7 +12,6 @@ #include -#include "sun4i_tcon.h" #include "sun4i_hdmi.h" struct sun4i_tmds { diff --git a/drivers/gpu/drm/sun4i/sun4i_rgb.c b/drivers/gpu/drm/sun4i/sun4i_rgb.c index a7f297ed40c1..832f8f9bc47f 100644 --- a/drivers/gpu/drm/sun4i/sun4i_rgb.c +++ b/drivers/gpu/drm/sun4i/sun4i_rgb.c @@ -153,22 +153,7 @@ static void sun4i_rgb_encoder_disable(struct drm_encoder *encoder) } } -static void sun4i_rgb_encoder_mode_set(struct drm_encoder *encoder, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - struct sun4i_rgb *rgb = drm_encoder_to_sun4i_rgb(encoder); - struct sun4i_tcon *tcon = rgb->tcon; - - sun4i_tcon0_mode_set(tcon, mode); - sun4i_tcon_set_mux(tcon, 0, encoder); - - /* FIXME: This seems to be board specific */ - clk_set_phase(tcon->dclk, 120); -} - static struct drm_encoder_helper_funcs sun4i_rgb_enc_helper_funcs = { - .mode_set = sun4i_rgb_encoder_mode_set, .disable= sun4i_rgb_encoder_disable, .enable = sun4i_rgb_encoder_enable, }; diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c b/drivers/gpu/drm/sun4i/sun4i_tcon.c index 964cf22a1ced..7ecd4f7c8411 100644 --- a/drivers/gpu/drm/sun4i/sun4i_tcon.c +++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c @@ -139,7 +139,6 @@ void sun4i_tco
[PATCH 10/23] clk: sunxi-ng: Add A83T display clocks
Unfortunately, the A83t display clocks are not children of the de clock, since that clocks doesn't exist at all on the A83t. For now, they are orphans, so let's move them to their true, existing, parent. Fixes: 763c5bd045b1 ("clk: sunxi-ng: add support for DE2 CCU") Signed-off-by: Maxime Ripard --- drivers/clk/sunxi-ng/ccu-sun8i-de2.c | 21 + 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-de2.c b/drivers/clk/sunxi-ng/ccu-sun8i-de2.c index 5cdaf52669e4..5cc9d9952121 100644 --- a/drivers/clk/sunxi-ng/ccu-sun8i-de2.c +++ b/drivers/clk/sunxi-ng/ccu-sun8i-de2.c @@ -41,11 +41,16 @@ static SUNXI_CCU_GATE(wb_clk, "wb", "wb-div", static SUNXI_CCU_M(mixer0_div_clk, "mixer0-div", "de", 0x0c, 0, 4, CLK_SET_RATE_PARENT); -static SUNXI_CCU_M(mixer1_div_clk, "mixer1-div", "de", 0x0c, 4, 4, - CLK_SET_RATE_PARENT); static SUNXI_CCU_M(wb_div_clk, "wb-div", "de", 0x0c, 8, 4, CLK_SET_RATE_PARENT); +static SUNXI_CCU_M(mixer0_div_a83_clk, "mixer0-div", "pll-de", 0x0c, 0, 4, + CLK_SET_RATE_PARENT); +static SUNXI_CCU_M(mixer1_div_a83_clk, "mixer1-div", "pll-de", 0x0c, 4, 4, + CLK_SET_RATE_PARENT); +static SUNXI_CCU_M(wb_div_a83_clk, "wb-div", "pll-de", 0x0c, 8, 4, + CLK_SET_RATE_PARENT); + static struct ccu_common *sun8i_a83t_de2_clks[] = { &mixer0_clk.common, &mixer1_clk.common, @@ -55,9 +60,9 @@ static struct ccu_common *sun8i_a83t_de2_clks[] = { &bus_mixer1_clk.common, &bus_wb_clk.common, - &mixer0_div_clk.common, - &mixer1_div_clk.common, - &wb_div_clk.common, + &mixer0_div_a83_clk.common, + &mixer1_div_a83_clk.common, + &wb_div_a83_clk.common, }; static struct ccu_common *sun8i_v3s_de2_clks[] = { @@ -81,9 +86,9 @@ static struct clk_hw_onecell_data sun8i_a83t_de2_hw_clks = { [CLK_BUS_MIXER1]= &bus_mixer1_clk.common.hw, [CLK_BUS_WB]= &bus_wb_clk.common.hw, - [CLK_MIXER0_DIV]= &mixer0_div_clk.common.hw, - [CLK_MIXER1_DIV]= &mixer1_div_clk.common.hw, - [CLK_WB_DIV]= &wb_div_clk.common.hw, + [CLK_MIXER0_DIV]= &mixer0_div_a83_clk.common.hw, + [CLK_MIXER1_DIV]= &mixer1_div_a83_clk.common.hw, + [CLK_WB_DIV]= &wb_div_a83_clk.common.hw, }, .num= CLK_NUMBER, }; -- git-series 0.9.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 19/23] arm: dts: sun8i: a83t: Add LVDS pins group
The A83T has an LVDS bus that can be connected to a panel or a bridge. Add the pinctrl group for it. Signed-off-by: Maxime Ripard --- arch/arm/boot/dts/sun8i-a83t.dtsi | 6 ++ 1 file changed, 6 insertions(+) diff --git a/arch/arm/boot/dts/sun8i-a83t.dtsi b/arch/arm/boot/dts/sun8i-a83t.dtsi index ef07a58859c7..6f1221556587 100644 --- a/arch/arm/boot/dts/sun8i-a83t.dtsi +++ b/arch/arm/boot/dts/sun8i-a83t.dtsi @@ -414,6 +414,12 @@ #interrupt-cells = <3>; #gpio-cells = <3>; + lcd_lvds_pins: lcd-lvds-pins { + pins = "PD18", "PD19", "PD20", "PD21", "PD22", + "PD23", "PD24", "PD25", "PD26", "PD27"; + function = "lvds0"; + }; + mmc0_pins: mmc0-pins { pins = "PF0", "PF1", "PF2", "PF3", "PF4", "PF5"; -- git-series 0.9.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 11/23] drm/sun4i: Rename layers to UI planes
The currently supported planes for DE2 are actually only UI planes, and the VI planes will differ both in terms of code and features. It will make sense to support them in a separate file, so let's make sure we don't create a confusing file name. Signed-off-by: Maxime Ripard --- drivers/gpu/drm/sun4i/Makefile | 2 +- drivers/gpu/drm/sun4i/sun8i_layer.c | 134 +- drivers/gpu/drm/sun4i/sun8i_layer.h | 36 + drivers/gpu/drm/sun4i/sun8i_mixer.c | 4 +- drivers/gpu/drm/sun4i/sun8i_ui.c| 134 +- drivers/gpu/drm/sun4i/sun8i_ui.h| 36 - 6 files changed, 173 insertions(+), 173 deletions(-) delete mode 100644 drivers/gpu/drm/sun4i/sun8i_layer.c delete mode 100644 drivers/gpu/drm/sun4i/sun8i_layer.h create mode 100644 drivers/gpu/drm/sun4i/sun8i_ui.c create mode 100644 drivers/gpu/drm/sun4i/sun8i_ui.h diff --git a/drivers/gpu/drm/sun4i/Makefile b/drivers/gpu/drm/sun4i/Makefile index af18b70ba5ed..cfba2c07519c 100644 --- a/drivers/gpu/drm/sun4i/Makefile +++ b/drivers/gpu/drm/sun4i/Makefile @@ -13,7 +13,7 @@ sun4i-tcon-y += sun4i_rgb.o sun4i-tcon-y += sun4i_dotclock.o sun4i-tcon-y += sun4i_crtc.o -sun8i-mixer-y += sun8i_mixer.o sun8i_layer.o +sun8i-mixer-y += sun8i_mixer.o sun8i_ui.o obj-$(CONFIG_DRM_SUN4I)+= sun4i-drm.o sun4i-tcon.o obj-$(CONFIG_DRM_SUN4I)+= sun6i_drc.o diff --git a/drivers/gpu/drm/sun4i/sun8i_layer.c b/drivers/gpu/drm/sun4i/sun8i_layer.c deleted file mode 100644 index 23810ff72684.. --- a/drivers/gpu/drm/sun4i/sun8i_layer.c +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright (C) Icenowy Zheng - * - * Based on sun4i_layer.h, which is: - * Copyright (C) 2015 Free Electrons - * Copyright (C) 2015 NextThing Co - * - * Maxime Ripard - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - */ - -#include -#include -#include - -#include "sun8i_layer.h" -#include "sun8i_mixer.h" - -struct sun8i_plane_desc { - enum drm_plane_type type; - const uint32_t *formats; - uint32_tnformats; -}; - -static void sun8i_mixer_layer_atomic_disable(struct drm_plane *plane, - struct drm_plane_state *old_state) -{ - struct sun8i_layer *layer = plane_to_sun8i_layer(plane); - struct sun8i_mixer *mixer = layer->mixer; - - sun8i_mixer_layer_enable(mixer, layer->id, false); -} - -static void sun8i_mixer_layer_atomic_update(struct drm_plane *plane, - struct drm_plane_state *old_state) -{ - struct sun8i_layer *layer = plane_to_sun8i_layer(plane); - struct sun8i_mixer *mixer = layer->mixer; - - sun8i_mixer_update_layer_coord(mixer, layer->id, plane); - sun8i_mixer_update_layer_formats(mixer, layer->id, plane); - sun8i_mixer_update_layer_buffer(mixer, layer->id, plane); - sun8i_mixer_layer_enable(mixer, layer->id, true); -} - -static struct drm_plane_helper_funcs sun8i_mixer_layer_helper_funcs = { - .atomic_disable = sun8i_mixer_layer_atomic_disable, - .atomic_update = sun8i_mixer_layer_atomic_update, -}; - -static const struct drm_plane_funcs sun8i_mixer_layer_funcs = { - .atomic_destroy_state = drm_atomic_helper_plane_destroy_state, - .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state, - .destroy= drm_plane_cleanup, - .disable_plane = drm_atomic_helper_disable_plane, - .reset = drm_atomic_helper_plane_reset, - .update_plane = drm_atomic_helper_update_plane, -}; - -static const uint32_t sun8i_mixer_layer_formats[] = { - DRM_FORMAT_RGB888, - DRM_FORMAT_ARGB, - DRM_FORMAT_XRGB, -}; - -static const struct sun8i_plane_desc sun8i_mixer_planes[] = { - { - .type = DRM_PLANE_TYPE_PRIMARY, - .formats = sun8i_mixer_layer_formats, - .nformats = ARRAY_SIZE(sun8i_mixer_layer_formats), - }, -}; - -static struct sun8i_layer *sun8i_layer_init_one(struct drm_device *drm, - struct sun8i_mixer *mixer, - const struct sun8i_plane_desc *plane) -{ - struct sun8i_layer *layer; - int ret; - - layer = devm_kzalloc(drm->dev, sizeof(*layer), GFP_KERNEL); - if (!layer) - return ERR_PTR(-ENOMEM); - - /* possible crtcs are set later */ - ret = drm_universal_plane_init(drm, &layer->plane, 0, - &sun8i_mixer_layer_funcs, -
[PATCH 00/23] drm/sun4i: Add A83t LVDS support
Hi, Here is an attempt at supporting the LVDS output in our DRM driver. This has been tested on the A83T (with DE2), but since everything is basically in the TCON, it should also be usable on the older SoCs with minor modifications. This was the occasion to refactor a bunch of things. The most notable ones would be the documentation, and split of the UI layers in the mixer code, and the switch to kfifo for our endpoint parsing code in the driver that fixes an issue introduced by the switch to BFS. Let me know what you think, Maxime Maxime Ripard (23): drm/sun4i: Implement endpoint parsing using kfifo drm/sun4i: Realign Makefile padding and reorder it drm/sun4i: tcon: Make tcon_set_mux mode argument const drm/sun4i: tcon: Make tcon_get_clk_delay mode argument const drm/sun4i: tcon: Don't rely on encoders to enable the TCON drm/sun4i: tcon: Don't rely on encoders to set the TCON mode drm/sun4i: tcon: Move out the tcon0 common setup dt-bindings: panel: lvds: Document power-supply property drm/panel: lvds: Add support for the power-supply property clk: sunxi-ng: Add A83T display clocks drm/sun4i: Rename layers to UI planes drm/sun4i: sun8i: properly support UI channels drm/sun4i: Reorder and document DE2 mixer registers drm/sun4i: Create minimal multipliers and dividers drm/sun4i: Add LVDS support drm/sun4i: Add A83T support arm: dts: sun8i: a83t: Add display pipeline arm: dts: sun8i: a83t: Enable the PWM arm: dts: sun8i: a83t: Add LVDS pins group arm: dts: sun8i: a83t: Add the PWM pin group arm: dts: sun8i: a711: Add regulator support arm: dts: sun8i: a711: Enable USB OTG arm: dts: sun8i: a711: Enable the LCD Documentation/devicetree/bindings/display/panel/panel-common.txt | 6 +- Documentation/devicetree/bindings/display/panel/panel-lvds.txt | 1 +- Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt| 3 +- arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts| 232 +-- arch/arm/boot/dts/sun8i-a83t.dtsi| 100 ++- drivers/clk/sunxi-ng/ccu-sun8i-de2.c | 21 +++-- drivers/gpu/drm/panel/panel-lvds.c | 23 +- drivers/gpu/drm/sun4i/Makefile | 29 +++--- drivers/gpu/drm/sun4i/sun4i_crtc.c | 32 ++- drivers/gpu/drm/sun4i/sun4i_dotclock.c | 10 +- drivers/gpu/drm/sun4i/sun4i_drv.c| 73 +++- drivers/gpu/drm/sun4i/sun4i_hdmi_ddc_clk.c | 1 +- drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c | 15 +--- drivers/gpu/drm/sun4i/sun4i_hdmi_tmds_clk.c | 1 +- drivers/gpu/drm/sun4i/sun4i_lvds.c | 183 - drivers/gpu/drm/sun4i/sun4i_lvds.h | 18 - drivers/gpu/drm/sun4i/sun4i_rgb.c| 29 +-- drivers/gpu/drm/sun4i/sun4i_tcon.c | 326 +++- drivers/gpu/drm/sun4i/sun4i_tcon.h | 50 +++ drivers/gpu/drm/sun4i/sun4i_tv.c | 12 +--- drivers/gpu/drm/sun4i/sun8i_layer.c | 134 +-- drivers/gpu/drm/sun4i/sun8i_layer.h | 36 + drivers/gpu/drm/sun4i/sun8i_mixer.c | 81 -- drivers/gpu/drm/sun4i/sun8i_mixer.h | 101 -- drivers/gpu/drm/sun4i/sun8i_ui.c | 136 ++- drivers/gpu/drm/sun4i/sun8i_ui.h | 37 - 26 files changed, 1212 insertions(+), 478 deletions(-) create mode 100644 drivers/gpu/drm/sun4i/sun4i_lvds.c create mode 100644 drivers/gpu/drm/sun4i/sun4i_lvds.h delete mode 100644 drivers/gpu/drm/sun4i/sun8i_layer.c delete mode 100644 drivers/gpu/drm/sun4i/sun8i_layer.h create mode 100644 drivers/gpu/drm/sun4i/sun8i_ui.c create mode 100644 drivers/gpu/drm/sun4i/sun8i_ui.h base-commit: 5ffd95d0dc16c6491631b6ca19403c96fd3db5d5 -- git-series 0.9.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 20/23] arm: dts: sun8i: a83t: Add the PWM pin group
The A83T has a PWM that can be output from the SoC. Let's add a pinctrl group for it. Signed-off-by: Maxime Ripard --- arch/arm/boot/dts/sun8i-a83t.dtsi | 5 + 1 file changed, 5 insertions(+) diff --git a/arch/arm/boot/dts/sun8i-a83t.dtsi b/arch/arm/boot/dts/sun8i-a83t.dtsi index 6f1221556587..1986e8341e33 100644 --- a/arch/arm/boot/dts/sun8i-a83t.dtsi +++ b/arch/arm/boot/dts/sun8i-a83t.dtsi @@ -445,6 +445,11 @@ bias-pull-up; }; + pwm_pin: pwm-pin { + pins = "PD28"; + function = "pwm"; + }; + spdif_tx_pin: spdif-tx-pin { pins = "PE18"; function = "spdif"; -- git-series 0.9.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 21/23] arm: dts: sun8i: a711: Add regulator support
Signed-off-by: Maxime Ripard --- arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts | 163 +-- 1 file changed, 154 insertions(+), 9 deletions(-) diff --git a/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts b/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts index 723641f56a74..98dc0c22160b 100644 --- a/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts +++ b/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts @@ -43,7 +43,8 @@ /dts-v1/; #include "sun8i-a83t.dtsi" -#include "sunxi-common-regulators.dtsi" + +#include / { model = "TBS A711 Tablet"; @@ -105,7 +106,7 @@ }; &mmc0 { - vmmc-supply = <®_vcc3v3>; + vmmc-supply = <®_dcdc1>; pinctrl-names = "default"; pinctrl-0 = <&mmc0_pins>; cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>; @@ -117,8 +118,8 @@ bus-width = <4>; pinctrl-names = "default"; pinctrl-0 = <&mmc1_pins>; - vmmc-supply = <®_vcc3v3>; - vqmmc-supply = <®_vcc3v3>; + vmmc-supply = <®_dldo1>; + vqmmc-supply = <®_dldo1>; non-removable; wakeup-source; status = "okay"; @@ -135,8 +136,8 @@ &mmc2 { pinctrl-0 = <&mmc2_8bit_emmc_pins>; pinctrl-names = "default"; - vmmc-supply = <®_vcc3v3>; - vqmmc-supply = <®_vcc3v3>; + vmmc-supply = <®_dcdc1>; + vqmmc-supply = <®_dcdc1>; bus-width = <8>; non-removable; cap-mmc-hw-reset; @@ -147,10 +148,11 @@ status = "okay"; axp813: pmic@3a3 { - compatible = "x-powers,axp813"; reg = <0x3a3>; interrupt-parent = <&r_intc>; interrupts = <0 IRQ_TYPE_LEVEL_LOW>; + swin-supply = <®_dcdc1>; + x-powers,drive-vbus-en; }; ac100: codec@e89 { @@ -179,6 +181,149 @@ }; +#include "axp813.dtsi" + +®_aldo1 { + regulator-min-microvolt = <180>; + regulator-max-microvolt = <180>; + regulator-name = "vcc-1.8"; +}; + +®_aldo2 { + regulator-min-microvolt = <180>; + regulator-max-microvolt = <180>; + regulator-always-on; + regulator-name = "vdd-drampll"; +}; + +®_aldo3 { + regulator-min-microvolt = <300>; + regulator-max-microvolt = <300>; + regulator-always-on; + regulator-name = "avcc"; +}; + +®_dcdc1 { + regulator-min-microvolt = <310>; + regulator-max-microvolt = <310>; + regulator-always-on; + regulator-name = "vcc-io"; +}; + +®_dcdc2 { + regulator-min-microvolt = <70>; + regulator-max-microvolt = <110>; + regulator-always-on; + regulator-name = "vdd-cpu-A"; +}; + +®_dcdc3 { + regulator-min-microvolt = <70>; + regulator-max-microvolt = <110>; + regulator-always-on; + regulator-name = "vdd-cpu-B"; +}; + +®_dcdc4 { + regulator-min-microvolt = <70>; + regulator-max-microvolt = <110>; + regulator-name = "vdd-gpu"; +}; + +®_dcdc5 { + regulator-min-microvolt = <120>; + regulator-max-microvolt = <150>; + regulator-always-on; + regulator-name = "vcc-dram"; +}; + +®_dcdc6 { + regulator-min-microvolt = <90>; + regulator-max-microvolt = <90>; + regulator-always-on; + regulator-name = "vdd-sys"; +}; + +®_dldo1 { + regulator-min-microvolt = <310>; + regulator-max-microvolt = <310>; + regulator-name = "vcc-wifi-io"; +}; + +®_dldo2 { + regulator-min-microvolt = <280>; + regulator-max-microvolt = <420>; + regulator-name = "vcc-mipi"; +}; + +®_dldo3 { + regulator-min-microvolt = <280>; + regulator-max-microvolt = <280>; + regulator-name = "vdd-csi"; +}; + +®_dldo4 { + regulator-min-microvolt = <280>; + regulator-max-microvolt = <280>; + regulator-name = "avdd-csi"; +}; + +®_drivevbus { + regulator-name = "usb0-vbus"; + status = "okay"; +}; + +®_eldo1 { + regulator-min-microvolt = <120>; + regulator-max-microvolt = <180>; + regulator-name = "dvdd-csi-r"; +}; + +®_eldo2 { + regulator-min-microvolt = <180>; + regulator-max-microvolt = <180>; + regulator-name = "vcc-dsi"; +}; + +®_eldo3 { + regulator-min-microvolt = <120>; + regulator-max-microvolt = <180>; + regulator-name = "dvdd-csi-f"; +}; + +®_fldo1 { + regulator-min-microvolt = <120>; + regulator-max-microvolt = <120>; + regulator-name = "vcc-hsic"; +}; + +®_fldo2 { + regulator-min-microvolt = <70>; + regulator-max-microvolt = <110>; + regulator-always-on; + regulator-name = "vdd-cpus"; +}; + +®_ldo_io0 { + regulator-min-microvolt = <310>; + regulator-max-microvolt = <310>; + regulator-name = "vcc-ctp"; + status = "okay"; +}; + +®_ldo_io1 { + regulator-min-microvolt = <310>; + regulator-max-microvol
[PATCH 22/23] arm: dts: sun8i: a711: Enable USB OTG
Signed-off-by: Maxime Ripard --- arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts | 7 +++ 1 file changed, 7 insertions(+) diff --git a/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts b/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts index 98dc0c22160b..e4d08bff3158 100644 --- a/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts +++ b/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts @@ -337,7 +337,14 @@ status = "okay"; }; +&usb_otg { + dr_mode = "otg"; + status = "okay"; +}; + &usbphy { + usb0_id_det-gpios = <&pio 7 11 GPIO_ACTIVE_HIGH>; /* PH11 */ + usb0_vbus-supply = <®_drivevbus>; usb1_vbus_supply = <®_vmain>; usb2_vbus_supply = <®_vmain>; status = "okay"; -- git-series 0.9.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 12/23] drm/sun4i: sun8i: properly support UI channels
The current code has the wrong macro to get the registers offsets of the UI-registers, with an off-by-0x1000 error. It works so far by accident, since the UI channel used everywhere else is the number of VI planes, which has always been 1 so far, and the offset between two UI channels is 0x1000. Let's correct that behaviour by setting the UI chan number in the sun8i_ui structure, and remove the hardcoded values pretty much everywhere. Once we have sane values, we can convert the macros to their actual definition. Signed-off-by: Maxime Ripard --- drivers/gpu/drm/sun4i/sun8i_mixer.c | 50 -- drivers/gpu/drm/sun4i/sun8i_mixer.h | 32 ++- drivers/gpu/drm/sun4i/sun8i_ui.c| 12 --- drivers/gpu/drm/sun4i/sun8i_ui.h| 1 +- 4 files changed, 46 insertions(+), 49 deletions(-) diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c b/drivers/gpu/drm/sun4i/sun8i_mixer.c index 1955b2a36ac5..5afe8ef709a5 100644 --- a/drivers/gpu/drm/sun4i/sun8i_mixer.c +++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c @@ -37,14 +37,12 @@ static void sun8i_mixer_commit(struct sunxi_engine *engine) SUN8I_MIXER_GLOBAL_DBUFF_ENABLE); } -void sun8i_mixer_layer_enable(struct sun8i_mixer *mixer, - int layer, bool enable) +void sun8i_mixer_layer_enable(struct sun8i_mixer *mixer, struct sun8i_ui *ui, + bool enable) { u32 val; - /* Currently the first UI channel is used */ - int chan = mixer->cfg->vi_num; - DRM_DEBUG_DRIVER("Enabling layer %d in channel %d\n", layer, chan); + DRM_DEBUG_DRIVER("Enabling layer %d in channel %d\n", ui->id, ui->chan); if (enable) val = SUN8I_MIXER_CHAN_UI_LAYER_ATTR_EN; @@ -52,16 +50,16 @@ void sun8i_mixer_layer_enable(struct sun8i_mixer *mixer, val = 0; regmap_update_bits(mixer->engine.regs, - SUN8I_MIXER_CHAN_UI_LAYER_ATTR(chan, layer), + SUN8I_MIXER_CHAN_UI_LAYER_ATTR(ui->chan, ui->id), SUN8I_MIXER_CHAN_UI_LAYER_ATTR_EN, val); /* Set the alpha configuration */ regmap_update_bits(mixer->engine.regs, - SUN8I_MIXER_CHAN_UI_LAYER_ATTR(chan, layer), + SUN8I_MIXER_CHAN_UI_LAYER_ATTR(ui->chan, ui->id), SUN8I_MIXER_CHAN_UI_LAYER_ATTR_ALPHA_MODE_MASK, SUN8I_MIXER_CHAN_UI_LAYER_ATTR_ALPHA_MODE_DEF); regmap_update_bits(mixer->engine.regs, - SUN8I_MIXER_CHAN_UI_LAYER_ATTR(chan, layer), + SUN8I_MIXER_CHAN_UI_LAYER_ATTR(ui->chan, ui->id), SUN8I_MIXER_CHAN_UI_LAYER_ATTR_ALPHA_MASK, SUN8I_MIXER_CHAN_UI_LAYER_ATTR_ALPHA_DEF); } @@ -90,14 +88,13 @@ static int sun8i_mixer_drm_format_to_layer(struct drm_plane *plane, } int sun8i_mixer_update_layer_coord(struct sun8i_mixer *mixer, -int layer, struct drm_plane *plane) + struct sun8i_ui *ui) { + struct drm_plane *plane = &ui->plane; struct drm_plane_state *state = plane->state; struct drm_framebuffer *fb = state->fb; - /* Currently the first UI channel is used */ - int chan = mixer->cfg->vi_num; - DRM_DEBUG_DRIVER("Updating layer %d\n", layer); + DRM_DEBUG_DRIVER("Updating layer %d\n", ui->id); if (plane->type == DRM_PLANE_TYPE_PRIMARY) { DRM_DEBUG_DRIVER("Primary layer, updating global size W: %u H: %u\n", @@ -115,7 +112,7 @@ int sun8i_mixer_update_layer_coord(struct sun8i_mixer *mixer, state->crtc_h)); DRM_DEBUG_DRIVER("Updating channel size\n"); regmap_write(mixer->engine.regs, -SUN8I_MIXER_CHAN_UI_OVL_SIZE(chan), +SUN8I_MIXER_CHAN_UI_OVL_SIZE(ui->chan), SUN8I_MIXER_SIZE(state->crtc_w, state->crtc_h)); } @@ -123,35 +120,34 @@ int sun8i_mixer_update_layer_coord(struct sun8i_mixer *mixer, /* Set the line width */ DRM_DEBUG_DRIVER("Layer line width: %d bytes\n", fb->pitches[0]); regmap_write(mixer->engine.regs, -SUN8I_MIXER_CHAN_UI_LAYER_PITCH(chan, layer), +SUN8I_MIXER_CHAN_UI_LAYER_PITCH(ui->chan, ui->id), fb->pitches[0]); /* Set height and width */ DRM_DEBUG_DRIVER("Layer size W: %u H: %u\n", state->crtc_w, state->crtc_h); regmap_write(mixer->engine.regs, -SUN8I_MIXER_CHAN_UI_LAYER_SIZE(chan, layer), +SUN8I_MIXER_CHAN_UI_LAYER_SIZE(ui->chan, ui->id), SUN8I_MIXER_SIZE(state->crtc_w, state->crtc_h)); /
[PATCH 04/23] drm/sun4i: tcon: Make tcon_get_clk_delay mode argument const
The drm_display_mode pointer can be mark const, so let's do it. Signed-off-by: Maxime Ripard --- drivers/gpu/drm/sun4i/sun4i_tcon.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c b/drivers/gpu/drm/sun4i/sun4i_tcon.c index 54e1796d2953..9b5b21ad8378 100644 --- a/drivers/gpu/drm/sun4i/sun4i_tcon.c +++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c @@ -146,7 +146,7 @@ void sun4i_tcon_set_mux(struct sun4i_tcon *tcon, int channel, } EXPORT_SYMBOL(sun4i_tcon_set_mux); -static int sun4i_tcon_get_clk_delay(struct drm_display_mode *mode, +static int sun4i_tcon_get_clk_delay(const struct drm_display_mode *mode, int channel) { int delay = mode->vtotal - mode->vdisplay; -- git-series 0.9.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 18/23] arm: dts: sun8i: a83t: Enable the PWM
The A83T has the same PWM block than the H3. Add it to our DT. Signed-off-by: Maxime Ripard --- arch/arm/boot/dts/sun8i-a83t.dtsi | 9 + 1 file changed, 9 insertions(+) diff --git a/arch/arm/boot/dts/sun8i-a83t.dtsi b/arch/arm/boot/dts/sun8i-a83t.dtsi index 57feeb6fee8b..ef07a58859c7 100644 --- a/arch/arm/boot/dts/sun8i-a83t.dtsi +++ b/arch/arm/boot/dts/sun8i-a83t.dtsi @@ -496,6 +496,15 @@ status = "disabled"; }; + pwm: pwm@1c21400 { + compatible = "allwinner,sun8i-a83t-pwm", +"allwinner,sun8i-h3-pwm"; + reg = <0x01c21400 0x400>; + clocks = <&osc24M>; + #pwm-cells = <3>; + status = "disabled"; + }; + uart0: serial@1c28000 { compatible = "snps,dw-apb-uart"; reg = <0x01c28000 0x400>; -- git-series 0.9.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 13/23] drm/sun4i: Reorder and document DE2 mixer registers
Some registers values have been hardcoded so far, or were not as descriptive as supposed to, because of missing information. The various BSP that poped up since have given us more details, some hopefully we can be more explicit about things. Signed-off-by: Maxime Ripard --- drivers/gpu/drm/sun4i/sun8i_mixer.c | 25 drivers/gpu/drm/sun4i/sun8i_mixer.h | 89 -- 2 files changed, 63 insertions(+), 51 deletions(-) diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c b/drivers/gpu/drm/sun4i/sun8i_mixer.c index 5afe8ef709a5..86c6c24b5105 100644 --- a/drivers/gpu/drm/sun4i/sun8i_mixer.c +++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c @@ -61,7 +61,7 @@ void sun8i_mixer_layer_enable(struct sun8i_mixer *mixer, struct sun8i_ui *ui, regmap_update_bits(mixer->engine.regs, SUN8I_MIXER_CHAN_UI_LAYER_ATTR(ui->chan, ui->id), SUN8I_MIXER_CHAN_UI_LAYER_ATTR_ALPHA_MASK, - SUN8I_MIXER_CHAN_UI_LAYER_ATTR_ALPHA_DEF); + SUN8I_MIXER_CHAN_UI_LAYER_ATTR_ALPHA(255)); } static int sun8i_mixer_drm_format_to_layer(struct drm_plane *plane, @@ -322,19 +322,20 @@ static int sun8i_mixer_bind(struct device *dev, struct device *master, /* Initialize blender */ regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_FCOLOR_CTL, -SUN8I_MIXER_BLEND_FCOLOR_CTL_DEF); - regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_PREMULTIPLY, -SUN8I_MIXER_BLEND_PREMULTIPLY_DEF); +SUN8I_MIXER_BLEND_FCOLOR_CTL_FCOLOR_EN(0) | +SUN8I_MIXER_BLEND_FCOLOR_CTL_EN(0)); + regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_PREMULTIPLY, 0); regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_BKCOLOR, -SUN8I_MIXER_BLEND_BKCOLOR_DEF); +SUN8I_MIXER_BLEND_BKCOLOR_ALPHA(255)); regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_MODE(0), -SUN8I_MIXER_BLEND_MODE_DEF); - regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_CK_CTL, -SUN8I_MIXER_BLEND_CK_CTL_DEF); - - regmap_write(mixer->engine.regs, -SUN8I_MIXER_BLEND_ATTR_FCOLOR(0), -SUN8I_MIXER_BLEND_ATTR_FCOLOR_DEF); +SUN8I_MIXER_BLEND_MODE_PIXEL_FS(1) | +SUN8I_MIXER_BLEND_MODE_PIXEL_FD(3) | +SUN8I_MIXER_BLEND_MODE_ALPHA_FS(1) | +SUN8I_MIXER_BLEND_MODE_ALPHA_FD(3)); + regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_CK_CTL, 0); + + regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_ATTR_FCOLOR(0), +SUN8I_MIXER_BLEND_ATTR_FCOLOR_ALPHA(255)); /* Select the first UI channel */ DRM_DEBUG_DRIVER("Selecting channel %d (first UI channel)\n", 1); diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.h b/drivers/gpu/drm/sun4i/sun8i_mixer.h index 20d2ee1c4187..22877a008e0d 100644 --- a/drivers/gpu/drm/sun4i/sun8i_mixer.h +++ b/drivers/gpu/drm/sun4i/sun8i_mixer.h @@ -22,71 +22,82 @@ #define SUN8I_MIXER_COORD(x, y)((y) << 16 | (x)) #define SUN8I_MIXER_GLOBAL_CTL 0x0 +#define SUN8I_MIXER_GLOBAL_CTL_RT_EN BIT(0) + #define SUN8I_MIXER_GLOBAL_STATUS 0x4 #define SUN8I_MIXER_GLOBAL_DBUFF 0x8 -#define SUN8I_MIXER_GLOBAL_SIZE0xc - -#define SUN8I_MIXER_GLOBAL_CTL_RT_EN 0x1 +#define SUN8I_MIXER_GLOBAL_DBUFF_ENABLEBIT(0) -#define SUN8I_MIXER_GLOBAL_DBUFF_ENABLE0x1 +#define SUN8I_MIXER_GLOBAL_SIZE0xc #define SUN8I_MIXER_BLEND_FCOLOR_CTL 0x1000 +#define SUN8I_MIXER_BLEND_FCOLOR_CTL_EN(x) BIT(8 + (x)) +#define SUN8I_MIXER_BLEND_FCOLOR_CTL_FCOLOR_EN(x) BIT(x) + #define SUN8I_MIXER_BLEND_ATTR_FCOLOR(x) (0x1004 + 0x10 * (x) + 0x0) +#define SUN8I_MIXER_BLEND_ATTR_FCOLOR_ALPHA(x) (((x) & 0xff) << 24) + #define SUN8I_MIXER_BLEND_ATTR_INSIZE(x) (0x1004 + 0x10 * (x) + 0x4) + #define SUN8I_MIXER_BLEND_ATTR_OFFSET(x) (0x1004 + 0x10 * (x) + 0x8) #define SUN8I_MIXER_BLEND_ROUTE0x1080 #define SUN8I_MIXER_BLEND_PREMULTIPLY 0x1084 + #define SUN8I_MIXER_BLEND_BKCOLOR 0x1088 +#define SUN8I_MIXER_BLEND_BKCOLOR_ALPHA(x) (((x) & 0xff) << 24) + #define SUN8I_MIXER_BLEND_OUTSIZE 0x108c + #define SUN8I_MIXER_BLEND_MODE(x) (0x1090 + 0x04 * (x)) +#define SUN8I_MIXER_BLEND_MODE_ALPHA_FD(x) (((x) & 0xf) << 24) +#define SUN8I_MIXER_BLEND_MODE_ALPHA_FS(x) (((x) & 0xf) << 16) +#define SUN8I_MIXER_BLEND_MODE_PIXEL_FD(x) (((x) & 0xf) << 8) +#define SUN8I_MIXER_BLEND_MODE_PIXEL_FS(x) ((x) & 0xf) + #define SUN8I_MIXER_BLEND_CK_CTL 0x10b0 #define SUN8I_MIXER_BLEND_CK_CFG
Re: [PATCH 0/4] drm/meson: power domain init related fixes
On 17/10/2017 11:06, Linus Lüssing wrote: > On Tue, Oct 17, 2017 at 10:07:40AM +0200, Neil Armstrong wrote: >> A PM Power Domain driver has been pushed at [1] to solve the main issue. > > URL to [1] missing? > Sorry, here it is : [1] https://lkml.kernel.org/r/1508228167-11753-1-git-send-email-narmstr...@baylibre.com ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 23/23] arm: dts: sun8i: a711: Enable the LCD
The A711 has 1024x600 LVDS panel, with a PWM-based backlight. Add it to our DT. Signed-off-by: Maxime Ripard --- arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts | 62 - 1 file changed, 62 insertions(+) diff --git a/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts b/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts index e4d08bff3158..5abcb3c9f4b3 100644 --- a/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts +++ b/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts @@ -45,6 +45,7 @@ #include "sun8i-a83t.dtsi" #include +#include / { model = "TBS A711 Tablet"; @@ -59,6 +60,44 @@ stdout-path = "serial0:115200n8"; }; + backlight: backlight { + compatible = "pwm-backlight"; + pwms = <&pwm 0 5 PWM_POLARITY_INVERTED>; + enable-gpios = <&pio 3 29 GPIO_ACTIVE_HIGH>; + + brightness-levels = <0 1 2 4 8 16 32 64 128 255>; + default-brightness-level = <9>; + }; + + panel { + compatible = "tbs,a711-panel", "panel-lvds"; + backlight = <&backlight>; + power-supply = <®_sw>; + + width-mm = <153>; + height-mm = <90>; + data-mapping = "vesa-24"; + + panel-timing { + /* 1024x600 @60Hz */ + clock-frequency = <5200>; + hactive = <1024>; + vactive = <600>; + hsync-len = <20>; + hfront-porch = <180>; + hback-porch = <160>; + vfront-porch = <12>; + vback-porch = <23>; + vsync-len = <5>; + }; + + port { + panel_input: endpoint { + remote-endpoint = <&tcon0_out_lcd>; + }; + }; + }; + reg_vbat: reg-vbat { compatible = "regulator-fixed"; regulator-name = "vbat"; @@ -89,6 +128,10 @@ }; }; +&de { + status = "okay"; +}; + /* * An USB-2 hub is connected here, which also means we don't need to * enable the OHCI controller. @@ -144,6 +187,12 @@ status = "okay"; }; +&pwm { + pinctrl-names = "default"; + pinctrl-0 = <&pwm_pin>; + status = "okay"; +}; + &r_rsb { status = "okay"; @@ -324,6 +373,19 @@ regulator-name = "vcc-lcd"; }; +&tcon0 { + pinctrl-names = "default"; + pinctrl-0 = <&lcd_lvds_pins>; + status = "okay"; +}; + +&tcon0_out { + tcon0_out_lcd: endpoint@0 { + reg = <0>; + remote-endpoint = <&panel_input>; + }; +}; + &uart0 { pinctrl-names = "default"; pinctrl-0 = <&uart0_pb_pins>; -- git-series 0.9.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 16/23] drm/sun4i: Add A83T support
Add support for the A83T display pipeline. Signed-off-by: Maxime Ripard --- Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt | 3 +++ drivers/gpu/drm/sun4i/sun4i_drv.c | 2 ++ drivers/gpu/drm/sun4i/sun4i_tcon.c| 1 + drivers/gpu/drm/sun4i/sun8i_mixer.c | 4 4 files changed, 10 insertions(+) diff --git a/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt b/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt index 46df3b78ae9e..c0fa233ec1fc 100644 --- a/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt +++ b/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt @@ -90,6 +90,7 @@ Required properties: * allwinner,sun6i-a31-tcon * allwinner,sun6i-a31s-tcon * allwinner,sun8i-a33-tcon + * allwinner,sun8i-a83t-tcon * allwinner,sun8i-v3s-tcon - reg: base address and size of memory-mapped region - interrupts: interrupt associated to this IP @@ -209,6 +210,7 @@ supported. Required properties: - compatible: value must be one of: +* allwinner,sun8i-a83t-de2-mixer * allwinner,sun8i-v3s-de2-mixer - reg: base address and size of the memory-mapped region. - clocks: phandles to the clocks feeding the mixer @@ -236,6 +238,7 @@ Required properties: * allwinner,sun6i-a31-display-engine * allwinner,sun6i-a31s-display-engine * allwinner,sun8i-a33-display-engine +* allwinner,sun8i-a83t-display-engine * allwinner,sun8i-v3s-display-engine - allwinner,pipelines: list of phandle to the display engine diff --git a/drivers/gpu/drm/sun4i/sun4i_drv.c b/drivers/gpu/drm/sun4i/sun4i_drv.c index a27efad9bc76..439f116bb3b5 100644 --- a/drivers/gpu/drm/sun4i/sun4i_drv.c +++ b/drivers/gpu/drm/sun4i/sun4i_drv.c @@ -189,6 +189,7 @@ static bool sun4i_drv_node_is_tcon(struct device_node *node) of_device_is_compatible(node, "allwinner,sun6i-a31-tcon") || of_device_is_compatible(node, "allwinner,sun6i-a31s-tcon") || of_device_is_compatible(node, "allwinner,sun8i-a33-tcon") || + of_device_is_compatible(node, "allwinner,sun8i-a83t-tcon") || of_device_is_compatible(node, "allwinner,sun8i-v3s-tcon"); } @@ -347,6 +348,7 @@ static const struct of_device_id sun4i_drv_of_table[] = { { .compatible = "allwinner,sun6i-a31-display-engine" }, { .compatible = "allwinner,sun6i-a31s-display-engine" }, { .compatible = "allwinner,sun8i-a33-display-engine" }, + { .compatible = "allwinner,sun8i-a83t-display-engine" }, { .compatible = "allwinner,sun8i-v3s-display-engine" }, { } }; diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c b/drivers/gpu/drm/sun4i/sun4i_tcon.c index 6a20a467ee6d..eb3c8bad4977 100644 --- a/drivers/gpu/drm/sun4i/sun4i_tcon.c +++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c @@ -1063,6 +1063,7 @@ static const struct of_device_id sun4i_tcon_of_table[] = { { .compatible = "allwinner,sun6i-a31-tcon", .data = &sun6i_a31_quirks }, { .compatible = "allwinner,sun6i-a31s-tcon", .data = &sun6i_a31s_quirks }, { .compatible = "allwinner,sun8i-a33-tcon", .data = &sun8i_a33_quirks }, + { .compatible = "allwinner,sun8i-a83t-tcon", .data = &sun8i_v3s_quirks }, { .compatible = "allwinner,sun8i-v3s-tcon", .data = &sun8i_v3s_quirks }, { } }; diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c b/drivers/gpu/drm/sun4i/sun8i_mixer.c index 86c6c24b5105..c6030ce130d3 100644 --- a/drivers/gpu/drm/sun4i/sun8i_mixer.c +++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c @@ -385,6 +385,10 @@ static const struct sun8i_mixer_cfg sun8i_v3s_mixer_cfg = { static const struct of_device_id sun8i_mixer_of_table[] = { { + .compatible = "allwinner,sun8i-a83t-de2-mixer", + .data = &sun8i_v3s_mixer_cfg, + }, + { .compatible = "allwinner,sun8i-v3s-de2-mixer", .data = &sun8i_v3s_mixer_cfg, }, -- git-series 0.9.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 05/23] drm/sun4i: tcon: Don't rely on encoders to enable the TCON
So far, we've required all the TCON-connected encoders to call the TCON enable and disable functions. This was made this way because in the RGB/LVDS case, the TCON is the CRTC and the encoder. However, in all the other cases (HDMI, TV, DSI, etc.), we have another encoder down the road that needs to be programmed. We also needed to know which channel the encoder is connected to, which is encoder-specific. The CRTC's enable and disable callbacks can work just fine for our use case, and we can get the channel to use just by looking at the type of encoder, since that is fixed. Implement those callbacks, which will remove some of the encoder boilerplate. Signed-off-by: Maxime Ripard --- drivers/gpu/drm/sun4i/sun4i_crtc.c | 22 ++- drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c | 8 +-- drivers/gpu/drm/sun4i/sun4i_rgb.c | 14 +--- drivers/gpu/drm/sun4i/sun4i_tcon.c | 87 --- drivers/gpu/drm/sun4i/sun4i_tcon.h | 10 +--- drivers/gpu/drm/sun4i/sun4i_tv.c | 6 +-- 6 files changed, 67 insertions(+), 80 deletions(-) diff --git a/drivers/gpu/drm/sun4i/sun4i_crtc.c b/drivers/gpu/drm/sun4i/sun4i_crtc.c index d097c6f93ad0..e86baa3746af 100644 --- a/drivers/gpu/drm/sun4i/sun4i_crtc.c +++ b/drivers/gpu/drm/sun4i/sun4i_crtc.c @@ -30,6 +30,22 @@ #include "sunxi_engine.h" #include "sun4i_tcon.h" +/* + * While this isn't really working in the DRM theory, in practice we + * can only ever have one encoder per TCON since we have a mux in our + * TCON. + */ +static struct drm_encoder *sun4i_crtc_get_encoder(struct drm_crtc *crtc) +{ + struct drm_encoder *encoder; + + drm_for_each_encoder(encoder, crtc->dev) + if (encoder->crtc == crtc) + return encoder; + + return NULL; +} + static void sun4i_crtc_atomic_begin(struct drm_crtc *crtc, struct drm_crtc_state *old_state) { @@ -72,11 +88,12 @@ static void sun4i_crtc_atomic_flush(struct drm_crtc *crtc, static void sun4i_crtc_atomic_disable(struct drm_crtc *crtc, struct drm_crtc_state *old_state) { + struct drm_encoder *encoder = sun4i_crtc_get_encoder(crtc); struct sun4i_crtc *scrtc = drm_crtc_to_sun4i_crtc(crtc); DRM_DEBUG_DRIVER("Disabling the CRTC\n"); - sun4i_tcon_disable(scrtc->tcon); + sun4i_tcon_set_status(scrtc->tcon, encoder, false); if (crtc->state->event && !crtc->state->active) { spin_lock_irq(&crtc->dev->event_lock); @@ -90,11 +107,12 @@ static void sun4i_crtc_atomic_disable(struct drm_crtc *crtc, static void sun4i_crtc_atomic_enable(struct drm_crtc *crtc, struct drm_crtc_state *old_state) { + struct drm_encoder *encoder = sun4i_crtc_get_encoder(crtc); struct sun4i_crtc *scrtc = drm_crtc_to_sun4i_crtc(crtc); DRM_DEBUG_DRIVER("Enabling the CRTC\n"); - sun4i_tcon_enable(scrtc->tcon); + sun4i_tcon_set_status(scrtc->tcon, encoder, true); } static const struct drm_crtc_helper_funcs sun4i_crtc_helper_funcs = { diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c index 6ca6e6a74c4a..482bf03d55c1 100644 --- a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c +++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c @@ -86,8 +86,6 @@ static int sun4i_hdmi_atomic_check(struct drm_encoder *encoder, static void sun4i_hdmi_disable(struct drm_encoder *encoder) { struct sun4i_hdmi *hdmi = drm_encoder_to_sun4i_hdmi(encoder); - struct sun4i_crtc *crtc = drm_crtc_to_sun4i_crtc(encoder->crtc); - struct sun4i_tcon *tcon = crtc->tcon; u32 val; DRM_DEBUG_DRIVER("Disabling the HDMI Output\n"); @@ -95,22 +93,16 @@ static void sun4i_hdmi_disable(struct drm_encoder *encoder) val = readl(hdmi->base + SUN4I_HDMI_VID_CTRL_REG); val &= ~SUN4I_HDMI_VID_CTRL_ENABLE; writel(val, hdmi->base + SUN4I_HDMI_VID_CTRL_REG); - - sun4i_tcon_channel_disable(tcon, 1); } static void sun4i_hdmi_enable(struct drm_encoder *encoder) { struct drm_display_mode *mode = &encoder->crtc->state->adjusted_mode; struct sun4i_hdmi *hdmi = drm_encoder_to_sun4i_hdmi(encoder); - struct sun4i_crtc *crtc = drm_crtc_to_sun4i_crtc(encoder->crtc); - struct sun4i_tcon *tcon = crtc->tcon; u32 val = 0; DRM_DEBUG_DRIVER("Enabling the HDMI Output\n"); - sun4i_tcon_channel_enable(tcon, 1); - sun4i_hdmi_setup_avi_infoframes(hdmi, mode); val |= SUN4I_HDMI_PKT_CTRL_TYPE(0, SUN4I_HDMI_PKT_AVI); val |= SUN4I_HDMI_PKT_CTRL_TYPE(1, SUN4I_HDMI_PKT_END); diff --git a/drivers/gpu/drm/sun4i/sun4i_rgb.c b/drivers/gpu/drm/sun4i/sun4i_rgb.c index 7cd7090ad63a..a7f297ed40c1 100644 --- a/drivers/gpu/drm/sun4i/sun4i_rgb.c +++ b/drivers/gpu/drm/sun4i/sun4i_rgb.c @@ -134,13 +134,10 @@ static void sun4i_rgb_encoder_enable(struct drm_encoder *encoder) DRM_DEB
[PATCH 14/23] drm/sun4i: Create minimal multipliers and dividers
The various outputs the TCON can provide have different constraints on the dotclock divider. Let's make them configurable by the various mode_set functions. Signed-off-by: Maxime Ripard --- drivers/gpu/drm/sun4i/sun4i_dotclock.c | 10 +++--- drivers/gpu/drm/sun4i/sun4i_tcon.c | 2 ++ drivers/gpu/drm/sun4i/sun4i_tcon.h | 2 ++ 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/sun4i/sun4i_dotclock.c b/drivers/gpu/drm/sun4i/sun4i_dotclock.c index d401156490f3..023f39bda633 100644 --- a/drivers/gpu/drm/sun4i/sun4i_dotclock.c +++ b/drivers/gpu/drm/sun4i/sun4i_dotclock.c @@ -17,8 +17,9 @@ #include "sun4i_dotclock.h" struct sun4i_dclk { - struct clk_hw hw; - struct regmap *regmap; + struct clk_hw hw; + struct regmap *regmap; + struct sun4i_tcon *tcon; }; static inline struct sun4i_dclk *hw_to_dclk(struct clk_hw *hw) @@ -73,11 +74,13 @@ static unsigned long sun4i_dclk_recalc_rate(struct clk_hw *hw, static long sun4i_dclk_round_rate(struct clk_hw *hw, unsigned long rate, unsigned long *parent_rate) { + struct sun4i_dclk *dclk = hw_to_dclk(hw); + struct sun4i_tcon *tcon = dclk->tcon; unsigned long best_parent = 0; u8 best_div = 1; int i; - for (i = 6; i <= 127; i++) { + for (i = tcon->dclk_min_div; i <= tcon->dclk_max_div; i++) { unsigned long ideal = rate * i; unsigned long rounded; @@ -167,6 +170,7 @@ int sun4i_dclk_create(struct device *dev, struct sun4i_tcon *tcon) dclk = devm_kzalloc(dev, sizeof(*dclk), GFP_KERNEL); if (!dclk) return -ENOMEM; + dclk->tcon = tcon; init.name = clk_name; init.ops = &sun4i_dclk_ops; diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c b/drivers/gpu/drm/sun4i/sun4i_tcon.c index f69bcdf11cb8..3efa1ab045cd 100644 --- a/drivers/gpu/drm/sun4i/sun4i_tcon.c +++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c @@ -177,6 +177,8 @@ static void sun4i_tcon0_mode_set_rgb(struct sun4i_tcon *tcon, u8 clk_delay; u32 val = 0; + tcon->dclk_min_div = 6; + tcon->dclk_max_div = 127; sun4i_tcon0_mode_set_common(tcon, mode); /* Adjust clock delay */ diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.h b/drivers/gpu/drm/sun4i/sun4i_tcon.h index f61bf6d83b4a..4141fbd97ddf 100644 --- a/drivers/gpu/drm/sun4i/sun4i_tcon.h +++ b/drivers/gpu/drm/sun4i/sun4i_tcon.h @@ -169,6 +169,8 @@ struct sun4i_tcon { /* Pixel clock */ struct clk *dclk; + u8 dclk_max_div; + u8 dclk_min_div; /* Reset control */ struct reset_control*lcd_rst; -- git-series 0.9.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 02/23] drm/sun4i: Realign Makefile padding and reorder it
On Tue, Oct 17, 2017 at 5:06 PM, Maxime Ripard wrote: > Some options were not padded as they should, and the order in the Makefile > was chaotic. Fix that. > > Signed-off-by: Maxime Ripard > --- > drivers/gpu/drm/sun4i/Makefile | 28 ++-- > 1 file changed, 14 insertions(+), 14 deletions(-) > > diff --git a/drivers/gpu/drm/sun4i/Makefile b/drivers/gpu/drm/sun4i/Makefile > index 43c753cafc88..af18b70ba5ed 100644 > --- a/drivers/gpu/drm/sun4i/Makefile > +++ b/drivers/gpu/drm/sun4i/Makefile > @@ -1,24 +1,24 @@ > -sun4i-drm-y += sun4i_drv.o > -sun4i-drm-y += sun4i_framebuffer.o > +sun4i-backend-y+= sun4i_backend.o sun4i_layer.o > > -sun4i-drm-hdmi-y += sun4i_hdmi_enc.o > -sun4i-drm-hdmi-y += sun4i_hdmi_i2c.o > -sun4i-drm-hdmi-y += sun4i_hdmi_ddc_clk.o > -sun4i-drm-hdmi-y += sun4i_hdmi_tmds_clk.o > +sun4i-drm-y+= sun4i_drv.o > +sun4i-drm-y+= sun4i_framebuffer.o > > -sun4i-tcon-y += sun4i_tcon.o > -sun4i-tcon-y += sun4i_rgb.o > -sun4i-tcon-y += sun4i_dotclock.o > -sun4i-tcon-y += sun4i_crtc.o > +sun4i-drm-hdmi-y += sun4i_hdmi_enc.o > +sun4i-drm-hdmi-y += sun4i_hdmi_i2c.o > +sun4i-drm-hdmi-y += sun4i_hdmi_ddc_clk.o > +sun4i-drm-hdmi-y += sun4i_hdmi_tmds_clk.o > > -sun4i-backend-y += sun4i_backend.o sun4i_layer.o > +sun4i-tcon-y += sun4i_tcon.o > +sun4i-tcon-y += sun4i_rgb.o > +sun4i-tcon-y += sun4i_dotclock.o > +sun4i-tcon-y += sun4i_crtc.o I don't know if you wanted to sort the file names as well. This would be a good time to do it. Otherwise, Reviewed-by: Chen-Yu Tsai > > -sun8i-mixer-y += sun8i_mixer.o sun8i_layer.o > +sun8i-mixer-y += sun8i_mixer.o sun8i_layer.o > > obj-$(CONFIG_DRM_SUN4I)+= sun4i-drm.o sun4i-tcon.o > obj-$(CONFIG_DRM_SUN4I)+= sun6i_drc.o > obj-$(CONFIG_DRM_SUN4I)+= sun4i_tv.o > > -obj-$(CONFIG_DRM_SUN4I_BACKEND)+= sun4i-backend.o > +obj-$(CONFIG_DRM_SUN4I_BACKEND)+= sun4i-backend.o > obj-$(CONFIG_DRM_SUN4I_HDMI) += sun4i-drm-hdmi.o > -obj-$(CONFIG_DRM_SUN8I_MIXER) += sun8i-mixer.o > +obj-$(CONFIG_DRM_SUN8I_MIXER) += sun8i-mixer.o > -- > git-series 0.9.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 01/23] drm/sun4i: Implement endpoint parsing using kfifo
On Tue, Oct 17, 2017 at 5:06 PM, Maxime Ripard wrote: > The commit da82b8785eeb ("drm/sun4i: add components in breadth first > traversal order") implemented a breadth first traversal of our device tree > nodes graph. However, it was relying on the kernel linked lists, and those > are not really safe for addition. > > Indeed, in a single pipeline stage, your first stage (ie, the mixer or > fronted) will be queued, and it will be the final iteration of that list as > far as list_for_each_entry_safe is concerned. Then, during that final > iteration, we'll queue another element (the TCON or the backend) that > list_for_each_entry_safe will not account for, and we will leave the loop > without having iterated over all the elements. And since we won't have > built our components list properly, the DRM driver will be left > non-functional. > > We can instead use a kfifo to queue and enqueue components in-order, as was > the original intention. This also has the benefit of removing any dynamic > allocation, making the error handling path simpler too. The only thing > we're losing is the ability to tell whether an element has already been > queued, but that was only needed to remove spurious logs, and therefore > purely cosmetic. > > This means that this commit effectively reverses e8afb7b67fba ("drm/sun4i: > don't add components that are already in the queue"). > > Fixes: da82b8785eeb ("drm/sun4i: add components in breadth first traversal > order") > Signed-off-by: Maxime Ripard > --- > drivers/gpu/drm/sun4i/sun4i_drv.c | 71 +--- > 1 file changed, 13 insertions(+), 58 deletions(-) > > diff --git a/drivers/gpu/drm/sun4i/sun4i_drv.c > b/drivers/gpu/drm/sun4i/sun4i_drv.c > index b5879d4620d8..a27efad9bc76 100644 > --- a/drivers/gpu/drm/sun4i/sun4i_drv.c > +++ b/drivers/gpu/drm/sun4i/sun4i_drv.c > @@ -11,6 +11,7 @@ > */ > > #include > +#include > #include > #include > > @@ -222,29 +223,15 @@ static int compare_of(struct device *dev, void *data) > * matching system handles this for us. > */ > struct endpoint_list { > - struct device_node *node; > - struct list_head list; > + DECLARE_KFIFO(fifo, struct device_node *, 16); > }; Is there any reason to keep using struct endpoint_list, other than to avoid using kfifo in function parameter lists? Otherwise the rest of the code looks sound. Reviewed-by: Chen-Yu Tsai ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 03/23] drm/sun4i: tcon: Make tcon_set_mux mode argument const
On Tue, Oct 17, 2017 at 5:06 PM, Maxime Ripard wrote: > The drm_display_mode pointer can be mark const, so let's do it. > > Signed-off-by: Maxime Ripard Reviewed-by: Chen-Yu Tsai ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 04/23] drm/sun4i: tcon: Make tcon_get_clk_delay mode argument const
On Tue, Oct 17, 2017 at 5:06 PM, Maxime Ripard wrote: > The drm_display_mode pointer can be mark const, so let's do it. > > Signed-off-by: Maxime Ripard Reviewed-by: Chen-Yu Tsai ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 05/23] drm/sun4i: tcon: Don't rely on encoders to enable the TCON
On Tue, Oct 17, 2017 at 5:06 PM, Maxime Ripard wrote: > So far, we've required all the TCON-connected encoders to call the TCON > enable and disable functions. > > This was made this way because in the RGB/LVDS case, the TCON is the CRTC > and the encoder. However, in all the other cases (HDMI, TV, DSI, etc.), we > have another encoder down the road that needs to be programmed. > > We also needed to know which channel the encoder is connected to, which is > encoder-specific. > > The CRTC's enable and disable callbacks can work just fine for our use > case, and we can get the channel to use just by looking at the type of > encoder, since that is fixed. Implement those callbacks, which will > remove some of the encoder boilerplate. > > Signed-off-by: Maxime Ripard Reviewed-by: Chen-Yu Tsai ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[Bug 102655] [CI][HSW] igt@gem_flink_race@flink_close - Failed assertion: obj_count == 0
https://bugs.freedesktop.org/show_bug.cgi?id=102655 --- Comment #5 from Chris Wilson --- Had a thought: drm/i915: Flush the idle-worker for debugfs/i915_drop_caches https://patchwork.freedesktop.org/patch/183116/ -- You are receiving this mail because: You are the assignee for the bug.___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
DRM Client Capability for aspect ratio
Hi All, I am working for adding the DRM Client cap for the aspect ratio support as part of the series: https://patchwork.freedesktop.org/series/10850/ : /Picture aspect ratio support in DRM layer/ by Shashank Sharma. I have an open as to how to go about it. I was going through the existing DRM Client Cap like DRM_CLIENT_CAP_STEREO_3D, DRM_CLIENT_CAP_ATOMIC. On Similar lines, I was able to add the new DRM_CLIENT_CAP_ASPECT_RATIO. I also added a member 'aspect_ratio_required' in drm_file structure, which is set, when the client calls drm_setclientcap( ), for aspect ratio, just like its being done for other DRM Client Caps. Now what I want to do is 1.Setting the aspect-ratio flag-bits (19-22) in drmModeModeInfo _only if_ the client advertises that it requires the aspect-ratio. So I need to have this information (that client requires aspect ratio) available in the function: *drm_mode_convert_to_umode( )* : Where the flag bits are actually set 2.Similarly in case of modeset request from the client, we would want to parse the aspect ratio bits from the requesteddrmModeModeInfo only if the client requires aspect ratio. This will require change in the function: *drm_mode_convert_umode()* : Where the flag bits of drm_mode_mode_info are read by the drm layer to determine the aspect ratio and set in drm_display_mode) The problem is that, both these functions have drm_mode_mode_info and drm_display_mode as the only arguments, but our flag aspect_ratio_required is in file_priv (struct drm_file). To do this there are two ways I can think of: 1.Change the drm_mode_convert_umode() to include aspect_ratio_required flag. Before calling this function, the file_priv->aspect_ratio_required will be checked and the flag will be set accordingly. 2.While getting the drmClientCap from client, instead of storing this information in file-priv, store this info in some other structure. Is my understanding correct or is there any other way I should handle the drm client cap? Thanks and Regards, Ankit ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 06/23] drm/sun4i: tcon: Don't rely on encoders to set the TCON mode
On Tue, Oct 17, 2017 at 5:06 PM, Maxime Ripard wrote: > Just like we did for the TCON enable and disable, for historical reasons we > used to rely on the encoders calling the TCON mode_set function, while the > CRTC has a callback for that. > > Let's implement it in order to reduce the boilerplate code. > > Signed-off-by: Maxime Ripard > --- > drivers/gpu/drm/sun4i/sun4i_crtc.c | 10 +++- > drivers/gpu/drm/sun4i/sun4i_hdmi_ddc_clk.c | 1 +- > drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c | 7 +- > drivers/gpu/drm/sun4i/sun4i_hdmi_tmds_clk.c | 1 +- > drivers/gpu/drm/sun4i/sun4i_rgb.c | 15 +--- > drivers/gpu/drm/sun4i/sun4i_tcon.c | 31 +- > drivers/gpu/drm/sun4i/sun4i_tcon.h | 11 ++-- > drivers/gpu/drm/sun4i/sun4i_tv.c| 6 + > 8 files changed, 37 insertions(+), 45 deletions(-) > > diff --git a/drivers/gpu/drm/sun4i/sun4i_crtc.c > b/drivers/gpu/drm/sun4i/sun4i_crtc.c > index e86baa3746af..5decae0069d0 100644 > --- a/drivers/gpu/drm/sun4i/sun4i_crtc.c > +++ b/drivers/gpu/drm/sun4i/sun4i_crtc.c > @@ -115,11 +115,21 @@ static void sun4i_crtc_atomic_enable(struct drm_crtc > *crtc, > sun4i_tcon_set_status(scrtc->tcon, encoder, true); > } > > +static void sun4i_crtc_mode_set_nofb(struct drm_crtc *crtc) > +{ > + struct drm_display_mode *mode = &crtc->state->adjusted_mode; > + struct drm_encoder *encoder = sun4i_crtc_get_encoder(crtc); > + struct sun4i_crtc *scrtc = drm_crtc_to_sun4i_crtc(crtc); > + > + sun4i_tcon_mode_set(scrtc->tcon, encoder, mode); > +} > + > static const struct drm_crtc_helper_funcs sun4i_crtc_helper_funcs = { > .atomic_begin = sun4i_crtc_atomic_begin, > .atomic_flush = sun4i_crtc_atomic_flush, > .atomic_enable = sun4i_crtc_atomic_enable, > .atomic_disable = sun4i_crtc_atomic_disable, > + .mode_set_nofb = sun4i_crtc_mode_set_nofb, > }; > > static int sun4i_crtc_enable_vblank(struct drm_crtc *crtc) > diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_ddc_clk.c > b/drivers/gpu/drm/sun4i/sun4i_hdmi_ddc_clk.c > index 04f85b1cf922..e826da34e919 100644 > --- a/drivers/gpu/drm/sun4i/sun4i_hdmi_ddc_clk.c > +++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_ddc_clk.c > @@ -13,7 +13,6 @@ > #include > #include > > -#include "sun4i_tcon.h" > #include "sun4i_hdmi.h" > > struct sun4i_ddc { > diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c > b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c > index 482bf03d55c1..d2eb0a60e568 100644 > --- a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c > +++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c > @@ -30,7 +30,6 @@ > #include "sun4i_crtc.h" > #include "sun4i_drv.h" > #include "sun4i_hdmi.h" > -#include "sun4i_tcon.h" > > static inline struct sun4i_hdmi * > drm_encoder_to_sun4i_hdmi(struct drm_encoder *encoder) > @@ -120,15 +119,9 @@ static void sun4i_hdmi_mode_set(struct drm_encoder > *encoder, > struct drm_display_mode *adjusted_mode) > { > struct sun4i_hdmi *hdmi = drm_encoder_to_sun4i_hdmi(encoder); > - struct sun4i_crtc *crtc = drm_crtc_to_sun4i_crtc(encoder->crtc); > - struct sun4i_tcon *tcon = crtc->tcon; > unsigned int x, y; > u32 val; > > - sun4i_tcon1_mode_set(tcon, mode); > - sun4i_tcon_set_mux(tcon, 1, encoder); > - > - clk_set_rate(tcon->sclk1, mode->crtc_clock * 1000); > clk_set_rate(hdmi->mod_clk, mode->crtc_clock * 1000); > clk_set_rate(hdmi->tmds_clk, mode->crtc_clock * 1000); > > diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_tmds_clk.c > b/drivers/gpu/drm/sun4i/sun4i_hdmi_tmds_clk.c > index 1b6b37aefc38..dc332ea56f6c 100644 > --- a/drivers/gpu/drm/sun4i/sun4i_hdmi_tmds_clk.c > +++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_tmds_clk.c > @@ -12,7 +12,6 @@ > > #include > > -#include "sun4i_tcon.h" > #include "sun4i_hdmi.h" > > struct sun4i_tmds { > diff --git a/drivers/gpu/drm/sun4i/sun4i_rgb.c > b/drivers/gpu/drm/sun4i/sun4i_rgb.c > index a7f297ed40c1..832f8f9bc47f 100644 > --- a/drivers/gpu/drm/sun4i/sun4i_rgb.c > +++ b/drivers/gpu/drm/sun4i/sun4i_rgb.c > @@ -153,22 +153,7 @@ static void sun4i_rgb_encoder_disable(struct drm_encoder > *encoder) > } > } > > -static void sun4i_rgb_encoder_mode_set(struct drm_encoder *encoder, > - struct drm_display_mode *mode, > - struct drm_display_mode *adjusted_mode) > -{ > - struct sun4i_rgb *rgb = drm_encoder_to_sun4i_rgb(encoder); > - struct sun4i_tcon *tcon = rgb->tcon; > - > - sun4i_tcon0_mode_set(tcon, mode); > - sun4i_tcon_set_mux(tcon, 0, encoder); > - > - /* FIXME: This seems to be board specific */ > - clk_set_phase(tcon->dclk, 120); > -} > - > static struct drm_encoder_helper_funcs sun4i_rgb_enc_helper_funcs = { > - .mode_set = sun4i_rgb_encoder_mode_set, > .disable= sun4i_rgb_encoder_disable, >
Re: [PATCH 07/23] drm/sun4i: tcon: Move out the tcon0 common setup
On Tue, Oct 17, 2017 at 5:06 PM, Maxime Ripard wrote: > Some channel0 setup has to be done, no matter what the output interface is > (RGB, CPU, LVDS). Move that code into a common function in order to avoid > duplication. > > Signed-off-by: Maxime Ripard Reviewed-by: Chen-Yu Tsai ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 08/23] dt-bindings: panel: lvds: Document power-supply property
On Tue, Oct 17, 2017 at 5:06 PM, Maxime Ripard wrote: > The power-supply property is used be a vast majority of panels, including ^^^ typo ChenYu ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 09/23] drm/panel: lvds: Add support for the power-supply property
On Tue, Oct 17, 2017 at 5:06 PM, Maxime Ripard wrote: > A significant number of panels need to power up a regulator in order to > operate properly. Add support for the power-supply property to enable and > disable such a regulator whenever needed. > > Signed-off-by: Maxime Ripard Reviewed-by: Chen-Yu Tsai ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel