diff options
| -rw-r--r-- | arch/arm/configs/minnow_defconfig | 3 | ||||
| -rw-r--r-- | drivers/leds/leds-lm3535.c | 21 | ||||
| -rw-r--r-- | drivers/video/omap2/displays/panel-minnow.c | 187 | ||||
| -rw-r--r-- | drivers/video/omap2/dss/core.c | 3 | ||||
| -rw-r--r-- | drivers/video/omap2/dss/dsi.c | 21 | ||||
| -rw-r--r-- | kernel/power/Kconfig | 7 | 
6 files changed, 125 insertions, 117 deletions
| diff --git a/arch/arm/configs/minnow_defconfig b/arch/arm/configs/minnow_defconfig index 285b69e34af..4eb092c483d 100644 --- a/arch/arm/configs/minnow_defconfig +++ b/arch/arm/configs/minnow_defconfig @@ -555,6 +555,7 @@ CONFIG_PM_OPP=y  CONFIG_PM_CLK=y  CONFIG_CPU_PM=y  # CONFIG_SUSPEND_TIME is not set +CONFIG_HAS_AMBIENTMODE=y  CONFIG_ARCH_SUSPEND_POSSIBLE=y  CONFIG_ARM_CPU_SUSPEND=y  CONFIG_NET=y @@ -1763,7 +1764,7 @@ CONFIG_FB_MODE_HELPERS=y  # CONFIG_FB_SIMPLE is not set  CONFIG_OMAP2_VRFB=y  CONFIG_OMAP2_DSS=y -CONFIG_OMAP2_DSS_DEBUG=y +# CONFIG_OMAP2_DSS_DEBUG is not set  CONFIG_OMAP2_DSS_DEBUGFS=y  # CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS is not set  # CONFIG_OMAP2_DSS_DPI is not set diff --git a/drivers/leds/leds-lm3535.c b/drivers/leds/leds-lm3535.c index 03915b63b5e..20dbf96c408 100644 --- a/drivers/leds/leds-lm3535.c +++ b/drivers/leds/leds-lm3535.c @@ -187,11 +187,12 @@ static struct early_suspend early_suspend_data = {      .suspend = lm3535_early_suspend,      .resume = lm3535_late_resume,  }; -  #endif +#if defined(CONFIG_HAS_EARLYSUSPEND) || !defined(CONFIG_HAS_AMBIENTMODE)  static int lm3535_suspend (struct i2c_client *client, pm_message_t mesg);  static int lm3535_resume (struct i2c_client *client);  #endif +#endif  static void (*lm3535_set_options_f)(uint8_t *buf, unsigned ramp) =       lm3535_set_options_r1; @@ -235,7 +236,7 @@ static struct i2c_driver lm3535_driver =      .id_table = lm3535_id,      .probe = lm3535_probe,      .remove  = lm3535_remove, -#ifndef CONFIG_HAS_EARLYSUSPEND +#if !defined(CONFIG_HAS_EARLYSUSPEND) && !defined(CONFIG_HAS_AMBIENTMODE)      .suspend    = lm3535_suspend,      .resume     = lm3535_resume,  #endif @@ -499,14 +500,12 @@ static void lm3535_brightness_set (struct led_classdev *led_cdev,      bright_zone = atomic_read (&lm3535_data.bright_zone);      mutex_lock (&lm3535_mutex); -    if (value == -1) { // Special case for ALS adjustment -        value = led_cdev->brightness; -    } - -    if ((value > 0) && (value <= 5)) -        value = 0; /* Special case for G2 */ -    if ((value > 5) && (value <= 10)) -        value = 1; /* Special dim case for G2 */ +    if (value == -1) +        value = led_cdev->brightness; /* Special case for ALS adjustment */ +    else if ((value > 0) && (value < 5)) +        value = 0; /* Special case for turn off */ +    else if ((value >= 5) && (value < 10)) +        value = 1; /* Special case for dim */      if ((value == 0) && (!lm3535_data.enabled)) {          /* If LED already disabled, we don't need to do anything */ @@ -1321,6 +1320,7 @@ static int lm3535_remove (struct i2c_client *client)      return 0;  } +#if defined(CONFIG_HAS_EARLYSUSPEND) || !defined(CONFIG_HAS_AMBIENTMODE)  static int lm3535_suspend (struct i2c_client *client, pm_message_t mesg)  {      printk_suspend ("%s: called with pm message %d\n",  @@ -1363,6 +1363,7 @@ static int lm3535_resume (struct i2c_client *client)      return 0;  } +#endif  #ifdef CONFIG_HAS_EARLYSUSPEND  static void lm3535_early_suspend (struct early_suspend *h) diff --git a/drivers/video/omap2/displays/panel-minnow.c b/drivers/video/omap2/displays/panel-minnow.c index ed9b9c7eea8..31c90f7faeb 100644 --- a/drivers/video/omap2/displays/panel-minnow.c +++ b/drivers/video/omap2/displays/panel-minnow.c @@ -408,6 +408,7 @@ struct minnow_panel_data {  	/* runtime variables */  	bool enabled; +	bool interactive;  	enum minnow_panel_dummy_type dummy_panel;  	bool te_enabled; @@ -494,22 +495,6 @@ exit1:  static void minnow_panel_esd_work(struct work_struct *work);  static void minnow_panel_ulps_work(struct work_struct *work); -static void hw_guard_start(struct minnow_panel_data *mpd, int guard_msec) -{ -	mpd->hw_guard_wait = msecs_to_jiffies(guard_msec); -	mpd->hw_guard_end = jiffies + mpd->hw_guard_wait; -} - -static void hw_guard_wait(struct minnow_panel_data *mpd) -{ -	unsigned long wait = mpd->hw_guard_end - jiffies; - -	if ((long)wait > 0 && wait <= mpd->hw_guard_wait) { -		set_current_state(TASK_UNINTERRUPTIBLE); -		schedule_timeout(wait); -	} -} -  static int set_bridge_retrans(struct minnow_panel_data *mpd, int enable)  {  	u8 data[2] = {0xFF, enable ? 0x01 : 0x00}; @@ -545,33 +530,6 @@ static int minnow_panel_dcs_write_1(struct minnow_panel_data *mpd, u8 dcs_cmd, u  	return dsi_vc_dcs_write(mpd->dssdev, mpd->channel, buf, 2);  } -static int minnow_panel_sleep_out(struct minnow_panel_data *mpd) -{ -	int r; - -	hw_guard_wait(mpd); - -	r = minnow_panel_dcs_write_0(mpd, MIPI_DCS_EXIT_SLEEP_MODE); -	if (r) -		return r; -	if (mpd->id_panel == MINNOW_PANEL_CM_BRIDGE_320X320) { -		r = set_bridge_retrans(mpd, true); -		if (!r) { -			r = minnow_panel_dcs_write_0(mpd, -						MIPI_DCS_EXIT_SLEEP_MODE); -			set_bridge_retrans(mpd, false); -		} -		if (r) -			return r; -	} - -	hw_guard_start(mpd, 120); - -	msleep(10); - -	return 0; -} -  static int minnow_panel_get_bridge_rev(struct minnow_panel_data *mpd,  					u8 *id1, u8 *id2, u8 *id3)  { @@ -976,11 +934,12 @@ static int minnow_panel_enter_ulps(struct omap_dss_device *dssdev)  	omapdss_dsi_display_disable(dssdev, false, true);  	mpd->ulps_enabled = true; +	dev_info(&dssdev->dev, "entered ULPS mode\n");  	return 0;  err: -	dev_err(&dssdev->dev, "enter ULPS failed"); +	dev_err(&dssdev->dev, "enter ULPS failed\n");  	minnow_panel_reset(dssdev);  	mpd->ulps_enabled = false; @@ -1019,10 +978,12 @@ static int minnow_panel_exit_ulps(struct omap_dss_device *dssdev)  	mpd->ulps_enabled = false; +	dev_info(&dssdev->dev, "exited ULPS mode\n"); +  	return 0;  err2: -	dev_err(&dssdev->dev, "failed to exit ULPS"); +	dev_err(&dssdev->dev, "failed to exit ULPS\n");  	r = minnow_panel_reset(dssdev);  	if (!r) { @@ -1384,6 +1345,7 @@ static ssize_t minnow_panel_show_ulps_timeout(struct device *dev,  	return snprintf(buf, PAGE_SIZE, "%u\n", t);  } +#ifdef	DEBUG  static ssize_t minnow_panel_store_init_data(struct device *dev,  		struct device_attribute *attr,  		const char *buf, size_t count) @@ -1440,6 +1402,56 @@ static ssize_t minnow_panel_show_init_data(struct device *dev,  	return i < PAGE_SIZE ? i : PAGE_SIZE;  } +#endif + +static ssize_t minnow_panel_show_interactivemode(struct device *dev, +		struct device_attribute *attr, +		char *buf) +{ +	struct omap_dss_device *dssdev = to_dss_device(dev); +	struct minnow_panel_data *mpd = dev_get_drvdata(&dssdev->dev); +	unsigned t; + +	mutex_lock(&mpd->lock); +	t = mpd->interactive; +	mutex_unlock(&mpd->lock); + +	return snprintf(buf, PAGE_SIZE, "%u\n", t); +} + +static ssize_t minnow_panel_store_interactivemode(struct device *dev, +		struct device_attribute *attr, +		const char *buf, size_t count) +{ +	struct omap_dss_device *dssdev = to_dss_device(dev); +	struct minnow_panel_data *mpd = dev_get_drvdata(&dssdev->dev); +	unsigned long t; +	int r; + +	r = strict_strtoul(buf, 10, &t); +	if (!r) { +		bool enable = !!t; +		/* Temporary force DSI goto ULPS mode when interactive mode +		 * turns OFF, it will add support to switch bridge/panel to +		 * low refresh mode later +		 */ +		mutex_lock(&mpd->lock); +		if (mpd->enabled && (mpd->interactive != enable)) { +			mpd->interactive = enable; +			dsi_bus_lock(dssdev); +			if (enable) +				r = minnow_panel_wake_up(dssdev); +			else +				r = minnow_panel_enter_ulps(dssdev); +			dsi_bus_unlock(dssdev); +		} +		mutex_unlock(&mpd->lock); +		dev_info(&dssdev->dev, "%s interactive mode%s\n", +			 enable ? "enable" : "disable", r ? " failed" : ""); +	} + +	return r ? r : count; +}  static DEVICE_ATTR(num_dsi_errors, S_IRUGO, minnow_panel_num_errors_show, NULL);  static DEVICE_ATTR(hw_revision, S_IRUGO, minnow_panel_hw_revision_show, NULL); @@ -1453,8 +1465,12 @@ static DEVICE_ATTR(ulps, S_IRUGO | S_IWUSR,  		minnow_panel_show_ulps, minnow_panel_store_ulps);  static DEVICE_ATTR(ulps_timeout, S_IRUGO | S_IWUSR,  		minnow_panel_show_ulps_timeout, minnow_panel_store_ulps_timeout); +#ifdef	DEBUG  static DEVICE_ATTR(init_data, S_IRUGO | S_IWUSR,  		minnow_panel_show_init_data, minnow_panel_store_init_data); +#endif +static DEVICE_ATTR(interactivemode, S_IRUGO | S_IWUSR, +		minnow_panel_show_interactivemode, minnow_panel_store_interactivemode);  static struct attribute *minnow_panel_attrs[] = {  	&dev_attr_num_dsi_errors.attr, @@ -1464,7 +1480,10 @@ static struct attribute *minnow_panel_attrs[] = {  	&dev_attr_esd_interval.attr,  	&dev_attr_ulps.attr,  	&dev_attr_ulps_timeout.attr, +#ifdef	DEBUG  	&dev_attr_init_data.attr, +#endif +	&dev_attr_interactivemode.attr,  	NULL,  }; @@ -1645,7 +1664,8 @@ static int minnow_panel_dt_init(struct minnow_panel_data *mpd)  		mpd->esd_interval = value;  		DTINFO("esd_interval = %d\n", mpd->esd_interval);  	} -	mpd->ulps_timeout = 0; +	/* automatically go to ULPS mode for none-update within 250ms */ +	mpd->ulps_timeout = 250;  	mpd->use_dsi_backlight = false;  	mpd->pin_config.num_pins = 4; @@ -1989,23 +2009,17 @@ init_start:  	/* for the first time power on, do not reset h/w to keep logo on */  	if (mpd->first_enable && def_skip_first_init) {  		dsi_vc_send_bta_sync(dssdev, mpd->channel); -		retry = 0; -	} else +	} else {  		_minnow_panel_hw_reset(dssdev); -	while (retry--) {  		r = minnow_panel_process_cmdbuf(mpd, &mpd->power_on);  		if (!r) {  			if (mpd->dummy_panel == DUMMY_DISABLED)  				r = minnow_panel_check_panel_status(mpd); -			if (!r) -				break;  		} -		if (!retry) -			goto err; -		dev_err(&dssdev->dev, "Reset hardware to retry ...\n"); -		_minnow_panel_hw_reset(dssdev); -		/* for dummy panel, it needs reset DSI */ -		if (mpd->dummy_panel == DUMMY_ENABLED) { +		if (r) { +			if (!retry--) +				goto err; +			dev_err(&dssdev->dev, "Reset hardware to retry ...\n");  			omapdss_dsi_display_disable(dssdev, true, false);  			goto init_start;  		} @@ -2033,7 +2047,8 @@ init_start:  	if (r)  		goto err; -	mpd->enabled = 1; +	mpd->enabled = true; +	mpd->interactive = true;  	if (mpd->first_enable)  		dev_info(&dssdev->dev, "panel revision %02x.%02x.%02x\n", @@ -2064,7 +2079,8 @@ static void minnow_panel_power_off(struct omap_dss_device *dssdev)  	omapdss_dsi_display_disable(dssdev, true, false); -	mpd->enabled = 0; +	mpd->enabled = false; +	mpd->interactive = false;  }  static int minnow_panel_reset(struct omap_dss_device *dssdev) @@ -2211,25 +2227,23 @@ static int minnow_panel_update(struct omap_dss_device *dssdev,  				    u16 x, u16 y, u16 w, u16 h)  {  	struct minnow_panel_data *mpd = dev_get_drvdata(&dssdev->dev); -	int r; +	int r = 0;  	/* for video mode, do not need manual update */  	if (mpd->dsi_config.mode == OMAP_DSS_DSI_VIDEO_MODE) -		return 0; +		return r;  	dev_dbg(&dssdev->dev, "update %d, %d, %d x %d\n", x, y, w, h);  	mutex_lock(&mpd->lock);  	dsi_bus_lock(dssdev); -	r = minnow_panel_wake_up(dssdev); -	if (r) +	if (!mpd->enabled)  		goto err; -	if (!mpd->enabled) { -		r = 0; +	r = minnow_panel_wake_up(dssdev); +	if (r)  		goto err; -	}  	/* XXX no need to send this every frame, but dsi break if not done */  	r = minnow_panel_set_update_window(mpd, 0, 0, @@ -2471,7 +2485,6 @@ static void minnow_panel_esd_work(struct work_struct *work)  	struct minnow_panel_data *mpd = container_of(work, struct minnow_panel_data,  			esd_work.work);  	struct omap_dss_device *dssdev = mpd->dssdev; -	u8 state1, state2;  	int r;  	mutex_lock(&mpd->lock); @@ -2489,57 +2502,29 @@ static void minnow_panel_esd_work(struct work_struct *work)  		goto err;  	} -	r = minnow_panel_dcs_read_1(mpd, MIPI_DCS_GET_DIAGNOSTIC_RESULT, &state1); -	if (r) { -		dev_err(&dssdev->dev, "failed to read minnow-panel status\n"); -		goto err; -	} - -	/* Run self diagnostics */ -	r = minnow_panel_sleep_out(mpd); -	if (r) { -		dev_err(&dssdev->dev, "failed to run minnow-panel self-diagnostics\n"); -		goto err; -	} - -	r = minnow_panel_dcs_read_1(mpd, MIPI_DCS_GET_DIAGNOSTIC_RESULT, &state2); +	r = minnow_panel_check_panel_status(mpd);  	if (r) {  		dev_err(&dssdev->dev, "failed to read minnow-panel status\n");  		goto err;  	} -	/* Each sleep out command will trigger a self diagnostic and flip -	 * Bit6 if the test passes. -	 */ -	if (!((state1 ^ state2) & (1 << 6))) { -		dev_err(&dssdev->dev, "LCD self diagnostics failed\n"); -		goto err; -	} -	/* Self-diagnostics result is also shown on TE GPIO line. We need -	 * to re-enable TE after self diagnostics */ -	if (mpd->te_enabled && gpio_is_valid(mpd->ext_te_gpio)) { -		r = minnow_panel_dcs_write_1(mpd, MIPI_DCS_SET_TEAR_ON, 0); -		if (r) -			goto err; -	} +	if (!mpd->interactive) +		minnow_panel_enter_ulps(dssdev);  	dsi_bus_unlock(dssdev);  	minnow_panel_queue_esd_work(dssdev); -  	mutex_unlock(&mpd->lock);  	return;  err:  	dev_err(&dssdev->dev, "performing LCD reset\n"); -	minnow_panel_reset(dssdev); -  	dsi_bus_unlock(dssdev); - -	minnow_panel_queue_esd_work(dssdev); -  	mutex_unlock(&mpd->lock); + +	minnow_panel_disable(dssdev); +	minnow_panel_enable(dssdev);  }  static struct omap_dss_driver minnow_panel_driver = { diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c index e08d71fef88..fc053fe1991 100644 --- a/drivers/video/omap2/dss/core.c +++ b/drivers/video/omap2/dss/core.c @@ -216,6 +216,7 @@ static int omap_dss_pm_notif(struct notifier_block *b, unsigned long v, void *d)  	DSSDBG("pm notif %lu\n", v);  	switch (v) { +#if !defined(CONFIG_HAS_AMBIENTMODE)  	case PM_SUSPEND_PREPARE:  		DSSDBG("suspending displays\n");  		return dss_suspend_all_devices(); @@ -223,7 +224,7 @@ static int omap_dss_pm_notif(struct notifier_block *b, unsigned long v, void *d)  	case PM_POST_SUSPEND:  		DSSDBG("resuming displays\n");  		return dss_resume_all_devices(); - +#endif  	default:  		return 0;  	} diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index 69b44185ed1..e2a0260a298 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -4570,6 +4570,22 @@ static void dsi_display_uninit_dsi(struct platform_device *dsidev,  	dsi_pll_uninit(dsidev, disconnect_lanes);  } +static int dsi_soft_reset(struct platform_device *dsidev) +{ +	int i = 5; +	/* enable DSI soft reset */ +	REG_FLD_MOD(dsidev, DSI_SYSCONFIG, 1, 1, 1); +	/* waiting for DSI soft reset done*/ +	while (REG_GET(dsidev, DSI_SYSSTATUS, 0, 0) == 0) { +		if (!i--) { +			DSSERR("DSI soft reset failed!\n"); +			return -ENODEV; +		} +		udelay(1); +	} +	return 0; +} +  int omapdss_dsi_display_enable(struct omap_dss_device *dssdev)  {  	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); @@ -4594,10 +4610,7 @@ int omapdss_dsi_display_enable(struct omap_dss_device *dssdev)  	dsi_enable_pll_clock(dsidev, 1); -#ifndef CONFIG_OMAP2_DSS_RESET -	dsi_vc_enable(dsidev, 0, 0); -	dsi_vc_enable(dsidev, 1, 0); -#endif +	dsi_soft_reset(dsidev);  	_dsi_initialize_irq(dsidev); diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig index f8cc6c43efe..361341b6069 100644 --- a/kernel/power/Kconfig +++ b/kernel/power/Kconfig @@ -289,3 +289,10 @@ config SUSPEND_TIME  	  Prints the time spent in suspend in the kernel log, and  	  keeps statistics on the time spent in suspend in  	  /sys/kernel/debug/suspend_time + +config HAS_AMBIENTMODE +	def_bool y +	depends on PM +	---help--- +	  Ambient mode should not turn off/on display/back-light/etc. +	  at suspend/resume time |