4 * HDMI library support functions for Nvidia Tegra processors.
6 * Copyright (C) 2012-2013 Google - http://www.google.com/
7 * Copyright (C) 2013-2016 NVIDIA CORPORATION. All rights reserved.
8 * Authors: John Grossman <johngro@google.com>
9 * Authors: Mike J. Chen <mjchen@google.com>
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License version 2 as published by
13 * the Free Software Foundation.
15 * This program is distributed in the hope that it will be useful, but WITHOUT
16 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
20 * You should have received a copy of the GNU General Public License along with
21 * this program. If not, see <http://www.gnu.org/licenses/>.
24 #include <linux/kernel.h>
28 #include <linux/switch.h>
30 #include <video/tegrafb.h>
33 #ifdef CONFIG_ADF_TEGRA
34 #include "tegra_adf.h"
37 #include "hdmi_state_machine.h"
39 /************************************************************
41 * state machine internal constants
43 ************************************************************/
44 #define MAX_EDID_READ_ATTEMPTS 5
45 #define HDMI_EDID_MAX_LENGTH 512
47 /* how long of an HPD drop before we consider it gone for good.
48 * this is mostly a preference to work around monitors users
49 * reported that occasionally drop HPD.
51 #define HPD_STABILIZE_MS 40
52 #define HPD_DROP_TIMEOUT_MS 1500
53 #define CHECK_PLUG_STATE_DELAY_MS 10
54 #define CHECK_EDID_DELAY_MS 60
56 /************************************************************
58 * state machine internal state
60 ************************************************************/
61 static DEFINE_RT_MUTEX(work_lock);
62 static struct hdmi_state_machine_worker_data {
63 struct delayed_work dwork;
64 struct tegra_dc_hdmi_data *hdmi;
71 /************************************************************
73 * state machine internal methods
75 ************************************************************/
76 static void hdmi_state_machine_sched_work_l(int resched_time)
78 cancel_delayed_work(&work_state.dwork);
79 if ((resched_time >= 0) && !work_state.shutdown)
80 queue_delayed_work(system_nrt_wq,
82 msecs_to_jiffies(resched_time));
85 static const char * const state_names[] = {
91 "Wait for HPD reassert",
93 "Takeover from bootloader",
96 static void hdmi_state_machine_set_state_l(int target_state, int resched_time)
98 rt_mutex_lock(&work_lock);
100 pr_info("%s: switching from state %d (%s) to state %d (%s)\n",
101 __func__, work_state.state, state_names[work_state.state],
102 target_state, state_names[target_state]);
103 work_state.state = target_state;
105 /* If virtual edid is active, schedule immediately. However, keep
106 * the possible negative value to maintain the transition behavior.
108 if (work_state.hdmi->dc->vedid && resched_time > 0)
111 /* If the pending_hpd_evt flag is already set, don't bother to
112 * reschedule the state machine worker. We should be able to assert
113 * that there is a worker callback already scheduled, and that it is
114 * scheduled to run immediately. This is particularly important when
115 * making the transition to the steady state ENABLED or DISABLED states.
116 * If an HPD event occurs while the worker is in flight, after the
117 * worker checks the state of the pending HPD flag, and then the state
118 * machine transitions to ENABLE or DISABLED, the system would end up
119 * canceling the callback to handle the HPD event were it not for this
122 if (!work_state.pending_hpd_evt)
123 hdmi_state_machine_sched_work_l(resched_time);
125 rt_mutex_unlock(&work_lock);
128 static void hdmi_state_machine_handle_hpd_l(int cur_hpd)
130 int tgt_state, timeout;
132 if ((HDMI_STATE_DONE_ENABLED == work_state.state) && !cur_hpd) {
133 /* Did HPD drop while we were in DONE_ENABLED? If so, hold
134 * steady and wait to see if it comes back.
136 tegra_nvhdcp_set_plug(work_state.hdmi->nvhdcp, 0);
137 tgt_state = HDMI_STATE_DONE_WAIT_FOR_HPD_REASSERT;
138 timeout = HPD_DROP_TIMEOUT_MS;
140 if (HDMI_STATE_DONE_WAIT_FOR_HPD_REASSERT == work_state.state &&
142 /* Looks like HPD dropped and eventually came back. Re-read the
143 * EDID and reset the system only if the EDID has changed.
145 work_state.edid_reads = 0;
146 tgt_state = HDMI_STATE_DONE_RECHECK_EDID;
147 timeout = CHECK_EDID_DELAY_MS;
149 if (HDMI_STATE_DONE_ENABLED == work_state.state && cur_hpd) {
150 /* Looks like HPD dropped but came back quickly, ignore it.
152 pr_info("%s: ignoring bouncing hpd\n", __func__);
155 if (HDMI_STATE_INIT_FROM_BOOTLOADER == work_state.state && cur_hpd) {
156 /* We follow the same protocol as HDMI_STATE_RESET in the
157 * last branch here, but avoid actually entering that state so
158 * we do not actively disable HDMI. Worker will check HPD
159 * level again when it's woke up after 40ms.
161 tgt_state = HDMI_STATE_CHECK_PLUG_STATE;
162 timeout = HPD_STABILIZE_MS;
164 /* Looks like there was HPD activity while we were neither
165 * waiting for it to go away during steady state output, nor
166 * looking for it to come back after such an event. Wait until
167 * HPD has been steady for at least 40 mSec, then restart the
170 tgt_state = HDMI_STATE_RESET;
171 timeout = HPD_STABILIZE_MS;
174 hdmi_state_machine_set_state_l(tgt_state, timeout);
177 /************************************************************
179 * internal state handlers and dispatch table
181 ************************************************************/
182 static void hdmi_disable_l(struct tegra_dc_hdmi_data *hdmi)
184 /* If the hotplug_state is controlled by the hotplug debug node,
185 * the value of dc->connected is changed directly. This affects
186 * the behavior of this function, as the state machine does not
187 * expect dc->connected to be changed externally. In that case,
188 * use a cached value which is only modified by the state machine.
191 if (hdmi->dc->out->hotplug_state == TEGRA_HPD_STATE_NORMAL)
192 was_connected = hdmi->dc->connected;
194 was_connected = hdmi->connected_cache;
196 switch_set_state(&hdmi->audio_switch, 0);
197 pr_info("%s: audio_switch 0\n", __func__);
198 switch_set_state(&hdmi->hpd_switch, 0);
199 pr_info("%s: hpd_switch 0\n", __func__);
201 tegra_nvhdcp_set_plug(hdmi->nvhdcp, 0);
203 pr_info("HDMI from connected to disconnected\n");
204 tegra_dc_disable(hdmi->dc);
206 hdmi->dc->connected = false;
207 hdmi->connected_cache = false;
208 #ifdef CONFIG_ADF_TEGRA
209 tegra_adf_process_hotplug_disconnected(hdmi->dc->adf);
211 tegra_fb_update_monspecs(hdmi->dc->fb, NULL, NULL);
213 #ifdef CONFIG_TEGRA_DC_EXTENSIONS
215 tegra_dc_ext_process_hotplug(hdmi->dc->ndev->id, false);
217 pr_info("%s: skipping redundant disconnect\n", __func__);
221 static void handle_reset_l(struct tegra_dc_hdmi_data *hdmi)
223 /* Were we just reset? If so, shut everything down, then schedule a
224 * check of the plug state in the near future.
226 hdmi_disable_l(hdmi);
227 hdmi_state_machine_set_state_l(HDMI_STATE_CHECK_PLUG_STATE,
228 CHECK_PLUG_STATE_DELAY_MS);
231 static void handle_check_plug_state_l(struct tegra_dc_hdmi_data *hdmi)
233 if (tegra_dc_hpd(work_state.hdmi->dc)) {
234 /* Looks like there is something plugged in.
235 * Get ready to read the sink's EDID information.
237 work_state.edid_reads = 0;
239 hdmi_state_machine_set_state_l(HDMI_STATE_CHECK_EDID,
240 CHECK_EDID_DELAY_MS);
242 /* nothing plugged in, so we are finished. Go to the
243 * DONE_DISABLED state and stay there until the next HPD event.
245 hdmi_disable_l(hdmi);
246 hdmi_state_machine_set_state_l(HDMI_STATE_DONE_DISABLED, -1);
250 static void handle_check_edid_l(struct tegra_dc_hdmi_data *hdmi)
252 struct fb_monspecs specs;
257 memset(&specs, 0, sizeof(specs));
258 #ifdef CONFIG_FRAMEBUFFER_CONSOLE
259 /* Set default videomode on dc before enabling it*/
260 tegra_dc_set_default_videomode(hdmi->dc);
263 if (!tegra_dc_hpd(work_state.hdmi->dc)) {
264 /* hpd dropped - stop EDID read */
265 pr_info("hpd == 0, aborting EDID read\n");
269 if (tegra_edid_get_monspecs(hdmi->edid, &specs)) {
270 /* Failed to read EDID. If we still have retry attempts left,
271 * schedule another attempt. Otherwise give up and just go to
272 * the disabled state.
274 work_state.edid_reads++;
275 if (work_state.edid_reads >= MAX_EDID_READ_ATTEMPTS) {
276 pr_info("Failed to read EDID after %d times. Giving up.\n",
277 work_state.edid_reads);
280 hdmi_state_machine_set_state_l(HDMI_STATE_CHECK_EDID,
281 CHECK_EDID_DELAY_MS);
287 if (tegra_edid_get_eld(hdmi->edid, &hdmi->eld) < 0) {
288 pr_err("error populating eld\n");
291 hdmi->eld_retrieved = true;
293 pr_info("panel size %d by %d\n", specs.max_x, specs.max_y);
295 /* monitors like to lie about these but they are still useful for
296 * detecting aspect ratios
298 hdmi->dc->out->h_size = specs.max_x * 10;
299 hdmi->dc->out->v_size = specs.max_y * 10;
301 hdmi->dvi = !(specs.misc & FB_MISC_HDMI);
303 #ifdef CONFIG_ADF_TEGRA
304 tegra_adf_process_hotplug_connected(hdmi->dc->adf, &specs);
306 #ifdef CONFIG_TEGRA_DC_EXTENSIONS
307 tegra_fb_update_monspecs(hdmi->dc->fb, &specs,
308 tegra_dc_hdmi_mode_filter);
311 state = tegra_edid_audio_supported(hdmi->edid) ? 1 : 0;
312 switch_set_state(&hdmi->audio_switch, state);
313 pr_info("%s: audio_switch %d\n", __func__, state);
314 switch_set_state(&hdmi->hpd_switch, 1);
315 pr_info("Display connected, hpd_switch 1\n");
317 hdmi->dc->connected = true;
318 hdmi->connected_cache = true;
320 #ifdef CONFIG_TEGRA_DC_EXTENSIONS
321 tegra_dc_ext_process_hotplug(hdmi->dc->ndev->id, true);
324 if (unlikely(tegra_is_clk_enabled(hdmi->clk))) {
325 /* the only time this should happen is on boot, where the
326 * sequence is that hdmi is enabled before EDID is read.
327 * hdmi_enable() doesn't have EDID information yet so can't
328 * setup audio and infoframes, so we have to do so here.
330 pr_info("%s: setting audio and infoframes\n", __func__);
331 tegra_dc_io_start(hdmi->dc);
332 tegra_dc_hdmi_setup_audio_and_infoframes(hdmi->dc);
333 tegra_dc_io_end(hdmi->dc);
336 hdmi_state_machine_set_state_l(HDMI_STATE_DONE_ENABLED, -1);
341 hdmi->eld_retrieved = false;
342 hdmi_disable_l(hdmi);
343 hdmi_state_machine_set_state_l(HDMI_STATE_DONE_DISABLED, -1);
346 static void handle_wait_for_hpd_reassert_l(struct tegra_dc_hdmi_data *hdmi)
348 /* Looks like HPD dropped and really did stay low. Go ahead and reset
351 hdmi_state_machine_set_state_l(HDMI_STATE_RESET, 0);
354 /* returns bytes read, or negative error */
355 static int read_edid_into_buffer(struct tegra_dc_hdmi_data *hdmi,
356 u8 *edid_data, size_t edid_data_len)
359 int extension_blocks;
360 int max_ext_blocks = (edid_data_len / 128) - 1;
362 err = tegra_edid_read_block(hdmi->edid, 0, edid_data);
364 pr_err("tegra_edid_read_block(0) returned err %d\n", err);
367 extension_blocks = edid_data[0x7e];
368 pr_info("%s: extension_blocks = %d, max_ext_blocks = %d\n",
369 __func__, extension_blocks, max_ext_blocks);
370 if (extension_blocks > max_ext_blocks)
371 extension_blocks = max_ext_blocks;
372 for (i = 1; i <= extension_blocks; i++) {
373 err = tegra_edid_read_block(hdmi->edid, i, edid_data + i * 128);
375 pr_err("tegra_edid_read_block(%d) returned err %d\n",
383 /* re-read the edid and check to see if it has changed. Return 0 on a
384 * successful E-EDID read, or a non-zero error code on failure. If we succeed,
385 * set match to 1 if the old E-EDID matches the new E-EDID. Otherwise, set
387 static int hdmi_recheck_edid(struct tegra_dc_hdmi_data *hdmi, int *match)
390 u8 tmp[HDMI_EDID_MAX_LENGTH] = {0};
392 ret = read_edid_into_buffer(hdmi, tmp, sizeof(tmp));
393 pr_info("%s: read_edid_into_buffer() returned %d\n", __func__, ret);
395 struct tegra_dc_edid *data = tegra_edid_get_data(hdmi->edid);
396 pr_info("old edid len = %ld\n", (long int)data->len);
397 *match = ((ret == data->len) &&
398 !memcmp(tmp, data->buf, data->len));
400 print_hex_dump(KERN_INFO, "tmp :", DUMP_PREFIX_ADDRESS,
401 16, 4, tmp, ret, true);
402 print_hex_dump(KERN_INFO, "data:", DUMP_PREFIX_ADDRESS,
403 16, 4, data->buf, data->len, true);
405 tegra_edid_put_data(data);
412 static void handle_recheck_edid_l(struct tegra_dc_hdmi_data *hdmi)
414 int match, tgt_state, timeout;
416 tgt_state = HDMI_STATE_RESET;
419 if (hdmi_recheck_edid(hdmi, &match)) {
420 /* Failed to read EDID. If we still have retry attempts left,
421 * schedule another attempt. Otherwise give up and reset;
423 work_state.edid_reads++;
424 if (work_state.edid_reads >= MAX_EDID_READ_ATTEMPTS) {
425 pr_info("Failed to read EDID after %d times. Giving up.\n",
426 work_state.edid_reads);
428 tgt_state = HDMI_STATE_DONE_RECHECK_EDID;
429 timeout = CHECK_EDID_DELAY_MS;
432 /* Successful read! If the EDID is unchanged, just go back to
433 * the DONE_ENABLED state and do nothing. If something changed,
434 * just reset the whole system.
437 pr_info("No EDID change after HPD bounce, taking no action.\n");
438 tgt_state = HDMI_STATE_DONE_ENABLED;
439 if (tegra_is_clk_enabled(hdmi->dc->clk)) {
440 tegra_nvhdcp_set_plug(hdmi->nvhdcp, 0);
441 tegra_nvhdcp_set_plug(hdmi->nvhdcp, 1);
443 pr_info("dc powergated, skipping hdcp reset\n");
447 pr_info("EDID change after HPD bounce, resetting\n");
451 hdmi_state_machine_set_state_l(tgt_state, timeout);
454 typedef void (*dispatch_func_t)(struct tegra_dc_hdmi_data *hdmi);
455 static const dispatch_func_t state_machine_dispatch[] = {
456 handle_reset_l, /* STATE_RESET */
457 handle_check_plug_state_l, /* STATE_CHECK_PLUG_STATE */
458 handle_check_edid_l, /* STATE_CHECK_EDID */
459 NULL, /* STATE_DONE_DISABLED */
460 NULL, /* STATE_DONE_ENABLED */
461 handle_wait_for_hpd_reassert_l, /* STATE_DONE_WAIT_FOR_HPD_REASSERT */
462 handle_recheck_edid_l, /* STATE_DONE_RECHECK_EDID */
463 NULL, /* STATE_INIT_FROM_BOOTLOADER */
466 /************************************************************
468 * main state machine worker function
470 ************************************************************/
471 static void hdmi_state_machine_worker(struct work_struct *work)
473 int pending_hpd_evt, cur_hpd;
475 /* Observe and clear the pending flag and latch the current HPD state.
477 rt_mutex_lock(&work_lock);
478 pending_hpd_evt = work_state.pending_hpd_evt;
479 work_state.pending_hpd_evt = 0;
480 rt_mutex_unlock(&work_lock);
481 cur_hpd = tegra_dc_hpd(work_state.hdmi->dc);
483 pr_info("%s (tid %p): state %d (%s), hpd %d, pending_hpd_evt %d\n",
484 __func__, current, work_state.state,
485 state_names[work_state.state], cur_hpd, pending_hpd_evt);
487 if (pending_hpd_evt) {
488 /* If we were woken up because of HPD activity, just schedule
489 * the next appropriate task and get out.
491 hdmi_state_machine_handle_hpd_l(cur_hpd);
492 } else if (work_state.state < ARRAY_SIZE(state_machine_dispatch)) {
493 dispatch_func_t func = state_machine_dispatch[work_state.state];
496 pr_warn("NULL state machine handler while in state %d; how did we end up here?",
499 func(work_state.hdmi);
501 pr_warn("hdmi state machine worker scheduled unexpected state %d",
506 /************************************************************
508 * state machine API implementation
510 ************************************************************/
511 void hdmi_state_machine_init(struct tegra_dc_hdmi_data *hdmi)
513 work_state.hdmi = hdmi;
514 work_state.state = HDMI_STATE_INIT_FROM_BOOTLOADER;
515 work_state.pending_hpd_evt = 1;
516 work_state.edid_reads = 0;
517 work_state.shutdown = 0;
518 INIT_DELAYED_WORK(&work_state.dwork, hdmi_state_machine_worker);
521 void hdmi_state_machine_shutdown(void)
523 work_state.shutdown = 1;
524 cancel_delayed_work_sync(&work_state.dwork);
527 void hdmi_state_machine_set_pending_hpd(void)
529 rt_mutex_lock(&work_lock);
531 /* We always schedule work any time there is a pending HPD event */
532 work_state.pending_hpd_evt = 1;
533 hdmi_state_machine_sched_work_l(0);
535 rt_mutex_unlock(&work_lock);
538 int hdmi_state_machine_get_state(void)
542 rt_mutex_lock(&work_lock);
543 ret = work_state.state;
544 rt_mutex_unlock(&work_lock);