Merge tag 'fbdev-updates-for-3.7' of git://github.com/schandinat/linux-2.6

Pull fbdev updates from Florian Tobias Schandinat:
 "This includes:
   - large updates for OMAP
     - basic OMAP5 DSS support for DPI and DSI outputs
     - large cleanups and restructuring
   - some update to Exynos and da8xx-fb
   - removal of the pnx4008 driver (arch removed)
   - various other small patches"

Fix up some trivial conflicts (mostly just include line changes, but
also some due to the renaming of the deferred work functions by Tejun).

* tag 'fbdev-updates-for-3.7' of git://github.com/schandinat/linux-2.6: (193 commits)
  gbefb: fix compile error
  video: mark nuc900fb_map_video_memory as __devinit
  video/mx3fb: set .owner to prevent module unloading while being used
  video: exynos_dp: use clk_prepare_enable and clk_disable_unprepare
  drivers/video/exynos/exynos_mipi_dsi.c: fix error return code
  drivers/video/savage/savagefb_driver.c: fix error return code
  video: s3c-fb: use clk_prepare_enable and clk_disable_unprepare
  da8xx-fb: save and restore LCDC context across suspend/resume cycle
  da8xx-fb: add pm_runtime support
  video/udlfb: fix line counting in fb_write
  OMAPDSS: add missing include for string.h
  OMAPDSS: DISPC: Configure color conversion coefficients for writeback
  OMAPDSS: DISPC: Add manager like functions for writeback
  OMAPDSS: DISPC: Configure writeback FIFOs
  OMAPDSS: DISPC: Configure writeback specific parameters in dispc_wb_setup()
  OMAPDSS: DISPC: Configure overlay-like parameters in dispc_wb_setup
  OMAPDSS: DISPC: Add function to set channel in for writeback
  OMAPDSS: DISPC: Don't set chroma resampling bit for writeback
  OMAPDSS: DISPC: Downscale chroma if plane is writeback
  OMAPDSS: DISPC: Configure input and output sizes for writeback
  ...
This commit is contained in:
Linus Torvalds
2012-10-12 10:21:02 +09:00
127 changed files with 5376 additions and 4747 deletions

View File

@@ -121,6 +121,18 @@ struct taal_data {
struct omap_dss_device *dssdev;
/* panel specific HW info */
struct panel_config *panel_config;
/* panel HW configuration from DT or platform data */
int reset_gpio;
int ext_te_gpio;
bool use_dsi_backlight;
struct omap_dsi_pin_config pin_config;
/* runtime variables */
bool enabled;
u8 rotate;
bool mirror;
@@ -145,16 +157,8 @@ struct taal_data {
bool ulps_enabled;
unsigned ulps_timeout;
struct delayed_work ulps_work;
struct panel_config *panel_config;
};
static inline struct nokia_dsi_panel_data
*get_panel_data(const struct omap_dss_device *dssdev)
{
return (struct nokia_dsi_panel_data *) dssdev->data;
}
static void taal_esd_work(struct work_struct *work);
static void taal_ulps_work(struct work_struct *work);
@@ -371,7 +375,6 @@ static void taal_cancel_ulps_work(struct omap_dss_device *dssdev)
static int taal_enter_ulps(struct omap_dss_device *dssdev)
{
struct taal_data *td = dev_get_drvdata(&dssdev->dev);
struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
int r;
if (td->ulps_enabled)
@@ -383,7 +386,8 @@ static int taal_enter_ulps(struct omap_dss_device *dssdev)
if (r)
goto err;
disable_irq(gpio_to_irq(panel_data->ext_te_gpio));
if (gpio_is_valid(td->ext_te_gpio))
disable_irq(gpio_to_irq(td->ext_te_gpio));
omapdss_dsi_display_disable(dssdev, false, true);
@@ -405,7 +409,6 @@ err:
static int taal_exit_ulps(struct omap_dss_device *dssdev)
{
struct taal_data *td = dev_get_drvdata(&dssdev->dev);
struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
int r;
if (!td->ulps_enabled)
@@ -425,7 +428,8 @@ static int taal_exit_ulps(struct omap_dss_device *dssdev)
goto err2;
}
enable_irq(gpio_to_irq(panel_data->ext_te_gpio));
if (gpio_is_valid(td->ext_te_gpio))
enable_irq(gpio_to_irq(td->ext_te_gpio));
taal_queue_ulps_work(dssdev);
@@ -438,7 +442,8 @@ err2:
r = taal_panel_reset(dssdev);
if (!r) {
enable_irq(gpio_to_irq(panel_data->ext_te_gpio));
if (gpio_is_valid(td->ext_te_gpio))
enable_irq(gpio_to_irq(td->ext_te_gpio));
td->ulps_enabled = false;
}
err1:
@@ -835,94 +840,135 @@ static struct attribute_group taal_attr_group = {
static void taal_hw_reset(struct omap_dss_device *dssdev)
{
struct taal_data *td = dev_get_drvdata(&dssdev->dev);
struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
if (panel_data->reset_gpio == -1)
if (!gpio_is_valid(td->reset_gpio))
return;
gpio_set_value(panel_data->reset_gpio, 1);
gpio_set_value(td->reset_gpio, 1);
if (td->panel_config->reset_sequence.high)
udelay(td->panel_config->reset_sequence.high);
/* reset the panel */
gpio_set_value(panel_data->reset_gpio, 0);
gpio_set_value(td->reset_gpio, 0);
/* assert reset */
if (td->panel_config->reset_sequence.low)
udelay(td->panel_config->reset_sequence.low);
gpio_set_value(panel_data->reset_gpio, 1);
gpio_set_value(td->reset_gpio, 1);
/* wait after releasing reset */
if (td->panel_config->sleep.hw_reset)
msleep(td->panel_config->sleep.hw_reset);
}
static void taal_probe_pdata(struct taal_data *td,
const struct nokia_dsi_panel_data *pdata)
{
td->reset_gpio = pdata->reset_gpio;
if (pdata->use_ext_te)
td->ext_te_gpio = pdata->ext_te_gpio;
else
td->ext_te_gpio = -1;
td->esd_interval = pdata->esd_interval;
td->ulps_timeout = pdata->ulps_timeout;
td->use_dsi_backlight = pdata->use_dsi_backlight;
td->pin_config = pdata->pin_config;
}
static int taal_probe(struct omap_dss_device *dssdev)
{
struct backlight_properties props;
struct taal_data *td;
struct backlight_device *bldev = NULL;
struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
struct panel_config *panel_config = NULL;
int r, i;
const char *panel_name;
dev_dbg(&dssdev->dev, "probe\n");
if (!panel_data || !panel_data->name) {
r = -EINVAL;
goto err;
td = devm_kzalloc(&dssdev->dev, sizeof(*td), GFP_KERNEL);
if (!td)
return -ENOMEM;
dev_set_drvdata(&dssdev->dev, td);
td->dssdev = dssdev;
if (dssdev->data) {
const struct nokia_dsi_panel_data *pdata = dssdev->data;
taal_probe_pdata(td, pdata);
panel_name = pdata->name;
} else {
return -ENODEV;
}
if (panel_name == NULL)
return -EINVAL;
for (i = 0; i < ARRAY_SIZE(panel_configs); i++) {
if (strcmp(panel_data->name, panel_configs[i].name) == 0) {
panel_config = &panel_configs[i];
if (strcmp(panel_name, panel_configs[i].name) == 0) {
td->panel_config = &panel_configs[i];
break;
}
}
if (!panel_config) {
r = -EINVAL;
goto err;
}
if (!td->panel_config)
return -EINVAL;
dssdev->panel.timings = panel_config->timings;
dssdev->panel.timings = td->panel_config->timings;
dssdev->panel.dsi_pix_fmt = OMAP_DSS_DSI_FMT_RGB888;
td = kzalloc(sizeof(*td), GFP_KERNEL);
if (!td) {
r = -ENOMEM;
goto err;
}
td->dssdev = dssdev;
td->panel_config = panel_config;
td->esd_interval = panel_data->esd_interval;
td->ulps_enabled = false;
td->ulps_timeout = panel_data->ulps_timeout;
dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE |
OMAP_DSS_DISPLAY_CAP_TEAR_ELIM;
mutex_init(&td->lock);
atomic_set(&td->do_update, 0);
if (gpio_is_valid(td->reset_gpio)) {
r = devm_gpio_request_one(&dssdev->dev, td->reset_gpio,
GPIOF_OUT_INIT_LOW, "taal rst");
if (r) {
dev_err(&dssdev->dev, "failed to request reset gpio\n");
return r;
}
}
if (gpio_is_valid(td->ext_te_gpio)) {
r = devm_gpio_request_one(&dssdev->dev, td->ext_te_gpio,
GPIOF_IN, "taal irq");
if (r) {
dev_err(&dssdev->dev, "GPIO request failed\n");
return r;
}
r = devm_request_irq(&dssdev->dev, gpio_to_irq(td->ext_te_gpio),
taal_te_isr,
IRQF_TRIGGER_RISING,
"taal vsync", dssdev);
if (r) {
dev_err(&dssdev->dev, "IRQ request failed\n");
return r;
}
INIT_DEFERRABLE_WORK(&td->te_timeout_work,
taal_te_timeout_work_callback);
dev_dbg(&dssdev->dev, "Using GPIO TE\n");
}
td->workqueue = create_singlethread_workqueue("taal_esd");
if (td->workqueue == NULL) {
dev_err(&dssdev->dev, "can't create ESD workqueue\n");
r = -ENOMEM;
goto err_wq;
return -ENOMEM;
}
INIT_DEFERRABLE_WORK(&td->esd_work, taal_esd_work);
INIT_DELAYED_WORK(&td->ulps_work, taal_ulps_work);
dev_set_drvdata(&dssdev->dev, td);
if (gpio_is_valid(panel_data->reset_gpio)) {
r = gpio_request_one(panel_data->reset_gpio, GPIOF_OUT_INIT_LOW,
"taal rst");
if (r) {
dev_err(&dssdev->dev, "failed to request reset gpio\n");
goto err_rst_gpio;
}
}
taal_hw_reset(dssdev);
if (panel_data->use_dsi_backlight) {
if (td->use_dsi_backlight) {
memset(&props, 0, sizeof(struct backlight_properties));
props.max_brightness = 255;
@@ -943,31 +989,6 @@ static int taal_probe(struct omap_dss_device *dssdev)
taal_bl_update_status(bldev);
}
if (panel_data->use_ext_te) {
int gpio = panel_data->ext_te_gpio;
r = gpio_request_one(gpio, GPIOF_IN, "taal irq");
if (r) {
dev_err(&dssdev->dev, "GPIO request failed\n");
goto err_gpio;
}
r = request_irq(gpio_to_irq(gpio), taal_te_isr,
IRQF_TRIGGER_RISING,
"taal vsync", dssdev);
if (r) {
dev_err(&dssdev->dev, "IRQ request failed\n");
gpio_free(gpio);
goto err_irq;
}
INIT_DEFERRABLE_WORK(&td->te_timeout_work,
taal_te_timeout_work_callback);
dev_dbg(&dssdev->dev, "Using GPIO TE\n");
}
r = omap_dsi_request_vc(dssdev, &td->channel);
if (r) {
dev_err(&dssdev->dev, "failed to get virtual channel\n");
@@ -991,29 +1012,16 @@ static int taal_probe(struct omap_dss_device *dssdev)
err_vc_id:
omap_dsi_release_vc(dssdev, td->channel);
err_req_vc:
if (panel_data->use_ext_te)
free_irq(gpio_to_irq(panel_data->ext_te_gpio), dssdev);
err_irq:
if (panel_data->use_ext_te)
gpio_free(panel_data->ext_te_gpio);
err_gpio:
if (bldev != NULL)
backlight_device_unregister(bldev);
err_bl:
if (gpio_is_valid(panel_data->reset_gpio))
gpio_free(panel_data->reset_gpio);
err_rst_gpio:
destroy_workqueue(td->workqueue);
err_wq:
kfree(td);
err:
return r;
}
static void __exit taal_remove(struct omap_dss_device *dssdev)
{
struct taal_data *td = dev_get_drvdata(&dssdev->dev);
struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
struct backlight_device *bldev;
dev_dbg(&dssdev->dev, "remove\n");
@@ -1021,12 +1029,6 @@ static void __exit taal_remove(struct omap_dss_device *dssdev)
sysfs_remove_group(&dssdev->dev.kobj, &taal_attr_group);
omap_dsi_release_vc(dssdev, td->channel);
if (panel_data->use_ext_te) {
int gpio = panel_data->ext_te_gpio;
free_irq(gpio_to_irq(gpio), dssdev);
gpio_free(gpio);
}
bldev = td->bldev;
if (bldev != NULL) {
bldev->props.power = FB_BLANK_POWERDOWN;
@@ -1040,26 +1042,31 @@ static void __exit taal_remove(struct omap_dss_device *dssdev)
/* reset, to be sure that the panel is in a valid state */
taal_hw_reset(dssdev);
if (gpio_is_valid(panel_data->reset_gpio))
gpio_free(panel_data->reset_gpio);
kfree(td);
}
static int taal_power_on(struct omap_dss_device *dssdev)
{
struct taal_data *td = dev_get_drvdata(&dssdev->dev);
struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
u8 id1, id2, id3;
int r;
r = omapdss_dsi_configure_pins(dssdev, &panel_data->pin_config);
r = omapdss_dsi_configure_pins(dssdev, &td->pin_config);
if (r) {
dev_err(&dssdev->dev, "failed to configure DSI pins\n");
goto err0;
};
omapdss_dsi_set_size(dssdev, dssdev->panel.timings.x_res,
dssdev->panel.timings.y_res);
omapdss_dsi_set_pixel_format(dssdev, OMAP_DSS_DSI_FMT_RGB888);
omapdss_dsi_set_operation_mode(dssdev, OMAP_DSS_DSI_CMD_MODE);
r = omapdss_dsi_set_clocks(dssdev, 216000000, 10000000);
if (r) {
dev_err(&dssdev->dev, "failed to set HS and LP clocks\n");
goto err0;
}
r = omapdss_dsi_display_enable(dssdev);
if (r) {
dev_err(&dssdev->dev, "failed to enable DSI\n");
@@ -1356,7 +1363,6 @@ static int taal_update(struct omap_dss_device *dssdev,
u16 x, u16 y, u16 w, u16 h)
{
struct taal_data *td = dev_get_drvdata(&dssdev->dev);
struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
int r;
dev_dbg(&dssdev->dev, "update %d, %d, %d x %d\n", x, y, w, h);
@@ -1380,7 +1386,7 @@ static int taal_update(struct omap_dss_device *dssdev,
if (r)
goto err;
if (td->te_enabled && panel_data->use_ext_te) {
if (td->te_enabled && gpio_is_valid(td->ext_te_gpio)) {
schedule_delayed_work(&td->te_timeout_work,
msecs_to_jiffies(250));
atomic_set(&td->do_update, 1);
@@ -1419,7 +1425,6 @@ static int taal_sync(struct omap_dss_device *dssdev)
static int _taal_enable_te(struct omap_dss_device *dssdev, bool enable)
{
struct taal_data *td = dev_get_drvdata(&dssdev->dev);
struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
int r;
if (enable)
@@ -1427,7 +1432,7 @@ static int _taal_enable_te(struct omap_dss_device *dssdev, bool enable)
else
r = taal_dcs_write_0(td, MIPI_DCS_SET_TEAR_OFF);
if (!panel_data->use_ext_te)
if (!gpio_is_valid(td->ext_te_gpio))
omapdss_dsi_enable_te(dssdev, enable);
if (td->panel_config->sleep.enable_te)
@@ -1487,6 +1492,7 @@ static int taal_get_te(struct omap_dss_device *dssdev)
static int taal_rotate(struct omap_dss_device *dssdev, u8 rotate)
{
struct taal_data *td = dev_get_drvdata(&dssdev->dev);
u16 dw, dh;
int r;
dev_dbg(&dssdev->dev, "rotate %d\n", rotate);
@@ -1508,6 +1514,16 @@ static int taal_rotate(struct omap_dss_device *dssdev, u8 rotate)
goto err;
}
if (rotate == 0 || rotate == 2) {
dw = dssdev->panel.timings.x_res;
dh = dssdev->panel.timings.y_res;
} else {
dw = dssdev->panel.timings.y_res;
dh = dssdev->panel.timings.x_res;
}
omapdss_dsi_set_size(dssdev, dw, dh);
td->rotate = rotate;
dsi_bus_unlock(dssdev);
@@ -1726,7 +1742,6 @@ static void taal_esd_work(struct work_struct *work)
struct taal_data *td = container_of(work, struct taal_data,
esd_work.work);
struct omap_dss_device *dssdev = td->dssdev;
struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
u8 state1, state2;
int r;
@@ -1773,7 +1788,7 @@ static void taal_esd_work(struct work_struct *work)
}
/* Self-diagnostics result is also shown on TE GPIO line. We need
* to re-enable TE after self diagnostics */
if (td->te_enabled && panel_data->use_ext_te) {
if (td->te_enabled && gpio_is_valid(td->ext_te_gpio)) {
r = taal_dcs_write_1(td, MIPI_DCS_SET_TEAR_ON, 0);
if (r)
goto err;