[PATCH v5 06/14] drm/exynos: fimd: support LCD I80 interface

2014-07-09 Thread YoungJun Cho
To support MIPI command mode based I80 interface panel,
FIMD should do followings:
- Sets LCD I80 interface timings configuration.
- Uses "lcd_sys" as an IRQ resource and sets relevant IRQ configuration.
- Sets LCD block configuration for I80 interface.
- Sets ideal(pixel) clock is 2 times faster than the original one
  to generate frame done IRQ prior to the next TE signal.
- Implements trigger feature that transfers image data if there is page
  flip request, and implements TE handler to call trigger function.

Signed-off-by: YoungJun Cho 
Acked-by: Inki Dae 
Acked-by: Kyungmin Park 
---
 drivers/gpu/drm/exynos/Kconfig   |   1 +
 drivers/gpu/drm/exynos/exynos_drm_fimd.c | 276 ++-
 include/video/samsung_fimd.h |   3 +-
 3 files changed, 235 insertions(+), 45 deletions(-)

diff --git a/drivers/gpu/drm/exynos/Kconfig b/drivers/gpu/drm/exynos/Kconfig
index 178d2a9..9ba1aae 100644
--- a/drivers/gpu/drm/exynos/Kconfig
+++ b/drivers/gpu/drm/exynos/Kconfig
@@ -28,6 +28,7 @@ config DRM_EXYNOS_FIMD
bool "Exynos DRM FIMD"
depends on DRM_EXYNOS && !FB_S3C
select FB_MODE_HELPERS
+   select MFD_SYSCON
help
  Choose this option if you want to use Exynos FIMD for DRM.

diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c 
b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
index 33161ad..28a3168 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
@@ -20,6 +20,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 

 #include 
 #include 
@@ -61,6 +63,24 @@
 /* color key value register for hardware window 1 ~ 4. */
 #define WKEYCON1_BASE(x)   ((WKEYCON1 + 0x140) + ((x - 1) * 8))

+/* I80 / RGB trigger control register */
+#define TRIGCON0x1A4
+#define TRGMODE_I80_RGB_ENABLE_I80 (1 << 0)
+#define SWTRGCMD_I80_RGB_ENABLE(1 << 1)
+
+/* display mode change control register except exynos4 */
+#define VIDOUT_CON 0x000
+#define VIDOUT_CON_F_I80_LDI0  (0x2 << 8)
+
+/* I80 interface control for main LDI register */
+#define I80IFCONFAx(x) (0x1B0 + (x) * 4)
+#define I80IFCONFBx(x) (0x1B8 + (x) * 4)
+#define LCD_CS_SETUP(x)((x) << 16)
+#define LCD_WR_SETUP(x)((x) << 12)
+#define LCD_WR_ACTIVE(x)   ((x) << 8)
+#define LCD_WR_HOLD(x) ((x) << 4)
+#define I80IFEN_ENABLE (1 << 0)
+
 /* FIMD has totally five hardware windows. */
 #define WINDOWS_NR 5

@@ -68,10 +88,14 @@

 struct fimd_driver_data {
unsigned int timing_base;
+   unsigned int lcdblk_offset;
+   unsigned int lcdblk_vt_shift;
+   unsigned int lcdblk_bypass_shift;

unsigned int has_shadowcon:1;
unsigned int has_clksel:1;
unsigned int has_limited_fmt:1;
+   unsigned int has_vidoutcon:1;
 };

 static struct fimd_driver_data s3c64xx_fimd_driver_data = {
@@ -82,12 +106,19 @@ static struct fimd_driver_data s3c64xx_fimd_driver_data = {

 static struct fimd_driver_data exynos4_fimd_driver_data = {
.timing_base = 0x0,
+   .lcdblk_offset = 0x210,
+   .lcdblk_vt_shift = 10,
+   .lcdblk_bypass_shift = 1,
.has_shadowcon = 1,
 };

 static struct fimd_driver_data exynos5_fimd_driver_data = {
.timing_base = 0x2,
+   .lcdblk_offset = 0x214,
+   .lcdblk_vt_shift = 24,
+   .lcdblk_bypass_shift = 15,
.has_shadowcon = 1,
+   .has_vidoutcon = 1,
 };

 struct fimd_win_data {
@@ -112,15 +143,22 @@ struct fimd_context {
struct clk  *bus_clk;
struct clk  *lcd_clk;
void __iomem*regs;
+   struct regmap   *sysreg;
struct drm_display_mode mode;
struct fimd_win_datawin_data[WINDOWS_NR];
unsigned intdefault_win;
unsigned long   irq_flags;
+   u32 vidcon0;
u32 vidcon1;
+   u32 vidout_con;
+   u32 i80ifcon;
+   booli80_if;
boolsuspended;
int pipe;
wait_queue_head_t   wait_vsync_queue;
atomic_twait_vsync_event;
+   atomic_twin_updated;
+   atomic_ttriggering;

struct exynos_drm_panel_info panel;
struct fimd_driver_data *driver_data;
@@ -243,6 +281,14 @@ static u32 fimd_calc_clkdiv(struct fimd_context *ctx,
unsigned long ideal_clk = mode->htotal * mode->vtotal * mode->vrefresh;
u32 clkdiv;

+   if (ctx->i80_if) {
+   /*
+* The frame done interrupt should be occur

[PATCH v5 06/14] drm/exynos: fimd: support LCD I80 interface

2014-07-09 Thread Inki Dae
2014-07-08 9:39 GMT+09:00 YoungJun Cho :
> To support MIPI command mode based I80 interface panel,
> FIMD should do followings:
> - Sets LCD I80 interface timings configuration.
> - Uses "lcd_sys" as an IRQ resource and sets relevant IRQ configuration.
> - Sets LCD block configuration for I80 interface.
> - Sets ideal(pixel) clock is 2 times faster than the original one
>   to generate frame done IRQ prior to the next TE signal.
> - Implements trigger feature that transfers image data if there is page
>   flip request, and implements TE handler to call trigger function.
>
> Signed-off-by: YoungJun Cho 
> Acked-by: Inki Dae 
> Acked-by: Kyungmin Park 
> ---
>  drivers/gpu/drm/exynos/Kconfig   |   1 +
>  drivers/gpu/drm/exynos/exynos_drm_fimd.c | 276 
> ++-
>  include/video/samsung_fimd.h |   3 +-
>  3 files changed, 235 insertions(+), 45 deletions(-)
>
> diff --git a/drivers/gpu/drm/exynos/Kconfig b/drivers/gpu/drm/exynos/Kconfig
> index 178d2a9..9ba1aae 100644
> --- a/drivers/gpu/drm/exynos/Kconfig
> +++ b/drivers/gpu/drm/exynos/Kconfig
> @@ -28,6 +28,7 @@ config DRM_EXYNOS_FIMD
> bool "Exynos DRM FIMD"
> depends on DRM_EXYNOS && !FB_S3C
> select FB_MODE_HELPERS
> +   select MFD_SYSCON
> help
>   Choose this option if you want to use Exynos FIMD for DRM.
>
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c 
> b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
> index 33161ad..207872d 100644
> --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
> +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
> @@ -20,6 +20,8 @@
>  #include 
>  #include 
>  #include 
> +#include 
> +#include 
>
>  #include 
>  #include 
> @@ -61,6 +63,24 @@
>  /* color key value register for hardware window 1 ~ 4. */
>  #define WKEYCON1_BASE(x)   ((WKEYCON1 + 0x140) + ((x - 1) * 8))
>
> +/* I80 / RGB trigger control register */
> +#define TRIGCON0x1A4
> +#define TRGMODE_I80_RGB_ENABLE_I80 (1 << 0)
> +#define SWTRGCMD_I80_RGB_ENABLE(1 << 1)
> +
> +/* display mode change control register except exynos4 */
> +#define VIDOUT_CON 0x000
> +#define VIDOUT_CON_F_I80_LDI0  (0x2 << 8)
> +
> +/* I80 interface control for main LDI register */
> +#define I80IFCONFAx(x) (0x1B0 + (x) * 4)
> +#define I80IFCONFBx(x) (0x1B8 + (x) * 4)
> +#define LCD_CS_SETUP(x)((x) << 16)
> +#define LCD_WR_SETUP(x)((x) << 12)
> +#define LCD_WR_ACTIVE(x)   ((x) << 8)
> +#define LCD_WR_HOLD(x) ((x) << 4)
> +#define I80IFEN_ENABLE (1 << 0)
> +
>  /* FIMD has totally five hardware windows. */
>  #define WINDOWS_NR 5
>
> @@ -68,10 +88,14 @@
>
>  struct fimd_driver_data {
> unsigned int timing_base;
> +   unsigned int lcdblk_offset;
> +   unsigned int lcdblk_vt_shift;
> +   unsigned int lcdblk_bypass_shift;
>
> unsigned int has_shadowcon:1;
> unsigned int has_clksel:1;
> unsigned int has_limited_fmt:1;
> +   unsigned int has_vidoutcon:1;
>  };
>
>  static struct fimd_driver_data s3c64xx_fimd_driver_data = {
> @@ -82,12 +106,19 @@ static struct fimd_driver_data s3c64xx_fimd_driver_data 
> = {
>
>  static struct fimd_driver_data exynos4_fimd_driver_data = {
> .timing_base = 0x0,
> +   .lcdblk_offset = 0x210,
> +   .lcdblk_vt_shift = 10,
> +   .lcdblk_bypass_shift = 1,
> .has_shadowcon = 1,
>  };
>
>  static struct fimd_driver_data exynos5_fimd_driver_data = {
> .timing_base = 0x2,
> +   .lcdblk_offset = 0x214,
> +   .lcdblk_vt_shift = 24,
> +   .lcdblk_bypass_shift = 15,
> .has_shadowcon = 1,
> +   .has_vidoutcon = 1,
>  };
>
>  struct fimd_win_data {
> @@ -112,15 +143,22 @@ struct fimd_context {
> struct clk  *bus_clk;
> struct clk  *lcd_clk;
> void __iomem*regs;
> +   struct regmap   *sysreg;
> struct drm_display_mode mode;
> struct fimd_win_datawin_data[WINDOWS_NR];
> unsigned intdefault_win;
> unsigned long   irq_flags;
> +   u32 vidcon0;
> u32 vidcon1;
> +   u32 vidout_con;
> +   u32 i80ifcon;
> +   booli80_if;
> boolsuspended;
> int pipe;
> wait_queue_head_t   wait_vsync_queue;
> atomic_twait_vsync_event;
> +   atomic_twin_updated;
> +   atomic_ttriggering;
>
> struct exynos_drm_panel_info panel;
> struct fimd_driver_data *driv

[PATCH v5 06/14] drm/exynos: fimd: support LCD I80 interface

2014-07-08 Thread YoungJun Cho
To support MIPI command mode based I80 interface panel,
FIMD should do followings:
- Sets LCD I80 interface timings configuration.
- Uses "lcd_sys" as an IRQ resource and sets relevant IRQ configuration.
- Sets LCD block configuration for I80 interface.
- Sets ideal(pixel) clock is 2 times faster than the original one
  to generate frame done IRQ prior to the next TE signal.
- Implements trigger feature that transfers image data if there is page
  flip request, and implements TE handler to call trigger function.

Signed-off-by: YoungJun Cho 
Acked-by: Inki Dae 
Acked-by: Kyungmin Park 
---
 drivers/gpu/drm/exynos/Kconfig   |   1 +
 drivers/gpu/drm/exynos/exynos_drm_fimd.c | 276 ++-
 include/video/samsung_fimd.h |   3 +-
 3 files changed, 235 insertions(+), 45 deletions(-)

diff --git a/drivers/gpu/drm/exynos/Kconfig b/drivers/gpu/drm/exynos/Kconfig
index 178d2a9..9ba1aae 100644
--- a/drivers/gpu/drm/exynos/Kconfig
+++ b/drivers/gpu/drm/exynos/Kconfig
@@ -28,6 +28,7 @@ config DRM_EXYNOS_FIMD
bool "Exynos DRM FIMD"
depends on DRM_EXYNOS && !FB_S3C
select FB_MODE_HELPERS
+   select MFD_SYSCON
help
  Choose this option if you want to use Exynos FIMD for DRM.

diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c 
b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
index 33161ad..207872d 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
@@ -20,6 +20,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 

 #include 
 #include 
@@ -61,6 +63,24 @@
 /* color key value register for hardware window 1 ~ 4. */
 #define WKEYCON1_BASE(x)   ((WKEYCON1 + 0x140) + ((x - 1) * 8))

+/* I80 / RGB trigger control register */
+#define TRIGCON0x1A4
+#define TRGMODE_I80_RGB_ENABLE_I80 (1 << 0)
+#define SWTRGCMD_I80_RGB_ENABLE(1 << 1)
+
+/* display mode change control register except exynos4 */
+#define VIDOUT_CON 0x000
+#define VIDOUT_CON_F_I80_LDI0  (0x2 << 8)
+
+/* I80 interface control for main LDI register */
+#define I80IFCONFAx(x) (0x1B0 + (x) * 4)
+#define I80IFCONFBx(x) (0x1B8 + (x) * 4)
+#define LCD_CS_SETUP(x)((x) << 16)
+#define LCD_WR_SETUP(x)((x) << 12)
+#define LCD_WR_ACTIVE(x)   ((x) << 8)
+#define LCD_WR_HOLD(x) ((x) << 4)
+#define I80IFEN_ENABLE (1 << 0)
+
 /* FIMD has totally five hardware windows. */
 #define WINDOWS_NR 5

@@ -68,10 +88,14 @@

 struct fimd_driver_data {
unsigned int timing_base;
+   unsigned int lcdblk_offset;
+   unsigned int lcdblk_vt_shift;
+   unsigned int lcdblk_bypass_shift;

unsigned int has_shadowcon:1;
unsigned int has_clksel:1;
unsigned int has_limited_fmt:1;
+   unsigned int has_vidoutcon:1;
 };

 static struct fimd_driver_data s3c64xx_fimd_driver_data = {
@@ -82,12 +106,19 @@ static struct fimd_driver_data s3c64xx_fimd_driver_data = {

 static struct fimd_driver_data exynos4_fimd_driver_data = {
.timing_base = 0x0,
+   .lcdblk_offset = 0x210,
+   .lcdblk_vt_shift = 10,
+   .lcdblk_bypass_shift = 1,
.has_shadowcon = 1,
 };

 static struct fimd_driver_data exynos5_fimd_driver_data = {
.timing_base = 0x2,
+   .lcdblk_offset = 0x214,
+   .lcdblk_vt_shift = 24,
+   .lcdblk_bypass_shift = 15,
.has_shadowcon = 1,
+   .has_vidoutcon = 1,
 };

 struct fimd_win_data {
@@ -112,15 +143,22 @@ struct fimd_context {
struct clk  *bus_clk;
struct clk  *lcd_clk;
void __iomem*regs;
+   struct regmap   *sysreg;
struct drm_display_mode mode;
struct fimd_win_datawin_data[WINDOWS_NR];
unsigned intdefault_win;
unsigned long   irq_flags;
+   u32 vidcon0;
u32 vidcon1;
+   u32 vidout_con;
+   u32 i80ifcon;
+   booli80_if;
boolsuspended;
int pipe;
wait_queue_head_t   wait_vsync_queue;
atomic_twait_vsync_event;
+   atomic_twin_updated;
+   atomic_ttriggering;

struct exynos_drm_panel_info panel;
struct fimd_driver_data *driver_data;
@@ -243,6 +281,14 @@ static u32 fimd_calc_clkdiv(struct fimd_context *ctx,
unsigned long ideal_clk = mode->htotal * mode->vtotal * mode->vrefresh;
u32 clkdiv;

+   if (ctx->i80_if) {
+   /*
+* The frame done interrupt should be occur