[PATCH v3 1/2] drm/panel: panel-boe-tv101wum-nl6: tune the power sequence to avoid leakage
Kevin Hilman
khilman at baylibre.com
Mon Jan 10 15:34:59 PST 2022
Jitao Shi <jitao.shi at mediatek.com> writes:
> "auo,kd101n80-45na" 2st LCD SPEC update, need to modify the timing
> between IOVCC and mipi data.
> The 2st version of SPEC modifies the timing requirements from IOVCC to
> Mipi Data. IOVCC is now required to take precedence over MIPI DATA,
> otherwise there is a risk of leakage. It is recommended that the time
> for MIPI to enter LP11 be postponed after IOVCC (delay20ms).
Similar to what Daniel said on v2: You're changing the behavior of
*all* users of this panel driver with this patch, in order to fix a
single user (in the next patch.)
> Signed-off-by: Jitao Shi <jitao.shi at mediatek.com>
> Change-Id: Ic5212e2145a7dbf2efef9e5585904a93e1bc5a28
Please drop gerrit IDs from upstream submissions.
Kevin
> ---
> drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c | 88 +++++++++++++++++++-------
> include/drm/panel_boe_tv101wum_nl6.h | 28 ++++++++
> 2 files changed, 94 insertions(+), 22 deletions(-)
> create mode 100644 include/drm/panel_boe_tv101wum_nl6.h
>
> diff --git a/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c b/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c
> index db9d0b86d542..02efee06c430 100644
> --- a/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c
> +++ b/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c
> @@ -49,7 +49,7 @@ struct boe_panel {
> struct regulator *avee;
> struct regulator *avdd;
> struct gpio_desc *enable_gpio;
> -
> + int powered_refcnt;
> bool prepared;
> };
>
> @@ -488,19 +488,15 @@ static int boe_panel_enter_sleep_mode(struct boe_panel *boe)
> return 0;
> }
>
> -static int boe_panel_unprepare(struct drm_panel *panel)
> +static int boe_panel_power_off(struct drm_panel *panel)
> {
> struct boe_panel *boe = to_boe_panel(panel);
> - int ret;
>
> - if (!boe->prepared)
> - return 0;
> + if (WARN_ON(boe->powered_refcnt == 0))
> + return -EINVAL;
>
> - ret = boe_panel_enter_sleep_mode(boe);
> - if (ret < 0) {
> - dev_err(panel->dev, "failed to set panel off: %d\n", ret);
> - return ret;
> - }
> + if (--boe->powered_refcnt != 0)
> + return 0;
>
> msleep(150);
>
> @@ -520,17 +516,45 @@ static int boe_panel_unprepare(struct drm_panel *panel)
> regulator_disable(boe->pp1800);
> }
>
> + return 0;
> +}
> +
> +int panel_unprepare_power(struct drm_panel *panel)
> +{
> + if (of_device_is_compatible(panel->dev->of_node, "auo,kd101n80-45na"))
> + return boe_panel_power_off(panel);
> +
> + return 0;
> +}
> +EXPORT_SYMBOL(panel_unprepare_power);
> +
> +static int boe_panel_unprepare(struct drm_panel *panel)
> +{
> + struct boe_panel *boe = to_boe_panel(panel);
> + int ret;
> +
> + if (!boe->prepared)
> + return 0;
> +
> + ret = boe_panel_enter_sleep_mode(boe);
> + if (ret < 0) {
> + dev_err(panel->dev, "failed to set panel off: %d\n", ret);
> + return ret;
> + }
> +
> + boe_panel_power_off(panel);
> +
> boe->prepared = false;
>
> return 0;
> }
>
> -static int boe_panel_prepare(struct drm_panel *panel)
> +static int boe_panel_power_on(struct drm_panel *panel)
> {
> struct boe_panel *boe = to_boe_panel(panel);
> int ret;
>
> - if (boe->prepared)
> + if (++boe->powered_refcnt != 1)
> return 0;
>
> gpiod_set_value(boe->enable_gpio, 0);
> @@ -558,18 +582,8 @@ static int boe_panel_prepare(struct drm_panel *panel)
> gpiod_set_value(boe->enable_gpio, 1);
> usleep_range(6000, 10000);
>
> - ret = boe_panel_init_dcs_cmd(boe);
> - if (ret < 0) {
> - dev_err(panel->dev, "failed to init panel: %d\n", ret);
> - goto poweroff;
> - }
> -
> - boe->prepared = true;
> -
> return 0;
>
> -poweroff:
> - regulator_disable(boe->avee);
> poweroffavdd:
> regulator_disable(boe->avdd);
> poweroff1v8:
> @@ -580,6 +594,36 @@ static int boe_panel_prepare(struct drm_panel *panel)
> return ret;
> }
>
> +int panel_prepare_power(struct drm_panel *panel)
> +{
> + if (of_device_is_compatible(panel->dev->of_node, "auo,kd101n80-45na"))
> + return boe_panel_power_on(panel);
> +
> + return 0;
> +}
> +EXPORT_SYMBOL(panel_prepare_power);
> +
> +static int boe_panel_prepare(struct drm_panel *panel)
> +{
> + struct boe_panel *boe = to_boe_panel(panel);
> + int ret;
> +
> + boe_panel_power_on(panel);
> +
> + if (boe->prepared)
> + return 0;
> +
> + ret = boe_panel_init_dcs_cmd(boe);
> + if (ret < 0) {
> + dev_err(panel->dev, "failed to init panel: %d\n", ret);
> + return ret;
> + }
> +
> + boe->prepared = true;
> +
> + return 0;
> +}
> +
> static int boe_panel_enable(struct drm_panel *panel)
> {
> msleep(130);
> diff --git a/include/drm/panel_boe_tv101wum_nl6.h b/include/drm/panel_boe_tv101wum_nl6.h
> new file mode 100644
> index 000000000000..72abe3eb7840
> --- /dev/null
> +++ b/include/drm/panel_boe_tv101wum_nl6.h
> @@ -0,0 +1,28 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (c) 2018 MediaTek Inc.
> + * Author: Jitao Shi <jitao.shi at mediatek.com>
> + */
> +
> +#ifndef __PANEL_BOE_TV101WUM_NL6_H__
> +#define __PANEL_BOE_TV101WUM_NL6_H__
> +
> +#include <linux/types.h>
> +#include <drm/drm_panel.h>
> +
> +#if defined(CONFIG_DRM_PANEL_BOE_TV101WUM_NL6)
> +int panel_unprepare_power(struct drm_panel *panel);
> +int panel_prepare_power(struct drm_panel *panel);
> +#else
> +int panel_unprepare_power(struct drm_panel *panel)
> +{
> + return 0;
> +}
> +
> +int panel_prepare_power(struct drm_panel *panel)
> +{
> + return 0;
> +}
> +#endif
> +#endif /* __PANEL_BOE_TV101WUM_NL6_H__ */
> +
> --
> 2.12.5
>
>
> _______________________________________________
> Linux-mediatek mailing list
> Linux-mediatek at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-mediatek
More information about the Linux-mediatek
mailing list