summaryrefslogtreecommitdiff
path: root/board/st/u8500/mcde_display.c
diff options
context:
space:
mode:
Diffstat (limited to 'board/st/u8500/mcde_display.c')
-rw-r--r--board/st/u8500/mcde_display.c380
1 files changed, 145 insertions, 235 deletions
diff --git a/board/st/u8500/mcde_display.c b/board/st/u8500/mcde_display.c
index 76ded82e6..9c738fac4 100644
--- a/board/st/u8500/mcde_display.c
+++ b/board/st/u8500/mcde_display.c
@@ -7,38 +7,32 @@
* License terms: GNU General Public License (GPL), version 2.
*/
-
#include <common.h>
#include <command.h>
-#include "mcde_display.h"
-#include "dsilink_regs.h"
-#include <tc35892.h>
-#include "mcde_regs.h"
#include <malloc.h>
-#include "mcde.h"
-#include <linux/err.h>
-#include <asm/arch/ab8500.h>
#include <asm/arch/common.h>
-#include <part.h>
-#include <mmc.h>
-
-#define DEBUG 0
-#define dbg_printk(format, arg...) \
- if (DEBUG) \
- printf("mcde: " format, ##arg) \
+#include <asm/arch/ab8500.h>
+#include <linux/err.h>
+#include <tc35892.h> /* Needed for DSI, to be removed */
+#include "mcde.h"
+#include "mcde_regs.h"
+#include "mcde_display.h"
+#include "dsilink_regs.h"
static struct mcde_chnl_state *chnl;
+#if CONFIG_SYS_DISPLAY_DSI
static struct mcde_port port0 = {
.type = MCDE_PORTTYPE_DSI,
.mode = MCDE_PORTMODE_CMD,
- .ifc = 0,
+ .ifc = 1,
.link = 0,
.sync_src = MCDE_SYNCSRC_BTA,
.phy = {
.dsi = {
.virt_id = 0,
.num_data_lanes = 2,
+ .ui = 9,
},
},
};
@@ -48,266 +42,182 @@ struct mcde_display_generic_platform_data main_display_data = {
.reset_delay = 10,
};
+struct mcde_platform_data platform_data = {
+ 0,
+};
+
+struct mcde_video_mode video_mode = {
+ .xres = CONFIG_SYS_DISPLAY_NATIVE_X_RES,
+ .yres = CONFIG_SYS_DISPLAY_NATIVE_Y_RES,
+ .pixclock = 37037, /* from kernel */
+ .interlaced = 0,
+ .bckcol = {255, 255, 255}, /* R, G, B */
+};
+
struct mcde_display_device main_display = {
.port = &port0,
- .chnl_id = MCDE_CHNL_C0,
- .fifo = MCDE_FIFO_A,
+ .chnl_id = MCDE_CHNL_A,
+ .fifo = MCDE_FIFO_C0,
.default_pixel_format = MCDE_OVLYPIXFMT_RGB565,
.port_pixel_format = MCDE_PORTPIXFMT_DSI_24BPP,
.native_x_res = CONFIG_SYS_DISPLAY_NATIVE_X_RES,
.native_y_res = CONFIG_SYS_DISPLAY_NATIVE_Y_RES,
};
+#endif
-static int mcde_enable_gpio(void)
-{
- int ret;
- dbg_printk("Enable GPIO pins!\n");
-
- /* Only main display should be initialized */
- ret = tc35892_gpio_dir(CONFIG_SYS_I2C_GPIOE_ADDR,
- main_display_data.reset_gpio, 1);
- if (ret) {
- printf("%s:Could not set direction for gpio \n", __func__);
- return -EINVAL;
- }
- ret = tc35892_gpio_set(CONFIG_SYS_I2C_GPIOE_ADDR,
- main_display_data.reset_gpio, 0);
- if (ret) {
- printf("%s:Could reset gpio \n", __func__);
- return -EINVAL;
- }
- mdelay(main_display_data.reset_delay);
- ret = tc35892_gpio_set(CONFIG_SYS_I2C_GPIOE_ADDR,
- main_display_data.reset_gpio, 1);
- if (ret) {
- printf("%s:Could set gpior\n", __func__);
- return -EINVAL;
- }
- mdelay(main_display_data.reset_delay);
-
- dbg_printk("All needed GPIOS enabled!\n");
- return 0;
-}
-
-#define DCS_CMD_EXIT_SLEEP_MODE 0x11
-#define DCS_CMD_SET_DISPLAY_ON 0x29
-
-int mcde_turn_on_display(void)
-{
- int ret = 0;
- dbg_printk("Turn on display!\n");
- ret = mcde_dsi_dcs_write(main_display.port,
- DCS_CMD_EXIT_SLEEP_MODE, NULL, 0);
- if (!ret) {
- dbg_printk("mcde_dsi_dcs_write "
- "DCS_CMD_EXIT_SLEEP_MODE success!\n");
- ret = mcde_dsi_dcs_write(main_display.port,
- DCS_CMD_SET_DISPLAY_ON, NULL, 0);
- if (!ret)
- dbg_printk("mcde_dsi_dcs_write "
- "DCS_CMD_SET_DISPLAY_ON success!\n");
- }
-
- return ret;
-}
-
-/* aux supplies */
-#define MASK_LDO_VAUX1 (0x3)
-#define MASK_LDO_VAUX1_SHIFT (0x0)
-#define VAUXSEL_VOLTAGE_MASK (0xf)
-
-#define VANA_ENABLE_IN_HP_MODE 0x05
-
-#define ENABLE_PWM1 0x01
-#define PWM_DUTY_LOW_1024_1024 0xFF
-#define PWM_DUTY_HI_1024_1024 0x03
-
+#if CONFIG_SYS_DISPLAY_DPI
/*
- * regulator layout
- * @voltage: supported voltage
- * @regval: register value to be written
+ * STE VUIB card
*/
-struct regulator_voltage {
- int voltage;
- int regval;
+static struct mcde_port port0 = {
+ .type = MCDE_PORTTYPE_DPI,
+ .mode = MCDE_PORTMODE_VID,
+ .ifc = 0,
+ .link = 1, /* DPI channel B can only be on link 1 */
+ .sync_src = MCDE_SYNCSRC_OFF, /* sync from output formatter */
+ .update_auto_trig = TRUE,
+ .phy = {
+ .dpi = {
+ .tv_mode = FALSE,
+ .clock_div = 2,
+ .polarity = DPI_ACT_LOW_VSYNC | DPI_ACT_LOW_HSYNC,
+ },
+ },
};
-/* voltage table for VAUXn regulators */
-static struct regulator_voltage vauxn_table[] = {
- { .voltage = 1100000, .regval = 0x0, },
- { .voltage = 1200000, .regval = 0x1, },
- { .voltage = 1300000, .regval = 0x2, },
- { .voltage = 1400000, .regval = 0x3, },
- { .voltage = 1500000, .regval = 0x4, },
- { .voltage = 1800000, .regval = 0x5, },
- { .voltage = 1850000, .regval = 0x6, },
- { .voltage = 1900000, .regval = 0x7, },
- { .voltage = 2500000, .regval = 0x8, },
- { .voltage = 2650000, .regval = 0x9, },
- { .voltage = 2700000, .regval = 0xa, },
- { .voltage = 2750000, .regval = 0xb, },
- { .voltage = 2800000, .regval = 0xc, },
- { .voltage = 2900000, .regval = 0xd, },
- { .voltage = 3000000, .regval = 0xe, },
- { .voltage = 3300000, .regval = 0xf, },
+struct mcde_display_generic_platform_data main_display_data = {
+ 0,
};
-
-/*
- * This code is derived from the handling of AB8500_LDO_VAUX1 in
- * ab8500_ldo_is_enabled in Linux.
- */
-static int mcde_is_vaux1_enabled(void)
-{
- int val;
- val = ab8500_read(AB8500_REGU_CTRL2,
- AB8500_REGU_VAUX12_REGU_REG);
- if (val & MASK_LDO_VAUX1)
- return TRUE;
- return FALSE;
-}
-
-/*
- * This code is derived from the handling of AB8500_LDO_VAUX1 in
- * ab8500_ldo_get_voltage in Linux.
- */
-static int mcde_get_vaux1_voltage(void)
-{
- int val;
- val = ab8500_read(AB8500_REGU_CTRL2,
- AB8500_REGU_VAUX1_SEL_REG);
- return vauxn_table[val & VAUXSEL_VOLTAGE_MASK].voltage;
-}
-
-static int mcde_display_power_init(void)
-{
- int val;
- int i;
-
+struct mcde_platform_data platform_data = {
+ /* DPI */
/*
- * On v1.1 HREF boards (HREF+) and V2 boards
- * Vaux1 needs to be enabled for the
- * display to work. This is done by enabling the regulators in the
- * AB8500 via PRCMU I2C transactions.
- *
- * This code is derived from the handling of AB8500_LDO_VAUX1 in
- * ab8500_ldo_enable(), ab8500_ldo_disable() and
- * ab8500_get_best_voltage in Linux.
+ * [0] = 3: 24 bits DPI: connect LSB Ch B to D[0:7]
+ * [3] = 4: 24 bits DPI: connect MID Ch B to D[24:31]
+ * [4] = 5: 24 bits DPI: connect MSB Ch B to D[32:39]
*
- * Turn off and delay is required to have it work across soft reboots.
+ * [1] = 3: TV out : connect LSB Ch B to D[8:15]
*/
+#define DONT_CARE 0
+ .outmux = { 3, 3, DONT_CARE, 4, 5 }, /* vuib500 */
+#undef DONT_CARE
+ .syncmux = 0x01, /* vuib500 */
+};
- val = ab8500_read(AB8500_REGU_CTRL2,
- AB8500_REGU_VAUX12_REGU_REG);
- if (val < 0) {
- printf("Read vaux1 status failed\n");
- return -EINVAL;
- }
-
- /* Turn off */
- if (ab8500_write(AB8500_REGU_CTRL2, AB8500_REGU_VAUX12_REGU_REG,
- val & ~MASK_LDO_VAUX1) < 0) {
- printf("Turn off Vaux1 failed\n");
- return -EINVAL;
- }
-
- udelay(10 * 1000);
-
-
- /* Find voltage from vauxn table */
- for (i = 0; i < ARRAY_SIZE(vauxn_table) ; i++) {
- if (vauxn_table[i].voltage == CONFIG_SYS_DISPLAY_VOLTAGE) {
- if (ab8500_write(AB8500_REGU_CTRL2,
- AB8500_REGU_VAUX1_SEL_REG,
- vauxn_table[i].regval) < 0) {
- printf("AB8500_REGU_VAUX1_SEL_REG failed\n");
- return -EINVAL;
- }
- break;
- }
- }
-
- val = val & ~MASK_LDO_VAUX1;
- val = val | (1 << MASK_LDO_VAUX1_SHIFT);
-
- /* Turn on the supply */
- if (ab8500_write(AB8500_REGU_CTRL2,
- AB8500_REGU_VAUX12_REGU_REG, val) < 0) {
- printf("Turn on Vaux1 failed\n");
- return -EINVAL;
- }
-
- /* DCI & CSI (DSI / PLL / Camera) */ /* Vana & Vpll HP mode */
- if (ab8500_write(AB8500_REGU_CTRL2, AB8500_REGU_VPLLVANA_REGU_REG,
- VANA_ENABLE_IN_HP_MODE) < 0) {
- printf("Turn on Vana failed\n");
- return -EINVAL;
- }
+#define DPI_PIXCLK_FREQ 25000000
+
+struct mcde_video_mode video_mode = {
+ .hbp = 40, /* Horizontal Back Porch */
+ .hfp = 8, /* Horizontal Front Porch */
+ .hsw = 96, /* Horizontal Synchronization pulse Width */
+ .vbp1 = 25, /* Vertical Back Porch 1 */
+ .vfp1 = 2, /* Vertical Front Porch 1 */
+ .vbp2 = 0, /* Vertical Back Porch 2 */
+ .vfp2 = 0, /* Vertical Front Porch 2 */
+ .vsw = 2, /* Vertical Synchronization pulse Width */
+ .pixclock = (int)(1e+12 * (1.0 / DPI_PIXCLK_FREQ)),
+ .interlaced = 0,
+ .bckcol = {255, 255, 255}, /* R, G, B */
+};
- /* Enable the PWM control for the backlight Main display */
- if (ab8500_write(AB8500_MISC, AB8500_PWM_OUT_CTRL7_REG,
- ENABLE_PWM1) < 0) {
- printf("Enable PWM1 failed\n");
- return -EINVAL;
- }
- if (ab8500_write(AB8500_MISC, AB8500_PWM_OUT_CTRL1_REG,
- PWM_DUTY_LOW_1024_1024) < 0) {
- printf("PWM_DUTY_LOW_1024_1024 failed\n");
- return -EINVAL;
- }
- if (ab8500_write(AB8500_MISC, AB8500_PWM_OUT_CTRL2_REG,
- PWM_DUTY_HI_1024_1024) < 0) {
- printf("PWM_DUTY_HI_1024_1024 failed\n");
- return -EINVAL;
- }
+struct mcde_display_device main_display = {
+ .port = &port0,
+ .chnl_id = MCDE_CHNL_A,
+ .fifo = MCDE_FIFO_A,
+ .default_pixel_format = MCDE_OVLYPIXFMT_RGB565,
+ .port_pixel_format = MCDE_PORTPIXFMT_DPI_24BPP,
+ .native_x_res = CONFIG_SYS_DISPLAY_NATIVE_X_RES,
+ .native_y_res = CONFIG_SYS_DISPLAY_NATIVE_Y_RES,
+};
+#endif
- if (!mcde_is_vaux1_enabled() || mcde_get_vaux1_voltage()
- != CONFIG_SYS_DISPLAY_VOLTAGE) {
- printf("VAUX is %d and is set to %d V should be %d\n"
- , mcde_is_vaux1_enabled(), mcde_get_vaux1_voltage()
- , CONFIG_SYS_DISPLAY_VOLTAGE);
- return -EINVAL;
- }
+int mcde_turn_on_display(void)
+{
+ debug("%s: Enter\n", __func__);
- return 0;
+ if (main_display.port->type == MCDE_PORTTYPE_DSI)
+ return mcde_turn_on_display_dsi();
+ else if (main_display.port->type == MCDE_PORTTYPE_DPI)
+ return mcde_turn_on_display_dpi();
+ return -ENODEV; /* Should never occur */
}
int mcde_splash_image(void)
{
- u8 num_dsilinks;
- int ret;
-
- num_dsilinks = main_display.port->phy.dsi.num_data_lanes;
- mcde_init(num_dsilinks);
- ret = mcde_display_power_init();
- if (ret)
- goto display_power_failed;
- mcde_enable_dss();
-
- ret = mcde_enable_gpio();
- if (ret)
- goto enable_gpio_failed;
+ int ret = -ENODEV;
+ struct mcde_rectangle rect;
+
+ debug("%s: enter\n", __func__);
+
+ if (main_display.port->type == MCDE_PORTTYPE_DSI)
+ ret = mcde_startup_dsi(&platform_data);
+ else if (main_display.port->type == MCDE_PORTTYPE_DPI)
+ ret = mcde_startup_dpi(&platform_data);
+ if (ret != 0) {
+ printf("%s: mcde_startup... -> %d\n", __func__, ret);
+ return ret;
+ }
+ /* dss enable display */
chnl = mcde_chnl_get(main_display.chnl_id, main_display.fifo,
main_display.port);
if (IS_ERR(chnl)) {
ret = PTR_ERR(chnl);
- printf("%s:Failed to acquire MCDE channel\n", __func__);
+ printf("%s: Failed to acquire MCDE channel ret=%d\n",
+ __func__, ret);
goto get_chnl_failed;
}
+
+ ret = mcde_chnl_set_power_mode(chnl, MCDE_DISPLAY_PM_STANDBY);
+ if (ret) {
+ printf("%s: mcde_chnl_set_power_mode() -> %d\n",
+ __func__, ret);
+ goto get_chnl_failed;
+ }
+
+ /* dss set video mode */
+ ret = mcde_chnl_set_video_mode(chnl, &video_mode);
+ if (ret < 0) {
+ printf("%s:Failed to set video mode on channel ret=%d\n",
+ __func__, ret);
+ goto set_video_mode_failed;
+ }
+
+ mcde_chnl_set_pixel_format(chnl, main_display.port_pixel_format);
mcde_chnl_set_update_area(chnl, 0, 0, main_display.native_x_res,
main_display.native_y_res);
- mcde_chnl_set_pixel_format(chnl, main_display.port_pixel_format);
mcde_chnl_apply(chnl);
- /* Everything setup ok, display image */
+ /* chnl setup ok, display image */
ret = mcde_display_image(chnl);
+ if (ret != 0) {
+ debug("%s: mcde_display_image() -> %d\n",
+ __func__, ret);
+ }
+
+ mcde_chnl_apply(chnl);
+ rect.x = 0;
+ rect.y = 0;
+ rect.w = main_display.native_x_res;
+ rect.h = main_display.native_y_res;
+ mcde_chnl_update(chnl, &rect);
+
+ ret = mcde_turn_on_display();
+ if (ret) {
+ printf("%s: mcde_turn_on_display() -> %d\n", __func__, ret);
+ goto get_chnl_failed;
+ }
+
+ ret = mcde_chnl_set_power_mode(chnl, MCDE_DISPLAY_PM_ON);
+ if (ret) {
+ printf("%s: mcde_chnl_set_power_mode() -> %d\n", __func__, ret);
+ goto get_chnl_failed;
+ }
return ret;
get_chnl_failed:
-display_power_failed:
-enable_gpio_failed:
+set_video_mode_failed:
mcde_exit();
return ret;
}