To support MIPI DSI command mode interface, FIMD should do followings:
- Sets LCD block configuration for I80 interface.
- Uses "lcd_sys" as an IRQ resource and sets relevant IRQ configuration.
- Implements trigger feature which transfers image date if there is
page flip request, and implements TE handler to call trigger function.
- Sets CPU mode timings configuration.
- Sets ideal(pixel) clock is 2 times faster than the original one to
generate frame done IRQ prior to the next TE signal.
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 | 280 +-
include/video/samsung_fimd.h |3 +-
3 files changed, 240 insertions(+), 44 deletions(-)
diff --git a/drivers/gpu/drm/exynos/Kconfig b/drivers/gpu/drm/exynos/Kconfig
index 5bf5bca..f4d34f0 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 && !ARCH_MULTIPLATFORM
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 40fd6cc..9015cf52 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
@@ -19,11 +19,14 @@
#include
#include
#include
+#include
+#include
#include
#include
#include
#include
+#include
#include "exynos_drm_drv.h"
#include "exynos_drm_fbdev.h"
@@ -59,6 +62,22 @@
/* 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
+
+/* 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_ACT(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
@@ -66,10 +85,14 @@
struct fimd_driver_data {
unsigned int timing_base;
+ unsigned int lcdblk_off;
+ 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 = {
@@ -80,12 +103,19 @@ static struct fimd_driver_data s3c64xx_fimd_driver_data = {
static struct fimd_driver_data exynos4_fimd_driver_data = {
.timing_base = 0x0,
+ .lcdblk_off = 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_off = 0x214,
+ .lcdblk_vt_shift = 24,
+ .lcdblk_bypass_shift = 15,
.has_shadowcon = 1,
+ .has_vidoutcon = 1,
};
struct fimd_win_data {
@@ -110,15 +140,23 @@ 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;
+ spinlock_t win_updated_lock;
struct exynos_drm_panel_info panel;
struct fimd_driver_data *driver_data;
@@ -190,6 +228,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) {
+ /*
+