2010-08-03 16:50:29 +04:00
/*
* Register interface file for Samsung Camera Interface ( FIMC ) driver
*
2012-04-25 13:55:42 +04:00
* Copyright ( C ) 2010 - 2012 Samsung Electronics Co . , Ltd .
* Sylwester Nawrocki , < s . nawrocki @ samsung . com >
2010-08-03 16:50:29 +04:00
*
* 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/io.h>
# include <linux/delay.h>
2010-12-27 20:42:15 +03:00
# include <media/s5p_fimc.h>
2010-08-03 16:50:29 +04:00
2012-05-02 13:14:49 +04:00
# include "fimc-reg.h"
2010-08-03 16:50:29 +04:00
# include "fimc-core.h"
void fimc_hw_reset ( struct fimc_dev * dev )
{
u32 cfg ;
2012-05-02 13:14:49 +04:00
cfg = readl ( dev - > regs + FIMC_REG_CISRCFMT ) ;
cfg | = FIMC_REG_CISRCFMT_ITU601_8BIT ;
writel ( cfg , dev - > regs + FIMC_REG_CISRCFMT ) ;
2010-08-03 16:50:29 +04:00
/* Software reset. */
2012-05-02 13:14:49 +04:00
cfg = readl ( dev - > regs + FIMC_REG_CIGCTRL ) ;
cfg | = ( FIMC_REG_CIGCTRL_SWRST | FIMC_REG_CIGCTRL_IRQ_LEVEL ) ;
writel ( cfg , dev - > regs + FIMC_REG_CIGCTRL ) ;
2011-09-02 13:25:32 +04:00
udelay ( 10 ) ;
2010-08-03 16:50:29 +04:00
2012-05-02 13:14:49 +04:00
cfg = readl ( dev - > regs + FIMC_REG_CIGCTRL ) ;
cfg & = ~ FIMC_REG_CIGCTRL_SWRST ;
writel ( cfg , dev - > regs + FIMC_REG_CIGCTRL ) ;
2011-10-05 21:20:45 +04:00
if ( dev - > variant - > out_buf_count > 4 )
fimc_hw_set_dma_seq ( dev , 0xF ) ;
2010-08-03 16:50:29 +04:00
}
2010-12-27 20:47:32 +03:00
static u32 fimc_hw_get_in_flip ( struct fimc_ctx * ctx )
2010-08-03 16:50:29 +04:00
{
2012-05-02 13:14:49 +04:00
u32 flip = FIMC_REG_MSCTRL_FLIP_NORMAL ;
2010-08-03 16:50:29 +04:00
2011-08-25 02:25:10 +04:00
if ( ctx - > hflip )
2012-05-02 13:14:49 +04:00
flip = FIMC_REG_MSCTRL_FLIP_Y_MIRROR ;
2012-11-26 18:08:26 +04:00
if ( ctx - > vflip )
flip = FIMC_REG_MSCTRL_FLIP_X_MIRROR ;
2011-08-25 02:25:10 +04:00
2010-12-27 20:47:32 +03:00
if ( ctx - > rotation < = 90 )
return flip ;
2010-08-03 16:50:29 +04:00
2012-05-02 13:14:49 +04:00
return ( flip ^ FIMC_REG_MSCTRL_FLIP_180 ) & FIMC_REG_MSCTRL_FLIP_180 ;
2010-08-03 16:50:29 +04:00
}
2010-12-27 20:47:32 +03:00
static u32 fimc_hw_get_target_flip ( struct fimc_ctx * ctx )
2010-08-03 16:50:29 +04:00
{
2012-05-02 13:14:49 +04:00
u32 flip = FIMC_REG_CITRGFMT_FLIP_NORMAL ;
2010-08-03 16:50:29 +04:00
2011-08-25 02:25:10 +04:00
if ( ctx - > hflip )
2012-05-02 13:14:49 +04:00
flip | = FIMC_REG_CITRGFMT_FLIP_Y_MIRROR ;
2012-11-26 18:08:26 +04:00
if ( ctx - > vflip )
flip | = FIMC_REG_CITRGFMT_FLIP_X_MIRROR ;
2011-08-25 02:25:10 +04:00
2010-12-27 20:47:32 +03:00
if ( ctx - > rotation < = 90 )
return flip ;
2012-05-02 13:14:49 +04:00
return ( flip ^ FIMC_REG_CITRGFMT_FLIP_180 ) & FIMC_REG_CITRGFMT_FLIP_180 ;
2010-08-03 16:50:29 +04:00
}
2010-10-08 12:01:22 +04:00
void fimc_hw_set_rotation ( struct fimc_ctx * ctx )
{
u32 cfg , flip ;
struct fimc_dev * dev = ctx - > fimc_dev ;
2012-05-02 13:14:49 +04:00
cfg = readl ( dev - > regs + FIMC_REG_CITRGFMT ) ;
cfg & = ~ ( FIMC_REG_CITRGFMT_INROT90 | FIMC_REG_CITRGFMT_OUTROT90 |
FIMC_REG_CITRGFMT_FLIP_180 ) ;
2010-10-08 12:01:22 +04:00
/*
* The input and output rotator cannot work simultaneously .
* Use the output rotator in output DMA mode or the input rotator
* in direct fifo output mode .
*/
if ( ctx - > rotation = = 90 | | ctx - > rotation = = 270 ) {
2012-04-26 13:26:29 +04:00
if ( ctx - > out_path = = FIMC_IO_LCDFIFO )
2012-05-02 13:14:49 +04:00
cfg | = FIMC_REG_CITRGFMT_INROT90 ;
2010-10-08 12:01:22 +04:00
else
2012-05-02 13:14:49 +04:00
cfg | = FIMC_REG_CITRGFMT_OUTROT90 ;
2010-10-08 12:01:22 +04:00
}
2012-04-26 13:26:29 +04:00
if ( ctx - > out_path = = FIMC_IO_DMA ) {
2010-12-27 20:47:32 +03:00
cfg | = fimc_hw_get_target_flip ( ctx ) ;
2012-05-02 13:14:49 +04:00
writel ( cfg , dev - > regs + FIMC_REG_CITRGFMT ) ;
2010-12-27 20:47:32 +03:00
} else {
/* LCD FIFO path */
2012-05-02 13:14:49 +04:00
flip = readl ( dev - > regs + FIMC_REG_MSCTRL ) ;
flip & = ~ FIMC_REG_MSCTRL_FLIP_MASK ;
2010-12-27 20:47:32 +03:00
flip | = fimc_hw_get_in_flip ( ctx ) ;
2012-05-02 13:14:49 +04:00
writel ( flip , dev - > regs + FIMC_REG_MSCTRL ) ;
2010-12-27 20:47:32 +03:00
}
2010-10-08 12:01:22 +04:00
}
2010-08-03 16:50:29 +04:00
void fimc_hw_set_target_format ( struct fimc_ctx * ctx )
{
u32 cfg ;
struct fimc_dev * dev = ctx - > fimc_dev ;
struct fimc_frame * frame = & ctx - > d_frame ;
dbg ( " w= %d, h= %d color: %d " , frame - > width ,
2012-05-02 13:14:49 +04:00
frame - > height , frame - > fmt - > color ) ;
2010-08-03 16:50:29 +04:00
2012-05-02 13:14:49 +04:00
cfg = readl ( dev - > regs + FIMC_REG_CITRGFMT ) ;
cfg & = ~ ( FIMC_REG_CITRGFMT_FMT_MASK | FIMC_REG_CITRGFMT_HSIZE_MASK |
FIMC_REG_CITRGFMT_VSIZE_MASK ) ;
2010-08-03 16:50:29 +04:00
switch ( frame - > fmt - > color ) {
2012-04-26 13:26:29 +04:00
case FIMC_FMT_RGB444 . . . FIMC_FMT_RGB888 :
2012-05-02 13:14:49 +04:00
cfg | = FIMC_REG_CITRGFMT_RGB ;
2010-08-03 16:50:29 +04:00
break ;
2012-04-26 13:26:29 +04:00
case FIMC_FMT_YCBCR420 :
2012-05-02 13:14:49 +04:00
cfg | = FIMC_REG_CITRGFMT_YCBCR420 ;
2010-08-03 16:50:29 +04:00
break ;
2012-04-26 13:26:29 +04:00
case FIMC_FMT_YCBYCR422 . . . FIMC_FMT_CRYCBY422 :
2010-12-08 20:05:08 +03:00
if ( frame - > fmt - > colplanes = = 1 )
2012-05-02 13:14:49 +04:00
cfg | = FIMC_REG_CITRGFMT_YCBCR422_1P ;
2010-08-03 16:50:29 +04:00
else
2012-05-02 13:14:49 +04:00
cfg | = FIMC_REG_CITRGFMT_YCBCR422 ;
2010-08-03 16:50:29 +04:00
break ;
default :
break ;
}
2012-05-02 13:14:49 +04:00
if ( ctx - > rotation = = 90 | | ctx - > rotation = = 270 )
cfg | = ( frame - > height < < 16 ) | frame - > width ;
else
cfg | = ( frame - > width < < 16 ) | frame - > height ;
2010-10-08 12:01:22 +04:00
2012-05-02 13:14:49 +04:00
writel ( cfg , dev - > regs + FIMC_REG_CITRGFMT ) ;
2010-08-03 16:50:29 +04:00
2012-05-02 13:14:49 +04:00
cfg = readl ( dev - > regs + FIMC_REG_CITAREA ) ;
cfg & = ~ FIMC_REG_CITAREA_MASK ;
2010-08-03 16:50:29 +04:00
cfg | = ( frame - > width * frame - > height ) ;
2012-05-02 13:14:49 +04:00
writel ( cfg , dev - > regs + FIMC_REG_CITAREA ) ;
2010-08-03 16:50:29 +04:00
}
static void fimc_hw_set_out_dma_size ( struct fimc_ctx * ctx )
{
struct fimc_dev * dev = ctx - > fimc_dev ;
struct fimc_frame * frame = & ctx - > d_frame ;
2010-10-08 12:01:22 +04:00
u32 cfg ;
2010-08-03 16:50:29 +04:00
2012-05-02 13:14:49 +04:00
cfg = ( frame - > f_height < < 16 ) | frame - > f_width ;
writel ( cfg , dev - > regs + FIMC_REG_ORGOSIZE ) ;
2010-10-07 17:06:16 +04:00
/* Select color space conversion equation (HD/SD size).*/
2012-05-02 13:14:49 +04:00
cfg = readl ( dev - > regs + FIMC_REG_CIGCTRL ) ;
2010-10-07 17:06:16 +04:00
if ( frame - > f_width > = 1280 ) /* HD */
2012-05-02 13:14:49 +04:00
cfg | = FIMC_REG_CIGCTRL_CSC_ITU601_709 ;
2010-10-07 17:06:16 +04:00
else /* SD */
2012-05-02 13:14:49 +04:00
cfg & = ~ FIMC_REG_CIGCTRL_CSC_ITU601_709 ;
writel ( cfg , dev - > regs + FIMC_REG_CIGCTRL ) ;
2010-10-07 17:06:16 +04:00
2010-08-03 16:50:29 +04:00
}
void fimc_hw_set_out_dma ( struct fimc_ctx * ctx )
{
struct fimc_dev * dev = ctx - > fimc_dev ;
struct fimc_frame * frame = & ctx - > d_frame ;
struct fimc_dma_offset * offset = & frame - > dma_offset ;
2011-12-01 21:02:24 +04:00
struct fimc_fmt * fmt = frame - > fmt ;
2012-05-02 13:14:49 +04:00
u32 cfg ;
2010-08-03 16:50:29 +04:00
/* Set the input dma offsets. */
2012-05-02 13:14:49 +04:00
cfg = ( offset - > y_v < < 16 ) | offset - > y_h ;
writel ( cfg , dev - > regs + FIMC_REG_CIOYOFF ) ;
2010-08-03 16:50:29 +04:00
2012-05-02 13:14:49 +04:00
cfg = ( offset - > cb_v < < 16 ) | offset - > cb_h ;
writel ( cfg , dev - > regs + FIMC_REG_CIOCBOFF ) ;
2010-08-03 16:50:29 +04:00
2012-05-02 13:14:49 +04:00
cfg = ( offset - > cr_v < < 16 ) | offset - > cr_h ;
writel ( cfg , dev - > regs + FIMC_REG_CIOCROFF ) ;
2010-08-03 16:50:29 +04:00
fimc_hw_set_out_dma_size ( ctx ) ;
/* Configure chroma components order. */
2012-05-02 13:14:49 +04:00
cfg = readl ( dev - > regs + FIMC_REG_CIOCTRL ) ;
2010-08-03 16:50:29 +04:00
2012-05-02 13:14:49 +04:00
cfg & = ~ ( FIMC_REG_CIOCTRL_ORDER2P_MASK |
FIMC_REG_CIOCTRL_ORDER422_MASK |
FIMC_REG_CIOCTRL_YCBCR_PLANE_MASK |
FIMC_REG_CIOCTRL_RGB16FMT_MASK ) ;
2010-08-03 16:50:29 +04:00
2011-12-01 21:02:24 +04:00
if ( fmt - > colplanes = = 1 )
2010-08-03 16:50:29 +04:00
cfg | = ctx - > out_order_1p ;
2011-12-01 21:02:24 +04:00
else if ( fmt - > colplanes = = 2 )
2012-05-02 13:14:49 +04:00
cfg | = ctx - > out_order_2p | FIMC_REG_CIOCTRL_YCBCR_2PLANE ;
2011-12-01 21:02:24 +04:00
else if ( fmt - > colplanes = = 3 )
2012-05-02 13:14:49 +04:00
cfg | = FIMC_REG_CIOCTRL_YCBCR_3PLANE ;
2010-08-03 16:50:29 +04:00
2012-04-26 13:26:29 +04:00
if ( fmt - > color = = FIMC_FMT_RGB565 )
2012-05-02 13:14:49 +04:00
cfg | = FIMC_REG_CIOCTRL_RGB565 ;
2012-04-26 13:26:29 +04:00
else if ( fmt - > color = = FIMC_FMT_RGB555 )
2012-05-02 13:14:49 +04:00
cfg | = FIMC_REG_CIOCTRL_ARGB1555 ;
2012-04-26 13:26:29 +04:00
else if ( fmt - > color = = FIMC_FMT_RGB444 )
2012-05-02 13:14:49 +04:00
cfg | = FIMC_REG_CIOCTRL_ARGB4444 ;
2011-12-01 21:02:24 +04:00
2012-05-02 13:14:49 +04:00
writel ( cfg , dev - > regs + FIMC_REG_CIOCTRL ) ;
2010-08-03 16:50:29 +04:00
}
static void fimc_hw_en_autoload ( struct fimc_dev * dev , int enable )
{
2012-05-02 13:14:49 +04:00
u32 cfg = readl ( dev - > regs + FIMC_REG_ORGISIZE ) ;
2010-08-03 16:50:29 +04:00
if ( enable )
2012-05-02 13:14:49 +04:00
cfg | = FIMC_REG_CIREAL_ISIZE_AUTOLOAD_EN ;
2010-08-03 16:50:29 +04:00
else
2012-05-02 13:14:49 +04:00
cfg & = ~ FIMC_REG_CIREAL_ISIZE_AUTOLOAD_EN ;
writel ( cfg , dev - > regs + FIMC_REG_ORGISIZE ) ;
2010-08-03 16:50:29 +04:00
}
void fimc_hw_en_lastirq ( struct fimc_dev * dev , int enable )
{
2012-05-02 13:14:49 +04:00
u32 cfg = readl ( dev - > regs + FIMC_REG_CIOCTRL ) ;
2010-08-03 16:50:29 +04:00
if ( enable )
2012-05-02 13:14:49 +04:00
cfg | = FIMC_REG_CIOCTRL_LASTIRQ_ENABLE ;
2010-08-03 16:50:29 +04:00
else
2012-05-02 13:14:49 +04:00
cfg & = ~ FIMC_REG_CIOCTRL_LASTIRQ_ENABLE ;
writel ( cfg , dev - > regs + FIMC_REG_CIOCTRL ) ;
2010-08-03 16:50:29 +04:00
}
2010-12-28 17:27:13 +03:00
void fimc_hw_set_prescaler ( struct fimc_ctx * ctx )
2010-08-03 16:50:29 +04:00
{
struct fimc_dev * dev = ctx - > fimc_dev ;
struct fimc_scaler * sc = & ctx - > scaler ;
2010-10-08 12:01:14 +04:00
u32 cfg , shfactor ;
2010-08-03 16:50:29 +04:00
shfactor = 10 - ( sc - > hfactor + sc - > vfactor ) ;
2012-05-02 13:14:49 +04:00
cfg = shfactor < < 28 ;
2010-08-03 16:50:29 +04:00
2012-05-02 13:14:49 +04:00
cfg | = ( sc - > pre_hratio < < 16 ) | sc - > pre_vratio ;
writel ( cfg , dev - > regs + FIMC_REG_CISCPRERATIO ) ;
2010-08-03 16:50:29 +04:00
2012-05-02 13:14:49 +04:00
cfg = ( sc - > pre_dst_width < < 16 ) | sc - > pre_dst_height ;
writel ( cfg , dev - > regs + FIMC_REG_CISCPREDST ) ;
2010-08-03 16:50:29 +04:00
}
2010-12-28 17:27:13 +03:00
static void fimc_hw_set_scaler ( struct fimc_ctx * ctx )
2010-08-03 16:50:29 +04:00
{
struct fimc_dev * dev = ctx - > fimc_dev ;
struct fimc_scaler * sc = & ctx - > scaler ;
struct fimc_frame * src_frame = & ctx - > s_frame ;
struct fimc_frame * dst_frame = & ctx - > d_frame ;
2011-10-05 21:20:45 +04:00
2012-05-02 13:14:49 +04:00
u32 cfg = readl ( dev - > regs + FIMC_REG_CISCCTRL ) ;
2011-10-05 21:20:45 +04:00
2012-05-02 13:14:49 +04:00
cfg & = ~ ( FIMC_REG_CISCCTRL_CSCR2Y_WIDE | FIMC_REG_CISCCTRL_CSCY2R_WIDE |
FIMC_REG_CISCCTRL_SCALEUP_H | FIMC_REG_CISCCTRL_SCALEUP_V |
FIMC_REG_CISCCTRL_SCALERBYPASS | FIMC_REG_CISCCTRL_ONE2ONE |
FIMC_REG_CISCCTRL_INRGB_FMT_MASK | FIMC_REG_CISCCTRL_OUTRGB_FMT_MASK |
FIMC_REG_CISCCTRL_INTERLACE | FIMC_REG_CISCCTRL_RGB_EXT ) ;
2010-08-03 16:50:29 +04:00
if ( ! ( ctx - > flags & FIMC_COLOR_RANGE_NARROW ) )
2012-05-02 13:14:49 +04:00
cfg | = ( FIMC_REG_CISCCTRL_CSCR2Y_WIDE |
FIMC_REG_CISCCTRL_CSCY2R_WIDE ) ;
2010-08-03 16:50:29 +04:00
if ( ! sc - > enabled )
2012-05-02 13:14:49 +04:00
cfg | = FIMC_REG_CISCCTRL_SCALERBYPASS ;
2010-08-03 16:50:29 +04:00
if ( sc - > scaleup_h )
2012-05-02 13:14:49 +04:00
cfg | = FIMC_REG_CISCCTRL_SCALEUP_H ;
2010-08-03 16:50:29 +04:00
if ( sc - > scaleup_v )
2012-05-02 13:14:49 +04:00
cfg | = FIMC_REG_CISCCTRL_SCALEUP_V ;
2010-08-03 16:50:29 +04:00
if ( sc - > copy_mode )
2012-05-02 13:14:49 +04:00
cfg | = FIMC_REG_CISCCTRL_ONE2ONE ;
2010-08-03 16:50:29 +04:00
2012-04-26 13:26:29 +04:00
if ( ctx - > in_path = = FIMC_IO_DMA ) {
2011-12-01 21:02:24 +04:00
switch ( src_frame - > fmt - > color ) {
2012-04-26 13:26:29 +04:00
case FIMC_FMT_RGB565 :
2012-05-02 13:14:49 +04:00
cfg | = FIMC_REG_CISCCTRL_INRGB_FMT_RGB565 ;
2011-12-01 21:02:24 +04:00
break ;
2012-04-26 13:26:29 +04:00
case FIMC_FMT_RGB666 :
2012-05-02 13:14:49 +04:00
cfg | = FIMC_REG_CISCCTRL_INRGB_FMT_RGB666 ;
2011-12-01 21:02:24 +04:00
break ;
2012-04-26 13:26:29 +04:00
case FIMC_FMT_RGB888 :
2012-05-02 13:14:49 +04:00
cfg | = FIMC_REG_CISCCTRL_INRGB_FMT_RGB888 ;
2011-12-01 21:02:24 +04:00
break ;
}
2010-08-03 16:50:29 +04:00
}
2012-04-26 13:26:29 +04:00
if ( ctx - > out_path = = FIMC_IO_DMA ) {
2011-12-01 21:02:24 +04:00
u32 color = dst_frame - > fmt - > color ;
2012-04-26 13:26:29 +04:00
if ( color > = FIMC_FMT_RGB444 & & color < = FIMC_FMT_RGB565 )
2012-05-02 13:14:49 +04:00
cfg | = FIMC_REG_CISCCTRL_OUTRGB_FMT_RGB565 ;
2012-04-26 13:26:29 +04:00
else if ( color = = FIMC_FMT_RGB666 )
2012-05-02 13:14:49 +04:00
cfg | = FIMC_REG_CISCCTRL_OUTRGB_FMT_RGB666 ;
2012-04-26 13:26:29 +04:00
else if ( color = = FIMC_FMT_RGB888 )
2012-05-02 13:14:49 +04:00
cfg | = FIMC_REG_CISCCTRL_OUTRGB_FMT_RGB888 ;
2010-08-03 16:50:29 +04:00
} else {
2012-05-02 13:14:49 +04:00
cfg | = FIMC_REG_CISCCTRL_OUTRGB_FMT_RGB888 ;
2010-08-03 16:50:29 +04:00
if ( ctx - > flags & FIMC_SCAN_MODE_INTERLACED )
2012-05-02 13:14:49 +04:00
cfg | = FIMC_REG_CISCCTRL_INTERLACE ;
2010-08-03 16:50:29 +04:00
}
2012-05-02 13:14:49 +04:00
writel ( cfg , dev - > regs + FIMC_REG_CISCCTRL ) ;
2010-12-28 17:27:13 +03:00
}
void fimc_hw_set_mainscaler ( struct fimc_ctx * ctx )
{
struct fimc_dev * dev = ctx - > fimc_dev ;
2012-04-27 16:33:23 +04:00
struct fimc_variant * variant = dev - > variant ;
2010-12-28 17:27:13 +03:00
struct fimc_scaler * sc = & ctx - > scaler ;
u32 cfg ;
dbg ( " main_hratio= 0x%X main_vratio= 0x%X " ,
2012-05-02 13:14:49 +04:00
sc - > main_hratio , sc - > main_vratio ) ;
2010-12-28 17:27:13 +03:00
fimc_hw_set_scaler ( ctx ) ;
2012-05-02 13:14:49 +04:00
cfg = readl ( dev - > regs + FIMC_REG_CISCCTRL ) ;
cfg & = ~ ( FIMC_REG_CISCCTRL_MHRATIO_MASK |
FIMC_REG_CISCCTRL_MVRATIO_MASK ) ;
2010-12-28 17:27:13 +03:00
2010-12-28 17:37:55 +03:00
if ( variant - > has_mainscaler_ext ) {
2012-05-02 13:14:49 +04:00
cfg | = FIMC_REG_CISCCTRL_MHRATIO_EXT ( sc - > main_hratio ) ;
cfg | = FIMC_REG_CISCCTRL_MVRATIO_EXT ( sc - > main_vratio ) ;
writel ( cfg , dev - > regs + FIMC_REG_CISCCTRL ) ;
2010-12-28 17:27:13 +03:00
2012-05-02 13:14:49 +04:00
cfg = readl ( dev - > regs + FIMC_REG_CIEXTEN ) ;
2010-12-28 17:27:13 +03:00
2012-05-02 13:14:49 +04:00
cfg & = ~ ( FIMC_REG_CIEXTEN_MVRATIO_EXT_MASK |
FIMC_REG_CIEXTEN_MHRATIO_EXT_MASK ) ;
cfg | = FIMC_REG_CIEXTEN_MHRATIO_EXT ( sc - > main_hratio ) ;
cfg | = FIMC_REG_CIEXTEN_MVRATIO_EXT ( sc - > main_vratio ) ;
writel ( cfg , dev - > regs + FIMC_REG_CIEXTEN ) ;
2010-12-28 17:37:55 +03:00
} else {
2012-05-02 13:14:49 +04:00
cfg | = FIMC_REG_CISCCTRL_MHRATIO ( sc - > main_hratio ) ;
cfg | = FIMC_REG_CISCCTRL_MVRATIO ( sc - > main_vratio ) ;
writel ( cfg , dev - > regs + FIMC_REG_CISCCTRL ) ;
2010-12-28 17:37:55 +03:00
}
2010-08-03 16:50:29 +04:00
}
2012-11-22 21:01:39 +04:00
void fimc_hw_enable_capture ( struct fimc_ctx * ctx )
2010-08-03 16:50:29 +04:00
{
struct fimc_dev * dev = ctx - > fimc_dev ;
2012-11-22 21:01:39 +04:00
u32 cfg ;
2010-08-03 16:50:29 +04:00
2012-11-22 21:01:39 +04:00
cfg = readl ( dev - > regs + FIMC_REG_CIIMGCPT ) ;
cfg | = FIMC_REG_CIIMGCPT_CPT_FREN_ENABLE ;
2010-08-03 16:50:29 +04:00
if ( ctx - > scaler . enabled )
2012-05-02 13:14:49 +04:00
cfg | = FIMC_REG_CIIMGCPT_IMGCPTEN_SC ;
2012-11-22 21:01:39 +04:00
else
cfg & = FIMC_REG_CIIMGCPT_IMGCPTEN_SC ;
2010-08-03 16:50:29 +04:00
2012-05-02 13:14:49 +04:00
cfg | = FIMC_REG_CIIMGCPT_IMGCPTEN ;
writel ( cfg , dev - > regs + FIMC_REG_CIIMGCPT ) ;
2010-08-03 16:50:29 +04:00
}
2012-11-22 21:01:39 +04:00
void fimc_hw_disable_capture ( struct fimc_dev * dev )
{
u32 cfg = readl ( dev - > regs + FIMC_REG_CIIMGCPT ) ;
cfg & = ~ ( FIMC_REG_CIIMGCPT_IMGCPTEN |
FIMC_REG_CIIMGCPT_IMGCPTEN_SC ) ;
writel ( cfg , dev - > regs + FIMC_REG_CIIMGCPT ) ;
}
2012-04-02 13:41:22 +04:00
void fimc_hw_set_effect ( struct fimc_ctx * ctx )
2010-08-03 16:50:29 +04:00
{
struct fimc_dev * dev = ctx - > fimc_dev ;
struct fimc_effect * effect = & ctx - > effect ;
2011-08-26 21:57:06 +04:00
u32 cfg = 0 ;
2010-08-03 16:50:29 +04:00
2012-04-02 13:41:22 +04:00
if ( effect - > type ! = FIMC_REG_CIIMGEFF_FIN_BYPASS ) {
2012-05-02 13:14:49 +04:00
cfg | = FIMC_REG_CIIMGEFF_IE_SC_AFTER |
FIMC_REG_CIIMGEFF_IE_ENABLE ;
2011-08-26 21:57:06 +04:00
cfg | = effect - > type ;
2012-05-02 13:14:49 +04:00
if ( effect - > type = = FIMC_REG_CIIMGEFF_FIN_ARBITRARY )
cfg | = ( effect - > pat_cb < < 13 ) | effect - > pat_cr ;
2010-08-03 16:50:29 +04:00
}
2012-05-02 13:14:49 +04:00
writel ( cfg , dev - > regs + FIMC_REG_CIIMGEFF ) ;
2010-08-03 16:50:29 +04:00
}
2011-12-01 21:02:24 +04:00
void fimc_hw_set_rgb_alpha ( struct fimc_ctx * ctx )
{
struct fimc_dev * dev = ctx - > fimc_dev ;
struct fimc_frame * frame = & ctx - > d_frame ;
u32 cfg ;
if ( ! ( frame - > fmt - > flags & FMT_HAS_ALPHA ) )
return ;
2012-05-02 13:14:49 +04:00
cfg = readl ( dev - > regs + FIMC_REG_CIOCTRL ) ;
cfg & = ~ FIMC_REG_CIOCTRL_ALPHA_OUT_MASK ;
2011-12-01 21:02:24 +04:00
cfg | = ( frame - > alpha < < 4 ) ;
2012-05-02 13:14:49 +04:00
writel ( cfg , dev - > regs + FIMC_REG_CIOCTRL ) ;
2011-12-01 21:02:24 +04:00
}
2010-08-03 16:50:29 +04:00
static void fimc_hw_set_in_dma_size ( struct fimc_ctx * ctx )
{
struct fimc_dev * dev = ctx - > fimc_dev ;
struct fimc_frame * frame = & ctx - > s_frame ;
u32 cfg_o = 0 ;
u32 cfg_r = 0 ;
2012-04-26 13:26:29 +04:00
if ( FIMC_IO_LCDFIFO = = ctx - > out_path )
2012-05-02 13:14:49 +04:00
cfg_r | = FIMC_REG_CIREAL_ISIZE_AUTOLOAD_EN ;
2010-08-03 16:50:29 +04:00
2012-05-02 13:14:49 +04:00
cfg_o | = ( frame - > f_height < < 16 ) | frame - > f_width ;
cfg_r | = ( frame - > height < < 16 ) | frame - > width ;
2010-08-03 16:50:29 +04:00
2012-05-02 13:14:49 +04:00
writel ( cfg_o , dev - > regs + FIMC_REG_ORGISIZE ) ;
writel ( cfg_r , dev - > regs + FIMC_REG_CIREAL_ISIZE ) ;
2010-08-03 16:50:29 +04:00
}
void fimc_hw_set_in_dma ( struct fimc_ctx * ctx )
{
struct fimc_dev * dev = ctx - > fimc_dev ;
struct fimc_frame * frame = & ctx - > s_frame ;
struct fimc_dma_offset * offset = & frame - > dma_offset ;
2010-10-08 12:01:14 +04:00
u32 cfg ;
2010-08-03 16:50:29 +04:00
/* Set the pixel offsets. */
2012-05-02 13:14:49 +04:00
cfg = ( offset - > y_v < < 16 ) | offset - > y_h ;
writel ( cfg , dev - > regs + FIMC_REG_CIIYOFF ) ;
2010-08-03 16:50:29 +04:00
2012-05-02 13:14:49 +04:00
cfg = ( offset - > cb_v < < 16 ) | offset - > cb_h ;
writel ( cfg , dev - > regs + FIMC_REG_CIICBOFF ) ;
2010-08-03 16:50:29 +04:00
2012-05-02 13:14:49 +04:00
cfg = ( offset - > cr_v < < 16 ) | offset - > cr_h ;
writel ( cfg , dev - > regs + FIMC_REG_CIICROFF ) ;
2010-08-03 16:50:29 +04:00
/* Input original and real size. */
fimc_hw_set_in_dma_size ( ctx ) ;
2010-10-08 12:01:14 +04:00
/* Use DMA autoload only in FIFO mode. */
2012-04-26 13:26:29 +04:00
fimc_hw_en_autoload ( dev , ctx - > out_path = = FIMC_IO_LCDFIFO ) ;
2010-08-03 16:50:29 +04:00
/* Set the input DMA to process single frame only. */
2012-05-02 13:14:49 +04:00
cfg = readl ( dev - > regs + FIMC_REG_MSCTRL ) ;
cfg & = ~ ( FIMC_REG_MSCTRL_INFORMAT_MASK
| FIMC_REG_MSCTRL_IN_BURST_COUNT_MASK
| FIMC_REG_MSCTRL_INPUT_MASK
| FIMC_REG_MSCTRL_C_INT_IN_MASK
| FIMC_REG_MSCTRL_2P_IN_ORDER_MASK ) ;
2010-08-03 16:50:29 +04:00
2012-05-02 13:14:49 +04:00
cfg | = ( FIMC_REG_MSCTRL_IN_BURST_COUNT ( 4 )
| FIMC_REG_MSCTRL_INPUT_MEMORY
| FIMC_REG_MSCTRL_FIFO_CTRL_FULL ) ;
2010-08-03 16:50:29 +04:00
switch ( frame - > fmt - > color ) {
2012-04-26 13:26:29 +04:00
case FIMC_FMT_RGB565 . . . FIMC_FMT_RGB888 :
2012-05-02 13:14:49 +04:00
cfg | = FIMC_REG_MSCTRL_INFORMAT_RGB ;
2010-08-03 16:50:29 +04:00
break ;
2012-04-26 13:26:29 +04:00
case FIMC_FMT_YCBCR420 :
2012-05-02 13:14:49 +04:00
cfg | = FIMC_REG_MSCTRL_INFORMAT_YCBCR420 ;
2010-08-03 16:50:29 +04:00
2010-12-08 20:05:08 +03:00
if ( frame - > fmt - > colplanes = = 2 )
2012-05-02 13:14:49 +04:00
cfg | = ctx - > in_order_2p | FIMC_REG_MSCTRL_C_INT_IN_2PLANE ;
2010-08-03 16:50:29 +04:00
else
2012-05-02 13:14:49 +04:00
cfg | = FIMC_REG_MSCTRL_C_INT_IN_3PLANE ;
2010-08-03 16:50:29 +04:00
break ;
2012-04-26 13:26:29 +04:00
case FIMC_FMT_YCBYCR422 . . . FIMC_FMT_CRYCBY422 :
2010-12-08 20:05:08 +03:00
if ( frame - > fmt - > colplanes = = 1 ) {
2010-08-03 16:50:29 +04:00
cfg | = ctx - > in_order_1p
2012-05-02 13:14:49 +04:00
| FIMC_REG_MSCTRL_INFORMAT_YCBCR422_1P ;
2010-08-03 16:50:29 +04:00
} else {
2012-05-02 13:14:49 +04:00
cfg | = FIMC_REG_MSCTRL_INFORMAT_YCBCR422 ;
2010-08-03 16:50:29 +04:00
2010-12-08 20:05:08 +03:00
if ( frame - > fmt - > colplanes = = 2 )
2010-08-03 16:50:29 +04:00
cfg | = ctx - > in_order_2p
2012-05-02 13:14:49 +04:00
| FIMC_REG_MSCTRL_C_INT_IN_2PLANE ;
2010-08-03 16:50:29 +04:00
else
2012-05-02 13:14:49 +04:00
cfg | = FIMC_REG_MSCTRL_C_INT_IN_3PLANE ;
2010-08-03 16:50:29 +04:00
}
break ;
default :
break ;
}
2012-05-02 13:14:49 +04:00
writel ( cfg , dev - > regs + FIMC_REG_MSCTRL ) ;
2010-08-03 16:50:29 +04:00
/* Input/output DMA linear/tiled mode. */
2012-05-02 13:14:49 +04:00
cfg = readl ( dev - > regs + FIMC_REG_CIDMAPARAM ) ;
cfg & = ~ FIMC_REG_CIDMAPARAM_TILE_MASK ;
2010-08-03 16:50:29 +04:00
if ( tiled_fmt ( ctx - > s_frame . fmt ) )
2012-05-02 13:14:49 +04:00
cfg | = FIMC_REG_CIDMAPARAM_R_64X32 ;
2010-08-03 16:50:29 +04:00
if ( tiled_fmt ( ctx - > d_frame . fmt ) )
2012-05-02 13:14:49 +04:00
cfg | = FIMC_REG_CIDMAPARAM_W_64X32 ;
2010-08-03 16:50:29 +04:00
2012-05-02 13:14:49 +04:00
writel ( cfg , dev - > regs + FIMC_REG_CIDMAPARAM ) ;
2010-08-03 16:50:29 +04:00
}
void fimc_hw_set_input_path ( struct fimc_ctx * ctx )
{
struct fimc_dev * dev = ctx - > fimc_dev ;
2012-05-02 13:14:49 +04:00
u32 cfg = readl ( dev - > regs + FIMC_REG_MSCTRL ) ;
cfg & = ~ FIMC_REG_MSCTRL_INPUT_MASK ;
2010-08-03 16:50:29 +04:00
2012-04-26 13:26:29 +04:00
if ( ctx - > in_path = = FIMC_IO_DMA )
2012-05-02 13:14:49 +04:00
cfg | = FIMC_REG_MSCTRL_INPUT_MEMORY ;
2010-08-03 16:50:29 +04:00
else
2012-05-02 13:14:49 +04:00
cfg | = FIMC_REG_MSCTRL_INPUT_EXTCAM ;
2010-08-03 16:50:29 +04:00
2012-05-02 13:14:49 +04:00
writel ( cfg , dev - > regs + FIMC_REG_MSCTRL ) ;
2010-08-03 16:50:29 +04:00
}
void fimc_hw_set_output_path ( struct fimc_ctx * ctx )
{
struct fimc_dev * dev = ctx - > fimc_dev ;
2012-05-02 13:14:49 +04:00
u32 cfg = readl ( dev - > regs + FIMC_REG_CISCCTRL ) ;
cfg & = ~ FIMC_REG_CISCCTRL_LCDPATHEN_FIFO ;
2012-04-26 13:26:29 +04:00
if ( ctx - > out_path = = FIMC_IO_LCDFIFO )
2012-05-02 13:14:49 +04:00
cfg | = FIMC_REG_CISCCTRL_LCDPATHEN_FIFO ;
writel ( cfg , dev - > regs + FIMC_REG_CISCCTRL ) ;
2010-08-03 16:50:29 +04:00
}
void fimc_hw_set_input_addr ( struct fimc_dev * dev , struct fimc_addr * paddr )
{
2012-05-02 13:14:49 +04:00
u32 cfg = readl ( dev - > regs + FIMC_REG_CIREAL_ISIZE ) ;
cfg | = FIMC_REG_CIREAL_ISIZE_ADDR_CH_DIS ;
writel ( cfg , dev - > regs + FIMC_REG_CIREAL_ISIZE ) ;
2010-08-03 16:50:29 +04:00
2012-05-02 13:14:49 +04:00
writel ( paddr - > y , dev - > regs + FIMC_REG_CIIYSA ( 0 ) ) ;
writel ( paddr - > cb , dev - > regs + FIMC_REG_CIICBSA ( 0 ) ) ;
writel ( paddr - > cr , dev - > regs + FIMC_REG_CIICRSA ( 0 ) ) ;
2010-08-03 16:50:29 +04:00
2012-05-02 13:14:49 +04:00
cfg & = ~ FIMC_REG_CIREAL_ISIZE_ADDR_CH_DIS ;
writel ( cfg , dev - > regs + FIMC_REG_CIREAL_ISIZE ) ;
2010-08-03 16:50:29 +04:00
}
2010-10-08 12:01:14 +04:00
void fimc_hw_set_output_addr ( struct fimc_dev * dev ,
struct fimc_addr * paddr , int index )
2010-08-03 16:50:29 +04:00
{
2010-10-08 12:01:14 +04:00
int i = ( index = = - 1 ) ? 0 : index ;
do {
2012-05-02 13:14:49 +04:00
writel ( paddr - > y , dev - > regs + FIMC_REG_CIOYSA ( i ) ) ;
writel ( paddr - > cb , dev - > regs + FIMC_REG_CIOCBSA ( i ) ) ;
writel ( paddr - > cr , dev - > regs + FIMC_REG_CIOCRSA ( i ) ) ;
2010-10-08 12:01:14 +04:00
dbg ( " dst_buf[%d]: 0x%X, cb: 0x%X, cr: 0x%X " ,
i , paddr - > y , paddr - > cb , paddr - > cr ) ;
} while ( index = = - 1 & & + + i < FIMC_MAX_OUT_BUFS ) ;
2010-08-03 16:50:29 +04:00
}
2010-10-07 17:06:16 +04:00
int fimc_hw_set_camera_polarity ( struct fimc_dev * fimc ,
2010-12-27 20:42:15 +03:00
struct s5p_fimc_isp_info * cam )
2010-10-07 17:06:16 +04:00
{
2012-05-02 13:14:49 +04:00
u32 cfg = readl ( fimc - > regs + FIMC_REG_CIGCTRL ) ;
2010-10-07 17:06:16 +04:00
2012-05-02 13:14:49 +04:00
cfg & = ~ ( FIMC_REG_CIGCTRL_INVPOLPCLK | FIMC_REG_CIGCTRL_INVPOLVSYNC |
FIMC_REG_CIGCTRL_INVPOLHREF | FIMC_REG_CIGCTRL_INVPOLHSYNC |
FIMC_REG_CIGCTRL_INVPOLFIELD ) ;
2010-10-07 17:06:16 +04:00
2011-09-19 19:38:35 +04:00
if ( cam - > flags & V4L2_MBUS_PCLK_SAMPLE_FALLING )
2012-05-02 13:14:49 +04:00
cfg | = FIMC_REG_CIGCTRL_INVPOLPCLK ;
2010-10-07 17:06:16 +04:00
2011-09-19 19:38:35 +04:00
if ( cam - > flags & V4L2_MBUS_VSYNC_ACTIVE_LOW )
2012-05-02 13:14:49 +04:00
cfg | = FIMC_REG_CIGCTRL_INVPOLVSYNC ;
2010-10-07 17:06:16 +04:00
2011-09-19 19:38:35 +04:00
if ( cam - > flags & V4L2_MBUS_HSYNC_ACTIVE_LOW )
2012-05-02 13:14:49 +04:00
cfg | = FIMC_REG_CIGCTRL_INVPOLHREF ;
2010-10-07 17:06:16 +04:00
2011-09-19 19:38:35 +04:00
if ( cam - > flags & V4L2_MBUS_HSYNC_ACTIVE_LOW )
2012-05-02 13:14:49 +04:00
cfg | = FIMC_REG_CIGCTRL_INVPOLHSYNC ;
2010-10-07 17:06:16 +04:00
2011-09-19 19:38:35 +04:00
if ( cam - > flags & V4L2_MBUS_FIELD_EVEN_LOW )
2012-05-02 13:14:49 +04:00
cfg | = FIMC_REG_CIGCTRL_INVPOLFIELD ;
2011-09-19 19:38:35 +04:00
2012-05-02 13:14:49 +04:00
writel ( cfg , fimc - > regs + FIMC_REG_CIGCTRL ) ;
2010-10-07 17:06:16 +04:00
return 0 ;
}
2012-05-02 13:14:49 +04:00
struct mbus_pixfmt_desc {
u32 pixelcode ;
u32 cisrcfmt ;
u16 bus_width ;
} ;
static const struct mbus_pixfmt_desc pix_desc [ ] = {
{ V4L2_MBUS_FMT_YUYV8_2X8 , FIMC_REG_CISRCFMT_ORDER422_YCBYCR , 8 } ,
{ V4L2_MBUS_FMT_YVYU8_2X8 , FIMC_REG_CISRCFMT_ORDER422_YCRYCB , 8 } ,
{ V4L2_MBUS_FMT_VYUY8_2X8 , FIMC_REG_CISRCFMT_ORDER422_CRYCBY , 8 } ,
{ V4L2_MBUS_FMT_UYVY8_2X8 , FIMC_REG_CISRCFMT_ORDER422_CBYCRY , 8 } ,
} ;
2010-10-07 17:06:16 +04:00
int fimc_hw_set_camera_source ( struct fimc_dev * fimc ,
2010-12-27 20:42:15 +03:00
struct s5p_fimc_isp_info * cam )
2010-10-07 17:06:16 +04:00
{
struct fimc_frame * f = & fimc - > vid_cap . ctx - > s_frame ;
u32 cfg = 0 ;
2010-12-27 21:02:16 +03:00
u32 bus_width ;
int i ;
2010-10-07 17:06:16 +04:00
if ( cam - > bus_type = = FIMC_ITU_601 | | cam - > bus_type = = FIMC_ITU_656 ) {
2010-12-27 21:02:16 +03:00
for ( i = 0 ; i < ARRAY_SIZE ( pix_desc ) ; i + + ) {
2011-08-25 03:35:30 +04:00
if ( fimc - > vid_cap . mf . code = = pix_desc [ i ] . pixelcode ) {
2010-12-27 21:02:16 +03:00
cfg = pix_desc [ i ] . cisrcfmt ;
bus_width = pix_desc [ i ] . bus_width ;
break ;
}
}
2010-10-07 17:06:16 +04:00
2010-12-27 21:02:16 +03:00
if ( i = = ARRAY_SIZE ( pix_desc ) ) {
2012-07-26 14:15:42 +04:00
v4l2_err ( & fimc - > vid_cap . vfd ,
2010-12-27 21:02:16 +03:00
" Camera color format not supported: %d \n " ,
2011-08-25 03:35:30 +04:00
fimc - > vid_cap . mf . code ) ;
2010-10-07 17:06:16 +04:00
return - EINVAL ;
}
if ( cam - > bus_type = = FIMC_ITU_601 ) {
2010-12-27 21:02:16 +03:00
if ( bus_width = = 8 )
2012-05-02 13:14:49 +04:00
cfg | = FIMC_REG_CISRCFMT_ITU601_8BIT ;
2010-12-27 21:02:16 +03:00
else if ( bus_width = = 16 )
2012-05-02 13:14:49 +04:00
cfg | = FIMC_REG_CISRCFMT_ITU601_16BIT ;
2010-10-07 17:06:16 +04:00
} /* else defaults to ITU-R BT.656 8-bit */
2011-08-26 21:57:06 +04:00
} else if ( cam - > bus_type = = FIMC_MIPI_CSI2 ) {
2012-09-24 18:08:45 +04:00
if ( fimc_fmt_is_user_defined ( f - > fmt - > color ) )
2012-05-02 13:14:49 +04:00
cfg | = FIMC_REG_CISRCFMT_ITU601_8BIT ;
2010-10-07 17:06:16 +04:00
}
2012-05-02 13:14:49 +04:00
cfg | = ( f - > o_width < < 16 ) | f - > o_height ;
writel ( cfg , fimc - > regs + FIMC_REG_CISRCFMT ) ;
2010-10-07 17:06:16 +04:00
return 0 ;
}
2012-05-02 13:14:49 +04:00
void fimc_hw_set_camera_offset ( struct fimc_dev * fimc , struct fimc_frame * f )
2010-10-07 17:06:16 +04:00
{
u32 hoff2 , voff2 ;
2012-05-02 13:14:49 +04:00
u32 cfg = readl ( fimc - > regs + FIMC_REG_CIWDOFST ) ;
2010-10-07 17:06:16 +04:00
2012-05-02 13:14:49 +04:00
cfg & = ~ ( FIMC_REG_CIWDOFST_HOROFF_MASK | FIMC_REG_CIWDOFST_VEROFF_MASK ) ;
cfg | = FIMC_REG_CIWDOFST_OFF_EN |
( f - > offs_h < < 16 ) | f - > offs_v ;
2010-10-07 17:06:16 +04:00
2012-05-02 13:14:49 +04:00
writel ( cfg , fimc - > regs + FIMC_REG_CIWDOFST ) ;
2010-10-07 17:06:16 +04:00
/* See CIWDOFSTn register description in the datasheet for details. */
hoff2 = f - > o_width - f - > width - f - > offs_h ;
voff2 = f - > o_height - f - > height - f - > offs_v ;
2012-05-02 13:14:49 +04:00
cfg = ( hoff2 < < 16 ) | voff2 ;
writel ( cfg , fimc - > regs + FIMC_REG_CIWDOFST2 ) ;
2010-10-07 17:06:16 +04:00
}
int fimc_hw_set_camera_type ( struct fimc_dev * fimc ,
2010-12-27 20:42:15 +03:00
struct s5p_fimc_isp_info * cam )
2010-10-07 17:06:16 +04:00
{
u32 cfg , tmp ;
struct fimc_vid_cap * vid_cap = & fimc - > vid_cap ;
2012-03-21 13:21:30 +04:00
u32 csis_data_alignment = 32 ;
2010-10-07 17:06:16 +04:00
2012-05-02 13:14:49 +04:00
cfg = readl ( fimc - > regs + FIMC_REG_CIGCTRL ) ;
2010-10-07 17:06:16 +04:00
/* Select ITU B interface, disable Writeback path and test pattern. */
2012-05-02 13:14:49 +04:00
cfg & = ~ ( FIMC_REG_CIGCTRL_TESTPAT_MASK | FIMC_REG_CIGCTRL_SELCAM_ITU_A |
FIMC_REG_CIGCTRL_SELCAM_MIPI | FIMC_REG_CIGCTRL_CAMIF_SELWB |
FIMC_REG_CIGCTRL_SELCAM_MIPI_A | FIMC_REG_CIGCTRL_CAM_JPEG ) ;
2010-10-07 17:06:16 +04:00
2012-07-24 19:06:26 +04:00
switch ( cam - > bus_type ) {
case FIMC_MIPI_CSI2 :
2012-05-02 13:14:49 +04:00
cfg | = FIMC_REG_CIGCTRL_SELCAM_MIPI ;
2010-10-07 17:06:16 +04:00
if ( cam - > mux_id = = 0 )
2012-05-02 13:14:49 +04:00
cfg | = FIMC_REG_CIGCTRL_SELCAM_MIPI_A ;
2010-10-07 17:06:16 +04:00
/* TODO: add remaining supported formats. */
2011-08-26 21:57:06 +04:00
switch ( vid_cap - > mf . code ) {
case V4L2_MBUS_FMT_VYUY8_2X8 :
2012-05-02 13:14:49 +04:00
tmp = FIMC_REG_CSIIMGFMT_YCBCR422_8BIT ;
2011-08-26 21:57:06 +04:00
break ;
case V4L2_MBUS_FMT_JPEG_1X8 :
2012-09-24 18:08:45 +04:00
case V4L2_MBUS_FMT_S5C_UYVY_JPEG_1X8 :
2012-05-02 13:14:49 +04:00
tmp = FIMC_REG_CSIIMGFMT_USER ( 1 ) ;
cfg | = FIMC_REG_CIGCTRL_CAM_JPEG ;
2011-08-26 21:57:06 +04:00
break ;
default :
2012-07-26 14:15:42 +04:00
v4l2_err ( & vid_cap - > vfd ,
2012-06-12 10:12:26 +04:00
" Not supported camera pixel format: %#x \n " ,
2011-08-25 03:35:30 +04:00
vid_cap - > mf . code ) ;
2010-10-07 17:06:16 +04:00
return - EINVAL ;
}
2012-03-21 13:21:30 +04:00
tmp | = ( csis_data_alignment = = 32 ) < < 8 ;
2011-02-21 18:09:01 +03:00
2012-05-02 13:14:49 +04:00
writel ( tmp , fimc - > regs + FIMC_REG_CSIIMGFMT ) ;
2012-07-24 19:06:26 +04:00
break ;
case FIMC_ITU_601 . . . FIMC_ITU_656 :
2010-10-07 17:06:16 +04:00
if ( cam - > mux_id = = 0 ) /* ITU-A, ITU-B: 0, 1 */
2012-05-02 13:14:49 +04:00
cfg | = FIMC_REG_CIGCTRL_SELCAM_ITU_A ;
2012-07-24 19:06:26 +04:00
break ;
case FIMC_LCD_WB :
2012-05-02 13:14:49 +04:00
cfg | = FIMC_REG_CIGCTRL_CAMIF_SELWB ;
2012-07-24 19:06:26 +04:00
break ;
default :
2012-07-26 14:15:42 +04:00
v4l2_err ( & vid_cap - > vfd , " Invalid camera bus type selected \n " ) ;
2010-10-07 17:06:16 +04:00
return - EINVAL ;
}
2012-05-02 13:14:49 +04:00
writel ( cfg , fimc - > regs + FIMC_REG_CIGCTRL ) ;
2010-10-07 17:06:16 +04:00
return 0 ;
}
2012-05-02 13:14:49 +04:00
void fimc_hw_clear_irq ( struct fimc_dev * dev )
{
u32 cfg = readl ( dev - > regs + FIMC_REG_CIGCTRL ) ;
cfg | = FIMC_REG_CIGCTRL_IRQ_CLR ;
writel ( cfg , dev - > regs + FIMC_REG_CIGCTRL ) ;
}
void fimc_hw_enable_scaler ( struct fimc_dev * dev , bool on )
{
u32 cfg = readl ( dev - > regs + FIMC_REG_CISCCTRL ) ;
if ( on )
cfg | = FIMC_REG_CISCCTRL_SCALERSTART ;
else
cfg & = ~ FIMC_REG_CISCCTRL_SCALERSTART ;
writel ( cfg , dev - > regs + FIMC_REG_CISCCTRL ) ;
}
void fimc_hw_activate_input_dma ( struct fimc_dev * dev , bool on )
{
u32 cfg = readl ( dev - > regs + FIMC_REG_MSCTRL ) ;
if ( on )
cfg | = FIMC_REG_MSCTRL_ENVID ;
else
cfg & = ~ FIMC_REG_MSCTRL_ENVID ;
writel ( cfg , dev - > regs + FIMC_REG_MSCTRL ) ;
}
/* Return an index to the buffer actually being written. */
2012-09-24 18:08:45 +04:00
s32 fimc_hw_get_frame_index ( struct fimc_dev * dev )
2012-05-02 13:14:49 +04:00
{
2012-09-24 18:08:45 +04:00
s32 reg ;
2012-05-02 13:14:49 +04:00
if ( dev - > variant - > has_cistatus2 ) {
2012-09-24 18:08:45 +04:00
reg = readl ( dev - > regs + FIMC_REG_CISTATUS2 ) & 0x3f ;
return reg - 1 ;
2012-05-02 13:14:49 +04:00
}
reg = readl ( dev - > regs + FIMC_REG_CISTATUS ) ;
return ( reg & FIMC_REG_CISTATUS_FRAMECNT_MASK ) > >
FIMC_REG_CISTATUS_FRAMECNT_SHIFT ;
}
2012-09-24 18:08:45 +04:00
/* Return an index to the buffer being written previously. */
s32 fimc_hw_get_prev_frame_index ( struct fimc_dev * dev )
{
s32 reg ;
if ( ! dev - > variant - > has_cistatus2 )
return - 1 ;
reg = readl ( dev - > regs + FIMC_REG_CISTATUS2 ) ;
return ( ( reg > > 7 ) & 0x3f ) - 1 ;
}
2012-05-02 13:14:49 +04:00
/* Locking: the caller holds fimc->slock */
void fimc_activate_capture ( struct fimc_ctx * ctx )
{
fimc_hw_enable_scaler ( ctx - > fimc_dev , ctx - > scaler . enabled ) ;
2012-11-22 21:01:39 +04:00
fimc_hw_enable_capture ( ctx ) ;
2012-05-02 13:14:49 +04:00
}
void fimc_deactivate_capture ( struct fimc_dev * fimc )
{
fimc_hw_en_lastirq ( fimc , true ) ;
2012-11-22 21:01:39 +04:00
fimc_hw_disable_capture ( fimc ) ;
2012-05-02 13:14:49 +04:00
fimc_hw_enable_scaler ( fimc , false ) ;
fimc_hw_en_lastirq ( fimc , false ) ;
}