diff options
-rw-r--r-- | arch/arm/mach-omap2/board-4430sdp.c | 132 | ||||
-rw-r--r-- | drivers/video/omap2/dss/dsi.c | 240 | ||||
-rw-r--r-- | drivers/video/omap2/dss/dss.c | 51 | ||||
-rw-r--r-- | drivers/video/omap2/dss/dss_features.c | 9 | ||||
-rw-r--r-- | drivers/video/omap2/dss/dss_features.h | 30 |
5 files changed, 346 insertions, 116 deletions
diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c index 56702c5e577f..05288c90f24f 100644 --- a/arch/arm/mach-omap2/board-4430sdp.c +++ b/arch/arm/mach-omap2/board-4430sdp.c @@ -37,6 +37,7 @@ #include <plat/mmc.h> #include <plat/omap4-keypad.h> #include <plat/display.h> +#include <plat/nokia-dsi-panel.h> #include "mux.h" #include "hsmmc.h" @@ -50,6 +51,11 @@ #define OMAP4_SFH7741_ENABLE_GPIO 188 #define HDMI_GPIO_HPD 60 /* Hot plug pin for HDMI */ #define HDMI_GPIO_LS_OE 41 /* Level shifter for HDMI */ +#define LCD_BL_GPIO 27 /* LCD Backlight GPIO */ +/* PWM2 and TOGGLE3 register offsets */ +#define LED_PWM2ON 0x03 +#define LED_PWM2OFF 0x04 +#define TWL6030_TOGGLE3 0x92 static const int sdp4430_keymap[] = { KEY(0, 0, KEY_E), @@ -306,24 +312,13 @@ error1: return status; } -static struct platform_device sdp4430_lcd_device = { - .name = "sdp4430_lcd", - .id = -1, -}; - static struct platform_device *sdp4430_devices[] __initdata = { - &sdp4430_lcd_device, &sdp4430_gpio_keys_device, &sdp4430_leds_gpio, &sdp4430_leds_pwm, }; -static struct omap_lcd_config sdp4430_lcd_config __initdata = { - .ctrl_name = "internal", -}; - static struct omap_board_config_kernel sdp4430_config[] __initdata = { - { OMAP_TAG_LCD, &sdp4430_lcd_config }, }; static void __init omap_4430sdp_init_early(void) @@ -378,6 +373,10 @@ static struct regulator_consumer_supply sdp4430_vmmc_supply[] = { .dev_name = "omap_hsmmc.0", }, }; +static struct regulator_consumer_supply sdp4430_vcxio_supply[] = { + REGULATOR_SUPPLY("vdds_dsi", "omapdss_dss"), + REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"), +}; static int omap4_twl6030_hsmmc_late_init(struct device *dev) { @@ -524,7 +523,10 @@ static struct regulator_init_data sdp4430_vcxio = { | REGULATOR_MODE_STANDBY, .valid_ops_mask = REGULATOR_CHANGE_MODE | REGULATOR_CHANGE_STATUS, + .always_on = true, }, + .num_consumer_supplies = ARRAY_SIZE(sdp4430_vcxio_supply), + .consumer_supplies = sdp4430_vcxio_supply, }; static struct regulator_init_data sdp4430_vdac = { @@ -631,6 +633,73 @@ static void __init omap_sfh7741prox_init(void) } } +static int dsi1_panel_set_backlight(struct omap_dss_device *dssdev, int level) +{ + int r; + + r = twl_i2c_write_u8(TWL_MODULE_PWM, 0x7F, LED_PWM2OFF); + if (r) + return r; + + if (level > 1) { + if (level == 255) + level = 0x7F; + else + level = (~(level/2)) & 0x7F; + + r = twl_i2c_write_u8(TWL_MODULE_PWM, level, LED_PWM2ON); + if (r) + return r; + r = twl_i2c_write_u8(TWL6030_MODULE_ID1, 0x30, TWL6030_TOGGLE3); + if (r) + return r; + } else if (level <= 1) { + r = twl_i2c_write_u8(TWL6030_MODULE_ID1, 0x08, TWL6030_TOGGLE3); + if (r) + return r; + r = twl_i2c_write_u8(TWL6030_MODULE_ID1, 0x28, TWL6030_TOGGLE3); + if (r) + return r; + r = twl_i2c_write_u8(TWL6030_MODULE_ID1, 0x00, TWL6030_TOGGLE3); + if (r) + return r; + } + + return 0; +} + +static struct nokia_dsi_panel_data dsi1_panel; + +static void sdp4430_lcd_init(void) +{ + u32 reg; + int status; + + /* Enable DSI1 Lanes */ + reg = omap4_ctrl_pad_readl(OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_DSIPHY); + reg |= OMAP4_DSI1_PIPD_MASK | OMAP4_DSI1_LANEENABLE_MASK; + omap4_ctrl_pad_writel(reg, OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_DSIPHY); + + /* Panel Taal reset and backlight GPIO init */ + status = gpio_request_one(dsi1_panel.reset_gpio, GPIOF_DIR_OUT, + "lcd_reset_gpio"); + if (status) + pr_err("%s: Could not get lcd_reset_gpio\n", __func__); + + if (dsi1_panel.use_ext_te) { + status = omap_mux_init_signal("gpmc_ncs4.gpio_101", + OMAP_PIN_INPUT_PULLUP); + if (status) + pr_err("%s: Could not get ext_te gpio\n", __func__); + } + + status = gpio_request_one(LCD_BL_GPIO, GPIOF_DIR_OUT, "lcd_bl_gpio"); + if (status) + pr_err("%s: Could not get lcd_bl_gpio\n", __func__); + + gpio_set_value(LCD_BL_GPIO, 0); +} + static void sdp4430_hdmi_mux_init(void) { /* PAD0_HDMI_HPD_PAD1_HDMI_CEC */ @@ -676,6 +745,43 @@ static void sdp4430_panel_disable_hdmi(struct omap_dss_device *dssdev) gpio_free(HDMI_GPIO_HPD); } +static struct nokia_dsi_panel_data dsi1_panel = { + .name = "taal", + .reset_gpio = 102, + .use_ext_te = false, + .ext_te_gpio = 101, + .use_esd_check = false, + .set_backlight = dsi1_panel_set_backlight, +}; + +static struct omap_dss_device sdp4430_lcd_device = { + .name = "lcd", + .driver_name = "taal", + .type = OMAP_DISPLAY_TYPE_DSI, + .data = &dsi1_panel, + .phy.dsi = { + .clk_lane = 1, + .clk_pol = 0, + .data1_lane = 2, + .data1_pol = 0, + .data2_lane = 3, + .data2_pol = 0, + .div = { + .regn = 16, /* Fint = 2.4 MHz */ + .regm = 180, /* DDR Clock = 216 MHz */ + .regm_dispc = 5, /* PLL1_CLK1 = 172.8 MHz */ + .regm_dsi = 5, /* PLL1_CLK2 = 172.8 MHz */ + + .lp_clk_div = 10, /* LP Clock = 8.64 MHz */ + + .lck_div = 1, /* Logic Clock = 172.8 MHz */ + .pck_div = 5, /* Pixel Clock = 34.56 MHz */ + + }, + }, + .channel = OMAP_DSS_CHANNEL_LCD, +}; + static struct omap_dss_device sdp4430_hdmi_device = { .name = "hdmi", .driver_name = "hdmi_panel", @@ -686,17 +792,19 @@ static struct omap_dss_device sdp4430_hdmi_device = { }; static struct omap_dss_device *sdp4430_dss_devices[] = { + &sdp4430_lcd_device, &sdp4430_hdmi_device, }; static struct omap_dss_board_info sdp4430_dss_data = { .num_devices = ARRAY_SIZE(sdp4430_dss_devices), .devices = sdp4430_dss_devices, - .default_device = &sdp4430_hdmi_device, + .default_device = &sdp4430_lcd_device, }; void omap_4430sdp_display_init(void) { + sdp4430_lcd_init(); sdp4430_hdmi_mux_init(); omap_display_init(&sdp4430_dss_data); } diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index 0a7f1a47f8e3..23d9bbe68b82 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -1270,7 +1270,7 @@ int dsi_pll_set_clock_div(struct dsi_clock_info *cinfo) { int r = 0; u32 l; - int f; + int f = 0; u8 regn_start, regn_end, regm_start, regm_end; u8 regm_dispc_start, regm_dispc_end, regm_dsi_start, regm_dsi_end; @@ -1341,19 +1341,19 @@ int dsi_pll_set_clock_div(struct dsi_clock_info *cinfo) dsi_write_reg(DSI_PLL_CONFIGURATION1, l); BUG_ON(cinfo->fint < dsi.fint_min || cinfo->fint > dsi.fint_max); - if (cinfo->fint < 1000000) - f = 0x3; - else if (cinfo->fint < 1250000) - f = 0x4; - else if (cinfo->fint < 1500000) - f = 0x5; - else if (cinfo->fint < 1750000) - f = 0x6; - else - f = 0x7; + + if (dss_has_feature(FEAT_DSI_PLL_FREQSEL)) { + f = cinfo->fint < 1000000 ? 0x3 : + cinfo->fint < 1250000 ? 0x4 : + cinfo->fint < 1500000 ? 0x5 : + cinfo->fint < 1750000 ? 0x6 : + 0x7; + } l = dsi_read_reg(DSI_PLL_CONFIGURATION2); - l = FLD_MOD(l, f, 4, 1); /* DSI_PLL_FREQSEL */ + + if (dss_has_feature(FEAT_DSI_PLL_FREQSEL)) + l = FLD_MOD(l, f, 4, 1); /* DSI_PLL_FREQSEL */ l = FLD_MOD(l, cinfo->use_sys_clk ? 0 : 1, 11, 11); /* DSI_PLL_CLKSEL */ l = FLD_MOD(l, cinfo->highfreq, @@ -1873,9 +1873,6 @@ static int dsi_complexio_init(struct omap_dss_device *dssdev) DSSDBG("dsi_complexio_init\n"); - /* CIO_CLK_ICG, enable L3 clk to CIO */ - REG_FLD_MOD(DSI_CLK_CTRL, 1, 14, 14); - /* A dummy read using the SCP interface to any DSIPHY register is * required after DSIPHY reset to complete the reset of the DSI complex * I/O. */ @@ -1900,10 +1897,12 @@ static int dsi_complexio_init(struct omap_dss_device *dssdev) goto err; } - if (wait_for_bit_change(DSI_COMPLEXIO_CFG1, 21, 1) != 1) { - DSSERR("ComplexIO LDO power down.\n"); - r = -ENODEV; - goto err; + if (dss_has_feature(FEAT_DSI_LDO_STATUS)) { + if (wait_for_bit_change(DSI_COMPLEXIO_CFG1, 21, 1) != 1) { + DSSERR("ComplexIO LDO power down.\n"); + r = -ENODEV; + goto err; + } } dsi_complexio_timings(); @@ -2034,6 +2033,114 @@ static int dsi_force_tx_stop_mode_io(void) return 0; } +static bool dsi_vc_is_enabled(int channel) +{ + return REG_GET(DSI_VC_CTRL(channel), 0, 0); +} + +static void dsi_packet_sent_handler_vp(void *data, u32 mask) +{ + const int channel = dsi.update_channel; + u8 bit = dsi.te_enabled ? 30 : 31; + + if (REG_GET(DSI_VC_TE(channel), bit, bit) == 0) + complete((struct completion *)data); +} + +static int dsi_sync_vc_vp(int channel) +{ + int r = 0; + u8 bit; + + DECLARE_COMPLETION_ONSTACK(completion); + + bit = dsi.te_enabled ? 30 : 31; + + r = dsi_register_isr_vc(channel, dsi_packet_sent_handler_vp, + &completion, DSI_VC_IRQ_PACKET_SENT); + if (r) + goto err0; + + /* Wait for completion only if TE_EN/TE_START is still set */ + if (REG_GET(DSI_VC_TE(channel), bit, bit)) { + if (wait_for_completion_timeout(&completion, + msecs_to_jiffies(10)) == 0) { + DSSERR("Failed to complete previous frame transfer\n"); + r = -EIO; + goto err1; + } + } + + dsi_unregister_isr_vc(channel, dsi_packet_sent_handler_vp, + &completion, DSI_VC_IRQ_PACKET_SENT); + + return 0; +err1: + dsi_unregister_isr_vc(channel, dsi_packet_sent_handler_vp, &completion, + DSI_VC_IRQ_PACKET_SENT); +err0: + return r; +} + +static void dsi_packet_sent_handler_l4(void *data, u32 mask) +{ + const int channel = dsi.update_channel; + + if (REG_GET(DSI_VC_CTRL(channel), 5, 5) == 0) + complete((struct completion *)data); +} + +static int dsi_sync_vc_l4(int channel) +{ + int r = 0; + + DECLARE_COMPLETION_ONSTACK(completion); + + r = dsi_register_isr_vc(channel, dsi_packet_sent_handler_l4, + &completion, DSI_VC_IRQ_PACKET_SENT); + if (r) + goto err0; + + /* Wait for completion only if TX_FIFO_NOT_EMPTY is still set */ + if (REG_GET(DSI_VC_CTRL(channel), 5, 5)) { + if (wait_for_completion_timeout(&completion, + msecs_to_jiffies(10)) == 0) { + DSSERR("Failed to complete previous l4 transfer\n"); + r = -EIO; + goto err1; + } + } + + dsi_unregister_isr_vc(channel, dsi_packet_sent_handler_l4, + &completion, DSI_VC_IRQ_PACKET_SENT); + + return 0; +err1: + dsi_unregister_isr_vc(channel, dsi_packet_sent_handler_l4, + &completion, DSI_VC_IRQ_PACKET_SENT); +err0: + return r; +} + +static int dsi_sync_vc(int channel) +{ + WARN_ON(!dsi_bus_is_locked()); + + WARN_ON(in_interrupt()); + + if (!dsi_vc_is_enabled(channel)) + return 0; + + switch (dsi.vc[channel].mode) { + case DSI_VC_MODE_VP: + return dsi_sync_vc_vp(channel); + case DSI_VC_MODE_L4: + return dsi_sync_vc_l4(channel); + default: + BUG(); + } +} + static int dsi_vc_enable(int channel, bool enable) { DSSDBG("dsi_vc_enable channel %d, enable %d\n", @@ -2070,6 +2177,8 @@ static void dsi_vc_initial_config(int channel) r = FLD_MOD(r, 1, 7, 7); /* CS_TX_EN */ r = FLD_MOD(r, 1, 8, 8); /* ECC_TX_EN */ r = FLD_MOD(r, 0, 9, 9); /* MODE_SPEED, high speed on/off */ + if (dss_has_feature(FEAT_DSI_VC_OCP_WIDTH)) + r = FLD_MOD(r, 3, 11, 10); /* OCP_WIDTH = 32 bit */ r = FLD_MOD(r, 4, 29, 27); /* DMA_RX_REQ_NB = no dma */ r = FLD_MOD(r, 4, 23, 21); /* DMA_TX_REQ_NB = no dma */ @@ -2084,6 +2193,8 @@ static int dsi_vc_config_l4(int channel) DSSDBGF("%d", channel); + dsi_sync_vc(channel); + dsi_vc_enable(channel, 0); /* VC_BUSY */ @@ -2094,6 +2205,10 @@ static int dsi_vc_config_l4(int channel) REG_FLD_MOD(DSI_VC_CTRL(channel), 0, 1, 1); /* SOURCE, 0 = L4 */ + /* DCS_CMD_ENABLE */ + if (dss_has_feature(FEAT_DSI_DCS_CMD_CONFIG_VC)) + REG_FLD_MOD(DSI_VC_CTRL(channel), 0, 30, 30); + dsi_vc_enable(channel, 1); dsi.vc[channel].mode = DSI_VC_MODE_L4; @@ -2108,6 +2223,8 @@ static int dsi_vc_config_vp(int channel) DSSDBGF("%d", channel); + dsi_sync_vc(channel); + dsi_vc_enable(channel, 0); /* VC_BUSY */ @@ -2118,6 +2235,10 @@ static int dsi_vc_config_vp(int channel) REG_FLD_MOD(DSI_VC_CTRL(channel), 1, 1, 1); /* SOURCE, 1 = video port */ + /* DCS_CMD_ENABLE */ + if (dss_has_feature(FEAT_DSI_DCS_CMD_CONFIG_VC)) + REG_FLD_MOD(DSI_VC_CTRL(channel), 1, 30, 30); + dsi_vc_enable(channel, 1); dsi.vc[channel].mode = DSI_VC_MODE_VP; @@ -2773,8 +2894,11 @@ static int dsi_proto_config(struct omap_dss_device *dssdev) r = FLD_MOD(r, 2, 13, 12); /* LINE_BUFFER, 2 lines */ r = FLD_MOD(r, 1, 14, 14); /* TRIGGER_RESET_MODE */ r = FLD_MOD(r, 1, 19, 19); /* EOT_ENABLE */ - r = FLD_MOD(r, 1, 24, 24); /* DCS_CMD_ENABLE */ - r = FLD_MOD(r, 0, 25, 25); /* DCS_CMD_CODE, 1=start, 0=continue */ + if (!dss_has_feature(FEAT_DSI_DCS_CMD_CONFIG_VC)) { + r = FLD_MOD(r, 1, 24, 24); /* DCS_CMD_ENABLE */ + /* DCS_CMD_CODE, 1=start, 0=continue */ + r = FLD_MOD(r, 0, 25, 25); + } dsi_write_reg(DSI_CTRL, r); @@ -3093,17 +3217,8 @@ static void dsi_te_timeout(unsigned long arg) } #endif -static void dsi_framedone_bta_callback(void *data, u32 mask); - static void dsi_handle_framedone(int error) { - const int channel = dsi.update_channel; - - dsi_unregister_isr_vc(channel, dsi_framedone_bta_callback, - NULL, DSI_VC_IRQ_BTA); - - cancel_delayed_work(&dsi.framedone_timeout_work); - /* SIDLEMODE back to smart-idle */ dispc_enable_sidle(); @@ -3112,14 +3227,6 @@ static void dsi_handle_framedone(int error) REG_FLD_MOD(DSI_TIMING2, 1, 15, 15); /* LP_RX_TO */ } - /* RX_FIFO_NOT_EMPTY */ - if (REG_GET(DSI_VC_CTRL(channel), 20, 20)) { - DSSERR("Received error during frame transfer:\n"); - dsi_vc_flush_receive_data(channel); - if (!error) - error = -EIO; - } - dsi.framedone_callback(error, dsi.framedone_data); if (!error) @@ -3140,61 +3247,20 @@ static void dsi_framedone_timeout_work_callback(struct work_struct *work) dsi_handle_framedone(-ETIMEDOUT); } -static void dsi_framedone_bta_callback(void *data, u32 mask) -{ - dsi_handle_framedone(0); - -#ifdef CONFIG_OMAP2_DSS_FAKE_VSYNC - dispc_fake_vsync_irq(); -#endif -} - static void dsi_framedone_irq_callback(void *data, u32 mask) { - const int channel = dsi.update_channel; - int r; - /* Note: We get FRAMEDONE when DISPC has finished sending pixels and * turns itself off. However, DSI still has the pixels in its buffers, * and is sending the data. */ - if (dsi.te_enabled) { - /* enable LP_RX_TO again after the TE */ - REG_FLD_MOD(DSI_TIMING2, 1, 15, 15); /* LP_RX_TO */ - } + __cancel_delayed_work(&dsi.framedone_timeout_work); - /* Send BTA after the frame. We need this for the TE to work, as TE - * trigger is only sent for BTAs without preceding packet. Thus we need - * to BTA after the pixel packets so that next BTA will cause TE - * trigger. - * - * This is not needed when TE is not in use, but we do it anyway to - * make sure that the transfer has been completed. It would be more - * optimal, but more complex, to wait only just before starting next - * transfer. - * - * Also, as there's no interrupt telling when the transfer has been - * done and the channel could be reconfigured, the only way is to - * busyloop until TE_SIZE is zero. With BTA we can do this - * asynchronously. - * */ - - r = dsi_register_isr_vc(channel, dsi_framedone_bta_callback, - NULL, DSI_VC_IRQ_BTA); - if (r) { - DSSERR("Failed to register BTA ISR\n"); - dsi_handle_framedone(-EIO); - return; - } + dsi_handle_framedone(0); - r = dsi_vc_send_bta(channel); - if (r) { - DSSERR("BTA after framedone failed\n"); - dsi_unregister_isr_vc(channel, dsi_framedone_bta_callback, - NULL, DSI_VC_IRQ_BTA); - dsi_handle_framedone(-EIO); - } +#ifdef CONFIG_OMAP2_DSS_FAKE_VSYNC + dispc_fake_vsync_irq(); +#endif } int omap_dsi_prepare_update(struct omap_dss_device *dssdev, @@ -3371,6 +3437,10 @@ static int dsi_display_init_dsi(struct omap_dss_device *dssdev) { int r; + /* The SCPClk is required for both PLL and CIO registers on OMAP4 */ + /* CIO_CLK_ICG, enable L3 clk to CIO */ + REG_FLD_MOD(DSI_CLK_CTRL, 1, 14, 14); + _dsi_print_reset_status(); r = dsi_pll_init(dssdev, true, true); @@ -3383,6 +3453,8 @@ static int dsi_display_init_dsi(struct omap_dss_device *dssdev) dss_select_dispc_clk_source(DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC); dss_select_dsi_clk_source(DSS_CLK_SRC_DSI_PLL_HSDIV_DSI); + dss_select_lcd_clk_source(dssdev->manager->id, + DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC); DSSDBG("PLL OK\n"); diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c index 3f1fee63c678..9a73af609c01 100644 --- a/drivers/video/omap2/dss/dss.c +++ b/drivers/video/omap2/dss/dss.c @@ -68,6 +68,7 @@ static struct { struct clk *dss_sys_clk; struct clk *dss_tv_fck; struct clk *dss_video_fck; + struct clk *dss_dss_clk; unsigned num_clks_enabled; unsigned long cache_req_pck; @@ -816,6 +817,7 @@ static int dss_get_clocks(void) dss.dss_sys_clk = NULL; dss.dss_tv_fck = NULL; dss.dss_video_fck = NULL; + dss.dss_dss_clk = NULL; r = dss_get_clock(&dss.dss_ick, "ick"); if (r) @@ -848,6 +850,12 @@ static int dss_get_clocks(void) goto err; } + if (pdata->opt_clock_available("dss_clk")) { + r = dss_get_clock(&dss.dss_dss_clk, "dss_clk"); + if (r) + goto err; + } + return 0; err: @@ -861,7 +869,8 @@ err: clk_put(dss.dss_tv_fck); if (dss.dss_video_fck) clk_put(dss.dss_video_fck); - + if (dss.dss_dss_clk) + clk_put(dss.dss_dss_clk); return r; } @@ -873,6 +882,8 @@ static void dss_put_clocks(void) clk_put(dss.dss_tv_fck); if (dss.dss_sys_clk) clk_put(dss.dss_sys_clk); + if (dss.dss_dss_clk) + clk_put(dss.dss_dss_clk); clk_put(dss.dss_fck); clk_put(dss.dss_ick); } @@ -882,8 +893,16 @@ unsigned long dss_clk_get_rate(enum dss_clock clk) switch (clk) { case DSS_CLK_ICK: return clk_get_rate(dss.dss_ick); + /* + * XXX: tie dss_dss_clk to FCK - this will change with following + * pm_runtime patches. Needed for getting the correct clock rate + * for DSS_CLK_FCLK on OMAP4. + */ case DSS_CLK_FCK: - return clk_get_rate(dss.dss_fck); + if (dss.dss_dss_clk) + return clk_get_rate(dss.dss_dss_clk); + else + return clk_get_rate(dss.dss_fck); case DSS_CLK_SYSCK: return clk_get_rate(dss.dss_sys_clk); case DSS_CLK_TVFCK: @@ -920,8 +939,16 @@ static void dss_clk_enable_no_ctx(enum dss_clock clks) if (clks & DSS_CLK_ICK) clk_enable(dss.dss_ick); - if (clks & DSS_CLK_FCK) + /* + * XXX: tie dss_dss_clk to FCK - this will change with following + * pm_runtime patches. Needed for OMAP4 boot up due to stricter + * clock cutting in pm framework post 2.6.38-rc5. + */ + if (clks & DSS_CLK_FCK) { clk_enable(dss.dss_fck); + if (dss.dss_dss_clk) + clk_enable(dss.dss_dss_clk); + } if ((clks & DSS_CLK_SYSCK) && dss.dss_sys_clk) clk_enable(dss.dss_sys_clk); if ((clks & DSS_CLK_TVFCK) && dss.dss_tv_fck) @@ -956,8 +983,16 @@ static void dss_clk_disable_no_ctx(enum dss_clock clks) if (clks & DSS_CLK_ICK) clk_disable(dss.dss_ick); - if (clks & DSS_CLK_FCK) + /* + * XXX: tie dss_dss_clk to FCK - this will change with following + * pm_runtime patches. Needed for OMAP4 boot up due to stricter + * clock cutting in pm framework post 2.6.38-rc5. + */ + if (clks & DSS_CLK_FCK) { clk_disable(dss.dss_fck); + if (dss.dss_dss_clk) + clk_disable(dss.dss_dss_clk); + } if ((clks & DSS_CLK_SYSCK) && dss.dss_sys_clk) clk_disable(dss.dss_sys_clk); if ((clks & DSS_CLK_TVFCK) && dss.dss_tv_fck) @@ -1015,6 +1050,14 @@ static void core_dump_clocks(struct seq_file *s) dss.dss_video_fck }; + /* + * XXX: tie dss_dss_clk to FCK - this will change with following + * pm_runtime patches. Needed for getting the correct clock rate + * for DSS_CLK_FCLK on OMAP4. + */ + if (dss.dss_dss_clk) + clocks[1] = dss.dss_dss_clk; + seq_printf(s, "- CORE -\n"); seq_printf(s, "internal clk count\t\t%u\n", dss.num_clks_enabled); diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/omap2/dss/dss_features.c index aa1622241d0d..179a7a4f63bb 100644 --- a/drivers/video/omap2/dss/dss_features.c +++ b/drivers/video/omap2/dss/dss_features.c @@ -252,7 +252,8 @@ static struct omap_dss_features omap3430_dss_features = { FEAT_GLOBAL_ALPHA | FEAT_LCDENABLEPOL | FEAT_LCDENABLESIGNAL | FEAT_PCKFREEENABLE | FEAT_FUNCGATED | FEAT_ROWREPEATENABLE | - FEAT_LINEBUFFERSPLIT | FEAT_RESIZECONF, + FEAT_LINEBUFFERSPLIT | FEAT_RESIZECONF | + FEAT_DSI_PLL_FREQSEL | FEAT_DSI_LDO_STATUS, .num_mgrs = 2, .num_ovls = 3, @@ -271,7 +272,8 @@ static struct omap_dss_features omap3630_dss_features = { FEAT_LCDENABLESIGNAL | FEAT_PCKFREEENABLE | FEAT_PRE_MULT_ALPHA | FEAT_FUNCGATED | FEAT_ROWREPEATENABLE | FEAT_LINEBUFFERSPLIT | - FEAT_RESIZECONF, + FEAT_RESIZECONF | FEAT_DSI_PLL_FREQSEL | + FEAT_DSI_LDO_STATUS, .num_mgrs = 2, .num_ovls = 3, @@ -289,7 +291,8 @@ static struct omap_dss_features omap4_dss_features = { .has_feature = FEAT_GLOBAL_ALPHA | FEAT_PRE_MULT_ALPHA | FEAT_MGR_LCD2 | FEAT_GLOBAL_ALPHA_VID1 | - FEAT_CORE_CLK_DIV | FEAT_LCD_CLK_SRC, + FEAT_CORE_CLK_DIV | FEAT_LCD_CLK_SRC | + FEAT_DSI_DCS_CMD_CONFIG_VC | FEAT_DSI_VC_OCP_WIDTH, .num_mgrs = 3, .num_ovls = 3, diff --git a/drivers/video/omap2/dss/dss_features.h b/drivers/video/omap2/dss/dss_features.h index 12e9c4ef0dec..c5c0b4001ab3 100644 --- a/drivers/video/omap2/dss/dss_features.h +++ b/drivers/video/omap2/dss/dss_features.h @@ -26,20 +26,24 @@ /* DSS has feature id */ enum dss_feat_id { - FEAT_GLOBAL_ALPHA = 1 << 0, - FEAT_GLOBAL_ALPHA_VID1 = 1 << 1, - FEAT_PRE_MULT_ALPHA = 1 << 2, - FEAT_LCDENABLEPOL = 1 << 3, - FEAT_LCDENABLESIGNAL = 1 << 4, - FEAT_PCKFREEENABLE = 1 << 5, - FEAT_FUNCGATED = 1 << 6, - FEAT_MGR_LCD2 = 1 << 7, - FEAT_LINEBUFFERSPLIT = 1 << 8, - FEAT_ROWREPEATENABLE = 1 << 9, - FEAT_RESIZECONF = 1 << 10, + FEAT_GLOBAL_ALPHA = 1 << 0, + FEAT_GLOBAL_ALPHA_VID1 = 1 << 1, + FEAT_PRE_MULT_ALPHA = 1 << 2, + FEAT_LCDENABLEPOL = 1 << 3, + FEAT_LCDENABLESIGNAL = 1 << 4, + FEAT_PCKFREEENABLE = 1 << 5, + FEAT_FUNCGATED = 1 << 6, + FEAT_MGR_LCD2 = 1 << 7, + FEAT_LINEBUFFERSPLIT = 1 << 8, + FEAT_ROWREPEATENABLE = 1 << 9, + FEAT_RESIZECONF = 1 << 10, /* Independent core clk divider */ - FEAT_CORE_CLK_DIV = 1 << 11, - FEAT_LCD_CLK_SRC = 1 << 12, + FEAT_CORE_CLK_DIV = 1 << 11, + FEAT_LCD_CLK_SRC = 1 << 12, + FEAT_DSI_PLL_FREQSEL = 1 << 13, + FEAT_DSI_LDO_STATUS = 1 << 14, + FEAT_DSI_DCS_CMD_CONFIG_VC = 1 << 15, + FEAT_DSI_VC_OCP_WIDTH = 1 << 16, }; /* DSS register field id */ |