diff options
| author | Jared Suttles <jsuttles@motorola.com> | 2014-05-01 11:57:41 -0500 |
|---|---|---|
| committer | audahadi <wan.audahadi@gmail.com> | 2015-08-24 04:08:20 +0800 |
| commit | abd2d3c7025e51e81c2dfb384fc9b8efd4759c31 (patch) | |
| tree | d3a3352db3c82f7ff59d6491990ec1ec3cf439b5 | |
| parent | ff4f2765d9aff89a2b6b82df0f707fcc9ccbad25 (diff) | |
msm: mdss: dont turn off the panel if it isnt on
It is possible to turn mdp on and then off without ever committing a
frame. In this case the driver gets out of sync because it doesnt check
to make sure the panel is on before attempting to turn it off.
Reviewed-by: Patrick Auchter <auchter@motorola.com>
Reviewed-by: Bang Nguyen <bangnguyen@motorola.com>
Reviewed-by: Joseph Swantek <jswantek@motorola.com>
Conflicts:
drivers/video/msm/mdss/mdss_mdp_intf_cmd.c
Change-Id: I2ed17929bfab231566fb0fe1feea20cb2db1ccd3
Signed-off-by: Jared Suttles <jsuttles@motorola.com>
| -rw-r--r-- | drivers/video/msm/mdss/lcd_notify.c | 52 | ||||
| -rw-r--r-- | drivers/video/msm/mdss/mdss_mdp_intf_cmd.c | 13 | ||||
| -rw-r--r-- | drivers/video/msm/mdss/mdss_mdp_trace.h | 255 |
3 files changed, 316 insertions, 4 deletions
diff --git a/drivers/video/msm/mdss/lcd_notify.c b/drivers/video/msm/mdss/lcd_notify.c new file mode 100644 index 00000000000..3b5a96c12ce --- /dev/null +++ b/drivers/video/msm/mdss/lcd_notify.c @@ -0,0 +1,52 @@ +/* + * drivers/video/msm/mdss/lcd_notify.c + * + * Copyright (C) 2013 LGE Inc + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <linux/lcd_notify.h> +#include <linux/notifier.h> +#include <linux/export.h> + +static BLOCKING_NOTIFIER_HEAD(lcd_notifier_list); + +/** + * lcd_register_client - register a client notifier + * @nb: notifier block to callback on events + */ +int lcd_register_client(struct notifier_block *nb) +{ + return blocking_notifier_chain_register(&lcd_notifier_list, nb); +} +EXPORT_SYMBOL(lcd_register_client); + +/** + * lcd_unregister_client - unregister a client notifier + * @nb: notifier block to callback on events + */ +int lcd_unregister_client(struct notifier_block *nb) +{ + return blocking_notifier_chain_unregister(&lcd_notifier_list, nb); +} +EXPORT_SYMBOL(lcd_unregister_client); + +/** + * lcd_notifier_call_chain - notify clients on lcd_events + * @val: Value passed unmodified to notifier function + * @v: pointer passed unmodified to notifier function + * + */ +int lcd_notifier_call_chain(unsigned long val, void *v) +{ + return blocking_notifier_call_chain(&lcd_notifier_list, val, v); +} +EXPORT_SYMBOL_GPL(lcd_notifier_call_chain); diff --git a/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c b/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c index f837c3d7887..b6a36272a4e 100644 --- a/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c +++ b/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c @@ -599,6 +599,7 @@ int mdss_mdp_cmd_stop(struct mdss_mdp_ctl *ctl) int need_wait = 0; int hz; int ret = 0, i = 0, rc = 0; + int turn_off_panel = 0; ctx = (struct mdss_mdp_cmd_ctx *) ctl->priv_data; if (!ctx) { @@ -652,6 +653,8 @@ int mdss_mdp_cmd_stop(struct mdss_mdp_ctl *ctl) MDSS_EVENT_REGISTER_RECOVERY_HANDLER, NULL); + turn_off_panel = ctx->panel_on; + ctx->panel_on = 0; mdss_mdp_cmd_clk_off(ctx); flush_work(&ctx->pp_done_work); @@ -666,11 +669,13 @@ int mdss_mdp_cmd_stop(struct mdss_mdp_ctl *ctl) memset(ctx, 0, sizeof(*ctx)); ctl->priv_data = NULL; - ret = mdss_mdp_ctl_intf_event(ctl, MDSS_EVENT_BLANK, NULL); - WARN(ret, "intf %d unblank error (%d)\n", ctl->intf_num, ret); + if (turn_off_panel) { + ret = mdss_mdp_ctl_intf_event(ctl, MDSS_EVENT_BLANK, NULL); + WARN(ret, "intf %d unblank error (%d)\n", ctl->intf_num, ret); - ret = mdss_mdp_ctl_intf_event(ctl, MDSS_EVENT_PANEL_OFF, NULL); - WARN(ret, "intf %d unblank error (%d)\n", ctl->intf_num, ret); + ret = mdss_mdp_ctl_intf_event(ctl, MDSS_EVENT_PANEL_OFF, NULL); + WARN(ret, "intf %d unblank error (%d)\n", ctl->intf_num, ret); + } ctl->stop_fnc = NULL; ctl->display_fnc = NULL; diff --git a/drivers/video/msm/mdss/mdss_mdp_trace.h b/drivers/video/msm/mdss/mdss_mdp_trace.h new file mode 100644 index 00000000000..730b7ff5a85 --- /dev/null +++ b/drivers/video/msm/mdss/mdss_mdp_trace.h @@ -0,0 +1,255 @@ +/* + * Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#if !defined(TRACE_MDSS_MDP_H) || defined(TRACE_HEADER_MULTI_READ) +#define TRACE_MDSS_MDP_H + +#undef TRACE_SYSTEM +#define TRACE_SYSTEM mdss +#undef TRACE_INCLUDE_PATH +#define TRACE_INCLUDE_PATH ../../drivers/video/msm/mdss +#undef TRACE_INCLUDE_FILE +#define TRACE_INCLUDE_FILE mdss_mdp_trace + +#include <linux/tracepoint.h> +#include "mdss_mdp.h" + +DECLARE_EVENT_CLASS(mdp_sspp_template, + TP_PROTO(struct mdss_mdp_pipe *pipe), + TP_ARGS(pipe), + TP_STRUCT__entry( + __field(u32, num) + __field(u32, play_cnt) + __field(u32, mixer) + __field(u32, stage) + __field(u32, flags) + __field(u32, format) + __field(u16, img_w) + __field(u16, img_h) + __field(u16, src_x) + __field(u16, src_y) + __field(u16, src_w) + __field(u16, src_h) + __field(u16, dst_x) + __field(u16, dst_y) + __field(u16, dst_w) + __field(u16, dst_h) + ), + TP_fast_assign( + __entry->num = pipe->num; + __entry->play_cnt = pipe->play_cnt; + __entry->mixer = pipe->mixer->num; + __entry->stage = pipe->mixer_stage; + __entry->flags = pipe->flags; + __entry->format = pipe->src_fmt ? + pipe->src_fmt->format : -1; + __entry->img_w = pipe->img_width; + __entry->img_h = pipe->img_height; + __entry->src_x = pipe->src.x; + __entry->src_y = pipe->src.y; + __entry->src_w = pipe->src.w; + __entry->src_h = pipe->src.h; + __entry->dst_x = pipe->dst.x; + __entry->dst_y = pipe->dst.y; + __entry->dst_w = pipe->dst.w; + __entry->dst_h = pipe->dst.h; + ), + + TP_printk("num=%d mixer=%d play_cnt=%d flags=0x%x stage=%d format=%d img=%dx%d src=[%d,%d,%d,%d] dst=[%d,%d,%d,%d]", + __entry->num, __entry->mixer, __entry->play_cnt, + __entry->flags, __entry->stage, + __entry->format, __entry->img_w, __entry->img_h, + __entry->src_x, __entry->src_y, + __entry->src_w, __entry->src_h, + __entry->dst_x, __entry->dst_y, + __entry->dst_w, __entry->dst_h) +); + +DEFINE_EVENT(mdp_sspp_template, mdp_sspp_set, + TP_PROTO(struct mdss_mdp_pipe *pipe), + TP_ARGS(pipe) +); + +DEFINE_EVENT(mdp_sspp_template, mdp_sspp_change, + TP_PROTO(struct mdss_mdp_pipe *pipe), + TP_ARGS(pipe) +); + +TRACE_EVENT(mdp_mixer_update, + TP_PROTO(u32 mixer_num), + TP_ARGS(mixer_num), + TP_STRUCT__entry( + __field(u32, mixer_num) + ), + TP_fast_assign( + __entry->mixer_num = mixer_num; + ), + TP_printk("mixer=%d", + __entry->mixer_num) +); + +TRACE_EVENT(mdp_commit, + TP_PROTO(struct mdss_mdp_ctl *ctl), + TP_ARGS(ctl), + TP_STRUCT__entry( + __field(u32, num) + __field(u32, play_cnt) + __field(u32, clk_rate) + __field(u64, bandwidth) + ), + TP_fast_assign( + __entry->num = ctl->num; + __entry->play_cnt = ctl->play_cnt; + __entry->clk_rate = ctl->new_perf.mdp_clk_rate; + __entry->bandwidth = ctl->new_perf.bw_ctl; + ), + TP_printk("num=%d play_cnt=%d bandwidth=%llu clk_rate=%u", + __entry->num, + __entry->play_cnt, + __entry->bandwidth, + __entry->clk_rate) +); + +TRACE_EVENT(mdp_video_underrun_done, + TP_PROTO(u32 ctl_num, u32 underrun_cnt), + TP_ARGS(ctl_num, underrun_cnt), + TP_STRUCT__entry( + __field(u32, ctl_num) + __field(u32, underrun_cnt) + ), + TP_fast_assign( + __entry->ctl_num = ctl_num; + __entry->underrun_cnt = underrun_cnt; + ), + TP_printk("ctl=%d count=%d", + __entry->ctl_num, __entry->underrun_cnt) +); + +TRACE_EVENT(mdp_perf_update_bus, + TP_PROTO(unsigned long long ab_quota, unsigned long long ib_quota), + TP_ARGS(ab_quota, ib_quota), + TP_STRUCT__entry( + __field(u64, ab_quota) + __field(u64, ib_quota) + ), + TP_fast_assign( + __entry->ab_quota = ab_quota; + __entry->ib_quota = ib_quota; + ), + TP_printk("ab=%llu ib=%llu", + __entry->ab_quota, + __entry->ib_quota) +); + +TRACE_EVENT(mdp_cmd_pingpong_done, + TP_PROTO(struct mdss_mdp_ctl *ctl, u32 pp_num, int koff_cnt), + TP_ARGS(ctl, pp_num, koff_cnt), + TP_STRUCT__entry( + __field(u32, ctl_num) + __field(u32, intf_num) + __field(u32, pp_num) + __field(int, koff_cnt) + ), + TP_fast_assign( + __entry->ctl_num = ctl->num; + __entry->intf_num = ctl->intf_num; + __entry->pp_num = pp_num; + __entry->koff_cnt = koff_cnt; + ), + TP_printk("ctl num:%d intf_num:%d ctx:%d kickoff:%d", + __entry->ctl_num, __entry->intf_num, __entry->pp_num, + __entry->koff_cnt) +); + +TRACE_EVENT(mdp_cmd_release_bw, + TP_PROTO(u32 ctl_num), + TP_ARGS(ctl_num), + TP_STRUCT__entry( + __field(u32, ctl_num) + ), + TP_fast_assign( + __entry->ctl_num = ctl_num; + ), + TP_printk("ctl num:%d", __entry->ctl_num) +); + +TRACE_EVENT(mdp_cmd_kickoff, + TP_PROTO(u32 ctl_num, int kickoff_cnt), + TP_ARGS(ctl_num, kickoff_cnt), + TP_STRUCT__entry( + __field(u32, ctl_num) + __field(int, kickoff_cnt) + ), + TP_fast_assign( + __entry->ctl_num = ctl_num; + __entry->kickoff_cnt = kickoff_cnt; + ), + TP_printk("kickoff ctl=%d cnt=%d", + __entry->ctl_num, + __entry->kickoff_cnt) +); + +TRACE_EVENT(mdp_cmd_wait_pingpong, + TP_PROTO(u32 ctl_num, int kickoff_cnt), + TP_ARGS(ctl_num, kickoff_cnt), + TP_STRUCT__entry( + __field(u32, ctl_num) + __field(int, kickoff_cnt) + ), + TP_fast_assign( + __entry->ctl_num = ctl_num; + __entry->kickoff_cnt = kickoff_cnt; + ), + TP_printk("pingpong ctl=%d cnt=%d", + __entry->ctl_num, + __entry->kickoff_cnt) +); + +TRACE_EVENT(tracing_mark_write, + TP_PROTO(int pid, const char *name, bool trace_begin), + TP_ARGS(pid, name, trace_begin), + TP_STRUCT__entry( + __field(int, pid) + __string(trace_name, name) + __field(bool, trace_begin) + ), + TP_fast_assign( + __entry->pid = pid; + __assign_str(trace_name, name); + __entry->trace_begin = trace_begin; + ), + TP_printk("%s|%d|%s", __entry->trace_begin ? "B" : "E", + __entry->pid, __get_str(trace_name)) +); + +TRACE_EVENT(mdp_trace_counter, + TP_PROTO(int pid, char *name, int value), + TP_ARGS(pid, name, value), + TP_STRUCT__entry( + __field(int, pid) + __string(counter_name, name) + __field(int, value) + ), + TP_fast_assign( + __entry->pid = current->tgid; + __assign_str(counter_name, name); + __entry->value = value; + ), + TP_printk("%d|%s|%d", __entry->pid, + __get_str(counter_name), __entry->value) +); + +#endif /* if !defined(TRACE_MDSS_MDP_H) || defined(TRACE_HEADER_MULTI_READ) */ + +/* This part must be outside protection */ +#include <trace/define_trace.h> |
