diff options
Diffstat (limited to 'drivers/video/samsung_duallcd/extension')
-rw-r--r-- | drivers/video/samsung_duallcd/extension/Makefile | 6 | ||||
-rw-r--r-- | drivers/video/samsung_duallcd/extension/cmc623.h | 725 | ||||
-rw-r--r-- | drivers/video/samsung_duallcd/extension/mdnie.c | 729 | ||||
-rw-r--r-- | drivers/video/samsung_duallcd/extension/mdnie.h | 134 | ||||
-rw-r--r-- | drivers/video/samsung_duallcd/extension/regs-mdnie.h | 166 | ||||
-rw-r--r-- | drivers/video/samsung_duallcd/extension/regs_fimd_lite.h | 396 | ||||
-rw-r--r-- | drivers/video/samsung_duallcd/extension/s5p_fimd_ext.c | 209 | ||||
-rw-r--r-- | drivers/video/samsung_duallcd/extension/s5p_fimd_ext.h | 30 | ||||
-rw-r--r-- | drivers/video/samsung_duallcd/extension/s5p_fimd_lite.c | 502 | ||||
-rw-r--r-- | drivers/video/samsung_duallcd/extension/s5p_fimd_lite.h | 37 |
10 files changed, 2934 insertions, 0 deletions
diff --git a/drivers/video/samsung_duallcd/extension/Makefile b/drivers/video/samsung_duallcd/extension/Makefile new file mode 100644 index 0000000..190c9cd --- /dev/null +++ b/drivers/video/samsung_duallcd/extension/Makefile @@ -0,0 +1,6 @@ +# +# Makefile for fimd extension driver. +# +obj-$(CONFIG_FIMD_EXT_SUPPORT) += s5p_fimd_ext.o +obj-$(CONFIG_FIMD_LITE_SUPPORT) += s5p_fimd_lite.o +obj-$(CONFIG_MDNIE_SUPPORT) += mdnie.o diff --git a/drivers/video/samsung_duallcd/extension/cmc623.h b/drivers/video/samsung_duallcd/extension/cmc623.h new file mode 100644 index 0000000..8da2e79 --- /dev/null +++ b/drivers/video/samsung_duallcd/extension/cmc623.h @@ -0,0 +1,725 @@ +/* + * CMC623 Setting table for SLP7 Machine. + * + * Author: InKi Dae <inki.dae@samsung.com> + * Eunchul Kim <chulspro.kim@samsung.com> + * + * 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 of the License, 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; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "mdnie.h" + +static const unsigned short dynamic_ui[] = { + 0x0000, 0x0000, /*BANK 0*/ + 0x0008, 0x008c, /*Dither8 UC4 ABC2 CP1 | + CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/ + 0x0030, 0x0000, /*FA cs1 de8 hdr2 fa1*/ + 0x0092, 0x0040, /*DE pe*/ + 0x0093, 0x0040, /*DE pf*/ + 0x0094, 0x0040, /*DE pb*/ + 0x0095, 0x0040, /*DE ne*/ + 0x0096, 0x0040, /*DE nf*/ + 0x0097, 0x0040, /*DE nb*/ + 0x0098, 0x1000, /*DE max ratio*/ + 0x0099, 0x0100, /*DE min ratio*/ + 0x00b0, 0x1010, /*CS hg ry*/ + 0x00b1, 0x1010, /*CS hg gc*/ + 0x00b2, 0x1010, /*CS hg bm*/ + 0x00b3, 0x1804, /*CS weight grayTH*/ + 0x0000, 0x0001, /*BANK 1*/ + 0x001f, 0x0080, /*CC chsel strength*/ + 0x0020, 0x0000, /*CC lut r 0*/ + 0x0021, 0x0d93, /*CC lut r 16 144*/ + 0x0022, 0x1aa5, /*CC lut r 32 160*/ + 0x0023, 0x29b7, /*CC lut r 48 176*/ + 0x0024, 0x39c8, /*CC lut r 64 192*/ + 0x0025, 0x4bd8, /*CC lut r 80 208*/ + 0x0026, 0x5de6, /*CC lut r 96 224*/ + 0x0027, 0x6ff4, /*CC lut r 112 240*/ + 0x0028, 0x81ff, /*CC lut r 128 255*/ + 0x00ff, 0x0000, /*Mask Release*/ +}; + +static const unsigned short dynamic_gallery[] = { + 0x0000, 0x0000, /*BANK 0*/ + 0x0008, 0x008c, /*Dither8 UC4 ABC2 CP1 | + CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/ + 0x0030, 0x0000, /*FA cs1 de8 hdr2 fa1*/ + 0x0092, 0x0080, /*DE pe*/ + 0x0093, 0x0080, /*DE pf*/ + 0x0094, 0x0080, /*DE pb*/ + 0x0095, 0x0080, /*DE ne*/ + 0x0096, 0x0080, /*DE nf*/ + 0x0097, 0x0080, /*DE nb*/ + 0x0098, 0x1000, /*DE max ratio*/ + 0x0099, 0x0100, /*DE min ratio*/ + 0x00b0, 0x1010, /*CS hg ry*/ + 0x00b1, 0x1010, /*CS hg gc*/ + 0x00b2, 0x1010, /*CS hg bm*/ + 0x00b3, 0x1404, /*CS weight grayTH*/ + 0x0000, 0x0001, /*BANK 1*/ + 0x001f, 0x0080, /*CC chsel strength*/ + 0x0020, 0x0000, /*CC lut r 0*/ + 0x0021, 0x0d93, /*CC lut r 16 144*/ + 0x0022, 0x1aa5, /*CC lut r 32 160*/ + 0x0023, 0x29b7, /*CC lut r 48 176*/ + 0x0024, 0x39c8, /*CC lut r 64 192*/ + 0x0025, 0x4bd8, /*CC lut r 80 208*/ + 0x0026, 0x5de6, /*CC lut r 96 224*/ + 0x0027, 0x6ff4, /*CC lut r 112 240*/ + 0x0028, 0x81ff, /*CC lut r 128 255*/ + 0x00ff, 0x0000, /*Mask Release*/ +}; + +static const unsigned short dynamic_video[] = { + 0x0000, 0x0000, /*BANK 0*/ + 0x0008, 0x008c, /*Dither8 UC4 ABC2 CP1 | + CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/ + 0x0030, 0x0000, /*FA cs1 de8 hdr2 fa1*/ + 0x0092, 0x0080, /*DE pe*/ + 0x0093, 0x0080, /*DE pf*/ + 0x0094, 0x0080, /*DE pb*/ + 0x0095, 0x0080, /*DE ne*/ + 0x0096, 0x0080, /*DE nf*/ + 0x0097, 0x0080, /*DE nb*/ + 0x0098, 0x1000, /*DE max ratio*/ + 0x0099, 0x0100, /*DE min ratio*/ + 0x00b0, 0x1010, /*CS hg ry*/ + 0x00b1, 0x1010, /*CS hg gc*/ + 0x00b2, 0x1010, /*CS hg bm*/ + 0x00b3, 0x1404, /*CS weight grayTH*/ + 0x00e1, 0xff00, /*SCR RrCr*/ + 0x00e2, 0x00ff, /*SCR RgCg*/ + 0x00e3, 0x00ff, /*SCR RbCb*/ + 0x00e4, 0x00ff, /*SCR GrMr*/ + 0x00e5, 0xff00, /*SCR GgMg*/ + 0x00e6, 0x00ff, /*SCR GbMb*/ + 0x00e7, 0x00ff, /*SCR BrYr*/ + 0x00e8, 0x00ff, /*SCR BgYg*/ + 0x00e9, 0xff00, /*SCR BbYb*/ + 0x00ea, 0x00ff, /*SCR KrWr*/ + 0x00eb, 0x00ff, /*SCR KgWg*/ + 0x00ec, 0x00ff, /*SCR KbWb*/ + 0x0000, 0x0001, /*BANK 1*/ + 0x001f, 0x0080, /*CC chsel strength*/ + 0x0020, 0x0000, /*CC lut r 0*/ + 0x0021, 0x0d93, /*CC lut r 16 144*/ + 0x0022, 0x1aa5, /*CC lut r 32 160*/ + 0x0023, 0x29b7, /*CC lut r 48 176*/ + 0x0024, 0x39c8, /*CC lut r 64 192*/ + 0x0025, 0x4bd8, /*CC lut r 80 208*/ + 0x0026, 0x5de6, /*CC lut r 96 224*/ + 0x0027, 0x6ff4, /*CC lut r 112 240*/ + 0x0028, 0x81ff, /*CC lut r 128 255*/ + 0x00ff, 0x0000, /*Mask Release*/ +}; + +static const unsigned short dynamic_vtcall[] = { + 0x0000, 0x0000, /*BANK 0*/ + 0x0008, 0x008e, /*Dither8 UC4 ABC2 CP1 | + CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/ + 0x0030, 0x0005, /*FA cs1 | de8 dnr4 hdr2 fa1*/ + 0x0039, 0x0080, /*FA dnrWeight*/ + 0x0080, 0x0fff, /*DNR dirTh*/ + 0x0081, 0x19ff, /*DNR dirnumTh decon7Th*/ + 0x0082, 0xff16, /*DNR decon5Th maskTh*/ + 0x0083, 0x0000, /*DNR blTh*/ + 0x0092, 0x00e0, /*DE pe*/ + 0x0093, 0x00e0, /*DE pf*/ + 0x0094, 0x00e0, /*DE pb*/ + 0x0095, 0x00e0, /*DE ne*/ + 0x0096, 0x00e0, /*DE nf*/ + 0x0097, 0x00e0, /*DE nb*/ + 0x0098, 0x1000, /*DE max ratio*/ + 0x0099, 0x0010, /*DE min ratio*/ + 0x00b0, 0x1010, /*CS hg ry*/ + 0x00b1, 0x1010, /*CS hg gc*/ + 0x00b2, 0x1010, /*CS hg bm*/ + 0x00b3, 0x1a04, /*CS weight grayTH*/ + 0x0000, 0x0001, /*BANK 1*/ + 0x001f, 0x0080, /*CC chsel strength*/ + 0x0020, 0x0000, /*CC lut r 0*/ + 0x0021, 0x0d93, /*CC lut r 16 144*/ + 0x0022, 0x1aa5, /*CC lut r 32 160*/ + 0x0023, 0x29b7, /*CC lut r 48 176*/ + 0x0024, 0x39c8, /*CC lut r 64 192*/ + 0x0025, 0x4bd8, /*CC lut r 80 208*/ + 0x0026, 0x5de6, /*CC lut r 96 224*/ + 0x0027, 0x6ff4, /*CC lut r 112 240*/ + 0x0028, 0x81ff, /*CC lut r 128 255*/ + 0x00ff, 0x0000, /*Mask Release*/ +}; + +static const unsigned short movie_ui[] = { + 0x0000, 0x0000, /*BANK 0*/ + 0x0008, 0x0020, /*Dither8 UC4 ABC2 CP1 | + CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/ + 0x0030, 0x0000, /*FA cs1 de8 hdr2 fa1*/ + 0x00e1, 0xd6ac, /*SCR RrCr*/ + 0x00e2, 0x32ff, /*SCR RgCg*/ + 0x00e3, 0x2ef0, /*SCR RbCb*/ + 0x00e4, 0xa5fa, /*SCR GrMr*/ + 0x00e5, 0xff4d, /*SCR GgMg*/ + 0x00e6, 0x59ff, /*SCR GbMb*/ + 0x00e7, 0x00ff, /*SCR BrYr*/ + 0x00e8, 0x00fb, /*SCR BgYg*/ + 0x00e9, 0xff61, /*SCR BbYb*/ + 0x00ea, 0x00ff, /*SCR KrWr*/ + 0x00eb, 0x00f8, /*SCR KgWg*/ + 0x00ec, 0x00f1, /*SCR KbWb*/ + 0x00ff, 0x0000, /*Mask Release*/ +}; + +static const unsigned short movie_gallery[] = { + 0x0000, 0x0000, /*BANK 0*/ + 0x0008, 0x0020, /*Dither8 UC4 ABC2 CP1 | + CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/ + 0x0030, 0x0000, /*FA cs1 de8 hdr2 fa1*/ + 0x00e1, 0xd6ac, /*SCR RrCr*/ + 0x00e2, 0x32ff, /*SCR RgCg*/ + 0x00e3, 0x2ef0, /*SCR RbCb*/ + 0x00e4, 0xa5fa, /*SCR GrMr*/ + 0x00e5, 0xff4d, /*SCR GgMg*/ + 0x00e6, 0x59ff, /*SCR GbMb*/ + 0x00e7, 0x00ff, /*SCR BrYr*/ + 0x00e8, 0x00fb, /*SCR BgYg*/ + 0x00e9, 0xff61, /*SCR BbYb*/ + 0x00ea, 0x00ff, /*SCR KrWr*/ + 0x00eb, 0x00f8, /*SCR KgWg*/ + 0x00ec, 0x00f1, /*SCR KbWb*/ + 0x00ff, 0x0000, /*Mask Release*/ +}; + +static const unsigned short movie_video[] = { + 0x0000, 0x0000, /*BANK 0*/ + 0x0008, 0x0020, /*Dither8 UC4 ABC2 CP1 | + CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/ + 0x0030, 0x0000, /*FA cs1 de8 hdr2 fa1*/ + 0x0092, 0x0000, /*DE pe*/ + 0x0093, 0x0000, /*DE pf*/ + 0x0094, 0x0000, /*DE pb*/ + 0x0095, 0x0000, /*DE ne*/ + 0x0096, 0x0000, /*DE nf*/ + 0x0097, 0x0000, /*DE nb*/ + 0x00b0, 0x1010, /*CS hg ry*/ + 0x00b1, 0x1010, /*CS hg gc*/ + 0x00b2, 0x1010, /*CS hg bm*/ + 0x00b3, 0x1004, /*CS weight grayTH*/ + 0x00e1, 0xd6ac, /*SCR RrCr*/ + 0x00e2, 0x32ff, /*SCR RgCg*/ + 0x00e3, 0x2ef0, /*SCR RbCb*/ + 0x00e4, 0xa5fa, /*SCR GrMr*/ + 0x00e5, 0xff4d, /*SCR GgMg*/ + 0x00e6, 0x59ff, /*SCR GbMb*/ + 0x00e7, 0x00ff, /*SCR BrYr*/ + 0x00e8, 0x00fb, /*SCR BgYg*/ + 0x00e9, 0xff61, /*SCR BbYb*/ + 0x00ea, 0x00ff, /*SCR KrWr*/ + 0x00eb, 0x00f8, /*SCR KgWg*/ + 0x00ec, 0x00f1, /*SCR KbWb*/ + 0x0000, 0x0001, /*BANK 1*/ + 0x001f, 0x0000, /*CC chsel strength*/ + 0x00ff, 0x0000, /*Mask Release*/ +}; + +static const unsigned short movie_vtcall[] = { + 0x0000, 0x0000, /*BANK 0*/ + 0x0008, 0x002e, /*Dither8 UC4 ABC2 CP1 | + CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/ + 0x0030, 0x0005, /*FA cs1 | de8 dnr4 hdr2 fa1*/ + 0x0039, 0x0080, /*FA dnrWeight*/ + 0x0080, 0x0fff, /*DNR dirTh*/ + 0x0081, 0x19ff, /*DNR dirnumTh decon7Th*/ + 0x0082, 0xff16, /*DNR decon5Th maskTh*/ + 0x0083, 0x0000, /*DNR blTh*/ + 0x0092, 0x0040, /*DE pe*/ + 0x0093, 0x0040, /*DE pf*/ + 0x0094, 0x0040, /*DE pb*/ + 0x0095, 0x0040, /*DE ne*/ + 0x0096, 0x0040, /*DE nf*/ + 0x0097, 0x0040, /*DE nb*/ + 0x0098, 0x1000, /*DE max ratio*/ + 0x0099, 0x0010, /*DE min ratio*/ + 0x00b0, 0x1010, /*CS hg ry*/ + 0x00b1, 0x1010, /*CS hg gc*/ + 0x00b2, 0x1010, /*CS hg bm*/ + 0x00b3, 0x1204, /*CS weight grayTH*/ + 0x00e1, 0xd6ac, /*SCR RrCr*/ + 0x00e2, 0x32ff, /*SCR RgCg*/ + 0x00e3, 0x2ef0, /*SCR RbCb*/ + 0x00e4, 0xa5fa, /*SCR GrMr*/ + 0x00e5, 0xff4d, /*SCR GgMg*/ + 0x00e6, 0x59ff, /*SCR GbMb*/ + 0x00e7, 0x00ff, /*SCR BrYr*/ + 0x00e8, 0x00fb, /*SCR BgYg*/ + 0x00e9, 0xff61, /*SCR BbYb*/ + 0x00ea, 0x00ff, /*SCR KrWr*/ + 0x00eb, 0x00f8, /*SCR KgWg*/ + 0x00ec, 0x00f1, /*SCR KbWb*/ + 0x00ff, 0x0000, /*Mask Release*/ +}; + +static const unsigned short natural_ui[] = { + 0x0000, 0x0000, /*BANK 0*/ + 0x0008, 0x002c, /*Dither8 UC4 ABC2 CP1 | + CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/ + 0x0030, 0x0000, /*FA cs1 de8 hdr2 fa1*/ + 0x0092, 0x0020, /*DE pe*/ + 0x0093, 0x0020, /*DE pf*/ + 0x0094, 0x0020, /*DE pb*/ + 0x0095, 0x0020, /*DE ne*/ + 0x0096, 0x0020, /*DE nf*/ + 0x0097, 0x0020, /*DE nb*/ + 0x0098, 0x1000, /*DE max ratio*/ + 0x0099, 0x0100, /*DE min ratio*/ + 0x00b0, 0x1010, /*CS hg ry*/ + 0x00b1, 0x1010, /*CS hg gc*/ + 0x00b2, 0x1010, /*CS hg bm*/ + 0x00b3, 0x1804, /*CS weight grayTH*/ + 0x00e1, 0xd6ac, /*SCR RrCr*/ + 0x00e2, 0x32ff, /*SCR RgCg*/ + 0x00e3, 0x2ef0, /*SCR RbCb*/ + 0x00e4, 0xa5fa, /*SCR GrMr*/ + 0x00e5, 0xff4d, /*SCR GgMg*/ + 0x00e6, 0x59ff, /*SCR GbMb*/ + 0x00e7, 0x00ff, /*SCR BrYr*/ + 0x00e8, 0x00fb, /*SCR BgYg*/ + 0x00e9, 0xff61, /*SCR BbYb*/ + 0x00ea, 0x00ff, /*SCR KrWr*/ + 0x00eb, 0x00fa, /*SCR KgWg*/ + 0x00ec, 0x00f8, /*SCR KbWb*/ + 0x00ff, 0x0000, /*Mask Release*/ +}; + +static const unsigned short natural_gallery[] = { + 0x0000, 0x0000, /*BANK 0*/ + 0x0008, 0x002c, /*Dither8 UC4 ABC2 CP1 | + CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/ + 0x0030, 0x0000, /*FA cs1 de8 hdr2 fa1*/ + 0x0092, 0x0060, /*DE pe*/ + 0x0093, 0x0060, /*DE pf*/ + 0x0094, 0x0060, /*DE pb*/ + 0x0095, 0x0060, /*DE ne*/ + 0x0096, 0x0060, /*DE nf*/ + 0x0097, 0x0060, /*DE nb*/ + 0x0098, 0x1000, /*DE max ratio*/ + 0x0099, 0x0100, /*DE min ratio*/ + 0x00b0, 0x1010, /*CS hg ry*/ + 0x00b1, 0x1010, /*CS hg gc*/ + 0x00b2, 0x1010, /*CS hg bm*/ + 0x00b3, 0x1804, /*CS weight grayTH*/ + 0x00e1, 0xd6ac, /*SCR RrCr*/ + 0x00e2, 0x32ff, /*SCR RgCg*/ + 0x00e3, 0x2ef0, /*SCR RbCb*/ + 0x00e4, 0xa5fa, /*SCR GrMr*/ + 0x00e5, 0xff4d, /*SCR GgMg*/ + 0x00e6, 0x59ff, /*SCR GbMb*/ + 0x00e7, 0x00ff, /*SCR BrYr*/ + 0x00e8, 0x00fb, /*SCR BgYg*/ + 0x00e9, 0xff61, /*SCR BbYb*/ + 0x00ea, 0x00ff, /*SCR KrWr*/ + 0x00eb, 0x00fa, /*SCR KgWg*/ + 0x00ec, 0x00f8, /*SCR KbWb*/ + 0x00ff, 0x0000, /*Mask Release*/ +}; + +static const unsigned short natural_video[] = { + 0x0000, 0x0000, /*BANK 0*/ + 0x0008, 0x002c, /*Dither8 UC4 ABC2 CP1 | + CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/ + 0x0030, 0x0000, /*FA cs1 de8 hdr2 fa1*/ + 0x0092, 0x0060, /*DE pe*/ + 0x0093, 0x0060, /*DE pf*/ + 0x0094, 0x0060, /*DE pb*/ + 0x0095, 0x0060, /*DE ne*/ + 0x0096, 0x0060, /*DE nf*/ + 0x0097, 0x0060, /*DE nb*/ + 0x0098, 0x1000, /*DE max ratio*/ + 0x0099, 0x0100, /*DE min ratio*/ + 0x00b0, 0x1010, /*CS hg ry*/ + 0x00b1, 0x1010, /*CS hg gc*/ + 0x00b2, 0x1010, /*CS hg bm*/ + 0x00b3, 0x1804, /*CS weight grayTH*/ + 0x00e1, 0xd6ac, /*SCR RrCr*/ + 0x00e2, 0x32ff, /*SCR RgCg*/ + 0x00e3, 0x2ef0, /*SCR RbCb*/ + 0x00e4, 0xa5fa, /*SCR GrMr*/ + 0x00e5, 0xff4d, /*SCR GgMg*/ + 0x00e6, 0x59ff, /*SCR GbMb*/ + 0x00e7, 0x00ff, /*SCR BrYr*/ + 0x00e8, 0x00fb, /*SCR BgYg*/ + 0x00e9, 0xff61, /*SCR BbYb*/ + 0x00ea, 0x00ff, /*SCR KrWr*/ + 0x00eb, 0x00fa, /*SCR KgWg*/ + 0x00ec, 0x00f8, /*SCR KbWb*/ + 0x0000, 0x0001, /*BANK 1*/ + 0x001f, 0x0000, /*CC chsel strength*/ + 0x00ff, 0x0000, /*Mask Release*/ +}; + +static const unsigned short natural_vtcall[] = { + 0x0000, 0x0000, /*BANK 0*/ + 0x0008, 0x002e, /*Dither8 UC4 ABC2 CP1 | + CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/ + 0x0030, 0x0005, /*FA cs1 | de8 dnr4 hdr2 fa1*/ + 0x0039, 0x0080, /*FA dnrWeight*/ + 0x0080, 0x0fff, /*DNR dirTh*/ + 0x0081, 0x19ff, /*DNR dirnumTh decon7Th*/ + 0x0082, 0xff16, /*DNR decon5Th maskTh*/ + 0x0083, 0x0000, /*DNR blTh*/ + 0x0092, 0x00c0, /*DE pe*/ + 0x0093, 0x00c0, /*DE pf*/ + 0x0094, 0x00c0, /*DE pb*/ + 0x0095, 0x00c0, /*DE ne*/ + 0x0096, 0x00c0, /*DE nf*/ + 0x0097, 0x00c0, /*DE nb*/ + 0x0098, 0x1000, /*DE max ratio*/ + 0x0099, 0x0010, /*DE min ratio*/ + 0x00b0, 0x1010, /*CS hg ry*/ + 0x00b1, 0x1010, /*CS hg gc*/ + 0x00b2, 0x1010, /*CS hg bm*/ + 0x00b3, 0x1804, /*CS weight grayTH*/ + 0x00e1, 0xd6ac, /*SCR RrCr*/ + 0x00e2, 0x32ff, /*SCR RgCg*/ + 0x00e3, 0x2ef0, /*SCR RbCb*/ + 0x00e4, 0xa5fa, /*SCR GrMr*/ + 0x00e5, 0xff4d, /*SCR GgMg*/ + 0x00e6, 0x59ff, /*SCR GbMb*/ + 0x00e7, 0x00ff, /*SCR BrYr*/ + 0x00e8, 0x00fb, /*SCR BgYg*/ + 0x00e9, 0xff61, /*SCR BbYb*/ + 0x00ea, 0x00ff, /*SCR KrWr*/ + 0x00eb, 0x00fa, /*SCR KgWg*/ + 0x00ec, 0x00f8, /*SCR KbWb*/ + 0x00ff, 0x0000, /*Mask Release*/ +}; + +static const unsigned short standard_ui[] = { + 0x0000, 0x0000, /*BANK 0*/ + 0x0008, 0x000c, /*Dither8 UC4 ABC2 CP1 | + CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/ + 0x0030, 0x0000, /*FA cs1 de8 hdr2 fa1*/ + 0x0092, 0x0020, /*DE pe*/ + 0x0093, 0x0020, /*DE pf*/ + 0x0094, 0x0020, /*DE pb*/ + 0x0095, 0x0020, /*DE ne*/ + 0x0096, 0x0020, /*DE nf*/ + 0x0097, 0x0020, /*DE nb*/ + 0x0098, 0x1000, /*DE max ratio*/ + 0x0099, 0x0100, /*DE min ratio*/ + 0x00b0, 0x1010, /*CS hg ry*/ + 0x00b1, 0x1010, /*CS hg gc*/ + 0x00b2, 0x1010, /*CS hg bm*/ + 0x00b3, 0x1604, /*CS weight grayTH*/ + 0x00ff, 0x0000, /*Mask Release*/ +}; + +static const unsigned short standard_gallery[] = { + 0x0000, 0x0000, /*BANK 0*/ + 0x0008, 0x000c, /*Dither8 UC4 ABC2 CP1 | + CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/ + 0x0030, 0x0000, /*FA cs1 de8 hdr2 fa1*/ + 0x0092, 0x0060, /*DE pe*/ + 0x0093, 0x0060, /*DE pf*/ + 0x0094, 0x0060, /*DE pb*/ + 0x0095, 0x0060, /*DE ne*/ + 0x0096, 0x0060, /*DE nf*/ + 0x0097, 0x0060, /*DE nb*/ + 0x0098, 0x1000, /*DE max ratio*/ + 0x0099, 0x0100, /*DE min ratio*/ + 0x00b0, 0x1010, /*CS hg ry*/ + 0x00b1, 0x1010, /*CS hg gc*/ + 0x00b2, 0x1010, /*CS hg bm*/ + 0x00b3, 0x1204, /*CS weight grayTH*/ + 0x00ff, 0x0000, /*Mask Release*/ +}; + +static const unsigned short standard_video[] = { + 0x0000, 0x0000, /*BANK 0*/ + 0x0008, 0x000c, /*Dither8 UC4 ABC2 CP1 | + CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/ + 0x0030, 0x0000, /*FA cs1 de8 hdr2 fa1*/ + 0x0092, 0x0060, /*DE pe*/ + 0x0093, 0x0060, /*DE pf*/ + 0x0094, 0x0060, /*DE pb*/ + 0x0095, 0x0060, /*DE ne*/ + 0x0096, 0x0060, /*DE nf*/ + 0x0097, 0x0060, /*DE nb*/ + 0x0098, 0x1000, /*DE max ratio*/ + 0x0099, 0x0100, /*DE min ratio*/ + 0x00b0, 0x1010, /*CS hg ry*/ + 0x00b1, 0x1010, /*CS hg gc*/ + 0x00b2, 0x1010, /*CS hg bm*/ + 0x00b3, 0x1204, /*CS weight grayTH*/ + 0x00e1, 0xff00, /*SCR RrCr*/ + 0x00e2, 0x00ff, /*SCR RgCg*/ + 0x00e3, 0x00ff, /*SCR RbCb*/ + 0x00e4, 0x00ff, /*SCR GrMr*/ + 0x00e5, 0xff00, /*SCR GgMg*/ + 0x00e6, 0x00ff, /*SCR GbMb*/ + 0x00e7, 0x00ff, /*SCR BrYr*/ + 0x00e8, 0x00ff, /*SCR BgYg*/ + 0x00e9, 0xff00, /*SCR BbYb*/ + 0x00ea, 0x00ff, /*SCR KrWr*/ + 0x00eb, 0x00ff, /*SCR KgWg*/ + 0x00ec, 0x00ff, /*SCR KbWb*/ + 0x0000, 0x0001, /*BANK 1*/ + 0x001f, 0x0000, /*CC chsel strength*/ + 0x00ff, 0x0000, /*Mask Release*/ +}; + +static const unsigned short standard_vtcall[] = { + 0x0000, 0x0000, /*BANK 0*/ + 0x0008, 0x000e, /*Dither8 UC4 ABC2 CP1 | + CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/ + 0x0030, 0x0005, /*FA cs1 | de8 dnr4 hdr2 fa1*/ + 0x0039, 0x0080, /*FA dnrWeight*/ + 0x0080, 0x0fff, /*DNR dirTh*/ + 0x0081, 0x19ff, /*DNR dirnumTh decon7Th*/ + 0x0082, 0xff16, /*DNR decon5Th maskTh*/ + 0x0083, 0x0000, /*DNR blTh*/ + 0x0092, 0x00c0, /*DE pe*/ + 0x0093, 0x00c0, /*DE pf*/ + 0x0094, 0x00c0, /*DE pb*/ + 0x0095, 0x00c0, /*DE ne*/ + 0x0096, 0x00c0, /*DE nf*/ + 0x0097, 0x00c0, /*DE nb*/ + 0x0098, 0x1000, /*DE max ratio*/ + 0x0099, 0x0010, /*DE min ratio*/ + 0x00b0, 0x1010, /*CS hg ry*/ + 0x00b1, 0x1010, /*CS hg gc*/ + 0x00b2, 0x1010, /*CS hg bm*/ + 0x00b3, 0x1804, /*CS weight grayTH*/ + 0x00ff, 0x0000, /*Mask Release*/ +}; + +static const unsigned short camera[] = { + 0x0000, 0x0000, /*BANK 0*/ + 0x0008, 0x000c, /*Dither8 UC4 ABC2 CP1 | + CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/ + 0x0030, 0x0000, /*FA cs1 de8 hdr2 fa1*/ + 0x0092, 0x0060, /*DE pe*/ + 0x0093, 0x0060, /*DE pf*/ + 0x0094, 0x0060, /*DE pb*/ + 0x0095, 0x0060, /*DE ne*/ + 0x0096, 0x0060, /*DE nf*/ + 0x0097, 0x0060, /*DE nb*/ + 0x0098, 0x1000, /*DE max ratio*/ + 0x0099, 0x0100, /*DE min ratio*/ + 0x00b0, 0x1010, /*CS hg ry*/ + 0x00b1, 0x1010, /*CS hg gc*/ + 0x00b2, 0x1010, /*CS hg bm*/ + 0x00b3, 0x1204, /*CS weight grayTH*/ + 0x00ff, 0x0000, /*Mask Release*/ +}; + +static const unsigned short camera_outdoor[] = { + 0x0000, 0x0000, /*BANK 0*/ + 0x0008, 0x040c, /*Dither8 UC4 ABC2 CP1 | + CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/ + 0x0030, 0x0000, /*FA cs1 de8 hdr2 fa1*/ + 0x0092, 0x0060, /*DE pe*/ + 0x0093, 0x0060, /*DE pf*/ + 0x0094, 0x0060, /*DE pb*/ + 0x0095, 0x0060, /*DE ne*/ + 0x0096, 0x0060, /*DE nf*/ + 0x0097, 0x0060, /*DE nb*/ + 0x0098, 0x1000, /*DE max ratio*/ + 0x0099, 0x0100, /*DE min ratio*/ + 0x00b0, 0x1010, /*CS hg RY*/ + 0x00b1, 0x1010, /*CS hg GC*/ + 0x00b2, 0x1010, /*CS hg BM*/ + 0x00b3, 0x1204, /*CS weight grayTH*/ + 0x0000, 0x0001, /*BANK 1*/ + 0x00d0, 0x01c0, /*UC y*/ + 0x00d1, 0x01ff, /*UC cs*/ + 0x00ff, 0x0000, /*Mask Release*/ +}; + +static const unsigned short browser_tone1[] = { + 0x0000, 0x0000, /*BANK 0*/ + 0x0008, 0x0020, /*Dither8 UC4 ABC2 CP1 | + CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/ + 0x0030, 0x0000, /*FA cs1 de8 hdr2 fa1*/ + 0x00e1, 0xaf00, /*SCR RrCr*/ + 0x00e2, 0x00b7, /*SCR RgCg*/ + 0x00e3, 0x00bc, /*SCR RbCb*/ + 0x00e4, 0x00af, /*SCR GrMr*/ + 0x00e5, 0xb700, /*SCR GgMg*/ + 0x00e6, 0x00bc, /*SCR GbMb*/ + 0x00e7, 0x00af, /*SCR BrYr*/ + 0x00e8, 0x00b7, /*SCR BgYg*/ + 0x00e9, 0xbc00, /*SCR BbYb*/ + 0x00ea, 0x00af, /*SCR KrWr*/ + 0x00eb, 0x00b7, /*SCR KgWg*/ + 0x00ec, 0x00bc, /*SCR KbWb*/ + 0x00ff, 0x0000, /*Mask Release*/ +}; + +static const unsigned short browser_tone2[] = { + 0x0000, 0x0000, /*BANK 0*/ + 0x0008, 0x0020, /*Dither8 UC4 ABC2 CP1 | + CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/ + 0x0030, 0x0000, /*FA cs1 de8 hdr2 fa1*/ + 0x00e1, 0xa000, /*SCR RrCr*/ + 0x00e2, 0x00a8, /*SCR RgCg*/ + 0x00e3, 0x00b2, /*SCR RbCb*/ + 0x00e4, 0x00a0, /*SCR GrMr*/ + 0x00e5, 0xa800, /*SCR GgMg*/ + 0x00e6, 0x00b2, /*SCR GbMb*/ + 0x00e7, 0x00a0, /*SCR BrYr*/ + 0x00e8, 0x00a8, /*SCR BgYg*/ + 0x00e9, 0xb200, /*SCR BbYb*/ + 0x00ea, 0x00a0, /*SCR KrWr*/ + 0x00eb, 0x00a8, /*SCR KgWg*/ + 0x00ec, 0x00b2, /*SCR KbWb*/ + 0x00ff, 0x0000, /*Mask Release*/ +}; + +static const unsigned short browser_tone3[] = { + 0x0000, 0x0000, /*BANK 0*/ + 0x0008, 0x0020, /*Dither8 UC4 ABC2 CP1 | + CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/ + 0x0030, 0x0000, /*FA cs1 de8 hdr2 fa1*/ + 0x00e1, 0x9100, /*SCR RrCr*/ + 0x00e2, 0x0099, /*SCR RgCg*/ + 0x00e3, 0x00a3, /*SCR RbCb*/ + 0x00e4, 0x0091, /*SCR GrMr*/ + 0x00e5, 0x9900, /*SCR GgMg*/ + 0x00e6, 0x00a3, /*SCR GbMb*/ + 0x00e7, 0x0091, /*SCR BrYr*/ + 0x00e8, 0x0099, /*SCR BgYg*/ + 0x00e9, 0xa300, /*SCR BbYb*/ + 0x00ea, 0x0091, /*SCR KrWr*/ + 0x00eb, 0x0099, /*SCR KgWg*/ + 0x00ec, 0x00a3, /*SCR KbWb*/ + 0x00ff, 0x0000, /*Mask Release*/ +}; + +static const unsigned short bypass[] = { + 0x0000, 0x0000, /*BANK 0*/ + 0x0008, 0x0000, /*Dither8 UC4 ABC2 CP1 | + CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/ + 0x0030, 0x0000, /*FA cs1 | de8 hdr2 fa1*/ + 0x00ff, 0x0000, /*Mask Release*/ +}; + +static const unsigned short negative[] = { + 0x0000, 0x0000, /*BANK 0*/ + 0x0008, 0x0020, /*SCR*/ + 0x00e1, 0x00ff, /*SCR RrCr*/ + 0x00e2, 0xff00, /*SCR RgCg*/ + 0x00e3, 0xff00, /*SCR RbCb*/ + 0x00e4, 0xff00, /*SCR GrMr*/ + 0x00e5, 0x00ff, /*SCR GgMg*/ + 0x00e6, 0xff00, /*SCR GbMb*/ + 0x00e7, 0xff00, /*SCR BrYr*/ + 0x00e8, 0xff00, /*SCR BgYg*/ + 0x00e9, 0x00ff, /*SCR BbYb*/ + 0x00ea, 0xff00, /*SCR KrWr*/ + 0x00eb, 0xff00, /*SCR KgWg*/ + 0x00ec, 0xff00, /*SCR KbWb*/ + 0x00ff, 0x0000, /*Mask Release*/ +}; + +static const unsigned short outdoor[] = { + 0x0000, 0x0000, /*BANK 0*/ + 0x0008, 0x04ac, /*Dither8 UC4 ABC2 CP1 | + CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/ + 0x0000, 0x0001, /*BANK 1*/ + 0x00d0, 0x01c0, /*UC y*/ + 0x00d1, 0x01ff, /*UC cs*/ + 0x00ff, 0x0000, /*Mask Release*/ +}; + +static const unsigned short cold[] = { + 0x0000, 0x0000, /*BANK 0*/ + 0x0008, 0x00ec, /*Dither8 UC4 ABC2 CP1 | + CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/ + 0x0000, 0x0001, /*BANK 1*/ + 0x0001, 0x0064, /*MCM 10000K*/ + 0x0009, 0xa08b, /*MCM 5cb 1cr W*/ + 0x000b, 0x7a7a, /*MCM 4cr 5cr W*/ + 0x00ff, 0x0000, /*Mask Release*/ +}; + +static const unsigned short cold_outdoor[] = { + 0x0000, 0x0000, /*BANK 0*/ + 0x0008, 0x04ec, /*Dither8 UC4 ABC2 CP1 | + CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/ + 0x0000, 0x0001, /*BANK 1*/ + 0x0001, 0x0064, /*MCM 10000K*/ + 0x0009, 0xa08b, /*MCM 5cb 1cr W*/ + 0x000b, 0x7a7a, /*MCM 4cr 5cr W*/ + 0x00d0, 0x01c0, /*UC y*/ + 0x00d1, 0x01ff, /*UC cs*/ + 0x00ff, 0x0000, /*Mask Release*/ +}; + +static const unsigned short warm[] = { + 0x0000, 0x0000, /*BANK 0*/ + 0x0008, 0x00ec, /*Dither8 UC4 ABC2 CP1 | + CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/ + 0x0000, 0x0001, /*BANK 1*/ + 0x0001, 0x0028, /*MCM 4000K*/ + 0x0007, 0x7878, /*MCM 1cb 2cb W*/ + 0x0009, 0xa08b, /*MCM 5cb 1cr W*/ + 0x00ff, 0x0000, /*Mask Release*/ +}; + +static const unsigned short warm_outdoor[] = { + 0x0000, 0x0000, /*BANK 0*/ + 0x0008, 0x04ec, /*Dither8 UC4 ABC2 CP1 | + CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/ + 0x0000, 0x0001, /*BANK 1*/ + 0x0001, 0x0028, /*MCM 4000K*/ + 0x0007, 0x7878, /*MCM 1cb 2cb W*/ + 0x0009, 0xa08b, /*MCM 5cb 1cr W*/ + 0x00d0, 0x01c0, /*UC y*/ + 0x00d1, 0x01ff, /*UC cs*/ + 0x00ff, 0x0000, /*Mask Release*/ +}; + +const struct mdnie_tables mdnie_main_tables[] = { + { "dynamic_ui", dynamic_ui, ARRAY_SIZE(dynamic_ui) }, + { "dynamic_gallery", dynamic_gallery, ARRAY_SIZE(dynamic_gallery) }, + { "dynamic_video", dynamic_video, ARRAY_SIZE(dynamic_video) }, + { "dynamic_vtcall", dynamic_vtcall, ARRAY_SIZE(dynamic_vtcall) }, + { "standard_ui", standard_ui, ARRAY_SIZE(standard_ui) }, + { "standard_gallery", standard_gallery, ARRAY_SIZE(standard_gallery) }, + { "standard_video", standard_video, ARRAY_SIZE(standard_video) }, + { "standard_vtcall", standard_vtcall, ARRAY_SIZE(standard_vtcall) }, + { "natural_ui", natural_ui, ARRAY_SIZE(natural_ui) }, + { "natural_gallery", natural_gallery, ARRAY_SIZE(natural_gallery) }, + { "natural_video", natural_video, ARRAY_SIZE(natural_video) }, + { "natural_vtcall", natural_vtcall, ARRAY_SIZE(natural_vtcall) }, + { "movie_ui", movie_ui, ARRAY_SIZE(movie_ui) }, + { "movie_gallery", movie_gallery, ARRAY_SIZE(movie_gallery) }, + { "movie_video", movie_video, ARRAY_SIZE(movie_video) }, + { "movie_vtcall", movie_vtcall, ARRAY_SIZE(movie_vtcall) }, + { "camera", camera, ARRAY_SIZE(camera) }, + { "camera_outdoor", camera_outdoor, ARRAY_SIZE(camera_outdoor) }, + { "browser_tone1", browser_tone1, ARRAY_SIZE(browser_tone1) }, + { "browser_tone2", browser_tone2, ARRAY_SIZE(browser_tone2) }, + { "browser_tone3", browser_tone3, ARRAY_SIZE(browser_tone3) }, + { "negative", negative, ARRAY_SIZE(negative) }, + { "bypass", bypass, ARRAY_SIZE(bypass) }, + { "outdoor", outdoor, ARRAY_SIZE(outdoor) }, + { "warm", warm, ARRAY_SIZE(warm) }, + { "warm_outdoor", warm_outdoor, ARRAY_SIZE(warm_outdoor) }, + { "cold", cold, ARRAY_SIZE(cold) }, + { "cold_outdoor", cold_outdoor, ARRAY_SIZE(cold_outdoor) }, +}; + diff --git a/drivers/video/samsung_duallcd/extension/mdnie.c b/drivers/video/samsung_duallcd/extension/mdnie.c new file mode 100644 index 0000000..e2ad4cc --- /dev/null +++ b/drivers/video/samsung_duallcd/extension/mdnie.c @@ -0,0 +1,729 @@ +/* /linux/driver/video/samsung/mdnie.c + * + * Samsung SoC mDNIe driver. + * + * Copyright (c) 2011 Samsung Electronics. + * Author: InKi Dae <inki.dae@samsung.com> + * Eunchul Kim <chulspro.kim@samsung.com> + * + * 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 of the License, 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; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/errno.h> +#include <linux/err.h> +#include <linux/io.h> +#include <linux/slab.h> +#include <linux/platform_device.h> +#include <linux/firmware.h> + +#include <plat/fimd_lite_ext.h> +#include <mach/map.h> + +#include "regs-mdnie.h" +#include "mdnie.h" +#include "s5p_fimd_ext.h" +#include "cmc623.h" + +/* FIXME:!! need to change chip id dynamically */ +#define MDNIE_CHIP_ID "cmc623p" + +static const char *mode_name[MODE_MAX] = { + "dynamic", + "standard", + "natural", + "movie" +}; + +static const char *scenario_name[SCENARIO_MAX] = { + "ui", + "gallery", + "video", + "vtcall", + "camera", + "browser", + "negative", + "bypass" +}; + +static const char *tone_name[TONE_MAX] = { + "", + "warm", + "cold", +}; + +static const char *tone_browser_name[TONE_BR_MAX] = { + "tone1", + "tone2", + "tone3" +}; + +static const char *outdoor_name[OUTDOOR_MAX] = { + "", + "outdoor" +}; + +#if defined(DEBUG) +#define mdnie_info(fmt, args...) \ + do { \ + printk(KERN_NOTICE"%s:"fmt"\n", __func__, ##args); \ + } while (0); +#else +#define mdnie_info(fmt, args...) +#endif + +static struct mdnie_platform_data + *to_mdnie_platform_data(struct s5p_fimd_ext_device *fx_dev) +{ + return fx_dev->dev.platform_data ? + (struct mdnie_platform_data *)fx_dev->dev.platform_data : NULL; +} + +static void mdnie_write_tune(struct s5p_mdnie *mdnie, + const unsigned short *tune, + unsigned int size) +{ + unsigned int i = 0; + + mdnie_info("size[%d]", size); + while (i < size) { + writel(tune[i + 1], mdnie->regs + tune[i] * 4); + i += 2; + } +} + +static int mdnie_request_fw(struct s5p_mdnie *mdnie, const char *name) +{ + const struct firmware *fw; + char fw_path[MDNIE_MAX_STR+1]; + int ret; + + snprintf(fw_path, MDNIE_MAX_STR, MDNIE_FW_PATH, MDNIE_CHIP_ID, name); + mdnie_info("fw_path[%s]", fw_path); + mutex_lock(&mdnie->lock); + + ret = request_firmware(&fw, fw_path, mdnie->dev); + if (ret) { + dev_err(mdnie->dev, "failed to request firmware.\n"); + mutex_unlock(&mdnie->lock); + return ret; + } + + mdnie_write_tune(mdnie, (const unsigned short *)fw->data, + fw->size / sizeof(const unsigned short)); + release_firmware(fw); + + mutex_unlock(&mdnie->lock); + + return 0; +} + +static int mdnie_request_tables(struct s5p_mdnie *mdnie, const char *name) +{ + struct mdnie_tables *tables; + int i; + + mdnie_info("name[%s]", name); + tables = (struct mdnie_tables *)&mdnie_main_tables; + if (!tables) { + dev_err(mdnie->dev, "mode mdnie tables is NULL.\n"); + return -EINVAL; + } + + for (i = 0; i < ARRAY_SIZE(mdnie_main_tables); i++) { + if (strcmp(name , tables[i].name) == 0) { + mdnie_info("tune_id[%d]name[%s]", i, tables[i].name); + mdnie_write_tune(mdnie, tables[i].value, + tables[i].size); + break; + } + } + + return 0; +} + +static int mdnie_get_name(struct s5p_mdnie *mdnie, char *name, + enum mdnie_set set) +{ + enum mdnie_mode mode = mdnie->mode; + enum mdnie_scenario scenario = mdnie->scenario; + int tone = mdnie->tone; + enum mdnie_outdoor outdoor = mdnie->outdoor; + + mdnie_info("set[%d]:mode[%d]scenario[%d]tone[%d]outdoor[%d]", + set, mode, scenario, tone, outdoor); + switch (scenario) { + case SCENARIO_CAMERA: + strcat(name, scenario_name[scenario]); + if (outdoor == OUTDOOR_ON) { + strcat(name, "_"); + strcat(name , outdoor_name[outdoor]); + } + break; + case SCENARIO_BROWSER: + strcat(name, scenario_name[scenario]); + strcat(name, "_"); + strcat(name, tone_browser_name[tone]); + break; + default: + if (set == SET_MAIN || + (tone == TONE_NORMAL && outdoor == OUTDOOR_OFF)) { + if (scenario < SCENARIO_MODE_MAX) { + if (mode < MODE_MAX) + strcat(name, mode_name[mode]); + + strcat(name, "_"); + + if (scenario < SCENARIO_MODE_MAX) + strcat(name, + scenario_name[scenario]); + } else + strcat(name, scenario_name[scenario]); + } else { + if (tone < TONE_MAX) + strcat(name, tone_name[tone]); + + if (tone != TONE_NORMAL && outdoor == OUTDOOR_ON) + strcat(name, "_"); + + if (outdoor < OUTDOOR_MAX) + strcat(name , outdoor_name[outdoor]); + } + break; + } + + return strlen(name); +} + +static int mdnie_set_commit(struct s5p_mdnie *mdnie, + enum mdnie_set set) +{ + struct mdnie_manager_ops *mops = mdnie->mops; + char name[MDNIE_MAX_STR+1]; + int ret = 0, len = 0; + + memset(name, 0, MDNIE_MAX_STR+1); + len = mdnie_get_name(mdnie, name, set); + if (len == 0) { + dev_err(mdnie->dev, "failed to find tune.\n"); + return ret; + } + + if (mops && mops->tune) { + ret = mops->tune(mdnie, name); + if (ret) { + dev_err(mdnie->dev, "failed to set tune.\n"); + return ret; + } + } else { + dev_err(mdnie->dev, "invalid mdnie mops.\n"); + return -EINVAL; + } + + return ret; +} + +static int mdnie_check_tone(struct s5p_mdnie *mdnie, int tone) +{ + unsigned long max_tone; + + if (mdnie->scenario == SCENARIO_BROWSER) + max_tone = TONE_BR_MAX; + else + max_tone = TONE_MAX; + + if (tone >= max_tone) { + dev_err(mdnie->dev, "invalid mdnie tone.\n"); + return -EINVAL; + } + + if (mdnie->scenario != SCENARIO_VIDEO + && mdnie->scenario != SCENARIO_BROWSER) { + /* Set to default */ + mdnie->tone = 0; + dev_err(mdnie->dev, "invalid mdnie scenario.\n"); + return -EIO; + } + + return 0; +} + +struct mdnie_manager_ops mdnie_set_mops = { + .tune = mdnie_request_tables, + .commit = mdnie_set_commit, + .check_tone = mdnie_check_tone, +}; + +static void mdnie_set_size(struct s5p_mdnie *mdnie, + unsigned int width, unsigned int height) +{ + unsigned int size; + + writel(0x0, mdnie->regs + MDNIE_R0); + + /* Input Data Unmask */ + writel(0x077, mdnie->regs + MDNIE_R1); + + /* LCD width */ + size = readl(mdnie->regs + MDNIE_R3); + size &= ~MDNIE_R34_WIDTH_MASK; + size |= width; + writel(size, mdnie->regs + MDNIE_R3); + + /* LCD height */ + size = readl(mdnie->regs + MDNIE_R4); + size &= ~MDNIE_R35_HEIGHT_MASK; + size |= height; + writel(size, mdnie->regs + MDNIE_R4); + + /* unmask all */ + writel(0, mdnie->regs + MDNIE_R28); +} + +static void mdnie_init_hardware(struct s5p_mdnie *mdnie) +{ + struct mdnie_platform_data *pdata = NULL; + + pdata = mdnie->pdata; + + /* set display size. */ + mdnie_set_size(mdnie, pdata->width, pdata->height); +} + +static int mdnie_setup(struct s5p_fimd_ext_device *fx_dev, unsigned int enable) +{ + struct s5p_mdnie *mdnie = fimd_ext_get_drvdata(fx_dev); + struct mdnie_manager_ops *mops = mdnie->mops; + int ret = 0; + + mdnie_info("enable[%d]", enable); + if (enable) { + int i; + mdnie_init_hardware(mdnie); + if (mops && mops->commit) { + for (i = 0; i < SET_MAX; i++) { + ret = mops->commit(mdnie, i); + if (ret) { + dev_err(mdnie->dev, "invalid mdnie set.\n"); + goto error; + } + } + } else { + dev_err(mdnie->dev, "invalid mdnie mops.\n"); + goto error; + } + } + + return 0; + +error: + return ret; +} + +static ssize_t store_mdnie_mode(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct s5p_fimd_ext_device *fx_dev = to_fimd_ext_device(dev); + struct s5p_mdnie *mdnie = fimd_ext_get_drvdata(fx_dev); + struct mdnie_manager_ops *mops = mdnie->mops; + unsigned long prev_mode; + unsigned long mode; + int ret; + + ret = kstrtoul(buf, 0, &mode); + if (ret) { + dev_err(&fx_dev->dev, "invalid mode value.\n"); + return -EINVAL; + } + + if (mode >= MODE_MAX) { + dev_err(&fx_dev->dev, "invalid mdnie mode.\n"); + return -EINVAL; + } + + if (mdnie->scenario >= SCENARIO_MODE_MAX) { + dev_err(&fx_dev->dev, "invalid mdnie scenario.\n"); + mdnie->scenario = SCENARIO_UI; + } + + prev_mode = mdnie->mode; + mdnie->mode = mode; + mdnie_info("mode[%d]", mdnie->mode); + if (mops && mops->commit) { + ret = mops->commit(mdnie, SET_MAIN); + if (ret) { + dev_err(&fx_dev->dev, "failed to set mode.\n"); + goto error_restore; + } + } else { + dev_err(&fx_dev->dev, "invalid mdnie mops.\n"); + ret = -EINVAL; + goto error_restore; + } + + return count; + +error_restore: + mdnie->mode = prev_mode; + return ret; +} + +static ssize_t show_mdnie_mode(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct s5p_fimd_ext_device *fx_dev = to_fimd_ext_device(dev); + struct s5p_mdnie *mdnie = fimd_ext_get_drvdata(fx_dev); + + mdnie_info("mode[%d]", mdnie->mode); + return snprintf(buf, PAGE_SIZE, "%d\n", mdnie->mode); +} + +static ssize_t store_mdnie_scenario(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct s5p_fimd_ext_device *fx_dev = to_fimd_ext_device(dev); + struct s5p_mdnie *mdnie = fimd_ext_get_drvdata(fx_dev); + struct mdnie_manager_ops *mops = mdnie->mops; + unsigned long prev_scenario; + unsigned long scenario; + int ret; + + ret = kstrtoul(buf, 0, &scenario); + if (ret) { + dev_err(&fx_dev->dev, "invalid scenario value.\n"); + return -EINVAL; + } + + if (scenario >= SCENARIO_MAX) { + dev_err(&fx_dev->dev, "invalid mdnie scenario.\n"); + return -EINVAL; + } + + prev_scenario = mdnie->scenario; + mdnie->scenario = scenario; + mdnie_info("scenario[%d]", mdnie->scenario); + if (mops && mops->commit) { + ret = mops->commit(mdnie, SET_MAIN); + if (ret) { + dev_err(&fx_dev->dev, "failed to set scenario.\n"); + goto error_restore; + } + } else { + dev_err(&fx_dev->dev, "invalid mdnie mops.\n"); + ret = -EINVAL; + goto error_restore; + } + + return count; + +error_restore: + mdnie->scenario = prev_scenario; + return ret; +} + +static ssize_t show_mdnie_scenario(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct s5p_fimd_ext_device *fx_dev = to_fimd_ext_device(dev); + struct s5p_mdnie *mdnie = fimd_ext_get_drvdata(fx_dev); + + mdnie_info("scenario[%d]", mdnie->scenario); + return snprintf(buf, PAGE_SIZE, "%d\n", mdnie->scenario); +} + +static ssize_t store_mdnie_tone(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct s5p_fimd_ext_device *fx_dev = to_fimd_ext_device(dev); + struct s5p_mdnie *mdnie = fimd_ext_get_drvdata(fx_dev); + struct mdnie_manager_ops *mops = mdnie->mops; + unsigned long prev_tone; + unsigned long tone; + int ret; + + ret = kstrtoul(buf, 0, &tone); + if (ret) { + dev_err(&fx_dev->dev, "invalid tone value.\n"); + return -EINVAL; + } + + if (mops && mops->check_tone) { + ret = mops->check_tone(mdnie, tone); + if (ret) { + dev_err(&fx_dev->dev, "failed to set tone.\n"); + return ret; + } + } else { + dev_err(&fx_dev->dev, "invalid mdnie mops.\n"); + ret = -EINVAL; + goto error_mops; + } + + prev_tone = mdnie->tone; + mdnie->tone = tone; + mdnie_info("tone[%d]", mdnie->tone); + if (mops && mops->commit) { + ret = mops->commit(mdnie, SET_OPTIONAL); + if (ret) { + dev_err(&fx_dev->dev, "failed to set tone.\n"); + goto error_restore; + } + } else { + dev_err(&fx_dev->dev, "invalid mdnie mops.\n"); + ret = -EINVAL; + goto error_restore; + } + + return count; + +error_restore: + mdnie->tone = prev_tone; +error_mops: + return ret; +} + +static ssize_t show_mdnie_tone(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct s5p_fimd_ext_device *fx_dev = to_fimd_ext_device(dev); + struct s5p_mdnie *mdnie = fimd_ext_get_drvdata(fx_dev); + + mdnie_info("tone[%d]", mdnie->tone); + return snprintf(buf, PAGE_SIZE, "%d\n", mdnie->tone); +} + +static ssize_t store_mdnie_outdoor(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct s5p_fimd_ext_device *fx_dev = to_fimd_ext_device(dev); + struct s5p_mdnie *mdnie = fimd_ext_get_drvdata(fx_dev); + struct mdnie_manager_ops *mops = mdnie->mops; + unsigned long prev_outdoor; + unsigned long outdoor; + int ret; + + ret = kstrtoul(buf, 0, &outdoor); + if (ret) { + dev_err(&fx_dev->dev, "invalid outdoor value.\n"); + return -EINVAL; + } + + if (outdoor >= OUTDOOR_MAX) { + dev_err(&fx_dev->dev, "invalid mdnie outdoor.\n"); + return -EINVAL; + } + + if (mdnie->scenario != SCENARIO_VIDEO + && mdnie->scenario != SCENARIO_CAMERA) { + /* Set to default */ + mdnie->outdoor = OUTDOOR_OFF; + dev_err(&fx_dev->dev, "invalid mdnie scenario.\n"); + return -EIO; + } + + prev_outdoor = mdnie->outdoor; + mdnie->outdoor = outdoor; + mdnie_info("outdoor[%d]", mdnie->outdoor); + if (mops && mops->commit) { + ret = mops->commit(mdnie, SET_OPTIONAL); + if (ret) { + dev_err(&fx_dev->dev, "failed to set outdoor.\n"); + goto error_restore; + } + } else { + dev_err(&fx_dev->dev, "invalid mdnie mops.\n"); + ret = -EINVAL; + goto error_restore; + } + + return count; + +error_restore: + mdnie->outdoor = prev_outdoor; + return ret; +} + +static ssize_t show_mdnie_outdoor(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct s5p_fimd_ext_device *fx_dev = to_fimd_ext_device(dev); + struct s5p_mdnie *mdnie = fimd_ext_get_drvdata(fx_dev); + + mdnie_info("outdoor[%d]", mdnie->outdoor); + return snprintf(buf, PAGE_SIZE, "%d\n", mdnie->outdoor); +} + +static ssize_t store_mdnie_tune(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct s5p_fimd_ext_device *fx_dev = to_fimd_ext_device(dev); + struct s5p_mdnie *mdnie = fimd_ext_get_drvdata(fx_dev); + struct mdnie_manager_ops *mops = mdnie->mops; + unsigned long prev_tune; + unsigned long tune; + int ret; + + ret = kstrtoul(buf, 0, &tune); + if (ret) { + dev_err(&fx_dev->dev, "invalid tune value.\n"); + return -EINVAL; + } + + if (tune >= TUNE_MAX) { + dev_err(&fx_dev->dev, "invalid mdnie tune.\n"); + return -EINVAL; + } + + prev_tune = mdnie->tune; + mdnie->tune = tune; + mdnie_info("tune[%d]", mdnie->tune); + if (mops) { + if (mdnie->tune == TUNE_FW) + mops->tune = mdnie_request_fw; + else + mops->tune = mdnie_request_tables; + } else { + dev_err(&fx_dev->dev, "invalid mdnie mops.\n"); + ret = -EINVAL; + goto error_restore; + } + + return count; + +error_restore: + mdnie->tune = prev_tune; + return ret; +} + +static ssize_t show_mdnie_tune(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct s5p_fimd_ext_device *fx_dev = to_fimd_ext_device(dev); + struct s5p_mdnie *mdnie = fimd_ext_get_drvdata(fx_dev); + + mdnie_info("tune[%d]", mdnie->tune); + return snprintf(buf, PAGE_SIZE, "%d\n", mdnie->tune); +} + +/* sys/devices/platform/mdnie */ +static struct device_attribute mdnie_device_attrs[] = { + __ATTR(mode, S_IRUGO|S_IWUSR, show_mdnie_mode, + store_mdnie_mode), + __ATTR(scenario, S_IRUGO|S_IWUSR, show_mdnie_scenario, + store_mdnie_scenario), + __ATTR(tone, S_IRUGO|S_IWUSR, show_mdnie_tone, + store_mdnie_tone), + __ATTR(outdoor, S_IRUGO|S_IWUSR, show_mdnie_outdoor, + store_mdnie_outdoor), + __ATTR(tune, S_IRUGO|S_IWUSR, show_mdnie_tune, + store_mdnie_tune), +}; + +static int mdnie_probe(struct s5p_fimd_ext_device *fx_dev) +{ + struct resource *res; + struct s5p_mdnie *mdnie; + int ret = -EINVAL; + int i; + + mdnie = kzalloc(sizeof(struct s5p_mdnie), GFP_KERNEL); + if (!mdnie) { + dev_err(&fx_dev->dev, "failed to alloc mdnie object.\n"); + return -EFAULT; + } + + mdnie->dev = &fx_dev->dev; + + mdnie->pdata = to_mdnie_platform_data(fx_dev); + if (mdnie->pdata == NULL) { + dev_err(&fx_dev->dev, "platform_data is NULL.\n"); + return -EFAULT; + } + + res = s5p_fimd_ext_get_resource(fx_dev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(&fx_dev->dev, "failed to get io memory region.\n"); + return -EINVAL; + } + + mdnie->regs = ioremap(res->start, resource_size(res)); + if (!mdnie->regs) { + dev_err(&fx_dev->dev, "failed to remap io region.\n'"); + return -EFAULT; + } + + mdnie->mode = MODE_STANDARD; + mdnie->scenario = SCENARIO_UI; + mdnie->tone = TONE_NORMAL; + mdnie->outdoor = OUTDOOR_OFF; + mdnie->tune = TUNE_TBL; + mdnie->mops = &mdnie_set_mops; + + mutex_init(&mdnie->lock); + + fimd_ext_set_drvdata(fx_dev, mdnie); + + for (i = 0; i < ARRAY_SIZE(mdnie_device_attrs); i++) { + ret = device_create_file(&fx_dev->dev, + &mdnie_device_attrs[i]); + if (ret) + break; + } + + if (ret < 0) + dev_err(&fx_dev->dev, "failed to add sysfs entries\n"); + + dev_info(&fx_dev->dev, "mDNIe driver has been probed.\n"); + + return 0; +} + +static struct s5p_fimd_ext_driver fimd_ext_driver = { + .driver = { + .name = "mdnie", + .owner = THIS_MODULE, + }, + .probe = mdnie_probe, + .setup = mdnie_setup, +}; + +static int __init mdnie_init(void) +{ + return s5p_fimd_ext_driver_register(&fimd_ext_driver); +} + +static void __exit mdnie_exit(void) +{ +} + +arch_initcall(mdnie_init); +module_exit(mdnie_exit); + +MODULE_AUTHOR("InKi Dae <inki.dae@samsung.com>"); +MODULE_AUTHOR("Eunchul Kim <chulspro.kim@samsung.com>"); +MODULE_DESCRIPTION("mDNIe Driver"); +MODULE_LICENSE("GPL"); + diff --git a/drivers/video/samsung_duallcd/extension/mdnie.h b/drivers/video/samsung_duallcd/extension/mdnie.h new file mode 100644 index 0000000..145efc1 --- /dev/null +++ b/drivers/video/samsung_duallcd/extension/mdnie.h @@ -0,0 +1,134 @@ +/* linux/arch/arm/plat-s5p/mdnie.h + * + * mDNIe Platform Specific Header Definitions. + * + * Copyright (c) 2011 Samsung Electronics + * InKi Dae <inki.dae@samsung.com> + * Eunchul Kim <chulspro.kim@samsung.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. +*/ + +#ifndef _MDNIE_H_ +#define _MDNIE_H_ + +#define MDNIE_MAX_STR 255 +#define MDNIE_FW_PATH "mdnie/%s/%s.bin" + +/* set - main, optional */ +enum mdnie_set { + SET_MAIN = 0, + SET_OPTIONAL, + SET_MAX +}; + +/* mode - dynamic, standard, natural, movie */ +enum mdnie_mode { + MODE_DYNAMIC = 0, + MODE_STANDARD, + MODE_NATURAL, + MODE_MOVIE, + MODE_MAX +}; + +/* scenario - ui, gallery, video, vtcall, camera, browser, negative, bypass */ +enum mdnie_scenario { + SCENARIO_UI = 0, + SCENARIO_GALLERY, + SCENARIO_VIDEO, + SCENARIO_VTCALL, + SCENARIO_MODE_MAX, + SCENARIO_CAMERA = SCENARIO_MODE_MAX, + SCENARIO_BROWSER, + SCENARIO_NEGATIVE, + SCENARIO_BYPASS, + SCENARIO_MAX +}; + +/* tone - normal, warm, cold */ +enum mdnie_tone { + TONE_NORMAL = 0, + TONE_WARM, + TONE_COLD, + TONE_MAX +}; + +/* tone browser - tone1, tone2, tone3 */ +enum mdnie_tone_br { + TONE_1 = 0, + TONE_2, + TONE_3, + TONE_BR_MAX +}; + +/* outdoor - off, on */ +enum mdnie_outdoor { + OUTDOOR_OFF = 0, + OUTDOOR_ON, + OUTDOOR_MAX +}; + +/* tune - tables, fw */ +enum mdnie_tune { + TUNE_TBL = 0, + TUNE_FW, + TUNE_MAX +}; + +/* + * A main structure for mDNIe. + * + * @dev: pointer to device object for sysfs + * @regs: memory mapped register map + * @mode: mdnie mode value + * @scenario: mdnie scenario value + * @tone: mdnie tone value + * @outdoor: mdnie outdoor value + * @lock: lock for request firmware waiting + * @pdata: platform data of width, height + * @mops: manager ops + */ +struct s5p_mdnie { + struct device *dev; + void __iomem *regs; + + enum mdnie_mode mode; + enum mdnie_scenario scenario; + int tone; + enum mdnie_outdoor outdoor; + enum mdnie_tune tune; + + struct mutex lock; + struct mdnie_platform_data *pdata; + struct mdnie_manager_ops *mops; +}; + +/** + * A structure for data tables. + * + * @name: table name + * @value: table value + * @size: table size + */ +struct mdnie_tables { + const char *name; + const unsigned short *value; + unsigned int size; +}; + +/* + * mDNIe manager ops. + * + * @tune: api of tune settings + * @commit: api of main,optional settings + * @check_tone: api of check tone + */ +struct mdnie_manager_ops { + int (*tune)(struct s5p_mdnie *mdnie, const char *name); + int (*commit)(struct s5p_mdnie *mdnie, enum mdnie_set set); + int (*check_tone)(struct s5p_mdnie *mdnie, int tone); +}; + +#endif /* _MDNIE_H_ */ diff --git a/drivers/video/samsung_duallcd/extension/regs-mdnie.h b/drivers/video/samsung_duallcd/extension/regs-mdnie.h new file mode 100644 index 0000000..a0ec8d7 --- /dev/null +++ b/drivers/video/samsung_duallcd/extension/regs-mdnie.h @@ -0,0 +1,166 @@ +/* linux/arch/arm/plat-s5p/include/plat/regs-mdnie.h + * + * Header file for Samsung SoC mDNIe device. + * + * Copyright (c) 2010 Samsung Electronics + * + * Author : Inki Dae <inki.dae@samsung.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. +*/ + +#ifndef _REGS_MDNIE_H +#define _REGS_MDNIE_H + +#define MDNIE_R0 0x0000 +#define MDNIE_R1 0x0004 +#define MDNIE_R2 0x0008 +#define MDNIE_R3 0x000C +#define MDNIE_R4 0x0010 +#define MDNIE_R5 0x0014 +#define MDNIE_R28 0x00A0 + +/* R1 */ +#define MDNIE_R1_MCM_BYPASS_MODE (1 << 2) +#define MDNIE_R1_ALG_DNR_HDTR_MASK (0x3 << 0) +#define MDNIE_R1_ALG_DNR_HDTR(x) (((x) & 0x3) << 0) +#define MDNIE_R1_ROI_PCA_OVE (1 << 10) +#define MDNIE_R1_ROI_HDTR (1 << 9) +#define MDNIE_R1_ROI_DNR (1 << 8) +#define MDNIE_R1_ROI_OUTSIDE (1 << 7) +#define MDNIE_R1_ABC_SEL_MASK (0x3 << 4) +#define MDNIE_R1_ABC_SEL(x) (((x) & 0x3) << 4) + +/* R2 */ +#define MDNIE_R2_H_START_MASK (0x7ff << 0) +#define MDNIE_R2_H_START(x) (((x) & 0x7ff) << 0) + +/* R3 */ +#define MDNIE_R3_WIDTH_MASK (0x7ff << 0) + +/* R4 */ +#define MDNIE_R4_HEIGHT_MASK (0x7ff << 0) + +/* R5 */ +#define MDNIE_R5_V_END_MASK (0x7ff << 0) +#define MDNIE_R5_V_END(x) (((x) & 0x7ff) << 0) + +/* R6 */ +#define MDNIE_R6_DITHER_ENABLE (1 << 4) + +/* R34 */ +#define MDNIE_R34_WIDTH_MASK (0x7ff << 0) +#define MDNIE_R34_WIDTH(x) (((x) & 0x7ff) << 0) + +/* R35 */ +#define MDNIE_R35_HEIGHT_MASK (0x7ff << 0) +#define MDNIE_R35_HEIGHT(x) (((x) & 0x7ff) << 0) + +/* R44 */ +#define MDNIE_R44_DNR_BYPASS_MODE (1 << 14) + +/* R58 */ +#define MDNIE_R58_HDTR_BYPASS_MODE (0x1f << 0) + +/* R73 */ +#define MDNIE_R73_SN_LVL_MASK (0x3 << 10) +#define MDNIE_R73_SN_LVL(x) (((x) & 0x3) << 10) +#define MDNIE_R73_SY_LVL_MASK (0x3 << 8) +#define MDNIE_R73_SY_LVL(x) (((x) & 0x3) << 8) +#define MDNIE_R73_GR_LVL_MASK (0x3 << 6) +#define MDNIE_R73_GR_LVL(x) (((x) & 0x3) << 6) +#define MDNIE_R73_RD_LVL_MASK (0x3 << 4) +#define MDNIE_R73_RD_LVL(x) (((x) & 0x3) << 4) +#define MDNIE_R73_YE_LVL_MASK (0x3 << 2) +#define MDNIE_R73_YE_LVL(x) (((x) & 0x3) << 2) +#define MDNIE_R73_PU_LVL_MASK (0x3 << 0) +#define MDNIE_R73_PU_LVL(x) (((x) & 0x3) << 0) + +/* R82 */ +#define MDNIE_R82_SN_CC_OFF (1 << 5) +#define MDNIE_R82_SY_CC_OFF (1 << 4) +#define MDNIE_R82_GR_CC_OFF (1 << 3) +#define MDNIE_R82_RD_CC_OFF (1 << 2) +#define MDNIE_R82_YE_CC_OFF (1 << 1) +#define MDNIE_R82_PU_CC_OFF (1 << 0) + +/* R84 */ +#define MDNIE_R84_LIGHT_P_MASK (0xff << 8) +#define MDNIE_R84_LIGHT_P(x) (((x) & 0xff) << 8) +#define MDNIE_R84_CHROMA_P_MASK (0xff << 0) +#define MDNIE_R84_CHROMA_P(x) (((x) & 0xff) << 0) + +/* R91 */ +#define MDNIE_R91_QUADRANT_ON (1 << 8) +#define MDNIE_R91_COLOR_TEMP_DEST_MASK (0xff << 0) +#define MDNIE_R91_COLOR_TEMP_DEST(x) (((x) & 0xff) << 0) + +/* R106 */ +#define MDNIE_R106_QUADRANT_TMP1_MASK (0xff << 8) +#define MDNIE_R106_QUADRANT_TMP1(x) (((x) & 0xff) << 8) +#define MDNIE_R106_QUADRANT_TMP2_MASK (0xff << 0) +#define MDNIE_R106_QUADRANT_TMP2(x) (((x) & 0xff) << 0) + +/* R107 */ +#define MDNIE_R107_QUADRANT_TMP3_MASK (0xff << 8) +#define MDNIE_R107_QUADRANT_TMP3(x) (((x) & 0xff) << 8) +#define MDNIE_R107_QUADRANT_TMP4_MASK (0xff << 0) +#define MDNIE_R107_QUADRANT_TMP4(x) (((x) & 0xff) << 0) + +/* R124 */ +#define MDNIE_R124_CABC_BLU_ENABLE (1 << 1) +#define MDNIE_R124_DISPLAY_SEL_OLED (1 << 0) + +/* R125 */ +#define MDNIE_R125_ALS_FLAG_UPDATED (1 << 0) + +/* R126 */ +#define MDNIE_R126_ALS_DATA_MASK (0xffff << 0) +#define MDNIE_R126_ALS_DATA(x) (((x) & 0xffff) << 0) + +/* R127 */ +#define MDNIE_R127_WIN_SIZE_MASK (0xf << 4) +#define MDNIE_R127_WIN_SIZE(x) (((x) & 0xf) << 4) +#define MDNIE_R127_ALS_MODE_MASK (0x3 << 0) +#define MDNIE_R127_ALS_MODE(x) (((x) & 0x3) << 0) + +/* R130 */ +#define MDNIE_R130_AMB_LVL_MASK (0x4 << 0) +#define MDNIE_R130_AMB_LVL(x) (((x) & 0x4) << 0) + +/* R179 */ +#define MDNIE_R179_UP_SL_MASK (0xff << 8) +#define MDNIE_R179_UP_SL(x) (((x) & 0xff) << 8) +#define MDNIE_R179_DOWN_SL_MASK (0xff << 0) +#define MDNIE_R179_DOWN_SL(x) (((x) & 0xff) << 0) + +/* R180 */ +#define MDNIE_R180_PWM_CE_PWM_COEFF (1 << 15) +#define MDNIE_R180_POLARITY_HIGH_ACTIVE (1 << 14) +#define MDNIE_R180_LABC_MODE_MASK (0x3 << 12) +#define MDNIE_R180_LABC_MODE(x) (((x) & 0x3) << 12) +#define MDNIE_R180_ALC_EN (1 << 11) +#define MDNIE_R180_PWM_COEFF_COUNT_MASK (0x7ff << 0) +#define MDNIE_R180_PWM_COEFF_COUNT(x) (((x) & 0x7ff) << 0) + +/* R238 */ +#define MDNIE_R238_ROI_DITHER (1 << 15) +#define MDNIE_R238_ROI_OUTSIDE (1 << 14) +#define MDNIE_R238_H_START_MASK (0x7ff << 0) +#define MDNIE_R238_H_START(x) (((x) & 0x7ff) << 0) + +/* R239 */ +#define MDNIE_R239_H_END_MASK (0x7ff << 0) +#define MDNIE_R239_H_END(x) (((x) & 0x7ff) << 0) + +/* R240 */ +#define MDNIE_R240_V_START_MASK (0x7ff << 0) +#define MDNIE_R240_V_START(x) (((x) & 0x7ff) << 0) + +/* R241 */ +#define MDNIE_R241_V_END_MASK (0x7ff << 0) +#define MDNIE_R241_V_END(x) (((x) & 0x7ff) << 0) + +#endif diff --git a/drivers/video/samsung_duallcd/extension/regs_fimd_lite.h b/drivers/video/samsung_duallcd/extension/regs_fimd_lite.h new file mode 100644 index 0000000..fda0d2a --- /dev/null +++ b/drivers/video/samsung_duallcd/extension/regs_fimd_lite.h @@ -0,0 +1,396 @@ +/* linux/asm/arch/regs-ielcd.h + * + * Register definition file for Samsung Display Controller (FIMD-lite) driver + * + * InKi Dae, <inki.dae@samsung.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. +*/ + +#ifndef _REGS_IELCD_H +#define _REGS_IELCD_H + +#define S5P_LCDREG(x) (x) +#define S5P_WINCON(x) S5P_LCDREG(0x0020 + (x * 0x04)) +#define S5P_VIDOSD_A(x) S5P_LCDREG(0x0040 + (x * 0x10)) +#define S5P_VIDOSD_B(x) S5P_LCDREG(0x0044 + (x * 0x10)) +#define S5P_VIDOSD_C(x) S5P_LCDREG(0x0048 + (x * 0x10)) +#define S5P_VIDOSD_D(x) S5P_LCDREG(0x004C + (x * 0x10)) +#define S5P_VIDADDR_START0(x) S5P_LCDREG(0x00A0 + (x * 0x08)) +#define S5P_VIDADDR_START1(x) S5P_LCDREG(0x00A4 + (x * 0x08)) +#define S5P_VIDADDR_END0(x) S5P_LCDREG(0x00D0 + (x * 0x08)) +#define S5P_VIDADDR_END1(x) S5P_LCDREG(0x00D4 + (x * 0x08)) +#define S5P_VIDADDR_SIZE(x) S5P_LCDREG(0x0100 + (x * 0x04)) +#define S5P_KEYCON(x) S5P_LCDREG(0x0140 + ((x - 1) * 0x08)) +#define S5P_KEYVAL(x) S5P_LCDREG(0x0144 + ((x - 1) * 0x08)) + +/* + * Register Map +*/ +#define S5P_VIDCON0 S5P_LCDREG(0x0000) +#define S5P_VIDCON1 S5P_LCDREG(0x0004) +#define S5P_VIDCON2 S5P_LCDREG(0x0008) +#define S5P_PRTCON S5P_LCDREG(0x000C) + +#define S5P_VIDTCON0 S5P_LCDREG(0x0010) +#define S5P_VIDTCON1 S5P_LCDREG(0x0014) +#define S5P_VIDTCON2 S5P_LCDREG(0x0018) +#define S5P_VIDTCON3 S5P_LCDREG(0x001C) + +#define S5P_WINCON0 S5P_LCDREG(0x0020) +#define S5P_WINCON1 S5P_LCDREG(0x0024) +#define S5P_WINCON2 S5P_LCDREG(0x0028) +#define S5P_WINCON3 S5P_LCDREG(0x002C) +#define S5P_WINCON4 S5P_LCDREG(0x0030) + +#define S5P_VIDOSD0A S5P_LCDREG(0x0040) +#define S5P_VIDOSD0B S5P_LCDREG(0x0044) +#define S5P_VIDOSD0C S5P_LCDREG(0x0048) + +#define S5P_VIDOSD1A S5P_LCDREG(0x0050) +#define S5P_VIDOSD1B S5P_LCDREG(0x0054) +#define S5P_VIDOSD1C S5P_LCDREG(0x0058) +#define S5P_VIDOSD1D S5P_LCDREG(0x005C) + +#define S5P_VIDOSD2A S5P_LCDREG(0x0060) +#define S5P_VIDOSD2B S5P_LCDREG(0x0064) +#define S5P_VIDOSD2C S5P_LCDREG(0x0068) +#define S5P_VIDOSD2D S5P_LCDREG(0x006C) + +#define S5P_VIDOSD3A S5P_LCDREG(0x0070) +#define S5P_VIDOSD3B S5P_LCDREG(0x0074) +#define S5P_VIDOSD3C S5P_LCDREG(0x0078) + +#define S5P_VIDOSD4A S5P_LCDREG(0x0080) +#define S5P_VIDOSD4B S5P_LCDREG(0x0084) +#define S5P_VIDOSD4C S5P_LCDREG(0x0088) + +#define S5P_VIDW00ADD0B0 S5P_LCDREG(0x00A0) +#define S5P_VIDW00ADD0B1 S5P_LCDREG(0x00A4) +#define S5P_VIDW01ADD0B0 S5P_LCDREG(0x00A8) +#define S5P_VIDW01ADD0B1 S5P_LCDREG(0x00AC) +#define S5P_VIDW02ADD0 S5P_LCDREG(0x00B0) +#define S5P_VIDW03ADD0 S5P_LCDREG(0x00B8) +#define S5P_VIDW04ADD0 S5P_LCDREG(0x00C0) +#define S5P_VIDW00ADD1B0 S5P_LCDREG(0x00D0) +#define S5P_VIDW00ADD1B1 S5P_LCDREG(0x00D4) +#define S5P_VIDW01ADD1B0 S5P_LCDREG(0x00D8) +#define S5P_VIDW01ADD1B1 S5P_LCDREG(0x00DC) +#define S5P_VIDW02ADD1 S5P_LCDREG(0x00E0) +#define S5P_VIDW03ADD1 S5P_LCDREG(0x00E8) +#define S5P_VIDW04ADD1 S5P_LCDREG(0x00F0) +#define S5P_VIDW00ADD2 S5P_LCDREG(0x0100) +#define S5P_VIDW01ADD2 S5P_LCDREG(0x0104) +#define S5P_VIDW02ADD2 S5P_LCDREG(0x0108) +#define S5P_VIDW03ADD2 S5P_LCDREG(0x010C) +#define S5P_VIDW04ADD2 S5P_LCDREG(0x0110) + +#define S5P_VP1TCON0 S5P_LCDREG(0x0118) +#define S5P_VP1TCON1 S5P_LCDREG(0x011C) + +#define S5P_VIDINTCON0 S5P_LCDREG(0x0130) +#define S5P_VIDINTCON1 S5P_LCDREG(0x0134) + +#define S5P_W1KEYCON0 S5P_LCDREG(0x0140) /* Color key control */ +#define S5P_W1KEYCON1 S5P_LCDREG(0x0144) +#define S5P_W2KEYCON0 S5P_LCDREG(0x0148) +#define S5P_W2KEYCON1 S5P_LCDREG(0x014C) +#define S5P_W3KEYCON0 S5P_LCDREG(0x0150) +#define S5P_W3KEYCON1 S5P_LCDREG(0x0154) +#define S5P_W4KEYCON0 S5P_LCDREG(0x0158) +#define S5P_W4KEYCON1 S5P_LCDREG(0x015C) + +#define S5P_W1KEYALPHA S5P_LCDREG(0x0160) +#define S5P_W2KEYALPHA S5P_LCDREG(0x0164) +#define S5P_W3KEYALPHA S5P_LCDREG(0x0168) +#define S5P_W4KEYALPHA S5P_LCDREG(0x016C) + +#define S5P_DITHMODE S5P_LCDREG(0x0170) + +#define S5P_WIN0MAP S5P_LCDREG(0x0180) +#define S5P_WIN1MAP S5P_LCDREG(0x0184) +#define S5P_WIN2MAP S5P_LCDREG(0x0188) +#define S5P_WIN3MAP S5P_LCDREG(0x018C) +#define S5P_WIN4MAP S5P_LCDREG(0x0190) + +#define S5P_WPALCON_H S5P_LCDREG(0x019C) +#define S5P_WPALCON_L S5P_LCDREG(0x01A0) + +#define S5P_VIDW0ALPHA0 S5P_LCDREG(0x0200) +#define S5P_VIDW0ALPHA1 S5P_LCDREG(0x0204) +#define S5P_VIDW1ALPHA0 S5P_LCDREG(0x0208) +#define S5P_VIDW1ALPHA1 S5P_LCDREG(0x020C) +#define S5P_VIDW2ALPHA0 S5P_LCDREG(0x0210) +#define S5P_VIDW2ALPHA1 S5P_LCDREG(0x0214) +#define S5P_VIDW3ALPHA0 S5P_LCDREG(0x0218) +#define S5P_VIDW3ALPHA1 S5P_LCDREG(0x021C) +#define S5P_VIDW4ALPHA0 S5P_LCDREG(0x0220) +#define S5P_VIDW4ALPHA1 S5P_LCDREG(0x0224) + +#define S5P_BLENDEQ1 S5P_LCDREG(0x0244) +#define S5P_BLENDEQ2 S5P_LCDREG(0x0248) +#define S5P_BLENDEQ3 S5P_LCDREG(0x024C) +#define S5P_BLENDEQ4 S5P_LCDREG(0x0250) +#define S5P_BLENDCON S5P_LCDREG(0x0260) /* Blending control */ +#define S5P_GPOUTCON0 S5P_LCDREG(0x0278) /* mDNIe */ +#define S5P_DUALRGB S5P_LCDREG(0x027C) /* DUALRGB Register */ + +/* + * Bit Definitions +*/ + +/* VIDCON0 */ +#define S5P_VIDCON0_DSI_DISABLE (0 << 30) +#define S5P_VIDCON0_DSI_ENABLE (1 << 30) +#define S5P_VIDCON0_SCAN_PROGRESSIVE (0 << 29) +#define S5P_VIDCON0_SCAN_INTERLACE (1 << 29) +#define S5P_VIDCON0_SCAN_MASK (1 << 29) +#define S5P_VIDCON0_VIDOUT_RGB (0 << 26) +#define S5P_VIDCON0_VIDOUT_ITU (1 << 26) +#define S5P_VIDCON0_VIDOUT_I80LDI0 (2 << 26) +#define S5P_VIDCON0_VIDOUT_I80LDI1 (3 << 26) +#define S5P_VIDCON0_VIDOUT_MASK (3 << 26) +#define S5P_VIDCON0_PNRMODE_RGB_P (0 << 17) +#define S5P_VIDCON0_PNRMODE_BGR_P (1 << 17) +#define S5P_VIDCON0_PNRMODE_RGB_S (2 << 17) +#define S5P_VIDCON0_PNRMODE_BGR_S (3 << 17) +#define S5P_VIDCON0_PNRMODE_MASK (3 << 17) +#define S5P_VIDCON0_PNRMODE_SHIFT (17) +#define S5P_VIDCON0_CLKVALUP_ALWAYS (0 << 16) +#define S5P_VIDCON0_CLKVALUP_START_FRAME (1 << 16) +#define S5P_VIDCON0_CLKVALUP_MASK (1 << 16) +#define S5P_VIDCON0_CLKVAL_F(x) (((x) & 0xff) << 6) +#define S5P_VIDCON0_VCLKEN_NORMAL (0 << 5) +#define S5P_VIDCON0_VCLKEN_FREERUN (1 << 5) +#define S5P_VIDCON0_VCLKEN_MASK (1 << 5) +#define S5P_VIDCON0_CLKDIR_DIRECTED (0 << 4) +#define S5P_VIDCON0_CLKDIR_DIVIDED (1 << 4) +#define S5P_VIDCON0_CLKDIR_MASK (1 << 4) +#define S5P_VIDCON0_CLKSEL_HCLK (0 << 2) +#define S5P_VIDCON0_CLKSEL_SCLK (1 << 2) +#define S5P_VIDCON0_CLKSEL_MASK (1 << 2) +#define S5P_VIDCON0_ENVID_ENABLE (1 << 1) +#define S5P_VIDCON0_ENVID_DISABLE (0 << 1) +#define S5P_VIDCON0_ENVID_F_ENABLE (1 << 0) +#define S5P_VIDCON0_ENVID_F_DISABLE (0 << 0) + +/* VIDCON1 */ + +#define S5P_VIDCON1_VSTATUS_VSYNC 0x0 +#define S5P_VIDCON1_VSTATUS_BACKPORCH 0x1 +#define S5P_VIDCON1_VSTATUS_ACTIVE 0x2 +#define S5P_VIDCON1_VSTATUS_FRONTPORCH 0x3 +#define S5P_VIDCON1_VSTATUS_MASK 0x3 + +#define S5P_VIDCON1_FIXVCLK_VDEN_DISABLE (3 << 9) +#define S5P_VIDCON1_FIXVCLK_RUNNING (1 << 9) +#define S5P_VIDCON1_FIXVCLK_HOLD (0 << 9) +#define S5P_VIDCON1_IVCLK_FALLING_EDGE (0 << 7) +#define S5P_VIDCON1_IVCLK_RISING_EDGE (1 << 7) +#define S5P_VIDCON1_IHSYNC_NORMAL (0 << 6) +#define S5P_VIDCON1_IHSYNC_INVERT (1 << 6) +#define S5P_VIDCON1_IVSYNC_NORMAL (0 << 5) +#define S5P_VIDCON1_IVSYNC_INVERT (1 << 5) +#define S5P_VIDCON1_IVDEN_NORMAL (0 << 4) +#define S5P_VIDCON1_IVDEN_INVERT (1 << 4) + +/* VIDCON2 */ +#define S5P_VIDCON2_EN601_DISABLE (0 << 23) +#define S5P_VIDCON2_EN601_ENABLE (1 << 23) +#define S5P_VIDCON2_EN601_MASK (1 << 23) +#define S5P_VIDCON2_ORGYUV_YCBCR (0 << 8) +#define S5P_VIDCON2_ORGYUV_CBCRY (1 << 8) +#define S5P_VIDCON2_ORGYUV_MASK (1 << 8) +#define S5P_VIDCON2_YUVORD_CBCR (0 << 7) +#define S5P_VIDCON2_YUVORD_CRCB (1 << 7) +#define S5P_VIDCON2_YUVORD_MASK (1 << 7) + +/* PRTCON */ +#define S5P_PRTCON_UPDATABLE (0 << 11) +#define S5P_PRTCON_PROTECT (1 << 11) + +/* VIDTCON0 */ +#define S5P_VIDTCON0_VBPDE(x) (((x) & 0xff) << 24) +#define S5P_VIDTCON0_VBPD(x) (((x) & 0xff) << 16) +#define S5P_VIDTCON0_VFPD(x) (((x) & 0xff) << 8) +#define S5P_VIDTCON0_VSPW(x) (((x) & 0xff) << 0) + +/* VIDTCON1 */ +#define S5P_VIDTCON1_VFPDE(x) (((x) & 0xff) << 24) +#define S5P_VIDTCON1_HBPD(x) (((x) & 0xff) << 16) +#define S5P_VIDTCON1_HFPD(x) (((x) & 0xff) << 8) +#define S5P_VIDTCON1_HSPW(x) (((x) & 0xff) << 0) + +/* VIDTCON2 */ +#define S5P_VIDTCON2_LINEVAL(x) (((x) & 0x7ff) << 11) +#define S5P_VIDTCON2_HOZVAL(x) (((x) & 0x7ff) << 0) + +/* VIDTCON3 */ +#define S5P_VIDTCON3_VSYNCEN (1 << 31) +#define S5P_VIDTCON3_FRMEN (1 << 29) +#define S5P_VIDTCON3_FRMVRATE(x) ((x) << 24) + +/* Window 0~4 Control - WINCONx */ +#define S5P_WINCON_DATAPATH_DMA (0 << 22) +#define S5P_WINCON_DATAPATH_LOCAL (1 << 22) +#define S5P_WINCON_DATAPATH_MASK (1 << 22) +#define S5P_WINCON_BUFSEL_0 (0 << 20) +#define S5P_WINCON_BUFSEL_1 (1 << 20) +#define S5P_WINCON_BUFSEL_MASK (1 << 20) +#define S5P_WINCON_BUFSEL_SHIFT (20) +#define S5P_WINCON_BUFAUTO_DISABLE (0 << 19) +#define S5P_WINCON_BUFAUTO_ENABLE (1 << 19) +#define S5P_WINCON_BUFAUTO_MASK (1 << 19) +#define S5P_WINCON_BITSWP_DISABLE (0 << 18) +#define S5P_WINCON_BITSWP_ENABLE (1 << 18) +#define S5P_WINCON_BITSWP_SHIFT (18) +#define S5P_WINCON_BYTESWP_DISABLE (0 << 17) +#define S5P_WINCON_BYTESWP_ENABLE (1 << 17) +#define S5P_WINCON_BYTESWP_SHIFT (17) +#define S5P_WINCON_HAWSWP_DISABLE (0 << 16) +#define S5P_WINCON_HAWSWP_ENABLE (1 << 16) +#define S5P_WINCON_HAWSWP_SHIFT (16) +#define S5P_WINCON_WSWP_DISABLE (0 << 15) +#define S5P_WINCON_WSWP_ENABLE (1 << 15) +#define S5P_WINCON_WSWP_SHIFT (15) +#define S5P_WINCON_INRGB_RGB (0 << 13) +#define S5P_WINCON_INRGB_YUV (1 << 13) +#define S5P_WINCON_INRGB_MASK (1 << 13) +#define S5P_WINCON_BURSTLEN_16WORD (0 << 9) +#define S5P_WINCON_BURSTLEN_8WORD (1 << 9) +#define S5P_WINCON_BURSTLEN_4WORD (2 << 9) +#define S5P_WINCON_BURSTLEN_MASK (3 << 9) +#define S5P_WINCON_ALPHA_MULTI_DISABLE (0 << 7) +#define S5P_WINCON_ALPHA_MULTI_ENABLE (1 << 7) +#define S5P_WINCON_BLD_PLANE (0 << 6) +#define S5P_WINCON_BLD_PIXEL (1 << 6) +#define S5P_WINCON_BLD_MASK (1 << 6) +#define S5P_WINCON_BPPMODE_1BPP (0 << 2) +#define S5P_WINCON_BPPMODE_2BPP (1 << 2) +#define S5P_WINCON_BPPMODE_4BPP (2 << 2) +#define S5P_WINCON_BPPMODE_8BPP_PAL (3 << 2) +#define S5P_WINCON_BPPMODE_8BPP (4 << 2) +#define S5P_WINCON_BPPMODE_16BPP_565 (5 << 2) +#define S5P_WINCON_BPPMODE_16BPP_A555 (6 << 2) +#define S5P_WINCON_BPPMODE_18BPP_666 (8 << 2) +#define S5P_WINCON_BPPMODE_18BPP_A665 (9 << 2) +#define S5P_WINCON_BPPMODE_24BPP_888 (0xb << 2) +#define S5P_WINCON_BPPMODE_24BPP_A887 (0xc << 2) +#define S5P_WINCON_BPPMODE_32BPP (0xd << 2) +#define S5P_WINCON_BPPMODE_16BPP_A444 (0xe << 2) +#define S5P_WINCON_BPPMODE_15BPP_555 (0xf << 2) +#define S5P_WINCON_BPPMODE_MASK (0xf << 2) +#define S5P_WINCON_BPPMODE_SHIFT (2) +#define S5P_WINCON_ALPHA0_SEL (0 << 1) +#define S5P_WINCON_ALPHA1_SEL (1 << 1) +#define S5P_WINCON_ALPHA_SEL_MASK (1 << 1) +#define S5P_WINCON_ENWIN_DISABLE (0 << 0) +#define S5P_WINCON_ENWIN_ENABLE (1 << 0) + +/* WINCON1 special */ +#define S5P_WINCON1_VP_DISABLE (0 << 24) +#define S5P_WINCON1_VP_ENABLE (1 << 24) +#define S5P_WINCON1_LOCALSEL_FIMC1 (0 << 23) +#define S5P_WINCON1_LOCALSEL_VP (1 << 23) +#define S5P_WINCON1_LOCALSEL_MASK (1 << 23) + +/* VIDOSDxA, VIDOSDxB */ +#define S5P_VIDOSD_LEFT_X(x) (((x) & 0x7ff) << 11) +#define S5P_VIDOSD_TOP_Y(x) (((x) & 0x7ff) << 0) +#define S5P_VIDOSD_RIGHT_X(x) (((x) & 0x7ff) << 11) +#define S5P_VIDOSD_BOTTOM_Y(x) (((x) & 0x7ff) << 0) + +/* VIDOSD0C, VIDOSDxD */ +#define S5P_VIDOSD_SIZE(x) (((x) & 0xffffff) << 0) + +/* VIDOSDxC (1~4) */ +#define S5P_VIDOSD_ALPHA0_R(x) (((x) & 0xf) << 20) +#define S5P_VIDOSD_ALPHA0_G(x) (((x) & 0xf) << 16) +#define S5P_VIDOSD_ALPHA0_B(x) (((x) & 0xf) << 12) +#define S5P_VIDOSD_ALPHA1_R(x) (((x) & 0xf) << 8) +#define S5P_VIDOSD_ALPHA1_G(x) (((x) & 0xf) << 4) +#define S5P_VIDOSD_ALPHA1_B(x) (((x) & 0xf) << 0) +#define S5P_VIDOSD_ALPHA0_SHIFT (12) +#define S5P_VIDOSD_ALPHA1_SHIFT (0) + +/* Start Address */ +#define S5P_VIDADDR_START_VBANK(x) (((x) & 0xff) << 24) +#define S5P_VIDADDR_START_VBASEU(x) (((x) & 0xffffff) << 0) + +/* End Address */ +#define S5P_VIDADDR_END_VBASEL(x) (((x) & 0xffffff) << 0) + +/* Buffer Size */ +#define S5P_VIDADDR_OFFSIZE(x) (((x) & 0x1fff) << 13) +#define S5P_VIDADDR_PAGEWIDTH(x) (((x) & 0x1fff) << 0) + +/* VIDINTCON0 */ +#define S5P_VIDINTCON0_SYSMAINCON_DISABLE (0 << 19) +#define S5P_VIDINTCON0_SYSMAINCON_ENABLE (1 << 19) +#define S5P_VIDINTCON0_SYSSUBCON_DISABLE (0 << 18) +#define S5P_VIDINTCON0_SYSSUBCON_ENABLE (1 << 18) +#define S5P_VIDINTCON0_SYSIFDONE_DISABLE (0 << 17) +#define S5P_VIDINTCON0_SYSIFDONE_ENABLE (1 << 17) +#define S5P_VIDINTCON0_FRAMESEL0_BACK (0 << 15) +#define S5P_VIDINTCON0_FRAMESEL0_VSYNC (1 << 15) +#define S5P_VIDINTCON0_FRAMESEL0_ACTIVE (2 << 15) +#define S5P_VIDINTCON0_FRAMESEL0_FRONT (3 << 15) +#define S5P_VIDINTCON0_FRAMESEL0_MASK (3 << 15) +#define S5P_VIDINTCON0_FRAMESEL1_NONE (0 << 13) +#define S5P_VIDINTCON0_FRAMESEL1_BACK (1 << 13) +#define S5P_VIDINTCON0_FRAMESEL1_VSYNC (2 << 13) +#define S5P_VIDINTCON0_FRAMESEL1_FRONT (3 << 13) +#define S5P_VIDINTCON0_INTFRMEN_DISABLE (0 << 12) +#define S5P_VIDINTCON0_INTFRMEN_ENABLE (1 << 12) +#define S5P_VIDINTCON0_FIFOSEL_WIN4 (1 << 11) +#define S5P_VIDINTCON0_FIFOSEL_WIN3 (1 << 10) +#define S5P_VIDINTCON0_FIFOSEL_WIN2 (1 << 9) +#define S5P_VIDINTCON0_FIFOSEL_WIN1 (1 << 6) +#define S5P_VIDINTCON0_FIFOSEL_WIN0 (1 << 5) +#define S5P_VIDINTCON0_FIFOSEL_ALL (0x73 << 5) +#define S5P_VIDINTCON0_FIFOSEL_MASK (0x73 << 5) +#define S5P_VIDINTCON0_FIFOLEVEL_25 (0 << 2) +#define S5P_VIDINTCON0_FIFOLEVEL_50 (1 << 2) +#define S5P_VIDINTCON0_FIFOLEVEL_75 (2 << 2) +#define S5P_VIDINTCON0_FIFOLEVEL_EMPTY (3 << 2) +#define S5P_VIDINTCON0_FIFOLEVEL_FULL (4 << 2) +#define S5P_VIDINTCON0_FIFOLEVEL_MASK (7 << 2) +#define S5P_VIDINTCON0_INTFIFO_DISABLE (0 << 1) +#define S5P_VIDINTCON0_INTFIFO_ENABLE (1 << 1) +#define S5P_VIDINTCON0_INT_DISABLE (0 << 0) +#define S5P_VIDINTCON0_INT_ENABLE (1 << 0) +#define S5P_VIDINTCON0_INT_MASK (1 << 0) + +/* VIDINTCON1 */ +#define S5P_VIDINTCON1_INTVPPEND (1 << 5) +#define S5P_VIDINTCON1_INTI80PEND (1 << 2) +#define S5P_VIDINTCON1_INTFRMPEND (1 << 1) +#define S5P_VIDINTCON1_INTFIFOPEND (1 << 0) + +/* WxKEYCON0 (1~4) */ +#define S5P_KEYCON0_KEYBLEN_DISABLE (0 << 26) +#define S5P_KEYCON0_KEYBLEN_ENABLE (1 << 26) +#define S5P_KEYCON0_KEY_DISABLEi (0 << 25) +#define S5P_KEYCON0_KEY_ENABLE (1 << 25) +#define S5P_KEYCON0_DIRCON_MATCH_FG (0 << 24) +#define S5P_KEYCON0_DIRCON_MATCH_BG (1 << 24) +#define S5P_KEYCON0_COMPKEY(x) (((x) & 0xffffff) << 0) + +/* WxKEYCON1 (1~4) */ +#define S5P_KEYCON1_COLVAL(x) (((x) & 0xffffff) << 0) + +/* DUALRGB */ +#define S5P_DUALRGB_BYPASS_SINGLE (0x00 << 0) +#define S5P_DUALRGB_BYPASS_DUAL (0x01 << 0) +#define S5P_DUALRGB_MIE_DUAL (0x10 << 0) +#define S5P_DUALRGB_MIE_SINGLE (0x11 << 0) +#define S5P_DUALRGB_LINESPLIT (0x0 << 2) +#define S5P_DUALRGB_FRAMESPLIT (0x1 << 2) +#define S5P_DUALRGB_SUB_CNT(x) ((x & 0xfff) << 4) +#define S5P_DUALRGB_VDEN_EN_DISABLE (0x0 << 16) +#define S5P_DUALRGB_VDEN_EN_ENABLE (0x1 << 16) +#define S5P_DUALRGB_MAIN_CNT(x) ((x & 0xfff) << 18) + +#endif /* _REGS_IELCD_H */ diff --git a/drivers/video/samsung_duallcd/extension/s5p_fimd_ext.c b/drivers/video/samsung_duallcd/extension/s5p_fimd_ext.c new file mode 100644 index 0000000..0c197b6 --- /dev/null +++ b/drivers/video/samsung_duallcd/extension/s5p_fimd_ext.c @@ -0,0 +1,209 @@ +/* linux/drivers/video/samsung/s5p_fimd_ext.c + * + * Samsung SoC FIMD Extension Device Framework. + * + * Inki Dae <inki.dae@samsung.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/module.h> +#include <linux/kernel.h> +#include <linux/errno.h> +#include <linux/types.h> +#include <linux/mutex.h> +#include <linux/slab.h> +#include <linux/platform_device.h> + +#include <plat/fimd_lite_ext.h> + +#include "s5p_fimd_ext.h" + +struct s5p_fimd_ext { + struct list_head list; + struct device *dev; +}; + +static LIST_HEAD(fimd_ext_list); +static DEFINE_MUTEX(fimd_ext_lock); + +struct s5p_fimd_ext_device *to_fimd_ext_device(struct device *dev) +{ + return dev ? container_of(dev, struct s5p_fimd_ext_device, dev) : NULL; +} +EXPORT_SYMBOL(to_fimd_ext_device); + +struct s5p_fimd_ext_driver *to_fimd_ext_driver(struct device_driver *drv) +{ + return drv ? container_of(drv, struct s5p_fimd_ext_driver, driver) : + NULL; +} +EXPORT_SYMBOL(to_fimd_ext_driver); + +static ssize_t modalias_show(struct device *dev, struct device_attribute *a, + char *buf) +{ + struct s5p_fimd_ext_device *fx_dev = to_fimd_ext_device(dev); + int len = snprintf(buf, PAGE_SIZE, "platform:%s\n", fx_dev->name); + + return (len >= PAGE_SIZE) ? (PAGE_SIZE - 1) : len; +} + +static struct device_attribute s5p_fimd_ext_dev_attrs[] = { + __ATTR_RO(modalias), + __ATTR_NULL, +}; + +static int s5p_fimd_ext_match_device(struct device *dev, + struct device_driver *drv) +{ + const struct s5p_fimd_ext_device *fx_dev = to_fimd_ext_device(dev); + const struct s5p_fimd_ext_driver *fx_drv = to_fimd_ext_driver(drv); + + return strcmp(fx_dev->name, fx_drv->driver.name) == 0; +} + +struct bus_type s5p_fimd_ext_bus_type = { + .name = "fimd_ext", + .dev_attrs = s5p_fimd_ext_dev_attrs, + .match = s5p_fimd_ext_match_device, +}; + +static int s5p_fimd_ext_drv_probe(struct device *dev) +{ + const struct s5p_fimd_ext_driver *fx_drv = + to_fimd_ext_driver(dev->driver); + + return fx_drv->probe(to_fimd_ext_device(dev)); +} + +struct resource *s5p_fimd_ext_get_resource(struct s5p_fimd_ext_device *fx_dev, + unsigned int type, unsigned int num) +{ + int i; + + for (i = 0; i < fx_dev->num_resources; i++) { + struct resource *r = &fx_dev->resource[i]; + + if (type == resource_type(r) && num-- == 0) + return r; + } + + return NULL; +} + +int s5p_fimd_ext_get_irq(struct s5p_fimd_ext_device *fx_dev, unsigned int num) +{ + struct resource *r = s5p_fimd_ext_get_resource(fx_dev, + IORESOURCE_IRQ, num); + + return r ? r->start : -ENXIO; +} + +int s5p_fimd_ext_device_register(struct s5p_fimd_ext_device *fx_dev) +{ + struct s5p_fimd_ext *fimd_ext; + int i, ret = 0; + + fimd_ext = kzalloc(sizeof(struct s5p_fimd_ext), GFP_KERNEL); + if (!fimd_ext) { + printk(KERN_ERR "failed to allocate fimd_ext object.\n"); + return -EFAULT; + } + + fimd_ext->dev = &fx_dev->dev; + + device_initialize(&fx_dev->dev); + + if (!fx_dev->dev.parent) + fx_dev->dev.parent = &platform_bus; + + fx_dev->dev.bus = &s5p_fimd_ext_bus_type; + + if (fx_dev->id != -1) + dev_set_name(&fx_dev->dev, "%s.%d", fx_dev->name, fx_dev->id); + else + dev_set_name(&fx_dev->dev, "%s", fx_dev->name); + + for (i = 0; i < fx_dev->num_resources; i++) { + struct resource *r = &fx_dev->resource[i]; + + if (r->name == NULL) + r->name = dev_name(&fx_dev->dev); + } + + ret = device_add(&fx_dev->dev); + if (ret == 0) { + mutex_lock(&fimd_ext_lock); + list_add_tail(&fimd_ext->list, &fimd_ext_list); + mutex_unlock(&fimd_ext_lock); + + return ret; + } + + kfree(fimd_ext); + + return ret; +} +EXPORT_SYMBOL(s5p_fimd_ext_device_register); + +int s5p_fimd_ext_driver_register(struct s5p_fimd_ext_driver *fx_drv) +{ + fx_drv->driver.bus = &s5p_fimd_ext_bus_type; + if (fx_drv->probe) + fx_drv->driver.probe = s5p_fimd_ext_drv_probe; + + /* add some callbacks here. */ + + printk(KERN_DEBUG "registered a driver(%s) to fimd_ext driver.\n", + fx_drv->driver.name); + + return driver_register(&fx_drv->driver); +} +EXPORT_SYMBOL(s5p_fimd_ext_driver_register); + +struct s5p_fimd_ext_device *s5p_fimd_ext_find_device(const char *name) +{ + struct s5p_fimd_ext *fimd_ext; + struct s5p_fimd_ext_device *fx_dev; + struct device *dev; + + mutex_lock(&fimd_ext_lock); + + printk(KERN_DEBUG "find ext driver (%s).\n", name); + + list_for_each_entry(fimd_ext, &fimd_ext_list, list) { + dev = fimd_ext->dev; + fx_dev = to_fimd_ext_device(dev); + + if ((strcmp(fx_dev->name, name)) == 0) { + mutex_unlock(&fimd_ext_lock); + printk(KERN_DEBUG "found!!!(%s).\n", fx_dev->name); + return fx_dev; + } + } + + printk(KERN_WARNING "failed to find ext device(%s).\n", name); + + mutex_unlock(&fimd_ext_lock); + + return NULL; +} + +static int __init s5p_fimd_ext_init(void) +{ + return bus_register(&s5p_fimd_ext_bus_type); +} + +static void __exit s5p_fimd_ext_exit(void) +{ +} + +early_initcall(s5p_fimd_ext_init); +module_exit(s5p_fimd_ext_exit); + +MODULE_AUTHOR("InKi Dae <inki.dae@samsung.com>"); +MODULE_DESCRIPTION("Samsung SoC FIMD Extension Framework"); +MODULE_LICENSE("GPL"); diff --git a/drivers/video/samsung_duallcd/extension/s5p_fimd_ext.h b/drivers/video/samsung_duallcd/extension/s5p_fimd_ext.h new file mode 100644 index 0000000..3a4dc3a --- /dev/null +++ b/drivers/video/samsung_duallcd/extension/s5p_fimd_ext.h @@ -0,0 +1,30 @@ +/* linux/driver/video/samsung/s5p_fimd_ext.h + * + * Samsung SoC FIMD Extension Framework Header. + * + * InKi Dae <inki.dae@samsung.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. +*/ + +#ifndef _S5P_FIMD_EXT_H +#define _S5P_FIMD_EXT_H + +#include <linux/device.h> + +struct s5p_fimd_ext_device + *to_fimd_ext_device(struct device *dev); + +struct resource *s5p_fimd_ext_get_resource(struct s5p_fimd_ext_device *fx_dev, + unsigned int type, unsigned int num); + +int s5p_fimd_ext_get_irq(struct s5p_fimd_ext_device *fx_dev, + unsigned int num); + +int s5p_fimd_ext_device_register(struct s5p_fimd_ext_device *fx_dev); + +int s5p_fimd_ext_driver_register(struct s5p_fimd_ext_driver *fx_drv); + +#endif /* _S5P_FIMD_EXT_H */ diff --git a/drivers/video/samsung_duallcd/extension/s5p_fimd_lite.c b/drivers/video/samsung_duallcd/extension/s5p_fimd_lite.c new file mode 100644 index 0000000..3e128b8 --- /dev/null +++ b/drivers/video/samsung_duallcd/extension/s5p_fimd_lite.c @@ -0,0 +1,502 @@ +/* /linux/driver/video/samsung/s5p_fimd_lite.c + * + * Samsung SoC FIMD Lite driver. + * + * Author: InKi Dae <inki.dae@samsung.com> + * + * 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 of the License, 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; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/errno.h> +#include <linux/err.h> +#include <linux/clk.h> +#include <linux/io.h> +#include <linux/irq.h> +#include <linux/slab.h> +#include <linux/interrupt.h> +#include <linux/fb.h> + +#include <plat/clock.h> +#include <plat/fb.h> +#include <plat/cpu.h> +#include <plat/fimd_lite_ext.h> +#include <plat/regs-fb.h> + +#include <mach/map.h> + +#include "s5p_fimd_ext.h" +#include "s5p_fimd_lite.h" +#include "regs_fimd_lite.h" + +static void *to_fimd_lite_platform_data(struct s5p_fimd_ext_device *fx_dev) +{ + return fx_dev->dev.platform_data ? (void *)fx_dev->dev.platform_data : + NULL; +} + +static void s5p_fimd_lite_set_par(struct s5p_fimd_lite *fimd_lite, + unsigned int win_id) +{ + struct exynos_drm_fimd_pdata *lcd; + struct fb_videomode timing; + unsigned int cfg; + + lcd = fimd_lite->lcd; + timing = lcd->panel.timing; + + /* set window control */ + cfg = readl(fimd_lite->iomem_base + S5P_WINCON(win_id)); + + cfg &= ~(S5P_WINCON_BITSWP_ENABLE | S5P_WINCON_BYTESWP_ENABLE | \ + S5P_WINCON_HAWSWP_ENABLE | S5P_WINCON_WSWP_ENABLE | \ + S5P_WINCON_BURSTLEN_MASK | S5P_WINCON_BPPMODE_MASK | \ + S5P_WINCON_INRGB_MASK | S5P_WINCON_DATAPATH_MASK); + + /* DATAPATH is LOCAL */ + cfg |= S5P_WINCON_DATAPATH_LOCAL; + + /* pixel format is unpacked RGB888 */ + cfg |= S5P_WINCON_INRGB_RGB | S5P_WINCON_BPPMODE_32BPP; + + writel(cfg, fimd_lite->iomem_base + S5P_WINCON(win_id)); + + /* set window position to x=0, y=0*/ + cfg = S5P_VIDOSD_LEFT_X(0) | S5P_VIDOSD_TOP_Y(0); + writel(cfg, fimd_lite->iomem_base + S5P_VIDOSD_A(win_id)); + + cfg = S5P_VIDOSD_RIGHT_X(timing.xres - 1) | + S5P_VIDOSD_BOTTOM_Y(timing.yres - 1); + writel(cfg, fimd_lite->iomem_base + S5P_VIDOSD_B(win_id)); + + /* set window size for window0*/ + cfg = S5P_VIDOSD_SIZE(timing.xres * timing.yres); + writel(cfg, fimd_lite->iomem_base + S5P_VIDOSD_C(win_id)); + + return; +} + +static void s5p_fimd_lite_set_clock(struct s5p_fimd_lite *fimd_lite) +{ + unsigned int cfg = 0, div = 0; + unsigned int pixel_clock, src_clock, max_clock; + struct clk *clk; + struct exynos_drm_fimd_pdata *lcd; + struct fb_videomode timing; + + lcd = fimd_lite->lcd; + timing = lcd->panel.timing; + + clk = fimd_lite->clk; + + max_clock = 86 * 1000000; + + pixel_clock = timing.refresh * + (timing.left_margin + timing.right_margin + + timing.hsync_len + timing.xres) * (timing.upper_margin + + timing.lower_margin + timing.vsync_len + timing.yres); + + src_clock = clk_get_rate(clk->parent); + + cfg = readl(fimd_lite->iomem_base + S5P_VIDCON0); + cfg &= ~(S5P_VIDCON0_VCLKEN_MASK | S5P_VIDCON0_CLKVALUP_MASK | + S5P_VIDCON0_CLKVAL_F(0xFF)); + cfg |= (S5P_VIDCON0_CLKVALUP_ALWAYS | S5P_VIDCON0_VCLKEN_NORMAL); + + cfg |= S5P_VIDCON0_CLKSEL_HCLK; + + if (pixel_clock > max_clock) + pixel_clock = max_clock; + + div = (unsigned int)(src_clock / pixel_clock); + if (src_clock % pixel_clock) + div++; + + cfg |= S5P_VIDCON0_CLKVAL_F(div - 1); + writel(cfg, fimd_lite->iomem_base + S5P_VIDCON0); + + return; +} + +static void s5p_fimd_lite_window_on(struct s5p_fimd_lite *fimd_lite, + unsigned int win_id, unsigned int enable) +{ + unsigned int cfg; + + /* enable window */ + cfg = readl(fimd_lite->iomem_base + S5P_WINCON(win_id)); + + cfg &= ~S5P_WINCON_ENWIN_ENABLE; + + if (enable) + cfg |= S5P_WINCON_ENWIN_ENABLE; + + writel(cfg, fimd_lite->iomem_base + S5P_WINCON(win_id)); +} + +static void s5p_fimd_lite_lcd_on(struct s5p_fimd_lite *fimd_lite, + unsigned int enable) +{ + unsigned int cfg; + + cfg = readl(fimd_lite->iomem_base + S5P_VIDCON0); + + cfg &= ~(S5P_VIDCON0_ENVID_ENABLE | S5P_VIDCON0_ENVID_F_ENABLE); + + if (enable) + cfg |= (S5P_VIDCON0_ENVID_ENABLE | S5P_VIDCON0_ENVID_F_ENABLE); + + writel(cfg, fimd_lite->iomem_base + S5P_VIDCON0); +} + +void s5p_fimd_lite_get_vsync_interrupt(struct s5p_fimd_lite *fimd_lite, + unsigned int enable) +{ + unsigned int cfg; + + cfg = readl(fimd_lite->iomem_base + S5P_VIDINTCON0); + cfg &= ~(S5P_VIDINTCON0_INTFRMEN_ENABLE | S5P_VIDINTCON0_INT_ENABLE | + S5P_VIDINTCON0_FRAMESEL0_VSYNC); + + if (enable) { + cfg |= (S5P_VIDINTCON0_INTFRMEN_ENABLE | + S5P_VIDINTCON0_INT_ENABLE | + S5P_VIDINTCON0_FRAMESEL0_VSYNC); + } else { + cfg |= (S5P_VIDINTCON0_INTFRMEN_DISABLE | + S5P_VIDINTCON0_INT_DISABLE); + + cfg &= ~S5P_VIDINTCON0_FRAMESEL0_VSYNC; + } + + writel(cfg, fimd_lite->iomem_base + S5P_VIDINTCON0); +} + +static void s5p_change_dynamic_refresh(struct s5p_fimd_dynamic_refresh + *fimd_refresh, struct s5p_fimd_ext_device *fx_dev) +{ + unsigned int cfg = 0, ret = 0; + struct s5p_fimd_lite *fimd_lite = fimd_ext_get_drvdata(fx_dev); + struct exynos_drm_fimd_pdata *lcd; + struct fb_videomode timing; + unsigned long flags; + u32 vclk, src_clk, refresh; + + lcd = fimd_lite->lcd; + timing = lcd->panel.timing; + + cfg = readl(fimd_lite->iomem_base + S5P_VIDCON0); + cfg &= ~(S5P_VIDCON0_CLKVALUP_START_FRAME | S5P_VIDCON0_CLKVAL_F(0xFF)); + cfg |= (S5P_VIDCON0_CLKVALUP_ALWAYS | S5P_VIDCON0_VCLKEN_NORMAL); + cfg |= S5P_VIDCON0_CLKVAL_F(fimd_refresh->clkdiv - 1); + + if (!irqs_disabled()) + local_irq_save(flags); + + if (timing.refresh == 60) { + while (1) { + ret = (__raw_readl(fimd_lite->iomem_base + + S5P_VIDCON1) >> 13) & + S5P_VIDCON1_VSTATUS_MASK; + if (ret == S5P_VIDCON1_VSTATUS_BACKPORCH) { + __raw_writel(cfg, fimd_lite->iomem_base + + S5P_VIDCON0); + ret = (__raw_readl(fimd_refresh->regs + + VIDCON1) >> 13) & + S5P_VIDCON1_VSTATUS_MASK; + if (ret == S5P_VIDCON1_VSTATUS_ACTIVE) { + __raw_writel(cfg, + fimd_refresh->regs + VIDCON0); + break; + } + } + } + } else { + while (1) { + ret = (__raw_readl(fimd_refresh->regs + VIDCON1) >> 13) + & S5P_VIDCON1_VSTATUS_MASK; + if (ret == S5P_VIDCON1_VSTATUS_ACTIVE) { + ret = (__raw_readl(fimd_lite->iomem_base + + S5P_VIDCON1) >> 13) & + S5P_VIDCON1_VSTATUS_MASK; + if (ret == S5P_VIDCON1_VSTATUS_FRONTPORCH) { + __raw_writel(cfg, + fimd_refresh->regs + VIDCON0); + __raw_writel(cfg, + fimd_lite->iomem_base + + S5P_VIDCON0); + break; + } + } + } + } + if (irqs_disabled()) + local_irq_restore(flags); + + src_clk = clk_get_rate(fimd_lite->clk->parent); + vclk = timing.refresh * (timing.left_margin + timing.hsync_len + + timing.right_margin + timing.xres) * + (timing.upper_margin + timing.vsync_len + + timing.lower_margin + timing.yres); + + refresh = timing.refresh - + ((vclk - (src_clk / fimd_refresh->clkdiv)) / MHZ); + dev_dbg(fimd_lite->dev, "expected refresh rate: %d fps\n", refresh); +} + +static irqreturn_t s5p_fimd_lite_irq_frame(int irq, void *dev_id) +{ + struct s5p_fimd_lite *fimd_lite; + + fimd_lite = (struct s5p_fimd_lite *)dev_id; + + disable_irq_nosync(fimd_lite->irq); + + enable_irq(fimd_lite->irq); + + return IRQ_HANDLED; +} + +static void s5p_fimd_lite_logic_start(struct s5p_fimd_lite *fimd_lite, + unsigned int enable) +{ + unsigned int cfg; + + cfg = 0x2ff47; + + if (enable) + writel(cfg, fimd_lite->iomem_base + S5P_GPOUTCON0); + else + writel(0, fimd_lite->iomem_base + S5P_GPOUTCON0); +} + +static void s5p_fimd_lite_lcd_init(struct s5p_fimd_lite *fimd_lite) +{ + unsigned int cfg, rgb_mode, win_id = 0; + struct exynos_drm_fimd_pdata *lcd; + struct fb_videomode timing; + + lcd = fimd_lite->lcd; + timing = lcd->panel.timing; + + cfg = 0; + cfg |= lcd->vidcon1; + + writel(cfg, fimd_lite->iomem_base + S5P_VIDCON1); + + /* set timing */ + cfg = 0; + cfg |= S5P_VIDTCON0_VBPD(timing.upper_margin - 1); + cfg |= S5P_VIDTCON0_VFPD(timing.lower_margin - 1); + cfg |= S5P_VIDTCON0_VSPW(timing.vsync_len - 1); + writel(cfg, fimd_lite->iomem_base + S5P_VIDTCON0); + + cfg = 0; + cfg |= S5P_VIDTCON1_HBPD(timing.left_margin - 1); + cfg |= S5P_VIDTCON1_HFPD(timing.right_margin - 1); + cfg |= S5P_VIDTCON1_HSPW(timing.hsync_len - 1); + + writel(cfg, fimd_lite->iomem_base + S5P_VIDTCON1); + + /* set lcd size */ + cfg = 0; + cfg |= S5P_VIDTCON2_HOZVAL(timing.xres - 1); + cfg |= S5P_VIDTCON2_LINEVAL(timing.yres - 1); + + writel(cfg, fimd_lite->iomem_base + S5P_VIDTCON2); + + writel(0, fimd_lite->iomem_base + S5P_DITHMODE); + + /* set output to RGB */ + rgb_mode = 0; /* MODE_RGB_P */ + cfg = readl(fimd_lite->iomem_base + S5P_VIDCON0); + cfg &= ~S5P_VIDCON0_VIDOUT_MASK; + + cfg |= S5P_VIDCON0_VIDOUT_RGB; + writel(cfg, fimd_lite->iomem_base + S5P_VIDCON0); + + /* set display mode */ + cfg = readl(fimd_lite->iomem_base + S5P_VIDCON0); + cfg &= ~S5P_VIDCON0_PNRMODE_MASK; + cfg |= (rgb_mode << S5P_VIDCON0_PNRMODE_SHIFT); + writel(cfg, fimd_lite->iomem_base + S5P_VIDCON0); + + s5p_fimd_lite_get_vsync_interrupt(fimd_lite, 0); + + /* set par */ + s5p_fimd_lite_set_par(fimd_lite, win_id); + + /* set buffer size */ + cfg = S5P_VIDADDR_PAGEWIDTH(timing.xres * lcd->bpp / 8); + writel(cfg, fimd_lite->iomem_base + S5P_VIDADDR_SIZE(win_id)); + + /* set clock */ + s5p_fimd_lite_set_clock(fimd_lite); + + return; +} + +static int s5p_fimd_lite_setup(struct s5p_fimd_ext_device *fx_dev, + unsigned int enable) +{ + struct s5p_fimd_lite *fimd_lite = fimd_ext_get_drvdata(fx_dev); + + s5p_fimd_lite_logic_start(fimd_lite, enable); + + s5p_fimd_lite_lcd_init(fimd_lite); + + + s5p_fimd_lite_window_on(fimd_lite, 0, 1); + + return 0; +} + +static int s5p_fimd_lite_start(struct s5p_fimd_ext_device *fx_dev) +{ + struct s5p_fimd_lite *fimd_lite = fimd_ext_get_drvdata(fx_dev); + + s5p_fimd_lite_lcd_on(fimd_lite, 1); + + return 0; +} + +static void s5p_fimd_lite_stop(struct s5p_fimd_ext_device *fx_dev) +{ + struct s5p_fimd_lite *fimd_lite = fimd_ext_get_drvdata(fx_dev); + + s5p_fimd_lite_lcd_on(fimd_lite, 0); +} + +static void s5p_fimd_lite_power_on(struct s5p_fimd_ext_device *fx_dev) +{ + struct s5p_fimd_lite *fimd_lite = fimd_ext_get_drvdata(fx_dev); + + clk_enable(fimd_lite->clk); +} + +static void s5p_fimd_lite_power_off(struct s5p_fimd_ext_device *fx_dev) +{ + struct s5p_fimd_lite *fimd_lite = fimd_ext_get_drvdata(fx_dev); + + clk_disable(fimd_lite->clk); +} + +static int s5p_fimd_lite_probe(struct s5p_fimd_ext_device *fx_dev) +{ + struct clk *sclk = NULL; + struct resource *res; + struct s5p_fimd_lite *fimd_lite; + int ret = -1; + + fimd_lite = kzalloc(sizeof(struct s5p_fimd_lite), GFP_KERNEL); + if (!fimd_lite) { + dev_err(&fx_dev->dev, "failed to alloc fimd_lite object.\n"); + return -EFAULT; + } + + fimd_lite->dev = &fx_dev->dev; + fimd_lite->lcd = (struct exynos_drm_fimd_pdata *) + to_fimd_lite_platform_data(fx_dev); + + res = s5p_fimd_ext_get_resource(fx_dev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(&fx_dev->dev, "failed to get io memory region.\n"); + ret = -EINVAL; + goto err0; + } + + fimd_lite->iomem_base = ioremap(res->start, resource_size(res)); + if (!fimd_lite->iomem_base) { + dev_err(&fx_dev->dev, "failed to remap io region\n"); + ret = -EFAULT; + goto err0; + } + + fimd_lite->clk = clk_get(&fx_dev->dev, "mdnie0"); + if (IS_ERR(fimd_lite->clk)) { + dev_err(&fx_dev->dev, "failed to get FIMD LITE clock source\n"); + ret = -EINVAL; + goto err1; + } + + sclk = clk_get(&fx_dev->dev, "sclk_mdnie"); + if (IS_ERR(sclk)) { + dev_err(&fx_dev->dev, "failed to get sclk_mdnie clock\n"); + ret = -EINVAL; + goto err2; + } + fimd_lite->clk->parent = sclk; + + fimd_lite->irq = s5p_fimd_ext_get_irq(fx_dev, 0); + + /* register interrupt handler for fimd-lite. */ + if (request_irq(fimd_lite->irq, s5p_fimd_lite_irq_frame, IRQF_DISABLED, + fx_dev->name, (void *)fimd_lite)) { + dev_err(&fx_dev->dev, "request_irq failed\n"); + ret = -EINVAL; + goto err3; + } + + fimd_ext_set_drvdata(fx_dev, fimd_lite); + + dev_info(&fx_dev->dev, "fimd lite driver has been probed.\n"); + + return 0; + +err3: + free_irq(fimd_lite->irq, fx_dev); +err2: + clk_put(sclk); +err1: + iounmap(fimd_lite->iomem_base); + clk_put(fimd_lite->clk); +err0: + kfree(fimd_lite); + + return ret; + +} + +static struct s5p_fimd_ext_driver fimd_ext_driver = { + .driver = { + .name = "fimd_lite", + .owner = THIS_MODULE, + }, + .change_clock = s5p_change_dynamic_refresh, + .power_on = s5p_fimd_lite_power_on, + .power_off = s5p_fimd_lite_power_off, + .setup = s5p_fimd_lite_setup, + .start = s5p_fimd_lite_start, + .stop = s5p_fimd_lite_stop, + .probe = s5p_fimd_lite_probe, +}; + +static int __init s5p_fimd_lite_init(void) +{ + return s5p_fimd_ext_driver_register(&fimd_ext_driver); +} + +static void __exit s5p_fimd_lite_exit(void) +{ +} + +arch_initcall(s5p_fimd_lite_init); +module_exit(s5p_fimd_lite_exit); + +MODULE_AUTHOR("InKi Dae <inki.dae@samsung.com>"); +MODULE_DESCRIPTION("FIMD Lite Driver"); +MODULE_LICENSE("GPL"); + diff --git a/drivers/video/samsung_duallcd/extension/s5p_fimd_lite.h b/drivers/video/samsung_duallcd/extension/s5p_fimd_lite.h new file mode 100644 index 0000000..a8ef492 --- /dev/null +++ b/drivers/video/samsung_duallcd/extension/s5p_fimd_lite.h @@ -0,0 +1,37 @@ +/* linux/arch/arm/plat-s5p/s5p_fimd_lite.h + * + * FIMD Lite Platform Specific Header Definitions. + * + * Copyright (c) 2010 Samsung Electronics + * InKi Dae <inki.dae@samsung.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. +*/ + +#ifndef _S5P_FIMD_LITE_H_ +#define _S5P_FIMD_LITE_H_ + +#include <drm/exynos_drm.h> + +struct s5p_fimd_lite_platform_data { + unsigned int reg_base; + unsigned int reg_map_size; + unsigned int irq; +}; + +struct s5p_fimd_lite { + struct device *dev; + struct clk *clk; + void __iomem *iomem_base; + unsigned int irq; + unsigned int dynamic_refresh; + + struct exynos_drm_fimd_pdata *lcd; +}; + +void s5p_fimd_lite_get_vsync_interrupt(struct s5p_fimd_lite *fimd_lite, + unsigned int enable); + +#endif /* _S5P_FIMD_LITE_H_ */ |