简介
tiny4412 lcd屏使用的液晶屏型号是S702,它通过RGB888跟4412进行数据通信。LCD驱动的实现方式有两种,一种是单独写驱动模块,另一种是基于源码s3c-fb.c去修改。
第一种方式可以参考
【TINY4412】LINUX移植笔记:(27)设备树LCD驱动
Exynos4412——LCD驱动
另外一种方式是参考fire brother的github去修改的。
第二种方式的思路是基于友善之臂的linux3.5源码移植过来,然后改成设备树的形式。我这里仅仅是做了移植操作,没有去仔细分析代码,所以我这里仅提供diff。
diff
diff --git a/arch/arm/boot/dts/exynos4.dtsi b/arch/arm/boot/dts/exynos4.dtsi
index 6085e92..7cf499e 100755
--- a/arch/arm/boot/dts/exynos4.dtsi
+++ b/arch/arm/boot/dts/exynos4.dtsi
@@ -722,8 +722,8 @@
reg = <0x11c00000 0x20000>;
interrupt-names = "fifo", "vsync", "lcd_sys";
interrupts = <11 0>, <11 1>, <11 2>;
- clocks = <&clock CLK_SCLK_FIMD0>, <&clock CLK_FIMD0>;
- clock-names = "sclk_fimd", "fimd";
+ clocks = <&clock CLK_FIMD0>, <&clock CLK_SCLK_FIMD0>;
+ clock-names = "fimd", "sclk_fimd";
power-domains = <&pd_lcd0>;
iommus = <&sysmmu_fimd0>;
samsung,sysreg = <&sys_reg>;
diff --git a/arch/arm/boot/dts/exynos4412-pinctrl.dtsi b/arch/arm/boot/dts/exynos4412-pinctrl.dtsi
old mode 100644
new mode 100755
index d7d5fdc..8bbb3a8
--- a/arch/arm/boot/dts/exynos4412-pinctrl.dtsi
+++ b/arch/arm/boot/dts/exynos4412-pinctrl.dtsi
@@ -363,7 +363,7 @@
samsung,pins = "gpf0-0", "gpf0-1", "gpf0-2", "gpf0-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
- samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+ samsung,pin-drv = <EXYNOS4_PIN_DRV_LV2>;
};
lcd_data16: lcd-data-width16 {
@@ -396,7 +396,7 @@
"gpf3-0", "gpf3-1", "gpf3-2", "gpf3-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
- samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+ samsung,pin-drv = <EXYNOS4_PIN_DRV_LV3>;
};
lcd_ldi: lcd-ldi {
diff --git a/arch/arm/boot/dts/exynos4412-tiny4412.dts b/arch/arm/boot/dts/exynos4412-tiny4412.dts
index f6b00a7..92aa0f0 100755
--- a/arch/arm/boot/dts/exynos4412-tiny4412.dts
+++ b/arch/arm/boot/dts/exynos4412-tiny4412.dts
@@ -11,6 +11,8 @@
/dts-v1/;
#include "exynos4412.dtsi"
#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/video/samsung_fimd.h>
+
/ {
model = "FriendlyARM TINY4412 board based on Exynos4412";
@@ -92,6 +94,147 @@
clock-frequency = <24000000>;
};
};
+ tiny4412_lcd {
+ status = "okay";
+
+ s702{
+ width = <800>;
+ height = <480>;
+ p_width = <155>;
+ p_height = <93>;
+ bpp = <24>;
+ freq = <63>;
+
+ timing {
+ h_fp = <80>;
+ h_bp = <36>;
+ h_sw = <10>;
+ v_fp = <22>;
+ v_fpe = <1>;
+ v_bp = <15>;
+ v_bpe = <1>;
+ v_sw = <8>;
+ };
+
+ polarity {
+ rise_vclk;
+ inv_hsync;
+ inv_vsync;
+ };
+ };
+ };
+
+&fimd {
+ compatible = "samsung,exynos4-fb";
+ sclk-fimd-rate = <800000000>;
+ pinctrl-0 = <&lcd_clk &lcd_data24>;
+ pinctrl-names = "lcd0_pin_cfg";
+ sysreg_lcd_blk_cfg_offset = /bits/ 32 <0x0210>;
+ status = "okay";
+ lcd_name = "s702";
+
+ lcd_default_config {
+ vidcon0 = <VIDCON0_VIDOUT_RGB VIDCON0_PNRMODE_RGB>;
+ vidcon1 = <VIDCON1_INV_HSYNC VIDCON1_INV_VSYNC>;
+ setup_gpio = "exynos4_fimd0_gpio_setup_24bpp";
+
+ vtiming {
+ left_margin = <9>;
+ right_margin = <9>;
+ upper_margin = <5>;
+ lower_margin = <5>;
+ hsync_len = <2>;
+ vsync_len = <2>;
+ xres = <480>;
+ yres = <800>;
+ };
+ wins_array {
+ win0 {
+ xres = /bits/ 16 <480>;
+ yres = /bits/ 16 <800>;
+ virtual_x = /bits/ 16 <480>;
+ virtual_y = /bits/ 16 <800>;
+ max_bpp = /bits/ 16 <32>;
+ default_bpp = /bits/ 16 <24>;
+ width = /bits/ 16 <66>;
+ height = /bits/ 16 <109>;
+ };
+
+ win1 {
+ xres = /bits/ 16 <480>;
+ yres = /bits/ 16 <800>;
+ virtual_x = /bits/ 16 <480>;
+ virtual_y = /bits/ 16 <800>;
+ max_bpp = /bits/ 16 <32>;
+ default_bpp = /bits/ 16 <24>;
+ width = /bits/ 16 <66>;
+ height = /bits/ 16 <109>;
+ };
+
+ win2 {
+ xres = /bits/ 16 <480>;
+ yres = /bits/ 16 <800>;
+ virtual_x = /bits/ 16 <480>;
+ virtual_y = /bits/ 16 <800>;
+ max_bpp = /bits/ 16 <32>;
+ default_bpp = /bits/ 16 <24>;
+ width = /bits/ 16 <66>;
+ height = /bits/ 16 <109>;
+ };
+
+ win3 {
+ xres = /bits/ 16 <480>;
+ yres = /bits/ 16 <800>;
+ virtual_x = /bits/ 16 <480>;
+ virtual_y = /bits/ 16 <800>;
+ max_bpp = /bits/ 16 <32>;
+ default_bpp = /bits/ 16 <24>;
+ width = /bits/ 16 <66>;
+ height = /bits/ 16 <109>;
+ };
+
+ win4 {
+ xres = /bits/ 16 <480>;
+ yres = /bits/ 16 <800>;
+ virtual_x = /bits/ 16 <480>;
+ virtual_y = /bits/ 16 <800>;
+ max_bpp = /bits/ 16 <32>;
+ default_bpp = /bits/ 16 <24>;
+ width = /bits/ 16 <66>;
+ height = /bits/ 16 <109>;
+ };
+ };
+
+ };
+
+
};
&i2c_0 {
diff --git a/drivers/video/fbdev/Makefile b/drivers/video/fbdev/Makefile
index 846b0c9..bf66a1d 100644
--- a/drivers/video/fbdev/Makefile
+++ b/drivers/video/fbdev/Makefile
@@ -102,7 +102,7 @@ obj-$(CONFIG_FB_BROADSHEET) += broadsheetfb.o
obj-$(CONFIG_FB_S1D13XXX) += s1d13xxxfb.o
obj-$(CONFIG_FB_SH7760) += sh7760fb.o
obj-$(CONFIG_FB_IMX) += imxfb.o
-obj-$(CONFIG_FB_S3C) += s3c-fb.o
+obj-y += s3c-fb.o
obj-$(CONFIG_FB_S3C2410) += s3c2410fb.o
obj-$(CONFIG_FB_FSL_DIU) += fsl-diu-fb.o
obj-$(CONFIG_FB_COBALT) += cobalt_lcdfb.o
diff --git a/drivers/video/fbdev/s3c-fb.c b/drivers/video/fbdev/s3c-fb.c
old mode 100644
new mode 100755
index 9ec85cc..a343636
--- a/drivers/video/fbdev/s3c-fb.c
+++ b/drivers/video/fbdev/s3c-fb.c
@@ -24,10 +24,17 @@
#include <linux/uaccess.h>
#include <linux/interrupt.h>
#include <linux/pm_runtime.h>
+#include <linux/dma-buf.h>
+
#include <linux/platform_data/video_s3c.h>
#include <video/samsung_fimd.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/gpio.h>
+#include <linux/byteorder/generic.h>
+
/* This driver will export a number of framebuffer interfaces depending
* on the configuration passed in via the platform data. Each fb instance
* maps to a hardware window. Currently there is no support for runtime
@@ -54,7 +61,7 @@
/* irq_flags bits */
#define S3C_FB_VSYNC_IRQ_EN 0
-#define VSYNC_TIMEOUT_MSEC 50
+#define VSYNC_TIMEOUT_MSEC 60
struct s3c_fb;
@@ -153,6 +160,13 @@ struct s3c_fb_palette {
struct fb_bitfield a;
};
+struct s3c_dma_buf_data {
+ struct dma_buf *dma_buf;
+ struct dma_buf_attachment *attachment;
+ struct sg_table *sg_table;
+ dma_addr_t dma_addr;
+};
+
/**
* struct s3c_fb_win - per window private data for each framebuffer.
* @windata: The platform data supplied for the window configuration.
@@ -174,6 +188,13 @@ struct s3c_fb_win {
u32 *palette_buffer;
u32 pseudo_palette[16];
unsigned int index;
+
+ struct s3c_dma_buf_data dma_buf_data;
+ struct fb_var_screeninfo prev_var;
+ struct fb_fix_screeninfo prev_fix;
+
+ int fps;
+
};
/**
@@ -221,6 +242,90 @@ struct s3c_fb {
struct s3c_fb_vsync vsync_info;
};
+#ifdef CONFIG_OF
+
+typedef struct lcd_io_reg_cfg{
+ struct pinctrl *pctrl;
+ struct pinctrl_state *pin_lcd_cfg;
+ void __iomem *lcd_blk_cfg_reg;
+} lcd_io_reg_cfg;
+
+static struct lcd_io_reg_cfg lcd_io_cfg = {
+ .lcd_blk_cfg_reg = NULL,
+ .pctrl = NULL,
+ .pin_lcd_cfg = NULL,
+};
+
+static const struct of_device_id s3c_fb_of_match[];
+static struct s3c_fb_platdata * of_get_s3_fb_lcd(const struct device_node *node,
+ const char *name);
+static int of_parse_lcd_io_reg_cfg(struct platform_device *pdev,
+ struct lcd_io_reg_cfg *pcfg);
+
+#endif
+
+
+/*
+ * struct s3cfb_lcd_polarity
+ * @rise_vclk: if 1, video data is fetched at rising edge
+ * @inv_hsync: if HSYNC polarity is inversed
+ * @inv_vsync: if VSYNC polarity is inversed
+ * @inv_vden: if VDEN polarity is inversed
+ */