aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/samsung_duallcd/s3cfb2_fimd4x.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/samsung_duallcd/s3cfb2_fimd4x.c')
-rw-r--r--drivers/video/samsung_duallcd/s3cfb2_fimd4x.c558
1 files changed, 0 insertions, 558 deletions
diff --git a/drivers/video/samsung_duallcd/s3cfb2_fimd4x.c b/drivers/video/samsung_duallcd/s3cfb2_fimd4x.c
deleted file mode 100644
index 2adcee2..0000000
--- a/drivers/video/samsung_duallcd/s3cfb2_fimd4x.c
+++ /dev/null
@@ -1,558 +0,0 @@
-/* linux/drivers/video/samsung/s3cfb2_fimd4x.c
- *
- * Register interface file for Samsung Display Controller (FIMD) driver
- *
- * Jinsung Yang, Copyright (c) 2009 Samsung Electronics
- * http://www.samsungsemi.com/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/delay.h>
-#include <linux/device.h>
-#include <linux/fb.h>
-#include <linux/io.h>
-#include <mach/map.h>
-#include <plat/clock.h>
-#include <plat/fb.h>
-#include <plat/regs-fb.h>
-
-#include "s3cfb2.h"
-
-void s3cfb_check_line_count(struct s3cfb_global *ctrl)
-{
- int timeout = 30 * 5300;
- int i = 0;
-
- do {
- if (!(readl(ctrl->regs + S3C_VIDCON1) & 0x7ff0000))
- break;
- i++;
- } while (i < timeout);
-
- if (i == timeout) {
- dev_err(ctrl->dev, "line count mismatch\n");
- s3cfb_display_on(ctrl);
- }
-}
-
-int s3cfb_set_output(struct s3cfb_global *ctrl)
-{
- unsigned int cfg;
-
- cfg = readl(ctrl->regs + S3C_VIDCON0);
- cfg &= ~S3C_VIDCON0_VIDOUT_MASK;
-
- if (ctrl->output == OUTPUT_RGB)
- cfg |= S3C_VIDCON0_VIDOUT_RGB;
- else if (ctrl->output == OUTPUT_ITU)
- cfg |= S3C_VIDCON0_VIDOUT_ITU;
- else if (ctrl->output == OUTPUT_I80LDI0)
- cfg |= S3C_VIDCON0_VIDOUT_I80LDI0;
- else if (ctrl->output == OUTPUT_I80LDI1)
- cfg |= S3C_VIDCON0_VIDOUT_I80LDI1;
- else {
- dev_err(ctrl->dev, "invalid output type: %d\n", ctrl->output);
- return -EINVAL;
- }
-
- writel(cfg, ctrl->regs + S3C_VIDCON0);
-
- return 0;
-}
-
-int s3cfb_set_display_mode(struct s3cfb_global *ctrl)
-{
- unsigned int cfg;
-
- cfg = readl(ctrl->regs + S3C_VIDCON0);
- cfg &= ~S3C_VIDCON0_PNRMODE_MASK;
- cfg |= (ctrl->rgb_mode << S3C_VIDCON0_PNRMODE_SHIFT);
- writel(cfg, ctrl->regs + S3C_VIDCON0);
-
- return 0;
-}
-
-int s3cfb_display_on(struct s3cfb_global *ctrl)
-{
- unsigned int cfg;
-
- cfg = readl(ctrl->regs + S3C_VIDCON0);
- cfg |= (S3C_VIDCON0_ENVID_ENABLE | S3C_VIDCON0_ENVID_F_ENABLE);
- writel(cfg, ctrl->regs + S3C_VIDCON0);
-
- dev_dbg(ctrl->dev, "global display is on\n");
-
- return 0;
-}
-
-int s3cfb_display_off(struct s3cfb_global *ctrl)
-{
- unsigned int cfg;
-
- cfg = readl(ctrl->regs + S3C_VIDCON0);
- cfg &= ~S3C_VIDCON0_ENVID_ENABLE;
- writel(cfg, ctrl->regs + S3C_VIDCON0);
-
- cfg &= ~S3C_VIDCON0_ENVID_F_ENABLE;
- writel(cfg, ctrl->regs + S3C_VIDCON0);
-
- dev_dbg(ctrl->dev, "global display is off\n");
-
- return 0;
-}
-
-int s3cfb_frame_off(struct s3cfb_global *ctrl)
-{
- unsigned int cfg;
-
- cfg = readl(ctrl->regs + S3C_VIDCON0);
- cfg &= ~S3C_VIDCON0_ENVID_F_ENABLE;
- writel(cfg, ctrl->regs + S3C_VIDCON0);
-
- dev_dbg(ctrl->dev, "current frame display is off\n");
-
- return 0;
-}
-
-int s3cfb_set_clock(struct s3cfb_global *ctrl)
-{
- struct s3c_platform_fb *pdata = to_fb_plat(ctrl->dev);
- unsigned int cfg, maxclk, src_clk, vclk, div;
-
- maxclk = 66 * 1000000;
-
- /* fixed clock source: hclk */
- cfg = readl(ctrl->regs + S3C_VIDCON0);
- cfg &= ~(S3C_VIDCON0_CLKSEL_MASK | S3C_VIDCON0_CLKVALUP_MASK |
- S3C_VIDCON0_VCLKEN_MASK | S3C_VIDCON0_CLKDIR_MASK);
- cfg |= (S3C_VIDCON0_CLKSEL_HCLK | S3C_VIDCON0_CLKVALUP_ALWAYS |
- S3C_VIDCON0_VCLKEN_NORMAL | S3C_VIDCON0_CLKDIR_DIVIDED);
-
- src_clk = ctrl->clock->parent->rate;
- vclk = ctrl->fb[pdata->default_win]->var.pixclock;
-
- if (vclk > maxclk)
- vclk = maxclk;
-
- div = src_clk / vclk;
- if (src_clk % vclk)
- div++;
-
- cfg |= S3C_VIDCON0_CLKVAL_F(div - 1);
- writel(cfg, ctrl->regs + S3C_VIDCON0);
-
- dev_dbg(ctrl->dev, "parent clock: %d, vclk: %d, vclk div: %d\n",
- src_clk, vclk, div);
-
- return 0;
-}
-
-int s3cfb_set_polarity(struct s3cfb_global *ctrl)
-{
- struct s3cfb_lcd_polarity *pol;
- unsigned int cfg;
-
- pol = &ctrl->lcd->polarity;
- cfg = 0;
-
- if (pol->rise_vclk)
- cfg |= S3C_VIDCON1_IVCLK_RISING_EDGE;
-
- if (pol->inv_hsync)
- cfg |= S3C_VIDCON1_IHSYNC_INVERT;
-
- if (pol->inv_vsync)
- cfg |= S3C_VIDCON1_IVSYNC_INVERT;
-
- if (pol->inv_vden)
- cfg |= S3C_VIDCON1_IVDEN_INVERT;
-
- writel(cfg, ctrl->regs + S3C_VIDCON1);
-
- return 0;
-}
-
-int s3cfb_set_timing(struct s3cfb_global *ctrl)
-{
- struct s3cfb_lcd_timing *time;
- unsigned int cfg;
-
- time = &ctrl->lcd->timing;
- cfg = 0;
-
- cfg |= S3C_VIDTCON0_VBPDE(time->v_bpe - 1);
- cfg |= S3C_VIDTCON0_VBPD(time->v_bp - 1);
- cfg |= S3C_VIDTCON0_VFPD(time->v_fp - 1);
- cfg |= S3C_VIDTCON0_VSPW(time->v_sw - 1);
-
- writel(cfg, ctrl->regs + S3C_VIDTCON0);
-
- cfg = 0;
-
- cfg |= S3C_VIDTCON1_VFPDE(time->v_fpe - 1);
- cfg |= S3C_VIDTCON1_HBPD(time->h_bp - 1);
- cfg |= S3C_VIDTCON1_HFPD(time->h_fp - 1);
- cfg |= S3C_VIDTCON1_HSPW(time->h_sw - 1);
-
- writel(cfg, ctrl->regs + S3C_VIDTCON1);
-
- return 0;
-}
-
-int s3cfb_set_lcd_size(struct s3cfb_global *ctrl)
-{
- unsigned int cfg = 0;
-
- cfg |= S3C_VIDTCON2_HOZVAL(ctrl->lcd->width - 1);
- cfg |= S3C_VIDTCON2_LINEVAL(ctrl->lcd->height - 1);
-
- writel(cfg, ctrl->regs + S3C_VIDTCON2);
-
- return 0;
-}
-
-int s3cfb_set_global_interrupt(struct s3cfb_global *ctrl, int enable)
-{
- unsigned int cfg = 0;
-
- cfg = readl(ctrl->regs + S3C_VIDINTCON0);
- cfg &= ~(S3C_VIDINTCON0_INTFRMEN_ENABLE |
- S3C_VIDINTCON0_INT_ENABLE);
-
- if (enable) {
- dev_dbg(ctrl->dev, "video interrupt is on\n");
- cfg |= (S3C_VIDINTCON0_INTFRMEN_ENABLE |
- S3C_VIDINTCON0_INT_ENABLE);
- } else {
- dev_dbg(ctrl->dev, "video interrupt is off\n");
- cfg |= (S3C_VIDINTCON0_INTFRMEN_DISABLE |
- S3C_VIDINTCON0_INT_DISABLE);
- }
-
- writel(cfg, ctrl->regs + S3C_VIDINTCON0);
-
- return 0;
-}
-
-int s3cfb_set_vsync_interrupt(struct s3cfb_global *ctrl, int enable)
-{
- unsigned int cfg = 0;
-
- cfg = readl(ctrl->regs + S3C_VIDINTCON0);
- cfg &= ~S3C_VIDINTCON0_FRAMESEL0_MASK;
-
- if (enable) {
- dev_dbg(ctrl->dev, "vsync interrupt is on\n");
- cfg |= S3C_VIDINTCON0_FRAMESEL0_VSYNC;
- } else {
- dev_dbg(ctrl->dev, "vsync interrupt is off\n");
- cfg &= ~S3C_VIDINTCON0_FRAMESEL0_VSYNC;
- }
-
- writel(cfg, ctrl->regs + S3C_VIDINTCON0);
-
- return 0;
-}
-
-#ifdef CONFIG_FB_S3C_V2_TRACE_UNDERRUN
-int s3cfb_set_fifo_interrupt(struct s3cfb_global *ctrl, int enable)
-{
- unsigned int cfg = 0;
-
- cfg = readl(ctrl->regs + S3C_VIDINTCON0);
-
- cfg &= ~(S3C_VIDINTCON0_FIFOSEL_MASK | S3C_VIDINTCON0_FIFOLEVEL_MASK);
- cfg |= (S3C_VIDINTCON0_FIFOSEL_ALL | S3C_VIDINTCON0_FIFOLEVEL_EMPTY);
-
- if (enable) {
- dev_dbg(ctrl->dev, "fifo interrupt is on\n");
- cfg |= (S3C_VIDINTCON0_INTFIFO_ENABLE |
- S3C_VIDINTCON0_INT_ENABLE);
- } else {
- dev_dbg(ctrl->dev, "fifo interrupt is off\n");
- cfg &= ~(S3C_VIDINTCON0_INTFIFO_ENABLE |
- S3C_VIDINTCON0_INT_ENABLE);
- }
-
- writel(cfg, ctrl->regs + S3C_VIDINTCON0);
-
- return 0;
-}
-#endif
-
-int s3cfb_clear_interrupt(struct s3cfb_global *ctrl)
-{
- unsigned int cfg = 0;
-
- cfg = readl(ctrl->regs + S3C_VIDINTCON1);
-
- if (cfg & S3C_VIDINTCON1_INTFIFOPEND)
- info("fifo underrun occur\n");
-
- cfg |= (S3C_VIDINTCON1_INTVPPEND | S3C_VIDINTCON1_INTI80PEND |
- S3C_VIDINTCON1_INTFRMPEND | S3C_VIDINTCON1_INTFIFOPEND);
-
- writel(cfg, ctrl->regs + S3C_VIDINTCON1);
-
- return 0;
-}
-
-int s3cfb_window_on(struct s3cfb_global *ctrl, int id)
-{
- unsigned int cfg;
-
- cfg = readl(ctrl->regs + S3C_WINCON(id));
- cfg |= S3C_WINCON_ENWIN_ENABLE;
- writel(cfg, ctrl->regs + S3C_WINCON(id));
-
- dev_dbg(ctrl->dev, "[fb%d] turn on\n", id);
-
- return 0;
-}
-
-int s3cfb_window_off(struct s3cfb_global *ctrl, int id)
-{
- unsigned int cfg;
-
- cfg = readl(ctrl->regs + S3C_WINCON(id));
- cfg &= ~S3C_WINCON_ENWIN_ENABLE;
- writel(cfg, ctrl->regs + S3C_WINCON(id));
-
- dev_dbg(ctrl->dev, "[fb%d] turn off\n", id);
-
- return 0;
-}
-
-int s3cfb_set_window_control(struct s3cfb_global *ctrl, int id)
-{
- struct s3c_platform_fb *pdata = to_fb_plat(ctrl->dev);
- struct fb_info *fb = ctrl->fb[id];
- struct fb_var_screeninfo *var = &fb->var;
- struct s3cfb_window *win = fb->par;
- unsigned int cfg;
-
- cfg = readl(ctrl->regs + S3C_WINCON(id));
-
- cfg &= ~(S3C_WINCON_BITSWP_ENABLE | S3C_WINCON_BYTESWP_ENABLE |
- S3C_WINCON_HAWSWP_ENABLE | S3C_WINCON_WSWP_ENABLE |
- S3C_WINCON_BURSTLEN_MASK | S3C_WINCON_BPPMODE_MASK |
- S3C_WINCON_INRGB_MASK | S3C_WINCON_DATAPATH_MASK);
-
- if (win->path == DATA_PATH_FIFO) {
- dev_dbg(ctrl->dev, "[fb%d] data path: fifo\n", id);
-
- cfg |= S3C_WINCON_DATAPATH_LOCAL;
- cfg |= S3C_WINCON_INRGB_RGB;
- cfg |= S3C_WINCON_BPPMODE_24BPP_888;
-
- if (id == 1) {
- cfg &= ~S3C_WINCON1_LOCALSEL_MASK;
-
- if (win->local_channel == 0)
- cfg |= S3C_WINCON1_LOCALSEL_TV;
- else
- cfg |= S3C_WINCON1_LOCALSEL_FIMC1;
- }
- } else {
- dev_dbg(ctrl->dev, "[fb%d] data path: dma\n", id);
-
- cfg |= S3C_WINCON_DATAPATH_DMA;
-
- if (fb->var.bits_per_pixel == 16 && pdata->swap & FB_SWAP_HWORD)
- cfg |= S3C_WINCON_HAWSWP_ENABLE;
-
- if (fb->var.bits_per_pixel == 32 && pdata->swap & FB_SWAP_WORD)
- cfg |= S3C_WINCON_WSWP_ENABLE;
-
- /* dma burst */
- if (win->dma_burst == 4)
- cfg |= S3C_WINCON_BURSTLEN_4WORD;
- else if (win->dma_burst == 8)
- cfg |= S3C_WINCON_BURSTLEN_8WORD;
- else
- cfg |= S3C_WINCON_BURSTLEN_16WORD;
-
- /* bpp mode set */
- switch (fb->var.bits_per_pixel) {
- case 16:
- if (var->transp.length == 1) {
- dev_dbg(ctrl->dev,
- "[fb%d] bpp mode: A1-R5-G5-B5\n", id);
- cfg |= S3C_WINCON_BPPMODE_16BPP_A555;
- } else if (var->transp.length == 4) {
- dev_dbg(ctrl->dev,
- "[fb%d] bpp mode: A4-R4-G4-B4\n", id);
- cfg |= S3C_WINCON_BPPMODE_16BPP_A444;
- } else {
- dev_dbg(ctrl->dev,
- "[fb%d] bpp mode: R5-G6-B5\n", id);
- cfg |= S3C_WINCON_BPPMODE_16BPP_565;
- }
- break;
-
- case 24: /* packed 24 bpp: nothing to do for 4.x fimd */
- break;
-
- case 32:
- if (var->transp.length == 0) {
- dev_dbg(ctrl->dev,
- "[fb%d] bpp mode: R8-G8-B8\n", id);
- cfg |= S3C_WINCON_BPPMODE_24BPP_888;
- } else {
- dev_dbg(ctrl->dev,
- "[fb%d] bpp mode: A4-R8-G8-B8\n", id);
- cfg |= S3C_WINCON_BPPMODE_28BPP_A888;
- }
- break;
- }
- }
-
- writel(cfg, ctrl->regs + S3C_WINCON(id));
-
- return 0;
-}
-
-int s3cfb_set_buffer_address(struct s3cfb_global *ctrl, int id)
-{
- struct fb_fix_screeninfo *fix = &ctrl->fb[id]->fix;
- struct fb_var_screeninfo *var = &ctrl->fb[id]->var;
- dma_addr_t start_addr = 0, end_addr = 0;
-
- if (fix->smem_start) {
- start_addr = fix->smem_start + (var->xres_virtual *
- (var->bits_per_pixel / 8) * var->yoffset);
-
- end_addr = start_addr + (var->xres_virtual *
- (var->bits_per_pixel / 8) * var->yres);
- }
-
- writel(start_addr, ctrl->regs + S3C_VIDADDR_START0(id));
- writel(end_addr, ctrl->regs + S3C_VIDADDR_END0(id));
-
- dev_dbg(ctrl->dev, "[fb%d] start_addr: 0x%08x, end_addr: 0x%08x\n",
- id, start_addr, end_addr);
-
- return 0;
-}
-
-int s3cfb_set_alpha_blending(struct s3cfb_global *ctrl, int id)
-{
- struct s3cfb_window *win = ctrl->fb[id]->par;
- struct s3cfb_alpha *alpha = &win->alpha;
- unsigned int avalue = 0, cfg;
-
- if (id == 0) {
- dev_err(ctrl->dev, "[fb%d] does not support alpha blending\n", id);
- return -EINVAL;
- }
-
- cfg = readl(ctrl->regs + S3C_WINCON(id));
- cfg &= ~(S3C_WINCON_BLD_MASK | S3C_WINCON_ALPHA_SEL_MASK);
-
- if (alpha->mode == PIXEL_BLENDING) {
- dev_dbg(ctrl->dev, "[fb%d] alpha mode: pixel blending\n", id);
-
- /* fixing to DATA[31:24] for alpha value */
- cfg |= (S3C_WINCON_BLD_PIXEL | S3C_WINCON_ALPHA1_SEL);
- } else {
- dev_dbg(ctrl->dev, "[fb%d] alpha mode: plane %d blending\n",
- id, alpha->channel);
-
- cfg |= S3C_WINCON_BLD_PLANE;
-
- if (alpha->channel == 0) {
- cfg |= S3C_WINCON_ALPHA0_SEL;
- avalue = (alpha->value << S3C_VIDOSD_ALPHA0_SHIFT);
- } else {
- cfg |= S3C_WINCON_ALPHA1_SEL;
- avalue = (alpha->value << S3C_VIDOSD_ALPHA1_SHIFT);
- }
- }
-
- writel(cfg, ctrl->regs + S3C_WINCON(id));
- writel(avalue, ctrl->regs + S3C_VIDOSD_C(id));
-
- return 0;
-}
-
-int s3cfb_set_window_position(struct s3cfb_global *ctrl, int id)
-{
- struct fb_var_screeninfo *var = &ctrl->fb[id]->var;
- struct s3cfb_window *win = ctrl->fb[id]->par;
- unsigned int cfg;
-
- cfg = S3C_VIDOSD_LEFT_X(win->x) | S3C_VIDOSD_TOP_Y(win->y);
- writel(cfg, ctrl->regs + S3C_VIDOSD_A(id));
-
- cfg = S3C_VIDOSD_RIGHT_X(win->x + var->xres - 1) |
- S3C_VIDOSD_BOTTOM_Y(win->y + var->yres - 1);
-
- writel(cfg, ctrl->regs + S3C_VIDOSD_B(id));
-
- dev_dbg(ctrl->dev, "[fb%d] offset: (%d, %d, %d, %d)\n", id,
- win->x, win->y, win->x + var->xres - 1, win->y + var->yres - 1);
-
- return 0;
-}
-
-int s3cfb_set_window_size(struct s3cfb_global *ctrl, int id)
-{
- struct fb_var_screeninfo *var = &ctrl->fb[id]->var;
- unsigned int cfg;
-
- if (id > 2)
- return 0;
-
- cfg = S3C_VIDOSD_SIZE(var->xres * var->yres);
-
- if (id == 0)
- writel(cfg, ctrl->regs + S3C_VIDOSD_C(id));
- else
- writel(cfg, ctrl->regs + S3C_VIDOSD_D(id));
-
- dev_dbg(ctrl->dev, "[fb%d] resolution: %d x %d\n", id,
- var->xres, var->yres);
-
- return 0;
-}
-
-int s3cfb_set_buffer_size(struct s3cfb_global *ctrl, int id)
-{
- struct fb_fix_screeninfo *fix = &ctrl->fb[id]->fix;
- unsigned int cfg = 0;
-
- cfg = S3C_VIDADDR_PAGEWIDTH(fix->line_length);
- writel(cfg, ctrl->regs + S3C_VIDADDR_SIZE(id));
-
- return 0;
-}
-
-int s3cfb_set_chroma_key(struct s3cfb_global *ctrl, int id)
-{
- struct s3cfb_window *win = ctrl->fb[id]->par;
- struct s3cfb_chroma *chroma = &win->chroma;
- unsigned int cfg = 0;
-
- if (id == 0) {
- dev_err(ctrl->dev, "[fb%d] does not support chroma key\n", id);
- return -EINVAL;
- }
-
- cfg = (S3C_KEYCON0_KEYBLEN_DISABLE | S3C_KEYCON0_DIRCON_MATCH_FG);
-
- if (chroma->enabled)
- cfg |= S3C_KEYCON0_KEY_ENABLE;
-
- writel(cfg, ctrl->regs + S3C_KEYCON(id));
-
- cfg = S3C_KEYCON1_COLVAL(chroma->key);
- writel(cfg, ctrl->regs + S3C_KEYVAL(id));
-
- dev_dbg(ctrl->dev, "[fb%d] chroma key: 0x%08x, %s\n", id, cfg,
- chroma->enabled ? "enabled" : "disabled");
-
- return 0;
-}