static void handle_check_edid_l(struct tegra_dc_hdmi_data *hdmi) { struct fb_monspecs specs; #ifdef CONFIG_SWITCH int state; #endif memset(&specs, 0, sizeof(specs)); #ifdef CONFIG_FRAMEBUFFER_CONSOLE /* Set default videomode on dc before enabling it*/ tegra_dc_set_default_videomode(hdmi->dc); #endif if (!tegra_dc_hpd(work_state.hdmi->dc)) { /* hpd dropped - stop EDID read */ pr_info("hpd == 0, aborting EDID read\n"); goto end_disabled; } if (tegra_edid_get_monspecs(hdmi->edid, &specs)) { /* Failed to read EDID. If we still have retry attempts left, * schedule another attempt. Otherwise give up and just go to * the disabled state. */ work_state.edid_reads++; if (work_state.edid_reads >= MAX_EDID_READ_ATTEMPTS) { pr_info("Failed to read EDID after %d times. Giving up.\n", work_state.edid_reads); goto end_disabled; } else { hdmi_state_machine_set_state_l(HDMI_STATE_CHECK_EDID, CHECK_EDID_DELAY_MS); } return; } if (tegra_edid_get_eld(hdmi->edid, &hdmi->eld) < 0) { pr_err("error populating eld\n"); goto end_disabled; } hdmi->eld_retrieved = true; pr_info("panel size %d by %d\n", specs.max_x, specs.max_y); /* monitors like to lie about these but they are still useful for * detecting aspect ratios */ hdmi->dc->out->h_size = specs.max_x * 1000; hdmi->dc->out->v_size = specs.max_y * 1000; hdmi->dvi = !(specs.misc & FB_MISC_HDMI); /* Need to unpowergate DC if it was powergated. Updating monitorspecs * triggers pan_display which tries updating windows */ if (hdmi->dc->enabled && !tegra_dc_is_powered(hdmi->dc)) tegra_dc_unpowergate_locked(hdmi->dc); tegra_fb_update_monspecs(hdmi->dc->fb, &specs, tegra_dc_hdmi_mode_filter); #ifdef CONFIG_SWITCH state = tegra_edid_audio_supported(hdmi->edid) ? 1 : 0; switch_set_state(&hdmi->audio_switch, state); pr_info("%s: audio_switch %d\n", __func__, state); switch_set_state(&hdmi->hpd_switch, 1); pr_info("Display connected, hpd_switch 1\n"); #endif hdmi->dc->connected = true; tegra_dc_ext_process_hotplug(hdmi->dc->ndev->id); hdmi_state_machine_set_state_l(HDMI_STATE_DONE_ENABLED, 0); return; end_disabled: hdmi->eld_retrieved = false; hdmi_disable_l(hdmi, true); hdmi_state_machine_set_state_l(HDMI_STATE_DONE_DISABLED, -1); }
static void handle_check_edid_l(struct tegra_dc_hdmi_data *hdmi) { struct fb_monspecs specs; #ifdef CONFIG_SWITCH int state; #endif memset(&specs, 0, sizeof(specs)); #ifdef CONFIG_FRAMEBUFFER_CONSOLE /* Set default videomode on dc before enabling it*/ tegra_dc_set_default_videomode(hdmi->dc); #endif if (!tegra_dc_hpd(work_state.hdmi->dc)) { /* hpd dropped - stop EDID read */ pr_info("hpd == 0, aborting EDID read\n"); goto end_disabled; } if (tegra_edid_get_monspecs(hdmi->edid, &specs)) { /* Failed to read EDID. If we still have retry attempts left, * schedule another attempt. Otherwise give up and just go to * the disabled state. */ work_state.edid_reads++; if (work_state.edid_reads >= MAX_EDID_READ_ATTEMPTS) { pr_info("Failed to read EDID after %d times. Giving up.\n", work_state.edid_reads); goto end_disabled; } else { hdmi_state_machine_set_state_l(HDMI_STATE_CHECK_EDID, CHECK_EDID_DELAY_MS); } return; } if (tegra_edid_get_eld(hdmi->edid, &hdmi->eld) < 0) { pr_err("error populating eld\n"); goto end_disabled; } hdmi->eld_retrieved = true; pr_info("panel size %d by %d\n", specs.max_x, specs.max_y); /* monitors like to lie about these but they are still useful for * detecting aspect ratios */ hdmi->dc->out->h_size = specs.max_x * 1000; hdmi->dc->out->v_size = specs.max_y * 1000; hdmi->dvi = !(specs.misc & FB_MISC_HDMI); #ifdef CONFIG_ADF_TEGRA tegra_adf_process_hotplug_connected(hdmi->dc->adf, &specs); #endif #ifdef CONFIG_TEGRA_DC_EXTENSIONS tegra_fb_update_monspecs(hdmi->dc->fb, &specs, tegra_dc_hdmi_mode_filter); #endif #ifdef CONFIG_SWITCH state = tegra_edid_audio_supported(hdmi->edid) ? 1 : 0; switch_set_state(&hdmi->audio_switch, state); pr_info("%s: audio_switch %d\n", __func__, state); switch_set_state(&hdmi->hpd_switch, 1); pr_info("Display connected, hpd_switch 1\n"); #endif hdmi->dc->connected = true; #ifdef CONFIG_TEGRA_DC_EXTENSIONS tegra_dc_ext_process_hotplug(hdmi->dc->ndev->id); #endif if (unlikely(tegra_is_clk_enabled(hdmi->clk))) { /* the only time this should happen is on boot, where the * sequence is that hdmi is enabled before EDID is read. * hdmi_enable() doesn't have EDID information yet so can't * setup audio and infoframes, so we have to do so here. */ pr_info("%s: setting audio and infoframes\n", __func__); tegra_dc_io_start(hdmi->dc); tegra_dc_hdmi_setup_audio_and_infoframes(hdmi->dc); tegra_dc_io_end(hdmi->dc); } hdmi_state_machine_set_state_l(HDMI_STATE_DONE_ENABLED, -1); return; end_disabled: hdmi->eld_retrieved = false; hdmi_disable_l(hdmi); hdmi_state_machine_set_state_l(HDMI_STATE_DONE_DISABLED, -1); }