Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 204745
b: refs/heads/master
c: 8b856f0
h: refs/heads/master
i:
  204743: 7b6af6d
v: v3
  • Loading branch information
Anatolij Gustschin authored and Grant Likely committed Aug 1, 2010
1 parent 01bcba4 commit 3383d04
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 7 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: a027b33348df3512d7680eed29bada1247f01ad7
refs/heads/master: 8b856f040c09024aa9d1f363c1a5cf2d3db73ebd
6 changes: 6 additions & 0 deletions trunk/Documentation/powerpc/dts-bindings/fsl/diu.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ Required properties:
- interrupt-parent : the phandle for the interrupt controller that
services interrupts for this device.

Optional properties:
- edid : verbatim EDID data block describing attached display.
Data from the detailed timing descriptor will be used to
program the display controller.

Example (MPC8610HPCD):
display@2c000 {
compatible = "fsl,diu";
Expand All @@ -25,4 +30,5 @@ Example for MPC5121:
reg = <0x2100 0x100>;
interrupts = <64 0x8>;
interrupt-parent = <&ipic>;
edid = [edid-data];
};
1 change: 1 addition & 0 deletions trunk/drivers/video/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -1871,6 +1871,7 @@ config FB_MBX_DEBUG
config FB_FSL_DIU
tristate "Freescale DIU framebuffer support"
depends on FB && FSL_SOC
select FB_MODE_HELPERS
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
Expand Down
80 changes: 74 additions & 6 deletions trunk/drivers/video/fsl-diu-fb.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@

#include <sysdev/fsl_soc.h>
#include <linux/fsl-diu-fb.h>
#include "edid.h"

/*
* These parameters give default parameters
Expand Down Expand Up @@ -217,6 +218,7 @@ struct mfb_info {
int x_aoi_d; /* aoi display x offset to physical screen */
int y_aoi_d; /* aoi display y offset to physical screen */
struct fsl_diu_data *parent;
u8 *edid_data;
};


Expand Down Expand Up @@ -1185,18 +1187,30 @@ static int __devinit install_fb(struct fb_info *info)
int rc;
struct mfb_info *mfbi = info->par;
const char *aoi_mode, *init_aoi_mode = "320x240";
struct fb_videomode *db = fsl_diu_mode_db;
unsigned int dbsize = ARRAY_SIZE(fsl_diu_mode_db);
int has_default_mode = 1;

if (init_fbinfo(info))
return -EINVAL;

if (mfbi->index == 0) /* plane 0 */
if (mfbi->index == 0) { /* plane 0 */
if (mfbi->edid_data) {
/* Now build modedb from EDID */
fb_edid_to_monspecs(mfbi->edid_data, &info->monspecs);
fb_videomode_to_modelist(info->monspecs.modedb,
info->monspecs.modedb_len,
&info->modelist);
db = info->monspecs.modedb;
dbsize = info->monspecs.modedb_len;
}
aoi_mode = fb_mode;
else
} else {
aoi_mode = init_aoi_mode;
}
pr_debug("mode used = %s\n", aoi_mode);
rc = fb_find_mode(&info->var, info, aoi_mode, fsl_diu_mode_db,
ARRAY_SIZE(fsl_diu_mode_db), &fsl_diu_default_mode, default_bpp);

rc = fb_find_mode(&info->var, info, aoi_mode, db, dbsize,
&fsl_diu_default_mode, default_bpp);
switch (rc) {
case 1:
pr_debug("using mode specified in @mode\n");
Expand All @@ -1214,10 +1228,50 @@ static int __devinit install_fb(struct fb_info *info)
default:
pr_debug("rc = %d\n", rc);
pr_debug("failed to find mode\n");
return -EINVAL;
/*
* For plane 0 we continue and look into
* driver's internal modedb.
*/
if (mfbi->index == 0 && mfbi->edid_data)
has_default_mode = 0;
else
return -EINVAL;
break;
}

if (!has_default_mode) {
rc = fb_find_mode(&info->var, info, aoi_mode, fsl_diu_mode_db,
ARRAY_SIZE(fsl_diu_mode_db),
&fsl_diu_default_mode,
default_bpp);
if (rc > 0 && rc < 5)
has_default_mode = 1;
}

/* Still not found, use preferred mode from database if any */
if (!has_default_mode && info->monspecs.modedb) {
struct fb_monspecs *specs = &info->monspecs;
struct fb_videomode *modedb = &specs->modedb[0];

/*
* Get preferred timing. If not found,
* first mode in database will be used.
*/
if (specs->misc & FB_MISC_1ST_DETAIL) {
int i;

for (i = 0; i < specs->modedb_len; i++) {
if (specs->modedb[i].flag & FB_MODE_IS_FIRST) {
modedb = &specs->modedb[i];
break;
}
}
}

info->var.bits_per_pixel = default_bpp;
fb_videomode_to_var(&info->var, modedb);
}

pr_debug("xres_virtual %d\n", info->var.xres_virtual);
pr_debug("bits_per_pixel %d\n", info->var.bits_per_pixel);

Expand Down Expand Up @@ -1256,6 +1310,9 @@ static void uninstall_fb(struct fb_info *info)
if (!mfbi->registered)
return;

if (mfbi->index == 0)
kfree(mfbi->edid_data);

unregister_framebuffer(info);
unmap_video_memory(info);
if (&info->cmap)
Expand Down Expand Up @@ -1456,6 +1513,17 @@ static int __devinit fsl_diu_probe(struct of_device *ofdev,
mfbi = machine_data->fsl_diu_info[i]->par;
memcpy(mfbi, &mfb_template[i], sizeof(struct mfb_info));
mfbi->parent = machine_data;

if (mfbi->index == 0) {
const u8 *prop;
int len;

/* Get EDID */
prop = of_get_property(np, "edid", &len);
if (prop && len == EDID_LENGTH)
mfbi->edid_data = kmemdup(prop, EDID_LENGTH,
GFP_KERNEL);
}
}

ret = of_address_to_resource(np, 0, &res);
Expand Down

0 comments on commit 3383d04

Please sign in to comment.