diff mbox

[U-Boot,v2] wandboard: add Future Eletronics 7" WVGA LCD extension board

Message ID 1398980110-29441-1-git-send-email-otavio@ossystems.com.br
State Changes Requested
Delegated to: Stefano Babic
Headers show

Commit Message

Otavio Salvador May 1, 2014, 9:35 p.m. UTC
This adds support for the 7" WVGA produced by Future Eletronics and
make it dynamically detect if it is connected or not based on the
touchscreen controller.

Signed-off-by: Otavio Salvador <otavio@ossystems.com.br>
---
Fabio, I haven't change the environment script as I consider important
to have it working with Wandboard kernel. Please take a look and comment
accordingly.

Changes in v2:
- Drop LDB related code (unused)

 board/wandboard/wandboard.c | 165 +++++++++++++++++++++++++++++++++++++-------
 include/configs/wandboard.h |  36 +++++++++-
 2 files changed, 174 insertions(+), 27 deletions(-)

Comments

Fabio Estevam May 1, 2014, 9:48 p.m. UTC | #1
On Thu, May 1, 2014 at 6:35 PM, Otavio Salvador <otavio@ossystems.com.br> wrote:

>  static void setup_display(void)
>  {
>         struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
> +       struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
>         int reg;
>
>         enable_ipu_clock();
> @@ -254,6 +343,28 @@ static void setup_display(void)
>         reg |= (CHSCCDR_CLK_SEL_LDB_DI0
>                 << MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_OFFSET);
>         writel(reg, &mxc_ccm->chsccdr);
> +
> +       reg = IOMUXC_GPR2_BGREF_RRMODE_EXTERNAL_RES
> +            | IOMUXC_GPR2_DI1_VS_POLARITY_ACTIVE_LOW
> +            | IOMUXC_GPR2_DI0_VS_POLARITY_ACTIVE_LOW
> +            | IOMUXC_GPR2_BIT_MAPPING_CH1_SPWG
> +            | IOMUXC_GPR2_DATA_WIDTH_CH1_18BIT
> +            | IOMUXC_GPR2_BIT_MAPPING_CH0_SPWG
> +            | IOMUXC_GPR2_DATA_WIDTH_CH0_18BIT
> +            | IOMUXC_GPR2_LVDS_CH0_MODE_DISABLED
> +            | IOMUXC_GPR2_LVDS_CH1_MODE_ENABLED_DI0;
> +       writel(reg, &iomux->gpr[2]);

This is all LVDS related and the LCD you are adding is not a LVDS.

> +
> +       reg = readl(&iomux->gpr[3]);
> +       reg = (reg & ~(IOMUXC_GPR3_LVDS1_MUX_CTL_MASK
> +                       | IOMUXC_GPR3_HDMI_MUX_CTL_MASK))
> +           | (IOMUXC_GPR3_MUX_SRC_IPU1_DI0
> +              << IOMUXC_GPR3_LVDS1_MUX_CTL_OFFSET);
> +       writel(reg, &iomux->gpr[3]);

Same here.

>  #if defined(CONFIG_MX6DL) || defined(CONFIG_MX6S)
>  #define CONFIG_DEFAULT_FDT_FILE                "imx6dl-wandboard.dtb"
> @@ -152,7 +160,33 @@
>                         "fi; "  \
>                 "fi\0" \
>         "mmcargs=setenv bootargs console=${console},${baudrate} " \
> -               "root=${mmcroot}\0" \
> +               "root=${mmcroot}; run videoargs\0" \
> +       "videoargs=" \
> +               "setenv nextcon 0; " \
> +               "if hdmidet; then " \
> +                       "setenv bootargs ${bootargs} " \
> +                               "video=mxcfb${nextcon}:dev=hdmi,1280x720M@60," \
> +                                       "if=RGB24; " \

This is unrelated to adding a LVDS display and would be better handled
on a separate patch.

> +                       "setenv fbmen fbmem=28M; " \
> +                       "setexpr nextcon ${nextcon} + 1; " \
> +               "else " \
> +                       "echo - no HDMI monitor;" \
> +               "fi; " \
> +               "i2c dev 1; " \
> +               "if i2c probe 0x10; then " \
> +                       "setenv bootargs ${bootargs} " \
> +                               "video=mxcfb${nextcon}:dev=lcd,800x480@60," \
> +                                       "if=RGB666; " \
> +                       "if test 0 -eq ${nextcon}; then " \
> +                               "setenv fbmem fbmem=10M; " \
> +                       "else " \
> +                               "setenv fbmem ${fbmem},10M; " \
> +                       "fi; " \
> +                       "setexpr nextcon ${nextcon} + 1; " \
> +               "else " \
> +                       "echo '- no FWBADAPT-7WVGA-LCD-F07A-0102 display';" \
> +               "fi; " \
> +               "setenv bootargs ${bootargs} ${fbmem}\0" \

Changing the environment variables would be more appropriate on a
separate patch, but still don't like the idea of hardcoding the video
argument specific to a FSL kernel version.
Otavio Salvador May 1, 2014, 10:03 p.m. UTC | #2
Hello Fabio,

On Thu, May 1, 2014 at 6:48 PM, Fabio Estevam <festevam@gmail.com> wrote:
> On Thu, May 1, 2014 at 6:35 PM, Otavio Salvador <otavio@ossystems.com.br> wrote:
>
>>  static void setup_display(void)
>>  {
>>         struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
>> +       struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
>>         int reg;
>>
>>         enable_ipu_clock();
>> @@ -254,6 +343,28 @@ static void setup_display(void)
>>         reg |= (CHSCCDR_CLK_SEL_LDB_DI0
>>                 << MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_OFFSET);
>>         writel(reg, &mxc_ccm->chsccdr);
>> +
>> +       reg = IOMUXC_GPR2_BGREF_RRMODE_EXTERNAL_RES
>> +            | IOMUXC_GPR2_DI1_VS_POLARITY_ACTIVE_LOW
>> +            | IOMUXC_GPR2_DI0_VS_POLARITY_ACTIVE_LOW
>> +            | IOMUXC_GPR2_BIT_MAPPING_CH1_SPWG
>> +            | IOMUXC_GPR2_DATA_WIDTH_CH1_18BIT
>> +            | IOMUXC_GPR2_BIT_MAPPING_CH0_SPWG
>> +            | IOMUXC_GPR2_DATA_WIDTH_CH0_18BIT
>> +            | IOMUXC_GPR2_LVDS_CH0_MODE_DISABLED
>> +            | IOMUXC_GPR2_LVDS_CH1_MODE_ENABLED_DI0;
>> +       writel(reg, &iomux->gpr[2]);
>
> This is all LVDS related and the LCD you are adding is not a LVDS.
>
>> +
>> +       reg = readl(&iomux->gpr[3]);
>> +       reg = (reg & ~(IOMUXC_GPR3_LVDS1_MUX_CTL_MASK
>> +                       | IOMUXC_GPR3_HDMI_MUX_CTL_MASK))
>> +           | (IOMUXC_GPR3_MUX_SRC_IPU1_DI0
>> +              << IOMUXC_GPR3_LVDS1_MUX_CTL_OFFSET);
>> +       writel(reg, &iomux->gpr[3]);
>
> Same here.
>
>>  #if defined(CONFIG_MX6DL) || defined(CONFIG_MX6S)
>>  #define CONFIG_DEFAULT_FDT_FILE                "imx6dl-wandboard.dtb"
>> @@ -152,7 +160,33 @@
>>                         "fi; "  \
>>                 "fi\0" \
>>         "mmcargs=setenv bootargs console=${console},${baudrate} " \
>> -               "root=${mmcroot}\0" \
>> +               "root=${mmcroot}; run videoargs\0" \
>> +       "videoargs=" \
>> +               "setenv nextcon 0; " \
>> +               "if hdmidet; then " \
>> +                       "setenv bootargs ${bootargs} " \
>> +                               "video=mxcfb${nextcon}:dev=hdmi,1280x720M@60," \
>> +                                       "if=RGB24; " \
>
> This is unrelated to adding a LVDS display and would be better handled
> on a separate patch.
>
>> +                       "setenv fbmen fbmem=28M; " \
>> +                       "setexpr nextcon ${nextcon} + 1; " \
>> +               "else " \
>> +                       "echo - no HDMI monitor;" \
>> +               "fi; " \
>> +               "i2c dev 1; " \
>> +               "if i2c probe 0x10; then " \
>> +                       "setenv bootargs ${bootargs} " \
>> +                               "video=mxcfb${nextcon}:dev=lcd,800x480@60," \
>> +                                       "if=RGB666; " \
>> +                       "if test 0 -eq ${nextcon}; then " \
>> +                               "setenv fbmem fbmem=10M; " \
>> +                       "else " \
>> +                               "setenv fbmem ${fbmem},10M; " \
>> +                       "fi; " \
>> +                       "setexpr nextcon ${nextcon} + 1; " \
>> +               "else " \
>> +                       "echo '- no FWBADAPT-7WVGA-LCD-F07A-0102 display';" \
>> +               "fi; " \
>> +               "setenv bootargs ${bootargs} ${fbmem}\0" \
>
> Changing the environment variables would be more appropriate on a
> separate patch, but still don't like the idea of hardcoding the video
> argument specific to a FSL kernel version.

I hope to have handled all the comments in v3 :-)
diff mbox

Patch

diff --git a/board/wandboard/wandboard.c b/board/wandboard/wandboard.c
index f1951dc..d88e9b7 100644
--- a/board/wandboard/wandboard.c
+++ b/board/wandboard/wandboard.c
@@ -1,5 +1,6 @@ 
 /*
  * Copyright (C) 2013 Freescale Semiconductor, Inc.
+ * Copyright (C) 2014 O.S. Systems Software LTDA.
  *
  * Author: Fabio Estevam <fabio.estevam@freescale.com>
  *
@@ -15,18 +16,19 @@ 
 #include <asm/arch/sys_proto.h>
 #include <asm/gpio.h>
 #include <asm/imx-common/iomux-v3.h>
+#include <asm/imx-common/mxc_i2c.h>
 #include <asm/imx-common/boot_mode.h>
+#include <asm/imx-common/video.h>
 #include <asm/io.h>
 #include <linux/sizes.h>
 #include <common.h>
 #include <fsl_esdhc.h>
-#include <ipu_pixfmt.h>
 #include <mmc.h>
 #include <miiphy.h>
 #include <netdev.h>
-#include <linux/fb.h>
 #include <phy.h>
 #include <input.h>
+#include <i2c.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -41,6 +43,10 @@  DECLARE_GLOBAL_DATA_PTR;
 #define ENET_PAD_CTRL  (PAD_CTL_PUS_100K_UP |			\
 	PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_HYS)
 
+#define I2C_PAD_CTRL	(PAD_CTL_PUS_100K_UP |			\
+	PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_HYS |	\
+	PAD_CTL_ODE | PAD_CTL_SRE_FAST)
+
 #define USDHC1_CD_GPIO		IMX_GPIO_NR(1, 2)
 #define USDHC3_CD_GPIO		IMX_GPIO_NR(3, 9)
 #define ETH_PHY_RESET		IMX_GPIO_NR(3, 29)
@@ -210,41 +216,124 @@  int board_phy_config(struct phy_device *phydev)
 }
 
 #if defined(CONFIG_VIDEO_IPUV3)
-static struct fb_videomode const hdmi = {
-	.name           = "HDMI",
-	.refresh        = 60,
-	.xres           = 1024,
-	.yres           = 768,
-	.pixclock       = 15385,
-	.left_margin    = 220,
-	.right_margin   = 40,
-	.upper_margin   = 21,
-	.lower_margin   = 7,
-	.hsync_len      = 60,
-	.vsync_len      = 10,
-	.sync           = FB_SYNC_EXT,
-	.vmode          = FB_VMODE_NONINTERLACED
+struct i2c_pads_info i2c2_pad_info = {
+	.scl = {
+		.i2c_mode = MX6_PAD_KEY_COL3__I2C2_SCL
+			| MUX_PAD_CTRL(I2C_PAD_CTRL),
+		.gpio_mode = MX6_PAD_KEY_COL3__GPIO4_IO12
+			| MUX_PAD_CTRL(I2C_PAD_CTRL),
+		.gp = IMX_GPIO_NR(4, 12)
+	},
+	.sda = {
+		.i2c_mode = MX6_PAD_KEY_ROW3__I2C2_SDA
+			| MUX_PAD_CTRL(I2C_PAD_CTRL),
+		.gpio_mode = MX6_PAD_KEY_ROW3__GPIO4_IO13
+			| MUX_PAD_CTRL(I2C_PAD_CTRL),
+		.gp = IMX_GPIO_NR(4, 13)
+	}
 };
 
-int board_video_skip(void)
-{
-	int ret;
+static iomux_v3_cfg_t const fwadapt_7wvga_pads[] = {
+	MX6_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK,
+	MX6_PAD_DI0_PIN2__IPU1_DI0_PIN02, /* HSync */
+	MX6_PAD_DI0_PIN3__IPU1_DI0_PIN03, /* VSync */
+	MX6_PAD_DI0_PIN4__IPU1_DI0_PIN04
+		| MUX_PAD_CTRL(PAD_CTL_DSE_120ohm), /* Contrast */
+	MX6_PAD_DI0_PIN15__IPU1_DI0_PIN15, /* DISP0_DRDY */
+
+	MX6_PAD_DISP0_DAT0__IPU1_DISP0_DATA00,
+	MX6_PAD_DISP0_DAT1__IPU1_DISP0_DATA01,
+	MX6_PAD_DISP0_DAT2__IPU1_DISP0_DATA02,
+	MX6_PAD_DISP0_DAT3__IPU1_DISP0_DATA03,
+	MX6_PAD_DISP0_DAT4__IPU1_DISP0_DATA04,
+	MX6_PAD_DISP0_DAT5__IPU1_DISP0_DATA05,
+	MX6_PAD_DISP0_DAT6__IPU1_DISP0_DATA06,
+	MX6_PAD_DISP0_DAT7__IPU1_DISP0_DATA07,
+	MX6_PAD_DISP0_DAT8__IPU1_DISP0_DATA08,
+	MX6_PAD_DISP0_DAT9__IPU1_DISP0_DATA09,
+	MX6_PAD_DISP0_DAT10__IPU1_DISP0_DATA10,
+	MX6_PAD_DISP0_DAT11__IPU1_DISP0_DATA11,
+	MX6_PAD_DISP0_DAT12__IPU1_DISP0_DATA12,
+	MX6_PAD_DISP0_DAT13__IPU1_DISP0_DATA13,
+	MX6_PAD_DISP0_DAT14__IPU1_DISP0_DATA14,
+	MX6_PAD_DISP0_DAT15__IPU1_DISP0_DATA15,
+	MX6_PAD_DISP0_DAT16__IPU1_DISP0_DATA16,
+	MX6_PAD_DISP0_DAT17__IPU1_DISP0_DATA17,
+
+	MX6_PAD_SD4_DAT2__GPIO2_IO10
+		| MUX_PAD_CTRL(NO_PAD_CTRL), /* DISP0_BKLEN */
+	MX6_PAD_SD4_DAT3__GPIO2_IO11
+		| MUX_PAD_CTRL(NO_PAD_CTRL), /* DISP0_VDDEN */
+};
 
-	ret = ipuv3_fb_init(&hdmi, 0, IPU_PIX_FMT_RGB24);
+static void do_enable_hdmi(struct display_info_t const *dev)
+{
+	imx_enable_hdmi_phy();
+}
 
-	if (ret) {
-		printf("HDMI cannot be configured: %d\n", ret);
-		return ret;
-	}
+static int detect_i2c(struct display_info_t const *dev)
+{
+	return (0 == i2c_set_bus_num(dev->bus)) &&
+			(0 == i2c_probe(dev->addr));
+}
 
-	imx_enable_hdmi_phy();
+static void enable_fwadapt_7wvga(struct display_info_t const *dev)
+{
+	imx_iomux_v3_setup_multiple_pads(
+		fwadapt_7wvga_pads,
+		ARRAY_SIZE(fwadapt_7wvga_pads));
 
-	return ret;
+	gpio_direction_output(IMX_GPIO_NR(2, 10), 1);
+	gpio_direction_output(IMX_GPIO_NR(2, 11), 1);
 }
 
+struct display_info_t const displays[] = {{
+	.bus	= -1,
+	.addr	= 0,
+	.pixfmt	= IPU_PIX_FMT_RGB24,
+	.detect	= detect_hdmi,
+	.enable	= do_enable_hdmi,
+	.mode	= {
+		.name           = "HDMI",
+		.refresh        = 60,
+		.xres           = 1024,
+		.yres           = 768,
+		.pixclock       = 15385,
+		.left_margin    = 220,
+		.right_margin   = 40,
+		.upper_margin   = 21,
+		.lower_margin   = 7,
+		.hsync_len      = 60,
+		.vsync_len      = 10,
+		.sync           = FB_SYNC_EXT,
+		.vmode          = FB_VMODE_NONINTERLACED
+} }, {
+	.bus	= 1,
+	.addr	= 0x10,
+	.pixfmt	= IPU_PIX_FMT_RGB666,
+	.detect	= detect_i2c,
+	.enable	= enable_fwadapt_7wvga,
+	.mode	= {
+		.name           = "FWBADAPT-LCD-F07A-0102",
+		.refresh        = 60,
+		.xres           = 800,
+		.yres           = 480,
+		.pixclock       = 33260,
+		.left_margin    = 128,
+		.right_margin   = 128,
+		.upper_margin   = 22,
+		.lower_margin   = 22,
+		.hsync_len      = 1,
+		.vsync_len      = 1,
+		.sync           = 0,
+		.vmode          = FB_VMODE_NONINTERLACED
+} } };
+size_t display_count = ARRAY_SIZE(displays);
+
 static void setup_display(void)
 {
 	struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
+	struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
 	int reg;
 
 	enable_ipu_clock();
@@ -254,6 +343,28 @@  static void setup_display(void)
 	reg |= (CHSCCDR_CLK_SEL_LDB_DI0
 		<< MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_OFFSET);
 	writel(reg, &mxc_ccm->chsccdr);
+
+	reg = IOMUXC_GPR2_BGREF_RRMODE_EXTERNAL_RES
+	     | IOMUXC_GPR2_DI1_VS_POLARITY_ACTIVE_LOW
+	     | IOMUXC_GPR2_DI0_VS_POLARITY_ACTIVE_LOW
+	     | IOMUXC_GPR2_BIT_MAPPING_CH1_SPWG
+	     | IOMUXC_GPR2_DATA_WIDTH_CH1_18BIT
+	     | IOMUXC_GPR2_BIT_MAPPING_CH0_SPWG
+	     | IOMUXC_GPR2_DATA_WIDTH_CH0_18BIT
+	     | IOMUXC_GPR2_LVDS_CH0_MODE_DISABLED
+	     | IOMUXC_GPR2_LVDS_CH1_MODE_ENABLED_DI0;
+	writel(reg, &iomux->gpr[2]);
+
+	reg = readl(&iomux->gpr[3]);
+	reg = (reg & ~(IOMUXC_GPR3_LVDS1_MUX_CTL_MASK
+			| IOMUXC_GPR3_HDMI_MUX_CTL_MASK))
+	    | (IOMUXC_GPR3_MUX_SRC_IPU1_DI0
+	       << IOMUXC_GPR3_LVDS1_MUX_CTL_OFFSET);
+	writel(reg, &iomux->gpr[3]);
+
+	/* Disable LCD backlight */
+	imx_iomux_v3_setup_pad(MX6_PAD_DI0_PIN4__GPIO4_IO20);
+	gpio_direction_input(IMX_GPIO_NR(4, 20));
 }
 #endif /* CONFIG_VIDEO_IPUV3 */
 
@@ -305,6 +416,8 @@  int board_init(void)
 	/* address of boot parameters */
 	gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
 
+	setup_i2c(1, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c2_pad_info);
+
 	return 0;
 }
 
diff --git a/include/configs/wandboard.h b/include/configs/wandboard.h
index a49544f..ac78ede 100644
--- a/include/configs/wandboard.h
+++ b/include/configs/wandboard.h
@@ -58,6 +58,12 @@ 
 #define CONFIG_LOADADDR			0x12000000
 #define CONFIG_SYS_TEXT_BASE		0x17800000
 
+/* I2C Configs */
+#define CONFIG_CMD_I2C
+#define CONFIG_SYS_I2C
+#define CONFIG_SYS_I2C_MXC
+#define CONFIG_SYS_I2C_SPEED		100000
+
 /* MMC Configuration */
 #define CONFIG_FSL_ESDHC
 #define CONFIG_FSL_USDHC
@@ -115,7 +121,9 @@ 
 #define CONFIG_VIDEO_LOGO
 #define CONFIG_VIDEO_BMP_LOGO
 #define CONFIG_IPUV3_CLK 260000000
+#define CONFIG_CMD_HDMIDETECT
 #define CONFIG_IMX_HDMI
+#define CONFIG_IMX_VIDEO_SKIP
 
 #if defined(CONFIG_MX6DL) || defined(CONFIG_MX6S)
 #define CONFIG_DEFAULT_FDT_FILE		"imx6dl-wandboard.dtb"
@@ -152,7 +160,33 @@ 
 			"fi; "	\
 		"fi\0" \
 	"mmcargs=setenv bootargs console=${console},${baudrate} " \
-		"root=${mmcroot}\0" \
+		"root=${mmcroot}; run videoargs\0" \
+	"videoargs=" \
+		"setenv nextcon 0; " \
+		"if hdmidet; then " \
+			"setenv bootargs ${bootargs} " \
+				"video=mxcfb${nextcon}:dev=hdmi,1280x720M@60," \
+					"if=RGB24; " \
+			"setenv fbmen fbmem=28M; " \
+			"setexpr nextcon ${nextcon} + 1; " \
+		"else " \
+			"echo - no HDMI monitor;" \
+		"fi; " \
+		"i2c dev 1; " \
+		"if i2c probe 0x10; then " \
+			"setenv bootargs ${bootargs} " \
+				"video=mxcfb${nextcon}:dev=lcd,800x480@60," \
+					"if=RGB666; " \
+			"if test 0 -eq ${nextcon}; then " \
+				"setenv fbmem fbmem=10M; " \
+			"else " \
+				"setenv fbmem ${fbmem},10M; " \
+			"fi; " \
+			"setexpr nextcon ${nextcon} + 1; " \
+		"else " \
+			"echo '- no FWBADAPT-7WVGA-LCD-F07A-0102 display';" \
+		"fi; " \
+		"setenv bootargs ${bootargs} ${fbmem}\0" \
 	"loadbootscript=" \
 		"fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${script};\0" \
 	"bootscript=echo Running bootscript from mmc ...; " \