mirror of
https://github.com/genesi/linux-legacy.git
synced 2026-09-04 05:47:41 +00:00
siihdmi: inline siihdmi_detect_sink
The framebuffer routines also work with the cea861 data. Move the edid reading into the function itself, which avoids us having to read the EDID data multiple times and allows us to pass the full EDID data to the framebuffer routines. We always have to read the first block to determine the actual length of the EDID data. In order to keep the reading logic the same all the time, we simply re-read the EDID data always (even if there are no extension blocks). This hopefully will help keep timing issues similar across all devices.
This commit is contained in:
committed by
Matt Sealey
parent
9660c7cc1b
commit
26b05ab66a
@@ -297,57 +297,6 @@ static void siihdmi_parse_cea861_timing_block(struct siihdmi_tx *tx,
|
||||
} while (index < cea->dtd_offset - offset);
|
||||
}
|
||||
|
||||
static void siihdmi_detect_sink(struct siihdmi_tx *tx)
|
||||
{
|
||||
u8 *edid;
|
||||
struct edid_extension *extensions, *extension;
|
||||
struct edid_block0 block0;
|
||||
u32 length;
|
||||
u8 i;
|
||||
|
||||
BUILD_BUG_ON(sizeof(block0) != EDID_BLOCK_SIZE);
|
||||
BUILD_BUG_ON(sizeof(*extension) != EDID_BLOCK_SIZE);
|
||||
|
||||
/* defaults */
|
||||
tx->connection_type = CONNECTION_TYPE_DVI;
|
||||
tx->pixel_mapping = PIXEL_MAPPING_EXACT;
|
||||
tx->enable_audio = false;
|
||||
|
||||
/* use EDID to identify sink characteristics */
|
||||
if (siihdmi_read_edid(tx, (u8 *) &block0, sizeof(block0)) < 0)
|
||||
return;
|
||||
|
||||
if (!block0.extensions)
|
||||
return;
|
||||
|
||||
/* need to allocate space for block 0 as well as the extensions */
|
||||
length = (block0.extensions + 1) * EDID_BLOCK_SIZE;
|
||||
|
||||
edid = kzalloc(length, GFP_KERNEL);
|
||||
if (!edid)
|
||||
return;
|
||||
|
||||
if (siihdmi_read_edid(tx, edid, length) < 0)
|
||||
goto out;
|
||||
|
||||
extensions = (struct edid_extension *) edid + sizeof(block0);
|
||||
|
||||
for (i = 0; i < block0.extensions; i++) {
|
||||
extension = &extensions[i];
|
||||
|
||||
switch (extension->tag) {
|
||||
case EDID_EXTENSION_CEA:
|
||||
siihdmi_parse_cea861_timing_block(tx, extension);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
kfree(edid);
|
||||
}
|
||||
|
||||
static inline unsigned long siihdmi_ps_to_hz(const unsigned long ps)
|
||||
{
|
||||
unsigned long long numerator = 1000000000000ull;
|
||||
@@ -674,17 +623,56 @@ static void siihdmi_dump_modelines(const struct fb_monspecs * const monspecs)
|
||||
|
||||
static int siihdmi_init_fb(struct siihdmi_tx *tx, struct fb_info *fb)
|
||||
{
|
||||
const struct edid_block0 edid;
|
||||
u8 *edid = NULL;
|
||||
const struct fb_videomode *mode = NULL;
|
||||
struct fb_var_screeninfo var = {0};
|
||||
int ret;
|
||||
struct edid_block0 block0;
|
||||
int ret = 0;
|
||||
u32 length;
|
||||
|
||||
siihdmi_detect_sink(tx);
|
||||
BUILD_BUG_ON(sizeof(struct edid_block0) != EDID_BLOCK_SIZE);
|
||||
BUILD_BUG_ON(sizeof(struct edid_extension) != EDID_BLOCK_SIZE);
|
||||
|
||||
/* TODO use platform_data to prune modelist */
|
||||
if ((ret = siihdmi_read_edid(tx, (u8 *) &edid, sizeof(edid))) < 0)
|
||||
/* defaults */
|
||||
tx->connection_type = CONNECTION_TYPE_DVI;
|
||||
tx->pixel_mapping = PIXEL_MAPPING_EXACT;
|
||||
tx->enable_audio = false;
|
||||
|
||||
/* use EDID to detect sink characteristics */
|
||||
if ((ret = siihdmi_read_edid(tx, (u8 *) &block0, sizeof(block0))) < 0)
|
||||
return ret;
|
||||
|
||||
/* need to allocate space for block 0 as well as the extensions */
|
||||
length = (block0.extensions + 1) * EDID_BLOCK_SIZE;
|
||||
|
||||
edid = kzalloc(length, GFP_KERNEL);
|
||||
if (!edid)
|
||||
return -ENOMEM;
|
||||
|
||||
if ((ret = siihdmi_read_edid(tx, edid, length)) < 0)
|
||||
goto out;
|
||||
|
||||
if (block0.extensions) {
|
||||
const struct edid_extension * const extensions =
|
||||
(struct edid_extension *) edid + sizeof(block0);
|
||||
u8 i;
|
||||
|
||||
for (i = 0; i < block0.extensions; i++) {
|
||||
const struct edid_extension * const extension =
|
||||
&extensions[i];
|
||||
|
||||
switch (extension->tag) {
|
||||
case EDID_EXTENSION_CEA:
|
||||
siihdmi_parse_cea861_timing_block(tx,
|
||||
extension);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO use platform_data to prune modelist */
|
||||
fb_edid_to_monspecs((u8 *) &edid, &fb->monspecs);
|
||||
siihdmi_dump_modelines(&fb->monspecs);
|
||||
/* TODO mxcfb_videomode_to_modelist did some additional work */
|
||||
@@ -698,9 +686,11 @@ static int siihdmi_init_fb(struct siihdmi_tx *tx, struct fb_info *fb)
|
||||
|
||||
/* TODO mxcfb_adjust did some additional work */
|
||||
fb_videomode_to_var(&var, mode);
|
||||
|
||||
msleep(10); // pause to let IPU settle
|
||||
|
||||
if ((ret = siihdmi_set_resolution(tx, &var)) < 0)
|
||||
return ret;
|
||||
goto out;
|
||||
|
||||
/* activate the framebuffer */
|
||||
var.activate = FB_ACTIVATE_ALL;
|
||||
@@ -711,7 +701,9 @@ static int siihdmi_init_fb(struct siihdmi_tx *tx, struct fb_info *fb)
|
||||
fb->flags &= ~FBINFO_MISC_USEREVENT;
|
||||
release_console_sem();
|
||||
|
||||
return 0;
|
||||
out:
|
||||
kfree(edid);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int siihdmi_blank(struct siihdmi_tx *tx, struct fb_var_screeninfo *var, int powerdown)
|
||||
|
||||
Reference in New Issue
Block a user