From 2c935bc57221cc2edc787c72ea0e2d30cdcd3d5e Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Mon, 14 Nov 2016 17:29:48 +0100 Subject: locking/atomic, kref: Add kref_read() Since we need to change the implementation, stop exposing internals. Provide kref_read() to read the current reference count; typically used for debug messages. Kills two anti-patterns: atomic_read(&kref->refcount) kref->refcount.counter Signed-off-by: Peter Zijlstra (Intel) Cc: Andrew Morton Cc: Greg Kroah-Hartman Cc: Linus Torvalds Cc: Paul E. McKenney Cc: Peter Zijlstra Cc: Thomas Gleixner Cc: linux-kernel@vger.kernel.org Signed-off-by: Ingo Molnar --- drivers/gpu/drm/i915/i915_gem_object.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm/i915') diff --git a/drivers/gpu/drm/i915/i915_gem_object.h b/drivers/gpu/drm/i915/i915_gem_object.h index 6a368de9d81e..ecfefb9d42e4 100644 --- a/drivers/gpu/drm/i915/i915_gem_object.h +++ b/drivers/gpu/drm/i915/i915_gem_object.h @@ -256,7 +256,7 @@ extern void drm_gem_object_unreference_unlocked(struct drm_gem_object *); static inline bool i915_gem_object_is_dead(const struct drm_i915_gem_object *obj) { - return atomic_read(&obj->base.refcount.refcount) == 0; + return kref_read(&obj->base.refcount) == 0; } static inline bool -- cgit From eef57324d926f0d8c7a40069e7d26e0cb0651b47 Mon Sep 17 00:00:00 2001 From: Jerome Anand Date: Wed, 25 Jan 2017 04:27:49 +0530 Subject: drm/i915: setup bridge for HDMI LPE audio driver Enable support for HDMI LPE audio mode on Baytrail and Cherrytrail when HDaudio controller is not detected Setup minimum required resources during i915_driver_load: 1. Create a platform device to share MMIO/IRQ resources 2. Make the platform device child of i915 device for runtime PM. 3. Create IRQ chip to forward HDMI LPE audio irqs. HDMI LPE audio driver (a standalone sound driver) probes the LPE audio device and creates a new sound card. Signed-off-by: Pierre-Louis Bossart Signed-off-by: Jerome Anand Acked-by: Jani Nikula Signed-off-by: Takashi Iwai --- drivers/gpu/drm/i915/Makefile | 3 + drivers/gpu/drm/i915/i915_drv.c | 4 +- drivers/gpu/drm/i915/i915_drv.h | 11 ++ drivers/gpu/drm/i915/i915_irq.c | 16 ++ drivers/gpu/drm/i915/i915_reg.h | 3 + drivers/gpu/drm/i915/intel_audio.c | 25 +++ drivers/gpu/drm/i915/intel_drv.h | 2 + drivers/gpu/drm/i915/intel_lpe_audio.c | 321 +++++++++++++++++++++++++++++++++ 8 files changed, 383 insertions(+), 2 deletions(-) create mode 100644 drivers/gpu/drm/i915/intel_lpe_audio.c (limited to 'drivers/gpu/drm/i915') diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index 3dea46af9fe6..78711dddd937 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -122,6 +122,9 @@ i915-y += intel_gvt.o include $(src)/gvt/Makefile endif +# LPE Audio for VLV and CHT +i915-y += intel_lpe_audio.o + obj-$(CONFIG_DRM_I915) += i915.o CFLAGS_i915_trace_points.o := -I$(src) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 445fec9c2841..9b8d81fa0441 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -1138,7 +1138,7 @@ static void i915_driver_register(struct drm_i915_private *dev_priv) if (IS_GEN5(dev_priv)) intel_gpu_ips_init(dev_priv); - i915_audio_component_init(dev_priv); + intel_audio_init(dev_priv); /* * Some ports require correctly set-up hpd registers for detection to @@ -1156,7 +1156,7 @@ static void i915_driver_register(struct drm_i915_private *dev_priv) */ static void i915_driver_unregister(struct drm_i915_private *dev_priv) { - i915_audio_component_cleanup(dev_priv); + intel_audio_deinit(dev_priv); intel_gpu_ips_teardown(); acpi_video_unregister(); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 243224aeabf8..c55bf144c4e2 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2136,6 +2136,12 @@ struct drm_i915_private { /* Used to save the pipe-to-encoder mapping for audio */ struct intel_encoder *av_enc_map[I915_MAX_PIPES]; + /* necessary resource sharing with HDMI LPE audio driver. */ + struct { + struct platform_device *platdev; + int irq; + } lpe_audio; + /* * NOTE: This is the dri1/ums dungeon, don't add stuff here. Your patch * will be rejected. Instead look for a better place. @@ -3390,6 +3396,11 @@ extern int i915_restore_state(struct drm_device *dev); void i915_setup_sysfs(struct drm_i915_private *dev_priv); void i915_teardown_sysfs(struct drm_i915_private *dev_priv); +/* intel_lpe_audio.c */ +int intel_lpe_audio_init(struct drm_i915_private *dev_priv); +void intel_lpe_audio_teardown(struct drm_i915_private *dev_priv); +void intel_lpe_audio_irq_handler(struct drm_i915_private *dev_priv); + /* intel_i2c.c */ extern int intel_setup_gmbus(struct drm_device *dev); extern void intel_teardown_gmbus(struct drm_device *dev); diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 07ca71cabb2b..f0880afbb878 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -1893,6 +1893,10 @@ static irqreturn_t valleyview_irq_handler(int irq, void *arg) * signalled in iir */ valleyview_pipestat_irq_ack(dev_priv, iir, pipe_stats); + if (iir & (I915_LPE_PIPE_A_INTERRUPT | + I915_LPE_PIPE_B_INTERRUPT)) + intel_lpe_audio_irq_handler(dev_priv); + /* * VLV_IIR is single buffered, and reflects the level * from PIPESTAT/PORT_HOTPLUG_STAT, hence clear it last. @@ -1973,6 +1977,11 @@ static irqreturn_t cherryview_irq_handler(int irq, void *arg) * signalled in iir */ valleyview_pipestat_irq_ack(dev_priv, iir, pipe_stats); + if (iir & (I915_LPE_PIPE_A_INTERRUPT | + I915_LPE_PIPE_B_INTERRUPT | + I915_LPE_PIPE_C_INTERRUPT)) + intel_lpe_audio_irq_handler(dev_priv); + /* * VLV_IIR is single buffered, and reflects the level * from PIPESTAT/PORT_HOTPLUG_STAT, hence clear it last. @@ -2914,6 +2923,7 @@ static void vlv_display_irq_postinstall(struct drm_i915_private *dev_priv) u32 pipestat_mask; u32 enable_mask; enum pipe pipe; + u32 val; pipestat_mask = PLANE_FLIP_DONE_INT_STATUS_VLV | PIPE_CRC_DONE_INTERRUPT_STATUS; @@ -2930,6 +2940,12 @@ static void vlv_display_irq_postinstall(struct drm_i915_private *dev_priv) WARN_ON(dev_priv->irq_mask != ~0); + val = (I915_LPE_PIPE_A_INTERRUPT | + I915_LPE_PIPE_B_INTERRUPT | + I915_LPE_PIPE_C_INTERRUPT); + + enable_mask |= val; + dev_priv->irq_mask = ~enable_mask; GEN5_IRQ_INIT(VLV_, dev_priv->irq_mask, enable_mask); diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index c70c07a7b586..a9ffc8df241b 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -2058,6 +2058,9 @@ enum skl_disp_power_wells { #define I915_ASLE_INTERRUPT (1<<0) #define I915_BSD_USER_INTERRUPT (1<<25) +#define I915_HDMI_LPE_AUDIO_BASE (VLV_DISPLAY_BASE + 0x65000) +#define I915_HDMI_LPE_AUDIO_SIZE 0x1000 + #define GEN6_BSD_RNCID _MMIO(0x12198) #define GEN7_FF_THREAD_MODE _MMIO(0x20a0) diff --git a/drivers/gpu/drm/i915/intel_audio.c b/drivers/gpu/drm/i915/intel_audio.c index 49f10538d4aa..1e93263b4c87 100644 --- a/drivers/gpu/drm/i915/intel_audio.c +++ b/drivers/gpu/drm/i915/intel_audio.c @@ -931,3 +931,28 @@ void i915_audio_component_cleanup(struct drm_i915_private *dev_priv) component_del(dev_priv->drm.dev, &i915_audio_component_bind_ops); dev_priv->audio_component_registered = false; } + +/** + * intel_audio_init() - Initialize the audio driver either using + * component framework or using lpe audio bridge + * @dev_priv: the i915 drm device private data + * + */ +void intel_audio_init(struct drm_i915_private *dev_priv) +{ + if (intel_lpe_audio_init(dev_priv) < 0) + i915_audio_component_init(dev_priv); +} + +/** + * intel_audio_deinit() - deinitialize the audio driver + * @dev_priv: the i915 drm device private data + * + */ +void intel_audio_deinit(struct drm_i915_private *dev_priv) +{ + if ((dev_priv)->lpe_audio.platdev != NULL) + intel_lpe_audio_teardown(dev_priv); + else + i915_audio_component_cleanup(dev_priv); +} diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index cd132c216a67..301c4be0544b 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1192,6 +1192,8 @@ void intel_audio_codec_enable(struct intel_encoder *encoder, void intel_audio_codec_disable(struct intel_encoder *encoder); void i915_audio_component_init(struct drm_i915_private *dev_priv); void i915_audio_component_cleanup(struct drm_i915_private *dev_priv); +void intel_audio_init(struct drm_i915_private *dev_priv); +void intel_audio_deinit(struct drm_i915_private *dev_priv); /* intel_display.c */ enum transcoder intel_crtc_pch_transcoder(struct intel_crtc *crtc); diff --git a/drivers/gpu/drm/i915/intel_lpe_audio.c b/drivers/gpu/drm/i915/intel_lpe_audio.c new file mode 100644 index 000000000000..7ce1b5b99275 --- /dev/null +++ b/drivers/gpu/drm/i915/intel_lpe_audio.c @@ -0,0 +1,321 @@ +/* + * Copyright © 2016 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + * Authors: + * Pierre-Louis Bossart + * Jerome Anand + * based on VED patches + * + */ + +/** + * DOC: LPE Audio integration for HDMI or DP playback + * + * Motivation: + * Atom platforms (e.g. valleyview and cherryTrail) integrates a DMA-based + * interface as an alternative to the traditional HDaudio path. While this + * mode is unrelated to the LPE aka SST audio engine, the documentation refers + * to this mode as LPE so we keep this notation for the sake of consistency. + * + * The interface is handled by a separate standalone driver maintained in the + * ALSA subsystem for simplicity. To minimize the interaction between the two + * subsystems, a bridge is setup between the hdmi-lpe-audio and i915: + * 1. Create a platform device to share MMIO/IRQ resources + * 2. Make the platform device child of i915 device for runtime PM. + * 3. Create IRQ chip to forward the LPE audio irqs. + * the hdmi-lpe-audio driver probes the lpe audio device and creates a new + * sound card + * + * Threats: + * Due to the restriction in Linux platform device model, user need manually + * uninstall the hdmi-lpe-audio driver before uninstalling i915 module, + * otherwise we might run into use-after-free issues after i915 removes the + * platform device: even though hdmi-lpe-audio driver is released, the modules + * is still in "installed" status. + * + * Implementation: + * The MMIO/REG platform resources are created according to the registers + * specification. + * When forwarding LPE audio irqs, the flow control handler selection depends + * on the platform, for example on valleyview handle_simple_irq is enough. + * + */ + +#include +#include +#include + +#include "i915_drv.h" +#include +#include + +#define HAS_LPE_AUDIO(dev_priv) ((dev_priv)->lpe_audio.platdev != NULL) + +static struct platform_device * +lpe_audio_platdev_create(struct drm_i915_private *dev_priv) +{ + int ret; + struct drm_device *dev = &dev_priv->drm; + struct platform_device_info pinfo = {}; + struct resource *rsc; + struct platform_device *platdev; + struct intel_hdmi_lpe_audio_pdata *pdata; + + pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); + if (!pdata) + return ERR_PTR(-ENOMEM); + + rsc = kcalloc(2, sizeof(*rsc), GFP_KERNEL); + if (!rsc) { + kfree(pdata); + return ERR_PTR(-ENOMEM); + } + + rsc[0].start = rsc[0].end = dev_priv->lpe_audio.irq; + rsc[0].flags = IORESOURCE_IRQ; + rsc[0].name = "hdmi-lpe-audio-irq"; + + rsc[1].start = pci_resource_start(dev->pdev, 0) + + I915_HDMI_LPE_AUDIO_BASE; + rsc[1].end = pci_resource_start(dev->pdev, 0) + + I915_HDMI_LPE_AUDIO_BASE + I915_HDMI_LPE_AUDIO_SIZE - 1; + rsc[1].flags = IORESOURCE_MEM; + rsc[1].name = "hdmi-lpe-audio-mmio"; + + pinfo.parent = dev->dev; + pinfo.name = "hdmi-lpe-audio"; + pinfo.id = -1; + pinfo.res = rsc; + pinfo.num_res = 2; + pinfo.data = pdata; + pinfo.size_data = sizeof(*pdata); + pinfo.dma_mask = DMA_BIT_MASK(32); + + spin_lock_init(&pdata->lpe_audio_slock); + + platdev = platform_device_register_full(&pinfo); + if (IS_ERR(platdev)) { + ret = PTR_ERR(platdev); + DRM_ERROR("Failed to allocate LPE audio platform device\n"); + goto err; + } + + kfree(rsc); + + return platdev; + +err: + kfree(rsc); + kfree(pdata); + return ERR_PTR(ret); +} + +static void lpe_audio_platdev_destroy(struct drm_i915_private *dev_priv) +{ + platform_device_unregister(dev_priv->lpe_audio.platdev); + kfree(dev_priv->lpe_audio.platdev->dev.dma_mask); +} + +static void lpe_audio_irq_unmask(struct irq_data *d) +{ + struct drm_i915_private *dev_priv = d->chip_data; + unsigned long irqflags; + u32 val = (I915_LPE_PIPE_A_INTERRUPT | + I915_LPE_PIPE_B_INTERRUPT); + + if (IS_CHERRYVIEW(dev_priv)) + val |= I915_LPE_PIPE_C_INTERRUPT; + + spin_lock_irqsave(&dev_priv->irq_lock, irqflags); + + dev_priv->irq_mask &= ~val; + I915_WRITE(VLV_IIR, val); + I915_WRITE(VLV_IIR, val); + I915_WRITE(VLV_IMR, dev_priv->irq_mask); + POSTING_READ(VLV_IMR); + + spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); +} + +static void lpe_audio_irq_mask(struct irq_data *d) +{ + struct drm_i915_private *dev_priv = d->chip_data; + unsigned long irqflags; + u32 val = (I915_LPE_PIPE_A_INTERRUPT | + I915_LPE_PIPE_B_INTERRUPT); + + if (IS_CHERRYVIEW(dev_priv)) + val |= I915_LPE_PIPE_C_INTERRUPT; + + spin_lock_irqsave(&dev_priv->irq_lock, irqflags); + + dev_priv->irq_mask |= val; + I915_WRITE(VLV_IMR, dev_priv->irq_mask); + I915_WRITE(VLV_IIR, val); + I915_WRITE(VLV_IIR, val); + POSTING_READ(VLV_IIR); + + spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); +} + +static struct irq_chip lpe_audio_irqchip = { + .name = "hdmi_lpe_audio_irqchip", + .irq_mask = lpe_audio_irq_mask, + .irq_unmask = lpe_audio_irq_unmask, +}; + +static int lpe_audio_irq_init(struct drm_i915_private *dev_priv) +{ + int irq = dev_priv->lpe_audio.irq; + + WARN_ON(!intel_irqs_enabled(dev_priv)); + irq_set_chip_and_handler_name(irq, + &lpe_audio_irqchip, + handle_simple_irq, + "hdmi_lpe_audio_irq_handler"); + + return irq_set_chip_data(irq, dev_priv); +} + +static bool lpe_audio_detect(struct drm_i915_private *dev_priv) +{ + int lpe_present = false; + + if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) { + static const struct pci_device_id atom_hdaudio_ids[] = { + /* Baytrail */ + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x0f04)}, + /* Braswell */ + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2284)}, + {} + }; + + if (!pci_dev_present(atom_hdaudio_ids)) { + DRM_INFO("%s\n", "HDaudio controller not detected, using LPE audio instead\n"); + lpe_present = true; + } + } + return lpe_present; +} + +static int lpe_audio_setup(struct drm_i915_private *dev_priv) +{ + int ret; + + dev_priv->lpe_audio.irq = irq_alloc_desc(0); + if (dev_priv->lpe_audio.irq < 0) { + DRM_ERROR("Failed to allocate IRQ desc: %d\n", + dev_priv->lpe_audio.irq); + ret = dev_priv->lpe_audio.irq; + goto err; + } + + DRM_DEBUG("irq = %d\n", dev_priv->lpe_audio.irq); + + ret = lpe_audio_irq_init(dev_priv); + + if (ret) { + DRM_ERROR("Failed to initialize irqchip for lpe audio: %d\n", + ret); + goto err_free_irq; + } + + dev_priv->lpe_audio.platdev = lpe_audio_platdev_create(dev_priv); + + if (IS_ERR(dev_priv->lpe_audio.platdev)) { + ret = PTR_ERR(dev_priv->lpe_audio.platdev); + DRM_ERROR("Failed to create lpe audio platform device: %d\n", + ret); + goto err_free_irq; + } + + return 0; +err_free_irq: + irq_free_desc(dev_priv->lpe_audio.irq); +err: + dev_priv->lpe_audio.irq = -1; + dev_priv->lpe_audio.platdev = NULL; + return ret; +} + +/** + * intel_lpe_audio_irq_handler() - forwards the LPE audio irq + * @dev_priv: the i915 drm device private data + * + * the LPE Audio irq is forwarded to the irq handler registered by LPE audio + * driver. + */ +void intel_lpe_audio_irq_handler(struct drm_i915_private *dev_priv) +{ + int ret; + + if (!HAS_LPE_AUDIO(dev_priv)) + return; + + ret = generic_handle_irq(dev_priv->lpe_audio.irq); + if (ret) + DRM_ERROR_RATELIMITED("error handling LPE audio irq: %d\n", + ret); +} + +/** + * intel_lpe_audio_init() - detect and setup the bridge between HDMI LPE Audio + * driver and i915 + * @dev_priv: the i915 drm device private data + * + * Return: 0 if successful. non-zero if detection or + * llocation/initialization fails + */ +int intel_lpe_audio_init(struct drm_i915_private *dev_priv) +{ + int ret = -ENODEV; + + if (lpe_audio_detect(dev_priv)) { + ret = lpe_audio_setup(dev_priv); + if (ret < 0) + DRM_ERROR("failed to setup LPE Audio bridge\n"); + } + return ret; +} + +/** + * intel_lpe_audio_teardown() - destroy the bridge between HDMI LPE + * audio driver and i915 + * @dev_priv: the i915 drm device private data + * + * release all the resources for LPE audio <-> i915 bridge. + */ +void intel_lpe_audio_teardown(struct drm_i915_private *dev_priv) +{ + struct irq_desc *desc; + + if (!HAS_LPE_AUDIO(dev_priv)) + return; + + desc = irq_to_desc(dev_priv->lpe_audio.irq); + + lpe_audio_irq_mask(&desc->irq_data); + + lpe_audio_platdev_destroy(dev_priv); + + irq_free_desc(dev_priv->lpe_audio.irq); +} -- cgit From 46d196ec460b9c45ca225f815c0b05f9de67290d Mon Sep 17 00:00:00 2001 From: Jerome Anand Date: Wed, 25 Jan 2017 04:27:50 +0530 Subject: drm/i915: Add support for audio driver notifications Notifiations like mode change, hot plug and edid to the audio driver are added. This is inturn used by the audio driver for its functionality. A new interface file capturing the notifications needed by the audio driver is added Signed-off-by: Pierre-Louis Bossart Signed-off-by: Jerome Anand Acked-by: Jani Nikula Signed-off-by: Takashi Iwai --- drivers/gpu/drm/i915/i915_drv.h | 2 ++ drivers/gpu/drm/i915/intel_audio.c | 6 +++++ drivers/gpu/drm/i915/intel_hdmi.c | 1 + drivers/gpu/drm/i915/intel_lpe_audio.c | 49 ++++++++++++++++++++++++++++++++++ 4 files changed, 58 insertions(+) (limited to 'drivers/gpu/drm/i915') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index c55bf144c4e2..3e3102cedc82 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -3400,6 +3400,8 @@ void i915_teardown_sysfs(struct drm_i915_private *dev_priv); int intel_lpe_audio_init(struct drm_i915_private *dev_priv); void intel_lpe_audio_teardown(struct drm_i915_private *dev_priv); void intel_lpe_audio_irq_handler(struct drm_i915_private *dev_priv); +void intel_lpe_audio_notify(struct drm_i915_private *dev_priv, + void *eld, int port, int tmds_clk_speed); /* intel_i2c.c */ extern int intel_setup_gmbus(struct drm_device *dev); diff --git a/drivers/gpu/drm/i915/intel_audio.c b/drivers/gpu/drm/i915/intel_audio.c index 1e93263b4c87..364f96207c40 100644 --- a/drivers/gpu/drm/i915/intel_audio.c +++ b/drivers/gpu/drm/i915/intel_audio.c @@ -24,6 +24,7 @@ #include #include #include +#include #include "intel_drv.h" #include @@ -630,6 +631,9 @@ void intel_audio_codec_enable(struct intel_encoder *intel_encoder, if (acomp && acomp->audio_ops && acomp->audio_ops->pin_eld_notify) acomp->audio_ops->pin_eld_notify(acomp->audio_ops->audio_ptr, (int) port, (int) pipe); + + intel_lpe_audio_notify(dev_priv, connector->eld, port, + crtc_state->port_clock); } /** @@ -663,6 +667,8 @@ void intel_audio_codec_disable(struct intel_encoder *intel_encoder) if (acomp && acomp->audio_ops && acomp->audio_ops->pin_eld_notify) acomp->audio_ops->pin_eld_notify(acomp->audio_ops->audio_ptr, (int) port, (int) pipe); + + intel_lpe_audio_notify(dev_priv, NULL, port, 0); } /** diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index fb88e32e25a3..02d50e334ac6 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -36,6 +36,7 @@ #include #include "intel_drv.h" #include +#include #include "i915_drv.h" static struct drm_device *intel_hdmi_to_dev(struct intel_hdmi *intel_hdmi) diff --git a/drivers/gpu/drm/i915/intel_lpe_audio.c b/drivers/gpu/drm/i915/intel_lpe_audio.c index 7ce1b5b99275..27d94255872d 100644 --- a/drivers/gpu/drm/i915/intel_lpe_audio.c +++ b/drivers/gpu/drm/i915/intel_lpe_audio.c @@ -319,3 +319,52 @@ void intel_lpe_audio_teardown(struct drm_i915_private *dev_priv) irq_free_desc(dev_priv->lpe_audio.irq); } + + +/** + * intel_lpe_audio_notify() - notify lpe audio event + * audio driver and i915 + * @dev_priv: the i915 drm device private data + * @eld : ELD data + * @port: port id + * @tmds_clk_speed: tmds clock frequency in Hz + * + * Notify lpe audio driver of eld change. + */ +void intel_lpe_audio_notify(struct drm_i915_private *dev_priv, + void *eld, int port, int tmds_clk_speed) +{ + unsigned long irq_flags; + struct intel_hdmi_lpe_audio_pdata *pdata = NULL; + + if (!HAS_LPE_AUDIO(dev_priv)) + return; + + pdata = dev_get_platdata( + &(dev_priv->lpe_audio.platdev->dev)); + + spin_lock_irqsave(&pdata->lpe_audio_slock, irq_flags); + + if (eld != NULL) { + memcpy(pdata->eld.eld_data, eld, + HDMI_MAX_ELD_BYTES); + pdata->eld.port_id = port; + pdata->hdmi_connected = true; + + if (tmds_clk_speed) + pdata->tmds_clock_speed = tmds_clk_speed; + } else { + memset(pdata->eld.eld_data, 0, + HDMI_MAX_ELD_BYTES); + pdata->hdmi_connected = false; + } + + if (pdata->notify_audio_lpe) + pdata->notify_audio_lpe( + (eld != NULL) ? &pdata->eld : NULL); + else + pdata->notify_pending = true; + + spin_unlock_irqrestore(&pdata->lpe_audio_slock, + irq_flags); +} -- cgit From b5f2be9ae5bf88f5751cc9f5813ed28e7f87402d Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Tue, 31 Jan 2017 14:16:48 -0600 Subject: drm/i915: add DP support in LPE audio mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If DisplayPort is detected, pass flag and link rate to audio driver Signed-off-by: Pierre-Louis Bossart Acked-by: Ville Syrjälä Signed-off-by: Takashi Iwai --- drivers/gpu/drm/i915/i915_drv.h | 3 ++- drivers/gpu/drm/i915/intel_audio.c | 19 +++++++++++++++---- drivers/gpu/drm/i915/intel_lpe_audio.c | 7 ++++++- 3 files changed, 23 insertions(+), 6 deletions(-) (limited to 'drivers/gpu/drm/i915') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 3e3102cedc82..836d823d476b 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -3401,7 +3401,8 @@ int intel_lpe_audio_init(struct drm_i915_private *dev_priv); void intel_lpe_audio_teardown(struct drm_i915_private *dev_priv); void intel_lpe_audio_irq_handler(struct drm_i915_private *dev_priv); void intel_lpe_audio_notify(struct drm_i915_private *dev_priv, - void *eld, int port, int tmds_clk_speed); + void *eld, int port, int tmds_clk_speed, + bool dp_output, int link_rate); /* intel_i2c.c */ extern int intel_setup_gmbus(struct drm_device *dev); diff --git a/drivers/gpu/drm/i915/intel_audio.c b/drivers/gpu/drm/i915/intel_audio.c index 364f96207c40..1645ce42b898 100644 --- a/drivers/gpu/drm/i915/intel_audio.c +++ b/drivers/gpu/drm/i915/intel_audio.c @@ -631,9 +631,20 @@ void intel_audio_codec_enable(struct intel_encoder *intel_encoder, if (acomp && acomp->audio_ops && acomp->audio_ops->pin_eld_notify) acomp->audio_ops->pin_eld_notify(acomp->audio_ops->audio_ptr, (int) port, (int) pipe); - - intel_lpe_audio_notify(dev_priv, connector->eld, port, - crtc_state->port_clock); + switch (intel_encoder->type) { + case INTEL_OUTPUT_HDMI: + intel_lpe_audio_notify(dev_priv, connector->eld, port, + crtc_state->port_clock, + false, 0); + break; + case INTEL_OUTPUT_DP: + intel_lpe_audio_notify(dev_priv, connector->eld, port, + adjusted_mode->crtc_clock, + true, crtc_state->port_clock); + break; + default: + break; + } } /** @@ -668,7 +679,7 @@ void intel_audio_codec_disable(struct intel_encoder *intel_encoder) acomp->audio_ops->pin_eld_notify(acomp->audio_ops->audio_ptr, (int) port, (int) pipe); - intel_lpe_audio_notify(dev_priv, NULL, port, 0); + intel_lpe_audio_notify(dev_priv, NULL, port, 0, false, 0); } /** diff --git a/drivers/gpu/drm/i915/intel_lpe_audio.c b/drivers/gpu/drm/i915/intel_lpe_audio.c index 27d94255872d..245523e14418 100644 --- a/drivers/gpu/drm/i915/intel_lpe_audio.c +++ b/drivers/gpu/drm/i915/intel_lpe_audio.c @@ -332,7 +332,8 @@ void intel_lpe_audio_teardown(struct drm_i915_private *dev_priv) * Notify lpe audio driver of eld change. */ void intel_lpe_audio_notify(struct drm_i915_private *dev_priv, - void *eld, int port, int tmds_clk_speed) + void *eld, int port, int tmds_clk_speed, + bool dp_output, int link_rate) { unsigned long irq_flags; struct intel_hdmi_lpe_audio_pdata *pdata = NULL; @@ -351,12 +352,16 @@ void intel_lpe_audio_notify(struct drm_i915_private *dev_priv, pdata->eld.port_id = port; pdata->hdmi_connected = true; + pdata->dp_output = dp_output; if (tmds_clk_speed) pdata->tmds_clock_speed = tmds_clk_speed; + if (link_rate) + pdata->link_rate = link_rate; } else { memset(pdata->eld.eld_data, 0, HDMI_MAX_ELD_BYTES); pdata->hdmi_connected = false; + pdata->dp_output = false; } if (pdata->notify_audio_lpe) -- cgit From d5d8c3a19e43ca588555d88e1d43a00aeacd0e56 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Tue, 31 Jan 2017 14:16:49 -0600 Subject: drm/i915: add DisplayPort amp unmute for LPE audio mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Enable unmute/mute amp notification. This doesn't seem to affect HDMI support so this is done unconditionally. An earlier version of this patch set a chicken bit at address 0x62F38 prior to the mute/unmute but this register doesn't seem to do anything so this phase was removed. v1->v2: Drop needless pipe A check, avoid temporary reg offset variable. v2->v3: Add "_" prefix to VLV_AUD_PORT_EN_X_DBG as they are internal. Signed-off-by: Pierre-Louis Bossart Acked-by: Ville Syrjälä Signed-off-by: Takashi Iwai --- drivers/gpu/drm/i915/i915_reg.h | 10 ++++++++++ drivers/gpu/drm/i915/intel_lpe_audio.c | 12 ++++++++++++ 2 files changed, 22 insertions(+) (limited to 'drivers/gpu/drm/i915') diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index a9ffc8df241b..4e24ba0cdbe8 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -2061,6 +2061,16 @@ enum skl_disp_power_wells { #define I915_HDMI_LPE_AUDIO_BASE (VLV_DISPLAY_BASE + 0x65000) #define I915_HDMI_LPE_AUDIO_SIZE 0x1000 +/* DisplayPort Audio w/ LPE */ +#define _VLV_AUD_PORT_EN_B_DBG (VLV_DISPLAY_BASE + 0x62F20) +#define _VLV_AUD_PORT_EN_C_DBG (VLV_DISPLAY_BASE + 0x62F30) +#define _VLV_AUD_PORT_EN_D_DBG (VLV_DISPLAY_BASE + 0x62F34) +#define VLV_AUD_PORT_EN_DBG(port) _MMIO_PORT3((port) - PORT_B, \ + _VLV_AUD_PORT_EN_B_DBG, \ + _VLV_AUD_PORT_EN_C_DBG, \ + _VLV_AUD_PORT_EN_D_DBG) +#define VLV_AMP_MUTE (1 << 1) + #define GEN6_BSD_RNCID _MMIO(0x12198) #define GEN7_FF_THREAD_MODE _MMIO(0x20a0) diff --git a/drivers/gpu/drm/i915/intel_lpe_audio.c b/drivers/gpu/drm/i915/intel_lpe_audio.c index 245523e14418..5da14f40f94a 100644 --- a/drivers/gpu/drm/i915/intel_lpe_audio.c +++ b/drivers/gpu/drm/i915/intel_lpe_audio.c @@ -337,6 +337,7 @@ void intel_lpe_audio_notify(struct drm_i915_private *dev_priv, { unsigned long irq_flags; struct intel_hdmi_lpe_audio_pdata *pdata = NULL; + u32 audio_enable; if (!HAS_LPE_AUDIO(dev_priv)) return; @@ -346,6 +347,8 @@ void intel_lpe_audio_notify(struct drm_i915_private *dev_priv, spin_lock_irqsave(&pdata->lpe_audio_slock, irq_flags); + audio_enable = I915_READ(VLV_AUD_PORT_EN_DBG(port)); + if (eld != NULL) { memcpy(pdata->eld.eld_data, eld, HDMI_MAX_ELD_BYTES); @@ -357,11 +360,20 @@ void intel_lpe_audio_notify(struct drm_i915_private *dev_priv, pdata->tmds_clock_speed = tmds_clk_speed; if (link_rate) pdata->link_rate = link_rate; + + /* Unmute the amp for both DP and HDMI */ + I915_WRITE(VLV_AUD_PORT_EN_DBG(port), + audio_enable & ~VLV_AMP_MUTE); + } else { memset(pdata->eld.eld_data, 0, HDMI_MAX_ELD_BYTES); pdata->hdmi_connected = false; pdata->dp_output = false; + + /* Mute the amp for both DP and HDMI */ + I915_WRITE(VLV_AUD_PORT_EN_DBG(port), + audio_enable | VLV_AMP_MUTE); } if (pdata->notify_audio_lpe) -- cgit From 9c9191f3de5926830346750ce4417d261027ab80 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 31 Jan 2017 14:16:50 -0600 Subject: drm/i915: Avoid MST pipe handling for LPE audio MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The pipe gets cleared to -1 for non-MST before the ELD audio notification due to the MST audio support. This makes sense for HD-audio that received the MST handling, but it's useless for LPE audio. Handle the MST pipe hack conditionally only for HD-audio. Reported-by: Pierre-Louis Bossart Acked-by: Ville Syrjälä Signed-off-by: Takashi Iwai --- drivers/gpu/drm/i915/intel_audio.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) (limited to 'drivers/gpu/drm/i915') diff --git a/drivers/gpu/drm/i915/intel_audio.c b/drivers/gpu/drm/i915/intel_audio.c index 1645ce42b898..d4e6d1136cfe 100644 --- a/drivers/gpu/drm/i915/intel_audio.c +++ b/drivers/gpu/drm/i915/intel_audio.c @@ -624,13 +624,14 @@ void intel_audio_codec_enable(struct intel_encoder *intel_encoder, dev_priv->av_enc_map[pipe] = intel_encoder; mutex_unlock(&dev_priv->av_mutex); - /* audio drivers expect pipe = -1 to indicate Non-MST cases */ - if (intel_encoder->type != INTEL_OUTPUT_DP_MST) - pipe = -1; - - if (acomp && acomp->audio_ops && acomp->audio_ops->pin_eld_notify) + if (acomp && acomp->audio_ops && acomp->audio_ops->pin_eld_notify) { + /* audio drivers expect pipe = -1 to indicate Non-MST cases */ + if (intel_encoder->type != INTEL_OUTPUT_DP_MST) + pipe = -1; acomp->audio_ops->pin_eld_notify(acomp->audio_ops->audio_ptr, (int) port, (int) pipe); + } + switch (intel_encoder->type) { case INTEL_OUTPUT_HDMI: intel_lpe_audio_notify(dev_priv, connector->eld, port, @@ -671,13 +672,13 @@ void intel_audio_codec_disable(struct intel_encoder *intel_encoder) dev_priv->av_enc_map[pipe] = NULL; mutex_unlock(&dev_priv->av_mutex); - /* audio drivers expect pipe = -1 to indicate Non-MST cases */ - if (intel_encoder->type != INTEL_OUTPUT_DP_MST) - pipe = -1; - - if (acomp && acomp->audio_ops && acomp->audio_ops->pin_eld_notify) + if (acomp && acomp->audio_ops && acomp->audio_ops->pin_eld_notify) { + /* audio drivers expect pipe = -1 to indicate Non-MST cases */ + if (intel_encoder->type != INTEL_OUTPUT_DP_MST) + pipe = -1; acomp->audio_ops->pin_eld_notify(acomp->audio_ops->audio_ptr, (int) port, (int) pipe); + } intel_lpe_audio_notify(dev_priv, NULL, port, 0, false, 0); } -- cgit From f95e29b92190607c66dc5c96b7e0de9c332062c2 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 31 Jan 2017 14:16:51 -0600 Subject: drm/i915: Pass pipe to LPE audio notification MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The LPE audio configuration depends on the pipe, thus we need to pass the currently used pipe. It's now embedded in struct intel_hdmi_lpe_audio_eld as well as port id. Acked-by: Ville Syrjälä Signed-off-by: Takashi Iwai --- drivers/gpu/drm/i915/i915_drv.h | 2 +- drivers/gpu/drm/i915/intel_audio.c | 6 +++--- drivers/gpu/drm/i915/intel_lpe_audio.c | 3 ++- 3 files changed, 6 insertions(+), 5 deletions(-) (limited to 'drivers/gpu/drm/i915') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 836d823d476b..27311a337e2b 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -3401,7 +3401,7 @@ int intel_lpe_audio_init(struct drm_i915_private *dev_priv); void intel_lpe_audio_teardown(struct drm_i915_private *dev_priv); void intel_lpe_audio_irq_handler(struct drm_i915_private *dev_priv); void intel_lpe_audio_notify(struct drm_i915_private *dev_priv, - void *eld, int port, int tmds_clk_speed, + void *eld, int port, int pipe, int tmds_clk_speed, bool dp_output, int link_rate); /* intel_i2c.c */ diff --git a/drivers/gpu/drm/i915/intel_audio.c b/drivers/gpu/drm/i915/intel_audio.c index d4e6d1136cfe..892169b7952b 100644 --- a/drivers/gpu/drm/i915/intel_audio.c +++ b/drivers/gpu/drm/i915/intel_audio.c @@ -634,12 +634,12 @@ void intel_audio_codec_enable(struct intel_encoder *intel_encoder, switch (intel_encoder->type) { case INTEL_OUTPUT_HDMI: - intel_lpe_audio_notify(dev_priv, connector->eld, port, + intel_lpe_audio_notify(dev_priv, connector->eld, port, pipe, crtc_state->port_clock, false, 0); break; case INTEL_OUTPUT_DP: - intel_lpe_audio_notify(dev_priv, connector->eld, port, + intel_lpe_audio_notify(dev_priv, connector->eld, port, pipe, adjusted_mode->crtc_clock, true, crtc_state->port_clock); break; @@ -680,7 +680,7 @@ void intel_audio_codec_disable(struct intel_encoder *intel_encoder) (int) port, (int) pipe); } - intel_lpe_audio_notify(dev_priv, NULL, port, 0, false, 0); + intel_lpe_audio_notify(dev_priv, NULL, port, pipe, 0, false, 0); } /** diff --git a/drivers/gpu/drm/i915/intel_lpe_audio.c b/drivers/gpu/drm/i915/intel_lpe_audio.c index 5da14f40f94a..68ebf3830433 100644 --- a/drivers/gpu/drm/i915/intel_lpe_audio.c +++ b/drivers/gpu/drm/i915/intel_lpe_audio.c @@ -332,7 +332,7 @@ void intel_lpe_audio_teardown(struct drm_i915_private *dev_priv) * Notify lpe audio driver of eld change. */ void intel_lpe_audio_notify(struct drm_i915_private *dev_priv, - void *eld, int port, int tmds_clk_speed, + void *eld, int port, int pipe, int tmds_clk_speed, bool dp_output, int link_rate) { unsigned long irq_flags; @@ -353,6 +353,7 @@ void intel_lpe_audio_notify(struct drm_i915_private *dev_priv, memcpy(pdata->eld.eld_data, eld, HDMI_MAX_ELD_BYTES); pdata->eld.port_id = port; + pdata->eld.pipe_id = pipe; pdata->hdmi_connected = true; pdata->dp_output = dp_output; -- cgit From b1c01f4df20a6376fe6245644225ff9fe97c5f95 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 30 Jan 2017 17:56:39 +0100 Subject: drm/i915: Pass platform device to LPE audio notifier MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This allows the LPE HDMI driver to clean up its global variable reference. Also drop to pass the eld pointer because the connection status and the ELD bytes can be retrieved from the attached pdata. Acked-by: Ville Syrjälä Signed-off-by: Takashi Iwai --- drivers/gpu/drm/i915/intel_lpe_audio.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers/gpu/drm/i915') diff --git a/drivers/gpu/drm/i915/intel_lpe_audio.c b/drivers/gpu/drm/i915/intel_lpe_audio.c index 68ebf3830433..d3ffe0012692 100644 --- a/drivers/gpu/drm/i915/intel_lpe_audio.c +++ b/drivers/gpu/drm/i915/intel_lpe_audio.c @@ -378,8 +378,7 @@ void intel_lpe_audio_notify(struct drm_i915_private *dev_priv, } if (pdata->notify_audio_lpe) - pdata->notify_audio_lpe( - (eld != NULL) ? &pdata->eld : NULL); + pdata->notify_audio_lpe(dev_priv->lpe_audio.platdev); else pdata->notify_pending = true; -- cgit From 9db13e5f2d6dc85150cb8a69ab220b84d9b9fbe7 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 2 Feb 2017 11:03:48 +0100 Subject: drm/i915: Enable VLV audio chicken bit for LPE audio MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The audio chicken bit (register offset 0x62f38) seems required to make DP audio working on some machines. At least, on Dell Wyse 3040, I failed to get the audio unless this bit is set once. Strangely, the bit seems necessary only once, and it persists after that, even some power-off cycles. The register is supposedly write-only, so it's no evidence whether the bit keeps effect persistently. But, judging from the experiment, it looks enough to set it up once at the device initialization. The patch is basically a cut from the original patch by Pierre-Louis Bossart. v1->v2: drop read since it's a write-only reg. Cc: Pierre-Louis Bossart Reviewed-by: Ville Syrjälä Signed-off-by: Takashi Iwai --- drivers/gpu/drm/i915/i915_reg.h | 3 +++ drivers/gpu/drm/i915/intel_lpe_audio.c | 5 +++++ 2 files changed, 8 insertions(+) (limited to 'drivers/gpu/drm/i915') diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 4e24ba0cdbe8..4f15a3dc6d98 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -2062,6 +2062,9 @@ enum skl_disp_power_wells { #define I915_HDMI_LPE_AUDIO_SIZE 0x1000 /* DisplayPort Audio w/ LPE */ +#define VLV_AUD_CHICKEN_BIT_REG _MMIO(VLV_DISPLAY_BASE + 0x62F38) +#define VLV_CHICKEN_BIT_DBG_ENABLE (1 << 0) + #define _VLV_AUD_PORT_EN_B_DBG (VLV_DISPLAY_BASE + 0x62F20) #define _VLV_AUD_PORT_EN_C_DBG (VLV_DISPLAY_BASE + 0x62F30) #define _VLV_AUD_PORT_EN_D_DBG (VLV_DISPLAY_BASE + 0x62F34) diff --git a/drivers/gpu/drm/i915/intel_lpe_audio.c b/drivers/gpu/drm/i915/intel_lpe_audio.c index d3ffe0012692..7a5b41b1c024 100644 --- a/drivers/gpu/drm/i915/intel_lpe_audio.c +++ b/drivers/gpu/drm/i915/intel_lpe_audio.c @@ -248,6 +248,11 @@ static int lpe_audio_setup(struct drm_i915_private *dev_priv) goto err_free_irq; } + /* enable chicken bit; at least this is required for Dell Wyse 3040 + * with DP outputs (but only sometimes by some reason!) + */ + I915_WRITE(VLV_AUD_CHICKEN_BIT_REG, VLV_CHICKEN_BIT_DBG_ENABLE); + return 0; err_free_irq: irq_free_desc(dev_priv->lpe_audio.irq); -- cgit From da7bdda2afdf1ae58546218b50771c2c646bb079 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 7 Feb 2017 17:16:03 +0100 Subject: drm/fb-helper: Automatically clean up fb_info MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Noticed that everyone duplicates the same logic here and we could safe a few lines per driver. Yay for lots of drivers to make such tiny refactors worth-while! v2: Forgot to git add everything :( v3: Actually remove release_fbi (Sean, Emil, Chris) ... Cc: Chris Wilson Cc: Sean Paul Cc: Noralf Trønnes Cc: Emil Velikov Reviewed-by: Sean Paul Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/20170207161603.17611-1-daniel.vetter@ffwll.ch --- drivers/gpu/drm/i915/intel_fbdev.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'drivers/gpu/drm/i915') diff --git a/drivers/gpu/drm/i915/intel_fbdev.c b/drivers/gpu/drm/i915/intel_fbdev.c index 1b8ba2e77539..281c5c48a84d 100644 --- a/drivers/gpu/drm/i915/intel_fbdev.c +++ b/drivers/gpu/drm/i915/intel_fbdev.c @@ -253,7 +253,7 @@ static int intelfb_create(struct drm_fb_helper *helper, if (IS_ERR(vaddr)) { DRM_ERROR("Failed to remap framebuffer into virtual memory\n"); ret = PTR_ERR(vaddr); - goto out_destroy_fbi; + goto out_unpin; } info->screen_base = vaddr; info->screen_size = vma->node.size; @@ -281,8 +281,6 @@ static int intelfb_create(struct drm_fb_helper *helper, vga_switcheroo_client_fb_set(pdev, info); return 0; -out_destroy_fbi: - drm_fb_helper_release_fbi(helper); out_unpin: intel_unpin_fb_vma(vma); out_unlock: @@ -543,7 +541,6 @@ static void intel_fbdev_destroy(struct intel_fbdev *ifbdev) */ drm_fb_helper_unregister_fbi(&ifbdev->helper); - drm_fb_helper_release_fbi(&ifbdev->helper); drm_fb_helper_fini(&ifbdev->helper); -- cgit From 967dd48417874dd25491a4e933648f394a64f70f Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Tue, 7 Feb 2017 17:16:14 +0800 Subject: drm: remove drm_vblank_no_hw_counter assignment from driver code Core code already makes drm_driver.get_vblank_counter hook optional by letting drm_vblank_no_hw_counter be the default implementation for the function hook. So the drm_vblank_no_hw_counter assignment in the driver code becomes redundant and can be removed now. Signed-off-by: Shawn Guo Cc: Alexey Brodkin Cc: Liviu Dudau Cc: Mali DP Maintainers Cc: Russell King Cc: Boris Brezillon Cc: Inki Dae Cc: Stefan Agner Cc: Xinliang Liu Cc: Daniel Vetter Cc: Philipp Zabel Cc: CK Hu Cc: Neil Armstrong Cc: Rob Clark Cc: Marek Vasut Cc: Ben Skeggs Cc: Tomi Valkeinen Cc: Laurent Pinchart Cc: Mark Yao Cc: Benjamin Gaignard Cc: Maxime Ripard Cc: Jyri Sarha Cc: Eric Anholt Acked-by: Maxime Ripard Acked-by: Boris Brezillon Acked-by: Neil Armstrong Acked-by: Russell King Reviewed-by: Laurent Pinchart Acked-by: Alexey Brodkin Acked-by: Liviu Dudau Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1486458995-31018-3-git-send-email-shawnguo@kernel.org --- drivers/gpu/drm/i915/i915_irq.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/gpu/drm/i915') diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 6fefc34ef602..ee313247673b 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -4202,7 +4202,6 @@ void intel_irq_init(struct drm_i915_private *dev_priv) if (IS_GEN2(dev_priv)) { /* Gen2 doesn't have a hardware frame counter */ dev->max_vblank_count = 0; - dev->driver->get_vblank_counter = drm_vblank_no_hw_counter; } else if (IS_G4X(dev_priv) || INTEL_INFO(dev_priv)->gen >= 5) { dev->max_vblank_count = 0xffffffff; /* full 32 bit counter */ dev->driver->get_vblank_counter = g4x_get_vblank_counter; -- cgit From 581e49fe6b411f407102a7f2377648849e0fa37f Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Mon, 16 Jan 2017 10:37:38 +0100 Subject: drm/atomic: Add new iterators over all state, v3. Add for_each_(old)(new)_(plane,connector,crtc)_in_state iterators to replace the old for_each_xxx_in_state ones. This is useful for >1 flip depth and getting rid of all xxx->state dereferences. This requires extra fixups done when committing a state after duplicating, which in general isn't valid but is used by suspend/resume. To handle these, introduce drm_atomic_helper_commit_duplicated_state which performs those fixups before checking & committing the state. Changes since v1: - Remove nonblock parameter for commit_duplicated_state. Changes since v2: - Use commit_duplicated_state for i915 load detection. - Add WARN_ON(old_state != obj->state) before swapping. Signed-off-by: Maarten Lankhorst Reviewed-by: Laurent Pinchart Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1484559464-27107-2-git-send-email-maarten.lankhorst@linux.intel.com --- drivers/gpu/drm/i915/intel_display.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'drivers/gpu/drm/i915') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index b3e773c9f872..36ecc864e711 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -3481,7 +3481,8 @@ static void intel_update_primary_planes(struct drm_device *dev) static int __intel_display_resume(struct drm_device *dev, - struct drm_atomic_state *state) + struct drm_atomic_state *state, + struct drm_modeset_acquire_ctx *ctx) { struct drm_crtc_state *crtc_state; struct drm_crtc *crtc; @@ -3505,7 +3506,7 @@ __intel_display_resume(struct drm_device *dev, /* ignore any reset values/BIOS leftovers in the WM registers */ to_intel_atomic_state(state)->skip_intermediate_wm = true; - ret = drm_atomic_commit(state); + ret = drm_atomic_helper_commit_duplicated_state(state, ctx); WARN_ON(ret == -EDEADLK); return ret; @@ -3595,7 +3596,7 @@ void intel_finish_reset(struct drm_i915_private *dev_priv) */ intel_update_primary_planes(dev); } else { - ret = __intel_display_resume(dev, state); + ret = __intel_display_resume(dev, state, ctx); if (ret) DRM_ERROR("Restoring old state failed with %i\n", ret); } @@ -3615,7 +3616,7 @@ void intel_finish_reset(struct drm_i915_private *dev_priv) dev_priv->display.hpd_irq_setup(dev_priv); spin_unlock_irq(&dev_priv->irq_lock); - ret = __intel_display_resume(dev, state); + ret = __intel_display_resume(dev, state, ctx); if (ret) DRM_ERROR("Restoring old state failed with %i\n", ret); @@ -11316,7 +11317,7 @@ void intel_release_load_detect_pipe(struct drm_connector *connector, if (!state) return; - ret = drm_atomic_commit(state); + ret = drm_atomic_helper_commit_duplicated_state(state, ctx); if (ret) DRM_DEBUG_KMS("Couldn't release load detect pipe: %i\n", ret); drm_atomic_state_put(state); @@ -17212,7 +17213,7 @@ void intel_display_resume(struct drm_device *dev) } if (!ret) - ret = __intel_display_resume(dev, state); + ret = __intel_display_resume(dev, state, &ctx); drm_modeset_drop_locks(&ctx); drm_modeset_acquire_fini(&ctx); -- cgit From f74ac01520c9f6d89bbc3c6931a72f757b742f86 Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Mon, 20 Feb 2017 16:51:23 +0100 Subject: mm: use helper for calling f_op->mmap() Signed-off-by: Miklos Szeredi --- drivers/gpu/drm/i915/i915_gem_dmabuf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm/i915') diff --git a/drivers/gpu/drm/i915/i915_gem_dmabuf.c b/drivers/gpu/drm/i915/i915_gem_dmabuf.c index 5e38299b5df6..84fc9f001576 100644 --- a/drivers/gpu/drm/i915/i915_gem_dmabuf.c +++ b/drivers/gpu/drm/i915/i915_gem_dmabuf.c @@ -141,7 +141,7 @@ static int i915_gem_dmabuf_mmap(struct dma_buf *dma_buf, struct vm_area_struct * if (!obj->base.filp) return -ENODEV; - ret = obj->base.filp->f_op->mmap(obj->base.filp, vma); + ret = call_mmap(obj->base.filp, vma); if (ret) return ret; -- cgit From 11bac80004499ea59f361ef2a5516c84b6eab675 Mon Sep 17 00:00:00 2001 From: Dave Jiang Date: Fri, 24 Feb 2017 14:56:41 -0800 Subject: mm, fs: reduce fault, page_mkwrite, and pfn_mkwrite to take only vmf ->fault(), ->page_mkwrite(), and ->pfn_mkwrite() calls do not need to take a vma and vmf parameter when the vma already resides in vmf. Remove the vma parameter to simplify things. [arnd@arndb.de: fix ARM build] Link: http://lkml.kernel.org/r/20170125223558.1451224-1-arnd@arndb.de Link: http://lkml.kernel.org/r/148521301778.19116.10840599906674778980.stgit@djiang5-desk3.ch.intel.com Signed-off-by: Dave Jiang Signed-off-by: Arnd Bergmann Reviewed-by: Ross Zwisler Cc: Theodore Ts'o Cc: Darrick J. Wong Cc: Matthew Wilcox Cc: Dave Hansen Cc: Christoph Hellwig Cc: Jan Kara Cc: Dan Williams Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/gpu/drm/i915/i915_drv.h | 2 +- drivers/gpu/drm/i915/i915_gem.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/gpu/drm/i915') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index bcc81912b5e5..0a4b42d31391 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -3352,7 +3352,7 @@ int __must_check i915_gem_wait_for_idle(struct drm_i915_private *dev_priv, unsigned int flags); int __must_check i915_gem_suspend(struct drm_i915_private *dev_priv); void i915_gem_resume(struct drm_i915_private *dev_priv); -int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf); +int i915_gem_fault(struct vm_fault *vmf); int i915_gem_object_wait(struct drm_i915_gem_object *obj, unsigned int flags, long timeout, diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 88f3628b4e29..6908123162d1 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1772,7 +1772,6 @@ compute_partial_view(struct drm_i915_gem_object *obj, /** * i915_gem_fault - fault a page into the GTT - * @area: CPU VMA in question * @vmf: fault info * * The fault handler is set up by drm_gem_mmap() when a object is GTT mapped @@ -1789,9 +1788,10 @@ compute_partial_view(struct drm_i915_gem_object *obj, * The current feature set supported by i915_gem_fault() and thus GTT mmaps * is exposed via I915_PARAM_MMAP_GTT_VERSION (see i915_gem_mmap_gtt_version). */ -int i915_gem_fault(struct vm_area_struct *area, struct vm_fault *vmf) +int i915_gem_fault(struct vm_fault *vmf) { #define MIN_CHUNK_PAGES ((1 << 20) >> PAGE_SHIFT) /* 1 MiB */ + struct vm_area_struct *area = vmf->vma; struct drm_i915_gem_object *obj = to_intel_bo(area->vm_private_data); struct drm_device *dev = obj->base.dev; struct drm_i915_private *dev_priv = to_i915(dev); -- cgit From 550116d21a656e8b5670073e586315e5a6d12f01 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 27 Feb 2017 14:28:58 -0800 Subject: scripts/spelling.txt: add "aligment" pattern and fix typo instances Fix typos and add the following to the scripts/spelling.txt: aligment||alignment I did not touch the "N_BYTE_ALIGMENT" macro in drivers/net/wireless/realtek/rtlwifi/wifi.h to avoid unpredictable impact. I fixed "_aligment_handler" in arch/openrisc/kernel/entry.S because it is surrounded by #if 0 ... #endif. It is surely safe and I confirmed "_alignment_handler" is correct. I also fixed the "controler" I found in the same hunk in arch/openrisc/kernel/head.S. Link: http://lkml.kernel.org/r/1481573103-11329-8-git-send-email-yamada.masahiro@socionext.com Signed-off-by: Masahiro Yamada Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/gpu/drm/i915/i915_gem_render_state.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm/i915') diff --git a/drivers/gpu/drm/i915/i915_gem_render_state.c b/drivers/gpu/drm/i915/i915_gem_render_state.c index b42c81b42487..7032c542a9b1 100644 --- a/drivers/gpu/drm/i915/i915_gem_render_state.c +++ b/drivers/gpu/drm/i915/i915_gem_render_state.c @@ -60,7 +60,7 @@ render_state_get_rodata(const struct intel_engine_cs *engine) * this is sufficient as the null state generator makes the final batch * with two passes to build command and state separately. At this point * the size of both are known and it compacts them by relocating the state - * right after the commands taking care of aligment so we should sufficient + * right after the commands taking care of alignment so we should sufficient * space below them for adding new commands. */ #define OUT_BATCH(batch, i, val) \ -- cgit From f1f1007644ffc8051a4c11427d58b1967ae7b75a Mon Sep 17 00:00:00 2001 From: Vegard Nossum Date: Mon, 27 Feb 2017 14:30:07 -0800 Subject: mm: add new mmgrab() helper Apart from adding the helper function itself, the rest of the kernel is converted mechanically using: git grep -l 'atomic_inc.*mm_count' | xargs sed -i 's/atomic_inc(&\(.*\)->mm_count);/mmgrab\(\1\);/' git grep -l 'atomic_inc.*mm_count' | xargs sed -i 's/atomic_inc(&\(.*\)\.mm_count);/mmgrab\(\&\1\);/' This is needed for a later patch that hooks into the helper, but might be a worthwhile cleanup on its own. (Michal Hocko provided most of the kerneldoc comment.) Link: http://lkml.kernel.org/r/20161218123229.22952-1-vegard.nossum@oracle.com Signed-off-by: Vegard Nossum Acked-by: Michal Hocko Acked-by: Peter Zijlstra (Intel) Acked-by: David Rientjes Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/gpu/drm/i915/i915_gem_userptr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm/i915') diff --git a/drivers/gpu/drm/i915/i915_gem_userptr.c b/drivers/gpu/drm/i915/i915_gem_userptr.c index 6a8fa085b74e..65802d93fdc1 100644 --- a/drivers/gpu/drm/i915/i915_gem_userptr.c +++ b/drivers/gpu/drm/i915/i915_gem_userptr.c @@ -334,7 +334,7 @@ i915_gem_userptr_init__mm_struct(struct drm_i915_gem_object *obj) mm->i915 = to_i915(obj->base.dev); mm->mm = current->mm; - atomic_inc(¤t->mm->mm_count); + mmgrab(current->mm); mm->mn = NULL; -- cgit From 388f79345502232d335467e8fa6f8e55a18844e1 Mon Sep 17 00:00:00 2001 From: Vegard Nossum Date: Mon, 27 Feb 2017 14:30:13 -0800 Subject: mm: use mmget_not_zero() helper We already have the helper, we can convert the rest of the kernel mechanically using: git grep -l 'atomic_inc_not_zero.*mm_users' | xargs sed -i 's/atomic_inc_not_zero(&\(.*\)->mm_users)/mmget_not_zero\(\1\)/' This is needed for a later patch that hooks into the helper, but might be a worthwhile cleanup on its own. Link: http://lkml.kernel.org/r/20161218123229.22952-3-vegard.nossum@oracle.com Signed-off-by: Vegard Nossum Acked-by: Michal Hocko Acked-by: Peter Zijlstra (Intel) Acked-by: David Rientjes Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/gpu/drm/i915/i915_gem_userptr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm/i915') diff --git a/drivers/gpu/drm/i915/i915_gem_userptr.c b/drivers/gpu/drm/i915/i915_gem_userptr.c index 65802d93fdc1..0115989e324a 100644 --- a/drivers/gpu/drm/i915/i915_gem_userptr.c +++ b/drivers/gpu/drm/i915/i915_gem_userptr.c @@ -507,7 +507,7 @@ __i915_gem_userptr_get_pages_worker(struct work_struct *_work) flags |= FOLL_WRITE; ret = -EFAULT; - if (atomic_inc_not_zero(&mm->mm_users)) { + if (mmget_not_zero(mm)) { down_read(&mm->mmap_sem); while (pinned < npages) { ret = get_user_pages_remote -- cgit From 8dfe162ac74f56b382d6e3d37365672897422f51 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Tue, 28 Feb 2017 04:55:54 -0800 Subject: gpu: drm: drivers: Convert printk(KERN_ to pr_ Use a more common logging style. Miscellanea: o Coalesce formats and realign arguments o Neaten a few macros now using pr_ Signed-off-by: Joe Perches Acked-by: Rob Clark Acked-by: Sinclair Yeh Acked-by: Patrik Jakobsson Acked-by: Tomi Valkeinen Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/76355db47b31668bb64d996865ceee53bd66b11f.1488285953.git.joe@perches.com --- drivers/gpu/drm/i915/i915_sw_fence.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/gpu/drm/i915') diff --git a/drivers/gpu/drm/i915/i915_sw_fence.c b/drivers/gpu/drm/i915/i915_sw_fence.c index 40f4e5efaf83..a277f8eb7beb 100644 --- a/drivers/gpu/drm/i915/i915_sw_fence.c +++ b/drivers/gpu/drm/i915/i915_sw_fence.c @@ -395,10 +395,10 @@ static void timer_i915_sw_fence_wake(unsigned long data) { struct i915_sw_dma_fence_cb *cb = (struct i915_sw_dma_fence_cb *)data; - printk(KERN_WARNING "asynchronous wait on fence %s:%s:%x timed out\n", - cb->dma->ops->get_driver_name(cb->dma), - cb->dma->ops->get_timeline_name(cb->dma), - cb->dma->seqno); + pr_warn("asynchronous wait on fence %s:%s:%x timed out\n", + cb->dma->ops->get_driver_name(cb->dma), + cb->dma->ops->get_timeline_name(cb->dma), + cb->dma->seqno); dma_fence_put(cb->dma); cb->dma = NULL; -- cgit From b05eeb0f47a3f9f2530f1c46b11dacfa0ca71876 Mon Sep 17 00:00:00 2001 From: Noralf Trønnes Date: Thu, 26 Jan 2017 23:56:21 +0100 Subject: drm/i915: Remove i915_debugfs_unregister() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit drm_debugfs_cleanup() now removes all minor->debugfs_list entries automatically, so no need to do this explicitly. Additionally it uses debugfs_remove_recursive() to clean up the debugfs files, so no need for adding fake drm_info_node entries. Cc: daniel.vetter@intel.com Cc: jani.nikula@linux.intel.com Signed-off-by: Noralf Trønnes Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/20170126225621.12314-20-noralf@tronnes.org --- drivers/gpu/drm/i915/i915_debugfs.c | 97 +++++------------------------------ drivers/gpu/drm/i915/i915_drv.c | 1 - drivers/gpu/drm/i915/i915_drv.h | 2 - drivers/gpu/drm/i915/intel_drv.h | 1 - drivers/gpu/drm/i915/intel_pipe_crc.c | 68 ++++-------------------- 5 files changed, 23 insertions(+), 146 deletions(-) (limited to 'drivers/gpu/drm/i915') diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index fa69d72fdcb9..7d7244798507 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -35,32 +35,6 @@ static inline struct drm_i915_private *node_to_i915(struct drm_info_node *node) return to_i915(node->minor->dev); } -/* As the drm_debugfs_init() routines are called before dev->dev_private is - * allocated we need to hook into the minor for release. */ -static int -drm_add_fake_info_node(struct drm_minor *minor, - struct dentry *ent, - const void *key) -{ - struct drm_info_node *node; - - node = kmalloc(sizeof(*node), GFP_KERNEL); - if (node == NULL) { - debugfs_remove(ent); - return -ENOMEM; - } - - node->minor = minor; - node->dent = ent; - node->info_ent = (void *)key; - - mutex_lock(&minor->debugfs_lock); - list_add(&node->list, &minor->debugfs_list); - mutex_unlock(&minor->debugfs_lock); - - return 0; -} - static int i915_capabilities(struct seq_file *m, void *data) { struct drm_i915_private *dev_priv = node_to_i915(m->private); @@ -4593,37 +4567,6 @@ static const struct file_operations i915_forcewake_fops = { .release = i915_forcewake_release, }; -static int i915_forcewake_create(struct dentry *root, struct drm_minor *minor) -{ - struct dentry *ent; - - ent = debugfs_create_file("i915_forcewake_user", - S_IRUSR, - root, to_i915(minor->dev), - &i915_forcewake_fops); - if (!ent) - return -ENOMEM; - - return drm_add_fake_info_node(minor, ent, &i915_forcewake_fops); -} - -static int i915_debugfs_create(struct dentry *root, - struct drm_minor *minor, - const char *name, - const struct file_operations *fops) -{ - struct dentry *ent; - - ent = debugfs_create_file(name, - S_IRUGO | S_IWUSR, - root, to_i915(minor->dev), - fops); - if (!ent) - return -ENOMEM; - - return drm_add_fake_info_node(minor, ent, fops); -} - static const struct drm_info_list i915_debugfs_list[] = { {"i915_capabilities", i915_capabilities, 0}, {"i915_gem_objects", i915_gem_object_info, 0}, @@ -4706,22 +4649,27 @@ static const struct i915_debugfs_files { int i915_debugfs_register(struct drm_i915_private *dev_priv) { struct drm_minor *minor = dev_priv->drm.primary; + struct dentry *ent; int ret, i; - ret = i915_forcewake_create(minor->debugfs_root, minor); - if (ret) - return ret; + ent = debugfs_create_file("i915_forcewake_user", S_IRUSR, + minor->debugfs_root, to_i915(minor->dev), + &i915_forcewake_fops); + if (!ent) + return -ENOMEM; ret = intel_pipe_crc_create(minor); if (ret) return ret; for (i = 0; i < ARRAY_SIZE(i915_debugfs_files); i++) { - ret = i915_debugfs_create(minor->debugfs_root, minor, - i915_debugfs_files[i].name, + ent = debugfs_create_file(i915_debugfs_files[i].name, + S_IRUGO | S_IWUSR, + minor->debugfs_root, + to_i915(minor->dev), i915_debugfs_files[i].fops); - if (ret) - return ret; + if (!ent) + return -ENOMEM; } return drm_debugfs_create_files(i915_debugfs_list, @@ -4729,27 +4677,6 @@ int i915_debugfs_register(struct drm_i915_private *dev_priv) minor->debugfs_root, minor); } -void i915_debugfs_unregister(struct drm_i915_private *dev_priv) -{ - struct drm_minor *minor = dev_priv->drm.primary; - int i; - - drm_debugfs_remove_files(i915_debugfs_list, - I915_DEBUGFS_ENTRIES, minor); - - drm_debugfs_remove_files((struct drm_info_list *)&i915_forcewake_fops, - 1, minor); - - intel_pipe_crc_cleanup(minor); - - for (i = 0; i < ARRAY_SIZE(i915_debugfs_files); i++) { - struct drm_info_list *info_list = - (struct drm_info_list *)i915_debugfs_files[i].fops; - - drm_debugfs_remove_files(info_list, 1, minor); - } -} - struct dpcd_block { /* DPCD dump start address. */ unsigned int offset; diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index f6017f2cfb86..8cdafef8eac9 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -1167,7 +1167,6 @@ static void i915_driver_unregister(struct drm_i915_private *dev_priv) i915_teardown_sysfs(dev_priv); i915_guc_log_unregister(dev_priv); - i915_debugfs_unregister(dev_priv); drm_dev_unregister(&dev_priv->drm); i915_gem_shrinker_cleanup(dev_priv); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index e44c598ecb82..75b0497649b9 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -3522,12 +3522,10 @@ u32 i915_gem_fence_alignment(struct drm_i915_private *dev_priv, u32 size, /* i915_debugfs.c */ #ifdef CONFIG_DEBUG_FS int i915_debugfs_register(struct drm_i915_private *dev_priv); -void i915_debugfs_unregister(struct drm_i915_private *dev_priv); int i915_debugfs_connector_add(struct drm_connector *connector); void intel_display_crc_init(struct drm_i915_private *dev_priv); #else static inline int i915_debugfs_register(struct drm_i915_private *dev_priv) {return 0;} -static inline void i915_debugfs_unregister(struct drm_i915_private *dev_priv) {} static inline int i915_debugfs_connector_add(struct drm_connector *connector) { return 0; } static inline void intel_display_crc_init(struct drm_i915_private *dev_priv) {} diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 40fed65a791d..3b797909f631 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1888,7 +1888,6 @@ void lspcon_wait_pcon_mode(struct intel_lspcon *lspcon); /* intel_pipe_crc.c */ int intel_pipe_crc_create(struct drm_minor *minor); -void intel_pipe_crc_cleanup(struct drm_minor *minor); #ifdef CONFIG_DEBUG_FS int intel_crtc_set_crc_source(struct drm_crtc *crtc, const char *source_name, size_t *values_cnt); diff --git a/drivers/gpu/drm/i915/intel_pipe_crc.c b/drivers/gpu/drm/i915/intel_pipe_crc.c index c0b1f99da37b..5aa524e32df7 100644 --- a/drivers/gpu/drm/i915/intel_pipe_crc.c +++ b/drivers/gpu/drm/i915/intel_pipe_crc.c @@ -36,31 +36,6 @@ struct pipe_crc_info { enum pipe pipe; }; -/* As the drm_debugfs_init() routines are called before dev->dev_private is - * allocated we need to hook into the minor for release. - */ -static int drm_add_fake_info_node(struct drm_minor *minor, - struct dentry *ent, const void *key) -{ - struct drm_info_node *node; - - node = kmalloc(sizeof(*node), GFP_KERNEL); - if (node == NULL) { - debugfs_remove(ent); - return -ENOMEM; - } - - node->minor = minor; - node->dent = ent; - node->info_ent = (void *) key; - - mutex_lock(&minor->debugfs_lock); - list_add(&node->list, &minor->debugfs_list); - mutex_unlock(&minor->debugfs_lock); - - return 0; -} - static int i915_pipe_crc_open(struct inode *inode, struct file *filep) { struct pipe_crc_info *info = inode->i_private; @@ -209,22 +184,6 @@ static struct pipe_crc_info i915_pipe_crc_data[I915_MAX_PIPES] = { }, }; -static int i915_pipe_crc_create(struct dentry *root, struct drm_minor *minor, - enum pipe pipe) -{ - struct drm_i915_private *dev_priv = to_i915(minor->dev); - struct dentry *ent; - struct pipe_crc_info *info = &i915_pipe_crc_data[pipe]; - - info->dev_priv = dev_priv; - ent = debugfs_create_file(info->name, S_IRUGO, root, info, - &i915_pipe_crc_fops); - if (!ent) - return -ENOMEM; - - return drm_add_fake_info_node(minor, ent, info); -} - static const char * const pipe_crc_sources[] = { "none", "plane1", @@ -928,27 +887,22 @@ void intel_display_crc_init(struct drm_i915_private *dev_priv) int intel_pipe_crc_create(struct drm_minor *minor) { - int ret, i; - - for (i = 0; i < ARRAY_SIZE(i915_pipe_crc_data); i++) { - ret = i915_pipe_crc_create(minor->debugfs_root, minor, i); - if (ret) - return ret; - } - - return 0; -} - -void intel_pipe_crc_cleanup(struct drm_minor *minor) -{ + struct drm_i915_private *dev_priv = to_i915(minor->dev); + struct dentry *ent; int i; for (i = 0; i < ARRAY_SIZE(i915_pipe_crc_data); i++) { - struct drm_info_list *info_list = - (struct drm_info_list *)&i915_pipe_crc_data[i]; + struct pipe_crc_info *info = &i915_pipe_crc_data[i]; - drm_debugfs_remove_files(info_list, 1, minor); + info->dev_priv = dev_priv; + ent = debugfs_create_file(info->name, S_IRUGO, + minor->debugfs_root, info, + &i915_pipe_crc_fops); + if (!ent) + return -ENOMEM; } + + return 0; } int intel_crtc_set_crc_source(struct drm_crtc *crtc, const char *source_name, -- cgit From 233ce881dd91fb13eb6b09deefae33168e6ead4c Mon Sep 17 00:00:00 2001 From: Manasi Navare Date: Fri, 16 Dec 2016 12:29:07 +0200 Subject: drm/i915: Implement Link Rate fallback on Link training failure If link training at a link rate optimal for a particular mode fails during modeset's atomic commit phase, then we let the modeset complete and then retry. We save the link rate value at which link training failed, update the link status property to "BAD" and use a lower link rate to prune the modes. It will redo the modeset on the current mode at lower link rate or if the current mode gets pruned due to lower link constraints then, it will send a hotplug uevent for userspace to handle it. This is also required to pass DP CTS tests 4.3.1.3, 4.3.1.4, 4.3.1.6. v9: * Use the trimmed max values of link rate/lane count based on link train fallback (Daniel Vetter) v8: * Set link_status to BAD first and then call mode_valid (Jani Nikula) v7: Remove the redundant variable in previous patch itself v6: * Obtain link rate index from fallback_link_rate using the helper intel_dp_link_rate_index (Jani Nikula) * Include fallback within intel_dp_start_link_train (Jani Nikula) v5: * Move set link status to drm core (Daniel Vetter, Jani Nikula) v4: * Add fallback support for non DDI platforms too * Set connector->link status inside set_link_status function (Jani Nikula) v3: * Set link status property to BAd unconditionally (Jani Nikula) * Dont use two separate variables link_train_failed and link_status to indicate same thing (Jani Nikula) v2: * Squashed a few patches (Jani Nikula) Acked-by: Tony Cheng Acked-by: Harry Wentland Cc: Jani Nikula Cc: Daniel Vetter Cc: Ville Syrjala Signed-off-by: Manasi Navare Reviewed-by: Jani Nikula Signed-off-by: Jani Nikula Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/d796cc0c2814d668a47ef43c464f9a4089d46d64.1481883920.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/intel_dp.c | 27 +++++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_dp_link_training.c | 22 ++++++++++++++++++++-- drivers/gpu/drm/i915/intel_drv.h | 3 +++ 3 files changed, 50 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm/i915') diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index d1670b8afbf5..af07a830fa95 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -5790,6 +5790,29 @@ out_vdd_off: return false; } +static void intel_dp_modeset_retry_work_fn(struct work_struct *work) +{ + struct intel_connector *intel_connector; + struct drm_connector *connector; + + intel_connector = container_of(work, typeof(*intel_connector), + modeset_retry_work); + connector = &intel_connector->base; + DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", connector->base.id, + connector->name); + + /* Grab the locks before changing connector property*/ + mutex_lock(&connector->dev->mode_config.mutex); + /* Set connector link status to BAD and send a Uevent to notify + * userspace to do a modeset. + */ + drm_mode_connector_set_link_status_property(connector, + DRM_MODE_LINK_STATUS_BAD); + mutex_unlock(&connector->dev->mode_config.mutex); + /* Send Hotplug uevent so userspace can reprobe */ + drm_kms_helper_hotplug_event(connector->dev); +} + bool intel_dp_init_connector(struct intel_digital_port *intel_dig_port, struct intel_connector *intel_connector) @@ -5802,6 +5825,10 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port, enum port port = intel_dig_port->port; int type; + /* Initialize the work for modeset in case of link train failure */ + INIT_WORK(&intel_connector->modeset_retry_work, + intel_dp_modeset_retry_work_fn); + if (WARN(intel_dig_port->max_lanes < 1, "Not enough lanes (%d) for DP on port %c\n", intel_dig_port->max_lanes, port_name(port))) diff --git a/drivers/gpu/drm/i915/intel_dp_link_training.c b/drivers/gpu/drm/i915/intel_dp_link_training.c index 0048b520baf7..955b239e7c2d 100644 --- a/drivers/gpu/drm/i915/intel_dp_link_training.c +++ b/drivers/gpu/drm/i915/intel_dp_link_training.c @@ -313,6 +313,24 @@ void intel_dp_stop_link_train(struct intel_dp *intel_dp) void intel_dp_start_link_train(struct intel_dp *intel_dp) { - intel_dp_link_training_clock_recovery(intel_dp); - intel_dp_link_training_channel_equalization(intel_dp); + struct intel_connector *intel_connector = intel_dp->attached_connector; + + if (!intel_dp_link_training_clock_recovery(intel_dp)) + goto failure_handling; + if (!intel_dp_link_training_channel_equalization(intel_dp)) + goto failure_handling; + + DRM_DEBUG_KMS("Link Training Passed at Link Rate = %d, Lane count = %d", + intel_dp->link_rate, intel_dp->lane_count); + return; + + failure_handling: + DRM_DEBUG_KMS("Link Training failed at link rate = %d, lane count = %d", + intel_dp->link_rate, intel_dp->lane_count); + if (!intel_dp_get_link_train_fallback_values(intel_dp, + intel_dp->link_rate, + intel_dp->lane_count)) + /* Schedule a Hotplug Uevent to userspace to start modeset */ + schedule_work(&intel_connector->modeset_retry_work); + return; } diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 3b797909f631..6c6abc932726 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -316,6 +316,9 @@ struct intel_connector { void *port; /* store this opaque as its illegal to dereference it */ struct intel_dp *mst_port; + + /* Work struct to schedule a uevent on link train failure */ + struct work_struct modeset_retry_work; }; struct dpll { -- cgit From e601757102cfd3eeae068f53b3bc1234f3a2b2e9 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Wed, 1 Feb 2017 16:36:40 +0100 Subject: sched/headers: Prepare for new header dependencies before moving code to We are going to split out of , which will have to be picked up from other headers and .c files. Create a trivial placeholder file that just maps to to make this patch obviously correct and bisectable. Include the new header in the files that are going to need it. Acked-by: Linus Torvalds Cc: Mike Galbraith Cc: Peter Zijlstra Cc: Thomas Gleixner Cc: linux-kernel@vger.kernel.org Signed-off-by: Ingo Molnar --- drivers/gpu/drm/i915/i915_gem_request.c | 2 ++ drivers/gpu/drm/i915/intel_drv.h | 1 + 2 files changed, 3 insertions(+) (limited to 'drivers/gpu/drm/i915') diff --git a/drivers/gpu/drm/i915/i915_gem_request.c b/drivers/gpu/drm/i915/i915_gem_request.c index f31deeb72703..df3fef393dbe 100644 --- a/drivers/gpu/drm/i915/i915_gem_request.c +++ b/drivers/gpu/drm/i915/i915_gem_request.c @@ -24,6 +24,8 @@ #include #include +#include +#include #include "i915_drv.h" diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index b9cde116dab3..344f238b283f 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -28,6 +28,7 @@ #include #include #include +#include #include #include "i915_drv.h" #include -- cgit From ae7e81c077d60507dcec139e40a6d10cf932cf4b Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Wed, 1 Feb 2017 18:07:51 +0100 Subject: sched/headers: Prepare for new header dependencies before moving code to We are going to move scheduler ABI details to , which will be used from a number of .c files. Create empty placeholder header that maps to . Include the new header in the files that are going to need it. Acked-by: Linus Torvalds Cc: Mike Galbraith Cc: Peter Zijlstra Cc: Thomas Gleixner Cc: linux-kernel@vger.kernel.org Signed-off-by: Ingo Molnar --- drivers/gpu/drm/i915/intel_breadcrumbs.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/gpu/drm/i915') diff --git a/drivers/gpu/drm/i915/intel_breadcrumbs.c b/drivers/gpu/drm/i915/intel_breadcrumbs.c index fcfa423d08bd..7044e9a6abf7 100644 --- a/drivers/gpu/drm/i915/intel_breadcrumbs.c +++ b/drivers/gpu/drm/i915/intel_breadcrumbs.c @@ -23,6 +23,7 @@ */ #include +#include #include "i915_drv.h" -- cgit From 6e84f31522f931027bf695752087ece278c10d3f Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Wed, 8 Feb 2017 18:51:29 +0100 Subject: sched/headers: Prepare for new header dependencies before moving code to We are going to split out of , which will have to be picked up from other headers and a couple of .c files. Create a trivial placeholder file that just maps to to make this patch obviously correct and bisectable. The APIs that are going to be moved first are: mm_alloc() __mmdrop() mmdrop() mmdrop_async_fn() mmdrop_async() mmget_not_zero() mmput() mmput_async() get_task_mm() mm_access() mm_release() Include the new header in the files that are going to need it. Acked-by: Linus Torvalds Cc: Mike Galbraith Cc: Peter Zijlstra Cc: Thomas Gleixner Cc: linux-kernel@vger.kernel.org Signed-off-by: Ingo Molnar --- drivers/gpu/drm/i915/i915_gem_userptr.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/gpu/drm/i915') diff --git a/drivers/gpu/drm/i915/i915_gem_userptr.c b/drivers/gpu/drm/i915/i915_gem_userptr.c index 0115989e324a..22b46398831e 100644 --- a/drivers/gpu/drm/i915/i915_gem_userptr.c +++ b/drivers/gpu/drm/i915/i915_gem_userptr.c @@ -31,6 +31,7 @@ #include #include #include +#include struct i915_mm_struct { struct mm_struct *mm; -- cgit From f361bf4a66c9bfabace46f6ff5d97005c9b524fe Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Fri, 3 Feb 2017 23:47:37 +0100 Subject: sched/headers: Prepare for the reduction of 's signal API dependency Instead of including the full , we are going to include the types-only header in , to further decouple the scheduler header from the signal headers. This means that various files which relied on the full need to be updated to gain an explicit dependency on it. Update the code that relies on sched.h's inclusion of the header. Acked-by: Linus Torvalds Cc: Mike Galbraith Cc: Peter Zijlstra Cc: Thomas Gleixner Cc: linux-kernel@vger.kernel.org Signed-off-by: Ingo Molnar --- drivers/gpu/drm/i915/i915_gem_request.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/gpu/drm/i915') diff --git a/drivers/gpu/drm/i915/i915_gem_request.c b/drivers/gpu/drm/i915/i915_gem_request.c index df3fef393dbe..e7c3c0318ff6 100644 --- a/drivers/gpu/drm/i915/i915_gem_request.c +++ b/drivers/gpu/drm/i915/i915_gem_request.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "i915_drv.h" -- cgit From afc1ebf4562a14b8a981a0de2a3aa063dbd4c5b2 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 1 Mar 2017 18:17:49 +0100 Subject: Revert "drm/i915: Implement Link Rate fallback on Link training failure" This reverts commit 233ce881dd91fb13eb6b09deefae33168e6ead4c. I assumed it's ok, but really should have double-checked - CI caught tons of fail :( Cc: Jani Nikula Cc: Manasi Navare Acked-by: Manasi Navare Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/20170301171749.13053-1-daniel.vetter@ffwll.ch --- drivers/gpu/drm/i915/intel_dp.c | 27 --------------------------- drivers/gpu/drm/i915/intel_dp_link_training.c | 22 ++-------------------- drivers/gpu/drm/i915/intel_drv.h | 3 --- 3 files changed, 2 insertions(+), 50 deletions(-) (limited to 'drivers/gpu/drm/i915') diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index af07a830fa95..d1670b8afbf5 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -5790,29 +5790,6 @@ out_vdd_off: return false; } -static void intel_dp_modeset_retry_work_fn(struct work_struct *work) -{ - struct intel_connector *intel_connector; - struct drm_connector *connector; - - intel_connector = container_of(work, typeof(*intel_connector), - modeset_retry_work); - connector = &intel_connector->base; - DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", connector->base.id, - connector->name); - - /* Grab the locks before changing connector property*/ - mutex_lock(&connector->dev->mode_config.mutex); - /* Set connector link status to BAD and send a Uevent to notify - * userspace to do a modeset. - */ - drm_mode_connector_set_link_status_property(connector, - DRM_MODE_LINK_STATUS_BAD); - mutex_unlock(&connector->dev->mode_config.mutex); - /* Send Hotplug uevent so userspace can reprobe */ - drm_kms_helper_hotplug_event(connector->dev); -} - bool intel_dp_init_connector(struct intel_digital_port *intel_dig_port, struct intel_connector *intel_connector) @@ -5825,10 +5802,6 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port, enum port port = intel_dig_port->port; int type; - /* Initialize the work for modeset in case of link train failure */ - INIT_WORK(&intel_connector->modeset_retry_work, - intel_dp_modeset_retry_work_fn); - if (WARN(intel_dig_port->max_lanes < 1, "Not enough lanes (%d) for DP on port %c\n", intel_dig_port->max_lanes, port_name(port))) diff --git a/drivers/gpu/drm/i915/intel_dp_link_training.c b/drivers/gpu/drm/i915/intel_dp_link_training.c index 955b239e7c2d..0048b520baf7 100644 --- a/drivers/gpu/drm/i915/intel_dp_link_training.c +++ b/drivers/gpu/drm/i915/intel_dp_link_training.c @@ -313,24 +313,6 @@ void intel_dp_stop_link_train(struct intel_dp *intel_dp) void intel_dp_start_link_train(struct intel_dp *intel_dp) { - struct intel_connector *intel_connector = intel_dp->attached_connector; - - if (!intel_dp_link_training_clock_recovery(intel_dp)) - goto failure_handling; - if (!intel_dp_link_training_channel_equalization(intel_dp)) - goto failure_handling; - - DRM_DEBUG_KMS("Link Training Passed at Link Rate = %d, Lane count = %d", - intel_dp->link_rate, intel_dp->lane_count); - return; - - failure_handling: - DRM_DEBUG_KMS("Link Training failed at link rate = %d, lane count = %d", - intel_dp->link_rate, intel_dp->lane_count); - if (!intel_dp_get_link_train_fallback_values(intel_dp, - intel_dp->link_rate, - intel_dp->lane_count)) - /* Schedule a Hotplug Uevent to userspace to start modeset */ - schedule_work(&intel_connector->modeset_retry_work); - return; + intel_dp_link_training_clock_recovery(intel_dp); + intel_dp_link_training_channel_equalization(intel_dp); } diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 6c6abc932726..3b797909f631 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -316,9 +316,6 @@ struct intel_connector { void *port; /* store this opaque as its illegal to dereference it */ struct intel_dp *mst_port; - - /* Work struct to schedule a uevent on link train failure */ - struct work_struct modeset_retry_work; }; struct dpll { -- cgit