From 767f17a70e5cc5147ddba112977fe7bed0a31bd2 Mon Sep 17 00:00:00 2001 From: Melchior Franz Date: Mon, 1 Apr 2019 17:46:53 +0200 Subject: fbdev: mxsfb: implement FB_PRE_INIT_FB option The FB_PRE_INIT_FB option keeps the kernel from reinitializing the display and prevents flickering during the transition from a bootloader splash screen to the kernel logo screen. Make this option available for the mxsfb driver. Signed-off-by: Melchior Franz Signed-off-by: Martin Kepplinger Signed-off-by: Manfred Schlaegl Cc: Shawn Guo Cc: Sascha Hauer Cc: Pengutronix Kernel Team Cc: Fabio Estevam Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/video/fbdev/Kconfig | 2 +- drivers/video/fbdev/mxsfb.c | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) (limited to 'drivers/video') diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig index 58a9590c9db6..0e7ab29c9c70 100644 --- a/drivers/video/fbdev/Kconfig +++ b/drivers/video/fbdev/Kconfig @@ -2183,7 +2183,7 @@ config FB_EP93XX config FB_PRE_INIT_FB bool "Don't reinitialize, use bootloader's GDC/Display configuration" - depends on FB && FB_MB862XX_LIME + depends on FB && (FB_MB862XX_LIME || FB_MXS) ---help--- Select this option if display contents should be inherited as set by the bootloader. diff --git a/drivers/video/fbdev/mxsfb.c b/drivers/video/fbdev/mxsfb.c index 12c8bd1d24d5..a017200a16b3 100644 --- a/drivers/video/fbdev/mxsfb.c +++ b/drivers/video/fbdev/mxsfb.c @@ -181,6 +181,7 @@ struct mxsfb_info { const struct mxsfb_devdata *devdata; u32 sync; struct regulator *reg_lcd; + int pre_init; }; #define mxsfb_is_v3(host) (host->devdata->ipversion == 3) @@ -419,6 +420,12 @@ static int mxsfb_set_par(struct fb_info *fb_info) fb_info->fix.line_length = line_size; + if (host->pre_init) { + mxsfb_enable_controller(fb_info); + host->pre_init = 0; + return 0; + } + /* * It seems, you can't re-program the controller if it is still running. * This may lead into shifted pictures (FIFO issue?). @@ -931,6 +938,10 @@ static int mxsfb_probe(struct platform_device *pdev) if (IS_ERR(host->reg_lcd)) host->reg_lcd = NULL; +#if defined(CONFIG_FB_PRE_INIT_FB) + host->pre_init = 1; +#endif + fb_info->pseudo_palette = devm_kcalloc(&pdev->dev, 16, sizeof(u32), GFP_KERNEL); if (!fb_info->pseudo_palette) { @@ -963,6 +974,7 @@ static int mxsfb_probe(struct platform_device *pdev) mxsfb_enable_controller(fb_info); } + host->pre_init = 0; dev_info(&pdev->dev, "initialized\n"); return 0; -- cgit v1.2.3 From a7ae716ecfe76d455ccb21864d1c926293a4656a Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Mon, 1 Apr 2019 17:46:54 +0200 Subject: video: fbdev: vesafb: fix indentation issue There are a couple of statements that are indented too deeply, fix this by removing tabs. Also add a space after a comma to clean up a cppcheck warning. Signed-off-by: Colin Ian King Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/video/fbdev/vesafb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/video') diff --git a/drivers/video/fbdev/vesafb.c b/drivers/video/fbdev/vesafb.c index 528fe917dd49..dc1f9cfb6e7e 100644 --- a/drivers/video/fbdev/vesafb.c +++ b/drivers/video/fbdev/vesafb.c @@ -336,8 +336,8 @@ static int vesafb_probe(struct platform_device *dev) printk(KERN_INFO "vesafb: pmi: set display start = %p, set palette = %p\n",pmi_start,pmi_pal); if (pmi_base[3]) { printk(KERN_INFO "vesafb: pmi: ports = "); - for (i = pmi_base[3]/2; pmi_base[i] != 0xffff; i++) - printk("%x ",pmi_base[i]); + for (i = pmi_base[3]/2; pmi_base[i] != 0xffff; i++) + printk("%x ", pmi_base[i]); printk("\n"); if (pmi_base[i] != 0xffff) { /* -- cgit v1.2.3 From 3f98434235c9d15d389458a9f30fb184db9693ac Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Mon, 1 Apr 2019 17:46:54 +0200 Subject: video: fbdev: savage: fix indentation issue The indentation in the if statement is not indented correctly, fix this with extra level of indentation. Signed-off-by: Colin Ian King Cc: Antonino Daplas Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/video/fbdev/savage/savagefb_driver.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/video') diff --git a/drivers/video/fbdev/savage/savagefb_driver.c b/drivers/video/fbdev/savage/savagefb_driver.c index c09d7426cd92..47b78f0138c3 100644 --- a/drivers/video/fbdev/savage/savagefb_driver.c +++ b/drivers/video/fbdev/savage/savagefb_driver.c @@ -2155,9 +2155,9 @@ static int savage_init_fb_info(struct fb_info *info, struct pci_dev *dev, err = fb_alloc_cmap(&info->cmap, NR_PALETTE, 0); if (!err) - info->flags |= FBINFO_HWACCEL_COPYAREA | - FBINFO_HWACCEL_FILLRECT | - FBINFO_HWACCEL_IMAGEBLIT; + info->flags |= FBINFO_HWACCEL_COPYAREA | + FBINFO_HWACCEL_FILLRECT | + FBINFO_HWACCEL_IMAGEBLIT; } #endif return err; -- cgit v1.2.3 From e4995b12e749873f25bd4c64ba056f506a6d2f1a Mon Sep 17 00:00:00 2001 From: Finn Thain Date: Mon, 1 Apr 2019 17:46:54 +0200 Subject: video/macfb: Remove redundant code The value of info->var.bits_per_pixel get checked in macfb_setcolreg(). Remove additional checks as they are redundant. macfb_defined.activate gets initialized to FB_ACTIVATE_NOW by the struct initializer. Remove redundant assignments. macfb_defined.bits_per_pixel, .width and .height all get assigned unconditionally. Remove redundant initializers. Signed-off-by: Finn Thain Tested-by: Stan Johnson Reviewed-by: Geert Uytterhoeven Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/video/fbdev/macfb.c | 24 ------------------------ 1 file changed, 24 deletions(-) (limited to 'drivers/video') diff --git a/drivers/video/fbdev/macfb.c b/drivers/video/fbdev/macfb.c index e707e617bf1c..00671055a611 100644 --- a/drivers/video/fbdev/macfb.c +++ b/drivers/video/fbdev/macfb.c @@ -120,10 +120,7 @@ struct jet_cmap_regs { #define PIXEL_TO_MM(a) (((a)*10)/28) /* width in mm at 72 dpi */ static struct fb_var_screeninfo macfb_defined = { - .bits_per_pixel = 8, .activate = FB_ACTIVATE_NOW, - .width = -1, - .height = -1, .right_margin = 32, .upper_margin = 16, .lower_margin = 4, @@ -201,9 +198,6 @@ static int v8_brazil_setpalette(unsigned int regno, unsigned int red, unsigned int bpp = info->var.bits_per_pixel; unsigned long flags; - if (bpp > 8) - return 1; /* failsafe */ - local_irq_save(flags); /* On these chips, the CLUT register numbers are spread out @@ -234,9 +228,6 @@ static int rbv_setpalette(unsigned int regno, unsigned int red, { unsigned long flags; - if (info->var.bits_per_pixel > 8) - return 1; /* failsafe */ - local_irq_save(flags); /* From the VideoToolbox driver. Seems to be saying that @@ -353,9 +344,6 @@ static int civic_setpalette(unsigned int regno, unsigned int red, unsigned long flags; int clut_status; - if (info->var.bits_per_pixel > 8) - return 1; /* failsafe */ - local_irq_save(flags); /* Set the register address */ @@ -688,17 +676,14 @@ static int __init macfb_init(void) case NUBUS_DRHW_APPLE_MDC: strcpy(macfb_fix.id, "Mac Disp. Card"); macfb_setpalette = mdc_setpalette; - macfb_defined.activate = FB_ACTIVATE_NOW; break; case NUBUS_DRHW_APPLE_TFB: strcpy(macfb_fix.id, "Toby"); macfb_setpalette = toby_setpalette; - macfb_defined.activate = FB_ACTIVATE_NOW; break; case NUBUS_DRHW_APPLE_JET: strcpy(macfb_fix.id, "Jet"); macfb_setpalette = jet_setpalette; - macfb_defined.activate = FB_ACTIVATE_NOW; break; default: strcpy(macfb_fix.id, "Generic NuBus"); @@ -731,7 +716,6 @@ static int __init macfb_init(void) strcpy(macfb_fix.id, "DAFB"); macfb_setpalette = dafb_setpalette; dafb_cmap_regs = ioremap(DAFB_BASE, 0x1000); - macfb_defined.activate = FB_ACTIVATE_NOW; break; /* @@ -741,7 +725,6 @@ static int __init macfb_init(void) strcpy(macfb_fix.id, "V8"); macfb_setpalette = v8_brazil_setpalette; v8_brazil_cmap_regs = ioremap(DAC_BASE, 0x1000); - macfb_defined.activate = FB_ACTIVATE_NOW; break; /* @@ -755,7 +738,6 @@ static int __init macfb_init(void) strcpy(macfb_fix.id, "Brazil"); macfb_setpalette = v8_brazil_setpalette; v8_brazil_cmap_regs = ioremap(DAC_BASE, 0x1000); - macfb_defined.activate = FB_ACTIVATE_NOW; break; /* @@ -772,7 +754,6 @@ static int __init macfb_init(void) strcpy(macfb_fix.id, "Sonora"); macfb_setpalette = v8_brazil_setpalette; v8_brazil_cmap_regs = ioremap(DAC_BASE, 0x1000); - macfb_defined.activate = FB_ACTIVATE_NOW; break; /* @@ -785,7 +766,6 @@ static int __init macfb_init(void) strcpy(macfb_fix.id, "RBV"); macfb_setpalette = rbv_setpalette; rbv_cmap_regs = ioremap(DAC_BASE, 0x1000); - macfb_defined.activate = FB_ACTIVATE_NOW; break; /* @@ -796,7 +776,6 @@ static int __init macfb_init(void) strcpy(macfb_fix.id, "Civic"); macfb_setpalette = civic_setpalette; civic_cmap_regs = ioremap(CIVIC_BASE, 0x1000); - macfb_defined.activate = FB_ACTIVATE_NOW; break; @@ -810,7 +789,6 @@ static int __init macfb_init(void) macfb_setpalette = v8_brazil_setpalette; v8_brazil_cmap_regs = ioremap(DAC_BASE, 0x1000); - macfb_defined.activate = FB_ACTIVATE_NOW; } break; @@ -823,7 +801,6 @@ static int __init macfb_init(void) macfb_setpalette = v8_brazil_setpalette; v8_brazil_cmap_regs = ioremap(DAC_BASE, 0x1000); - macfb_defined.activate = FB_ACTIVATE_NOW; } break; @@ -892,7 +869,6 @@ static int __init macfb_init(void) strcpy(macfb_fix.id, "CSC"); macfb_setpalette = csc_setpalette; csc_cmap_regs = ioremap(CSC_BASE, 0x1000); - macfb_defined.activate = FB_ACTIVATE_NOW; break; default: -- cgit v1.2.3 From e4bedbb625c9fbf205d9fd3d9532e7ebda4a977d Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 1 Apr 2019 17:46:54 +0200 Subject: fbdev: atafb: Stop printing virtual screen_base Printing (hashed) virtual addresses is useless. Signed-off-by: Geert Uytterhoeven Cc: Michael Schmitz Cc: Paul Gortmaker Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/video/fbdev/atafb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/video') diff --git a/drivers/video/fbdev/atafb.c b/drivers/video/fbdev/atafb.c index fcd2dd670a65..e9d31a4299ee 100644 --- a/drivers/video/fbdev/atafb.c +++ b/drivers/video/fbdev/atafb.c @@ -3175,8 +3175,8 @@ int __init atafb_init(void) kernel_set_cachemode(screen_base, screen_len, IOMAP_WRITETHROUGH); } - printk("atafb: screen_base %p phys_screen_base %lx screen_len %d\n", - screen_base, phys_screen_base, screen_len); + printk("atafb: phys_screen_base %lx screen_len %d\n", + phys_screen_base, screen_len); #ifdef ATAFB_EXT } else { /* Map the video memory (physical address given) to somewhere -- cgit v1.2.3 From 577eabb2cbe2e7d0ab1ceef3047ea698caf5db15 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 1 Apr 2019 17:46:55 +0200 Subject: fbdev: atafb: Remove obsolete module support CONFIG_FB_ATARI is bool, hence the Atari frame buffer driver cannot be built as a module. In addition, the module support code refers to a function atafb_deinit(), which never existed. Replace module_init() by device_initcall(). Signed-off-by: Geert Uytterhoeven Cc: Michael Schmitz Cc: Paul Gortmaker Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/video/fbdev/atafb.c | 16 +--------------- drivers/video/fbdev/atafb_iplan2p2.c | 23 ----------------------- drivers/video/fbdev/atafb_iplan2p4.c | 23 ----------------------- drivers/video/fbdev/atafb_iplan2p8.c | 23 ----------------------- drivers/video/fbdev/atafb_mfb.c | 23 ----------------------- 5 files changed, 1 insertion(+), 107 deletions(-) (limited to 'drivers/video') diff --git a/drivers/video/fbdev/atafb.c b/drivers/video/fbdev/atafb.c index e9d31a4299ee..d82007c113e6 100644 --- a/drivers/video/fbdev/atafb.c +++ b/drivers/video/fbdev/atafb.c @@ -47,7 +47,6 @@ #define ATAFB_EXT #define ATAFB_FALCON -#include #include #include #include @@ -3078,14 +3077,11 @@ int __init atafb_init(void) int pad, detected_mode, error; unsigned int defmode = 0; unsigned long mem_req; - -#ifndef MODULE char *option = NULL; if (fb_get_options("atafb", &option)) return -ENODEV; atafb_setup(option); -#endif printk("atafb_init: start\n"); if (!MACH_IS_ATARI) @@ -3251,14 +3247,4 @@ int __init atafb_init(void) return 0; } -module_init(atafb_init); - -#ifdef MODULE -MODULE_LICENSE("GPL"); - -int cleanup_module(void) -{ - unregister_framebuffer(&fb_info); - return atafb_deinit(); -} -#endif /* MODULE */ +device_initcall(atafb_init); diff --git a/drivers/video/fbdev/atafb_iplan2p2.c b/drivers/video/fbdev/atafb_iplan2p2.c index 8cc9c50379d0..a1660c24bf36 100644 --- a/drivers/video/fbdev/atafb_iplan2p2.c +++ b/drivers/video/fbdev/atafb_iplan2p2.c @@ -10,7 +10,6 @@ * more details. */ -#include #include #include @@ -269,25 +268,3 @@ void atafb_iplan2p2_linefill(struct fb_info *info, u_long next_line, if (width) fill8_2col((u8 *)dest, fgcolor, bgcolor, *data); } - -#ifdef MODULE -MODULE_LICENSE("GPL"); - -int init_module(void) -{ - return 0; -} - -void cleanup_module(void) -{ -} -#endif /* MODULE */ - - - /* - * Visible symbols for modules - */ - -EXPORT_SYMBOL(atafb_iplan2p2_copyarea); -EXPORT_SYMBOL(atafb_iplan2p2_fillrect); -EXPORT_SYMBOL(atafb_iplan2p2_linefill); diff --git a/drivers/video/fbdev/atafb_iplan2p4.c b/drivers/video/fbdev/atafb_iplan2p4.c index bee0d89463f7..663d66582d79 100644 --- a/drivers/video/fbdev/atafb_iplan2p4.c +++ b/drivers/video/fbdev/atafb_iplan2p4.c @@ -10,7 +10,6 @@ * more details. */ -#include #include #include @@ -284,25 +283,3 @@ void atafb_iplan2p4_linefill(struct fb_info *info, u_long next_line, if (width) fill8_2col((u8 *)dest, fgcolor, bgcolor, *data); } - -#ifdef MODULE -MODULE_LICENSE("GPL"); - -int init_module(void) -{ - return 0; -} - -void cleanup_module(void) -{ -} -#endif /* MODULE */ - - - /* - * Visible symbols for modules - */ - -EXPORT_SYMBOL(atafb_iplan2p4_copyarea); -EXPORT_SYMBOL(atafb_iplan2p4_fillrect); -EXPORT_SYMBOL(atafb_iplan2p4_linefill); diff --git a/drivers/video/fbdev/atafb_iplan2p8.c b/drivers/video/fbdev/atafb_iplan2p8.c index 356fb52ce443..39a6cbbb6ca3 100644 --- a/drivers/video/fbdev/atafb_iplan2p8.c +++ b/drivers/video/fbdev/atafb_iplan2p8.c @@ -10,7 +10,6 @@ * more details. */ -#include #include #include @@ -321,25 +320,3 @@ void atafb_iplan2p8_linefill(struct fb_info *info, u_long next_line, if (width) fill8_2col((u8 *)dest, fgcolor, bgcolor, *data); } - -#ifdef MODULE -MODULE_LICENSE("GPL"); - -int init_module(void) -{ - return 0; -} - -void cleanup_module(void) -{ -} -#endif /* MODULE */ - - - /* - * Visible symbols for modules - */ - -EXPORT_SYMBOL(atafb_iplan2p8_copyarea); -EXPORT_SYMBOL(atafb_iplan2p8_fillrect); -EXPORT_SYMBOL(atafb_iplan2p8_linefill); diff --git a/drivers/video/fbdev/atafb_mfb.c b/drivers/video/fbdev/atafb_mfb.c index 6a352d62eecf..384fd3e4d3e1 100644 --- a/drivers/video/fbdev/atafb_mfb.c +++ b/drivers/video/fbdev/atafb_mfb.c @@ -9,7 +9,6 @@ * more details. */ -#include #include #include @@ -88,25 +87,3 @@ void atafb_mfb_linefill(struct fb_info *info, u_long next_line, *dest++ = *data++; } } - -#ifdef MODULE -MODULE_LICENSE("GPL"); - -int init_module(void) -{ - return 0; -} - -void cleanup_module(void) -{ -} -#endif /* MODULE */ - - - /* - * Visible symbols for modules - */ - -EXPORT_SYMBOL(atafb_mfb_copyarea); -EXPORT_SYMBOL(atafb_mfb_fillrect); -EXPORT_SYMBOL(atafb_mfb_linefill); -- cgit v1.2.3 From 80cf96357db7f0f41912c7ff30ae5f01ef515993 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 1 Apr 2019 17:46:55 +0200 Subject: fbdev: atafb: Fix broken frame buffer after kexec On Falcon, Atari frame buffer initialization relies on preprogrammed register values. These register values are changed to blank the console. Hence when using kexec to boot into a new kernel while the console is blanked, the new kernel cannot determine the current video configuration, and the Atari frame buffer driver fails to initialize: atafb: phys_screen_base 6ce000 screen_len 4096 Fix this by doing a straight-forward conversion of the driver to a platform device driver, and adding a shutdown handler that unblanks the display. Signed-off-by: Geert Uytterhoeven Cc: Michael Schmitz Cc: Paul Gortmaker Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/video/fbdev/atafb.c | 34 ++++++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) (limited to 'drivers/video') diff --git a/drivers/video/fbdev/atafb.c b/drivers/video/fbdev/atafb.c index d82007c113e6..4db8166d11b3 100644 --- a/drivers/video/fbdev/atafb.c +++ b/drivers/video/fbdev/atafb.c @@ -54,6 +54,7 @@ #include #include #include +#include #include #include @@ -3072,7 +3073,7 @@ int __init atafb_setup(char *options) return 0; } -int __init atafb_init(void) +static int __init atafb_probe(struct platform_device *pdev) { int pad, detected_mode, error; unsigned int defmode = 0; @@ -3084,9 +3085,6 @@ int __init atafb_init(void) atafb_setup(option); printk("atafb_init: start\n"); - if (!MACH_IS_ATARI) - return -ENODEV; - do { #ifdef ATAFB_EXT if (external_addr) { @@ -3247,4 +3245,32 @@ int __init atafb_init(void) return 0; } +static void atafb_shutdown(struct platform_device *pdev) +{ + /* Unblank before kexec */ + if (fbhw->blank) + fbhw->blank(0); +} + +static struct platform_driver atafb_driver = { + .shutdown = atafb_shutdown, + .driver = { + .name = "atafb", + }, +}; + +static int __init atafb_init(void) +{ + struct platform_device *pdev; + + if (!MACH_IS_ATARI) + return -ENODEV; + + pdev = platform_device_register_simple("atafb", -1, NULL, 0); + if (IS_ERR(pdev)) + return PTR_ERR(pdev); + + return platform_driver_probe(&atafb_driver, atafb_probe); +} + device_initcall(atafb_init); -- cgit v1.2.3 From cbb91d5d487dfd2f8fc0ddd4604563477c8efd2a Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 1 Apr 2019 17:46:55 +0200 Subject: fbdev: atafb: Modernize printing of kernel messages Now the driver has been converted to a platform driver, the legacy printk() calls without any log level can be replaced by proper dev_*() calls. Signed-off-by: Geert Uytterhoeven Cc: Michael Schmitz Cc: Paul Gortmaker Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/video/fbdev/atafb.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) (limited to 'drivers/video') diff --git a/drivers/video/fbdev/atafb.c b/drivers/video/fbdev/atafb.c index 4db8166d11b3..b986af2a8042 100644 --- a/drivers/video/fbdev/atafb.c +++ b/drivers/video/fbdev/atafb.c @@ -3083,12 +3083,12 @@ static int __init atafb_probe(struct platform_device *pdev) if (fb_get_options("atafb", &option)) return -ENODEV; atafb_setup(option); - printk("atafb_init: start\n"); + dev_dbg(&pdev->dev, "%s: start\n", __func__); do { #ifdef ATAFB_EXT if (external_addr) { - printk("atafb_init: initializing external hw\n"); + dev_dbg(&pdev->dev, "initializing external hw\n"); fbhw = &ext_switch; atafb_ops.fb_setcolreg = &ext_setcolreg; defmode = DEFMODE_EXT; @@ -3097,7 +3097,7 @@ static int __init atafb_probe(struct platform_device *pdev) #endif #ifdef ATAFB_TT if (ATARIHW_PRESENT(TT_SHIFTER)) { - printk("atafb_init: initializing TT hw\n"); + dev_dbg(&pdev->dev, "initializing TT hw\n"); fbhw = &tt_switch; atafb_ops.fb_setcolreg = &tt_setcolreg; defmode = DEFMODE_TT; @@ -3106,7 +3106,7 @@ static int __init atafb_probe(struct platform_device *pdev) #endif #ifdef ATAFB_FALCON if (ATARIHW_PRESENT(VIDEL_SHIFTER)) { - printk("atafb_init: initializing Falcon hw\n"); + dev_dbg(&pdev->dev, "initializing Falcon hw\n"); fbhw = &falcon_switch; atafb_ops.fb_setcolreg = &falcon_setcolreg; error = request_irq(IRQ_AUTO_4, falcon_vbl_switcher, 0, @@ -3121,7 +3121,7 @@ static int __init atafb_probe(struct platform_device *pdev) #ifdef ATAFB_STE if (ATARIHW_PRESENT(STND_SHIFTER) || ATARIHW_PRESENT(EXTD_SHIFTER)) { - printk("atafb_init: initializing ST/E hw\n"); + dev_dbg(&pdev->dev, "initializing ST/E hw\n"); fbhw = &st_switch; atafb_ops.fb_setcolreg = &stste_setcolreg; defmode = DEFMODE_STE; @@ -3129,7 +3129,8 @@ static int __init atafb_probe(struct platform_device *pdev) } fbhw = &st_switch; atafb_ops.fb_setcolreg = &stste_setcolreg; - printk("Cannot determine video hardware; defaulting to ST(e)\n"); + dev_warn(&pdev->dev, + "Cannot determine video hardware; defaulting to ST(e)\n"); #else /* ATAFB_STE */ /* no default driver included */ /* Nobody will ever see this message :-) */ @@ -3169,8 +3170,8 @@ static int __init atafb_probe(struct platform_device *pdev) kernel_set_cachemode(screen_base, screen_len, IOMAP_WRITETHROUGH); } - printk("atafb: phys_screen_base %lx screen_len %d\n", - phys_screen_base, screen_len); + dev_info(&pdev->dev, "phys_screen_base %lx screen_len %d\n", + phys_screen_base, screen_len); #ifdef ATAFB_EXT } else { /* Map the video memory (physical address given) to somewhere @@ -3217,12 +3218,12 @@ static int __init atafb_probe(struct platform_device *pdev) fb_alloc_cmap(&(fb_info.cmap), 1 << fb_info.var.bits_per_pixel, 0); - printk("Determined %dx%d, depth %d\n", - fb_info.var.xres, fb_info.var.yres, fb_info.var.bits_per_pixel); + dev_info(&pdev->dev, "Determined %dx%d, depth %d\n", fb_info.var.xres, + fb_info.var.yres, fb_info.var.bits_per_pixel); if ((fb_info.var.xres != fb_info.var.xres_virtual) || (fb_info.var.yres != fb_info.var.yres_virtual)) - printk(" virtual %dx%d\n", fb_info.var.xres_virtual, - fb_info.var.yres_virtual); + dev_info(&pdev->dev, " virtual %dx%d\n", + fb_info.var.xres_virtual, fb_info.var.yres_virtual); if (register_framebuffer(&fb_info) < 0) { #ifdef ATAFB_EXT -- cgit v1.2.3 From f82301661c6ca3414fb0f6c223f206be938b9495 Mon Sep 17 00:00:00 2001 From: Finn Thain Date: Mon, 1 Apr 2019 17:46:55 +0200 Subject: video/macfb: Call fb_invert_cmaps() The 'inverse' parameter has no effect otherwise. Remove set-but-unused variable. Signed-off-by: Finn Thain Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/video/fbdev/macfb.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers/video') diff --git a/drivers/video/fbdev/macfb.c b/drivers/video/fbdev/macfb.c index 00671055a611..37c56c45ee39 100644 --- a/drivers/video/fbdev/macfb.c +++ b/drivers/video/fbdev/macfb.c @@ -136,7 +136,6 @@ static struct fb_fix_screeninfo macfb_fix = { static void *slot_addr; static struct fb_info fb_info; static u32 pseudo_palette[16]; -static int inverse; static int vidtest; /* @@ -520,7 +519,7 @@ static void __init macfb_setup(char *options) continue; if (!strcmp(this_opt, "inverse")) - inverse = 1; + fb_invert_cmaps(); else if (!strcmp(this_opt, "vidtest")) vidtest = 1; /* enable experimental CLUT code */ -- cgit v1.2.3 From 36884ceb76661b09af62005c3b60b41670ae71aa Mon Sep 17 00:00:00 2001 From: Finn Thain Date: Mon, 1 Apr 2019 17:46:55 +0200 Subject: video/macfb: Always initialize DAFB colour table pointer register Don't skip the framebuffer CLUT pointer register initialization when the first dafb_setpalette() invocation has regno equal to zero. Suggested-by: Geert Uytterhoeven Signed-off-by: Finn Thain Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/video/fbdev/macfb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/video') diff --git a/drivers/video/fbdev/macfb.c b/drivers/video/fbdev/macfb.c index 37c56c45ee39..8820a556014c 100644 --- a/drivers/video/fbdev/macfb.c +++ b/drivers/video/fbdev/macfb.c @@ -148,7 +148,7 @@ static int dafb_setpalette(unsigned int regno, unsigned int red, unsigned int green, unsigned int blue, struct fb_info *info) { - static int lastreg = -1; + static int lastreg = -2; unsigned long flags; local_irq_save(flags); -- cgit v1.2.3 From 787a79230a0f9984e59549b9baa4daf274973a0d Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Mon, 1 Apr 2019 17:46:56 +0200 Subject: omapfb: add missing of_node_put after of_device_is_available Add an of_node_put when a tested device node is not available. The semantic patch that fixes this problem is as follows (http://coccinelle.lip6.fr): // @@ identifier f; local idexpression e; expression x; @@ e = f(...); ... when != of_node_put(e) when != x = e when != e = x when any if (<+...of_device_is_available(e)...+>) { ... when != of_node_put(e) ( return e; | + of_node_put(e); return ...; ) } // Fixes: f76ee892a99e6 ("omapfb: copy omapdss & displays for omapfb") Signed-off-by: Julia Lawall Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/video/fbdev/omap2/omapfb/dss/omapdss-boot-init.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/video') diff --git a/drivers/video/fbdev/omap2/omapfb/dss/omapdss-boot-init.c b/drivers/video/fbdev/omap2/omapfb/dss/omapdss-boot-init.c index 136d30484d02..cb6acbac9c47 100644 --- a/drivers/video/fbdev/omap2/omapfb/dss/omapdss-boot-init.c +++ b/drivers/video/fbdev/omap2/omapfb/dss/omapdss-boot-init.c @@ -193,8 +193,10 @@ static int __init omapdss_boot_init(void) dss = of_find_matching_node(NULL, omapdss_of_match); - if (dss == NULL || !of_device_is_available(dss)) + if (dss == NULL || !of_device_is_available(dss)) { + of_node_put(dss); return 0; + } omapdss_walk_device(dss, true); -- cgit v1.2.3 From 546f98c1e94157d5d58ac6f452bb409ebd1e37b2 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Mon, 1 Apr 2019 17:46:56 +0200 Subject: video: fbdev: atmel_lcdfb: drop AVR and platform_data support Make the driver OF only as since AVR32 has been removed from the kernel, there are only OF enabled platform using it. Signed-off-by: Alexandre Belloni Acked-by: Nicolas Ferre Reviewed-by: Sam Ravnborg Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/video/fbdev/Kconfig | 6 +- drivers/video/fbdev/atmel_lcdfb.c | 114 ++------------------------------------ 2 files changed, 7 insertions(+), 113 deletions(-) (limited to 'drivers/video') diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig index 0e7ab29c9c70..7bb50c3e7226 100644 --- a/drivers/video/fbdev/Kconfig +++ b/drivers/video/fbdev/Kconfig @@ -866,8 +866,8 @@ config FB_S1D13XXX config FB_ATMEL - tristate "AT91/AT32 LCD Controller support" - depends on FB && HAVE_FB_ATMEL + tristate "AT91 LCD Controller support" + depends on FB && OF && HAVE_FB_ATMEL select FB_BACKLIGHT select FB_CFB_FILLRECT select FB_CFB_COPYAREA @@ -875,7 +875,7 @@ config FB_ATMEL select FB_MODE_HELPERS select VIDEOMODE_HELPERS help - This enables support for the AT91/AT32 LCD Controller. + This enables support for the AT91 LCD Controller. config FB_NVIDIA tristate "nVidia Framebuffer Support" diff --git a/drivers/video/fbdev/atmel_lcdfb.c b/drivers/video/fbdev/atmel_lcdfb.c index 4ed55e6bbb84..b8786ff62b87 100644 --- a/drivers/video/fbdev/atmel_lcdfb.c +++ b/drivers/video/fbdev/atmel_lcdfb.c @@ -1,5 +1,5 @@ /* - * Driver for AT91/AT32 LCD Controller + * Driver for AT91 LCD Controller * * Copyright (C) 2007 Atmel Corporation * @@ -99,86 +99,6 @@ static struct atmel_lcdfb_config at91sam9rl_config = { .have_intensity_bit = true, }; -static struct atmel_lcdfb_config at32ap_config = { - .have_hozval = true, -}; - -static const struct platform_device_id atmel_lcdfb_devtypes[] = { - { - .name = "at91sam9261-lcdfb", - .driver_data = (unsigned long)&at91sam9261_config, - }, { - .name = "at91sam9263-lcdfb", - .driver_data = (unsigned long)&at91sam9263_config, - }, { - .name = "at91sam9g10-lcdfb", - .driver_data = (unsigned long)&at91sam9g10_config, - }, { - .name = "at91sam9g45-lcdfb", - .driver_data = (unsigned long)&at91sam9g45_config, - }, { - .name = "at91sam9g45es-lcdfb", - .driver_data = (unsigned long)&at91sam9g45es_config, - }, { - .name = "at91sam9rl-lcdfb", - .driver_data = (unsigned long)&at91sam9rl_config, - }, { - .name = "at32ap-lcdfb", - .driver_data = (unsigned long)&at32ap_config, - }, { - /* terminator */ - } -}; -MODULE_DEVICE_TABLE(platform, atmel_lcdfb_devtypes); - -static struct atmel_lcdfb_config * -atmel_lcdfb_get_config(struct platform_device *pdev) -{ - unsigned long data; - - data = platform_get_device_id(pdev)->driver_data; - - return (struct atmel_lcdfb_config *)data; -} - -#if defined(CONFIG_ARCH_AT91) -#define ATMEL_LCDFB_FBINFO_DEFAULT (FBINFO_DEFAULT \ - | FBINFO_PARTIAL_PAN_OK \ - | FBINFO_HWACCEL_YPAN) - -static inline void atmel_lcdfb_update_dma2d(struct atmel_lcdfb_info *sinfo, - struct fb_var_screeninfo *var, - struct fb_info *info) -{ - -} -#elif defined(CONFIG_AVR32) -#define ATMEL_LCDFB_FBINFO_DEFAULT (FBINFO_DEFAULT \ - | FBINFO_PARTIAL_PAN_OK \ - | FBINFO_HWACCEL_XPAN \ - | FBINFO_HWACCEL_YPAN) - -static void atmel_lcdfb_update_dma2d(struct atmel_lcdfb_info *sinfo, - struct fb_var_screeninfo *var, - struct fb_info *info) -{ - u32 dma2dcfg; - u32 pixeloff; - - pixeloff = (var->xoffset * info->var.bits_per_pixel) & 0x1f; - - dma2dcfg = (info->var.xres_virtual - info->var.xres) - * info->var.bits_per_pixel / 8; - dma2dcfg |= pixeloff << ATMEL_LCDC_PIXELOFF_OFFSET; - lcdc_writel(sinfo, ATMEL_LCDC_DMA2DCFG, dma2dcfg); - - /* Update configuration */ - lcdc_writel(sinfo, ATMEL_LCDC_DMACON, - lcdc_readl(sinfo, ATMEL_LCDC_DMACON) - | ATMEL_LCDC_DMAUPDT); -} -#endif - static u32 contrast_ctr = ATMEL_LCDC_PS_DIV8 | ATMEL_LCDC_POL_POSITIVE | ATMEL_LCDC_ENA_PWMENABLE; @@ -404,8 +324,6 @@ static void atmel_lcdfb_update_dma(struct fb_info *info, /* Set framebuffer DMA base address and pixel offset */ lcdc_writel(sinfo, ATMEL_LCDC_DMABADDR1, dma_addr); - - atmel_lcdfb_update_dma2d(sinfo, var, info); } static inline void atmel_lcdfb_free_video_memory(struct atmel_lcdfb_info *sinfo) @@ -978,7 +896,6 @@ static void atmel_lcdfb_stop_clock(struct atmel_lcdfb_info *sinfo) clk_disable_unprepare(sinfo->lcdc_clk); } -#ifdef CONFIG_OF static const struct of_device_id atmel_lcdfb_dt_ids[] = { { .compatible = "atmel,at91sam9261-lcdc" , .data = &at91sam9261_config, }, { .compatible = "atmel,at91sam9263-lcdc" , .data = &at91sam9263_config, }, @@ -986,7 +903,6 @@ static const struct of_device_id atmel_lcdfb_dt_ids[] = { { .compatible = "atmel,at91sam9g45-lcdc" , .data = &at91sam9g45_config, }, { .compatible = "atmel,at91sam9g45es-lcdc" , .data = &at91sam9g45es_config, }, { .compatible = "atmel,at91sam9rl-lcdc" , .data = &at91sam9rl_config, }, - { .compatible = "atmel,at32ap-lcdc" , .data = &at32ap_config, }, { /* sentinel */ } }; @@ -1122,19 +1038,12 @@ put_display_node: of_node_put(display_np); return ret; } -#else -static int atmel_lcdfb_of_init(struct atmel_lcdfb_info *sinfo) -{ - return 0; -} -#endif static int __init atmel_lcdfb_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct fb_info *info; struct atmel_lcdfb_info *sinfo; - struct atmel_lcdfb_pdata *pdata = NULL; struct resource *regs = NULL; struct resource *map = NULL; struct fb_modelist *modelist; @@ -1159,21 +1068,6 @@ static int __init atmel_lcdfb_probe(struct platform_device *pdev) ret = atmel_lcdfb_of_init(sinfo); if (ret) goto free_info; - } else if (dev_get_platdata(dev)) { - struct fb_monspecs *monspecs; - int i; - - pdata = dev_get_platdata(dev); - monspecs = pdata->default_monspecs; - sinfo->pdata = *pdata; - - for (i = 0; i < monspecs->modedb_len; i++) - fb_add_videomode(&monspecs->modedb[i], &info->modelist); - - sinfo->config = atmel_lcdfb_get_config(pdev); - - info->var.bits_per_pixel = pdata->default_bpp ? pdata->default_bpp : 16; - memcpy(&info->monspecs, pdata->default_monspecs, sizeof(info->monspecs)); } else { dev_err(dev, "cannot get default configuration\n"); goto free_info; @@ -1186,7 +1080,8 @@ static int __init atmel_lcdfb_probe(struct platform_device *pdev) if (IS_ERR(sinfo->reg_lcd)) sinfo->reg_lcd = NULL; - info->flags = ATMEL_LCDFB_FBINFO_DEFAULT; + info->flags = FBINFO_DEFAULT | FBINFO_PARTIAL_PAN_OK | + FBINFO_HWACCEL_YPAN; info->pseudo_palette = sinfo->pseudo_palette; info->fbops = &atmel_lcdfb_ops; @@ -1435,7 +1330,6 @@ static struct platform_driver atmel_lcdfb_driver = { .remove = __exit_p(atmel_lcdfb_remove), .suspend = atmel_lcdfb_suspend, .resume = atmel_lcdfb_resume, - .id_table = atmel_lcdfb_devtypes, .driver = { .name = "atmel_lcdfb", .of_match_table = of_match_ptr(atmel_lcdfb_dt_ids), @@ -1444,6 +1338,6 @@ static struct platform_driver atmel_lcdfb_driver = { module_platform_driver_probe(atmel_lcdfb_driver, atmel_lcdfb_probe); -MODULE_DESCRIPTION("AT91/AT32 LCD Controller framebuffer driver"); +MODULE_DESCRIPTION("AT91 LCD Controller framebuffer driver"); MODULE_AUTHOR("Nicolas Ferre "); MODULE_LICENSE("GPL"); -- cgit v1.2.3 From bd86b6c5c60711dbd4fa21bdb497a188ecb6cf63 Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Mon, 1 Apr 2019 17:46:56 +0200 Subject: udlfb: delete the unused parameter for dlfb_handle_damage Remove the unused parameter "data" and unused variable "ret". Signed-off-by: Mikulas Patocka Cc: Bernie Thompson Cc: Ladislav Michl Cc: Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/video/fbdev/udlfb.c | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) (limited to 'drivers/video') diff --git a/drivers/video/fbdev/udlfb.c b/drivers/video/fbdev/udlfb.c index 1d034dddc556..cf4e9928001c 100644 --- a/drivers/video/fbdev/udlfb.c +++ b/drivers/video/fbdev/udlfb.c @@ -594,10 +594,9 @@ static int dlfb_render_hline(struct dlfb_data *dlfb, struct urb **urb_ptr, return 0; } -static int dlfb_handle_damage(struct dlfb_data *dlfb, int x, int y, - int width, int height, char *data) +static int dlfb_handle_damage(struct dlfb_data *dlfb, int x, int y, int width, int height) { - int i, ret; + int i; char *cmd; cycles_t start_cycles, end_cycles; int bytes_sent = 0; @@ -641,7 +640,7 @@ static int dlfb_handle_damage(struct dlfb_data *dlfb, int x, int y, *cmd++ = 0xAF; /* Send partial buffer remaining before exiting */ len = cmd - (char *) urb->transfer_buffer; - ret = dlfb_submit_urb(dlfb, urb, len); + dlfb_submit_urb(dlfb, urb, len); bytes_sent += len; } else dlfb_urb_completion(urb); @@ -679,7 +678,7 @@ static ssize_t dlfb_ops_write(struct fb_info *info, const char __user *buf, (u32)info->var.yres); dlfb_handle_damage(dlfb, 0, start, info->var.xres, - lines, info->screen_base); + lines); } return result; @@ -695,7 +694,7 @@ static void dlfb_ops_copyarea(struct fb_info *info, sys_copyarea(info, area); dlfb_handle_damage(dlfb, area->dx, area->dy, - area->width, area->height, info->screen_base); + area->width, area->height); } static void dlfb_ops_imageblit(struct fb_info *info, @@ -706,7 +705,7 @@ static void dlfb_ops_imageblit(struct fb_info *info, sys_imageblit(info, image); dlfb_handle_damage(dlfb, image->dx, image->dy, - image->width, image->height, info->screen_base); + image->width, image->height); } static void dlfb_ops_fillrect(struct fb_info *info, @@ -717,7 +716,7 @@ static void dlfb_ops_fillrect(struct fb_info *info, sys_fillrect(info, rect); dlfb_handle_damage(dlfb, rect->dx, rect->dy, rect->width, - rect->height, info->screen_base); + rect->height); } /* @@ -859,8 +858,7 @@ static int dlfb_ops_ioctl(struct fb_info *info, unsigned int cmd, if (area.y > info->var.yres) area.y = info->var.yres; - dlfb_handle_damage(dlfb, area.x, area.y, area.w, area.h, - info->screen_base); + dlfb_handle_damage(dlfb, area.x, area.y, area.w, area.h); } return 0; @@ -1065,8 +1063,7 @@ static int dlfb_ops_set_par(struct fb_info *info) pix_framebuffer[i] = 0x37e6; } - dlfb_handle_damage(dlfb, 0, 0, info->var.xres, info->var.yres, - info->screen_base); + dlfb_handle_damage(dlfb, 0, 0, info->var.xres, info->var.yres); return 0; } -- cgit v1.2.3 From 6b11f9d8433b471fdd3ebed232b43a4b723be6ff Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Mon, 1 Apr 2019 17:46:56 +0200 Subject: udlfb: fix sleeping inside spinlock If a framebuffer device is used as a console, the rendering calls (copyarea, fillrect, imageblit) may be done with the console spinlock held. On udlfb, these function call dlfb_handle_damage that takes a blocking semaphore before acquiring an URB. In order to fix the bug, this patch changes the calls copyarea, fillrect and imageblit to offload USB work to a workqueue. A side effect of this patch is 3x improvement in console scrolling speed because the device doesn't have to be updated after each copyarea call. Signed-off-by: Mikulas Patocka Cc: Bernie Thompson Cc: Ladislav Michl Cc: Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/video/fbdev/udlfb.c | 56 ++++++++++++++++++++++++++++++++++++++++++--- include/video/udlfb.h | 6 +++++ 2 files changed, 59 insertions(+), 3 deletions(-) (limited to 'drivers/video') diff --git a/drivers/video/fbdev/udlfb.c b/drivers/video/fbdev/udlfb.c index cf4e9928001c..ce30fa710244 100644 --- a/drivers/video/fbdev/udlfb.c +++ b/drivers/video/fbdev/udlfb.c @@ -657,6 +657,50 @@ error: return 0; } +static void dlfb_init_damage(struct dlfb_data *dlfb) +{ + dlfb->damage_x = INT_MAX; + dlfb->damage_x2 = 0; + dlfb->damage_y = INT_MAX; + dlfb->damage_y2 = 0; +} + +static void dlfb_damage_work(struct work_struct *w) +{ + struct dlfb_data *dlfb = container_of(w, struct dlfb_data, damage_work); + int x, x2, y, y2; + + spin_lock_irq(&dlfb->damage_lock); + x = dlfb->damage_x; + x2 = dlfb->damage_x2; + y = dlfb->damage_y; + y2 = dlfb->damage_y2; + dlfb_init_damage(dlfb); + spin_unlock_irq(&dlfb->damage_lock); + + if (x < x2 && y < y2) + dlfb_handle_damage(dlfb, x, y, x2 - x, y2 - y); +} + +static void dlfb_offload_damage(struct dlfb_data *dlfb, int x, int y, int width, int height) +{ + unsigned long flags; + int x2 = x + width; + int y2 = y + height; + + if (x >= x2 || y >= y2) + return; + + spin_lock_irqsave(&dlfb->damage_lock, flags); + dlfb->damage_x = min(x, dlfb->damage_x); + dlfb->damage_x2 = max(x2, dlfb->damage_x2); + dlfb->damage_y = min(y, dlfb->damage_y); + dlfb->damage_y2 = max(y2, dlfb->damage_y2); + spin_unlock_irqrestore(&dlfb->damage_lock, flags); + + schedule_work(&dlfb->damage_work); +} + /* * Path triggered by usermode clients who write to filesystem * e.g. cat filename > /dev/fb1 @@ -693,7 +737,7 @@ static void dlfb_ops_copyarea(struct fb_info *info, sys_copyarea(info, area); - dlfb_handle_damage(dlfb, area->dx, area->dy, + dlfb_offload_damage(dlfb, area->dx, area->dy, area->width, area->height); } @@ -704,7 +748,7 @@ static void dlfb_ops_imageblit(struct fb_info *info, sys_imageblit(info, image); - dlfb_handle_damage(dlfb, image->dx, image->dy, + dlfb_offload_damage(dlfb, image->dx, image->dy, image->width, image->height); } @@ -715,7 +759,7 @@ static void dlfb_ops_fillrect(struct fb_info *info, sys_fillrect(info, rect); - dlfb_handle_damage(dlfb, rect->dx, rect->dy, rect->width, + dlfb_offload_damage(dlfb, rect->dx, rect->dy, rect->width, rect->height); } @@ -940,6 +984,8 @@ static void dlfb_ops_destroy(struct fb_info *info) { struct dlfb_data *dlfb = info->par; + cancel_work_sync(&dlfb->damage_work); + if (info->cmap.len != 0) fb_dealloc_cmap(&info->cmap); if (info->monspecs.modedb) @@ -1636,6 +1682,10 @@ static int dlfb_usb_probe(struct usb_interface *intf, dlfb->ops = dlfb_ops; info->fbops = &dlfb->ops; + dlfb_init_damage(dlfb); + spin_lock_init(&dlfb->damage_lock); + INIT_WORK(&dlfb->damage_work, dlfb_damage_work); + INIT_LIST_HEAD(&info->modelist); if (!dlfb_alloc_urb_list(dlfb, WRITES_IN_FLIGHT, MAX_TRANSFER)) { diff --git a/include/video/udlfb.h b/include/video/udlfb.h index 7d09e54ae54e..a3724f1fca1c 100644 --- a/include/video/udlfb.h +++ b/include/video/udlfb.h @@ -48,6 +48,12 @@ struct dlfb_data { int base8; u32 pseudo_palette[256]; int blank_mode; /*one of FB_BLANK_ */ + int damage_x; + int damage_y; + int damage_x2; + int damage_y2; + spinlock_t damage_lock; + struct work_struct damage_work; struct fb_ops ops; /* blit-only rendering path metrics, exposed through sysfs */ atomic_t bytes_rendered; /* raw pixel-bytes driver asked to render */ -- cgit v1.2.3 From babc250e278eac7b0e671bdaedf833759b43bb78 Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Mon, 1 Apr 2019 17:46:57 +0200 Subject: udlfb: introduce a rendering mutex Rendering calls may be done simultaneously from the workqueue, dlfb_ops_write, dlfb_ops_ioctl, dlfb_ops_set_par and dlfb_dpy_deferred_io. The code is robust enough so that it won't crash on concurrent rendering. However, concurrent rendering may cause display corruption if the same pixel is simultaneously being rendered. In order to avoid this corruption, this patch adds a mutex around the rendering calls. Signed-off-by: Mikulas Patocka Cc: Bernie Thompson Cc: Ladislav Michl Cc: [b.zolnierkie: replace "dlfb:" with "uldfb:" in the patch summary] Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/video/fbdev/udlfb.c | 41 ++++++++++++++++++++++++++++++----------- include/video/udlfb.h | 1 + 2 files changed, 31 insertions(+), 11 deletions(-) (limited to 'drivers/video') diff --git a/drivers/video/fbdev/udlfb.c b/drivers/video/fbdev/udlfb.c index ce30fa710244..5a0d6fb02bbc 100644 --- a/drivers/video/fbdev/udlfb.c +++ b/drivers/video/fbdev/udlfb.c @@ -596,7 +596,7 @@ static int dlfb_render_hline(struct dlfb_data *dlfb, struct urb **urb_ptr, static int dlfb_handle_damage(struct dlfb_data *dlfb, int x, int y, int width, int height) { - int i; + int i, ret; char *cmd; cycles_t start_cycles, end_cycles; int bytes_sent = 0; @@ -606,21 +606,29 @@ static int dlfb_handle_damage(struct dlfb_data *dlfb, int x, int y, int width, i start_cycles = get_cycles(); + mutex_lock(&dlfb->render_mutex); + aligned_x = DL_ALIGN_DOWN(x, sizeof(unsigned long)); width = DL_ALIGN_UP(width + (x-aligned_x), sizeof(unsigned long)); x = aligned_x; if ((width <= 0) || (x + width > dlfb->info->var.xres) || - (y + height > dlfb->info->var.yres)) - return -EINVAL; + (y + height > dlfb->info->var.yres)) { + ret = -EINVAL; + goto unlock_ret; + } - if (!atomic_read(&dlfb->usb_active)) - return 0; + if (!atomic_read(&dlfb->usb_active)) { + ret = 0; + goto unlock_ret; + } urb = dlfb_get_urb(dlfb); - if (!urb) - return 0; + if (!urb) { + ret = 0; + goto unlock_ret; + } cmd = urb->transfer_buffer; for (i = y; i < y + height ; i++) { @@ -654,7 +662,11 @@ error: >> 10)), /* Kcycles */ &dlfb->cpu_kcycles_used); - return 0; + ret = 0; + +unlock_ret: + mutex_unlock(&dlfb->render_mutex); + return ret; } static void dlfb_init_damage(struct dlfb_data *dlfb) @@ -782,17 +794,19 @@ static void dlfb_dpy_deferred_io(struct fb_info *info, int bytes_identical = 0; int bytes_rendered = 0; + mutex_lock(&dlfb->render_mutex); + if (!fb_defio) - return; + goto unlock_ret; if (!atomic_read(&dlfb->usb_active)) - return; + goto unlock_ret; start_cycles = get_cycles(); urb = dlfb_get_urb(dlfb); if (!urb) - return; + goto unlock_ret; cmd = urb->transfer_buffer; @@ -825,6 +839,8 @@ error: atomic_add(((unsigned int) ((end_cycles - start_cycles) >> 10)), /* Kcycles */ &dlfb->cpu_kcycles_used); +unlock_ret: + mutex_unlock(&dlfb->render_mutex); } static int dlfb_get_edid(struct dlfb_data *dlfb, char *edid, int len) @@ -986,6 +1002,8 @@ static void dlfb_ops_destroy(struct fb_info *info) cancel_work_sync(&dlfb->damage_work); + mutex_destroy(&dlfb->render_mutex); + if (info->cmap.len != 0) fb_dealloc_cmap(&info->cmap); if (info->monspecs.modedb) @@ -1682,6 +1700,7 @@ static int dlfb_usb_probe(struct usb_interface *intf, dlfb->ops = dlfb_ops; info->fbops = &dlfb->ops; + mutex_init(&dlfb->render_mutex); dlfb_init_damage(dlfb); spin_lock_init(&dlfb->damage_lock); INIT_WORK(&dlfb->damage_work, dlfb_damage_work); diff --git a/include/video/udlfb.h b/include/video/udlfb.h index a3724f1fca1c..58fb5732831a 100644 --- a/include/video/udlfb.h +++ b/include/video/udlfb.h @@ -48,6 +48,7 @@ struct dlfb_data { int base8; u32 pseudo_palette[256]; int blank_mode; /*one of FB_BLANK_ */ + struct mutex render_mutex; int damage_x; int damage_y; int damage_x2; -- cgit v1.2.3 From 17de805aa69e594785592f08ea08c85602432bb9 Mon Sep 17 00:00:00 2001 From: Gustavo A. R. Silva Date: Mon, 1 Apr 2019 17:46:57 +0200 Subject: xen, fbfront: mark expected switch fall-through In preparation to enabling -Wimplicit-fallthrough, mark switch cases where we are expecting to fall through. This patch fixes the following warning: drivers/video/fbdev/xen-fbfront.c: In function ‘xenfb_backend_changed’: drivers/video/fbdev/xen-fbfront.c:678:6: warning: this statement may fall through [-Wimplicit-fallthrough=] if (dev->state == XenbusStateClosed) ^ drivers/video/fbdev/xen-fbfront.c:681:2: note: here case XenbusStateClosing: ^~~~ Warning level 3 was used: -Wimplicit-fallthrough=3 Notice that, in this particular case, the code comment is modified in accordance with what GCC is expecting to find. This patch is part of the ongoing efforts to enable -Wimplicit-fallthrough. Signed-off-by: Gustavo A. R. Silva Cc: Kees Cook Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/video/fbdev/xen-fbfront.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/video') diff --git a/drivers/video/fbdev/xen-fbfront.c b/drivers/video/fbdev/xen-fbfront.c index 6a4bbc9e1fb0..a3d6b6db221b 100644 --- a/drivers/video/fbdev/xen-fbfront.c +++ b/drivers/video/fbdev/xen-fbfront.c @@ -677,7 +677,7 @@ static void xenfb_backend_changed(struct xenbus_device *dev, case XenbusStateClosed: if (dev->state == XenbusStateClosed) break; - /* Missed the backend's CLOSING state -- fallthrough */ + /* fall through - Missed the backend's CLOSING state. */ case XenbusStateClosing: xenbus_frontend_closed(dev); break; -- cgit v1.2.3 From 31fa6e2ae65feed0de10823c5d1eea21a93086c9 Mon Sep 17 00:00:00 2001 From: Aditya Pakki Date: Mon, 1 Apr 2019 17:46:57 +0200 Subject: omapfb: Fix potential NULL pointer dereference in kmalloc Memory allocated, using kmalloc, for new_compat may fail. This patch checks for such an error and prevents potential NULL pointer dereference. Signed-off-by: Aditya Pakki Cc: Kangjie Lu Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/video/fbdev/omap2/omapfb/dss/omapdss-boot-init.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/video') diff --git a/drivers/video/fbdev/omap2/omapfb/dss/omapdss-boot-init.c b/drivers/video/fbdev/omap2/omapfb/dss/omapdss-boot-init.c index cb6acbac9c47..5da7ed6d653e 100644 --- a/drivers/video/fbdev/omap2/omapfb/dss/omapdss-boot-init.c +++ b/drivers/video/fbdev/omap2/omapfb/dss/omapdss-boot-init.c @@ -111,6 +111,8 @@ static void __init omapdss_omapify_node(struct device_node *node) new_len = prop->length + strlen(prefix) * num_strs; new_compat = kmalloc(new_len, GFP_KERNEL); + if (!new_compat) + return; omapdss_prefix_strcpy(new_compat, new_len, prop->value, prop->length); -- cgit v1.2.3 From a4bd25259e9744948a408c5d2ee575a9f1888fb4 Mon Sep 17 00:00:00 2001 From: Enrico Weigelt, metux IT consult Date: Mon, 1 Apr 2019 17:46:57 +0200 Subject: drivers: video: fbdev: Kconfig: pedantic cleanups Formatting of Kconfig files doesn't look so pretty, so let the Great White Handkerchief come around and clean it up. Signed-off-by: Enrico Weigelt, metux IT consult [b.zolnierkie: add missing patch description] Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/video/fbdev/Kconfig | 288 +++++++++++----------- drivers/video/fbdev/mmp/Kconfig | 6 +- drivers/video/fbdev/omap/Kconfig | 20 +- drivers/video/fbdev/omap2/omapfb/Kconfig | 18 +- drivers/video/fbdev/omap2/omapfb/displays/Kconfig | 40 +-- drivers/video/fbdev/omap2/omapfb/dss/Kconfig | 6 +- 6 files changed, 188 insertions(+), 190 deletions(-) (limited to 'drivers/video') diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig index 7bb50c3e7226..8fae27903eb8 100644 --- a/drivers/video/fbdev/Kconfig +++ b/drivers/video/fbdev/Kconfig @@ -45,25 +45,25 @@ menuconfig FB device-aware may cause unexpected results. If unsure, say N. config FIRMWARE_EDID - bool "Enable firmware EDID" - depends on FB - ---help--- - This enables access to the EDID transferred from the firmware. - On the i386, this is from the Video BIOS. Enable this if DDC/I2C - transfers do not work for your driver and if you are using - nvidiafb, i810fb or savagefb. - - In general, choosing Y for this option is safe. If you - experience extremely long delays while booting before you get - something on your display, try setting this to N. Matrox cards in - combination with certain motherboards and monitors are known to - suffer from this problem. + bool "Enable firmware EDID" + depends on FB + ---help--- + This enables access to the EDID transferred from the firmware. + On the i386, this is from the Video BIOS. Enable this if DDC/I2C + transfers do not work for your driver and if you are using + nvidiafb, i810fb or savagefb. + + In general, choosing Y for this option is safe. If you + experience extremely long delays while booting before you get + something on your display, try setting this to N. Matrox cards in + combination with certain motherboards and monitors are known to + suffer from this problem. config FB_DDC - tristate - depends on FB - select I2C_ALGOBIT - select I2C + tristate + depends on FB + select I2C_ALGOBIT + select I2C config FB_BOOT_VESA_SUPPORT bool @@ -160,8 +160,8 @@ config FB_LITTLE_ENDIAN endchoice config FB_SYS_FOPS - tristate - depends on FB + tristate + depends on FB config FB_DEFERRED_IO bool @@ -180,8 +180,8 @@ config FB_SVGALIB cards. config FB_MACMODES - tristate - depends on FB + tristate + depends on FB config FB_BACKLIGHT tristate @@ -190,31 +190,31 @@ config FB_BACKLIGHT select BACKLIGHT_CLASS_DEVICE config FB_MODE_HELPERS - bool "Enable Video Mode Handling Helpers" - depends on FB + bool "Enable Video Mode Handling Helpers" + depends on FB ---help--- This enables functions for handling video modes using the Generalized Timing Formula and the EDID parser. A few drivers rely - on this feature such as the radeonfb, rivafb, and the i810fb. If + on this feature such as the radeonfb, rivafb, and the i810fb. If your driver does not take advantage of this feature, choosing Y will just increase the kernel size by about 5K. config FB_TILEBLITTING - bool "Enable Tile Blitting Support" - depends on FB - ---help--- - This enables tile blitting. Tile blitting is a drawing technique - where the screen is divided into rectangular sections (tiles), whereas - the standard blitting divides the screen into pixels. Because the - default drawing element is a tile, drawing functions will be passed - parameters in terms of number of tiles instead of number of pixels. - For example, to draw a single character, instead of using bitmaps, - an index to an array of bitmaps will be used. To clear or move a - rectangular section of a screen, the rectangle will be described in - terms of number of tiles in the x- and y-axis. - - This is particularly important to one driver, matroxfb. If - unsure, say N. + bool "Enable Tile Blitting Support" + depends on FB + ---help--- + This enables tile blitting. Tile blitting is a drawing technique + where the screen is divided into rectangular sections (tiles), whereas + the standard blitting divides the screen into pixels. Because the + default drawing element is a tile, drawing functions will be passed + parameters in terms of number of tiles instead of number of pixels. + For example, to draw a single character, instead of using bitmaps, + an index to an array of bitmaps will be used. To clear or move a + rectangular section of a screen, the rectangle will be described in + terms of number of tiles in the x- and y-axis. + + This is particularly important to one driver, matroxfb. If + unsure, say N. comment "Frame buffer hardware drivers" depends on FB @@ -226,7 +226,7 @@ config FB_GRVGA select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT ---help--- - This enables support for the SVGACTRL framebuffer in the GRLIB IP library from Aeroflex Gaisler. + This enables support for the SVGACTRL framebuffer in the GRLIB IP library from Aeroflex Gaisler. config FB_CIRRUS tristate "Cirrus Logic support" @@ -655,17 +655,17 @@ config FB_EFI using the EFI framebuffer as your console. config FB_N411 - tristate "N411 Apollo/Hecuba devkit support" - depends on FB && X86 && MMU - select FB_SYS_FILLRECT - select FB_SYS_COPYAREA - select FB_SYS_IMAGEBLIT - select FB_SYS_FOPS - select FB_DEFERRED_IO - select FB_HECUBA - help - This enables support for the Apollo display controller in its - Hecuba form using the n411 devkit. + tristate "N411 Apollo/Hecuba devkit support" + depends on FB && X86 && MMU + select FB_SYS_FILLRECT + select FB_SYS_COPYAREA + select FB_SYS_IMAGEBLIT + select FB_SYS_FOPS + select FB_DEFERRED_IO + select FB_HECUBA + help + This enables support for the Apollo display controller in its + Hecuba form using the n411 devkit. config FB_HGA tristate "Hercules mono graphics support" @@ -685,7 +685,7 @@ config FB_GBE select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT - help + help This is the frame buffer device driver for SGI Graphics Backend. This chip is used in SGI O2 and Visual Workstation 320/540. @@ -897,10 +897,10 @@ config FB_NVIDIA module will be called nvidiafb. config FB_NVIDIA_I2C - bool "Enable DDC Support" - depends on FB_NVIDIA - select FB_DDC - help + bool "Enable DDC Support" + depends on FB_NVIDIA + select FB_DDC + help This enables I2C support for nVidia Chipsets. This is used only for getting EDID information from the attached display allowing for robust video mode handling and switching. @@ -943,10 +943,10 @@ config FB_RIVA module will be called rivafb. config FB_RIVA_I2C - bool "Enable DDC Support" - depends on FB_RIVA - select FB_DDC - help + bool "Enable DDC Support" + depends on FB_RIVA + select FB_DDC + help This enables I2C support for nVidia Chipsets. This is used only for getting EDID information from the attached display allowing for robust video mode handling and switching. @@ -991,37 +991,37 @@ config FB_I810 select FB_CFB_IMAGEBLIT select VGASTATE help - This driver supports the on-board graphics built in to the Intel 810 - and 815 chipsets. Say Y if you have and plan to use such a board. + This driver supports the on-board graphics built in to the Intel 810 + and 815 chipsets. Say Y if you have and plan to use such a board. - To compile this driver as a module, choose M here: the + To compile this driver as a module, choose M here: the module will be called i810fb. - For more information, please read + For more information, please read config FB_I810_GTF bool "use VESA Generalized Timing Formula" depends on FB_I810 help - If you say Y, then the VESA standard, Generalized Timing Formula - or GTF, will be used to calculate the required video timing values - per video mode. Since the GTF allows nondiscrete timings - (nondiscrete being a range of values as opposed to discrete being a - set of values), you'll be able to use any combination of horizontal + If you say Y, then the VESA standard, Generalized Timing Formula + or GTF, will be used to calculate the required video timing values + per video mode. Since the GTF allows nondiscrete timings + (nondiscrete being a range of values as opposed to discrete being a + set of values), you'll be able to use any combination of horizontal and vertical resolutions, and vertical refresh rates without having to specify your own timing parameters. This is especially useful - to maximize the performance of an aging display, or if you just - have a display with nonstandard dimensions. A VESA compliant + to maximize the performance of an aging display, or if you just + have a display with nonstandard dimensions. A VESA compliant monitor is recommended, but can still work with non-compliant ones. - If you need or want this, then select this option. The timings may - not be compliant with Intel's recommended values. Use at your own + If you need or want this, then select this option. The timings may + not be compliant with Intel's recommended values. Use at your own risk. - If you say N, the driver will revert to discrete video timings + If you say N, the driver will revert to discrete video timings using a set recommended by Intel in their documentation. - - If unsure, say N. + + If unsure, say N. config FB_I810_I2C bool "Enable DDC Support" @@ -1060,8 +1060,8 @@ config FB_INTEL depends on !DRM_I915 help This driver supports the on-board graphics built in to the Intel - 830M/845G/852GM/855GM/865G/915G/915GM/945G/945GM/965G/965GM chipsets. - Say Y if you have and plan to use such a board. + 830M/845G/852GM/855GM/865G/915G/915GM/945G/945GM/965G/965GM chipsets. + Say Y if you have and plan to use such a board. To make FB_INTEL=Y work you need to say AGP_INTEL=y too. @@ -1142,10 +1142,10 @@ config FB_MATROX_G G450/G550 secondary head and digital output are supported without additional modules. - The driver starts in monitor mode. You must use the matroxset tool - (available at ) to - swap primary and secondary head outputs, or to change output mode. - Secondary head driver always start in 640x480 resolution and you + The driver starts in monitor mode. You must use the matroxset tool + (available at ) to + swap primary and secondary head outputs, or to change output mode. + Secondary head driver always start in 640x480 resolution and you must use fbset to change it. Do not forget that second head supports only 16 and 32 bpp @@ -1228,7 +1228,7 @@ config FB_RADEON_I2C select FB_DDC default y help - Say Y here if you want DDC/I2C support for your Radeon board. + Say Y here if you want DDC/I2C support for your Radeon board. config FB_RADEON_BACKLIGHT bool "Support for backlight control" @@ -1357,10 +1357,10 @@ config FB_SAVAGE will be called savagefb. config FB_SAVAGE_I2C - bool "Enable DDC2 Support" - depends on FB_SAVAGE - select FB_DDC - help + bool "Enable DDC2 Support" + depends on FB_SAVAGE + select FB_DDC + help This enables I2C support for S3 Savage Chipsets. This is used only for getting EDID information from the attached display allowing for robust video mode handling and switching. @@ -1370,12 +1370,12 @@ config FB_SAVAGE_I2C here. config FB_SAVAGE_ACCEL - bool "Enable Console Acceleration" - depends on FB_SAVAGE - help - This option will compile in console acceleration support. If - the resulting framebuffer console has bothersome glitches, then - choose N here. + bool "Enable Console Acceleration" + depends on FB_SAVAGE + help + This option will compile in console acceleration support. If + the resulting framebuffer console has bothersome glitches, then + choose N here. config FB_SIS tristate "SiS/XGI display support" @@ -1408,17 +1408,17 @@ config FB_SIS_315 as XGI V3XT, V5, V8 and Z7. config FB_VIA - tristate "VIA UniChrome (Pro) and Chrome9 display support" - depends on FB && PCI && GPIOLIB && I2C && (X86 || COMPILE_TEST) - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - select I2C_ALGOBIT - help + tristate "VIA UniChrome (Pro) and Chrome9 display support" + depends on FB && PCI && GPIOLIB && I2C && (X86 || COMPILE_TEST) + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + select I2C_ALGOBIT + help This is the frame buffer device driver for Graphics chips of VIA UniChrome (Pro) Family (CLE266,PM800/CN400,P4M800CE/P4M800Pro/ CN700/VN800,CX700/VX700,P4M890) and Chrome9 Family (K8M890,CN896 - /P4M900,VX800) + /P4M900,VX800) Say Y if you have a VIA UniChrome graphics board. To compile this driver as a module, choose M here: the @@ -1455,7 +1455,7 @@ config FB_NEOMAGIC select VGASTATE help This driver supports notebooks with NeoMagic PCI chips. - Say Y if you have such a graphics card. + Say Y if you have such a graphics card. To compile this driver as a module, choose M here: the module will be called neofb. @@ -1510,7 +1510,7 @@ config FB_VOODOO1 select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT ---help--- - Say Y here if you have a 3Dfx Voodoo Graphics (Voodoo1/sst1) or + Say Y here if you have a 3Dfx Voodoo Graphics (Voodoo1/sst1) or Voodoo2 (cvg) based graphics card. To compile this driver as a module, choose M here: the @@ -1679,9 +1679,9 @@ config FB_HIT config FB_PMAG_AA tristate "PMAG-AA TURBOchannel framebuffer support" depends on FB && TC - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT help Support for the PMAG-AA TURBOchannel framebuffer card (1280x1024x1) used mainly in the MIPS-based DECstation series. @@ -1689,9 +1689,9 @@ config FB_PMAG_AA config FB_PMAG_BA tristate "PMAG-BA TURBOchannel framebuffer support" depends on FB && TC - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT help Support for the PMAG-BA TURBOchannel framebuffer card (1024x864x8) used mainly in the MIPS-based DECstation series. @@ -1699,9 +1699,9 @@ config FB_PMAG_BA config FB_PMAGB_B tristate "PMAGB-B TURBOchannel framebuffer support" depends on FB && TC - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT help Support for the PMAGB-B TURBOchannel framebuffer card used mainly in the MIPS-based DECstation series. The card is currently only @@ -1710,9 +1710,9 @@ config FB_PMAGB_B config FB_MAXINE bool "Maxine (Personal DECstation) onboard framebuffer support" depends on (FB = y) && MACH_DECSTATION - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT help Support for the onboard framebuffer (1024x768x8) in the Personal DECstation series (Personal DECstation 5000/20, /25, /33, /50, @@ -1721,9 +1721,9 @@ config FB_MAXINE config FB_G364 bool "G364 frame buffer support" depends on (FB = y) && (MIPS_MAGNUM_4000 || OLIVETTI_M700) - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT help The G364 driver is the framebuffer used in MIPS Magnum 4000 and Olivetti M700-10 systems. @@ -1731,9 +1731,9 @@ config FB_G364 config FB_68328 bool "Motorola 68328 native frame buffer support" depends on (FB = y) && (M68328 || M68EZ328 || M68VZ328) - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT help Say Y here if you want to support the built-in frame buffer of the Motorola 68328 CPU family. @@ -1812,13 +1812,13 @@ config FB_MBX Accelerator config FB_MBX_DEBUG - bool "Enable debugging info via debugfs" - depends on FB_MBX && DEBUG_FS - ---help--- - Enable this if you want debugging information using the debug - filesystem (debugfs) + bool "Enable debugging info via debugfs" + depends on FB_MBX && DEBUG_FS + ---help--- + Enable this if you want debugging information using the debug + filesystem (debugfs) - If unsure, say N. + If unsure, say N. config FB_FSL_DIU tristate "Freescale DIU framebuffer support" @@ -1834,9 +1834,9 @@ config FB_FSL_DIU config FB_W100 tristate "W100 frame buffer support" depends on FB && ARCH_PXA - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT ---help--- Frame buffer driver for the w100 as found on the Sharp SL-Cxx series. It can also drive the w3220 chip found on iPAQ hx4700. @@ -1901,10 +1901,10 @@ config FB_S3C Currently the support is only for the S3C6400 and S3C6410 SoCs. config FB_S3C_DEBUG_REGWRITE - bool "Debug register writes" - depends on FB_S3C - ---help--- - Show all register writes via pr_debug() + bool "Debug register writes" + depends on FB_S3C + ---help--- + Show all register writes via pr_debug() config FB_S3C2410 tristate "S3C2410 LCD framebuffer support" @@ -1930,18 +1930,18 @@ config FB_S3C2410_DEBUG through sysfs config FB_NUC900 - tristate "NUC900 LCD framebuffer support" - depends on FB && ARCH_W90X900 - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - ---help--- - Frame buffer driver for the built-in LCD controller in the Nuvoton - NUC900 processor + tristate "NUC900 LCD framebuffer support" + depends on FB && ARCH_W90X900 + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + ---help--- + Frame buffer driver for the built-in LCD controller in the Nuvoton + NUC900 processor config GPM1040A0_320X240 - bool "Giantplus Technology GPM1040A0 320x240 Color TFT LCD" - depends on FB_NUC900 + bool "Giantplus Technology GPM1040A0 320x240 Color TFT LCD" + depends on FB_NUC900 config FB_SM501 tristate "Silicon Motion SM501 framebuffer support" diff --git a/drivers/video/fbdev/mmp/Kconfig b/drivers/video/fbdev/mmp/Kconfig index f56a7e2e8136..1b5e80c8a984 100644 --- a/drivers/video/fbdev/mmp/Kconfig +++ b/drivers/video/fbdev/mmp/Kconfig @@ -1,7 +1,7 @@ menuconfig MMP_DISP - tristate "Marvell MMP Display Subsystem support" - depends on CPU_PXA910 || CPU_MMP2 - help + tristate "Marvell MMP Display Subsystem support" + depends on CPU_PXA910 || CPU_MMP2 + help Marvell Display Subsystem support. if MMP_DISP diff --git a/drivers/video/fbdev/omap/Kconfig b/drivers/video/fbdev/omap/Kconfig index 29d250da8a3e..ca147936bb5c 100644 --- a/drivers/video/fbdev/omap/Kconfig +++ b/drivers/video/fbdev/omap/Kconfig @@ -6,7 +6,7 @@ config FB_OMAP select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT help - Frame buffer driver for OMAP based boards. + Frame buffer driver for OMAP based boards. config FB_OMAP_LCDC_EXTERNAL bool "External LCD controller support" @@ -49,13 +49,11 @@ config FB_OMAP_LCD_H3 H3 board. config FB_OMAP_DMA_TUNE - bool "Set DMA SDRAM access priority high" - depends on FB_OMAP - help - On systems in which video memory is in system memory - (SDRAM) this will speed up graphics DMA operations. - If you have such a system and want to use rotation - answer yes. Answer no if you have a dedicated video - memory, or don't use any of the accelerated features. - - + bool "Set DMA SDRAM access priority high" + depends on FB_OMAP + help + On systems in which video memory is in system memory + (SDRAM) this will speed up graphics DMA operations. + If you have such a system and want to use rotation + answer yes. Answer no if you have a dedicated video + memory, or don't use any of the accelerated features. diff --git a/drivers/video/fbdev/omap2/omapfb/Kconfig b/drivers/video/fbdev/omap2/omapfb/Kconfig index 3bf154e676d1..0410e07bb29e 100644 --- a/drivers/video/fbdev/omap2/omapfb/Kconfig +++ b/drivers/video/fbdev/omap2/omapfb/Kconfig @@ -2,23 +2,23 @@ config OMAP2_VRFB bool menuconfig FB_OMAP2 - tristate "OMAP2+ frame buffer support" - depends on FB - depends on DRM_OMAP = n + tristate "OMAP2+ frame buffer support" + depends on FB + depends on DRM_OMAP = n depends on GPIOLIB - select FB_OMAP2_DSS + select FB_OMAP2_DSS select OMAP2_VRFB if ARCH_OMAP2 || ARCH_OMAP3 - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - help + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help Frame buffer driver for OMAP2+ based boards. if FB_OMAP2 config FB_OMAP2_DEBUG_SUPPORT - bool "Debug support for OMAP2+ FB" + bool "Debug support for OMAP2+ FB" default y depends on FB_OMAP2 help diff --git a/drivers/video/fbdev/omap2/omapfb/displays/Kconfig b/drivers/video/fbdev/omap2/omapfb/displays/Kconfig index 08f12039dd02..3df8736cf8d8 100644 --- a/drivers/video/fbdev/omap2/omapfb/displays/Kconfig +++ b/drivers/video/fbdev/omap2/omapfb/displays/Kconfig @@ -1,5 +1,5 @@ menu "OMAPFB Panel and Encoder Drivers" - depends on FB_OMAP2_DSS + depends on FB_OMAP2_DSS config FB_OMAP2_ENCODER_OPA362 tristate "OPA362 external analog amplifier" @@ -8,29 +8,29 @@ config FB_OMAP2_ENCODER_OPA362 through a GPIO. config FB_OMAP2_ENCODER_TFP410 - tristate "TFP410 DPI to DVI Encoder" + tristate "TFP410 DPI to DVI Encoder" help Driver for TFP410 DPI to DVI encoder. config FB_OMAP2_ENCODER_TPD12S015 - tristate "TPD12S015 HDMI ESD protection and level shifter" + tristate "TPD12S015 HDMI ESD protection and level shifter" help Driver for TPD12S015, which offers HDMI ESD protection and level shifting. config FB_OMAP2_CONNECTOR_DVI - tristate "DVI Connector" + tristate "DVI Connector" depends on I2C help Driver for a generic DVI connector. config FB_OMAP2_CONNECTOR_HDMI - tristate "HDMI Connector" + tristate "HDMI Connector" help Driver for a generic HDMI connector. config FB_OMAP2_CONNECTOR_ANALOG_TV - tristate "Analog TV Connector" + tristate "Analog TV Connector" help Driver for a generic analog TV connector. @@ -58,29 +58,29 @@ config FB_OMAP2_PANEL_LGPHILIPS_LB035Q02 LCD Panel used on the Gumstix Overo Palo35 config FB_OMAP2_PANEL_SHARP_LS037V7DW01 - tristate "Sharp LS037V7DW01 LCD Panel" - depends on BACKLIGHT_CLASS_DEVICE - help - LCD Panel used in TI's SDP3430 and EVM boards + tristate "Sharp LS037V7DW01 LCD Panel" + depends on BACKLIGHT_CLASS_DEVICE + help + LCD Panel used in TI's SDP3430 and EVM boards config FB_OMAP2_PANEL_TPO_TD028TTEC1 - tristate "TPO TD028TTEC1 LCD Panel" - depends on SPI - help - LCD panel used in Openmoko. + tristate "TPO TD028TTEC1 LCD Panel" + depends on SPI + help + LCD panel used in Openmoko. config FB_OMAP2_PANEL_TPO_TD043MTEA1 - tristate "TPO TD043MTEA1 LCD Panel" - depends on SPI - help - LCD Panel used in OMAP3 Pandora + tristate "TPO TD043MTEA1 LCD Panel" + depends on SPI + help + LCD Panel used in OMAP3 Pandora config FB_OMAP2_PANEL_NEC_NL8048HL11 tristate "NEC NL8048HL11 Panel" depends on SPI depends on BACKLIGHT_CLASS_DEVICE help - This NEC NL8048HL11 panel is TFT LCD used in the - Zoom2/3/3630 sdp boards. + This NEC NL8048HL11 panel is TFT LCD used in the + Zoom2/3/3630 sdp boards. endmenu diff --git a/drivers/video/fbdev/omap2/omapfb/dss/Kconfig b/drivers/video/fbdev/omap2/omapfb/dss/Kconfig index 356b89b378d4..a34820e8ab97 100644 --- a/drivers/video/fbdev/omap2/omapfb/dss/Kconfig +++ b/drivers/video/fbdev/omap2/omapfb/dss/Kconfig @@ -3,7 +3,7 @@ config FB_OMAP2_DSS_INIT bool config FB_OMAP2_DSS - tristate + tristate select VIDEOMODE_HELPERS select FB_OMAP2_DSS_INIT select HDMI @@ -53,7 +53,7 @@ config FB_OMAP2_DSS_RFBI config FB_OMAP2_DSS_VENC bool "VENC support" - default y + default y help OMAP Video Encoder support for S-Video and composite TV-out. @@ -62,7 +62,7 @@ config FB_OMAP2_DSS_HDMI_COMMON config FB_OMAP4_DSS_HDMI bool "HDMI support for OMAP4" - default y + default y select FB_OMAP2_DSS_HDMI_COMMON help HDMI support for OMAP4 based SoCs. -- cgit v1.2.3 From b0e999c9558194a7b8908c41eaa7903e27fdb8c8 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Mon, 1 Apr 2019 17:46:57 +0200 Subject: fbdev: list all pci memory bars as conflicting apertures Simply add all pci memory bars to struct apertures_struct in remove_conflicting_pci_framebuffers(), without depending on the res_id parameter. The plan is to drop the res_id parameter later on. For now keep the parameter, use it for sanity-checking and warn on inconsistencies. Signed-off-by: Gerd Hoffmann Reviewed-by: Daniel Vetter Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/video/fbdev/core/fbmem.c | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) (limited to 'drivers/video') diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c index 4721491e6c8c..d1949c92be98 100644 --- a/drivers/video/fbdev/core/fbmem.c +++ b/drivers/video/fbdev/core/fbmem.c @@ -1882,14 +1882,35 @@ int remove_conflicting_pci_framebuffers(struct pci_dev *pdev, int res_id, const { struct apertures_struct *ap; bool primary = false; - int err; + int err, idx, bar; + bool res_id_found = false; + + for (idx = 0, bar = 0; bar < PCI_ROM_RESOURCE; bar++) { + if (!(pci_resource_flags(pdev, bar) & IORESOURCE_MEM)) + continue; + idx++; + } - ap = alloc_apertures(1); + ap = alloc_apertures(idx); if (!ap) return -ENOMEM; - ap->ranges[0].base = pci_resource_start(pdev, res_id); - ap->ranges[0].size = pci_resource_len(pdev, res_id); + for (idx = 0, bar = 0; bar < PCI_ROM_RESOURCE; bar++) { + if (!(pci_resource_flags(pdev, bar) & IORESOURCE_MEM)) + continue; + ap->ranges[idx].base = pci_resource_start(pdev, bar); + ap->ranges[idx].size = pci_resource_len(pdev, bar); + pci_info(pdev, "%s: bar %d: 0x%lx -> 0x%lx\n", __func__, bar, + (unsigned long)pci_resource_start(pdev, bar), + (unsigned long)pci_resource_end(pdev, bar)); + idx++; + if (res_id == bar) + res_id_found = true; + } + if (!res_id_found) + pci_warn(pdev, "%s: passed res_id (%d) is not a memory bar\n", + __func__, res_id); + #ifdef CONFIG_X86 primary = pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW; -- cgit v1.2.3 From ec7f6aad57ad29e4e66cc2e18e1e1599ddb02542 Mon Sep 17 00:00:00 2001 From: Kangjie Lu Date: Mon, 1 Apr 2019 17:46:58 +0200 Subject: video: hgafb: fix potential NULL pointer dereference When ioremap fails, hga_vram should not be dereferenced. The fix check the failure to avoid NULL pointer dereference. Signed-off-by: Kangjie Lu Cc: Aditya Pakki Cc: Ferenc Bakonyi [b.zolnierkie: minor patch summary fixup] Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/video/fbdev/hgafb.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/video') diff --git a/drivers/video/fbdev/hgafb.c b/drivers/video/fbdev/hgafb.c index 463028543173..59e1cae57948 100644 --- a/drivers/video/fbdev/hgafb.c +++ b/drivers/video/fbdev/hgafb.c @@ -285,6 +285,8 @@ static int hga_card_detect(void) hga_vram_len = 0x08000; hga_vram = ioremap(0xb0000, hga_vram_len); + if (!hga_vram) + goto error; if (request_region(0x3b0, 12, "hgafb")) release_io_ports = 1; -- cgit v1.2.3 From 1d84353d205a953e2381044953b7fa31c8c9702d Mon Sep 17 00:00:00 2001 From: Kangjie Lu Date: Mon, 1 Apr 2019 17:46:58 +0200 Subject: video: imsttfb: fix potential NULL pointer dereferences In case ioremap fails, the fix releases resources and returns -ENOMEM to avoid NULL pointer dereferences. Signed-off-by: Kangjie Lu Cc: Aditya Pakki Cc: Finn Thain Cc: Rob Herring Cc: Greg Kroah-Hartman [b.zolnierkie: minor patch summary fixup] Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/video/fbdev/imsttfb.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers/video') diff --git a/drivers/video/fbdev/imsttfb.c b/drivers/video/fbdev/imsttfb.c index 4b9615e4ce74..35bba3c2036d 100644 --- a/drivers/video/fbdev/imsttfb.c +++ b/drivers/video/fbdev/imsttfb.c @@ -1515,6 +1515,11 @@ static int imsttfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) info->fix.smem_start = addr; info->screen_base = (__u8 *)ioremap(addr, par->ramdac == IBM ? 0x400000 : 0x800000); + if (!info->screen_base) { + release_mem_region(addr, size); + framebuffer_release(info); + return -ENOMEM; + } info->fix.mmio_start = addr + 0x800000; par->dc_regs = ioremap(addr + 0x800000, 0x1000); par->cmap_regs_phys = addr + 0x840000; -- cgit v1.2.3 From 8069053880e0ee3a75fd6d7e0a30293265fe3de4 Mon Sep 17 00:00:00 2001 From: Yifeng Li Date: Mon, 1 Apr 2019 17:46:58 +0200 Subject: fbdev: sm712fb: fix white screen of death on reboot, don't set CR3B-CR3F On a Thinkpad s30 (Pentium III / i440MX, Lynx3DM), rebooting with sm712fb framebuffer driver would cause a white screen of death on the next POST, presumably the proper timings for the LCD panel was not reprogrammed properly by the BIOS. Experiments showed a few CRTC Scratch Registers, including CRT3D, CRT3E and CRT3F may be used internally by BIOS as some flags. CRT3B is a hardware testing register, we shouldn't mess with it. CRT3C has blanking signal and line compare control, which is not needed for this driver. Stop writing to CR3B-CR3F (a.k.a CRT3B-CRT3F) registers. Even if these registers don't have side-effect on other systems, writing to them is also highly questionable. Signed-off-by: Yifeng Li Tested-by: Sudip Mukherjee Cc: Teddy Wang Cc: # v4.4+ Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/video/fbdev/sm712fb.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers/video') diff --git a/drivers/video/fbdev/sm712fb.c b/drivers/video/fbdev/sm712fb.c index 502d0de2feec..d05379affa32 100644 --- a/drivers/video/fbdev/sm712fb.c +++ b/drivers/video/fbdev/sm712fb.c @@ -1171,8 +1171,12 @@ static void sm7xx_set_timing(struct smtcfb_info *sfb) smtc_crtcw(i, vgamode[j].init_cr00_cr18[i]); /* init CRTC register CR30 - CR4D */ - for (i = 0; i < SIZE_CR30_CR4D; i++) + for (i = 0; i < SIZE_CR30_CR4D; i++) { + if ((i + 0x30) >= 0x3B && (i + 0x30) <= 0x3F) + /* side-effect, don't write to CR3B-CR3F */ + continue; smtc_crtcw(i + 0x30, vgamode[j].init_cr30_cr4d[i]); + } /* init CRTC register CR90 - CRA7 */ for (i = 0; i < SIZE_CR90_CRA7; i++) -- cgit v1.2.3 From 5481115e25e42b9215f2619452aa99c95f08492f Mon Sep 17 00:00:00 2001 From: Yifeng Li Date: Mon, 1 Apr 2019 17:46:58 +0200 Subject: fbdev: sm712fb: fix brightness control on reboot, don't set SR30 On a Thinkpad s30 (Pentium III / i440MX, Lynx3DM), rebooting with sm712fb framebuffer driver would cause the role of brightness up/down button to swap. Experiments showed the FPR30 register caused this behavior. Moreover, even if this register don't have side-effect on other systems, over- writing it is also highly questionable, since it was originally configurated by the motherboard manufacturer by hardwiring pull-down resistors to indicate the type of LCD panel. We should not mess with it. Stop writing to the SR30 (a.k.a FPR30) register. Signed-off-by: Yifeng Li Tested-by: Sudip Mukherjee Cc: Teddy Wang Cc: # v4.4+ Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/video/fbdev/sm712fb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/video') diff --git a/drivers/video/fbdev/sm712fb.c b/drivers/video/fbdev/sm712fb.c index d05379affa32..a19655babf67 100644 --- a/drivers/video/fbdev/sm712fb.c +++ b/drivers/video/fbdev/sm712fb.c @@ -1145,8 +1145,8 @@ static void sm7xx_set_timing(struct smtcfb_info *sfb) /* init SEQ register SR30 - SR75 */ for (i = 0; i < SIZE_SR30_SR75; i++) - if ((i + 0x30) != 0x62 && (i + 0x30) != 0x6a && - (i + 0x30) != 0x6b) + if ((i + 0x30) != 0x30 && (i + 0x30) != 0x62 && + (i + 0x30) != 0x6a && (i + 0x30) != 0x6b) smtc_seqw(i + 0x30, vgamode[j].init_sr30_sr75[i]); -- cgit v1.2.3 From dcf9070595e100942c539e229dde4770aaeaa4e9 Mon Sep 17 00:00:00 2001 From: Yifeng Li Date: Mon, 1 Apr 2019 17:46:58 +0200 Subject: fbdev: sm712fb: fix VRAM detection, don't set SR70/71/74/75 On a Thinkpad s30 (Pentium III / i440MX, Lynx3DM), the amount of Video RAM is not detected correctly by the xf86-video-siliconmotion driver. This is because sm712fb overwrites the GPR71 Scratch Pad Register, which is set by BIOS on x86 and used to indicate amount of VRAM. Other Scratch Pad Registers, including GPR70/74/75, don't have the same side-effect, but overwriting to them is still questionable, as they are not related to modesetting. Stop writing to SR70/71/74/75 (a.k.a GPR70/71/74/75). Signed-off-by: Yifeng Li Tested-by: Sudip Mukherjee Cc: Teddy Wang Cc: # v4.4+ Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/video/fbdev/sm712fb.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/video') diff --git a/drivers/video/fbdev/sm712fb.c b/drivers/video/fbdev/sm712fb.c index a19655babf67..1a3d232c2916 100644 --- a/drivers/video/fbdev/sm712fb.c +++ b/drivers/video/fbdev/sm712fb.c @@ -1146,7 +1146,9 @@ static void sm7xx_set_timing(struct smtcfb_info *sfb) /* init SEQ register SR30 - SR75 */ for (i = 0; i < SIZE_SR30_SR75; i++) if ((i + 0x30) != 0x30 && (i + 0x30) != 0x62 && - (i + 0x30) != 0x6a && (i + 0x30) != 0x6b) + (i + 0x30) != 0x6a && (i + 0x30) != 0x6b && + (i + 0x30) != 0x70 && (i + 0x30) != 0x71 && + (i + 0x30) != 0x74 && (i + 0x30) != 0x75) smtc_seqw(i + 0x30, vgamode[j].init_sr30_sr75[i]); -- cgit v1.2.3 From ec1587d5073f29820e358f3a383850d61601d981 Mon Sep 17 00:00:00 2001 From: Yifeng Li Date: Mon, 1 Apr 2019 17:46:59 +0200 Subject: fbdev: sm712fb: fix boot screen glitch when sm712fb replaces VGA When the machine is booted in VGA mode, loading sm712fb would cause a glitch of random pixels shown on the screen. To prevent it from happening, we first clear the entire framebuffer, and we also need to stop calling smtcfb_setmode() during initialization, the fbdev layer will call it for us later when it's ready. Signed-off-by: Yifeng Li Tested-by: Sudip Mukherjee Cc: Teddy Wang Cc: # v4.4+ Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/video/fbdev/sm712fb.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers/video') diff --git a/drivers/video/fbdev/sm712fb.c b/drivers/video/fbdev/sm712fb.c index 1a3d232c2916..e8149f0f47d5 100644 --- a/drivers/video/fbdev/sm712fb.c +++ b/drivers/video/fbdev/sm712fb.c @@ -1493,7 +1493,11 @@ static int smtcfb_pci_probe(struct pci_dev *pdev, if (err) goto failed; - smtcfb_setmode(sfb); + /* + * The screen would be temporarily garbled when sm712fb takes over + * vesafb or VGA text mode. Zero the framebuffer. + */ + memset_io(sfb->lfb, 0, sfb->fb->fix.smem_len); err = register_framebuffer(info); if (err < 0) -- cgit v1.2.3 From 9e0e59993df0601cddb95c4f6c61aa3d5e753c00 Mon Sep 17 00:00:00 2001 From: Yifeng Li Date: Mon, 1 Apr 2019 17:46:59 +0200 Subject: fbdev: sm712fb: fix crashes during framebuffer writes by correctly mapping VRAM On a Thinkpad s30 (Pentium III / i440MX, Lynx3DM), running fbtest or X will crash the machine instantly, because the VRAM/framebuffer is not mapped correctly. On SM712, the framebuffer starts at the beginning of address space, but SM720's framebuffer starts at the 1 MiB offset from the beginning. However, sm712fb fails to take this into account, as a result, writing to the framebuffer will destroy all the registers and kill the system immediately. Another problem is the driver assumes 8 MiB of VRAM for SM720, but some SM720 system, such as this IBM Thinkpad, only has 4 MiB of VRAM. Fix this problem by removing the hardcoded VRAM size, adding a function to query the amount of VRAM from register MCR76 on SM720, and adding proper framebuffer offset. Please note that the memory map may have additional problems on Big-Endian system, which is not available for testing by myself. But I highly suspect that the original code is also broken on Big-Endian machines for SM720, so at least we are not making the problem worse. More, the driver also assumed SM710/SM712 has 4 MiB of VRAM, but it has a 2 MiB version as well, and used in earlier laptops, such as IBM Thinkpad 240X, the driver would probably crash on them. I've never seen one of those machines and cannot fix it, but I have documented these problems in the comments. Signed-off-by: Yifeng Li Tested-by: Sudip Mukherjee Cc: Teddy Wang Cc: # v4.4+ Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/video/fbdev/sm712.h | 5 ----- drivers/video/fbdev/sm712fb.c | 48 +++++++++++++++++++++++++++++++++++++++---- 2 files changed, 44 insertions(+), 9 deletions(-) (limited to 'drivers/video') diff --git a/drivers/video/fbdev/sm712.h b/drivers/video/fbdev/sm712.h index aad1cc4be34a..2cba1e73ed24 100644 --- a/drivers/video/fbdev/sm712.h +++ b/drivers/video/fbdev/sm712.h @@ -19,11 +19,6 @@ #define SCREEN_Y_RES 600 #define SCREEN_BPP 16 -/*Assume SM712 graphics chip has 4MB VRAM */ -#define SM712_VIDEOMEMORYSIZE 0x00400000 -/*Assume SM722 graphics chip has 8MB VRAM */ -#define SM722_VIDEOMEMORYSIZE 0x00800000 - #define dac_reg (0x3c8) #define dac_val (0x3c9) diff --git a/drivers/video/fbdev/sm712fb.c b/drivers/video/fbdev/sm712fb.c index e8149f0f47d5..52234c57be02 100644 --- a/drivers/video/fbdev/sm712fb.c +++ b/drivers/video/fbdev/sm712fb.c @@ -1329,6 +1329,11 @@ static int smtc_map_smem(struct smtcfb_info *sfb, { sfb->fb->fix.smem_start = pci_resource_start(pdev, 0); + if (sfb->chip_id == 0x720) + /* on SM720, the framebuffer starts at the 1 MB offset */ + sfb->fb->fix.smem_start += 0x00200000; + + /* XXX: is it safe for SM720 on Big-Endian? */ if (sfb->fb->var.bits_per_pixel == 32) sfb->fb->fix.smem_start += big_addr; @@ -1366,12 +1371,45 @@ static inline void sm7xx_init_hw(void) outb_p(0x11, 0x3c5); } +static u_long sm7xx_vram_probe(struct smtcfb_info *sfb) +{ + u8 vram; + + switch (sfb->chip_id) { + case 0x710: + case 0x712: + /* + * Assume SM712 graphics chip has 4MB VRAM. + * + * FIXME: SM712 can have 2MB VRAM, which is used on earlier + * laptops, such as IBM Thinkpad 240X. This driver would + * probably crash on those machines. If anyone gets one of + * those and is willing to help, run "git blame" and send me + * an E-mail. + */ + return 0x00400000; + case 0x720: + outb_p(0x76, 0x3c4); + vram = inb_p(0x3c5) >> 6; + + if (vram == 0x00) + return 0x00800000; /* 8 MB */ + else if (vram == 0x01) + return 0x01000000; /* 16 MB */ + else if (vram == 0x02) + return 0x00400000; /* illegal, fallback to 4 MB */ + else if (vram == 0x03) + return 0x00400000; /* 4 MB */ + } + return 0; /* unknown hardware */ +} + static int smtcfb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { struct smtcfb_info *sfb; struct fb_info *info; - u_long smem_size = 0x00800000; /* default 8MB */ + u_long smem_size; int err; unsigned long mmio_base; @@ -1428,12 +1466,15 @@ static int smtcfb_pci_probe(struct pci_dev *pdev, mmio_base = pci_resource_start(pdev, 0); pci_read_config_byte(pdev, PCI_REVISION_ID, &sfb->chip_rev_id); + smem_size = sm7xx_vram_probe(sfb); + dev_info(&pdev->dev, "%lu MiB of VRAM detected.\n", + smem_size / 1048576); + switch (sfb->chip_id) { case 0x710: case 0x712: sfb->fb->fix.mmio_start = mmio_base + 0x00400000; sfb->fb->fix.mmio_len = 0x00400000; - smem_size = SM712_VIDEOMEMORYSIZE; sfb->lfb = ioremap(mmio_base, mmio_addr); if (!sfb->lfb) { dev_err(&pdev->dev, @@ -1465,8 +1506,7 @@ static int smtcfb_pci_probe(struct pci_dev *pdev, case 0x720: sfb->fb->fix.mmio_start = mmio_base; sfb->fb->fix.mmio_len = 0x00200000; - smem_size = SM722_VIDEOMEMORYSIZE; - sfb->dp_regs = ioremap(mmio_base, 0x00a00000); + sfb->dp_regs = ioremap(mmio_base, 0x00200000 + smem_size); sfb->lfb = sfb->dp_regs + 0x00200000; sfb->mmio = (smtc_regbaseaddress = sfb->dp_regs + 0x000c0000); -- cgit v1.2.3 From f627caf55b8e735dcec8fa6538e9668632b55276 Mon Sep 17 00:00:00 2001 From: Yifeng Li Date: Mon, 1 Apr 2019 17:46:59 +0200 Subject: fbdev: sm712fb: fix crashes and garbled display during DPMS modesetting On a Thinkpad s30 (Pentium III / i440MX, Lynx3DM), blanking the display or starting the X server will crash and freeze the system, or garble the display. Experiments showed this problem can mostly be solved by adjusting the order of register writes. Also, sm712fb failed to consider the difference of clock frequency when unblanking the display, and programs the clock for SM712 to SM720. Fix them by adjusting the order of register writes, and adding an additional check for SM720 for programming the clock frequency. Signed-off-by: Yifeng Li Tested-by: Sudip Mukherjee Cc: Teddy Wang Cc: # v4.4+ Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/video/fbdev/sm712fb.c | 64 +++++++++++++++++++++++++------------------ 1 file changed, 38 insertions(+), 26 deletions(-) (limited to 'drivers/video') diff --git a/drivers/video/fbdev/sm712fb.c b/drivers/video/fbdev/sm712fb.c index 52234c57be02..a40d0ae7cb66 100644 --- a/drivers/video/fbdev/sm712fb.c +++ b/drivers/video/fbdev/sm712fb.c @@ -827,67 +827,79 @@ static inline unsigned int chan_to_field(unsigned int chan, static int smtc_blank(int blank_mode, struct fb_info *info) { + struct smtcfb_info *sfb = info->par; + /* clear DPMS setting */ switch (blank_mode) { case FB_BLANK_UNBLANK: /* Screen On: HSync: On, VSync : On */ + + switch (sfb->chip_id) { + case 0x710: + case 0x712: + smtc_seqw(0x6a, 0x16); + smtc_seqw(0x6b, 0x02); + case 0x720: + smtc_seqw(0x6a, 0x0d); + smtc_seqw(0x6b, 0x02); + break; + } + + smtc_seqw(0x23, (smtc_seqr(0x23) & (~0xc0))); smtc_seqw(0x01, (smtc_seqr(0x01) & (~0x20))); - smtc_seqw(0x6a, 0x16); - smtc_seqw(0x6b, 0x02); smtc_seqw(0x21, (smtc_seqr(0x21) & 0x77)); smtc_seqw(0x22, (smtc_seqr(0x22) & (~0x30))); - smtc_seqw(0x23, (smtc_seqr(0x23) & (~0xc0))); - smtc_seqw(0x24, (smtc_seqr(0x24) | 0x01)); smtc_seqw(0x31, (smtc_seqr(0x31) | 0x03)); + smtc_seqw(0x24, (smtc_seqr(0x24) | 0x01)); break; case FB_BLANK_NORMAL: /* Screen Off: HSync: On, VSync : On Soft blank */ + smtc_seqw(0x24, (smtc_seqr(0x24) | 0x01)); + smtc_seqw(0x31, ((smtc_seqr(0x31) & (~0x07)) | 0x00)); + smtc_seqw(0x23, (smtc_seqr(0x23) & (~0xc0))); smtc_seqw(0x01, (smtc_seqr(0x01) & (~0x20))); + smtc_seqw(0x22, (smtc_seqr(0x22) & (~0x30))); smtc_seqw(0x6a, 0x16); smtc_seqw(0x6b, 0x02); - smtc_seqw(0x22, (smtc_seqr(0x22) & (~0x30))); - smtc_seqw(0x23, (smtc_seqr(0x23) & (~0xc0))); - smtc_seqw(0x24, (smtc_seqr(0x24) | 0x01)); - smtc_seqw(0x31, ((smtc_seqr(0x31) & (~0x07)) | 0x00)); break; case FB_BLANK_VSYNC_SUSPEND: /* Screen On: HSync: On, VSync : Off */ + smtc_seqw(0x24, (smtc_seqr(0x24) & (~0x01))); + smtc_seqw(0x31, ((smtc_seqr(0x31) & (~0x07)) | 0x00)); + smtc_seqw(0x23, ((smtc_seqr(0x23) & (~0xc0)) | 0x20)); smtc_seqw(0x01, (smtc_seqr(0x01) | 0x20)); - smtc_seqw(0x20, (smtc_seqr(0x20) & (~0xB0))); - smtc_seqw(0x6a, 0x0c); - smtc_seqw(0x6b, 0x02); smtc_seqw(0x21, (smtc_seqr(0x21) | 0x88)); + smtc_seqw(0x20, (smtc_seqr(0x20) & (~0xB0))); smtc_seqw(0x22, ((smtc_seqr(0x22) & (~0x30)) | 0x20)); - smtc_seqw(0x23, ((smtc_seqr(0x23) & (~0xc0)) | 0x20)); - smtc_seqw(0x24, (smtc_seqr(0x24) & (~0x01))); - smtc_seqw(0x31, ((smtc_seqr(0x31) & (~0x07)) | 0x00)); smtc_seqw(0x34, (smtc_seqr(0x34) | 0x80)); + smtc_seqw(0x6a, 0x0c); + smtc_seqw(0x6b, 0x02); break; case FB_BLANK_HSYNC_SUSPEND: /* Screen On: HSync: Off, VSync : On */ + smtc_seqw(0x24, (smtc_seqr(0x24) & (~0x01))); + smtc_seqw(0x31, ((smtc_seqr(0x31) & (~0x07)) | 0x00)); + smtc_seqw(0x23, ((smtc_seqr(0x23) & (~0xc0)) | 0xD8)); smtc_seqw(0x01, (smtc_seqr(0x01) | 0x20)); - smtc_seqw(0x20, (smtc_seqr(0x20) & (~0xB0))); - smtc_seqw(0x6a, 0x0c); - smtc_seqw(0x6b, 0x02); smtc_seqw(0x21, (smtc_seqr(0x21) | 0x88)); + smtc_seqw(0x20, (smtc_seqr(0x20) & (~0xB0))); smtc_seqw(0x22, ((smtc_seqr(0x22) & (~0x30)) | 0x10)); - smtc_seqw(0x23, ((smtc_seqr(0x23) & (~0xc0)) | 0xD8)); - smtc_seqw(0x24, (smtc_seqr(0x24) & (~0x01))); - smtc_seqw(0x31, ((smtc_seqr(0x31) & (~0x07)) | 0x00)); smtc_seqw(0x34, (smtc_seqr(0x34) | 0x80)); + smtc_seqw(0x6a, 0x0c); + smtc_seqw(0x6b, 0x02); break; case FB_BLANK_POWERDOWN: /* Screen On: HSync: Off, VSync : Off */ + smtc_seqw(0x24, (smtc_seqr(0x24) & (~0x01))); + smtc_seqw(0x31, ((smtc_seqr(0x31) & (~0x07)) | 0x00)); + smtc_seqw(0x23, ((smtc_seqr(0x23) & (~0xc0)) | 0xD8)); smtc_seqw(0x01, (smtc_seqr(0x01) | 0x20)); - smtc_seqw(0x20, (smtc_seqr(0x20) & (~0xB0))); - smtc_seqw(0x6a, 0x0c); - smtc_seqw(0x6b, 0x02); smtc_seqw(0x21, (smtc_seqr(0x21) | 0x88)); + smtc_seqw(0x20, (smtc_seqr(0x20) & (~0xB0))); smtc_seqw(0x22, ((smtc_seqr(0x22) & (~0x30)) | 0x30)); - smtc_seqw(0x23, ((smtc_seqr(0x23) & (~0xc0)) | 0xD8)); - smtc_seqw(0x24, (smtc_seqr(0x24) & (~0x01))); - smtc_seqw(0x31, ((smtc_seqr(0x31) & (~0x07)) | 0x00)); smtc_seqw(0x34, (smtc_seqr(0x34) | 0x80)); + smtc_seqw(0x6a, 0x0c); + smtc_seqw(0x6b, 0x02); break; default: return -EINVAL; -- cgit v1.2.3 From 6053d3a4793e5bde6299ac5388e76a3bf679ff65 Mon Sep 17 00:00:00 2001 From: Yifeng Li Date: Mon, 1 Apr 2019 17:46:59 +0200 Subject: fbdev: sm712fb: fix support for 1024x768-16 mode In order to support the 1024x600 panel on Yeeloong Loongson MIPS laptop, the original 1024x768-16 table was modified to 1024x600-16, without leaving the original. It causes problem on x86 laptop as the 1024x768-16 support was still claimed but not working. Fix it by introducing the 1024x768-16 mode. Signed-off-by: Yifeng Li Tested-by: Sudip Mukherjee Cc: Teddy Wang Cc: # v4.4+ Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/video/fbdev/sm712fb.c | 59 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) (limited to 'drivers/video') diff --git a/drivers/video/fbdev/sm712fb.c b/drivers/video/fbdev/sm712fb.c index a40d0ae7cb66..c39a2641182a 100644 --- a/drivers/video/fbdev/sm712fb.c +++ b/drivers/video/fbdev/sm712fb.c @@ -530,6 +530,65 @@ static const struct modeinit vgamode[] = { 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x15, 0x03, }, }, + { /* 1024 x 768 16Bpp 60Hz */ + 1024, 768, 16, 60, + /* Init_MISC */ + 0xEB, + { /* Init_SR0_SR4 */ + 0x03, 0x01, 0x0F, 0x03, 0x0E, + }, + { /* Init_SR10_SR24 */ + 0xF3, 0xB6, 0xC0, 0xDD, 0x00, 0x0E, 0x17, 0x2C, + 0x99, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xC4, 0x30, 0x02, 0x01, 0x01, + }, + { /* Init_SR30_SR75 */ + 0x38, 0x03, 0x20, 0x09, 0xC0, 0x3A, 0x3A, 0x3A, + 0x3A, 0x3A, 0x3A, 0x3A, 0x00, 0x00, 0x03, 0xFF, + 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC, + 0x20, 0x0C, 0x44, 0x20, 0x00, 0x00, 0x00, 0x3A, + 0x06, 0x68, 0xA7, 0x7F, 0x83, 0x24, 0xFF, 0x03, + 0x0F, 0x60, 0x59, 0x3A, 0x3A, 0x00, 0x00, 0x3A, + 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00, + 0x50, 0x03, 0x74, 0x14, 0x3B, 0x0D, 0x09, 0x02, + 0x04, 0x45, 0x30, 0x30, 0x40, 0x20, + }, + { /* Init_SR80_SR93 */ + 0xFF, 0x07, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x3A, + 0xF7, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x3A, 0x3A, + 0x00, 0x00, 0x00, 0x00, + }, + { /* Init_SRA0_SRAF */ + 0x00, 0xFB, 0x9F, 0x01, 0x00, 0xED, 0xED, 0xED, + 0x7B, 0xFB, 0xFF, 0xFF, 0x97, 0xEF, 0xBF, 0xDF, + }, + { /* Init_GR00_GR08 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, + 0xFF, + }, + { /* Init_AR00_AR14 */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x41, 0x00, 0x0F, 0x00, 0x00, + }, + { /* Init_CR00_CR18 */ + 0xA3, 0x7F, 0x7F, 0x00, 0x85, 0x16, 0x24, 0xF5, + 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x09, 0xFF, 0x80, 0x40, 0xFF, 0x00, 0xE3, + 0xFF, + }, + { /* Init_CR30_CR4D */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x20, + 0x00, 0x00, 0x00, 0x40, 0x00, 0xFF, 0xBF, 0xFF, + 0xA3, 0x7F, 0x00, 0x86, 0x15, 0x24, 0xFF, 0x00, + 0x01, 0x07, 0xE5, 0x20, 0x7F, 0xFF, + }, + { /* Init_CR90_CRA7 */ + 0x55, 0xD9, 0x5D, 0xE1, 0x86, 0x1B, 0x8E, 0x26, + 0xDA, 0x8D, 0xDE, 0x94, 0x00, 0x00, 0x18, 0x00, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x15, 0x03, + }, + }, { /* mode#5: 1024 x 768 24Bpp 60Hz */ 1024, 768, 24, 60, /* Init_MISC */ -- cgit v1.2.3 From 4ed7d2ccb7684510ec5f7a8f7ef534bc6a3d55b2 Mon Sep 17 00:00:00 2001 From: Yifeng Li Date: Mon, 1 Apr 2019 17:46:59 +0200 Subject: fbdev: sm712fb: use 1024x768 by default on non-MIPS, fix garbled display Loongson MIPS netbooks use 1024x600 LCD panels, which is the original target platform of this driver, but nearly all old x86 laptops have 1024x768. Lighting 768 panels using 600's timings would partially garble the display. Since it's not possible to distinguish them reliably, we change the default to 768, but keep 600 as-is on MIPS. Further, earlier laptops, such as IBM Thinkpad 240X, has a 800x600 LCD panel, this driver would probably garbled those display. As we don't have one for testing, the original behavior of the driver is kept as-is, but the problem has been documented is the comments. Signed-off-by: Yifeng Li Tested-by: Sudip Mukherjee Cc: Teddy Wang Cc: # v4.4+ Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/video/fbdev/sm712.h | 7 +++--- drivers/video/fbdev/sm712fb.c | 53 ++++++++++++++++++++++++++++++++----------- 2 files changed, 44 insertions(+), 16 deletions(-) (limited to 'drivers/video') diff --git a/drivers/video/fbdev/sm712.h b/drivers/video/fbdev/sm712.h index 2cba1e73ed24..c7ebf03b8d53 100644 --- a/drivers/video/fbdev/sm712.h +++ b/drivers/video/fbdev/sm712.h @@ -15,9 +15,10 @@ #define FB_ACCEL_SMI_LYNX 88 -#define SCREEN_X_RES 1024 -#define SCREEN_Y_RES 600 -#define SCREEN_BPP 16 +#define SCREEN_X_RES 1024 +#define SCREEN_Y_RES_PC 768 +#define SCREEN_Y_RES_NETBOOK 600 +#define SCREEN_BPP 16 #define dac_reg (0x3c8) #define dac_val (0x3c9) diff --git a/drivers/video/fbdev/sm712fb.c b/drivers/video/fbdev/sm712fb.c index c39a2641182a..1e2503b52c6f 100644 --- a/drivers/video/fbdev/sm712fb.c +++ b/drivers/video/fbdev/sm712fb.c @@ -1475,6 +1475,43 @@ static u_long sm7xx_vram_probe(struct smtcfb_info *sfb) return 0; /* unknown hardware */ } +static void sm7xx_resolution_probe(struct smtcfb_info *sfb) +{ + /* get mode parameter from smtc_scr_info */ + if (smtc_scr_info.lfb_width != 0) { + sfb->fb->var.xres = smtc_scr_info.lfb_width; + sfb->fb->var.yres = smtc_scr_info.lfb_height; + sfb->fb->var.bits_per_pixel = smtc_scr_info.lfb_depth; + goto final; + } + + /* + * No parameter, default resolution is 1024x768-16. + * + * FIXME: earlier laptops, such as IBM Thinkpad 240X, has a 800x600 + * panel, also see the comments about Thinkpad 240X above. + */ + sfb->fb->var.xres = SCREEN_X_RES; + sfb->fb->var.yres = SCREEN_Y_RES_PC; + sfb->fb->var.bits_per_pixel = SCREEN_BPP; + +#ifdef CONFIG_MIPS + /* + * Loongson MIPS netbooks use 1024x600 LCD panels, which is the original + * target platform of this driver, but nearly all old x86 laptops have + * 1024x768. Lighting 768 panels using 600's timings would partially + * garble the display, so we don't want that. But it's not possible to + * distinguish them reliably. + * + * So we change the default to 768, but keep 600 as-is on MIPS. + */ + sfb->fb->var.yres = SCREEN_Y_RES_NETBOOK; +#endif + +final: + big_pixel_depth(sfb->fb->var.bits_per_pixel, smtc_scr_info.lfb_depth); +} + static int smtcfb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { @@ -1520,19 +1557,6 @@ static int smtcfb_pci_probe(struct pci_dev *pdev, sm7xx_init_hw(); - /* get mode parameter from smtc_scr_info */ - if (smtc_scr_info.lfb_width != 0) { - sfb->fb->var.xres = smtc_scr_info.lfb_width; - sfb->fb->var.yres = smtc_scr_info.lfb_height; - sfb->fb->var.bits_per_pixel = smtc_scr_info.lfb_depth; - } else { - /* default resolution 1024x600 16bit mode */ - sfb->fb->var.xres = SCREEN_X_RES; - sfb->fb->var.yres = SCREEN_Y_RES; - sfb->fb->var.bits_per_pixel = SCREEN_BPP; - } - - big_pixel_depth(sfb->fb->var.bits_per_pixel, smtc_scr_info.lfb_depth); /* Map address and memory detection */ mmio_base = pci_resource_start(pdev, 0); pci_read_config_byte(pdev, PCI_REVISION_ID, &sfb->chip_rev_id); @@ -1594,6 +1618,9 @@ static int smtcfb_pci_probe(struct pci_dev *pdev, goto failed_fb; } + /* probe and decide resolution */ + sm7xx_resolution_probe(sfb); + /* can support 32 bpp */ if (sfb->fb->var.bits_per_pixel == 15) sfb->fb->var.bits_per_pixel = 16; -- cgit v1.2.3 From cf84807f6dd0be5214378e66460cfc9187f532f9 Mon Sep 17 00:00:00 2001 From: Shile Zhang Date: Mon, 1 Apr 2019 17:47:00 +0200 Subject: fbdev: fix divide error in fb_var_to_videomode To fix following divide-by-zero error found by Syzkaller: divide error: 0000 [#1] SMP PTI CPU: 7 PID: 8447 Comm: test Kdump: loaded Not tainted 4.19.24-8.al7.x86_64 #1 Hardware name: Alibaba Cloud Alibaba Cloud ECS, BIOS rel-1.12.0-0-ga698c8995f-prebuilt.qemu.org 04/01/2014 RIP: 0010:fb_var_to_videomode+0xae/0xc0 Code: 04 44 03 46 78 03 4e 7c 44 03 46 68 03 4e 70 89 ce d1 ee 69 c0 e8 03 00 00 f6 c2 01 0f 45 ce 83 e2 02 8d 34 09 0f 45 ce 31 d2 <41> f7 f0 31 d2 f7 f1 89 47 08 f3 c3 66 0f 1f 44 00 00 0f 1f 44 00 RSP: 0018:ffffb7e189347bf0 EFLAGS: 00010246 RAX: 00000000e1692410 RBX: ffffb7e189347d60 RCX: 0000000000000000 RDX: 0000000000000000 RSI: 0000000000000000 RDI: ffffb7e189347c10 RBP: ffff99972a091c00 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000100 R13: 0000000000010000 R14: 00007ffd66baf6d0 R15: 0000000000000000 FS: 00007f2054d11740(0000) GS:ffff99972fbc0000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007f205481fd20 CR3: 00000004288a0001 CR4: 00000000001606a0 Call Trace: fb_set_var+0x257/0x390 ? lookup_fast+0xbb/0x2b0 ? fb_open+0xc0/0x140 ? chrdev_open+0xa6/0x1a0 do_fb_ioctl+0x445/0x5a0 do_vfs_ioctl+0x92/0x5f0 ? __alloc_fd+0x3d/0x160 ksys_ioctl+0x60/0x90 __x64_sys_ioctl+0x16/0x20 do_syscall_64+0x5b/0x190 entry_SYSCALL_64_after_hwframe+0x44/0xa9 RIP: 0033:0x7f20548258d7 Code: 44 00 00 48 8b 05 b9 15 2d 00 64 c7 00 26 00 00 00 48 c7 c0 ff ff ff ff c3 66 2e 0f 1f 84 00 00 00 00 00 b8 10 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 89 15 2d 00 f7 d8 64 89 01 48 It can be triggered easily with following test code: #include #include #include int main(void) { struct fb_var_screeninfo var = {.activate = 0x100, .pixclock = 60}; int fd = open("/dev/fb0", O_RDWR); if (fd < 0) return 1; if (ioctl(fd, FBIOPUT_VSCREENINFO, &var)) return 1; return 0; } Signed-off-by: Shile Zhang Cc: Fredrik Noring Cc: Daniel Vetter Reviewed-by: Mukesh Ojha Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/video/fbdev/core/modedb.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/video') diff --git a/drivers/video/fbdev/core/modedb.c b/drivers/video/fbdev/core/modedb.c index 283d9307df21..ac049871704d 100644 --- a/drivers/video/fbdev/core/modedb.c +++ b/drivers/video/fbdev/core/modedb.c @@ -935,6 +935,9 @@ void fb_var_to_videomode(struct fb_videomode *mode, if (var->vmode & FB_VMODE_DOUBLE) vtotal *= 2; + if (!htotal || !vtotal) + return; + hfreq = pixclock/htotal; mode->refresh = hfreq/vtotal; } -- cgit v1.2.3 From 9dc20113988b9a75ea6b3abd68dc45e2d73ccdab Mon Sep 17 00:00:00 2001 From: Yifeng Li Date: Tue, 2 Apr 2019 17:14:10 +0200 Subject: fbdev: sm712fb: fix memory frequency by avoiding a switch/case fallthrough A fallthrough in switch/case was introduced in f627caf55b8e ("fbdev: sm712fb: fix crashes and garbled display during DPMS modesetting"), due to my copy-paste error, which would cause the memory clock frequency for SM720 to be programmed to SM712. Since it only reprograms the clock to a different frequency, it's only a benign issue without visible side-effect, so it also evaded Sudip Mukherjee's code review and regression tests. scripts/checkpatch.pl also failed to discover the issue, possibly due to nested switch statements. This issue was found by Stephen Rothwell by building linux-next with -Wimplicit-fallthrough. Reported-by: Stephen Rothwell Fixes: f627caf55b8e ("fbdev: sm712fb: fix crashes and garbled display during DPMS modesetting") Signed-off-by: Yifeng Li Cc: Sudip Mukherjee Cc: "Gustavo A. R. Silva" Cc: Kees Cook Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/video/fbdev/sm712fb.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/video') diff --git a/drivers/video/fbdev/sm712fb.c b/drivers/video/fbdev/sm712fb.c index 1e2503b52c6f..f1dcc6766d1e 100644 --- a/drivers/video/fbdev/sm712fb.c +++ b/drivers/video/fbdev/sm712fb.c @@ -898,6 +898,7 @@ static int smtc_blank(int blank_mode, struct fb_info *info) case 0x712: smtc_seqw(0x6a, 0x16); smtc_seqw(0x6b, 0x02); + break; case 0x720: smtc_seqw(0x6a, 0x0d); smtc_seqw(0x6b, 0x02); -- cgit v1.2.3 From a6fdbd551573d9e303823c93075c0f0edff8d98e Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Thu, 11 Apr 2019 19:25:12 +0200 Subject: video: amba-clcd: Decomission Versatile and Nomadik These board families are now handled in the DRM subsystem where we can have reusable panel drivers and some other stuff. The PL111 there is now the driver used in the defconfig for Versatile and Nomadik so no need to keep this code around. There are a few minor machines in arch/arm/ such as mach-netx still using the old driver, so we need to keep the core fbdev driver around for some time. Signed-off-by: Linus Walleij Cc: Russell King Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/video/fbdev/Kconfig | 8 - drivers/video/fbdev/Makefile | 2 - drivers/video/fbdev/amba-clcd-nomadik.c | 251 ------------- drivers/video/fbdev/amba-clcd-nomadik.h | 24 -- drivers/video/fbdev/amba-clcd-versatile.c | 567 ------------------------------ drivers/video/fbdev/amba-clcd-versatile.h | 17 - drivers/video/fbdev/amba-clcd.c | 98 +----- include/linux/amba/clcd.h | 31 -- 8 files changed, 2 insertions(+), 996 deletions(-) delete mode 100644 drivers/video/fbdev/amba-clcd-nomadik.c delete mode 100644 drivers/video/fbdev/amba-clcd-nomadik.h delete mode 100644 drivers/video/fbdev/amba-clcd-versatile.c delete mode 100644 drivers/video/fbdev/amba-clcd-versatile.h (limited to 'drivers/video') diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig index 8fae27903eb8..47ecf9ad4d51 100644 --- a/drivers/video/fbdev/Kconfig +++ b/drivers/video/fbdev/Kconfig @@ -293,14 +293,6 @@ config FB_ARMCLCD here and read . The module will be called amba-clcd. -# Helper logic selected only by the ARM Versatile platform family. -config PLAT_VERSATILE_CLCD - def_bool ARCH_VERSATILE || ARCH_REALVIEW || ARCH_VEXPRESS || ARCH_INTEGRATOR - depends on ARM - depends on FB_ARMCLCD && FB=y - select REGMAP - select MFD_SYSCON - config FB_ACORN bool "Acorn VIDC support" depends on (FB = y) && ARM && ARCH_ACORN diff --git a/drivers/video/fbdev/Makefile b/drivers/video/fbdev/Makefile index 846b0c9ea9db..655f2537cac1 100644 --- a/drivers/video/fbdev/Makefile +++ b/drivers/video/fbdev/Makefile @@ -76,8 +76,6 @@ obj-$(CONFIG_FB_ATMEL) += atmel_lcdfb.o obj-$(CONFIG_FB_PVR2) += pvr2fb.o obj-$(CONFIG_FB_VOODOO1) += sstfb.o obj-$(CONFIG_FB_ARMCLCD) += amba-clcd.o -obj-$(CONFIG_ARCH_NOMADIK) += amba-clcd-nomadik.o -obj-$(CONFIG_PLAT_VERSATILE_CLCD) += amba-clcd-versatile.o obj-$(CONFIG_FB_GOLDFISH) += goldfishfb.o obj-$(CONFIG_FB_68328) += 68328fb.o obj-$(CONFIG_FB_GBE) += gbefb.o diff --git a/drivers/video/fbdev/amba-clcd-nomadik.c b/drivers/video/fbdev/amba-clcd-nomadik.c deleted file mode 100644 index cd2db1113e67..000000000000 --- a/drivers/video/fbdev/amba-clcd-nomadik.c +++ /dev/null @@ -1,251 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "amba-clcd-nomadik.h" - -static struct gpio_desc *grestb; -static struct gpio_desc *scen; -static struct gpio_desc *scl; -static struct gpio_desc *sda; - -static u8 tpg110_readwrite_reg(bool write, u8 address, u8 outval) -{ - int i; - u8 inval = 0; - - /* Assert SCEN */ - gpiod_set_value_cansleep(scen, 1); - ndelay(150); - /* Hammer out the address */ - for (i = 5; i >= 0; i--) { - if (address & BIT(i)) - gpiod_set_value_cansleep(sda, 1); - else - gpiod_set_value_cansleep(sda, 0); - ndelay(150); - /* Send an SCL pulse */ - gpiod_set_value_cansleep(scl, 1); - ndelay(160); - gpiod_set_value_cansleep(scl, 0); - ndelay(160); - } - - if (write) { - /* WRITE */ - gpiod_set_value_cansleep(sda, 0); - } else { - /* READ */ - gpiod_set_value_cansleep(sda, 1); - } - ndelay(150); - /* Send an SCL pulse */ - gpiod_set_value_cansleep(scl, 1); - ndelay(160); - gpiod_set_value_cansleep(scl, 0); - ndelay(160); - - if (!write) - /* HiZ turn-around cycle */ - gpiod_direction_input(sda); - ndelay(150); - /* Send an SCL pulse */ - gpiod_set_value_cansleep(scl, 1); - ndelay(160); - gpiod_set_value_cansleep(scl, 0); - ndelay(160); - - /* Hammer in/out the data */ - for (i = 7; i >= 0; i--) { - int value; - - if (write) { - value = !!(outval & BIT(i)); - gpiod_set_value_cansleep(sda, value); - } else { - value = gpiod_get_value(sda); - if (value) - inval |= BIT(i); - } - ndelay(150); - /* Send an SCL pulse */ - gpiod_set_value_cansleep(scl, 1); - ndelay(160); - gpiod_set_value_cansleep(scl, 0); - ndelay(160); - } - - gpiod_direction_output(sda, 0); - /* Deassert SCEN */ - gpiod_set_value_cansleep(scen, 0); - /* Satisfies SCEN pulse width */ - udelay(1); - - return inval; -} - -static u8 tpg110_read_reg(u8 address) -{ - return tpg110_readwrite_reg(false, address, 0); -} - -static void tpg110_write_reg(u8 address, u8 outval) -{ - tpg110_readwrite_reg(true, address, outval); -} - -static void tpg110_startup(struct device *dev) -{ - u8 val; - - dev_info(dev, "TPG110 display enable\n"); - /* De-assert the reset signal */ - gpiod_set_value_cansleep(grestb, 0); - mdelay(1); - dev_info(dev, "de-asserted GRESTB\n"); - - /* Test display communication */ - tpg110_write_reg(0x00, 0x55); - val = tpg110_read_reg(0x00); - if (val == 0x55) - dev_info(dev, "passed communication test\n"); - val = tpg110_read_reg(0x01); - dev_info(dev, "TPG110 chip ID: %d version: %d\n", - val>>4, val&0x0f); - - /* Show display resolution */ - val = tpg110_read_reg(0x02); - val &= 7; - switch (val) { - case 0x0: - dev_info(dev, "IN 400x240 RGB -> OUT 800x480 RGB (dual scan)"); - break; - case 0x1: - dev_info(dev, "IN 480x272 RGB -> OUT 800x480 RGB (dual scan)"); - break; - case 0x4: - dev_info(dev, "480x640 RGB"); - break; - case 0x5: - dev_info(dev, "480x272 RGB"); - break; - case 0x6: - dev_info(dev, "640x480 RGB"); - break; - case 0x7: - dev_info(dev, "800x480 RGB"); - break; - default: - dev_info(dev, "ILLEGAL RESOLUTION"); - break; - } - - val = tpg110_read_reg(0x03); - dev_info(dev, "resolution is controlled by %s\n", - (val & BIT(7)) ? "software" : "hardware"); -} - -static void tpg110_enable(struct clcd_fb *fb) -{ - struct device *dev = &fb->dev->dev; - static bool startup; - u8 val; - - if (!startup) { - tpg110_startup(dev); - startup = true; - } - - /* Take chip out of standby */ - val = tpg110_read_reg(0x03); - val |= BIT(0); - tpg110_write_reg(0x03, val); -} - -static void tpg110_disable(struct clcd_fb *fb) -{ - u8 val; - - dev_info(&fb->dev->dev, "TPG110 display disable\n"); - val = tpg110_read_reg(0x03); - /* Put into standby */ - val &= ~BIT(0); - tpg110_write_reg(0x03, val); -} - -static void tpg110_init(struct device *dev, struct device_node *np, - struct clcd_board *board) -{ - dev_info(dev, "TPG110 display init\n"); - - /* This asserts the GRESTB signal, putting the display into reset */ - grestb = devm_fwnode_get_gpiod_from_child(dev, "grestb", &np->fwnode, - GPIOD_OUT_HIGH, "grestb"); - if (IS_ERR(grestb)) { - dev_err(dev, "no GRESTB GPIO\n"); - return; - } - scen = devm_fwnode_get_gpiod_from_child(dev, "scen", &np->fwnode, - GPIOD_OUT_LOW, "scen"); - if (IS_ERR(scen)) { - dev_err(dev, "no SCEN GPIO\n"); - return; - } - scl = devm_fwnode_get_gpiod_from_child(dev, "scl", &np->fwnode, - GPIOD_OUT_LOW, "scl"); - if (IS_ERR(scl)) { - dev_err(dev, "no SCL GPIO\n"); - return; - } - sda = devm_fwnode_get_gpiod_from_child(dev, "sda", &np->fwnode, - GPIOD_OUT_LOW, "sda"); - if (IS_ERR(sda)) { - dev_err(dev, "no SDA GPIO\n"); - return; - } - board->enable = tpg110_enable; - board->disable = tpg110_disable; -} - -int nomadik_clcd_init_panel(struct clcd_fb *fb, struct device_node *panel) -{ - if (of_device_is_compatible(panel, "tpo,tpg110")) - tpg110_init(&fb->dev->dev, panel, fb->board); - else - dev_info(&fb->dev->dev, "unknown panel\n"); - - /* Unknown panel, fall through */ - return 0; -} -EXPORT_SYMBOL_GPL(nomadik_clcd_init_panel); - -#define PMU_CTRL_OFFSET 0x0000 -#define PMU_CTRL_LCDNDIF BIT(26) - -int nomadik_clcd_init_board(struct amba_device *adev, - struct clcd_board *board) -{ - struct regmap *pmu_regmap; - - dev_info(&adev->dev, "Nomadik CLCD board init\n"); - pmu_regmap = - syscon_regmap_lookup_by_compatible("stericsson,nomadik-pmu"); - if (IS_ERR(pmu_regmap)) { - dev_err(&adev->dev, "could not find PMU syscon regmap\n"); - return PTR_ERR(pmu_regmap); - } - regmap_update_bits(pmu_regmap, - PMU_CTRL_OFFSET, - PMU_CTRL_LCDNDIF, - 0); - dev_info(&adev->dev, "set PMU mux to CLCD mode\n"); - - return 0; -} -EXPORT_SYMBOL_GPL(nomadik_clcd_init_board); diff --git a/drivers/video/fbdev/amba-clcd-nomadik.h b/drivers/video/fbdev/amba-clcd-nomadik.h deleted file mode 100644 index 462c31381fa1..000000000000 --- a/drivers/video/fbdev/amba-clcd-nomadik.h +++ /dev/null @@ -1,24 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef _AMBA_CLCD_NOMADIK_H -#define _AMBA_CLCD_NOMADIK_H - -#include - -#ifdef CONFIG_ARCH_NOMADIK -int nomadik_clcd_init_board(struct amba_device *adev, - struct clcd_board *board); -int nomadik_clcd_init_panel(struct clcd_fb *fb, struct device_node *panel); -#else -static inline int nomadik_clcd_init_board(struct amba_device *adev, - struct clcd_board *board) -{ - return 0; -} -static inline int nomadik_clcd_init_panel(struct clcd_fb *fb, - struct device_node *panel) -{ - return 0; -} -#endif - -#endif /* inclusion guard */ diff --git a/drivers/video/fbdev/amba-clcd-versatile.c b/drivers/video/fbdev/amba-clcd-versatile.c deleted file mode 100644 index d42047dc4e4e..000000000000 --- a/drivers/video/fbdev/amba-clcd-versatile.c +++ /dev/null @@ -1,567 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "amba-clcd-versatile.h" - -static struct clcd_panel vga = { - .mode = { - .name = "VGA", - .refresh = 60, - .xres = 640, - .yres = 480, - .pixclock = 39721, - .left_margin = 40, - .right_margin = 24, - .upper_margin = 32, - .lower_margin = 11, - .hsync_len = 96, - .vsync_len = 2, - .sync = 0, - .vmode = FB_VMODE_NONINTERLACED, - }, - .width = -1, - .height = -1, - .tim2 = TIM2_BCD | TIM2_IPC, - .cntl = CNTL_LCDTFT | CNTL_BGR | CNTL_LCDVCOMP(1), - .caps = CLCD_CAP_5551 | CLCD_CAP_565 | CLCD_CAP_888, - .bpp = 16, -}; - -static struct clcd_panel xvga = { - .mode = { - .name = "XVGA", - .refresh = 60, - .xres = 1024, - .yres = 768, - .pixclock = 15748, - .left_margin = 152, - .right_margin = 48, - .upper_margin = 23, - .lower_margin = 3, - .hsync_len = 104, - .vsync_len = 4, - .sync = 0, - .vmode = FB_VMODE_NONINTERLACED, - }, - .width = -1, - .height = -1, - .tim2 = TIM2_BCD | TIM2_IPC, - .cntl = CNTL_LCDTFT | CNTL_BGR | CNTL_LCDVCOMP(1), - .caps = CLCD_CAP_5551 | CLCD_CAP_565 | CLCD_CAP_888, - .bpp = 16, -}; - -/* Sanyo TM38QV67A02A - 3.8 inch QVGA (320x240) Color TFT */ -static struct clcd_panel sanyo_tm38qv67a02a = { - .mode = { - .name = "Sanyo TM38QV67A02A", - .refresh = 116, - .xres = 320, - .yres = 240, - .pixclock = 100000, - .left_margin = 6, - .right_margin = 6, - .upper_margin = 5, - .lower_margin = 5, - .hsync_len = 6, - .vsync_len = 6, - .sync = 0, - .vmode = FB_VMODE_NONINTERLACED, - }, - .width = -1, - .height = -1, - .tim2 = TIM2_BCD, - .cntl = CNTL_LCDTFT | CNTL_BGR | CNTL_LCDVCOMP(1), - .caps = CLCD_CAP_5551, - .bpp = 16, -}; - -static struct clcd_panel sanyo_2_5_in = { - .mode = { - .name = "Sanyo QVGA Portrait", - .refresh = 116, - .xres = 240, - .yres = 320, - .pixclock = 100000, - .left_margin = 20, - .right_margin = 10, - .upper_margin = 2, - .lower_margin = 2, - .hsync_len = 10, - .vsync_len = 2, - .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, - .vmode = FB_VMODE_NONINTERLACED, - }, - .width = -1, - .height = -1, - .tim2 = TIM2_IVS | TIM2_IHS | TIM2_IPC, - .cntl = CNTL_LCDTFT | CNTL_BGR | CNTL_LCDVCOMP(1), - .caps = CLCD_CAP_5551, - .bpp = 16, -}; - -/* Epson L2F50113T00 - 2.2 inch 176x220 Color TFT */ -static struct clcd_panel epson_l2f50113t00 = { - .mode = { - .name = "Epson L2F50113T00", - .refresh = 390, - .xres = 176, - .yres = 220, - .pixclock = 62500, - .left_margin = 3, - .right_margin = 2, - .upper_margin = 1, - .lower_margin = 0, - .hsync_len = 3, - .vsync_len = 2, - .sync = 0, - .vmode = FB_VMODE_NONINTERLACED, - }, - .width = -1, - .height = -1, - .tim2 = TIM2_BCD | TIM2_IPC, - .cntl = CNTL_LCDTFT | CNTL_BGR | CNTL_LCDVCOMP(1), - .caps = CLCD_CAP_5551, - .bpp = 16, -}; - -static struct clcd_panel *panels[] = { - &vga, - &xvga, - &sanyo_tm38qv67a02a, - &sanyo_2_5_in, - &epson_l2f50113t00, -}; - -struct clcd_panel *versatile_clcd_get_panel(const char *name) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(panels); i++) - if (strcmp(panels[i]->mode.name, name) == 0) - break; - - if (i < ARRAY_SIZE(panels)) - return panels[i]; - - pr_err("CLCD: couldn't get parameters for panel %s\n", name); - - return NULL; -} - -int versatile_clcd_setup_dma(struct clcd_fb *fb, unsigned long framesize) -{ - dma_addr_t dma; - - fb->fb.screen_base = dma_alloc_wc(&fb->dev->dev, framesize, &dma, - GFP_KERNEL); - if (!fb->fb.screen_base) { - pr_err("CLCD: unable to map framebuffer\n"); - return -ENOMEM; - } - - fb->fb.fix.smem_start = dma; - fb->fb.fix.smem_len = framesize; - - return 0; -} - -int versatile_clcd_mmap_dma(struct clcd_fb *fb, struct vm_area_struct *vma) -{ - return dma_mmap_wc(&fb->dev->dev, vma, fb->fb.screen_base, - fb->fb.fix.smem_start, fb->fb.fix.smem_len); -} - -void versatile_clcd_remove_dma(struct clcd_fb *fb) -{ - dma_free_wc(&fb->dev->dev, fb->fb.fix.smem_len, fb->fb.screen_base, - fb->fb.fix.smem_start); -} - -#ifdef CONFIG_OF - -static struct regmap *versatile_syscon_map; -static struct regmap *versatile_ib2_map; - -/* - * We detect the different syscon types from the compatible strings. - */ -enum versatile_clcd { - INTEGRATOR_CLCD_CM, - VERSATILE_CLCD, - REALVIEW_CLCD_EB, - REALVIEW_CLCD_PB1176, - REALVIEW_CLCD_PB11MP, - REALVIEW_CLCD_PBA8, - REALVIEW_CLCD_PBX, -}; - -static const struct of_device_id versatile_clcd_of_match[] = { - { - .compatible = "arm,core-module-integrator", - .data = (void *)INTEGRATOR_CLCD_CM, - }, - { - .compatible = "arm,versatile-sysreg", - .data = (void *)VERSATILE_CLCD, - }, - { - .compatible = "arm,realview-eb-syscon", - .data = (void *)REALVIEW_CLCD_EB, - }, - { - .compatible = "arm,realview-pb1176-syscon", - .data = (void *)REALVIEW_CLCD_PB1176, - }, - { - .compatible = "arm,realview-pb11mp-syscon", - .data = (void *)REALVIEW_CLCD_PB11MP, - }, - { - .compatible = "arm,realview-pba8-syscon", - .data = (void *)REALVIEW_CLCD_PBA8, - }, - { - .compatible = "arm,realview-pbx-syscon", - .data = (void *)REALVIEW_CLCD_PBX, - }, - {}, -}; - -/* - * Core module CLCD control on the Integrator/CP, bits - * 8 thru 19 of the CM_CONTROL register controls a bunch - * of CLCD settings. - */ -#define INTEGRATOR_HDR_CTRL_OFFSET 0x0C -#define INTEGRATOR_CLCD_LCDBIASEN BIT(8) -#define INTEGRATOR_CLCD_LCDBIASUP BIT(9) -#define INTEGRATOR_CLCD_LCDBIASDN BIT(10) -/* Bits 11,12,13 controls the LCD type */ -#define INTEGRATOR_CLCD_LCDMUX_MASK (BIT(11)|BIT(12)|BIT(13)) -#define INTEGRATOR_CLCD_LCDMUX_LCD24 BIT(11) -#define INTEGRATOR_CLCD_LCDMUX_VGA565 BIT(12) -#define INTEGRATOR_CLCD_LCDMUX_SHARP (BIT(11)|BIT(12)) -#define INTEGRATOR_CLCD_LCDMUX_VGA555 BIT(13) -#define INTEGRATOR_CLCD_LCDMUX_VGA24 (BIT(11)|BIT(12)|BIT(13)) -#define INTEGRATOR_CLCD_LCD0_EN BIT(14) -#define INTEGRATOR_CLCD_LCD1_EN BIT(15) -/* R/L flip on Sharp */ -#define INTEGRATOR_CLCD_LCD_STATIC1 BIT(16) -/* U/D flip on Sharp */ -#define INTEGRATOR_CLCD_LCD_STATIC2 BIT(17) -/* No connection on Sharp */ -#define INTEGRATOR_CLCD_LCD_STATIC BIT(18) -/* 0 = 24bit VGA, 1 = 18bit VGA */ -#define INTEGRATOR_CLCD_LCD_N24BITEN BIT(19) - -#define INTEGRATOR_CLCD_MASK (INTEGRATOR_CLCD_LCDBIASEN | \ - INTEGRATOR_CLCD_LCDBIASUP | \ - INTEGRATOR_CLCD_LCDBIASDN | \ - INTEGRATOR_CLCD_LCDMUX_MASK | \ - INTEGRATOR_CLCD_LCD0_EN | \ - INTEGRATOR_CLCD_LCD1_EN | \ - INTEGRATOR_CLCD_LCD_STATIC1 | \ - INTEGRATOR_CLCD_LCD_STATIC2 | \ - INTEGRATOR_CLCD_LCD_STATIC | \ - INTEGRATOR_CLCD_LCD_N24BITEN) - -static void integrator_clcd_enable(struct clcd_fb *fb) -{ - struct fb_var_screeninfo *var = &fb->fb.var; - u32 val; - - dev_info(&fb->dev->dev, "enable Integrator CLCD connectors\n"); - - /* FIXME: really needed? */ - val = INTEGRATOR_CLCD_LCD_STATIC1 | INTEGRATOR_CLCD_LCD_STATIC2 | - INTEGRATOR_CLCD_LCD0_EN | INTEGRATOR_CLCD_LCD1_EN; - if (var->bits_per_pixel <= 8 || - (var->bits_per_pixel == 16 && var->green.length == 5)) - /* Pseudocolor, RGB555, BGR555 */ - val |= INTEGRATOR_CLCD_LCDMUX_VGA555; - else if (fb->fb.var.bits_per_pixel <= 16) - /* truecolor RGB565 */ - val |= INTEGRATOR_CLCD_LCDMUX_VGA565; - else - val = 0; /* no idea for this, don't trust the docs */ - - regmap_update_bits(versatile_syscon_map, - INTEGRATOR_HDR_CTRL_OFFSET, - INTEGRATOR_CLCD_MASK, - val); -} - -/* - * This configuration register in the Versatile and RealView - * family is uniformly present but appears more and more - * unutilized starting with the RealView series. - */ -#define SYS_CLCD 0x50 -#define SYS_CLCD_MODE_MASK (BIT(0)|BIT(1)) -#define SYS_CLCD_MODE_888 0 -#define SYS_CLCD_MODE_5551 BIT(0) -#define SYS_CLCD_MODE_565_R_LSB BIT(1) -#define SYS_CLCD_MODE_565_B_LSB (BIT(0)|BIT(1)) -#define SYS_CLCD_CONNECTOR_MASK (BIT(2)|BIT(3)|BIT(4)|BIT(5)) -#define SYS_CLCD_NLCDIOON BIT(2) -#define SYS_CLCD_VDDPOSSWITCH BIT(3) -#define SYS_CLCD_PWR3V5SWITCH BIT(4) -#define SYS_CLCD_VDDNEGSWITCH BIT(5) -#define SYS_CLCD_TSNSS BIT(6) /* touchscreen enable */ -#define SYS_CLCD_SSPEXP BIT(7) /* SSP expansion enable */ - -/* The Versatile can detect the connected panel type */ -#define SYS_CLCD_CLCDID_MASK (BIT(8)|BIT(9)|BIT(10)|BIT(11)|BIT(12)) -#define SYS_CLCD_ID_SANYO_3_8 (0x00 << 8) -#define SYS_CLCD_ID_SHARP_8_4 (0x01 << 8) -#define SYS_CLCD_ID_EPSON_2_2 (0x02 << 8) -#define SYS_CLCD_ID_SANYO_2_5 (0x07 << 8) -#define SYS_CLCD_ID_VGA (0x1f << 8) - -#define SYS_CLCD_TSNDAV BIT(13) /* data ready from TS */ - -/* IB2 control register for the Versatile daughterboard */ -#define IB2_CTRL 0x00 -#define IB2_CTRL_LCD_SD BIT(1) /* 1 = shut down LCD */ -#define IB2_CTRL_LCD_BL_ON BIT(0) -#define IB2_CTRL_LCD_MASK (BIT(0)|BIT(1)) - -static void versatile_clcd_disable(struct clcd_fb *fb) -{ - dev_info(&fb->dev->dev, "disable Versatile CLCD connectors\n"); - regmap_update_bits(versatile_syscon_map, - SYS_CLCD, - SYS_CLCD_CONNECTOR_MASK, - 0); - - /* If we're on an IB2 daughterboard, turn off display */ - if (versatile_ib2_map) { - dev_info(&fb->dev->dev, "disable IB2 display\n"); - regmap_update_bits(versatile_ib2_map, - IB2_CTRL, - IB2_CTRL_LCD_MASK, - IB2_CTRL_LCD_SD); - } -} - -static void versatile_clcd_enable(struct clcd_fb *fb) -{ - struct fb_var_screeninfo *var = &fb->fb.var; - u32 val = 0; - - dev_info(&fb->dev->dev, "enable Versatile CLCD connectors\n"); - switch (var->green.length) { - case 5: - val |= SYS_CLCD_MODE_5551; - break; - case 6: - if (var->red.offset == 0) - val |= SYS_CLCD_MODE_565_R_LSB; - else - val |= SYS_CLCD_MODE_565_B_LSB; - break; - case 8: - val |= SYS_CLCD_MODE_888; - break; - } - - /* Set up the MUX */ - regmap_update_bits(versatile_syscon_map, - SYS_CLCD, - SYS_CLCD_MODE_MASK, - val); - - /* Then enable the display */ - regmap_update_bits(versatile_syscon_map, - SYS_CLCD, - SYS_CLCD_CONNECTOR_MASK, - SYS_CLCD_NLCDIOON | SYS_CLCD_PWR3V5SWITCH); - - /* If we're on an IB2 daughterboard, turn on display */ - if (versatile_ib2_map) { - dev_info(&fb->dev->dev, "enable IB2 display\n"); - regmap_update_bits(versatile_ib2_map, - IB2_CTRL, - IB2_CTRL_LCD_MASK, - IB2_CTRL_LCD_BL_ON); - } -} - -static void versatile_clcd_decode(struct clcd_fb *fb, struct clcd_regs *regs) -{ - clcdfb_decode(fb, regs); - - /* Always clear BGR for RGB565: we do the routing externally */ - if (fb->fb.var.green.length == 6) - regs->cntl &= ~CNTL_BGR; -} - -static void realview_clcd_disable(struct clcd_fb *fb) -{ - dev_info(&fb->dev->dev, "disable RealView CLCD connectors\n"); - regmap_update_bits(versatile_syscon_map, - SYS_CLCD, - SYS_CLCD_CONNECTOR_MASK, - 0); -} - -static void realview_clcd_enable(struct clcd_fb *fb) -{ - dev_info(&fb->dev->dev, "enable RealView CLCD connectors\n"); - regmap_update_bits(versatile_syscon_map, - SYS_CLCD, - SYS_CLCD_CONNECTOR_MASK, - SYS_CLCD_NLCDIOON | SYS_CLCD_PWR3V5SWITCH); -} - -struct versatile_panel { - u32 id; - char *compatible; - bool ib2; -}; - -static const struct versatile_panel versatile_panels[] = { - { - .id = SYS_CLCD_ID_VGA, - .compatible = "VGA", - }, - { - .id = SYS_CLCD_ID_SANYO_3_8, - .compatible = "sanyo,tm38qv67a02a", - }, - { - .id = SYS_CLCD_ID_SHARP_8_4, - .compatible = "sharp,lq084v1dg21", - }, - { - .id = SYS_CLCD_ID_EPSON_2_2, - .compatible = "epson,l2f50113t00", - }, - { - .id = SYS_CLCD_ID_SANYO_2_5, - .compatible = "sanyo,alr252rgt", - .ib2 = true, - }, -}; - -static void versatile_panel_probe(struct device *dev, struct device_node *panel) -{ - struct versatile_panel const *vpanel = NULL; - u32 val; - int ret; - int i; - - /* - * The Versatile CLCD has a panel auto-detection mechanism. - * We use this and look for the compatible panel in the - * device tree. - */ - ret = regmap_read(versatile_syscon_map, SYS_CLCD, &val); - if (ret) { - dev_err(dev, "cannot read CLCD syscon register\n"); - return; - } - val &= SYS_CLCD_CLCDID_MASK; - - /* First find corresponding panel information */ - for (i = 0; i < ARRAY_SIZE(versatile_panels); i++) { - vpanel = &versatile_panels[i]; - - if (val == vpanel->id) { - dev_err(dev, "autodetected panel \"%s\"\n", - vpanel->compatible); - break; - } - } - if (i == ARRAY_SIZE(versatile_panels)) { - dev_err(dev, "could not auto-detect panel\n"); - return; - } - - if (!of_device_is_compatible(panel, vpanel->compatible)) - dev_err(dev, "panel in DT is not compatible with the " - "auto-detected panel, continuing anyway\n"); - - /* - * If we have a Sanyo 2.5" port - * that we're running on an IB2 and proceed to look for the - * IB2 syscon regmap. - */ - if (!vpanel->ib2) - return; - - versatile_ib2_map = syscon_regmap_lookup_by_compatible( - "arm,versatile-ib2-syscon"); - if (IS_ERR(versatile_ib2_map)) { - dev_err(dev, "could not locate IB2 control register\n"); - versatile_ib2_map = NULL; - return; - } -} - -int versatile_clcd_init_panel(struct clcd_fb *fb, struct device_node *panel) -{ - const struct of_device_id *clcd_id; - enum versatile_clcd versatile_clcd_type; - struct device_node *np; - struct regmap *map; - struct device *dev = &fb->dev->dev; - - np = of_find_matching_node_and_match(NULL, versatile_clcd_of_match, - &clcd_id); - if (!np) { - /* Vexpress does not have this */ - return 0; - } - versatile_clcd_type = (enum versatile_clcd)clcd_id->data; - - map = syscon_node_to_regmap(np); - if (IS_ERR(map)) { - dev_err(dev, "no Versatile syscon regmap\n"); - return PTR_ERR(map); - } - - switch (versatile_clcd_type) { - case INTEGRATOR_CLCD_CM: - versatile_syscon_map = map; - fb->board->enable = integrator_clcd_enable; - /* Override the caps, we have only these */ - fb->board->caps = CLCD_CAP_5551 | CLCD_CAP_RGB565 | - CLCD_CAP_888; - dev_info(dev, "set up callbacks for Integrator PL110\n"); - break; - case VERSATILE_CLCD: - versatile_syscon_map = map; - fb->board->enable = versatile_clcd_enable; - fb->board->disable = versatile_clcd_disable; - fb->board->decode = versatile_clcd_decode; - versatile_panel_probe(dev, panel); - dev_info(dev, "set up callbacks for Versatile\n"); - break; - case REALVIEW_CLCD_EB: - case REALVIEW_CLCD_PB1176: - case REALVIEW_CLCD_PB11MP: - case REALVIEW_CLCD_PBA8: - case REALVIEW_CLCD_PBX: - versatile_syscon_map = map; - fb->board->enable = realview_clcd_enable; - fb->board->disable = realview_clcd_disable; - dev_info(dev, "set up callbacks for RealView PL111\n"); - break; - default: - dev_info(dev, "unknown Versatile system controller\n"); - break; - } - - return 0; -} -EXPORT_SYMBOL_GPL(versatile_clcd_init_panel); -#endif diff --git a/drivers/video/fbdev/amba-clcd-versatile.h b/drivers/video/fbdev/amba-clcd-versatile.h deleted file mode 100644 index b20baa47e6ad..000000000000 --- a/drivers/video/fbdev/amba-clcd-versatile.h +++ /dev/null @@ -1,17 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Special local versatile callbacks - */ -#include -#include -#include - -#if defined(CONFIG_PLAT_VERSATILE_CLCD) && defined(CONFIG_OF) -int versatile_clcd_init_panel(struct clcd_fb *fb, struct device_node *panel); -#else -static inline int versatile_clcd_init_panel(struct clcd_fb *fb, - struct device_node *panel) -{ - return 0; -} -#endif diff --git a/drivers/video/fbdev/amba-clcd.c b/drivers/video/fbdev/amba-clcd.c index 38c1f324ce15..89324e42a033 100644 --- a/drivers/video/fbdev/amba-clcd.c +++ b/drivers/video/fbdev/amba-clcd.c @@ -30,9 +30,6 @@ #include