summaryrefslogtreecommitdiff
path: root/drivers/video/fbdev
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2019-09-16 15:52:38 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2019-09-16 15:52:38 -0700
commit399eb9b6cbf31ff6ef91a6930e2e94c703d74078 (patch)
tree60c26e51c167efdfec5ab5821111df9ea90cbf7f /drivers/video/fbdev
parent2b97c39514a6130f38b14227a36d9cd37e650a9d (diff)
parent3dc8dcb02fdba3370aec0696727e6adfe8033aa4 (diff)
Merge tag 'armsoc-drivers' of git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc
Pull ARM SoC driver updates from Arnd Bergmann: "This contains driver changes that are tightly connected to SoC specific code. Aside from smaller cleanups and bug fixes, here is a list of the notable changes. New device drivers: - The Turris Mox router has a new "moxtet" bus driver for its on-board pluggable extension bus. The same platform also gains a firmware driver. - The Samsung Exynos family gains a new Chipid driver exporting using the soc device sysfs interface - A similar socinfo driver for Qualcomm Snapdragon chips. - A firmware driver for the NXP i.MX DSP IPC protocol using shared memory and a mailbox Other changes: - The i.MX reset controller driver now supports the NXP i.MX8MM chip - Amlogic SoC specific drivers gain support for the S905X3 and A311D chips - A rework of the TI Davinci framebuffer driver to allow important cleanups in the platform code - A couple of device drivers for removed ARM SoC platforms are removed. Most of the removals were picked up by other maintainers, this contains whatever was left" * tag 'armsoc-drivers' of git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc: (123 commits) bus: uniphier-system-bus: use devm_platform_ioremap_resource() soc: ti: ti_sci_pm_domains: Add support for exclusive and shared access dt-bindings: ti_sci_pm_domains: Add support for exclusive and shared access firmware: ti_sci: Allow for device shared and exclusive requests bus: imx-weim: remove incorrect __init annotations fbdev: remove w90x900/nuc900 platform drivers spi: remove w90x900 driver net: remove w90p910-ether driver net: remove ks8695 driver firmware: turris-mox-rwtm: Add sysfs documentation firmware: Add Turris Mox rWTM firmware driver dt-bindings: firmware: Document cznic,turris-mox-rwtm binding bus: moxtet: fix unsigned comparison to less than zero bus: moxtet: remove set but not used variable 'dummy' ARM: scoop: Use the right include dt-bindings: power: add Amlogic Everything-Else power domains bindings soc: amlogic: Add support for Everything-Else power domains controller fbdev: da8xx: use resource management for dma fbdev: da8xx-fb: drop a redundant if fbdev: da8xx-fb: use devm_platform_ioremap_resource() ...
Diffstat (limited to 'drivers/video/fbdev')
-rw-r--r--drivers/video/fbdev/Kconfig14
-rw-r--r--drivers/video/fbdev/Makefile1
-rw-r--r--drivers/video/fbdev/da8xx-fb.c118
-rw-r--r--drivers/video/fbdev/nuc900fb.c760
-rw-r--r--drivers/video/fbdev/nuc900fb.h51
5 files changed, 65 insertions, 879 deletions
diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig
index 6b2de93bd302..5f83cd715387 100644
--- a/drivers/video/fbdev/Kconfig
+++ b/drivers/video/fbdev/Kconfig
@@ -1924,20 +1924,6 @@ config FB_S3C2410_DEBUG
Turn on debugging messages. Note that you can set/unset at run time
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
-
-config GPM1040A0_320X240
- bool "Giantplus Technology GPM1040A0 320x240 Color TFT LCD"
- depends on FB_NUC900
-
config FB_SM501
tristate "Silicon Motion SM501 framebuffer support"
depends on FB && MFD_SM501
diff --git a/drivers/video/fbdev/Makefile b/drivers/video/fbdev/Makefile
index 7dc4861a93e6..aab7155884ea 100644
--- a/drivers/video/fbdev/Makefile
+++ b/drivers/video/fbdev/Makefile
@@ -116,7 +116,6 @@ obj-y += omap2/
obj-$(CONFIG_XEN_FBDEV_FRONTEND) += xen-fbfront.o
obj-$(CONFIG_FB_CARMINE) += carminefb.o
obj-$(CONFIG_FB_MB862XX) += mb862xx/
-obj-$(CONFIG_FB_NUC900) += nuc900fb.o
obj-$(CONFIG_FB_JZ4740) += jz4740_fb.o
obj-$(CONFIG_FB_PUV3_UNIGFX) += fb-puv3.o
obj-$(CONFIG_FB_HYPERV) += hyperv_fb.o
diff --git a/drivers/video/fbdev/da8xx-fb.c b/drivers/video/fbdev/da8xx-fb.c
index b1cf248f3291..2d3dcc52fcf3 100644
--- a/drivers/video/fbdev/da8xx-fb.c
+++ b/drivers/video/fbdev/da8xx-fb.c
@@ -19,6 +19,7 @@
#include <linux/clk.h>
#include <linux/cpufreq.h>
#include <linux/console.h>
+#include <linux/regulator/consumer.h>
#include <linux/spinlock.h>
#include <linux/slab.h>
#include <linux/delay.h>
@@ -164,7 +165,7 @@ struct da8xx_fb_par {
struct notifier_block freq_transition;
#endif
unsigned int lcdc_clk_rate;
- void (*panel_power_ctrl)(int);
+ struct regulator *lcd_supply;
u32 pseudo_palette[16];
struct fb_videomode mode;
struct lcd_ctrl_config cfg;
@@ -1066,33 +1067,30 @@ static void lcd_da8xx_cpufreq_deregister(struct da8xx_fb_par *par)
static int fb_remove(struct platform_device *dev)
{
struct fb_info *info = dev_get_drvdata(&dev->dev);
-
- if (info) {
- struct da8xx_fb_par *par = info->par;
+ struct da8xx_fb_par *par = info->par;
+ int ret;
#ifdef CONFIG_CPU_FREQ
- lcd_da8xx_cpufreq_deregister(par);
+ lcd_da8xx_cpufreq_deregister(par);
#endif
- if (par->panel_power_ctrl)
- par->panel_power_ctrl(0);
+ if (par->lcd_supply) {
+ ret = regulator_disable(par->lcd_supply);
+ if (ret)
+ return ret;
+ }
- lcd_disable_raster(DA8XX_FRAME_WAIT);
- lcdc_write(0, LCD_RASTER_CTRL_REG);
+ lcd_disable_raster(DA8XX_FRAME_WAIT);
+ lcdc_write(0, LCD_RASTER_CTRL_REG);
- /* disable DMA */
- lcdc_write(0, LCD_DMA_CTRL_REG);
+ /* disable DMA */
+ lcdc_write(0, LCD_DMA_CTRL_REG);
- unregister_framebuffer(info);
- fb_dealloc_cmap(&info->cmap);
- dma_free_coherent(par->dev, PALETTE_SIZE, par->v_palette_base,
- par->p_palette_base);
- dma_free_coherent(par->dev, par->vram_size, par->vram_virt,
- par->vram_phys);
- pm_runtime_put_sync(&dev->dev);
- pm_runtime_disable(&dev->dev);
- framebuffer_release(info);
+ unregister_framebuffer(info);
+ fb_dealloc_cmap(&info->cmap);
+ pm_runtime_put_sync(&dev->dev);
+ pm_runtime_disable(&dev->dev);
+ framebuffer_release(info);
- }
return 0;
}
@@ -1179,15 +1177,21 @@ static int cfb_blank(int blank, struct fb_info *info)
case FB_BLANK_UNBLANK:
lcd_enable_raster();
- if (par->panel_power_ctrl)
- par->panel_power_ctrl(1);
+ if (par->lcd_supply) {
+ ret = regulator_enable(par->lcd_supply);
+ if (ret)
+ return ret;
+ }
break;
case FB_BLANK_NORMAL:
case FB_BLANK_VSYNC_SUSPEND:
case FB_BLANK_HSYNC_SUSPEND:
case FB_BLANK_POWERDOWN:
- if (par->panel_power_ctrl)
- par->panel_power_ctrl(0);
+ if (par->lcd_supply) {
+ ret = regulator_disable(par->lcd_supply);
+ if (ret)
+ return ret;
+ }
lcd_disable_raster(DA8XX_FRAME_WAIT);
break;
@@ -1328,7 +1332,6 @@ static int fb_probe(struct platform_device *device)
{
struct da8xx_lcdc_platform_data *fb_pdata =
dev_get_platdata(&device->dev);
- struct resource *lcdc_regs;
struct lcd_ctrl_config *lcd_cfg;
struct fb_videomode *lcdc_info;
struct fb_info *da8xx_fb_info;
@@ -1346,8 +1349,7 @@ static int fb_probe(struct platform_device *device)
if (lcdc_info == NULL)
return -ENODEV;
- lcdc_regs = platform_get_resource(device, IORESOURCE_MEM, 0);
- da8xx_fb_reg_base = devm_ioremap_resource(&device->dev, lcdc_regs);
+ da8xx_fb_reg_base = devm_platform_ioremap_resource(device, 0);
if (IS_ERR(da8xx_fb_reg_base))
return PTR_ERR(da8xx_fb_reg_base);
@@ -1395,9 +1397,19 @@ static int fb_probe(struct platform_device *device)
par->dev = &device->dev;
par->lcdc_clk = tmp_lcdc_clk;
par->lcdc_clk_rate = clk_get_rate(par->lcdc_clk);
- if (fb_pdata->panel_power_ctrl) {
- par->panel_power_ctrl = fb_pdata->panel_power_ctrl;
- par->panel_power_ctrl(1);
+
+ par->lcd_supply = devm_regulator_get_optional(&device->dev, "lcd");
+ if (IS_ERR(par->lcd_supply)) {
+ if (PTR_ERR(par->lcd_supply) == -EPROBE_DEFER) {
+ ret = -EPROBE_DEFER;
+ goto err_pm_runtime_disable;
+ }
+
+ par->lcd_supply = NULL;
+ } else {
+ ret = regulator_enable(par->lcd_supply);
+ if (ret)
+ goto err_pm_runtime_disable;
}
fb_videomode_to_var(&da8xx_fb_var, lcdc_info);
@@ -1411,10 +1423,10 @@ static int fb_probe(struct platform_device *device)
par->vram_size = roundup(par->vram_size/8, ulcm);
par->vram_size = par->vram_size * LCD_NUM_BUFFERS;
- par->vram_virt = dma_alloc_coherent(par->dev,
- par->vram_size,
- &par->vram_phys,
- GFP_KERNEL | GFP_DMA);
+ par->vram_virt = dmam_alloc_coherent(par->dev,
+ par->vram_size,
+ &par->vram_phys,
+ GFP_KERNEL | GFP_DMA);
if (!par->vram_virt) {
dev_err(&device->dev,
"GLCD: kmalloc for frame buffer failed\n");
@@ -1432,20 +1444,20 @@ static int fb_probe(struct platform_device *device)
da8xx_fb_fix.line_length - 1;
/* allocate palette buffer */
- par->v_palette_base = dma_alloc_coherent(par->dev, PALETTE_SIZE,
- &par->p_palette_base,
- GFP_KERNEL | GFP_DMA);
+ par->v_palette_base = dmam_alloc_coherent(par->dev, PALETTE_SIZE,
+ &par->p_palette_base,
+ GFP_KERNEL | GFP_DMA);
if (!par->v_palette_base) {
dev_err(&device->dev,
"GLCD: kmalloc for palette buffer failed\n");
ret = -EINVAL;
- goto err_release_fb_mem;
+ goto err_release_fb;
}
par->irq = platform_get_irq(device, 0);
if (par->irq < 0) {
ret = -ENOENT;
- goto err_release_pl_mem;
+ goto err_release_fb;
}
da8xx_fb_var.grayscale =
@@ -1463,7 +1475,7 @@ static int fb_probe(struct platform_device *device)
ret = fb_alloc_cmap(&da8xx_fb_info->cmap, PALETTE_SIZE, 0);
if (ret)
- goto err_release_pl_mem;
+ goto err_release_fb;
da8xx_fb_info->cmap.len = par->palette_sz;
/* initialize var_screeninfo */
@@ -1517,14 +1529,6 @@ err_cpu_freq:
err_dealloc_cmap:
fb_dealloc_cmap(&da8xx_fb_info->cmap);
-err_release_pl_mem:
- dma_free_coherent(par->dev, PALETTE_SIZE, par->v_palette_base,
- par->p_palette_base);
-
-err_release_fb_mem:
- dma_free_coherent(par->dev, par->vram_size, par->vram_virt,
- par->vram_phys);
-
err_release_fb:
framebuffer_release(da8xx_fb_info);
@@ -1603,10 +1607,14 @@ static int fb_suspend(struct device *dev)
{
struct fb_info *info = dev_get_drvdata(dev);
struct da8xx_fb_par *par = info->par;
+ int ret;
console_lock();
- if (par->panel_power_ctrl)
- par->panel_power_ctrl(0);
+ if (par->lcd_supply) {
+ ret = regulator_disable(par->lcd_supply);
+ if (ret)
+ return ret;
+ }
fb_set_suspend(info, 1);
lcd_disable_raster(DA8XX_FRAME_WAIT);
@@ -1620,6 +1628,7 @@ static int fb_resume(struct device *dev)
{
struct fb_info *info = dev_get_drvdata(dev);
struct da8xx_fb_par *par = info->par;
+ int ret;
console_lock();
pm_runtime_get_sync(dev);
@@ -1627,8 +1636,11 @@ static int fb_resume(struct device *dev)
if (par->blank == FB_BLANK_UNBLANK) {
lcd_enable_raster();
- if (par->panel_power_ctrl)
- par->panel_power_ctrl(1);
+ if (par->lcd_supply) {
+ ret = regulator_enable(par->lcd_supply);
+ if (ret)
+ return ret;
+ }
}
fb_set_suspend(info, 0);
diff --git a/drivers/video/fbdev/nuc900fb.c b/drivers/video/fbdev/nuc900fb.c
deleted file mode 100644
index 4fd851598584..000000000000
--- a/drivers/video/fbdev/nuc900fb.c
+++ /dev/null
@@ -1,760 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- *
- * Copyright (c) 2009 Nuvoton technology corporation
- * All rights reserved.
- *
- * Description:
- * Nuvoton LCD Controller Driver
- * Author:
- * Wang Qiang (rurality.linux@gmail.com) 2009/12/11
- */
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/err.h>
-#include <linux/errno.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/tty.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include <linux/fb.h>
-#include <linux/init.h>
-#include <linux/dma-mapping.h>
-#include <linux/interrupt.h>
-#include <linux/workqueue.h>
-#include <linux/wait.h>
-#include <linux/platform_device.h>
-#include <linux/clk.h>
-#include <linux/cpufreq.h>
-#include <linux/io.h>
-#include <linux/pm.h>
-#include <linux/device.h>
-
-#include <mach/map.h>
-#include <mach/regs-clock.h>
-#include <mach/regs-ldm.h>
-#include <linux/platform_data/video-nuc900fb.h>
-
-#include "nuc900fb.h"
-
-
-/*
- * Initialize the nuc900 video (dual) buffer address
- */
-static void nuc900fb_set_lcdaddr(struct fb_info *info)
-{
- struct nuc900fb_info *fbi = info->par;
- void __iomem *regs = fbi->io;
- unsigned long vbaddr1, vbaddr2;
-
- vbaddr1 = info->fix.smem_start;
- vbaddr2 = info->fix.smem_start;
- vbaddr2 += info->fix.line_length * info->var.yres;
-
- /* set frambuffer start phy addr*/
- writel(vbaddr1, regs + REG_LCM_VA_BADDR0);
- writel(vbaddr2, regs + REG_LCM_VA_BADDR1);
-
- writel(fbi->regs.lcd_va_fbctrl, regs + REG_LCM_VA_FBCTRL);
- writel(fbi->regs.lcd_va_scale, regs + REG_LCM_VA_SCALE);
-}
-
-/*
- * calculate divider for lcd div
- */
-static unsigned int nuc900fb_calc_pixclk(struct nuc900fb_info *fbi,
- unsigned long pixclk)
-{
- unsigned long clk = fbi->clk_rate;
- unsigned long long div;
-
- /* pixclk is in picseconds. our clock is in Hz*/
- /* div = (clk * pixclk)/10^12 */
- div = (unsigned long long)clk * pixclk;
- div >>= 12;
- do_div(div, 625 * 625UL * 625);
-
- dev_dbg(fbi->dev, "pixclk %ld, divisor is %lld\n", pixclk, div);
-
- return div;
-}
-
-/*
- * Check the video params of 'var'.
- */
-static int nuc900fb_check_var(struct fb_var_screeninfo *var,
- struct fb_info *info)
-{
- struct nuc900fb_info *fbi = info->par;
- struct nuc900fb_mach_info *mach_info = dev_get_platdata(fbi->dev);
- struct nuc900fb_display *display = NULL;
- struct nuc900fb_display *default_display = mach_info->displays +
- mach_info->default_display;
- int i;
-
- dev_dbg(fbi->dev, "check_var(var=%p, info=%p)\n", var, info);
-
- /* validate x/y resolution */
- /* choose default mode if possible */
- if (var->xres == default_display->xres &&
- var->yres == default_display->yres &&
- var->bits_per_pixel == default_display->bpp)
- display = default_display;
- else
- for (i = 0; i < mach_info->num_displays; i++)
- if (var->xres == mach_info->displays[i].xres &&
- var->yres == mach_info->displays[i].yres &&
- var->bits_per_pixel == mach_info->displays[i].bpp) {
- display = mach_info->displays + i;
- break;
- }
-
- if (display == NULL) {
- printk(KERN_ERR "wrong resolution or depth %dx%d at %d bit per pixel\n",
- var->xres, var->yres, var->bits_per_pixel);
- return -EINVAL;
- }
-
- /* it should be the same size as the display */
- var->xres_virtual = display->xres;
- var->yres_virtual = display->yres;
- var->height = display->height;
- var->width = display->width;
-
- /* copy lcd settings */
- var->pixclock = display->pixclock;
- var->left_margin = display->left_margin;
- var->right_margin = display->right_margin;
- var->upper_margin = display->upper_margin;
- var->lower_margin = display->lower_margin;
- var->vsync_len = display->vsync_len;
- var->hsync_len = display->hsync_len;
-
- var->transp.offset = 0;
- var->transp.length = 0;
-
- fbi->regs.lcd_dccs = display->dccs;
- fbi->regs.lcd_device_ctrl = display->devctl;
- fbi->regs.lcd_va_fbctrl = display->fbctrl;
- fbi->regs.lcd_va_scale = display->scale;
-
- /* set R/G/B possions */
- switch (var->bits_per_pixel) {
- case 1:
- case 2:
- case 4:
- case 8:
- default:
- var->red.offset = 0;
- var->red.length = var->bits_per_pixel;
- var->green = var->red;
- var->blue = var->red;
- break;
- case 12:
- var->red.length = 4;
- var->green.length = 4;
- var->blue.length = 4;
- var->red.offset = 8;
- var->green.offset = 4;
- var->blue.offset = 0;
- break;
- case 16:
- var->red.length = 5;
- var->green.length = 6;
- var->blue.length = 5;
- var->red.offset = 11;
- var->green.offset = 5;
- var->blue.offset = 0;
- break;
- case 18:
- var->red.length = 6;
- var->green.length = 6;
- var->blue.length = 6;
- var->red.offset = 12;
- var->green.offset = 6;
- var->blue.offset = 0;
- break;
- case 32:
- var->red.length = 8;
- var->green.length = 8;
- var->blue.length = 8;
- var->red.offset = 16;
- var->green.offset = 8;
- var->blue.offset = 0;
- break;
- }
-
- return 0;
-}
-
-/*
- * Calculate lcd register values from var setting & save into hw
- */
-static void nuc900fb_calculate_lcd_regs(const struct fb_info *info,
- struct nuc900fb_hw *regs)
-{
- const struct fb_var_screeninfo *var = &info->var;
- int vtt = var->height + var->upper_margin + var->lower_margin;
- int htt = var->width + var->left_margin + var->right_margin;
- int hsync = var->width + var->right_margin;
- int vsync = var->height + var->lower_margin;
-
- regs->lcd_crtc_size = LCM_CRTC_SIZE_VTTVAL(vtt) |
- LCM_CRTC_SIZE_HTTVAL(htt);
- regs->lcd_crtc_dend = LCM_CRTC_DEND_VDENDVAL(var->height) |
- LCM_CRTC_DEND_HDENDVAL(var->width);
- regs->lcd_crtc_hr = LCM_CRTC_HR_EVAL(var->width + 5) |
- LCM_CRTC_HR_SVAL(var->width + 1);
- regs->lcd_crtc_hsync = LCM_CRTC_HSYNC_EVAL(hsync + var->hsync_len) |
- LCM_CRTC_HSYNC_SVAL(hsync);
- regs->lcd_crtc_vr = LCM_CRTC_VR_EVAL(vsync + var->vsync_len) |
- LCM_CRTC_VR_SVAL(vsync);
-
-}
-
-/*
- * Activate (set) the controller from the given framebuffer
- * information
- */
-static void nuc900fb_activate_var(struct fb_info *info)
-{
- struct nuc900fb_info *fbi = info->par;
- void __iomem *regs = fbi->io;
- struct fb_var_screeninfo *var = &info->var;
- int clkdiv;
-
- clkdiv = nuc900fb_calc_pixclk(fbi, var->pixclock) - 1;
- if (clkdiv < 0)
- clkdiv = 0;
-
- nuc900fb_calculate_lcd_regs(info, &fbi->regs);
-
- /* set the new lcd registers*/
-
- dev_dbg(fbi->dev, "new lcd register set:\n");
- dev_dbg(fbi->dev, "dccs = 0x%08x\n", fbi->regs.lcd_dccs);
- dev_dbg(fbi->dev, "dev_ctl = 0x%08x\n", fbi->regs.lcd_device_ctrl);
- dev_dbg(fbi->dev, "crtc_size = 0x%08x\n", fbi->regs.lcd_crtc_size);
- dev_dbg(fbi->dev, "crtc_dend = 0x%08x\n", fbi->regs.lcd_crtc_dend);
- dev_dbg(fbi->dev, "crtc_hr = 0x%08x\n", fbi->regs.lcd_crtc_hr);
- dev_dbg(fbi->dev, "crtc_hsync = 0x%08x\n", fbi->regs.lcd_crtc_hsync);
- dev_dbg(fbi->dev, "crtc_vr = 0x%08x\n", fbi->regs.lcd_crtc_vr);
-
- writel(fbi->regs.lcd_device_ctrl, regs + REG_LCM_DEV_CTRL);
- writel(fbi->regs.lcd_crtc_size, regs + REG_LCM_CRTC_SIZE);
- writel(fbi->regs.lcd_crtc_dend, regs + REG_LCM_CRTC_DEND);
- writel(fbi->regs.lcd_crtc_hr, regs + REG_LCM_CRTC_HR);
- writel(fbi->regs.lcd_crtc_hsync, regs + REG_LCM_CRTC_HSYNC);
- writel(fbi->regs.lcd_crtc_vr, regs + REG_LCM_CRTC_VR);
-
- /* set lcd address pointers */
- nuc900fb_set_lcdaddr(info);
-
- writel(fbi->regs.lcd_dccs, regs + REG_LCM_DCCS);
-}
-
-/*
- * Alters the hardware state.
- *
- */
-static int nuc900fb_set_par(struct fb_info *info)
-{
- struct fb_var_screeninfo *var = &info->var;
-
- switch (var->bits_per_pixel) {
- case 32:
- case 24:
- case 18:
- case 16:
- case 12:
- info->fix.visual = FB_VISUAL_TRUECOLOR;
- break;
- case 1:
- info->fix.visual = FB_VISUAL_MONO01;
- break;
- default:
- info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
- break;
- }
-
- info->fix.line_length = (var->xres_virtual * var->bits_per_pixel) / 8;
-
- /* activate this new configuration */
- nuc900fb_activate_var(info);
- return 0;
-}
-
-static inline unsigned int chan_to_field(unsigned int chan,
- struct fb_bitfield *bf)
-{
- chan &= 0xffff;
- chan >>= 16 - bf->length;
- return chan << bf->offset;
-}
-
-static int nuc900fb_setcolreg(unsigned regno,
- unsigned red, unsigned green, unsigned blue,
- unsigned transp, struct fb_info *info)
-{
- unsigned int val;
-
- switch (info->fix.visual) {
- case FB_VISUAL_TRUECOLOR:
- /* true-colour, use pseuo-palette */
- if (regno < 16) {
- u32 *pal = info->pseudo_palette;
-
- val = chan_to_field(red, &info->var.red);
- val |= chan_to_field(green, &info->var.green);
- val |= chan_to_field(blue, &info->var.blue);
- pal[regno] = val;
- }
- break;
-
- default:
- return 1; /* unknown type */
- }
- return 0;
-}
-
-/**
- * nuc900fb_blank
- *
- */
-static int nuc900fb_blank(int blank_mode, struct fb_info *info)
-{
-
- return 0;
-}
-
-static struct fb_ops nuc900fb_ops = {
- .owner = THIS_MODULE,
- .fb_check_var = nuc900fb_check_var,
- .fb_set_par = nuc900fb_set_par,
- .fb_blank = nuc900fb_blank,
- .fb_setcolreg = nuc900fb_setcolreg,
- .fb_fillrect = cfb_fillrect,
- .fb_copyarea = cfb_copyarea,
- .fb_imageblit = cfb_imageblit,
-};
-
-
-static inline void modify_gpio(void __iomem *reg,
- unsigned long set, unsigned long mask)
-{
- unsigned long tmp;
- tmp = readl(reg) & ~mask;
- writel(tmp | set, reg);
-}
-
-/*
- * Initialise LCD-related registers
- */
-static int nuc900fb_init_registers(struct fb_info *info)
-{
- struct nuc900fb_info *fbi = info->par;
- struct nuc900fb_mach_info *mach_info = dev_get_platdata(fbi->dev);
- void __iomem *regs = fbi->io;
-
- /*reset the display engine*/
- writel(0, regs + REG_LCM_DCCS);
- writel(readl(regs + REG_LCM_DCCS) | LCM_DCCS_ENG_RST,
- regs + REG_LCM_DCCS);
- ndelay(100);
- writel(readl(regs + REG_LCM_DCCS) & (~LCM_DCCS_ENG_RST),
- regs + REG_LCM_DCCS);
- ndelay(100);
-
- writel(0, regs + REG_LCM_DEV_CTRL);
-
- /* config gpio output */
- modify_gpio(W90X900_VA_GPIO + 0x54, mach_info->gpio_dir,
- mach_info->gpio_dir_mask);
- modify_gpio(W90X900_VA_GPIO + 0x58, mach_info->gpio_data,
- mach_info->gpio_data_mask);
-
- return 0;
-}
-
-
-/*
- * Alloc the SDRAM region of NUC900 for the frame buffer.
- * The buffer should be a non-cached, non-buffered, memory region
- * to allow palette and pixel writes without flushing the cache.
- */
-static int nuc900fb_map_video_memory(struct fb_info *info)
-{
- struct nuc900fb_info *fbi = info->par;
- dma_addr_t map_dma;
- unsigned long map_size = PAGE_ALIGN(info->fix.smem_len);
-
- dev_dbg(fbi->dev, "nuc900fb_map_video_memory(fbi=%p) map_size %lu\n",
- fbi, map_size);
-
- info->screen_base = dma_alloc_wc(fbi->dev, map_size, &map_dma,
- GFP_KERNEL);
-
- if (!info->screen_base)
- return -ENOMEM;
-
- memset(info->screen_base, 0x00, map_size);
- info->fix.smem_start = map_dma;
-
- return 0;
-}
-
-static inline void nuc900fb_unmap_video_memory(struct fb_info *info)
-{
- struct nuc900fb_info *fbi = info->par;
- dma_free_wc(fbi->dev, PAGE_ALIGN(info->fix.smem_len),
- info->screen_base, info->fix.smem_start);
-}
-
-static irqreturn_t nuc900fb_irqhandler(int irq, void *dev_id)
-{
- struct nuc900fb_info *fbi = dev_id;
- void __iomem *regs = fbi->io;
- void __iomem *irq_base = fbi->irq_base;
- unsigned long lcdirq = readl(regs + REG_LCM_INT_CS);
-
- if (lcdirq & LCM_INT_CS_DISP_F_STATUS) {
- writel(readl(irq_base) | 1<<30, irq_base);
-
- /* wait VA_EN low */
- if ((readl(regs + REG_LCM_DCCS) &
- LCM_DCCS_SINGLE) == LCM_DCCS_SINGLE)
- while ((readl(regs + REG_LCM_DCCS) &
- LCM_DCCS_VA_EN) == LCM_DCCS_VA_EN)
- ;
- /* display_out-enable */
- writel(readl(regs + REG_LCM_DCCS) | LCM_DCCS_DISP_OUT_EN,
- regs + REG_LCM_DCCS);
- /* va-enable*/
- writel(readl(regs + REG_LCM_DCCS) | LCM_DCCS_VA_EN,
- regs + REG_LCM_DCCS);
- } else if (lcdirq & LCM_INT_CS_UNDERRUN_INT) {
- writel(readl(irq_base) | LCM_INT_CS_UNDERRUN_INT, irq_base);
- } else if (lcdirq & LCM_INT_CS_BUS_ERROR_INT) {
- writel(readl(irq_base) | LCM_INT_CS_BUS_ERROR_INT, irq_base);
- }
-
- return IRQ_HANDLED;
-}
-
-#ifdef CONFIG_CPU_FREQ
-
-static int nuc900fb_cpufreq_transition(struct notifier_block *nb,
- unsigned long val, void *data)
-{
- struct nuc900fb_info *info;
- struct fb_info *fbinfo;
- long delta_f;
- info = container_of(nb, struct nuc900fb_info, freq_transition);
- fbinfo = dev_get_drvdata(info->dev);
-
- delta_f = info->clk_rate - clk_get_rate(info->clk);
-
- if ((val == CPUFREQ_POSTCHANGE && delta_f > 0) ||
- (val == CPUFREQ_PRECHANGE && delta_f < 0)) {
- info->clk_rate = clk_get_rate(info->clk);
- nuc900fb_activate_var(fbinfo);
- }
-
- return 0;
-}
-
-static inline int nuc900fb_cpufreq_register(struct nuc900fb_info *fbi)
-{
- fbi->freq_transition.notifier_call = nuc900fb_cpufreq_transition;
- return cpufreq_register_notifier(&fbi->freq_transition,
- CPUFREQ_TRANSITION_NOTIFIER);
-}
-
-static inline void nuc900fb_cpufreq_deregister(struct nuc900fb_info *fbi)
-{
- cpufreq_unregister_notifier(&fbi->freq_transition,
- CPUFREQ_TRANSITION_NOTIFIER);
-}
-#else
-static inline int nuc900fb_cpufreq_transition(struct notifier_block *nb,
- unsigned long val, void *data)
-{
- return 0;
-}
-
-static inline int nuc900fb_cpufreq_register(struct nuc900fb_info *fbi)
-{
- return 0;
-}
-
-static inline void nuc900fb_cpufreq_deregister(struct nuc900fb_info *info)
-{
-}
-#endif
-
-static char driver_name[] = "nuc900fb";
-
-static int nuc900fb_probe(struct platform_device *pdev)
-{
- struct nuc900fb_info *fbi;
- struct nuc900fb_display *display;
- struct fb_info *fbinfo;
- struct nuc900fb_mach_info *mach_info;
- struct resource *res;
- int ret;
- int irq;
- int i;
- int size;
-
- dev_dbg(&pdev->dev, "devinit\n");
- mach_info = dev_get_platdata(&pdev->dev);
- if (mach_info == NULL) {
- dev_err(&pdev->dev,
- "no platform data for lcd, cannot attach\n");
- return -EINVAL;
- }
-
- if (mach_info->default_display > mach_info->num_displays) {
- dev_err(&pdev->dev,
- "default display No. is %d but only %d displays \n",
- mach_info->default_display, mach_info->num_displays);
- return -EINVAL;
- }
-
-
- display = mach_info->displays + mach_info->default_display;
-
- irq = platform_get_irq(pdev, 0);
- if (irq < 0) {
- dev_err(&pdev->dev, "no irq for device\n");
- return -ENOENT;
- }
-
- fbinfo = framebuffer_alloc(sizeof(struct nuc900fb_info), &pdev->dev);
- if (!fbinfo)
- return -ENOMEM;
-
- platform_set_drvdata(pdev, fbinfo);
-
- fbi = fbinfo->par;
- fbi->dev = &pdev->dev;
-
-#ifdef CONFIG_CPU_NUC950
- fbi->drv_type = LCDDRV_NUC950;
-#endif
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-
- size = resource_size(res);
- fbi->mem = request_mem_region(res->start, size, pdev->name);
- if (fbi->mem == NULL) {
- dev_err(&pdev->dev, "failed to alloc memory region\n");
- ret = -ENOENT;
- goto free_fb;
- }
-
- fbi->io = ioremap(res->start, size);
- if (fbi->io == NULL) {
- dev_err(&pdev->dev, "ioremap() of lcd registers failed\n");
- ret = -ENXIO;
- goto release_mem_region;
- }
-
- fbi->irq_base = fbi->io + REG_LCM_INT_CS;
-
-
- /* Stop the LCD */
- writel(0, fbi->io + REG_LCM_DCCS);
-
- /* fill the fbinfo*/
- strcpy(fbinfo->fix.id, driver_name);
- fbinfo->fix.type = FB_TYPE_PACKED_PIXELS;
- fbinfo->fix.type_aux = 0;
- fbinfo->fix.xpanstep = 0;
- fbinfo->fix.ypanstep = 0;
- fbinfo->fix.ywrapstep = 0;
- fbinfo->fix.accel = FB_ACCEL_NONE;
- fbinfo->var.nonstd = 0;
- fbinfo->var.activate = FB_ACTIVATE_NOW;
- fbinfo->var.accel_flags = 0;
- fbinfo->var.vmode = FB_VMODE_NONINTERLACED;
- fbinfo->fbops = &nuc900fb_ops;
- fbinfo->flags = FBINFO_FLAG_DEFAULT;
- fbinfo->pseudo_palette = &fbi->pseudo_pal;
-
- ret = request_irq(irq, nuc900fb_irqhandler, 0, pdev->name, fbi);
- if (ret) {
- dev_err(&pdev->dev, "cannot register irq handler %d -err %d\n",
- irq, ret);
- ret = -EBUSY;
- goto release_regs;
- }
-
- fbi->clk = clk_get(&pdev->dev, NULL);
- if (IS_ERR(fbi->clk)) {
- printk(KERN_ERR "nuc900-lcd:failed to get lcd clock source\n");
- ret = PTR_ERR(fbi->clk);
- goto release_irq;
- }
-
- clk_enable(fbi->clk);
- dev_dbg(&pdev->dev, "got and enabled clock\n");
-
- fbi->clk_rate = clk_get_rate(fbi->clk);
-
- /* calutate the video buffer size */
- for (i = 0; i < mach_info->num_displays; i++) {
- unsigned long smem_len = mach_info->displays[i].xres;
- smem_len *= mach_info->displays[i].yres;
- smem_len *= mach_info->displays[i].bpp;
- smem_len >>= 3;
- if (fbinfo->fix.smem_len < smem_len)
- fbinfo->fix.smem_len = smem_len;
- }
-
- /* Initialize Video Memory */
- ret = nuc900fb_map_video_memory(fbinfo);
- if (ret) {
- printk(KERN_ERR "Failed to allocate video RAM: %x\n", ret);
- goto release_clock;
- }
-
- dev_dbg(&pdev->dev, "got video memory\n");
-
- fbinfo->var.xres = display->xres;
- fbinfo->var.yres = display->yres;
- fbinfo->var.bits_per_pixel = display->bpp;
-
- nuc900fb_init_registers(fbinfo);
-
- nuc900fb_check_var(&fbinfo->var, fbinfo);
-
- ret = nuc900fb_cpufreq_register(fbi);
- if (ret < 0) {
- dev_err(&pdev->dev, "Failed to register cpufreq\n");
- goto free_video_memory;
- }
-
- ret = register_framebuffer(fbinfo);
- if (ret) {
- printk(KERN_ERR "failed to register framebuffer device: %d\n",
- ret);
- goto free_cpufreq;
- }
-
- fb_info(fbinfo, "%s frame buffer device\n", fbinfo->fix.id);
-
- return 0;
-
-free_cpufreq:
- nuc900fb_cpufreq_deregister(fbi);
-free_video_memory:
- nuc900fb_unmap_video_memory(fbinfo);
-release_clock:
- clk_disable(fbi->clk);
- clk_put(fbi->clk);
-release_irq:
- free_irq(irq, fbi);
-release_regs:
- iounmap(fbi->io);
-release_mem_region:
- release_mem_region(res->start, size);
-free_fb:
- framebuffer_release(fbinfo);
- return ret;
-}
-
-/*
- * shutdown the lcd controller
- */
-static void nuc900fb_stop_lcd(struct fb_info *info)
-{
- struct nuc900fb_info *fbi = info->par;
- void __iomem *regs = fbi->io;
-
- writel((~LCM_DCCS_DISP_INT_EN) | (~LCM_DCCS_VA_EN) | (~LCM_DCCS_OSD_EN),
- regs + REG_LCM_DCCS);
-}
-
-/*
- * Cleanup
- */
-static int nuc900fb_remove(struct platform_device *pdev)
-{
- struct fb_info *fbinfo = platform_get_drvdata(pdev);
- struct nuc900fb_info *fbi = fbinfo->par;
- int irq;
-
- nuc900fb_stop_lcd(fbinfo);
- msleep(1);
-
- unregister_framebuffer(fbinfo);
- nuc900fb_cpufreq_deregister(fbi);
- nuc900fb_unmap_video_memory(fbinfo);
-
- iounmap(fbi->io);
-
- irq = platform_get_irq(pdev, 0);
- free_irq(irq, fbi);
-
- release_resource(fbi->mem);
- kfree(fbi->mem);
-
- framebuffer_release(fbinfo);
-
- return 0;
-}
-
-#ifdef CONFIG_PM
-
-/*
- * suspend and resume support for the lcd controller
- */
-
-static int nuc900fb_suspend(struct platform_device *dev, pm_message_t state)
-{
- struct fb_info *fbinfo = platform_get_drvdata(dev);
- struct nuc900fb_info *info = fbinfo->par;
-
- nuc900fb_stop_lcd(fbinfo);
- msleep(1);
- clk_disable(info->clk);
- return 0;
-}
-
-static int nuc900fb_resume(struct platform_device *dev)
-{
- struct fb_info *fbinfo = platform_get_drvdata(dev);
- struct nuc900fb_info *fbi = fbinfo->par;
-
- printk(KERN_INFO "nuc900fb resume\n");
-
- clk_enable(fbi->clk);
- msleep(1);
-
- nuc900fb_init_registers(fbinfo);
- nuc900fb_activate_var(fbinfo);
-
- return 0;
-}
-
-#else
-#define nuc900fb_suspend NULL
-#define nuc900fb_resume NULL
-#endif
-
-static struct platform_driver nuc900fb_driver = {
- .probe = nuc900fb_probe,
- .remove = nuc900fb_remove,
- .suspend = nuc900fb_suspend,
- .resume = nuc900fb_resume,
- .driver = {
- .name = "nuc900-lcd",
- },
-};
-
-module_platform_driver(nuc900fb_driver);
-
-MODULE_DESCRIPTION("Framebuffer driver for the NUC900");
-MODULE_LICENSE("GPL");
diff --git a/drivers/video/fbdev/nuc900fb.h b/drivers/video/fbdev/nuc900fb.h
deleted file mode 100644
index 055ae9297931..000000000000
--- a/drivers/video/fbdev/nuc900fb.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- *
- * Copyright (c) 2009 Nuvoton technology corporation
- * All rights reserved.
- *
- * Author:
- * Wang Qiang(rurality.linux@gmail.com) 2009/12/16
- */
-
-#ifndef __NUC900FB_H
-#define __NUC900FB_H
-
-#include <mach/map.h>
-#include <linux/platform_data/video-nuc900fb.h>
-
-enum nuc900_lcddrv_type {
- LCDDRV_NUC910,
- LCDDRV_NUC930,
- LCDDRV_NUC932,
- LCDDRV_NUC950,
- LCDDRV_NUC960,
-};
-
-
-#define PALETTE_BUFFER_SIZE 256
-#define PALETTE_BUFF_CLEAR (0x80000000) /* entry is clear/invalid */
-
-struct nuc900fb_info {
- struct device *dev;
- struct clk *clk;
-
- struct resource *mem;
- void __iomem *io;
- void __iomem *irq_base;
- int drv_type;
- struct nuc900fb_hw regs;
- unsigned long clk_rate;
-
-#ifdef CONFIG_CPU_FREQ
- struct notifier_block freq_transition;
-#endif
-
- /* keep these registers in case we need to re-write palette */
- u32 palette_buffer[PALETTE_BUFFER_SIZE];
- u32 pseudo_pal[16];
-};
-
-int nuc900fb_init(void);
-
-#endif /* __NUC900FB_H */