Thanks again Daniel for the clarification. However I cannot seem to find the repo for the drm-misc and documentation on how to get it from the main kernel tree. Could you can give me some pointers on where to get the git tree of the drm-misc for small drivers. Sorry as I am not very familiar with the DRM architecture >-----Original Message----- >From: daniel.vetter@xxxxxxxx [mailto:daniel.vetter@xxxxxxxx] On Behalf Of Daniel >Vetter >Sent: Sunday, April 9, 2017 12:31 AM >To: Ong, Hean Loong <hean.loong.ong@xxxxxxxxx> >Cc: Vetter, Daniel <daniel.vetter@xxxxxxxxx>; airlied@xxxxxxxx; dri- >devel@xxxxxxxxxxxxxxxxxxxxx >Subject: Re: DRM Display driver for Intel FPGA Video and Image Processing Suite > >On Sat, Apr 8, 2017 at 7:41 AM, Ong, Hean Loong <hean.loong.ong@xxxxxxxxx> >wrote: >> Hi Daniel >> >> Thanks for the time and patience for reviewing my changes. I would ensure that >subsequent patches will not have the same mail problems. >> >> I have some question on the validation methods. Since my drivers are >processing the images with an FPGA would running the tests with >https://dri.freedesktop.org/docs/drm/gpu/drm-uapi.html#testing-and-validation >be relevant? > >igt testcases automatically skip when they don't apply for a given platform/driver. >They might need some bugfixes if your driver is a completely new case, but it >should work. > >> The display images are streamed to the monitor via a Display Port connector >thus I don' t think it is virtual. The FPGA is programmed to run with a proprietary >Display Port IP. The driver just feeds it with display data. > >Well, it looked like a virtual driver (since the real DP handling is somewhere else >like you explain). And since it works like a virtual driver we could extract a helper >library to reduce duplicated code. >Virtual driver here means "just feeds display data to something else that handles >the real output handling duties". That applies to virtualized gpus, but also to your >case here. > >Btw a small ascii-art block diagram for your driver hw architecture to explain stuff >like this would be awesome (but it either into a code comment or into the commit >message). > >> I would take your advice in implementing it in the small drivers, but since its new >are there any special cases that I would have to look out for in implementing this >driver in the drm-misc ? > >Small drivers is only about how to maintain it once it's merged, not about the >code itself. We assume/hope that people who submit drivers stay around for >helping maintaining it going forward (but if that doesn't happen, also no big deal). >-Daniel > >> >>>-----Original Message----- >>>From: daniel.vetter@xxxxxxxx [mailto:daniel.vetter@xxxxxxxx] On Behalf >>>Of Daniel Vetter >>>Sent: Saturday, April 8, 2017 12:32 AM >>>To: Ong, Hean Loong <hean.loong.ong@xxxxxxxxx> >>>Cc: Vetter, Daniel <daniel.vetter@xxxxxxxxx>; airlied@xxxxxxxx; dri- >>>devel@xxxxxxxxxxxxxxxxxxxxx >>>Subject: Re: DRM Display driver for Intel FPGA Video and Image >>>Processing Suite >>> >>>On Thu, Apr 6, 2017 at 8:29 AM, Ong, Hean Loong >>><hean.loong.ong@xxxxxxxxx> >>>wrote: >>>> Hi All, >>>> >>>> Any comments for the patch below? >>> >>>Seems the same version that I already reviewed. My comment about not >>>sending inline was more for the next version, especially once it's >>>about applying the patch, attached patches are a bit of a pain (since they break >the tooling here). >>>-Daniel >>>> >>>> Thanks >>>> >>>> Hean Loong >>>> >>>> On Tue, 2017-04-04 at 04:01 +0000, Ong, Hean Loong wrote: >>>>> Hi All, >>>>> >>>>> Apologies for the attachment earlier. Below are the inline changes >>>>> for the patch >>>>> >>>>> From 0de293e3646a1780ed603cf8e1f2a19d9aebbe83 Mon Sep 17 00:00:00 >>>>> 2001 >>>>> From: Ong, Hean Loong <hean.loong.ong@xxxxxxxxx> >>>>> Date: Thu, 30 Mar 2017 18:02:22 +0800 >>>>> Subject: [PATCHv0] Intel FPGA Video and Image Processing Suite >>>>> Frame Buffer II driver >>>>> >>>>> Signed-off-by: Ong, Hean Loong <hean.loong.ong@xxxxxxxxx> >>>>> --- >>>>> drivers/gpu/drm/Kconfig | 2 + >>>>> drivers/gpu/drm/Makefile | 1 + >>>>> drivers/gpu/drm/ivip/Kconfig | 22 ++++ >>>>> drivers/gpu/drm/ivip/Makefile | 9 ++ >>>>> drivers/gpu/drm/ivip/intel_vip_conn.c | 145 >>>>> ++++++++++++++++++++++ drivers/gpu/drm/ivip/intel_vip_core.c | 215 >>>>> +++++++++++++++++++++++++++++++++ >>>>> drivers/gpu/drm/ivip/intel_vip_crtc.c | 161 >>>>> ++++++++++++++++++++++++ >>>>> drivers/gpu/drm/ivip/intel_vip_drv.h | 55 +++++++++ >>>>> drivers/gpu/drm/ivip/intel_vip_of.c | 146 ++++++++++++++++++++++ >>>>> 9 files changed, 756 insertions(+), 0 deletions(-) create mode >>>>> 100644 drivers/gpu/drm/ivip/Kconfig create mode 100644 >>>>> drivers/gpu/drm/ivip/Makefile create mode 100644 >>>>> drivers/gpu/drm/ivip/intel_vip_conn.c >>>>> create mode 100644 drivers/gpu/drm/ivip/intel_vip_core.c >>>>> create mode 100644 drivers/gpu/drm/ivip/intel_vip_crtc.c >>>>> create mode 100644 drivers/gpu/drm/ivip/intel_vip_drv.h >>>>> create mode 100644 drivers/gpu/drm/ivip/intel_vip_of.c >>>>> >>>>> diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig >>>>> index >>>>> ebfe840..c487507 100644 >>>>> --- a/drivers/gpu/drm/Kconfig >>>>> +++ b/drivers/gpu/drm/Kconfig >>>>> @@ -167,6 +167,8 @@ source "drivers/gpu/drm/nouveau/Kconfig" >>>>> >>>>> source "drivers/gpu/drm/i915/Kconfig" >>>>> >>>>> +source "drivers/gpu/drm/ivip/Kconfig" >>>>> + >>>>> config DRM_VGEM >>>>> tristate "Virtual GEM provider" >>>>> depends on DRM >>>>> diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile >>>>> index b9ae428..945cf53 100644 >>>>> --- a/drivers/gpu/drm/Makefile >>>>> +++ b/drivers/gpu/drm/Makefile >>>>> @@ -52,6 +52,7 @@ obj-$(CONFIG_DRM_AMDGPU)+= amd/amdgpu/ >>>>> obj-$(CONFIG_DRM_MGA) += mga/ >>>>> obj-$(CONFIG_DRM_I810) += i810/ >>>>> obj-$(CONFIG_DRM_I915) += i915/ >>>>> +obj-$(CONFIG_DRM_IVIP) += ivip/ >>>>> obj-$(CONFIG_DRM_MGAG200) += mgag200/ >>>>> obj-$(CONFIG_DRM_VC4) += vc4/ >>>>> obj-$(CONFIG_DRM_CIRRUS_QEMU) += cirrus/ diff --git >>>>> a/drivers/gpu/drm/ivip/Kconfig b/drivers/gpu/drm/ivip/Kconfig new >>>>> file mode 100644 index 0000000..ddf3cb5 >>>>> --- /dev/null >>>>> +++ b/drivers/gpu/drm/ivip/Kconfig >>>>> @@ -0,0 +1,22 @@ >>>>> +config DRM_IVIP >>>>> + tristate "Intel FGPA Video and Image Processing" >>>>> + depends on DRM >>>>> + select DRM_GEM_CMA_HELPER >>>>> + select DRM_KMS_HELPER >>>>> + select DRM_KMS_FB_HELPER >>>>> + select DRM_KMS_CMA_HELPER >>>>> + help >>>>> + Choose this option if you have a Intel FPGA Arria >>>>> +10 >>>>> system >>>>> + and above with a Display Port IP. This does not >>>>> support legacy >>>>> + Intel FPGA Cyclone V display port. Currently only >>>>> single frame >>>>> + buffer is supported. Note that ACPI and X_86 >>>>> architecture is yet >>>>> + to be supported. >>>>> + >>>>> +config DRM_IVIP_OF >>>>> + tristate "Intel FGPA Video and Image Processing Open >>>>> Firmware Systems" >>>>> + depends on DRM_IVIP && OF >>>>> + help >>>>> + Choose this option if the Intel FPGA system is >>>>> + using >>>>> Open >>>>> + Firmware systems (Arria 10). If M is selected the >>>>> module would >>>>> + be called ivip. >>>>> + >>>>> diff --git a/drivers/gpu/drm/ivip/Makefile >>>>> b/drivers/gpu/drm/ivip/Makefile new file mode 100644 index >>>>> 0000000..7be1e99 >>>>> --- /dev/null >>>>> +++ b/drivers/gpu/drm/ivip/Makefile >>>>> @@ -0,0 +1,9 @@ >>>>> +# >>>>> +# Makefile for the drm device driver. This driver provides >>>>> +support >>>>> for the >>>>> +# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. >>>>> + >>>>> +ccflags-y := -Iinclude/drm >>>>> + >>>>> +obj-$(CONFIG_DRM_IVIP_OF) += ivip.o ivip-objs := intel_vip_of.o >>>>> +intel_vip_core.o \ intel_vip_conn.o intel_vip_crtc.o >>>>> diff --git a/drivers/gpu/drm/ivip/intel_vip_conn.c >>>>> b/drivers/gpu/drm/ivip/intel_vip_conn.c >>>>> new file mode 100644 >>>>> index 0000000..89ab587 >>>>> --- /dev/null >>>>> +++ b/drivers/gpu/drm/ivip/intel_vip_conn.c >>>>> @@ -0,0 +1,145 @@ >>>>> +/* >>>>> + * intel_vip_conn.c -- Intel Video and Image Processing(VIP) >>>>> + * Frame Buffer II driver >>>>> + * >>>>> + * This driver supports the Intel VIP Frame Reader component. >>>>> + * More info on the hardware can be found in the Intel Video >>>>> + * and Image Processing Suite User Guide at this address >>>>> + * http://www.altera.com/literature/ug/ug_vip.pdf. >>>>> + * >>>>> + * This program is free software; you can redistribute it and/or >>>>> modify it >>>>> + * under the terms and conditions of the GNU General Public >>>>> + License, >>>>> + * version 2, as published by the Free Software Foundation. >>>>> + * >>>>> + * This program is distributed in the hope it will be useful, but >>>>> WITHOUT >>>>> + * ANY WARRANTY; without even the implied warranty of >>>>> MERCHANTABILITY or >>>>> + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public >>>>> License for >>>>> + * more details. >>>>> + * >>>>> + * Authors: >>>>> + * Ong, Hean-Loong <hean.loong.ong@xxxxxxxxx> >>>>> + * >>>>> + */ >>>>> + >>>>> +#include <linux/init.h> >>>>> +#include <linux/kernel.h> >>>>> +#include <drm/drm_atomic_helper.h> #include >>>>> +<drm/drm_crtc_helper.h> #include <drm/drm_encoder_slave.h> >>>>> +#include <drm/drm_plane_helper.h> >>>>> + >>>>> +static enum drm_connector_status >>>>> +intelvipfb_drm_connector_detect(struct drm_connector *connector, >>>>> bool force) >>>>> +{ >>>>> + return connector_status_connected; } >>>>> + >>>>> +static void intelvipfb_drm_connector_destroy(struct drm_connector >>>>> *connector) >>>>> +{ >>>>> + drm_connector_unregister(connector); >>>>> + drm_connector_cleanup(connector); } >>>>> + >>>>> +static const struct drm_connector_funcs >>>>> intelvipfb_drm_connector_funcs = { >>>>> + .dpms = drm_helper_connector_dpms, >>>>> + .reset = drm_atomic_helper_connector_reset, >>>>> + .detect = intelvipfb_drm_connector_detect, >>>>> + .fill_modes = drm_helper_probe_single_connector_modes, >>>>> + .destroy = intelvipfb_drm_connector_destroy, >>>>> + .atomic_duplicate_state = >>>>> drm_atomic_helper_connector_duplicate_state, >>>>> + .atomic_destroy_state = >>>>> drm_atomic_helper_connector_destroy_state, >>>>> +}; >>>>> + >>>>> +static int intelvipfb_drm_connector_get_modes(struct drm_connector >>>>> *connector) >>>>> +{ >>>>> + struct drm_device *drm = connector->dev; >>>>> + int count; >>>>> + >>>>> + count = drm_add_modes_noedid(connector, drm- >>>>> >mode_config.max_width, >>>>> + drm->mode_config.max_height); >>>>> + drm_set_preferred_mode(connector, drm- >>>>> >mode_config.max_width, >>>>> + drm->mode_config.max_height); >>>>> + return count; >>>>> +} >>>>> + >>>>> +static const struct drm_connector_helper_funcs >>>>> +intelvipfb_drm_connector_helper_funcs = { >>>>> + .get_modes = intelvipfb_drm_connector_get_modes, >>>>> +}; >>>>> + >>>>> +static const struct drm_encoder_funcs intelvipfb_drm_encoder_funcs >>>>> += { >>>>> + .destroy = drm_encoder_cleanup, }; >>>>> + >>>>> +static void intelvipfb_mode_set(struct drm_encoder *encoder, >>>>> + struct drm_display_mode *mode, >>>>> + struct drm_display_mode >>>>> *adjusted_mode) >>>>> +{ >>>>> + /* do nothing */ >>>>> +} >>>>> + >>>>> +static void intelvipfb_nop(struct drm_encoder *encoder) { >>>>> + /* do nothing */ >>>>> +} >>>>> + >>>>> +static const struct drm_encoder_helper_funcs i >>>>> +intelvipfb_drm_encoder_helper = { >>>>> + .mode_set = intelvipfb_mode_set, >>>>> + .enable = intelvipfb_nop, >>>>> + .disable = intelvipfb_nop, >>>>> +}; >>>>> + >>>>> +int intelvipfb_drm_conn_init(struct drm_device *drm) { >>>>> + struct drm_encoder_slave *encoder; >>>>> + struct drm_connector *conn; >>>>> + int ret; >>>>> + >>>>> + encoder = devm_kzalloc(drm->dev, sizeof(*encoder), >>>>> GFP_KERNEL); >>>>> + if (!encoder) >>>>> + return -ENOMEM; >>>>> + >>>>> + encoder->base.possible_crtcs = 1; >>>>> + encoder->base.possible_clones = 0; >>>>> + >>>>> + ret = drm_encoder_init(drm, &encoder->base, >>>>> + &intelvipfb_drm_encoder_funcs, >>>>> + DRM_MODE_ENCODER_VIRTUAL, NULL); >>>>> + if (ret) >>>>> + return ret; >>>>> + >>>>> + drm_encoder_helper_add(&encoder->base, >>>>> &intelvipfb_drm_encoder_helper); >>>>> + >>>>> + conn = devm_kzalloc(drm->dev, sizeof(*conn), GFP_KERNEL); >>>>> + if (IS_ERR(conn)) >>>>> + return PTR_ERR(conn); >>>>> + >>>>> + ret = drm_connector_init(drm, conn, >>>>> &intelvipfb_drm_connector_funcs, >>>>> + DRM_MODE_CONNECTOR_DisplayPort); >>>>> + if (ret < 0) { >>>>> + dev_err(drm->dev, "failed to initialize drm >>>>> connector\n"); >>>>> + ret = -ENOMEM; >>>>> + goto error_encoder_cleanup; >>>>> + } >>>>> + >>>>> + drm_connector_helper_add(conn, >>>>> &intelvipfb_drm_connector_helper_funcs); >>>>> + >>>>> + ret = drm_mode_connector_attach_encoder(conn, &encoder- >>>>> >base); >>>>> + if (ret < 0) { >>>>> + dev_err(drm->dev, "could not attach connector to >>>>> encoder\n"); >>>>> + drm_connector_unregister(conn); >>>>> + goto error_connector_cleanup; >>>>> + } >>>>> + >>>>> + return 0; >>>>> + >>>>> +error_connector_cleanup: >>>>> + drm_connector_cleanup(conn); >>>>> + >>>>> +error_encoder_cleanup: >>>>> + drm_encoder_cleanup(&encoder->base); >>>>> + >>>>> + return ret; >>>>> +} >>>>> diff --git a/drivers/gpu/drm/ivip/intel_vip_core.c >>>>> b/drivers/gpu/drm/ivip/intel_vip_core.c >>>>> new file mode 100644 >>>>> index 0000000..3001ad0 >>>>> --- /dev/null >>>>> +++ b/drivers/gpu/drm/ivip/intel_vip_core.c >>>>> @@ -0,0 +1,215 @@ >>>>> +/* >>>>> + * intel_vip_core.c -- Intel Video and Image Processing(VIP) >>>>> + * Frame Buffer II driver >>>>> + * >>>>> + * This driver supports the Intel VIP Frame Reader component. >>>>> + * More info on the hardware can be found in the Intel Video >>>>> + * and Image Processing Suite User Guide at this address >>>>> + * http://www.altera.com/literature/ug/ug_vip.pdf. >>>>> + * >>>>> + * This program is free software; you can redistribute it and/or >>>>> modify it >>>>> + * under the terms and conditions of the GNU General Public >>>>> + License, >>>>> + * version 2, as published by the Free Software Foundation. >>>>> + * >>>>> + * This program is distributed in the hope it will be useful, but >>>>> WITHOUT >>>>> + * ANY WARRANTY; without even the implied warranty of >>>>> MERCHANTABILITY or >>>>> + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public >>>>> License for >>>>> + * more details. >>>>> + * >>>>> + * Authors: >>>>> + * Ong, Hean-Loong <hean.loong.ong@xxxxxxxxx> >>>>> + * >>>>> + */ >>>>> + >>>>> +#include <linux/init.h> >>>>> +#include <linux/kernel.h> >>>>> +#include <linux/module.h> >>>>> + >>>>> +#include <drm/drmP.h> >>>>> +#include <drm/drm_atomic.h> >>>>> +#include <drm/drm_atomic_helper.h> #include >>>>> +<drm/drm_crtc_helper.h> #include <drm/drm_fb_helper.h> #include >>>>> +<drm/drm_fb_cma_helper.h> #include <drm/drm_gem_cma_helper.h> >>>>> +#include <drm/drm_of.h> >>>>> + >>>>> +#include "intel_vip_drv.h" >>>>> + >>>>> +static const struct file_operations intelvipfb_drm_fops = { >>>>> + .owner = THIS_MODULE, >>>>> + .open = drm_open, >>>>> + .release = drm_release, >>>>> + .unlocked_ioctl = drm_ioctl, >>>>> + .poll = drm_poll, >>>>> + .read = drm_read, >>>>> + .llseek = no_llseek, >>>>> + .mmap = drm_gem_cma_mmap, >>>>> +}; >>>>> + >>>>> +static void intelvipfb_lastclose(struct drm_device *drm) { >>>>> + struct intelvipfb_priv *fbpriv = drm->dev_private; >>>>> + >>>>> + drm_fbdev_cma_restore_mode(fbpriv->fbcma); >>>>> +} >>>>> + >>>>> +static struct drm_driver intelvipfb_drm = { >>>>> + .driver_features = >>>>> + DRIVER_GEM | DRIVER_PRIME | >>>>> + DRIVER_RENDER | DRIVER_MODESET | DRIVER_ATOMIC, >>>>> + .gem_free_object_unlocked = drm_gem_cma_free_object, >>>>> + .gem_vm_ops = &drm_gem_cma_vm_ops, >>>>> + .dumb_create = drm_gem_cma_dumb_create, >>>>> + .dumb_map_offset = drm_gem_cma_dumb_map_offset, >>>>> + .dumb_destroy = drm_gem_dumb_destroy, >>>>> + .prime_handle_to_fd = drm_gem_prime_handle_to_fd, >>>>> + .prime_fd_to_handle = drm_gem_prime_fd_to_handle, >>>>> + .gem_prime_export = drm_gem_prime_export, >>>>> + .gem_prime_import = drm_gem_prime_import, >>>>> + .gem_prime_get_sg_table = drm_gem_cma_prime_get_sg_table, >>>>> + .gem_prime_import_sg_table = >>>>> drm_gem_cma_prime_import_sg_table, >>>>> + .gem_prime_vmap = drm_gem_cma_prime_vmap, >>>>> + .gem_prime_vunmap = drm_gem_cma_prime_vunmap, >>>>> + .gem_prime_mmap = drm_gem_cma_prime_mmap, >>>>> + .name = DRIVER_NAME, >>>>> + .date = "20170329", >>>>> + .desc = "Intel FPGA VIP SUITE", >>>>> + .major = 1, >>>>> + .minor = 0, >>>>> + .patchlevel = 0, >>>>> + .lastclose = intelvipfb_lastclose, >>>>> + .fops = &intelvipfb_drm_fops, }; >>>>> + >>>>> +static void intelvipfb_start_hw(void __iomem *base, >>>>> +resource_size_t >>>>> addr) >>>>> +{ >>>>> + /* >>>>> + * The frameinfo variable has to correspond to the size of >>>>> the VIP Suite >>>>> + * Frame Reader register 7 which will determine the maximum >>>>> size used >>>>> + * in this frameinfo >>>>> + */ >>>>> + >>>>> + u32 frameinfo; >>>>> + >>>>> + frameinfo = >>>>> + readl(base + INTELVIPFB_FRAME_READER) & 0x00ffffff; >>>>> + >>>>> + writel(frameinfo, base + INTELVIPFB_FRAME_INFO); >>>>> + >>>>> + writel(addr, base + INTELVIPFB_FRAME_START); >>>>> + /* Finally set the control register to 1 to start streaming >>>>> */ >>>>> + writel(1, base + INTELVIPFB_CONTROL); } >>>>> + >>>>> +static void intelvipfb_disable_hw(void __iomem *base) { >>>>> + /* set the control register to 0 to stop streaming */ >>>>> + writel(0, base + INTELVIPFB_CONTROL); } >>>>> + >>>>> +static void intelvipfb_output_poll_changed(struct drm_device *drm) { >>>>> + struct intelvipfb_priv *fbpriv = drm->dev_private; >>>>> + >>>>> + drm_fbdev_cma_hotplug_event(fbpriv->fbcma); >>>>> +} >>>>> + >>>>> +static const struct drm_mode_config_funcs >>>>> intelvipfb_mode_config_funcs = { >>>>> + .fb_create = drm_fb_cma_create, >>>>> + .output_poll_changed = intelvipfb_output_poll_changed, >>>>> + .atomic_check = drm_atomic_helper_check, >>>>> + .atomic_commit = drm_atomic_helper_commit, }; >>>>> + >>>>> +static struct drm_mode_config_helper_funcs >>>>> intelvipfb_mode_config_helpers = { >>>>> + .atomic_commit_tail = drm_atomic_helper_commit_tail, }; >>>>> + >>>>> +static void intelvipfb_setup_mode_config(struct drm_device *drm, >>>>> + struct fb_info *info) { >>>>> + drm_mode_config_init(drm); >>>>> + drm->mode_config.min_width = 0; >>>>> + drm->mode_config.min_height = 0; >>>>> + drm->mode_config.max_width = info->var.xres; >>>>> + drm->mode_config.max_height = info->var.yres; >>>>> + drm->mode_config.preferred_depth = 32; >>>>> + drm->mode_config.funcs = &intelvipfb_mode_config_funcs; >>>>> + drm->mode_config.helper_private = >>>>> &intelvipfb_mode_config_helpers; >>>>> +} >>>>> + >>>>> +int intelvipfb_probe(struct device *dev, void __iomem *base) { >>>>> + int retval; >>>>> + struct drm_device *drm; >>>>> + struct intelvipfb_priv *fbpriv = dev_get_drvdata(dev); >>>>> + struct fb_info *info = &fbpriv->info; >>>>> + >>>>> + /*setup DRM */ >>>>> + drm = drm_dev_alloc(&intelvipfb_drm, dev); >>>>> + if (IS_ERR(drm)) >>>>> + return PTR_ERR(drm); >>>>> + >>>>> + drm->dev_private = fbpriv; >>>>> + >>>>> + dev_set_drvdata(dev, drm); >>>>> + >>>>> + intelvipfb_setup_mode_config(drm, info); >>>>> + >>>>> + retval = dma_set_mask_and_coherent(drm->dev, >>>>> DMA_BIT_MASK(32)); >>>>> + if (retval) >>>>> + return -ENODEV; >>>>> + >>>>> + retval = intelvipfb_setup_crtc(drm); >>>>> + if (retval < 0) >>>>> + return -ENODEV; >>>>> + >>>>> + retval = intelvipfb_drm_conn_init(drm); >>>>> + if (retval) >>>>> + return -ENOMEM; >>>>> + >>>>> + drm_mode_config_reset(drm); >>>>> + >>>>> + fbpriv->fbcma = drm_fbdev_cma_init(drm, PREF_BPP, >>>>> + CRTC_NUM, >>>>> CONN_NUM); >>>>> + if (!fbpriv->fbcma) { >>>>> + fbpriv->fbcma = NULL; >>>>> + return -ENODEV; >>>>> + } >>>>> + >>>>> + intelvipfb_start_hw(base, drm->mode_config.fb_base); >>>>> + >>>>> + drm_kms_helper_poll_init(drm); >>>>> + >>>>> + drm_dev_register(drm, 0); >>>>> + >>>>> + return retval; >>>>> +} >>>>> +EXPORT_SYMBOL_GPL(intelvipfb_probe); >>>>> + >>>>> +int intelvipfb_remove(struct device *dev) { >>>>> + struct drm_device *drm = dev_get_drvdata(dev); >>>>> + struct intelvipfb_priv *fbpriv = drm->dev_private; >>>>> + >>>>> + drm_dev_unregister(drm); >>>>> + >>>>> + drm_kms_helper_poll_fini(drm); >>>>> + drm_fbdev_cma_fini(fbpriv->fbcma); >>>>> + >>>>> + intelvipfb_disable_hw(fbpriv->base); >>>>> + >>>>> +drm_mode_config_cleanup(drm); >>>>> + >>>>> +drm_dev_unref(drm); >>>>> + >>>>> +devm_kfree(dev, fbpriv); >>>>> + >>>>> + return 0; >>>>> +} >>>>> +EXPORT_SYMBOL_GPL(intelvipfb_remove); >>>>> + >>>>> +MODULE_AUTHOR("Ong, Hean-Loong <hean.loong.ong@xxxxxxxxx>"); >>>>> +MODULE_DESCRIPTION("Intel VIP Frame Buffer II driver"); >>>>> +MODULE_LICENSE("GPL v2"); >>>>> diff --git a/drivers/gpu/drm/ivip/intel_vip_crtc.c >>>>> b/drivers/gpu/drm/ivip/intel_vip_crtc.c >>>>> new file mode 100644 >>>>> index 0000000..97a3954 >>>>> --- /dev/null >>>>> +++ b/drivers/gpu/drm/ivip/intel_vip_crtc.c >>>>> @@ -0,0 +1,161 @@ >>>>> +/* >>>>> + * intel_vip_crtc.c -- Intel Video and Image Processing(VIP) >>>>> + * Frame Buffer II driver >>>>> + * >>>>> + * This driver supports the Intel VIP Frame Reader component. >>>>> + * More info on the hardware can be found in the Intel Video >>>>> + * and Image Processing Suite User Guide at this address >>>>> + * http://www.altera.com/literature/ug/ug_vip.pdf. >>>>> + * >>>>> + * This program is free software; you can redistribute it and/or >>>>> modify it >>>>> + * under the terms and conditions of the GNU General Public >>>>> + License, >>>>> + * version 2, as published by the Free Software Foundation. >>>>> + * >>>>> + * This program is distributed in the hope it will be useful, but >>>>> WITHOUT >>>>> + * ANY WARRANTY; without even the implied warranty of >>>>> MERCHANTABILITY or >>>>> + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public >>>>> License for >>>>> + * more details. >>>>> + * >>>>> + * Authors: >>>>> + * Ong, Hean-Loong <hean.loong.ong@xxxxxxxxx> >>>>> + * >>>>> + */ >>>>> + >>>>> +#include <linux/init.h> >>>>> +#include <linux/kernel.h> >>>>> +#include <linux/platform_data/simplefb.h> >>>>> + >>>>> +#include <drm/drm_atomic.h> >>>>> +#include <drm/drm_atomic_helper.h> #include <drm/drm_crtc.h> >>>>> +#include <drm/drm_crtc_helper.h> #include >>>>> +<drm/drm_fb_cma_helper.h> #include <drm/drm_gem_cma_helper.h> >>>>> +#include <drm/drm_plane_helper.h> >>>>> + >>>>> +#include "intel_vip_drv.h" >>>>> + >>>>> +static struct simplefb_format intelvipfb_formats[] = >>>>> SIMPLEFB_FORMATS; >>>>> + >>>>> +static void intelvipfb_crtc_destroy(struct drm_crtc *crtc) { >>>>> + drm_crtc_cleanup(crtc); >>>>> + kfree(crtc); >>>>> +} >>>>> + >>>>> +static const struct drm_crtc_funcs intelvipfb_crtc_funcs = { >>>>> + .destroy = intelvipfb_crtc_destroy, >>>>> + .set_config = drm_atomic_helper_set_config, >>>>> + .page_flip = drm_atomic_helper_page_flip, >>>>> + .reset = drm_atomic_helper_crtc_reset, >>>>> + .atomic_duplicate_state = >>>>> drm_atomic_helper_crtc_duplicate_state, >>>>> + .atomic_destroy_state = >>>>> drm_atomic_helper_crtc_destroy_state, >>>>> +}; >>>>> + >>>>> +static void intelvipfb_crtc_atomic_begin(struct drm_crtc *crtc, >>>>> + struct drm_crtc_state >>>>> *state) >>>>> +{ >>>>> + struct drm_pending_vblank_event *event = crtc->state->event; >>>>> + >>>>> + if (event) { >>>>> + crtc->state->event = NULL; >>>>> + >>>>> + spin_lock_irq(&crtc->dev->event_lock); >>>>> + drm_crtc_send_vblank_event(crtc, event); >>>>> + spin_unlock_irq(&crtc->dev->event_lock); >>>>> + } >>>>> +} >>>>> + >>>>> +static void intelvipfb_crtc_nop(struct drm_crtc *crtc) { >>>>> + /* do nothing */; >>>>> +} >>>>> + >>>>> +static const struct drm_crtc_helper_funcs >>>>> intelvipfb_crtc_helper_funcs = { >>>>> + .atomic_begin = intelvipfb_crtc_atomic_begin, >>>>> + .enable = intelvipfb_crtc_nop, }; >>>>> + >>>>> +static void intelvipfb_plane_destroy(struct drm_plane *plane) { >>>>> + drm_plane_helper_disable(plane); >>>>> + drm_plane_cleanup(plane); >>>>> +} >>>>> + >>>>> +static const struct drm_plane_funcs intelvipfb_plane_funcs = { >>>>> + .update_plane = >>>>> drm_atomic_helper_update_plane, >>>>> + .disable_plane = >>>>> drm_atomic_helper_disable_plane, >>>>> + .destroy = intelvipfb_plane_destroy, >>>>> + .reset = >>>>> drm_atomic_helper_plane_reset, >>>>> + .atomic_duplicate_state = >>>>> drm_atomic_helper_plane_duplicate_state, >>>>> + .atomic_destroy_state = >>>>> drm_atomic_helper_plane_destroy_state, >>>>> +}; >>>>> + >>>>> +static void intelvipfb_plane_atomic_update(struct drm_plane *plane, >>>>> + struct drm_plane_state >>>>> *state) >>>>> +{ >>>>> + struct intelvipfb_priv *fbpriv; >>>>> + struct drm_gem_cma_object *gem; >>>>> + >>>>> + if (!plane->state->crtc || !plane->state->fb) >>>>> + return; >>>>> + >>>>> + fbpriv = plane->dev->dev_private; >>>>> + gem = drm_fb_cma_get_gem_obj(plane->state->fb, 0); >>>>> + writel(gem->paddr, fbpriv->base + INTELVIPFB_FRAME_START); } >>>>> + >>>>> +static const struct drm_plane_helper_funcs >>>>> intelvipfb_plane_helper_funcs = { >>>>> + .atomic_update = intelvipfb_plane_atomic_update, }; >>>>> + >>>>> +static struct drm_plane *intelvipfb_plane_init(struct drm_device >>>>> *drm) >>>>> +{ >>>>> + struct drm_plane *plane = NULL; >>>>> + u32 formats[ARRAY_SIZE(intelvipfb_formats)], i; >>>>> + int ret; >>>>> + >>>>> + plane = devm_kzalloc(drm->dev, sizeof(*plane), GFP_KERNEL); >>>>> + if (!plane) >>>>> + return ERR_PTR(-ENOMEM); >>>>> + >>>>> + for (i = 0; i < ARRAY_SIZE(intelvipfb_formats); i++) >>>>> + formats[i] = intelvipfb_formats[i].fourcc; >>>>> + >>>>> + ret = drm_universal_plane_init(drm, plane, 0xff, >>>>> + &intelvipfb_plane_funcs, >>>>> + formats, ARRAY_SIZE(formats), >>>>> + DRM_PLANE_TYPE_PRIMARY, >>>>> NULL); >>>>> + if (ret) >>>>> + return ERR_PTR(ret); >>>>> + >>>>> + drm_plane_helper_add(plane, &intelvipfb_plane_helper_funcs); >>>>> + >>>>> + return plane; >>>>> +} >>>>> + >>>>> +int intelvipfb_setup_crtc(struct drm_device *drm) { >>>>> + struct drm_crtc *crtc; >>>>> + struct drm_plane *primary; >>>>> + int ret; >>>>> + >>>>> + crtc = kzalloc(sizeof(*crtc), GFP_KERNEL); >>>>> + if (!crtc) >>>>> + return -ENOMEM; >>>>> + >>>>> + primary = intelvipfb_plane_init(drm); >>>>> + if (IS_ERR(primary)) >>>>> + return PTR_ERR(primary); >>>>> + >>>>> + ret = drm_crtc_init_with_planes(drm, crtc, primary, NULL, >>>>> + &intelvipfb_crtc_funcs, >>>>> NULL); >>>>> + >>>>> + if (ret) { >>>>> + intelvipfb_plane_destroy(primary); >>>>> + return ret; >>>>> + } >>>>> + >>>>> + drm_crtc_helper_add(crtc, &intelvipfb_crtc_helper_funcs); >>>>> + return 0; >>>>> +} >>>>> diff --git a/drivers/gpu/drm/ivip/intel_vip_drv.h >>>>> b/drivers/gpu/drm/ivip/intel_vip_drv.h >>>>> new file mode 100644 >>>>> index 0000000..657f23c >>>>> --- /dev/null >>>>> +++ b/drivers/gpu/drm/ivip/intel_vip_drv.h >>>>> @@ -0,0 +1,55 @@ >>>>> +/* >>>>> + * Copyright (C) 2017 Intel Corporation. >>>>> + * >>>>> + * Intel Video and Image Processing(VIP) Frame Buffer II driver. >>>>> + * >>>>> + * This program is free software; you can redistribute it and/or >>>>> modify it >>>>> + * under the terms and conditions of the GNU General Public >>>>> + License, >>>>> + * version 2, as published by the Free Software Foundation. >>>>> + * >>>>> + * This program is distributed in the hope it will be useful, but >>>>> WITHOUT >>>>> + * ANY WARRANTY; without even the implied warranty of >>>>> MERCHANTABILITY or >>>>> + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public >>>>> License for >>>>> + * more details. >>>>> + * >>>>> + * You should have received a copy of the GNU General Public >>>>> + License >>>>> along with >>>>> + * this program. If not, see <http://www.gnu.org/licenses/>. >>>>> + * >>>>> + * Authors: >>>>> + * Ong, Hean-Loong <hean.loong.ong@xxxxxxxxx> >>>>> + * >>>>> + */ >>>>> +#ifndef _INTEL_VIP_DRV_H >>>>> +#define _INTEL_VIP_DRV_H >>>>> +#include <linux/io.h> >>>>> +#include <linux/fb.h> >>>>> + >>>>> +#define DRIVER_NAME "intelvipfb" >>>>> +#define BYTES_PER_PIXEL 4 >>>>> +#define PREF_BPP 32 >>>>> +#define CRTC_NUM 1 >>>>> +#define CONN_NUM 1 >>>>> + >>>>> +/* control registers */ >>>>> +#define INTELVIPFB_CONTROL 0 >>>>> +#define INTELVIPFB_STATUS 0x4 >>>>> +#define INTELVIPFB_INTERRUPT 0x8 >>>>> +#define INTELVIPFB_FRAME_COUNTER 0xC >>>>> +#define INTELVIPFB_FRAME_DROP 0x10 >>>>> +#define INTELVIPFB_FRAME_INFO 0x14 >>>>> +#define INTELVIPFB_FRAME_START 0x18 >>>>> +#define INTELVIPFB_FRAME_READER 0x1C >>>>> + >>>>> +int intelvipfb_probe(struct device *dev, void __iomem *base); int >>>>> +intelvipfb_remove(struct device *dev); int >>>>> +intelvipfb_setup_crtc(struct drm_device *drm); int >>>>> +intelvipfb_drm_conn_init(struct drm_device *drm); >>>>> + >>>>> +struct intelvipfb_priv { >>>>> + struct drm_fbdev_cma *fbcma; >>>>> + struct drm_device *drm; >>>>> + struct fb_info info; >>>>> + void __iomem *base; >>>>> +}; >>>>> + >>>>> +#endif >>>>> diff --git a/drivers/gpu/drm/ivip/intel_vip_of.c >>>>> b/drivers/gpu/drm/ivip/intel_vip_of.c >>>>> new file mode 100644 >>>>> index 0000000..17dff36 >>>>> --- /dev/null >>>>> +++ b/drivers/gpu/drm/ivip/intel_vip_of.c >>>>> @@ -0,0 +1,146 @@ >>>>> +/* >>>>> + * intel_vip_of.c -- Intel Video and Image Processing(VIP) >>>>> + * Frame Buffer II driver >>>>> + * >>>>> + * This driver supports the Intel VIP Frame Reader component. >>>>> + * More info on the hardware can be found in the Intel Video >>>>> + * and Image Processing Suite User Guide at this address >>>>> + * http://www.altera.com/literature/ug/ug_vip.pdf. >>>>> + * >>>>> + * This program is free software; you can redistribute it and/or >>>>> modify it >>>>> + * under the terms and conditions of the GNU General Public >>>>> + License, >>>>> + * version 2, as published by the Free Software Foundation. >>>>> + * >>>>> + * This program is distributed in the hope it will be useful, but >>>>> WITHOUT >>>>> + * ANY WARRANTY; without even the implied warranty of >>>>> MERCHANTABILITY or >>>>> + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public >>>>> License for >>>>> + * more details. >>>>> + * >>>>> + * Authors: >>>>> + * Ong, Hean-Loong <hean.loong.ong@xxxxxxxxx> >>>>> + * >>>>> + */ >>>>> + >>>>> +#include <linux/fb.h> >>>>> +#include <linux/init.h> >>>>> +#include <linux/kernel.h> >>>>> +#include <linux/module.h> >>>>> +#include <linux/platform_device.h> >>>>> + >>>>> +#include <drm/drm_fb_helper.h> >>>>> +#include "intel_vip_drv.h" >>>>> + >>>>> +/* >>>>> + * Setting up information derived from OF Device Tree Nodes >>>>> + * max-width, max-height, bits per pixel, memory port width */ >>>>> + >>>>> +static int intelvipfb_of_setup(struct intelvipfb_priv *fbdata, >>>>> + struct platform_device *pdev) { >>>>> + int ret; >>>>> + int mem_word_width; >>>>> + u32 bits_per_color; >>>>> + struct device_node *np = pdev->dev.of_node; >>>>> + >>>>> + ret = of_property_read_u32(np, "altr,max-width", >>>>> + &fbdata->info.var.xres); >>>>> + if (ret) { >>>>> + dev_err(&pdev->dev, >>>>> + "Missing required parameter 'altr,max- >>>>> width'"); >>>>> + return ret; >>>>> + } >>>>> + fbdata->info.var.xres_virtual = fbdata->info.var.xres; >>>>> + >>>>> + ret = of_property_read_u32(np, "altr,max-height", >>>>> + &fbdata->info.var.yres); >>>>> + if (ret) { >>>>> + dev_err(&pdev->dev, >>>>> + "Missing required parameter 'altr,max- >>>>> height'"); >>>>> + return ret; >>>>> + } >>>>> + fbdata->info.var.yres_virtual = fbdata->info.var.yres; >>>>> + >>>>> + ret = of_property_read_u32(np, "altr,bits-per-symbol", >>>>> &bits_per_color); >>>>> + if (ret) { >>>>> + dev_err(&pdev->dev, >>>>> + "Missing required parameter 'altr,bits-per- >>>>> symbol'"); >>>>> + return ret; >>>>> + } >>>>> + >>>>> + fbdata->info.var.bits_per_pixel = bits_per_color * >>>>> BYTES_PER_PIXEL; >>>>> + >>>>> + ret = of_property_read_u32(np, "altr,mem-port-width", >>>>> &mem_word_width); >>>>> + if (ret) { >>>>> + dev_err(&pdev->dev, >>>>> + "Missing required parameter 'altr,mem-port- >>>>> width '"); >>>>> + return ret; >>>>> + } >>>>> + >>>>> + if (!(mem_word_width >= 32 && mem_word_width % 32 == 0)) { >>>>> + dev_err(&pdev->dev, >>>>> + "mem-word-width is set to %i. must be >= 32 >>>>> and multiple of 32.", >>>>> + mem_word_width); >>>>> + return -ENODEV; >>>>> + } >>>>> + >>>>> + return 0; >>>>> +} >>>>> + >>>>> +static int intelvipfb_of_probe(struct platform_device *pdev) { >>>>> + int retval; >>>>> + struct resource *reg_res; >>>>> + struct intelvipfb_priv *fbdata; >>>>> + >>>>> + fbdata = devm_kzalloc(&pdev->dev, sizeof(*fbdata), >>>>> GFP_KERNEL); >>>>> + if (!fbdata) >>>>> + return -ENOMEM; >>>>> + >>>>> + reg_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); >>>>> + if (!reg_res) >>>>> + return -ENOMEM; >>>>> + >>>>> + fbdata->base = devm_ioremap_resource(&pdev->dev, reg_res); >>>>> + >>>>> + if (IS_ERR(fbdata->base)) { >>>>> + dev_err(&pdev->dev, "devm_ioremap_resource >>>>> failed\n"); >>>>> + retval = PTR_ERR(fbdata->base); >>>>> + return -ENOMEM; >>>>> + } >>>>> + >>>>> + intelvipfb_of_setup(fbdata, pdev); >>>>> + >>>>> + platform_set_drvdata(pdev, fbdata); >>>>> + >>>>> + return intelvipfb_probe(&pdev->dev, fbdata->base); } >>>>> + >>>>> +static int intelvipfb_of_remove(struct platform_device *pdev) { >>>>> + return intelvipfb_remove(&pdev->dev); } >>>>> + >>>>> +/* >>>>> + * The name vip-frame-buffer-2.0 is derived from >>>>> + * http://www.altera.com/literature/ug/ug_vip.pdf >>>>> + * frame buffer IP cores section 14 */ >>>>> + >>>>> +static const struct of_device_id intelvipfb_of_match[] = { >>>>> + { .compatible = "altr,vip-frame-buffer-2.0" }, >>>>> + {}, >>>>> +}; >>>>> + >>>>> +MODULE_DEVICE_TABLE(of, intelvipfb_of_match); >>>>> + >>>>> +static struct platform_driver intelvipfb_driver = { >>>>> + .probe = intelvipfb_of_probe, >>>>> + .remove = intelvipfb_of_remove, >>>>> + .driver = { >>>>> + .name = DRIVER_NAME, >>>>> + .of_match_table = intelvipfb_of_match, >>>>> + }, >>>>> +}; >>>>> + >>>>> +module_platform_driver(intelvipfb_driver); >>>>> -- >>>>> 1.7.1 >>>>> >>>>> >>>>> -----Original Message----- >>>>> From: Ong, Hean Loong >>>>> Sent: Friday, March 31, 2017 5:09 PM >>>>> To: Vetter, Daniel <daniel.vetter@xxxxxxxxx>; airlied@xxxxxxxx >>>>> Cc: dri-devel@xxxxxxxxxxxxxxxxxxxxx >>>>> Subject: DRM Display driver for Intel FPGA Video and Image >>>>> Processing Suite >>>>> >>>>> Hi, >>>>> >>>>> I would like to upstream the attached Intel FPGA Video and Image >>>>> Processing Suite. The attached patch supports the Intel Arria10 >>>>> devkit and its variants. The purpose of the patch is to enable the >>>>> FPGA driven display designed from the Intel Quartus FPGA design >>>>> suite. >>>>> >>>>> The driver is required as part of the Intel Arria10 devkit >>>>> reference design. The driver was tested on: >>>>> - The Open Embedded Angstrom Distro. >>>>> - The matchbox-terminal and window-manager was used for functional >>>>> testing >>>>> >>>>> Current the intention of the driver is meant to validate the FPGA >>>>> designs on the Arria10 devkit for Display Port connecter. We have >>>>> not verified its performance of or stability in 3D acceleration or >>>>> other non Intel FPGA hardware >>>>> >>>>> BR >>>>> >>>>> Hean Loong >>>> _______________________________________________ >>>> dri-devel mailing list >>>> dri-devel@xxxxxxxxxxxxxxxxxxxxx >>>> https://lists.freedesktop.org/mailman/listinfo/dri-devel >>> >>> >>> >>>-- >>>Daniel Vetter >>>Software Engineer, Intel Corporation >>>+41 (0) 79 365 57 48 - http://blog.ffwll.ch > > > >-- >Daniel Vetter >Software Engineer, Intel Corporation >+41 (0) 79 365 57 48 - http://blog.ffwll.ch _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/dri-devel