[PATCH v5 06/14] drm/exynos: fimd: support LCD I80 interface
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-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
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