* [PATCHv2 0/4] LS1021A: Add dcfb framebuffer driver support. @ 2014-12-03 9:15 ` Xiubo Li 0 siblings, 0 replies; 35+ messages in thread From: Xiubo Li @ 2014-12-03 9:15 UTC (permalink / raw) To: plagnioj, tomi.valkeinen Cc: alexander.stein, shawn.guo, linux-fbdev, linux-arm-kernel, linux-kernel, Xiubo Li Framebuffer driver for the Freescale SoC Display Controller. Change in V2: - Use the native-mode timing as default. - Add to_fsl_private(). Xiubo Li (4): video: fsl-dcfb: Add dcfb framebuffer driver for LS1021A platform video: fsl-dcfb: Add devicetree binding support ARM: ls1021a: dtsi: Add dt node support for dcfb. ARM: ls1021a: dts: Add and enable dt node for dcfb. .../devicetree/bindings/video/fsl,dcfb.txt | 52 ++ arch/arm/boot/dts/ls1021a-twr.dts | 26 + arch/arm/boot/dts/ls1021a.dtsi | 10 + drivers/video/fbdev/Kconfig | 19 + drivers/video/fbdev/Makefile | 1 + drivers/video/fbdev/fsl-dcfb.c | 814 +++++++++++++++++++++ 6 files changed, 922 insertions(+) create mode 100644 Documentation/devicetree/bindings/video/fsl,dcfb.txt create mode 100644 drivers/video/fbdev/fsl-dcfb.c -- 2.1.0.27.g96db324 ^ permalink raw reply [flat|nested] 35+ messages in thread
* [PATCHv2 0/4] LS1021A: Add dcfb framebuffer driver support. @ 2014-12-03 9:15 ` Xiubo Li 0 siblings, 0 replies; 35+ messages in thread From: Xiubo Li @ 2014-12-03 9:15 UTC (permalink / raw) To: linux-arm-kernel Framebuffer driver for the Freescale SoC Display Controller. Change in V2: - Use the native-mode timing as default. - Add to_fsl_private(). Xiubo Li (4): video: fsl-dcfb: Add dcfb framebuffer driver for LS1021A platform video: fsl-dcfb: Add devicetree binding support ARM: ls1021a: dtsi: Add dt node support for dcfb. ARM: ls1021a: dts: Add and enable dt node for dcfb. .../devicetree/bindings/video/fsl,dcfb.txt | 52 ++ arch/arm/boot/dts/ls1021a-twr.dts | 26 + arch/arm/boot/dts/ls1021a.dtsi | 10 + drivers/video/fbdev/Kconfig | 19 + drivers/video/fbdev/Makefile | 1 + drivers/video/fbdev/fsl-dcfb.c | 814 +++++++++++++++++++++ 6 files changed, 922 insertions(+) create mode 100644 Documentation/devicetree/bindings/video/fsl,dcfb.txt create mode 100644 drivers/video/fbdev/fsl-dcfb.c -- 2.1.0.27.g96db324 ^ permalink raw reply [flat|nested] 35+ messages in thread
* [PATCHv2 0/4] LS1021A: Add dcfb framebuffer driver support. @ 2014-12-03 9:15 ` Xiubo Li 0 siblings, 0 replies; 35+ messages in thread From: Xiubo Li @ 2014-12-03 9:15 UTC (permalink / raw) To: linux-arm-kernel Framebuffer driver for the Freescale SoC Display Controller. Change in V2: - Use the native-mode timing as default. - Add to_fsl_private(). Xiubo Li (4): video: fsl-dcfb: Add dcfb framebuffer driver for LS1021A platform video: fsl-dcfb: Add devicetree binding support ARM: ls1021a: dtsi: Add dt node support for dcfb. ARM: ls1021a: dts: Add and enable dt node for dcfb. .../devicetree/bindings/video/fsl,dcfb.txt | 52 ++ arch/arm/boot/dts/ls1021a-twr.dts | 26 + arch/arm/boot/dts/ls1021a.dtsi | 10 + drivers/video/fbdev/Kconfig | 19 + drivers/video/fbdev/Makefile | 1 + drivers/video/fbdev/fsl-dcfb.c | 814 +++++++++++++++++++++ 6 files changed, 922 insertions(+) create mode 100644 Documentation/devicetree/bindings/video/fsl,dcfb.txt create mode 100644 drivers/video/fbdev/fsl-dcfb.c -- 2.1.0.27.g96db324 ^ permalink raw reply [flat|nested] 35+ messages in thread
* [PATCHv2 1/4] video: fsl-dcfb: Add dcfb framebuffer driver for LS1021A platform 2014-12-03 9:15 ` Xiubo Li (?) @ 2014-12-03 9:15 ` Xiubo Li -1 siblings, 0 replies; 35+ messages in thread From: Xiubo Li @ 2014-12-03 9:15 UTC (permalink / raw) To: plagnioj, tomi.valkeinen Cc: alexander.stein, shawn.guo, linux-fbdev, linux-arm-kernel, linux-kernel, Xiubo Li The Display Controller module is a system master that fetches graphics stored in internal/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 configurable. The dcfb has these features: o Full RGB888 output to TFT LCD panel. o Optional output to system memory dependent on implementation. o Supports Programmable panel size upto a maximum of 2032x2047. The actual resolution supported depends upon the pixel clock and bus bandwidth available. o Gamma correction with 8-bit resolution on each color component. o Dedicated memory blocks to store a cursor and Color Look Up Tables(CLUTs). o Temporal Dithering. Signed-off-by: Xiubo Li <Li.Xiubo@freescale.com> --- drivers/video/fbdev/Kconfig | 19 + drivers/video/fbdev/Makefile | 1 + drivers/video/fbdev/fsl-dcfb.c | 814 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 834 insertions(+) create mode 100644 drivers/video/fbdev/fsl-dcfb.c diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig index 4916c97..460fe39 100644 --- a/drivers/video/fbdev/Kconfig +++ b/drivers/video/fbdev/Kconfig @@ -1948,6 +1948,25 @@ config FB_MBX_DEBUG If unsure, say N. +config FB_FSL_DCFB + tristate "Freescale Display Control Framebuffer Support" + depends on FB + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + select FB_MODE_HELPERS + select VIDEOMODE_HELPERS + select REGMAP_MMIO + ---help--- + Framebuffer driver for the Freescale SoC Display Control. + + This driver is also available as a module ( = code which can be + inserted and removed from the running kernel whenever you want). + If you want to compile it as a module, say M here and read + <file:Documentation/kbuild/modules.txt>. + + If unsure, say N. + config FB_FSL_DIU tristate "Freescale DIU framebuffer support" depends on FB && FSL_SOC diff --git a/drivers/video/fbdev/Makefile b/drivers/video/fbdev/Makefile index 1979aff..9015138 100644 --- a/drivers/video/fbdev/Makefile +++ b/drivers/video/fbdev/Makefile @@ -109,6 +109,7 @@ obj-$(CONFIG_FB_SH7760) += sh7760fb.o obj-$(CONFIG_FB_IMX) += imxfb.o obj-$(CONFIG_FB_S3C) += s3c-fb.o obj-$(CONFIG_FB_S3C2410) += s3c2410fb.o +obj-$(CONFIG_FB_FSL_DCFB) += fsl-dcfb.o obj-$(CONFIG_FB_FSL_DIU) += fsl-diu-fb.o obj-$(CONFIG_FB_COBALT) += cobalt_lcdfb.o obj-$(CONFIG_FB_IBM_GXT4500) += gxt4500.o diff --git a/drivers/video/fbdev/fsl-dcfb.c b/drivers/video/fbdev/fsl-dcfb.c new file mode 100644 index 0000000..c3843bf --- /dev/null +++ b/drivers/video/fbdev/fsl-dcfb.c @@ -0,0 +1,814 @@ +/* + * Copyright 2012-2014 Freescale Semiconductor, Inc. + * + * Freescale Dispaly Controller Framebuffer 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/delay.h> +#include <linux/dma-mapping.h> +#include <linux/fb.h> +#include <linux/interrupt.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/of_platform.h> +#include <linux/regmap.h> +#include <video/of_display_timing.h> +#include <video/videomode.h> + +#define FSL_SCFG_CTRL 0x28 +#define FSL_SCFG_PIXEL_EN BIT(31) + +#define FSL_DCFB_MODE 0x10 +#define FSL_DCFB_BGND 0x14 +#define FSL_DCFB_FIX_SIZE 0x18 +#define FSL_DCFB_HSYN 0x1c +#define FSL_DCFB_VSYN 0x20 +#define FSL_DCFB_SP 0x24 +#define FSL_DCFB_TS 0x28 +#define FSL_DCFB_DIV_RATIO 0x54 +#define FSL_DCFB_UPDATE 0xcc +#define FSL_DCFB_VAR_SIZE 0x200 +#define FSL_DCFB_POS 0x204 +#define FSL_DCFB_BASE 0x208 +#define FSL_DCFB_CTRL 0x20c +#define FSL_DCFB_CKMAX 0x210 +#define FSL_DCFB_CKMIN 0x214 +#define FSL_DCFB_FCOLOR 0x21c +#define FSL_DCFB_BCOLOR 0x220 +#define FSL_DCFB_SKIP 0x224 +#define FSL_DCFB_MAX 0x300 + +#define FSL_DCFB_HSYN_BP(x) ((x) << 22) +#define FSL_DCFB_HSYN_PW(x) ((x) << 11) +#define FSL_DCFB_HSYN_FP(x) (x) +#define FSL_DCFB_VSYN_BP(x) ((x) << 22) +#define FSL_DCFB_VSYN_PW(x) ((x) << 11) +#define FSL_DCFB_VSYN_FP(x) (x) + +#define FSL_DCFB_SP_VS BIT(1) +#define FSL_DCFB_SP_HS BIT(0) + +#define FSL_DCFB_TS_LBV(x) ((x) << 16) +#define FSL_DCFB_TS_OBH(x) ((x) << 8) +#define FSL_DCFB_TS_OBL(x) (x) + +#define FSL_DCFB_UPDATE_MODE BIT(31) +#define FSL_DCFB_UPDATE_READREG BIT(30) + +#define FSL_DCFB_VAR_SIZE_H(x) ((x) << 16) +#define FSL_DCFB_VAR_SIZE_W(x) (x) + +#define FSL_DCFB_POSY(x) ((x) << 16) +#define FSL_DCFB_POSX(x) (x) + +#define FSL_DCFB_CTRL_EN BIT(31) +#define FSL_DCFB_CTRL_TILE_EN BIT(30) +#define FSL_DCFB_CTRL_DATA_SEL_CLUT BIT(29) +#define FSL_DCFB_CTRL_SAFETY_EN BIT(28) +#define FSL_DCFB_CTRL_TRANS(x) ((x) << 20) +#define FSL_DCFB_CTRL_BPP(x) ((x) << 16) +#define FSL_DCFB_CTRL_RLE_EN BIT(15) +#define FSL_DCFB_CTRL_LUOFFS(x) ((x) << 4) +#define FSL_DCFB_CTRL_BB_ON BIT(2) + +#define FSL_DCFB_CKMAX_R(x) ((x) << 16) +#define FSL_DCFB_CKMAX_G(x) ((x) << 8) +#define FSL_DCFB_CKMAX_B(x) (x) + +#define FSL_DCFB_CKMIN_R(x) ((x) << 16) +#define FSL_DCFB_CKMIN_G(x) ((x) << 8) +#define FSL_DCFB_CKMIN_B(x) (x) + +#define FSL_DCFB_TILE_SIZE_W(x) ((x) << 16) +#define FSL_DCFB_TILE_SIZE_H(x) (x) + +#define FSL_DCFB_FCOLOR_OFF(x) (x) +#define FSL_DCFB_BCOLOR_OFF(x) (x) + +#define FSL_DCFB_MODE_BITER(x) ((x) << 20) +#define FSL_DCFB_MODE_RASTER_EN BIT(14) +#define FSL_DCFB_MODE_MODE(x) (x) +#define FSL_DCFB_MODE_MODE_MASK 0x03 + +#define FSL_DCFB_BGND_R(x) ((x) << 16) +#define FSL_DCFB_BGND_G(x) ((x) << 8) +#define FSL_DCFB_BGND_B(x) (x) + +#define FSL_DCFB_FIX_SIZE_Y(x) ((x) << 16) +#define FSL_DCFB_FIX_SIZE_X(x) (x) + +enum fsl_dcfb_fmt { + FSL_DCFB_RGB565 = 4, + FSL_DCFB_RGB888, + FSL_DCFB_ARGB8888, +}; + +enum fsl_dcfb_mode { + FSL_DCFB_MOD_OFF = 0, + FSL_DCFB_MOD_NORMAL, + FSL_DCFB_MOD_TEST, + FSL_DCFB_MOD_COLORBAR, +}; + +struct fsl_dcfb_fb_private { + struct fb_info *fsl_dcfb_info; + struct device *dev; + struct regmap *regmap; + struct clk *clk; +}; + +struct fsl_dcfb_fb_info { + unsigned long pseudo_palette[16]; + unsigned int count; + struct fsl_dcfb_fb_private *parent; +}; + +static inline struct fsl_dcfb_fb_private *to_fsl_private(struct fb_info *info) +{ + struct fsl_dcfb_fb_info *fsl_info = info->par; + + return (struct fsl_dcfb_fb_private *)fsl_info->parent; +} + +static int fsl_dcfb_get_bpp(unsigned int bits_per_pixel) +{ + int bpp; + + switch (bits_per_pixel) { + case 16: + bpp = FSL_DCFB_RGB565; + break; + case 24: + bpp = FSL_DCFB_RGB888; + break; + case 32: + bpp = FSL_DCFB_ARGB8888; + break; + default: + return -EINVAL; + } + + return bpp; +} + +static int fsl_dcfb_set_panel(struct fb_info *info) +{ + struct fb_var_screeninfo *var = &info->var; + struct fsl_dcfb_fb_private *dcfb = to_fsl_private(info); + int bpp; + + regmap_write(dcfb->regmap, FSL_DCFB_VAR_SIZE, + FSL_DCFB_VAR_SIZE_H(var->yres) | + FSL_DCFB_VAR_SIZE_W(var->xres)); + regmap_write(dcfb->regmap, FSL_DCFB_POS, + FSL_DCFB_POSY(0) | FSL_DCFB_POSX(0)); + + regmap_write(dcfb->regmap, FSL_DCFB_BASE, info->fix.smem_start); + + bpp = fsl_dcfb_get_bpp(var->bits_per_pixel); + if (bpp < 0) { + dev_err(dcfb->dev, "unsupported color depth: %u\n", + var->bits_per_pixel); + return bpp; + } + + regmap_write(dcfb->regmap, FSL_DCFB_CTRL, FSL_DCFB_CTRL_EN | + FSL_DCFB_CTRL_TRANS(0xFF) | FSL_DCFB_CTRL_BPP(bpp)); + regmap_write(dcfb->regmap, FSL_DCFB_CKMAX, FSL_DCFB_CKMAX_R(0xFF) | + FSL_DCFB_CKMAX_G(0xFF) | FSL_DCFB_CKMAX_B(0xFF)); + regmap_write(dcfb->regmap, FSL_DCFB_CKMIN, FSL_DCFB_CKMIN_R(0) | + FSL_DCFB_CKMIN_G(0) | FSL_DCFB_CKMIN_B(0)); + + regmap_write(dcfb->regmap, FSL_DCFB_FCOLOR, FSL_DCFB_FCOLOR_OFF(0)); + regmap_write(dcfb->regmap, FSL_DCFB_BCOLOR, FSL_DCFB_BCOLOR_OFF(0)); + + regmap_write(dcfb->regmap, FSL_DCFB_UPDATE, FSL_DCFB_UPDATE_READREG); + + return 0; +} + +static int fsl_dcfb_reset_panel(struct fsl_dcfb_fb_private *dcfb) +{ + regmap_write(dcfb->regmap, FSL_DCFB_VAR_SIZE, 0x0); + regmap_write(dcfb->regmap, FSL_DCFB_POS, 0x0); + regmap_write(dcfb->regmap, FSL_DCFB_BASE, 0x0); + regmap_write(dcfb->regmap, FSL_DCFB_CTRL, 0x0); + regmap_write(dcfb->regmap, FSL_DCFB_CKMAX, 0x0); + regmap_write(dcfb->regmap, FSL_DCFB_CKMIN, 0x0); + regmap_write(dcfb->regmap, FSL_DCFB_FCOLOR, 0x0); + regmap_write(dcfb->regmap, FSL_DCFB_BCOLOR, 0x0); + regmap_write(dcfb->regmap, FSL_DCFB_SKIP, 0x0); + + regmap_write(dcfb->regmap, FSL_DCFB_UPDATE, FSL_DCFB_UPDATE_READREG); + + return 0; +} + +static void fsl_dcfb_modeset(struct fsl_dcfb_fb_private *dcfb, + enum fsl_dcfb_mode mode) +{ + regmap_update_bits(dcfb->regmap, FSL_DCFB_MODE, + FSL_DCFB_MODE_MODE_MASK, + FSL_DCFB_MODE_MODE(mode)); +} + +static int fsl_dcfb_check_var(struct fb_var_screeninfo *var, + struct fb_info *info) +{ + struct fsl_dcfb_fb_private *dcfb = to_fsl_private(info); + + if (var->xres_virtual < var->xres) + var->xres_virtual = var->xres; + if (var->yres_virtual < var->yres) + var->yres_virtual = var->yres; + + if (var->xoffset + info->var.xres > info->var.xres_virtual) + var->xoffset = info->var.xres_virtual - info->var.xres; + + if (var->yoffset + info->var.yres > info->var.yres_virtual) + var->yoffset = info->var.yres_virtual - info->var.yres; + + switch (var->bits_per_pixel) { + case 16: + var->red.length = 5; + var->red.offset = 11; + var->red.msb_right = 0; + + var->green.length = 6; + var->green.offset = 5; + var->green.msb_right = 0; + + var->blue.length = 5; + var->blue.offset = 0; + var->blue.msb_right = 0; + + var->transp.length = 0; + var->transp.offset = 0; + var->transp.msb_right = 0; + break; + case 24: + var->red.length = 8; + var->red.offset = 16; + var->red.msb_right = 0; + + var->green.length = 8; + var->green.offset = 8; + var->green.msb_right = 0; + + var->blue.length = 8; + var->blue.offset = 0; + var->blue.msb_right = 0; + + var->transp.length = 0; + var->transp.offset = 0; + var->transp.msb_right = 0; + break; + case 32: + var->red.length = 8; + var->red.offset = 16; + var->red.msb_right = 0; + + var->green.length = 8; + var->green.offset = 8; + var->green.msb_right = 0; + + var->blue.length = 8; + var->blue.offset = 0; + var->blue.msb_right = 0; + + var->transp.length = 8; + var->transp.offset = 24; + var->transp.msb_right = 0; + break; + default: + dev_err(dcfb->dev, "unsupported color depth: %u\n", + var->bits_per_pixel); + return -EINVAL; + } + + return 0; +} + +static int fsl_dcfb_alloc_mem(struct fb_info *info) +{ + struct fsl_dcfb_fb_private *dcfb = to_fsl_private(info); + u32 smem_len = info->fix.line_length * info->var.yres_virtual; + + info->fix.smem_len = smem_len; + + info->screen_base = dma_alloc_writecombine(info->device, + info->fix.smem_len, (dma_addr_t *)&info->fix.smem_start, + GFP_KERNEL); + if (!info->screen_base) { + dev_err(dcfb->dev, "unable to allocate fb memory\n"); + return -ENOMEM; + } + + memset(info->screen_base, 0, info->fix.smem_len); + + return 0; +} + +static void fsl_dcfb_free_mem(struct fb_info *info) +{ + if (!info->screen_base) + return; + + dma_free_writecombine(info->device, info->fix.smem_len, + info->screen_base, info->fix.smem_start); + + info->screen_base = NULL; + info->fix.smem_start = 0; + info->fix.smem_len = 0; +} + +static int fsl_dcfb_set_par(struct fb_info *info) +{ + struct fb_var_screeninfo *var = &info->var; + struct fb_fix_screeninfo *fix = &info->fix; + struct fsl_dcfb_fb_private *dcfb = to_fsl_private(info); + unsigned int div, len; + + fix->type = FB_TYPE_PACKED_PIXELS; + fix->accel = FB_ACCEL_NONE; + fix->visual = FB_VISUAL_TRUECOLOR; + fix->xpanstep = fix->ypanstep = 1; + + fix->line_length = var->xres_virtual * var->bits_per_pixel / 8; + len = info->var.yres_virtual * info->fix.line_length; + if (len != info->fix.smem_len) { + if (info->fix.smem_start) + fsl_dcfb_free_mem(info); + + if (fsl_dcfb_alloc_mem(info)) { + dev_err(dcfb->dev, "unable to allocate FB memory\n"); + return -ENOMEM; + } + } + + div = KHZ2PICOS(clk_get_rate(dcfb->clk) / 1000); + regmap_write(dcfb->regmap, FSL_DCFB_DIV_RATIO, + info->var.pixclock / div); + + regmap_write(dcfb->regmap, FSL_DCFB_FIX_SIZE, + FSL_DCFB_FIX_SIZE_Y(var->yres) | + FSL_DCFB_FIX_SIZE_X(var->xres / 16)); + + regmap_write(dcfb->regmap, FSL_DCFB_HSYN, + FSL_DCFB_HSYN_BP(var->left_margin) | + FSL_DCFB_HSYN_PW(var->hsync_len) | + FSL_DCFB_HSYN_FP(var->right_margin)); + + regmap_write(dcfb->regmap, FSL_DCFB_VSYN, + FSL_DCFB_VSYN_BP(var->upper_margin) | + FSL_DCFB_VSYN_PW(var->vsync_len) | + FSL_DCFB_VSYN_FP(var->lower_margin)); + + regmap_write(dcfb->regmap, FSL_DCFB_SP, + FSL_DCFB_SP_VS | FSL_DCFB_SP_HS); + + regmap_write(dcfb->regmap, FSL_DCFB_BGND, FSL_DCFB_BGND_R(0) | + FSL_DCFB_BGND_G(0) | FSL_DCFB_BGND_B(0)); + + regmap_write(dcfb->regmap, FSL_DCFB_MODE, + FSL_DCFB_MODE_BITER(1) | FSL_DCFB_MODE_RASTER_EN); + + regmap_write(dcfb->regmap, FSL_DCFB_TS, FSL_DCFB_TS_LBV(0x03) | + FSL_DCFB_TS_OBH(0x78) | FSL_DCFB_TS_OBL(0x0A)); + + regmap_write(dcfb->regmap, FSL_DCFB_UPDATE, FSL_DCFB_UPDATE_READREG); + + fsl_dcfb_modeset(dcfb, FSL_DCFB_MOD_NORMAL); + fsl_dcfb_set_panel(info); + + return 0; +} + +#define CNVT_TOHW(val, width) ((((val) << (width)) + 0x7FFF - (val)) >> 16) +static int fsl_dcfb_setcolreg(unsigned regno, unsigned red, unsigned green, + unsigned blue, unsigned transp, + struct fb_info *info) +{ + int ret = 1; + + /* + * If greyscale is true, then we convert the RGB value + * to greyscale no matter what visual we are using. + */ + if (info->var.grayscale) + red = green = blue = (19595 * red + 38470 * green + + 7471 * blue) >> 16; + + switch (info->fix.visual) { + case FB_VISUAL_TRUECOLOR: + if (regno < 16) { + u32 *pal = info->pseudo_palette; + u32 value; + + red = CNVT_TOHW(red, info->var.red.length); + green = CNVT_TOHW(green, info->var.green.length); + blue = CNVT_TOHW(blue, info->var.blue.length); + transp = CNVT_TOHW(transp, info->var.transp.length); + + value = (red << info->var.red.offset) | + (green << info->var.green.offset) | + (blue << info->var.blue.offset) | + (transp << info->var.transp.offset); + + pal[regno] = value; + ret = 0; + } + break; + case FB_VISUAL_STATIC_PSEUDOCOLOR: + case FB_VISUAL_PSEUDOCOLOR: + break; + } + + return ret; +} +#undef CNVT_TOHW + +static int fsl_dcfb_pan_display(struct fb_var_screeninfo *var, + struct fb_info *info) +{ + struct fsl_dcfb_fb_private *dcfb = to_fsl_private(info); + unsigned long addr; + int offset; + + if ((info->var.xoffset == var->xoffset) && + (info->var.yoffset == var->yoffset)) + return 0; + + if ((var->xoffset + info->var.xres) > info->var.xres_virtual + || (var->yoffset + info->var.yres) > info->var.yres_virtual) + return -EINVAL; + + info->var.xoffset = var->xoffset; + info->var.yoffset = var->yoffset; + + if (var->vmode & FB_VMODE_YWRAP) + info->var.vmode |= FB_VMODE_YWRAP; + else + info->var.vmode &= ~FB_VMODE_YWRAP; + + offset = (info->var.yoffset * info->var.xres_virtual); + offset += info->var.xoffset; + addr = info->fix.smem_start + + (offset * (info->var.bits_per_pixel >> 3)); + + regmap_write(dcfb->regmap, FSL_DCFB_BASE, addr); + regmap_write(dcfb->regmap, FSL_DCFB_UPDATE, FSL_DCFB_UPDATE_READREG); + + return 0; +} + +static int fsl_dcfb_blank(int blank_mode, struct fb_info *info) +{ + struct fsl_dcfb_fb_private *dcfb = to_fsl_private(info); + + switch (blank_mode) { + case FB_BLANK_VSYNC_SUSPEND: + case FB_BLANK_HSYNC_SUSPEND: + case FB_BLANK_NORMAL: + fsl_dcfb_reset_panel(dcfb); + break; + case FB_BLANK_POWERDOWN: + fsl_dcfb_modeset(dcfb, FSL_DCFB_MOD_OFF); + break; + case FB_BLANK_UNBLANK: + fsl_dcfb_set_panel(info); + break; + } + + return 0; +} + +static int fsl_dcfb_open(struct fb_info *info, int user) +{ + struct fsl_dcfb_fb_info *fsl_info = info->par; + int ret = 0; + + fsl_info->count++; + if (fsl_info->count == 1) { + fsl_dcfb_check_var(&info->var, info); + ret = fsl_dcfb_set_par(info); + if (ret < 0) + fsl_info->count--; + } + + return ret; +} + +static int fsl_dcfb_release(struct fb_info *info, int user) +{ + struct fsl_dcfb_fb_info *fsl_info = info->par; + struct fsl_dcfb_fb_private *dcfb = to_fsl_private(info); + int ret = 0; + + fsl_info->count--; + if (fsl_info->count == 0) + ret = fsl_dcfb_reset_panel(dcfb); + + return ret; +} + +static struct fb_ops fsl_dcfb_ops = { + .owner = THIS_MODULE, + .fb_check_var = fsl_dcfb_check_var, + .fb_set_par = fsl_dcfb_set_par, + .fb_setcolreg = fsl_dcfb_setcolreg, + .fb_blank = fsl_dcfb_blank, + .fb_pan_display = fsl_dcfb_pan_display, + .fb_fillrect = cfb_fillrect, + .fb_copyarea = cfb_copyarea, + .fb_imageblit = cfb_imageblit, + .fb_open = fsl_dcfb_open, + .fb_release = fsl_dcfb_release, +}; + +static int fsl_dcfb_init_fbinfo(struct fb_info *info) +{ + struct fb_var_screeninfo *var = &info->var; + struct fsl_dcfb_fb_private *dcfb = to_fsl_private(info); + struct device_node *np = dcfb->dev->of_node; + struct device_node *dnp, *tnp; + struct display_timings *timings; + struct fb_videomode fb_vm; + int i, ret; + + INIT_LIST_HEAD(&info->modelist); + + dnp = of_parse_phandle(np, "display", 0); + if (!dnp) { + dev_err(dcfb->dev, "failed to find \"display\" phandle.\n"); + return -ENODEV; + } + + ret = of_property_read_u32(dnp, "bits-per-pixel", + &var->bits_per_pixel); + if (ret < 0) { + dev_err(dcfb->dev, "failed to get \"bits-per-pixel\" property.\n"); + goto put_dnp; + } + + timings = of_get_display_timings(dnp); + if (!timings) { + dev_err(dcfb->dev, "failed to get display timings\n"); + return -ENODEV; + goto put_dnp; + } + + tnp = of_find_node_by_name(dnp, "display-timings"); + if (!tnp) { + dev_err(dcfb->dev, "failed to find \"display-timings\" node\n"); + return -ENODEV; + goto put_dnp; + } + + for (i = 0; i < of_get_child_count(tnp); i++) { + struct videomode vm; + + ret = videomode_from_timings(timings, &vm, i); + if (ret < 0) + goto put_tnp; + + ret = fb_videomode_from_videomode(&vm, &fb_vm); + if (ret < 0) + goto put_tnp; + + fb_add_videomode(&fb_vm, &info->modelist); + } + + ret = of_get_fb_videomode(dnp, &fb_vm, OF_USE_NATIVE_MODE); + if (ret) + goto put_dnp; + + fb_videomode_to_var(&info->var, &fb_vm); + ret = fsl_dcfb_check_var(&info->var, info); + +put_tnp: + of_node_put(tnp); +put_dnp: + of_node_put(dnp); + + return ret; +} + +static const struct regmap_config fsl_scfg_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + + .max_register = FSL_SCFG_CTRL, +}; + +static int scfg_config(struct fsl_dcfb_fb_private *dcfb, struct device_node *np) +{ + struct device_node *snp; + struct platform_device *pdev; + struct resource *res; + void __iomem *base; + struct regmap *regmap; + int ret = 0; + + snp = of_parse_phandle(np, "scfg-controller", 0); + if (!snp) + return -ENODEV; + + pdev = of_find_device_by_node(snp); + if (!pdev) { + ret = -ENODEV; + goto put_snp; + } + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + ret = -ENODEV; + goto put_snp; + } + + base = ioremap(res->start, SZ_4K); + if (IS_ERR(base)) { + dev_err(&pdev->dev, "could not ioremap scfg resource\n"); + ret = PTR_ERR(base); + goto put_snp; + } + + regmap = regmap_init_mmio(&pdev->dev, base, + &fsl_scfg_regmap_config); + if (IS_ERR(regmap)) { + dev_err(&pdev->dev, "regmap init failed\n"); + ret = PTR_ERR(regmap); + goto ioremap; + } + + regmap_write(regmap, FSL_SCFG_CTRL, FSL_SCFG_PIXEL_EN); + + regmap_exit(regmap); +ioremap: + iounmap(base); +put_snp: + of_node_put(snp); + + return ret; +} + +static int fsl_dcfb_dev_init(struct device_node *np, + struct fsl_dcfb_fb_private *dcfb) +{ + int ret; + + ret = scfg_config(dcfb, np); + if (ret) { + dev_err(dcfb->dev, "could not config scfg\n"); + return -EINVAL; + } + + return fsl_dcfb_reset_panel(dcfb); +} + +static const struct regmap_config fsl_dcfb_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + + .max_register = FSL_DCFB_MAX, +}; + +static int fsl_dcfb_probe(struct platform_device *pdev) +{ + struct device_node *np = pdev->dev.of_node; + struct fsl_dcfb_fb_private *dcfb; + struct fsl_dcfb_fb_info *fsl_info; + struct fb_info *info; + struct resource *res; + void __iomem *base; + int ret = 0; + + dcfb = devm_kzalloc(&pdev->dev, + sizeof(struct fsl_dcfb_fb_private), GFP_KERNEL); + if (!dcfb) + return -ENOMEM; + + dcfb->dev = &pdev->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)) { + dev_err(&pdev->dev, "could not ioremap resource\n"); + return PTR_ERR(base); + } + + dcfb->regmap = devm_regmap_init_mmio_clk(&pdev->dev, + NULL, base, &fsl_dcfb_regmap_config); + if (IS_ERR(dcfb->regmap)) { + dev_err(&pdev->dev, "regmap init failed\n"); + return PTR_ERR(dcfb->regmap); + } + + dcfb->clk = devm_clk_get(&pdev->dev, "dcfb"); + if (IS_ERR(dcfb->clk)) { + ret = PTR_ERR(dcfb->clk); + dev_err(&pdev->dev, "could not get clock\n"); + return -EINVAL; + } + clk_prepare_enable(dcfb->clk); + + fsl_dcfb_dev_init(np, dcfb); + + dcfb->fsl_dcfb_info = + framebuffer_alloc(sizeof(struct fsl_dcfb_fb_info), &pdev->dev); + if (!dcfb->fsl_dcfb_info) { + ret = -ENOMEM; + goto err_clk; + } + + dcfb->fsl_dcfb_info->fix.smem_start = 0; + + fsl_info = dcfb->fsl_dcfb_info->par; + fsl_info->count = 0, + fsl_info->parent = dcfb; + + info = dcfb->fsl_dcfb_info; + info->var.activate = FB_ACTIVATE_NOW; + info->fbops = &fsl_dcfb_ops; + info->flags = FBINFO_FLAG_DEFAULT; + info->pseudo_palette = &fsl_info->pseudo_palette; + + ret = fb_alloc_cmap(&info->cmap, 16, 0); + if (ret) { + ret = -ENOMEM; + goto err_mem; + } + + ret = fsl_dcfb_init_fbinfo(info); + if (ret) + goto err_cmap; + + ret = register_framebuffer(info); + if (ret < 0) { + dev_err(dcfb->dev, "failed to register framebuffer device\n"); + goto err_cmap; + } + + dev_set_drvdata(&pdev->dev, dcfb); + + goto out; + +err_cmap: + fb_dealloc_cmap(&info->cmap); +err_mem: + framebuffer_release(dcfb->fsl_dcfb_info); +err_clk: + clk_disable_unprepare(dcfb->clk); +out: + return ret; +} + +static int fsl_dcfb_remove(struct platform_device *pdev) +{ + struct fsl_dcfb_fb_private *dcfb = dev_get_drvdata(&pdev->dev); + struct fb_info *info = dcfb->fsl_dcfb_info; + + fsl_dcfb_modeset(dcfb, FSL_DCFB_MOD_OFF); + fsl_dcfb_free_mem(info); + + unregister_framebuffer(info); + fb_dealloc_cmap(&info->cmap); + framebuffer_release(dcfb->fsl_dcfb_info); + clk_disable_unprepare(dcfb->clk); + + return 0; +} + +static struct of_device_id fsl_dcfb_dt_ids[] = { + { .compatible = "fsl,ls1021a-dcfb", }, + {} +}; + +static struct platform_driver fsl_dcfb_driver = { + .driver = { + .name = "fsl-dcfb", + .owner = THIS_MODULE, + .of_match_table = fsl_dcfb_dt_ids, + }, + .probe = fsl_dcfb_probe, + .remove = fsl_dcfb_remove, +}; + +module_platform_driver(fsl_dcfb_driver); + +MODULE_DESCRIPTION("Freescale Simple Display Controller FB Driver"); +MODULE_ALIAS("platform:fsl-dcfb"); +MODULE_LICENSE("GPL v2"); -- 2.1.0.27.g96db324 ^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCHv2 1/4] video: fsl-dcfb: Add dcfb framebuffer driver for LS1021A platform @ 2014-12-03 9:15 ` Xiubo Li 0 siblings, 0 replies; 35+ messages in thread From: Xiubo Li @ 2014-12-03 9:15 UTC (permalink / raw) To: linux-arm-kernel The Display Controller module is a system master that fetches graphics stored in internal/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 configurable. The dcfb has these features: o Full RGB888 output to TFT LCD panel. o Optional output to system memory dependent on implementation. o Supports Programmable panel size upto a maximum of 2032x2047. The actual resolution supported depends upon the pixel clock and bus bandwidth available. o Gamma correction with 8-bit resolution on each color component. o Dedicated memory blocks to store a cursor and Color Look Up Tables(CLUTs). o Temporal Dithering. Signed-off-by: Xiubo Li <Li.Xiubo@freescale.com> --- drivers/video/fbdev/Kconfig | 19 + drivers/video/fbdev/Makefile | 1 + drivers/video/fbdev/fsl-dcfb.c | 814 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 834 insertions(+) create mode 100644 drivers/video/fbdev/fsl-dcfb.c diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig index 4916c97..460fe39 100644 --- a/drivers/video/fbdev/Kconfig +++ b/drivers/video/fbdev/Kconfig @@ -1948,6 +1948,25 @@ config FB_MBX_DEBUG If unsure, say N. +config FB_FSL_DCFB + tristate "Freescale Display Control Framebuffer Support" + depends on FB + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + select FB_MODE_HELPERS + select VIDEOMODE_HELPERS + select REGMAP_MMIO + ---help--- + Framebuffer driver for the Freescale SoC Display Control. + + This driver is also available as a module ( = code which can be + inserted and removed from the running kernel whenever you want). + If you want to compile it as a module, say M here and read + <file:Documentation/kbuild/modules.txt>. + + If unsure, say N. + config FB_FSL_DIU tristate "Freescale DIU framebuffer support" depends on FB && FSL_SOC diff --git a/drivers/video/fbdev/Makefile b/drivers/video/fbdev/Makefile index 1979aff..9015138 100644 --- a/drivers/video/fbdev/Makefile +++ b/drivers/video/fbdev/Makefile @@ -109,6 +109,7 @@ obj-$(CONFIG_FB_SH7760) += sh7760fb.o obj-$(CONFIG_FB_IMX) += imxfb.o obj-$(CONFIG_FB_S3C) += s3c-fb.o obj-$(CONFIG_FB_S3C2410) += s3c2410fb.o +obj-$(CONFIG_FB_FSL_DCFB) += fsl-dcfb.o obj-$(CONFIG_FB_FSL_DIU) += fsl-diu-fb.o obj-$(CONFIG_FB_COBALT) += cobalt_lcdfb.o obj-$(CONFIG_FB_IBM_GXT4500) += gxt4500.o diff --git a/drivers/video/fbdev/fsl-dcfb.c b/drivers/video/fbdev/fsl-dcfb.c new file mode 100644 index 0000000..c3843bf --- /dev/null +++ b/drivers/video/fbdev/fsl-dcfb.c @@ -0,0 +1,814 @@ +/* + * Copyright 2012-2014 Freescale Semiconductor, Inc. + * + * Freescale Dispaly Controller Framebuffer 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/delay.h> +#include <linux/dma-mapping.h> +#include <linux/fb.h> +#include <linux/interrupt.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/of_platform.h> +#include <linux/regmap.h> +#include <video/of_display_timing.h> +#include <video/videomode.h> + +#define FSL_SCFG_CTRL 0x28 +#define FSL_SCFG_PIXEL_EN BIT(31) + +#define FSL_DCFB_MODE 0x10 +#define FSL_DCFB_BGND 0x14 +#define FSL_DCFB_FIX_SIZE 0x18 +#define FSL_DCFB_HSYN 0x1c +#define FSL_DCFB_VSYN 0x20 +#define FSL_DCFB_SP 0x24 +#define FSL_DCFB_TS 0x28 +#define FSL_DCFB_DIV_RATIO 0x54 +#define FSL_DCFB_UPDATE 0xcc +#define FSL_DCFB_VAR_SIZE 0x200 +#define FSL_DCFB_POS 0x204 +#define FSL_DCFB_BASE 0x208 +#define FSL_DCFB_CTRL 0x20c +#define FSL_DCFB_CKMAX 0x210 +#define FSL_DCFB_CKMIN 0x214 +#define FSL_DCFB_FCOLOR 0x21c +#define FSL_DCFB_BCOLOR 0x220 +#define FSL_DCFB_SKIP 0x224 +#define FSL_DCFB_MAX 0x300 + +#define FSL_DCFB_HSYN_BP(x) ((x) << 22) +#define FSL_DCFB_HSYN_PW(x) ((x) << 11) +#define FSL_DCFB_HSYN_FP(x) (x) +#define FSL_DCFB_VSYN_BP(x) ((x) << 22) +#define FSL_DCFB_VSYN_PW(x) ((x) << 11) +#define FSL_DCFB_VSYN_FP(x) (x) + +#define FSL_DCFB_SP_VS BIT(1) +#define FSL_DCFB_SP_HS BIT(0) + +#define FSL_DCFB_TS_LBV(x) ((x) << 16) +#define FSL_DCFB_TS_OBH(x) ((x) << 8) +#define FSL_DCFB_TS_OBL(x) (x) + +#define FSL_DCFB_UPDATE_MODE BIT(31) +#define FSL_DCFB_UPDATE_READREG BIT(30) + +#define FSL_DCFB_VAR_SIZE_H(x) ((x) << 16) +#define FSL_DCFB_VAR_SIZE_W(x) (x) + +#define FSL_DCFB_POSY(x) ((x) << 16) +#define FSL_DCFB_POSX(x) (x) + +#define FSL_DCFB_CTRL_EN BIT(31) +#define FSL_DCFB_CTRL_TILE_EN BIT(30) +#define FSL_DCFB_CTRL_DATA_SEL_CLUT BIT(29) +#define FSL_DCFB_CTRL_SAFETY_EN BIT(28) +#define FSL_DCFB_CTRL_TRANS(x) ((x) << 20) +#define FSL_DCFB_CTRL_BPP(x) ((x) << 16) +#define FSL_DCFB_CTRL_RLE_EN BIT(15) +#define FSL_DCFB_CTRL_LUOFFS(x) ((x) << 4) +#define FSL_DCFB_CTRL_BB_ON BIT(2) + +#define FSL_DCFB_CKMAX_R(x) ((x) << 16) +#define FSL_DCFB_CKMAX_G(x) ((x) << 8) +#define FSL_DCFB_CKMAX_B(x) (x) + +#define FSL_DCFB_CKMIN_R(x) ((x) << 16) +#define FSL_DCFB_CKMIN_G(x) ((x) << 8) +#define FSL_DCFB_CKMIN_B(x) (x) + +#define FSL_DCFB_TILE_SIZE_W(x) ((x) << 16) +#define FSL_DCFB_TILE_SIZE_H(x) (x) + +#define FSL_DCFB_FCOLOR_OFF(x) (x) +#define FSL_DCFB_BCOLOR_OFF(x) (x) + +#define FSL_DCFB_MODE_BITER(x) ((x) << 20) +#define FSL_DCFB_MODE_RASTER_EN BIT(14) +#define FSL_DCFB_MODE_MODE(x) (x) +#define FSL_DCFB_MODE_MODE_MASK 0x03 + +#define FSL_DCFB_BGND_R(x) ((x) << 16) +#define FSL_DCFB_BGND_G(x) ((x) << 8) +#define FSL_DCFB_BGND_B(x) (x) + +#define FSL_DCFB_FIX_SIZE_Y(x) ((x) << 16) +#define FSL_DCFB_FIX_SIZE_X(x) (x) + +enum fsl_dcfb_fmt { + FSL_DCFB_RGB565 = 4, + FSL_DCFB_RGB888, + FSL_DCFB_ARGB8888, +}; + +enum fsl_dcfb_mode { + FSL_DCFB_MOD_OFF = 0, + FSL_DCFB_MOD_NORMAL, + FSL_DCFB_MOD_TEST, + FSL_DCFB_MOD_COLORBAR, +}; + +struct fsl_dcfb_fb_private { + struct fb_info *fsl_dcfb_info; + struct device *dev; + struct regmap *regmap; + struct clk *clk; +}; + +struct fsl_dcfb_fb_info { + unsigned long pseudo_palette[16]; + unsigned int count; + struct fsl_dcfb_fb_private *parent; +}; + +static inline struct fsl_dcfb_fb_private *to_fsl_private(struct fb_info *info) +{ + struct fsl_dcfb_fb_info *fsl_info = info->par; + + return (struct fsl_dcfb_fb_private *)fsl_info->parent; +} + +static int fsl_dcfb_get_bpp(unsigned int bits_per_pixel) +{ + int bpp; + + switch (bits_per_pixel) { + case 16: + bpp = FSL_DCFB_RGB565; + break; + case 24: + bpp = FSL_DCFB_RGB888; + break; + case 32: + bpp = FSL_DCFB_ARGB8888; + break; + default: + return -EINVAL; + } + + return bpp; +} + +static int fsl_dcfb_set_panel(struct fb_info *info) +{ + struct fb_var_screeninfo *var = &info->var; + struct fsl_dcfb_fb_private *dcfb = to_fsl_private(info); + int bpp; + + regmap_write(dcfb->regmap, FSL_DCFB_VAR_SIZE, + FSL_DCFB_VAR_SIZE_H(var->yres) | + FSL_DCFB_VAR_SIZE_W(var->xres)); + regmap_write(dcfb->regmap, FSL_DCFB_POS, + FSL_DCFB_POSY(0) | FSL_DCFB_POSX(0)); + + regmap_write(dcfb->regmap, FSL_DCFB_BASE, info->fix.smem_start); + + bpp = fsl_dcfb_get_bpp(var->bits_per_pixel); + if (bpp < 0) { + dev_err(dcfb->dev, "unsupported color depth: %u\n", + var->bits_per_pixel); + return bpp; + } + + regmap_write(dcfb->regmap, FSL_DCFB_CTRL, FSL_DCFB_CTRL_EN | + FSL_DCFB_CTRL_TRANS(0xFF) | FSL_DCFB_CTRL_BPP(bpp)); + regmap_write(dcfb->regmap, FSL_DCFB_CKMAX, FSL_DCFB_CKMAX_R(0xFF) | + FSL_DCFB_CKMAX_G(0xFF) | FSL_DCFB_CKMAX_B(0xFF)); + regmap_write(dcfb->regmap, FSL_DCFB_CKMIN, FSL_DCFB_CKMIN_R(0) | + FSL_DCFB_CKMIN_G(0) | FSL_DCFB_CKMIN_B(0)); + + regmap_write(dcfb->regmap, FSL_DCFB_FCOLOR, FSL_DCFB_FCOLOR_OFF(0)); + regmap_write(dcfb->regmap, FSL_DCFB_BCOLOR, FSL_DCFB_BCOLOR_OFF(0)); + + regmap_write(dcfb->regmap, FSL_DCFB_UPDATE, FSL_DCFB_UPDATE_READREG); + + return 0; +} + +static int fsl_dcfb_reset_panel(struct fsl_dcfb_fb_private *dcfb) +{ + regmap_write(dcfb->regmap, FSL_DCFB_VAR_SIZE, 0x0); + regmap_write(dcfb->regmap, FSL_DCFB_POS, 0x0); + regmap_write(dcfb->regmap, FSL_DCFB_BASE, 0x0); + regmap_write(dcfb->regmap, FSL_DCFB_CTRL, 0x0); + regmap_write(dcfb->regmap, FSL_DCFB_CKMAX, 0x0); + regmap_write(dcfb->regmap, FSL_DCFB_CKMIN, 0x0); + regmap_write(dcfb->regmap, FSL_DCFB_FCOLOR, 0x0); + regmap_write(dcfb->regmap, FSL_DCFB_BCOLOR, 0x0); + regmap_write(dcfb->regmap, FSL_DCFB_SKIP, 0x0); + + regmap_write(dcfb->regmap, FSL_DCFB_UPDATE, FSL_DCFB_UPDATE_READREG); + + return 0; +} + +static void fsl_dcfb_modeset(struct fsl_dcfb_fb_private *dcfb, + enum fsl_dcfb_mode mode) +{ + regmap_update_bits(dcfb->regmap, FSL_DCFB_MODE, + FSL_DCFB_MODE_MODE_MASK, + FSL_DCFB_MODE_MODE(mode)); +} + +static int fsl_dcfb_check_var(struct fb_var_screeninfo *var, + struct fb_info *info) +{ + struct fsl_dcfb_fb_private *dcfb = to_fsl_private(info); + + if (var->xres_virtual < var->xres) + var->xres_virtual = var->xres; + if (var->yres_virtual < var->yres) + var->yres_virtual = var->yres; + + if (var->xoffset + info->var.xres > info->var.xres_virtual) + var->xoffset = info->var.xres_virtual - info->var.xres; + + if (var->yoffset + info->var.yres > info->var.yres_virtual) + var->yoffset = info->var.yres_virtual - info->var.yres; + + switch (var->bits_per_pixel) { + case 16: + var->red.length = 5; + var->red.offset = 11; + var->red.msb_right = 0; + + var->green.length = 6; + var->green.offset = 5; + var->green.msb_right = 0; + + var->blue.length = 5; + var->blue.offset = 0; + var->blue.msb_right = 0; + + var->transp.length = 0; + var->transp.offset = 0; + var->transp.msb_right = 0; + break; + case 24: + var->red.length = 8; + var->red.offset = 16; + var->red.msb_right = 0; + + var->green.length = 8; + var->green.offset = 8; + var->green.msb_right = 0; + + var->blue.length = 8; + var->blue.offset = 0; + var->blue.msb_right = 0; + + var->transp.length = 0; + var->transp.offset = 0; + var->transp.msb_right = 0; + break; + case 32: + var->red.length = 8; + var->red.offset = 16; + var->red.msb_right = 0; + + var->green.length = 8; + var->green.offset = 8; + var->green.msb_right = 0; + + var->blue.length = 8; + var->blue.offset = 0; + var->blue.msb_right = 0; + + var->transp.length = 8; + var->transp.offset = 24; + var->transp.msb_right = 0; + break; + default: + dev_err(dcfb->dev, "unsupported color depth: %u\n", + var->bits_per_pixel); + return -EINVAL; + } + + return 0; +} + +static int fsl_dcfb_alloc_mem(struct fb_info *info) +{ + struct fsl_dcfb_fb_private *dcfb = to_fsl_private(info); + u32 smem_len = info->fix.line_length * info->var.yres_virtual; + + info->fix.smem_len = smem_len; + + info->screen_base = dma_alloc_writecombine(info->device, + info->fix.smem_len, (dma_addr_t *)&info->fix.smem_start, + GFP_KERNEL); + if (!info->screen_base) { + dev_err(dcfb->dev, "unable to allocate fb memory\n"); + return -ENOMEM; + } + + memset(info->screen_base, 0, info->fix.smem_len); + + return 0; +} + +static void fsl_dcfb_free_mem(struct fb_info *info) +{ + if (!info->screen_base) + return; + + dma_free_writecombine(info->device, info->fix.smem_len, + info->screen_base, info->fix.smem_start); + + info->screen_base = NULL; + info->fix.smem_start = 0; + info->fix.smem_len = 0; +} + +static int fsl_dcfb_set_par(struct fb_info *info) +{ + struct fb_var_screeninfo *var = &info->var; + struct fb_fix_screeninfo *fix = &info->fix; + struct fsl_dcfb_fb_private *dcfb = to_fsl_private(info); + unsigned int div, len; + + fix->type = FB_TYPE_PACKED_PIXELS; + fix->accel = FB_ACCEL_NONE; + fix->visual = FB_VISUAL_TRUECOLOR; + fix->xpanstep = fix->ypanstep = 1; + + fix->line_length = var->xres_virtual * var->bits_per_pixel / 8; + len = info->var.yres_virtual * info->fix.line_length; + if (len != info->fix.smem_len) { + if (info->fix.smem_start) + fsl_dcfb_free_mem(info); + + if (fsl_dcfb_alloc_mem(info)) { + dev_err(dcfb->dev, "unable to allocate FB memory\n"); + return -ENOMEM; + } + } + + div = KHZ2PICOS(clk_get_rate(dcfb->clk) / 1000); + regmap_write(dcfb->regmap, FSL_DCFB_DIV_RATIO, + info->var.pixclock / div); + + regmap_write(dcfb->regmap, FSL_DCFB_FIX_SIZE, + FSL_DCFB_FIX_SIZE_Y(var->yres) | + FSL_DCFB_FIX_SIZE_X(var->xres / 16)); + + regmap_write(dcfb->regmap, FSL_DCFB_HSYN, + FSL_DCFB_HSYN_BP(var->left_margin) | + FSL_DCFB_HSYN_PW(var->hsync_len) | + FSL_DCFB_HSYN_FP(var->right_margin)); + + regmap_write(dcfb->regmap, FSL_DCFB_VSYN, + FSL_DCFB_VSYN_BP(var->upper_margin) | + FSL_DCFB_VSYN_PW(var->vsync_len) | + FSL_DCFB_VSYN_FP(var->lower_margin)); + + regmap_write(dcfb->regmap, FSL_DCFB_SP, + FSL_DCFB_SP_VS | FSL_DCFB_SP_HS); + + regmap_write(dcfb->regmap, FSL_DCFB_BGND, FSL_DCFB_BGND_R(0) | + FSL_DCFB_BGND_G(0) | FSL_DCFB_BGND_B(0)); + + regmap_write(dcfb->regmap, FSL_DCFB_MODE, + FSL_DCFB_MODE_BITER(1) | FSL_DCFB_MODE_RASTER_EN); + + regmap_write(dcfb->regmap, FSL_DCFB_TS, FSL_DCFB_TS_LBV(0x03) | + FSL_DCFB_TS_OBH(0x78) | FSL_DCFB_TS_OBL(0x0A)); + + regmap_write(dcfb->regmap, FSL_DCFB_UPDATE, FSL_DCFB_UPDATE_READREG); + + fsl_dcfb_modeset(dcfb, FSL_DCFB_MOD_NORMAL); + fsl_dcfb_set_panel(info); + + return 0; +} + +#define CNVT_TOHW(val, width) ((((val) << (width)) + 0x7FFF - (val)) >> 16) +static int fsl_dcfb_setcolreg(unsigned regno, unsigned red, unsigned green, + unsigned blue, unsigned transp, + struct fb_info *info) +{ + int ret = 1; + + /* + * If greyscale is true, then we convert the RGB value + * to greyscale no matter what visual we are using. + */ + if (info->var.grayscale) + red = green = blue = (19595 * red + 38470 * green + + 7471 * blue) >> 16; + + switch (info->fix.visual) { + case FB_VISUAL_TRUECOLOR: + if (regno < 16) { + u32 *pal = info->pseudo_palette; + u32 value; + + red = CNVT_TOHW(red, info->var.red.length); + green = CNVT_TOHW(green, info->var.green.length); + blue = CNVT_TOHW(blue, info->var.blue.length); + transp = CNVT_TOHW(transp, info->var.transp.length); + + value = (red << info->var.red.offset) | + (green << info->var.green.offset) | + (blue << info->var.blue.offset) | + (transp << info->var.transp.offset); + + pal[regno] = value; + ret = 0; + } + break; + case FB_VISUAL_STATIC_PSEUDOCOLOR: + case FB_VISUAL_PSEUDOCOLOR: + break; + } + + return ret; +} +#undef CNVT_TOHW + +static int fsl_dcfb_pan_display(struct fb_var_screeninfo *var, + struct fb_info *info) +{ + struct fsl_dcfb_fb_private *dcfb = to_fsl_private(info); + unsigned long addr; + int offset; + + if ((info->var.xoffset == var->xoffset) && + (info->var.yoffset == var->yoffset)) + return 0; + + if ((var->xoffset + info->var.xres) > info->var.xres_virtual + || (var->yoffset + info->var.yres) > info->var.yres_virtual) + return -EINVAL; + + info->var.xoffset = var->xoffset; + info->var.yoffset = var->yoffset; + + if (var->vmode & FB_VMODE_YWRAP) + info->var.vmode |= FB_VMODE_YWRAP; + else + info->var.vmode &= ~FB_VMODE_YWRAP; + + offset = (info->var.yoffset * info->var.xres_virtual); + offset += info->var.xoffset; + addr = info->fix.smem_start + + (offset * (info->var.bits_per_pixel >> 3)); + + regmap_write(dcfb->regmap, FSL_DCFB_BASE, addr); + regmap_write(dcfb->regmap, FSL_DCFB_UPDATE, FSL_DCFB_UPDATE_READREG); + + return 0; +} + +static int fsl_dcfb_blank(int blank_mode, struct fb_info *info) +{ + struct fsl_dcfb_fb_private *dcfb = to_fsl_private(info); + + switch (blank_mode) { + case FB_BLANK_VSYNC_SUSPEND: + case FB_BLANK_HSYNC_SUSPEND: + case FB_BLANK_NORMAL: + fsl_dcfb_reset_panel(dcfb); + break; + case FB_BLANK_POWERDOWN: + fsl_dcfb_modeset(dcfb, FSL_DCFB_MOD_OFF); + break; + case FB_BLANK_UNBLANK: + fsl_dcfb_set_panel(info); + break; + } + + return 0; +} + +static int fsl_dcfb_open(struct fb_info *info, int user) +{ + struct fsl_dcfb_fb_info *fsl_info = info->par; + int ret = 0; + + fsl_info->count++; + if (fsl_info->count == 1) { + fsl_dcfb_check_var(&info->var, info); + ret = fsl_dcfb_set_par(info); + if (ret < 0) + fsl_info->count--; + } + + return ret; +} + +static int fsl_dcfb_release(struct fb_info *info, int user) +{ + struct fsl_dcfb_fb_info *fsl_info = info->par; + struct fsl_dcfb_fb_private *dcfb = to_fsl_private(info); + int ret = 0; + + fsl_info->count--; + if (fsl_info->count == 0) + ret = fsl_dcfb_reset_panel(dcfb); + + return ret; +} + +static struct fb_ops fsl_dcfb_ops = { + .owner = THIS_MODULE, + .fb_check_var = fsl_dcfb_check_var, + .fb_set_par = fsl_dcfb_set_par, + .fb_setcolreg = fsl_dcfb_setcolreg, + .fb_blank = fsl_dcfb_blank, + .fb_pan_display = fsl_dcfb_pan_display, + .fb_fillrect = cfb_fillrect, + .fb_copyarea = cfb_copyarea, + .fb_imageblit = cfb_imageblit, + .fb_open = fsl_dcfb_open, + .fb_release = fsl_dcfb_release, +}; + +static int fsl_dcfb_init_fbinfo(struct fb_info *info) +{ + struct fb_var_screeninfo *var = &info->var; + struct fsl_dcfb_fb_private *dcfb = to_fsl_private(info); + struct device_node *np = dcfb->dev->of_node; + struct device_node *dnp, *tnp; + struct display_timings *timings; + struct fb_videomode fb_vm; + int i, ret; + + INIT_LIST_HEAD(&info->modelist); + + dnp = of_parse_phandle(np, "display", 0); + if (!dnp) { + dev_err(dcfb->dev, "failed to find \"display\" phandle.\n"); + return -ENODEV; + } + + ret = of_property_read_u32(dnp, "bits-per-pixel", + &var->bits_per_pixel); + if (ret < 0) { + dev_err(dcfb->dev, "failed to get \"bits-per-pixel\" property.\n"); + goto put_dnp; + } + + timings = of_get_display_timings(dnp); + if (!timings) { + dev_err(dcfb->dev, "failed to get display timings\n"); + return -ENODEV; + goto put_dnp; + } + + tnp = of_find_node_by_name(dnp, "display-timings"); + if (!tnp) { + dev_err(dcfb->dev, "failed to find \"display-timings\" node\n"); + return -ENODEV; + goto put_dnp; + } + + for (i = 0; i < of_get_child_count(tnp); i++) { + struct videomode vm; + + ret = videomode_from_timings(timings, &vm, i); + if (ret < 0) + goto put_tnp; + + ret = fb_videomode_from_videomode(&vm, &fb_vm); + if (ret < 0) + goto put_tnp; + + fb_add_videomode(&fb_vm, &info->modelist); + } + + ret = of_get_fb_videomode(dnp, &fb_vm, OF_USE_NATIVE_MODE); + if (ret) + goto put_dnp; + + fb_videomode_to_var(&info->var, &fb_vm); + ret = fsl_dcfb_check_var(&info->var, info); + +put_tnp: + of_node_put(tnp); +put_dnp: + of_node_put(dnp); + + return ret; +} + +static const struct regmap_config fsl_scfg_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + + .max_register = FSL_SCFG_CTRL, +}; + +static int scfg_config(struct fsl_dcfb_fb_private *dcfb, struct device_node *np) +{ + struct device_node *snp; + struct platform_device *pdev; + struct resource *res; + void __iomem *base; + struct regmap *regmap; + int ret = 0; + + snp = of_parse_phandle(np, "scfg-controller", 0); + if (!snp) + return -ENODEV; + + pdev = of_find_device_by_node(snp); + if (!pdev) { + ret = -ENODEV; + goto put_snp; + } + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + ret = -ENODEV; + goto put_snp; + } + + base = ioremap(res->start, SZ_4K); + if (IS_ERR(base)) { + dev_err(&pdev->dev, "could not ioremap scfg resource\n"); + ret = PTR_ERR(base); + goto put_snp; + } + + regmap = regmap_init_mmio(&pdev->dev, base, + &fsl_scfg_regmap_config); + if (IS_ERR(regmap)) { + dev_err(&pdev->dev, "regmap init failed\n"); + ret = PTR_ERR(regmap); + goto ioremap; + } + + regmap_write(regmap, FSL_SCFG_CTRL, FSL_SCFG_PIXEL_EN); + + regmap_exit(regmap); +ioremap: + iounmap(base); +put_snp: + of_node_put(snp); + + return ret; +} + +static int fsl_dcfb_dev_init(struct device_node *np, + struct fsl_dcfb_fb_private *dcfb) +{ + int ret; + + ret = scfg_config(dcfb, np); + if (ret) { + dev_err(dcfb->dev, "could not config scfg\n"); + return -EINVAL; + } + + return fsl_dcfb_reset_panel(dcfb); +} + +static const struct regmap_config fsl_dcfb_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + + .max_register = FSL_DCFB_MAX, +}; + +static int fsl_dcfb_probe(struct platform_device *pdev) +{ + struct device_node *np = pdev->dev.of_node; + struct fsl_dcfb_fb_private *dcfb; + struct fsl_dcfb_fb_info *fsl_info; + struct fb_info *info; + struct resource *res; + void __iomem *base; + int ret = 0; + + dcfb = devm_kzalloc(&pdev->dev, + sizeof(struct fsl_dcfb_fb_private), GFP_KERNEL); + if (!dcfb) + return -ENOMEM; + + dcfb->dev = &pdev->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)) { + dev_err(&pdev->dev, "could not ioremap resource\n"); + return PTR_ERR(base); + } + + dcfb->regmap = devm_regmap_init_mmio_clk(&pdev->dev, + NULL, base, &fsl_dcfb_regmap_config); + if (IS_ERR(dcfb->regmap)) { + dev_err(&pdev->dev, "regmap init failed\n"); + return PTR_ERR(dcfb->regmap); + } + + dcfb->clk = devm_clk_get(&pdev->dev, "dcfb"); + if (IS_ERR(dcfb->clk)) { + ret = PTR_ERR(dcfb->clk); + dev_err(&pdev->dev, "could not get clock\n"); + return -EINVAL; + } + clk_prepare_enable(dcfb->clk); + + fsl_dcfb_dev_init(np, dcfb); + + dcfb->fsl_dcfb_info = + framebuffer_alloc(sizeof(struct fsl_dcfb_fb_info), &pdev->dev); + if (!dcfb->fsl_dcfb_info) { + ret = -ENOMEM; + goto err_clk; + } + + dcfb->fsl_dcfb_info->fix.smem_start = 0; + + fsl_info = dcfb->fsl_dcfb_info->par; + fsl_info->count = 0, + fsl_info->parent = dcfb; + + info = dcfb->fsl_dcfb_info; + info->var.activate = FB_ACTIVATE_NOW; + info->fbops = &fsl_dcfb_ops; + info->flags = FBINFO_FLAG_DEFAULT; + info->pseudo_palette = &fsl_info->pseudo_palette; + + ret = fb_alloc_cmap(&info->cmap, 16, 0); + if (ret) { + ret = -ENOMEM; + goto err_mem; + } + + ret = fsl_dcfb_init_fbinfo(info); + if (ret) + goto err_cmap; + + ret = register_framebuffer(info); + if (ret < 0) { + dev_err(dcfb->dev, "failed to register framebuffer device\n"); + goto err_cmap; + } + + dev_set_drvdata(&pdev->dev, dcfb); + + goto out; + +err_cmap: + fb_dealloc_cmap(&info->cmap); +err_mem: + framebuffer_release(dcfb->fsl_dcfb_info); +err_clk: + clk_disable_unprepare(dcfb->clk); +out: + return ret; +} + +static int fsl_dcfb_remove(struct platform_device *pdev) +{ + struct fsl_dcfb_fb_private *dcfb = dev_get_drvdata(&pdev->dev); + struct fb_info *info = dcfb->fsl_dcfb_info; + + fsl_dcfb_modeset(dcfb, FSL_DCFB_MOD_OFF); + fsl_dcfb_free_mem(info); + + unregister_framebuffer(info); + fb_dealloc_cmap(&info->cmap); + framebuffer_release(dcfb->fsl_dcfb_info); + clk_disable_unprepare(dcfb->clk); + + return 0; +} + +static struct of_device_id fsl_dcfb_dt_ids[] = { + { .compatible = "fsl,ls1021a-dcfb", }, + {} +}; + +static struct platform_driver fsl_dcfb_driver = { + .driver = { + .name = "fsl-dcfb", + .owner = THIS_MODULE, + .of_match_table = fsl_dcfb_dt_ids, + }, + .probe = fsl_dcfb_probe, + .remove = fsl_dcfb_remove, +}; + +module_platform_driver(fsl_dcfb_driver); + +MODULE_DESCRIPTION("Freescale Simple Display Controller FB Driver"); +MODULE_ALIAS("platform:fsl-dcfb"); +MODULE_LICENSE("GPL v2"); -- 2.1.0.27.g96db324 ^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCHv2 1/4] video: fsl-dcfb: Add dcfb framebuffer driver for LS1021A platform @ 2014-12-03 9:15 ` Xiubo Li 0 siblings, 0 replies; 35+ messages in thread From: Xiubo Li @ 2014-12-03 9:15 UTC (permalink / raw) To: linux-arm-kernel The Display Controller module is a system master that fetches graphics stored in internal/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 configurable. The dcfb has these features: o Full RGB888 output to TFT LCD panel. o Optional output to system memory dependent on implementation. o Supports Programmable panel size upto a maximum of 2032x2047. The actual resolution supported depends upon the pixel clock and bus bandwidth available. o Gamma correction with 8-bit resolution on each color component. o Dedicated memory blocks to store a cursor and Color Look Up Tables(CLUTs). o Temporal Dithering. Signed-off-by: Xiubo Li <Li.Xiubo@freescale.com> --- drivers/video/fbdev/Kconfig | 19 + drivers/video/fbdev/Makefile | 1 + drivers/video/fbdev/fsl-dcfb.c | 814 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 834 insertions(+) create mode 100644 drivers/video/fbdev/fsl-dcfb.c diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig index 4916c97..460fe39 100644 --- a/drivers/video/fbdev/Kconfig +++ b/drivers/video/fbdev/Kconfig @@ -1948,6 +1948,25 @@ config FB_MBX_DEBUG If unsure, say N. +config FB_FSL_DCFB + tristate "Freescale Display Control Framebuffer Support" + depends on FB + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + select FB_MODE_HELPERS + select VIDEOMODE_HELPERS + select REGMAP_MMIO + ---help--- + Framebuffer driver for the Freescale SoC Display Control. + + This driver is also available as a module ( = code which can be + inserted and removed from the running kernel whenever you want). + If you want to compile it as a module, say M here and read + <file:Documentation/kbuild/modules.txt>. + + If unsure, say N. + config FB_FSL_DIU tristate "Freescale DIU framebuffer support" depends on FB && FSL_SOC diff --git a/drivers/video/fbdev/Makefile b/drivers/video/fbdev/Makefile index 1979aff..9015138 100644 --- a/drivers/video/fbdev/Makefile +++ b/drivers/video/fbdev/Makefile @@ -109,6 +109,7 @@ obj-$(CONFIG_FB_SH7760) += sh7760fb.o obj-$(CONFIG_FB_IMX) += imxfb.o obj-$(CONFIG_FB_S3C) += s3c-fb.o obj-$(CONFIG_FB_S3C2410) += s3c2410fb.o +obj-$(CONFIG_FB_FSL_DCFB) += fsl-dcfb.o obj-$(CONFIG_FB_FSL_DIU) += fsl-diu-fb.o obj-$(CONFIG_FB_COBALT) += cobalt_lcdfb.o obj-$(CONFIG_FB_IBM_GXT4500) += gxt4500.o diff --git a/drivers/video/fbdev/fsl-dcfb.c b/drivers/video/fbdev/fsl-dcfb.c new file mode 100644 index 0000000..c3843bf --- /dev/null +++ b/drivers/video/fbdev/fsl-dcfb.c @@ -0,0 +1,814 @@ +/* + * Copyright 2012-2014 Freescale Semiconductor, Inc. + * + * Freescale Dispaly Controller Framebuffer 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/delay.h> +#include <linux/dma-mapping.h> +#include <linux/fb.h> +#include <linux/interrupt.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/of_platform.h> +#include <linux/regmap.h> +#include <video/of_display_timing.h> +#include <video/videomode.h> + +#define FSL_SCFG_CTRL 0x28 +#define FSL_SCFG_PIXEL_EN BIT(31) + +#define FSL_DCFB_MODE 0x10 +#define FSL_DCFB_BGND 0x14 +#define FSL_DCFB_FIX_SIZE 0x18 +#define FSL_DCFB_HSYN 0x1c +#define FSL_DCFB_VSYN 0x20 +#define FSL_DCFB_SP 0x24 +#define FSL_DCFB_TS 0x28 +#define FSL_DCFB_DIV_RATIO 0x54 +#define FSL_DCFB_UPDATE 0xcc +#define FSL_DCFB_VAR_SIZE 0x200 +#define FSL_DCFB_POS 0x204 +#define FSL_DCFB_BASE 0x208 +#define FSL_DCFB_CTRL 0x20c +#define FSL_DCFB_CKMAX 0x210 +#define FSL_DCFB_CKMIN 0x214 +#define FSL_DCFB_FCOLOR 0x21c +#define FSL_DCFB_BCOLOR 0x220 +#define FSL_DCFB_SKIP 0x224 +#define FSL_DCFB_MAX 0x300 + +#define FSL_DCFB_HSYN_BP(x) ((x) << 22) +#define FSL_DCFB_HSYN_PW(x) ((x) << 11) +#define FSL_DCFB_HSYN_FP(x) (x) +#define FSL_DCFB_VSYN_BP(x) ((x) << 22) +#define FSL_DCFB_VSYN_PW(x) ((x) << 11) +#define FSL_DCFB_VSYN_FP(x) (x) + +#define FSL_DCFB_SP_VS BIT(1) +#define FSL_DCFB_SP_HS BIT(0) + +#define FSL_DCFB_TS_LBV(x) ((x) << 16) +#define FSL_DCFB_TS_OBH(x) ((x) << 8) +#define FSL_DCFB_TS_OBL(x) (x) + +#define FSL_DCFB_UPDATE_MODE BIT(31) +#define FSL_DCFB_UPDATE_READREG BIT(30) + +#define FSL_DCFB_VAR_SIZE_H(x) ((x) << 16) +#define FSL_DCFB_VAR_SIZE_W(x) (x) + +#define FSL_DCFB_POSY(x) ((x) << 16) +#define FSL_DCFB_POSX(x) (x) + +#define FSL_DCFB_CTRL_EN BIT(31) +#define FSL_DCFB_CTRL_TILE_EN BIT(30) +#define FSL_DCFB_CTRL_DATA_SEL_CLUT BIT(29) +#define FSL_DCFB_CTRL_SAFETY_EN BIT(28) +#define FSL_DCFB_CTRL_TRANS(x) ((x) << 20) +#define FSL_DCFB_CTRL_BPP(x) ((x) << 16) +#define FSL_DCFB_CTRL_RLE_EN BIT(15) +#define FSL_DCFB_CTRL_LUOFFS(x) ((x) << 4) +#define FSL_DCFB_CTRL_BB_ON BIT(2) + +#define FSL_DCFB_CKMAX_R(x) ((x) << 16) +#define FSL_DCFB_CKMAX_G(x) ((x) << 8) +#define FSL_DCFB_CKMAX_B(x) (x) + +#define FSL_DCFB_CKMIN_R(x) ((x) << 16) +#define FSL_DCFB_CKMIN_G(x) ((x) << 8) +#define FSL_DCFB_CKMIN_B(x) (x) + +#define FSL_DCFB_TILE_SIZE_W(x) ((x) << 16) +#define FSL_DCFB_TILE_SIZE_H(x) (x) + +#define FSL_DCFB_FCOLOR_OFF(x) (x) +#define FSL_DCFB_BCOLOR_OFF(x) (x) + +#define FSL_DCFB_MODE_BITER(x) ((x) << 20) +#define FSL_DCFB_MODE_RASTER_EN BIT(14) +#define FSL_DCFB_MODE_MODE(x) (x) +#define FSL_DCFB_MODE_MODE_MASK 0x03 + +#define FSL_DCFB_BGND_R(x) ((x) << 16) +#define FSL_DCFB_BGND_G(x) ((x) << 8) +#define FSL_DCFB_BGND_B(x) (x) + +#define FSL_DCFB_FIX_SIZE_Y(x) ((x) << 16) +#define FSL_DCFB_FIX_SIZE_X(x) (x) + +enum fsl_dcfb_fmt { + FSL_DCFB_RGB565 = 4, + FSL_DCFB_RGB888, + FSL_DCFB_ARGB8888, +}; + +enum fsl_dcfb_mode { + FSL_DCFB_MOD_OFF = 0, + FSL_DCFB_MOD_NORMAL, + FSL_DCFB_MOD_TEST, + FSL_DCFB_MOD_COLORBAR, +}; + +struct fsl_dcfb_fb_private { + struct fb_info *fsl_dcfb_info; + struct device *dev; + struct regmap *regmap; + struct clk *clk; +}; + +struct fsl_dcfb_fb_info { + unsigned long pseudo_palette[16]; + unsigned int count; + struct fsl_dcfb_fb_private *parent; +}; + +static inline struct fsl_dcfb_fb_private *to_fsl_private(struct fb_info *info) +{ + struct fsl_dcfb_fb_info *fsl_info = info->par; + + return (struct fsl_dcfb_fb_private *)fsl_info->parent; +} + +static int fsl_dcfb_get_bpp(unsigned int bits_per_pixel) +{ + int bpp; + + switch (bits_per_pixel) { + case 16: + bpp = FSL_DCFB_RGB565; + break; + case 24: + bpp = FSL_DCFB_RGB888; + break; + case 32: + bpp = FSL_DCFB_ARGB8888; + break; + default: + return -EINVAL; + } + + return bpp; +} + +static int fsl_dcfb_set_panel(struct fb_info *info) +{ + struct fb_var_screeninfo *var = &info->var; + struct fsl_dcfb_fb_private *dcfb = to_fsl_private(info); + int bpp; + + regmap_write(dcfb->regmap, FSL_DCFB_VAR_SIZE, + FSL_DCFB_VAR_SIZE_H(var->yres) | + FSL_DCFB_VAR_SIZE_W(var->xres)); + regmap_write(dcfb->regmap, FSL_DCFB_POS, + FSL_DCFB_POSY(0) | FSL_DCFB_POSX(0)); + + regmap_write(dcfb->regmap, FSL_DCFB_BASE, info->fix.smem_start); + + bpp = fsl_dcfb_get_bpp(var->bits_per_pixel); + if (bpp < 0) { + dev_err(dcfb->dev, "unsupported color depth: %u\n", + var->bits_per_pixel); + return bpp; + } + + regmap_write(dcfb->regmap, FSL_DCFB_CTRL, FSL_DCFB_CTRL_EN | + FSL_DCFB_CTRL_TRANS(0xFF) | FSL_DCFB_CTRL_BPP(bpp)); + regmap_write(dcfb->regmap, FSL_DCFB_CKMAX, FSL_DCFB_CKMAX_R(0xFF) | + FSL_DCFB_CKMAX_G(0xFF) | FSL_DCFB_CKMAX_B(0xFF)); + regmap_write(dcfb->regmap, FSL_DCFB_CKMIN, FSL_DCFB_CKMIN_R(0) | + FSL_DCFB_CKMIN_G(0) | FSL_DCFB_CKMIN_B(0)); + + regmap_write(dcfb->regmap, FSL_DCFB_FCOLOR, FSL_DCFB_FCOLOR_OFF(0)); + regmap_write(dcfb->regmap, FSL_DCFB_BCOLOR, FSL_DCFB_BCOLOR_OFF(0)); + + regmap_write(dcfb->regmap, FSL_DCFB_UPDATE, FSL_DCFB_UPDATE_READREG); + + return 0; +} + +static int fsl_dcfb_reset_panel(struct fsl_dcfb_fb_private *dcfb) +{ + regmap_write(dcfb->regmap, FSL_DCFB_VAR_SIZE, 0x0); + regmap_write(dcfb->regmap, FSL_DCFB_POS, 0x0); + regmap_write(dcfb->regmap, FSL_DCFB_BASE, 0x0); + regmap_write(dcfb->regmap, FSL_DCFB_CTRL, 0x0); + regmap_write(dcfb->regmap, FSL_DCFB_CKMAX, 0x0); + regmap_write(dcfb->regmap, FSL_DCFB_CKMIN, 0x0); + regmap_write(dcfb->regmap, FSL_DCFB_FCOLOR, 0x0); + regmap_write(dcfb->regmap, FSL_DCFB_BCOLOR, 0x0); + regmap_write(dcfb->regmap, FSL_DCFB_SKIP, 0x0); + + regmap_write(dcfb->regmap, FSL_DCFB_UPDATE, FSL_DCFB_UPDATE_READREG); + + return 0; +} + +static void fsl_dcfb_modeset(struct fsl_dcfb_fb_private *dcfb, + enum fsl_dcfb_mode mode) +{ + regmap_update_bits(dcfb->regmap, FSL_DCFB_MODE, + FSL_DCFB_MODE_MODE_MASK, + FSL_DCFB_MODE_MODE(mode)); +} + +static int fsl_dcfb_check_var(struct fb_var_screeninfo *var, + struct fb_info *info) +{ + struct fsl_dcfb_fb_private *dcfb = to_fsl_private(info); + + if (var->xres_virtual < var->xres) + var->xres_virtual = var->xres; + if (var->yres_virtual < var->yres) + var->yres_virtual = var->yres; + + if (var->xoffset + info->var.xres > info->var.xres_virtual) + var->xoffset = info->var.xres_virtual - info->var.xres; + + if (var->yoffset + info->var.yres > info->var.yres_virtual) + var->yoffset = info->var.yres_virtual - info->var.yres; + + switch (var->bits_per_pixel) { + case 16: + var->red.length = 5; + var->red.offset = 11; + var->red.msb_right = 0; + + var->green.length = 6; + var->green.offset = 5; + var->green.msb_right = 0; + + var->blue.length = 5; + var->blue.offset = 0; + var->blue.msb_right = 0; + + var->transp.length = 0; + var->transp.offset = 0; + var->transp.msb_right = 0; + break; + case 24: + var->red.length = 8; + var->red.offset = 16; + var->red.msb_right = 0; + + var->green.length = 8; + var->green.offset = 8; + var->green.msb_right = 0; + + var->blue.length = 8; + var->blue.offset = 0; + var->blue.msb_right = 0; + + var->transp.length = 0; + var->transp.offset = 0; + var->transp.msb_right = 0; + break; + case 32: + var->red.length = 8; + var->red.offset = 16; + var->red.msb_right = 0; + + var->green.length = 8; + var->green.offset = 8; + var->green.msb_right = 0; + + var->blue.length = 8; + var->blue.offset = 0; + var->blue.msb_right = 0; + + var->transp.length = 8; + var->transp.offset = 24; + var->transp.msb_right = 0; + break; + default: + dev_err(dcfb->dev, "unsupported color depth: %u\n", + var->bits_per_pixel); + return -EINVAL; + } + + return 0; +} + +static int fsl_dcfb_alloc_mem(struct fb_info *info) +{ + struct fsl_dcfb_fb_private *dcfb = to_fsl_private(info); + u32 smem_len = info->fix.line_length * info->var.yres_virtual; + + info->fix.smem_len = smem_len; + + info->screen_base = dma_alloc_writecombine(info->device, + info->fix.smem_len, (dma_addr_t *)&info->fix.smem_start, + GFP_KERNEL); + if (!info->screen_base) { + dev_err(dcfb->dev, "unable to allocate fb memory\n"); + return -ENOMEM; + } + + memset(info->screen_base, 0, info->fix.smem_len); + + return 0; +} + +static void fsl_dcfb_free_mem(struct fb_info *info) +{ + if (!info->screen_base) + return; + + dma_free_writecombine(info->device, info->fix.smem_len, + info->screen_base, info->fix.smem_start); + + info->screen_base = NULL; + info->fix.smem_start = 0; + info->fix.smem_len = 0; +} + +static int fsl_dcfb_set_par(struct fb_info *info) +{ + struct fb_var_screeninfo *var = &info->var; + struct fb_fix_screeninfo *fix = &info->fix; + struct fsl_dcfb_fb_private *dcfb = to_fsl_private(info); + unsigned int div, len; + + fix->type = FB_TYPE_PACKED_PIXELS; + fix->accel = FB_ACCEL_NONE; + fix->visual = FB_VISUAL_TRUECOLOR; + fix->xpanstep = fix->ypanstep = 1; + + fix->line_length = var->xres_virtual * var->bits_per_pixel / 8; + len = info->var.yres_virtual * info->fix.line_length; + if (len != info->fix.smem_len) { + if (info->fix.smem_start) + fsl_dcfb_free_mem(info); + + if (fsl_dcfb_alloc_mem(info)) { + dev_err(dcfb->dev, "unable to allocate FB memory\n"); + return -ENOMEM; + } + } + + div = KHZ2PICOS(clk_get_rate(dcfb->clk) / 1000); + regmap_write(dcfb->regmap, FSL_DCFB_DIV_RATIO, + info->var.pixclock / div); + + regmap_write(dcfb->regmap, FSL_DCFB_FIX_SIZE, + FSL_DCFB_FIX_SIZE_Y(var->yres) | + FSL_DCFB_FIX_SIZE_X(var->xres / 16)); + + regmap_write(dcfb->regmap, FSL_DCFB_HSYN, + FSL_DCFB_HSYN_BP(var->left_margin) | + FSL_DCFB_HSYN_PW(var->hsync_len) | + FSL_DCFB_HSYN_FP(var->right_margin)); + + regmap_write(dcfb->regmap, FSL_DCFB_VSYN, + FSL_DCFB_VSYN_BP(var->upper_margin) | + FSL_DCFB_VSYN_PW(var->vsync_len) | + FSL_DCFB_VSYN_FP(var->lower_margin)); + + regmap_write(dcfb->regmap, FSL_DCFB_SP, + FSL_DCFB_SP_VS | FSL_DCFB_SP_HS); + + regmap_write(dcfb->regmap, FSL_DCFB_BGND, FSL_DCFB_BGND_R(0) | + FSL_DCFB_BGND_G(0) | FSL_DCFB_BGND_B(0)); + + regmap_write(dcfb->regmap, FSL_DCFB_MODE, + FSL_DCFB_MODE_BITER(1) | FSL_DCFB_MODE_RASTER_EN); + + regmap_write(dcfb->regmap, FSL_DCFB_TS, FSL_DCFB_TS_LBV(0x03) | + FSL_DCFB_TS_OBH(0x78) | FSL_DCFB_TS_OBL(0x0A)); + + regmap_write(dcfb->regmap, FSL_DCFB_UPDATE, FSL_DCFB_UPDATE_READREG); + + fsl_dcfb_modeset(dcfb, FSL_DCFB_MOD_NORMAL); + fsl_dcfb_set_panel(info); + + return 0; +} + +#define CNVT_TOHW(val, width) ((((val) << (width)) + 0x7FFF - (val)) >> 16) +static int fsl_dcfb_setcolreg(unsigned regno, unsigned red, unsigned green, + unsigned blue, unsigned transp, + struct fb_info *info) +{ + int ret = 1; + + /* + * If greyscale is true, then we convert the RGB value + * to greyscale no matter what visual we are using. + */ + if (info->var.grayscale) + red = green = blue = (19595 * red + 38470 * green + + 7471 * blue) >> 16; + + switch (info->fix.visual) { + case FB_VISUAL_TRUECOLOR: + if (regno < 16) { + u32 *pal = info->pseudo_palette; + u32 value; + + red = CNVT_TOHW(red, info->var.red.length); + green = CNVT_TOHW(green, info->var.green.length); + blue = CNVT_TOHW(blue, info->var.blue.length); + transp = CNVT_TOHW(transp, info->var.transp.length); + + value = (red << info->var.red.offset) | + (green << info->var.green.offset) | + (blue << info->var.blue.offset) | + (transp << info->var.transp.offset); + + pal[regno] = value; + ret = 0; + } + break; + case FB_VISUAL_STATIC_PSEUDOCOLOR: + case FB_VISUAL_PSEUDOCOLOR: + break; + } + + return ret; +} +#undef CNVT_TOHW + +static int fsl_dcfb_pan_display(struct fb_var_screeninfo *var, + struct fb_info *info) +{ + struct fsl_dcfb_fb_private *dcfb = to_fsl_private(info); + unsigned long addr; + int offset; + + if ((info->var.xoffset = var->xoffset) && + (info->var.yoffset = var->yoffset)) + return 0; + + if ((var->xoffset + info->var.xres) > info->var.xres_virtual + || (var->yoffset + info->var.yres) > info->var.yres_virtual) + return -EINVAL; + + info->var.xoffset = var->xoffset; + info->var.yoffset = var->yoffset; + + if (var->vmode & FB_VMODE_YWRAP) + info->var.vmode |= FB_VMODE_YWRAP; + else + info->var.vmode &= ~FB_VMODE_YWRAP; + + offset = (info->var.yoffset * info->var.xres_virtual); + offset += info->var.xoffset; + addr = info->fix.smem_start + + (offset * (info->var.bits_per_pixel >> 3)); + + regmap_write(dcfb->regmap, FSL_DCFB_BASE, addr); + regmap_write(dcfb->regmap, FSL_DCFB_UPDATE, FSL_DCFB_UPDATE_READREG); + + return 0; +} + +static int fsl_dcfb_blank(int blank_mode, struct fb_info *info) +{ + struct fsl_dcfb_fb_private *dcfb = to_fsl_private(info); + + switch (blank_mode) { + case FB_BLANK_VSYNC_SUSPEND: + case FB_BLANK_HSYNC_SUSPEND: + case FB_BLANK_NORMAL: + fsl_dcfb_reset_panel(dcfb); + break; + case FB_BLANK_POWERDOWN: + fsl_dcfb_modeset(dcfb, FSL_DCFB_MOD_OFF); + break; + case FB_BLANK_UNBLANK: + fsl_dcfb_set_panel(info); + break; + } + + return 0; +} + +static int fsl_dcfb_open(struct fb_info *info, int user) +{ + struct fsl_dcfb_fb_info *fsl_info = info->par; + int ret = 0; + + fsl_info->count++; + if (fsl_info->count = 1) { + fsl_dcfb_check_var(&info->var, info); + ret = fsl_dcfb_set_par(info); + if (ret < 0) + fsl_info->count--; + } + + return ret; +} + +static int fsl_dcfb_release(struct fb_info *info, int user) +{ + struct fsl_dcfb_fb_info *fsl_info = info->par; + struct fsl_dcfb_fb_private *dcfb = to_fsl_private(info); + int ret = 0; + + fsl_info->count--; + if (fsl_info->count = 0) + ret = fsl_dcfb_reset_panel(dcfb); + + return ret; +} + +static struct fb_ops fsl_dcfb_ops = { + .owner = THIS_MODULE, + .fb_check_var = fsl_dcfb_check_var, + .fb_set_par = fsl_dcfb_set_par, + .fb_setcolreg = fsl_dcfb_setcolreg, + .fb_blank = fsl_dcfb_blank, + .fb_pan_display = fsl_dcfb_pan_display, + .fb_fillrect = cfb_fillrect, + .fb_copyarea = cfb_copyarea, + .fb_imageblit = cfb_imageblit, + .fb_open = fsl_dcfb_open, + .fb_release = fsl_dcfb_release, +}; + +static int fsl_dcfb_init_fbinfo(struct fb_info *info) +{ + struct fb_var_screeninfo *var = &info->var; + struct fsl_dcfb_fb_private *dcfb = to_fsl_private(info); + struct device_node *np = dcfb->dev->of_node; + struct device_node *dnp, *tnp; + struct display_timings *timings; + struct fb_videomode fb_vm; + int i, ret; + + INIT_LIST_HEAD(&info->modelist); + + dnp = of_parse_phandle(np, "display", 0); + if (!dnp) { + dev_err(dcfb->dev, "failed to find \"display\" phandle.\n"); + return -ENODEV; + } + + ret = of_property_read_u32(dnp, "bits-per-pixel", + &var->bits_per_pixel); + if (ret < 0) { + dev_err(dcfb->dev, "failed to get \"bits-per-pixel\" property.\n"); + goto put_dnp; + } + + timings = of_get_display_timings(dnp); + if (!timings) { + dev_err(dcfb->dev, "failed to get display timings\n"); + return -ENODEV; + goto put_dnp; + } + + tnp = of_find_node_by_name(dnp, "display-timings"); + if (!tnp) { + dev_err(dcfb->dev, "failed to find \"display-timings\" node\n"); + return -ENODEV; + goto put_dnp; + } + + for (i = 0; i < of_get_child_count(tnp); i++) { + struct videomode vm; + + ret = videomode_from_timings(timings, &vm, i); + if (ret < 0) + goto put_tnp; + + ret = fb_videomode_from_videomode(&vm, &fb_vm); + if (ret < 0) + goto put_tnp; + + fb_add_videomode(&fb_vm, &info->modelist); + } + + ret = of_get_fb_videomode(dnp, &fb_vm, OF_USE_NATIVE_MODE); + if (ret) + goto put_dnp; + + fb_videomode_to_var(&info->var, &fb_vm); + ret = fsl_dcfb_check_var(&info->var, info); + +put_tnp: + of_node_put(tnp); +put_dnp: + of_node_put(dnp); + + return ret; +} + +static const struct regmap_config fsl_scfg_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + + .max_register = FSL_SCFG_CTRL, +}; + +static int scfg_config(struct fsl_dcfb_fb_private *dcfb, struct device_node *np) +{ + struct device_node *snp; + struct platform_device *pdev; + struct resource *res; + void __iomem *base; + struct regmap *regmap; + int ret = 0; + + snp = of_parse_phandle(np, "scfg-controller", 0); + if (!snp) + return -ENODEV; + + pdev = of_find_device_by_node(snp); + if (!pdev) { + ret = -ENODEV; + goto put_snp; + } + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + ret = -ENODEV; + goto put_snp; + } + + base = ioremap(res->start, SZ_4K); + if (IS_ERR(base)) { + dev_err(&pdev->dev, "could not ioremap scfg resource\n"); + ret = PTR_ERR(base); + goto put_snp; + } + + regmap = regmap_init_mmio(&pdev->dev, base, + &fsl_scfg_regmap_config); + if (IS_ERR(regmap)) { + dev_err(&pdev->dev, "regmap init failed\n"); + ret = PTR_ERR(regmap); + goto ioremap; + } + + regmap_write(regmap, FSL_SCFG_CTRL, FSL_SCFG_PIXEL_EN); + + regmap_exit(regmap); +ioremap: + iounmap(base); +put_snp: + of_node_put(snp); + + return ret; +} + +static int fsl_dcfb_dev_init(struct device_node *np, + struct fsl_dcfb_fb_private *dcfb) +{ + int ret; + + ret = scfg_config(dcfb, np); + if (ret) { + dev_err(dcfb->dev, "could not config scfg\n"); + return -EINVAL; + } + + return fsl_dcfb_reset_panel(dcfb); +} + +static const struct regmap_config fsl_dcfb_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + + .max_register = FSL_DCFB_MAX, +}; + +static int fsl_dcfb_probe(struct platform_device *pdev) +{ + struct device_node *np = pdev->dev.of_node; + struct fsl_dcfb_fb_private *dcfb; + struct fsl_dcfb_fb_info *fsl_info; + struct fb_info *info; + struct resource *res; + void __iomem *base; + int ret = 0; + + dcfb = devm_kzalloc(&pdev->dev, + sizeof(struct fsl_dcfb_fb_private), GFP_KERNEL); + if (!dcfb) + return -ENOMEM; + + dcfb->dev = &pdev->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)) { + dev_err(&pdev->dev, "could not ioremap resource\n"); + return PTR_ERR(base); + } + + dcfb->regmap = devm_regmap_init_mmio_clk(&pdev->dev, + NULL, base, &fsl_dcfb_regmap_config); + if (IS_ERR(dcfb->regmap)) { + dev_err(&pdev->dev, "regmap init failed\n"); + return PTR_ERR(dcfb->regmap); + } + + dcfb->clk = devm_clk_get(&pdev->dev, "dcfb"); + if (IS_ERR(dcfb->clk)) { + ret = PTR_ERR(dcfb->clk); + dev_err(&pdev->dev, "could not get clock\n"); + return -EINVAL; + } + clk_prepare_enable(dcfb->clk); + + fsl_dcfb_dev_init(np, dcfb); + + dcfb->fsl_dcfb_info + framebuffer_alloc(sizeof(struct fsl_dcfb_fb_info), &pdev->dev); + if (!dcfb->fsl_dcfb_info) { + ret = -ENOMEM; + goto err_clk; + } + + dcfb->fsl_dcfb_info->fix.smem_start = 0; + + fsl_info = dcfb->fsl_dcfb_info->par; + fsl_info->count = 0, + fsl_info->parent = dcfb; + + info = dcfb->fsl_dcfb_info; + info->var.activate = FB_ACTIVATE_NOW; + info->fbops = &fsl_dcfb_ops; + info->flags = FBINFO_FLAG_DEFAULT; + info->pseudo_palette = &fsl_info->pseudo_palette; + + ret = fb_alloc_cmap(&info->cmap, 16, 0); + if (ret) { + ret = -ENOMEM; + goto err_mem; + } + + ret = fsl_dcfb_init_fbinfo(info); + if (ret) + goto err_cmap; + + ret = register_framebuffer(info); + if (ret < 0) { + dev_err(dcfb->dev, "failed to register framebuffer device\n"); + goto err_cmap; + } + + dev_set_drvdata(&pdev->dev, dcfb); + + goto out; + +err_cmap: + fb_dealloc_cmap(&info->cmap); +err_mem: + framebuffer_release(dcfb->fsl_dcfb_info); +err_clk: + clk_disable_unprepare(dcfb->clk); +out: + return ret; +} + +static int fsl_dcfb_remove(struct platform_device *pdev) +{ + struct fsl_dcfb_fb_private *dcfb = dev_get_drvdata(&pdev->dev); + struct fb_info *info = dcfb->fsl_dcfb_info; + + fsl_dcfb_modeset(dcfb, FSL_DCFB_MOD_OFF); + fsl_dcfb_free_mem(info); + + unregister_framebuffer(info); + fb_dealloc_cmap(&info->cmap); + framebuffer_release(dcfb->fsl_dcfb_info); + clk_disable_unprepare(dcfb->clk); + + return 0; +} + +static struct of_device_id fsl_dcfb_dt_ids[] = { + { .compatible = "fsl,ls1021a-dcfb", }, + {} +}; + +static struct platform_driver fsl_dcfb_driver = { + .driver = { + .name = "fsl-dcfb", + .owner = THIS_MODULE, + .of_match_table = fsl_dcfb_dt_ids, + }, + .probe = fsl_dcfb_probe, + .remove = fsl_dcfb_remove, +}; + +module_platform_driver(fsl_dcfb_driver); + +MODULE_DESCRIPTION("Freescale Simple Display Controller FB Driver"); +MODULE_ALIAS("platform:fsl-dcfb"); +MODULE_LICENSE("GPL v2"); -- 2.1.0.27.g96db324 ^ permalink raw reply related [flat|nested] 35+ messages in thread
* Re: [PATCHv2 1/4] video: fsl-dcfb: Add dcfb framebuffer driver for LS1021A platform 2014-12-03 9:15 ` Xiubo Li (?) @ 2014-12-04 9:21 ` Alexander Stein -1 siblings, 0 replies; 35+ messages in thread From: Alexander Stein @ 2014-12-04 9:21 UTC (permalink / raw) To: Xiubo Li Cc: plagnioj, tomi.valkeinen, shawn.guo, linux-fbdev, linux-arm-kernel, linux-kernel On Wednesday 03 December 2014 17:15:59, Xiubo Li wrote: > + tnp = of_find_node_by_name(dnp, "display-timings"); > + if (!tnp) { > + dev_err(dcfb->dev, "failed to find \"display-timings\" node\n"); > + return -ENODEV; > + goto put_dnp; > + } > + > + for (i = 0; i < of_get_child_count(tnp); i++) { > + struct videomode vm; > + > + ret = videomode_from_timings(timings, &vm, i); > + if (ret < 0) > + goto put_tnp; > + > + ret = fb_videomode_from_videomode(&vm, &fb_vm); > + if (ret < 0) > + goto put_tnp; > + > + fb_add_videomode(&fb_vm, &info->modelist); > + } > + > + ret = of_get_fb_videomode(dnp, &fb_vm, OF_USE_NATIVE_MODE); > + if (ret) > + goto put_dnp; Souldn't this be put_tnp like in the loop above? > + fb_videomode_to_var(&info->var, &fb_vm); > + ret = fsl_dcfb_check_var(&info->var, info); But picking the native mode per default looks nice to be! :) Best regards, Alexander -- Dipl.-Inf. Alexander Stein SYS TEC electronic GmbH Am Windrad 2 08468 Heinsdorfergrund Tel.: 03765 38600-1156 Fax: 03765 38600-4100 Email: alexander.stein@systec-electronic.com Website: www.systec-electronic.com Managing Director: Dipl.-Phys. Siegmar Schmidt Commercial registry: Amtsgericht Chemnitz, HRB 28082 ^ permalink raw reply [flat|nested] 35+ messages in thread
* [PATCHv2 1/4] video: fsl-dcfb: Add dcfb framebuffer driver for LS1021A platform @ 2014-12-04 9:21 ` Alexander Stein 0 siblings, 0 replies; 35+ messages in thread From: Alexander Stein @ 2014-12-04 9:21 UTC (permalink / raw) To: linux-arm-kernel On Wednesday 03 December 2014 17:15:59, Xiubo Li wrote: > + tnp = of_find_node_by_name(dnp, "display-timings"); > + if (!tnp) { > + dev_err(dcfb->dev, "failed to find \"display-timings\" node\n"); > + return -ENODEV; > + goto put_dnp; > + } > + > + for (i = 0; i < of_get_child_count(tnp); i++) { > + struct videomode vm; > + > + ret = videomode_from_timings(timings, &vm, i); > + if (ret < 0) > + goto put_tnp; > + > + ret = fb_videomode_from_videomode(&vm, &fb_vm); > + if (ret < 0) > + goto put_tnp; > + > + fb_add_videomode(&fb_vm, &info->modelist); > + } > + > + ret = of_get_fb_videomode(dnp, &fb_vm, OF_USE_NATIVE_MODE); > + if (ret) > + goto put_dnp; Souldn't this be put_tnp like in the loop above? > + fb_videomode_to_var(&info->var, &fb_vm); > + ret = fsl_dcfb_check_var(&info->var, info); But picking the native mode per default looks nice to be! :) Best regards, Alexander -- Dipl.-Inf. Alexander Stein SYS TEC electronic GmbH Am Windrad 2 08468 Heinsdorfergrund Tel.: 03765 38600-1156 Fax: 03765 38600-4100 Email: alexander.stein at systec-electronic.com Website: www.systec-electronic.com Managing Director: Dipl.-Phys. Siegmar Schmidt Commercial registry: Amtsgericht Chemnitz, HRB 28082 ^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [PATCHv2 1/4] video: fsl-dcfb: Add dcfb framebuffer driver for LS1021A platform @ 2014-12-04 9:21 ` Alexander Stein 0 siblings, 0 replies; 35+ messages in thread From: Alexander Stein @ 2014-12-04 9:21 UTC (permalink / raw) To: linux-arm-kernel On Wednesday 03 December 2014 17:15:59, Xiubo Li wrote: > + tnp = of_find_node_by_name(dnp, "display-timings"); > + if (!tnp) { > + dev_err(dcfb->dev, "failed to find \"display-timings\" node\n"); > + return -ENODEV; > + goto put_dnp; > + } > + > + for (i = 0; i < of_get_child_count(tnp); i++) { > + struct videomode vm; > + > + ret = videomode_from_timings(timings, &vm, i); > + if (ret < 0) > + goto put_tnp; > + > + ret = fb_videomode_from_videomode(&vm, &fb_vm); > + if (ret < 0) > + goto put_tnp; > + > + fb_add_videomode(&fb_vm, &info->modelist); > + } > + > + ret = of_get_fb_videomode(dnp, &fb_vm, OF_USE_NATIVE_MODE); > + if (ret) > + goto put_dnp; Souldn't this be put_tnp like in the loop above? > + fb_videomode_to_var(&info->var, &fb_vm); > + ret = fsl_dcfb_check_var(&info->var, info); But picking the native mode per default looks nice to be! :) Best regards, Alexander -- Dipl.-Inf. Alexander Stein SYS TEC electronic GmbH Am Windrad 2 08468 Heinsdorfergrund Tel.: 03765 38600-1156 Fax: 03765 38600-4100 Email: alexander.stein@systec-electronic.com Website: www.systec-electronic.com Managing Director: Dipl.-Phys. Siegmar Schmidt Commercial registry: Amtsgericht Chemnitz, HRB 28082 ^ permalink raw reply [flat|nested] 35+ messages in thread
* [PATCHv2 2/4] video: fsl-dcfb: Add devicetree binding support 2014-12-03 9:15 ` Xiubo Li (?) @ 2014-12-03 9:16 ` Xiubo Li -1 siblings, 0 replies; 35+ messages in thread From: Xiubo Li @ 2014-12-03 9:16 UTC (permalink / raw) To: plagnioj, tomi.valkeinen Cc: alexander.stein, shawn.guo, linux-fbdev, linux-arm-kernel, linux-kernel, Xiubo Li Add devicetree binding support for fsl-dcfb framebuffer driver. It uses the generic display bindings and helper functions. Signed-off-by: Xiubo Li <Li.Xiubo@freescale.com> --- .../devicetree/bindings/video/fsl,dcfb.txt | 52 ++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 Documentation/devicetree/bindings/video/fsl,dcfb.txt diff --git a/Documentation/devicetree/bindings/video/fsl,dcfb.txt b/Documentation/devicetree/bindings/video/fsl,dcfb.txt new file mode 100644 index 0000000..2f3d02b --- /dev/null +++ b/Documentation/devicetree/bindings/video/fsl,dcfb.txt @@ -0,0 +1,52 @@ +* Freescale Simple Display Controller FB Driver + +=== For dcfb node === +Required properties: +- compatible: Should be one of "fsl,ls1021a-dcfb". +- reg: Address and length of the register set for dcfb. +- clocks: From common clock binding: handle to dcfb clock. +- clock-names: From common clock binding: Shall be "dcfb". +- display: The phandle to display node. + +Optional properties: +- scfg-controller: The phandle of scfg node. + +=== For display sub-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: +dcfb: dcfb@2ce0000 { + compatible = "fsl,ls1021a-dcfb"; + reg = <0x0 0x2ce0000 0x0 0x10000>; + clocks = <&platform_clk 0>; + clock-names = "dcfb"; + scfg-controller = <&scfg>; + display = <&display>; + + display: display@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>; + }; + }; + }; +}; -- 2.1.0.27.g96db324 ^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCHv2 2/4] video: fsl-dcfb: Add devicetree binding support @ 2014-12-03 9:16 ` Xiubo Li 0 siblings, 0 replies; 35+ messages in thread From: Xiubo Li @ 2014-12-03 9:16 UTC (permalink / raw) To: linux-arm-kernel Add devicetree binding support for fsl-dcfb framebuffer driver. It uses the generic display bindings and helper functions. Signed-off-by: Xiubo Li <Li.Xiubo@freescale.com> --- .../devicetree/bindings/video/fsl,dcfb.txt | 52 ++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 Documentation/devicetree/bindings/video/fsl,dcfb.txt diff --git a/Documentation/devicetree/bindings/video/fsl,dcfb.txt b/Documentation/devicetree/bindings/video/fsl,dcfb.txt new file mode 100644 index 0000000..2f3d02b --- /dev/null +++ b/Documentation/devicetree/bindings/video/fsl,dcfb.txt @@ -0,0 +1,52 @@ +* Freescale Simple Display Controller FB Driver + +=== For dcfb node === +Required properties: +- compatible: Should be one of "fsl,ls1021a-dcfb". +- reg: Address and length of the register set for dcfb. +- clocks: From common clock binding: handle to dcfb clock. +- clock-names: From common clock binding: Shall be "dcfb". +- display: The phandle to display node. + +Optional properties: +- scfg-controller: The phandle of scfg node. + +=== For display sub-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: +dcfb: dcfb at 2ce0000 { + compatible = "fsl,ls1021a-dcfb"; + reg = <0x0 0x2ce0000 0x0 0x10000>; + clocks = <&platform_clk 0>; + clock-names = "dcfb"; + scfg-controller = <&scfg>; + 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>; + }; + }; + }; +}; -- 2.1.0.27.g96db324 ^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCHv2 2/4] video: fsl-dcfb: Add devicetree binding support @ 2014-12-03 9:16 ` Xiubo Li 0 siblings, 0 replies; 35+ messages in thread From: Xiubo Li @ 2014-12-03 9:16 UTC (permalink / raw) To: linux-arm-kernel Add devicetree binding support for fsl-dcfb framebuffer driver. It uses the generic display bindings and helper functions. Signed-off-by: Xiubo Li <Li.Xiubo@freescale.com> --- .../devicetree/bindings/video/fsl,dcfb.txt | 52 ++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 Documentation/devicetree/bindings/video/fsl,dcfb.txt diff --git a/Documentation/devicetree/bindings/video/fsl,dcfb.txt b/Documentation/devicetree/bindings/video/fsl,dcfb.txt new file mode 100644 index 0000000..2f3d02b --- /dev/null +++ b/Documentation/devicetree/bindings/video/fsl,dcfb.txt @@ -0,0 +1,52 @@ +* Freescale Simple Display Controller FB Driver + +== For dcfb node =+Required properties: +- compatible: Should be one of "fsl,ls1021a-dcfb". +- reg: Address and length of the register set for dcfb. +- clocks: From common clock binding: handle to dcfb clock. +- clock-names: From common clock binding: Shall be "dcfb". +- display: The phandle to display node. + +Optional properties: +- scfg-controller: The phandle of scfg node. + +== For display sub-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: +dcfb: dcfb@2ce0000 { + compatible = "fsl,ls1021a-dcfb"; + reg = <0x0 0x2ce0000 0x0 0x10000>; + clocks = <&platform_clk 0>; + clock-names = "dcfb"; + scfg-controller = <&scfg>; + display = <&display>; + + display: display@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>; + }; + }; + }; +}; -- 2.1.0.27.g96db324 ^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCHv2 3/4] ARM: ls1021a: dtsi: Add dt node support for dcfb. 2014-12-03 9:15 ` Xiubo Li (?) @ 2014-12-03 9:16 ` Xiubo Li -1 siblings, 0 replies; 35+ messages in thread From: Xiubo Li @ 2014-12-03 9:16 UTC (permalink / raw) To: plagnioj, tomi.valkeinen Cc: alexander.stein, shawn.guo, linux-fbdev, linux-arm-kernel, linux-kernel, Xiubo Li On LS1021A SoC, the dcfb device is in BE mode. Signed-off-by: Xiubo Li <Li.Xiubo@freescale.com> --- arch/arm/boot/dts/ls1021a.dtsi | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/arch/arm/boot/dts/ls1021a.dtsi b/arch/arm/boot/dts/ls1021a.dtsi index c70bb27..740a04e 100644 --- a/arch/arm/boot/dts/ls1021a.dtsi +++ b/arch/arm/boot/dts/ls1021a.dtsi @@ -383,6 +383,16 @@ <&platform_clk 1>; }; + dcfb: dcfb@2ce0000 { + compatible = "fsl,ls1021a-dcfb"; + reg = <0x0 0x2ce0000 0x0 0x10000>; + clocks = <&platform_clk 0>; + clock-names = "dcfb"; + scfg-controller = <&scfg>; + big-endian; + status = "disabled"; + }; + mdio0: mdio@2d24000 { compatible = "gianfar"; device_type = "mdio"; -- 2.1.0.27.g96db324 ^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCHv2 3/4] ARM: ls1021a: dtsi: Add dt node support for dcfb. @ 2014-12-03 9:16 ` Xiubo Li 0 siblings, 0 replies; 35+ messages in thread From: Xiubo Li @ 2014-12-03 9:16 UTC (permalink / raw) To: linux-arm-kernel On LS1021A SoC, the dcfb device is in BE mode. Signed-off-by: Xiubo Li <Li.Xiubo@freescale.com> --- arch/arm/boot/dts/ls1021a.dtsi | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/arch/arm/boot/dts/ls1021a.dtsi b/arch/arm/boot/dts/ls1021a.dtsi index c70bb27..740a04e 100644 --- a/arch/arm/boot/dts/ls1021a.dtsi +++ b/arch/arm/boot/dts/ls1021a.dtsi @@ -383,6 +383,16 @@ <&platform_clk 1>; }; + dcfb: dcfb at 2ce0000 { + compatible = "fsl,ls1021a-dcfb"; + reg = <0x0 0x2ce0000 0x0 0x10000>; + clocks = <&platform_clk 0>; + clock-names = "dcfb"; + scfg-controller = <&scfg>; + big-endian; + status = "disabled"; + }; + mdio0: mdio at 2d24000 { compatible = "gianfar"; device_type = "mdio"; -- 2.1.0.27.g96db324 ^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCHv2 3/4] ARM: ls1021a: dtsi: Add dt node support for dcfb. @ 2014-12-03 9:16 ` Xiubo Li 0 siblings, 0 replies; 35+ messages in thread From: Xiubo Li @ 2014-12-03 9:16 UTC (permalink / raw) To: linux-arm-kernel On LS1021A SoC, the dcfb device is in BE mode. Signed-off-by: Xiubo Li <Li.Xiubo@freescale.com> --- arch/arm/boot/dts/ls1021a.dtsi | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/arch/arm/boot/dts/ls1021a.dtsi b/arch/arm/boot/dts/ls1021a.dtsi index c70bb27..740a04e 100644 --- a/arch/arm/boot/dts/ls1021a.dtsi +++ b/arch/arm/boot/dts/ls1021a.dtsi @@ -383,6 +383,16 @@ <&platform_clk 1>; }; + dcfb: dcfb@2ce0000 { + compatible = "fsl,ls1021a-dcfb"; + reg = <0x0 0x2ce0000 0x0 0x10000>; + clocks = <&platform_clk 0>; + clock-names = "dcfb"; + scfg-controller = <&scfg>; + big-endian; + status = "disabled"; + }; + mdio0: mdio@2d24000 { compatible = "gianfar"; device_type = "mdio"; -- 2.1.0.27.g96db324 ^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCHv2 4/4] ARM: ls1021a: dts: Add and enable dt node for dcfb. 2014-12-03 9:15 ` Xiubo Li (?) @ 2014-12-03 9:16 ` Xiubo Li -1 siblings, 0 replies; 35+ messages in thread From: Xiubo Li @ 2014-12-03 9:16 UTC (permalink / raw) To: plagnioj, tomi.valkeinen Cc: alexander.stein, shawn.guo, linux-fbdev, linux-arm-kernel, linux-kernel, Xiubo Li On LS1021A TWR board, the TFT LCD panel is WQVGA "480x272", and the bpp is 24. Signed-off-by: Xiubo Li <Li.Xiubo@freescale.com> --- arch/arm/boot/dts/ls1021a-twr.dts | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/arch/arm/boot/dts/ls1021a-twr.dts b/arch/arm/boot/dts/ls1021a-twr.dts index a2c591e..3602286 100644 --- a/arch/arm/boot/dts/ls1021a-twr.dts +++ b/arch/arm/boot/dts/ls1021a-twr.dts @@ -58,6 +58,32 @@ }; }; +&dcfb { + display = <&display>; + status = "okay"; + + display: display@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 = <2>; + vfront-porch = <2>; + hsync-len = <41>; + vsync-len = <4>; + hsync-active = <1>; + vsync-active = <1>; + }; + }; + }; +}; + &dspi1 { bus-num = <0>; status = "okay"; -- 2.1.0.27.g96db324 ^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCHv2 4/4] ARM: ls1021a: dts: Add and enable dt node for dcfb. @ 2014-12-03 9:16 ` Xiubo Li 0 siblings, 0 replies; 35+ messages in thread From: Xiubo Li @ 2014-12-03 9:16 UTC (permalink / raw) To: linux-arm-kernel On LS1021A TWR board, the TFT LCD panel is WQVGA "480x272", and the bpp is 24. Signed-off-by: Xiubo Li <Li.Xiubo@freescale.com> --- arch/arm/boot/dts/ls1021a-twr.dts | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/arch/arm/boot/dts/ls1021a-twr.dts b/arch/arm/boot/dts/ls1021a-twr.dts index a2c591e..3602286 100644 --- a/arch/arm/boot/dts/ls1021a-twr.dts +++ b/arch/arm/boot/dts/ls1021a-twr.dts @@ -58,6 +58,32 @@ }; }; +&dcfb { + display = <&display>; + status = "okay"; + + 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 = <2>; + vfront-porch = <2>; + hsync-len = <41>; + vsync-len = <4>; + hsync-active = <1>; + vsync-active = <1>; + }; + }; + }; +}; + &dspi1 { bus-num = <0>; status = "okay"; -- 2.1.0.27.g96db324 ^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCHv2 4/4] ARM: ls1021a: dts: Add and enable dt node for dcfb. @ 2014-12-03 9:16 ` Xiubo Li 0 siblings, 0 replies; 35+ messages in thread From: Xiubo Li @ 2014-12-03 9:16 UTC (permalink / raw) To: linux-arm-kernel On LS1021A TWR board, the TFT LCD panel is WQVGA "480x272", and the bpp is 24. Signed-off-by: Xiubo Li <Li.Xiubo@freescale.com> --- arch/arm/boot/dts/ls1021a-twr.dts | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/arch/arm/boot/dts/ls1021a-twr.dts b/arch/arm/boot/dts/ls1021a-twr.dts index a2c591e..3602286 100644 --- a/arch/arm/boot/dts/ls1021a-twr.dts +++ b/arch/arm/boot/dts/ls1021a-twr.dts @@ -58,6 +58,32 @@ }; }; +&dcfb { + display = <&display>; + status = "okay"; + + display: display@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 = <2>; + vfront-porch = <2>; + hsync-len = <41>; + vsync-len = <4>; + hsync-active = <1>; + vsync-active = <1>; + }; + }; + }; +}; + &dspi1 { bus-num = <0>; status = "okay"; -- 2.1.0.27.g96db324 ^ permalink raw reply related [flat|nested] 35+ messages in thread
* Re: [PATCHv2 0/4] LS1021A: Add dcfb framebuffer driver support. 2014-12-03 9:15 ` Xiubo Li (?) @ 2014-12-03 9:51 ` Arnd Bergmann -1 siblings, 0 replies; 35+ messages in thread From: Arnd Bergmann @ 2014-12-03 9:51 UTC (permalink / raw) To: linux-arm-kernel Cc: Xiubo Li, plagnioj, tomi.valkeinen, linux-fbdev, linux-kernel, shawn.guo, alexander.stein On Wednesday 03 December 2014 17:15:58 Xiubo Li wrote: > Framebuffer driver for the Freescale SoC Display Controller. > > > Change in V2: > - Use the native-mode timing as default. > - Add to_fsl_private(). <standard reply> We try to not have any new framebuffer drivers. Please consider making this a DRM/KMS driver instead. </standard reply> Arnd ^ permalink raw reply [flat|nested] 35+ messages in thread
* [PATCHv2 0/4] LS1021A: Add dcfb framebuffer driver support. @ 2014-12-03 9:51 ` Arnd Bergmann 0 siblings, 0 replies; 35+ messages in thread From: Arnd Bergmann @ 2014-12-03 9:51 UTC (permalink / raw) To: linux-arm-kernel On Wednesday 03 December 2014 17:15:58 Xiubo Li wrote: > Framebuffer driver for the Freescale SoC Display Controller. > > > Change in V2: > - Use the native-mode timing as default. > - Add to_fsl_private(). <standard reply> We try to not have any new framebuffer drivers. Please consider making this a DRM/KMS driver instead. </standard reply> Arnd ^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [PATCHv2 0/4] LS1021A: Add dcfb framebuffer driver support. @ 2014-12-03 9:51 ` Arnd Bergmann 0 siblings, 0 replies; 35+ messages in thread From: Arnd Bergmann @ 2014-12-03 9:51 UTC (permalink / raw) To: linux-arm-kernel On Wednesday 03 December 2014 17:15:58 Xiubo Li wrote: > Framebuffer driver for the Freescale SoC Display Controller. > > > Change in V2: > - Use the native-mode timing as default. > - Add to_fsl_private(). <standard reply> We try to not have any new framebuffer drivers. Please consider making this a DRM/KMS driver instead. </standard reply> Arnd ^ permalink raw reply [flat|nested] 35+ messages in thread
* RE: [PATCHv2 0/4] LS1021A: Add dcfb framebuffer driver support. 2014-12-03 9:51 ` Arnd Bergmann @ 2014-12-04 1:56 ` Li.Xiubo -1 siblings, 0 replies; 35+ messages in thread From: Li.Xiubo @ 2014-12-04 1:56 UTC (permalink / raw) To: Arnd Bergmann Cc: plagnioj, tomi.valkeinen, linux-fbdev, linux-kernel, shawn.guo, alexander.stein Hi Arnd, Thanks for you advice. Because this is very emergency for customers and have delayed for monthes, and the DRM/KMS will have a little long time to be supported. So I'd like to add this first and will add DRM/KMS version later. Thanks very much, BRs Xiubo > -----Original Message----- > From: linux-fbdev-owner@vger.kernel.org [mailto:linux-fbdev- > owner@vger.kernel.org] On Behalf Of Arnd Bergmann > Sent: Wednesday, December 03, 2014 5:52 PM > To: linux-arm-kernel@lists.infradead.org > Cc: Xiubo Li-B47053; plagnioj@jcrosoft.com; tomi.valkeinen@ti.com; linux- > fbdev@vger.kernel.org; linux-kernel@vger.kernel.org; shawn.guo@linaro.org; > alexander.stein@systec-electronic.com > Subject: Re: [PATCHv2 0/4] LS1021A: Add dcfb framebuffer driver support. > > On Wednesday 03 December 2014 17:15:58 Xiubo Li wrote: > > Framebuffer driver for the Freescale SoC Display Controller. > > > > > > Change in V2: > > - Use the native-mode timing as default. > > - Add to_fsl_private(). > > <standard reply> > > We try to not have any new framebuffer drivers. Please consider making > this a DRM/KMS driver instead. > > </standard reply> > > Arnd > -- > To unsubscribe from this list: send the line "unsubscribe linux-fbdev" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 35+ messages in thread
* RE: [PATCHv2 0/4] LS1021A: Add dcfb framebuffer driver support. @ 2014-12-04 1:56 ` Li.Xiubo 0 siblings, 0 replies; 35+ messages in thread From: Li.Xiubo @ 2014-12-04 1:56 UTC (permalink / raw) To: Arnd Bergmann Cc: plagnioj, tomi.valkeinen, linux-fbdev, linux-kernel, shawn.guo, alexander.stein Hi Arnd, Thanks for you advice. Because this is very emergency for customers and have delayed for monthes, and the DRM/KMS will have a little long time to be supported. So I'd like to add this first and will add DRM/KMS version later. Thanks very much, BRs Xiubo > -----Original Message----- > From: linux-fbdev-owner@vger.kernel.org [mailto:linux-fbdev- > owner@vger.kernel.org] On Behalf Of Arnd Bergmann > Sent: Wednesday, December 03, 2014 5:52 PM > To: linux-arm-kernel@lists.infradead.org > Cc: Xiubo Li-B47053; plagnioj@jcrosoft.com; tomi.valkeinen@ti.com; linux- > fbdev@vger.kernel.org; linux-kernel@vger.kernel.org; shawn.guo@linaro.org; > alexander.stein@systec-electronic.com > Subject: Re: [PATCHv2 0/4] LS1021A: Add dcfb framebuffer driver support. > > On Wednesday 03 December 2014 17:15:58 Xiubo Li wrote: > > Framebuffer driver for the Freescale SoC Display Controller. > > > > > > Change in V2: > > - Use the native-mode timing as default. > > - Add to_fsl_private(). > > <standard reply> > > We try to not have any new framebuffer drivers. Please consider making > this a DRM/KMS driver instead. > > </standard reply> > > Arnd > -- > To unsubscribe from this list: send the line "unsubscribe linux-fbdev" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [PATCHv2 0/4] LS1021A: Add dcfb framebuffer driver support. 2014-12-04 1:56 ` Li.Xiubo @ 2014-12-04 8:10 ` Tomi Valkeinen -1 siblings, 0 replies; 35+ messages in thread From: Tomi Valkeinen @ 2014-12-04 8:10 UTC (permalink / raw) To: Li.Xiubo, Arnd Bergmann Cc: plagnioj, linux-fbdev, linux-kernel, shawn.guo, alexander.stein [-- Attachment #1: Type: text/plain, Size: 751 bytes --] Hi Xiubo, On 04/12/14 03:56, Li.Xiubo@freescale.com wrote: > Hi Arnd, > > Thanks for you advice. > > Because this is very emergency for customers and have delayed for monthes, and the > DRM/KMS will have a little long time to be supported. So I'd like to add this first > and will add DRM/KMS version later. I would also suggest to just write a drm driver for this. I don't see anything special in this driver that would be better supported via fbdev. With drm you'll get a more modern framework, and you will still have the same /dev/fbX device to use for legacy userspace software. What do you mean with "delayed for months"? The first version of this series (that I can find) was posted less than two weeks ago. Tomi [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 819 bytes --] ^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [PATCHv2 0/4] LS1021A: Add dcfb framebuffer driver support. @ 2014-12-04 8:10 ` Tomi Valkeinen 0 siblings, 0 replies; 35+ messages in thread From: Tomi Valkeinen @ 2014-12-04 8:10 UTC (permalink / raw) To: Li.Xiubo, Arnd Bergmann Cc: plagnioj, linux-fbdev, linux-kernel, shawn.guo, alexander.stein [-- Attachment #1: Type: text/plain, Size: 751 bytes --] Hi Xiubo, On 04/12/14 03:56, Li.Xiubo@freescale.com wrote: > Hi Arnd, > > Thanks for you advice. > > Because this is very emergency for customers and have delayed for monthes, and the > DRM/KMS will have a little long time to be supported. So I'd like to add this first > and will add DRM/KMS version later. I would also suggest to just write a drm driver for this. I don't see anything special in this driver that would be better supported via fbdev. With drm you'll get a more modern framework, and you will still have the same /dev/fbX device to use for legacy userspace software. What do you mean with "delayed for months"? The first version of this series (that I can find) was posted less than two weeks ago. Tomi [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 819 bytes --] ^ permalink raw reply [flat|nested] 35+ messages in thread
* RE: [PATCHv2 0/4] LS1021A: Add dcfb framebuffer driver support. 2014-12-04 8:10 ` Tomi Valkeinen @ 2014-12-04 8:30 ` Li.Xiubo -1 siblings, 0 replies; 35+ messages in thread From: Li.Xiubo @ 2014-12-04 8:30 UTC (permalink / raw) To: Tomi Valkeinen, Arnd Bergmann Cc: plagnioj, linux-fbdev, linux-kernel, shawn.guo, alexander.stein Hi Tomi, > -----Original Message----- > From: Tomi Valkeinen [mailto:tomi.valkeinen@ti.com] > Sent: Thursday, December 04, 2014 4:10 PM > To: Xiubo Li-B47053; Arnd Bergmann > Cc: plagnioj@jcrosoft.com; linux-fbdev@vger.kernel.org; linux- > kernel@vger.kernel.org; shawn.guo@linaro.org; alexander.stein@systec- > electronic.com > Subject: Re: [PATCHv2 0/4] LS1021A: Add dcfb framebuffer driver support. > > Hi Xiubo, > > On 04/12/14 03:56, Li.Xiubo@freescale.com wrote: > > Hi Arnd, > > > > Thanks for you advice. > > > > Because this is very emergency for customers and have delayed for monthes, > and the > > DRM/KMS will have a little long time to be supported. So I'd like to add > this first > > and will add DRM/KMS version later. > > I would also suggest to just write a drm driver for this. I don't see > anything special in this driver that would be better supported via > fbdev. With drm you'll get a more modern framework, and you will still > have the same /dev/fbX device to use for legacy userspace software. > > What do you mean with "delayed for months"? The first version of this > series (that I can find) was posted less than two weeks ago. > Sorry for confusing, it was delayed for other reasons internal. I am not familiar about the DRM, and I'd like to know if the DRM driver will be support, should I also develop the libdrm too ? Or just coding in kernel level ? Is there any Document about how to have /dev/fbX device to use ? If possible, I'd like this could be accept for this time. And I will add the DRM Version later(for developing and testing will take a long time). Thanks very much, BRs Xiubo > Tomi > ^ permalink raw reply [flat|nested] 35+ messages in thread
* RE: [PATCHv2 0/4] LS1021A: Add dcfb framebuffer driver support. @ 2014-12-04 8:30 ` Li.Xiubo 0 siblings, 0 replies; 35+ messages in thread From: Li.Xiubo @ 2014-12-04 8:30 UTC (permalink / raw) To: Tomi Valkeinen, Arnd Bergmann Cc: plagnioj, linux-fbdev, linux-kernel, shawn.guo, alexander.stein Hi Tomi, > -----Original Message----- > From: Tomi Valkeinen [mailto:tomi.valkeinen@ti.com] > Sent: Thursday, December 04, 2014 4:10 PM > To: Xiubo Li-B47053; Arnd Bergmann > Cc: plagnioj@jcrosoft.com; linux-fbdev@vger.kernel.org; linux- > kernel@vger.kernel.org; shawn.guo@linaro.org; alexander.stein@systec- > electronic.com > Subject: Re: [PATCHv2 0/4] LS1021A: Add dcfb framebuffer driver support. > > Hi Xiubo, > > On 04/12/14 03:56, Li.Xiubo@freescale.com wrote: > > Hi Arnd, > > > > Thanks for you advice. > > > > Because this is very emergency for customers and have delayed for monthes, > and the > > DRM/KMS will have a little long time to be supported. So I'd like to add > this first > > and will add DRM/KMS version later. > > I would also suggest to just write a drm driver for this. I don't see > anything special in this driver that would be better supported via > fbdev. With drm you'll get a more modern framework, and you will still > have the same /dev/fbX device to use for legacy userspace software. > > What do you mean with "delayed for months"? The first version of this > series (that I can find) was posted less than two weeks ago. > Sorry for confusing, it was delayed for other reasons internal. I am not familiar about the DRM, and I'd like to know if the DRM driver will be support, should I also develop the libdrm too ? Or just coding in kernel level ? Is there any Document about how to have /dev/fbX device to use ? If possible, I'd like this could be accept for this time. And I will add the DRM Version later(for developing and testing will take a long time). Thanks very much, BRs Xiubo > Tomi > ^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [PATCHv2 0/4] LS1021A: Add dcfb framebuffer driver support. 2014-12-04 8:30 ` Li.Xiubo @ 2014-12-04 9:09 ` Tomi Valkeinen -1 siblings, 0 replies; 35+ messages in thread From: Tomi Valkeinen @ 2014-12-04 9:09 UTC (permalink / raw) To: Li.Xiubo Cc: Arnd Bergmann, plagnioj, linux-fbdev, linux-kernel, shawn.guo, alexander.stein [-- Attachment #1: Type: text/plain, Size: 1585 bytes --] On 04/12/14 10:30, Li.Xiubo@freescale.com wrote: > Sorry for confusing, it was delayed for other reasons internal. > > I am not familiar about the DRM, and I'd like to know if the DRM driver will be > support, should I also develop the libdrm too ? Or just coding in kernel level ? For simple drm drivers (this looks like it would be a simple one), I don't think there's any need for libdrm support. The generic DRM interfaces should be enough, so just kernel level coding needed. > Is there any Document about how to have /dev/fbX device to use ? There's DRM documentation here: https://www.kernel.org/doc/htmldocs/drm/index.html And many existing drivers to use as examples. The dri-devel list (http://lists.freedesktop.org/mailman/listinfo/dri-devel), which is the mailing list used for DRM development, is active and you probably can get more support from there than from the fbdev list. It should not be a huge effort to write a drm driver for a simple LCD controller like this. I would bet that you can write a working driver in a week. > If possible, I'd like this could be accept for this time. And I will add the DRM > Version later(for developing and testing will take a long time). I'm sorry but "it was delayed for internal reasons" and "our customer needs this driver" are not very good reasons for getting a driver merged to mainline Linux. You can provide your driver to your customer as a separate patch series which they can apply. There should be no conflicts or other issues there, so it should be simple. Tomi [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 819 bytes --] ^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [PATCHv2 0/4] LS1021A: Add dcfb framebuffer driver support. @ 2014-12-04 9:09 ` Tomi Valkeinen 0 siblings, 0 replies; 35+ messages in thread From: Tomi Valkeinen @ 2014-12-04 9:09 UTC (permalink / raw) To: Li.Xiubo Cc: Arnd Bergmann, plagnioj, linux-fbdev, linux-kernel, shawn.guo, alexander.stein [-- Attachment #1: Type: text/plain, Size: 1585 bytes --] On 04/12/14 10:30, Li.Xiubo@freescale.com wrote: > Sorry for confusing, it was delayed for other reasons internal. > > I am not familiar about the DRM, and I'd like to know if the DRM driver will be > support, should I also develop the libdrm too ? Or just coding in kernel level ? For simple drm drivers (this looks like it would be a simple one), I don't think there's any need for libdrm support. The generic DRM interfaces should be enough, so just kernel level coding needed. > Is there any Document about how to have /dev/fbX device to use ? There's DRM documentation here: https://www.kernel.org/doc/htmldocs/drm/index.html And many existing drivers to use as examples. The dri-devel list (http://lists.freedesktop.org/mailman/listinfo/dri-devel), which is the mailing list used for DRM development, is active and you probably can get more support from there than from the fbdev list. It should not be a huge effort to write a drm driver for a simple LCD controller like this. I would bet that you can write a working driver in a week. > If possible, I'd like this could be accept for this time. And I will add the DRM > Version later(for developing and testing will take a long time). I'm sorry but "it was delayed for internal reasons" and "our customer needs this driver" are not very good reasons for getting a driver merged to mainline Linux. You can provide your driver to your customer as a separate patch series which they can apply. There should be no conflicts or other issues there, so it should be simple. Tomi [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 819 bytes --] ^ permalink raw reply [flat|nested] 35+ messages in thread
* RE: [PATCHv2 0/4] LS1021A: Add dcfb framebuffer driver support. 2014-12-04 9:09 ` Tomi Valkeinen @ 2014-12-04 9:54 ` Li.Xiubo -1 siblings, 0 replies; 35+ messages in thread From: Li.Xiubo @ 2014-12-04 9:54 UTC (permalink / raw) To: Tomi Valkeinen Cc: Arnd Bergmann, plagnioj, linux-fbdev, linux-kernel, shawn.guo, alexander.stein Hi Tomi, Thanks for your information very much. > > Sorry for confusing, it was delayed for other reasons internal. > > > > I am not familiar about the DRM, and I'd like to know if the DRM driver will > be > > support, should I also develop the libdrm too ? Or just coding in kernel > level ? > > For simple drm drivers (this looks like it would be a simple one), I > don't think there's any need for libdrm support. The generic DRM > interfaces should be enough, so just kernel level coding needed. > That's to say, if I am using the X11 server without any code in usrspace, If the DRM driver will support /dev/fbX, it could work correctly ? Thanks, BRs Xiubo ^ permalink raw reply [flat|nested] 35+ messages in thread
* RE: [PATCHv2 0/4] LS1021A: Add dcfb framebuffer driver support. @ 2014-12-04 9:54 ` Li.Xiubo 0 siblings, 0 replies; 35+ messages in thread From: Li.Xiubo @ 2014-12-04 9:54 UTC (permalink / raw) To: Tomi Valkeinen Cc: Arnd Bergmann, plagnioj, linux-fbdev, linux-kernel, shawn.guo, alexander.stein Hi Tomi, Thanks for your information very much. > > Sorry for confusing, it was delayed for other reasons internal. > > > > I am not familiar about the DRM, and I'd like to know if the DRM driver will > be > > support, should I also develop the libdrm too ? Or just coding in kernel > level ? > > For simple drm drivers (this looks like it would be a simple one), I > don't think there's any need for libdrm support. The generic DRM > interfaces should be enough, so just kernel level coding needed. > That's to say, if I am using the X11 server without any code in usrspace, If the DRM driver will support /dev/fbX, it could work correctly ? Thanks, BRs Xiubo ^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [PATCHv2 0/4] LS1021A: Add dcfb framebuffer driver support. 2014-12-04 9:54 ` Li.Xiubo @ 2014-12-04 9:59 ` Tomi Valkeinen -1 siblings, 0 replies; 35+ messages in thread From: Tomi Valkeinen @ 2014-12-04 9:59 UTC (permalink / raw) To: Li.Xiubo Cc: Arnd Bergmann, plagnioj, linux-fbdev, linux-kernel, shawn.guo, alexander.stein [-- Attachment #1: Type: text/plain, Size: 940 bytes --] On 04/12/14 11:54, Li.Xiubo@freescale.com wrote: > Hi Tomi, > > Thanks for your information very much. > >>> Sorry for confusing, it was delayed for other reasons internal. >>> >>> I am not familiar about the DRM, and I'd like to know if the DRM driver will >> be >>> support, should I also develop the libdrm too ? Or just coding in kernel >> level ? >> >> For simple drm drivers (this looks like it would be a simple one), I >> don't think there's any need for libdrm support. The generic DRM >> interfaces should be enough, so just kernel level coding needed. >> > > That's to say, if I am using the X11 server without any code in usrspace, > If the DRM driver will support /dev/fbX, it could work correctly ? Yes. DRM offers helper code to add /dev/fbX with not too many lines. You can look at the docs and drm_fb_helper.c. And X11 should work fine on top of that, using the X11 fbdev support. Tomi [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 819 bytes --] ^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [PATCHv2 0/4] LS1021A: Add dcfb framebuffer driver support. @ 2014-12-04 9:59 ` Tomi Valkeinen 0 siblings, 0 replies; 35+ messages in thread From: Tomi Valkeinen @ 2014-12-04 9:59 UTC (permalink / raw) To: Li.Xiubo Cc: Arnd Bergmann, plagnioj, linux-fbdev, linux-kernel, shawn.guo, alexander.stein [-- Attachment #1: Type: text/plain, Size: 940 bytes --] On 04/12/14 11:54, Li.Xiubo@freescale.com wrote: > Hi Tomi, > > Thanks for your information very much. > >>> Sorry for confusing, it was delayed for other reasons internal. >>> >>> I am not familiar about the DRM, and I'd like to know if the DRM driver will >> be >>> support, should I also develop the libdrm too ? Or just coding in kernel >> level ? >> >> For simple drm drivers (this looks like it would be a simple one), I >> don't think there's any need for libdrm support. The generic DRM >> interfaces should be enough, so just kernel level coding needed. >> > > That's to say, if I am using the X11 server without any code in usrspace, > If the DRM driver will support /dev/fbX, it could work correctly ? Yes. DRM offers helper code to add /dev/fbX with not too many lines. You can look at the docs and drm_fb_helper.c. And X11 should work fine on top of that, using the X11 fbdev support. Tomi [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 819 bytes --] ^ permalink raw reply [flat|nested] 35+ messages in thread
* RE: [PATCHv2 0/4] LS1021A: Add dcfb framebuffer driver support. 2014-12-04 9:59 ` Tomi Valkeinen @ 2014-12-04 10:03 ` Li.Xiubo -1 siblings, 0 replies; 35+ messages in thread From: Li.Xiubo @ 2014-12-04 10:03 UTC (permalink / raw) To: Tomi Valkeinen Cc: Arnd Bergmann, plagnioj, linux-fbdev, linux-kernel, shawn.guo, alexander.stein Hi Tomi, Thanks very much for your help. I will have a try these days. BRs Xiubo > -----Original Message----- > From: Tomi Valkeinen [mailto:tomi.valkeinen@ti.com] > Sent: Thursday, December 04, 2014 6:00 PM > To: Xiubo Li-B47053 > Cc: Arnd Bergmann; plagnioj@jcrosoft.com; linux-fbdev@vger.kernel.org; linux- > kernel@vger.kernel.org; shawn.guo@linaro.org; alexander.stein@systec- > electronic.com > Subject: Re: [PATCHv2 0/4] LS1021A: Add dcfb framebuffer driver support. > > On 04/12/14 11:54, Li.Xiubo@freescale.com wrote: > > Hi Tomi, > > > > Thanks for your information very much. > > > >>> Sorry for confusing, it was delayed for other reasons internal. > >>> > >>> I am not familiar about the DRM, and I'd like to know if the DRM driver > will > >> be > >>> support, should I also develop the libdrm too ? Or just coding in kernel > >> level ? > >> > >> For simple drm drivers (this looks like it would be a simple one), I > >> don't think there's any need for libdrm support. The generic DRM > >> interfaces should be enough, so just kernel level coding needed. > >> > > > > That's to say, if I am using the X11 server without any code in usrspace, > > If the DRM driver will support /dev/fbX, it could work correctly ? > > Yes. DRM offers helper code to add /dev/fbX with not too many lines. You > can look at the docs and drm_fb_helper.c. > > And X11 should work fine on top of that, using the X11 fbdev support. > > Tomi > ^ permalink raw reply [flat|nested] 35+ messages in thread
* RE: [PATCHv2 0/4] LS1021A: Add dcfb framebuffer driver support. @ 2014-12-04 10:03 ` Li.Xiubo 0 siblings, 0 replies; 35+ messages in thread From: Li.Xiubo @ 2014-12-04 10:03 UTC (permalink / raw) To: Tomi Valkeinen Cc: Arnd Bergmann, plagnioj, linux-fbdev, linux-kernel, shawn.guo, alexander.stein Hi Tomi, Thanks very much for your help. I will have a try these days. BRs Xiubo > -----Original Message----- > From: Tomi Valkeinen [mailto:tomi.valkeinen@ti.com] > Sent: Thursday, December 04, 2014 6:00 PM > To: Xiubo Li-B47053 > Cc: Arnd Bergmann; plagnioj@jcrosoft.com; linux-fbdev@vger.kernel.org; linux- > kernel@vger.kernel.org; shawn.guo@linaro.org; alexander.stein@systec- > electronic.com > Subject: Re: [PATCHv2 0/4] LS1021A: Add dcfb framebuffer driver support. > > On 04/12/14 11:54, Li.Xiubo@freescale.com wrote: > > Hi Tomi, > > > > Thanks for your information very much. > > > >>> Sorry for confusing, it was delayed for other reasons internal. > >>> > >>> I am not familiar about the DRM, and I'd like to know if the DRM driver > will > >> be > >>> support, should I also develop the libdrm too ? Or just coding in kernel > >> level ? > >> > >> For simple drm drivers (this looks like it would be a simple one), I > >> don't think there's any need for libdrm support. The generic DRM > >> interfaces should be enough, so just kernel level coding needed. > >> > > > > That's to say, if I am using the X11 server without any code in usrspace, > > If the DRM driver will support /dev/fbX, it could work correctly ? > > Yes. DRM offers helper code to add /dev/fbX with not too many lines. You > can look at the docs and drm_fb_helper.c. > > And X11 should work fine on top of that, using the X11 fbdev support. > > Tomi > ^ permalink raw reply [flat|nested] 35+ messages in thread
end of thread, other threads:[~2014-12-04 10:19 UTC | newest] Thread overview: 35+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2014-12-03 9:15 [PATCHv2 0/4] LS1021A: Add dcfb framebuffer driver support Xiubo Li 2014-12-03 9:15 ` Xiubo Li 2014-12-03 9:15 ` Xiubo Li 2014-12-03 9:15 ` [PATCHv2 1/4] video: fsl-dcfb: Add dcfb framebuffer driver for LS1021A platform Xiubo Li 2014-12-03 9:15 ` Xiubo Li 2014-12-03 9:15 ` Xiubo Li 2014-12-04 9:21 ` Alexander Stein 2014-12-04 9:21 ` Alexander Stein 2014-12-04 9:21 ` Alexander Stein 2014-12-03 9:16 ` [PATCHv2 2/4] video: fsl-dcfb: Add devicetree binding support Xiubo Li 2014-12-03 9:16 ` Xiubo Li 2014-12-03 9:16 ` Xiubo Li 2014-12-03 9:16 ` [PATCHv2 3/4] ARM: ls1021a: dtsi: Add dt node support for dcfb Xiubo Li 2014-12-03 9:16 ` Xiubo Li 2014-12-03 9:16 ` Xiubo Li 2014-12-03 9:16 ` [PATCHv2 4/4] ARM: ls1021a: dts: Add and enable dt node " Xiubo Li 2014-12-03 9:16 ` Xiubo Li 2014-12-03 9:16 ` Xiubo Li 2014-12-03 9:51 ` [PATCHv2 0/4] LS1021A: Add dcfb framebuffer driver support Arnd Bergmann 2014-12-03 9:51 ` Arnd Bergmann 2014-12-03 9:51 ` Arnd Bergmann 2014-12-04 1:56 ` Li.Xiubo 2014-12-04 1:56 ` Li.Xiubo 2014-12-04 8:10 ` Tomi Valkeinen 2014-12-04 8:10 ` Tomi Valkeinen 2014-12-04 8:30 ` Li.Xiubo 2014-12-04 8:30 ` Li.Xiubo 2014-12-04 9:09 ` Tomi Valkeinen 2014-12-04 9:09 ` Tomi Valkeinen 2014-12-04 9:54 ` Li.Xiubo 2014-12-04 9:54 ` Li.Xiubo 2014-12-04 9:59 ` Tomi Valkeinen 2014-12-04 9:59 ` Tomi Valkeinen 2014-12-04 10:03 ` Li.Xiubo 2014-12-04 10:03 ` Li.Xiubo
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.