static int tegra_dc_rgb_init(struct tegra_dc *dc) { struct tegra_edid *edid; struct tegra_dc_edid *dc_edid; struct fb_monspecs specs; int err; if (dc->out == NULL || dc->out->dcc_bus < 0) return 0; edid = tegra_edid_create(dc->out->dcc_bus); if (IS_ERR_OR_NULL(edid)) { dev_err(&dc->ndev->dev, "rgb: can't create edid\n"); return PTR_ERR(edid); } err = tegra_edid_get_monspecs(edid, &specs); if (err < 0) { dev_err(&dc->ndev->dev, "error reading edid\n"); return err; } if (dc->pdata->default_out->n_modes > 0) { dc->mode.h_sync_width = specs.modedb->hsync_len; dc->mode.v_sync_width = specs.modedb->vsync_len; dc->mode.h_back_porch = specs.modedb->left_margin; dc->mode.v_back_porch = specs.modedb->upper_margin; dc->mode.h_active = specs.modedb->xres; dc->mode.v_active = specs.modedb->yres; dc->mode.h_front_porch = specs.modedb->right_margin; if (!machine_is_avalon() && !machine_is_titan()) dc->mode.pclk = PICOS2KHZ(specs.modedb->pixclock) * 1000; if (!machine_is_avalon()) dc->mode.v_front_porch = specs.modedb->lower_margin; } if (dc->pdata->fb) { dc->pdata->fb->xres = specs.modedb->xres; dc->pdata->fb->yres = specs.modedb->yres; } dc_edid = tegra_edid_get_data(edid); if (IS_ERR_OR_NULL(dc_edid)) return PTR_ERR(dc_edid); dc->out->width = dc_edid->buf[DTD_H_SIZE]; dc->out->height = dc_edid->buf[DTD_V_SIZE]; tegra_edid_put_data(dc_edid); if (specs.modedb->xres > specs.modedb->yres) { if (dc->out->width <= dc->out->height) dc->out->width += 0xFF; } else { if (dc->out->width > dc->out->height) dc->out->height += 0xFF; } fb_destroy_modedb(specs.modedb); return 0; }
/* re-read the edid and check to see if it has changed. Return 0 on a * successful E-EDID read, or a non-zero error code on failure. If we succeed, * set match to 1 if the old E-EDID matches the new E-EDID. Otherwise, set * match to 0. */ static int hdmi_recheck_edid(struct tegra_dc_hdmi_data *hdmi, int *match) { int ret; u8 tmp[HDMI_EDID_MAX_LENGTH] = {0}; ret = read_edid_into_buffer(hdmi, tmp, sizeof(tmp)); pr_info("%s: read_edid_into_buffer() returned %d\n", __func__, ret); if (ret > 0) { struct tegra_dc_edid *data = tegra_edid_get_data(hdmi->edid); pr_info("old edid len = %d\n", data->len); *match = ((ret == data->len) && !memcmp(tmp, data->buf, data->len)); if (*match == 0) { print_hex_dump(KERN_INFO, "tmp :", DUMP_PREFIX_ADDRESS, 16, 4, tmp, ret, true); print_hex_dump(KERN_INFO, "data:", DUMP_PREFIX_ADDRESS, 16, 4, data->buf, data->len, true); } tegra_edid_put_data(data); ret = 0; } return ret; }