]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
ENGR00174106-1 - EPDC fb: Support EPDC on MX 6DL/S
authorDanny Nold <dannynold@freescale.com>
Thu, 9 Feb 2012 03:28:42 +0000 (21:28 -0600)
committerLothar Waßmann <LW@KARO-electronics.de>
Fri, 24 May 2013 06:34:03 +0000 (08:34 +0200)
- Added EPDC and EPD PMIC (Maxim 17135) to MX6Q ARM2 board file
- Added EPDC-related IOMUX and GPIO settings
- Added EPDC clock configuration settings to clock file
- Updated config files with EPDC and Maxim 17135 config entries

Signed-off-by: Danny Nold <dannynold@freescale.com>
arch/arm/configs/imx6_defconfig
arch/arm/configs/imx6_updater_defconfig
arch/arm/mach-mx6/Kconfig
arch/arm/mach-mx6/board-mx6dl_arm2.h
arch/arm/mach-mx6/board-mx6q_arm2.c
arch/arm/mach-mx6/clock.c
arch/arm/plat-mxc/devices/platform-imx-epdc-fb.c

index 8f00d362cc15e986beb3055f6fff50dcf2f2b337..5d9d768b34c251f0c3535460a2ae358d930c341f 100644 (file)
@@ -275,6 +275,7 @@ CONFIG_IMX_HAVE_PLATFORM_IMX_VIIM=y
 CONFIG_IMX_HAVE_PLATFORM_PERFMON=y
 CONFIG_IMX_HAVE_PLATFORM_LDB=y
 CONFIG_IMX_HAVE_PLATFORM_IMX_PXP=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_EPDC=y
 CONFIG_IMX_HAVE_PLATFORM_IMX_SPDIF=y
 CONFIG_IMX_HAVE_PLATFORM_VIV_GPU=y
 CONFIG_IMX_HAVE_PLATFORM_MXC_HDMI=y
@@ -1443,7 +1444,7 @@ CONFIG_MFD_PFUZE=y
 # CONFIG_EZX_PCAP is not set
 # CONFIG_MFD_WL1273_CORE is not set
 # CONFIG_MFD_TPS65910 is not set
-# CONFIG_MFD_MAX17135 is not set
+CONFIG_MFD_MAX17135=y
 CONFIG_MFD_MXC_HDMI=y
 CONFIG_REGULATOR=y
 # CONFIG_REGULATOR_DEBUG is not set
@@ -1466,6 +1467,7 @@ CONFIG_REGULATOR_PFUZE100=y
 # CONFIG_REGULATOR_AD5398 is not set
 CONFIG_REGULATOR_ANATOP=y
 # CONFIG_REGULATOR_TPS6524X is not set
+CONFIG_REGULATOR_MAX17135=y
 CONFIG_MEDIA_SUPPORT=y
 
 #
index d0d8e7607563eb09d5d06089dbac07fd69a8726f..b03276bf28ba9703db2a8dad721c5377b7067a06 100644 (file)
@@ -1217,7 +1217,7 @@ CONFIG_MFD_PFUZE=y
 # CONFIG_EZX_PCAP is not set
 # CONFIG_MFD_TPS6586X is not set
 # CONFIG_MFD_WL1273_CORE is not set
-# CONFIG_MFD_MAX17135 is not set
+CONFIG_MFD_MAX17135=y
 CONFIG_MFD_MXC_HDMI=y
 CONFIG_REGULATOR=y
 # CONFIG_REGULATOR_DEBUG is not set
@@ -1238,8 +1238,9 @@ CONFIG_REGULATOR_PFUZE100=y
 # CONFIG_REGULATOR_TPS6507X is not set
 # CONFIG_REGULATOR_ISL6271A is not set
 # CONFIG_REGULATOR_AD5398 is not set
-# CONFIG_REGULATOR_TPS6524X is not set
 CONFIG_REGULATOR_ANATOP=y
+# CONFIG_REGULATOR_TPS6524X is not set
+CONFIG_REGULATOR_MAX17135=y
 CONFIG_MEDIA_SUPPORT=y
 
 #
index aa081b6ce0c1cbbc58ef7d20ee3994cb9a3c8806..3c083feb1742a937cc5502e1a081392062842eec 100644 (file)
@@ -57,6 +57,7 @@ config MACH_MX6Q_ARM2
        select IMX_HAVE_PLATFORM_IMX_MIPI_CSI2
        select IMX_HAVE_PLATFORM_PERFMON
        select IMX_HAVE_PLATFORM_MXC_MLB
+       select IMX_HAVE_PLATFORM_IMX_EPDC
        select IMX_HAVE_PLATFORM_IMX_PXP
        help
          Include support for i.MX 6Quad Armadillo2 platform. This includes specific
index 9261a28fb6d14008f15950db7c1cb5c23958e24c..4528da53694a23ab16305c4e9f97a06c9e182a49 100644 (file)
@@ -187,6 +187,11 @@ static iomux_v3_cfg_t mx6dl_arm2_pads[] = {
        MX6DL_PAD_GPIO_3__MLB_MLBCLK,
        MX6DL_PAD_GPIO_6__MLB_MLBSIG,
        MX6DL_PAD_GPIO_2__MLB_MLBDAT,
+
+       /* EPDC pins */
+       MX6DL_PAD_EIM_A17__GPIO_2_21,
+       MX6DL_PAD_EIM_D17__GPIO_3_17,
+       MX6DL_PAD_EIM_A18__GPIO_2_20,
 };
 
 static iomux_v3_cfg_t mx6dl_arm2_i2c3_pads[] = {
index 4fa511c8cdf2a3716708973b332a7e9c9e33df6c..71161e82185f846e0aeb4909f7c95e91730ed392 100644 (file)
@@ -50,6 +50,7 @@
 #include <linux/regulator/consumer.h>
 #include <linux/regulator/machine.h>
 #include <linux/regulator/fixed.h>
+#include <linux/mfd/max17135.h>
 
 #include <mach/common.h>
 #include <mach/hardware.h>
 #define MX6_ARM2_CAN1_EN               IMX_GPIO_NR(7, 13)
 #define MX6_ARM2_MAX7310_1_BASE_ADDR   IMX_GPIO_NR(8, 0)
 #define MX6_ARM2_MAX7310_2_BASE_ADDR   IMX_GPIO_NR(8, 8)
+#define MX6DL_ARM2_EPDC_SDDO_0         IMX_GPIO_NR(2, 22)
+#define MX6DL_ARM2_EPDC_SDDO_1         IMX_GPIO_NR(3, 10)
+#define MX6DL_ARM2_EPDC_SDDO_2         IMX_GPIO_NR(3, 12)
+#define MX6DL_ARM2_EPDC_SDDO_3         IMX_GPIO_NR(3, 11)
+#define MX6DL_ARM2_EPDC_SDDO_4         IMX_GPIO_NR(2, 27)
+#define MX6DL_ARM2_EPDC_SDDO_5         IMX_GPIO_NR(2, 30)
+#define MX6DL_ARM2_EPDC_SDDO_6         IMX_GPIO_NR(2, 23)
+#define MX6DL_ARM2_EPDC_SDDO_7         IMX_GPIO_NR(2, 26)
+#define MX6DL_ARM2_EPDC_SDDO_8         IMX_GPIO_NR(2, 24)
+#define MX6DL_ARM2_EPDC_SDDO_9         IMX_GPIO_NR(3, 15)
+#define MX6DL_ARM2_EPDC_SDDO_10                IMX_GPIO_NR(3, 16)
+#define MX6DL_ARM2_EPDC_SDDO_11                IMX_GPIO_NR(3, 23)
+#define MX6DL_ARM2_EPDC_SDDO_12                IMX_GPIO_NR(3, 19)
+#define MX6DL_ARM2_EPDC_SDDO_13                IMX_GPIO_NR(3, 13)
+#define MX6DL_ARM2_EPDC_SDDO_14                IMX_GPIO_NR(3, 14)
+#define MX6DL_ARM2_EPDC_SDDO_15                IMX_GPIO_NR(5, 2)
+#define MX6DL_ARM2_EPDC_GDCLK          IMX_GPIO_NR(2, 17)
+#define MX6DL_ARM2_EPDC_GDSP           IMX_GPIO_NR(2, 16)
+#define MX6DL_ARM2_EPDC_GDOE           IMX_GPIO_NR(6, 6)
+#define MX6DL_ARM2_EPDC_GDRL           IMX_GPIO_NR(5, 4)
+#define MX6DL_ARM2_EPDC_SDCLK          IMX_GPIO_NR(3, 31)
+#define MX6DL_ARM2_EPDC_SDOEZ          IMX_GPIO_NR(3, 30)
+#define MX6DL_ARM2_EPDC_SDOED          IMX_GPIO_NR(3, 26)
+#define MX6DL_ARM2_EPDC_SDOE           IMX_GPIO_NR(3, 27)
+#define MX6DL_ARM2_EPDC_SDLE           IMX_GPIO_NR(3, 1)
+#define MX6DL_ARM2_EPDC_SDCLKN         IMX_GPIO_NR(3, 0)
+#define MX6DL_ARM2_EPDC_SDSHR          IMX_GPIO_NR(2, 29)
+#define MX6DL_ARM2_EPDC_PWRCOM         IMX_GPIO_NR(2, 28)
+#define MX6DL_ARM2_EPDC_PWRSTAT                IMX_GPIO_NR(2, 21)
+#define MX6DL_ARM2_EPDC_PWRCTRL0       IMX_GPIO_NR(2, 20)
+#define MX6DL_ARM2_EPDC_PWRCTRL1       IMX_GPIO_NR(2, 19)
+#define MX6DL_ARM2_EPDC_PWRCTRL2       IMX_GPIO_NR(2, 18)
+#define MX6DL_ARM2_EPDC_PWRCTRL3       IMX_GPIO_NR(3, 28)
+#define MX6DL_ARM2_EPDC_BDR0           IMX_GPIO_NR(3, 2)
+#define MX6DL_ARM2_EPDC_BDR1           IMX_GPIO_NR(3, 3)
+#define MX6DL_ARM2_EPDC_SDCE0          IMX_GPIO_NR(3, 4)
+#define MX6DL_ARM2_EPDC_SDCE1          IMX_GPIO_NR(3, 5)
+#define MX6DL_ARM2_EPDC_SDCE2          IMX_GPIO_NR(3, 6)
+#define MX6DL_ARM2_EPDC_SDCE3          IMX_GPIO_NR(3, 7)
+#define MX6DL_ARM2_EPDC_SDCE4          IMX_GPIO_NR(3, 8)
+#define MX6DL_ARM2_EPDC_SDCE5          IMX_GPIO_NR(3, 9)
+#define MX6DL_ARM2_EPDC_PMIC_WAKE      IMX_GPIO_NR(2, 31)
+#define MX6DL_ARM2_EPDC_PMIC_INT       IMX_GPIO_NR(2, 25)
+#define MX6DL_ARM2_EPDC_VCOM           IMX_GPIO_NR(3, 17)
 
 #define MX6_ARM2_IO_EXP_GPIO1(x)       (MX6_ARM2_MAX7310_1_BASE_ADDR + (x))
 #define MX6_ARM2_IO_EXP_GPIO2(x)       (MX6_ARM2_MAX7310_2_BASE_ADDR + (x))
@@ -117,6 +162,7 @@ extern struct regulator *(*get_cpu_regulator)(void);
 extern void (*put_cpu_regulator)(void);
 extern char *gp_reg_id;
 extern void mx6_cpu_regulator_init(void);
+static int max17135_regulator_init(struct max17135 *max17135);
 
 enum sd_pad_mode {
        SD_PAD_MODE_LOW_SPEED,
@@ -597,6 +643,175 @@ static struct fsl_mxc_camera_platform_data ov5640_mipi_data = {
        .io_init        = mx6_mipi_sensor_io_init,
 };
 
+#define mV_to_uV(mV) (mV * 1000)
+#define uV_to_mV(uV) (uV / 1000)
+#define V_to_uV(V) (mV_to_uV(V * 1000))
+#define uV_to_V(uV) (uV_to_mV(uV) / 1000)
+
+static struct regulator_consumer_supply display_consumers[] = {
+       {
+               /* MAX17135 */
+               .supply = "DISPLAY",
+       },
+};
+
+static struct regulator_consumer_supply vcom_consumers[] = {
+       {
+               /* MAX17135 */
+               .supply = "VCOM",
+       },
+};
+
+static struct regulator_consumer_supply v3p3_consumers[] = {
+       {
+               /* MAX17135 */
+               .supply = "V3P3",
+       },
+};
+
+static struct regulator_init_data max17135_init_data[] = {
+       {
+               .constraints = {
+                       .name = "DISPLAY",
+                       .valid_ops_mask =  REGULATOR_CHANGE_STATUS,
+               },
+               .num_consumer_supplies = ARRAY_SIZE(display_consumers),
+               .consumer_supplies = display_consumers,
+       }, {
+               .constraints = {
+                       .name = "GVDD",
+                       .min_uV = V_to_uV(20),
+                       .max_uV = V_to_uV(20),
+               },
+       }, {
+               .constraints = {
+                       .name = "GVEE",
+                       .min_uV = V_to_uV(-22),
+                       .max_uV = V_to_uV(-22),
+               },
+       }, {
+               .constraints = {
+                       .name = "HVINN",
+                       .min_uV = V_to_uV(-22),
+                       .max_uV = V_to_uV(-22),
+               },
+       }, {
+               .constraints = {
+                       .name = "HVINP",
+                       .min_uV = V_to_uV(20),
+                       .max_uV = V_to_uV(20),
+               },
+       }, {
+               .constraints = {
+                       .name = "VCOM",
+                       .min_uV = mV_to_uV(-4325),
+                       .max_uV = mV_to_uV(-500),
+                       .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+                       REGULATOR_CHANGE_STATUS,
+               },
+               .num_consumer_supplies = ARRAY_SIZE(vcom_consumers),
+               .consumer_supplies = vcom_consumers,
+       }, {
+               .constraints = {
+                       .name = "VNEG",
+                       .min_uV = V_to_uV(-15),
+                       .max_uV = V_to_uV(-15),
+               },
+       }, {
+               .constraints = {
+                       .name = "VPOS",
+                       .min_uV = V_to_uV(15),
+                       .max_uV = V_to_uV(15),
+               },
+       }, {
+               .constraints = {
+                       .name = "V3P3",
+                       .valid_ops_mask =  REGULATOR_CHANGE_STATUS,
+               },
+               .num_consumer_supplies = ARRAY_SIZE(v3p3_consumers),
+               .consumer_supplies = v3p3_consumers,
+       },
+};
+
+static struct platform_device max17135_sensor_device = {
+       .name = "max17135_sensor",
+       .id = 0,
+};
+
+static struct max17135_platform_data max17135_pdata __initdata = {
+       .vneg_pwrup = 1,
+       .gvee_pwrup = 1,
+       .vpos_pwrup = 2,
+       .gvdd_pwrup = 1,
+       .gvdd_pwrdn = 1,
+       .vpos_pwrdn = 2,
+       .gvee_pwrdn = 1,
+       .vneg_pwrdn = 1,
+       .gpio_pmic_pwrgood = MX6DL_ARM2_EPDC_PWRSTAT,
+       .gpio_pmic_vcom_ctrl = MX6DL_ARM2_EPDC_VCOM,
+       .gpio_pmic_wakeup = MX6DL_ARM2_EPDC_PMIC_WAKE,
+       .gpio_pmic_v3p3 = MX6DL_ARM2_EPDC_PWRCTRL0,
+       .gpio_pmic_intr = MX6DL_ARM2_EPDC_PMIC_INT,
+       .regulator_init = max17135_init_data,
+       .init = max17135_regulator_init,
+};
+
+static int max17135_regulator_init(struct max17135 *max17135)
+{
+       struct max17135_platform_data *pdata = &max17135_pdata;
+       int i, ret;
+
+       max17135->gvee_pwrup = pdata->gvee_pwrup;
+       max17135->vneg_pwrup = pdata->vneg_pwrup;
+       max17135->vpos_pwrup = pdata->vpos_pwrup;
+       max17135->gvdd_pwrup = pdata->gvdd_pwrup;
+       max17135->gvdd_pwrdn = pdata->gvdd_pwrdn;
+       max17135->vpos_pwrdn = pdata->vpos_pwrdn;
+       max17135->vneg_pwrdn = pdata->vneg_pwrdn;
+       max17135->gvee_pwrdn = pdata->gvee_pwrdn;
+
+       max17135->max_wait = pdata->vpos_pwrup + pdata->vneg_pwrup +
+               pdata->gvdd_pwrup + pdata->gvee_pwrup;
+
+       max17135->gpio_pmic_pwrgood = pdata->gpio_pmic_pwrgood;
+       max17135->gpio_pmic_vcom_ctrl = pdata->gpio_pmic_vcom_ctrl;
+       max17135->gpio_pmic_wakeup = pdata->gpio_pmic_wakeup;
+       max17135->gpio_pmic_v3p3 = pdata->gpio_pmic_v3p3;
+       max17135->gpio_pmic_intr = pdata->gpio_pmic_intr;
+
+       gpio_request(max17135->gpio_pmic_wakeup, "epdc-pmic-wake");
+       gpio_direction_output(max17135->gpio_pmic_wakeup, 0);
+
+       gpio_request(max17135->gpio_pmic_vcom_ctrl, "epdc-vcom");
+       gpio_direction_output(max17135->gpio_pmic_vcom_ctrl, 0);
+
+       gpio_request(max17135->gpio_pmic_v3p3, "epdc-v3p3");
+       gpio_direction_output(max17135->gpio_pmic_v3p3, 0);
+
+       gpio_request(max17135->gpio_pmic_intr, "epdc-pmic-int");
+       gpio_direction_input(max17135->gpio_pmic_intr);
+
+       gpio_request(max17135->gpio_pmic_pwrgood, "epdc-pwrstat");
+       gpio_direction_input(max17135->gpio_pmic_pwrgood);
+
+       max17135->vcom_setup = false;
+       max17135->init_done = false;
+
+       for (i = 0; i < MAX17135_NUM_REGULATORS; i++) {
+               ret = max17135_register_regulator(max17135, i,
+                       &pdata->regulator_init[i]);
+               if (ret != 0) {
+                       printk(KERN_ERR"max17135 regulator init failed: %d\n",
+                               ret);
+                       return ret;
+               }
+       }
+
+       regulator_has_full_constraints();
+
+       return 0;
+}
+
 static struct i2c_board_info mxc_i2c0_board_info[] __initdata = {
        {
                I2C_BOARD_INFO("cs42888", 0x48),
@@ -623,6 +838,9 @@ static struct imxi2c_platform_data mx6_arm2_i2c2_data = {
 
 static struct i2c_board_info mxc_i2c2_board_info[] __initdata = {
        {
+               I2C_BOARD_INFO("max17135", 0x48),
+               .platform_data = &max17135_pdata,
+       }, {
                I2C_BOARD_INFO("max7310", 0x1F),
                .platform_data = &max7310_platdata,
        }, {
@@ -653,6 +871,309 @@ static struct i2c_board_info mxc_i2c1_board_info[] __initdata = {
        },
 };
 
+static int epdc_get_pins(void)
+{
+       int ret = 0;
+
+       /* Claim GPIOs for EPDC pins - used during power up/down */
+       ret |= gpio_request(MX6DL_ARM2_EPDC_SDDO_0, "epdc_d0");
+       ret |= gpio_request(MX6DL_ARM2_EPDC_SDDO_1, "epdc_d1");
+       ret |= gpio_request(MX6DL_ARM2_EPDC_SDDO_2, "epdc_d2");
+       ret |= gpio_request(MX6DL_ARM2_EPDC_SDDO_3, "epdc_d3");
+       ret |= gpio_request(MX6DL_ARM2_EPDC_SDDO_4, "epdc_d4");
+       ret |= gpio_request(MX6DL_ARM2_EPDC_SDDO_5, "epdc_d5");
+       ret |= gpio_request(MX6DL_ARM2_EPDC_SDDO_6, "epdc_d6");
+       ret |= gpio_request(MX6DL_ARM2_EPDC_SDDO_7, "epdc_d7");
+       ret |= gpio_request(MX6DL_ARM2_EPDC_GDCLK, "epdc_gdclk");
+       ret |= gpio_request(MX6DL_ARM2_EPDC_GDSP, "epdc_gdsp");
+       ret |= gpio_request(MX6DL_ARM2_EPDC_GDOE, "epdc_gdoe");
+       ret |= gpio_request(MX6DL_ARM2_EPDC_GDRL, "epdc_gdrl");
+       ret |= gpio_request(MX6DL_ARM2_EPDC_SDCLK, "epdc_sdclk");
+       ret |= gpio_request(MX6DL_ARM2_EPDC_SDOE, "epdc_sdoe");
+       ret |= gpio_request(MX6DL_ARM2_EPDC_SDLE, "epdc_sdle");
+       ret |= gpio_request(MX6DL_ARM2_EPDC_SDSHR, "epdc_sdshr");
+       ret |= gpio_request(MX6DL_ARM2_EPDC_BDR0, "epdc_bdr0");
+       ret |= gpio_request(MX6DL_ARM2_EPDC_SDCE0, "epdc_sdce0");
+       ret |= gpio_request(MX6DL_ARM2_EPDC_SDCE1, "epdc_sdce1");
+       ret |= gpio_request(MX6DL_ARM2_EPDC_SDCE2, "epdc_sdce2");
+
+       return ret;
+}
+
+static void epdc_put_pins(void)
+{
+       gpio_free(MX6DL_ARM2_EPDC_SDDO_0);
+       gpio_free(MX6DL_ARM2_EPDC_SDDO_1);
+       gpio_free(MX6DL_ARM2_EPDC_SDDO_2);
+       gpio_free(MX6DL_ARM2_EPDC_SDDO_3);
+       gpio_free(MX6DL_ARM2_EPDC_SDDO_4);
+       gpio_free(MX6DL_ARM2_EPDC_SDDO_5);
+       gpio_free(MX6DL_ARM2_EPDC_SDDO_6);
+       gpio_free(MX6DL_ARM2_EPDC_SDDO_7);
+       gpio_free(MX6DL_ARM2_EPDC_GDCLK);
+       gpio_free(MX6DL_ARM2_EPDC_GDSP);
+       gpio_free(MX6DL_ARM2_EPDC_GDOE);
+       gpio_free(MX6DL_ARM2_EPDC_GDRL);
+       gpio_free(MX6DL_ARM2_EPDC_SDCLK);
+       gpio_free(MX6DL_ARM2_EPDC_SDOE);
+       gpio_free(MX6DL_ARM2_EPDC_SDLE);
+       gpio_free(MX6DL_ARM2_EPDC_SDSHR);
+       gpio_free(MX6DL_ARM2_EPDC_BDR0);
+       gpio_free(MX6DL_ARM2_EPDC_SDCE0);
+       gpio_free(MX6DL_ARM2_EPDC_SDCE1);
+       gpio_free(MX6DL_ARM2_EPDC_SDCE2);
+}
+
+static iomux_v3_cfg_t mx6dl_epdc_pads_enabled[] = {
+       MX6DL_PAD_EIM_A16__EPDC_SDDO_0,
+       MX6DL_PAD_EIM_DA10__EPDC_SDDO_1,
+       MX6DL_PAD_EIM_DA12__EPDC_SDDO_2,
+       MX6DL_PAD_EIM_DA11__EPDC_SDDO_3,
+       MX6DL_PAD_EIM_LBA__EPDC_SDDO_4,
+       MX6DL_PAD_EIM_EB2__EPDC_SDDO_5,
+       MX6DL_PAD_EIM_CS0__EPDC_SDDO_6,
+       MX6DL_PAD_EIM_RW__EPDC_SDDO_7,
+       MX6DL_PAD_EIM_CS1__EPDC_SDDO_8,
+       MX6DL_PAD_EIM_DA15__EPDC_SDDO_9,
+       MX6DL_PAD_EIM_D16__EPDC_SDDO_10,
+       MX6DL_PAD_EIM_D23__EPDC_SDDO_11,
+       MX6DL_PAD_EIM_D19__EPDC_SDDO_12,
+       MX6DL_PAD_EIM_DA13__EPDC_SDDO_13,
+       MX6DL_PAD_EIM_DA14__EPDC_SDDO_14,
+       MX6DL_PAD_EIM_A25__EPDC_SDDO_15,
+       MX6DL_PAD_EIM_A21__EPDC_GDCLK,
+       MX6DL_PAD_EIM_A22__EPDC_GDSP,
+       MX6DL_PAD_EIM_A23__EPDC_GDOE,
+       MX6DL_PAD_EIM_A24__EPDC_GDRL,
+       MX6DL_PAD_EIM_D31__EPDC_SDCLK,
+       MX6DL_PAD_EIM_D27__EPDC_SDOE,
+       MX6DL_PAD_EIM_DA1__EPDC_SDLE,
+       MX6DL_PAD_EIM_EB1__EPDC_SDSHR,
+       MX6DL_PAD_EIM_DA2__EPDC_BDR_0,
+       MX6DL_PAD_EIM_DA4__EPDC_SDCE_0,
+       MX6DL_PAD_EIM_DA5__EPDC_SDCE_1,
+       MX6DL_PAD_EIM_DA6__EPDC_SDCE_2,
+};
+
+static iomux_v3_cfg_t mx6dl_epdc_pads_disabled[] = {
+       MX6DL_PAD_EIM_A16__GPIO_2_22,
+       MX6DL_PAD_EIM_DA10__GPIO_3_10,
+       MX6DL_PAD_EIM_DA12__GPIO_3_12,
+       MX6DL_PAD_EIM_DA11__GPIO_3_11,
+       MX6DL_PAD_EIM_LBA__GPIO_2_27,
+       MX6DL_PAD_EIM_EB2__GPIO_2_30,
+       MX6DL_PAD_EIM_CS0__GPIO_2_23,
+       MX6DL_PAD_EIM_RW__GPIO_2_26,
+       MX6DL_PAD_EIM_CS1__GPIO_2_24,
+       MX6DL_PAD_EIM_DA15__GPIO_3_15,
+       MX6DL_PAD_EIM_D16__GPIO_3_16,
+       MX6DL_PAD_EIM_D23__GPIO_3_23,
+       MX6DL_PAD_EIM_D19__GPIO_3_19,
+       MX6DL_PAD_EIM_DA13__GPIO_3_13,
+       MX6DL_PAD_EIM_DA14__GPIO_3_14,
+       MX6DL_PAD_EIM_A25__GPIO_5_2,
+       MX6DL_PAD_EIM_A21__GPIO_2_17,
+       MX6DL_PAD_EIM_A22__GPIO_2_16,
+       MX6DL_PAD_EIM_A23__GPIO_6_6,
+       MX6DL_PAD_EIM_A24__GPIO_5_4,
+       MX6DL_PAD_EIM_D31__GPIO_3_31,
+       MX6DL_PAD_EIM_D27__GPIO_3_27,
+       MX6DL_PAD_EIM_DA1__GPIO_3_1,
+       MX6DL_PAD_EIM_EB1__GPIO_2_29,
+       MX6DL_PAD_EIM_DA2__GPIO_3_2,
+       MX6DL_PAD_EIM_DA4__GPIO_3_4,
+       MX6DL_PAD_EIM_DA5__GPIO_3_5,
+       MX6DL_PAD_EIM_DA6__GPIO_3_6,
+};
+static void epdc_enable_pins(void)
+{
+       /* Configure MUX settings to enable EPDC use */
+       mxc_iomux_v3_setup_multiple_pads(mx6dl_epdc_pads_enabled, \
+                               ARRAY_SIZE(mx6dl_epdc_pads_enabled));
+
+       gpio_direction_input(MX6DL_ARM2_EPDC_SDDO_0);
+       gpio_direction_input(MX6DL_ARM2_EPDC_SDDO_1);
+       gpio_direction_input(MX6DL_ARM2_EPDC_SDDO_2);
+       gpio_direction_input(MX6DL_ARM2_EPDC_SDDO_3);
+       gpio_direction_input(MX6DL_ARM2_EPDC_SDDO_4);
+       gpio_direction_input(MX6DL_ARM2_EPDC_SDDO_5);
+       gpio_direction_input(MX6DL_ARM2_EPDC_SDDO_6);
+       gpio_direction_input(MX6DL_ARM2_EPDC_SDDO_7);
+       gpio_direction_input(MX6DL_ARM2_EPDC_GDCLK);
+       gpio_direction_input(MX6DL_ARM2_EPDC_GDSP);
+       gpio_direction_input(MX6DL_ARM2_EPDC_GDOE);
+       gpio_direction_input(MX6DL_ARM2_EPDC_GDRL);
+       gpio_direction_input(MX6DL_ARM2_EPDC_SDCLK);
+       gpio_direction_input(MX6DL_ARM2_EPDC_SDOE);
+       gpio_direction_input(MX6DL_ARM2_EPDC_SDLE);
+       gpio_direction_input(MX6DL_ARM2_EPDC_SDSHR);
+       gpio_direction_input(MX6DL_ARM2_EPDC_BDR0);
+       gpio_direction_input(MX6DL_ARM2_EPDC_SDCE0);
+       gpio_direction_input(MX6DL_ARM2_EPDC_SDCE1);
+       gpio_direction_input(MX6DL_ARM2_EPDC_SDCE2);
+}
+
+static void epdc_disable_pins(void)
+{
+       /* Configure MUX settings for EPDC pins to
+        * GPIO and drive to 0. */
+       mxc_iomux_v3_setup_multiple_pads(mx6dl_epdc_pads_disabled, \
+                               ARRAY_SIZE(mx6dl_epdc_pads_disabled));
+
+       gpio_direction_output(MX6DL_ARM2_EPDC_SDDO_0, 0);
+       gpio_direction_output(MX6DL_ARM2_EPDC_SDDO_1, 0);
+       gpio_direction_output(MX6DL_ARM2_EPDC_SDDO_2, 0);
+       gpio_direction_output(MX6DL_ARM2_EPDC_SDDO_3, 0);
+       gpio_direction_output(MX6DL_ARM2_EPDC_SDDO_4, 0);
+       gpio_direction_output(MX6DL_ARM2_EPDC_SDDO_5, 0);
+       gpio_direction_output(MX6DL_ARM2_EPDC_SDDO_6, 0);
+       gpio_direction_output(MX6DL_ARM2_EPDC_SDDO_7, 0);
+       gpio_direction_output(MX6DL_ARM2_EPDC_GDCLK, 0);
+       gpio_direction_output(MX6DL_ARM2_EPDC_GDSP, 0);
+       gpio_direction_output(MX6DL_ARM2_EPDC_GDOE, 0);
+       gpio_direction_output(MX6DL_ARM2_EPDC_GDRL, 0);
+       gpio_direction_output(MX6DL_ARM2_EPDC_SDCLK, 0);
+       gpio_direction_output(MX6DL_ARM2_EPDC_SDOE, 0);
+       gpio_direction_output(MX6DL_ARM2_EPDC_SDLE, 0);
+       gpio_direction_output(MX6DL_ARM2_EPDC_SDSHR, 0);
+       gpio_direction_output(MX6DL_ARM2_EPDC_BDR0, 0);
+       gpio_direction_output(MX6DL_ARM2_EPDC_SDCE0, 0);
+       gpio_direction_output(MX6DL_ARM2_EPDC_SDCE1, 0);
+       gpio_direction_output(MX6DL_ARM2_EPDC_SDCE2, 0);
+}
+
+static struct fb_videomode e60_v110_mode = {
+       .name = "E60_V110",
+       .refresh = 50,
+       .xres = 800,
+       .yres = 600,
+       .pixclock = 18604700,
+       .left_margin = 8,
+       .right_margin = 178,
+       .upper_margin = 4,
+       .lower_margin = 10,
+       .hsync_len = 20,
+       .vsync_len = 4,
+       .sync = 0,
+       .vmode = FB_VMODE_NONINTERLACED,
+       .flag = 0,
+};
+static struct fb_videomode e60_v220_mode = {
+       .name = "E60_V220",
+       .refresh = 85,
+       .xres = 800,
+       .yres = 600,
+       .pixclock = 30000000,
+       .left_margin = 8,
+       .right_margin = 164,
+       .upper_margin = 4,
+       .lower_margin = 8,
+       .hsync_len = 4,
+       .vsync_len = 1,
+       .sync = 0,
+       .vmode = FB_VMODE_NONINTERLACED,
+       .flag = 0,
+       .refresh = 85,
+       .xres = 800,
+       .yres = 600,
+};
+static struct fb_videomode e060scm_mode = {
+       .name = "E060SCM",
+       .refresh = 85,
+       .xres = 800,
+       .yres = 600,
+       .pixclock = 26666667,
+       .left_margin = 8,
+       .right_margin = 100,
+       .upper_margin = 4,
+       .lower_margin = 8,
+       .hsync_len = 4,
+       .vsync_len = 1,
+       .sync = 0,
+       .vmode = FB_VMODE_NONINTERLACED,
+       .flag = 0,
+};
+static struct fb_videomode e97_v110_mode = {
+       .name = "E97_V110",
+       .refresh = 50,
+       .xres = 1200,
+       .yres = 825,
+       .pixclock = 32000000,
+       .left_margin = 12,
+       .right_margin = 128,
+       .upper_margin = 4,
+       .lower_margin = 10,
+       .hsync_len = 20,
+       .vsync_len = 4,
+       .sync = 0,
+       .vmode = FB_VMODE_NONINTERLACED,
+       .flag = 0,
+};
+
+static struct imx_epdc_fb_mode panel_modes[] = {
+       {
+               &e60_v110_mode,
+               4,      /* vscan_holdoff */
+               10,     /* sdoed_width */
+               20,     /* sdoed_delay */
+               10,     /* sdoez_width */
+               20,     /* sdoez_delay */
+               428,    /* gdclk_hp_offs */
+               20,     /* gdsp_offs */
+               0,      /* gdoe_offs */
+               1,      /* gdclk_offs */
+               1,      /* num_ce */
+       },
+       {
+               &e60_v220_mode,
+               4,      /* vscan_holdoff */
+               10,     /* sdoed_width */
+               20,     /* sdoed_delay */
+               10,     /* sdoez_width */
+               20,     /* sdoez_delay */
+               465,    /* gdclk_hp_offs */
+               20,     /* gdsp_offs */
+               0,      /* gdoe_offs */
+               9,      /* gdclk_offs */
+               1,      /* num_ce */
+       },
+       {
+               &e060scm_mode,
+               4,      /* vscan_holdoff */
+               10,     /* sdoed_width */
+               20,     /* sdoed_delay */
+               10,     /* sdoez_width */
+               20,     /* sdoez_delay */
+               419,    /* gdclk_hp_offs */
+               20,     /* gdsp_offs */
+               0,      /* gdoe_offs */
+               5,      /* gdclk_offs */
+               1,      /* num_ce */
+       },
+       {
+               &e97_v110_mode,
+               8,      /* vscan_holdoff */
+               10,     /* sdoed_width */
+               20,     /* sdoed_delay */
+               10,     /* sdoez_width */
+               20,     /* sdoez_delay */
+               632,    /* gdclk_hp_offs */
+               20,     /* gdsp_offs */
+               0,      /* gdoe_offs */
+               1,      /* gdclk_offs */
+               3,      /* num_ce */
+       }
+};
+
+static struct imx_epdc_fb_platform_data epdc_data = {
+       .epdc_mode = panel_modes,
+       .num_modes = ARRAY_SIZE(panel_modes),
+       .get_pins = epdc_get_pins,
+       .put_pins = epdc_put_pins,
+       .enable_pins = epdc_enable_pins,
+       .disable_pins = epdc_disable_pins,
+};
+
 static void imx6_arm2_usbotg_vbus(bool on)
 {
        if (on)
@@ -1564,6 +2085,8 @@ static void __init mx6_arm2_init(void)
        if (cpu_is_mx6dl()) {
                imx6dl_add_imx_pxp();
                imx6dl_add_imx_pxp_client();
+               mxc_register_device(&max17135_sensor_device, NULL);
+               imx6dl_add_imx_epdc(&epdc_data);
        }
 }
 
index e52dcab916cea462cfe6f3aebb1ab4dd08e17224..58dcbe103ae0891a4721360aacd355eef3961f8e 100644 (file)
@@ -99,6 +99,21 @@ static int cpu_op_nr;
 static unsigned long external_high_reference, external_low_reference;
 static unsigned long oscillator_reference, ckih2_reference;
 
+/* For MX 6DL/S, Video PLL may be used by synchronous display devices,
+ * such as HDMI or LVDS, and also by the EPDC.  If EPDC is in use,
+ * it must use the Video PLL to achieve the clock frequencies it needs.
+ * So if EPDC is in use, the "epdc" string should be added to kernel
+ * parameters, in order to set the EPDC parent clock to the Video PLL.
+ * This will have an impact on the behavior of HDMI and LVDS.
+ */
+static int epdc_use_video_pll;
+static int __init epdc_clk_setup(char *__unused)
+{
+       epdc_use_video_pll = 1;
+       return 1;
+}
+__setup("epdc", epdc_clk_setup);
+
 static void __calc_pre_post_dividers(u32 max_podf, u32 div, u32 *pre, u32 *post)
 {
        u32 min_pre, temp_pre, old_err, err;
@@ -781,7 +796,7 @@ static unsigned long  _clk_audio_video_get_rate(struct clk *clk)
        else
                pllbase = PLL5_VIDEO_BASE_ADDR;
 
-       if (rev >= IMX_CHIP_REVISION_1_1) {
+       if ((rev >= IMX_CHIP_REVISION_1_1) || cpu_is_mx6dl()) {
                test_div_sel = (__raw_readl(pllbase)
                        & ANADIG_PLL_AV_TEST_DIV_SEL_MASK)
                        >> ANADIG_PLL_AV_TEST_DIV_SEL_OFFSET;
@@ -823,7 +838,7 @@ static int _clk_audio_video_set_rate(struct clk *clk, unsigned long rate)
        u32 test_div_sel = 2;
        u32 control3 = 0;
 
-       if (rev < IMX_CHIP_REVISION_1_1)
+       if ((rev < IMX_CHIP_REVISION_1_1) && !cpu_is_mx6dl())
                min_clk_rate = AUDIO_VIDEO_MIN_CLK_FREQ;
        else if (clk == &pll4_audio_main_clk)
                min_clk_rate = AUDIO_VIDEO_MIN_CLK_FREQ / 4;
@@ -839,7 +854,7 @@ static int _clk_audio_video_set_rate(struct clk *clk, unsigned long rate)
                pllbase = PLL5_VIDEO_BASE_ADDR;
 
        pre_div_rate = rate;
-       if (rev >= IMX_CHIP_REVISION_1_1) {
+       if ((rev >= IMX_CHIP_REVISION_1_1) || cpu_is_mx6dl()) {
                while (pre_div_rate < AUDIO_VIDEO_MIN_CLK_FREQ) {
                        pre_div_rate *= 2;
                        /*
@@ -902,7 +917,7 @@ static unsigned long _clk_audio_video_round_rate(struct clk *clk,
        unsigned long final_rate;
        int rev = mx6q_revision();
 
-       if (rev < IMX_CHIP_REVISION_1_1)
+       if ((rev < IMX_CHIP_REVISION_1_1) && !cpu_is_mx6dl())
                min_clk_rate = AUDIO_VIDEO_MIN_CLK_FREQ;
        else if (clk == &pll4_audio_main_clk)
                min_clk_rate = AUDIO_VIDEO_MIN_CLK_FREQ / 4;
@@ -916,7 +931,7 @@ static unsigned long _clk_audio_video_round_rate(struct clk *clk,
                return AUDIO_VIDEO_MAX_CLK_FREQ;
 
        pre_div_rate = rate;
-       if (rev >= IMX_CHIP_REVISION_1_1) {
+       if ((rev >= IMX_CHIP_REVISION_1_1) || cpu_is_mx6dl()) {
                while (pre_div_rate < AUDIO_VIDEO_MIN_CLK_FREQ) {
                        pre_div_rate *= 2;
                        post_div *= 2;
@@ -5111,6 +5126,8 @@ static struct clk_lookup lookups[] = {
        _REGISTER_CLOCK(NULL, "clko_clk", clko_clk),
        _REGISTER_CLOCK(NULL, "clko2_clk", clko2_clk),
        _REGISTER_CLOCK(NULL, "pxp_axi", ipu2_clk),
+       _REGISTER_CLOCK(NULL, "epdc_axi", ipu2_clk),
+       _REGISTER_CLOCK(NULL, "epdc_pix", ipu2_di_clk[1]),
        _REGISTER_CLOCK("mxs-perfmon.0", "perfmon", perfmon0_clk),
        _REGISTER_CLOCK("mxs-perfmon.1", "perfmon", perfmon1_clk),
        _REGISTER_CLOCK("mxs-perfmon.2", "perfmon", perfmon2_clk),
@@ -5271,6 +5288,13 @@ int __init mx6_clocks_init(unsigned long ckil, unsigned long osc,
                gpt_clk[0].get_rate = NULL;
                }
 
+       if (cpu_is_mx6dl()) {
+               if (epdc_use_video_pll)
+                       clk_set_parent(&ipu2_di_clk[1], &pll5_video_main_clk);
+               else
+                       clk_set_parent(&ipu2_di_clk[1], &pll3_pfd_540M);
+       }
+
        base = ioremap(GPT_BASE_ADDR, SZ_4K);
        mxc_timer_init(&gpt_clk[0], base, MXC_INT_GPT);
 
index d7dbe3edcaefba3dff10fbdba7df2ddddb87600c..404a264e7ddc64766150b304d68b33a66047246c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2011-2012 Freescale Semiconductor, Inc. All Rights Reserved.
  */
 
 /*
@@ -22,7 +22,7 @@
 #include <mach/hardware.h>
 #include <mach/devices-common.h>
 
-#define imx5_epdc_data_entry_single(soc, size) \
+#define imx_epdc_data_entry_single(soc, size)  \
        {                                                               \
                .iobase = soc ## _EPDC_BASE_ADDR,                       \
                .irq = soc ## _INT_EPDC,                                \
 
 #ifdef CONFIG_SOC_IMX50
 const struct imx_epdc_data imx50_epdc_data __initconst =
-                       imx5_epdc_data_entry_single(MX50, SZ_4K);
+                       imx_epdc_data_entry_single(MX50, SZ_4K);
+#endif
+
+#ifdef CONFIG_SOC_IMX6Q
+const struct imx_epdc_data imx6dl_epdc_data __initconst =
+                       imx_epdc_data_entry_single(MX6DL, SZ_16K);
 #endif
 
 struct platform_device *__init imx_add_imx_epdc(