diff options
Diffstat (limited to 'drivers/video')
55 files changed, 615 insertions, 1935 deletions
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 0217f7415ef5..67c695c0148f 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -2151,21 +2151,6 @@ config FB_UDL mplayer -vo fbdev. Supports all USB 2.0 era DisplayLink devices. To compile as a module, choose M here: the module name is udlfb. -config FB_PNX4008_DUM - tristate "Display Update Module support on Philips PNX4008 board" - depends on FB && ARCH_PNX4008 - ---help--- - Say Y here to enable support for PNX4008 Display Update Module (DUM) - -config FB_PNX4008_DUM_RGB - tristate "RGB Framebuffer support on Philips PNX4008 board" - depends on FB_PNX4008_DUM - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - ---help--- - Say Y here to enable support for PNX4008 RGB Framebuffer - config FB_IBM_GXT4500 tristate "Framebuffer support for IBM GXT4500P adaptor" depends on FB && PPC diff --git a/drivers/video/Makefile b/drivers/video/Makefile index ee8dafb69e36..4d5789931da1 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile @@ -128,8 +128,6 @@ obj-$(CONFIG_FB_S3C) += s3c-fb.o obj-$(CONFIG_FB_S3C2410) += s3c2410fb.o obj-$(CONFIG_FB_FSL_DIU) += fsl-diu-fb.o obj-$(CONFIG_FB_COBALT) += cobalt_lcdfb.o -obj-$(CONFIG_FB_PNX4008_DUM) += pnx4008/ -obj-$(CONFIG_FB_PNX4008_DUM_RGB) += pnx4008/ obj-$(CONFIG_FB_IBM_GXT4500) += gxt4500.o obj-$(CONFIG_FB_PS3) += ps3fb.o obj-$(CONFIG_FB_SM501) += sm501fb.o diff --git a/drivers/video/amifb.c b/drivers/video/amifb.c index 887df9d81422..7fa1bf823729 100644 --- a/drivers/video/amifb.c +++ b/drivers/video/amifb.c @@ -949,7 +949,6 @@ static int round_down_bpp = 1; /* for mode probing */ static int amifb_ilbm = 0; /* interleaved or normal bitplanes */ -static int amifb_inverse = 0; static u32 amifb_hfmin __initdata; /* monitor hfreq lower limit (Hz) */ static u32 amifb_hfmax __initdata; /* monitor hfreq upper limit (Hz) */ @@ -2355,7 +2354,6 @@ static int __init amifb_setup(char *options) if (!*this_opt) continue; if (!strcmp(this_opt, "inverse")) { - amifb_inverse = 1; fb_invert_cmaps(); } else if (!strcmp(this_opt, "ilbm")) amifb_ilbm = 1; diff --git a/drivers/video/arcfb.c b/drivers/video/arcfb.c index a1d58e9d3073..4659d5da6ff8 100644 --- a/drivers/video/arcfb.c +++ b/drivers/video/arcfb.c @@ -552,6 +552,7 @@ static int __devinit arcfb_probe(struct platform_device *dev) "arcfb", info)) { printk(KERN_INFO "arcfb: Failed req IRQ %d\n", par->irq); + retval = -EBUSY; goto err1; } } diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c index 15055395cd95..94cac9f9919f 100644 --- a/drivers/video/atmel_lcdfb.c +++ b/drivers/video/atmel_lcdfb.c @@ -931,8 +931,10 @@ static int __init atmel_lcdfb_probe(struct platform_device *pdev) } info->screen_base = ioremap(info->fix.smem_start, info->fix.smem_len); - if (!info->screen_base) + if (!info->screen_base) { + ret = -ENOMEM; goto release_intmem; + } /* * Don't clear the framebuffer -- someone may have set @@ -960,6 +962,7 @@ static int __init atmel_lcdfb_probe(struct platform_device *pdev) sinfo->mmio = ioremap(info->fix.mmio_start, info->fix.mmio_len); if (!sinfo->mmio) { dev_err(dev, "cannot map LCDC registers\n"); + ret = -ENOMEM; goto release_mem; } diff --git a/drivers/video/bf537-lq035.c b/drivers/video/bf537-lq035.c index befbc80d11fc..7347aa1e5e4a 100644 --- a/drivers/video/bf537-lq035.c +++ b/drivers/video/bf537-lq035.c @@ -760,18 +760,20 @@ static int __devinit bfin_lq035_probe(struct platform_device *pdev) bfin_lq035_fb.flags = FBINFO_DEFAULT; - bfin_lq035_fb.pseudo_palette = kzalloc(sizeof(u32) * 16, GFP_KERNEL); + bfin_lq035_fb.pseudo_palette = devm_kzalloc(&pdev->dev, + sizeof(u32) * 16, + GFP_KERNEL); if (bfin_lq035_fb.pseudo_palette == NULL) { pr_err("failed to allocate pseudo_palette\n"); ret = -ENOMEM; - goto out_palette; + goto out_table; } if (fb_alloc_cmap(&bfin_lq035_fb.cmap, NBR_PALETTE, 0) < 0) { pr_err("failed to allocate colormap (%d entries)\n", NBR_PALETTE); ret = -EFAULT; - goto out_cmap; + goto out_table; } if (register_framebuffer(&bfin_lq035_fb) < 0) { @@ -804,9 +806,6 @@ out_lcd: unregister_framebuffer(&bfin_lq035_fb); out_reg: fb_dealloc_cmap(&bfin_lq035_fb.cmap); -out_cmap: - kfree(bfin_lq035_fb.pseudo_palette); -out_palette: out_table: dma_free_coherent(NULL, TOTAL_VIDEO_MEM_SIZE, fb_buffer, 0); fb_buffer = NULL; @@ -834,7 +833,6 @@ static int __devexit bfin_lq035_remove(struct platform_device *pdev) free_dma(CH_PPI); - kfree(bfin_lq035_fb.pseudo_palette); fb_dealloc_cmap(&bfin_lq035_fb.cmap); diff --git a/drivers/video/bf54x-lq043fb.c b/drivers/video/bf54x-lq043fb.c index dc2f0047769b..ff5663f5c64f 100644 --- a/drivers/video/bf54x-lq043fb.c +++ b/drivers/video/bf54x-lq043fb.c @@ -525,6 +525,7 @@ static int __devinit bfin_bf54x_probe(struct platform_device *pdev) info = fbinfo->par; info->fb = fbinfo; info->dev = &pdev->dev; + spin_lock_init(&info->lock); platform_set_drvdata(pdev, fbinfo); @@ -601,7 +602,8 @@ static int __devinit bfin_bf54x_probe(struct platform_device *pdev) fbinfo->fbops = &bfin_bf54x_fb_ops; - fbinfo->pseudo_palette = kzalloc(sizeof(u32) * 16, GFP_KERNEL); + fbinfo->pseudo_palette = devm_kzalloc(&pdev->dev, sizeof(u32) * 16, + GFP_KERNEL); if (!fbinfo->pseudo_palette) { printk(KERN_ERR DRIVER_NAME "Fail to allocate pseudo_palette\n"); @@ -616,7 +618,7 @@ static int __devinit bfin_bf54x_probe(struct platform_device *pdev) "Fail to allocate colormap (%d entries)\n", BFIN_LCD_NBR_PALETTE_ENTRIES); ret = -EFAULT; - goto out5; + goto out4; } if (request_ports(info)) { @@ -671,8 +673,6 @@ out7: free_ports(info); out6: fb_dealloc_cmap(&fbinfo->cmap); -out5: - kfree(fbinfo->pseudo_palette); out4: dma_free_coherent(NULL, fbinfo->fix.smem_len, info->fb_buffer, info->dma_handle); @@ -699,7 +699,6 @@ static int __devexit bfin_bf54x_remove(struct platform_device *pdev) dma_free_coherent(NULL, fbinfo->fix.smem_len, info->fb_buffer, info->dma_handle); - kfree(fbinfo->pseudo_palette); fb_dealloc_cmap(&fbinfo->cmap); #ifndef NO_BL_SUPPORT diff --git a/drivers/video/bfin-lq035q1-fb.c b/drivers/video/bfin-lq035q1-fb.c index 353c02fe8a95..6fbc75c2f0a1 100644 --- a/drivers/video/bfin-lq035q1-fb.c +++ b/drivers/video/bfin-lq035q1-fb.c @@ -577,6 +577,7 @@ static int __devinit bfin_lq035q1_probe(struct platform_device *pdev) info = fbinfo->par; info->fb = fbinfo; info->dev = &pdev->dev; + spin_lock_init(&info->lock); info->disp_info = pdev->dev.platform_data; @@ -853,17 +854,7 @@ static struct platform_driver bfin_lq035q1_driver = { }, }; -static int __init bfin_lq035q1_driver_init(void) -{ - return platform_driver_register(&bfin_lq035q1_driver); -} -module_init(bfin_lq035q1_driver_init); - -static void __exit bfin_lq035q1_driver_cleanup(void) -{ - platform_driver_unregister(&bfin_lq035q1_driver); -} -module_exit(bfin_lq035q1_driver_cleanup); +module_platform_driver(bfin_lq035q1_driver); MODULE_DESCRIPTION("Blackfin TFT LCD Driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/video/bfin-t350mcqb-fb.c b/drivers/video/bfin-t350mcqb-fb.c index 7a0c05f3537e..ae0fb24b8b43 100644 --- a/drivers/video/bfin-t350mcqb-fb.c +++ b/drivers/video/bfin-t350mcqb-fb.c @@ -447,6 +447,7 @@ static int __devinit bfin_t350mcqb_probe(struct platform_device *pdev) info = fbinfo->par; info->fb = fbinfo; info->dev = &pdev->dev; + spin_lock_init(&info->lock); platform_set_drvdata(pdev, fbinfo); diff --git a/drivers/video/bw2.c b/drivers/video/bw2.c index 7ba74cd4be61..6bea9a936798 100644 --- a/drivers/video/bw2.c +++ b/drivers/video/bw2.c @@ -319,8 +319,10 @@ static int __devinit bw2_probe(struct platform_device *op) info->screen_base = of_ioremap(&op->resource[0], 0, info->fix.smem_len, "bw2 ram"); - if (!info->screen_base) + if (!info->screen_base) { + err = -ENOMEM; goto out_unmap_regs; + } bw2_blank(FB_BLANK_UNBLANK, info); diff --git a/drivers/video/cg3.c b/drivers/video/cg3.c index f927a7b1a8d4..c5e7612ff876 100644 --- a/drivers/video/cg3.c +++ b/drivers/video/cg3.c @@ -398,7 +398,8 @@ static int __devinit cg3_probe(struct platform_device *op) goto out_unmap_screen; } - if (fb_alloc_cmap(&info->cmap, 256, 0)) + err = fb_alloc_cmap(&info->cmap, 256, 0); + if (err) goto out_unmap_screen; fb_set_cmap(&info->cmap, info); diff --git a/drivers/video/cobalt_lcdfb.c b/drivers/video/cobalt_lcdfb.c index eae46f6457e2..01a4ee7cc6b1 100644 --- a/drivers/video/cobalt_lcdfb.c +++ b/drivers/video/cobalt_lcdfb.c @@ -348,7 +348,8 @@ static int __devinit cobalt_lcdfb_probe(struct platform_device *dev) } info->screen_size = resource_size(res); - info->screen_base = ioremap(res->start, info->screen_size); + info->screen_base = devm_ioremap(&dev->dev, res->start, + info->screen_size); info->fbops = &cobalt_lcd_fbops; info->fix = cobalt_lcdfb_fix; info->fix.smem_start = res->start; @@ -359,7 +360,6 @@ static int __devinit cobalt_lcdfb_probe(struct platform_device *dev) retval = register_framebuffer(info); if (retval < 0) { - iounmap(info->screen_base); framebuffer_release(info); return retval; } @@ -380,7 +380,6 @@ static int __devexit cobalt_lcdfb_remove(struct platform_device *dev) info = platform_get_drvdata(dev); if (info) { - iounmap(info->screen_base); unregister_framebuffer(info); framebuffer_release(info); } diff --git a/drivers/video/console/font_mini_4x6.c b/drivers/video/console/font_mini_4x6.c index fa6e698e63c4..838caa1cfef7 100644 --- a/drivers/video/console/font_mini_4x6.c +++ b/drivers/video/console/font_mini_4x6.c @@ -1092,7 +1092,7 @@ static const unsigned char fontdata_mini_4x6[FONTDATAMAX] = { /*{*/ /* Char 124: '|' */ 0x44, /*= [ * ] */ 0x44, /*= [ * ] */ - 0x00, /*= [ ] */ + 0x44, /*= [ * ] */ 0x44, /*= [ * ] */ 0x44, /*= [ * ] */ 0x00, /*= [ ] */ diff --git a/drivers/video/console/font_sun8x16.c b/drivers/video/console/font_sun8x16.c index 5abf290c6eb7..268151325b83 100644 --- a/drivers/video/console/font_sun8x16.c +++ b/drivers/video/console/font_sun8x16.c @@ -127,7 +127,7 @@ static const unsigned char fontdata_sun8x16[FONTDATAMAX] = { /*y*/ 0x00,0x00,0x00,0x00,0x00,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0x7e,0x06,0x0c,0xf8,0x00, /*z*/ 0x00,0x00,0x00,0x00,0x00,0xfe,0xcc,0x18,0x30,0x60,0xc6,0xfe,0x00,0x00,0x00,0x00, /*{*/ 0x00,0x00,0x0e,0x18,0x18,0x18,0x70,0x18,0x18,0x18,0x18,0x0e,0x00,0x00,0x00,0x00, -/*|*/ 0x00,0x00,0x18,0x18,0x18,0x18,0x00,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00, +/*|*/ 0x00,0x00,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00, /*}*/ 0x00,0x00,0x70,0x18,0x18,0x18,0x0e,0x18,0x18,0x18,0x18,0x70,0x00,0x00,0x00,0x00, /*~*/ 0x00,0x00,0x76,0xdc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* */ 0x00,0x00,0x00,0x00,0x10,0x38,0x6c,0xc6,0xc6,0xc6,0xfe,0x00,0x00,0x00,0x00,0x00, diff --git a/drivers/video/cyber2000fb.c b/drivers/video/cyber2000fb.c index c1527f5b47ee..e40125cb313e 100644 --- a/drivers/video/cyber2000fb.c +++ b/drivers/video/cyber2000fb.c @@ -1804,8 +1804,10 @@ cyberpro_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) cfb->irq = dev->irq; cfb->region = pci_ioremap_bar(dev, 0); - if (!cfb->region) + if (!cfb->region) { + err = -ENOMEM; goto failed_ioremap; + } cfb->regs = cfb->region + MMIO_OFFSET; cfb->fb.device = &dev->dev; diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c index 7ae9d53f2bf1..65a11ef87e1c 100644 --- a/drivers/video/da8xx-fb.c +++ b/drivers/video/da8xx-fb.c @@ -26,7 +26,9 @@ #include <linux/device.h> #include <linux/platform_device.h> #include <linux/uaccess.h> +#include <linux/pm_runtime.h> #include <linux/interrupt.h> +#include <linux/wait.h> #include <linux/clk.h> #include <linux/cpufreq.h> #include <linux/console.h> @@ -48,6 +50,7 @@ #define LCD_PL_LOAD_DONE BIT(6) #define LCD_FIFO_UNDERFLOW BIT(5) #define LCD_SYNC_LOST BIT(2) +#define LCD_FRAME_DONE BIT(0) /* LCD DMA Control Register */ #define LCD_DMA_BURST_SIZE(x) ((x) << 4) @@ -86,6 +89,8 @@ #define LCD_V2_LIDD_CLK_EN BIT(1) #define LCD_V2_CORE_CLK_EN BIT(0) #define LCD_V2_LPP_B10 26 +#define LCD_V2_TFT_24BPP_MODE BIT(25) +#define LCD_V2_TFT_24BPP_UNPACK BIT(26) /* LCD Raster Timing 2 Register */ #define LCD_AC_BIAS_TRANSITIONS_PER_INT(x) ((x) << 16) @@ -135,6 +140,8 @@ static resource_size_t da8xx_fb_reg_base; static struct resource *lcdc_regs; static unsigned int lcd_revision; static irq_handler_t lcdc_irq_handler; +static wait_queue_head_t frame_done_wq; +static int frame_done_flag; static inline unsigned int lcdc_read(unsigned int addr) { @@ -156,7 +163,6 @@ struct da8xx_fb_par { unsigned int dma_end; struct clk *lcdc_clk; int irq; - unsigned short pseudo_palette[16]; unsigned int palette_sz; unsigned int pxl_clk; int blank; @@ -175,6 +181,7 @@ struct da8xx_fb_par { unsigned int lcd_fck_rate; #endif void (*panel_power_ctrl)(int); + u32 pseudo_palette[16]; }; /* Variable Screen Information */ @@ -288,13 +295,26 @@ static inline void lcd_enable_raster(void) } /* Disable the Raster Engine of the LCD Controller */ -static inline void lcd_disable_raster(void) +static inline void lcd_disable_raster(bool wait_for_frame_done) { u32 reg; + int ret; reg = lcdc_read(LCD_RASTER_CTRL_REG); if (reg & LCD_RASTER_ENABLE) lcdc_write(reg & ~LCD_RASTER_ENABLE, LCD_RASTER_CTRL_REG); + else + /* return if already disabled */ + return; + + if ((wait_for_frame_done == true) && (lcd_revision == LCD_VERSION_2)) { + frame_done_flag = 0; + ret = wait_event_interruptible_timeout(frame_done_wq, + frame_done_flag != 0, + msecs_to_jiffies(50)); + if (ret == 0) + pr_err("LCD Controller timed out\n"); + } } static void lcd_blit(int load_mode, struct da8xx_fb_par *par) @@ -321,7 +341,8 @@ static void lcd_blit(int load_mode, struct da8xx_fb_par *par) } else { reg_int = lcdc_read(LCD_INT_ENABLE_SET_REG) | LCD_V2_END_OF_FRAME0_INT_ENA | - LCD_V2_END_OF_FRAME1_INT_ENA; + LCD_V2_END_OF_FRAME1_INT_ENA | + LCD_FRAME_DONE; lcdc_write(reg_int, LCD_INT_ENABLE_SET_REG); } reg_dma |= LCD_DUAL_FRAME_BUFFER_ENABLE; @@ -499,6 +520,9 @@ static int lcd_cfg_frame_buffer(struct da8xx_fb_par *par, u32 width, u32 height, { u32 reg; + if (bpp > 16 && lcd_revision == LCD_VERSION_1) + return -EINVAL; + /* Set the Panel Width */ /* Pixels per line = (PPL + 1)*16 */ if (lcd_revision == LCD_VERSION_1) { @@ -542,14 +566,19 @@ static int lcd_cfg_frame_buffer(struct da8xx_fb_par *par, u32 width, u32 height, reg = lcdc_read(LCD_RASTER_CTRL_REG) & ~(1 << 8); if (raster_order) reg |= LCD_RASTER_ORDER; - lcdc_write(reg, LCD_RASTER_CTRL_REG); + + par->palette_sz = 16 * 2; switch (bpp) { case 1: case 2: case 4: case 16: - par->palette_sz = 16 * 2; + break; + case 24: + reg |= LCD_V2_TFT_24BPP_MODE; + case 32: + reg |= LCD_V2_TFT_24BPP_UNPACK; break; case 8: @@ -560,9 +589,12 @@ static int lcd_cfg_frame_buffer(struct da8xx_fb_par *par, u32 width, u32 height, return -EINVAL; } + lcdc_write(reg, LCD_RASTER_CTRL_REG); + return 0; } +#define CNVT_TOHW(val, width) ((((val) << (width)) + 0x7FFF - (val)) >> 16) static int fb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue, unsigned transp, struct fb_info *info) @@ -578,13 +610,38 @@ static int fb_setcolreg(unsigned regno, unsigned red, unsigned green, if (info->fix.visual == FB_VISUAL_DIRECTCOLOR) return 1; - if (info->var.bits_per_pixel == 4) { - if (regno > 15) - return 1; + if (info->var.bits_per_pixel > 16 && lcd_revision == LCD_VERSION_1) + return -EINVAL; - if (info->var.grayscale) { - pal = regno; - } else { + switch (info->fix.visual) { + case FB_VISUAL_TRUECOLOR: + red = CNVT_TOHW(red, info->var.red.length); + green = CNVT_TOHW(green, info->var.green.length); + blue = CNVT_TOHW(blue, info->var.blue.length); + break; + case FB_VISUAL_PSEUDOCOLOR: + switch (info->var.bits_per_pixel) { + case 4: + if (regno > 15) + return -EINVAL; + + if (info->var.grayscale) { + pal = regno; + } else { + red >>= 4; + green >>= 8; + blue >>= 12; + + pal = red & 0x0f00; + pal |= green & 0x00f0; + pal |= blue & 0x000f; + } + if (regno == 0) + pal |= 0x2000; + palette[regno] = pal; + break; + + case 8: red >>= 4; green >>= 8; blue >>= 12; @@ -592,36 +649,36 @@ static int fb_setcolreg(unsigned regno, unsigned red, unsigned green, pal = (red & 0x0f00); pal |= (green & 0x00f0); pal |= (blue & 0x000f); - } - if (regno == 0) - pal |= 0x2000; - palette[regno] = pal; - - } else if (info->var.bits_per_pixel == 8) { - red >>= 4; - green >>= 8; - blue >>= 12; - - pal = (red & 0x0f00); - pal |= (green & 0x00f0); - pal |= (blue & 0x000f); - if (palette[regno] != pal) { - update_hw = 1; - palette[regno] = pal; + if (palette[regno] != pal) { + update_hw = 1; + palette[regno] = pal; + } + break; } - } else if ((info->var.bits_per_pixel == 16) && regno < 16) { - red >>= (16 - info->var.red.length); - red <<= info->var.red.offset; + break; + } - green >>= (16 - info->var.green.length); - green <<= info->var.green.offset; + /* Truecolor has hardware independent palette */ + if (info->fix.visual == FB_VISUAL_TRUECOLOR) { + u32 v; - blue >>= (16 - info->var.blue.length); - blue <<= info->var.blue.offset; + if (regno > 15) + return -EINVAL; - par->pseudo_palette[regno] = red | green | blue; + v = (red << info->var.red.offset) | + (green << info->var.green.offset) | + (blue << info->var.blue.offset); + switch (info->var.bits_per_pixel) { + case 16: + ((u16 *) (info->pseudo_palette))[regno] = v; + break; + case 24: + case 32: + ((u32 *) (info->pseudo_palette))[regno] = v; + break; + } if (palette[0] != 0x4000) { update_hw = 1; palette[0] = 0x4000; @@ -634,11 +691,12 @@ static int fb_setcolreg(unsigned regno, unsigned red, unsigned green, return 0; } +#undef CNVT_TOHW static void lcd_reset(struct da8xx_fb_par *par) { /* Disable the Raster if previously Enabled */ - lcd_disable_raster(); + lcd_disable_raster(false); /* DMA has to be disabled */ lcdc_write(0, LCD_DMA_CTRL_REG); @@ -734,7 +792,7 @@ static irqreturn_t lcdc_irq_handler_rev02(int irq, void *arg) u32 stat = lcdc_read(LCD_MASKED_STAT_REG); if ((stat & LCD_SYNC_LOST) && (stat & LCD_FIFO_UNDERFLOW)) { - lcd_disable_raster(); + lcd_disable_raster(false); lcdc_write(stat, LCD_MASKED_STAT_REG); lcd_enable_raster(); } else if (stat & LCD_PL_LOAD_DONE) { @@ -744,7 +802,7 @@ static irqreturn_t lcdc_irq_handler_rev02(int irq, void *arg) * interrupt via the following write to the status register. If * this is done after then one gets multiple PL done interrupts. */ - lcd_disable_raster(); + lcd_disable_raster(false); lcdc_write(stat, LCD_MASKED_STAT_REG); @@ -775,6 +833,14 @@ static irqreturn_t lcdc_irq_handler_rev02(int irq, void *arg) par->vsync_flag = 1; wake_up_interruptible(&par->vsync_wait); } + + /* Set only when controller is disabled and at the end of + * active frame + */ + if (stat & BIT(0)) { + frame_done_flag = 1; + wake_up_interruptible(&frame_done_wq); + } } lcdc_write(0, LCD_END_OF_INT_IND_REG); @@ -789,7 +855,7 @@ static irqreturn_t lcdc_irq_handler_rev01(int irq, void *arg) u32 reg_ras; if ((stat & LCD_SYNC_LOST) && (stat & LCD_FIFO_UNDERFLOW)) { - lcd_disable_raster(); + lcd_disable_raster(false); lcdc_write(stat, LCD_STAT_REG); lcd_enable_raster(); } else if (stat & LCD_PL_LOAD_DONE) { @@ -799,7 +865,7 @@ static irqreturn_t lcdc_irq_handler_rev01(int irq, void *arg) * interrupt via the following write to the status register. If * this is done after then one gets multiple PL done interrupts. */ - lcd_disable_raster(); + lcd_disable_raster(false); lcdc_write(stat, LCD_STAT_REG); @@ -842,6 +908,9 @@ static int fb_check_var(struct fb_var_screeninfo *var, { int err = 0; + if (var->bits_per_pixel > 16 && lcd_revision == LCD_VERSION_1) + return -EINVAL; + switch (var->bits_per_pixel) { case 1: case 8: @@ -877,6 +946,26 @@ static int fb_check_var(struct fb_var_screeninfo *var, var->transp.length = 0; var->nonstd = 0; break; + case 24: + var->red.offset = 16; + var->red.length = 8; + var->green.offset = 8; + var->green.length = 8; + var->blue.offset = 0; + var->blue.length = 8; + var->nonstd = 0; + break; + case 32: + var->transp.offset = 24; + var->transp.length = 8; + var->red.offset = 16; + var->red.length = 8; + var->green.offset = 8; + var->green.length = 8; + var->blue.offset = 0; + var->blue.length = 8; + var->nonstd = 0; + break; default: err = -EINVAL; } @@ -898,9 +987,10 @@ static int lcd_da8xx_cpufreq_transition(struct notifier_block *nb, if (val == CPUFREQ_POSTCHANGE) { if (par->lcd_fck_rate != clk_get_rate(par->lcdc_clk)) { par->lcd_fck_rate = clk_get_rate(par->lcdc_clk); - lcd_disable_raster(); + lcd_disable_raster(true); lcd_calc_clk_divider(par); - lcd_enable_raster(); + if (par->blank == FB_BLANK_UNBLANK) + lcd_enable_raster(); } } @@ -935,7 +1025,7 @@ static int __devexit fb_remove(struct platform_device *dev) if (par->panel_power_ctrl) par->panel_power_ctrl(0); - lcd_disable_raster(); + lcd_disable_raster(true); lcdc_write(0, LCD_RASTER_CTRL_REG); /* disable DMA */ @@ -948,8 +1038,8 @@ static int __devexit fb_remove(struct platform_device *dev) dma_free_coherent(NULL, par->vram_size, par->vram_virt, par->vram_phys); free_irq(par->irq, par); - clk_disable(par->lcdc_clk); - clk_put(par->lcdc_clk); + pm_runtime_put_sync(&dev->dev); + pm_runtime_disable(&dev->dev); framebuffer_release(info); iounmap((void __iomem *)da8xx_fb_reg_base); release_mem_region(lcdc_regs->start, resource_size(lcdc_regs)); @@ -1051,7 +1141,7 @@ static int cfb_blank(int blank, struct fb_info *info) if (par->panel_power_ctrl) par->panel_power_ctrl(0); - lcd_disable_raster(); + lcd_disable_raster(true); break; default: ret = -EINVAL; @@ -1183,9 +1273,9 @@ static int __devinit fb_probe(struct platform_device *device) ret = -ENODEV; goto err_ioremap; } - ret = clk_enable(fb_clk); - if (ret) - goto err_clk_put; + + pm_runtime_enable(&device->dev); + pm_runtime_get_sync(&device->dev); /* Determine LCD IP Version */ switch (lcdc_read(LCD_PID_REG)) { @@ -1213,7 +1303,7 @@ static int __devinit fb_probe(struct platform_device *device) if (i == ARRAY_SIZE(known_lcd_panels)) { dev_err(&device->dev, "GLCD: No valid panel found\n"); ret = -ENODEV; - goto err_clk_disable; + goto err_pm_runtime_disable; } else dev_info(&device->dev, "GLCD: Found %s panel\n", fb_pdata->type); @@ -1225,7 +1315,7 @@ static int __devinit fb_probe(struct platform_device *device) if (!da8xx_fb_info) { dev_dbg(&device->dev, "Memory allocation failed for fb_info\n"); ret = -ENOMEM; - goto err_clk_disable; + goto err_pm_runtime_disable; } par = da8xx_fb_info->par; @@ -1356,8 +1446,10 @@ static int __devinit fb_probe(struct platform_device *device) if (lcd_revision == LCD_VERSION_1) lcdc_irq_handler = lcdc_irq_handler_rev01; - else + else { + init_waitqueue_head(&frame_done_wq); lcdc_irq_handler = lcdc_irq_handler_rev02; + } ret = request_irq(par->irq, lcdc_irq_handler, 0, DRIVER_NAME, par); @@ -1385,11 +1477,9 @@ err_release_fb_mem: err_release_fb: framebuffer_release(da8xx_fb_info); -err_clk_disable: - clk_disable(fb_clk); - -err_clk_put: - clk_put(fb_clk); +err_pm_runtime_disable: + pm_runtime_put_sync(&device->dev); + pm_runtime_disable(&device->dev); err_ioremap: iounmap((void __iomem *)da8xx_fb_reg_base); @@ -1401,6 +1491,69 @@ err_request_mem: } #ifdef CONFIG_PM +struct lcdc_context { + u32 clk_enable; + u32 ctrl; + u32 dma_ctrl; + u32 raster_timing_0; + u32 raster_timing_1; + u32 raster_timing_2; + u32 int_enable_set; + u32 dma_frm_buf_base_addr_0; + u32 dma_frm_buf_ceiling_addr_0; + u32 dma_frm_buf_base_addr_1; + u32 dma_frm_buf_ceiling_addr_1; + u32 raster_ctrl; +} reg_context; + +static void lcd_context_save(void) +{ + if (lcd_revision == LCD_VERSION_2) { + reg_context.clk_enable = lcdc_read(LCD_CLK_ENABLE_REG); + reg_context.int_enable_set = lcdc_read(LCD_INT_ENABLE_SET_REG); + } + + reg_context.ctrl = lcdc_read(LCD_CTRL_REG); + reg_context.dma_ctrl = lcdc_read(LCD_DMA_CTRL_REG); + reg_context.raster_timing_0 = lcdc_read(LCD_RASTER_TIMING_0_REG); + reg_context.raster_timing_1 = lcdc_read(LCD_RASTER_TIMING_1_REG); + reg_context.raster_timing_2 = lcdc_read(LCD_RASTER_TIMING_2_REG); + reg_context.dma_frm_buf_base_addr_0 = + lcdc_read(LCD_DMA_FRM_BUF_BASE_ADDR_0_REG); + reg_context.dma_frm_buf_ceiling_addr_0 = + lcdc_read(LCD_DMA_FRM_BUF_CEILING_ADDR_0_REG); + reg_context.dma_frm_buf_base_addr_1 = + lcdc_read(LCD_DMA_FRM_BUF_BASE_ADDR_1_REG); + reg_context.dma_frm_buf_ceiling_addr_1 = + lcdc_read(LCD_DMA_FRM_BUF_CEILING_ADDR_1_REG); + reg_context.raster_ctrl = lcdc_read(LCD_RASTER_CTRL_REG); + return; +} + +static void lcd_context_restore(void) +{ + if (lcd_revision == LCD_VERSION_2) { + lcdc_write(reg_context.clk_enable, LCD_CLK_ENABLE_REG); + lcdc_write(reg_context.int_enable_set, LCD_INT_ENABLE_SET_REG); + } + + lcdc_write(reg_context.ctrl, LCD_CTRL_REG); + lcdc_write(reg_context.dma_ctrl, LCD_DMA_CTRL_REG); + lcdc_write(reg_context.raster_timing_0, LCD_RASTER_TIMING_0_REG); + lcdc_write(reg_context.raster_timing_1, LCD_RASTER_TIMING_1_REG); + lcdc_write(reg_context.raster_timing_2, LCD_RASTER_TIMING_2_REG); + lcdc_write(reg_context.dma_frm_buf_base_addr_0, + LCD_DMA_FRM_BUF_BASE_ADDR_0_REG); + lcdc_write(reg_context.dma_frm_buf_ceiling_addr_0, + LCD_DMA_FRM_BUF_CEILING_ADDR_0_REG); + lcdc_write(reg_context.dma_frm_buf_base_addr_1, + LCD_DMA_FRM_BUF_BASE_ADDR_1_REG); + lcdc_write(reg_context.dma_frm_buf_ceiling_addr_1, + LCD_DMA_FRM_BUF_CEILING_ADDR_1_REG); + lcdc_write(reg_context.raster_ctrl, LCD_RASTER_CTRL_REG); + return; +} + static int fb_suspend(struct platform_device *dev, pm_message_t state) { struct fb_info *info = platform_get_drvdata(dev); @@ -1411,8 +1564,9 @@ static int fb_suspend(struct platform_device *dev, pm_message_t state) par->panel_power_ctrl(0); fb_set_suspend(info, 1); - lcd_disable_raster(); - clk_disable(par->lcdc_clk); + lcd_disable_raster(true); + lcd_context_save(); + pm_runtime_put_sync(&dev->dev); console_unlock(); return 0; @@ -1423,11 +1577,14 @@ static int fb_resume(struct platform_device *dev) struct da8xx_fb_par *par = info->par; console_lock(); - clk_enable(par->lcdc_clk); - lcd_enable_raster(); + pm_runtime_get_sync(&dev->dev); + lcd_context_restore(); + if (par->blank == FB_BLANK_UNBLANK) { + lcd_enable_raster(); - if (par->panel_power_ctrl) - par->panel_power_ctrl(1); + if (par->panel_power_ctrl) + par->panel_power_ctrl(1); + } fb_set_suspend(info, 0); console_unlock(); diff --git a/drivers/video/ep93xx-fb.c b/drivers/video/ep93xx-fb.c index 345d96230978..69c89f263aa8 100644 --- a/drivers/video/ep93xx-fb.c +++ b/drivers/video/ep93xx-fb.c @@ -529,7 +529,8 @@ static int __devinit ep93xxfb_probe(struct platform_device *pdev) * any of the framebuffer registers. */ fbi->res = res; - fbi->mmio_base = ioremap(res->start, resource_size(res)); + fbi->mmio_base = devm_ioremap(&pdev->dev, res->start, + resource_size(res)); if (!fbi->mmio_base) { err = -ENXIO; goto failed_resource; @@ -553,20 +554,20 @@ static int __devinit ep93xxfb_probe(struct platform_device *pdev) if (err == 0) { dev_err(info->dev, "No suitable video mode found\n"); err = -EINVAL; - goto failed_mode; + goto failed_resource; } if (mach_info->setup) { err = mach_info->setup(pdev); if (err) - goto failed_mode; + goto failed_resource; } err = ep93xxfb_check_var(&info->var, info); if (err) goto failed_check; - fbi->clk = clk_get(info->dev, NULL); + fbi->clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(fbi->clk)) { err = PTR_ERR(fbi->clk); fbi->clk = NULL; @@ -578,19 +579,15 @@ static int __devinit ep93xxfb_probe(struct platform_device *pdev) err = register_framebuffer(info); if (err) - goto failed; + goto failed_check; dev_info(info->dev, "registered. Mode = %dx%d-%d\n", info->var.xres, info->var.yres, info->var.bits_per_pixel); return 0; -failed: - clk_put(fbi->clk); failed_check: if (fbi->mach_info->teardown) fbi->mach_info->teardown(pdev); -failed_mode: - iounmap(fbi->mmio_base); failed_resource: ep93xxfb_dealloc_videomem(info); failed_videomem: @@ -609,8 +606,6 @@ static int __devexit ep93xxfb_remove(struct platform_device *pdev) unregister_framebuffer(info); clk_disable(fbi->clk); - clk_put(fbi->clk); - iounmap(fbi->mmio_base); ep93xxfb_dealloc_videomem(info); fb_dealloc_cmap(&info->cmap); diff --git a/drivers/video/epson1355fb.c b/drivers/video/epson1355fb.c index 68b9b511ce80..246da1e2968c 100644 --- a/drivers/video/epson1355fb.c +++ b/drivers/video/epson1355fb.c @@ -592,12 +592,8 @@ static int epson1355fb_remove(struct platform_device *dev) if (info) { fb_dealloc_cmap(&info->cmap); - if (info->screen_base) - iounmap(info->screen_base); framebuffer_release(info); } - release_mem_region(EPSON1355FB_FB_PHYS, EPSON1355FB_FB_LEN); - release_mem_region(EPSON1355FB_REGS_PHYS, EPSON1355FB_REGS_LEN); return 0; } @@ -608,15 +604,18 @@ static int __devinit epson1355fb_probe(struct platform_device *dev) u8 revision; int rc = 0; - if (!request_mem_region(EPSON1355FB_REGS_PHYS, EPSON1355FB_REGS_LEN, "S1D13505 registers")) { + if (!devm_request_mem_region(&dev->dev, EPSON1355FB_REGS_PHYS, + EPSON1355FB_REGS_LEN, + "S1D13505 registers")) { printk(KERN_ERR "epson1355fb: unable to reserve " "registers at 0x%0x\n", EPSON1355FB_REGS_PHYS); rc = -EBUSY; goto bail; } - if (!request_mem_region(EPSON1355FB_FB_PHYS, EPSON1355FB_FB_LEN, - "S1D13505 framebuffer")) { + if (!devm_request_mem_region(&dev->dev, EPSON1355FB_FB_PHYS, + EPSON1355FB_FB_LEN, + "S1D13505 framebuffer")) { printk(KERN_ERR "epson1355fb: unable to reserve " "framebuffer at 0x%0x\n", EPSON1355FB_FB_PHYS); rc = -EBUSY; @@ -638,7 +637,8 @@ static int __devinit epson1355fb_probe(struct platform_device *dev) } info->pseudo_palette = default_par->pseudo_palette; - info->screen_base = ioremap(EPSON1355FB_FB_PHYS, EPSON1355FB_FB_LEN); + info->screen_base = devm_ioremap(&dev->dev, EPSON1355FB_FB_PHYS, + EPSON1355FB_FB_LEN); if (!info->screen_base) { printk(KERN_ERR "epson1355fb: unable to map framebuffer\n"); rc = -ENOMEM; diff --git a/drivers/video/exynos/exynos_dp_core.c b/drivers/video/exynos/exynos_dp_core.c index c6c016a506ce..d55470e75412 100644 --- a/drivers/video/exynos/exynos_dp_core.c +++ b/drivers/video/exynos/exynos_dp_core.c @@ -29,6 +29,9 @@ static int exynos_dp_init_dp(struct exynos_dp_device *dp) exynos_dp_swreset(dp); + exynos_dp_init_analog_param(dp); + exynos_dp_init_interrupt(dp); + /* SW defined function Normal operation */ exynos_dp_enable_sw_function(dp); @@ -260,7 +263,7 @@ static void exynos_dp_set_lane_lane_pre_emphasis(struct exynos_dp_device *dp, static void exynos_dp_link_start(struct exynos_dp_device *dp) { - u8 buf[5]; + u8 buf[4]; int lane; int lane_count; @@ -295,10 +298,10 @@ static void exynos_dp_link_start(struct exynos_dp_device *dp) exynos_dp_set_training_pattern(dp, TRAINING_PTN1); /* Set RX training pattern */ - buf[0] = DPCD_SCRAMBLING_DISABLED | - DPCD_TRAINING_PATTERN_1; exynos_dp_write_byte_to_dpcd(dp, - DPCD_ADDR_TRAINING_PATTERN_SET, buf[0]); + DPCD_ADDR_TRAINING_PATTERN_SET, + DPCD_SCRAMBLING_DISABLED | + DPCD_TRAINING_PATTERN_1); for (lane = 0; lane < lane_count; lane++) buf[lane] = DPCD_PRE_EMPHASIS_PATTERN2_LEVEL0 | @@ -308,7 +311,7 @@ static void exynos_dp_link_start(struct exynos_dp_device *dp) lane_count, buf); } -static unsigned char exynos_dp_get_lane_status(u8 link_status[6], int lane) +static unsigned char exynos_dp_get_lane_status(u8 link_status[2], int lane) { int shift = (lane & 1) * 4; u8 link_value = link_status[lane>>1]; @@ -316,7 +319,7 @@ static unsigned char exynos_dp_get_lane_status(u8 link_status[6], int lane) return (link_value >> shift) & 0xf; } -static int exynos_dp_clock_recovery_ok(u8 link_status[6], int lane_count) +static int exynos_dp_clock_recovery_ok(u8 link_status[2], int lane_count) { int lane; u8 lane_status; @@ -329,22 +332,23 @@ static int exynos_dp_clock_recovery_ok(u8 link_status[6], int lane_count) return 0; } -static int exynos_dp_channel_eq_ok(u8 link_status[6], int lane_count) +static int exynos_dp_channel_eq_ok(u8 link_align[3], int lane_count) { int lane; u8 lane_align; u8 lane_status; - lane_align = link_status[2]; + lane_align = link_align[2]; if ((lane_align & DPCD_INTERLANE_ALIGN_DONE) == 0) return -EINVAL; for (lane = 0; lane < lane_count; lane++) { - lane_status = exynos_dp_get_lane_status(link_status, lane); + lane_status = exynos_dp_get_lane_status(link_align, lane); lane_status &= DPCD_CHANNEL_EQ_BITS; if (lane_status != DPCD_CHANNEL_EQ_BITS) return -EINVAL; } + return 0; } @@ -417,69 +421,17 @@ static unsigned int exynos_dp_get_lane_link_training( static void exynos_dp_reduce_link_rate(struct exynos_dp_device *dp) { - if (dp->link_train.link_rate == LINK_RATE_2_70GBPS) { - /* set to reduced bit rate */ - dp->link_train.link_rate = LINK_RATE_1_62GBPS; - dev_err(dp->dev, "set to bandwidth %.2x\n", - dp->link_train.link_rate); - dp->link_train.lt_state = START; - } else { - exynos_dp_training_pattern_dis(dp); - /* set enhanced mode if available */ - exynos_dp_set_enhanced_mode(dp); - dp->link_train.lt_state = FAILED; - } -} + exynos_dp_training_pattern_dis(dp); + exynos_dp_set_enhanced_mode(dp); -static void exynos_dp_get_adjust_train(struct exynos_dp_device *dp, - u8 adjust_request[2]) -{ - int lane; - int lane_count; - u8 voltage_swing; - u8 pre_emphasis; - u8 training_lane; - - lane_count = dp->link_train.lane_count; - for (lane = 0; lane < lane_count; lane++) { - voltage_swing = exynos_dp_get_adjust_request_voltage( - adjust_request, lane); - pre_emphasis = exynos_dp_get_adjust_request_pre_emphasis( - adjust_request, lane); - training_lane = DPCD_VOLTAGE_SWING_SET(voltage_swing) | - DPCD_PRE_EMPHASIS_SET(pre_emphasis); - - if (voltage_swing == VOLTAGE_LEVEL_3 || - pre_emphasis == PRE_EMPHASIS_LEVEL_3) { - training_lane |= DPCD_MAX_SWING_REACHED; - training_lane |= DPCD_MAX_PRE_EMPHASIS_REACHED; - } - dp->link_train.training_lane[lane] = training_lane; - } -} - -static int exynos_dp_check_max_cr_loop(struct exynos_dp_device *dp, - u8 voltage_swing) -{ - int lane; - int lane_count; - - lane_count = dp->link_train.lane_count; - for (lane = 0; lane < lane_count; lane++) { - if (voltage_swing == VOLTAGE_LEVEL_3 || - dp->link_train.cr_loop[lane] == MAX_CR_LOOP) - return -EINVAL; - } - return 0; + dp->link_train.lt_state = FAILED; } static int exynos_dp_process_clock_recovery(struct exynos_dp_device *dp) { - u8 data; - u8 link_status[6]; + u8 link_status[2]; int lane; int lane_count; - u8 buf[5]; u8 adjust_request[2]; u8 voltage_swing; @@ -488,100 +440,154 @@ static int exynos_dp_process_clock_recovery(struct exynos_dp_device *dp) usleep_range(100, 101); - exynos_dp_read_bytes_from_dpcd(dp, DPCD_ADDR_LANE0_1_STATUS, - 6, link_status); lane_count = dp->link_train.lane_count; + exynos_dp_read_bytes_from_dpcd(dp, DPCD_ADDR_LANE0_1_STATUS, + 2, link_status); + if (exynos_dp_clock_recovery_ok(link_status, lane_count) == 0) { /* set training pattern 2 for EQ */ exynos_dp_set_training_pattern(dp, TRAINING_PTN2); - adjust_request[0] = link_status[4]; - adjust_request[1] = link_status[5]; + for (lane = 0; lane < lane_count; lane++) { + exynos_dp_read_bytes_from_dpcd(dp, + DPCD_ADDR_ADJUST_REQUEST_LANE0_1, + 2, adjust_request); + voltage_swing = exynos_dp_get_adjust_request_voltage( + adjust_request, lane); + pre_emphasis = exynos_dp_get_adjust_request_pre_emphasis( + adjust_request, lane); + training_lane = DPCD_VOLTAGE_SWING_SET(voltage_swing) | + DPCD_PRE_EMPHASIS_SET(pre_emphasis); - exynos_dp_get_adjust_train(dp, adjust_request); + if (voltage_swing == VOLTAGE_LEVEL_3) + training_lane |= DPCD_MAX_SWING_REACHED; + if (pre_emphasis == PRE_EMPHASIS_LEVEL_3) + training_lane |= DPCD_MAX_PRE_EMPHASIS_REACHED; - buf[0] = DPCD_SCRAMBLING_DISABLED | - DPCD_TRAINING_PATTERN_2; - exynos_dp_write_byte_to_dpcd(dp, - DPCD_ADDR_TRAINING_PATTERN_SET, - buf[0]); + dp->link_train.training_lane[lane] = training_lane; - for (lane = 0; lane < lane_count; lane++) { exynos_dp_set_lane_link_training(dp, dp->link_train.training_lane[lane], lane); - buf[lane] = dp->link_train.training_lane[lane]; - exynos_dp_write_byte_to_dpcd(dp, - DPCD_ADDR_TRAINING_LANE0_SET + lane, - buf[lane]); } - dp->link_train.lt_state = EQUALIZER_TRAINING; - } else { - exynos_dp_read_byte_from_dpcd(dp, - DPCD_ADDR_ADJUST_REQUEST_LANE0_1, - &data); - adjust_request[0] = data; - exynos_dp_read_byte_from_dpcd(dp, - DPCD_ADDR_ADJUST_REQUEST_LANE2_3, - &data); - adjust_request[1] = data; + exynos_dp_write_byte_to_dpcd(dp, + DPCD_ADDR_TRAINING_PATTERN_SET, + DPCD_SCRAMBLING_DISABLED | + DPCD_TRAINING_PATTERN_2); + + exynos_dp_write_bytes_to_dpcd(dp, + DPCD_ADDR_TRAINING_LANE0_SET, + lane_count, + dp->link_train.training_lane); + dev_info(dp->dev, "Link Training Clock Recovery success\n"); + dp->link_train.lt_state = EQUALIZER_TRAINING; + } else { for (lane = 0; lane < lane_count; lane++) { training_lane = exynos_dp_get_lane_link_training( dp, lane); + exynos_dp_read_bytes_from_dpcd(dp, + DPCD_ADDR_ADJUST_REQUEST_LANE0_1, + 2, adjust_request); voltage_swing = exynos_dp_get_adjust_request_voltage( adjust_request, lane); pre_emphasis = exynos_dp_get_adjust_request_pre_emphasis( adjust_request, lane); - if ((DPCD_VOLTAGE_SWING_GET(training_lane) == voltage_swing) && - (DPCD_PRE_EMPHASIS_GET(training_lane) == pre_emphasis)) - dp->link_train.cr_loop[lane]++; - dp->link_train.training_lane[lane] = training_lane; - } - if (exynos_dp_check_max_cr_loop(dp, voltage_swing) != 0) { - exynos_dp_reduce_link_rate(dp); - } else { - exynos_dp_get_adjust_train(dp, adjust_request); + if (voltage_swing == VOLTAGE_LEVEL_3 || + pre_emphasis == PRE_EMPHASIS_LEVEL_3) { + dev_err(dp->dev, "voltage or pre emphasis reached max level\n"); + goto reduce_link_rate; + } - for (lane = 0; lane < lane_count; lane++) { - exynos_dp_set_lane_link_training(dp, - dp->link_train.training_lane[lane], - lane); - buf[lane] = dp->link_train.training_lane[lane]; - exynos_dp_write_byte_to_dpcd(dp, - DPCD_ADDR_TRAINING_LANE0_SET + lane, - buf[lane]); + if ((DPCD_VOLTAGE_SWING_GET(training_lane) == + voltage_swing) && + (DPCD_PRE_EMPHASIS_GET(training_lane) == + pre_emphasis)) { + dp->link_train.cr_loop[lane]++; + if (dp->link_train.cr_loop[lane] == MAX_CR_LOOP) { + dev_err(dp->dev, "CR Max loop\n"); + goto reduce_link_rate; + } } + + training_lane = DPCD_VOLTAGE_SWING_SET(voltage_swing) | + DPCD_PRE_EMPHASIS_SET(pre_emphasis); + + if (voltage_swing == VOLTAGE_LEVEL_3) + training_lane |= DPCD_MAX_SWING_REACHED; + if (pre_emphasis == PRE_EMPHASIS_LEVEL_3) + training_lane |= DPCD_MAX_PRE_EMPHASIS_REACHED; + + dp->link_train.training_lane[lane] = training_lane; + + exynos_dp_set_lane_link_training(dp, + dp->link_train.training_lane[lane], lane); } + + exynos_dp_write_bytes_to_dpcd(dp, + DPCD_ADDR_TRAINING_LANE0_SET, + lane_count, + dp->link_train.training_lane); } return 0; + +reduce_link_rate: + exynos_dp_reduce_link_rate(dp); + return -EIO; } static int exynos_dp_process_equalizer_training(struct exynos_dp_device *dp) { - u8 link_status[6]; + u8 link_status[2]; + u8 link_align[3]; int lane; int lane_count; - u8 buf[5]; u32 reg; u8 adjust_request[2]; + u8 voltage_swing; + u8 pre_emphasis; + u8 training_lane; usleep_range(400, 401); - exynos_dp_read_bytes_from_dpcd(dp, DPCD_ADDR_LANE0_1_STATUS, - 6, link_status); lane_count = dp->link_train.lane_count; + exynos_dp_read_bytes_from_dpcd(dp, DPCD_ADDR_LANE0_1_STATUS, + 2, link_status); + if (exynos_dp_clock_recovery_ok(link_status, lane_count) == 0) { - adjust_request[0] = link_status[4]; - adjust_request[1] = link_status[5]; + link_align[0] = link_status[0]; + link_align[1] = link_status[1]; - if (exynos_dp_channel_eq_ok(link_status, lane_count) == 0) { + exynos_dp_read_byte_from_dpcd(dp, + DPCD_ADDR_LANE_ALIGN_STATUS_UPDATED, + &link_align[2]); + + for (lane = 0; lane < lane_count; lane++) { + exynos_dp_read_bytes_from_dpcd(dp, + DPCD_ADDR_ADJUST_REQUEST_LANE0_1, + 2, adjust_request); + voltage_swing = exynos_dp_get_adjust_request_voltage( + adjust_request, lane); + pre_emphasis = exynos_dp_get_adjust_request_pre_emphasis( + adjust_request, lane); + training_lane = DPCD_VOLTAGE_SWING_SET(voltage_swing) | + DPCD_PRE_EMPHASIS_SET(pre_emphasis); + + if (voltage_swing == VOLTAGE_LEVEL_3) + training_lane |= DPCD_MAX_SWING_REACHED; + if (pre_emphasis == PRE_EMPHASIS_LEVEL_3) + training_lane |= DPCD_MAX_PRE_EMPHASIS_REACHED; + + dp->link_train.training_lane[lane] = training_lane; + } + + if (exynos_dp_channel_eq_ok(link_align, lane_count) == 0) { /* traing pattern Set to Normal */ exynos_dp_training_pattern_dis(dp); @@ -596,39 +602,42 @@ static int exynos_dp_process_equalizer_training(struct exynos_dp_device *dp) dp->link_train.lane_count = reg; dev_dbg(dp->dev, "final lane count = %.2x\n", dp->link_train.lane_count); + /* set enhanced mode if available */ exynos_dp_set_enhanced_mode(dp); - dp->link_train.lt_state = FINISHED; } else { /* not all locked */ dp->link_train.eq_loop++; if (dp->link_train.eq_loop > MAX_EQ_LOOP) { - exynos_dp_reduce_link_rate(dp); - } else { - exynos_dp_get_adjust_train(dp, adjust_request); - - for (lane = 0; lane < lane_count; lane++) { - exynos_dp_set_lane_link_training(dp, - dp->link_train.training_lane[lane], - lane); - buf[lane] = dp->link_train.training_lane[lane]; - exynos_dp_write_byte_to_dpcd(dp, - DPCD_ADDR_TRAINING_LANE0_SET + lane, - buf[lane]); - } + dev_err(dp->dev, "EQ Max loop\n"); + goto reduce_link_rate; } + + for (lane = 0; lane < lane_count; lane++) + exynos_dp_set_lane_link_training(dp, + dp->link_train.training_lane[lane], + lane); + + exynos_dp_write_bytes_to_dpcd(dp, + DPCD_ADDR_TRAINING_LANE0_SET, + lane_count, + dp->link_train.training_lane); } } else { - exynos_dp_reduce_link_rate(dp); + goto reduce_link_rate; } return 0; + +reduce_link_rate: + exynos_dp_reduce_link_rate(dp); + return -EIO; } static void exynos_dp_get_max_rx_bandwidth(struct exynos_dp_device *dp, - u8 *bandwidth) + u8 *bandwidth) { u8 data; @@ -641,7 +650,7 @@ static void exynos_dp_get_max_rx_bandwidth(struct exynos_dp_device *dp, } static void exynos_dp_get_max_rx_lane_count(struct exynos_dp_device *dp, - u8 *lane_count) + u8 *lane_count) { u8 data; @@ -693,13 +702,7 @@ static void exynos_dp_init_training(struct exynos_dp_device *dp, static int exynos_dp_sw_link_training(struct exynos_dp_device *dp) { int retval = 0; - int training_finished; - - /* Turn off unnecessary lane */ - if (dp->link_train.lane_count == 1) - exynos_dp_set_analog_power_down(dp, CH1_BLOCK, 1); - - training_finished = 0; + int training_finished = 0; dp->link_train.lt_state = START; @@ -710,10 +713,14 @@ static int exynos_dp_sw_link_training(struct exynos_dp_device *dp) exynos_dp_link_start(dp); break; case CLOCK_RECOVERY: - exynos_dp_process_clock_recovery(dp); + retval = exynos_dp_process_clock_recovery(dp); + if (retval) + dev_err(dp->dev, "LT CR failed!\n"); break; case EQUALIZER_TRAINING: - exynos_dp_process_equalizer_training(dp); + retval = exynos_dp_process_equalizer_training(dp); + if (retval) + dev_err(dp->dev, "LT EQ failed!\n"); break; case FINISHED: training_finished = 1; @@ -872,40 +879,33 @@ static int __devinit exynos_dp_probe(struct platform_device *pdev) dp->dev = &pdev->dev; - dp->clock = clk_get(&pdev->dev, "dp"); + dp->clock = devm_clk_get(&pdev->dev, "dp"); if (IS_ERR(dp->clock)) { dev_err(&pdev->dev, "failed to get clock\n"); return PTR_ERR(dp->clock); } - clk_enable(dp->clock); + clk_prepare_enable(dp->clock); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(&pdev->dev, "failed to get registers\n"); - ret = -EINVAL; - goto err_clock; - } dp->reg_base = devm_request_and_ioremap(&pdev->dev, res); if (!dp->reg_base) { dev_err(&pdev->dev, "failed to ioremap\n"); - ret = -ENOMEM; - goto err_clock; + return -ENOMEM; } dp->irq = platform_get_irq(pdev, 0); if (!dp->irq) { dev_err(&pdev->dev, "failed to get irq\n"); - ret = -ENODEV; - goto err_clock; + return -ENODEV; } ret = devm_request_irq(&pdev->dev, dp->irq, exynos_dp_irq_handler, 0, "exynos-dp", dp); if (ret) { dev_err(&pdev->dev, "failed to request irq\n"); - goto err_clock; + return ret; } dp->video_info = pdata->video_info; @@ -917,7 +917,7 @@ static int __devinit exynos_dp_probe(struct platform_device *pdev) ret = exynos_dp_detect_hpd(dp); if (ret) { dev_err(&pdev->dev, "unable to detect hpd\n"); - goto err_clock; + return ret; } exynos_dp_handle_edid(dp); @@ -926,7 +926,7 @@ static int __devinit exynos_dp_probe(struct platform_device *pdev) dp->video_info->link_rate); if (ret) { dev_err(&pdev->dev, "unable to do link train\n"); - goto err_clock; + return ret; } exynos_dp_enable_scramble(dp, 1); @@ -940,17 +940,12 @@ static int __devinit exynos_dp_probe(struct platform_device *pdev) ret = exynos_dp_config_video(dp, dp->video_info); if (ret) { dev_err(&pdev->dev, "unable to config video\n"); - goto err_clock; + return ret; } platform_set_drvdata(pdev, dp); return 0; - -err_clock: - clk_put(dp->clock); - - return ret; } static int __devexit exynos_dp_remove(struct platform_device *pdev) @@ -961,8 +956,7 @@ static int __devexit exynos_dp_remove(struct platform_device *pdev) if (pdata && pdata->phy_exit) pdata->phy_exit(); - clk_disable(dp->clock); - clk_put(dp->clock); + clk_disable_unprepare(dp->clock); return 0; } @@ -977,7 +971,7 @@ static int exynos_dp_suspend(struct device *dev) if (pdata && pdata->phy_exit) pdata->phy_exit(); - clk_disable(dp->clock); + clk_disable_unprepare(dp->clock); return 0; } @@ -991,7 +985,7 @@ static int exynos_dp_resume(struct device *dev) if (pdata && pdata->phy_init) pdata->phy_init(); - clk_enable(dp->clock); + clk_prepare_enable(dp->clock); exynos_dp_init_dp(dp); diff --git a/drivers/video/exynos/exynos_dp_core.h b/drivers/video/exynos/exynos_dp_core.h index 8526e548c385..57b8a6531c0e 100644 --- a/drivers/video/exynos/exynos_dp_core.h +++ b/drivers/video/exynos/exynos_dp_core.h @@ -43,7 +43,7 @@ void exynos_dp_init_interrupt(struct exynos_dp_device *dp); void exynos_dp_reset(struct exynos_dp_device *dp); void exynos_dp_swreset(struct exynos_dp_device *dp); void exynos_dp_config_interrupt(struct exynos_dp_device *dp); -u32 exynos_dp_get_pll_lock_status(struct exynos_dp_device *dp); +enum pll_status exynos_dp_get_pll_lock_status(struct exynos_dp_device *dp); void exynos_dp_set_pll_power_down(struct exynos_dp_device *dp, bool enable); void exynos_dp_set_analog_power_down(struct exynos_dp_device *dp, enum analog_power_block block, @@ -105,7 +105,7 @@ u32 exynos_dp_get_lane1_link_training(struct exynos_dp_device *dp); u32 exynos_dp_get_lane2_link_training(struct exynos_dp_device *dp); u32 exynos_dp_get_lane3_link_training(struct exynos_dp_device *dp); void exynos_dp_reset_macro(struct exynos_dp_device *dp); -int exynos_dp_init_video(struct exynos_dp_device *dp); +void exynos_dp_init_video(struct exynos_dp_device *dp); void exynos_dp_set_video_color_format(struct exynos_dp_device *dp, u32 color_depth, @@ -144,7 +144,7 @@ void exynos_dp_disable_scrambling(struct exynos_dp_device *dp); #define DPCD_ADDR_TRAINING_PATTERN_SET 0x0102 #define DPCD_ADDR_TRAINING_LANE0_SET 0x0103 #define DPCD_ADDR_LANE0_1_STATUS 0x0202 -#define DPCD_ADDR_LANE_ALIGN__STATUS_UPDATED 0x0204 +#define DPCD_ADDR_LANE_ALIGN_STATUS_UPDATED 0x0204 #define DPCD_ADDR_ADJUST_REQUEST_LANE0_1 0x0206 #define DPCD_ADDR_ADJUST_REQUEST_LANE2_3 0x0207 #define DPCD_ADDR_TEST_REQUEST 0x0218 diff --git a/drivers/video/exynos/exynos_dp_reg.c b/drivers/video/exynos/exynos_dp_reg.c index 2db5b9aa250a..3f5ca8a0d5ea 100644 --- a/drivers/video/exynos/exynos_dp_reg.c +++ b/drivers/video/exynos/exynos_dp_reg.c @@ -77,7 +77,7 @@ void exynos_dp_init_analog_param(struct exynos_dp_device *dp) writel(reg, dp->reg_base + EXYNOS_DP_ANALOG_CTL_3); reg = PD_RING_OSC | AUX_TERMINAL_CTRL_50_OHM | - TX_CUR1_2X | TX_CUR_8_MA; + TX_CUR1_2X | TX_CUR_16_MA; writel(reg, dp->reg_base + EXYNOS_DP_PLL_FILTER_CTL_1); reg = CH3_AMP_400_MV | CH2_AMP_400_MV | @@ -148,9 +148,6 @@ void exynos_dp_reset(struct exynos_dp_device *dp) writel(0x2, dp->reg_base + EXYNOS_DP_M_AUD_GEN_FILTER_TH); writel(0x00000101, dp->reg_base + EXYNOS_DP_SOC_GENERAL_CTL); - - exynos_dp_init_analog_param(dp); - exynos_dp_init_interrupt(dp); } void exynos_dp_swreset(struct exynos_dp_device *dp) @@ -179,7 +176,7 @@ void exynos_dp_config_interrupt(struct exynos_dp_device *dp) writel(reg, dp->reg_base + EXYNOS_DP_INT_STA_MASK); } -u32 exynos_dp_get_pll_lock_status(struct exynos_dp_device *dp) +enum pll_status exynos_dp_get_pll_lock_status(struct exynos_dp_device *dp) { u32 reg; @@ -401,6 +398,7 @@ int exynos_dp_start_aux_transaction(struct exynos_dp_device *dp) { int reg; int retval = 0; + int timeout_loop = 0; /* Enable AUX CH operation */ reg = readl(dp->reg_base + EXYNOS_DP_AUX_CH_CTL_2); @@ -409,8 +407,15 @@ int exynos_dp_start_aux_transaction(struct exynos_dp_device *dp) /* Is AUX CH command reply received? */ reg = readl(dp->reg_base + EXYNOS_DP_INT_STA); - while (!(reg & RPLY_RECEIV)) + while (!(reg & RPLY_RECEIV)) { + timeout_loop++; + if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) { + dev_err(dp->dev, "AUX CH command reply failed!\n"); + return -ETIMEDOUT; + } reg = readl(dp->reg_base + EXYNOS_DP_INT_STA); + usleep_range(10, 11); + } /* Clear interrupt source for AUX CH command reply */ writel(RPLY_RECEIV, dp->reg_base + EXYNOS_DP_INT_STA); @@ -471,7 +476,8 @@ int exynos_dp_write_byte_to_dpcd(struct exynos_dp_device *dp, if (retval == 0) break; else - dev_err(dp->dev, "Aux Transaction fail!\n"); + dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", + __func__); } return retval; @@ -511,7 +517,8 @@ int exynos_dp_read_byte_from_dpcd(struct exynos_dp_device *dp, if (retval == 0) break; else - dev_err(dp->dev, "Aux Transaction fail!\n"); + dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", + __func__); } /* Read data buffer */ @@ -575,7 +582,8 @@ int exynos_dp_write_bytes_to_dpcd(struct exynos_dp_device *dp, if (retval == 0) break; else - dev_err(dp->dev, "Aux Transaction fail!\n"); + dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", + __func__); } start_offset += cur_data_count; @@ -632,7 +640,8 @@ int exynos_dp_read_bytes_from_dpcd(struct exynos_dp_device *dp, if (retval == 0) break; else - dev_err(dp->dev, "Aux Transaction fail!\n"); + dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", + __func__); } for (cur_data_idx = 0; cur_data_idx < cur_data_count; @@ -677,7 +686,7 @@ int exynos_dp_select_i2c_device(struct exynos_dp_device *dp, /* Start AUX transaction */ retval = exynos_dp_start_aux_transaction(dp); if (retval != 0) - dev_err(dp->dev, "Aux Transaction fail!\n"); + dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", __func__); return retval; } @@ -717,7 +726,8 @@ int exynos_dp_read_byte_from_i2c(struct exynos_dp_device *dp, if (retval == 0) break; else - dev_err(dp->dev, "Aux Transaction fail!\n"); + dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", + __func__); } /* Read data */ @@ -777,7 +787,9 @@ int exynos_dp_read_bytes_from_i2c(struct exynos_dp_device *dp, if (retval == 0) break; else - dev_err(dp->dev, "Aux Transaction fail!\n"); + dev_dbg(dp->dev, + "%s: Aux Transaction fail!\n", + __func__); } /* Check if Rx sends defer */ reg = readl(dp->reg_base + EXYNOS_DP_AUX_RX_COMM); @@ -883,7 +895,9 @@ void exynos_dp_set_lane0_pre_emphasis(struct exynos_dp_device *dp, u32 level) { u32 reg; - reg = level << PRE_EMPHASIS_SET_SHIFT; + reg = readl(dp->reg_base + EXYNOS_DP_LN0_LINK_TRAINING_CTL); + reg &= ~PRE_EMPHASIS_SET_MASK; + reg |= level << PRE_EMPHASIS_SET_SHIFT; writel(reg, dp->reg_base + EXYNOS_DP_LN0_LINK_TRAINING_CTL); } @@ -891,7 +905,9 @@ void exynos_dp_set_lane1_pre_emphasis(struct exynos_dp_device *dp, u32 level) { u32 reg; - reg = level << PRE_EMPHASIS_SET_SHIFT; + reg = readl(dp->reg_base + EXYNOS_DP_LN1_LINK_TRAINING_CTL); + reg &= ~PRE_EMPHASIS_SET_MASK; + reg |= level << PRE_EMPHASIS_SET_SHIFT; writel(reg, dp->reg_base + EXYNOS_DP_LN1_LINK_TRAINING_CTL); } @@ -899,7 +915,9 @@ void exynos_dp_set_lane2_pre_emphasis(struct exynos_dp_device *dp, u32 level) { u32 reg; - reg = level << PRE_EMPHASIS_SET_SHIFT; + reg = readl(dp->reg_base + EXYNOS_DP_LN2_LINK_TRAINING_CTL); + reg &= ~PRE_EMPHASIS_SET_MASK; + reg |= level << PRE_EMPHASIS_SET_SHIFT; writel(reg, dp->reg_base + EXYNOS_DP_LN2_LINK_TRAINING_CTL); } @@ -907,7 +925,9 @@ void exynos_dp_set_lane3_pre_emphasis(struct exynos_dp_device *dp, u32 level) { u32 reg; - reg = level << PRE_EMPHASIS_SET_SHIFT; + reg = readl(dp->reg_base + EXYNOS_DP_LN3_LINK_TRAINING_CTL); + reg &= ~PRE_EMPHASIS_SET_MASK; + reg |= level << PRE_EMPHASIS_SET_SHIFT; writel(reg, dp->reg_base + EXYNOS_DP_LN3_LINK_TRAINING_CTL); } @@ -994,7 +1014,7 @@ void exynos_dp_reset_macro(struct exynos_dp_device *dp) writel(reg, dp->reg_base + EXYNOS_DP_PHY_TEST); } -int exynos_dp_init_video(struct exynos_dp_device *dp) +void exynos_dp_init_video(struct exynos_dp_device *dp) { u32 reg; @@ -1012,8 +1032,6 @@ int exynos_dp_init_video(struct exynos_dp_device *dp) reg = VID_HRES_TH(2) | VID_VRES_TH(0); writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_8); - - return 0; } void exynos_dp_set_video_color_format(struct exynos_dp_device *dp, diff --git a/drivers/video/exynos/exynos_dp_reg.h b/drivers/video/exynos/exynos_dp_reg.h index 125b27cd57ae..1f2f014cfe88 100644 --- a/drivers/video/exynos/exynos_dp_reg.h +++ b/drivers/video/exynos/exynos_dp_reg.h @@ -187,7 +187,7 @@ #define PD_RING_OSC (0x1 << 6) #define AUX_TERMINAL_CTRL_50_OHM (0x2 << 4) #define TX_CUR1_2X (0x1 << 2) -#define TX_CUR_8_MA (0x2 << 0) +#define TX_CUR_16_MA (0x3 << 0) /* EXYNOS_DP_TX_AMP_TUNING_CTL */ #define CH3_AMP_400_MV (0x0 << 24) @@ -285,6 +285,7 @@ #define SW_TRAINING_PATTERN_SET_NORMAL (0x0 << 0) /* EXYNOS_DP_LN0_LINK_TRAINING_CTL */ +#define PRE_EMPHASIS_SET_MASK (0x3 << 3) #define PRE_EMPHASIS_SET_SHIFT (3) /* EXYNOS_DP_DEBUG_CTL */ diff --git a/drivers/video/exynos/exynos_mipi_dsi.c b/drivers/video/exynos/exynos_mipi_dsi.c index 4bc2b8a5dd8b..1f5de896bd3f 100644 --- a/drivers/video/exynos/exynos_mipi_dsi.c +++ b/drivers/video/exynos/exynos_mipi_dsi.c @@ -205,7 +205,8 @@ int exynos_mipi_dsi_register_lcd_device(struct mipi_dsim_lcd_device *lcd_dev) return 0; } -struct mipi_dsim_ddi *exynos_mipi_dsi_find_lcd_device(struct mipi_dsim_lcd_driver *lcd_drv) +static struct mipi_dsim_ddi *exynos_mipi_dsi_find_lcd_device( + struct mipi_dsim_lcd_driver *lcd_drv) { struct mipi_dsim_ddi *dsim_ddi, *next; struct mipi_dsim_lcd_device *lcd_dev; @@ -265,7 +266,8 @@ int exynos_mipi_dsi_register_lcd_driver(struct mipi_dsim_lcd_driver *lcd_drv) } -struct mipi_dsim_ddi *exynos_mipi_dsi_bind_lcd_ddi(struct mipi_dsim_device *dsim, +static struct mipi_dsim_ddi *exynos_mipi_dsi_bind_lcd_ddi( + struct mipi_dsim_device *dsim, const char *name) { struct mipi_dsim_ddi *dsim_ddi, *next; @@ -373,6 +375,7 @@ static int exynos_mipi_dsi_probe(struct platform_device *pdev) dsim->clock = clk_get(&pdev->dev, "dsim0"); if (IS_ERR(dsim->clock)) { dev_err(&pdev->dev, "failed to get dsim clock source\n"); + ret = -ENODEV; goto err_clock_get; } @@ -381,6 +384,7 @@ static int exynos_mipi_dsi_probe(struct platform_device *pdev) res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { dev_err(&pdev->dev, "failed to get io memory region\n"); + ret = -ENODEV; goto err_platform_get; } @@ -405,6 +409,7 @@ static int exynos_mipi_dsi_probe(struct platform_device *pdev) dsim_ddi = exynos_mipi_dsi_bind_lcd_ddi(dsim, dsim_pd->lcd_panel_name); if (!dsim_ddi) { dev_err(&pdev->dev, "mipi_dsim_ddi object not found.\n"); + ret = -EINVAL; goto err_bind; } diff --git a/drivers/video/exynos/exynos_mipi_dsi_common.c b/drivers/video/exynos/exynos_mipi_dsi_common.c index 47b533a183be..3cd29a4fc10a 100644 --- a/drivers/video/exynos/exynos_mipi_dsi_common.c +++ b/drivers/video/exynos/exynos_mipi_dsi_common.c @@ -79,11 +79,6 @@ irqreturn_t exynos_mipi_dsi_interrupt_handler(int irq, void *dev_id) struct mipi_dsim_device *dsim = dev_id; unsigned int intsrc, intmsk; - if (dsim == NULL) { - dev_err(dsim->dev, "%s: wrong parameter\n", __func__); - return IRQ_NONE; - } - intsrc = exynos_mipi_dsi_read_interrupt(dsim); intmsk = exynos_mipi_dsi_read_interrupt_mask(dsim); intmsk = ~intmsk & intsrc; @@ -288,9 +283,6 @@ int exynos_mipi_dsi_wr_data(struct mipi_dsim_device *dsim, unsigned int data_id, mutex_unlock(&dsim->lock); return -EINVAL; } - - mutex_unlock(&dsim->lock); - return 0; } static unsigned int exynos_mipi_dsi_long_data_rd(struct mipi_dsim_device *dsim, diff --git a/drivers/video/fsl-diu-fb.c b/drivers/video/fsl-diu-fb.c index 458c00664ade..ede9e55413f8 100644 --- a/drivers/video/fsl-diu-fb.c +++ b/drivers/video/fsl-diu-fb.c @@ -1501,8 +1501,8 @@ static int __devinit fsl_diu_probe(struct platform_device *pdev) unsigned int i; int ret; - data = dma_alloc_coherent(&pdev->dev, sizeof(struct fsl_diu_data), - &dma_addr, GFP_DMA | __GFP_ZERO); + data = dmam_alloc_coherent(&pdev->dev, sizeof(struct fsl_diu_data), + &dma_addr, GFP_DMA | __GFP_ZERO); if (!data) return -ENOMEM; data->dma_addr = dma_addr; @@ -1628,9 +1628,6 @@ error: iounmap(data->diu_reg); - dma_free_coherent(&pdev->dev, sizeof(struct fsl_diu_data), data, - data->dma_addr); - return ret; } @@ -1648,9 +1645,6 @@ static int fsl_diu_remove(struct platform_device *pdev) iounmap(data->diu_reg); - dma_free_coherent(&pdev->dev, sizeof(struct fsl_diu_data), data, - data->dma_addr); - return 0; } diff --git a/drivers/video/gbefb.c b/drivers/video/gbefb.c index 7e7b7a9ba274..9b79d3835f04 100644 --- a/drivers/video/gbefb.c +++ b/drivers/video/gbefb.c @@ -1156,7 +1156,8 @@ static int __devinit gbefb_probe(struct platform_device *p_dev) goto out_release_framebuffer; } - gbe = (struct sgi_gbe *) ioremap(GBE_BASE, sizeof(struct sgi_gbe)); + gbe = (struct sgi_gbe *) devm_ioremap(&p_dev->dev, GBE_BASE, + sizeof(struct sgi_gbe)); if (!gbe) { printk(KERN_ERR "gbefb: couldn't map mmio region\n"); ret = -ENXIO; @@ -1170,12 +1171,13 @@ static int __devinit gbefb_probe(struct platform_device *p_dev) if (!gbe_tiles.cpu) { printk(KERN_ERR "gbefb: couldn't allocate tiles table\n"); ret = -ENOMEM; - goto out_unmap; + goto out_release_mem_region; } if (gbe_mem_phys) { /* memory was allocated at boot time */ - gbe_mem = ioremap_nocache(gbe_mem_phys, gbe_mem_size); + gbe_mem = devm_ioremap_nocache(&p_dev->dev, gbe_mem_phys, + gbe_mem_size); if (!gbe_mem) { printk(KERN_ERR "gbefb: couldn't map framebuffer\n"); ret = -ENOMEM; @@ -1241,13 +1243,9 @@ static int __devinit gbefb_probe(struct platform_device *p_dev) out_gbe_unmap: if (gbe_dma_addr) dma_free_coherent(NULL, gbe_mem_size, gbe_mem, gbe_mem_phys); - else - iounmap(gbe_mem); out_tiles_free: dma_free_coherent(NULL, GBE_TLB_SIZE * sizeof(uint16_t), (void *)gbe_tiles.cpu, gbe_tiles.dma); -out_unmap: - iounmap(gbe); out_release_mem_region: release_mem_region(GBE_BASE, sizeof(struct sgi_gbe)); out_release_framebuffer: @@ -1264,12 +1262,9 @@ static int __devexit gbefb_remove(struct platform_device* p_dev) gbe_turn_off(); if (gbe_dma_addr) dma_free_coherent(NULL, gbe_mem_size, gbe_mem, gbe_mem_phys); - else - iounmap(gbe_mem); dma_free_coherent(NULL, GBE_TLB_SIZE * sizeof(uint16_t), (void *)gbe_tiles.cpu, gbe_tiles.dma); release_mem_region(GBE_BASE, sizeof(struct sgi_gbe)); - iounmap(gbe); gbefb_remove_sysfs(&p_dev->dev); framebuffer_release(info); diff --git a/drivers/video/hpfb.c b/drivers/video/hpfb.c index ebf8495ff198..7324865f965f 100644 --- a/drivers/video/hpfb.c +++ b/drivers/video/hpfb.c @@ -210,6 +210,7 @@ static int __devinit hpfb_init_one(unsigned long phys_base, unsigned long virt_base) { unsigned long fboff, fb_width, fb_height, fb_start; + int ret; fb_regs = virt_base; fboff = (in_8(fb_regs + HPFB_FBOMSB) << 8) | in_8(fb_regs + HPFB_FBOLSB); @@ -290,19 +291,29 @@ static int __devinit hpfb_init_one(unsigned long phys_base, fb_info.var = hpfb_defined; fb_info.screen_base = (char *)fb_start; - fb_alloc_cmap(&fb_info.cmap, 1 << hpfb_defined.bits_per_pixel, 0); + ret = fb_alloc_cmap(&fb_info.cmap, 1 << hpfb_defined.bits_per_pixel, 0); + if (ret < 0) + goto unmap_screen_base; - if (register_framebuffer(&fb_info) < 0) { - fb_dealloc_cmap(&fb_info.cmap); - iounmap(fb_info.screen_base); - fb_info.screen_base = NULL; - return 1; - } + ret = register_framebuffer(&fb_info); + if (ret < 0) + goto dealloc_cmap; printk(KERN_INFO "fb%d: %s frame buffer device\n", fb_info.node, fb_info.fix.id); return 0; + +dealloc_cmap: + fb_dealloc_cmap(&fb_info.cmap); + +unmap_screen_base: + if (fb_info.screen_base) { + iounmap(fb_info.screen_base); + fb_info.screen_base = NULL; + } + + return ret; } /* @@ -345,6 +356,9 @@ static void __devexit hpfb_remove_one(struct dio_dev *d) if (d->scode >= DIOII_SCBASE) iounmap((void *)fb_regs); release_mem_region(d->resource.start, resource_size(&d->resource)); + fb_dealloc_cmap(&fb_info.cmap); + if (fb_info.screen_base) + iounmap(fb_info.screen_base); } static struct dio_device_id hpfb_dio_tbl[] = { diff --git a/drivers/video/imxfb.c b/drivers/video/imxfb.c index caad3689b4e6..469b07c6d741 100644 --- a/drivers/video/imxfb.c +++ b/drivers/video/imxfb.c @@ -803,6 +803,7 @@ static int __init imxfb_probe(struct platform_device *pdev) fbi->regs = ioremap(res->start, resource_size(res)); if (fbi->regs == NULL) { dev_err(&pdev->dev, "Cannot map frame buffer registers\n"); + ret = -ENOMEM; goto failed_ioremap; } diff --git a/drivers/video/jz4740_fb.c b/drivers/video/jz4740_fb.c index de366937c933..b0df279cb011 100644 --- a/drivers/video/jz4740_fb.c +++ b/drivers/video/jz4740_fb.c @@ -632,23 +632,10 @@ static int __devinit jzfb_probe(struct platform_device *pdev) return -ENXIO; } - mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!mem) { - dev_err(&pdev->dev, "Failed to get register memory resource\n"); - return -ENXIO; - } - - mem = request_mem_region(mem->start, resource_size(mem), pdev->name); - if (!mem) { - dev_err(&pdev->dev, "Failed to request register memory region\n"); - return -EBUSY; - } - fb = framebuffer_alloc(sizeof(struct jzfb), &pdev->dev); if (!fb) { dev_err(&pdev->dev, "Failed to allocate framebuffer device\n"); - ret = -ENOMEM; - goto err_release_mem_region; + return -ENOMEM; } fb->fbops = &jzfb_ops; @@ -657,27 +644,26 @@ static int __devinit jzfb_probe(struct platform_device *pdev) jzfb = fb->par; jzfb->pdev = pdev; jzfb->pdata = pdata; - jzfb->mem = mem; - jzfb->ldclk = clk_get(&pdev->dev, "lcd"); + jzfb->ldclk = devm_clk_get(&pdev->dev, "lcd"); if (IS_ERR(jzfb->ldclk)) { ret = PTR_ERR(jzfb->ldclk); dev_err(&pdev->dev, "Failed to get lcd clock: %d\n", ret); goto err_framebuffer_release; } - jzfb->lpclk = clk_get(&pdev->dev, "lcd_pclk"); + jzfb->lpclk = devm_clk_get(&pdev->dev, "lcd_pclk"); if (IS_ERR(jzfb->lpclk)) { ret = PTR_ERR(jzfb->lpclk); dev_err(&pdev->dev, "Failed to get lcd pixel clock: %d\n", ret); - goto err_put_ldclk; + goto err_framebuffer_release; } - jzfb->base = ioremap(mem->start, resource_size(mem)); + mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + jzfb->base = devm_request_and_ioremap(&pdev->dev, mem); if (!jzfb->base) { - dev_err(&pdev->dev, "Failed to ioremap register memory region\n"); ret = -EBUSY; - goto err_put_lpclk; + goto err_framebuffer_release; } platform_set_drvdata(pdev, jzfb); @@ -693,7 +679,7 @@ static int __devinit jzfb_probe(struct platform_device *pdev) ret = jzfb_alloc_devmem(jzfb); if (ret) { dev_err(&pdev->dev, "Failed to allocate video memory\n"); - goto err_iounmap; + goto err_framebuffer_release; } fb->fix = jzfb_fix; @@ -734,16 +720,8 @@ err_free_devmem: fb_dealloc_cmap(&fb->cmap); jzfb_free_devmem(jzfb); -err_iounmap: - iounmap(jzfb->base); -err_put_lpclk: - clk_put(jzfb->lpclk); -err_put_ldclk: - clk_put(jzfb->ldclk); err_framebuffer_release: framebuffer_release(fb); -err_release_mem_region: - release_mem_region(mem->start, resource_size(mem)); return ret; } @@ -756,17 +734,11 @@ static int __devexit jzfb_remove(struct platform_device *pdev) jz_gpio_bulk_free(jz_lcd_ctrl_pins, jzfb_num_ctrl_pins(jzfb)); jz_gpio_bulk_free(jz_lcd_data_pins, jzfb_num_data_pins(jzfb)); - iounmap(jzfb->base); - release_mem_region(jzfb->mem->start, resource_size(jzfb->mem)); - fb_dealloc_cmap(&jzfb->fb->cmap); jzfb_free_devmem(jzfb); platform_set_drvdata(pdev, NULL); - clk_put(jzfb->lpclk); - clk_put(jzfb->ldclk); - framebuffer_release(jzfb->fb); return 0; diff --git a/drivers/video/mb862xx/mb862xxfbdrv.c b/drivers/video/mb862xx/mb862xxfbdrv.c index 57d940be5f3d..d68e332aa21c 100644 --- a/drivers/video/mb862xx/mb862xxfbdrv.c +++ b/drivers/video/mb862xx/mb862xxfbdrv.c @@ -1052,12 +1052,14 @@ static int __devinit mb862xx_pci_probe(struct pci_dev *pdev, break; default: /* should never occur */ + ret = -EIO; goto rel_reg; } par->fb_base = ioremap(par->fb_base_phys, par->mapped_vram); if (par->fb_base == NULL) { dev_err(dev, "Cannot map framebuffer\n"); + ret = -EIO; goto rel_reg; } @@ -1073,11 +1075,13 @@ static int __devinit mb862xx_pci_probe(struct pci_dev *pdev, dev_dbg(dev, "mmio phys 0x%llx 0x%lx\n", (unsigned long long)par->mmio_base_phys, (ulong)par->mmio_len); - if (mb862xx_pci_gdc_init(par)) + ret = mb862xx_pci_gdc_init(par); + if (ret) goto io_unmap; - if (request_irq(par->irq, mb862xx_intr, IRQF_SHARED, - DRV_NAME, (void *)par)) { + ret = request_irq(par->irq, mb862xx_intr, IRQF_SHARED, + DRV_NAME, (void *)par); + if (ret) { dev_err(dev, "Cannot request irq\n"); goto io_unmap; } diff --git a/drivers/video/mbx/mbxfb.c b/drivers/video/mbx/mbxfb.c index 85e4f44bfa61..6563e50413c1 100644 --- a/drivers/video/mbx/mbxfb.c +++ b/drivers/video/mbx/mbxfb.c @@ -26,8 +26,7 @@ #include <linux/module.h> #include <linux/platform_device.h> #include <linux/uaccess.h> - -#include <asm/io.h> +#include <linux/io.h> #include <video/mbxfb.h> @@ -939,8 +938,9 @@ static int __devinit mbxfb_probe(struct platform_device *dev) } mfbi->reg_phys_addr = mfbi->reg_res->start; - mfbi->reg_virt_addr = ioremap_nocache(mfbi->reg_phys_addr, - res_size(mfbi->reg_req)); + mfbi->reg_virt_addr = devm_ioremap_nocache(&dev->dev, + mfbi->reg_phys_addr, + res_size(mfbi->reg_req)); if (!mfbi->reg_virt_addr) { dev_err(&dev->dev, "failed to ioremap Marathon registers\n"); ret = -EINVAL; @@ -948,12 +948,12 @@ static int __devinit mbxfb_probe(struct platform_device *dev) } virt_base_2700 = mfbi->reg_virt_addr; - mfbi->fb_virt_addr = ioremap_nocache(mfbi->fb_phys_addr, - res_size(mfbi->fb_req)); + mfbi->fb_virt_addr = devm_ioremap_nocache(&dev->dev, mfbi->fb_phys_addr, + res_size(mfbi->fb_req)); if (!mfbi->fb_virt_addr) { dev_err(&dev->dev, "failed to ioremap frame buffer\n"); ret = -EINVAL; - goto err4; + goto err3; } fbi->screen_base = (char __iomem *)(mfbi->fb_virt_addr + 0x60000); @@ -971,7 +971,7 @@ static int __devinit mbxfb_probe(struct platform_device *dev) if (ret < 0) { dev_err(&dev->dev, "fb_alloc_cmap failed\n"); ret = -EINVAL; - goto err5; + goto err3; } platform_set_drvdata(dev, fbi); @@ -996,10 +996,6 @@ static int __devinit mbxfb_probe(struct platform_device *dev) err6: fb_dealloc_cmap(&fbi->cmap); -err5: - iounmap(mfbi->fb_virt_addr); -err4: - iounmap(mfbi->reg_virt_addr); err3: release_mem_region(mfbi->reg_res->start, res_size(mfbi->reg_res)); err2: @@ -1026,10 +1022,7 @@ static int __devexit mbxfb_remove(struct platform_device *dev) if (mfbi->platform_remove) mfbi->platform_remove(fbi); - if (mfbi->fb_virt_addr) - iounmap(mfbi->fb_virt_addr); - if (mfbi->reg_virt_addr) - iounmap(mfbi->reg_virt_addr); + if (mfbi->reg_req) release_mem_region(mfbi->reg_req->start, res_size(mfbi->reg_req)); diff --git a/drivers/video/msm/mddi.c b/drivers/video/msm/mddi.c index b061d709bc44..d43e178fae27 100644 --- a/drivers/video/msm/mddi.c +++ b/drivers/video/msm/mddi.c @@ -26,9 +26,6 @@ #include <linux/clk.h> #include <linux/io.h> #include <linux/sched.h> -#include <mach/msm_iomap.h> -#include <mach/irqs.h> -#include <mach/board.h> #include <mach/msm_fb.h> #include "mddi_hw.h" diff --git a/drivers/video/msm/mddi_client_nt35399.c b/drivers/video/msm/mddi_client_nt35399.c index 7fcd67e132bf..66b314e68dee 100644 --- a/drivers/video/msm/mddi_client_nt35399.c +++ b/drivers/video/msm/mddi_client_nt35399.c @@ -189,8 +189,9 @@ static int mddi_nt35399_probe(struct platform_device *pdev) int ret; - struct panel_info *panel = kzalloc(sizeof(struct panel_info), - GFP_KERNEL); + struct panel_info *panel = devm_kzalloc(&pdev->dev, + sizeof(struct panel_info), + GFP_KERNEL); printk(KERN_DEBUG "%s: enter.\n", __func__); @@ -233,7 +234,6 @@ static int mddi_nt35399_remove(struct platform_device *pdev) struct panel_info *panel = platform_get_drvdata(pdev); setup_vsync(panel, 0); - kfree(panel); return 0; } diff --git a/drivers/video/msm/mdp.c b/drivers/video/msm/mdp.c index cb2ddf164c98..752eff7de3ce 100644 --- a/drivers/video/msm/mdp.c +++ b/drivers/video/msm/mdp.c @@ -25,7 +25,6 @@ #include <linux/major.h> #include <linux/slab.h> -#include <mach/msm_iomap.h> #include <mach/msm_fb.h> #include <linux/platform_device.h> #include <linux/export.h> diff --git a/drivers/video/msm/mdp_hw.h b/drivers/video/msm/mdp_hw.h index d80477415caa..2a8413742630 100644 --- a/drivers/video/msm/mdp_hw.h +++ b/drivers/video/msm/mdp_hw.h @@ -15,7 +15,6 @@ #ifndef _MDP_HW_H_ #define _MDP_HW_H_ -#include <mach/msm_iomap.h> #include <mach/msm_fb.h> struct mdp_info { diff --git a/drivers/video/mx3fb.c b/drivers/video/mx3fb.c index c89f8a8d36d2..c63ddb11e050 100644 --- a/drivers/video/mx3fb.c +++ b/drivers/video/mx3fb.c @@ -1568,7 +1568,8 @@ static int mx3fb_remove(struct platform_device *dev) static struct platform_driver mx3fb_driver = { .driver = { - .name = MX3FB_NAME, + .name = MX3FB_NAME, + .owner = THIS_MODULE, }, .probe = mx3fb_probe, .remove = mx3fb_remove, diff --git a/drivers/video/nuc900fb.c b/drivers/video/nuc900fb.c index e10f551ade21..b31b12bcba70 100644 --- a/drivers/video/nuc900fb.c +++ b/drivers/video/nuc900fb.c @@ -387,7 +387,7 @@ static int nuc900fb_init_registers(struct fb_info *info) * The buffer should be a non-cached, non-buffered, memory region * to allow palette and pixel writes without flushing the cache. */ -static int __init nuc900fb_map_video_memory(struct fb_info *info) +static int __devinit nuc900fb_map_video_memory(struct fb_info *info) { struct nuc900fb_info *fbi = info->par; dma_addr_t map_dma; diff --git a/drivers/video/pnx4008/Makefile b/drivers/video/pnx4008/Makefile deleted file mode 100644 index 636aaccf01fd..000000000000 --- a/drivers/video/pnx4008/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -# -# Makefile for the new PNX4008 framebuffer device driver -# - -obj-$(CONFIG_FB_PNX4008_DUM) += sdum.o -obj-$(CONFIG_FB_PNX4008_DUM_RGB) += pnxrgbfb.o - diff --git a/drivers/video/pnx4008/dum.h b/drivers/video/pnx4008/dum.h deleted file mode 100644 index 1234d4375d92..000000000000 --- a/drivers/video/pnx4008/dum.h +++ /dev/null @@ -1,211 +0,0 @@ -/* - * linux/drivers/video/pnx4008/dum.h - * - * Internal header for SDUM - * - * 2005 (c) Koninklijke Philips N.V. This file is licensed under - * the terms of the GNU General Public License version 2. This program - * is licensed "as is" without any warranty of any kind, whether express - * or implied. - */ - -#ifndef __PNX008_DUM_H__ -#define __PNX008_DUM_H__ - -#include <mach/platform.h> - -#define PNX4008_DUMCONF_VA_BASE IO_ADDRESS(PNX4008_DUMCONF_BASE) -#define PNX4008_DUM_MAIN_VA_BASE IO_ADDRESS(PNX4008_DUM_MAINCFG_BASE) - -/* DUM CFG ADDRESSES */ -#define DUM_CH_BASE_ADR (PNX4008_DUMCONF_VA_BASE + 0x00) -#define DUM_CH_MIN_ADR (PNX4008_DUMCONF_VA_BASE + 0x00) -#define DUM_CH_MAX_ADR (PNX4008_DUMCONF_VA_BASE + 0x04) -#define DUM_CH_CONF_ADR (PNX4008_DUMCONF_VA_BASE + 0x08) -#define DUM_CH_STAT_ADR (PNX4008_DUMCONF_VA_BASE + 0x0C) -#define DUM_CH_CTRL_ADR (PNX4008_DUMCONF_VA_BASE + 0x10) - -#define CH_MARG (0x100 / sizeof(u32)) -#define DUM_CH_MIN(i) (*((volatile u32 *)DUM_CH_MIN_ADR + (i) * CH_MARG)) -#define DUM_CH_MAX(i) (*((volatile u32 *)DUM_CH_MAX_ADR + (i) * CH_MARG)) -#define DUM_CH_CONF(i) (*((volatile u32 *)DUM_CH_CONF_ADR + (i) * CH_MARG)) -#define DUM_CH_STAT(i) (*((volatile u32 *)DUM_CH_STAT_ADR + (i) * CH_MARG)) -#define DUM_CH_CTRL(i) (*((volatile u32 *)DUM_CH_CTRL_ADR + (i) * CH_MARG)) - -#define DUM_CONF_ADR (PNX4008_DUM_MAIN_VA_BASE + 0x00) -#define DUM_CTRL_ADR (PNX4008_DUM_MAIN_VA_BASE + 0x04) -#define DUM_STAT_ADR (PNX4008_DUM_MAIN_VA_BASE + 0x08) -#define DUM_DECODE_ADR (PNX4008_DUM_MAIN_VA_BASE + 0x0C) -#define DUM_COM_BASE_ADR (PNX4008_DUM_MAIN_VA_BASE + 0x10) -#define DUM_SYNC_C_ADR (PNX4008_DUM_MAIN_VA_BASE + 0x14) -#define DUM_CLK_DIV_ADR (PNX4008_DUM_MAIN_VA_BASE + 0x18) -#define DUM_DIRTY_LOW_ADR (PNX4008_DUM_MAIN_VA_BASE + 0x20) -#define DUM_DIRTY_HIGH_ADR (PNX4008_DUM_MAIN_VA_BASE + 0x24) -#define DUM_FORMAT_ADR (PNX4008_DUM_MAIN_VA_BASE + 0x28) -#define DUM_WTCFG1_ADR (PNX4008_DUM_MAIN_VA_BASE + 0x30) -#define DUM_RTCFG1_ADR (PNX4008_DUM_MAIN_VA_BASE + 0x34) -#define DUM_WTCFG2_ADR (PNX4008_DUM_MAIN_VA_BASE + 0x38) -#define DUM_RTCFG2_ADR (PNX4008_DUM_MAIN_VA_BASE + 0x3C) -#define DUM_TCFG_ADR (PNX4008_DUM_MAIN_VA_BASE + 0x40) -#define DUM_OUTP_FORMAT1_ADR (PNX4008_DUM_MAIN_VA_BASE + 0x44) -#define DUM_OUTP_FORMAT2_ADR (PNX4008_DUM_MAIN_VA_BASE + 0x48) -#define DUM_SYNC_MODE_ADR (PNX4008_DUM_MAIN_VA_BASE + 0x4C) -#define DUM_SYNC_OUT_C_ADR (PNX4008_DUM_MAIN_VA_BASE + 0x50) - -#define DUM_CONF (*(volatile u32 *)(DUM_CONF_ADR)) -#define DUM_CTRL (*(volatile u32 *)(DUM_CTRL_ADR)) -#define DUM_STAT (*(volatile u32 *)(DUM_STAT_ADR)) -#define DUM_DECODE (*(volatile u32 *)(DUM_DECODE_ADR)) -#define DUM_COM_BASE (*(volatile u32 *)(DUM_COM_BASE_ADR)) -#define DUM_SYNC_C (*(volatile u32 *)(DUM_SYNC_C_ADR)) -#define DUM_CLK_DIV (*(volatile u32 *)(DUM_CLK_DIV_ADR)) -#define DUM_DIRTY_LOW (*(volatile u32 *)(DUM_DIRTY_LOW_ADR)) -#define DUM_DIRTY_HIGH (*(volatile u32 *)(DUM_DIRTY_HIGH_ADR)) -#define DUM_FORMAT (*(volatile u32 *)(DUM_FORMAT_ADR)) -#define DUM_WTCFG1 (*(volatile u32 *)(DUM_WTCFG1_ADR)) -#define DUM_RTCFG1 (*(volatile u32 *)(DUM_RTCFG1_ADR)) -#define DUM_WTCFG2 (*(volatile u32 *)(DUM_WTCFG2_ADR)) -#define DUM_RTCFG2 (*(volatile u32 *)(DUM_RTCFG2_ADR)) -#define DUM_TCFG (*(volatile u32 *)(DUM_TCFG_ADR)) -#define DUM_OUTP_FORMAT1 (*(volatile u32 *)(DUM_OUTP_FORMAT1_ADR)) -#define DUM_OUTP_FORMAT2 (*(volatile u32 *)(DUM_OUTP_FORMAT2_ADR)) -#define DUM_SYNC_MODE (*(volatile u32 *)(DUM_SYNC_MODE_ADR)) -#define DUM_SYNC_OUT_C (*(volatile u32 *)(DUM_SYNC_OUT_C_ADR)) - -/* DUM SLAVE ADDRESSES */ -#define DUM_SLAVE_WRITE_ADR (PNX4008_DUM_MAINCFG_BASE + 0x0000000) -#define DUM_SLAVE_READ1_I_ADR (PNX4008_DUM_MAINCFG_BASE + 0x1000000) -#define DUM_SLAVE_READ1_R_ADR (PNX4008_DUM_MAINCFG_BASE + 0x1000004) -#define DUM_SLAVE_READ2_I_ADR (PNX4008_DUM_MAINCFG_BASE + 0x1000008) -#define DUM_SLAVE_READ2_R_ADR (PNX4008_DUM_MAINCFG_BASE + 0x100000C) - -#define DUM_SLAVE_WRITE_W ((volatile u32 *)(DUM_SLAVE_WRITE_ADR)) -#define DUM_SLAVE_WRITE_HW ((volatile u16 *)(DUM_SLAVE_WRITE_ADR)) -#define DUM_SLAVE_READ1_I ((volatile u8 *)(DUM_SLAVE_READ1_I_ADR)) -#define DUM_SLAVE_READ1_R ((volatile u16 *)(DUM_SLAVE_READ1_R_ADR)) -#define DUM_SLAVE_READ2_I ((volatile u8 *)(DUM_SLAVE_READ2_I_ADR)) -#define DUM_SLAVE_READ2_R ((volatile u16 *)(DUM_SLAVE_READ2_R_ADR)) - -/* Sony display register addresses */ -#define DISP_0_REG (0x00) -#define DISP_1_REG (0x01) -#define DISP_CAL_REG (0x20) -#define DISP_ID_REG (0x2A) -#define DISP_XMIN_L_REG (0x30) -#define DISP_XMIN_H_REG (0x31) -#define DISP_YMIN_REG (0x32) -#define DISP_XMAX_L_REG (0x34) -#define DISP_XMAX_H_REG (0x35) -#define DISP_YMAX_REG (0x36) -#define DISP_SYNC_EN_REG (0x38) -#define DISP_SYNC_RISE_L_REG (0x3C) -#define DISP_SYNC_RISE_H_REG (0x3D) -#define DISP_SYNC_FALL_L_REG (0x3E) -#define DISP_SYNC_FALL_H_REG (0x3F) -#define DISP_PIXEL_REG (0x0B) -#define DISP_DUMMY1_REG (0x28) -#define DISP_DUMMY2_REG (0x29) -#define DISP_TIMING_REG (0x98) -#define DISP_DUMP_REG (0x99) - -/* Sony display constants */ -#define SONY_ID1 (0x22) -#define SONY_ID2 (0x23) - -/* Philips display register addresses */ -#define PH_DISP_ORIENT_REG (0x003) -#define PH_DISP_YPOINT_REG (0x200) -#define PH_DISP_XPOINT_REG (0x201) -#define PH_DISP_PIXEL_REG (0x202) -#define PH_DISP_YMIN_REG (0x406) -#define PH_DISP_YMAX_REG (0x407) -#define PH_DISP_XMIN_REG (0x408) -#define PH_DISP_XMAX_REG (0x409) - -/* Misc constants */ -#define NO_VALID_DISPLAY_FOUND (0) -#define DISPLAY2_IS_NOT_CONNECTED (0) - -/* register values */ -#define V_BAC_ENABLE (BIT(0)) -#define V_BAC_DISABLE_IDLE (BIT(1)) -#define V_BAC_DISABLE_TRIG (BIT(2)) -#define V_DUM_RESET (BIT(3)) -#define V_MUX_RESET (BIT(4)) -#define BAC_ENABLED (BIT(0)) -#define BAC_DISABLED 0 - -/* Sony LCD commands */ -#define V_LCD_STANDBY_OFF ((BIT(25)) | (0 << 16) | DISP_0_REG) -#define V_LCD_USE_9BIT_BUS ((BIT(25)) | (2 << 16) | DISP_1_REG) -#define V_LCD_SYNC_RISE_L ((BIT(25)) | (0 << 16) | DISP_SYNC_RISE_L_REG) -#define V_LCD_SYNC_RISE_H ((BIT(25)) | (0 << 16) | DISP_SYNC_RISE_H_REG) -#define V_LCD_SYNC_FALL_L ((BIT(25)) | (160 << 16) | DISP_SYNC_FALL_L_REG) -#define V_LCD_SYNC_FALL_H ((BIT(25)) | (0 << 16) | DISP_SYNC_FALL_H_REG) -#define V_LCD_SYNC_ENABLE ((BIT(25)) | (128 << 16) | DISP_SYNC_EN_REG) -#define V_LCD_DISPLAY_ON ((BIT(25)) | (64 << 16) | DISP_0_REG) - -enum { - PAD_NONE, - PAD_512, - PAD_1024 -}; - -enum { - RGB888, - RGB666, - RGB565, - BGR565, - ARGB1555, - ABGR1555, - ARGB4444, - ABGR4444 -}; - -struct dum_setup { - int sync_neg_edge; - int round_robin; - int mux_int; - int synced_dirty_flag_int; - int dirty_flag_int; - int error_int; - int pf_empty_int; - int sf_empty_int; - int bac_dis_int; - u32 dirty_base_adr; - u32 command_base_adr; - u32 sync_clk_div; - int sync_output; - u32 sync_restart_val; - u32 set_sync_high; - u32 set_sync_low; -}; - -struct dum_ch_setup { - int disp_no; - u32 xmin; - u32 ymin; - u32 xmax; - u32 ymax; - int xmirror; - int ymirror; - int rotate; - u32 minadr; - u32 maxadr; - u32 dirtybuffer; - int pad; - int format; - int hwdirty; - int slave_trans; -}; - -struct disp_window { - u32 xmin_l; - u32 xmin_h; - u32 ymin; - u32 xmax_l; - u32 xmax_h; - u32 ymax; -}; - -#endif /* #ifndef __PNX008_DUM_H__ */ diff --git a/drivers/video/pnx4008/fbcommon.h b/drivers/video/pnx4008/fbcommon.h deleted file mode 100644 index 4ebc87dafafb..000000000000 --- a/drivers/video/pnx4008/fbcommon.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (C) 2005 Philips Semiconductors - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA, or http://www.gnu.org/licenses/gpl.html -*/ - -#define QCIF_W (176) -#define QCIF_H (144) - -#define CIF_W (352) -#define CIF_H (288) - -#define LCD_X_RES 208 -#define LCD_Y_RES 320 -#define LCD_X_PAD 256 -#define LCD_BBP 4 /* Bytes Per Pixel */ - -#define DISP_MAX_X_SIZE (320) -#define DISP_MAX_Y_SIZE (208) - -#define RETURNVAL_BASE (0x400) - -enum fb_ioctl_returntype { - ENORESOURCESLEFT = RETURNVAL_BASE, - ERESOURCESNOTFREED, - EPROCNOTOWNER, - EFBNOTOWNER, - ECOPYFAILED, - EIOREMAPFAILED, -}; diff --git a/drivers/video/pnx4008/pnxrgbfb.c b/drivers/video/pnx4008/pnxrgbfb.c deleted file mode 100644 index 6d30428e9cf9..000000000000 --- a/drivers/video/pnx4008/pnxrgbfb.c +++ /dev/null @@ -1,198 +0,0 @@ -/* - * drivers/video/pnx4008/pnxrgbfb.c - * - * PNX4008's framebuffer support - * - * Author: Grigory Tolstolytkin <gtolstolytkin@ru.mvista.com> - * Based on Philips Semiconductors's code - * - * Copyrght (c) 2005 MontaVista Software, Inc. - * Copyright (c) 2005 Philips Semiconductors - * This file is licensed under the terms of the GNU General Public License - * version 2. This program is licensed "as is" without any warranty of any - * kind, whether express or implied. - */ - -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/errno.h> -#include <linux/string.h> -#include <linux/mm.h> -#include <linux/vmalloc.h> -#include <linux/delay.h> -#include <linux/interrupt.h> -#include <linux/fb.h> -#include <linux/init.h> -#include <linux/platform_device.h> - -#include "sdum.h" -#include "fbcommon.h" - -static u32 colreg[16]; - -static struct fb_var_screeninfo rgbfb_var __initdata = { - .xres = LCD_X_RES, - .yres = LCD_Y_RES, - .xres_virtual = LCD_X_RES, - .yres_virtual = LCD_Y_RES, - .bits_per_pixel = 32, - .red.offset = 16, - .red.length = 8, - .green.offset = 8, - .green.length = 8, - .blue.offset = 0, - .blue.length = 8, - .left_margin = 0, - .right_margin = 0, - .upper_margin = 0, - .lower_margin = 0, - .vmode = FB_VMODE_NONINTERLACED, -}; -static struct fb_fix_screeninfo rgbfb_fix __initdata = { - .id = "RGBFB", - .line_length = LCD_X_RES * LCD_BBP, - .type = FB_TYPE_PACKED_PIXELS, - .visual = FB_VISUAL_TRUECOLOR, - .xpanstep = 0, - .ypanstep = 0, - .ywrapstep = 0, - .accel = FB_ACCEL_NONE, -}; - -static int channel_owned; - -static int no_cursor(struct fb_info *info, struct fb_cursor *cursor) -{ - return 0; -} - -static int rgbfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, - u_int transp, struct fb_info *info) -{ - if (regno > 15) - return 1; - - colreg[regno] = ((red & 0xff00) << 8) | (green & 0xff00) | - ((blue & 0xff00) >> 8); - return 0; -} - -static int rgbfb_mmap(struct fb_info *info, struct vm_area_struct *vma) -{ - return pnx4008_sdum_mmap(info, vma, NULL); -} - -static struct fb_ops rgbfb_ops = { - .fb_mmap = rgbfb_mmap, - .fb_setcolreg = rgbfb_setcolreg, - .fb_fillrect = cfb_fillrect, - .fb_copyarea = cfb_copyarea, - .fb_imageblit = cfb_imageblit, -}; - -static int rgbfb_remove(struct platform_device *pdev) -{ - struct fb_info *info = platform_get_drvdata(pdev); - - if (info) { - unregister_framebuffer(info); - fb_dealloc_cmap(&info->cmap); - framebuffer_release(info); - platform_set_drvdata(pdev, NULL); - } - - pnx4008_free_dum_channel(channel_owned, pdev->id); - pnx4008_set_dum_exit_notification(pdev->id); - - return 0; -} - -static int __devinit rgbfb_probe(struct platform_device *pdev) -{ - struct fb_info *info; - struct dumchannel_uf chan_uf; - int ret; - char *option; - - info = framebuffer_alloc(sizeof(u32) * 16, &pdev->dev); - if (!info) { - ret = -ENOMEM; - goto err; - } - - pnx4008_get_fb_addresses(FB_TYPE_RGB, (void **)&info->screen_base, - (dma_addr_t *) &rgbfb_fix.smem_start, - &rgbfb_fix.smem_len); - - if ((ret = pnx4008_alloc_dum_channel(pdev->id)) < 0) - goto err0; - else { - channel_owned = ret; - chan_uf.channelnr = channel_owned; - chan_uf.dirty = (u32 *) NULL; - chan_uf.source = (u32 *) rgbfb_fix.smem_start; - chan_uf.x_offset = 0; - chan_uf.y_offset = 0; - chan_uf.width = LCD_X_RES; - chan_uf.height = LCD_Y_RES; - - if ((ret = pnx4008_put_dum_channel_uf(chan_uf, pdev->id))< 0) - goto err1; - - if ((ret = - pnx4008_set_dum_channel_sync(channel_owned, CONF_SYNC_ON, - pdev->id)) < 0) - goto err1; - - if ((ret = - pnx4008_set_dum_channel_dirty_detect(channel_owned, - CONF_DIRTYDETECTION_ON, - pdev->id)) < 0) - goto err1; - } - - if (!fb_get_options("pnxrgbfb", &option) && option && - !strcmp(option, "nocursor")) - rgbfb_ops.fb_cursor = no_cursor; - - info->node = -1; - info->flags = FBINFO_FLAG_DEFAULT; - info->fbops = &rgbfb_ops; - info->fix = rgbfb_fix; - info->var = rgbfb_var; - info->screen_size = rgbfb_fix.smem_len; - info->pseudo_palette = info->par; - info->par = NULL; - - ret = fb_alloc_cmap(&info->cmap, 256, 0); - if (ret < 0) - goto err1; - - ret = register_framebuffer(info); - if (ret < 0) - goto err2; - platform_set_drvdata(pdev, info); - - return 0; - -err2: - fb_dealloc_cmap(&info->cmap); -err1: - pnx4008_free_dum_channel(channel_owned, pdev->id); -err0: - framebuffer_release(info); -err: - return ret; -} - -static struct platform_driver rgbfb_driver = { - .driver = { - .name = "pnx4008-rgbfb", - }, - .probe = rgbfb_probe, - .remove = rgbfb_remove, -}; - -module_platform_driver(rgbfb_driver); - -MODULE_LICENSE("GPL"); diff --git a/drivers/video/pnx4008/sdum.c b/drivers/video/pnx4008/sdum.c deleted file mode 100644 index c5c741452cac..000000000000 --- a/drivers/video/pnx4008/sdum.c +++ /dev/null @@ -1,861 +0,0 @@ -/* - * drivers/video/pnx4008/sdum.c - * - * Display Update Master support - * - * Authors: Grigory Tolstolytkin <gtolstolytkin@ru.mvista.com> - * Vitaly Wool <vitalywool@gmail.com> - * Based on Philips Semiconductors's code - * - * Copyrght (c) 2005-2006 MontaVista Software, Inc. - * Copyright (c) 2005 Philips Semiconductors - * This file is licensed under the terms of the GNU General Public License - * version 2. This program is licensed "as is" without any warranty of any - * kind, whether express or implied. - */ - -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/errno.h> -#include <linux/string.h> -#include <linux/mm.h> -#include <linux/tty.h> -#include <linux/vmalloc.h> -#include <linux/delay.h> -#include <linux/interrupt.h> -#include <linux/platform_device.h> -#include <linux/fb.h> -#include <linux/init.h> -#include <linux/dma-mapping.h> -#include <linux/clk.h> -#include <linux/gfp.h> -#include <asm/uaccess.h> -#include <asm/gpio.h> - -#include "sdum.h" -#include "fbcommon.h" -#include "dum.h" - -/* Framebuffers we have */ - -static struct pnx4008_fb_addr { - int fb_type; - long addr_offset; - long fb_length; -} fb_addr[] = { - [0] = { - FB_TYPE_YUV, 0, 0xB0000 - }, - [1] = { - FB_TYPE_RGB, 0xB0000, 0x50000 - }, -}; - -static struct dum_data { - u32 lcd_phys_start; - u32 lcd_virt_start; - u32 slave_phys_base; - u32 *slave_virt_base; - int fb_owning_channel[MAX_DUM_CHANNELS]; - struct dumchannel_uf chan_uf_store[MAX_DUM_CHANNELS]; -} dum_data; - -/* Different local helper functions */ - -static u32 nof_pixels_dx(struct dum_ch_setup *ch_setup) -{ - return (ch_setup->xmax - ch_setup->xmin + 1); -} - -static u32 nof_pixels_dy(struct dum_ch_setup *ch_setup) -{ - return (ch_setup->ymax - ch_setup->ymin + 1); -} - -static u32 nof_pixels_dxy(struct dum_ch_setup *ch_setup) -{ - return (nof_pixels_dx(ch_setup) * nof_pixels_dy(ch_setup)); -} - -static u32 nof_bytes(struct dum_ch_setup *ch_setup) -{ - u32 r = nof_pixels_dxy(ch_setup); - switch (ch_setup->format) { - case RGB888: - case RGB666: - r *= 4; - break; - - default: - r *= 2; - break; - } - return r; -} - -static u32 build_command(int disp_no, u32 reg, u32 val) -{ - return ((disp_no << 26) | BIT(25) | (val << 16) | (disp_no << 10) | - (reg << 0)); -} - -static u32 build_double_index(int disp_no, u32 val) -{ - return ((disp_no << 26) | (val << 16) | (disp_no << 10) | (val << 0)); -} - -static void build_disp_window(struct dum_ch_setup * ch_setup, struct disp_window * dw) -{ - dw->ymin = ch_setup->ymin; - dw->ymax = ch_setup->ymax; - dw->xmin_l = ch_setup->xmin & 0xFF; - dw->xmin_h = (ch_setup->xmin & BIT(8)) >> 8; - dw->xmax_l = ch_setup->xmax & 0xFF; - dw->xmax_h = (ch_setup->xmax & BIT(8)) >> 8; -} - -static int put_channel(struct dumchannel chan) -{ - int i = chan.channelnr; - - if (i < 0 || i > MAX_DUM_CHANNELS) - return -EINVAL; - else { - DUM_CH_MIN(i) = chan.dum_ch_min; - DUM_CH_MAX(i) = chan.dum_ch_max; - DUM_CH_CONF(i) = chan.dum_ch_conf; - DUM_CH_CTRL(i) = chan.dum_ch_ctrl; - } - - return 0; -} - -static void clear_channel(int channr) -{ - struct dumchannel chan; - - chan.channelnr = channr; - chan.dum_ch_min = 0; - chan.dum_ch_max = 0; - chan.dum_ch_conf = 0; - chan.dum_ch_ctrl = 0; - - put_channel(chan); -} - -static int put_cmd_string(struct cmdstring cmds) -{ - u16 *cmd_str_virtaddr; - u32 *cmd_ptr0_virtaddr; - u32 cmd_str_physaddr; - - int i = cmds.channelnr; - - if (i < 0 || i > MAX_DUM_CHANNELS) - return -EINVAL; - else if ((cmd_ptr0_virtaddr = - (int *)ioremap_nocache(DUM_COM_BASE, - sizeof(int) * MAX_DUM_CHANNELS)) == - NULL) - return -EIOREMAPFAILED; - else { - cmd_str_physaddr = ioread32(&cmd_ptr0_virtaddr[cmds.channelnr]); - if ((cmd_str_virtaddr = - (u16 *) ioremap_nocache(cmd_str_physaddr, - sizeof(cmds))) == NULL) { - iounmap(cmd_ptr0_virtaddr); - return -EIOREMAPFAILED; - } else { - int t; - for (t = 0; t < 8; t++) - iowrite16(*((u16 *)&cmds.prestringlen + t), - cmd_str_virtaddr + t); - - for (t = 0; t < cmds.prestringlen / 2; t++) - iowrite16(*((u16 *)&cmds.precmd + t), - cmd_str_virtaddr + t + 8); - - for (t = 0; t < cmds.poststringlen / 2; t++) - iowrite16(*((u16 *)&cmds.postcmd + t), - cmd_str_virtaddr + t + 8 + - cmds.prestringlen / 2); - - iounmap(cmd_ptr0_virtaddr); - iounmap(cmd_str_virtaddr); - } - } - - return 0; -} - -static u32 dum_ch_setup(int ch_no, struct dum_ch_setup * ch_setup) -{ - struct cmdstring cmds_c; - struct cmdstring *cmds = &cmds_c; - struct disp_window dw; - int standard; - u32 orientation = 0; - struct dumchannel chan = { 0 }; - int ret; - - if ((ch_setup->xmirror) || (ch_setup->ymirror) || (ch_setup->rotate)) { - standard = 0; - - orientation = BIT(1); /* always set 9-bit-bus */ - if (ch_setup->xmirror) - orientation |= BIT(4); - if (ch_setup->ymirror) - orientation |= BIT(3); - if (ch_setup->rotate) - orientation |= BIT(0); - } else - standard = 1; - - cmds->channelnr = ch_no; - - /* build command string header */ - if (standard) { - cmds->prestringlen = 32; - cmds->poststringlen = 0; - } else { - cmds->prestringlen = 48; - cmds->poststringlen = 16; - } - - cmds->format = - (u16) ((ch_setup->disp_no << 4) | (BIT(3)) | (ch_setup->format)); - cmds->reserved = 0x0; - cmds->startaddr_low = (ch_setup->minadr & 0xFFFF); - cmds->startaddr_high = (ch_setup->minadr >> 16); - - if ((ch_setup->minadr == 0) && (ch_setup->maxadr == 0) - && (ch_setup->xmin == 0) - && (ch_setup->ymin == 0) && (ch_setup->xmax == 0) - && (ch_setup->ymax == 0)) { - cmds->pixdatlen_low = 0; - cmds->pixdatlen_high = 0; - } else { - u32 nbytes = nof_bytes(ch_setup); - cmds->pixdatlen_low = (nbytes & 0xFFFF); - cmds->pixdatlen_high = (nbytes >> 16); - } - - if (ch_setup->slave_trans) - cmds->pixdatlen_high |= BIT(15); - - /* build pre-string */ - build_disp_window(ch_setup, &dw); - - if (standard) { - cmds->precmd[0] = - build_command(ch_setup->disp_no, DISP_XMIN_L_REG, 0x99); - cmds->precmd[1] = - build_command(ch_setup->disp_no, DISP_XMIN_L_REG, - dw.xmin_l); - cmds->precmd[2] = - build_command(ch_setup->disp_no, DISP_XMIN_H_REG, - dw.xmin_h); - cmds->precmd[3] = - build_command(ch_setup->disp_no, DISP_YMIN_REG, dw.ymin); - cmds->precmd[4] = - build_command(ch_setup->disp_no, DISP_XMAX_L_REG, - dw.xmax_l); - cmds->precmd[5] = - build_command(ch_setup->disp_no, DISP_XMAX_H_REG, - dw.xmax_h); - cmds->precmd[6] = - build_command(ch_setup->disp_no, DISP_YMAX_REG, dw.ymax); - cmds->precmd[7] = - build_double_index(ch_setup->disp_no, DISP_PIXEL_REG); - } else { - if (dw.xmin_l == ch_no) - cmds->precmd[0] = - build_command(ch_setup->disp_no, DISP_XMIN_L_REG, - 0x99); - else - cmds->precmd[0] = - build_command(ch_setup->disp_no, DISP_XMIN_L_REG, - ch_no); - - cmds->precmd[1] = - build_command(ch_setup->disp_no, DISP_XMIN_L_REG, - dw.xmin_l); - cmds->precmd[2] = - build_command(ch_setup->disp_no, DISP_XMIN_H_REG, - dw.xmin_h); - cmds->precmd[3] = - build_command(ch_setup->disp_no, DISP_YMIN_REG, dw.ymin); - cmds->precmd[4] = - build_command(ch_setup->disp_no, DISP_XMAX_L_REG, - dw.xmax_l); - cmds->precmd[5] = - build_command(ch_setup->disp_no, DISP_XMAX_H_REG, - dw.xmax_h); - cmds->precmd[6] = - build_command(ch_setup->disp_no, DISP_YMAX_REG, dw.ymax); - cmds->precmd[7] = - build_command(ch_setup->disp_no, DISP_1_REG, orientation); - cmds->precmd[8] = - build_double_index(ch_setup->disp_no, DISP_PIXEL_REG); - cmds->precmd[9] = - build_double_index(ch_setup->disp_no, DISP_PIXEL_REG); - cmds->precmd[0xA] = - build_double_index(ch_setup->disp_no, DISP_PIXEL_REG); - cmds->precmd[0xB] = - build_double_index(ch_setup->disp_no, DISP_PIXEL_REG); - cmds->postcmd[0] = - build_command(ch_setup->disp_no, DISP_1_REG, BIT(1)); - cmds->postcmd[1] = - build_command(ch_setup->disp_no, DISP_DUMMY1_REG, 1); - cmds->postcmd[2] = - build_command(ch_setup->disp_no, DISP_DUMMY1_REG, 2); - cmds->postcmd[3] = - build_command(ch_setup->disp_no, DISP_DUMMY1_REG, 3); - } - - if ((ret = put_cmd_string(cmds_c)) != 0) { - return ret; - } - - chan.channelnr = cmds->channelnr; - chan.dum_ch_min = ch_setup->dirtybuffer + ch_setup->minadr; - chan.dum_ch_max = ch_setup->dirtybuffer + ch_setup->maxadr; - chan.dum_ch_conf = 0x002; - chan.dum_ch_ctrl = 0x04; - - put_channel(chan); - - return 0; -} - -static u32 display_open(int ch_no, int auto_update, u32 * dirty_buffer, - u32 * frame_buffer, u32 xpos, u32 ypos, u32 w, u32 h) -{ - - struct dum_ch_setup k; - int ret; - - /* keep width & height within display area */ - if ((xpos + w) > DISP_MAX_X_SIZE) - w = DISP_MAX_X_SIZE - xpos; - - if ((ypos + h) > DISP_MAX_Y_SIZE) - h = DISP_MAX_Y_SIZE - ypos; - - /* assume 1 display only */ - k.disp_no = 0; - k.xmin = xpos; - k.ymin = ypos; - k.xmax = xpos + (w - 1); - k.ymax = ypos + (h - 1); - - /* adjust min and max values if necessary */ - if (k.xmin > DISP_MAX_X_SIZE - 1) - k.xmin = DISP_MAX_X_SIZE - 1; - if (k.ymin > DISP_MAX_Y_SIZE - 1) - k.ymin = DISP_MAX_Y_SIZE - 1; - - if (k.xmax > DISP_MAX_X_SIZE - 1) - k.xmax = DISP_MAX_X_SIZE - 1; - if (k.ymax > DISP_MAX_Y_SIZE - 1) - k.ymax = DISP_MAX_Y_SIZE - 1; - - k.xmirror = 0; - k.ymirror = 0; - k.rotate = 0; - k.minadr = (u32) frame_buffer; - k.maxadr = (u32) frame_buffer + (((w - 1) << 10) | ((h << 2) - 2)); - k.pad = PAD_1024; - k.dirtybuffer = (u32) dirty_buffer; - k.format = RGB888; - k.hwdirty = 0; - k.slave_trans = 0; - - ret = dum_ch_setup(ch_no, &k); - - return ret; -} - -static void lcd_reset(void) -{ - u32 *dum_pio_base = (u32 *)IO_ADDRESS(PNX4008_PIO_BASE); - - udelay(1); - iowrite32(BIT(19), &dum_pio_base[2]); - udelay(1); - iowrite32(BIT(19), &dum_pio_base[1]); - udelay(1); -} - -static int dum_init(struct platform_device *pdev) -{ - struct clk *clk; - - /* enable DUM clock */ - clk = clk_get(&pdev->dev, "dum_ck"); - if (IS_ERR(clk)) { - printk(KERN_ERR "pnx4008_dum: Unable to access DUM clock\n"); - return PTR_ERR(clk); - } - - clk_set_rate(clk, 1); - clk_put(clk); - - DUM_CTRL = V_DUM_RESET; - - /* set priority to "round-robin". All other params to "false" */ - DUM_CONF = BIT(9); - - /* Display 1 */ - DUM_WTCFG1 = PNX4008_DUM_WT_CFG; - DUM_RTCFG1 = PNX4008_DUM_RT_CFG; - DUM_TCFG = PNX4008_DUM_T_CFG; - - return 0; -} - -static void dum_chan_init(void) -{ - int i = 0, ch = 0; - u32 *cmdptrs; - u32 *cmdstrings; - - DUM_COM_BASE = - CMDSTRING_BASEADDR + BYTES_PER_CMDSTRING * NR_OF_CMDSTRINGS; - - if ((cmdptrs = - (u32 *) ioremap_nocache(DUM_COM_BASE, - sizeof(u32) * NR_OF_CMDSTRINGS)) == NULL) - return; - - for (ch = 0; ch < NR_OF_CMDSTRINGS; ch++) - iowrite32(CMDSTRING_BASEADDR + BYTES_PER_CMDSTRING * ch, - cmdptrs + ch); - - for (ch = 0; ch < MAX_DUM_CHANNELS; ch++) - clear_channel(ch); - - /* Clear the cmdstrings */ - cmdstrings = - (u32 *)ioremap_nocache(*cmdptrs, - BYTES_PER_CMDSTRING * NR_OF_CMDSTRINGS); - - if (!cmdstrings) - goto out; - - for (i = 0; i < NR_OF_CMDSTRINGS * BYTES_PER_CMDSTRING / sizeof(u32); - i++) - iowrite32(0, cmdstrings + i); - - iounmap((u32 *)cmdstrings); - -out: - iounmap((u32 *)cmdptrs); -} - -static void lcd_init(void) -{ - lcd_reset(); - - DUM_OUTP_FORMAT1 = 0; /* RGB666 */ - - udelay(1); - iowrite32(V_LCD_STANDBY_OFF, dum_data.slave_virt_base); - udelay(1); - iowrite32(V_LCD_USE_9BIT_BUS, dum_data.slave_virt_base); - udelay(1); - iowrite32(V_LCD_SYNC_RISE_L, dum_data.slave_virt_base); - udelay(1); - iowrite32(V_LCD_SYNC_RISE_H, dum_data.slave_virt_base); - udelay(1); - iowrite32(V_LCD_SYNC_FALL_L, dum_data.slave_virt_base); - udelay(1); - iowrite32(V_LCD_SYNC_FALL_H, dum_data.slave_virt_base); - udelay(1); - iowrite32(V_LCD_SYNC_ENABLE, dum_data.slave_virt_base); - udelay(1); - iowrite32(V_LCD_DISPLAY_ON, dum_data.slave_virt_base); - udelay(1); -} - -/* Interface exported to framebuffer drivers */ - -int pnx4008_get_fb_addresses(int fb_type, void **virt_addr, - dma_addr_t *phys_addr, int *fb_length) -{ - int i; - int ret = -1; - for (i = 0; i < ARRAY_SIZE(fb_addr); i++) - if (fb_addr[i].fb_type == fb_type) { - *virt_addr = (void *)(dum_data.lcd_virt_start + - fb_addr[i].addr_offset); - *phys_addr = - dum_data.lcd_phys_start + fb_addr[i].addr_offset; - *fb_length = fb_addr[i].fb_length; - ret = 0; - break; - } - - return ret; -} - -EXPORT_SYMBOL(pnx4008_get_fb_addresses); - -int pnx4008_alloc_dum_channel(int dev_id) -{ - int i = 0; - - while ((i < MAX_DUM_CHANNELS) && (dum_data.fb_owning_channel[i] != -1)) - i++; - - if (i == MAX_DUM_CHANNELS) - return -ENORESOURCESLEFT; - else { - dum_data.fb_owning_channel[i] = dev_id; - return i; - } -} - -EXPORT_SYMBOL(pnx4008_alloc_dum_channel); - -int pnx4008_free_dum_channel(int channr, int dev_id) -{ - if (channr < 0 || channr > MAX_DUM_CHANNELS) - return -EINVAL; - else if (dum_data.fb_owning_channel[channr] != dev_id) - return -EFBNOTOWNER; - else { - clear_channel(channr); - dum_data.fb_owning_channel[channr] = -1; - } - - return 0; -} - -EXPORT_SYMBOL(pnx4008_free_dum_channel); - -int pnx4008_put_dum_channel_uf(struct dumchannel_uf chan_uf, int dev_id) -{ - int i = chan_uf.channelnr; - int ret; - - if (i < 0 || i > MAX_DUM_CHANNELS) - return -EINVAL; - else if (dum_data.fb_owning_channel[i] != dev_id) - return -EFBNOTOWNER; - else if ((ret = - display_open(chan_uf.channelnr, 0, chan_uf.dirty, - chan_uf.source, chan_uf.y_offset, - chan_uf.x_offset, chan_uf.height, - chan_uf.width)) != 0) - return ret; - else { - dum_data.chan_uf_store[i].dirty = chan_uf.dirty; - dum_data.chan_uf_store[i].source = chan_uf.source; - dum_data.chan_uf_store[i].x_offset = chan_uf.x_offset; - dum_data.chan_uf_store[i].y_offset = chan_uf.y_offset; - dum_data.chan_uf_store[i].width = chan_uf.width; - dum_data.chan_uf_store[i].height = chan_uf.height; - } - - return 0; -} - -EXPORT_SYMBOL(pnx4008_put_dum_channel_uf); - -int pnx4008_set_dum_channel_sync(int channr, int val, int dev_id) -{ - if (channr < 0 || channr > MAX_DUM_CHANNELS) - return -EINVAL; - else if (dum_data.fb_owning_channel[channr] != dev_id) - return -EFBNOTOWNER; - else { - if (val == CONF_SYNC_ON) { - DUM_CH_CONF(channr) |= CONF_SYNCENABLE; - DUM_CH_CONF(channr) |= DUM_CHANNEL_CFG_SYNC_MASK | - DUM_CHANNEL_CFG_SYNC_MASK_SET; - } else if (val == CONF_SYNC_OFF) - DUM_CH_CONF(channr) &= ~CONF_SYNCENABLE; - else - return -EINVAL; - } - - return 0; -} - -EXPORT_SYMBOL(pnx4008_set_dum_channel_sync); - -int pnx4008_set_dum_channel_dirty_detect(int channr, int val, int dev_id) -{ - if (channr < 0 || channr > MAX_DUM_CHANNELS) - return -EINVAL; - else if (dum_data.fb_owning_channel[channr] != dev_id) - return -EFBNOTOWNER; - else { - if (val == CONF_DIRTYDETECTION_ON) - DUM_CH_CONF(channr) |= CONF_DIRTYENABLE; - else if (val == CONF_DIRTYDETECTION_OFF) - DUM_CH_CONF(channr) &= ~CONF_DIRTYENABLE; - else - return -EINVAL; - } - - return 0; -} - -EXPORT_SYMBOL(pnx4008_set_dum_channel_dirty_detect); - -#if 0 /* Functions not used currently, but likely to be used in future */ - -static int get_channel(struct dumchannel *p_chan) -{ - int i = p_chan->channelnr; - - if (i < 0 || i > MAX_DUM_CHANNELS) - return -EINVAL; - else { - p_chan->dum_ch_min = DUM_CH_MIN(i); - p_chan->dum_ch_max = DUM_CH_MAX(i); - p_chan->dum_ch_conf = DUM_CH_CONF(i); - p_chan->dum_ch_stat = DUM_CH_STAT(i); - p_chan->dum_ch_ctrl = 0; /* WriteOnly control register */ - } - - return 0; -} - -int pnx4008_get_dum_channel_uf(struct dumchannel_uf *p_chan_uf, int dev_id) -{ - int i = p_chan_uf->channelnr; - - if (i < 0 || i > MAX_DUM_CHANNELS) - return -EINVAL; - else if (dum_data.fb_owning_channel[i] != dev_id) - return -EFBNOTOWNER; - else { - p_chan_uf->dirty = dum_data.chan_uf_store[i].dirty; - p_chan_uf->source = dum_data.chan_uf_store[i].source; - p_chan_uf->x_offset = dum_data.chan_uf_store[i].x_offset; - p_chan_uf->y_offset = dum_data.chan_uf_store[i].y_offset; - p_chan_uf->width = dum_data.chan_uf_store[i].width; - p_chan_uf->height = dum_data.chan_uf_store[i].height; - } - - return 0; -} - -EXPORT_SYMBOL(pnx4008_get_dum_channel_uf); - -int pnx4008_get_dum_channel_config(int channr, int dev_id) -{ - int ret; - struct dumchannel chan; - - if (channr < 0 || channr > MAX_DUM_CHANNELS) - return -EINVAL; - else if (dum_data.fb_owning_channel[channr] != dev_id) - return -EFBNOTOWNER; - else { - chan.channelnr = channr; - if ((ret = get_channel(&chan)) != 0) - return ret; - } - - return (chan.dum_ch_conf & DUM_CHANNEL_CFG_MASK); -} - -EXPORT_SYMBOL(pnx4008_get_dum_channel_config); - -int pnx4008_force_update_dum_channel(int channr, int dev_id) -{ - if (channr < 0 || channr > MAX_DUM_CHANNELS) - return -EINVAL; - - else if (dum_data.fb_owning_channel[channr] != dev_id) - return -EFBNOTOWNER; - else - DUM_CH_CTRL(channr) = CTRL_SETDIRTY; - - return 0; -} - -EXPORT_SYMBOL(pnx4008_force_update_dum_channel); - -#endif - -int pnx4008_sdum_mmap(struct fb_info *info, struct vm_area_struct *vma, - struct device *dev) -{ - unsigned long off = vma->vm_pgoff << PAGE_SHIFT; - - if (off < info->fix.smem_len) { - vma->vm_pgoff += 1; - return dma_mmap_writecombine(dev, vma, - (void *)dum_data.lcd_virt_start, - dum_data.lcd_phys_start, - FB_DMA_SIZE); - } - return -EINVAL; -} - -EXPORT_SYMBOL(pnx4008_sdum_mmap); - -int pnx4008_set_dum_exit_notification(int dev_id) -{ - int i; - - for (i = 0; i < MAX_DUM_CHANNELS; i++) - if (dum_data.fb_owning_channel[i] == dev_id) - return -ERESOURCESNOTFREED; - - return 0; -} - -EXPORT_SYMBOL(pnx4008_set_dum_exit_notification); - -/* Platform device driver for DUM */ - -static int sdum_suspend(struct platform_device *pdev, pm_message_t state) -{ - int retval = 0; - struct clk *clk; - - clk = clk_get(0, "dum_ck"); - if (!IS_ERR(clk)) { - clk_set_rate(clk, 0); - clk_put(clk); - } else - retval = PTR_ERR(clk); - - /* disable BAC */ - DUM_CTRL = V_BAC_DISABLE_IDLE; - - /* LCD standby & turn off display */ - lcd_reset(); - - return retval; -} - -static int sdum_resume(struct platform_device *pdev) -{ - int retval = 0; - struct clk *clk; - - clk = clk_get(0, "dum_ck"); - if (!IS_ERR(clk)) { - clk_set_rate(clk, 1); - clk_put(clk); - } else - retval = PTR_ERR(clk); - - /* wait for BAC disable */ - DUM_CTRL = V_BAC_DISABLE_TRIG; - - while (DUM_CTRL & BAC_ENABLED) - udelay(10); - - /* re-init LCD */ - lcd_init(); - - /* enable BAC and reset MUX */ - DUM_CTRL = V_BAC_ENABLE; - udelay(1); - DUM_CTRL = V_MUX_RESET; - return 0; -} - -static int __devinit sdum_probe(struct platform_device *pdev) -{ - int ret = 0, i = 0; - - /* map frame buffer */ - dum_data.lcd_virt_start = (u32) dma_alloc_writecombine(&pdev->dev, - FB_DMA_SIZE, - &dum_data.lcd_phys_start, - GFP_KERNEL); - - if (!dum_data.lcd_virt_start) { - ret = -ENOMEM; - goto out_3; - } - - /* map slave registers */ - dum_data.slave_phys_base = PNX4008_DUM_SLAVE_BASE; - dum_data.slave_virt_base = - (u32 *) ioremap_nocache(dum_data.slave_phys_base, sizeof(u32)); - - if (dum_data.slave_virt_base == NULL) { - ret = -ENOMEM; - goto out_2; - } - - /* initialize DUM and LCD display */ - ret = dum_init(pdev); - if (ret) - goto out_1; - - dum_chan_init(); - lcd_init(); - - DUM_CTRL = V_BAC_ENABLE; - udelay(1); - DUM_CTRL = V_MUX_RESET; - - /* set decode address and sync clock divider */ - DUM_DECODE = dum_data.lcd_phys_start & DUM_DECODE_MASK; - DUM_CLK_DIV = PNX4008_DUM_CLK_DIV; - - for (i = 0; i < MAX_DUM_CHANNELS; i++) - dum_data.fb_owning_channel[i] = -1; - - /*setup wakeup interrupt */ - start_int_set_rising_edge(SE_DISP_SYNC_INT); - start_int_ack(SE_DISP_SYNC_INT); - start_int_umask(SE_DISP_SYNC_INT); - - return 0; - -out_1: - iounmap((void *)dum_data.slave_virt_base); -out_2: - dma_free_writecombine(&pdev->dev, FB_DMA_SIZE, - (void *)dum_data.lcd_virt_start, - dum_data.lcd_phys_start); -out_3: - return ret; -} - -static int sdum_remove(struct platform_device *pdev) -{ - struct clk *clk; - - start_int_mask(SE_DISP_SYNC_INT); - - clk = clk_get(0, "dum_ck"); - if (!IS_ERR(clk)) { - clk_set_rate(clk, 0); - clk_put(clk); - } - - iounmap((void *)dum_data.slave_virt_base); - - dma_free_writecombine(&pdev->dev, FB_DMA_SIZE, - (void *)dum_data.lcd_virt_start, - dum_data.lcd_phys_start); - - return 0; -} - -static struct platform_driver sdum_driver = { - .driver = { - .name = "pnx4008-sdum", - }, - .probe = sdum_probe, - .remove = sdum_remove, - .suspend = sdum_suspend, - .resume = sdum_resume, -}; - -module_platform_driver(sdum_driver); - -MODULE_LICENSE("GPL"); diff --git a/drivers/video/pnx4008/sdum.h b/drivers/video/pnx4008/sdum.h deleted file mode 100644 index 189c3d641383..000000000000 --- a/drivers/video/pnx4008/sdum.h +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright (C) 2005 Philips Semiconductors - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA, or http://www.gnu.org/licenses/gpl.html -*/ - -#define MAX_DUM_CHANNELS 64 - -#define RGB_MEM_WINDOW(x) (0x10000000 + (x)*0x00100000) - -#define QCIF_OFFSET(x) (((x) == 0) ? 0x00000: ((x) == 1) ? 0x30000: -1) -#define CIF_OFFSET(x) (((x) == 0) ? 0x00000: ((x) == 1) ? 0x60000: -1) - -#define CTRL_SETDIRTY (0x00000001) -#define CONF_DIRTYENABLE (0x00000020) -#define CONF_SYNCENABLE (0x00000004) - -#define DIRTY_ENABLED(conf) ((conf) & 0x0020) -#define SYNC_ENABLED(conf) ((conf) & 0x0004) - -/* Display 1 & 2 Write Timing Configuration */ -#define PNX4008_DUM_WT_CFG 0x00372000 - -/* Display 1 & 2 Read Timing Configuration */ -#define PNX4008_DUM_RT_CFG 0x00003A47 - -/* DUM Transit State Timing Configuration */ -#define PNX4008_DUM_T_CFG 0x1D /* 29 HCLK cycles */ - -/* DUM Sync count clock divider */ -#define PNX4008_DUM_CLK_DIV 0x02DD - -/* Memory size for framebuffer, allocated through dma_alloc_writecombine(). - * Must be PAGE aligned - */ -#define FB_DMA_SIZE (PAGE_ALIGN(SZ_1M + PAGE_SIZE)) - -#define OFFSET_RGBBUFFER (0xB0000) -#define OFFSET_YUVBUFFER (0x00000) - -#define YUVBUFFER (lcd_video_start + OFFSET_YUVBUFFER) -#define RGBBUFFER (lcd_video_start + OFFSET_RGBBUFFER) - -#define CMDSTRING_BASEADDR (0x00C000) /* iram */ -#define BYTES_PER_CMDSTRING (0x80) -#define NR_OF_CMDSTRINGS (64) - -#define MAX_NR_PRESTRINGS (0x40) -#define MAX_NR_POSTSTRINGS (0x40) - -/* various mask definitions */ -#define DUM_CLK_ENABLE 0x01 -#define DUM_CLK_DISABLE 0 -#define DUM_DECODE_MASK 0x1FFFFFFF -#define DUM_CHANNEL_CFG_MASK 0x01FF -#define DUM_CHANNEL_CFG_SYNC_MASK 0xFFFE00FF -#define DUM_CHANNEL_CFG_SYNC_MASK_SET 0x0CA00 - -#define SDUM_RETURNVAL_BASE (0x500) - -#define CONF_SYNC_OFF (0x602) -#define CONF_SYNC_ON (0x603) - -#define CONF_DIRTYDETECTION_OFF (0x600) -#define CONF_DIRTYDETECTION_ON (0x601) - -struct dumchannel_uf { - int channelnr; - u32 *dirty; - u32 *source; - u32 x_offset; - u32 y_offset; - u32 width; - u32 height; -}; - -enum { - FB_TYPE_YUV, - FB_TYPE_RGB -}; - -struct cmdstring { - int channelnr; - uint16_t prestringlen; - uint16_t poststringlen; - uint16_t format; - uint16_t reserved; - uint16_t startaddr_low; - uint16_t startaddr_high; - uint16_t pixdatlen_low; - uint16_t pixdatlen_high; - u32 precmd[MAX_NR_PRESTRINGS]; - u32 postcmd[MAX_NR_POSTSTRINGS]; - -}; - -struct dumchannel { - int channelnr; - int dum_ch_min; - int dum_ch_max; - int dum_ch_conf; - int dum_ch_stat; - int dum_ch_ctrl; -}; - -int pnx4008_alloc_dum_channel(int dev_id); -int pnx4008_free_dum_channel(int channr, int dev_id); - -int pnx4008_get_dum_channel_uf(struct dumchannel_uf *pChan_uf, int dev_id); -int pnx4008_put_dum_channel_uf(struct dumchannel_uf chan_uf, int dev_id); - -int pnx4008_set_dum_channel_sync(int channr, int val, int dev_id); -int pnx4008_set_dum_channel_dirty_detect(int channr, int val, int dev_id); - -int pnx4008_force_dum_update_channel(int channr, int dev_id); - -int pnx4008_get_dum_channel_config(int channr, int dev_id); - -int pnx4008_sdum_mmap(struct fb_info *info, struct vm_area_struct *vma, struct device *dev); -int pnx4008_set_dum_exit_notification(int dev_id); - -int pnx4008_get_fb_addresses(int fb_type, void **virt_addr, - dma_addr_t * phys_addr, int *fb_length); diff --git a/drivers/video/ps3fb.c b/drivers/video/ps3fb.c index 213fbbcf613b..26d321dbb5bf 100644 --- a/drivers/video/ps3fb.c +++ b/drivers/video/ps3fb.c @@ -1035,6 +1035,7 @@ static int __devinit ps3fb_probe(struct ps3_system_bus_device *dev) if (status) { dev_err(&dev->core, "%s: lv1_gpu_memory_allocate failed: %d\n", __func__, status); + retval = -ENOMEM; goto err_close_device; } dev_dbg(&dev->core, "ddr:lpar:0x%llx\n", ddr_lpar); @@ -1047,6 +1048,7 @@ static int __devinit ps3fb_probe(struct ps3_system_bus_device *dev) dev_err(&dev->core, "%s: lv1_gpu_context_allocate failed: %d\n", __func__, status); + retval = -ENOMEM; goto err_gpu_memory_free; } @@ -1054,6 +1056,7 @@ static int __devinit ps3fb_probe(struct ps3_system_bus_device *dev) dinfo = (void __force *)ioremap(lpar_driver_info, 128 * 1024); if (!dinfo) { dev_err(&dev->core, "%s: ioremap failed\n", __func__); + retval = -ENOMEM; goto err_gpu_context_free; } @@ -1122,8 +1125,10 @@ static int __devinit ps3fb_probe(struct ps3_system_bus_device *dev) } info = framebuffer_alloc(sizeof(struct ps3fb_par), &dev->core); - if (!info) + if (!info) { + retval = -ENOMEM; goto err_context_fb_close; + } par = info->par; par->mode_id = ~ps3fb_mode; /* != ps3fb_mode, to trigger change */ diff --git a/drivers/video/s3c-fb.c b/drivers/video/s3c-fb.c index 69bf9d07c237..2ed7b633bbd9 100644 --- a/drivers/video/s3c-fb.c +++ b/drivers/video/s3c-fb.c @@ -25,8 +25,8 @@ #include <linux/interrupt.h> #include <linux/pm_runtime.h> +#include <video/samsung_fimd.h> #include <mach/map.h> -#include <plat/regs-fb-v4.h> #include <plat/fb.h> /* This driver will export a number of framebuffer interfaces depending @@ -1398,35 +1398,28 @@ static int __devinit s3c_fb_probe(struct platform_device *pdev) spin_lock_init(&sfb->slock); - sfb->bus_clk = clk_get(dev, "lcd"); + sfb->bus_clk = devm_clk_get(dev, "lcd"); if (IS_ERR(sfb->bus_clk)) { dev_err(dev, "failed to get bus clock\n"); - ret = PTR_ERR(sfb->bus_clk); - goto err_sfb; + return PTR_ERR(sfb->bus_clk); } - clk_enable(sfb->bus_clk); + clk_prepare_enable(sfb->bus_clk); if (!sfb->variant.has_clksel) { - sfb->lcd_clk = clk_get(dev, "sclk_fimd"); + sfb->lcd_clk = devm_clk_get(dev, "sclk_fimd"); if (IS_ERR(sfb->lcd_clk)) { dev_err(dev, "failed to get lcd clock\n"); ret = PTR_ERR(sfb->lcd_clk); goto err_bus_clk; } - clk_enable(sfb->lcd_clk); + clk_prepare_enable(sfb->lcd_clk); } pm_runtime_enable(sfb->dev); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(dev, "failed to find registers\n"); - ret = -ENOENT; - goto err_lcd_clk; - } - sfb->regs = devm_request_and_ioremap(dev, res); if (!sfb->regs) { dev_err(dev, "failed to map registers\n"); @@ -1510,16 +1503,12 @@ err_pm_runtime: err_lcd_clk: pm_runtime_disable(sfb->dev); - if (!sfb->variant.has_clksel) { - clk_disable(sfb->lcd_clk); - clk_put(sfb->lcd_clk); - } + if (!sfb->variant.has_clksel) + clk_disable_unprepare(sfb->lcd_clk); err_bus_clk: - clk_disable(sfb->bus_clk); - clk_put(sfb->bus_clk); + clk_disable_unprepare(sfb->bus_clk); -err_sfb: return ret; } @@ -1541,13 +1530,10 @@ static int __devexit s3c_fb_remove(struct platform_device *pdev) if (sfb->windows[win]) s3c_fb_release_win(sfb, sfb->windows[win]); - if (!sfb->variant.has_clksel) { - clk_disable(sfb->lcd_clk); - clk_put(sfb->lcd_clk); - } + if (!sfb->variant.has_clksel) + clk_disable_unprepare(sfb->lcd_clk); - clk_disable(sfb->bus_clk); - clk_put(sfb->bus_clk); + clk_disable_unprepare(sfb->bus_clk); pm_runtime_put_sync(sfb->dev); pm_runtime_disable(sfb->dev); @@ -1575,9 +1561,9 @@ static int s3c_fb_suspend(struct device *dev) } if (!sfb->variant.has_clksel) - clk_disable(sfb->lcd_clk); + clk_disable_unprepare(sfb->lcd_clk); - clk_disable(sfb->bus_clk); + clk_disable_unprepare(sfb->bus_clk); pm_runtime_put_sync(sfb->dev); @@ -1595,10 +1581,10 @@ static int s3c_fb_resume(struct device *dev) pm_runtime_get_sync(sfb->dev); - clk_enable(sfb->bus_clk); + clk_prepare_enable(sfb->bus_clk); if (!sfb->variant.has_clksel) - clk_enable(sfb->lcd_clk); + clk_prepare_enable(sfb->lcd_clk); /* setup gpio and output polarity controls */ pd->setup_gpio(); @@ -1654,9 +1640,9 @@ static int s3c_fb_runtime_suspend(struct device *dev) struct s3c_fb *sfb = platform_get_drvdata(pdev); if (!sfb->variant.has_clksel) - clk_disable(sfb->lcd_clk); + clk_disable_unprepare(sfb->lcd_clk); - clk_disable(sfb->bus_clk); + clk_disable_unprepare(sfb->bus_clk); return 0; } @@ -1667,10 +1653,10 @@ static int s3c_fb_runtime_resume(struct device *dev) struct s3c_fb *sfb = platform_get_drvdata(pdev); struct s3c_fb_platdata *pd = sfb->pdata; - clk_enable(sfb->bus_clk); + clk_prepare_enable(sfb->bus_clk); if (!sfb->variant.has_clksel) - clk_enable(sfb->lcd_clk); + clk_prepare_enable(sfb->lcd_clk); /* setup gpio and output polarity controls */ pd->setup_gpio(); diff --git a/drivers/video/s3c2410fb.c b/drivers/video/s3c2410fb.c index 77f34c614c86..1083bb9469ee 100644 --- a/drivers/video/s3c2410fb.c +++ b/drivers/video/s3c2410fb.c @@ -11,6 +11,8 @@ * Driver based on skeletonfb.c, sa1100fb.c and others. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include <linux/module.h> #include <linux/kernel.h> #include <linux/err.h> @@ -48,7 +50,11 @@ static int debug = 1; static int debug; #endif -#define dprintk(msg...) if (debug) printk(KERN_DEBUG "s3c2410fb: " msg); +#define dprintk(msg...) \ +do { \ + if (debug) \ + pr_debug(msg); \ +} while (0) /* useful functions */ @@ -598,11 +604,11 @@ static int s3c2410fb_debug_store(struct device *dev, if (strnicmp(buf, "on", 2) == 0 || strnicmp(buf, "1", 1) == 0) { debug = 1; - printk(KERN_DEBUG "s3c2410fb: Debug On"); + dev_dbg(dev, "s3c2410fb: Debug On"); } else if (strnicmp(buf, "off", 3) == 0 || strnicmp(buf, "0", 1) == 0) { debug = 0; - printk(KERN_DEBUG "s3c2410fb: Debug Off"); + dev_dbg(dev, "s3c2410fb: Debug Off"); } else { return -EINVAL; } @@ -921,7 +927,7 @@ static int __devinit s3c24xxfb_probe(struct platform_device *pdev, info->clk = clk_get(NULL, "lcd"); if (IS_ERR(info->clk)) { - printk(KERN_ERR "failed to get lcd clock source\n"); + dev_err(&pdev->dev, "failed to get lcd clock source\n"); ret = PTR_ERR(info->clk); goto release_irq; } @@ -929,7 +935,7 @@ static int __devinit s3c24xxfb_probe(struct platform_device *pdev, clk_enable(info->clk); dprintk("got and enabled clock\n"); - usleep_range(1000, 1000); + usleep_range(1000, 1100); info->clk_rate = clk_get_rate(info->clk); @@ -947,7 +953,7 @@ static int __devinit s3c24xxfb_probe(struct platform_device *pdev, /* Initialize video memory */ ret = s3c2410fb_map_video_memory(fbinfo); if (ret) { - printk(KERN_ERR "Failed to allocate video RAM: %d\n", ret); + dev_err(&pdev->dev, "Failed to allocate video RAM: %d\n", ret); ret = -ENOMEM; goto release_clock; } @@ -970,7 +976,7 @@ static int __devinit s3c24xxfb_probe(struct platform_device *pdev, ret = register_framebuffer(fbinfo); if (ret < 0) { - printk(KERN_ERR "Failed to register framebuffer device: %d\n", + dev_err(&pdev->dev, "Failed to register framebuffer device: %d\n", ret); goto free_cpufreq; } @@ -978,9 +984,9 @@ static int __devinit s3c24xxfb_probe(struct platform_device *pdev, /* create device files */ ret = device_create_file(&pdev->dev, &dev_attr_debug); if (ret) - printk(KERN_ERR "failed to add debug attribute\n"); + dev_err(&pdev->dev, "failed to add debug attribute\n"); - printk(KERN_INFO "fb%d: %s frame buffer device\n", + dev_info(&pdev->dev, "fb%d: %s frame buffer device\n", fbinfo->node, fbinfo->fix.id); return 0; @@ -1028,7 +1034,7 @@ static int __devexit s3c2410fb_remove(struct platform_device *pdev) s3c2410fb_cpufreq_deregister(info); s3c2410fb_lcd_enable(info, 0); - usleep_range(1000, 1000); + usleep_range(1000, 1100); s3c2410fb_unmap_video_memory(fbinfo); @@ -1065,7 +1071,7 @@ static int s3c2410fb_suspend(struct platform_device *dev, pm_message_t state) * the LCD DMA engine is not going to get back on the bus * before the clock goes off again (bjd) */ - usleep_range(1000, 1000); + usleep_range(1000, 1100); clk_disable(info->clk); return 0; @@ -1077,7 +1083,7 @@ static int s3c2410fb_resume(struct platform_device *dev) struct s3c2410fb_info *info = fbinfo->par; clk_enable(info->clk); - usleep_range(1000, 1000); + usleep_range(1000, 1100); s3c2410fb_init_registers(fbinfo); @@ -1134,8 +1140,8 @@ static void __exit s3c2410fb_cleanup(void) module_init(s3c2410fb_init); module_exit(s3c2410fb_cleanup); -MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>, " - "Ben Dooks <ben-linux@fluff.org>"); +MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>"); +MODULE_AUTHOR("Ben Dooks <ben-linux@fluff.org>"); MODULE_DESCRIPTION("Framebuffer driver for the s3c2410"); MODULE_LICENSE("GPL"); MODULE_ALIAS("platform:s3c2410-lcd"); diff --git a/drivers/video/savage/savagefb_driver.c b/drivers/video/savage/savagefb_driver.c index 0d0f52c18fd8..f4f53b082d05 100644 --- a/drivers/video/savage/savagefb_driver.c +++ b/drivers/video/savage/savagefb_driver.c @@ -2266,8 +2266,10 @@ static int __devinit savagefb_probe(struct pci_dev* dev, lpitch = info->var.xres_virtual*((info->var.bits_per_pixel + 7) >> 3); info->var.yres_virtual = info->fix.smem_len/lpitch; - if (info->var.yres_virtual < info->var.yres) + if (info->var.yres_virtual < info->var.yres) { + err = -ENOMEM; goto failed; + } #if defined(CONFIG_FB_SAVAGE_ACCEL) /* diff --git a/drivers/video/sis/initextlfb.c b/drivers/video/sis/initextlfb.c index 9dec64da4015..3ab18f5a3759 100644 --- a/drivers/video/sis/initextlfb.c +++ b/drivers/video/sis/initextlfb.c @@ -65,7 +65,7 @@ sisfb_mode_rate_to_dclock(struct SiS_Private *SiS_Pr, unsigned char modeno, } #endif - if(!(SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex))) {; + if(!(SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex))) { printk(KERN_ERR "Could not find mode %x\n", ModeNo); return 65000; } diff --git a/drivers/video/sunxvr1000.c b/drivers/video/sunxvr1000.c index b7f27acaf817..729a50722bdf 100644 --- a/drivers/video/sunxvr1000.c +++ b/drivers/video/sunxvr1000.c @@ -141,8 +141,10 @@ static int __devinit gfb_probe(struct platform_device *op) gp->fb_base = of_ioremap(&op->resource[6], 0, gp->fb_size, "gfb fb"); - if (!gp->fb_base) + if (!gp->fb_base) { + err = -ENOMEM; goto err_release_fb; + } err = gfb_set_fbinfo(gp); if (err) diff --git a/drivers/video/sunxvr2500.c b/drivers/video/sunxvr2500.c index 5848436c19da..7fbcba86d1a2 100644 --- a/drivers/video/sunxvr2500.c +++ b/drivers/video/sunxvr2500.c @@ -181,8 +181,10 @@ static int __devinit s3d_pci_register(struct pci_dev *pdev, sp->fb_size = info->fix.line_length * sp->height; sp->fb_base = ioremap(sp->fb_base_phys, sp->fb_size); - if (!sp->fb_base) + if (!sp->fb_base) { + err = -ENOMEM; goto err_release_pci; + } err = s3d_set_fbinfo(sp); if (err) diff --git a/drivers/video/sunxvr500.c b/drivers/video/sunxvr500.c index eb931b8626fa..6c71b1b44477 100644 --- a/drivers/video/sunxvr500.c +++ b/drivers/video/sunxvr500.c @@ -298,8 +298,10 @@ static int __devinit e3d_pci_register(struct pci_dev *pdev, goto err_release_fb; } ep->ramdac = ioremap(ep->regs_base_phys + 0x8000, 0x1000); - if (!ep->ramdac) + if (!ep->ramdac) { + err = -ENOMEM; goto err_release_pci1; + } ep->fb8_0_off = readl(ep->ramdac + RAMDAC_VID_8FB_0); ep->fb8_0_off -= ep->fb_base_reg; @@ -343,8 +345,10 @@ static int __devinit e3d_pci_register(struct pci_dev *pdev, ep->fb_size = info->fix.line_length * ep->height; ep->fb_base = ioremap(ep->fb_base_phys, ep->fb_size); - if (!ep->fb_base) + if (!ep->fb_base) { + err = -ENOMEM; goto err_release_pci0; + } err = e3d_set_fbinfo(ep); if (err) diff --git a/drivers/video/udlfb.c b/drivers/video/udlfb.c index 8af64148294b..38fcfff3c911 100644 --- a/drivers/video/udlfb.c +++ b/drivers/video/udlfb.c @@ -647,7 +647,7 @@ static ssize_t dlfb_ops_write(struct fb_info *info, const char __user *buf, result = fb_sys_write(info, buf, count, ppos); if (result > 0) { - int start = max((int)(offset / info->fix.line_length) - 1, 0); + int start = max((int)(offset / info->fix.line_length), 0); int lines = min((u32)((result / info->fix.line_length) + 1), (u32)info->var.yres); diff --git a/drivers/video/uvesafb.c b/drivers/video/uvesafb.c index b0e2a4261afe..2f8f82d874a1 100644 --- a/drivers/video/uvesafb.c +++ b/drivers/video/uvesafb.c @@ -659,6 +659,8 @@ static int __devinit uvesafb_vbe_getedid(struct uvesafb_ktask *task, task->t.flags = TF_BUF_RET | TF_BUF_ESDI; task->t.buf_len = EDID_LENGTH; task->buf = kzalloc(EDID_LENGTH, GFP_KERNEL); + if (!task->buf) + return -ENOMEM; err = uvesafb_exec(task); diff --git a/drivers/video/vermilion/vermilion.c b/drivers/video/vermilion/vermilion.c index 970e43d13f52..083f0c844892 100644 --- a/drivers/video/vermilion/vermilion.c +++ b/drivers/video/vermilion/vermilion.c @@ -1168,8 +1168,7 @@ void vmlfb_unregister_subsys(struct vml_sys *sys) list_for_each_entry_safe(entry, next, &global_has_mode, head) { printk(KERN_DEBUG MODULE_NAME ": subsys disable pipe\n"); vmlfb_disable_pipe(entry); - list_del(&entry->head); - list_add_tail(&entry->head, &global_no_mode); + list_move_tail(&entry->head, &global_no_mode); } mutex_unlock(&vml_mutex); } diff --git a/drivers/video/via/via_clock.c b/drivers/video/via/via_clock.c index af8f26b643c1..db1e39277e32 100644 --- a/drivers/video/via/via_clock.c +++ b/drivers/video/via/via_clock.c @@ -25,6 +25,7 @@ #include <linux/kernel.h> #include <linux/via-core.h> +#include <asm/olpc.h> #include "via_clock.h" #include "global.h" #include "debug.h" @@ -289,6 +290,10 @@ static void dummy_set_pll(struct via_pll_config config) printk(KERN_INFO "Using undocumented set PLL.\n%s", via_slap); } +static void noop_set_clock_state(u8 state) +{ +} + void via_clock_init(struct via_clock *clock, int gfx_chip) { switch (gfx_chip) { @@ -346,4 +351,18 @@ void via_clock_init(struct via_clock *clock, int gfx_chip) break; } + + if (machine_is_olpc()) { + /* The OLPC XO-1.5 cannot suspend/resume reliably if the + * IGA1/IGA2 clocks are set as on or off (memory rot + * occasionally happens during suspend under such + * configurations). + * + * The only known stable scenario is to leave this bits as-is, + * which in their default states are documented to enable the + * clock only when it is needed. + */ + clock->set_primary_clock_state = noop_set_clock_state; + clock->set_secondary_clock_state = noop_set_clock_state; + } } |