Mark yao | 1 Jul 03:59 2015

Re: [PATCH v5 1/3] drm/layerscape: Add Freescale DCU DRM driver

On 2015年06月30日 18:01, Wang J.W. wrote:
From: Jianwei Wang <b52261 <at> freescale.com> This patch add support for Two Dimensional Animation and Compositing Engine (2D-ACE) on the Freescale SoCs. 2D-ACE is a Freescale display controller. 2D-ACE describes the functionality of the module extremely well its name is a value that cannot be used as a token in programming languages. Instead the valid token "DCU" is used to tag the register names and function names. The Display Controller Unit (DCU) module is a system master that fetches graphics stored in internal or external memory and displays them on a TFT LCD panel. A wide range of panel sizes is supported and the timing of the interface signals is highly configurable. Graphics are read directly from memory and then blended in real-time, which allows for dynamic content creation with minimal CPU intervention. The features: (1) Full RGB888 output to TFT LCD panel. (2) For the current LCD panel, WQVGA "480x272" is supported. (3) Blending of each pixel using up to 4 source layers dependent on size of panel. (4) Each graphic layer can be placed with one pixel resolution in either axis. (5) Each graphic layer support RGB565 and RGB888 direct colors without alpha channel and BGRA8888 BGRA4444 ARGB1555 direct colors with an alpha channel and YUV422 format. (6) Each graphic layer support alpha blending with 8-bit resolution. This is a simplified version, only one primary plane, one framebuffer created for fbdev, one crtc, one connector for TFT LCD panel, an encoder. Signed-off-by: Alison Wang <b18965 <at> freescale.com> Signed-off-by: Xiubo Li <lixiubo <at> cmss.chinamobile.com> Signed-off-by: Jianwei Wang <jianwei.wang <at> freescale.com> --- Changed in V5 - Update commit message - Add layer registers initialization - Remove unused functions - Rename driver folder - Move pixel clock control functions to fsl_dcu_drm_drv.c - remove redundant enable the clock implicitly using regmap - Add maintainer message Changed in V4: -This version doesn't have functionality changed Just a minor adjustment. Changed in V3: - Test driver on Vybrid board and add compatible string - Remove unused functions - set default crtc for encoder - replace legacy functions with atomic help functions - Set the unique name of the DRM device - Implement irq handle function for vblank interrupt Changed in v2: - Add atomic support - Modify bindings file - Rename node for compatibility - Move platform related code out for compatibility .../devicetree/bindings/drm/fsl-dcu/fsl,dcu.txt | 50 +++ MAINTAINERS | 8 + drivers/gpu/drm/Kconfig | 2 + drivers/gpu/drm/Makefile | 1 + drivers/gpu/drm/fsl-dcu/Kconfig | 17 + drivers/gpu/drm/fsl-dcu/Makefile | 7 + drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_connector.c | 194 +++++++++++ drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_connector.h | 30 ++ drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c | 172 ++++++++++ drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.h | 22 ++ drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c | 373 +++++++++++++++++++++ drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.h | 223 ++++++++++++ drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_fbdev.c | 26 ++ drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_kms.c | 42 +++ drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_kms.h | 17 + drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.c | 192 +++++++++++ drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.h | 23 ++ 17 files changed, 1399 insertions(+) create mode 100644 Documentation/devicetree/bindings/drm/fsl-dcu/fsl,dcu.txt create mode 100644 drivers/gpu/drm/fsl-dcu/Kconfig create mode 100644 drivers/gpu/drm/fsl-dcu/Makefile create mode 100644 drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_connector.c create mode 100644 drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_connector.h create mode 100644 drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c create mode 100644 drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.h create mode 100644 drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c create mode 100644 drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.h create mode 100644 drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_fbdev.c create mode 100644 drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_kms.c create mode 100644 drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_kms.h create mode 100644 drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.c create mode 100644 drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.h diff --git a/Documentation/devicetree/bindings/drm/fsl-dcu/fsl,dcu.txt b/Documentation/devicetree/bindings/drm/fsl-dcu/fsl,dcu.txt new file mode 100644 index 0000000..bdc7d5b --- /dev/null +++ b/Documentation/devicetree/bindings/drm/fsl-dcu/fsl,dcu.txt <at> <at> -0,0 +1,49 <at> <at> +Device Tree bindings for Freescale DCU DRM Driver + +Required properties: +- compatible: Should be one of + * "fsl,ls1021a-dcu". + * "fsl,vf610-dcu". +- reg: Address and length of the register set for dcu. +- clocks: From common clock binding: handle to dcu clock. +- clock-names: From common clock binding: Shall be "dcu". +- display: The phandle to display node. + +Required properties: +- bits-per-pixel: <16> for RGB565, + <24> for RGB888, + <32> for RGB8888. + +Required timing node for dispplay sub-node: +- display-timings: Refer to binding doc display-timing.txt for details. + +Examples: +dcu: dcu <at> 2ce0000 { + compatible = "fsl,ls1021a-dcu"; + reg = <0x0 0x2ce0000 0x0 0x10000>; + clocks = <&platform_clk 0>; + clock-names = "dcu"; + big-endian; + display = <&display>; + + display: display <at> 0 { + bits-per-pixel = <24>; + + display-timings { + native-mode = <&timing0>; + timing0: nl4827hc19 { + clock-frequency = <10870000>; + hactive = <480>; + vactive = <272>; + hback-porch = <2>; + hfront-porch = <2>; + vback-porch = <1>; + vfront-porch = <1>; + hsync-len = <41>; + vsync-len = <2>; + hsync-active = <1>; + vsync-active = <1>; + }; + }; + }; +}; diff --git a/MAINTAINERS b/MAINTAINERS index 885be14..a6cff2f4 100644 --- a/MAINTAINERS +++ b/MAINTAINERS <at> <at> -3398,6 +3398,14 <at> <at> S: Maintained F: drivers/gpu/drm/imx/ F: Documentation/devicetree/bindings/drm/imx/ +DRM DRIVERS FOR FREESCALE DCU +M: Jianwei Wang <jianwei.wang <at> freescale.com> +M: Alison Wang <alison.wang <at> freescale.com> +L: dri-devel <at> lists.freedesktop.org +S: Supported +F: drivers/gpu/drm/fsl-dcu/ +F: Documentation/devicetree/bindings/drm/fsl-dcu/ + DRM DRIVERS FOR NVIDIA TEGRA M: Thierry Reding <thierry.reding <at> gmail.com> M: Terje Bergström <tbergstrom <at> nvidia.com> diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index 151a050..e64cf18 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig <at> <at> -199,6 +199,8 <at> <at> source "drivers/gpu/drm/bochs/Kconfig" source "drivers/gpu/drm/msm/Kconfig" +source "drivers/gpu/drm/fsl-dcu/Kconfig" + source "drivers/gpu/drm/tegra/Kconfig" source "drivers/gpu/drm/panel/Kconfig" diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index 2c239b9..398eccf 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile <at> <at> -56,6 +56,7 <at> <at> obj-$(CONFIG_DRM_UDL) += udl/ obj-$(CONFIG_DRM_AST) += ast/ obj-$(CONFIG_DRM_ARMADA) += armada/ obj-$(CONFIG_DRM_ATMEL_HLCDC) += atmel-hlcdc/ +obj-$(CONFIG_DRM_FSL_DCU) += fsl-dcu/ obj-$(CONFIG_DRM_RCAR_DU) += rcar-du/ obj-$(CONFIG_DRM_SHMOBILE) +=shmobile/ obj-$(CONFIG_DRM_OMAP) += omapdrm/ diff --git a/drivers/gpu/drm/fsl-dcu/Kconfig b/drivers/gpu/drm/fsl-dcu/Kconfig new file mode 100644 index 0000000..e4f8df0 --- /dev/null +++ b/drivers/gpu/drm/fsl-dcu/Kconfig <at> <at> -0,0 +1,17 <at> <at> +config DRM_FSL_DCU + tristate "DRM Support for Freescale DCU" + depends on DRM && OF && ARM + select DRM_KMS_HELPER + select DRM_KMS_CMA_HELPER + select VIDEOMODE_HELPERS + select BACKLIGHT_CLASS_DEVICE + select BACKLIGHT_LCD_SUPPORT + select REGMAP_MMIO + select DRM_KMS_FB_HELPER + select FB_SYS_FILLRECT + select FB_SYS_COPYAREA + select FB_SYS_IMAGEBLIT + select FB_SYS_FOPS + help + Choose this option if you have an Freescale DCU chipset. + If M is selected the module will be called fsl-dcu-drm. diff --git a/drivers/gpu/drm/fsl-dcu/Makefile b/drivers/gpu/drm/fsl-dcu/Makefile new file mode 100644 index 0000000..336b4a6 --- /dev/null +++ b/drivers/gpu/drm/fsl-dcu/Makefile <at> <at> -0,0 +1,7 <at> <at> +fsl-dcu-drm-y := fsl_dcu_drm_drv.o \ + fsl_dcu_drm_kms.o \ + fsl_dcu_drm_connector.o \ + fsl_dcu_drm_plane.o \ + fsl_dcu_drm_crtc.o \ + fsl_dcu_drm_fbdev.o +obj-$(CONFIG_DRM_FSL_DCU) += fsl-dcu-drm.o diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_connector.c b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_connector.c new file mode 100644 index 0000000..799682d --- /dev/null +++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_connector.c <at> <at> -0,0 +1,194 <at> <at> +/* + * Copyright 2015 Freescale Semiconductor, Inc. + * + * Freescale DCU drm device driver + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include <linux/backlight.h> + +#include <drm/drmP.h> +#include <drm/drm_atomic_helper.h> +#include <video/of_display_timing.h> + +#include "fsl_dcu_drm_drv.h" +#include "fsl_dcu_drm_connector.h" + +static void fsl_dcu_drm_encoder_dpms(struct drm_encoder *encoder, int +mode) { } + +static void fsl_dcu_drm_encoder_mode_prepare(struct drm_encoder +*encoder) { } + +static void fsl_dcu_drm_encoder_mode_set(struct drm_encoder *encoder, + struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode) { } + +static void fsl_dcu_drm_encoder_mode_commit(struct drm_encoder +*encoder) { } + +static void fsl_dcu_drm_encoder_disable(struct drm_encoder *encoder) { +} + +static int +fsl_dcu_drm_encoder_atomic_check(struct drm_encoder *encoder, + struct drm_crtc_state *crtc_state, + struct drm_connector_state *conn_state) { + return 0; +} + +static void fsl_dcu_drm_encoder_destroy(struct drm_encoder *encoder) { + drm_encoder_cleanup(encoder); +} + +static const struct drm_encoder_helper_funcs encoder_helper_funcs = { + .dpms = fsl_dcu_drm_encoder_dpms, + .prepare = fsl_dcu_drm_encoder_mode_prepare, + .commit = fsl_dcu_drm_encoder_mode_commit, + .mode_set = fsl_dcu_drm_encoder_mode_set, + .disable = fsl_dcu_drm_encoder_disable, + .atomic_check = fsl_dcu_drm_encoder_atomic_check, }; + +static const struct drm_encoder_funcs encoder_funcs = { + .destroy = fsl_dcu_drm_encoder_destroy, }; + +int fsl_dcu_drm_encoder_create(struct fsl_dcu_drm_device *fsl_dev, + struct drm_crtc *crtc) +{ + struct drm_encoder *encoder = &fsl_dev->encoder; + int ret; + + encoder->possible_crtcs = 1; + ret = drm_encoder_init(fsl_dev->ddev, encoder, &encoder_funcs, + DRM_MODE_ENCODER_LVDS); + if (ret < 0) + return ret; + + drm_encoder_helper_add(encoder, &encoder_helper_funcs); + encoder->crtc = crtc; + + return 0; +} + +#define to_fsl_dcu_connector(connector) \ + container_of(connector, struct fsl_dcu_drm_connector, connector) + +static int fsl_dcu_drm_connector_get_modes(struct drm_connector +*connector) { + struct drm_device *dev = connector->dev; + struct device_node *display_np, *np = dev->dev->of_node; + struct drm_display_mode *mode = drm_mode_create(connector->dev); + int num_modes = 0; + + if (np) { + display_np = of_parse_phandle(np, "display", 0); + if (!display_np) { + dev_err(dev->dev, "failed to find display phandle\n"); + return num_modes; + }
Use panel-simple driver instead the display node timing I think is better.
See Documentation/devicetree/bindings/panel/simple-panel.txt and
       drivers/gpu/drm/panel/panel-simple.c

Panel info add into panel driver, other people will easy to reuse the panel.

+ of_get_drm_display_mode(display_np, mode, OF_USE_NATIVE_MODE); + mode->type |= DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED, + drm_mode_probed_add(connector, mode); + num_modes++; + } + + return num_modes; +} + +static int fsl_dcu_drm_connector_mode_valid(struct drm_connector *connector, + struct drm_display_mode *mode) { + return MODE_OK; +} + +static struct drm_encoder * +fsl_dcu_drm_connector_best_encoder(struct drm_connector *connector) { + struct fsl_dcu_drm_connector *fsl_con = +to_fsl_dcu_connector(connector); + + return fsl_con->encoder; +} + +static void fsl_dcu_drm_connector_destroy(struct drm_connector +*connector) { + drm_connector_unregister(connector); + drm_connector_cleanup(connector); +} + +static enum drm_connector_status +fsl_dcu_drm_connector_detect(struct drm_connector *connector, bool +force) { + return connector_status_connected; +} + +static const struct drm_connector_funcs fsl_dcu_drm_connector_funcs = { + .dpms = drm_atomic_helper_connector_dpms, + .reset = drm_atomic_helper_connector_reset, + .detect = fsl_dcu_drm_connector_detect, + .fill_modes = drm_helper_probe_single_connector_modes, + .destroy = fsl_dcu_drm_connector_destroy, + .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, + .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, +}; + +static const struct drm_connector_helper_funcs connector_helper_funcs = { + .get_modes = fsl_dcu_drm_connector_get_modes, + .mode_valid = fsl_dcu_drm_connector_mode_valid, + .best_encoder = fsl_dcu_drm_connector_best_encoder, +}; + +int fsl_dcu_drm_connector_create(struct fsl_dcu_drm_device *fsl_dev, + struct drm_encoder *encoder) +{ + struct drm_connector *connector = &fsl_dev->connector.connector; + int ret; + + fsl_dev->connector.encoder = encoder; + + connector->display_info.width_mm = 0; + connector->display_info.height_mm = 0; + + ret = drm_connector_init(fsl_dev->ddev, connector, + &fsl_dcu_drm_connector_funcs, + DRM_MODE_CONNECTOR_LVDS); + if (ret < 0) + return ret; + + connector->dpms = DRM_MODE_DPMS_OFF; + drm_connector_helper_add(connector, &connector_helper_funcs); + ret = drm_connector_register(connector); + if (ret < 0) + goto err_cleanup; + + ret = drm_mode_connector_attach_encoder(connector, encoder); + if (ret < 0) + goto err_sysfs; + + connector->encoder = encoder; + + drm_object_property_set_value + (&connector->base, fsl_dev->ddev->mode_config.dpms_property, + DRM_MODE_DPMS_OFF); + + return 0; + +err_sysfs: + drm_connector_unregister(connector); +err_cleanup: + drm_connector_cleanup(connector); + return ret; +} diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_connector.h b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_connector.h new file mode 100644 index 0000000..8141a29 --- /dev/null +++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_connector.h <at> <at> -0,0 +1,30 <at> <at> +/* + * Copyright 2015 Freescale Semiconductor, Inc. + * + * Freescale DCU drm device driver + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#ifndef __FSL_DCU_DRM_CONNECTOR_H__ +#define __FSL_DCU_DRM_CONNECTOR_H__ + +#include <drm/drmP.h> +#include <drm/drm_crtc.h> +#include "fsl_dcu_drm_crtc.h" + +struct fsl_dcu_drm_device; +struct fsl_dcu_drm_connector { + struct drm_connector connector; + struct drm_encoder *encoder; +}; + +int fsl_dcu_drm_encoder_create(struct fsl_dcu_drm_device *fsl_dev, + struct drm_crtc *crtc); +int fsl_dcu_drm_connector_create(struct fsl_dcu_drm_device *fsl_dev, + struct drm_encoder *encoder); + +#endif /* __FSL_DCU_DRM_CONNECTOR_H__ */ diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c new file mode 100644 index 0000000..4065a7c --- /dev/null +++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c <at> <at> -0,0 +1,172 <at> <at> +/* + * Copyright 2015 Freescale Semiconductor, Inc. + * + * Freescale DCU drm device driver + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include <linux/regmap.h> +#include <linux/clk.h> + +#include <drm/drmP.h> +#include <drm/drm_atomic.h> +#include <drm/drm_atomic_helper.h> +#include <drm/drm_crtc.h> + +#include "fsl_dcu_drm_crtc.h" +#include "fsl_dcu_drm_drv.h" +#include "fsl_dcu_drm_plane.h" + +#define to_fsl_dcu_crtc(c) container_of(c, struct fsl_dcu_drm_crtc, crtc) + +static void fsl_dcu_drm_crtc_mode_set_nofb(struct drm_crtc *crtc) { + struct drm_device *dev = crtc->dev; + struct fsl_dcu_drm_device *fsl_dev = dev->dev_private; + struct drm_display_mode *mode = &crtc->state->mode; + uint32_t hbp, hfp, hsw, vbp, vfp, vsw, div, index; + + DBG(": set mode: %d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x", + mode->base.id, mode->name, + mode->vrefresh, mode->clock, + mode->hdisplay, mode->hsync_start, + mode->hsync_end, mode->htotal, + mode->vdisplay, mode->vsync_start, + mode->vsync_end, mode->vtotal, + mode->type, mode->flags); + + index = drm_crtc_index(crtc); + div = (uint32_t)clk_get_rate(fsl_dev->clk) / mode->clock / 1000; + + /* Configure timings: */ + hbp = mode->htotal - mode->hsync_end; + hfp = mode->hsync_start - mode->hdisplay; + hsw = mode->hsync_end - mode->hsync_start; + vbp = mode->vtotal - mode->vsync_end; + vfp = mode->vsync_start - mode->vdisplay; + vsw = mode->vsync_end - mode->vsync_start; + + regmap_write(fsl_dev->regmap, DCU_HSYN_PARA, + DCU_HSYN_PARA_BP(hbp) | + DCU_HSYN_PARA_PW(hsw) | + DCU_HSYN_PARA_FP(hfp)); + regmap_write(fsl_dev->regmap, DCU_VSYN_PARA, + DCU_VSYN_PARA_BP(vbp) | + DCU_VSYN_PARA_PW(vsw) | + DCU_VSYN_PARA_FP(vfp)); + regmap_write(fsl_dev->regmap, DCU_DISP_SIZE, + DCU_DISP_SIZE_DELTA_Y(mode->vdisplay) | + DCU_DISP_SIZE_DELTA_X(mode->hdisplay)); + regmap_write(fsl_dev->regmap, DCU_DIV_RATIO, div); + regmap_write(fsl_dev->regmap, DCU_UPDATE_MODE, +DCU_UPDATE_MODE_READREG); } + +static bool fsl_dcu_drm_crtc_mode_fixup(struct drm_crtc *crtc, + const struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode) { + return true; +} + +static void fsl_dcu_drm_crtc_prepare(struct drm_crtc *crtc) { } + +/* Now enable the clocks, plane, pipe, and connectors that we set up. +*/ static void fsl_dcu_drm_crtc_mode_commit(struct drm_crtc *crtc) { } + +static int fsl_dcu_drm_crtc_atomic_check(struct drm_crtc *crtc, + struct drm_crtc_state *state) +{ + return 0; +} + +static void fsl_dcu_drm_crtc_atomic_begin(struct drm_crtc *crtc) { } + +static void fsl_dcu_drm_crtc_atomic_flush(struct drm_crtc *crtc) { } + +static void fsl_dcu_drm_disable_crtc(struct drm_crtc *crtc) { } + +static void fsl_dcu_drm_crtc_dpms(struct drm_crtc *crtc, int mode) { } + +static const struct drm_crtc_funcs fsl_dcu_drm_crtc_funcs = { + .page_flip = drm_atomic_helper_page_flip, + .set_config = drm_atomic_helper_set_config, + .destroy = drm_crtc_cleanup, + .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 const struct drm_crtc_helper_funcs fsl_dcu_drm_crtc_helper_funcs = { + .disable = fsl_dcu_drm_disable_crtc, + .mode_fixup = fsl_dcu_drm_crtc_mode_fixup, + .mode_set = drm_helper_crtc_mode_set, + .mode_set_nofb = fsl_dcu_drm_crtc_mode_set_nofb, + .mode_set_base = drm_helper_crtc_mode_set_base, + .prepare = fsl_dcu_drm_crtc_prepare, + .commit = fsl_dcu_drm_crtc_mode_commit, + .atomic_check = fsl_dcu_drm_crtc_atomic_check, + .atomic_begin = fsl_dcu_drm_crtc_atomic_begin, + .atomic_flush = fsl_dcu_drm_crtc_atomic_flush, + .dpms = fsl_dcu_drm_crtc_dpms, +}; + +int fsl_dcu_drm_crtc_create(struct fsl_dcu_drm_device *fsl_dev) { + struct drm_plane *primary; + struct drm_crtc *crtc = &fsl_dev->crtc; + int i, ret; + + primary = fsl_dcu_drm_primary_create_plane(fsl_dev->ddev); + ret = drm_crtc_init_with_planes(fsl_dev->ddev, crtc, primary, NULL, + &fsl_dcu_drm_crtc_funcs); + if (ret < 0) + return ret; + + drm_crtc_helper_add(crtc, &fsl_dcu_drm_crtc_helper_funcs); + + for (i = 0; i < DCU_TOTAL_LAYER_NUM; i++) { + regmap_write(fsl_dev->regmap, DCU_CTRLDESCLN_1(i), 0); + regmap_write(fsl_dev->regmap, DCU_CTRLDESCLN_2(i), 0); + regmap_write(fsl_dev->regmap, DCU_CTRLDESCLN_3(i), 0); + regmap_write(fsl_dev->regmap, DCU_CTRLDESCLN_4(i), 0); + regmap_write(fsl_dev->regmap, DCU_CTRLDESCLN_5(i), 0); + regmap_write(fsl_dev->regmap, DCU_CTRLDESCLN_6(i), 0); + regmap_write(fsl_dev->regmap, DCU_CTRLDESCLN_7(i), 0); + regmap_write(fsl_dev->regmap, DCU_CTRLDESCLN_8(i), 0); + regmap_write(fsl_dev->regmap, DCU_CTRLDESCLN_9(i), 0); + if (of_device_is_compatible(fsl_dev->np, "fsl,ls1021a-dcu")) + regmap_write(fsl_dev->regmap, DCU_CTRLDESCLN_10(i), 0); + } + regmap_write(fsl_dev->regmap, DCU_SYN_POL, + DCU_SYN_POL_INV_VS_LOW | DCU_SYN_POL_INV_HS_LOW); + regmap_write(fsl_dev->regmap, DCU_BGND, DCU_BGND_R(0) | + DCU_BGND_G(0) | DCU_BGND_B(0)); + regmap_write(fsl_dev->regmap, DCU_DCU_MODE, + DCU_MODE_BLEND_ITER(1) | DCU_MODE_RASTER_EN); + regmap_write(fsl_dev->regmap, DCU_THRESHOLD, + DCU_THRESHOLD_LS_BF_VS(BF_VS_VAL) | + DCU_THRESHOLD_OUT_BUF_HIGH(BUF_MAX_VAL) | + DCU_THRESHOLD_OUT_BUF_LOW(BUF_MIN_VAL)); + regmap_update_bits(fsl_dev->regmap, DCU_DCU_MODE, + DCU_MODE_DCU_MODE_MASK, + DCU_MODE_DCU_MODE(DCU_MODE_OFF)); + regmap_write(fsl_dev->regmap, DCU_UPDATE_MODE, +DCU_UPDATE_MODE_READREG); + + return 0; +} diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.h b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.h new file mode 100644 index 0000000..193785f --- /dev/null +++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.h <at> <at> -0,0 +1,22 <at> <at> +/* + * Copyright 2015 Freescale Semiconductor, Inc. + * + * Freescale DCU drm device driver + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#ifndef __FSL_DCU_DRM_CRTC_H__ +#define __FSL_DCU_DRM_CRTC_H__ + +#include <drm/drmP.h> +#include <drm/drm_crtc.h> + +struct fsl_dcu_drm_device; + +int fsl_dcu_drm_crtc_create(struct fsl_dcu_drm_device *fsl_dev); + +#endif /* __FSL_DCU_DRM_CRTC_H__ */ diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c new file mode 100644 index 0000000..1edf7be --- /dev/null +++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c <at> <at> -0,0 +1,373 <at> <at> +/* + * Copyright 2015 Freescale Semiconductor, Inc. + * + * Freescale DCU drm device driver + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include <linux/clk.h> +#include <linux/io.h> +#include <linux/mm.h> +#include <linux/module.h> +#include <linux/of_platform.h> +#include <linux/platform_device.h> +#include <linux/pm.h> +#include <linux/pm_runtime.h> +#include <linux/regmap.h> +#include <linux/mfd/syscon.h> + +#include <drm/drmP.h> + +#include "fsl_dcu_drm_drv.h" +#include "fsl_dcu_drm_crtc.h" +#include "fsl_dcu_drm_kms.h" + +static int fsl_dcu_unload(struct drm_device *dev) { + drm_mode_config_cleanup(dev); + drm_vblank_cleanup(dev); + drm_irq_uninstall(dev); + + dev->dev_private = NULL; + + return 0; +} + +static struct regmap_config fsl_dcu_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, +}; + +static int fsl_dcu_bypass_tcon(struct fsl_dcu_drm_device *fsl_dev, + struct device_node *np) +{ + struct device_node *tcon_np; + struct platform_device *pdev; + struct clk *tcon_clk; + struct resource *res; + void __iomem *base; + + tcon_np = of_parse_phandle(np, "tcon-controller", 0); + if (!tcon_np) + return -EINVAL; + + pdev = of_find_device_by_node(tcon_np); + if (!pdev) + return -EINVAL; + + tcon_clk = devm_clk_get(&pdev->dev, "tcon"); + if (IS_ERR(tcon_clk)) + return PTR_ERR(tcon_clk); + clk_prepare_enable(tcon_clk); + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) + return -ENODEV; + + base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(base)) + return PTR_ERR(base); + + fsl_dev->tcon_regmap = devm_regmap_init_mmio(&pdev->dev, + base, &fsl_dcu_regmap_config); + if (IS_ERR(fsl_dev->tcon_regmap)) { + dev_err(&pdev->dev, "regmap init failed\n"); + return PTR_ERR(fsl_dev->tcon_regmap); + } + + regmap_write(fsl_dev->tcon_regmap, TCON_CTRL1, TCON_BYPASS_ENABLE); + return 0; +} + +static void dcu_pixclk_enable(void) +{ + struct regmap *scfg_regmap; + + scfg_regmap = syscon_regmap_lookup_by_compatible("fsl,ls1021a-scfg"); + if (IS_ERR(scfg_regmap)) { + pr_err("No syscfg phandle specified\n"); + return; + } + + regmap_write(scfg_regmap, SCFG_PIXCLKCR, PXCK_ENABLE); } + +static int fsl_dcu_drm_irq_init(struct drm_device *dev) { + struct platform_device *pdev = dev->platformdev; + struct fsl_dcu_drm_device *fsl_dev = dev->dev_private; + unsigned int int_mask; + int ret; + + ret = drm_irq_install(dev, platform_get_irq(dev->platformdev, 0)); + if (ret < 0) + dev_err(&pdev->dev, "failed to install IRQ handler\n"); + + dev->irq_enabled = true; + dev->vblank_disable_allowed = true; + + regmap_write(fsl_dev->regmap, DCU_INT_STATUS, 0); + regmap_read(fsl_dev->regmap, DCU_INT_MASK, &int_mask); + regmap_write(fsl_dev->regmap, DCU_INT_MASK, int_mask & + ~DCU_INT_MASK_VBLANK); + regmap_write(fsl_dev->regmap, DCU_UPDATE_MODE, +DCU_UPDATE_MODE_READREG); + + return 0; +} + +static int fsl_dcu_load(struct drm_device *dev, unsigned long flags) { + struct platform_device *pdev = dev->platformdev; + struct fsl_dcu_drm_device *fsl_dev; + struct resource *res; + void __iomem *base; + int ret; + + fsl_dev = devm_kzalloc(&pdev->dev, sizeof(*fsl_dev), GFP_KERNEL); + if (!fsl_dev) + return -ENOMEM; + + fsl_dev->dev = &pdev->dev; + fsl_dev->ddev = dev; + fsl_dev->np = pdev->dev.of_node; + dev->dev_private = fsl_dev; + dev_set_drvdata(dev->dev, fsl_dev); + drm_dev_set_unique(dev, dev_name(dev->dev)); + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(&pdev->dev, "could not get memory IO resource\n"); + return -ENODEV; + } + + base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(base)) { + ret = PTR_ERR(base); + return ret; + } + + fsl_dev->clk = devm_clk_get(&pdev->dev, "dcu"); + if (IS_ERR(fsl_dev->clk)) { + ret = PTR_ERR(fsl_dev->clk); + dev_err(&pdev->dev, "could not get clock\n"); + return ret; + } + clk_prepare_enable(fsl_dev->clk); + fsl_dev->regmap = devm_regmap_init_mmio(&pdev->dev, base, + &fsl_dcu_regmap_config); + if (IS_ERR(fsl_dev->regmap)) { + dev_err(&pdev->dev, "regmap init failed\n"); + return PTR_ERR(fsl_dev->regmap); + } + + /* Put TCON in bypass mode, so the input signals from DCU are passed + * through TCON unchanged */ + fsl_dcu_bypass_tcon(fsl_dev, fsl_dev->np); + + if (of_device_is_compatible(fsl_dev->np, "fsl,ls1021a-dcu")) + dcu_pixclk_enable(); + ret = fsl_dcu_drm_modeset_init(fsl_dev); + if (ret < 0) { + dev_err(&pdev->dev, "failed to initialize mode setting\n"); + return ret; + } + + ret = drm_vblank_init(dev, dev->mode_config.num_crtc); + if (ret < 0) { + dev_err(&pdev->dev, "failed to initialize vblank\n"); + goto done; + } + + ret = fsl_dcu_drm_irq_init(dev); + if (ret < 0) + goto done; + + fsl_dcu_fbdev_init(dev); + + return 0; +done: + if (ret) + fsl_dcu_unload(dev); + + return ret; +} + +static void fsl_dcu_drm_preclose(struct drm_device *dev, struct +drm_file *file) { } + +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; + + regmap_read(fsl_dev->regmap, DCU_INT_STATUS, &int_status); + if (int_status & DCU_INT_STATUS_VBLANK) + drm_handle_vblank(dev, 0); + + regmap_write(fsl_dev->regmap, DCU_INT_STATUS, 0xffffffff); + regmap_write(fsl_dev->regmap, DCU_UPDATE_MODE, +DCU_UPDATE_MODE_READREG); + + return IRQ_HANDLED; +} + +static int fsl_dcu_drm_enable_vblank(struct drm_device *dev, int crtc) +{ + return 0; +} + +static void fsl_dcu_drm_disable_vblank(struct drm_device *dev, int +crtc) { } + +static const struct file_operations fsl_dcu_drm_fops = { + .owner = THIS_MODULE, + .open = drm_open, + .release = drm_release, + .unlocked_ioctl = drm_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = drm_compat_ioctl, +#endif + .poll = drm_poll, + .read = drm_read, + .llseek = no_llseek, + .mmap = drm_gem_cma_mmap, +}; + +static struct drm_driver fsl_dcu_drm_driver = { + .driver_features = DRIVER_HAVE_IRQ | DRIVER_GEM | DRIVER_MODESET + | DRIVER_PRIME,

Your patch support atomic, I think driver_features need add DRIVER_ATOMIC

+ .load = fsl_dcu_load, + .unload = fsl_dcu_unload, + .preclose = fsl_dcu_drm_preclose, + .irq_handler = fsl_dcu_drm_irq, + .get_vblank_counter = drm_vblank_count, + .enable_vblank = fsl_dcu_drm_enable_vblank, + .disable_vblank = fsl_dcu_drm_disable_vblank, + .gem_free_object = drm_gem_cma_free_object, + .gem_vm_ops = &drm_gem_cma_vm_ops, + .prime_handle_to_fd = drm_gem_prime_handle_to_fd, + .prime_fd_to_handle = drm_gem_prime_fd_to_handle, + .gem_prime_import = drm_gem_prime_import, + .gem_prime_export = drm_gem_prime_export, + .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, + .dumb_create = drm_gem_cma_dumb_create, + .dumb_map_offset = drm_gem_cma_dumb_map_offset, + .dumb_destroy = drm_gem_dumb_destroy, + .fops = &fsl_dcu_drm_fops, + .name = "fsl-dcu-drm", + .desc = "Freescale DCU DRM", + .date = "20150213", + .major = 1, + .minor = 0, +}; + +#ifdef CONFIG_PM_SLEEP +static void dcu_pixclk_disable(void) +{ + struct regmap *scfg_regmap; + + scfg_regmap = syscon_regmap_lookup_by_compatible("fsl,ls1021a-scfg"); + if (IS_ERR(scfg_regmap)) { + pr_err("No syscfg phandle specified\n"); + return; + } + + regmap_write(scfg_regmap, SCFG_PIXCLKCR, PXCK_DISABLE); } + +static int fsl_dcu_drm_pm_suspend(struct device *dev) { + struct fsl_dcu_drm_device *fsl_dev = dev_get_drvdata(dev);
Andrzej Hajda told me at my drm driver: drm_dev can be NULL here, it can happen when system is suspended before all components are bound. It can also contain invalid pointer if after successfull drm initialization de-initialization happens for some reason. Some workaround is to check for null here and set drvdata to null on master unbind. But I guess it should be protected somehow to avoid races in accessing drvdata. You didn't use components, but maybe fsl_dev can be NULL for some reason as Andrzej said.
+ + if (of_device_is_compatible(fsl_dev->np, "fsl,ls1021a-dcu")) + dcu_pixclk_disable(); + + drm_kms_helper_poll_disable(fsl_dev->ddev); + regcache_cache_only(fsl_dev->regmap, true); + regcache_mark_dirty(fsl_dev->regmap); + clk_disable_unprepare(fsl_dev->clk); + + if (fsl_dev->tcon_regmap) { + regcache_cache_only(fsl_dev->tcon_regmap, true); + regcache_mark_dirty(fsl_dev->tcon_regmap); + clk_disable_unprepare(fsl_dev->tcon_clk); + } + + return 0; +} + +static int fsl_dcu_drm_pm_resume(struct device *dev) { + struct fsl_dcu_drm_device *fsl_dev = dev_get_drvdata(dev); + + /* Enable clocks and restore all registers */ + if (fsl_dev->tcon_regmap) { + clk_prepare_enable(fsl_dev->tcon_clk); + regcache_cache_only(fsl_dev->tcon_regmap, false); + regcache_sync(fsl_dev->tcon_regmap); + } + + clk_prepare_enable(fsl_dev->clk); + drm_kms_helper_poll_enable(fsl_dev->ddev); + regcache_cache_only(fsl_dev->regmap, false); + regcache_sync(fsl_dev->regmap); + + if (of_device_is_compatible(fsl_dev->np, "fsl,ls1021a-dcu")) + dcu_pixclk_enable(); + + return 0; +} +#endif + +static const struct dev_pm_ops fsl_dcu_drm_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(fsl_dcu_drm_pm_suspend, fsl_dcu_drm_pm_resume) +}; + +static int fsl_dcu_drm_probe(struct platform_device *pdev) { + return drm_platform_init(&fsl_dcu_drm_driver, pdev); } + +static int fsl_dcu_drm_remove(struct platform_device *pdev) { + struct fsl_dcu_drm_device *fsl_dev = platform_get_drvdata(pdev); + + drm_put_dev(fsl_dev->ddev); + + return 0; +} + +static const struct of_device_id fsl_dcu_of_match[] = { + { .compatible = "fsl,ls1021a-dcu", }, + { .compatible = "fsl,vf610-dcu", }, + { }, +}; +MODULE_DEVICE_TABLE(of, fsl_dcu_of_match); + +static struct platform_driver fsl_dcu_drm_platform_driver = { + .probe = fsl_dcu_drm_probe, + .remove = fsl_dcu_drm_remove, + .driver = { + .owner = THIS_MODULE, + .name = "fsl,dcu", + .pm = &fsl_dcu_drm_pm_ops, + .of_match_table = fsl_dcu_of_match, + }, +}; + +module_platform_driver(fsl_dcu_drm_platform_driver); + +MODULE_ALIAS("platform:fsl-dcu-drm"); +MODULE_DESCRIPTION("Freescale DCU DRM Driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.h b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.h new file mode 100644 index 0000000..40df1c5 --- /dev/null +++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.h <at> <at> -0,0 +1,223 <at> <at> +/* + * Copyright 2015 Freescale Semiconductor, Inc. + * + * Freescale DCU drm device driver + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#ifndef __FSL_DCU_DRM_DRV_H__ +#define __FSL_DCU_DRM_DRV_H__ + +#include <linux/kernel.h> +#include <linux/spinlock.h> +#include <stddef.h> +#include <drm/drm.h> +#include <drm/drmP.h> +#include <drm/drm_fb_helper.h> +#include <drm/drm_crtc_helper.h> +#include <drm/drm_gem_cma_helper.h> +#include <drm/drm_fb_cma_helper.h> + +#include "fsl_dcu_drm_crtc.h" +#include "fsl_dcu_drm_plane.h" +#include "fsl_dcu_drm_connector.h" +#define DRIVER_NAME "fsl-dcu-drm" + +#define DCU_DCU_MODE 0x0010 +#define DCU_MODE_BLEND_ITER(x) ((x) << 20) +#define DCU_MODE_RASTER_EN BIT(14) +#define DCU_MODE_DCU_MODE(x) (x) +#define DCU_MODE_DCU_MODE_MASK 0x03 +#define DCU_MODE_OFF 0 +#define DCU_MODE_NORMAL 1 +#define DCU_MODE_TEST 2 +#define DCU_MODE_COLORBAR 3 + +#define DCU_BGND 0x0014 +#define DCU_BGND_R(x) ((x) << 16) +#define DCU_BGND_G(x) ((x) << 8) +#define DCU_BGND_B(x) (x) + +#define DCU_DISP_SIZE 0x0018 +#define DCU_DISP_SIZE_DELTA_Y(x) ((x) << 16) +/*Regisiter value 1/16 of horizontal resolution*/ +#define DCU_DISP_SIZE_DELTA_X(x) ((x) >> 4) + +#define DCU_HSYN_PARA 0x001c +#define DCU_HSYN_PARA_BP(x) ((x) << 22) +#define DCU_HSYN_PARA_PW(x) ((x) << 11) +#define DCU_HSYN_PARA_FP(x) (x) + +#define DCU_VSYN_PARA 0x0020 +#define DCU_VSYN_PARA_BP(x) ((x) << 22) +#define DCU_VSYN_PARA_PW(x) ((x) << 11) +#define DCU_VSYN_PARA_FP(x) (x) + +#define DCU_SYN_POL 0x0024 +#define DCU_SYN_POL_INV_PXCK_FALL (0 << 6) +#define DCU_SYN_POL_NEG_REMAIN (0 << 5) +#define DCU_SYN_POL_INV_VS_LOW BIT(1) +#define DCU_SYN_POL_INV_HS_LOW BIT(0) + +#define DCU_THRESHOLD 0x0028 +#define DCU_THRESHOLD_LS_BF_VS(x) ((x) << 16) +#define DCU_THRESHOLD_OUT_BUF_HIGH(x) ((x) << 8) +#define DCU_THRESHOLD_OUT_BUF_LOW(x) (x) +#define BF_VS_VAL 0x03 +#define BUF_MAX_VAL 0x78 +#define BUF_MIN_VAL 0x0a + +#define DCU_INT_STATUS 0x002C +#define DCU_INT_STATUS_VSYNC BIT(0) +#define DCU_INT_STATUS_UNDRUN BIT(1) +#define DCU_INT_STATUS_LSBFVS BIT(2) +#define DCU_INT_STATUS_VBLANK BIT(3) +#define DCU_INT_STATUS_CRCREADY BIT(4) +#define DCU_INT_STATUS_CRCOVERFLOW BIT(5) +#define DCU_INT_STATUS_P1FIFOLO BIT(6) +#define DCU_INT_STATUS_P1FIFOHI BIT(7) +#define DCU_INT_STATUS_P2FIFOLO BIT(8) +#define DCU_INT_STATUS_P2FIFOHI BIT(9) +#define DCU_INT_STATUS_PROGEND BIT(10) +#define DCU_INT_STATUS_IPMERROR BIT(11) +#define DCU_INT_STATUS_LYRTRANS BIT(12) +#define DCU_INT_STATUS_DMATRANS BIT(14) +#define DCU_INT_STATUS_P3FIFOLO BIT(16) +#define DCU_INT_STATUS_P3FIFOHI BIT(17) +#define DCU_INT_STATUS_P4FIFOLO BIT(18) +#define DCU_INT_STATUS_P4FIFOHI BIT(19) +#define DCU_INT_STATUS_P1EMPTY BIT(26) +#define DCU_INT_STATUS_P2EMPTY BIT(27) +#define DCU_INT_STATUS_P3EMPTY BIT(28) +#define DCU_INT_STATUS_P4EMPTY BIT(29) + +#define DCU_INT_MASK 0x0030 +#define DCU_INT_MASK_VSYNC BIT(0) +#define DCU_INT_MASK_UNDRUN BIT(1) +#define DCU_INT_MASK_LSBFVS BIT(2) +#define DCU_INT_MASK_VBLANK BIT(3) +#define DCU_INT_MASK_CRCREADY BIT(4) +#define DCU_INT_MASK_CRCOVERFLOW BIT(5) +#define DCU_INT_MASK_P1FIFOLO BIT(6) +#define DCU_INT_MASK_P1FIFOHI BIT(7) +#define DCU_INT_MASK_P2FIFOLO BIT(8) +#define DCU_INT_MASK_P2FIFOHI BIT(9) +#define DCU_INT_MASK_PROGEND BIT(10) +#define DCU_INT_MASK_IPMERROR BIT(11) +#define DCU_INT_MASK_LYRTRANS BIT(12) +#define DCU_INT_MASK_DMATRANS BIT(14) +#define DCU_INT_MASK_P3FIFOLO BIT(16) +#define DCU_INT_MASK_P3FIFOHI BIT(17) +#define DCU_INT_MASK_P4FIFOLO BIT(18) +#define DCU_INT_MASK_P4FIFOHI BIT(19) +#define DCU_INT_MASK_P1EMPTY BIT(26) +#define DCU_INT_MASK_P2EMPTY BIT(27) +#define DCU_INT_MASK_P3EMPTY BIT(28) +#define DCU_INT_MASK_P4EMPTY BIT(29) + +#define DCU_DIV_RATIO 0x0054 + +#define DCU_UPDATE_MODE 0x00cc +#define DCU_UPDATE_MODE_MODE BIT(31) +#define DCU_UPDATE_MODE_READREG BIT(30) + +#define DCU_DCFB_MAX 0x300 + +#define DCU_CTRLDESCLN_1(x) (0x200 + (x) * 0x40) +#define DCU_CTRLDESCLN_1_HEIGHT(x) ((x) << 16) +#define DCU_CTRLDESCLN_1_WIDTH(x) (x) + +#define DCU_CTRLDESCLN_2(x) (0x204 + (x) * 0x40) +#define DCU_CTRLDESCLN_2_POSY(x) ((x) << 16) +#define DCU_CTRLDESCLN_2_POSX(x) (x) + +#define DCU_CTRLDESCLN_3(x) (0x208 + (x) * 0x40) + +#define DCU_CTRLDESCLN_4(x) (0x20c + (x) * 0x40) +#define DCU_CTRLDESCLN_4_EN BIT(31) +#define DCU_CTRLDESCLN_4_TILE_EN BIT(30) +#define DCU_CTRLDESCLN_4_DATA_SEL_CLUT BIT(29) +#define DCU_CTRLDESCLN_4_SAFETY_EN BIT(28) +#define DCU_CTRLDESCLN_4_TRANS(x) ((x) << 20) +#define DCU_CTRLDESCLN_4_BPP(x) ((x) << 16) +#define DCU_CTRLDESCLN_4_RLE_EN BIT(15) +#define DCU_CTRLDESCLN_4_LUOFFS(x) ((x) << 4) +#define DCU_CTRLDESCLN_4_BB_ON BIT(2) +#define DCU_CTRLDESCLN_4_AB(x) (x) + +#define DCU_CTRLDESCLN_5(x) (0x210 + (x) * 0x40) +#define DCU_CTRLDESCLN_5_CKMAX_R(x) ((x) << 16) +#define DCU_CTRLDESCLN_5_CKMAX_G(x) ((x) << 8) +#define DCU_CTRLDESCLN_5_CKMAX_B(x) (x) + +#define DCU_CTRLDESCLN_6(x) (0x214 + (x) * 0x40) +#define DCU_CTRLDESCLN_6_CKMIN_R(x) ((x) << 16) +#define DCU_CTRLDESCLN_6_CKMIN_G(x) ((x) << 8) +#define DCU_CTRLDESCLN_6_CKMIN_B(x) (x) + +#define DCU_CTRLDESCLN_7(x) (0x218 + (x) * 0x40) +#define DCU_CTRLDESCLN_7_TILE_VER(x) ((x) << 16) +#define DCU_CTRLDESCLN_7_TILE_HOR(x) (x) + +#define DCU_CTRLDESCLN_8(x) (0x21c + (x) * 0x40) +#define DCU_CTRLDESCLN_8_FG_FCOLOR(x) (x) + +#define DCU_CTRLDESCLN_9(x) (0x220 + (x) * 0x40) +#define DCU_CTRLDESCLN_9_BG_BCOLOR(x) (x) + +#define DCU_CTRLDESCLN_10(x) (0x224 + (x) * 0x40) +#define DCU_CTRLDESCLN_10_POST_SKIP(x) ((x) << 16) +#define DCU_CTRLDESCLN_10_PRE_SKIP(x) (x) + +#ifdef CONFIG_SOC_VF610 +#define DCU_TOTAL_LAYER_NUM 64 +#define DCU_LAYER_NUM_MAX 6 +#else +#define DCU_TOTAL_LAYER_NUM 16 +#define DCU_LAYER_NUM_MAX 4 +#endif + +#define FSL_DCU_RGB565 4 +#define FSL_DCU_RGB888 5 +#define FSL_DCU_ARGB8888 6 +#define FSL_DCU_ARGB1555 11 +#define FSL_DCU_ARGB4444 12 +#define FSL_DCU_YUV422 14 + +#define TCON_CTRL1 0x0000 +#define TCON_BYPASS_ENABLE BIT(29) + +#define SCFG_PIXCLKCR 0x28 +#define PXCK_ENABLE BIT(31) +#define PXCK_DISABLE 0 + +#define DBG(fmt, ...) DRM_DEBUG(fmt"\n", ##__VA_ARGS__) + +struct clk; +struct device; +struct drm_device; + +struct fsl_dcu_drm_device { + struct device *dev; + struct device_node *np; + struct regmap *regmap; + struct regmap *tcon_regmap; + unsigned int irq; + struct clk *clk; + struct clk *tcon_clk; + /*protects hardware register*/ + spinlock_t irq_lock; + struct drm_device *ddev; + struct drm_fbdev_cma *fbdev; + struct drm_crtc crtc; + struct drm_encoder encoder; + struct fsl_dcu_drm_connector connector; }; + +void fsl_dcu_fbdev_init(struct drm_device *dev); + +#endif /* __FSL_DCU_DRM_DRV_H__ */ diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_fbdev.c b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_fbdev.c new file mode 100644 index 0000000..f8ef0e1 --- /dev/null +++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_fbdev.c <at> <at> -0,0 +1,26 <at> <at> +/* + * Copyright 2015 Freescale Semiconductor, Inc. + * + * This program is free software; you can redistribute it and/or modify +it + * under the terms of the GNU General Public License version 2 as +published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but +WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +License for + * more details. + * + */ + +#include <drm/drmP.h> +#include <drm/drm_fb_cma_helper.h> + +#include "fsl_dcu_drm_drv.h" + +/* initialize fbdev helper */ +void fsl_dcu_fbdev_init(struct drm_device *dev) { + struct fsl_dcu_drm_device *fsl_dev = dev_get_drvdata(dev->dev); + + fsl_dev->fbdev = drm_fbdev_cma_init(dev, 24, 1, 1); } diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_kms.c b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_kms.c new file mode 100644 index 0000000..0de21c6 --- /dev/null +++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_kms.c <at> <at> -0,0 +1,42 <at> <at> +/* + * Copyright 2015 Freescale Semiconductor, Inc. + * + * Freescale DCU drm device driver + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include <drm/drmP.h> +#include <drm/drm_atomic_helper.h> + +#include "fsl_dcu_drm_crtc.h" +#include "fsl_dcu_drm_connector.h" +#include "fsl_dcu_drm_drv.h" + +static const struct drm_mode_config_funcs fsl_dcu_drm_mode_config_funcs = { + .fb_create = drm_fb_cma_create, + .atomic_check = drm_atomic_helper_check, + .atomic_commit = drm_atomic_helper_commit, }; + +int fsl_dcu_drm_modeset_init(struct fsl_dcu_drm_device *fsl_dev) { + drm_mode_config_init(fsl_dev->ddev); + + fsl_dev->ddev->mode_config.min_width = 0; + fsl_dev->ddev->mode_config.min_height = 0; + fsl_dev->ddev->mode_config.max_width = 2031; + fsl_dev->ddev->mode_config.max_height = 2047; + fsl_dev->ddev->mode_config.funcs = &fsl_dcu_drm_mode_config_funcs; + + drm_kms_helper_poll_init(fsl_dev->ddev); + fsl_dcu_drm_crtc_create(fsl_dev); + fsl_dcu_drm_encoder_create(fsl_dev, &fsl_dev->crtc); + fsl_dcu_drm_connector_create(fsl_dev, &fsl_dev->encoder); + drm_mode_config_reset(fsl_dev->ddev); + + return 0; +} diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_kms.h b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_kms.h new file mode 100644 index 0000000..b9bd299 --- /dev/null +++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_kms.h <at> <at> -0,0 +1,17 <at> <at> +/* + * Copyright 2015 Freescale Semiconductor, Inc. + * + * Freescale DCU drm device driver + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#ifndef __FSL_DCU_DRM_KMS_H__ +#define __FSL_DCU_DRM_KMS_H__ + +int fsl_dcu_drm_modeset_init(struct fsl_dcu_drm_device *fsl_dev); + +#endif /* __FSL_DCU_DRM_KMS_H__ */ diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.c b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.c new file mode 100644 index 0000000..6146e80 --- /dev/null +++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.c <at> <at> -0,0 +1,192 <at> <at> +/* + * Copyright 2015 Freescale Semiconductor, Inc. + * + * Freescale DCU drm device driver + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include <drm/drmP.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 <linux/regmap.h> +#include <drm/drm_plane_helper.h> +#include <drm/drm_atomic_helper.h> + +#include "fsl_dcu_drm_drv.h" +#include "fsl_dcu_drm_kms.h" +#include "fsl_dcu_drm_plane.h" + +#define to_fsl_dcu_plane(plane) \ + container_of(plane, struct fsl_dcu_drm_plane, plane) + +static int +fsl_dcu_drm_plane_prepare_fb(struct drm_plane *plane, + struct drm_framebuffer *fb, + const struct drm_plane_state *new_state) { + return 0; +} + +static void +fsl_dcu_drm_plane_cleanup_fb(struct drm_plane *plane, + struct drm_framebuffer *fb, + const struct drm_plane_state *new_state) { } + +static int fsl_dcu_drm_plane_atomic_check(struct drm_plane *plane, + struct drm_plane_state *state) +{ + return 0; +} + +static void fsl_dcu_drm_plane_atomic_disable(struct drm_plane *plane, + struct drm_plane_state *old_state) { } + +void fsl_dcu_drm_plane_atomic_update(struct drm_plane *plane, + struct drm_plane_state *old_state) { + struct fsl_dcu_drm_device *fsl_dev = plane->dev->dev_private; + struct drm_plane_state *state = plane->state; + struct drm_framebuffer *fb = plane->state->fb; + u32 index, alpha, bpp; + struct drm_gem_cma_object *gem; + struct fsl_dcu_drm_plane *fsl_plane = to_fsl_dcu_plane(plane); + + index = fsl_plane->index; + gem = drm_fb_cma_get_gem_obj(fb, 0); + + switch (fb->pixel_format) { + case DRM_FORMAT_RGB565: + bpp = FSL_DCU_RGB565; + alpha = 0xff; + break; + case DRM_FORMAT_RGB888: + bpp = FSL_DCU_RGB888; + alpha = 0xff; + break; + case DRM_FORMAT_ARGB8888: + bpp = FSL_DCU_ARGB8888; + alpha = 0xff; + break; + case DRM_FORMAT_BGRA4444: + bpp = FSL_DCU_ARGB4444; + alpha = 0xff; + break; + case DRM_FORMAT_ARGB1555: + bpp = FSL_DCU_ARGB1555; + alpha = 0xff; + break; + case DRM_FORMAT_YUV422: + bpp = FSL_DCU_YUV422; + alpha = 0xff; + break; + default: + return; + } + + regmap_write(fsl_dev->regmap, DCU_CTRLDESCLN_1(index), + DCU_CTRLDESCLN_1_HEIGHT(state->crtc_h) | + DCU_CTRLDESCLN_1_WIDTH(state->crtc_w)); + regmap_write(fsl_dev->regmap, DCU_CTRLDESCLN_2(index), + DCU_CTRLDESCLN_2_POSY(state->crtc_y) | + DCU_CTRLDESCLN_2_POSX(state->crtc_x)); + regmap_write(fsl_dev->regmap, DCU_CTRLDESCLN_3(index), gem->paddr); + regmap_write(fsl_dev->regmap, DCU_CTRLDESCLN_4(index), + DCU_CTRLDESCLN_4_EN | + DCU_CTRLDESCLN_4_TRANS(alpha) | + DCU_CTRLDESCLN_4_BPP(bpp) | + DCU_CTRLDESCLN_4_AB(0)); + regmap_write(fsl_dev->regmap, DCU_CTRLDESCLN_5(index), + DCU_CTRLDESCLN_5_CKMAX_R(0xFF) | + DCU_CTRLDESCLN_5_CKMAX_G(0xFF) | + DCU_CTRLDESCLN_5_CKMAX_B(0xFF)); + regmap_write(fsl_dev->regmap, DCU_CTRLDESCLN_6(index), + DCU_CTRLDESCLN_6_CKMIN_R(0) | + DCU_CTRLDESCLN_6_CKMIN_G(0) | + DCU_CTRLDESCLN_6_CKMIN_B(0)); + regmap_write(fsl_dev->regmap, DCU_CTRLDESCLN_7(index), 0); + regmap_write(fsl_dev->regmap, DCU_CTRLDESCLN_8(index), + DCU_CTRLDESCLN_8_FG_FCOLOR(0)); + regmap_write(fsl_dev->regmap, DCU_CTRLDESCLN_9(index), + DCU_CTRLDESCLN_9_BG_BCOLOR(0)); + if (of_device_is_compatible(fsl_dev->np, "fsl,ls1021a-dcu")) + regmap_write(fsl_dev->regmap, DCU_CTRLDESCLN_10(index), + DCU_CTRLDESCLN_10_POST_SKIP(0) | + DCU_CTRLDESCLN_10_PRE_SKIP(0)); + regmap_update_bits(fsl_dev->regmap, DCU_DCU_MODE, + DCU_MODE_DCU_MODE_MASK, + DCU_MODE_DCU_MODE(DCU_MODE_NORMAL)); + regmap_write(fsl_dev->regmap, DCU_UPDATE_MODE, +DCU_UPDATE_MODE_READREG); } + +int fsl_dcu_drm_plane_disable(struct drm_plane *plane) { + return 0; +} + +void fsl_dcu_drm_plane_destroy(struct drm_plane *plane) { + fsl_dcu_drm_plane_disable(plane); + drm_plane_cleanup(plane); +} + +static const uint32_t fsl_dcu_drm_plane_formats[] = { + DRM_FORMAT_RGB565, + DRM_FORMAT_RGB888, + DRM_FORMAT_ARGB8888, + DRM_FORMAT_ARGB4444, + DRM_FORMAT_ARGB1555, + DRM_FORMAT_YUV422, +}; + +static const struct drm_plane_funcs fsl_dcu_drm_plane_funcs = { + .update_plane = drm_atomic_helper_update_plane, + .disable_plane = drm_atomic_helper_disable_plane, + .destroy = fsl_dcu_drm_plane_destroy, + .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state, + .atomic_destroy_state = drm_atomic_helper_plane_destroy_state, + .reset = drm_atomic_helper_plane_reset, }; + +static const struct drm_plane_helper_funcs fsl_dcu_drm_plane_helper_funcs = { + .prepare_fb = fsl_dcu_drm_plane_prepare_fb, + .cleanup_fb = fsl_dcu_drm_plane_cleanup_fb, + .atomic_check = fsl_dcu_drm_plane_atomic_check, + .atomic_update = fsl_dcu_drm_plane_atomic_update, + .atomic_disable = fsl_dcu_drm_plane_atomic_disable, }; + +struct drm_plane *fsl_dcu_drm_primary_create_plane(struct drm_device +*dev) { + struct drm_plane *primary; + int ret; + + primary = kzalloc(sizeof(*primary), GFP_KERNEL); + if (!primary) { + DRM_DEBUG_KMS("Failed to allocate primary plane\n"); + return NULL; + } + + /* possible_crtc's will be filled in later by crtc_init */ + ret = drm_universal_plane_init(dev, primary, 0, + &fsl_dcu_drm_plane_funcs, + fsl_dcu_drm_plane_formats, + ARRAY_SIZE(fsl_dcu_drm_plane_formats), + DRM_PLANE_TYPE_PRIMARY); + if (ret) { + kfree(primary); + primary = NULL; + } + drm_plane_helper_add(primary, &fsl_dcu_drm_plane_helper_funcs); + + return primary; +} diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.h b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.h new file mode 100644 index 0000000..ccbfa61 --- /dev/null +++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.h <at> <at> -0,0 +1,23 <at> <at> +/* + * Copyright 2015 Freescale Semiconductor, Inc. + * + * Freescale DCU drm device driver + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#ifndef __FSL_DCU_DRM_PLANE_H__ +#define __FSL_DCU_DRM_PLANE_H__ + +struct fsl_dcu_drm_device; +struct fsl_dcu_drm_plane { + struct drm_plane plane; + unsigned int index; +}; + +struct drm_plane *fsl_dcu_drm_primary_create_plane(struct drm_device +*dev); + +#endif /* __FSL_DCU_DRM_PLANE_H__ */ -- 2.1.0.27.g96db324


-- Mark
_______________________________________________
dri-devel mailing list
dri-devel <at> lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel
bugzilla-daemon | 1 Jul 00:15 2015

[Bug 64891] [snd_hda_codec] BUG: soft lockup - CPU#0 stuck for 22s (when using vgaswitcheroo)

https://bugzilla.kernel.org/show_bug.cgi?id=64891

Tommaso Falchi Delitala <volalto86 <at> gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |volalto86 <at> gmail.com

--- Comment #46 from Tommaso Falchi Delitala <volalto86 <at> gmail.com> ---
Created attachment 181501
  --> https://bugzilla.kernel.org/attachment.cgi?id=181501&action=edit
dmesg showing lockpuos (radeon off)

I still experience lockups related to audio with discrete card disabled via
vgaswitcheroo. Moreover the systems hangs at shutdown.

Kernel 4.0.6-1-ARCH
AMD Mobility Radeon HD5470 + intel integrated.

# cat /sys/kernel/debug/vgaswitcheroo/switch 
0:IGD:+:Pwr:0000:00:02.0
1:DIS: :DynOff:0000:01:00.0
2:DIS-Audio: :Off:0000:01:00.1

Interesting dmesg print:

snd_hda_intel 0000:01:00.1: Disabling via VGA-switcheroo
snd_hda_intel 0000:01:00.1: Cannot lock devices!
INFO: task kworker/u16:0:6 blocked for more than 120 seconds.
      Tainted: G        W       4.0.6-1-ARCH #1
"echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
kworker/u16:0   D ffff880132fd7ca8     0     6      2 0x00000000
Workqueue: hd-audio1 hdmi_repoll_eld [snd_hda_codec_hdmi]

See complete dmesg in attachment.

--

-- 
You are receiving this mail because:
You are watching the assignee of the bug.
_______________________________________________
dri-devel mailing list
dri-devel <at> lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel
bugzilla-daemon | 30 Jun 19:19 2015

[Bug 89420] DELL U2415 monitor detection issue

Comment # 3 on bug 89420 from Just an update. At the moment I'm running a newer kernel. 4.1.1-040101-generic Behaviour has changed. I don't have to use the extra kernel parameter drm_kms_helper.edid_firmware. Without it the monitor seems to be detected properly. So resolution is as it should be 1920X1200, at boot time, and also when logging in. However the power save issue still remains. - when the system tell the monitors to go to sleep, they both do, but when wakingg the screens, the U2415 offten won't come out of power save mode, the system is very sluggish at that moment. I'm not able to trigger the monitor to come out of standby. Not by calling xrandr in terminal, switching between VT's, or powering down the monitor. After plugging out the displayport of the U2415, the system becomes responsive again. - after a system suspend to ram the same as above happens. With a reboot everything seems normal again, and in the event the U2415 has gone into power save mode during login, switching between VT's will normally get it out off power save.
You are receiving this mail because:
  • You are the assignee for the bug.
_______________________________________________
dri-devel mailing list
dri-devel <at> lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel
David Weinehall | 30 Jun 14:24 2015
Picon

[PATCH 0/2] I915 GEM context updates

This patch contains a few minor updates related to
I915 GEM context.

David Weinehall (2):
  intel: Add get/set context parameter helpers
  Add the I915_CONTEXT_PARAM_NO_ZEROMAP parameter

 include/drm/i915_drm.h   |  1 +
 intel/intel_bufmgr.h     |  4 ++++
 intel/intel_bufmgr_gem.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 62 insertions(+)

--

-- 
2.1.4

_______________________________________________
dri-devel mailing list
dri-devel <at> lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel
Michal Hocko | 30 Jun 13:57 2015
Picon

WARNING: CPU: 0 PID: 3634 at drivers/gpu/drm/drm_irq.c:1141 drm_wait_one_vblank

Hi,
I am getting the following warning when I switch to the text console
from X. I do not know when this has started because I have noticed
that only now (in 4.1 kernel). I can try some older kernels if this is
useful.

I have tried to instrument drm_wait_one_vblank and dump drm_vblank_count
before the wait_event and the value when it returns (see the diff below)
and it seems to be increasing with new switching to the text console:
$ dmesg | grep XXX
[    6.531908] XXX: last:36
[    6.545852] XXX: drm_vblank_count:37
[    9.038658] XXX: last:186
[    9.051332] XXX: drm_vblank_count:187
[    9.051424] XXX: last:187
[    9.068036] XXX: drm_vblank_count:188
[   16.962193] XXX: last:660
[   16.968683] XXX: drm_vblank_count:661
[   30.592874] XXX: last:1476
[   30.598656] XXX: drm_vblank_count:1477
[   30.598768] XXX: last:1477
[   30.615339] XXX: drm_vblank_count:1478
[   37.313338] XXX: last:1879
[   37.330102] XXX: drm_vblank_count:1880
[   39.726809] XXX: last:2023
[   39.735265] XXX: drm_vblank_count:2024
[   39.735375] XXX: last:2024
[   39.752094] XXX: drm_vblank_count:2025
[   60.842401] XXX: last:3287
[   60.848437] XXX: drm_vblank_count:3288
[   62.149546] XXX: last:3365
[   62.151277] XXX: drm_vblank_count:3366
[   62.151411] XXX: last:3366
[   62.249376] XXX: drm_vblank_count:3366
[   92.198305] XXX: last:5160
[   92.297091] XXX: drm_vblank_count:5160
[   93.822331] XXX: last:5253
[   93.922153] XXX: drm_vblank_count:5253
[   93.922424] XXX: last:5254
[   94.022213] XXX: drm_vblank_count:5254
[  100.877802] XXX: last:5665
[  100.974740] XXX: drm_vblank_count:5665

I am sorry about the lack of information in this report but I am really
not sure what might be helpful. I can only tell that I haven't observed
anything wrong going on after the warning so it might be harmless.

Let me know what kind of information might be helpful.

[ 7322.444556] ------------[ cut here ]------------
[ 7322.444569] WARNING: CPU: 0 PID: 3634 at drivers/gpu/drm/drm_irq.c:1141
drm_wait_one_vblank+0x144/0x16f [drm]()
[ 7322.444570] vblank wait timed out on crtc 0
[ 7322.444586] Modules linked in: i915 fbcon cfbfillrect bitblit softcursor cfbimgblt font
i2c_algo_bit cfbcopyarea drm_kms_helper drm fb fbdev binfmt_misc snd_hda_codec_hdmi uvcvideo
videobuf2_vmalloc videobuf2_memops snd_hda_codec_idt i2c_i801 snd_hda_codec_generic
snd_hda_intel snd_hda_controller videobuf2_core arc4 snd_hda_codec snd_hda_core snd_pcm_oss
v4l2_common snd_mixer_oss videodev iwldvm media i2c_core mac80211 video iwlwifi backlight snd_pcm
sdhci_pci sdhci mmc_core cfg80211 snd_timer snd
[ 7322.444588] CPU: 0 PID: 3634 Comm: Xorg Not tainted 4.1.0 #587
[ 7322.444589] Hardware name: Dell Inc. Latitude E6320/09PHH9, BIOS A08 10/18/2011
[ 7322.444591]  0000000000000009 ffff8800c5bb7888 ffffffff8151b709 0000000080000000
[ 7322.444592]  ffff8800c5bb78d8 ffff8800c5bb78c8 ffffffff8104550a ffff8800c5bb7958
[ 7322.444593]  ffffffffa02d414e 0000000000000000 0000000000000000 ffff8800c58d7000
[ 7322.444594] Call Trace:
[ 7322.444599]  [<ffffffff8151b709>] dump_stack+0x4f/0x7b
[ 7322.444601]  [<ffffffff8104550a>] warn_slowpath_common+0xa1/0xbb
[ 7322.444608]  [<ffffffffa02d414e>] ? drm_wait_one_vblank+0x144/0x16f [drm]
[ 7322.444609]  [<ffffffff8104556a>] warn_slowpath_fmt+0x46/0x48
[ 7322.444611]  [<ffffffff81075b7d>] ? finish_wait+0x59/0x62
[ 7322.444617]  [<ffffffffa02d414e>] drm_wait_one_vblank+0x144/0x16f [drm]
[ 7322.444618]  [<ffffffff81075c9d>] ? wait_woken+0x76/0x76
[ 7322.444624]  [<ffffffffa02d4196>] drm_crtc_wait_one_vblank+0x1d/0x21 [drm]
[ 7322.444628]  [<ffffffffa0331baa>] drm_plane_helper_commit+0x1b3/0x240 [drm_kms_helper]
[ 7322.444631]  [<ffffffffa0331cfe>] drm_plane_helper_update+0xc7/0xd6 [drm_kms_helper]
[ 7322.444652]  [<ffffffffa03cd9a5>] intel_crtc_set_config+0x95e/0xc4f [i915]
[ 7322.444661]  [<ffffffffa02db020>] drm_mode_set_config_internal+0x5c/0xe8 [drm]
[ 7322.444666]  [<ffffffffa0338ae3>] drm_fb_helper_pan_display+0xa2/0xd8 [drm_kms_helper]
[ 7322.444668]  [<ffffffffa02be312>] fb_pan_display+0xee/0x131 [fb]
[ 7322.444670]  [<ffffffffa0353254>] bit_update_start+0x20/0x43 [bitblit]
[ 7322.444672]  [<ffffffffa035fa24>] fbcon_switch+0x3b7/0x438 [fbcon]
[ 7322.444674]  [<ffffffff812f7f0d>] redraw_screen+0x112/0x1e3
[ 7322.444676]  [<ffffffff812f0711>] complete_change_console+0x3e/0xc7
[ 7322.444678]  [<ffffffff812f1684>] vt_ioctl+0xeea/0x117f
[ 7322.444680]  [<ffffffff812e7538>] tty_ioctl+0xa01/0xa74
[ 7322.444682]  [<ffffffff81065154>] ? preempt_count_sub+0xc6/0xd3
[ 7322.444684]  [<ffffffff81156204>] do_vfs_ioctl+0x377/0x425
[ 7322.444685]  [<ffffffff8115e2a9>] ? __fget+0x70/0x7b
[ 7322.444686]  [<ffffffff811562f6>] SyS_ioctl+0x44/0x63
[ 7322.444688]  [<ffffffff81520197>] system_call_fastpath+0x12/0x6a
[ 7322.444689] ---[ end trace 9d3b554e7f553db3 ]---
[ 7326.066994] ------------[ cut here ]------------

Debugging patch
--
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
index af9662e58272..446f4ce02a9d 100644
--- a/drivers/gpu/drm/drm_irq.c
+++ b/drivers/gpu/drm/drm_irq.c
 <at>  <at>  -1126,17 +1126,19  <at>  <at>  EXPORT_SYMBOL(drm_crtc_vblank_put);
 void drm_wait_one_vblank(struct drm_device *dev, int crtc)
 {
 	int ret;
-	u32 last;
+	u32 last, l;

 	ret = drm_vblank_get(dev, crtc);
 	if (WARN(ret, "vblank not available on crtc %i, ret=%i\n", crtc, ret))
 		return;

 	last = drm_vblank_count(dev, crtc);
+	pr_info("XXX: last:%u\n", last);

 	ret = wait_event_timeout(dev->vblank[crtc].queue,
-				 last != drm_vblank_count(dev, crtc),
+				 last != (l = drm_vblank_count(dev, crtc)),
 				 msecs_to_jiffies(100));
+	pr_info("XXX: drm_vblank_count:%u\n", l);

 	WARN(ret == 0, "vblank wait timed out on crtc %i\n", crtc);

--

-- 
Michal Hocko
SUSE Labs
_______________________________________________
dri-devel mailing list
dri-devel <at> lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel
Jyri Sarha | 30 Jun 12:30 2015
Picon

[PATCH] drm/tilcdc: Implement dma-buf support for tilcdc

There is nothing special about tilcdc HW when the video memory is
concerned. Just using the standard drm helpers for implementation is
enough.

Signed-off-by: Jyri Sarha <jsarha <at> ti.com>
---
 drivers/gpu/drm/tilcdc/tilcdc_drv.c | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
index 0f283a3..4908c1f 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
 <at>  <at>  -553,7 +553,8  <at>  <at>  static const struct file_operations fops = {
 };

 static struct drm_driver tilcdc_driver = {
-	.driver_features    = DRIVER_HAVE_IRQ | DRIVER_GEM | DRIVER_MODESET,
+	.driver_features    = (DRIVER_HAVE_IRQ | DRIVER_GEM | DRIVER_MODESET |
+			       DRIVER_PRIME),
 	.load               = tilcdc_load,
 	.unload             = tilcdc_unload,
 	.preclose           = tilcdc_preclose,
 <at>  <at>  -571,6 +572,16  <at>  <at>  static struct drm_driver tilcdc_driver = {
 	.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_import	= drm_gem_prime_import,
+	.gem_prime_export	= drm_gem_prime_export,
+	.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,
 #ifdef CONFIG_DEBUG_FS
 	.debugfs_init       = tilcdc_debugfs_init,
 	.debugfs_cleanup    = tilcdc_debugfs_cleanup,
--

-- 
1.9.1

_______________________________________________
dri-devel mailing list
dri-devel <at> lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel
Laurent Pinchart | 30 Jun 12:20 2015

[PATCH] drm: omapdrm: Use destroy helper in plane reset handler

Call __drm_atomic_helper_plane_destroy_state() in the plane reset
handler instead of open-coding it. This will avoid changes to the driver
if plane state later gets more fields that need to be reset.

Signed-off-by: Laurent Pinchart <laurent.pinchart <at> ideasonboard.com>
---
 drivers/gpu/drm/omapdrm/omap_plane.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_plane.c b/drivers/gpu/drm/omapdrm/omap_plane.c
index cfa8276c4deb..ddcc74a6059d 100644
--- a/drivers/gpu/drm/omapdrm/omap_plane.c
+++ b/drivers/gpu/drm/omapdrm/omap_plane.c
 <at>  <at>  -165,8 +165,7  <at>  <at>  static void omap_plane_reset(struct drm_plane *plane)
 	struct omap_plane *omap_plane = to_omap_plane(plane);
 	struct omap_plane_state *omap_state;

-	if (plane->state && plane->state->fb)
-		drm_framebuffer_unreference(plane->state->fb);
+	__drm_atomic_helper_plane_destroy_state(plane, plane->state);

 	kfree(plane->state);
 	plane->state = NULL;
--

-- 
Regards,

Laurent Pinchart

_______________________________________________
dri-devel mailing list
dri-devel <at> lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel
Mark yao | 30 Jun 08:50 2015

[GIT PULL] drm/rockchip: fixes and new features

Hi Dave.

     Some fixes and some new features. I'd like you can pull them.

The following changes since commit c5fd936e992dd2829167d2adc63e151675ca6898:

   drm/nouveau: Pause between setting gpu to D3hot and cutting the power 
(2015-06-26 10:26:37 +1000)

are available in the git repository at:

   https://github.com/markyzq/kernel-drm-rockchip.git 
drm-rockchip-2015-06-30

for you to fetch changes up to 5295c05eb30d743987172853179333c80b8242bc:

   drm/rockchip: default enable win2/3 area0 bit (2015-06-30 14:24:10 +0800)

----------------------------------------------------------------
Heiko Stübner (1):
       drm/rockchip: only call drm_fb_helper_hotplug_event if fb_helper 
present

Mark Yao (6):
       drm/rockchip: import dma_buf to gem
       drm/rockchip: vop: optimize virtual stride calculate
       drm/rockchip: vop: fix yuv plane support
       drm/rockchip: vop: support plane scale
       drm/rockchip: vop: switch cursor plane to window 3
       drm/rockchip: default enable win2/3 area0 bit

Tomasz Figa (1):
       drm/rockchip: Add BGR formats to VOP

  drivers/gpu/drm/rockchip/rockchip_drm_drv.c |    1 +
  drivers/gpu/drm/rockchip/rockchip_drm_fb.c  |    3 +-
  drivers/gpu/drm/rockchip/rockchip_drm_gem.c |   40 ++-
  drivers/gpu/drm/rockchip/rockchip_drm_gem.h |    5 +-
  drivers/gpu/drm/rockchip/rockchip_drm_vop.c |  500 
++++++++++++++++++++++++++-
  drivers/gpu/drm/rockchip/rockchip_drm_vop.h |   96 +++++
  6 files changed, 628 insertions(+), 17 deletions(-)

--

-- 
Mark

_______________________________________________
dri-devel mailing list
dri-devel <at> lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel
Rodrigo Vivi | 29 Jun 22:44 2015
Picon

[PATCH 1/4] drm/i915: Make fb user dirty operation to invalidate frontbuffer

This patch introduces a frontbuffer invalidation on dirty fb
user callback.

It is mainly used for DIRTYFB drm ioctl, but can be extended
for fbdev use on following patch.

This patch itself already solves the biggest PSR known issue, that is
missed screen updates during boot, mainly when there is a splash
screen involved like plymouth.

Plymoth will do a modeset over ioctl that flushes frontbuffer
tracking and PSR gets back to work while it cannot track the
screen updates and exit properly. However plymouth also uses
a dirtyfb ioctl whenever updating the screen. So let's use it
to invalidate PSR back again.

This patch also introduces the ORIGIN_FB_DIRTY to frontbuffer tracking.
The reason is that whenever using this invalidate path we don't need to
keep continuously invalidating the frontbuffer for every call. One call
between flips is enough to keep frontbuffer tracking invalidated and
let all users aware. If a sync or async flip completed it means that we
probably can flush everything and enable powersavings features back.
If this isn't the case on the next dirty call we invalidate it again
until next flip.

Signed-off-by: Rodrigo Vivi <rodrigo.vivi <at> intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h          |  2 ++
 drivers/gpu/drm/i915/intel_display.c     | 18 ++++++++++++++++++
 drivers/gpu/drm/i915/intel_frontbuffer.c | 18 ++++++++++++++++++
 3 files changed, 38 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index ea9caf2..e0591d3 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
 <at>  <at>  -889,6 +889,7  <at>  <at>  enum fb_op_origin {
 	ORIGIN_CPU,
 	ORIGIN_CS,
 	ORIGIN_FLIP,
+	ORIGIN_FB_DIRTY,
 };

 struct i915_fbc {
 <at>  <at>  -1628,6 +1629,7  <at>  <at>  struct i915_frontbuffer_tracking {
 	 */
 	unsigned busy_bits;
 	unsigned flip_bits;
+	bool fb_dirty;
 };

 struct i915_wa_reg {
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 01eaab8..19c2ab3 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
 <at>  <at>  -14330,9 +14330,27  <at>  <at>  static int intel_user_framebuffer_create_handle(struct drm_framebuffer *fb,
 	return drm_gem_handle_create(file, &obj->base, handle);
 }

+static int intel_user_framebuffer_dirty(struct drm_framebuffer *fb,
+					       struct drm_file *file,
+					       unsigned flags, unsigned color,
+					       struct drm_clip_rect *clips,
+					       unsigned num_clips)
+{
+	struct drm_device *dev = fb->dev;
+	struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb);
+	struct drm_i915_gem_object *obj = intel_fb->obj;
+
+	mutex_lock(&dev->struct_mutex);
+	intel_fb_obj_invalidate(obj, ORIGIN_FB_DIRTY);
+	mutex_unlock(&dev->struct_mutex);
+
+	return 0;
+}
+
 static const struct drm_framebuffer_funcs intel_fb_funcs = {
 	.destroy = intel_user_framebuffer_destroy,
 	.create_handle = intel_user_framebuffer_create_handle,
+	.dirty = intel_user_framebuffer_dirty,
 };

 static
diff --git a/drivers/gpu/drm/i915/intel_frontbuffer.c b/drivers/gpu/drm/i915/intel_frontbuffer.c
index 6e90e2b..329b6fc 100644
--- a/drivers/gpu/drm/i915/intel_frontbuffer.c
+++ b/drivers/gpu/drm/i915/intel_frontbuffer.c
 <at>  <at>  -81,12 +81,28  <at>  <at>  void intel_fb_obj_invalidate(struct drm_i915_gem_object *obj,
 {
 	struct drm_device *dev = obj->base.dev;
 	struct drm_i915_private *dev_priv = to_i915(dev);
+	bool fb_dirty;

 	WARN_ON(!mutex_is_locked(&dev->struct_mutex));

 	if (!obj->frontbuffer_bits)
 		return;

+	/*
+	 * We just invalidate the frontbuffer on the first dirty and keep
+	 * it dirty and invalid until next flip.
+	 */
+	if (origin == ORIGIN_FB_DIRTY) {
+		mutex_lock(&dev_priv->fb_tracking.lock);
+		fb_dirty = dev_priv->fb_tracking.fb_dirty;
+		dev_priv->fb_tracking.fb_dirty = true;
+		mutex_unlock(&dev_priv->fb_tracking.lock);
+
+		if (fb_dirty)
+			return;
+		DRM_ERROR("PSR FBT invalidate dirty\n");
+	}
+
 	if (origin == ORIGIN_CS) {
 		mutex_lock(&dev_priv->fb_tracking.lock);
 		dev_priv->fb_tracking.busy_bits
 <at>  <at>  -207,6 +223,7  <at>  <at>  void intel_frontbuffer_flip_complete(struct drm_device *dev,
 	struct drm_i915_private *dev_priv = to_i915(dev);

 	mutex_lock(&dev_priv->fb_tracking.lock);
+	dev_priv->fb_tracking.fb_dirty = false;
 	/* Mask any cancelled flips. */
 	frontbuffer_bits &= dev_priv->fb_tracking.flip_bits;
 	dev_priv->fb_tracking.flip_bits &= ~frontbuffer_bits;
 <at>  <at>  -233,6 +250,7  <at>  <at>  void intel_frontbuffer_flip(struct drm_device *dev,
 	struct drm_i915_private *dev_priv = to_i915(dev);

 	mutex_lock(&dev_priv->fb_tracking.lock);
+	dev_priv->fb_tracking.fb_dirty = false;
 	/* Remove stale busy bits due to the old buffer. */
 	dev_priv->fb_tracking.busy_bits &= ~frontbuffer_bits;
 	mutex_unlock(&dev_priv->fb_tracking.lock);
--

-- 
2.1.0

_______________________________________________
dri-devel mailing list
dri-devel <at> lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel
Emil Velikov | 29 Jun 21:50 2015
Picon

[ANNOUNCE] libdrm 2.4.62

This release introduces the atomic and blob APIs, adds support
for new devices (AMD Bonaire) and a new flag for coherent BOs
in nouveau.

Alex Deucher (1):
      radeon: add new bonaire pci id

Alexandre Courbot (1):
      nouveau: add coherent BO attribute

Boris BREZILLON (2):
      modetest: add atmel-hlcdc driver support
      tests/kmstest: support atmel-hlcdc

Damien Lespiau (1):
      intel: Add the Broxton PCI IDs

Daniel Stone (1):
      Add blob property create/destroy ioctl wrappers

Emil Velikov (7):
      modetest: explicitly zero the newly allocated memory
      modetest: replace malloc + memset with calloc
      xf86drm: simplify drmMalloc/drmFree
      Revert "Add device enumeration interface (v4)"
      xf86drmMode: remove unused valgrind(VG) macros
      xf86drmMode: include config.h before anything else
      configure.ac: bump version to 2.4.62 for release

Guillaume Desmottes (1):
      drmPrime*: initialize output args to 0

Ilia Mirkin (1):
      nouveau: add asserts to make sure krefs are there

Jammy Zhou (1):
      Fix one warning (v2)

Matt Turner (1):
      configure: Add flag to disable valgrind support.

Tobias Jakobi (11):
      modetest: make middle SMPTE colors transparent
      modetest: only select plane with matching format
      exynos: fimg2d: fix return codes
      tests/exynos: replace return by break
      exynos/fimg2d: simplify g2d_fini()
      tests/exynos: clean struct connector
      tests/exynos: remove unused define
      tests/exynos: remove struct fimg2d_test_case
      tests/exynos: simplify drm_set_crtc
      tests/exynos: remove connector_find_plane
      tests/exynos: handle G2D_IMGBUF_COLOR in switch statements

Ville Syrjälä (1):
      Support atomic modesetting ioctl

frank (1):
      Add device enumeration interface (v4)

git tag: libdrm-2.4.62

http://dri.freedesktop.org/libdrm/libdrm-2.4.62.tar.bz2
MD5:  c9291bae0e5ca65d1483821d3698d3ab  libdrm-2.4.62.tar.bz2
SHA1: 882b59a372508a301aabd6ba8f8bd124f3a69a16  libdrm-2.4.62.tar.bz2
SHA256: 906c294bdbe1c94c3ca084305d61a6e5a8367f3b4986e6cc13b1e9b3f75931dc  libdrm-2.4.62.tar.bz2
PGP:  http://dri.freedesktop.org/libdrm/libdrm-2.4.62.tar.bz2.sig

http://dri.freedesktop.org/libdrm/libdrm-2.4.62.tar.gz
MD5:  e94fd03ad36b4154b8e10e8f6854f863  libdrm-2.4.62.tar.gz
SHA1: 270d8f3f03d605a08af7749e3762d508a3cef7b5  libdrm-2.4.62.tar.gz
SHA256: f7df6b73c8d787cdde7e49eae6e761313f606b784051004b1cb2e81bf2d490fa  libdrm-2.4.62.tar.gz
PGP:  http://dri.freedesktop.org/libdrm/libdrm-2.4.62.tar.gz.sig

_______________________________________________
dri-devel mailing list
dri-devel <at> lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel
bugzilla-daemon | 29 Jun 15:28 2015

[Bug 90728] dvd playback with vlc and vdpau causes segmentation fault

Comment # 21 on bug 90728 from (In reply to mehmet.giritli from comment #19) > One question: If you commit this, what is the earliest release which will > contain this fix? I have marked it as "CC: mesa-stable...", so it should show up in the next stable release. But I honestly don't know of hand which release that will be. > Marking this as fixed. As Michel already noted please don't do so. The workflow is that I mark it as fixes as soon as the patch is pushed and you can close it after that acknowledging that the problem is really fixed. Apart from that thanks for the help, that was a really long outstanding issue.
You are receiving this mail because:
  • You are the assignee for the bug.
_______________________________________________
dri-devel mailing list
dri-devel <at> lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

Gmane