提交 2819cf0e 编写于 作者: D Dave Airlie

Merge tag 'drm-misc-next-2021-08-12' of git://anongit.freedesktop.org/drm/drm-misc into drm-next

drm-misc-next for v5.15:

UAPI Changes:

Cross-subsystem Changes:
- Add lockdep_assert(once) helpers.

Core Changes:
- Add lockdep assert to drm_is_current_master_locked.
- Fix typos in dma-buf documentation.
- Mark drm irq midlayer as legacy only.
- Fix GPF in udmabuf_create.
- Rename member to correct value in drm_edid.h

Driver Changes:
- Build fix to make nouveau build with NOUVEAU_BACKLIGHT.
- Add MI101AIT-ICP1, LTTD800480070-L6WWH-RT panels.
- Assorted fixes to bridge/it66121, anx7625.
- Add custom crtc_state to simple helpers, and use it to
  convert pll handling in mgag200 to atomic.
- Convert drivers to use offset-adjusted framebuffer bo mappings.
- Assorted small fixes and fix for a use-after-free in vmwgfx.
- Convert remaining callers of non-legacy drivers to use linux irqs directly.
- Small cleanup in ingenic.
- Small fixes to virtio and ti-sn65dsi86.
Signed-off-by: NDave Airlie <airlied@redhat.com>

From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/1cf2d7fc-402d-1852-574a-21cbbd2eaebf@linux.intel.com
...@@ -227,8 +227,8 @@ static long udmabuf_create(struct miscdevice *device, ...@@ -227,8 +227,8 @@ static long udmabuf_create(struct miscdevice *device,
if (!hpage) { if (!hpage) {
hpage = find_get_page_flags(mapping, pgoff, hpage = find_get_page_flags(mapping, pgoff,
FGP_ACCESSED); FGP_ACCESSED);
if (IS_ERR(hpage)) { if (!hpage) {
ret = PTR_ERR(hpage); ret = -EINVAL;
goto err; goto err;
} }
} }
......
...@@ -1786,7 +1786,6 @@ static const struct drm_driver amdgpu_kms_driver = { ...@@ -1786,7 +1786,6 @@ static const struct drm_driver amdgpu_kms_driver = {
.open = amdgpu_driver_open_kms, .open = amdgpu_driver_open_kms,
.postclose = amdgpu_driver_postclose_kms, .postclose = amdgpu_driver_postclose_kms,
.lastclose = amdgpu_driver_lastclose_kms, .lastclose = amdgpu_driver_lastclose_kms,
.irq_handler = amdgpu_irq_handler,
.ioctls = amdgpu_ioctls_kms, .ioctls = amdgpu_ioctls_kms,
.num_ioctls = ARRAY_SIZE(amdgpu_ioctls_kms), .num_ioctls = ARRAY_SIZE(amdgpu_ioctls_kms),
.dumb_create = amdgpu_mode_dumb_create, .dumb_create = amdgpu_mode_dumb_create,
......
...@@ -46,7 +46,6 @@ ...@@ -46,7 +46,6 @@
#include <linux/pci.h> #include <linux/pci.h>
#include <drm/drm_crtc_helper.h> #include <drm/drm_crtc_helper.h>
#include <drm/drm_irq.h>
#include <drm/drm_vblank.h> #include <drm/drm_vblank.h>
#include <drm/amdgpu_drm.h> #include <drm/amdgpu_drm.h>
#include <drm/drm_drv.h> #include <drm/drm_drv.h>
...@@ -184,7 +183,7 @@ void amdgpu_irq_disable_all(struct amdgpu_device *adev) ...@@ -184,7 +183,7 @@ void amdgpu_irq_disable_all(struct amdgpu_device *adev)
* Returns: * Returns:
* result of handling the IRQ, as defined by &irqreturn_t * result of handling the IRQ, as defined by &irqreturn_t
*/ */
irqreturn_t amdgpu_irq_handler(int irq, void *arg) static irqreturn_t amdgpu_irq_handler(int irq, void *arg)
{ {
struct drm_device *dev = (struct drm_device *) arg; struct drm_device *dev = (struct drm_device *) arg;
struct amdgpu_device *adev = drm_to_adev(dev); struct amdgpu_device *adev = drm_to_adev(dev);
...@@ -307,6 +306,7 @@ static void amdgpu_restore_msix(struct amdgpu_device *adev) ...@@ -307,6 +306,7 @@ static void amdgpu_restore_msix(struct amdgpu_device *adev)
int amdgpu_irq_init(struct amdgpu_device *adev) int amdgpu_irq_init(struct amdgpu_device *adev)
{ {
int r = 0; int r = 0;
unsigned int irq;
spin_lock_init(&adev->irq.lock); spin_lock_init(&adev->irq.lock);
...@@ -349,15 +349,22 @@ int amdgpu_irq_init(struct amdgpu_device *adev) ...@@ -349,15 +349,22 @@ int amdgpu_irq_init(struct amdgpu_device *adev)
INIT_WORK(&adev->irq.ih2_work, amdgpu_irq_handle_ih2); INIT_WORK(&adev->irq.ih2_work, amdgpu_irq_handle_ih2);
INIT_WORK(&adev->irq.ih_soft_work, amdgpu_irq_handle_ih_soft); INIT_WORK(&adev->irq.ih_soft_work, amdgpu_irq_handle_ih_soft);
adev->irq.installed = true; /* Use vector 0 for MSI-X. */
/* Use vector 0 for MSI-X */ r = pci_irq_vector(adev->pdev, 0);
r = drm_irq_install(adev_to_drm(adev), pci_irq_vector(adev->pdev, 0)); if (r < 0)
return r;
irq = r;
/* PCI devices require shared interrupts. */
r = request_irq(irq, amdgpu_irq_handler, IRQF_SHARED, adev_to_drm(adev)->driver->name,
adev_to_drm(adev));
if (r) { if (r) {
adev->irq.installed = false;
if (!amdgpu_device_has_dc_support(adev)) if (!amdgpu_device_has_dc_support(adev))
flush_work(&adev->hotplug_work); flush_work(&adev->hotplug_work);
return r; return r;
} }
adev->irq.installed = true;
adev->irq.irq = irq;
adev_to_drm(adev)->max_vblank_count = 0x00ffffff; adev_to_drm(adev)->max_vblank_count = 0x00ffffff;
DRM_DEBUG("amdgpu: irq initialized.\n"); DRM_DEBUG("amdgpu: irq initialized.\n");
...@@ -368,7 +375,7 @@ int amdgpu_irq_init(struct amdgpu_device *adev) ...@@ -368,7 +375,7 @@ int amdgpu_irq_init(struct amdgpu_device *adev)
void amdgpu_irq_fini_hw(struct amdgpu_device *adev) void amdgpu_irq_fini_hw(struct amdgpu_device *adev)
{ {
if (adev->irq.installed) { if (adev->irq.installed) {
drm_irq_uninstall(&adev->ddev); free_irq(adev->irq.irq, adev_to_drm(adev));
adev->irq.installed = false; adev->irq.installed = false;
if (adev->irq.msi_enabled) if (adev->irq.msi_enabled)
pci_free_irq_vectors(adev->pdev); pci_free_irq_vectors(adev->pdev);
......
...@@ -80,6 +80,7 @@ struct amdgpu_irq_src_funcs { ...@@ -80,6 +80,7 @@ struct amdgpu_irq_src_funcs {
struct amdgpu_irq { struct amdgpu_irq {
bool installed; bool installed;
unsigned int irq;
spinlock_t lock; spinlock_t lock;
/* interrupt sources */ /* interrupt sources */
struct amdgpu_irq_client client[AMDGPU_IRQ_CLIENTID_MAX]; struct amdgpu_irq_client client[AMDGPU_IRQ_CLIENTID_MAX];
...@@ -100,7 +101,6 @@ struct amdgpu_irq { ...@@ -100,7 +101,6 @@ struct amdgpu_irq {
}; };
void amdgpu_irq_disable_all(struct amdgpu_device *adev); void amdgpu_irq_disable_all(struct amdgpu_device *adev);
irqreturn_t amdgpu_irq_handler(int irq, void *arg);
int amdgpu_irq_init(struct amdgpu_device *adev); int amdgpu_irq_init(struct amdgpu_device *adev);
void amdgpu_irq_fini_sw(struct amdgpu_device *adev); void amdgpu_irq_fini_sw(struct amdgpu_device *adev);
......
...@@ -29,7 +29,6 @@ ...@@ -29,7 +29,6 @@
#include <drm/drm_fb_helper.h> #include <drm/drm_fb_helper.h>
#include <drm/drm_gem_cma_helper.h> #include <drm/drm_gem_cma_helper.h>
#include <drm/drm_gem_framebuffer_helper.h> #include <drm/drm_gem_framebuffer_helper.h>
#include <drm/drm_irq.h>
#include <drm/drm_modeset_helper.h> #include <drm/drm_modeset_helper.h>
#include <drm/drm_of.h> #include <drm/drm_of.h>
#include <drm/drm_probe_helper.h> #include <drm/drm_probe_helper.h>
...@@ -38,6 +37,94 @@ ...@@ -38,6 +37,94 @@
#include "hdlcd_drv.h" #include "hdlcd_drv.h"
#include "hdlcd_regs.h" #include "hdlcd_regs.h"
static irqreturn_t hdlcd_irq(int irq, void *arg)
{
struct drm_device *drm = arg;
struct hdlcd_drm_private *hdlcd = drm->dev_private;
unsigned long irq_status;
irq_status = hdlcd_read(hdlcd, HDLCD_REG_INT_STATUS);
#ifdef CONFIG_DEBUG_FS
if (irq_status & HDLCD_INTERRUPT_UNDERRUN)
atomic_inc(&hdlcd->buffer_underrun_count);
if (irq_status & HDLCD_INTERRUPT_DMA_END)
atomic_inc(&hdlcd->dma_end_count);
if (irq_status & HDLCD_INTERRUPT_BUS_ERROR)
atomic_inc(&hdlcd->bus_error_count);
if (irq_status & HDLCD_INTERRUPT_VSYNC)
atomic_inc(&hdlcd->vsync_count);
#endif
if (irq_status & HDLCD_INTERRUPT_VSYNC)
drm_crtc_handle_vblank(&hdlcd->crtc);
/* acknowledge interrupt(s) */
hdlcd_write(hdlcd, HDLCD_REG_INT_CLEAR, irq_status);
return IRQ_HANDLED;
}
static void hdlcd_irq_preinstall(struct drm_device *drm)
{
struct hdlcd_drm_private *hdlcd = drm->dev_private;
/* Ensure interrupts are disabled */
hdlcd_write(hdlcd, HDLCD_REG_INT_MASK, 0);
hdlcd_write(hdlcd, HDLCD_REG_INT_CLEAR, ~0);
}
static void hdlcd_irq_postinstall(struct drm_device *drm)
{
#ifdef CONFIG_DEBUG_FS
struct hdlcd_drm_private *hdlcd = drm->dev_private;
unsigned long irq_mask = hdlcd_read(hdlcd, HDLCD_REG_INT_MASK);
/* enable debug interrupts */
irq_mask |= HDLCD_DEBUG_INT_MASK;
hdlcd_write(hdlcd, HDLCD_REG_INT_MASK, irq_mask);
#endif
}
static int hdlcd_irq_install(struct drm_device *drm, int irq)
{
int ret;
if (irq == IRQ_NOTCONNECTED)
return -ENOTCONN;
hdlcd_irq_preinstall(drm);
ret = request_irq(irq, hdlcd_irq, 0, drm->driver->name, drm);
if (ret)
return ret;
hdlcd_irq_postinstall(drm);
return 0;
}
static void hdlcd_irq_uninstall(struct drm_device *drm)
{
struct hdlcd_drm_private *hdlcd = drm->dev_private;
/* disable all the interrupts that we might have enabled */
unsigned long irq_mask = hdlcd_read(hdlcd, HDLCD_REG_INT_MASK);
#ifdef CONFIG_DEBUG_FS
/* disable debug interrupts */
irq_mask &= ~HDLCD_DEBUG_INT_MASK;
#endif
/* disable vsync interrupts */
irq_mask &= ~HDLCD_INTERRUPT_VSYNC;
hdlcd_write(hdlcd, HDLCD_REG_INT_MASK, irq_mask);
free_irq(hdlcd->irq, drm);
}
static int hdlcd_load(struct drm_device *drm, unsigned long flags) static int hdlcd_load(struct drm_device *drm, unsigned long flags)
{ {
struct hdlcd_drm_private *hdlcd = drm->dev_private; struct hdlcd_drm_private *hdlcd = drm->dev_private;
...@@ -90,7 +177,12 @@ static int hdlcd_load(struct drm_device *drm, unsigned long flags) ...@@ -90,7 +177,12 @@ static int hdlcd_load(struct drm_device *drm, unsigned long flags)
goto setup_fail; goto setup_fail;
} }
ret = drm_irq_install(drm, platform_get_irq(pdev, 0)); ret = platform_get_irq(pdev, 0);
if (ret < 0)
goto irq_fail;
hdlcd->irq = ret;
ret = hdlcd_irq_install(drm, hdlcd->irq);
if (ret < 0) { if (ret < 0) {
DRM_ERROR("failed to install IRQ handler\n"); DRM_ERROR("failed to install IRQ handler\n");
goto irq_fail; goto irq_fail;
...@@ -122,76 +214,6 @@ static void hdlcd_setup_mode_config(struct drm_device *drm) ...@@ -122,76 +214,6 @@ static void hdlcd_setup_mode_config(struct drm_device *drm)
drm->mode_config.funcs = &hdlcd_mode_config_funcs; drm->mode_config.funcs = &hdlcd_mode_config_funcs;
} }
static irqreturn_t hdlcd_irq(int irq, void *arg)
{
struct drm_device *drm = arg;
struct hdlcd_drm_private *hdlcd = drm->dev_private;
unsigned long irq_status;
irq_status = hdlcd_read(hdlcd, HDLCD_REG_INT_STATUS);
#ifdef CONFIG_DEBUG_FS
if (irq_status & HDLCD_INTERRUPT_UNDERRUN)
atomic_inc(&hdlcd->buffer_underrun_count);
if (irq_status & HDLCD_INTERRUPT_DMA_END)
atomic_inc(&hdlcd->dma_end_count);
if (irq_status & HDLCD_INTERRUPT_BUS_ERROR)
atomic_inc(&hdlcd->bus_error_count);
if (irq_status & HDLCD_INTERRUPT_VSYNC)
atomic_inc(&hdlcd->vsync_count);
#endif
if (irq_status & HDLCD_INTERRUPT_VSYNC)
drm_crtc_handle_vblank(&hdlcd->crtc);
/* acknowledge interrupt(s) */
hdlcd_write(hdlcd, HDLCD_REG_INT_CLEAR, irq_status);
return IRQ_HANDLED;
}
static void hdlcd_irq_preinstall(struct drm_device *drm)
{
struct hdlcd_drm_private *hdlcd = drm->dev_private;
/* Ensure interrupts are disabled */
hdlcd_write(hdlcd, HDLCD_REG_INT_MASK, 0);
hdlcd_write(hdlcd, HDLCD_REG_INT_CLEAR, ~0);
}
static int hdlcd_irq_postinstall(struct drm_device *drm)
{
#ifdef CONFIG_DEBUG_FS
struct hdlcd_drm_private *hdlcd = drm->dev_private;
unsigned long irq_mask = hdlcd_read(hdlcd, HDLCD_REG_INT_MASK);
/* enable debug interrupts */
irq_mask |= HDLCD_DEBUG_INT_MASK;
hdlcd_write(hdlcd, HDLCD_REG_INT_MASK, irq_mask);
#endif
return 0;
}
static void hdlcd_irq_uninstall(struct drm_device *drm)
{
struct hdlcd_drm_private *hdlcd = drm->dev_private;
/* disable all the interrupts that we might have enabled */
unsigned long irq_mask = hdlcd_read(hdlcd, HDLCD_REG_INT_MASK);
#ifdef CONFIG_DEBUG_FS
/* disable debug interrupts */
irq_mask &= ~HDLCD_DEBUG_INT_MASK;
#endif
/* disable vsync interrupts */
irq_mask &= ~HDLCD_INTERRUPT_VSYNC;
hdlcd_write(hdlcd, HDLCD_REG_INT_MASK, irq_mask);
}
#ifdef CONFIG_DEBUG_FS #ifdef CONFIG_DEBUG_FS
static int hdlcd_show_underrun_count(struct seq_file *m, void *arg) static int hdlcd_show_underrun_count(struct seq_file *m, void *arg)
{ {
...@@ -236,10 +258,6 @@ DEFINE_DRM_GEM_CMA_FOPS(fops); ...@@ -236,10 +258,6 @@ DEFINE_DRM_GEM_CMA_FOPS(fops);
static const struct drm_driver hdlcd_driver = { static const struct drm_driver hdlcd_driver = {
.driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC, .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
.irq_handler = hdlcd_irq,
.irq_preinstall = hdlcd_irq_preinstall,
.irq_postinstall = hdlcd_irq_postinstall,
.irq_uninstall = hdlcd_irq_uninstall,
DRM_GEM_CMA_DRIVER_OPS, DRM_GEM_CMA_DRIVER_OPS,
#ifdef CONFIG_DEBUG_FS #ifdef CONFIG_DEBUG_FS
.debugfs_init = hdlcd_debugfs_init, .debugfs_init = hdlcd_debugfs_init,
...@@ -316,7 +334,7 @@ static int hdlcd_drm_bind(struct device *dev) ...@@ -316,7 +334,7 @@ static int hdlcd_drm_bind(struct device *dev)
err_unload: err_unload:
of_node_put(hdlcd->crtc.port); of_node_put(hdlcd->crtc.port);
hdlcd->crtc.port = NULL; hdlcd->crtc.port = NULL;
drm_irq_uninstall(drm); hdlcd_irq_uninstall(drm);
of_reserved_mem_device_release(drm->dev); of_reserved_mem_device_release(drm->dev);
err_free: err_free:
drm_mode_config_cleanup(drm); drm_mode_config_cleanup(drm);
...@@ -338,7 +356,7 @@ static void hdlcd_drm_unbind(struct device *dev) ...@@ -338,7 +356,7 @@ static void hdlcd_drm_unbind(struct device *dev)
hdlcd->crtc.port = NULL; hdlcd->crtc.port = NULL;
pm_runtime_get_sync(dev); pm_runtime_get_sync(dev);
drm_atomic_helper_shutdown(drm); drm_atomic_helper_shutdown(drm);
drm_irq_uninstall(drm); hdlcd_irq_uninstall(drm);
pm_runtime_put(dev); pm_runtime_put(dev);
if (pm_runtime_enabled(dev)) if (pm_runtime_enabled(dev))
pm_runtime_disable(dev); pm_runtime_disable(dev);
......
...@@ -11,6 +11,7 @@ struct hdlcd_drm_private { ...@@ -11,6 +11,7 @@ struct hdlcd_drm_private {
struct clk *clk; struct clk *clk;
struct drm_crtc crtc; struct drm_crtc crtc;
struct drm_plane *plane; struct drm_plane *plane;
unsigned int irq;
#ifdef CONFIG_DEBUG_FS #ifdef CONFIG_DEBUG_FS
atomic_t buffer_underrun_count; atomic_t buffer_underrun_count;
atomic_t bus_error_count; atomic_t bus_error_count;
......
...@@ -808,7 +808,7 @@ ast_cursor_plane_helper_atomic_update(struct drm_plane *plane, ...@@ -808,7 +808,7 @@ ast_cursor_plane_helper_atomic_update(struct drm_plane *plane,
ast_cursor_plane->hwc[ast_cursor_plane->next_hwc_index].map; ast_cursor_plane->hwc[ast_cursor_plane->next_hwc_index].map;
u64 dst_off = u64 dst_off =
ast_cursor_plane->hwc[ast_cursor_plane->next_hwc_index].off; ast_cursor_plane->hwc[ast_cursor_plane->next_hwc_index].off;
struct dma_buf_map src_map = shadow_plane_state->map[0]; struct dma_buf_map src_map = shadow_plane_state->data[0];
unsigned int offset_x, offset_y; unsigned int offset_x, offset_y;
u16 x, y; u16 x, y;
u8 x_offset, y_offset; u8 x_offset, y_offset;
......
...@@ -22,7 +22,6 @@ ...@@ -22,7 +22,6 @@
#include <drm/drm_fb_helper.h> #include <drm/drm_fb_helper.h>
#include <drm/drm_gem_cma_helper.h> #include <drm/drm_gem_cma_helper.h>
#include <drm/drm_gem_framebuffer_helper.h> #include <drm/drm_gem_framebuffer_helper.h>
#include <drm/drm_irq.h>
#include <drm/drm_probe_helper.h> #include <drm/drm_probe_helper.h>
#include <drm/drm_vblank.h> #include <drm/drm_vblank.h>
...@@ -557,6 +556,51 @@ static irqreturn_t atmel_hlcdc_dc_irq_handler(int irq, void *data) ...@@ -557,6 +556,51 @@ static irqreturn_t atmel_hlcdc_dc_irq_handler(int irq, void *data)
return IRQ_HANDLED; return IRQ_HANDLED;
} }
static void atmel_hlcdc_dc_irq_postinstall(struct drm_device *dev)
{
struct atmel_hlcdc_dc *dc = dev->dev_private;
unsigned int cfg = 0;
int i;
/* Enable interrupts on activated layers */
for (i = 0; i < ATMEL_HLCDC_MAX_LAYERS; i++) {
if (dc->layers[i])
cfg |= ATMEL_HLCDC_LAYER_STATUS(i);
}
regmap_write(dc->hlcdc->regmap, ATMEL_HLCDC_IER, cfg);
}
static void atmel_hlcdc_dc_irq_disable(struct drm_device *dev)
{
struct atmel_hlcdc_dc *dc = dev->dev_private;
unsigned int isr;
regmap_write(dc->hlcdc->regmap, ATMEL_HLCDC_IDR, 0xffffffff);
regmap_read(dc->hlcdc->regmap, ATMEL_HLCDC_ISR, &isr);
}
static int atmel_hlcdc_dc_irq_install(struct drm_device *dev, unsigned int irq)
{
int ret;
atmel_hlcdc_dc_irq_disable(dev);
ret = devm_request_irq(dev->dev, irq, atmel_hlcdc_dc_irq_handler, 0,
dev->driver->name, dev);
if (ret)
return ret;
atmel_hlcdc_dc_irq_postinstall(dev);
return 0;
}
static void atmel_hlcdc_dc_irq_uninstall(struct drm_device *dev)
{
atmel_hlcdc_dc_irq_disable(dev);
}
static const struct drm_mode_config_funcs mode_config_funcs = { static const struct drm_mode_config_funcs mode_config_funcs = {
.fb_create = drm_gem_fb_create, .fb_create = drm_gem_fb_create,
.atomic_check = drm_atomic_helper_check, .atomic_check = drm_atomic_helper_check,
...@@ -647,7 +691,7 @@ static int atmel_hlcdc_dc_load(struct drm_device *dev) ...@@ -647,7 +691,7 @@ static int atmel_hlcdc_dc_load(struct drm_device *dev)
drm_mode_config_reset(dev); drm_mode_config_reset(dev);
pm_runtime_get_sync(dev->dev); pm_runtime_get_sync(dev->dev);
ret = drm_irq_install(dev, dc->hlcdc->irq); ret = atmel_hlcdc_dc_irq_install(dev, dc->hlcdc->irq);
pm_runtime_put_sync(dev->dev); pm_runtime_put_sync(dev->dev);
if (ret < 0) { if (ret < 0) {
dev_err(dev->dev, "failed to install IRQ handler\n"); dev_err(dev->dev, "failed to install IRQ handler\n");
...@@ -676,7 +720,7 @@ static void atmel_hlcdc_dc_unload(struct drm_device *dev) ...@@ -676,7 +720,7 @@ static void atmel_hlcdc_dc_unload(struct drm_device *dev)
drm_mode_config_cleanup(dev); drm_mode_config_cleanup(dev);
pm_runtime_get_sync(dev->dev); pm_runtime_get_sync(dev->dev);
drm_irq_uninstall(dev); atmel_hlcdc_dc_irq_uninstall(dev);
pm_runtime_put_sync(dev->dev); pm_runtime_put_sync(dev->dev);
dev->dev_private = NULL; dev->dev_private = NULL;
...@@ -685,40 +729,10 @@ static void atmel_hlcdc_dc_unload(struct drm_device *dev) ...@@ -685,40 +729,10 @@ static void atmel_hlcdc_dc_unload(struct drm_device *dev)
clk_disable_unprepare(dc->hlcdc->periph_clk); clk_disable_unprepare(dc->hlcdc->periph_clk);
} }
static int atmel_hlcdc_dc_irq_postinstall(struct drm_device *dev)
{
struct atmel_hlcdc_dc *dc = dev->dev_private;
unsigned int cfg = 0;
int i;
/* Enable interrupts on activated layers */
for (i = 0; i < ATMEL_HLCDC_MAX_LAYERS; i++) {
if (dc->layers[i])
cfg |= ATMEL_HLCDC_LAYER_STATUS(i);
}
regmap_write(dc->hlcdc->regmap, ATMEL_HLCDC_IER, cfg);
return 0;
}
static void atmel_hlcdc_dc_irq_uninstall(struct drm_device *dev)
{
struct atmel_hlcdc_dc *dc = dev->dev_private;
unsigned int isr;
regmap_write(dc->hlcdc->regmap, ATMEL_HLCDC_IDR, 0xffffffff);
regmap_read(dc->hlcdc->regmap, ATMEL_HLCDC_ISR, &isr);
}
DEFINE_DRM_GEM_CMA_FOPS(fops); DEFINE_DRM_GEM_CMA_FOPS(fops);
static const struct drm_driver atmel_hlcdc_dc_driver = { static const struct drm_driver atmel_hlcdc_dc_driver = {
.driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC, .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
.irq_handler = atmel_hlcdc_dc_irq_handler,
.irq_preinstall = atmel_hlcdc_dc_irq_uninstall,
.irq_postinstall = atmel_hlcdc_dc_irq_postinstall,
.irq_uninstall = atmel_hlcdc_dc_irq_uninstall,
DRM_GEM_CMA_DRIVER_OPS, DRM_GEM_CMA_DRIVER_OPS,
.fops = &fops, .fops = &fops,
.name = "atmel-hlcdc", .name = "atmel-hlcdc",
......
...@@ -384,6 +384,25 @@ static int anx7625_odfc_config(struct anx7625_data *ctx, ...@@ -384,6 +384,25 @@ static int anx7625_odfc_config(struct anx7625_data *ctx,
return ret; return ret;
} }
/*
* The MIPI source video data exist large variation (e.g. 59Hz ~ 61Hz),
* anx7625 defined K ratio for matching MIPI input video clock and
* DP output video clock. Increase K value can match bigger video data
* variation. IVO panel has small variation than DP CTS spec, need
* decrease the K value.
*/
static int anx7625_set_k_value(struct anx7625_data *ctx)
{
struct edid *edid = (struct edid *)ctx->slimport_edid_p.edid_raw_data;
if (edid->mfg_id[0] == IVO_MID0 && edid->mfg_id[1] == IVO_MID1)
return anx7625_reg_write(ctx, ctx->i2c.rx_p1_client,
MIPI_DIGITAL_ADJ_1, 0x3B);
return anx7625_reg_write(ctx, ctx->i2c.rx_p1_client,
MIPI_DIGITAL_ADJ_1, 0x3D);
}
static int anx7625_dsi_video_timing_config(struct anx7625_data *ctx) static int anx7625_dsi_video_timing_config(struct anx7625_data *ctx)
{ {
struct device *dev = &ctx->client->dev; struct device *dev = &ctx->client->dev;
...@@ -470,9 +489,8 @@ static int anx7625_dsi_video_timing_config(struct anx7625_data *ctx) ...@@ -470,9 +489,8 @@ static int anx7625_dsi_video_timing_config(struct anx7625_data *ctx)
MIPI_PLL_N_NUM_15_8, (n >> 8) & 0xff); MIPI_PLL_N_NUM_15_8, (n >> 8) & 0xff);
ret |= anx7625_reg_write(ctx, ctx->i2c.rx_p1_client, MIPI_PLL_N_NUM_7_0, ret |= anx7625_reg_write(ctx, ctx->i2c.rx_p1_client, MIPI_PLL_N_NUM_7_0,
(n & 0xff)); (n & 0xff));
/* Diff */
ret |= anx7625_reg_write(ctx, ctx->i2c.rx_p1_client, anx7625_set_k_value(ctx);
MIPI_DIGITAL_ADJ_1, 0x3D);
ret |= anx7625_odfc_config(ctx, post_divider - 1); ret |= anx7625_odfc_config(ctx, post_divider - 1);
......
...@@ -210,7 +210,9 @@ ...@@ -210,7 +210,9 @@
#define MIPI_VIDEO_STABLE_CNT 0x0A #define MIPI_VIDEO_STABLE_CNT 0x0A
#define MIPI_LANE_CTRL_10 0x0F #define MIPI_LANE_CTRL_10 0x0F
#define MIPI_DIGITAL_ADJ_1 0x1B #define MIPI_DIGITAL_ADJ_1 0x1B
#define IVO_MID0 0x26
#define IVO_MID1 0xCF
#define MIPI_PLL_M_NUM_23_16 0x1E #define MIPI_PLL_M_NUM_23_16 0x1E
#define MIPI_PLL_M_NUM_15_8 0x1F #define MIPI_PLL_M_NUM_15_8 0x1F
......
...@@ -536,6 +536,8 @@ static int it66121_bridge_attach(struct drm_bridge *bridge, ...@@ -536,6 +536,8 @@ static int it66121_bridge_attach(struct drm_bridge *bridge,
return -EINVAL; return -EINVAL;
ret = drm_bridge_attach(bridge->encoder, ctx->next_bridge, bridge, flags); ret = drm_bridge_attach(bridge->encoder, ctx->next_bridge, bridge, flags);
if (ret)
return ret;
ret = regmap_write_bits(ctx->regmap, IT66121_CLK_BANK_REG, ret = regmap_write_bits(ctx->regmap, IT66121_CLK_BANK_REG,
IT66121_CLK_BANK_PWROFF_RCLK, 0); IT66121_CLK_BANK_PWROFF_RCLK, 0);
......
...@@ -739,6 +739,9 @@ static int ti_sn_bridge_attach(struct drm_bridge *bridge, ...@@ -739,6 +739,9 @@ static int ti_sn_bridge_attach(struct drm_bridge *bridge,
} }
pdata->dsi = dsi; pdata->dsi = dsi;
/* We never want the next bridge to *also* create a connector: */
flags |= DRM_BRIDGE_ATTACH_NO_CONNECTOR;
/* Attach the next bridge */ /* Attach the next bridge */
ret = drm_bridge_attach(bridge->encoder, pdata->next_bridge, ret = drm_bridge_attach(bridge->encoder, pdata->next_bridge,
&pdata->bridge, flags); &pdata->bridge, flags);
......
...@@ -63,9 +63,9 @@ ...@@ -63,9 +63,9 @@
static bool drm_is_current_master_locked(struct drm_file *fpriv) static bool drm_is_current_master_locked(struct drm_file *fpriv)
{ {
/* Either drm_device.master_mutex or drm_file.master_lookup_lock lockdep_assert_once(lockdep_is_held(&fpriv->master_lookup_lock) ||
* should be held here. lockdep_is_held(&fpriv->minor->dev->master_mutex));
*/
return fpriv->is_master && drm_lease_owner(fpriv->master) == fpriv->minor->dev->master; return fpriv->is_master && drm_lease_owner(fpriv->master) == fpriv->minor->dev->master;
} }
......
...@@ -339,7 +339,7 @@ int drm_gem_prepare_shadow_fb(struct drm_plane *plane, struct drm_plane_state *p ...@@ -339,7 +339,7 @@ int drm_gem_prepare_shadow_fb(struct drm_plane *plane, struct drm_plane_state *p
if (ret) if (ret)
return ret; return ret;
return drm_gem_fb_vmap(fb, shadow_plane_state->map); return drm_gem_fb_vmap(fb, shadow_plane_state->map, shadow_plane_state->data);
} }
EXPORT_SYMBOL(drm_gem_prepare_shadow_fb); EXPORT_SYMBOL(drm_gem_prepare_shadow_fb);
......
...@@ -315,19 +315,25 @@ EXPORT_SYMBOL_GPL(drm_gem_fb_create_with_dirty); ...@@ -315,19 +315,25 @@ EXPORT_SYMBOL_GPL(drm_gem_fb_create_with_dirty);
* drm_gem_fb_vmap - maps all framebuffer BOs into kernel address space * drm_gem_fb_vmap - maps all framebuffer BOs into kernel address space
* @fb: the framebuffer * @fb: the framebuffer
* @map: returns the mapping's address for each BO * @map: returns the mapping's address for each BO
* @data: returns the data address for each BO, can be NULL
* *
* This function maps all buffer objects of the given framebuffer into * This function maps all buffer objects of the given framebuffer into
* kernel address space and stores them in struct dma_buf_map. If the * kernel address space and stores them in struct dma_buf_map. If the
* mapping operation fails for one of the BOs, the function unmaps the * mapping operation fails for one of the BOs, the function unmaps the
* already established mappings automatically. * already established mappings automatically.
* *
* Callers that want to access a BO's stored data should pass @data.
* The argument returns the addresses of the data stored in each BO. This
* is different from @map if the framebuffer's offsets field is non-zero.
*
* See drm_gem_fb_vunmap() for unmapping. * See drm_gem_fb_vunmap() for unmapping.
* *
* Returns: * Returns:
* 0 on success, or a negative errno code otherwise. * 0 on success, or a negative errno code otherwise.
*/ */
int drm_gem_fb_vmap(struct drm_framebuffer *fb, int drm_gem_fb_vmap(struct drm_framebuffer *fb,
struct dma_buf_map map[static DRM_FORMAT_MAX_PLANES]) struct dma_buf_map map[static DRM_FORMAT_MAX_PLANES],
struct dma_buf_map data[DRM_FORMAT_MAX_PLANES])
{ {
struct drm_gem_object *obj; struct drm_gem_object *obj;
unsigned int i; unsigned int i;
...@@ -344,6 +350,15 @@ int drm_gem_fb_vmap(struct drm_framebuffer *fb, ...@@ -344,6 +350,15 @@ int drm_gem_fb_vmap(struct drm_framebuffer *fb,
goto err_drm_gem_vunmap; goto err_drm_gem_vunmap;
} }
if (data) {
for (i = 0; i < DRM_FORMAT_MAX_PLANES; ++i) {
memcpy(&data[i], &map[i], sizeof(data[i]));
if (dma_buf_map_is_null(&data[i]))
continue;
dma_buf_map_incr(&data[i], fb->offsets[i]);
}
}
return 0; return 0;
err_drm_gem_vunmap: err_drm_gem_vunmap:
......
...@@ -60,46 +60,14 @@ ...@@ -60,46 +60,14 @@
#include <drm/drm.h> #include <drm/drm.h>
#include <drm/drm_device.h> #include <drm/drm_device.h>
#include <drm/drm_drv.h> #include <drm/drm_drv.h>
#include <drm/drm_irq.h> #include <drm/drm_legacy.h>
#include <drm/drm_print.h> #include <drm/drm_print.h>
#include <drm/drm_vblank.h> #include <drm/drm_vblank.h>
#include "drm_internal.h" #include "drm_internal.h"
/** #if IS_ENABLED(CONFIG_DRM_LEGACY)
* DOC: irq helpers static int drm_legacy_irq_install(struct drm_device *dev, int irq)
*
* The DRM core provides very simple support helpers to enable IRQ handling on a
* device through the drm_irq_install() and drm_irq_uninstall() functions. This
* only supports devices with a single interrupt on the main device stored in
* &drm_device.dev and set as the device parameter in drm_dev_alloc().
*
* These IRQ helpers are strictly optional. Since these helpers don't automatically
* clean up the requested interrupt like e.g. devm_request_irq() they're not really
* recommended.
*/
/**
* drm_irq_install - install IRQ handler
* @dev: DRM device
* @irq: IRQ number to install the handler for
*
* Initializes the IRQ related data. Installs the handler, calling the driver
* &drm_driver.irq_preinstall and &drm_driver.irq_postinstall functions before
* and after the installation.
*
* This is the simplified helper interface provided for drivers with no special
* needs.
*
* @irq must match the interrupt number that would be passed to request_irq(),
* if called directly instead of using this helper function.
*
* &drm_driver.irq_handler is called to handle the registered interrupt.
*
* Returns:
* Zero on success or a negative error code on failure.
*/
int drm_irq_install(struct drm_device *dev, int irq)
{ {
int ret; int ret;
unsigned long sh_flags = 0; unsigned long sh_flags = 0;
...@@ -144,24 +112,8 @@ int drm_irq_install(struct drm_device *dev, int irq) ...@@ -144,24 +112,8 @@ int drm_irq_install(struct drm_device *dev, int irq)
return ret; return ret;
} }
EXPORT_SYMBOL(drm_irq_install);
/** int drm_legacy_irq_uninstall(struct drm_device *dev)
* drm_irq_uninstall - uninstall the IRQ handler
* @dev: DRM device
*
* Calls the driver's &drm_driver.irq_uninstall function and unregisters the IRQ
* handler. This should only be called by drivers which used drm_irq_install()
* to set up their interrupt handler.
*
* Note that for kernel modesetting drivers it is a bug if this function fails.
* The sanity checks are only to catch buggy user modesetting drivers which call
* the same function through an ioctl.
*
* Returns:
* Zero on success or a negative error code on failure.
*/
int drm_irq_uninstall(struct drm_device *dev)
{ {
unsigned long irqflags; unsigned long irqflags;
bool irq_enabled; bool irq_enabled;
...@@ -207,41 +159,8 @@ int drm_irq_uninstall(struct drm_device *dev) ...@@ -207,41 +159,8 @@ int drm_irq_uninstall(struct drm_device *dev)
return 0; return 0;
} }
EXPORT_SYMBOL(drm_irq_uninstall); EXPORT_SYMBOL(drm_legacy_irq_uninstall);
static void devm_drm_irq_uninstall(void *data)
{
drm_irq_uninstall(data);
}
/**
* devm_drm_irq_install - install IRQ handler
* @dev: DRM device
* @irq: IRQ number to install the handler for
*
* devm_drm_irq_install is a help function of drm_irq_install.
*
* if the driver uses devm_drm_irq_install, there is no need
* to call drm_irq_uninstall when the drm module get unloaded,
* as this will done automagically.
*
* Returns:
* Zero on success or a negative error code on failure.
*/
int devm_drm_irq_install(struct drm_device *dev, int irq)
{
int ret;
ret = drm_irq_install(dev, irq);
if (ret)
return ret;
return devm_add_action_or_reset(dev->dev,
devm_drm_irq_uninstall, dev);
}
EXPORT_SYMBOL(devm_drm_irq_install);
#if IS_ENABLED(CONFIG_DRM_LEGACY)
int drm_legacy_irq_control(struct drm_device *dev, void *data, int drm_legacy_irq_control(struct drm_device *dev, void *data,
struct drm_file *file_priv) struct drm_file *file_priv)
{ {
...@@ -270,13 +189,13 @@ int drm_legacy_irq_control(struct drm_device *dev, void *data, ...@@ -270,13 +189,13 @@ int drm_legacy_irq_control(struct drm_device *dev, void *data,
ctl->irq != irq) ctl->irq != irq)
return -EINVAL; return -EINVAL;
mutex_lock(&dev->struct_mutex); mutex_lock(&dev->struct_mutex);
ret = drm_irq_install(dev, irq); ret = drm_legacy_irq_install(dev, irq);
mutex_unlock(&dev->struct_mutex); mutex_unlock(&dev->struct_mutex);
return ret; return ret;
case DRM_UNINST_HANDLER: case DRM_UNINST_HANDLER:
mutex_lock(&dev->struct_mutex); mutex_lock(&dev->struct_mutex);
ret = drm_irq_uninstall(dev); ret = drm_legacy_irq_uninstall(dev);
mutex_unlock(&dev->struct_mutex); mutex_unlock(&dev->struct_mutex);
return ret; return ret;
......
...@@ -35,7 +35,6 @@ ...@@ -35,7 +35,6 @@
#include <drm/drm_device.h> #include <drm/drm_device.h>
#include <drm/drm_drv.h> #include <drm/drm_drv.h>
#include <drm/drm_irq.h>
#include <drm/drm_print.h> #include <drm/drm_print.h>
#include "drm_internal.h" #include "drm_internal.h"
...@@ -78,7 +77,7 @@ int drm_legacy_setup(struct drm_device * dev) ...@@ -78,7 +77,7 @@ int drm_legacy_setup(struct drm_device * dev)
void drm_legacy_dev_reinit(struct drm_device *dev) void drm_legacy_dev_reinit(struct drm_device *dev)
{ {
if (dev->irq_enabled) if (dev->irq_enabled)
drm_irq_uninstall(dev); drm_legacy_irq_uninstall(dev);
mutex_lock(&dev->struct_mutex); mutex_lock(&dev->struct_mutex);
......
...@@ -145,6 +145,39 @@ static const struct drm_crtc_helper_funcs drm_simple_kms_crtc_helper_funcs = { ...@@ -145,6 +145,39 @@ static const struct drm_crtc_helper_funcs drm_simple_kms_crtc_helper_funcs = {
.atomic_disable = drm_simple_kms_crtc_disable, .atomic_disable = drm_simple_kms_crtc_disable,
}; };
static void drm_simple_kms_crtc_reset(struct drm_crtc *crtc)
{
struct drm_simple_display_pipe *pipe;
pipe = container_of(crtc, struct drm_simple_display_pipe, crtc);
if (!pipe->funcs || !pipe->funcs->reset_crtc)
return drm_atomic_helper_crtc_reset(crtc);
return pipe->funcs->reset_crtc(pipe);
}
static struct drm_crtc_state *drm_simple_kms_crtc_duplicate_state(struct drm_crtc *crtc)
{
struct drm_simple_display_pipe *pipe;
pipe = container_of(crtc, struct drm_simple_display_pipe, crtc);
if (!pipe->funcs || !pipe->funcs->duplicate_crtc_state)
return drm_atomic_helper_crtc_duplicate_state(crtc);
return pipe->funcs->duplicate_crtc_state(pipe);
}
static void drm_simple_kms_crtc_destroy_state(struct drm_crtc *crtc, struct drm_crtc_state *state)
{
struct drm_simple_display_pipe *pipe;
pipe = container_of(crtc, struct drm_simple_display_pipe, crtc);
if (!pipe->funcs || !pipe->funcs->destroy_crtc_state)
drm_atomic_helper_crtc_destroy_state(crtc, state);
else
pipe->funcs->destroy_crtc_state(pipe, state);
}
static int drm_simple_kms_crtc_enable_vblank(struct drm_crtc *crtc) static int drm_simple_kms_crtc_enable_vblank(struct drm_crtc *crtc)
{ {
struct drm_simple_display_pipe *pipe; struct drm_simple_display_pipe *pipe;
...@@ -168,12 +201,12 @@ static void drm_simple_kms_crtc_disable_vblank(struct drm_crtc *crtc) ...@@ -168,12 +201,12 @@ static void drm_simple_kms_crtc_disable_vblank(struct drm_crtc *crtc)
} }
static const struct drm_crtc_funcs drm_simple_kms_crtc_funcs = { static const struct drm_crtc_funcs drm_simple_kms_crtc_funcs = {
.reset = drm_atomic_helper_crtc_reset, .reset = drm_simple_kms_crtc_reset,
.destroy = drm_crtc_cleanup, .destroy = drm_crtc_cleanup,
.set_config = drm_atomic_helper_set_config, .set_config = drm_atomic_helper_set_config,
.page_flip = drm_atomic_helper_page_flip, .page_flip = drm_atomic_helper_page_flip,
.atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state, .atomic_duplicate_state = drm_simple_kms_crtc_duplicate_state,
.atomic_destroy_state = drm_atomic_helper_crtc_destroy_state, .atomic_destroy_state = drm_simple_kms_crtc_destroy_state,
.enable_vblank = drm_simple_kms_crtc_enable_vblank, .enable_vblank = drm_simple_kms_crtc_enable_vblank,
.disable_vblank = drm_simple_kms_crtc_disable_vblank, .disable_vblank = drm_simple_kms_crtc_disable_vblank,
}; };
......
...@@ -1739,10 +1739,10 @@ static void drm_wait_vblank_reply(struct drm_device *dev, unsigned int pipe, ...@@ -1739,10 +1739,10 @@ static void drm_wait_vblank_reply(struct drm_device *dev, unsigned int pipe,
static bool drm_wait_vblank_supported(struct drm_device *dev) static bool drm_wait_vblank_supported(struct drm_device *dev)
{ {
if (IS_ENABLED(CONFIG_DRM_LEGACY)) { #if IS_ENABLED(CONFIG_DRM_LEGACY)
if (unlikely(drm_core_check_feature(dev, DRIVER_LEGACY))) if (unlikely(drm_core_check_feature(dev, DRIVER_LEGACY)))
return dev->irq_enabled; return dev->irq_enabled;
} #endif
return drm_dev_has_vblank(dev); return drm_dev_has_vblank(dev);
} }
......
...@@ -23,7 +23,6 @@ ...@@ -23,7 +23,6 @@
#include <drm/drm_fb_cma_helper.h> #include <drm/drm_fb_cma_helper.h>
#include <drm/drm_fb_helper.h> #include <drm/drm_fb_helper.h>
#include <drm/drm_gem_cma_helper.h> #include <drm/drm_gem_cma_helper.h>
#include <drm/drm_irq.h>
#include <drm/drm_modeset_helper.h> #include <drm/drm_modeset_helper.h>
#include <drm/drm_probe_helper.h> #include <drm/drm_probe_helper.h>
#include <drm/drm_vblank.h> #include <drm/drm_vblank.h>
...@@ -51,7 +50,7 @@ static const struct regmap_config fsl_dcu_regmap_config = { ...@@ -51,7 +50,7 @@ static const struct regmap_config fsl_dcu_regmap_config = {
.volatile_reg = fsl_dcu_drm_is_volatile_reg, .volatile_reg = fsl_dcu_drm_is_volatile_reg,
}; };
static void fsl_dcu_irq_uninstall(struct drm_device *dev) static void fsl_dcu_irq_reset(struct drm_device *dev)
{ {
struct fsl_dcu_drm_device *fsl_dev = dev->dev_private; struct fsl_dcu_drm_device *fsl_dev = dev->dev_private;
...@@ -59,6 +58,45 @@ static void fsl_dcu_irq_uninstall(struct drm_device *dev) ...@@ -59,6 +58,45 @@ static void fsl_dcu_irq_uninstall(struct drm_device *dev)
regmap_write(fsl_dev->regmap, DCU_INT_MASK, ~0); regmap_write(fsl_dev->regmap, DCU_INT_MASK, ~0);
} }
static irqreturn_t fsl_dcu_drm_irq(int irq, void *arg)
{
struct drm_device *dev = arg;
struct fsl_dcu_drm_device *fsl_dev = dev->dev_private;
unsigned int int_status;
int ret;
ret = regmap_read(fsl_dev->regmap, DCU_INT_STATUS, &int_status);
if (ret) {
dev_err(dev->dev, "read DCU_INT_STATUS failed\n");
return IRQ_NONE;
}
if (int_status & DCU_INT_STATUS_VBLANK)
drm_handle_vblank(dev, 0);
regmap_write(fsl_dev->regmap, DCU_INT_STATUS, int_status);
return IRQ_HANDLED;
}
static int fsl_dcu_irq_install(struct drm_device *dev, unsigned int irq)
{
if (irq == IRQ_NOTCONNECTED)
return -ENOTCONN;
fsl_dcu_irq_reset(dev);
return request_irq(irq, fsl_dcu_drm_irq, 0, dev->driver->name, dev);
}
static void fsl_dcu_irq_uninstall(struct drm_device *dev)
{
struct fsl_dcu_drm_device *fsl_dev = dev->dev_private;
fsl_dcu_irq_reset(dev);
free_irq(fsl_dev->irq, dev);
}
static int fsl_dcu_load(struct drm_device *dev, unsigned long flags) static int fsl_dcu_load(struct drm_device *dev, unsigned long flags)
{ {
struct fsl_dcu_drm_device *fsl_dev = dev->dev_private; struct fsl_dcu_drm_device *fsl_dev = dev->dev_private;
...@@ -73,13 +111,13 @@ static int fsl_dcu_load(struct drm_device *dev, unsigned long flags) ...@@ -73,13 +111,13 @@ static int fsl_dcu_load(struct drm_device *dev, unsigned long flags)
ret = drm_vblank_init(dev, dev->mode_config.num_crtc); ret = drm_vblank_init(dev, dev->mode_config.num_crtc);
if (ret < 0) { if (ret < 0) {
dev_err(dev->dev, "failed to initialize vblank\n"); dev_err(dev->dev, "failed to initialize vblank\n");
goto done; goto done_vblank;
} }
ret = drm_irq_install(dev, fsl_dev->irq); ret = fsl_dcu_irq_install(dev, fsl_dev->irq);
if (ret < 0) { if (ret < 0) {
dev_err(dev->dev, "failed to install IRQ handler\n"); dev_err(dev->dev, "failed to install IRQ handler\n");
goto done; goto done_irq;
} }
if (legacyfb_depth != 16 && legacyfb_depth != 24 && if (legacyfb_depth != 16 && legacyfb_depth != 24 &&
...@@ -90,11 +128,11 @@ static int fsl_dcu_load(struct drm_device *dev, unsigned long flags) ...@@ -90,11 +128,11 @@ static int fsl_dcu_load(struct drm_device *dev, unsigned long flags)
} }
return 0; return 0;
done: done_irq:
drm_kms_helper_poll_fini(dev); drm_kms_helper_poll_fini(dev);
drm_mode_config_cleanup(dev); drm_mode_config_cleanup(dev);
drm_irq_uninstall(dev); done_vblank:
dev->dev_private = NULL; dev->dev_private = NULL;
return ret; return ret;
...@@ -106,41 +144,17 @@ static void fsl_dcu_unload(struct drm_device *dev) ...@@ -106,41 +144,17 @@ static void fsl_dcu_unload(struct drm_device *dev)
drm_kms_helper_poll_fini(dev); drm_kms_helper_poll_fini(dev);
drm_mode_config_cleanup(dev); drm_mode_config_cleanup(dev);
drm_irq_uninstall(dev); fsl_dcu_irq_uninstall(dev);
dev->dev_private = NULL; dev->dev_private = NULL;
} }
static irqreturn_t fsl_dcu_drm_irq(int irq, void *arg)
{
struct drm_device *dev = arg;
struct fsl_dcu_drm_device *fsl_dev = dev->dev_private;
unsigned int int_status;
int ret;
ret = regmap_read(fsl_dev->regmap, DCU_INT_STATUS, &int_status);
if (ret) {
dev_err(dev->dev, "read DCU_INT_STATUS failed\n");
return IRQ_NONE;
}
if (int_status & DCU_INT_STATUS_VBLANK)
drm_handle_vblank(dev, 0);
regmap_write(fsl_dev->regmap, DCU_INT_STATUS, int_status);
return IRQ_HANDLED;
}
DEFINE_DRM_GEM_CMA_FOPS(fsl_dcu_drm_fops); DEFINE_DRM_GEM_CMA_FOPS(fsl_dcu_drm_fops);
static const struct drm_driver fsl_dcu_drm_driver = { static const struct drm_driver fsl_dcu_drm_driver = {
.driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC, .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
.load = fsl_dcu_load, .load = fsl_dcu_load,
.unload = fsl_dcu_unload, .unload = fsl_dcu_unload,
.irq_handler = fsl_dcu_drm_irq,
.irq_preinstall = fsl_dcu_irq_uninstall,
.irq_uninstall = fsl_dcu_irq_uninstall,
DRM_GEM_CMA_DRIVER_OPS, DRM_GEM_CMA_DRIVER_OPS,
.fops = &fsl_dcu_drm_fops, .fops = &fsl_dcu_drm_fops,
.name = "fsl-dcu-drm", .name = "fsl-dcu-drm",
......
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
#include "psb_drv.h" #include "psb_drv.h"
#include "psb_reg.h" #include "psb_reg.h"
#include "psb_intel_reg.h" #include "psb_intel_reg.h"
#include "psb_irq.h"
#include <linux/mutex.h> #include <linux/mutex.h>
#include <linux/pm_runtime.h> #include <linux/pm_runtime.h>
......
...@@ -23,7 +23,6 @@ ...@@ -23,7 +23,6 @@
#include <drm/drm_fb_helper.h> #include <drm/drm_fb_helper.h>
#include <drm/drm_file.h> #include <drm/drm_file.h>
#include <drm/drm_ioctl.h> #include <drm/drm_ioctl.h>
#include <drm/drm_irq.h>
#include <drm/drm_pciids.h> #include <drm/drm_pciids.h>
#include <drm/drm_vblank.h> #include <drm/drm_vblank.h>
...@@ -33,6 +32,7 @@ ...@@ -33,6 +32,7 @@
#include "power.h" #include "power.h"
#include "psb_drv.h" #include "psb_drv.h"
#include "psb_intel_reg.h" #include "psb_intel_reg.h"
#include "psb_irq.h"
#include "psb_reg.h" #include "psb_reg.h"
static const struct drm_driver driver; static const struct drm_driver driver;
...@@ -380,7 +380,7 @@ static int psb_driver_load(struct drm_device *dev, unsigned long flags) ...@@ -380,7 +380,7 @@ static int psb_driver_load(struct drm_device *dev, unsigned long flags)
PSB_WVDC32(0xFFFFFFFF, PSB_INT_MASK_R); PSB_WVDC32(0xFFFFFFFF, PSB_INT_MASK_R);
spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags); spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
drm_irq_install(dev, pdev->irq); psb_irq_install(dev, pdev->irq);
dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */ dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */
...@@ -515,10 +515,6 @@ static const struct drm_driver driver = { ...@@ -515,10 +515,6 @@ static const struct drm_driver driver = {
.lastclose = drm_fb_helper_lastclose, .lastclose = drm_fb_helper_lastclose,
.num_ioctls = ARRAY_SIZE(psb_ioctls), .num_ioctls = ARRAY_SIZE(psb_ioctls),
.irq_preinstall = psb_irq_preinstall,
.irq_postinstall = psb_irq_postinstall,
.irq_uninstall = psb_irq_uninstall,
.irq_handler = psb_irq_handler,
.dumb_create = psb_gem_dumb_create, .dumb_create = psb_gem_dumb_create,
.ioctls = psb_ioctls, .ioctls = psb_ioctls,
......
...@@ -624,11 +624,6 @@ static inline struct drm_psb_private *psb_priv(struct drm_device *dev) ...@@ -624,11 +624,6 @@ static inline struct drm_psb_private *psb_priv(struct drm_device *dev)
} }
/* psb_irq.c */ /* psb_irq.c */
extern irqreturn_t psb_irq_handler(int irq, void *arg);
extern void psb_irq_preinstall(struct drm_device *dev);
extern int psb_irq_postinstall(struct drm_device *dev);
extern void psb_irq_uninstall(struct drm_device *dev);
extern void psb_irq_uninstall_islands(struct drm_device *dev, int hw_islands); extern void psb_irq_uninstall_islands(struct drm_device *dev, int hw_islands);
extern int psb_vblank_wait2(struct drm_device *dev, unsigned int *sequence); extern int psb_vblank_wait2(struct drm_device *dev, unsigned int *sequence);
extern int psb_vblank_wait(struct drm_device *dev, unsigned int *sequence); extern int psb_vblank_wait(struct drm_device *dev, unsigned int *sequence);
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
* *
**************************************************************************/ **************************************************************************/
#include <drm/drm_drv.h>
#include <drm/drm_vblank.h> #include <drm/drm_vblank.h>
#include "power.h" #include "power.h"
...@@ -222,7 +223,7 @@ static void psb_sgx_interrupt(struct drm_device *dev, u32 stat_1, u32 stat_2) ...@@ -222,7 +223,7 @@ static void psb_sgx_interrupt(struct drm_device *dev, u32 stat_1, u32 stat_2)
PSB_RSGX32(PSB_CR_EVENT_HOST_CLEAR2); PSB_RSGX32(PSB_CR_EVENT_HOST_CLEAR2);
} }
irqreturn_t psb_irq_handler(int irq, void *arg) static irqreturn_t psb_irq_handler(int irq, void *arg)
{ {
struct drm_device *dev = arg; struct drm_device *dev = arg;
struct drm_psb_private *dev_priv = dev->dev_private; struct drm_psb_private *dev_priv = dev->dev_private;
...@@ -304,7 +305,7 @@ void psb_irq_preinstall(struct drm_device *dev) ...@@ -304,7 +305,7 @@ void psb_irq_preinstall(struct drm_device *dev)
spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags); spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
} }
int psb_irq_postinstall(struct drm_device *dev) void psb_irq_postinstall(struct drm_device *dev)
{ {
struct drm_psb_private *dev_priv = dev->dev_private; struct drm_psb_private *dev_priv = dev->dev_private;
unsigned long irqflags; unsigned long irqflags;
...@@ -332,12 +333,31 @@ int psb_irq_postinstall(struct drm_device *dev) ...@@ -332,12 +333,31 @@ int psb_irq_postinstall(struct drm_device *dev)
dev_priv->ops->hotplug_enable(dev, true); dev_priv->ops->hotplug_enable(dev, true);
spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags); spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
}
int psb_irq_install(struct drm_device *dev, unsigned int irq)
{
int ret;
if (irq == IRQ_NOTCONNECTED)
return -ENOTCONN;
psb_irq_preinstall(dev);
/* PCI devices require shared interrupts. */
ret = request_irq(irq, psb_irq_handler, IRQF_SHARED, dev->driver->name, dev);
if (ret)
return ret;
psb_irq_postinstall(dev);
return 0; return 0;
} }
void psb_irq_uninstall(struct drm_device *dev) void psb_irq_uninstall(struct drm_device *dev)
{ {
struct drm_psb_private *dev_priv = dev->dev_private; struct drm_psb_private *dev_priv = dev->dev_private;
struct pci_dev *pdev = to_pci_dev(dev->dev);
unsigned long irqflags; unsigned long irqflags;
unsigned int i; unsigned int i;
...@@ -366,6 +386,8 @@ void psb_irq_uninstall(struct drm_device *dev) ...@@ -366,6 +386,8 @@ void psb_irq_uninstall(struct drm_device *dev)
/* This register is safe even if display island is off */ /* This register is safe even if display island is off */
PSB_WVDC32(PSB_RVDC32(PSB_INT_IDENTITY_R), PSB_INT_IDENTITY_R); PSB_WVDC32(PSB_RVDC32(PSB_INT_IDENTITY_R), PSB_INT_IDENTITY_R);
spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags); spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
free_irq(pdev->irq, dev);
} }
/* /*
......
...@@ -19,9 +19,9 @@ bool sysirq_init(struct drm_device *dev); ...@@ -19,9 +19,9 @@ bool sysirq_init(struct drm_device *dev);
void sysirq_uninit(struct drm_device *dev); void sysirq_uninit(struct drm_device *dev);
void psb_irq_preinstall(struct drm_device *dev); void psb_irq_preinstall(struct drm_device *dev);
int psb_irq_postinstall(struct drm_device *dev); void psb_irq_postinstall(struct drm_device *dev);
int psb_irq_install(struct drm_device *dev, unsigned int irq);
void psb_irq_uninstall(struct drm_device *dev); void psb_irq_uninstall(struct drm_device *dev);
irqreturn_t psb_irq_handler(int irq, void *arg);
int psb_enable_vblank(struct drm_crtc *crtc); int psb_enable_vblank(struct drm_crtc *crtc);
void psb_disable_vblank(struct drm_crtc *crtc); void psb_disable_vblank(struct drm_crtc *crtc);
......
...@@ -153,6 +153,7 @@ static int gud_prep_flush(struct gud_device *gdrm, struct drm_framebuffer *fb, ...@@ -153,6 +153,7 @@ static int gud_prep_flush(struct gud_device *gdrm, struct drm_framebuffer *fb,
struct dma_buf_attachment *import_attach = fb->obj[0]->import_attach; struct dma_buf_attachment *import_attach = fb->obj[0]->import_attach;
u8 compression = gdrm->compression; u8 compression = gdrm->compression;
struct dma_buf_map map[DRM_FORMAT_MAX_PLANES]; struct dma_buf_map map[DRM_FORMAT_MAX_PLANES];
struct dma_buf_map map_data[DRM_FORMAT_MAX_PLANES];
void *vaddr, *buf; void *vaddr, *buf;
size_t pitch, len; size_t pitch, len;
int ret = 0; int ret = 0;
...@@ -162,11 +163,11 @@ static int gud_prep_flush(struct gud_device *gdrm, struct drm_framebuffer *fb, ...@@ -162,11 +163,11 @@ static int gud_prep_flush(struct gud_device *gdrm, struct drm_framebuffer *fb,
if (len > gdrm->bulk_len) if (len > gdrm->bulk_len)
return -E2BIG; return -E2BIG;
ret = drm_gem_fb_vmap(fb, map); ret = drm_gem_fb_vmap(fb, map, map_data);
if (ret) if (ret)
return ret; return ret;
vaddr = map[0].vaddr + fb->offsets[0]; vaddr = map_data[0].vaddr;
ret = drm_gem_fb_begin_cpu_access(fb, DMA_FROM_DEVICE); ret = drm_gem_fb_begin_cpu_access(fb, DMA_FROM_DEVICE);
if (ret) if (ret)
......
...@@ -105,7 +105,7 @@ static void hyperv_pipe_enable(struct drm_simple_display_pipe *pipe, ...@@ -105,7 +105,7 @@ static void hyperv_pipe_enable(struct drm_simple_display_pipe *pipe,
crtc_state->mode.hdisplay, crtc_state->mode.hdisplay,
crtc_state->mode.vdisplay, crtc_state->mode.vdisplay,
plane_state->fb->pitches[0]); plane_state->fb->pitches[0]);
hyperv_blit_to_vram_fullscreen(plane_state->fb, &shadow_plane_state->map[0]); hyperv_blit_to_vram_fullscreen(plane_state->fb, &shadow_plane_state->data[0]);
} }
static int hyperv_pipe_check(struct drm_simple_display_pipe *pipe, static int hyperv_pipe_check(struct drm_simple_display_pipe *pipe,
...@@ -133,7 +133,7 @@ static void hyperv_pipe_update(struct drm_simple_display_pipe *pipe, ...@@ -133,7 +133,7 @@ static void hyperv_pipe_update(struct drm_simple_display_pipe *pipe,
struct drm_rect rect; struct drm_rect rect;
if (drm_atomic_helper_damage_merged(old_state, state, &rect)) { if (drm_atomic_helper_damage_merged(old_state, state, &rect)) {
hyperv_blit_to_vram_rect(state->fb, &shadow_plane_state->map[0], &rect); hyperv_blit_to_vram_rect(state->fb, &shadow_plane_state->data[0], &rect);
hyperv_update_dirt(hv->hdev, &rect); hyperv_update_dirt(hv->hdev, &rect);
} }
} }
......
...@@ -38,7 +38,6 @@ ...@@ -38,7 +38,6 @@
#include <drm/drm_drv.h> #include <drm/drm_drv.h>
#include <drm/drm_file.h> #include <drm/drm_file.h>
#include <drm/drm_ioctl.h> #include <drm/drm_ioctl.h>
#include <drm/drm_irq.h>
#include <drm/drm_print.h> #include <drm/drm_print.h>
#include <drm/i810_drm.h> #include <drm/i810_drm.h>
...@@ -209,7 +208,7 @@ static int i810_dma_cleanup(struct drm_device *dev) ...@@ -209,7 +208,7 @@ static int i810_dma_cleanup(struct drm_device *dev)
* is freed, it's too late. * is freed, it's too late.
*/ */
if (drm_core_check_feature(dev, DRIVER_HAVE_IRQ) && dev->irq_enabled) if (drm_core_check_feature(dev, DRIVER_HAVE_IRQ) && dev->irq_enabled)
drm_irq_uninstall(dev); drm_legacy_irq_uninstall(dev);
if (dev->dev_private) { if (dev->dev_private) {
int i; int i;
......
...@@ -701,29 +701,6 @@ static int ingenic_drm_encoder_atomic_check(struct drm_encoder *encoder, ...@@ -701,29 +701,6 @@ static int ingenic_drm_encoder_atomic_check(struct drm_encoder *encoder,
} }
} }
static void ingenic_drm_atomic_helper_commit_tail(struct drm_atomic_state *old_state)
{
/*
* Just your regular drm_atomic_helper_commit_tail(), but only calls
* drm_atomic_helper_wait_for_vblanks() if priv->no_vblank.
*/
struct drm_device *dev = old_state->dev;
struct ingenic_drm *priv = drm_device_get_priv(dev);
drm_atomic_helper_commit_modeset_disables(dev, old_state);
drm_atomic_helper_commit_planes(dev, old_state, 0);
drm_atomic_helper_commit_modeset_enables(dev, old_state);
drm_atomic_helper_commit_hw_done(old_state);
if (!priv->no_vblank)
drm_atomic_helper_wait_for_vblanks(dev, old_state);
drm_atomic_helper_cleanup_planes(dev, old_state);
}
static irqreturn_t ingenic_drm_irq_handler(int irq, void *arg) static irqreturn_t ingenic_drm_irq_handler(int irq, void *arg)
{ {
struct ingenic_drm *priv = drm_device_get_priv(arg); struct ingenic_drm *priv = drm_device_get_priv(arg);
...@@ -744,6 +721,9 @@ static int ingenic_drm_enable_vblank(struct drm_crtc *crtc) ...@@ -744,6 +721,9 @@ static int ingenic_drm_enable_vblank(struct drm_crtc *crtc)
{ {
struct ingenic_drm *priv = drm_crtc_get_priv(crtc); struct ingenic_drm *priv = drm_crtc_get_priv(crtc);
if (priv->no_vblank)
return -EINVAL;
regmap_update_bits(priv->map, JZ_REG_LCD_CTRL, regmap_update_bits(priv->map, JZ_REG_LCD_CTRL,
JZ_LCD_CTRL_EOF_IRQ, JZ_LCD_CTRL_EOF_IRQ); JZ_LCD_CTRL_EOF_IRQ, JZ_LCD_CTRL_EOF_IRQ);
...@@ -851,7 +831,7 @@ static const struct drm_mode_config_funcs ingenic_drm_mode_config_funcs = { ...@@ -851,7 +831,7 @@ static const struct drm_mode_config_funcs ingenic_drm_mode_config_funcs = {
}; };
static struct drm_mode_config_helper_funcs ingenic_drm_mode_config_helpers = { static struct drm_mode_config_helper_funcs ingenic_drm_mode_config_helpers = {
.atomic_commit_tail = ingenic_drm_atomic_helper_commit_tail, .atomic_commit_tail = drm_atomic_helper_commit_tail,
}; };
static void ingenic_drm_unbind_all(void *d) static void ingenic_drm_unbind_all(void *d)
...@@ -984,9 +964,6 @@ static int ingenic_drm_bind(struct device *dev, bool has_components) ...@@ -984,9 +964,6 @@ static int ingenic_drm_bind(struct device *dev, bool has_components)
priv->dma_hwdescs->hwdesc_pal.cmd = JZ_LCD_CMD_ENABLE_PAL priv->dma_hwdescs->hwdesc_pal.cmd = JZ_LCD_CMD_ENABLE_PAL
| (sizeof(priv->dma_hwdescs->palette) / 4); | (sizeof(priv->dma_hwdescs->palette) / 4);
if (soc_info->has_osd)
priv->ipu_plane = drm_plane_from_index(drm, 0);
primary = priv->soc_info->has_osd ? &priv->f1 : &priv->f0; primary = priv->soc_info->has_osd ? &priv->f1 : &priv->f0;
drm_plane_helper_add(primary, &ingenic_drm_plane_helper_funcs); drm_plane_helper_add(primary, &ingenic_drm_plane_helper_funcs);
......
...@@ -17,7 +17,6 @@ ...@@ -17,7 +17,6 @@
#include <drm/drm_drv.h> #include <drm/drm_drv.h>
#include <drm/drm_gem_cma_helper.h> #include <drm/drm_gem_cma_helper.h>
#include <drm/drm_gem_framebuffer_helper.h> #include <drm/drm_gem_framebuffer_helper.h>
#include <drm/drm_irq.h>
#include <drm/drm_probe_helper.h> #include <drm/drm_probe_helper.h>
#include <drm/drm_vblank.h> #include <drm/drm_vblank.h>
...@@ -399,14 +398,29 @@ static void kmb_irq_reset(struct drm_device *drm) ...@@ -399,14 +398,29 @@ static void kmb_irq_reset(struct drm_device *drm)
kmb_write_lcd(to_kmb(drm), LCD_INT_ENABLE, 0); kmb_write_lcd(to_kmb(drm), LCD_INT_ENABLE, 0);
} }
static int kmb_irq_install(struct drm_device *drm, unsigned int irq)
{
if (irq == IRQ_NOTCONNECTED)
return -ENOTCONN;
kmb_irq_reset(drm);
return request_irq(irq, kmb_isr, 0, drm->driver->name, drm);
}
static void kmb_irq_uninstall(struct drm_device *drm)
{
struct kmb_drm_private *kmb = to_kmb(drm);
kmb_irq_reset(drm);
free_irq(kmb->irq_lcd, drm);
}
DEFINE_DRM_GEM_CMA_FOPS(fops); DEFINE_DRM_GEM_CMA_FOPS(fops);
static const struct drm_driver kmb_driver = { static const struct drm_driver kmb_driver = {
.driver_features = DRIVER_GEM | .driver_features = DRIVER_GEM |
DRIVER_MODESET | DRIVER_ATOMIC, DRIVER_MODESET | DRIVER_ATOMIC,
.irq_handler = kmb_isr,
.irq_preinstall = kmb_irq_reset,
.irq_uninstall = kmb_irq_reset,
/* GEM Operations */ /* GEM Operations */
.fops = &fops, .fops = &fops,
DRM_GEM_CMA_DRIVER_OPS_VMAP, DRM_GEM_CMA_DRIVER_OPS_VMAP,
...@@ -428,7 +442,7 @@ static int kmb_remove(struct platform_device *pdev) ...@@ -428,7 +442,7 @@ static int kmb_remove(struct platform_device *pdev)
of_node_put(kmb->crtc.port); of_node_put(kmb->crtc.port);
kmb->crtc.port = NULL; kmb->crtc.port = NULL;
pm_runtime_get_sync(drm->dev); pm_runtime_get_sync(drm->dev);
drm_irq_uninstall(drm); kmb_irq_uninstall(drm);
pm_runtime_put_sync(drm->dev); pm_runtime_put_sync(drm->dev);
pm_runtime_disable(drm->dev); pm_runtime_disable(drm->dev);
...@@ -518,7 +532,7 @@ static int kmb_probe(struct platform_device *pdev) ...@@ -518,7 +532,7 @@ static int kmb_probe(struct platform_device *pdev)
if (ret) if (ret)
goto err_free; goto err_free;
ret = drm_irq_install(&kmb->drm, kmb->irq_lcd); ret = kmb_irq_install(&kmb->drm, kmb->irq_lcd);
if (ret < 0) { if (ret < 0) {
drm_err(&kmb->drm, "failed to install IRQ handler\n"); drm_err(&kmb->drm, "failed to install IRQ handler\n");
goto err_irq; goto err_irq;
......
...@@ -949,7 +949,7 @@ static int mga_do_cleanup_dma(struct drm_device *dev, int full_cleanup) ...@@ -949,7 +949,7 @@ static int mga_do_cleanup_dma(struct drm_device *dev, int full_cleanup)
* is freed, it's too late. * is freed, it's too late.
*/ */
if (dev->irq_enabled) if (dev->irq_enabled)
drm_irq_uninstall(dev); drm_legacy_irq_uninstall(dev);
if (dev->dev_private) { if (dev->dev_private) {
drm_mga_private_t *dev_priv = dev->dev_private; drm_mga_private_t *dev_priv = dev->dev_private;
......
...@@ -38,7 +38,6 @@ ...@@ -38,7 +38,6 @@
#include <drm/drm_device.h> #include <drm/drm_device.h>
#include <drm/drm_file.h> #include <drm/drm_file.h>
#include <drm/drm_ioctl.h> #include <drm/drm_ioctl.h>
#include <drm/drm_irq.h>
#include <drm/drm_legacy.h> #include <drm/drm_legacy.h>
#include <drm/drm_print.h> #include <drm/drm_print.h>
#include <drm/drm_sarea.h> #include <drm/drm_sarea.h>
......
# SPDX-License-Identifier: GPL-2.0-only # SPDX-License-Identifier: GPL-2.0-only
mgag200-y := mgag200_drv.o mgag200_i2c.o mgag200_mm.o mgag200_mode.o mgag200-y := mgag200_drv.o mgag200_i2c.o mgag200_mm.o mgag200_mode.o mgag200_pll.o
obj-$(CONFIG_DRM_MGAG200) += mgag200.o obj-$(CONFIG_DRM_MGAG200) += mgag200.o
...@@ -43,6 +43,22 @@ ...@@ -43,6 +43,22 @@
#define ATTR_INDEX 0x1fc0 #define ATTR_INDEX 0x1fc0
#define ATTR_DATA 0x1fc1 #define ATTR_DATA 0x1fc1
#define WREG_MISC(v) \
WREG8(MGA_MISC_OUT, v)
#define RREG_MISC(v) \
((v) = RREG8(MGA_MISC_IN))
#define WREG_MISC_MASKED(v, mask) \
do { \
u8 misc_; \
u8 mask_ = (mask); \
RREG_MISC(misc_); \
misc_ &= ~mask_; \
misc_ |= ((v) & mask_); \
WREG_MISC(misc_); \
} while (0)
#define WREG_ATTR(reg, v) \ #define WREG_ATTR(reg, v) \
do { \ do { \
RREG8(0x1fda); \ RREG8(0x1fda); \
...@@ -110,6 +126,48 @@ ...@@ -110,6 +126,48 @@
#define MGAG200_MAX_FB_HEIGHT 4096 #define MGAG200_MAX_FB_HEIGHT 4096
#define MGAG200_MAX_FB_WIDTH 4096 #define MGAG200_MAX_FB_WIDTH 4096
struct mga_device;
struct mgag200_pll;
/*
* Stores parameters for programming the PLLs
*
* Fref: reference frequency (A: 25.175 Mhz, B: 28.361, C: XX Mhz)
* Fo: output frequency
* Fvco = Fref * (N / M)
* Fo = Fvco / P
*
* S = [0..3]
*/
struct mgag200_pll_values {
unsigned int m;
unsigned int n;
unsigned int p;
unsigned int s;
};
struct mgag200_pll_funcs {
int (*compute)(struct mgag200_pll *pll, long clock, struct mgag200_pll_values *pllc);
void (*update)(struct mgag200_pll *pll, const struct mgag200_pll_values *pllc);
};
struct mgag200_pll {
struct mga_device *mdev;
const struct mgag200_pll_funcs *funcs;
};
struct mgag200_crtc_state {
struct drm_crtc_state base;
struct mgag200_pll_values pixpllc;
};
static inline struct mgag200_crtc_state *to_mgag200_crtc_state(struct drm_crtc_state *base)
{
return container_of(base, struct mgag200_crtc_state, base);
}
#define to_mga_connector(x) container_of(x, struct mga_connector, base) #define to_mga_connector(x) container_of(x, struct mga_connector, base)
struct mga_i2c_chan { struct mga_i2c_chan {
...@@ -180,8 +238,8 @@ struct mga_device { ...@@ -180,8 +238,8 @@ struct mga_device {
} g200se; } g200se;
} model; } model;
struct mga_connector connector; struct mga_connector connector;
struct mgag200_pll pixpll;
struct drm_simple_display_pipe display_pipe; struct drm_simple_display_pipe display_pipe;
}; };
...@@ -200,4 +258,7 @@ void mgag200_i2c_destroy(struct mga_i2c_chan *i2c); ...@@ -200,4 +258,7 @@ void mgag200_i2c_destroy(struct mga_i2c_chan *i2c);
/* mgag200_mm.c */ /* mgag200_mm.c */
int mgag200_mm_init(struct mga_device *mdev); int mgag200_mm_init(struct mga_device *mdev);
/* mgag200_pll.c */
int mgag200_pixpll_init(struct mgag200_pll *pixpll, struct mga_device *mdev);
#endif /* __MGAG200_DRV_H__ */ #endif /* __MGAG200_DRV_H__ */
此差异已折叠。
...@@ -222,11 +222,10 @@ ...@@ -222,11 +222,10 @@
#define MGAREG_MISC_IOADSEL (0x1 << 0) #define MGAREG_MISC_IOADSEL (0x1 << 0)
#define MGAREG_MISC_RAMMAPEN (0x1 << 1) #define MGAREG_MISC_RAMMAPEN (0x1 << 1)
#define MGAREG_MISC_CLK_SEL_MASK GENMASK(3, 2) #define MGAREG_MISC_CLKSEL_MASK GENMASK(3, 2)
#define MGAREG_MISC_CLK_SEL_VGA25 (0x0 << 2) #define MGAREG_MISC_CLKSEL_VGA25 (0x0 << 2)
#define MGAREG_MISC_CLK_SEL_VGA28 (0x1 << 2) #define MGAREG_MISC_CLKSEL_VGA28 (0x1 << 2)
#define MGAREG_MISC_CLK_SEL_MGA_PIX (0x2 << 2) #define MGAREG_MISC_CLKSEL_MGA (0x3 << 2)
#define MGAREG_MISC_CLK_SEL_MGA_MSK (0x3 << 2)
#define MGAREG_MISC_VIDEO_DIS (0x1 << 4) #define MGAREG_MISC_VIDEO_DIS (0x1 << 4)
#define MGAREG_MISC_HIGH_PG_SEL (0x1 << 5) #define MGAREG_MISC_HIGH_PG_SEL (0x1 << 5)
#define MGAREG_MISC_HSYNCPOL BIT(6) #define MGAREG_MISC_HSYNCPOL BIT(6)
......
...@@ -14,7 +14,6 @@ ...@@ -14,7 +14,6 @@
#include <drm/drm_drv.h> #include <drm/drm_drv.h>
#include <drm/drm_file.h> #include <drm/drm_file.h>
#include <drm/drm_ioctl.h> #include <drm/drm_ioctl.h>
#include <drm/drm_irq.h>
#include <drm/drm_prime.h> #include <drm/drm_prime.h>
#include <drm/drm_of.h> #include <drm/drm_of.h>
#include <drm/drm_vblank.h> #include <drm/drm_vblank.h>
...@@ -201,6 +200,71 @@ void msm_rmw(void __iomem *addr, u32 mask, u32 or) ...@@ -201,6 +200,71 @@ void msm_rmw(void __iomem *addr, u32 mask, u32 or)
msm_writel(val | or, addr); msm_writel(val | or, addr);
} }
static irqreturn_t msm_irq(int irq, void *arg)
{
struct drm_device *dev = arg;
struct msm_drm_private *priv = dev->dev_private;
struct msm_kms *kms = priv->kms;
BUG_ON(!kms);
return kms->funcs->irq(kms);
}
static void msm_irq_preinstall(struct drm_device *dev)
{
struct msm_drm_private *priv = dev->dev_private;
struct msm_kms *kms = priv->kms;
BUG_ON(!kms);
kms->funcs->irq_preinstall(kms);
}
static int msm_irq_postinstall(struct drm_device *dev)
{
struct msm_drm_private *priv = dev->dev_private;
struct msm_kms *kms = priv->kms;
BUG_ON(!kms);
if (kms->funcs->irq_postinstall)
return kms->funcs->irq_postinstall(kms);
return 0;
}
static int msm_irq_install(struct drm_device *dev, unsigned int irq)
{
int ret;
if (irq == IRQ_NOTCONNECTED)
return -ENOTCONN;
msm_irq_preinstall(dev);
ret = request_irq(irq, msm_irq, 0, dev->driver->name, dev);
if (ret)
return ret;
ret = msm_irq_postinstall(dev);
if (ret) {
free_irq(irq, dev);
return ret;
}
return 0;
}
static void msm_irq_uninstall(struct drm_device *dev)
{
struct msm_drm_private *priv = dev->dev_private;
struct msm_kms *kms = priv->kms;
kms->funcs->irq_uninstall(kms);
free_irq(kms->irq, dev);
}
struct msm_vblank_work { struct msm_vblank_work {
struct work_struct work; struct work_struct work;
int crtc_id; int crtc_id;
...@@ -265,7 +329,7 @@ static int msm_drm_uninit(struct device *dev) ...@@ -265,7 +329,7 @@ static int msm_drm_uninit(struct device *dev)
} }
/* We must cancel and cleanup any pending vblank enable/disable /* We must cancel and cleanup any pending vblank enable/disable
* work before drm_irq_uninstall() to avoid work re-enabling an * work before msm_irq_uninstall() to avoid work re-enabling an
* irq after uninstall has disabled it. * irq after uninstall has disabled it.
*/ */
...@@ -294,7 +358,7 @@ static int msm_drm_uninit(struct device *dev) ...@@ -294,7 +358,7 @@ static int msm_drm_uninit(struct device *dev)
drm_mode_config_cleanup(ddev); drm_mode_config_cleanup(ddev);
pm_runtime_get_sync(dev); pm_runtime_get_sync(dev);
drm_irq_uninstall(ddev); msm_irq_uninstall(ddev);
pm_runtime_put_sync(dev); pm_runtime_put_sync(dev);
if (kms && kms->funcs) if (kms && kms->funcs)
...@@ -553,7 +617,7 @@ static int msm_drm_init(struct device *dev, const struct drm_driver *drv) ...@@ -553,7 +617,7 @@ static int msm_drm_init(struct device *dev, const struct drm_driver *drv)
if (kms) { if (kms) {
pm_runtime_get_sync(dev); pm_runtime_get_sync(dev);
ret = drm_irq_install(ddev, kms->irq); ret = msm_irq_install(ddev, kms->irq);
pm_runtime_put_sync(dev); pm_runtime_put_sync(dev);
if (ret < 0) { if (ret < 0) {
DRM_DEV_ERROR(dev, "failed to install IRQ handler\n"); DRM_DEV_ERROR(dev, "failed to install IRQ handler\n");
...@@ -662,43 +726,6 @@ static void msm_postclose(struct drm_device *dev, struct drm_file *file) ...@@ -662,43 +726,6 @@ static void msm_postclose(struct drm_device *dev, struct drm_file *file)
context_close(ctx); context_close(ctx);
} }
static irqreturn_t msm_irq(int irq, void *arg)
{
struct drm_device *dev = arg;
struct msm_drm_private *priv = dev->dev_private;
struct msm_kms *kms = priv->kms;
BUG_ON(!kms);
return kms->funcs->irq(kms);
}
static void msm_irq_preinstall(struct drm_device *dev)
{
struct msm_drm_private *priv = dev->dev_private;
struct msm_kms *kms = priv->kms;
BUG_ON(!kms);
kms->funcs->irq_preinstall(kms);
}
static int msm_irq_postinstall(struct drm_device *dev)
{
struct msm_drm_private *priv = dev->dev_private;
struct msm_kms *kms = priv->kms;
BUG_ON(!kms);
if (kms->funcs->irq_postinstall)
return kms->funcs->irq_postinstall(kms);
return 0;
}
static void msm_irq_uninstall(struct drm_device *dev)
{
struct msm_drm_private *priv = dev->dev_private;
struct msm_kms *kms = priv->kms;
BUG_ON(!kms);
kms->funcs->irq_uninstall(kms);
}
int msm_crtc_enable_vblank(struct drm_crtc *crtc) int msm_crtc_enable_vblank(struct drm_crtc *crtc)
{ {
struct drm_device *dev = crtc->dev; struct drm_device *dev = crtc->dev;
...@@ -1051,10 +1078,6 @@ static const struct drm_driver msm_driver = { ...@@ -1051,10 +1078,6 @@ static const struct drm_driver msm_driver = {
.open = msm_open, .open = msm_open,
.postclose = msm_postclose, .postclose = msm_postclose,
.lastclose = drm_fb_helper_lastclose, .lastclose = drm_fb_helper_lastclose,
.irq_handler = msm_irq,
.irq_preinstall = msm_irq_preinstall,
.irq_postinstall = msm_irq_postinstall,
.irq_uninstall = msm_irq_uninstall,
.dumb_create = msm_gem_dumb_create, .dumb_create = msm_gem_dumb_create,
.dumb_map_offset = msm_gem_dumb_map_offset, .dumb_map_offset = msm_gem_dumb_map_offset,
.prime_handle_to_fd = drm_gem_prime_handle_to_fd, .prime_handle_to_fd = drm_gem_prime_handle_to_fd,
......
...@@ -150,7 +150,7 @@ struct msm_kms { ...@@ -150,7 +150,7 @@ struct msm_kms {
const struct msm_kms_funcs *funcs; const struct msm_kms_funcs *funcs;
struct drm_device *dev; struct drm_device *dev;
/* irq number to be passed on to drm_irq_install */ /* irq number to be passed on to msm_irq_install */
int irq; int irq;
/* mapper-id used to request GEM buffer mapped for scanout: */ /* mapper-id used to request GEM buffer mapped for scanout: */
......
...@@ -24,7 +24,6 @@ ...@@ -24,7 +24,6 @@
#include <drm/drm_fourcc.h> #include <drm/drm_fourcc.h>
#include <drm/drm_gem_cma_helper.h> #include <drm/drm_gem_cma_helper.h>
#include <drm/drm_gem_framebuffer_helper.h> #include <drm/drm_gem_framebuffer_helper.h>
#include <drm/drm_irq.h>
#include <drm/drm_mode_config.h> #include <drm/drm_mode_config.h>
#include <drm/drm_of.h> #include <drm/drm_of.h>
#include <drm/drm_probe_helper.h> #include <drm/drm_probe_helper.h>
...@@ -153,6 +152,49 @@ static int mxsfb_attach_bridge(struct mxsfb_drm_private *mxsfb) ...@@ -153,6 +152,49 @@ static int mxsfb_attach_bridge(struct mxsfb_drm_private *mxsfb)
return 0; return 0;
} }
static irqreturn_t mxsfb_irq_handler(int irq, void *data)
{
struct drm_device *drm = data;
struct mxsfb_drm_private *mxsfb = drm->dev_private;
u32 reg;
reg = readl(mxsfb->base + LCDC_CTRL1);
if (reg & CTRL1_CUR_FRAME_DONE_IRQ)
drm_crtc_handle_vblank(&mxsfb->crtc);
writel(CTRL1_CUR_FRAME_DONE_IRQ, mxsfb->base + LCDC_CTRL1 + REG_CLR);
return IRQ_HANDLED;
}
static void mxsfb_irq_disable(struct drm_device *drm)
{
struct mxsfb_drm_private *mxsfb = drm->dev_private;
mxsfb_enable_axi_clk(mxsfb);
mxsfb->crtc.funcs->disable_vblank(&mxsfb->crtc);
mxsfb_disable_axi_clk(mxsfb);
}
static int mxsfb_irq_install(struct drm_device *dev, int irq)
{
if (irq == IRQ_NOTCONNECTED)
return -ENOTCONN;
mxsfb_irq_disable(dev);
return request_irq(irq, mxsfb_irq_handler, 0, dev->driver->name, dev);
}
static void mxsfb_irq_uninstall(struct drm_device *dev)
{
struct mxsfb_drm_private *mxsfb = dev->dev_private;
mxsfb_irq_disable(dev);
free_irq(mxsfb->irq, dev);
}
static int mxsfb_load(struct drm_device *drm, static int mxsfb_load(struct drm_device *drm,
const struct mxsfb_devdata *devdata) const struct mxsfb_devdata *devdata)
{ {
...@@ -226,8 +268,13 @@ static int mxsfb_load(struct drm_device *drm, ...@@ -226,8 +268,13 @@ static int mxsfb_load(struct drm_device *drm,
drm_mode_config_reset(drm); drm_mode_config_reset(drm);
ret = platform_get_irq(pdev, 0);
if (ret < 0)
goto err_vblank;
mxsfb->irq = ret;
pm_runtime_get_sync(drm->dev); pm_runtime_get_sync(drm->dev);
ret = drm_irq_install(drm, platform_get_irq(pdev, 0)); ret = mxsfb_irq_install(drm, mxsfb->irq);
pm_runtime_put_sync(drm->dev); pm_runtime_put_sync(drm->dev);
if (ret < 0) { if (ret < 0) {
...@@ -255,7 +302,7 @@ static void mxsfb_unload(struct drm_device *drm) ...@@ -255,7 +302,7 @@ static void mxsfb_unload(struct drm_device *drm)
drm_mode_config_cleanup(drm); drm_mode_config_cleanup(drm);
pm_runtime_get_sync(drm->dev); pm_runtime_get_sync(drm->dev);
drm_irq_uninstall(drm); mxsfb_irq_uninstall(drm);
pm_runtime_put_sync(drm->dev); pm_runtime_put_sync(drm->dev);
drm->dev_private = NULL; drm->dev_private = NULL;
...@@ -263,38 +310,10 @@ static void mxsfb_unload(struct drm_device *drm) ...@@ -263,38 +310,10 @@ static void mxsfb_unload(struct drm_device *drm)
pm_runtime_disable(drm->dev); pm_runtime_disable(drm->dev);
} }
static void mxsfb_irq_disable(struct drm_device *drm)
{
struct mxsfb_drm_private *mxsfb = drm->dev_private;
mxsfb_enable_axi_clk(mxsfb);
mxsfb->crtc.funcs->disable_vblank(&mxsfb->crtc);
mxsfb_disable_axi_clk(mxsfb);
}
static irqreturn_t mxsfb_irq_handler(int irq, void *data)
{
struct drm_device *drm = data;
struct mxsfb_drm_private *mxsfb = drm->dev_private;
u32 reg;
reg = readl(mxsfb->base + LCDC_CTRL1);
if (reg & CTRL1_CUR_FRAME_DONE_IRQ)
drm_crtc_handle_vblank(&mxsfb->crtc);
writel(CTRL1_CUR_FRAME_DONE_IRQ, mxsfb->base + LCDC_CTRL1 + REG_CLR);
return IRQ_HANDLED;
}
DEFINE_DRM_GEM_CMA_FOPS(fops); DEFINE_DRM_GEM_CMA_FOPS(fops);
static const struct drm_driver mxsfb_driver = { static const struct drm_driver mxsfb_driver = {
.driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC, .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
.irq_handler = mxsfb_irq_handler,
.irq_preinstall = mxsfb_irq_disable,
.irq_uninstall = mxsfb_irq_disable,
DRM_GEM_CMA_DRIVER_OPS, DRM_GEM_CMA_DRIVER_OPS,
.fops = &fops, .fops = &fops,
.name = "mxsfb-drm", .name = "mxsfb-drm",
......
...@@ -33,6 +33,8 @@ struct mxsfb_drm_private { ...@@ -33,6 +33,8 @@ struct mxsfb_drm_private {
struct clk *clk_axi; struct clk *clk_axi;
struct clk *clk_disp_axi; struct clk *clk_disp_axi;
unsigned int irq;
struct drm_device *drm; struct drm_device *drm;
struct { struct {
struct drm_plane primary; struct drm_plane primary;
......
...@@ -1659,23 +1659,27 @@ static void ...@@ -1659,23 +1659,27 @@ static void
nv50_sor_atomic_disable(struct drm_encoder *encoder, struct drm_atomic_state *state) nv50_sor_atomic_disable(struct drm_encoder *encoder, struct drm_atomic_state *state)
{ {
struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
struct nouveau_drm *drm = nouveau_drm(nv_encoder->base.base.dev);
struct nouveau_crtc *nv_crtc = nouveau_crtc(nv_encoder->crtc); struct nouveau_crtc *nv_crtc = nouveau_crtc(nv_encoder->crtc);
struct nouveau_connector *nv_connector = nv50_outp_get_old_connector(state, nv_encoder); struct nouveau_connector *nv_connector = nv50_outp_get_old_connector(state, nv_encoder);
#ifdef CONFIG_DRM_NOUVEAU_BACKLIGHT
struct nouveau_drm *drm = nouveau_drm(nv_encoder->base.base.dev);
struct nouveau_backlight *backlight = nv_connector->backlight; struct nouveau_backlight *backlight = nv_connector->backlight;
#endif
struct drm_dp_aux *aux = &nv_connector->aux; struct drm_dp_aux *aux = &nv_connector->aux;
int ret; int ret;
u8 pwr; u8 pwr;
#ifdef CONFIG_DRM_NOUVEAU_BACKLIGHT
if (backlight && backlight->uses_dpcd) { if (backlight && backlight->uses_dpcd) {
ret = drm_edp_backlight_disable(aux, &backlight->edp_info); ret = drm_edp_backlight_disable(aux, &backlight->edp_info);
if (ret < 0) if (ret < 0)
NV_ERROR(drm, "Failed to disable backlight on [CONNECTOR:%d:%s]: %d\n", NV_ERROR(drm, "Failed to disable backlight on [CONNECTOR:%d:%s]: %d\n",
nv_connector->base.base.id, nv_connector->base.name, ret); nv_connector->base.base.id, nv_connector->base.name, ret);
} }
#endif
if (nv_encoder->dcb->type == DCB_OUTPUT_DP) { if (nv_encoder->dcb->type == DCB_OUTPUT_DP) {
int ret = drm_dp_dpcd_readb(aux, DP_SET_POWER, &pwr); ret = drm_dp_dpcd_readb(aux, DP_SET_POWER, &pwr);
if (ret == 0) { if (ret == 0) {
pwr &= ~DP_SET_POWER_MASK; pwr &= ~DP_SET_POWER_MASK;
......
...@@ -3126,6 +3126,38 @@ static const struct panel_desc logictechno_lt170410_2whc = { ...@@ -3126,6 +3126,38 @@ static const struct panel_desc logictechno_lt170410_2whc = {
.connector_type = DRM_MODE_CONNECTOR_LVDS, .connector_type = DRM_MODE_CONNECTOR_LVDS,
}; };
static const struct drm_display_mode logictechno_lttd800480070_l6wh_rt_mode = {
.clock = 33000,
.hdisplay = 800,
.hsync_start = 800 + 154,
.hsync_end = 800 + 154 + 3,
.htotal = 800 + 154 + 3 + 43,
.vdisplay = 480,
.vsync_start = 480 + 47,
.vsync_end = 480 + 47 + 3,
.vtotal = 480 + 47 + 3 + 20,
.flags = DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_NHSYNC,
};
static const struct panel_desc logictechno_lttd800480070_l6wh_rt = {
.modes = &logictechno_lttd800480070_l6wh_rt_mode,
.num_modes = 1,
.bpc = 8,
.size = {
.width = 154,
.height = 86,
},
.delay = {
.prepare = 45,
.enable = 100,
.disable = 100,
.unprepare = 45
},
.bus_format = MEDIA_BUS_FMT_RGB888_1X24,
.bus_flags = DRM_BUS_FLAG_PIXDATA_SAMPLE_NEGEDGE,
.connector_type = DRM_MODE_CONNECTOR_DPI,
};
static const struct drm_display_mode mitsubishi_aa070mc01_mode = { static const struct drm_display_mode mitsubishi_aa070mc01_mode = {
.clock = 30400, .clock = 30400,
.hdisplay = 800, .hdisplay = 800,
...@@ -3192,6 +3224,37 @@ static const struct panel_desc mitsubishi_aa070mc01 = { ...@@ -3192,6 +3224,37 @@ static const struct panel_desc mitsubishi_aa070mc01 = {
.bus_flags = DRM_BUS_FLAG_DE_HIGH, .bus_flags = DRM_BUS_FLAG_DE_HIGH,
}; };
static const struct display_timing multi_inno_mi1010ait_1cp_timing = {
.pixelclock = { 68900000, 70000000, 73400000 },
.hactive = { 1280, 1280, 1280 },
.hfront_porch = { 30, 60, 71 },
.hback_porch = { 30, 60, 71 },
.hsync_len = { 10, 10, 48 },
.vactive = { 800, 800, 800 },
.vfront_porch = { 5, 10, 10 },
.vback_porch = { 5, 10, 10 },
.vsync_len = { 5, 6, 13 },
.flags = DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_LOW |
DISPLAY_FLAGS_DE_HIGH,
};
static const struct panel_desc multi_inno_mi1010ait_1cp = {
.timings = &multi_inno_mi1010ait_1cp_timing,
.num_timings = 1,
.bpc = 8,
.size = {
.width = 217,
.height = 136,
},
.delay = {
.enable = 50,
.disable = 50,
},
.bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
.bus_flags = DRM_BUS_FLAG_DE_HIGH,
.connector_type = DRM_MODE_CONNECTOR_LVDS,
};
static const struct display_timing nec_nl12880bc20_05_timing = { static const struct display_timing nec_nl12880bc20_05_timing = {
.pixelclock = { 67000000, 71000000, 75000000 }, .pixelclock = { 67000000, 71000000, 75000000 },
.hactive = { 1280, 1280, 1280 }, .hactive = { 1280, 1280, 1280 },
...@@ -4675,9 +4738,15 @@ static const struct of_device_id platform_of_match[] = { ...@@ -4675,9 +4738,15 @@ static const struct of_device_id platform_of_match[] = {
}, { }, {
.compatible = "logictechno,lt170410-2whc", .compatible = "logictechno,lt170410-2whc",
.data = &logictechno_lt170410_2whc, .data = &logictechno_lt170410_2whc,
}, {
.compatible = "logictechno,lttd800480070-l6wh-rt",
.data = &logictechno_lttd800480070_l6wh_rt,
}, { }, {
.compatible = "mitsubishi,aa070mc01-ca1", .compatible = "mitsubishi,aa070mc01-ca1",
.data = &mitsubishi_aa070mc01, .data = &mitsubishi_aa070mc01,
}, {
.compatible = "multi-inno,mi1010ait-1cp",
.data = &multi_inno_mi1010ait_1cp,
}, { }, {
.compatible = "nec,nl12880bc20-05", .compatible = "nec,nl12880bc20-05",
.data = &nec_nl12880bc20_05, .data = &nec_nl12880bc20_05,
......
...@@ -39,7 +39,6 @@ ...@@ -39,7 +39,6 @@
#include <drm/drm_device.h> #include <drm/drm_device.h>
#include <drm/drm_file.h> #include <drm/drm_file.h>
#include <drm/drm_irq.h>
#include <drm/drm_legacy.h> #include <drm/drm_legacy.h>
#include <drm/drm_print.h> #include <drm/drm_print.h>
#include <drm/r128_drm.h> #include <drm/r128_drm.h>
...@@ -603,7 +602,7 @@ int r128_do_cleanup_cce(struct drm_device *dev) ...@@ -603,7 +602,7 @@ int r128_do_cleanup_cce(struct drm_device *dev)
* is freed, it's too late. * is freed, it's too late.
*/ */
if (dev->irq_enabled) if (dev->irq_enabled)
drm_irq_uninstall(dev); drm_legacy_irq_uninstall(dev);
if (dev->dev_private) { if (dev->dev_private) {
drm_r128_private_t *dev_priv = dev->dev_private; drm_r128_private_t *dev_priv = dev->dev_private;
......
...@@ -607,10 +607,6 @@ static const struct drm_driver kms_driver = { ...@@ -607,10 +607,6 @@ static const struct drm_driver kms_driver = {
.postclose = radeon_driver_postclose_kms, .postclose = radeon_driver_postclose_kms,
.lastclose = radeon_driver_lastclose_kms, .lastclose = radeon_driver_lastclose_kms,
.unload = radeon_driver_unload_kms, .unload = radeon_driver_unload_kms,
.irq_preinstall = radeon_driver_irq_preinstall_kms,
.irq_postinstall = radeon_driver_irq_postinstall_kms,
.irq_uninstall = radeon_driver_irq_uninstall_kms,
.irq_handler = radeon_driver_irq_handler_kms,
.ioctls = radeon_ioctls_kms, .ioctls = radeon_ioctls_kms,
.num_ioctls = ARRAY_SIZE(radeon_ioctls_kms), .num_ioctls = ARRAY_SIZE(radeon_ioctls_kms),
.dumb_create = radeon_mode_dumb_create, .dumb_create = radeon_mode_dumb_create,
......
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
#include <drm/drm_crtc_helper.h> #include <drm/drm_crtc_helper.h>
#include <drm/drm_device.h> #include <drm/drm_device.h>
#include <drm/drm_irq.h> #include <drm/drm_drv.h>
#include <drm/drm_probe_helper.h> #include <drm/drm_probe_helper.h>
#include <drm/drm_vblank.h> #include <drm/drm_vblank.h>
#include <drm/radeon_drm.h> #include <drm/radeon_drm.h>
...@@ -51,7 +51,7 @@ ...@@ -51,7 +51,7 @@
* radeon_irq_process is a macro that points to the per-asic * radeon_irq_process is a macro that points to the per-asic
* irq handler callback. * irq handler callback.
*/ */
irqreturn_t radeon_driver_irq_handler_kms(int irq, void *arg) static irqreturn_t radeon_driver_irq_handler_kms(int irq, void *arg)
{ {
struct drm_device *dev = (struct drm_device *) arg; struct drm_device *dev = (struct drm_device *) arg;
struct radeon_device *rdev = dev->dev_private; struct radeon_device *rdev = dev->dev_private;
...@@ -118,7 +118,7 @@ static void radeon_dp_work_func(struct work_struct *work) ...@@ -118,7 +118,7 @@ static void radeon_dp_work_func(struct work_struct *work)
* Gets the hw ready to enable irqs (all asics). * Gets the hw ready to enable irqs (all asics).
* This function disables all interrupt sources on the GPU. * This function disables all interrupt sources on the GPU.
*/ */
void radeon_driver_irq_preinstall_kms(struct drm_device *dev) static void radeon_driver_irq_preinstall_kms(struct drm_device *dev)
{ {
struct radeon_device *rdev = dev->dev_private; struct radeon_device *rdev = dev->dev_private;
unsigned long irqflags; unsigned long irqflags;
...@@ -150,7 +150,7 @@ void radeon_driver_irq_preinstall_kms(struct drm_device *dev) ...@@ -150,7 +150,7 @@ void radeon_driver_irq_preinstall_kms(struct drm_device *dev)
* Handles stuff to be done after enabling irqs (all asics). * Handles stuff to be done after enabling irqs (all asics).
* Returns 0 on success. * Returns 0 on success.
*/ */
int radeon_driver_irq_postinstall_kms(struct drm_device *dev) static int radeon_driver_irq_postinstall_kms(struct drm_device *dev)
{ {
struct radeon_device *rdev = dev->dev_private; struct radeon_device *rdev = dev->dev_private;
...@@ -169,7 +169,7 @@ int radeon_driver_irq_postinstall_kms(struct drm_device *dev) ...@@ -169,7 +169,7 @@ int radeon_driver_irq_postinstall_kms(struct drm_device *dev)
* *
* This function disables all interrupt sources on the GPU (all asics). * This function disables all interrupt sources on the GPU (all asics).
*/ */
void radeon_driver_irq_uninstall_kms(struct drm_device *dev) static void radeon_driver_irq_uninstall_kms(struct drm_device *dev)
{ {
struct radeon_device *rdev = dev->dev_private; struct radeon_device *rdev = dev->dev_private;
unsigned long irqflags; unsigned long irqflags;
...@@ -194,6 +194,36 @@ void radeon_driver_irq_uninstall_kms(struct drm_device *dev) ...@@ -194,6 +194,36 @@ void radeon_driver_irq_uninstall_kms(struct drm_device *dev)
spin_unlock_irqrestore(&rdev->irq.lock, irqflags); spin_unlock_irqrestore(&rdev->irq.lock, irqflags);
} }
static int radeon_irq_install(struct radeon_device *rdev, int irq)
{
struct drm_device *dev = rdev->ddev;
int ret;
if (irq == IRQ_NOTCONNECTED)
return -ENOTCONN;
radeon_driver_irq_preinstall_kms(dev);
/* PCI devices require shared interrupts. */
ret = request_irq(irq, radeon_driver_irq_handler_kms,
IRQF_SHARED, dev->driver->name, dev);
if (ret)
return ret;
radeon_driver_irq_postinstall_kms(dev);
return 0;
}
static void radeon_irq_uninstall(struct radeon_device *rdev)
{
struct drm_device *dev = rdev->ddev;
struct pci_dev *pdev = to_pci_dev(dev->dev);
radeon_driver_irq_uninstall_kms(dev);
free_irq(pdev->irq, dev);
}
/** /**
* radeon_msi_ok - asic specific msi checks * radeon_msi_ok - asic specific msi checks
* *
...@@ -314,7 +344,7 @@ int radeon_irq_kms_init(struct radeon_device *rdev) ...@@ -314,7 +344,7 @@ int radeon_irq_kms_init(struct radeon_device *rdev)
INIT_WORK(&rdev->audio_work, r600_audio_update_hdmi); INIT_WORK(&rdev->audio_work, r600_audio_update_hdmi);
rdev->irq.installed = true; rdev->irq.installed = true;
r = drm_irq_install(rdev->ddev, rdev->pdev->irq); r = radeon_irq_install(rdev, rdev->pdev->irq);
if (r) { if (r) {
rdev->irq.installed = false; rdev->irq.installed = false;
flush_delayed_work(&rdev->hotplug_work); flush_delayed_work(&rdev->hotplug_work);
...@@ -335,7 +365,7 @@ int radeon_irq_kms_init(struct radeon_device *rdev) ...@@ -335,7 +365,7 @@ int radeon_irq_kms_init(struct radeon_device *rdev)
void radeon_irq_kms_fini(struct radeon_device *rdev) void radeon_irq_kms_fini(struct radeon_device *rdev)
{ {
if (rdev->irq.installed) { if (rdev->irq.installed) {
drm_irq_uninstall(rdev->ddev); radeon_irq_uninstall(rdev);
rdev->irq.installed = false; rdev->irq.installed = false;
if (rdev->msi_enabled) if (rdev->msi_enabled)
pci_disable_msi(rdev->pdev); pci_disable_msi(rdev->pdev);
......
...@@ -31,9 +31,5 @@ ...@@ -31,9 +31,5 @@
u32 radeon_get_vblank_counter_kms(struct drm_crtc *crtc); u32 radeon_get_vblank_counter_kms(struct drm_crtc *crtc);
int radeon_enable_vblank_kms(struct drm_crtc *crtc); int radeon_enable_vblank_kms(struct drm_crtc *crtc);
void radeon_disable_vblank_kms(struct drm_crtc *crtc); void radeon_disable_vblank_kms(struct drm_crtc *crtc);
irqreturn_t radeon_driver_irq_handler_kms(int irq, void *arg);
void radeon_driver_irq_preinstall_kms(struct drm_device *dev);
int radeon_driver_irq_postinstall_kms(struct drm_device *dev);
void radeon_driver_irq_uninstall_kms(struct drm_device *dev);
#endif /* __RADEON_KMS_H__ */ #endif /* __RADEON_KMS_H__ */
...@@ -16,7 +16,6 @@ ...@@ -16,7 +16,6 @@
#include <drm/drm_drv.h> #include <drm/drm_drv.h>
#include <drm/drm_fb_helper.h> #include <drm/drm_fb_helper.h>
#include <drm/drm_gem_cma_helper.h> #include <drm/drm_gem_cma_helper.h>
#include <drm/drm_irq.h>
#include <drm/drm_managed.h> #include <drm/drm_managed.h>
#include <drm/drm_probe_helper.h> #include <drm/drm_probe_helper.h>
...@@ -118,11 +117,6 @@ static const struct drm_driver tidss_driver = { ...@@ -118,11 +117,6 @@ static const struct drm_driver tidss_driver = {
.date = "20180215", .date = "20180215",
.major = 1, .major = 1,
.minor = 0, .minor = 0,
.irq_preinstall = tidss_irq_preinstall,
.irq_postinstall = tidss_irq_postinstall,
.irq_handler = tidss_irq_handler,
.irq_uninstall = tidss_irq_uninstall,
}; };
static int tidss_probe(struct platform_device *pdev) static int tidss_probe(struct platform_device *pdev)
...@@ -172,10 +166,11 @@ static int tidss_probe(struct platform_device *pdev) ...@@ -172,10 +166,11 @@ static int tidss_probe(struct platform_device *pdev)
ret = irq; ret = irq;
goto err_runtime_suspend; goto err_runtime_suspend;
} }
tidss->irq = irq;
ret = drm_irq_install(ddev, irq); ret = tidss_irq_install(ddev, irq);
if (ret) { if (ret) {
dev_err(dev, "drm_irq_install failed: %d\n", ret); dev_err(dev, "tidss_irq_install failed: %d\n", ret);
goto err_runtime_suspend; goto err_runtime_suspend;
} }
...@@ -196,7 +191,7 @@ static int tidss_probe(struct platform_device *pdev) ...@@ -196,7 +191,7 @@ static int tidss_probe(struct platform_device *pdev)
return 0; return 0;
err_irq_uninstall: err_irq_uninstall:
drm_irq_uninstall(ddev); tidss_irq_uninstall(ddev);
err_runtime_suspend: err_runtime_suspend:
#ifndef CONFIG_PM #ifndef CONFIG_PM
...@@ -219,7 +214,7 @@ static int tidss_remove(struct platform_device *pdev) ...@@ -219,7 +214,7 @@ static int tidss_remove(struct platform_device *pdev)
drm_atomic_helper_shutdown(ddev); drm_atomic_helper_shutdown(ddev);
drm_irq_uninstall(ddev); tidss_irq_uninstall(ddev);
#ifndef CONFIG_PM #ifndef CONFIG_PM
/* If we don't have PM, we need to call suspend manually */ /* If we don't have PM, we need to call suspend manually */
......
...@@ -27,6 +27,8 @@ struct tidss_device { ...@@ -27,6 +27,8 @@ struct tidss_device {
unsigned int num_planes; unsigned int num_planes;
struct drm_plane *planes[TIDSS_MAX_PLANES]; struct drm_plane *planes[TIDSS_MAX_PLANES];
unsigned int irq;
spinlock_t wait_lock; /* protects the irq masks */ spinlock_t wait_lock; /* protects the irq masks */
dispc_irq_t irq_mask; /* enabled irqs in addition to wait_list */ dispc_irq_t irq_mask; /* enabled irqs in addition to wait_list */
}; };
......
...@@ -4,6 +4,9 @@ ...@@ -4,6 +4,9 @@
* Author: Tomi Valkeinen <tomi.valkeinen@ti.com> * Author: Tomi Valkeinen <tomi.valkeinen@ti.com>
*/ */
#include <linux/platform_device.h>
#include <drm/drm_drv.h>
#include <drm/drm_print.h> #include <drm/drm_print.h>
#include "tidss_crtc.h" #include "tidss_crtc.h"
...@@ -50,7 +53,7 @@ void tidss_irq_disable_vblank(struct drm_crtc *crtc) ...@@ -50,7 +53,7 @@ void tidss_irq_disable_vblank(struct drm_crtc *crtc)
spin_unlock_irqrestore(&tidss->wait_lock, flags); spin_unlock_irqrestore(&tidss->wait_lock, flags);
} }
irqreturn_t tidss_irq_handler(int irq, void *arg) static irqreturn_t tidss_irq_handler(int irq, void *arg)
{ {
struct drm_device *ddev = (struct drm_device *)arg; struct drm_device *ddev = (struct drm_device *)arg;
struct tidss_device *tidss = to_tidss(ddev); struct tidss_device *tidss = to_tidss(ddev);
...@@ -90,7 +93,7 @@ void tidss_irq_resume(struct tidss_device *tidss) ...@@ -90,7 +93,7 @@ void tidss_irq_resume(struct tidss_device *tidss)
spin_unlock_irqrestore(&tidss->wait_lock, flags); spin_unlock_irqrestore(&tidss->wait_lock, flags);
} }
void tidss_irq_preinstall(struct drm_device *ddev) static void tidss_irq_preinstall(struct drm_device *ddev)
{ {
struct tidss_device *tidss = to_tidss(ddev); struct tidss_device *tidss = to_tidss(ddev);
...@@ -104,7 +107,7 @@ void tidss_irq_preinstall(struct drm_device *ddev) ...@@ -104,7 +107,7 @@ void tidss_irq_preinstall(struct drm_device *ddev)
tidss_runtime_put(tidss); tidss_runtime_put(tidss);
} }
int tidss_irq_postinstall(struct drm_device *ddev) static void tidss_irq_postinstall(struct drm_device *ddev)
{ {
struct tidss_device *tidss = to_tidss(ddev); struct tidss_device *tidss = to_tidss(ddev);
unsigned long flags; unsigned long flags;
...@@ -129,6 +132,22 @@ int tidss_irq_postinstall(struct drm_device *ddev) ...@@ -129,6 +132,22 @@ int tidss_irq_postinstall(struct drm_device *ddev)
spin_unlock_irqrestore(&tidss->wait_lock, flags); spin_unlock_irqrestore(&tidss->wait_lock, flags);
tidss_runtime_put(tidss); tidss_runtime_put(tidss);
}
int tidss_irq_install(struct drm_device *ddev, unsigned int irq)
{
int ret;
if (irq == IRQ_NOTCONNECTED)
return -ENOTCONN;
tidss_irq_preinstall(ddev);
ret = request_irq(irq, tidss_irq_handler, 0, ddev->driver->name, ddev);
if (ret)
return ret;
tidss_irq_postinstall(ddev);
return 0; return 0;
} }
...@@ -140,4 +159,6 @@ void tidss_irq_uninstall(struct drm_device *ddev) ...@@ -140,4 +159,6 @@ void tidss_irq_uninstall(struct drm_device *ddev)
tidss_runtime_get(tidss); tidss_runtime_get(tidss);
dispc_set_irqenable(tidss->dispc, 0); dispc_set_irqenable(tidss->dispc, 0);
tidss_runtime_put(tidss); tidss_runtime_put(tidss);
free_irq(tidss->irq, ddev);
} }
...@@ -67,10 +67,8 @@ struct tidss_device; ...@@ -67,10 +67,8 @@ struct tidss_device;
void tidss_irq_enable_vblank(struct drm_crtc *crtc); void tidss_irq_enable_vblank(struct drm_crtc *crtc);
void tidss_irq_disable_vblank(struct drm_crtc *crtc); void tidss_irq_disable_vblank(struct drm_crtc *crtc);
void tidss_irq_preinstall(struct drm_device *ddev); int tidss_irq_install(struct drm_device *ddev, unsigned int irq);
int tidss_irq_postinstall(struct drm_device *ddev);
void tidss_irq_uninstall(struct drm_device *ddev); void tidss_irq_uninstall(struct drm_device *ddev);
irqreturn_t tidss_irq_handler(int irq, void *arg);
void tidss_irq_resume(struct tidss_device *tidss); void tidss_irq_resume(struct tidss_device *tidss);
......
...@@ -20,7 +20,6 @@ ...@@ -20,7 +20,6 @@
#include <drm/drm_fourcc.h> #include <drm/drm_fourcc.h>
#include <drm/drm_gem_cma_helper.h> #include <drm/drm_gem_cma_helper.h>
#include <drm/drm_gem_framebuffer_helper.h> #include <drm/drm_gem_framebuffer_helper.h>
#include <drm/drm_irq.h>
#include <drm/drm_mm.h> #include <drm/drm_mm.h>
#include <drm/drm_probe_helper.h> #include <drm/drm_probe_helper.h>
#include <drm/drm_vblank.h> #include <drm/drm_vblank.h>
...@@ -124,6 +123,39 @@ static int cpufreq_transition(struct notifier_block *nb, ...@@ -124,6 +123,39 @@ static int cpufreq_transition(struct notifier_block *nb,
} }
#endif #endif
static irqreturn_t tilcdc_irq(int irq, void *arg)
{
struct drm_device *dev = arg;
struct tilcdc_drm_private *priv = dev->dev_private;
return tilcdc_crtc_irq(priv->crtc);
}
static int tilcdc_irq_install(struct drm_device *dev, unsigned int irq)
{
struct tilcdc_drm_private *priv = dev->dev_private;
int ret;
ret = request_irq(irq, tilcdc_irq, 0, dev->driver->name, dev);
if (ret)
return ret;
priv->irq_enabled = false;
return 0;
}
static void tilcdc_irq_uninstall(struct drm_device *dev)
{
struct tilcdc_drm_private *priv = dev->dev_private;
if (!priv->irq_enabled)
return;
free_irq(priv->irq, dev);
priv->irq_enabled = false;
}
/* /*
* DRM operations: * DRM operations:
*/ */
...@@ -145,7 +177,7 @@ static void tilcdc_fini(struct drm_device *dev) ...@@ -145,7 +177,7 @@ static void tilcdc_fini(struct drm_device *dev)
drm_dev_unregister(dev); drm_dev_unregister(dev);
drm_kms_helper_poll_fini(dev); drm_kms_helper_poll_fini(dev);
drm_irq_uninstall(dev); tilcdc_irq_uninstall(dev);
drm_mode_config_cleanup(dev); drm_mode_config_cleanup(dev);
if (priv->clk) if (priv->clk)
...@@ -336,7 +368,12 @@ static int tilcdc_init(const struct drm_driver *ddrv, struct device *dev) ...@@ -336,7 +368,12 @@ static int tilcdc_init(const struct drm_driver *ddrv, struct device *dev)
goto init_failed; goto init_failed;
} }
ret = drm_irq_install(ddev, platform_get_irq(pdev, 0)); ret = platform_get_irq(pdev, 0);
if (ret < 0)
goto init_failed;
priv->irq = ret;
ret = tilcdc_irq_install(ddev, priv->irq);
if (ret < 0) { if (ret < 0) {
dev_err(dev, "failed to install IRQ handler\n"); dev_err(dev, "failed to install IRQ handler\n");
goto init_failed; goto init_failed;
...@@ -360,13 +397,6 @@ static int tilcdc_init(const struct drm_driver *ddrv, struct device *dev) ...@@ -360,13 +397,6 @@ static int tilcdc_init(const struct drm_driver *ddrv, struct device *dev)
return ret; return ret;
} }
static irqreturn_t tilcdc_irq(int irq, void *arg)
{
struct drm_device *dev = arg;
struct tilcdc_drm_private *priv = dev->dev_private;
return tilcdc_crtc_irq(priv->crtc);
}
#if defined(CONFIG_DEBUG_FS) #if defined(CONFIG_DEBUG_FS)
static const struct { static const struct {
const char *name; const char *name;
...@@ -454,7 +484,6 @@ DEFINE_DRM_GEM_CMA_FOPS(fops); ...@@ -454,7 +484,6 @@ DEFINE_DRM_GEM_CMA_FOPS(fops);
static const struct drm_driver tilcdc_driver = { static const struct drm_driver tilcdc_driver = {
.driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC, .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
.irq_handler = tilcdc_irq,
DRM_GEM_CMA_DRIVER_OPS, DRM_GEM_CMA_DRIVER_OPS,
#ifdef CONFIG_DEBUG_FS #ifdef CONFIG_DEBUG_FS
.debugfs_init = tilcdc_debugfs_init, .debugfs_init = tilcdc_debugfs_init,
......
...@@ -46,6 +46,8 @@ struct tilcdc_drm_private { ...@@ -46,6 +46,8 @@ struct tilcdc_drm_private {
struct clk *clk; /* functional clock */ struct clk *clk; /* functional clock */
int rev; /* IP revision */ int rev; /* IP revision */
unsigned int irq;
/* don't attempt resolutions w/ higher W * H * Hz: */ /* don't attempt resolutions w/ higher W * H * Hz: */
uint32_t max_bandwidth; uint32_t max_bandwidth;
/* /*
...@@ -82,6 +84,7 @@ struct tilcdc_drm_private { ...@@ -82,6 +84,7 @@ struct tilcdc_drm_private {
bool is_registered; bool is_registered;
bool is_componentized; bool is_componentized;
bool irq_enabled;
}; };
/* Sub-module for display. Since we don't know at compile time what panels /* Sub-module for display. Since we don't know at compile time what panels
......
...@@ -435,7 +435,7 @@ static void cirrus_pipe_enable(struct drm_simple_display_pipe *pipe, ...@@ -435,7 +435,7 @@ static void cirrus_pipe_enable(struct drm_simple_display_pipe *pipe,
struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(plane_state); struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(plane_state);
cirrus_mode_set(cirrus, &crtc_state->mode, plane_state->fb); cirrus_mode_set(cirrus, &crtc_state->mode, plane_state->fb);
cirrus_fb_blit_fullscreen(plane_state->fb, &shadow_plane_state->map[0]); cirrus_fb_blit_fullscreen(plane_state->fb, &shadow_plane_state->data[0]);
} }
static void cirrus_pipe_update(struct drm_simple_display_pipe *pipe, static void cirrus_pipe_update(struct drm_simple_display_pipe *pipe,
...@@ -451,7 +451,7 @@ static void cirrus_pipe_update(struct drm_simple_display_pipe *pipe, ...@@ -451,7 +451,7 @@ static void cirrus_pipe_update(struct drm_simple_display_pipe *pipe,
cirrus_mode_set(cirrus, &crtc->mode, state->fb); cirrus_mode_set(cirrus, &crtc->mode, state->fb);
if (drm_atomic_helper_damage_merged(old_state, state, &rect)) if (drm_atomic_helper_damage_merged(old_state, state, &rect))
cirrus_fb_blit_rect(state->fb, &shadow_plane_state->map[0], &rect); cirrus_fb_blit_rect(state->fb, &shadow_plane_state->data[0], &rect);
} }
static const struct drm_simple_display_pipe_funcs cirrus_pipe_funcs = { static const struct drm_simple_display_pipe_funcs cirrus_pipe_funcs = {
......
...@@ -554,7 +554,7 @@ static void gm12u320_pipe_enable(struct drm_simple_display_pipe *pipe, ...@@ -554,7 +554,7 @@ static void gm12u320_pipe_enable(struct drm_simple_display_pipe *pipe,
struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(plane_state); struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(plane_state);
gm12u320->fb_update.draw_status_timeout = FIRST_FRAME_TIMEOUT; gm12u320->fb_update.draw_status_timeout = FIRST_FRAME_TIMEOUT;
gm12u320_fb_mark_dirty(plane_state->fb, &shadow_plane_state->map[0], &rect); gm12u320_fb_mark_dirty(plane_state->fb, &shadow_plane_state->data[0], &rect);
} }
static void gm12u320_pipe_disable(struct drm_simple_display_pipe *pipe) static void gm12u320_pipe_disable(struct drm_simple_display_pipe *pipe)
...@@ -572,7 +572,7 @@ static void gm12u320_pipe_update(struct drm_simple_display_pipe *pipe, ...@@ -572,7 +572,7 @@ static void gm12u320_pipe_update(struct drm_simple_display_pipe *pipe,
struct drm_rect rect; struct drm_rect rect;
if (drm_atomic_helper_damage_merged(old_state, state, &rect)) if (drm_atomic_helper_damage_merged(old_state, state, &rect))
gm12u320_fb_mark_dirty(state->fb, &shadow_plane_state->map[0], &rect); gm12u320_fb_mark_dirty(state->fb, &shadow_plane_state->data[0], &rect);
} }
static const struct drm_simple_display_pipe_funcs gm12u320_pipe_funcs = { static const struct drm_simple_display_pipe_funcs gm12u320_pipe_funcs = {
......
...@@ -639,7 +639,7 @@ simpledrm_simple_display_pipe_enable(struct drm_simple_display_pipe *pipe, ...@@ -639,7 +639,7 @@ simpledrm_simple_display_pipe_enable(struct drm_simple_display_pipe *pipe,
struct simpledrm_device *sdev = simpledrm_device_of_dev(pipe->crtc.dev); struct simpledrm_device *sdev = simpledrm_device_of_dev(pipe->crtc.dev);
struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(plane_state); struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(plane_state);
struct drm_framebuffer *fb = plane_state->fb; struct drm_framebuffer *fb = plane_state->fb;
void *vmap = shadow_plane_state->map[0].vaddr; /* TODO: Use mapping abstraction properly */ void *vmap = shadow_plane_state->data[0].vaddr; /* TODO: Use mapping abstraction */
struct drm_device *dev = &sdev->dev; struct drm_device *dev = &sdev->dev;
int idx; int idx;
...@@ -677,7 +677,7 @@ simpledrm_simple_display_pipe_update(struct drm_simple_display_pipe *pipe, ...@@ -677,7 +677,7 @@ simpledrm_simple_display_pipe_update(struct drm_simple_display_pipe *pipe,
struct simpledrm_device *sdev = simpledrm_device_of_dev(pipe->crtc.dev); struct simpledrm_device *sdev = simpledrm_device_of_dev(pipe->crtc.dev);
struct drm_plane_state *plane_state = pipe->plane.state; struct drm_plane_state *plane_state = pipe->plane.state;
struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(plane_state); struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(plane_state);
void *vmap = shadow_plane_state->map[0].vaddr; /* TODO: Use mapping abstraction properly */ void *vmap = shadow_plane_state->data[0].vaddr; /* TODO: Use mapping abstraction */
struct drm_framebuffer *fb = plane_state->fb; struct drm_framebuffer *fb = plane_state->fb;
struct drm_device *dev = &sdev->dev; struct drm_device *dev = &sdev->dev;
struct drm_rect clip; struct drm_rect clip;
......
...@@ -379,7 +379,7 @@ udl_simple_display_pipe_enable(struct drm_simple_display_pipe *pipe, ...@@ -379,7 +379,7 @@ udl_simple_display_pipe_enable(struct drm_simple_display_pipe *pipe,
udl->mode_buf_len = wrptr - buf; udl->mode_buf_len = wrptr - buf;
udl_handle_damage(fb, &shadow_plane_state->map[0], 0, 0, fb->width, fb->height); udl_handle_damage(fb, &shadow_plane_state->data[0], 0, 0, fb->width, fb->height);
if (!crtc_state->mode_changed) if (!crtc_state->mode_changed)
return; return;
...@@ -422,7 +422,7 @@ udl_simple_display_pipe_update(struct drm_simple_display_pipe *pipe, ...@@ -422,7 +422,7 @@ udl_simple_display_pipe_update(struct drm_simple_display_pipe *pipe,
return; return;
if (drm_atomic_helper_damage_merged(old_plane_state, state, &rect)) if (drm_atomic_helper_damage_merged(old_plane_state, state, &rect))
udl_handle_damage(fb, &shadow_plane_state->map[0], rect.x1, rect.y1, udl_handle_damage(fb, &shadow_plane_state->data[0], rect.x1, rect.y1,
rect.x2 - rect.x1, rect.y2 - rect.y1); rect.x2 - rect.x1, rect.y2 - rect.y1);
} }
......
...@@ -398,7 +398,7 @@ static void vbox_cursor_atomic_update(struct drm_plane *plane, ...@@ -398,7 +398,7 @@ static void vbox_cursor_atomic_update(struct drm_plane *plane,
u32 height = new_state->crtc_h; u32 height = new_state->crtc_h;
struct drm_shadow_plane_state *shadow_plane_state = struct drm_shadow_plane_state *shadow_plane_state =
to_drm_shadow_plane_state(new_state); to_drm_shadow_plane_state(new_state);
struct dma_buf_map map = shadow_plane_state->map[0]; struct dma_buf_map map = shadow_plane_state->data[0];
u8 *src = map.vaddr; /* TODO: Use mapping abstraction properly */ u8 *src = map.vaddr; /* TODO: Use mapping abstraction properly */
size_t data_size, mask_size; size_t data_size, mask_size;
u32 flags; u32 flags;
......
...@@ -168,10 +168,6 @@ static struct drm_driver vc4_drm_driver = { ...@@ -168,10 +168,6 @@ static struct drm_driver vc4_drm_driver = {
DRIVER_SYNCOBJ), DRIVER_SYNCOBJ),
.open = vc4_open, .open = vc4_open,
.postclose = vc4_close, .postclose = vc4_close,
.irq_handler = vc4_irq,
.irq_preinstall = vc4_irq_preinstall,
.irq_postinstall = vc4_irq_postinstall,
.irq_uninstall = vc4_irq_uninstall,
#if defined(CONFIG_DEBUG_FS) #if defined(CONFIG_DEBUG_FS)
.debugfs_init = vc4_debugfs_init, .debugfs_init = vc4_debugfs_init,
......
...@@ -74,6 +74,8 @@ struct vc4_perfmon { ...@@ -74,6 +74,8 @@ struct vc4_perfmon {
struct vc4_dev { struct vc4_dev {
struct drm_device base; struct drm_device base;
unsigned int irq;
struct vc4_hvs *hvs; struct vc4_hvs *hvs;
struct vc4_v3d *v3d; struct vc4_v3d *v3d;
struct vc4_dpi *dpi; struct vc4_dpi *dpi;
...@@ -895,9 +897,9 @@ extern struct platform_driver vc4_vec_driver; ...@@ -895,9 +897,9 @@ extern struct platform_driver vc4_vec_driver;
extern struct platform_driver vc4_txp_driver; extern struct platform_driver vc4_txp_driver;
/* vc4_irq.c */ /* vc4_irq.c */
irqreturn_t vc4_irq(int irq, void *arg); void vc4_irq_enable(struct drm_device *dev);
void vc4_irq_preinstall(struct drm_device *dev); void vc4_irq_disable(struct drm_device *dev);
int vc4_irq_postinstall(struct drm_device *dev); int vc4_irq_install(struct drm_device *dev, int irq);
void vc4_irq_uninstall(struct drm_device *dev); void vc4_irq_uninstall(struct drm_device *dev);
void vc4_irq_reset(struct drm_device *dev); void vc4_irq_reset(struct drm_device *dev);
......
...@@ -45,6 +45,10 @@ ...@@ -45,6 +45,10 @@
* current job can make progress. * current job can make progress.
*/ */
#include <linux/platform_device.h>
#include <drm/drm_drv.h>
#include "vc4_drv.h" #include "vc4_drv.h"
#include "vc4_regs.h" #include "vc4_regs.h"
...@@ -192,7 +196,7 @@ vc4_irq_finish_render_job(struct drm_device *dev) ...@@ -192,7 +196,7 @@ vc4_irq_finish_render_job(struct drm_device *dev)
schedule_work(&vc4->job_done_work); schedule_work(&vc4->job_done_work);
} }
irqreturn_t static irqreturn_t
vc4_irq(int irq, void *arg) vc4_irq(int irq, void *arg)
{ {
struct drm_device *dev = arg; struct drm_device *dev = arg;
...@@ -234,8 +238,8 @@ vc4_irq(int irq, void *arg) ...@@ -234,8 +238,8 @@ vc4_irq(int irq, void *arg)
return status; return status;
} }
void static void
vc4_irq_preinstall(struct drm_device *dev) vc4_irq_prepare(struct drm_device *dev)
{ {
struct vc4_dev *vc4 = to_vc4_dev(dev); struct vc4_dev *vc4 = to_vc4_dev(dev);
...@@ -251,24 +255,22 @@ vc4_irq_preinstall(struct drm_device *dev) ...@@ -251,24 +255,22 @@ vc4_irq_preinstall(struct drm_device *dev)
V3D_WRITE(V3D_INTCTL, V3D_DRIVER_IRQS); V3D_WRITE(V3D_INTCTL, V3D_DRIVER_IRQS);
} }
int void
vc4_irq_postinstall(struct drm_device *dev) vc4_irq_enable(struct drm_device *dev)
{ {
struct vc4_dev *vc4 = to_vc4_dev(dev); struct vc4_dev *vc4 = to_vc4_dev(dev);
if (!vc4->v3d) if (!vc4->v3d)
return 0; return;
/* Enable the render done interrupts. The out-of-memory interrupt is /* Enable the render done interrupts. The out-of-memory interrupt is
* enabled as soon as we have a binner BO allocated. * enabled as soon as we have a binner BO allocated.
*/ */
V3D_WRITE(V3D_INTENA, V3D_INT_FLDONE | V3D_INT_FRDONE); V3D_WRITE(V3D_INTENA, V3D_INT_FLDONE | V3D_INT_FRDONE);
return 0;
} }
void void
vc4_irq_uninstall(struct drm_device *dev) vc4_irq_disable(struct drm_device *dev)
{ {
struct vc4_dev *vc4 = to_vc4_dev(dev); struct vc4_dev *vc4 = to_vc4_dev(dev);
...@@ -282,11 +284,37 @@ vc4_irq_uninstall(struct drm_device *dev) ...@@ -282,11 +284,37 @@ vc4_irq_uninstall(struct drm_device *dev)
V3D_WRITE(V3D_INTCTL, V3D_DRIVER_IRQS); V3D_WRITE(V3D_INTCTL, V3D_DRIVER_IRQS);
/* Finish any interrupt handler still in flight. */ /* Finish any interrupt handler still in flight. */
disable_irq(dev->irq); disable_irq(vc4->irq);
cancel_work_sync(&vc4->overflow_mem_work); cancel_work_sync(&vc4->overflow_mem_work);
} }
int vc4_irq_install(struct drm_device *dev, int irq)
{
int ret;
if (irq == IRQ_NOTCONNECTED)
return -ENOTCONN;
vc4_irq_prepare(dev);
ret = request_irq(irq, vc4_irq, 0, dev->driver->name, dev);
if (ret)
return ret;
vc4_irq_enable(dev);
return 0;
}
void vc4_irq_uninstall(struct drm_device *dev)
{
struct vc4_dev *vc4 = to_vc4_dev(dev);
vc4_irq_disable(dev);
free_irq(vc4->irq, dev);
}
/** Reinitializes interrupt registers when a GPU reset is performed. */ /** Reinitializes interrupt registers when a GPU reset is performed. */
void vc4_irq_reset(struct drm_device *dev) void vc4_irq_reset(struct drm_device *dev)
{ {
......
...@@ -10,8 +10,6 @@ ...@@ -10,8 +10,6 @@
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/pm_runtime.h> #include <linux/pm_runtime.h>
#include <drm/drm_irq.h>
#include "vc4_drv.h" #include "vc4_drv.h"
#include "vc4_regs.h" #include "vc4_regs.h"
...@@ -361,7 +359,7 @@ static int vc4_v3d_runtime_suspend(struct device *dev) ...@@ -361,7 +359,7 @@ static int vc4_v3d_runtime_suspend(struct device *dev)
struct vc4_v3d *v3d = dev_get_drvdata(dev); struct vc4_v3d *v3d = dev_get_drvdata(dev);
struct vc4_dev *vc4 = v3d->vc4; struct vc4_dev *vc4 = v3d->vc4;
vc4_irq_uninstall(&vc4->base); vc4_irq_disable(&vc4->base);
clk_disable_unprepare(v3d->clk); clk_disable_unprepare(v3d->clk);
...@@ -381,8 +379,8 @@ static int vc4_v3d_runtime_resume(struct device *dev) ...@@ -381,8 +379,8 @@ static int vc4_v3d_runtime_resume(struct device *dev)
vc4_v3d_init_hw(&vc4->base); vc4_v3d_init_hw(&vc4->base);
/* We disabled the IRQ as part of vc4_irq_uninstall in suspend. */ /* We disabled the IRQ as part of vc4_irq_uninstall in suspend. */
enable_irq(vc4->base.irq); enable_irq(vc4->irq);
vc4_irq_postinstall(&vc4->base); vc4_irq_enable(&vc4->base);
return 0; return 0;
} }
...@@ -448,7 +446,12 @@ static int vc4_v3d_bind(struct device *dev, struct device *master, void *data) ...@@ -448,7 +446,12 @@ static int vc4_v3d_bind(struct device *dev, struct device *master, void *data)
vc4_v3d_init_hw(drm); vc4_v3d_init_hw(drm);
ret = drm_irq_install(drm, platform_get_irq(pdev, 0)); ret = platform_get_irq(pdev, 0);
if (ret < 0)
return ret;
vc4->irq = ret;
ret = vc4_irq_install(drm, vc4->irq);
if (ret) { if (ret) {
DRM_ERROR("Failed to install IRQ handler\n"); DRM_ERROR("Failed to install IRQ handler\n");
return ret; return ret;
...@@ -473,7 +476,7 @@ static void vc4_v3d_unbind(struct device *dev, struct device *master, ...@@ -473,7 +476,7 @@ static void vc4_v3d_unbind(struct device *dev, struct device *master,
pm_runtime_disable(dev); pm_runtime_disable(dev);
drm_irq_uninstall(drm); vc4_irq_uninstall(drm);
/* Disable the binner's overflow memory address, so the next /* Disable the binner's overflow memory address, so the next
* driver probe (if any) doesn't try to reuse our old * driver probe (if any) doesn't try to reuse our old
......
...@@ -29,7 +29,6 @@ ...@@ -29,7 +29,6 @@
#include <drm/drm_device.h> #include <drm/drm_device.h>
#include <drm/drm_file.h> #include <drm/drm_file.h>
#include <drm/drm_irq.h>
#include <drm/via_drm.h> #include <drm/via_drm.h>
#include "via_drv.h" #include "via_drv.h"
...@@ -86,7 +85,7 @@ int via_final_context(struct drm_device *dev, int context) ...@@ -86,7 +85,7 @@ int via_final_context(struct drm_device *dev, int context)
/* Last context, perform cleanup */ /* Last context, perform cleanup */
if (list_is_singular(&dev->ctxlist)) { if (list_is_singular(&dev->ctxlist)) {
DRM_DEBUG("Last Context\n"); DRM_DEBUG("Last Context\n");
drm_irq_uninstall(dev); drm_legacy_irq_uninstall(dev);
via_cleanup_futex(dev_priv); via_cleanup_futex(dev_priv);
via_do_cleanup_map(dev); via_do_cleanup_map(dev);
} }
......
...@@ -98,6 +98,8 @@ struct dma_buf *virtgpu_gem_prime_export(struct drm_gem_object *obj, ...@@ -98,6 +98,8 @@ struct dma_buf *virtgpu_gem_prime_export(struct drm_gem_object *obj,
} else { } else {
bo->uuid_state = STATE_ERR; bo->uuid_state = STATE_ERR;
} }
} else if (!(bo->blob_flags & VIRTGPU_BLOB_FLAG_USE_CROSS_DEVICE)) {
bo->uuid_state = STATE_ERR;
} }
exp_info.ops = &virtgpu_dmabuf_ops.ops; exp_info.ops = &virtgpu_dmabuf_ops.ops;
......
...@@ -257,7 +257,7 @@ void vkms_composer_worker(struct work_struct *work) ...@@ -257,7 +257,7 @@ void vkms_composer_worker(struct work_struct *work)
return; return;
if (wb_pending) if (wb_pending)
vaddr_out = crtc_state->active_writeback->map[0].vaddr; vaddr_out = crtc_state->active_writeback->data[0].vaddr;
ret = compose_active_planes(&vaddr_out, primary_composer, ret = compose_active_planes(&vaddr_out, primary_composer,
crtc_state); crtc_state);
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
struct vkms_writeback_job { struct vkms_writeback_job {
struct dma_buf_map map[DRM_FORMAT_MAX_PLANES]; struct dma_buf_map map[DRM_FORMAT_MAX_PLANES];
struct dma_buf_map data[DRM_FORMAT_MAX_PLANES];
}; };
struct vkms_composer { struct vkms_composer {
......
...@@ -111,7 +111,7 @@ static void vkms_plane_atomic_update(struct drm_plane *plane, ...@@ -111,7 +111,7 @@ static void vkms_plane_atomic_update(struct drm_plane *plane,
memcpy(&composer->src, &new_state->src, sizeof(struct drm_rect)); memcpy(&composer->src, &new_state->src, sizeof(struct drm_rect));
memcpy(&composer->dst, &new_state->dst, sizeof(struct drm_rect)); memcpy(&composer->dst, &new_state->dst, sizeof(struct drm_rect));
memcpy(&composer->fb, fb, sizeof(struct drm_framebuffer)); memcpy(&composer->fb, fb, sizeof(struct drm_framebuffer));
memcpy(&composer->map, &shadow_plane_state->map, sizeof(composer->map)); memcpy(&composer->map, &shadow_plane_state->data, sizeof(composer->map));
drm_framebuffer_get(&composer->fb); drm_framebuffer_get(&composer->fb);
composer->offset = fb->offsets[0]; composer->offset = fb->offsets[0];
composer->pitch = fb->pitches[0]; composer->pitch = fb->pitches[0];
......
...@@ -75,7 +75,7 @@ static int vkms_wb_prepare_job(struct drm_writeback_connector *wb_connector, ...@@ -75,7 +75,7 @@ static int vkms_wb_prepare_job(struct drm_writeback_connector *wb_connector,
if (!vkmsjob) if (!vkmsjob)
return -ENOMEM; return -ENOMEM;
ret = drm_gem_fb_vmap(job->fb, vkmsjob->map); ret = drm_gem_fb_vmap(job->fb, vkmsjob->map, vkmsjob->data);
if (ret) { if (ret) {
DRM_ERROR("vmap failed: %d\n", ret); DRM_ERROR("vmap failed: %d\n", ret);
goto err_kfree; goto err_kfree;
......
...@@ -97,19 +97,18 @@ typedef __attribute__((aligned(32))) struct MKSGuestStatInfoEntry { ...@@ -97,19 +97,18 @@ typedef __attribute__((aligned(32))) struct MKSGuestStatInfoEntry {
} MKSGuestStatInfoEntry; } MKSGuestStatInfoEntry;
#define INVALID_PPN64 ((PPN64)0x000fffffffffffffULL) #define INVALID_PPN64 ((PPN64)0x000fffffffffffffULL)
#define vmw_num_pages(size) (PAGE_ALIGN(size) >> PAGE_SHIFT)
#define MKS_GUEST_STAT_INSTANCE_DESC_LENGTH 1024 #define MKS_GUEST_STAT_INSTANCE_DESC_LENGTH 1024
#define MKS_GUEST_STAT_INSTANCE_MAX_STATS 4096 #define MKS_GUEST_STAT_INSTANCE_MAX_STATS 4096
#define MKS_GUEST_STAT_INSTANCE_MAX_STAT_PPNS \ #define MKS_GUEST_STAT_INSTANCE_MAX_STAT_PPNS \
(vmw_num_pages(MKS_GUEST_STAT_INSTANCE_MAX_STATS * \ (PFN_UP(MKS_GUEST_STAT_INSTANCE_MAX_STATS * \
sizeof(MKSGuestStatCounterTime))) sizeof(MKSGuestStatCounterTime)))
#define MKS_GUEST_STAT_INSTANCE_MAX_INFO_PPNS \ #define MKS_GUEST_STAT_INSTANCE_MAX_INFO_PPNS \
(vmw_num_pages(MKS_GUEST_STAT_INSTANCE_MAX_STATS * \ (PFN_UP(MKS_GUEST_STAT_INSTANCE_MAX_STATS * \
sizeof(MKSGuestStatInfoEntry))) sizeof(MKSGuestStatInfoEntry)))
#define MKS_GUEST_STAT_AVERAGE_NAME_LENGTH 40 #define MKS_GUEST_STAT_AVERAGE_NAME_LENGTH 40
#define MKS_GUEST_STAT_INSTANCE_MAX_STRS_PPNS \ #define MKS_GUEST_STAT_INSTANCE_MAX_STRS_PPNS \
(vmw_num_pages(MKS_GUEST_STAT_INSTANCE_MAX_STATS * \ (PFN_UP(MKS_GUEST_STAT_INSTANCE_MAX_STATS * \
MKS_GUEST_STAT_AVERAGE_NAME_LENGTH)) MKS_GUEST_STAT_AVERAGE_NAME_LENGTH))
/* /*
......
...@@ -405,7 +405,7 @@ static size_t vmw_bo_acc_size(struct vmw_private *dev_priv, size_t size, ...@@ -405,7 +405,7 @@ static size_t vmw_bo_acc_size(struct vmw_private *dev_priv, size_t size,
bool user) bool user)
{ {
static size_t struct_size, user_struct_size; static size_t struct_size, user_struct_size;
size_t num_pages = PAGE_ALIGN(size) >> PAGE_SHIFT; size_t num_pages = PFN_UP(size);
size_t page_array_size = ttm_round_pot(num_pages * sizeof(void *)); size_t page_array_size = ttm_round_pot(num_pages * sizeof(void *));
if (unlikely(struct_size == 0)) { if (unlikely(struct_size == 0)) {
...@@ -474,7 +474,6 @@ int vmw_bo_create_kernel(struct vmw_private *dev_priv, unsigned long size, ...@@ -474,7 +474,6 @@ int vmw_bo_create_kernel(struct vmw_private *dev_priv, unsigned long size,
struct ttm_placement *placement, struct ttm_placement *placement,
struct ttm_buffer_object **p_bo) struct ttm_buffer_object **p_bo)
{ {
unsigned npages = PAGE_ALIGN(size) >> PAGE_SHIFT;
struct ttm_operation_ctx ctx = { false, false }; struct ttm_operation_ctx ctx = { false, false };
struct ttm_buffer_object *bo; struct ttm_buffer_object *bo;
size_t acc_size; size_t acc_size;
...@@ -485,7 +484,7 @@ int vmw_bo_create_kernel(struct vmw_private *dev_priv, unsigned long size, ...@@ -485,7 +484,7 @@ int vmw_bo_create_kernel(struct vmw_private *dev_priv, unsigned long size,
return -ENOMEM; return -ENOMEM;
acc_size = ttm_round_pot(sizeof(*bo)); acc_size = ttm_round_pot(sizeof(*bo));
acc_size += ttm_round_pot(npages * sizeof(void *)); acc_size += ttm_round_pot(PFN_UP(size) * sizeof(void *));
acc_size += ttm_round_pot(sizeof(struct ttm_tt)); acc_size += ttm_round_pot(sizeof(struct ttm_tt));
ret = ttm_mem_global_alloc(&ttm_mem_glob, acc_size, &ctx); ret = ttm_mem_global_alloc(&ttm_mem_glob, acc_size, &ctx);
......
...@@ -358,8 +358,7 @@ static void vmw_cmdbuf_ctx_submit(struct vmw_cmdbuf_man *man, ...@@ -358,8 +358,7 @@ static void vmw_cmdbuf_ctx_submit(struct vmw_cmdbuf_man *man,
break; break;
} }
list_del(&entry->list); list_move_tail(&entry->list, &ctx->hw_submitted);
list_add_tail(&entry->list, &ctx->hw_submitted);
ctx->num_hw_submitted++; ctx->num_hw_submitted++;
} }
...@@ -802,7 +801,7 @@ static int vmw_cmdbuf_alloc_space(struct vmw_cmdbuf_man *man, ...@@ -802,7 +801,7 @@ static int vmw_cmdbuf_alloc_space(struct vmw_cmdbuf_man *man,
{ {
struct vmw_cmdbuf_alloc_info info; struct vmw_cmdbuf_alloc_info info;
info.page_size = PAGE_ALIGN(size) >> PAGE_SHIFT; info.page_size = PFN_UP(size);
info.node = node; info.node = node;
info.done = false; info.done = false;
......
...@@ -169,8 +169,7 @@ void vmw_cmdbuf_res_revert(struct list_head *list) ...@@ -169,8 +169,7 @@ void vmw_cmdbuf_res_revert(struct list_head *list)
case VMW_CMDBUF_RES_DEL: case VMW_CMDBUF_RES_DEL:
ret = drm_ht_insert_item(&entry->man->resources, &entry->hash); ret = drm_ht_insert_item(&entry->man->resources, &entry->hash);
BUG_ON(ret); BUG_ON(ret);
list_del(&entry->head); list_move_tail(&entry->head, &entry->man->list);
list_add_tail(&entry->head, &entry->man->list);
entry->state = VMW_CMDBUF_RES_COMMITTED; entry->state = VMW_CMDBUF_RES_COMMITTED;
break; break;
default: default:
......
...@@ -607,8 +607,7 @@ struct vmw_resource *vmw_cotable_alloc(struct vmw_private *dev_priv, ...@@ -607,8 +607,7 @@ struct vmw_resource *vmw_cotable_alloc(struct vmw_private *dev_priv,
if (num_entries < co_info[type].min_initial_entries) { if (num_entries < co_info[type].min_initial_entries) {
vcotbl->res.backup_size = co_info[type].min_initial_entries * vcotbl->res.backup_size = co_info[type].min_initial_entries *
co_info[type].size; co_info[type].size;
vcotbl->res.backup_size = vcotbl->res.backup_size = PFN_ALIGN(vcotbl->res.backup_size);
(vcotbl->res.backup_size + PAGE_SIZE - 1) & PAGE_MASK;
} }
vcotbl->scrubbed = true; vcotbl->scrubbed = true;
......
...@@ -1295,7 +1295,6 @@ extern struct vmw_cmdbuf_res_manager * ...@@ -1295,7 +1295,6 @@ extern struct vmw_cmdbuf_res_manager *
vmw_context_res_man(struct vmw_resource *ctx); vmw_context_res_man(struct vmw_resource *ctx);
extern struct vmw_resource *vmw_context_cotable(struct vmw_resource *ctx, extern struct vmw_resource *vmw_context_cotable(struct vmw_resource *ctx,
SVGACOTableType cotable_type); SVGACOTableType cotable_type);
extern struct list_head *vmw_context_binding_list(struct vmw_resource *ctx);
struct vmw_ctx_binding_state; struct vmw_ctx_binding_state;
extern struct vmw_ctx_binding_state * extern struct vmw_ctx_binding_state *
vmw_context_binding_state(struct vmw_resource *ctx); vmw_context_binding_state(struct vmw_resource *ctx);
......
...@@ -100,7 +100,7 @@ static int vmw_cursor_update_bo(struct vmw_private *dev_priv, ...@@ -100,7 +100,7 @@ static int vmw_cursor_update_bo(struct vmw_private *dev_priv,
int ret; int ret;
kmap_offset = 0; kmap_offset = 0;
kmap_num = (width*height*4 + PAGE_SIZE - 1) >> PAGE_SHIFT; kmap_num = PFN_UP(width*height*4);
ret = ttm_bo_reserve(&bo->base, true, false, NULL); ret = ttm_bo_reserve(&bo->base, true, false, NULL);
if (unlikely(ret != 0)) { if (unlikely(ret != 0)) {
......
...@@ -256,8 +256,7 @@ static int vmw_otable_batch_setup(struct vmw_private *dev_priv, ...@@ -256,8 +256,7 @@ static int vmw_otable_batch_setup(struct vmw_private *dev_priv,
if (!otables[i].enabled) if (!otables[i].enabled)
continue; continue;
otables[i].size = otables[i].size = PFN_ALIGN(otables[i].size);
(otables[i].size + PAGE_SIZE - 1) & PAGE_MASK;
bo_size += otables[i].size; bo_size += otables[i].size;
} }
...@@ -385,7 +384,7 @@ static unsigned long vmw_mob_calculate_pt_pages(unsigned long data_pages) ...@@ -385,7 +384,7 @@ static unsigned long vmw_mob_calculate_pt_pages(unsigned long data_pages)
while (likely(data_size > PAGE_SIZE)) { while (likely(data_size > PAGE_SIZE)) {
data_size = DIV_ROUND_UP(data_size, PAGE_SIZE); data_size = DIV_ROUND_UP(data_size, PAGE_SIZE);
data_size *= VMW_PPN_SIZE; data_size *= VMW_PPN_SIZE;
tot_size += (data_size + PAGE_SIZE - 1) & PAGE_MASK; tot_size += PFN_ALIGN(data_size);
} }
return tot_size >> PAGE_SHIFT; return tot_size >> PAGE_SHIFT;
......
...@@ -1016,9 +1016,9 @@ int vmw_mksstat_add_ioctl(struct drm_device *dev, void *data, ...@@ -1016,9 +1016,9 @@ int vmw_mksstat_add_ioctl(struct drm_device *dev, void *data,
struct page *page; struct page *page;
MKSGuestStatInstanceDescriptor *pdesc; MKSGuestStatInstanceDescriptor *pdesc;
const size_t num_pages_stat = vmw_num_pages(arg->stat_len); const size_t num_pages_stat = PFN_UP(arg->stat_len);
const size_t num_pages_info = vmw_num_pages(arg->info_len); const size_t num_pages_info = PFN_UP(arg->info_len);
const size_t num_pages_strs = vmw_num_pages(arg->strs_len); const size_t num_pages_strs = PFN_UP(arg->strs_len);
long desc_len; long desc_len;
long nr_pinned_stat; long nr_pinned_stat;
long nr_pinned_info; long nr_pinned_info;
......
...@@ -353,8 +353,7 @@ int vmw_user_lookup_handle(struct vmw_private *dev_priv, ...@@ -353,8 +353,7 @@ int vmw_user_lookup_handle(struct vmw_private *dev_priv,
static int vmw_resource_buf_alloc(struct vmw_resource *res, static int vmw_resource_buf_alloc(struct vmw_resource *res,
bool interruptible) bool interruptible)
{ {
unsigned long size = unsigned long size = PFN_ALIGN(res->backup_size);
(res->backup_size + PAGE_SIZE - 1) & PAGE_MASK;
struct vmw_buffer_object *backup; struct vmw_buffer_object *backup;
int ret; int ret;
......
...@@ -981,8 +981,7 @@ int vmw_compat_shader_add(struct vmw_private *dev_priv, ...@@ -981,8 +981,7 @@ int vmw_compat_shader_add(struct vmw_private *dev_priv,
goto no_reserve; goto no_reserve;
/* Map and copy shader bytecode. */ /* Map and copy shader bytecode. */
ret = ttm_bo_kmap(&buf->base, 0, PAGE_ALIGN(size) >> PAGE_SHIFT, ret = ttm_bo_kmap(&buf->base, 0, PFN_UP(size), &map);
&map);
if (unlikely(ret != 0)) { if (unlikely(ret != 0)) {
ttm_bo_unreserve(&buf->base); ttm_bo_unreserve(&buf->base);
goto no_reserve; goto no_reserve;
......
...@@ -865,7 +865,7 @@ int vmw_surface_define_ioctl(struct drm_device *dev, void *data, ...@@ -865,7 +865,7 @@ int vmw_surface_define_ioctl(struct drm_device *dev, void *data,
user_srf->prime.base.shareable = false; user_srf->prime.base.shareable = false;
user_srf->prime.base.tfile = NULL; user_srf->prime.base.tfile = NULL;
if (drm_is_primary_client(file_priv)) if (drm_is_primary_client(file_priv))
user_srf->master = drm_master_get(file_priv->master); user_srf->master = drm_file_get_master(file_priv);
/** /**
* From this point, the generic resource management functions * From this point, the generic resource management functions
...@@ -1534,7 +1534,7 @@ vmw_gb_surface_define_internal(struct drm_device *dev, ...@@ -1534,7 +1534,7 @@ vmw_gb_surface_define_internal(struct drm_device *dev,
user_srf = container_of(srf, struct vmw_user_surface, srf); user_srf = container_of(srf, struct vmw_user_surface, srf);
if (drm_is_primary_client(file_priv)) if (drm_is_primary_client(file_priv))
user_srf->master = drm_master_get(file_priv->master); user_srf->master = drm_file_get_master(file_priv);
res = &user_srf->srf.res; res = &user_srf->srf.res;
......
...@@ -191,20 +191,6 @@ struct drm_device { ...@@ -191,20 +191,6 @@ struct drm_device {
*/ */
struct list_head clientlist; struct list_head clientlist;
/**
* @irq_enabled:
*
* Indicates that interrupt handling is enabled, specifically vblank
* handling. Drivers which don't use drm_irq_install() need to set this
* to true manually.
*/
bool irq_enabled;
/**
* @irq: Used by the drm_irq_install() and drm_irq_unistall() helpers.
*/
int irq;
/** /**
* @vblank_disable_immediate: * @vblank_disable_immediate:
* *
...@@ -372,6 +358,10 @@ struct drm_device { ...@@ -372,6 +358,10 @@ struct drm_device {
/* Scatter gather memory */ /* Scatter gather memory */
struct drm_sg_mem *sg; struct drm_sg_mem *sg;
/* IRQs */
bool irq_enabled;
int irq;
#endif #endif
}; };
......
...@@ -137,10 +137,6 @@ enum drm_driver_feature { ...@@ -137,10 +137,6 @@ enum drm_driver_feature {
* @DRIVER_HAVE_IRQ: * @DRIVER_HAVE_IRQ:
* *
* Legacy irq support. Only for legacy drivers. Do not use. * Legacy irq support. Only for legacy drivers. Do not use.
*
* New drivers can either use the drm_irq_install() and
* drm_irq_uninstall() helper functions, or roll their own irq support
* code by calling request_irq() directly.
*/ */
DRIVER_HAVE_IRQ = BIT(30), DRIVER_HAVE_IRQ = BIT(30),
/** /**
...@@ -271,42 +267,6 @@ struct drm_driver { ...@@ -271,42 +267,6 @@ struct drm_driver {
*/ */
void (*release) (struct drm_device *); void (*release) (struct drm_device *);
/**
* @irq_handler:
*
* Interrupt handler called when using drm_irq_install(). Not used by
* drivers which implement their own interrupt handling.
*/
irqreturn_t(*irq_handler) (int irq, void *arg);
/**
* @irq_preinstall:
*
* Optional callback used by drm_irq_install() which is called before
* the interrupt handler is registered. This should be used to clear out
* any pending interrupts (from e.g. firmware based drives) and reset
* the interrupt handling registers.
*/
void (*irq_preinstall) (struct drm_device *dev);
/**
* @irq_postinstall:
*
* Optional callback used by drm_irq_install() which is called after
* the interrupt handler is registered. This should be used to enable
* interrupt generation in the hardware.
*/
int (*irq_postinstall) (struct drm_device *dev);
/**
* @irq_uninstall:
*
* Optional callback used by drm_irq_uninstall() which is called before
* the interrupt handler is unregistered. This should be used to disable
* interrupt generation in the hardware.
*/
void (*irq_uninstall) (struct drm_device *dev);
/** /**
* @master_set: * @master_set:
* *
...@@ -504,6 +464,10 @@ struct drm_driver { ...@@ -504,6 +464,10 @@ struct drm_driver {
int (*dma_ioctl) (struct drm_device *dev, void *data, struct drm_file *file_priv); int (*dma_ioctl) (struct drm_device *dev, void *data, struct drm_file *file_priv);
int (*dma_quiescent) (struct drm_device *); int (*dma_quiescent) (struct drm_device *);
int (*context_dtor) (struct drm_device *dev, int context); int (*context_dtor) (struct drm_device *dev, int context);
irqreturn_t (*irq_handler)(int irq, void *arg);
void (*irq_preinstall)(struct drm_device *dev);
int (*irq_postinstall)(struct drm_device *dev);
void (*irq_uninstall)(struct drm_device *dev);
u32 (*get_vblank_counter)(struct drm_device *dev, unsigned int pipe); u32 (*get_vblank_counter)(struct drm_device *dev, unsigned int pipe);
int (*enable_vblank)(struct drm_device *dev, unsigned int pipe); int (*enable_vblank)(struct drm_device *dev, unsigned int pipe);
void (*disable_vblank)(struct drm_device *dev, unsigned int pipe); void (*disable_vblank)(struct drm_device *dev, unsigned int pipe);
......
...@@ -336,7 +336,7 @@ struct edid { ...@@ -336,7 +336,7 @@ struct edid {
u8 features; u8 features;
/* Color characteristics */ /* Color characteristics */
u8 red_green_lo; u8 red_green_lo;
u8 black_white_lo; u8 blue_white_lo;
u8 red_x; u8 red_x;
u8 red_y; u8 red_y;
u8 green_x; u8 green_x;
......
...@@ -233,6 +233,10 @@ struct drm_file { ...@@ -233,6 +233,10 @@ struct drm_file {
* this only matches &drm_device.master if the master is the currently * this only matches &drm_device.master if the master is the currently
* active one. * active one.
* *
* To update @master, both &drm_device.master_mutex and
* @master_lookup_lock need to be held, therefore holding either of
* them is safe and enough for the read side.
*
* When dereferencing this pointer, either hold struct * When dereferencing this pointer, either hold struct
* &drm_device.master_mutex for the duration of the pointer's use, or * &drm_device.master_mutex for the duration of the pointer's use, or
* use drm_file_get_master() if struct &drm_device.master_mutex is not * use drm_file_get_master() if struct &drm_device.master_mutex is not
......
...@@ -42,6 +42,14 @@ struct drm_shadow_plane_state { ...@@ -42,6 +42,14 @@ struct drm_shadow_plane_state {
* prepare_fb callback and removed in the cleanup_fb callback. * prepare_fb callback and removed in the cleanup_fb callback.
*/ */
struct dma_buf_map map[DRM_FORMAT_MAX_PLANES]; struct dma_buf_map map[DRM_FORMAT_MAX_PLANES];
/**
* @data: Address of each framebuffer BO's data
*
* The address of the data stored in each mapping. This is different
* for framebuffers with non-zero offset fields.
*/
struct dma_buf_map data[DRM_FORMAT_MAX_PLANES];
}; };
/** /**
......
...@@ -40,7 +40,8 @@ drm_gem_fb_create_with_dirty(struct drm_device *dev, struct drm_file *file, ...@@ -40,7 +40,8 @@ drm_gem_fb_create_with_dirty(struct drm_device *dev, struct drm_file *file,
const struct drm_mode_fb_cmd2 *mode_cmd); const struct drm_mode_fb_cmd2 *mode_cmd);
int drm_gem_fb_vmap(struct drm_framebuffer *fb, int drm_gem_fb_vmap(struct drm_framebuffer *fb,
struct dma_buf_map map[static DRM_FORMAT_MAX_PLANES]); struct dma_buf_map map[static DRM_FORMAT_MAX_PLANES],
struct dma_buf_map data[DRM_FORMAT_MAX_PLANES]);
void drm_gem_fb_vunmap(struct drm_framebuffer *fb, void drm_gem_fb_vunmap(struct drm_framebuffer *fb,
struct dma_buf_map map[static DRM_FORMAT_MAX_PLANES]); struct dma_buf_map map[static DRM_FORMAT_MAX_PLANES]);
int drm_gem_fb_begin_cpu_access(struct drm_framebuffer *fb, enum dma_data_direction dir); int drm_gem_fb_begin_cpu_access(struct drm_framebuffer *fb, enum dma_data_direction dir);
......
/*
* Copyright 2016 Intel Corp.
*
* 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
* VA LINUX SYSTEMS AND/OR ITS SUPPLIERS 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.
*/
#ifndef _DRM_IRQ_H_
#define _DRM_IRQ_H_
struct drm_device;
int drm_irq_install(struct drm_device *dev, int irq);
int drm_irq_uninstall(struct drm_device *dev);
int devm_drm_irq_install(struct drm_device *dev, int irq);
#endif
...@@ -192,6 +192,9 @@ do { \ ...@@ -192,6 +192,9 @@ do { \
void drm_legacy_idlelock_take(struct drm_lock_data *lock); void drm_legacy_idlelock_take(struct drm_lock_data *lock);
void drm_legacy_idlelock_release(struct drm_lock_data *lock); void drm_legacy_idlelock_release(struct drm_lock_data *lock);
/* drm_irq.c */
int drm_legacy_irq_uninstall(struct drm_device *dev);
/* drm_pci.c */ /* drm_pci.c */
#ifdef CONFIG_PCI #ifdef CONFIG_PCI
......
...@@ -153,6 +153,33 @@ struct drm_simple_display_pipe_funcs { ...@@ -153,6 +153,33 @@ struct drm_simple_display_pipe_funcs {
*/ */
void (*disable_vblank)(struct drm_simple_display_pipe *pipe); void (*disable_vblank)(struct drm_simple_display_pipe *pipe);
/**
* @reset_crtc:
*
* Optional, called by &drm_crtc_funcs.reset. Please read the
* documentation for the &drm_crtc_funcs.reset hook for more details.
*/
void (*reset_crtc)(struct drm_simple_display_pipe *pipe);
/**
* @duplicate_crtc_state:
*
* Optional, called by &drm_crtc_funcs.atomic_duplicate_state. Please
* read the documentation for the &drm_crtc_funcs.atomic_duplicate_state
* hook for more details.
*/
struct drm_crtc_state * (*duplicate_crtc_state)(struct drm_simple_display_pipe *pipe);
/**
* @destroy_crtc_state:
*
* Optional, called by &drm_crtc_funcs.atomic_destroy_state. Please
* read the documentation for the &drm_crtc_funcs.atomic_destroy_state
* hook for more details.
*/
void (*destroy_crtc_state)(struct drm_simple_display_pipe *pipe,
struct drm_crtc_state *crtc_state);
/** /**
* @reset_plane: * @reset_plane:
* *
......
...@@ -54,7 +54,7 @@ struct dma_buf_ops { ...@@ -54,7 +54,7 @@ struct dma_buf_ops {
* device), and otherwise need to fail the attach operation. * device), and otherwise need to fail the attach operation.
* *
* The exporter should also in general check whether the current * The exporter should also in general check whether the current
* allocation fullfills the DMA constraints of the new device. If this * allocation fulfills the DMA constraints of the new device. If this
* is not the case, and the allocation cannot be moved, it should also * is not the case, and the allocation cannot be moved, it should also
* fail the attach operation. * fail the attach operation.
* *
...@@ -161,7 +161,7 @@ struct dma_buf_ops { ...@@ -161,7 +161,7 @@ struct dma_buf_ops {
* *
* Returns: * Returns:
* *
* A &sg_table scatter list of or the backing storage of the DMA buffer, * A &sg_table scatter list of the backing storage of the DMA buffer,
* already mapped into the device address space of the &device attached * already mapped into the device address space of the &device attached
* with the provided &dma_buf_attachment. The addresses and lengths in * with the provided &dma_buf_attachment. The addresses and lengths in
* the scatter list are PAGE_SIZE aligned. * the scatter list are PAGE_SIZE aligned.
...@@ -183,7 +183,7 @@ struct dma_buf_ops { ...@@ -183,7 +183,7 @@ struct dma_buf_ops {
* *
* This is called by dma_buf_unmap_attachment() and should unmap and * This is called by dma_buf_unmap_attachment() and should unmap and
* release the &sg_table allocated in @map_dma_buf, and it is mandatory. * release the &sg_table allocated in @map_dma_buf, and it is mandatory.
* For static dma_buf handling this might also unpins the backing * For static dma_buf handling this might also unpin the backing
* storage if this is the last mapping of the DMA buffer. * storage if this is the last mapping of the DMA buffer.
*/ */
void (*unmap_dma_buf)(struct dma_buf_attachment *, void (*unmap_dma_buf)(struct dma_buf_attachment *,
...@@ -252,7 +252,7 @@ struct dma_buf_ops { ...@@ -252,7 +252,7 @@ struct dma_buf_ops {
* This callback is used by the dma_buf_mmap() function * This callback is used by the dma_buf_mmap() function
* *
* Note that the mapping needs to be incoherent, userspace is expected * Note that the mapping needs to be incoherent, userspace is expected
* to braket CPU access using the DMA_BUF_IOCTL_SYNC interface. * to bracket CPU access using the DMA_BUF_IOCTL_SYNC interface.
* *
* Because dma-buf buffers have invariant size over their lifetime, the * Because dma-buf buffers have invariant size over their lifetime, the
* dma-buf core checks whether a vma is too large and rejects such * dma-buf core checks whether a vma is too large and rejects such
...@@ -580,7 +580,7 @@ static inline bool dma_buf_is_dynamic(struct dma_buf *dmabuf) ...@@ -580,7 +580,7 @@ static inline bool dma_buf_is_dynamic(struct dma_buf *dmabuf)
/** /**
* dma_buf_attachment_is_dynamic - check if a DMA-buf attachment uses dynamic * dma_buf_attachment_is_dynamic - check if a DMA-buf attachment uses dynamic
* mappinsg * mappings
* @attach: the DMA-buf attachment to check * @attach: the DMA-buf attachment to check
* *
* Returns true if a DMA-buf importer wants to call the map/unmap functions with * Returns true if a DMA-buf importer wants to call the map/unmap functions with
......
...@@ -306,31 +306,29 @@ extern void lock_unpin_lock(struct lockdep_map *lock, struct pin_cookie); ...@@ -306,31 +306,29 @@ extern void lock_unpin_lock(struct lockdep_map *lock, struct pin_cookie);
#define lockdep_depth(tsk) (debug_locks ? (tsk)->lockdep_depth : 0) #define lockdep_depth(tsk) (debug_locks ? (tsk)->lockdep_depth : 0)
#define lockdep_assert_held(l) do { \ #define lockdep_assert(cond) \
WARN_ON(debug_locks && \ do { WARN_ON(debug_locks && !(cond)); } while (0)
lockdep_is_held(l) == LOCK_STATE_NOT_HELD); \
} while (0)
#define lockdep_assert_not_held(l) do { \ #define lockdep_assert_once(cond) \
WARN_ON(debug_locks && \ do { WARN_ON_ONCE(debug_locks && !(cond)); } while (0)
lockdep_is_held(l) == LOCK_STATE_HELD); \
} while (0)
#define lockdep_assert_held_write(l) do { \ #define lockdep_assert_held(l) \
WARN_ON(debug_locks && !lockdep_is_held_type(l, 0)); \ lockdep_assert(lockdep_is_held(l) != LOCK_STATE_NOT_HELD)
} while (0)
#define lockdep_assert_held_read(l) do { \ #define lockdep_assert_not_held(l) \
WARN_ON(debug_locks && !lockdep_is_held_type(l, 1)); \ lockdep_assert(lockdep_is_held(l) != LOCK_STATE_HELD)
} while (0)
#define lockdep_assert_held_once(l) do { \ #define lockdep_assert_held_write(l) \
WARN_ON_ONCE(debug_locks && !lockdep_is_held(l)); \ lockdep_assert(lockdep_is_held_type(l, 0))
} while (0)
#define lockdep_assert_none_held_once() do { \ #define lockdep_assert_held_read(l) \
WARN_ON_ONCE(debug_locks && current->lockdep_depth); \ lockdep_assert(lockdep_is_held_type(l, 1))
} while (0)
#define lockdep_assert_held_once(l) \
lockdep_assert_once(lockdep_is_held(l) != LOCK_STATE_NOT_HELD)
#define lockdep_assert_none_held_once() \
lockdep_assert_once(!current->lockdep_depth)
#define lockdep_recursing(tsk) ((tsk)->lockdep_recursion) #define lockdep_recursing(tsk) ((tsk)->lockdep_recursion)
...@@ -407,6 +405,9 @@ extern int lock_is_held(const void *); ...@@ -407,6 +405,9 @@ extern int lock_is_held(const void *);
extern int lockdep_is_held(const void *); extern int lockdep_is_held(const void *);
#define lockdep_is_held_type(l, r) (1) #define lockdep_is_held_type(l, r) (1)
#define lockdep_assert(c) do { } while (0)
#define lockdep_assert_once(c) do { } while (0)
#define lockdep_assert_held(l) do { (void)(l); } while (0) #define lockdep_assert_held(l) do { (void)(l); } while (0)
#define lockdep_assert_not_held(l) do { (void)(l); } while (0) #define lockdep_assert_not_held(l) do { (void)(l); } while (0)
#define lockdep_assert_held_write(l) do { (void)(l); } while (0) #define lockdep_assert_held_write(l) do { (void)(l); } while (0)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册