OMAP display subsystem changes for 3.11 (part 1/2)

This is the first part of OMAP DSS changes for 3.11. This part contains fixes,
 cleanups and reorganizations that are not directly related to the new DSS
 device model that is added in part 2, although many of the reorganizations are
 made to make the part 2 possible.
 
 There should not be any functional changes visible to the user except the few
 bug fixes.
 
 The main new internal features:
 
 - Display (dis)connect support, which allows us to explicitly (dis)connect a
   whole display pipeline
 
 - Panel list, which allows us to operate without the specific DSS bus
 
 - Combine omap_dss_output to omap_dss_device, so that we have one generic
   "entity" for display pipeline blocks
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1.4.12 (GNU/Linux)
 
 iQIcBAABAgAGBQJRvw+OAAoJEPo9qoy8lh71tygP/1NFil82hCslZeO3+jzEFhHq
 0g16FuUtBeYtFnt6+bRcpMAEmoCrDQQBBQTNWloTQPxW6G3qmkxnKm+uKO9BPmfm
 uz7Fo37qrYQqu4oa/CoWEvgPlHjcfvjL5/NGGwGiiQNYNrjNLLMf5vKp3UhuqKFn
 N6CdPWoI8TuBtiFUYzbb2DYjcO60Ky8Gqr+/Lms9wjILFVXbav7KmqyYPqdxtEVx
 Vy9uA50YHxeQ61Ib6/cnBmxxuycX4jI545zOAsexPYotFh9SjLxQoHMbcbWAkBqE
 UkUi+zQpVhE9t3hPd8GnEZPDPo3AEYE034zXxU6QjEWzftUQDl5gzyAEMQLOdGyi
 5x2Q4n7bsQG0vEXje4ko3o5VuPXzEmptgnm0J3pMpnMiJlZwBWtQHm1Tw7fOgv17
 vvzMd9ojbLZVUa+ywWWR4Xb/4XH7PkLPSgk1x+MCcJ+6f2m/S/5ddqI6u+xd9CWH
 eaw5R4z6izG84bASaI7iEIZBhbP+TcUd+kNT3bqD4dQVp4ACJimb5P8DBSoP8yZL
 ViHhBcPixHrXxzucyV0PucYcvaiTG0HD4GMxFQQ1zabS4dqEG3Us3W5zNWzkAhf8
 TeGcYi03gt+R6CL+GuzP9q1SkX3uYEETm57IFmSIpzxlZFW5pRVXj9F0CiscwbgM
 RuIzyzFoHG7w3dLIwh52
 =I6Y2
 -----END PGP SIGNATURE-----

Merge tag 'omapdss-for-3.11-1' of git://gitorious.org/linux-omap-dss2/linux into fbdev/for-next

OMAP display subsystem changes for 3.11 (part 1/2)

This is the first part of OMAP DSS changes for 3.11. This part contains fixes,
cleanups and reorganizations that are not directly related to the new DSS
device model that is added in part 2, although many of the reorganizations are
made to make the part 2 possible.

There should not be any functional changes visible to the user except the few
bug fixes.

The main new internal features:

- Display (dis)connect support, which allows us to explicitly (dis)connect a
  whole display pipeline

- Panel list, which allows us to operate without the specific DSS bus

- Combine omap_dss_output to omap_dss_device, so that we have one generic
  "entity" for display pipeline blocks
This commit is contained in:
Jean-Christophe PLAGNIOL-VILLARD 2013-06-28 17:59:10 +08:00
Родитель a66e62ae56 595470a785
Коммит 8e9804557c
39 изменённых файлов: 1143 добавлений и 905 удалений

Просмотреть файл

@ -40,7 +40,7 @@ struct omap_crtc {
* mgr->id.) Eventually this will be replaced w/ something * mgr->id.) Eventually this will be replaced w/ something
* more common-panel-framework-y * more common-panel-framework-y
*/ */
struct omap_overlay_manager mgr; struct omap_overlay_manager *mgr;
struct omap_video_timings timings; struct omap_video_timings timings;
bool enabled; bool enabled;
@ -90,7 +90,32 @@ uint32_t pipe2vbl(struct drm_crtc *crtc)
* job of sequencing the setup of the video pipe in the proper order * job of sequencing the setup of the video pipe in the proper order
*/ */
/* ovl-mgr-id -> crtc */
static struct omap_crtc *omap_crtcs[8];
/* we can probably ignore these until we support command-mode panels: */ /* we can probably ignore these until we support command-mode panels: */
static int omap_crtc_connect(struct omap_overlay_manager *mgr,
struct omap_dss_device *dst)
{
if (mgr->output)
return -EINVAL;
if ((mgr->supported_outputs & dst->id) == 0)
return -EINVAL;
dst->manager = mgr;
mgr->output = dst;
return 0;
}
static void omap_crtc_disconnect(struct omap_overlay_manager *mgr,
struct omap_dss_device *dst)
{
mgr->output->manager = NULL;
mgr->output = NULL;
}
static void omap_crtc_start_update(struct omap_overlay_manager *mgr) static void omap_crtc_start_update(struct omap_overlay_manager *mgr)
{ {
} }
@ -107,7 +132,7 @@ static void omap_crtc_disable(struct omap_overlay_manager *mgr)
static void omap_crtc_set_timings(struct omap_overlay_manager *mgr, static void omap_crtc_set_timings(struct omap_overlay_manager *mgr,
const struct omap_video_timings *timings) const struct omap_video_timings *timings)
{ {
struct omap_crtc *omap_crtc = container_of(mgr, struct omap_crtc, mgr); struct omap_crtc *omap_crtc = omap_crtcs[mgr->id];
DBG("%s", omap_crtc->name); DBG("%s", omap_crtc->name);
omap_crtc->timings = *timings; omap_crtc->timings = *timings;
omap_crtc->full_update = true; omap_crtc->full_update = true;
@ -116,7 +141,7 @@ static void omap_crtc_set_timings(struct omap_overlay_manager *mgr,
static void omap_crtc_set_lcd_config(struct omap_overlay_manager *mgr, static void omap_crtc_set_lcd_config(struct omap_overlay_manager *mgr,
const struct dss_lcd_mgr_config *config) const struct dss_lcd_mgr_config *config)
{ {
struct omap_crtc *omap_crtc = container_of(mgr, struct omap_crtc, mgr); struct omap_crtc *omap_crtc = omap_crtcs[mgr->id];
DBG("%s", omap_crtc->name); DBG("%s", omap_crtc->name);
dispc_mgr_set_lcd_config(omap_crtc->channel, config); dispc_mgr_set_lcd_config(omap_crtc->channel, config);
} }
@ -135,6 +160,8 @@ static void omap_crtc_unregister_framedone_handler(
} }
static const struct dss_mgr_ops mgr_ops = { static const struct dss_mgr_ops mgr_ops = {
.connect = omap_crtc_connect,
.disconnect = omap_crtc_disconnect,
.start_update = omap_crtc_start_update, .start_update = omap_crtc_start_update,
.enable = omap_crtc_enable, .enable = omap_crtc_enable,
.disable = omap_crtc_disable, .disable = omap_crtc_disable,
@ -569,7 +596,7 @@ static void omap_crtc_pre_apply(struct omap_drm_apply *apply)
} else { } else {
if (encoder) { if (encoder) {
omap_encoder_set_enabled(encoder, false); omap_encoder_set_enabled(encoder, false);
omap_encoder_update(encoder, &omap_crtc->mgr, omap_encoder_update(encoder, omap_crtc->mgr,
&omap_crtc->timings); &omap_crtc->timings);
omap_encoder_set_enabled(encoder, true); omap_encoder_set_enabled(encoder, true);
omap_crtc->full_update = false; omap_crtc->full_update = false;
@ -595,6 +622,11 @@ static const char *channel_names[] = {
[OMAP_DSS_CHANNEL_LCD2] = "lcd2", [OMAP_DSS_CHANNEL_LCD2] = "lcd2",
}; };
void omap_crtc_pre_init(void)
{
dss_install_mgr_ops(&mgr_ops);
}
/* initialize crtc */ /* initialize crtc */
struct drm_crtc *omap_crtc_init(struct drm_device *dev, struct drm_crtc *omap_crtc_init(struct drm_device *dev,
struct drm_plane *plane, enum omap_channel channel, int id) struct drm_plane *plane, enum omap_channel channel, int id)
@ -635,9 +667,7 @@ struct drm_crtc *omap_crtc_init(struct drm_device *dev,
omap_irq_register(dev, &omap_crtc->error_irq); omap_irq_register(dev, &omap_crtc->error_irq);
/* temporary: */ /* temporary: */
omap_crtc->mgr.id = channel; omap_crtc->mgr = omap_dss_get_overlay_manager(channel);
dss_install_mgr_ops(&mgr_ops);
/* TODO: fix hard-coded setup.. add properties! */ /* TODO: fix hard-coded setup.. add properties! */
info = &omap_crtc->info; info = &omap_crtc->info;
@ -651,6 +681,8 @@ struct drm_crtc *omap_crtc_init(struct drm_device *dev,
omap_plane_install_properties(omap_crtc->plane, &crtc->base); omap_plane_install_properties(omap_crtc->plane, &crtc->base);
omap_crtcs[channel] = omap_crtc;
return crtc; return crtc;
fail: fail:

Просмотреть файл

@ -97,6 +97,9 @@ static int omap_modeset_init(struct drm_device *dev)
int num_mgrs = dss_feat_get_num_mgrs(); int num_mgrs = dss_feat_get_num_mgrs();
int num_crtcs; int num_crtcs;
int i, id = 0; int i, id = 0;
int r;
omap_crtc_pre_init();
drm_mode_config_init(dev); drm_mode_config_init(dev);
@ -116,6 +119,7 @@ static int omap_modeset_init(struct drm_device *dev)
struct drm_connector *connector; struct drm_connector *connector;
struct drm_encoder *encoder; struct drm_encoder *encoder;
enum omap_channel channel; enum omap_channel channel;
struct omap_overlay_manager *mgr;
if (!dssdev->driver) { if (!dssdev->driver) {
dev_warn(dev->dev, "%s has no driver.. skipping it\n", dev_warn(dev->dev, "%s has no driver.. skipping it\n",
@ -131,6 +135,13 @@ static int omap_modeset_init(struct drm_device *dev)
continue; continue;
} }
r = dssdev->driver->connect(dssdev);
if (r) {
dev_err(dev->dev, "could not connect display: %s\n",
dssdev->name);
continue;
}
encoder = omap_encoder_init(dev, dssdev); encoder = omap_encoder_init(dev, dssdev);
if (!encoder) { if (!encoder) {
@ -172,8 +183,9 @@ static int omap_modeset_init(struct drm_device *dev)
* other possible channels to which the encoder can connect are * other possible channels to which the encoder can connect are
* not considered. * not considered.
*/ */
channel = dssdev->output->dispc_channel;
mgr = omapdss_find_mgr_from_display(dssdev);
channel = mgr->id;
/* /*
* if this channel hasn't already been taken by a previously * if this channel hasn't already been taken by a previously
* allocated crtc, we create a new crtc for it * allocated crtc, we create a new crtc for it
@ -247,6 +259,9 @@ static int omap_modeset_init(struct drm_device *dev)
struct drm_encoder *encoder = priv->encoders[i]; struct drm_encoder *encoder = priv->encoders[i];
struct omap_dss_device *dssdev = struct omap_dss_device *dssdev =
omap_encoder_get_dssdev(encoder); omap_encoder_get_dssdev(encoder);
struct omap_dss_device *output;
output = omapdss_find_output_from_display(dssdev);
/* figure out which crtc's we can connect the encoder to: */ /* figure out which crtc's we can connect the encoder to: */
encoder->possible_crtcs = 0; encoder->possible_crtcs = 0;
@ -259,9 +274,11 @@ static int omap_modeset_init(struct drm_device *dev)
supported_outputs = supported_outputs =
dss_feat_get_supported_outputs(crtc_channel); dss_feat_get_supported_outputs(crtc_channel);
if (supported_outputs & dssdev->output->id) if (supported_outputs & output->id)
encoder->possible_crtcs |= (1 << id); encoder->possible_crtcs |= (1 << id);
} }
omap_dss_put_device(output);
} }
DBG("registered %d planes, %d crtcs, %d encoders and %d connectors\n", DBG("registered %d planes, %d crtcs, %d encoders and %d connectors\n",

Просмотреть файл

@ -157,6 +157,7 @@ const struct omap_video_timings *omap_crtc_timings(struct drm_crtc *crtc);
enum omap_channel omap_crtc_channel(struct drm_crtc *crtc); enum omap_channel omap_crtc_channel(struct drm_crtc *crtc);
int omap_crtc_apply(struct drm_crtc *crtc, int omap_crtc_apply(struct drm_crtc *crtc,
struct omap_drm_apply *apply); struct omap_drm_apply *apply);
void omap_crtc_pre_init(void);
struct drm_crtc *omap_crtc_init(struct drm_device *dev, struct drm_crtc *omap_crtc_init(struct drm_device *dev,
struct drm_plane *plane, enum omap_channel channel, int id); struct drm_plane *plane, enum omap_channel channel, int id);

Просмотреть файл

@ -510,7 +510,7 @@ static int acx_panel_probe(struct omap_dss_device *dssdev)
int max_brightness, brightness; int max_brightness, brightness;
struct backlight_properties props; struct backlight_properties props;
dev_dbg(&dssdev->dev, "%s\n", __func__); dev_dbg(dssdev->dev, "%s\n", __func__);
if (!panel_data) if (!panel_data)
return -EINVAL; return -EINVAL;
@ -519,7 +519,7 @@ static int acx_panel_probe(struct omap_dss_device *dssdev)
dssdev->panel.timings = acx_panel_timings; dssdev->panel.timings = acx_panel_timings;
if (gpio_is_valid(panel_data->reset_gpio)) { if (gpio_is_valid(panel_data->reset_gpio)) {
r = devm_gpio_request_one(&dssdev->dev, panel_data->reset_gpio, r = devm_gpio_request_one(dssdev->dev, panel_data->reset_gpio,
GPIOF_OUT_INIT_LOW, "lcd reset"); GPIOF_OUT_INIT_LOW, "lcd reset");
if (r) if (r)
return r; return r;
@ -538,7 +538,7 @@ static int acx_panel_probe(struct omap_dss_device *dssdev)
r = panel_detect(md); r = panel_detect(md);
if (r) { if (r) {
dev_err(&dssdev->dev, "%s panel detect error\n", __func__); dev_err(dssdev->dev, "%s panel detect error\n", __func__);
if (!md->enabled && gpio_is_valid(panel_data->reset_gpio)) if (!md->enabled && gpio_is_valid(panel_data->reset_gpio))
gpio_set_value(panel_data->reset_gpio, 0); gpio_set_value(panel_data->reset_gpio, 0);
@ -593,7 +593,7 @@ static void acx_panel_remove(struct omap_dss_device *dssdev)
{ {
struct acx565akm_device *md = &acx_dev; struct acx565akm_device *md = &acx_dev;
dev_dbg(&dssdev->dev, "%s\n", __func__); dev_dbg(dssdev->dev, "%s\n", __func__);
sysfs_remove_group(&md->bl_dev->dev.kobj, &bldev_attr_group); sysfs_remove_group(&md->bl_dev->dev.kobj, &bldev_attr_group);
backlight_device_unregister(md->bl_dev); backlight_device_unregister(md->bl_dev);
mutex_lock(&acx_dev.mutex); mutex_lock(&acx_dev.mutex);
@ -607,7 +607,7 @@ static int acx_panel_power_on(struct omap_dss_device *dssdev)
struct panel_acx565akm_data *panel_data = get_panel_data(dssdev); struct panel_acx565akm_data *panel_data = get_panel_data(dssdev);
int r; int r;
dev_dbg(&dssdev->dev, "%s\n", __func__); dev_dbg(dssdev->dev, "%s\n", __func__);
if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
return 0; return 0;
@ -667,7 +667,7 @@ static void acx_panel_power_off(struct omap_dss_device *dssdev)
struct acx565akm_device *md = &acx_dev; struct acx565akm_device *md = &acx_dev;
struct panel_acx565akm_data *panel_data = get_panel_data(dssdev); struct panel_acx565akm_data *panel_data = get_panel_data(dssdev);
dev_dbg(&dssdev->dev, "%s\n", __func__); dev_dbg(dssdev->dev, "%s\n", __func__);
if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
return; return;
@ -704,7 +704,7 @@ static int acx_panel_enable(struct omap_dss_device *dssdev)
{ {
int r; int r;
dev_dbg(&dssdev->dev, "%s\n", __func__); dev_dbg(dssdev->dev, "%s\n", __func__);
r = acx_panel_power_on(dssdev); r = acx_panel_power_on(dssdev);
if (r) if (r)
@ -716,7 +716,7 @@ static int acx_panel_enable(struct omap_dss_device *dssdev)
static void acx_panel_disable(struct omap_dss_device *dssdev) static void acx_panel_disable(struct omap_dss_device *dssdev)
{ {
dev_dbg(&dssdev->dev, "%s\n", __func__); dev_dbg(dssdev->dev, "%s\n", __func__);
acx_panel_power_off(dssdev); acx_panel_power_off(dssdev);
dssdev->state = OMAP_DSS_DISPLAY_DISABLED; dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
} }

Просмотреть файл

@ -536,7 +536,7 @@ static int generic_dpi_panel_power_on(struct omap_dss_device *dssdev)
{ {
int r, i; int r, i;
struct panel_generic_dpi_data *panel_data = get_panel_data(dssdev); struct panel_generic_dpi_data *panel_data = get_panel_data(dssdev);
struct panel_drv_data *drv_data = dev_get_drvdata(&dssdev->dev); struct panel_drv_data *drv_data = dev_get_drvdata(dssdev->dev);
struct panel_config *panel_config = drv_data->panel_config; struct panel_config *panel_config = drv_data->panel_config;
if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
@ -567,7 +567,7 @@ err0:
static void generic_dpi_panel_power_off(struct omap_dss_device *dssdev) static void generic_dpi_panel_power_off(struct omap_dss_device *dssdev)
{ {
struct panel_generic_dpi_data *panel_data = get_panel_data(dssdev); struct panel_generic_dpi_data *panel_data = get_panel_data(dssdev);
struct panel_drv_data *drv_data = dev_get_drvdata(&dssdev->dev); struct panel_drv_data *drv_data = dev_get_drvdata(dssdev->dev);
struct panel_config *panel_config = drv_data->panel_config; struct panel_config *panel_config = drv_data->panel_config;
int i; int i;
@ -593,7 +593,7 @@ static int generic_dpi_panel_probe(struct omap_dss_device *dssdev)
struct panel_drv_data *drv_data = NULL; struct panel_drv_data *drv_data = NULL;
int i, r; int i, r;
dev_dbg(&dssdev->dev, "probe\n"); dev_dbg(dssdev->dev, "probe\n");
if (!panel_data || !panel_data->name) if (!panel_data || !panel_data->name)
return -EINVAL; return -EINVAL;
@ -609,7 +609,7 @@ static int generic_dpi_panel_probe(struct omap_dss_device *dssdev)
return -EINVAL; return -EINVAL;
for (i = 0; i < panel_data->num_gpios; ++i) { for (i = 0; i < panel_data->num_gpios; ++i) {
r = devm_gpio_request_one(&dssdev->dev, panel_data->gpios[i], r = devm_gpio_request_one(dssdev->dev, panel_data->gpios[i],
panel_data->gpio_invert[i] ? panel_data->gpio_invert[i] ?
GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW, GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW,
"panel gpio"); "panel gpio");
@ -619,7 +619,7 @@ static int generic_dpi_panel_probe(struct omap_dss_device *dssdev)
dssdev->panel.timings = panel_config->timings; dssdev->panel.timings = panel_config->timings;
drv_data = devm_kzalloc(&dssdev->dev, sizeof(*drv_data), GFP_KERNEL); drv_data = devm_kzalloc(dssdev->dev, sizeof(*drv_data), GFP_KERNEL);
if (!drv_data) if (!drv_data)
return -ENOMEM; return -ENOMEM;
@ -628,21 +628,21 @@ static int generic_dpi_panel_probe(struct omap_dss_device *dssdev)
mutex_init(&drv_data->lock); mutex_init(&drv_data->lock);
dev_set_drvdata(&dssdev->dev, drv_data); dev_set_drvdata(dssdev->dev, drv_data);
return 0; return 0;
} }
static void __exit generic_dpi_panel_remove(struct omap_dss_device *dssdev) static void __exit generic_dpi_panel_remove(struct omap_dss_device *dssdev)
{ {
dev_dbg(&dssdev->dev, "remove\n"); dev_dbg(dssdev->dev, "remove\n");
dev_set_drvdata(&dssdev->dev, NULL); dev_set_drvdata(dssdev->dev, NULL);
} }
static int generic_dpi_panel_enable(struct omap_dss_device *dssdev) static int generic_dpi_panel_enable(struct omap_dss_device *dssdev)
{ {
struct panel_drv_data *drv_data = dev_get_drvdata(&dssdev->dev); struct panel_drv_data *drv_data = dev_get_drvdata(dssdev->dev);
int r; int r;
mutex_lock(&drv_data->lock); mutex_lock(&drv_data->lock);
@ -660,7 +660,7 @@ err:
static void generic_dpi_panel_disable(struct omap_dss_device *dssdev) static void generic_dpi_panel_disable(struct omap_dss_device *dssdev)
{ {
struct panel_drv_data *drv_data = dev_get_drvdata(&dssdev->dev); struct panel_drv_data *drv_data = dev_get_drvdata(dssdev->dev);
mutex_lock(&drv_data->lock); mutex_lock(&drv_data->lock);
@ -674,7 +674,7 @@ static void generic_dpi_panel_disable(struct omap_dss_device *dssdev)
static void generic_dpi_panel_set_timings(struct omap_dss_device *dssdev, static void generic_dpi_panel_set_timings(struct omap_dss_device *dssdev,
struct omap_video_timings *timings) struct omap_video_timings *timings)
{ {
struct panel_drv_data *drv_data = dev_get_drvdata(&dssdev->dev); struct panel_drv_data *drv_data = dev_get_drvdata(dssdev->dev);
mutex_lock(&drv_data->lock); mutex_lock(&drv_data->lock);
@ -688,7 +688,7 @@ static void generic_dpi_panel_set_timings(struct omap_dss_device *dssdev,
static void generic_dpi_panel_get_timings(struct omap_dss_device *dssdev, static void generic_dpi_panel_get_timings(struct omap_dss_device *dssdev,
struct omap_video_timings *timings) struct omap_video_timings *timings)
{ {
struct panel_drv_data *drv_data = dev_get_drvdata(&dssdev->dev); struct panel_drv_data *drv_data = dev_get_drvdata(dssdev->dev);
mutex_lock(&drv_data->lock); mutex_lock(&drv_data->lock);
@ -700,7 +700,7 @@ static void generic_dpi_panel_get_timings(struct omap_dss_device *dssdev,
static int generic_dpi_panel_check_timings(struct omap_dss_device *dssdev, static int generic_dpi_panel_check_timings(struct omap_dss_device *dssdev,
struct omap_video_timings *timings) struct omap_video_timings *timings)
{ {
struct panel_drv_data *drv_data = dev_get_drvdata(&dssdev->dev); struct panel_drv_data *drv_data = dev_get_drvdata(dssdev->dev);
int r; int r;
mutex_lock(&drv_data->lock); mutex_lock(&drv_data->lock);

Просмотреть файл

@ -109,12 +109,12 @@ static int lb035q02_panel_probe(struct omap_dss_device *dssdev)
dssdev->panel.timings = lb035q02_timings; dssdev->panel.timings = lb035q02_timings;
ld = devm_kzalloc(&dssdev->dev, sizeof(*ld), GFP_KERNEL); ld = devm_kzalloc(dssdev->dev, sizeof(*ld), GFP_KERNEL);
if (!ld) if (!ld)
return -ENOMEM; return -ENOMEM;
for (i = 0; i < panel_data->num_gpios; ++i) { for (i = 0; i < panel_data->num_gpios; ++i) {
r = devm_gpio_request_one(&dssdev->dev, panel_data->gpios[i], r = devm_gpio_request_one(dssdev->dev, panel_data->gpios[i],
panel_data->gpio_invert[i] ? panel_data->gpio_invert[i] ?
GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW, GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW,
"panel gpio"); "panel gpio");
@ -123,7 +123,7 @@ static int lb035q02_panel_probe(struct omap_dss_device *dssdev)
} }
mutex_init(&ld->lock); mutex_init(&ld->lock);
dev_set_drvdata(&dssdev->dev, ld); dev_set_drvdata(dssdev->dev, ld);
return 0; return 0;
} }
@ -134,7 +134,7 @@ static void lb035q02_panel_remove(struct omap_dss_device *dssdev)
static int lb035q02_panel_enable(struct omap_dss_device *dssdev) static int lb035q02_panel_enable(struct omap_dss_device *dssdev)
{ {
struct lb035q02_data *ld = dev_get_drvdata(&dssdev->dev); struct lb035q02_data *ld = dev_get_drvdata(dssdev->dev);
int r; int r;
mutex_lock(&ld->lock); mutex_lock(&ld->lock);
@ -153,7 +153,7 @@ err:
static void lb035q02_panel_disable(struct omap_dss_device *dssdev) static void lb035q02_panel_disable(struct omap_dss_device *dssdev)
{ {
struct lb035q02_data *ld = dev_get_drvdata(&dssdev->dev); struct lb035q02_data *ld = dev_get_drvdata(dssdev->dev);
mutex_lock(&ld->lock); mutex_lock(&ld->lock);

Просмотреть файл

@ -311,16 +311,16 @@ static int n8x0_panel_power_on(struct omap_dss_device *dssdev)
switch (rev & 0xfc) { switch (rev & 0xfc) {
case 0x9c: case 0x9c:
ddata->blizzard_ver = BLIZZARD_VERSION_S1D13744; ddata->blizzard_ver = BLIZZARD_VERSION_S1D13744;
dev_info(&dssdev->dev, "s1d13744 LCD controller rev %d " dev_info(dssdev->dev, "s1d13744 LCD controller rev %d "
"initialized (CNF pins %x)\n", rev & 0x03, conf & 0x07); "initialized (CNF pins %x)\n", rev & 0x03, conf & 0x07);
break; break;
case 0xa4: case 0xa4:
ddata->blizzard_ver = BLIZZARD_VERSION_S1D13745; ddata->blizzard_ver = BLIZZARD_VERSION_S1D13745;
dev_info(&dssdev->dev, "s1d13745 LCD controller rev %d " dev_info(dssdev->dev, "s1d13745 LCD controller rev %d "
"initialized (CNF pins %x)\n", rev & 0x03, conf & 0x07); "initialized (CNF pins %x)\n", rev & 0x03, conf & 0x07);
break; break;
default: default:
dev_err(&dssdev->dev, "invalid s1d1374x revision %02x\n", rev); dev_err(dssdev->dev, "invalid s1d1374x revision %02x\n", rev);
r = -ENODEV; r = -ENODEV;
goto err_inv_chip; goto err_inv_chip;
} }
@ -341,13 +341,13 @@ static int n8x0_panel_power_on(struct omap_dss_device *dssdev)
panel_name = "ls041y3"; panel_name = "ls041y3";
break; break;
default: default:
dev_err(&dssdev->dev, "invalid display ID 0x%x\n", dev_err(dssdev->dev, "invalid display ID 0x%x\n",
display_id[0]); display_id[0]);
r = -ENODEV; r = -ENODEV;
goto err_inv_panel; goto err_inv_panel;
} }
dev_info(&dssdev->dev, "%s rev %02x LCD detected\n", dev_info(dssdev->dev, "%s rev %02x LCD detected\n",
panel_name, display_id[1]); panel_name, display_id[1]);
send_sleep_out(spi); send_sleep_out(spi);
@ -416,7 +416,7 @@ static int n8x0_panel_probe(struct omap_dss_device *dssdev)
struct panel_drv_data *ddata; struct panel_drv_data *ddata;
int r; int r;
dev_dbg(&dssdev->dev, "probe\n"); dev_dbg(dssdev->dev, "probe\n");
if (!bdata) if (!bdata)
return -EINVAL; return -EINVAL;
@ -434,14 +434,14 @@ static int n8x0_panel_probe(struct omap_dss_device *dssdev)
dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE; dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE;
if (gpio_is_valid(bdata->panel_reset)) { if (gpio_is_valid(bdata->panel_reset)) {
r = devm_gpio_request_one(&dssdev->dev, bdata->panel_reset, r = devm_gpio_request_one(dssdev->dev, bdata->panel_reset,
GPIOF_OUT_INIT_LOW, "PANEL RESET"); GPIOF_OUT_INIT_LOW, "PANEL RESET");
if (r) if (r)
return r; return r;
} }
if (gpio_is_valid(bdata->ctrl_pwrdown)) { if (gpio_is_valid(bdata->ctrl_pwrdown)) {
r = devm_gpio_request_one(&dssdev->dev, bdata->ctrl_pwrdown, r = devm_gpio_request_one(dssdev->dev, bdata->ctrl_pwrdown,
GPIOF_OUT_INIT_LOW, "PANEL PWRDOWN"); GPIOF_OUT_INIT_LOW, "PANEL PWRDOWN");
if (r) if (r)
return r; return r;
@ -452,9 +452,9 @@ static int n8x0_panel_probe(struct omap_dss_device *dssdev)
static void n8x0_panel_remove(struct omap_dss_device *dssdev) static void n8x0_panel_remove(struct omap_dss_device *dssdev)
{ {
dev_dbg(&dssdev->dev, "remove\n"); dev_dbg(dssdev->dev, "remove\n");
dev_set_drvdata(&dssdev->dev, NULL); dev_set_drvdata(dssdev->dev, NULL);
} }
static int n8x0_panel_enable(struct omap_dss_device *dssdev) static int n8x0_panel_enable(struct omap_dss_device *dssdev)
@ -462,7 +462,7 @@ static int n8x0_panel_enable(struct omap_dss_device *dssdev)
struct panel_drv_data *ddata = get_drv_data(dssdev); struct panel_drv_data *ddata = get_drv_data(dssdev);
int r; int r;
dev_dbg(&dssdev->dev, "enable\n"); dev_dbg(dssdev->dev, "enable\n");
mutex_lock(&ddata->lock); mutex_lock(&ddata->lock);
@ -488,7 +488,7 @@ static void n8x0_panel_disable(struct omap_dss_device *dssdev)
{ {
struct panel_drv_data *ddata = get_drv_data(dssdev); struct panel_drv_data *ddata = get_drv_data(dssdev);
dev_dbg(&dssdev->dev, "disable\n"); dev_dbg(dssdev->dev, "disable\n");
mutex_lock(&ddata->lock); mutex_lock(&ddata->lock);
@ -521,13 +521,13 @@ static int n8x0_panel_update(struct omap_dss_device *dssdev,
struct panel_drv_data *ddata = get_drv_data(dssdev); struct panel_drv_data *ddata = get_drv_data(dssdev);
u16 dw, dh; u16 dw, dh;
dev_dbg(&dssdev->dev, "update\n"); dev_dbg(dssdev->dev, "update\n");
dw = dssdev->panel.timings.x_res; dw = dssdev->panel.timings.x_res;
dh = dssdev->panel.timings.y_res; dh = dssdev->panel.timings.y_res;
if (x != 0 || y != 0 || w != dw || h != dh) { if (x != 0 || y != 0 || w != dw || h != dh) {
dev_err(&dssdev->dev, "invaid update region %d, %d, %d, %d\n", dev_err(dssdev->dev, "invaid update region %d, %d, %d, %d\n",
x, y, w, h); x, y, w, h);
return -EINVAL; return -EINVAL;
} }
@ -548,7 +548,7 @@ static int n8x0_panel_sync(struct omap_dss_device *dssdev)
{ {
struct panel_drv_data *ddata = get_drv_data(dssdev); struct panel_drv_data *ddata = get_drv_data(dssdev);
dev_dbg(&dssdev->dev, "sync\n"); dev_dbg(dssdev->dev, "sync\n");
mutex_lock(&ddata->lock); mutex_lock(&ddata->lock);
rfbi_bus_lock(); rfbi_bus_lock();

Просмотреть файл

@ -98,14 +98,14 @@ static int nec_8048_panel_probe(struct omap_dss_device *dssdev)
dssdev->panel.timings = nec_8048_panel_timings; dssdev->panel.timings = nec_8048_panel_timings;
if (gpio_is_valid(pd->qvga_gpio)) { if (gpio_is_valid(pd->qvga_gpio)) {
r = devm_gpio_request_one(&dssdev->dev, pd->qvga_gpio, r = devm_gpio_request_one(dssdev->dev, pd->qvga_gpio,
GPIOF_OUT_INIT_HIGH, "lcd QVGA"); GPIOF_OUT_INIT_HIGH, "lcd QVGA");
if (r) if (r)
return r; return r;
} }
if (gpio_is_valid(pd->res_gpio)) { if (gpio_is_valid(pd->res_gpio)) {
r = devm_gpio_request_one(&dssdev->dev, pd->res_gpio, r = devm_gpio_request_one(dssdev->dev, pd->res_gpio,
GPIOF_OUT_INIT_LOW, "lcd RES"); GPIOF_OUT_INIT_LOW, "lcd RES");
if (r) if (r)
return r; return r;

Просмотреть файл

@ -351,7 +351,7 @@ static struct i2c_driver picodlp_i2c_driver = {
static int picodlp_panel_power_on(struct omap_dss_device *dssdev) static int picodlp_panel_power_on(struct omap_dss_device *dssdev)
{ {
int r, trial = 100; int r, trial = 100;
struct picodlp_data *picod = dev_get_drvdata(&dssdev->dev); struct picodlp_data *picod = dev_get_drvdata(dssdev->dev);
struct picodlp_panel_data *picodlp_pdata = get_panel_data(dssdev); struct picodlp_panel_data *picodlp_pdata = get_panel_data(dssdev);
gpio_set_value(picodlp_pdata->pwrgood_gpio, 0); gpio_set_value(picodlp_pdata->pwrgood_gpio, 0);
@ -360,7 +360,7 @@ static int picodlp_panel_power_on(struct omap_dss_device *dssdev)
while (!gpio_get_value(picodlp_pdata->emu_done_gpio)) { while (!gpio_get_value(picodlp_pdata->emu_done_gpio)) {
if (!trial--) { if (!trial--) {
dev_err(&dssdev->dev, "emu_done signal not" dev_err(dssdev->dev, "emu_done signal not"
" going high\n"); " going high\n");
return -ETIMEDOUT; return -ETIMEDOUT;
} }
@ -378,7 +378,7 @@ static int picodlp_panel_power_on(struct omap_dss_device *dssdev)
r = omapdss_dpi_display_enable(dssdev); r = omapdss_dpi_display_enable(dssdev);
if (r) { if (r) {
dev_err(&dssdev->dev, "failed to enable DPI\n"); dev_err(dssdev->dev, "failed to enable DPI\n");
goto err1; goto err1;
} }
@ -418,7 +418,7 @@ static int picodlp_panel_probe(struct omap_dss_device *dssdev)
if (!picodlp_pdata) if (!picodlp_pdata)
return -EINVAL; return -EINVAL;
picod = devm_kzalloc(&dssdev->dev, sizeof(*picod), GFP_KERNEL); picod = devm_kzalloc(dssdev->dev, sizeof(*picod), GFP_KERNEL);
if (!picod) if (!picod)
return -ENOMEM; return -ENOMEM;
@ -428,23 +428,23 @@ static int picodlp_panel_probe(struct omap_dss_device *dssdev)
adapter = i2c_get_adapter(picodlp_adapter_id); adapter = i2c_get_adapter(picodlp_adapter_id);
if (!adapter) { if (!adapter) {
dev_err(&dssdev->dev, "can't get i2c adapter\n"); dev_err(dssdev->dev, "can't get i2c adapter\n");
return -ENODEV; return -ENODEV;
} }
picodlp_i2c_client = i2c_new_device(adapter, &picodlp_i2c_board_info); picodlp_i2c_client = i2c_new_device(adapter, &picodlp_i2c_board_info);
if (!picodlp_i2c_client) { if (!picodlp_i2c_client) {
dev_err(&dssdev->dev, "can't add i2c device::" dev_err(dssdev->dev, "can't add i2c device::"
" picodlp_i2c_client is NULL\n"); " picodlp_i2c_client is NULL\n");
return -ENODEV; return -ENODEV;
} }
picod->picodlp_i2c_client = picodlp_i2c_client; picod->picodlp_i2c_client = picodlp_i2c_client;
dev_set_drvdata(&dssdev->dev, picod); dev_set_drvdata(dssdev->dev, picod);
if (gpio_is_valid(picodlp_pdata->emu_done_gpio)) { if (gpio_is_valid(picodlp_pdata->emu_done_gpio)) {
r = devm_gpio_request_one(&dssdev->dev, r = devm_gpio_request_one(dssdev->dev,
picodlp_pdata->emu_done_gpio, picodlp_pdata->emu_done_gpio,
GPIOF_IN, "DLP EMU DONE"); GPIOF_IN, "DLP EMU DONE");
if (r) if (r)
@ -452,7 +452,7 @@ static int picodlp_panel_probe(struct omap_dss_device *dssdev)
} }
if (gpio_is_valid(picodlp_pdata->pwrgood_gpio)) { if (gpio_is_valid(picodlp_pdata->pwrgood_gpio)) {
r = devm_gpio_request_one(&dssdev->dev, r = devm_gpio_request_one(dssdev->dev,
picodlp_pdata->pwrgood_gpio, picodlp_pdata->pwrgood_gpio,
GPIOF_OUT_INIT_LOW, "DLP PWRGOOD"); GPIOF_OUT_INIT_LOW, "DLP PWRGOOD");
if (r) if (r)
@ -464,21 +464,19 @@ static int picodlp_panel_probe(struct omap_dss_device *dssdev)
static void picodlp_panel_remove(struct omap_dss_device *dssdev) static void picodlp_panel_remove(struct omap_dss_device *dssdev)
{ {
struct picodlp_data *picod = dev_get_drvdata(&dssdev->dev); struct picodlp_data *picod = dev_get_drvdata(dssdev->dev);
i2c_unregister_device(picod->picodlp_i2c_client); i2c_unregister_device(picod->picodlp_i2c_client);
dev_set_drvdata(&dssdev->dev, NULL); dev_set_drvdata(dssdev->dev, NULL);
dev_dbg(&dssdev->dev, "removing picodlp panel\n"); dev_dbg(dssdev->dev, "removing picodlp panel\n");
kfree(picod);
} }
static int picodlp_panel_enable(struct omap_dss_device *dssdev) static int picodlp_panel_enable(struct omap_dss_device *dssdev)
{ {
struct picodlp_data *picod = dev_get_drvdata(&dssdev->dev); struct picodlp_data *picod = dev_get_drvdata(dssdev->dev);
int r; int r;
dev_dbg(&dssdev->dev, "enabling picodlp panel\n"); dev_dbg(dssdev->dev, "enabling picodlp panel\n");
mutex_lock(&picod->lock); mutex_lock(&picod->lock);
if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) { if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) {
@ -494,7 +492,7 @@ static int picodlp_panel_enable(struct omap_dss_device *dssdev)
static void picodlp_panel_disable(struct omap_dss_device *dssdev) static void picodlp_panel_disable(struct omap_dss_device *dssdev)
{ {
struct picodlp_data *picod = dev_get_drvdata(&dssdev->dev); struct picodlp_data *picod = dev_get_drvdata(dssdev->dev);
mutex_lock(&picod->lock); mutex_lock(&picod->lock);
/* Turn off DLP Power */ /* Turn off DLP Power */
@ -504,7 +502,7 @@ static void picodlp_panel_disable(struct omap_dss_device *dssdev)
dssdev->state = OMAP_DSS_DISPLAY_DISABLED; dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
mutex_unlock(&picod->lock); mutex_unlock(&picod->lock);
dev_dbg(&dssdev->dev, "disabling picodlp panel\n"); dev_dbg(dssdev->dev, "disabling picodlp panel\n");
} }
static void picodlp_get_resolution(struct omap_dss_device *dssdev, static void picodlp_get_resolution(struct omap_dss_device *dssdev,

Просмотреть файл

@ -66,35 +66,35 @@ static int sharp_ls_panel_probe(struct omap_dss_device *dssdev)
dssdev->panel.timings = sharp_ls_timings; dssdev->panel.timings = sharp_ls_timings;
if (gpio_is_valid(pd->mo_gpio)) { if (gpio_is_valid(pd->mo_gpio)) {
r = devm_gpio_request_one(&dssdev->dev, pd->mo_gpio, r = devm_gpio_request_one(dssdev->dev, pd->mo_gpio,
GPIOF_OUT_INIT_LOW, "lcd MO"); GPIOF_OUT_INIT_LOW, "lcd MO");
if (r) if (r)
return r; return r;
} }
if (gpio_is_valid(pd->lr_gpio)) { if (gpio_is_valid(pd->lr_gpio)) {
r = devm_gpio_request_one(&dssdev->dev, pd->lr_gpio, r = devm_gpio_request_one(dssdev->dev, pd->lr_gpio,
GPIOF_OUT_INIT_HIGH, "lcd LR"); GPIOF_OUT_INIT_HIGH, "lcd LR");
if (r) if (r)
return r; return r;
} }
if (gpio_is_valid(pd->ud_gpio)) { if (gpio_is_valid(pd->ud_gpio)) {
r = devm_gpio_request_one(&dssdev->dev, pd->ud_gpio, r = devm_gpio_request_one(dssdev->dev, pd->ud_gpio,
GPIOF_OUT_INIT_HIGH, "lcd UD"); GPIOF_OUT_INIT_HIGH, "lcd UD");
if (r) if (r)
return r; return r;
} }
if (gpio_is_valid(pd->resb_gpio)) { if (gpio_is_valid(pd->resb_gpio)) {
r = devm_gpio_request_one(&dssdev->dev, pd->resb_gpio, r = devm_gpio_request_one(dssdev->dev, pd->resb_gpio,
GPIOF_OUT_INIT_LOW, "lcd RESB"); GPIOF_OUT_INIT_LOW, "lcd RESB");
if (r) if (r)
return r; return r;
} }
if (gpio_is_valid(pd->ini_gpio)) { if (gpio_is_valid(pd->ini_gpio)) {
r = devm_gpio_request_one(&dssdev->dev, pd->ini_gpio, r = devm_gpio_request_one(dssdev->dev, pd->ini_gpio,
GPIOF_OUT_INIT_LOW, "lcd INI"); GPIOF_OUT_INIT_LOW, "lcd INI");
if (r) if (r)
return r; return r;

Просмотреть файл

@ -237,7 +237,7 @@ static int taal_set_update_window(struct taal_data *td,
static void taal_queue_esd_work(struct omap_dss_device *dssdev) static void taal_queue_esd_work(struct omap_dss_device *dssdev)
{ {
struct taal_data *td = dev_get_drvdata(&dssdev->dev); struct taal_data *td = dev_get_drvdata(dssdev->dev);
if (td->esd_interval > 0) if (td->esd_interval > 0)
queue_delayed_work(td->workqueue, &td->esd_work, queue_delayed_work(td->workqueue, &td->esd_work,
@ -246,14 +246,14 @@ static void taal_queue_esd_work(struct omap_dss_device *dssdev)
static void taal_cancel_esd_work(struct omap_dss_device *dssdev) static void taal_cancel_esd_work(struct omap_dss_device *dssdev)
{ {
struct taal_data *td = dev_get_drvdata(&dssdev->dev); struct taal_data *td = dev_get_drvdata(dssdev->dev);
cancel_delayed_work(&td->esd_work); cancel_delayed_work(&td->esd_work);
} }
static void taal_queue_ulps_work(struct omap_dss_device *dssdev) static void taal_queue_ulps_work(struct omap_dss_device *dssdev)
{ {
struct taal_data *td = dev_get_drvdata(&dssdev->dev); struct taal_data *td = dev_get_drvdata(dssdev->dev);
if (td->ulps_timeout > 0) if (td->ulps_timeout > 0)
queue_delayed_work(td->workqueue, &td->ulps_work, queue_delayed_work(td->workqueue, &td->ulps_work,
@ -262,14 +262,14 @@ static void taal_queue_ulps_work(struct omap_dss_device *dssdev)
static void taal_cancel_ulps_work(struct omap_dss_device *dssdev) static void taal_cancel_ulps_work(struct omap_dss_device *dssdev)
{ {
struct taal_data *td = dev_get_drvdata(&dssdev->dev); struct taal_data *td = dev_get_drvdata(dssdev->dev);
cancel_delayed_work(&td->ulps_work); cancel_delayed_work(&td->ulps_work);
} }
static int taal_enter_ulps(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 taal_data *td = dev_get_drvdata(dssdev->dev);
int r; int r;
if (td->ulps_enabled) if (td->ulps_enabled)
@ -291,7 +291,7 @@ static int taal_enter_ulps(struct omap_dss_device *dssdev)
return 0; return 0;
err: err:
dev_err(&dssdev->dev, "enter ULPS failed"); dev_err(dssdev->dev, "enter ULPS failed");
taal_panel_reset(dssdev); taal_panel_reset(dssdev);
td->ulps_enabled = false; td->ulps_enabled = false;
@ -303,7 +303,7 @@ err:
static int taal_exit_ulps(struct omap_dss_device *dssdev) static int taal_exit_ulps(struct omap_dss_device *dssdev)
{ {
struct taal_data *td = dev_get_drvdata(&dssdev->dev); struct taal_data *td = dev_get_drvdata(dssdev->dev);
int r; int r;
if (!td->ulps_enabled) if (!td->ulps_enabled)
@ -311,7 +311,7 @@ static int taal_exit_ulps(struct omap_dss_device *dssdev)
r = omapdss_dsi_display_enable(dssdev); r = omapdss_dsi_display_enable(dssdev);
if (r) { if (r) {
dev_err(&dssdev->dev, "failed to enable DSI\n"); dev_err(dssdev->dev, "failed to enable DSI\n");
goto err1; goto err1;
} }
@ -319,7 +319,7 @@ static int taal_exit_ulps(struct omap_dss_device *dssdev)
r = _taal_enable_te(dssdev, true); r = _taal_enable_te(dssdev, true);
if (r) { if (r) {
dev_err(&dssdev->dev, "failed to re-enable TE"); dev_err(dssdev->dev, "failed to re-enable TE");
goto err2; goto err2;
} }
@ -333,7 +333,7 @@ static int taal_exit_ulps(struct omap_dss_device *dssdev)
return 0; return 0;
err2: err2:
dev_err(&dssdev->dev, "failed to exit ULPS"); dev_err(dssdev->dev, "failed to exit ULPS");
r = taal_panel_reset(dssdev); r = taal_panel_reset(dssdev);
if (!r) { if (!r) {
@ -349,7 +349,7 @@ err1:
static int taal_wake_up(struct omap_dss_device *dssdev) static int taal_wake_up(struct omap_dss_device *dssdev)
{ {
struct taal_data *td = dev_get_drvdata(&dssdev->dev); struct taal_data *td = dev_get_drvdata(dssdev->dev);
if (td->ulps_enabled) if (td->ulps_enabled)
return taal_exit_ulps(dssdev); return taal_exit_ulps(dssdev);
@ -362,7 +362,7 @@ static int taal_wake_up(struct omap_dss_device *dssdev)
static int taal_bl_update_status(struct backlight_device *dev) static int taal_bl_update_status(struct backlight_device *dev)
{ {
struct omap_dss_device *dssdev = dev_get_drvdata(&dev->dev); struct omap_dss_device *dssdev = dev_get_drvdata(&dev->dev);
struct taal_data *td = dev_get_drvdata(&dssdev->dev); struct taal_data *td = dev_get_drvdata(dssdev->dev);
int r; int r;
int level; int level;
@ -372,7 +372,7 @@ static int taal_bl_update_status(struct backlight_device *dev)
else else
level = 0; level = 0;
dev_dbg(&dssdev->dev, "update brightness to %d\n", level); dev_dbg(dssdev->dev, "update brightness to %d\n", level);
mutex_lock(&td->lock); mutex_lock(&td->lock);
@ -418,7 +418,7 @@ static ssize_t taal_num_errors_show(struct device *dev,
struct device_attribute *attr, char *buf) struct device_attribute *attr, char *buf)
{ {
struct omap_dss_device *dssdev = to_dss_device(dev); struct omap_dss_device *dssdev = to_dss_device(dev);
struct taal_data *td = dev_get_drvdata(&dssdev->dev); struct taal_data *td = dev_get_drvdata(dssdev->dev);
u8 errors = 0; u8 errors = 0;
int r; int r;
@ -448,7 +448,7 @@ static ssize_t taal_hw_revision_show(struct device *dev,
struct device_attribute *attr, char *buf) struct device_attribute *attr, char *buf)
{ {
struct omap_dss_device *dssdev = to_dss_device(dev); struct omap_dss_device *dssdev = to_dss_device(dev);
struct taal_data *td = dev_get_drvdata(&dssdev->dev); struct taal_data *td = dev_get_drvdata(dssdev->dev);
u8 id1, id2, id3; u8 id1, id2, id3;
int r; int r;
@ -486,7 +486,7 @@ static ssize_t show_cabc_mode(struct device *dev,
char *buf) char *buf)
{ {
struct omap_dss_device *dssdev = to_dss_device(dev); struct omap_dss_device *dssdev = to_dss_device(dev);
struct taal_data *td = dev_get_drvdata(&dssdev->dev); struct taal_data *td = dev_get_drvdata(dssdev->dev);
const char *mode_str; const char *mode_str;
int mode; int mode;
int len; int len;
@ -506,7 +506,7 @@ static ssize_t store_cabc_mode(struct device *dev,
const char *buf, size_t count) const char *buf, size_t count)
{ {
struct omap_dss_device *dssdev = to_dss_device(dev); struct omap_dss_device *dssdev = to_dss_device(dev);
struct taal_data *td = dev_get_drvdata(&dssdev->dev); struct taal_data *td = dev_get_drvdata(dssdev->dev);
int i; int i;
int r; int r;
@ -568,7 +568,7 @@ static ssize_t taal_store_esd_interval(struct device *dev,
const char *buf, size_t count) const char *buf, size_t count)
{ {
struct omap_dss_device *dssdev = to_dss_device(dev); struct omap_dss_device *dssdev = to_dss_device(dev);
struct taal_data *td = dev_get_drvdata(&dssdev->dev); struct taal_data *td = dev_get_drvdata(dssdev->dev);
unsigned long t; unsigned long t;
int r; int r;
@ -592,7 +592,7 @@ static ssize_t taal_show_esd_interval(struct device *dev,
char *buf) char *buf)
{ {
struct omap_dss_device *dssdev = to_dss_device(dev); struct omap_dss_device *dssdev = to_dss_device(dev);
struct taal_data *td = dev_get_drvdata(&dssdev->dev); struct taal_data *td = dev_get_drvdata(dssdev->dev);
unsigned t; unsigned t;
mutex_lock(&td->lock); mutex_lock(&td->lock);
@ -607,7 +607,7 @@ static ssize_t taal_store_ulps(struct device *dev,
const char *buf, size_t count) const char *buf, size_t count)
{ {
struct omap_dss_device *dssdev = to_dss_device(dev); struct omap_dss_device *dssdev = to_dss_device(dev);
struct taal_data *td = dev_get_drvdata(&dssdev->dev); struct taal_data *td = dev_get_drvdata(dssdev->dev);
unsigned long t; unsigned long t;
int r; int r;
@ -641,7 +641,7 @@ static ssize_t taal_show_ulps(struct device *dev,
char *buf) char *buf)
{ {
struct omap_dss_device *dssdev = to_dss_device(dev); struct omap_dss_device *dssdev = to_dss_device(dev);
struct taal_data *td = dev_get_drvdata(&dssdev->dev); struct taal_data *td = dev_get_drvdata(dssdev->dev);
unsigned t; unsigned t;
mutex_lock(&td->lock); mutex_lock(&td->lock);
@ -656,7 +656,7 @@ static ssize_t taal_store_ulps_timeout(struct device *dev,
const char *buf, size_t count) const char *buf, size_t count)
{ {
struct omap_dss_device *dssdev = to_dss_device(dev); struct omap_dss_device *dssdev = to_dss_device(dev);
struct taal_data *td = dev_get_drvdata(&dssdev->dev); struct taal_data *td = dev_get_drvdata(dssdev->dev);
unsigned long t; unsigned long t;
int r; int r;
@ -687,7 +687,7 @@ static ssize_t taal_show_ulps_timeout(struct device *dev,
char *buf) char *buf)
{ {
struct omap_dss_device *dssdev = to_dss_device(dev); struct omap_dss_device *dssdev = to_dss_device(dev);
struct taal_data *td = dev_get_drvdata(&dssdev->dev); struct taal_data *td = dev_get_drvdata(dssdev->dev);
unsigned t; unsigned t;
mutex_lock(&td->lock); mutex_lock(&td->lock);
@ -727,7 +727,7 @@ static struct attribute_group taal_attr_group = {
static void taal_hw_reset(struct omap_dss_device *dssdev) static void taal_hw_reset(struct omap_dss_device *dssdev)
{ {
struct taal_data *td = dev_get_drvdata(&dssdev->dev); struct taal_data *td = dev_get_drvdata(dssdev->dev);
if (!gpio_is_valid(td->reset_gpio)) if (!gpio_is_valid(td->reset_gpio))
return; return;
@ -768,13 +768,13 @@ static int taal_probe(struct omap_dss_device *dssdev)
struct backlight_device *bldev = NULL; struct backlight_device *bldev = NULL;
int r; int r;
dev_dbg(&dssdev->dev, "probe\n"); dev_dbg(dssdev->dev, "probe\n");
td = devm_kzalloc(&dssdev->dev, sizeof(*td), GFP_KERNEL); td = devm_kzalloc(dssdev->dev, sizeof(*td), GFP_KERNEL);
if (!td) if (!td)
return -ENOMEM; return -ENOMEM;
dev_set_drvdata(&dssdev->dev, td); dev_set_drvdata(dssdev->dev, td);
td->dssdev = dssdev; td->dssdev = dssdev;
if (dssdev->data) { if (dssdev->data) {
@ -797,41 +797,41 @@ static int taal_probe(struct omap_dss_device *dssdev)
atomic_set(&td->do_update, 0); atomic_set(&td->do_update, 0);
if (gpio_is_valid(td->reset_gpio)) { if (gpio_is_valid(td->reset_gpio)) {
r = devm_gpio_request_one(&dssdev->dev, td->reset_gpio, r = devm_gpio_request_one(dssdev->dev, td->reset_gpio,
GPIOF_OUT_INIT_LOW, "taal rst"); GPIOF_OUT_INIT_LOW, "taal rst");
if (r) { if (r) {
dev_err(&dssdev->dev, "failed to request reset gpio\n"); dev_err(dssdev->dev, "failed to request reset gpio\n");
return r; return r;
} }
} }
if (gpio_is_valid(td->ext_te_gpio)) { if (gpio_is_valid(td->ext_te_gpio)) {
r = devm_gpio_request_one(&dssdev->dev, td->ext_te_gpio, r = devm_gpio_request_one(dssdev->dev, td->ext_te_gpio,
GPIOF_IN, "taal irq"); GPIOF_IN, "taal irq");
if (r) { if (r) {
dev_err(&dssdev->dev, "GPIO request failed\n"); dev_err(dssdev->dev, "GPIO request failed\n");
return r; return r;
} }
r = devm_request_irq(&dssdev->dev, gpio_to_irq(td->ext_te_gpio), r = devm_request_irq(dssdev->dev, gpio_to_irq(td->ext_te_gpio),
taal_te_isr, taal_te_isr,
IRQF_TRIGGER_RISING, IRQF_TRIGGER_RISING,
"taal vsync", dssdev); "taal vsync", dssdev);
if (r) { if (r) {
dev_err(&dssdev->dev, "IRQ request failed\n"); dev_err(dssdev->dev, "IRQ request failed\n");
return r; return r;
} }
INIT_DEFERRABLE_WORK(&td->te_timeout_work, INIT_DEFERRABLE_WORK(&td->te_timeout_work,
taal_te_timeout_work_callback); taal_te_timeout_work_callback);
dev_dbg(&dssdev->dev, "Using GPIO TE\n"); dev_dbg(dssdev->dev, "Using GPIO TE\n");
} }
td->workqueue = create_singlethread_workqueue("taal_esd"); td->workqueue = create_singlethread_workqueue("taal_esd");
if (td->workqueue == NULL) { if (td->workqueue == NULL) {
dev_err(&dssdev->dev, "can't create ESD workqueue\n"); dev_err(dssdev->dev, "can't create ESD workqueue\n");
return -ENOMEM; return -ENOMEM;
} }
INIT_DEFERRABLE_WORK(&td->esd_work, taal_esd_work); INIT_DEFERRABLE_WORK(&td->esd_work, taal_esd_work);
@ -844,8 +844,8 @@ static int taal_probe(struct omap_dss_device *dssdev)
props.max_brightness = 255; props.max_brightness = 255;
props.type = BACKLIGHT_RAW; props.type = BACKLIGHT_RAW;
bldev = backlight_device_register(dev_name(&dssdev->dev), bldev = backlight_device_register(dev_name(dssdev->dev),
&dssdev->dev, dssdev, &taal_bl_ops, &props); dssdev->dev, dssdev, &taal_bl_ops, &props);
if (IS_ERR(bldev)) { if (IS_ERR(bldev)) {
r = PTR_ERR(bldev); r = PTR_ERR(bldev);
goto err_bl; goto err_bl;
@ -862,19 +862,19 @@ static int taal_probe(struct omap_dss_device *dssdev)
r = omap_dsi_request_vc(dssdev, &td->channel); r = omap_dsi_request_vc(dssdev, &td->channel);
if (r) { if (r) {
dev_err(&dssdev->dev, "failed to get virtual channel\n"); dev_err(dssdev->dev, "failed to get virtual channel\n");
goto err_req_vc; goto err_req_vc;
} }
r = omap_dsi_set_vc_id(dssdev, td->channel, TCH); r = omap_dsi_set_vc_id(dssdev, td->channel, TCH);
if (r) { if (r) {
dev_err(&dssdev->dev, "failed to set VC_ID\n"); dev_err(dssdev->dev, "failed to set VC_ID\n");
goto err_vc_id; goto err_vc_id;
} }
r = sysfs_create_group(&dssdev->dev.kobj, &taal_attr_group); r = sysfs_create_group(&dssdev->dev->kobj, &taal_attr_group);
if (r) { if (r) {
dev_err(&dssdev->dev, "failed to create sysfs files\n"); dev_err(dssdev->dev, "failed to create sysfs files\n");
goto err_vc_id; goto err_vc_id;
} }
@ -892,12 +892,12 @@ err_bl:
static void __exit taal_remove(struct omap_dss_device *dssdev) static void __exit taal_remove(struct omap_dss_device *dssdev)
{ {
struct taal_data *td = dev_get_drvdata(&dssdev->dev); struct taal_data *td = dev_get_drvdata(dssdev->dev);
struct backlight_device *bldev; struct backlight_device *bldev;
dev_dbg(&dssdev->dev, "remove\n"); dev_dbg(dssdev->dev, "remove\n");
sysfs_remove_group(&dssdev->dev.kobj, &taal_attr_group); sysfs_remove_group(&dssdev->dev->kobj, &taal_attr_group);
omap_dsi_release_vc(dssdev, td->channel); omap_dsi_release_vc(dssdev, td->channel);
bldev = td->bldev; bldev = td->bldev;
@ -917,7 +917,7 @@ static void __exit taal_remove(struct omap_dss_device *dssdev)
static int taal_power_on(struct omap_dss_device *dssdev) static int taal_power_on(struct omap_dss_device *dssdev)
{ {
struct taal_data *td = dev_get_drvdata(&dssdev->dev); struct taal_data *td = dev_get_drvdata(dssdev->dev);
u8 id1, id2, id3; u8 id1, id2, id3;
int r; int r;
struct omap_dss_dsi_config dsi_config = { struct omap_dss_dsi_config dsi_config = {
@ -932,19 +932,19 @@ static int taal_power_on(struct omap_dss_device *dssdev)
r = omapdss_dsi_configure_pins(dssdev, &td->pin_config); r = omapdss_dsi_configure_pins(dssdev, &td->pin_config);
if (r) { if (r) {
dev_err(&dssdev->dev, "failed to configure DSI pins\n"); dev_err(dssdev->dev, "failed to configure DSI pins\n");
goto err0; goto err0;
}; };
r = omapdss_dsi_set_config(dssdev, &dsi_config); r = omapdss_dsi_set_config(dssdev, &dsi_config);
if (r) { if (r) {
dev_err(&dssdev->dev, "failed to configure DSI\n"); dev_err(dssdev->dev, "failed to configure DSI\n");
goto err0; goto err0;
} }
r = omapdss_dsi_display_enable(dssdev); r = omapdss_dsi_display_enable(dssdev);
if (r) { if (r) {
dev_err(&dssdev->dev, "failed to enable DSI\n"); dev_err(dssdev->dev, "failed to enable DSI\n");
goto err0; goto err0;
} }
@ -999,10 +999,10 @@ static int taal_power_on(struct omap_dss_device *dssdev)
td->enabled = 1; td->enabled = 1;
if (!td->intro_printed) { if (!td->intro_printed) {
dev_info(&dssdev->dev, "panel revision %02x.%02x.%02x\n", dev_info(dssdev->dev, "panel revision %02x.%02x.%02x\n",
id1, id2, id3); id1, id2, id3);
if (td->cabc_broken) if (td->cabc_broken)
dev_info(&dssdev->dev, dev_info(dssdev->dev,
"old Taal version, CABC disabled\n"); "old Taal version, CABC disabled\n");
td->intro_printed = true; td->intro_printed = true;
} }
@ -1011,7 +1011,7 @@ static int taal_power_on(struct omap_dss_device *dssdev)
return 0; return 0;
err: err:
dev_err(&dssdev->dev, "error while enabling panel, issuing HW reset\n"); dev_err(dssdev->dev, "error while enabling panel, issuing HW reset\n");
taal_hw_reset(dssdev); taal_hw_reset(dssdev);
@ -1022,7 +1022,7 @@ err0:
static void taal_power_off(struct omap_dss_device *dssdev) static void taal_power_off(struct omap_dss_device *dssdev)
{ {
struct taal_data *td = dev_get_drvdata(&dssdev->dev); struct taal_data *td = dev_get_drvdata(dssdev->dev);
int r; int r;
dsi_disable_video_output(dssdev, td->channel); dsi_disable_video_output(dssdev, td->channel);
@ -1032,7 +1032,7 @@ static void taal_power_off(struct omap_dss_device *dssdev)
r = taal_sleep_in(td); r = taal_sleep_in(td);
if (r) { if (r) {
dev_err(&dssdev->dev, dev_err(dssdev->dev,
"error disabling panel, issuing HW reset\n"); "error disabling panel, issuing HW reset\n");
taal_hw_reset(dssdev); taal_hw_reset(dssdev);
} }
@ -1044,7 +1044,7 @@ static void taal_power_off(struct omap_dss_device *dssdev)
static int taal_panel_reset(struct omap_dss_device *dssdev) static int taal_panel_reset(struct omap_dss_device *dssdev)
{ {
dev_err(&dssdev->dev, "performing LCD reset\n"); dev_err(dssdev->dev, "performing LCD reset\n");
taal_power_off(dssdev); taal_power_off(dssdev);
taal_hw_reset(dssdev); taal_hw_reset(dssdev);
@ -1053,10 +1053,10 @@ static int taal_panel_reset(struct omap_dss_device *dssdev)
static int taal_enable(struct omap_dss_device *dssdev) static int taal_enable(struct omap_dss_device *dssdev)
{ {
struct taal_data *td = dev_get_drvdata(&dssdev->dev); struct taal_data *td = dev_get_drvdata(dssdev->dev);
int r; int r;
dev_dbg(&dssdev->dev, "enable\n"); dev_dbg(dssdev->dev, "enable\n");
mutex_lock(&td->lock); mutex_lock(&td->lock);
@ -1082,16 +1082,16 @@ static int taal_enable(struct omap_dss_device *dssdev)
return 0; return 0;
err: err:
dev_dbg(&dssdev->dev, "enable failed\n"); dev_dbg(dssdev->dev, "enable failed\n");
mutex_unlock(&td->lock); mutex_unlock(&td->lock);
return r; return r;
} }
static void taal_disable(struct omap_dss_device *dssdev) static void taal_disable(struct omap_dss_device *dssdev)
{ {
struct taal_data *td = dev_get_drvdata(&dssdev->dev); struct taal_data *td = dev_get_drvdata(dssdev->dev);
dev_dbg(&dssdev->dev, "disable\n"); dev_dbg(dssdev->dev, "disable\n");
mutex_lock(&td->lock); mutex_lock(&td->lock);
@ -1118,14 +1118,14 @@ static void taal_disable(struct omap_dss_device *dssdev)
static void taal_framedone_cb(int err, void *data) static void taal_framedone_cb(int err, void *data)
{ {
struct omap_dss_device *dssdev = data; struct omap_dss_device *dssdev = data;
dev_dbg(&dssdev->dev, "framedone, err %d\n", err); dev_dbg(dssdev->dev, "framedone, err %d\n", err);
dsi_bus_unlock(dssdev); dsi_bus_unlock(dssdev);
} }
static irqreturn_t taal_te_isr(int irq, void *data) static irqreturn_t taal_te_isr(int irq, void *data)
{ {
struct omap_dss_device *dssdev = data; struct omap_dss_device *dssdev = data;
struct taal_data *td = dev_get_drvdata(&dssdev->dev); struct taal_data *td = dev_get_drvdata(dssdev->dev);
int old; int old;
int r; int r;
@ -1142,7 +1142,7 @@ static irqreturn_t taal_te_isr(int irq, void *data)
return IRQ_HANDLED; return IRQ_HANDLED;
err: err:
dev_err(&dssdev->dev, "start update failed\n"); dev_err(dssdev->dev, "start update failed\n");
dsi_bus_unlock(dssdev); dsi_bus_unlock(dssdev);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
@ -1153,7 +1153,7 @@ static void taal_te_timeout_work_callback(struct work_struct *work)
te_timeout_work.work); te_timeout_work.work);
struct omap_dss_device *dssdev = td->dssdev; struct omap_dss_device *dssdev = td->dssdev;
dev_err(&dssdev->dev, "TE not received for 250ms!\n"); dev_err(dssdev->dev, "TE not received for 250ms!\n");
atomic_set(&td->do_update, 0); atomic_set(&td->do_update, 0);
dsi_bus_unlock(dssdev); dsi_bus_unlock(dssdev);
@ -1162,10 +1162,10 @@ static void taal_te_timeout_work_callback(struct work_struct *work)
static int taal_update(struct omap_dss_device *dssdev, static int taal_update(struct omap_dss_device *dssdev,
u16 x, u16 y, u16 w, u16 h) u16 x, u16 y, u16 w, u16 h)
{ {
struct taal_data *td = dev_get_drvdata(&dssdev->dev); struct taal_data *td = dev_get_drvdata(dssdev->dev);
int r; int r;
dev_dbg(&dssdev->dev, "update %d, %d, %d x %d\n", x, y, w, h); dev_dbg(dssdev->dev, "update %d, %d, %d x %d\n", x, y, w, h);
mutex_lock(&td->lock); mutex_lock(&td->lock);
dsi_bus_lock(dssdev); dsi_bus_lock(dssdev);
@ -1208,23 +1208,23 @@ err:
static int taal_sync(struct omap_dss_device *dssdev) static int taal_sync(struct omap_dss_device *dssdev)
{ {
struct taal_data *td = dev_get_drvdata(&dssdev->dev); struct taal_data *td = dev_get_drvdata(dssdev->dev);
dev_dbg(&dssdev->dev, "sync\n"); dev_dbg(dssdev->dev, "sync\n");
mutex_lock(&td->lock); mutex_lock(&td->lock);
dsi_bus_lock(dssdev); dsi_bus_lock(dssdev);
dsi_bus_unlock(dssdev); dsi_bus_unlock(dssdev);
mutex_unlock(&td->lock); mutex_unlock(&td->lock);
dev_dbg(&dssdev->dev, "sync done\n"); dev_dbg(dssdev->dev, "sync done\n");
return 0; return 0;
} }
static int _taal_enable_te(struct omap_dss_device *dssdev, bool enable) static int _taal_enable_te(struct omap_dss_device *dssdev, bool enable)
{ {
struct taal_data *td = dev_get_drvdata(&dssdev->dev); struct taal_data *td = dev_get_drvdata(dssdev->dev);
int r; int r;
if (enable) if (enable)
@ -1243,7 +1243,7 @@ static int _taal_enable_te(struct omap_dss_device *dssdev, bool enable)
static int taal_enable_te(struct omap_dss_device *dssdev, bool enable) static int taal_enable_te(struct omap_dss_device *dssdev, bool enable)
{ {
struct taal_data *td = dev_get_drvdata(&dssdev->dev); struct taal_data *td = dev_get_drvdata(dssdev->dev);
int r; int r;
mutex_lock(&td->lock); mutex_lock(&td->lock);
@ -1279,7 +1279,7 @@ err:
static int taal_get_te(struct omap_dss_device *dssdev) static int taal_get_te(struct omap_dss_device *dssdev)
{ {
struct taal_data *td = dev_get_drvdata(&dssdev->dev); struct taal_data *td = dev_get_drvdata(dssdev->dev);
int r; int r;
mutex_lock(&td->lock); mutex_lock(&td->lock);
@ -1291,7 +1291,7 @@ static int taal_get_te(struct omap_dss_device *dssdev)
static int taal_run_test(struct omap_dss_device *dssdev, int test_num) static int taal_run_test(struct omap_dss_device *dssdev, int test_num)
{ {
struct taal_data *td = dev_get_drvdata(&dssdev->dev); struct taal_data *td = dev_get_drvdata(dssdev->dev);
u8 id1, id2, id3; u8 id1, id2, id3;
int r; int r;
@ -1336,7 +1336,7 @@ static int taal_memory_read(struct omap_dss_device *dssdev,
int first = 1; int first = 1;
int plen; int plen;
unsigned buf_used = 0; unsigned buf_used = 0;
struct taal_data *td = dev_get_drvdata(&dssdev->dev); struct taal_data *td = dev_get_drvdata(dssdev->dev);
if (size < w * h * 3) if (size < w * h * 3)
return -ENOMEM; return -ENOMEM;
@ -1380,19 +1380,19 @@ static int taal_memory_read(struct omap_dss_device *dssdev,
buf + buf_used, size - buf_used); buf + buf_used, size - buf_used);
if (r < 0) { if (r < 0) {
dev_err(&dssdev->dev, "read error\n"); dev_err(dssdev->dev, "read error\n");
goto err3; goto err3;
} }
buf_used += r; buf_used += r;
if (r < plen) { if (r < plen) {
dev_err(&dssdev->dev, "short read\n"); dev_err(dssdev->dev, "short read\n");
break; break;
} }
if (signal_pending(current)) { if (signal_pending(current)) {
dev_err(&dssdev->dev, "signal pending, " dev_err(dssdev->dev, "signal pending, "
"aborting memory read\n"); "aborting memory read\n");
r = -ERESTARTSYS; r = -ERESTARTSYS;
goto err3; goto err3;
@ -1450,26 +1450,26 @@ static void taal_esd_work(struct work_struct *work)
r = taal_wake_up(dssdev); r = taal_wake_up(dssdev);
if (r) { if (r) {
dev_err(&dssdev->dev, "failed to exit ULPS\n"); dev_err(dssdev->dev, "failed to exit ULPS\n");
goto err; goto err;
} }
r = taal_dcs_read_1(td, MIPI_DCS_GET_DIAGNOSTIC_RESULT, &state1); r = taal_dcs_read_1(td, MIPI_DCS_GET_DIAGNOSTIC_RESULT, &state1);
if (r) { if (r) {
dev_err(&dssdev->dev, "failed to read Taal status\n"); dev_err(dssdev->dev, "failed to read Taal status\n");
goto err; goto err;
} }
/* Run self diagnostics */ /* Run self diagnostics */
r = taal_sleep_out(td); r = taal_sleep_out(td);
if (r) { if (r) {
dev_err(&dssdev->dev, "failed to run Taal self-diagnostics\n"); dev_err(dssdev->dev, "failed to run Taal self-diagnostics\n");
goto err; goto err;
} }
r = taal_dcs_read_1(td, MIPI_DCS_GET_DIAGNOSTIC_RESULT, &state2); r = taal_dcs_read_1(td, MIPI_DCS_GET_DIAGNOSTIC_RESULT, &state2);
if (r) { if (r) {
dev_err(&dssdev->dev, "failed to read Taal status\n"); dev_err(dssdev->dev, "failed to read Taal status\n");
goto err; goto err;
} }
@ -1477,7 +1477,7 @@ static void taal_esd_work(struct work_struct *work)
* Bit6 if the test passes. * Bit6 if the test passes.
*/ */
if (!((state1 ^ state2) & (1 << 6))) { if (!((state1 ^ state2) & (1 << 6))) {
dev_err(&dssdev->dev, "LCD self diagnostics failed\n"); dev_err(dssdev->dev, "LCD self diagnostics failed\n");
goto err; goto err;
} }
/* Self-diagnostics result is also shown on TE GPIO line. We need /* Self-diagnostics result is also shown on TE GPIO line. We need
@ -1495,7 +1495,7 @@ static void taal_esd_work(struct work_struct *work)
mutex_unlock(&td->lock); mutex_unlock(&td->lock);
return; return;
err: err:
dev_err(&dssdev->dev, "performing LCD reset\n"); dev_err(dssdev->dev, "performing LCD reset\n");
taal_panel_reset(dssdev); taal_panel_reset(dssdev);

Просмотреть файл

@ -59,7 +59,7 @@ struct panel_drv_data {
static int tfp410_power_on(struct omap_dss_device *dssdev) static int tfp410_power_on(struct omap_dss_device *dssdev)
{ {
struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev); struct panel_drv_data *ddata = dev_get_drvdata(dssdev->dev);
int r; int r;
if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
@ -82,7 +82,7 @@ err0:
static void tfp410_power_off(struct omap_dss_device *dssdev) static void tfp410_power_off(struct omap_dss_device *dssdev)
{ {
struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev); struct panel_drv_data *ddata = dev_get_drvdata(dssdev->dev);
if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
return; return;
@ -99,7 +99,7 @@ static int tfp410_probe(struct omap_dss_device *dssdev)
int r; int r;
int i2c_bus_num; int i2c_bus_num;
ddata = devm_kzalloc(&dssdev->dev, sizeof(*ddata), GFP_KERNEL); ddata = devm_kzalloc(dssdev->dev, sizeof(*ddata), GFP_KERNEL);
if (!ddata) if (!ddata)
return -ENOMEM; return -ENOMEM;
@ -119,10 +119,10 @@ static int tfp410_probe(struct omap_dss_device *dssdev)
} }
if (gpio_is_valid(ddata->pd_gpio)) { if (gpio_is_valid(ddata->pd_gpio)) {
r = devm_gpio_request_one(&dssdev->dev, ddata->pd_gpio, r = devm_gpio_request_one(dssdev->dev, ddata->pd_gpio,
GPIOF_OUT_INIT_LOW, "tfp410 pd"); GPIOF_OUT_INIT_LOW, "tfp410 pd");
if (r) { if (r) {
dev_err(&dssdev->dev, "Failed to request PD GPIO %d\n", dev_err(dssdev->dev, "Failed to request PD GPIO %d\n",
ddata->pd_gpio); ddata->pd_gpio);
return r; return r;
} }
@ -133,7 +133,7 @@ static int tfp410_probe(struct omap_dss_device *dssdev)
adapter = i2c_get_adapter(i2c_bus_num); adapter = i2c_get_adapter(i2c_bus_num);
if (!adapter) { if (!adapter) {
dev_err(&dssdev->dev, "Failed to get I2C adapter, bus %d\n", dev_err(dssdev->dev, "Failed to get I2C adapter, bus %d\n",
i2c_bus_num); i2c_bus_num);
return -EPROBE_DEFER; return -EPROBE_DEFER;
} }
@ -141,28 +141,28 @@ static int tfp410_probe(struct omap_dss_device *dssdev)
ddata->i2c_adapter = adapter; ddata->i2c_adapter = adapter;
} }
dev_set_drvdata(&dssdev->dev, ddata); dev_set_drvdata(dssdev->dev, ddata);
return 0; return 0;
} }
static void __exit tfp410_remove(struct omap_dss_device *dssdev) static void __exit tfp410_remove(struct omap_dss_device *dssdev)
{ {
struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev); struct panel_drv_data *ddata = dev_get_drvdata(dssdev->dev);
mutex_lock(&ddata->lock); mutex_lock(&ddata->lock);
if (ddata->i2c_adapter) if (ddata->i2c_adapter)
i2c_put_adapter(ddata->i2c_adapter); i2c_put_adapter(ddata->i2c_adapter);
dev_set_drvdata(&dssdev->dev, NULL); dev_set_drvdata(dssdev->dev, NULL);
mutex_unlock(&ddata->lock); mutex_unlock(&ddata->lock);
} }
static int tfp410_enable(struct omap_dss_device *dssdev) static int tfp410_enable(struct omap_dss_device *dssdev)
{ {
struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev); struct panel_drv_data *ddata = dev_get_drvdata(dssdev->dev);
int r; int r;
mutex_lock(&ddata->lock); mutex_lock(&ddata->lock);
@ -178,7 +178,7 @@ static int tfp410_enable(struct omap_dss_device *dssdev)
static void tfp410_disable(struct omap_dss_device *dssdev) static void tfp410_disable(struct omap_dss_device *dssdev)
{ {
struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev); struct panel_drv_data *ddata = dev_get_drvdata(dssdev->dev);
mutex_lock(&ddata->lock); mutex_lock(&ddata->lock);
@ -192,7 +192,7 @@ static void tfp410_disable(struct omap_dss_device *dssdev)
static void tfp410_set_timings(struct omap_dss_device *dssdev, static void tfp410_set_timings(struct omap_dss_device *dssdev,
struct omap_video_timings *timings) struct omap_video_timings *timings)
{ {
struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev); struct panel_drv_data *ddata = dev_get_drvdata(dssdev->dev);
mutex_lock(&ddata->lock); mutex_lock(&ddata->lock);
omapdss_dpi_set_timings(dssdev, timings); omapdss_dpi_set_timings(dssdev, timings);
@ -203,7 +203,7 @@ static void tfp410_set_timings(struct omap_dss_device *dssdev,
static void tfp410_get_timings(struct omap_dss_device *dssdev, static void tfp410_get_timings(struct omap_dss_device *dssdev,
struct omap_video_timings *timings) struct omap_video_timings *timings)
{ {
struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev); struct panel_drv_data *ddata = dev_get_drvdata(dssdev->dev);
mutex_lock(&ddata->lock); mutex_lock(&ddata->lock);
*timings = dssdev->panel.timings; *timings = dssdev->panel.timings;
@ -213,7 +213,7 @@ static void tfp410_get_timings(struct omap_dss_device *dssdev,
static int tfp410_check_timings(struct omap_dss_device *dssdev, static int tfp410_check_timings(struct omap_dss_device *dssdev,
struct omap_video_timings *timings) struct omap_video_timings *timings)
{ {
struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev); struct panel_drv_data *ddata = dev_get_drvdata(dssdev->dev);
int r; int r;
mutex_lock(&ddata->lock); mutex_lock(&ddata->lock);
@ -258,7 +258,7 @@ static int tfp410_ddc_read(struct i2c_adapter *adapter,
static int tfp410_read_edid(struct omap_dss_device *dssdev, static int tfp410_read_edid(struct omap_dss_device *dssdev,
u8 *edid, int len) u8 *edid, int len)
{ {
struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev); struct panel_drv_data *ddata = dev_get_drvdata(dssdev->dev);
int r, l, bytes_read; int r, l, bytes_read;
mutex_lock(&ddata->lock); mutex_lock(&ddata->lock);
@ -298,7 +298,7 @@ err:
static bool tfp410_detect(struct omap_dss_device *dssdev) static bool tfp410_detect(struct omap_dss_device *dssdev)
{ {
struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev); struct panel_drv_data *ddata = dev_get_drvdata(dssdev->dev);
unsigned char out; unsigned char out;
int r; int r;

Просмотреть файл

@ -126,7 +126,7 @@ static int tpo_td043_write_mirror(struct spi_device *spi, bool h, bool v)
static int tpo_td043_set_hmirror(struct omap_dss_device *dssdev, bool enable) static int tpo_td043_set_hmirror(struct omap_dss_device *dssdev, bool enable)
{ {
struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev); struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dssdev->dev);
tpo_td043->hmirror = enable; tpo_td043->hmirror = enable;
return tpo_td043_write_mirror(tpo_td043->spi, tpo_td043->hmirror, return tpo_td043_write_mirror(tpo_td043->spi, tpo_td043->hmirror,
@ -135,7 +135,7 @@ static int tpo_td043_set_hmirror(struct omap_dss_device *dssdev, bool enable)
static bool tpo_td043_get_hmirror(struct omap_dss_device *dssdev) static bool tpo_td043_get_hmirror(struct omap_dss_device *dssdev)
{ {
struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev); struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dssdev->dev);
return tpo_td043->hmirror; return tpo_td043->hmirror;
} }
@ -338,7 +338,7 @@ static void tpo_td043_power_off(struct tpo_td043_device *tpo_td043)
static int tpo_td043_enable_dss(struct omap_dss_device *dssdev) static int tpo_td043_enable_dss(struct omap_dss_device *dssdev)
{ {
struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev); struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dssdev->dev);
int r; int r;
if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
@ -372,7 +372,7 @@ err0:
static void tpo_td043_disable_dss(struct omap_dss_device *dssdev) static void tpo_td043_disable_dss(struct omap_dss_device *dssdev)
{ {
struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev); struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dssdev->dev);
if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
return; return;
@ -385,14 +385,14 @@ static void tpo_td043_disable_dss(struct omap_dss_device *dssdev)
static int tpo_td043_enable(struct omap_dss_device *dssdev) static int tpo_td043_enable(struct omap_dss_device *dssdev)
{ {
dev_dbg(&dssdev->dev, "enable\n"); dev_dbg(dssdev->dev, "enable\n");
return tpo_td043_enable_dss(dssdev); return tpo_td043_enable_dss(dssdev);
} }
static void tpo_td043_disable(struct omap_dss_device *dssdev) static void tpo_td043_disable(struct omap_dss_device *dssdev)
{ {
dev_dbg(&dssdev->dev, "disable\n"); dev_dbg(dssdev->dev, "disable\n");
tpo_td043_disable_dss(dssdev); tpo_td043_disable_dss(dssdev);
@ -405,10 +405,10 @@ static int tpo_td043_probe(struct omap_dss_device *dssdev)
struct panel_tpo_td043_data *pdata = get_panel_data(dssdev); struct panel_tpo_td043_data *pdata = get_panel_data(dssdev);
int ret = 0; int ret = 0;
dev_dbg(&dssdev->dev, "probe\n"); dev_dbg(dssdev->dev, "probe\n");
if (tpo_td043 == NULL) { if (tpo_td043 == NULL) {
dev_err(&dssdev->dev, "missing tpo_td043_device\n"); dev_err(dssdev->dev, "missing tpo_td043_device\n");
return -ENODEV; return -ENODEV;
} }
@ -423,28 +423,28 @@ static int tpo_td043_probe(struct omap_dss_device *dssdev)
tpo_td043->mode = TPO_R02_MODE_800x480; tpo_td043->mode = TPO_R02_MODE_800x480;
memcpy(tpo_td043->gamma, tpo_td043_def_gamma, sizeof(tpo_td043->gamma)); memcpy(tpo_td043->gamma, tpo_td043_def_gamma, sizeof(tpo_td043->gamma));
tpo_td043->vcc_reg = regulator_get(&dssdev->dev, "vcc"); tpo_td043->vcc_reg = regulator_get(dssdev->dev, "vcc");
if (IS_ERR(tpo_td043->vcc_reg)) { if (IS_ERR(tpo_td043->vcc_reg)) {
dev_err(&dssdev->dev, "failed to get LCD VCC regulator\n"); dev_err(dssdev->dev, "failed to get LCD VCC regulator\n");
ret = PTR_ERR(tpo_td043->vcc_reg); ret = PTR_ERR(tpo_td043->vcc_reg);
goto fail_regulator; goto fail_regulator;
} }
if (gpio_is_valid(tpo_td043->nreset_gpio)) { if (gpio_is_valid(tpo_td043->nreset_gpio)) {
ret = devm_gpio_request_one(&dssdev->dev, ret = devm_gpio_request_one(dssdev->dev,
tpo_td043->nreset_gpio, GPIOF_OUT_INIT_LOW, tpo_td043->nreset_gpio, GPIOF_OUT_INIT_LOW,
"lcd reset"); "lcd reset");
if (ret < 0) { if (ret < 0) {
dev_err(&dssdev->dev, "couldn't request reset GPIO\n"); dev_err(dssdev->dev, "couldn't request reset GPIO\n");
goto fail_gpio_req; goto fail_gpio_req;
} }
} }
ret = sysfs_create_group(&dssdev->dev.kobj, &tpo_td043_attr_group); ret = sysfs_create_group(&dssdev->dev->kobj, &tpo_td043_attr_group);
if (ret) if (ret)
dev_warn(&dssdev->dev, "failed to create sysfs files\n"); dev_warn(dssdev->dev, "failed to create sysfs files\n");
dev_set_drvdata(&dssdev->dev, tpo_td043); dev_set_drvdata(dssdev->dev, tpo_td043);
return 0; return 0;
@ -457,11 +457,11 @@ fail_regulator:
static void tpo_td043_remove(struct omap_dss_device *dssdev) static void tpo_td043_remove(struct omap_dss_device *dssdev)
{ {
struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev); struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dssdev->dev);
dev_dbg(&dssdev->dev, "remove\n"); dev_dbg(dssdev->dev, "remove\n");
sysfs_remove_group(&dssdev->dev.kobj, &tpo_td043_attr_group); sysfs_remove_group(&dssdev->dev->kobj, &tpo_td043_attr_group);
regulator_put(tpo_td043->vcc_reg); regulator_put(tpo_td043->vcc_reg);
} }

Просмотреть файл

@ -1,5 +1,6 @@
menuconfig OMAP2_DSS menuconfig OMAP2_DSS
tristate "OMAP2+ Display Subsystem support" tristate "OMAP2+ Display Subsystem support"
select VIDEOMODE_HELPERS
help help
OMAP2+ Display Subsystem support. OMAP2+ Display Subsystem support.

Просмотреть файл

@ -420,18 +420,16 @@ static void wait_pending_extra_info_updates(void)
DSSWARN("timeout in wait_pending_extra_info_updates\n"); DSSWARN("timeout in wait_pending_extra_info_updates\n");
} }
static inline struct omap_dss_device *dss_ovl_get_device(struct omap_overlay *ovl) static struct omap_dss_device *dss_mgr_get_device(struct omap_overlay_manager *mgr)
{
return ovl->manager ?
(ovl->manager->output ? ovl->manager->output->device : NULL) :
NULL;
}
static inline struct omap_dss_device *dss_mgr_get_device(struct omap_overlay_manager *mgr)
{ {
return mgr->output ? mgr->output->device : NULL; return mgr->output ? mgr->output->device : NULL;
} }
static struct omap_dss_device *dss_ovl_get_device(struct omap_overlay *ovl)
{
return ovl->manager ? dss_mgr_get_device(ovl->manager) : NULL;
}
static int dss_mgr_wait_for_vsync(struct omap_overlay_manager *mgr) static int dss_mgr_wait_for_vsync(struct omap_overlay_manager *mgr)
{ {
unsigned long timeout = msecs_to_jiffies(500); unsigned long timeout = msecs_to_jiffies(500);
@ -792,6 +790,18 @@ static void mgr_clear_shadow_dirty(struct omap_overlay_manager *mgr)
} }
} }
static int dss_mgr_connect_compat(struct omap_overlay_manager *mgr,
struct omap_dss_device *dst)
{
return mgr->set_output(mgr, dst);
}
static void dss_mgr_disconnect_compat(struct omap_overlay_manager *mgr,
struct omap_dss_device *dst)
{
mgr->unset_output(mgr);
}
static void dss_mgr_start_update_compat(struct omap_overlay_manager *mgr) static void dss_mgr_start_update_compat(struct omap_overlay_manager *mgr)
{ {
struct mgr_priv_data *mp = get_mgr_priv(mgr); struct mgr_priv_data *mp = get_mgr_priv(mgr);
@ -1156,7 +1166,7 @@ static void dss_mgr_get_info(struct omap_overlay_manager *mgr,
} }
static int dss_mgr_set_output(struct omap_overlay_manager *mgr, static int dss_mgr_set_output(struct omap_overlay_manager *mgr,
struct omap_dss_output *output) struct omap_dss_device *output)
{ {
int r; int r;
@ -1554,6 +1564,8 @@ static void dss_mgr_unregister_framedone_handler_compat(struct omap_overlay_mana
} }
static const struct dss_mgr_ops apply_mgr_ops = { static const struct dss_mgr_ops apply_mgr_ops = {
.connect = dss_mgr_connect_compat,
.disconnect = dss_mgr_disconnect_compat,
.start_update = dss_mgr_start_update_compat, .start_update = dss_mgr_start_update_compat,
.enable = dss_mgr_enable_compat, .enable = dss_mgr_enable_compat,
.disable = dss_mgr_disable_compat, .disable = dss_mgr_disable_compat,
@ -1569,7 +1581,6 @@ static DEFINE_MUTEX(compat_init_lock);
int omapdss_compat_init(void) int omapdss_compat_init(void)
{ {
struct platform_device *pdev = dss_get_core_pdev(); struct platform_device *pdev = dss_get_core_pdev();
struct omap_dss_device *dssdev = NULL;
int i, r; int i, r;
mutex_lock(&compat_init_lock); mutex_lock(&compat_init_lock);
@ -1579,7 +1590,7 @@ int omapdss_compat_init(void)
apply_init_priv(); apply_init_priv();
dss_init_overlay_managers(pdev); dss_init_overlay_managers_sysfs(pdev);
dss_init_overlays(pdev); dss_init_overlays(pdev);
for (i = 0; i < omap_dss_get_num_overlay_managers(); i++) { for (i = 0; i < omap_dss_get_num_overlay_managers(); i++) {
@ -1615,12 +1626,9 @@ int omapdss_compat_init(void)
if (r) if (r)
goto err_mgr_ops; goto err_mgr_ops;
for_each_dss_dev(dssdev) { r = display_init_sysfs(pdev);
r = display_init_sysfs(pdev, dssdev); if (r)
/* XXX uninit sysfs files on error */ goto err_disp_sysfs;
if (r)
goto err_disp_sysfs;
}
dispc_runtime_get(); dispc_runtime_get();
@ -1637,12 +1645,13 @@ out:
err_init_irq: err_init_irq:
dispc_runtime_put(); dispc_runtime_put();
display_uninit_sysfs(pdev);
err_disp_sysfs: err_disp_sysfs:
dss_uninstall_mgr_ops(); dss_uninstall_mgr_ops();
err_mgr_ops: err_mgr_ops:
dss_uninit_overlay_managers(pdev); dss_uninit_overlay_managers_sysfs(pdev);
dss_uninit_overlays(pdev); dss_uninit_overlays(pdev);
compat_refcnt--; compat_refcnt--;
@ -1656,7 +1665,6 @@ EXPORT_SYMBOL(omapdss_compat_init);
void omapdss_compat_uninit(void) void omapdss_compat_uninit(void)
{ {
struct platform_device *pdev = dss_get_core_pdev(); struct platform_device *pdev = dss_get_core_pdev();
struct omap_dss_device *dssdev = NULL;
mutex_lock(&compat_init_lock); mutex_lock(&compat_init_lock);
@ -1665,12 +1673,11 @@ void omapdss_compat_uninit(void)
dss_dispc_uninitialize_irq(); dss_dispc_uninitialize_irq();
for_each_dss_dev(dssdev) display_uninit_sysfs(pdev);
display_uninit_sysfs(pdev, dssdev);
dss_uninstall_mgr_ops(); dss_uninstall_mgr_ops();
dss_uninit_overlay_managers(pdev); dss_uninit_overlay_managers_sysfs(pdev);
dss_uninit_overlays(pdev); dss_uninit_overlays(pdev);
out: out:
mutex_unlock(&compat_init_lock); mutex_unlock(&compat_init_lock);

Просмотреть файл

@ -88,7 +88,7 @@ struct regulator *dss_get_vdds_dsi(void)
if (core.vdds_dsi_reg != NULL) if (core.vdds_dsi_reg != NULL)
return core.vdds_dsi_reg; return core.vdds_dsi_reg;
reg = regulator_get(&core.pdev->dev, "vdds_dsi"); reg = devm_regulator_get(&core.pdev->dev, "vdds_dsi");
if (!IS_ERR(reg)) if (!IS_ERR(reg))
core.vdds_dsi_reg = reg; core.vdds_dsi_reg = reg;
@ -102,7 +102,7 @@ struct regulator *dss_get_vdds_sdi(void)
if (core.vdds_sdi_reg != NULL) if (core.vdds_sdi_reg != NULL)
return core.vdds_sdi_reg; return core.vdds_sdi_reg;
reg = regulator_get(&core.pdev->dev, "vdds_sdi"); reg = devm_regulator_get(&core.pdev->dev, "vdds_sdi");
if (!IS_ERR(reg)) if (!IS_ERR(reg))
core.vdds_sdi_reg = reg; core.vdds_sdi_reg = reg;
@ -243,6 +243,8 @@ static int __init omap_dss_probe(struct platform_device *pdev)
if (def_disp_name) if (def_disp_name)
core.default_display_name = def_disp_name; core.default_display_name = def_disp_name;
else if (pdata->default_display_name)
core.default_display_name = pdata->default_display_name;
else if (pdata->default_device) else if (pdata->default_device)
core.default_display_name = pdata->default_device->name; core.default_display_name = pdata->default_device->name;
@ -290,37 +292,9 @@ static int dss_bus_match(struct device *dev, struct device_driver *driver)
return strcmp(dssdev->driver_name, driver->name) == 0; return strcmp(dssdev->driver_name, driver->name) == 0;
} }
static ssize_t device_name_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct omap_dss_device *dssdev = to_dss_device(dev);
return snprintf(buf, PAGE_SIZE, "%s\n",
dssdev->name ?
dssdev->name : "");
}
static struct device_attribute default_dev_attrs[] = {
__ATTR(name, S_IRUGO, device_name_show, NULL),
__ATTR_NULL,
};
static ssize_t driver_name_show(struct device_driver *drv, char *buf)
{
struct omap_dss_driver *dssdrv = to_dss_driver(drv);
return snprintf(buf, PAGE_SIZE, "%s\n",
dssdrv->driver.name ?
dssdrv->driver.name : "");
}
static struct driver_attribute default_drv_attrs[] = {
__ATTR(name, S_IRUGO, driver_name_show, NULL),
__ATTR_NULL,
};
static struct bus_type dss_bus_type = { static struct bus_type dss_bus_type = {
.name = "omapdss", .name = "omapdss",
.match = dss_bus_match, .match = dss_bus_match,
.dev_attrs = default_dev_attrs,
.drv_attrs = default_drv_attrs,
}; };
static void dss_bus_release(struct device *dev) static void dss_bus_release(struct device *dev)
@ -377,6 +351,46 @@ static int dss_driver_remove(struct device *dev)
return 0; return 0;
} }
static int omapdss_default_connect(struct omap_dss_device *dssdev)
{
struct omap_dss_device *out;
struct omap_overlay_manager *mgr;
int r;
out = dssdev->output;
if (out == NULL)
return -ENODEV;
mgr = omap_dss_get_overlay_manager(out->dispc_channel);
if (!mgr)
return -ENODEV;
r = dss_mgr_connect(mgr, out);
if (r)
return r;
return 0;
}
static void omapdss_default_disconnect(struct omap_dss_device *dssdev)
{
struct omap_dss_device *out;
struct omap_overlay_manager *mgr;
out = dssdev->output;
if (out == NULL)
return;
mgr = out->manager;
if (mgr == NULL)
return;
dss_mgr_disconnect(mgr, out);
}
int omap_dss_register_driver(struct omap_dss_driver *dssdriver) int omap_dss_register_driver(struct omap_dss_driver *dssdriver)
{ {
dssdriver->driver.bus = &dss_bus_type; dssdriver->driver.bus = &dss_bus_type;
@ -390,6 +404,10 @@ int omap_dss_register_driver(struct omap_dss_driver *dssdriver)
omapdss_default_get_recommended_bpp; omapdss_default_get_recommended_bpp;
if (dssdriver->get_timings == NULL) if (dssdriver->get_timings == NULL)
dssdriver->get_timings = omapdss_default_get_timings; dssdriver->get_timings = omapdss_default_get_timings;
if (dssdriver->connect == NULL)
dssdriver->connect = omapdss_default_connect;
if (dssdriver->disconnect == NULL)
dssdriver->disconnect = omapdss_default_disconnect;
return driver_register(&dssdriver->driver); return driver_register(&dssdriver->driver);
} }
@ -419,29 +437,33 @@ struct omap_dss_device *dss_alloc_and_init_device(struct device *parent)
if (!dssdev) if (!dssdev)
return NULL; return NULL;
dssdev->dev.bus = &dss_bus_type; dssdev->old_dev.bus = &dss_bus_type;
dssdev->dev.parent = parent; dssdev->old_dev.parent = parent;
dssdev->dev.release = omap_dss_dev_release; dssdev->old_dev.release = omap_dss_dev_release;
dev_set_name(&dssdev->dev, "display%d", disp_num_counter++); dev_set_name(&dssdev->old_dev, "display%d", disp_num_counter++);
device_initialize(&dssdev->dev); device_initialize(&dssdev->old_dev);
return dssdev; return dssdev;
} }
int dss_add_device(struct omap_dss_device *dssdev) int dss_add_device(struct omap_dss_device *dssdev)
{ {
return device_add(&dssdev->dev); dssdev->dev = &dssdev->old_dev;
omapdss_register_display(dssdev);
return device_add(&dssdev->old_dev);
} }
void dss_put_device(struct omap_dss_device *dssdev) void dss_put_device(struct omap_dss_device *dssdev)
{ {
put_device(&dssdev->dev); put_device(&dssdev->old_dev);
} }
void dss_unregister_device(struct omap_dss_device *dssdev) void dss_unregister_device(struct omap_dss_device *dssdev)
{ {
device_unregister(&dssdev->dev); device_unregister(&dssdev->old_dev);
omapdss_unregister_display(dssdev);
} }
static int dss_unregister_dss_dev(struct device *dev, void *data) static int dss_unregister_dss_dev(struct device *dev, void *data)
@ -618,16 +640,6 @@ static int __init omap_dss_init(void)
static void __exit omap_dss_exit(void) static void __exit omap_dss_exit(void)
{ {
if (core.vdds_dsi_reg != NULL) {
regulator_put(core.vdds_dsi_reg);
core.vdds_dsi_reg = NULL;
}
if (core.vdds_sdi_reg != NULL) {
regulator_put(core.vdds_sdi_reg);
core.vdds_sdi_reg = NULL;
}
omap_dss_unregister_drivers(); omap_dss_unregister_drivers();
omap_dss_bus_unregister(); omap_dss_bus_unregister();

Просмотреть файл

@ -360,8 +360,7 @@ static void dispc_error_worker(struct work_struct *work)
if (bit & errors) { if (bit & errors) {
DSSERR("FIFO UNDERFLOW on %s, disabling the overlay\n", DSSERR("FIFO UNDERFLOW on %s, disabling the overlay\n",
ovl->name); ovl->name);
dispc_ovl_enable(ovl->id, false); ovl->disable(ovl);
dispc_mgr_go(ovl->manager->id);
msleep(50); msleep(50);
} }
} }

Просмотреть файл

@ -103,6 +103,7 @@ static struct {
int irq; int irq;
unsigned long core_clk_rate; unsigned long core_clk_rate;
unsigned long tv_pclk_rate;
u32 fifo_size[DISPC_MAX_NR_FIFOS]; u32 fifo_size[DISPC_MAX_NR_FIFOS];
/* maps which plane is using a fifo. fifo-id -> plane-id */ /* maps which plane is using a fifo. fifo-id -> plane-id */
@ -3071,22 +3072,15 @@ unsigned long dispc_mgr_pclk_rate(enum omap_channel channel)
return r / pcd; return r / pcd;
} else { } else {
enum dss_hdmi_venc_clk_source_select source; return dispc.tv_pclk_rate;
source = dss_get_hdmi_venc_clk_source();
switch (source) {
case DSS_VENC_TV_CLK:
return venc_get_pixel_clock();
case DSS_HDMI_M_PCLK:
return hdmi_get_pixel_clock();
default:
BUG();
return 0;
}
} }
} }
void dispc_set_tv_pclk(unsigned long pclk)
{
dispc.tv_pclk_rate = pclk;
}
unsigned long dispc_core_clk_rate(void) unsigned long dispc_core_clk_rate(void)
{ {
return dispc.core_clk_rate; return dispc.core_clk_rate;
@ -3710,6 +3704,8 @@ static int __init omap_dispchw_probe(struct platform_device *pdev)
dispc_runtime_put(); dispc_runtime_put();
dss_init_overlay_managers();
dss_debugfs_create_file("dispc", dispc_dump_regs); dss_debugfs_create_file("dispc", dispc_dump_regs);
return 0; return 0;
@ -3723,6 +3719,8 @@ static int __exit omap_dispchw_remove(struct platform_device *pdev)
{ {
pm_runtime_disable(&pdev->dev); pm_runtime_disable(&pdev->dev);
dss_uninit_overlay_managers();
return 0; return 0;
} }

Просмотреть файл

@ -22,42 +22,69 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/jiffies.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/sysfs.h>
#include <video/omapdss.h> #include <video/omapdss.h>
#include "dss.h" #include "dss.h"
#include "dss_features.h"
static struct omap_dss_device *to_dss_device_sysfs(struct device *dev)
{
struct omap_dss_device *dssdev = NULL;
for_each_dss_dev(dssdev) {
if (dssdev->dev == dev) {
omap_dss_put_device(dssdev);
return dssdev;
}
}
return NULL;
}
static ssize_t display_name_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct omap_dss_device *dssdev = to_dss_device_sysfs(dev);
return snprintf(buf, PAGE_SIZE, "%s\n",
dssdev->name ?
dssdev->name : "");
}
static ssize_t display_enabled_show(struct device *dev, static ssize_t display_enabled_show(struct device *dev,
struct device_attribute *attr, char *buf) struct device_attribute *attr, char *buf)
{ {
struct omap_dss_device *dssdev = to_dss_device(dev); struct omap_dss_device *dssdev = to_dss_device_sysfs(dev);
bool enabled = dssdev->state != OMAP_DSS_DISPLAY_DISABLED;
return snprintf(buf, PAGE_SIZE, "%d\n", enabled); return snprintf(buf, PAGE_SIZE, "%d\n",
omapdss_device_is_enabled(dssdev));
} }
static ssize_t display_enabled_store(struct device *dev, static ssize_t display_enabled_store(struct device *dev,
struct device_attribute *attr, struct device_attribute *attr,
const char *buf, size_t size) const char *buf, size_t size)
{ {
struct omap_dss_device *dssdev = to_dss_device(dev); struct omap_dss_device *dssdev = to_dss_device_sysfs(dev);
int r; int r;
bool enabled; bool enable;
r = strtobool(buf, &enabled); r = strtobool(buf, &enable);
if (r) if (r)
return r; return r;
if (enabled != (dssdev->state != OMAP_DSS_DISPLAY_DISABLED)) { if (enable == omapdss_device_is_enabled(dssdev))
if (enabled) { return size;
r = dssdev->driver->enable(dssdev);
if (r) if (omapdss_device_is_connected(dssdev) == false)
return r; return -ENODEV;
} else {
dssdev->driver->disable(dssdev); if (enable) {
} r = dssdev->driver->enable(dssdev);
if (r)
return r;
} else {
dssdev->driver->disable(dssdev);
} }
return size; return size;
@ -66,7 +93,7 @@ static ssize_t display_enabled_store(struct device *dev,
static ssize_t display_tear_show(struct device *dev, static ssize_t display_tear_show(struct device *dev,
struct device_attribute *attr, char *buf) struct device_attribute *attr, char *buf)
{ {
struct omap_dss_device *dssdev = to_dss_device(dev); struct omap_dss_device *dssdev = to_dss_device_sysfs(dev);
return snprintf(buf, PAGE_SIZE, "%d\n", return snprintf(buf, PAGE_SIZE, "%d\n",
dssdev->driver->get_te ? dssdev->driver->get_te ?
dssdev->driver->get_te(dssdev) : 0); dssdev->driver->get_te(dssdev) : 0);
@ -75,7 +102,7 @@ static ssize_t display_tear_show(struct device *dev,
static ssize_t display_tear_store(struct device *dev, static ssize_t display_tear_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t size) struct device_attribute *attr, const char *buf, size_t size)
{ {
struct omap_dss_device *dssdev = to_dss_device(dev); struct omap_dss_device *dssdev = to_dss_device_sysfs(dev);
int r; int r;
bool te; bool te;
@ -96,7 +123,7 @@ static ssize_t display_tear_store(struct device *dev,
static ssize_t display_timings_show(struct device *dev, static ssize_t display_timings_show(struct device *dev,
struct device_attribute *attr, char *buf) struct device_attribute *attr, char *buf)
{ {
struct omap_dss_device *dssdev = to_dss_device(dev); struct omap_dss_device *dssdev = to_dss_device_sysfs(dev);
struct omap_video_timings t; struct omap_video_timings t;
if (!dssdev->driver->get_timings) if (!dssdev->driver->get_timings)
@ -113,7 +140,7 @@ static ssize_t display_timings_show(struct device *dev,
static ssize_t display_timings_store(struct device *dev, static ssize_t display_timings_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t size) struct device_attribute *attr, const char *buf, size_t size)
{ {
struct omap_dss_device *dssdev = to_dss_device(dev); struct omap_dss_device *dssdev = to_dss_device_sysfs(dev);
struct omap_video_timings t = dssdev->panel.timings; struct omap_video_timings t = dssdev->panel.timings;
int r, found; int r, found;
@ -152,7 +179,7 @@ static ssize_t display_timings_store(struct device *dev,
static ssize_t display_rotate_show(struct device *dev, static ssize_t display_rotate_show(struct device *dev,
struct device_attribute *attr, char *buf) struct device_attribute *attr, char *buf)
{ {
struct omap_dss_device *dssdev = to_dss_device(dev); struct omap_dss_device *dssdev = to_dss_device_sysfs(dev);
int rotate; int rotate;
if (!dssdev->driver->get_rotate) if (!dssdev->driver->get_rotate)
return -ENOENT; return -ENOENT;
@ -163,7 +190,7 @@ static ssize_t display_rotate_show(struct device *dev,
static ssize_t display_rotate_store(struct device *dev, static ssize_t display_rotate_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t size) struct device_attribute *attr, const char *buf, size_t size)
{ {
struct omap_dss_device *dssdev = to_dss_device(dev); struct omap_dss_device *dssdev = to_dss_device_sysfs(dev);
int rot, r; int rot, r;
if (!dssdev->driver->set_rotate || !dssdev->driver->get_rotate) if (!dssdev->driver->set_rotate || !dssdev->driver->get_rotate)
@ -183,7 +210,7 @@ static ssize_t display_rotate_store(struct device *dev,
static ssize_t display_mirror_show(struct device *dev, static ssize_t display_mirror_show(struct device *dev,
struct device_attribute *attr, char *buf) struct device_attribute *attr, char *buf)
{ {
struct omap_dss_device *dssdev = to_dss_device(dev); struct omap_dss_device *dssdev = to_dss_device_sysfs(dev);
int mirror; int mirror;
if (!dssdev->driver->get_mirror) if (!dssdev->driver->get_mirror)
return -ENOENT; return -ENOENT;
@ -194,7 +221,7 @@ static ssize_t display_mirror_show(struct device *dev,
static ssize_t display_mirror_store(struct device *dev, static ssize_t display_mirror_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t size) struct device_attribute *attr, const char *buf, size_t size)
{ {
struct omap_dss_device *dssdev = to_dss_device(dev); struct omap_dss_device *dssdev = to_dss_device_sysfs(dev);
int r; int r;
bool mirror; bool mirror;
@ -215,7 +242,7 @@ static ssize_t display_mirror_store(struct device *dev,
static ssize_t display_wss_show(struct device *dev, static ssize_t display_wss_show(struct device *dev,
struct device_attribute *attr, char *buf) struct device_attribute *attr, char *buf)
{ {
struct omap_dss_device *dssdev = to_dss_device(dev); struct omap_dss_device *dssdev = to_dss_device_sysfs(dev);
unsigned int wss; unsigned int wss;
if (!dssdev->driver->get_wss) if (!dssdev->driver->get_wss)
@ -229,7 +256,7 @@ static ssize_t display_wss_show(struct device *dev,
static ssize_t display_wss_store(struct device *dev, static ssize_t display_wss_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t size) struct device_attribute *attr, const char *buf, size_t size)
{ {
struct omap_dss_device *dssdev = to_dss_device(dev); struct omap_dss_device *dssdev = to_dss_device_sysfs(dev);
u32 wss; u32 wss;
int r; int r;
@ -250,6 +277,7 @@ static ssize_t display_wss_store(struct device *dev,
return size; return size;
} }
static DEVICE_ATTR(name, S_IRUGO, display_name_show, NULL);
static DEVICE_ATTR(enabled, S_IRUGO|S_IWUSR, static DEVICE_ATTR(enabled, S_IRUGO|S_IWUSR,
display_enabled_show, display_enabled_store); display_enabled_show, display_enabled_store);
static DEVICE_ATTR(tear_elim, S_IRUGO|S_IWUSR, static DEVICE_ATTR(tear_elim, S_IRUGO|S_IWUSR,
@ -263,59 +291,55 @@ static DEVICE_ATTR(mirror, S_IRUGO|S_IWUSR,
static DEVICE_ATTR(wss, S_IRUGO|S_IWUSR, static DEVICE_ATTR(wss, S_IRUGO|S_IWUSR,
display_wss_show, display_wss_store); display_wss_show, display_wss_store);
static struct device_attribute *display_sysfs_attrs[] = { static const struct attribute *display_sysfs_attrs[] = {
&dev_attr_enabled, &dev_attr_name.attr,
&dev_attr_tear_elim, &dev_attr_enabled.attr,
&dev_attr_timings, &dev_attr_tear_elim.attr,
&dev_attr_rotate, &dev_attr_timings.attr,
&dev_attr_mirror, &dev_attr_rotate.attr,
&dev_attr_wss, &dev_attr_mirror.attr,
&dev_attr_wss.attr,
NULL NULL
}; };
int display_init_sysfs(struct platform_device *pdev, int display_init_sysfs(struct platform_device *pdev)
struct omap_dss_device *dssdev)
{ {
struct device_attribute *attr; struct omap_dss_device *dssdev = NULL;
int i, r; int r;
/* create device sysfs files */ for_each_dss_dev(dssdev) {
i = 0; struct kobject *kobj = &dssdev->dev->kobj;
while ((attr = display_sysfs_attrs[i++]) != NULL) {
r = device_create_file(&dssdev->dev, attr); r = sysfs_create_files(kobj, display_sysfs_attrs);
if (r) { if (r) {
for (i = i - 2; i >= 0; i--) { DSSERR("failed to create sysfs files\n");
attr = display_sysfs_attrs[i]; goto err;
device_remove_file(&dssdev->dev, attr); }
}
DSSERR("failed to create sysfs file\n"); r = sysfs_create_link(&pdev->dev.kobj, kobj, dssdev->alias);
return r; if (r) {
sysfs_remove_files(kobj, display_sysfs_attrs);
DSSERR("failed to create sysfs display link\n");
goto err;
} }
} }
/* create display? sysfs links */
r = sysfs_create_link(&pdev->dev.kobj, &dssdev->dev.kobj,
dev_name(&dssdev->dev));
if (r) {
while ((attr = display_sysfs_attrs[i++]) != NULL)
device_remove_file(&dssdev->dev, attr);
DSSERR("failed to create sysfs display link\n");
return r;
}
return 0; return 0;
err:
display_uninit_sysfs(pdev);
return r;
} }
void display_uninit_sysfs(struct platform_device *pdev, void display_uninit_sysfs(struct platform_device *pdev)
struct omap_dss_device *dssdev)
{ {
struct device_attribute *attr; struct omap_dss_device *dssdev = NULL;
int i = 0;
sysfs_remove_link(&pdev->dev.kobj, dev_name(&dssdev->dev)); for_each_dss_dev(dssdev) {
sysfs_remove_link(&pdev->dev.kobj, dssdev->alias);
while ((attr = display_sysfs_attrs[i++]) != NULL) sysfs_remove_files(&dssdev->dev->kobj,
device_remove_file(&dssdev->dev, attr); display_sysfs_attrs);
}
} }

Просмотреть файл

@ -76,110 +76,154 @@ void omapdss_default_get_timings(struct omap_dss_device *dssdev,
} }
EXPORT_SYMBOL(omapdss_default_get_timings); EXPORT_SYMBOL(omapdss_default_get_timings);
static int dss_suspend_device(struct device *dev, void *data)
{
struct omap_dss_device *dssdev = to_dss_device(dev);
if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) {
dssdev->activate_after_resume = false;
return 0;
}
dssdev->driver->disable(dssdev);
dssdev->activate_after_resume = true;
return 0;
}
int dss_suspend_all_devices(void) int dss_suspend_all_devices(void)
{ {
int r; struct omap_dss_device *dssdev = NULL;
struct bus_type *bus = dss_get_bus();
r = bus_for_each_dev(bus, NULL, NULL, dss_suspend_device); for_each_dss_dev(dssdev) {
if (r) { if (!dssdev->driver)
/* resume all displays that were suspended */ continue;
dss_resume_all_devices();
return r; if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
dssdev->driver->disable(dssdev);
dssdev->activate_after_resume = true;
} else {
dssdev->activate_after_resume = false;
}
} }
return 0; return 0;
} }
static int dss_resume_device(struct device *dev, void *data)
{
int r;
struct omap_dss_device *dssdev = to_dss_device(dev);
if (dssdev->activate_after_resume) {
r = dssdev->driver->enable(dssdev);
if (r)
return r;
}
dssdev->activate_after_resume = false;
return 0;
}
int dss_resume_all_devices(void) int dss_resume_all_devices(void)
{ {
struct bus_type *bus = dss_get_bus(); struct omap_dss_device *dssdev = NULL;
return bus_for_each_dev(bus, NULL, NULL, dss_resume_device); for_each_dss_dev(dssdev) {
} if (!dssdev->driver)
continue;
static int dss_disable_device(struct device *dev, void *data) if (dssdev->activate_after_resume) {
{ dssdev->driver->enable(dssdev);
struct omap_dss_device *dssdev = to_dss_device(dev); dssdev->activate_after_resume = false;
}
if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) }
dssdev->driver->disable(dssdev);
return 0; return 0;
} }
void dss_disable_all_devices(void) void dss_disable_all_devices(void)
{ {
struct bus_type *bus = dss_get_bus(); struct omap_dss_device *dssdev = NULL;
bus_for_each_dev(bus, NULL, NULL, dss_disable_device);
for_each_dss_dev(dssdev) {
if (!dssdev->driver)
continue;
if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
dssdev->driver->disable(dssdev);
}
} }
static LIST_HEAD(panel_list);
static DEFINE_MUTEX(panel_list_mutex);
static int disp_num_counter;
void omap_dss_get_device(struct omap_dss_device *dssdev) int omapdss_register_display(struct omap_dss_device *dssdev)
{ {
get_device(&dssdev->dev); struct omap_dss_driver *drv = dssdev->driver;
snprintf(dssdev->alias, sizeof(dssdev->alias),
"display%d", disp_num_counter++);
if (drv && drv->get_resolution == NULL)
drv->get_resolution = omapdss_default_get_resolution;
if (drv && drv->get_recommended_bpp == NULL)
drv->get_recommended_bpp = omapdss_default_get_recommended_bpp;
if (drv && drv->get_timings == NULL)
drv->get_timings = omapdss_default_get_timings;
mutex_lock(&panel_list_mutex);
list_add_tail(&dssdev->panel_list, &panel_list);
mutex_unlock(&panel_list_mutex);
return 0;
}
EXPORT_SYMBOL(omapdss_register_display);
void omapdss_unregister_display(struct omap_dss_device *dssdev)
{
mutex_lock(&panel_list_mutex);
list_del(&dssdev->panel_list);
mutex_unlock(&panel_list_mutex);
}
EXPORT_SYMBOL(omapdss_unregister_display);
struct omap_dss_device *omap_dss_get_device(struct omap_dss_device *dssdev)
{
if (!try_module_get(dssdev->owner))
return NULL;
if (get_device(dssdev->dev) == NULL) {
module_put(dssdev->owner);
return NULL;
}
return dssdev;
} }
EXPORT_SYMBOL(omap_dss_get_device); EXPORT_SYMBOL(omap_dss_get_device);
void omap_dss_put_device(struct omap_dss_device *dssdev) void omap_dss_put_device(struct omap_dss_device *dssdev)
{ {
put_device(&dssdev->dev); put_device(dssdev->dev);
module_put(dssdev->owner);
} }
EXPORT_SYMBOL(omap_dss_put_device); EXPORT_SYMBOL(omap_dss_put_device);
/* ref count of the found device is incremented. ref count /*
* of from-device is decremented. */ * ref count of the found device is incremented.
* ref count of from-device is decremented.
*/
struct omap_dss_device *omap_dss_get_next_device(struct omap_dss_device *from) struct omap_dss_device *omap_dss_get_next_device(struct omap_dss_device *from)
{ {
struct device *dev; struct list_head *l;
struct device *dev_start = NULL; struct omap_dss_device *dssdev;
struct omap_dss_device *dssdev = NULL;
int match(struct device *dev, void *data) mutex_lock(&panel_list_mutex);
{
return 1; if (list_empty(&panel_list)) {
dssdev = NULL;
goto out;
} }
if (from) if (from == NULL) {
dev_start = &from->dev; dssdev = list_first_entry(&panel_list, struct omap_dss_device,
dev = bus_find_device(dss_get_bus(), dev_start, NULL, match); panel_list);
if (dev) omap_dss_get_device(dssdev);
dssdev = to_dss_device(dev); goto out;
if (from) }
put_device(&from->dev);
omap_dss_put_device(from);
list_for_each(l, &panel_list) {
dssdev = list_entry(l, struct omap_dss_device, panel_list);
if (dssdev == from) {
if (list_is_last(l, &panel_list)) {
dssdev = NULL;
goto out;
}
dssdev = list_entry(l->next, struct omap_dss_device,
panel_list);
omap_dss_get_device(dssdev);
goto out;
}
}
WARN(1, "'from' dssdev not found\n");
dssdev = NULL;
out:
mutex_unlock(&panel_list_mutex);
return dssdev; return dssdev;
} }
EXPORT_SYMBOL(omap_dss_get_next_device); EXPORT_SYMBOL(omap_dss_get_next_device);
@ -198,24 +242,72 @@ struct omap_dss_device *omap_dss_find_device(void *data,
} }
EXPORT_SYMBOL(omap_dss_find_device); EXPORT_SYMBOL(omap_dss_find_device);
int omap_dss_start_device(struct omap_dss_device *dssdev) void videomode_to_omap_video_timings(const struct videomode *vm,
struct omap_video_timings *ovt)
{ {
if (!dssdev->driver) { memset(ovt, 0, sizeof(*ovt));
DSSDBG("no driver\n");
return -ENODEV;
}
if (!try_module_get(dssdev->dev.driver->owner)) { ovt->pixel_clock = vm->pixelclock / 1000;
return -ENODEV; ovt->x_res = vm->hactive;
} ovt->hbp = vm->hback_porch;
ovt->hfp = vm->hfront_porch;
ovt->hsw = vm->hsync_len;
ovt->y_res = vm->vactive;
ovt->vbp = vm->vback_porch;
ovt->vfp = vm->vfront_porch;
ovt->vsw = vm->vsync_len;
return 0; ovt->vsync_level = vm->flags & DISPLAY_FLAGS_VSYNC_HIGH ?
OMAPDSS_SIG_ACTIVE_HIGH :
OMAPDSS_SIG_ACTIVE_LOW;
ovt->hsync_level = vm->flags & DISPLAY_FLAGS_HSYNC_HIGH ?
OMAPDSS_SIG_ACTIVE_HIGH :
OMAPDSS_SIG_ACTIVE_LOW;
ovt->de_level = vm->flags & DISPLAY_FLAGS_DE_HIGH ?
OMAPDSS_SIG_ACTIVE_HIGH :
OMAPDSS_SIG_ACTIVE_HIGH;
ovt->data_pclk_edge = vm->flags & DISPLAY_FLAGS_PIXDATA_POSEDGE ?
OMAPDSS_DRIVE_SIG_RISING_EDGE :
OMAPDSS_DRIVE_SIG_FALLING_EDGE;
ovt->sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES;
} }
EXPORT_SYMBOL(omap_dss_start_device); EXPORT_SYMBOL(videomode_to_omap_video_timings);
void omap_dss_stop_device(struct omap_dss_device *dssdev) void omap_video_timings_to_videomode(const struct omap_video_timings *ovt,
struct videomode *vm)
{ {
module_put(dssdev->dev.driver->owner); memset(vm, 0, sizeof(*vm));
}
EXPORT_SYMBOL(omap_dss_stop_device);
vm->pixelclock = ovt->pixel_clock * 1000;
vm->hactive = ovt->x_res;
vm->hback_porch = ovt->hbp;
vm->hfront_porch = ovt->hfp;
vm->hsync_len = ovt->hsw;
vm->vactive = ovt->y_res;
vm->vback_porch = ovt->vbp;
vm->vfront_porch = ovt->vfp;
vm->vsync_len = ovt->vsw;
if (ovt->hsync_level == OMAPDSS_SIG_ACTIVE_HIGH)
vm->flags |= DISPLAY_FLAGS_HSYNC_HIGH;
else
vm->flags |= DISPLAY_FLAGS_HSYNC_LOW;
if (ovt->vsync_level == OMAPDSS_SIG_ACTIVE_HIGH)
vm->flags |= DISPLAY_FLAGS_VSYNC_HIGH;
else
vm->flags |= DISPLAY_FLAGS_VSYNC_LOW;
if (ovt->de_level == OMAPDSS_SIG_ACTIVE_HIGH)
vm->flags |= DISPLAY_FLAGS_DE_HIGH;
else
vm->flags |= DISPLAY_FLAGS_DE_LOW;
if (ovt->data_pclk_edge == OMAPDSS_DRIVE_SIG_RISING_EDGE)
vm->flags |= DISPLAY_FLAGS_PIXDATA_POSEDGE;
else
vm->flags |= DISPLAY_FLAGS_PIXDATA_NEGEDGE;
}
EXPORT_SYMBOL(omap_video_timings_to_videomode);

Просмотреть файл

@ -37,6 +37,8 @@
#include "dss_features.h" #include "dss_features.h"
static struct { static struct {
struct platform_device *pdev;
struct regulator *vdds_dsi_reg; struct regulator *vdds_dsi_reg;
struct platform_device *dsidev; struct platform_device *dsidev;
@ -46,7 +48,7 @@ static struct {
struct dss_lcd_mgr_config mgr_config; struct dss_lcd_mgr_config mgr_config;
int data_lines; int data_lines;
struct omap_dss_output output; struct omap_dss_device output;
} dpi; } dpi;
static struct platform_device *dpi_get_dsidev(enum omap_channel channel) static struct platform_device *dpi_get_dsidev(enum omap_channel channel)
@ -345,7 +347,7 @@ static void dpi_config_lcd_manager(struct omap_overlay_manager *mgr)
int omapdss_dpi_display_enable(struct omap_dss_device *dssdev) int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
{ {
struct omap_dss_output *out = &dpi.output; struct omap_dss_device *out = &dpi.output;
int r; int r;
mutex_lock(&dpi.lock); mutex_lock(&dpi.lock);
@ -362,12 +364,6 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
goto err_no_out_mgr; goto err_no_out_mgr;
} }
r = omap_dss_start_device(dssdev);
if (r) {
DSSERR("failed to start device\n");
goto err_start_dev;
}
if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI)) { if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI)) {
r = regulator_enable(dpi.vdds_dsi_reg); r = regulator_enable(dpi.vdds_dsi_reg);
if (r) if (r)
@ -422,8 +418,6 @@ err_get_dispc:
if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI)) if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI))
regulator_disable(dpi.vdds_dsi_reg); regulator_disable(dpi.vdds_dsi_reg);
err_reg_enable: err_reg_enable:
omap_dss_stop_device(dssdev);
err_start_dev:
err_no_out_mgr: err_no_out_mgr:
err_no_reg: err_no_reg:
mutex_unlock(&dpi.lock); mutex_unlock(&dpi.lock);
@ -450,8 +444,6 @@ void omapdss_dpi_display_disable(struct omap_dss_device *dssdev)
if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI)) if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI))
regulator_disable(dpi.vdds_dsi_reg); regulator_disable(dpi.vdds_dsi_reg);
omap_dss_stop_device(dssdev);
mutex_unlock(&dpi.lock); mutex_unlock(&dpi.lock);
} }
EXPORT_SYMBOL(omapdss_dpi_display_disable); EXPORT_SYMBOL(omapdss_dpi_display_disable);
@ -542,6 +534,50 @@ static int dpi_verify_dsi_pll(struct platform_device *dsidev)
return 0; return 0;
} }
static int dpi_init_regulator(void)
{
struct regulator *vdds_dsi;
if (!dss_has_feature(FEAT_DPI_USES_VDDS_DSI))
return 0;
if (dpi.vdds_dsi_reg)
return 0;
vdds_dsi = dss_get_vdds_dsi();
if (IS_ERR(vdds_dsi)) {
vdds_dsi = devm_regulator_get(&dpi.pdev->dev, "vdds_dsi");
if (IS_ERR(vdds_dsi)) {
DSSERR("can't get VDDS_DSI regulator\n");
return PTR_ERR(vdds_dsi);
}
}
dpi.vdds_dsi_reg = vdds_dsi;
return 0;
}
static void dpi_init_pll(void)
{
struct platform_device *dsidev;
if (dpi.dsidev)
return;
dsidev = dpi_get_dsidev(dpi.output.dispc_channel);
if (!dsidev)
return;
if (dpi_verify_dsi_pll(dsidev)) {
DSSWARN("DSI PLL not operational\n");
return;
}
dpi.dsidev = dsidev;
}
/* /*
* Return a hardcoded channel for the DPI output. This should work for * Return a hardcoded channel for the DPI output. This should work for
* current use cases, but this can be later expanded to either resolve * current use cases, but this can be later expanded to either resolve
@ -572,41 +608,6 @@ static enum omap_channel dpi_get_channel(void)
} }
} }
static int dpi_init_display(struct omap_dss_device *dssdev)
{
struct platform_device *dsidev;
DSSDBG("init_display\n");
if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI) &&
dpi.vdds_dsi_reg == NULL) {
struct regulator *vdds_dsi;
vdds_dsi = dss_get_vdds_dsi();
if (IS_ERR(vdds_dsi)) {
DSSERR("can't get VDDS_DSI regulator\n");
return PTR_ERR(vdds_dsi);
}
dpi.vdds_dsi_reg = vdds_dsi;
}
dsidev = dpi_get_dsidev(dpi.output.dispc_channel);
if (dsidev && dpi_verify_dsi_pll(dsidev)) {
dsidev = NULL;
DSSWARN("DSI PLL not operational\n");
}
if (dsidev)
DSSDBG("using DSI PLL for DPI clock\n");
dpi.dsidev = dsidev;
return 0;
}
static struct omap_dss_device *dpi_find_dssdev(struct platform_device *pdev) static struct omap_dss_device *dpi_find_dssdev(struct platform_device *pdev)
{ {
struct omap_dss_board_info *pdata = pdev->dev.platform_data; struct omap_dss_board_info *pdata = pdev->dev.platform_data;
@ -646,19 +647,18 @@ static int dpi_probe_pdata(struct platform_device *dpidev)
if (!plat_dssdev) if (!plat_dssdev)
return 0; return 0;
r = dpi_init_regulator();
if (r)
return r;
dpi_init_pll();
dssdev = dss_alloc_and_init_device(&dpidev->dev); dssdev = dss_alloc_and_init_device(&dpidev->dev);
if (!dssdev) if (!dssdev)
return -ENOMEM; return -ENOMEM;
dss_copy_device_pdata(dssdev, plat_dssdev); dss_copy_device_pdata(dssdev, plat_dssdev);
r = dpi_init_display(dssdev);
if (r) {
DSSERR("device %s init failed: %d\n", dssdev->name, r);
dss_put_device(dssdev);
return r;
}
r = omapdss_output_set_device(&dpi.output, dssdev); r = omapdss_output_set_device(&dpi.output, dssdev);
if (r) { if (r) {
DSSERR("failed to connect output to new device: %s\n", DSSERR("failed to connect output to new device: %s\n",
@ -680,20 +680,21 @@ static int dpi_probe_pdata(struct platform_device *dpidev)
static void dpi_init_output(struct platform_device *pdev) static void dpi_init_output(struct platform_device *pdev)
{ {
struct omap_dss_output *out = &dpi.output; struct omap_dss_device *out = &dpi.output;
out->pdev = pdev; out->dev = &pdev->dev;
out->id = OMAP_DSS_OUTPUT_DPI; out->id = OMAP_DSS_OUTPUT_DPI;
out->type = OMAP_DISPLAY_TYPE_DPI; out->output_type = OMAP_DISPLAY_TYPE_DPI;
out->name = "dpi.0"; out->name = "dpi.0";
out->dispc_channel = dpi_get_channel(); out->dispc_channel = dpi_get_channel();
out->owner = THIS_MODULE;
dss_register_output(out); dss_register_output(out);
} }
static void __exit dpi_uninit_output(struct platform_device *pdev) static void __exit dpi_uninit_output(struct platform_device *pdev)
{ {
struct omap_dss_output *out = &dpi.output; struct omap_dss_device *out = &dpi.output;
dss_unregister_output(out); dss_unregister_output(out);
} }
@ -702,17 +703,23 @@ static int omap_dpi_probe(struct platform_device *pdev)
{ {
int r; int r;
dpi.pdev = pdev;
mutex_init(&dpi.lock); mutex_init(&dpi.lock);
dpi_init_output(pdev); dpi_init_output(pdev);
r = dpi_probe_pdata(pdev); if (pdev->dev.platform_data) {
if (r) { r = dpi_probe_pdata(pdev);
dpi_uninit_output(pdev); if (r)
return r; goto err_probe;
} }
return 0; return 0;
err_probe:
dpi_uninit_output(pdev);
return r;
} }
static int __exit omap_dpi_remove(struct platform_device *pdev) static int __exit omap_dpi_remove(struct platform_device *pdev)

Просмотреть файл

@ -363,7 +363,7 @@ struct dsi_data {
enum omap_dss_dsi_mode mode; enum omap_dss_dsi_mode mode;
struct omap_dss_dsi_videomode_timings vm_timings; struct omap_dss_dsi_videomode_timings vm_timings;
struct omap_dss_output output; struct omap_dss_device output;
}; };
struct dsi_packet_sent_handler_data { struct dsi_packet_sent_handler_data {
@ -383,12 +383,12 @@ static inline struct dsi_data *dsi_get_dsidrv_data(struct platform_device *dside
static inline struct platform_device *dsi_get_dsidev_from_dssdev(struct omap_dss_device *dssdev) static inline struct platform_device *dsi_get_dsidev_from_dssdev(struct omap_dss_device *dssdev)
{ {
return dssdev->output->pdev; return to_platform_device(dssdev->output->dev);
} }
struct platform_device *dsi_get_dsidev_from_id(int module) struct platform_device *dsi_get_dsidev_from_id(int module)
{ {
struct omap_dss_output *out; struct omap_dss_device *out;
enum omap_dss_output_id id; enum omap_dss_output_id id;
switch (module) { switch (module) {
@ -404,7 +404,7 @@ struct platform_device *dsi_get_dsidev_from_id(int module)
out = omap_dss_get_output(id); out = omap_dss_get_output(id);
return out ? out->pdev : NULL; return out ? to_platform_device(out->dev) : NULL;
} }
static inline void dsi_write_reg(struct platform_device *dsidev, static inline void dsi_write_reg(struct platform_device *dsidev,
@ -1114,6 +1114,30 @@ void dsi_runtime_put(struct platform_device *dsidev)
WARN_ON(r < 0 && r != -ENOSYS); WARN_ON(r < 0 && r != -ENOSYS);
} }
static int dsi_regulator_init(struct platform_device *dsidev)
{
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
struct regulator *vdds_dsi;
if (dsi->vdds_dsi_reg != NULL)
return 0;
vdds_dsi = devm_regulator_get(&dsi->pdev->dev, "vdds_dsi");
/* DT HACK: try VCXIO to make omapdss work for o4 sdp/panda */
if (IS_ERR(vdds_dsi))
vdds_dsi = devm_regulator_get(&dsi->pdev->dev, "VCXIO");
if (IS_ERR(vdds_dsi)) {
DSSERR("can't get VDDS_DSI regulator\n");
return PTR_ERR(vdds_dsi);
}
dsi->vdds_dsi_reg = vdds_dsi;
return 0;
}
/* source clock for DSI PLL. this could also be PCLKFREE */ /* source clock for DSI PLL. this could also be PCLKFREE */
static inline void dsi_enable_pll_clock(struct platform_device *dsidev, static inline void dsi_enable_pll_clock(struct platform_device *dsidev,
bool enable) bool enable)
@ -1592,22 +1616,9 @@ int dsi_pll_init(struct platform_device *dsidev, bool enable_hsclk,
*/ */
enable_hsclk = enable_hsdiv = true; enable_hsclk = enable_hsdiv = true;
if (dsi->vdds_dsi_reg == NULL) { r = dsi_regulator_init(dsidev);
struct regulator *vdds_dsi; if (r)
return r;
vdds_dsi = regulator_get(&dsi->pdev->dev, "vdds_dsi");
/* DT HACK: try VCXIO to make omapdss work for o4 sdp/panda */
if (IS_ERR(vdds_dsi))
vdds_dsi = regulator_get(&dsi->pdev->dev, "VCXIO");
if (IS_ERR(vdds_dsi)) {
DSSERR("can't get VDDS_DSI regulator\n");
return PTR_ERR(vdds_dsi);
}
dsi->vdds_dsi_reg = vdds_dsi;
}
dsi_enable_pll_clock(dsidev, 1); dsi_enable_pll_clock(dsidev, 1);
/* /*
@ -4122,7 +4133,7 @@ int dsi_enable_video_output(struct omap_dss_device *dssdev, int channel)
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
struct omap_overlay_manager *mgr = dsi->output.manager; struct omap_overlay_manager *mgr = dsi->output.manager;
int bpp = dsi_get_pixel_size(dsi->pix_fmt); int bpp = dsi_get_pixel_size(dsi->pix_fmt);
struct omap_dss_output *out = &dsi->output; struct omap_dss_device *out = &dsi->output;
u8 data_type; u8 data_type;
u16 word_count; u16 word_count;
int r; int r;
@ -4581,12 +4592,6 @@ int omapdss_dsi_display_enable(struct omap_dss_device *dssdev)
mutex_lock(&dsi->lock); mutex_lock(&dsi->lock);
r = omap_dss_start_device(dssdev);
if (r) {
DSSERR("failed to start device\n");
goto err_start_dev;
}
r = dsi_runtime_get(dsidev); r = dsi_runtime_get(dsidev);
if (r) if (r)
goto err_get_dsi; goto err_get_dsi;
@ -4607,8 +4612,6 @@ err_init_dsi:
dsi_enable_pll_clock(dsidev, 0); dsi_enable_pll_clock(dsidev, 0);
dsi_runtime_put(dsidev); dsi_runtime_put(dsidev);
err_get_dsi: err_get_dsi:
omap_dss_stop_device(dssdev);
err_start_dev:
mutex_unlock(&dsi->lock); mutex_unlock(&dsi->lock);
DSSDBG("dsi_display_enable FAILED\n"); DSSDBG("dsi_display_enable FAILED\n");
return r; return r;
@ -4637,8 +4640,6 @@ void omapdss_dsi_display_disable(struct omap_dss_device *dssdev,
dsi_runtime_put(dsidev); dsi_runtime_put(dsidev);
dsi_enable_pll_clock(dsidev, 0); dsi_enable_pll_clock(dsidev, 0);
omap_dss_stop_device(dssdev);
mutex_unlock(&dsi->lock); mutex_unlock(&dsi->lock);
} }
EXPORT_SYMBOL(omapdss_dsi_display_disable); EXPORT_SYMBOL(omapdss_dsi_display_disable);
@ -5225,34 +5226,6 @@ static enum omap_channel dsi_get_channel(int module_id)
} }
} }
static int dsi_init_display(struct omap_dss_device *dssdev)
{
struct platform_device *dsidev =
dsi_get_dsidev_from_id(dssdev->phy.dsi.module);
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
DSSDBG("DSI init\n");
if (dsi->vdds_dsi_reg == NULL) {
struct regulator *vdds_dsi;
vdds_dsi = regulator_get(&dsi->pdev->dev, "vdds_dsi");
/* DT HACK: try VCXIO to make omapdss work for o4 sdp/panda */
if (IS_ERR(vdds_dsi))
vdds_dsi = regulator_get(&dsi->pdev->dev, "VCXIO");
if (IS_ERR(vdds_dsi)) {
DSSERR("can't get VDDS_DSI regulator\n");
return PTR_ERR(vdds_dsi);
}
dsi->vdds_dsi_reg = vdds_dsi;
}
return 0;
}
int omap_dsi_request_vc(struct omap_dss_device *dssdev, int *channel) int omap_dsi_request_vc(struct omap_dss_device *dssdev, int *channel)
{ {
struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
@ -5410,19 +5383,16 @@ static int dsi_probe_pdata(struct platform_device *dsidev)
if (!plat_dssdev) if (!plat_dssdev)
return 0; return 0;
r = dsi_regulator_init(dsidev);
if (r)
return r;
dssdev = dss_alloc_and_init_device(&dsidev->dev); dssdev = dss_alloc_and_init_device(&dsidev->dev);
if (!dssdev) if (!dssdev)
return -ENOMEM; return -ENOMEM;
dss_copy_device_pdata(dssdev, plat_dssdev); dss_copy_device_pdata(dssdev, plat_dssdev);
r = dsi_init_display(dssdev);
if (r) {
DSSERR("device %s init failed: %d\n", dssdev->name, r);
dss_put_device(dssdev);
return r;
}
r = omapdss_output_set_device(&dsi->output, dssdev); r = omapdss_output_set_device(&dsi->output, dssdev);
if (r) { if (r) {
DSSERR("failed to connect output to new device: %s\n", DSSERR("failed to connect output to new device: %s\n",
@ -5445,15 +5415,16 @@ static int dsi_probe_pdata(struct platform_device *dsidev)
static void dsi_init_output(struct platform_device *dsidev) static void dsi_init_output(struct platform_device *dsidev)
{ {
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
struct omap_dss_output *out = &dsi->output; struct omap_dss_device *out = &dsi->output;
out->pdev = dsidev; out->dev = &dsidev->dev;
out->id = dsi->module_id == 0 ? out->id = dsi->module_id == 0 ?
OMAP_DSS_OUTPUT_DSI1 : OMAP_DSS_OUTPUT_DSI2; OMAP_DSS_OUTPUT_DSI1 : OMAP_DSS_OUTPUT_DSI2;
out->type = OMAP_DISPLAY_TYPE_DSI; out->output_type = OMAP_DISPLAY_TYPE_DSI;
out->name = dsi->module_id == 0 ? "dsi.0" : "dsi.1"; out->name = dsi->module_id == 0 ? "dsi.0" : "dsi.1";
out->dispc_channel = dsi_get_channel(dsi->module_id); out->dispc_channel = dsi_get_channel(dsi->module_id);
out->owner = THIS_MODULE;
dss_register_output(out); dss_register_output(out);
} }
@ -5461,7 +5432,7 @@ static void dsi_init_output(struct platform_device *dsidev)
static void dsi_uninit_output(struct platform_device *dsidev) static void dsi_uninit_output(struct platform_device *dsidev)
{ {
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
struct omap_dss_output *out = &dsi->output; struct omap_dss_device *out = &dsi->output;
dss_unregister_output(out); dss_unregister_output(out);
} }
@ -5563,12 +5534,10 @@ static int omap_dsihw_probe(struct platform_device *dsidev)
dsi_init_output(dsidev); dsi_init_output(dsidev);
r = dsi_probe_pdata(dsidev); if (dsidev->dev.platform_data) {
if (r) { r = dsi_probe_pdata(dsidev);
dsi_runtime_put(dsidev); if (r)
dsi_uninit_output(dsidev); goto err_probe;
pm_runtime_disable(&dsidev->dev);
return r;
} }
dsi_runtime_put(dsidev); dsi_runtime_put(dsidev);
@ -5586,6 +5555,9 @@ static int omap_dsihw_probe(struct platform_device *dsidev)
#endif #endif
return 0; return 0;
err_probe:
dsi_runtime_put(dsidev);
dsi_uninit_output(dsidev);
err_runtime_get: err_runtime_get:
pm_runtime_disable(&dsidev->dev); pm_runtime_disable(&dsidev->dev);
return r; return r;
@ -5603,14 +5575,9 @@ static int __exit omap_dsihw_remove(struct platform_device *dsidev)
pm_runtime_disable(&dsidev->dev); pm_runtime_disable(&dsidev->dev);
if (dsi->vdds_dsi_reg != NULL) { if (dsi->vdds_dsi_reg != NULL && dsi->vdds_dsi_enabled) {
if (dsi->vdds_dsi_enabled) { regulator_disable(dsi->vdds_dsi_reg);
regulator_disable(dsi->vdds_dsi_reg); dsi->vdds_dsi_enabled = false;
dsi->vdds_dsi_enabled = false;
}
regulator_put(dsi->vdds_dsi_reg);
dsi->vdds_dsi_reg = NULL;
} }
return 0; return 0;

Просмотреть файл

@ -157,7 +157,8 @@ static void dss_restore_context(void)
int dss_get_ctx_loss_count(void) int dss_get_ctx_loss_count(void)
{ {
struct omap_dss_board_info *board_data = dss.pdev->dev.platform_data; struct platform_device *core_pdev = dss_get_core_pdev();
struct omap_dss_board_info *board_data = core_pdev->dev.platform_data;
int cnt; int cnt;
if (!board_data->get_context_loss_count) if (!board_data->get_context_loss_count)

Просмотреть файл

@ -180,22 +180,22 @@ void dss_copy_device_pdata(struct omap_dss_device *dst,
const struct omap_dss_device *src); const struct omap_dss_device *src);
/* output */ /* output */
void dss_register_output(struct omap_dss_output *out); void dss_register_output(struct omap_dss_device *out);
void dss_unregister_output(struct omap_dss_output *out); void dss_unregister_output(struct omap_dss_device *out);
/* display */ /* display */
int dss_suspend_all_devices(void); int dss_suspend_all_devices(void);
int dss_resume_all_devices(void); int dss_resume_all_devices(void);
void dss_disable_all_devices(void); void dss_disable_all_devices(void);
int display_init_sysfs(struct platform_device *pdev, int display_init_sysfs(struct platform_device *pdev);
struct omap_dss_device *dssdev); void display_uninit_sysfs(struct platform_device *pdev);
void display_uninit_sysfs(struct platform_device *pdev,
struct omap_dss_device *dssdev);
/* manager */ /* manager */
int dss_init_overlay_managers(struct platform_device *pdev); int dss_init_overlay_managers(void);
void dss_uninit_overlay_managers(struct platform_device *pdev); void dss_uninit_overlay_managers(void);
int dss_init_overlay_managers_sysfs(struct platform_device *pdev);
void dss_uninit_overlay_managers_sysfs(struct platform_device *pdev);
int dss_mgr_simple_check(struct omap_overlay_manager *mgr, int dss_mgr_simple_check(struct omap_overlay_manager *mgr,
const struct omap_overlay_manager_info *info); const struct omap_overlay_manager_info *info);
int dss_mgr_check_timings(struct omap_overlay_manager *mgr, int dss_mgr_check_timings(struct omap_overlay_manager *mgr,
@ -426,6 +426,7 @@ void dispc_mgr_set_clock_div(enum omap_channel channel,
const struct dispc_clock_info *cinfo); const struct dispc_clock_info *cinfo);
int dispc_mgr_get_clock_div(enum omap_channel channel, int dispc_mgr_get_clock_div(enum omap_channel channel,
struct dispc_clock_info *cinfo); struct dispc_clock_info *cinfo);
void dispc_set_tv_pclk(unsigned long pclk);
u32 dispc_wb_get_framedone_irq(void); u32 dispc_wb_get_framedone_irq(void);
bool dispc_wb_go_busy(void); bool dispc_wb_go_busy(void);
@ -437,17 +438,8 @@ int dispc_wb_setup(const struct omap_dss_writeback_info *wi,
bool mem_to_mem, const struct omap_video_timings *timings); bool mem_to_mem, const struct omap_video_timings *timings);
/* VENC */ /* VENC */
#ifdef CONFIG_OMAP2_DSS_VENC
int venc_init_platform_driver(void) __init; int venc_init_platform_driver(void) __init;
void venc_uninit_platform_driver(void) __exit; void venc_uninit_platform_driver(void) __exit;
unsigned long venc_get_pixel_clock(void);
#else
static inline unsigned long venc_get_pixel_clock(void)
{
WARN("%s: VENC not compiled in, returning pclk as 0\n", __func__);
return 0;
}
#endif
int omapdss_venc_display_enable(struct omap_dss_device *dssdev); int omapdss_venc_display_enable(struct omap_dss_device *dssdev);
void omapdss_venc_display_disable(struct omap_dss_device *dssdev); void omapdss_venc_display_disable(struct omap_dss_device *dssdev);
void omapdss_venc_set_timings(struct omap_dss_device *dssdev, void omapdss_venc_set_timings(struct omap_dss_device *dssdev,
@ -464,17 +456,8 @@ int venc_panel_init(void);
void venc_panel_exit(void); void venc_panel_exit(void);
/* HDMI */ /* HDMI */
#ifdef CONFIG_OMAP4_DSS_HDMI
int hdmi_init_platform_driver(void) __init; int hdmi_init_platform_driver(void) __init;
void hdmi_uninit_platform_driver(void) __exit; void hdmi_uninit_platform_driver(void) __exit;
unsigned long hdmi_get_pixel_clock(void);
#else
static inline unsigned long hdmi_get_pixel_clock(void)
{
WARN("%s: HDMI not compiled in, returning pclk as 0\n", __func__);
return 0;
}
#endif
int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev); int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev);
void omapdss_hdmi_display_disable(struct omap_dss_device *dssdev); void omapdss_hdmi_display_disable(struct omap_dss_device *dssdev);
int omapdss_hdmi_core_enable(struct omap_dss_device *dssdev); int omapdss_hdmi_core_enable(struct omap_dss_device *dssdev);

Просмотреть файл

@ -797,7 +797,6 @@ static const struct ti_hdmi_ip_ops omap4_hdmi_functions = {
.phy_enable = ti_hdmi_4xxx_phy_enable, .phy_enable = ti_hdmi_4xxx_phy_enable,
.phy_disable = ti_hdmi_4xxx_phy_disable, .phy_disable = ti_hdmi_4xxx_phy_disable,
.read_edid = ti_hdmi_4xxx_read_edid, .read_edid = ti_hdmi_4xxx_read_edid,
.detect = ti_hdmi_4xxx_detect,
.pll_enable = ti_hdmi_4xxx_pll_enable, .pll_enable = ti_hdmi_4xxx_pll_enable,
.pll_disable = ti_hdmi_4xxx_pll_disable, .pll_disable = ti_hdmi_4xxx_pll_disable,
.video_enable = ti_hdmi_4xxx_wp_video_start, .video_enable = ti_hdmi_4xxx_wp_video_start,

Просмотреть файл

@ -70,7 +70,7 @@ static struct {
int ls_oe_gpio; int ls_oe_gpio;
int hpd_gpio; int hpd_gpio;
struct omap_dss_output output; struct omap_dss_device output;
} hdmi; } hdmi;
/* /*
@ -328,6 +328,29 @@ static void hdmi_runtime_put(void)
WARN_ON(r < 0 && r != -ENOSYS); WARN_ON(r < 0 && r != -ENOSYS);
} }
static int hdmi_init_regulator(void)
{
struct regulator *reg;
if (hdmi.vdda_hdmi_dac_reg != NULL)
return 0;
reg = devm_regulator_get(&hdmi.pdev->dev, "vdda_hdmi_dac");
/* DT HACK: try VDAC to make omapdss work for o4 sdp/panda */
if (IS_ERR(reg))
reg = devm_regulator_get(&hdmi.pdev->dev, "VDAC");
if (IS_ERR(reg)) {
DSSERR("can't get VDDA_HDMI_DAC regulator\n");
return PTR_ERR(reg);
}
hdmi.vdda_hdmi_dac_reg = reg;
return 0;
}
static int hdmi_init_display(struct omap_dss_device *dssdev) static int hdmi_init_display(struct omap_dss_device *dssdev)
{ {
int r; int r;
@ -342,22 +365,9 @@ static int hdmi_init_display(struct omap_dss_device *dssdev)
dss_init_hdmi_ip_ops(&hdmi.ip_data, omapdss_get_version()); dss_init_hdmi_ip_ops(&hdmi.ip_data, omapdss_get_version());
if (hdmi.vdda_hdmi_dac_reg == NULL) { r = hdmi_init_regulator();
struct regulator *reg; if (r)
return r;
reg = devm_regulator_get(&hdmi.pdev->dev, "vdda_hdmi_dac");
/* DT HACK: try VDAC to make omapdss work for o4 sdp/panda */
if (IS_ERR(reg))
reg = devm_regulator_get(&hdmi.pdev->dev, "VDAC");
if (IS_ERR(reg)) {
DSSERR("can't get VDDA_HDMI_DAC regulator\n");
return PTR_ERR(reg);
}
hdmi.vdda_hdmi_dac_reg = reg;
}
r = gpio_request_array(gpios, ARRAY_SIZE(gpios)); r = gpio_request_array(gpios, ARRAY_SIZE(gpios));
if (r) if (r)
@ -455,12 +465,6 @@ end: return cm;
} }
unsigned long hdmi_get_pixel_clock(void)
{
/* HDMI Pixel Clock in Mhz */
return hdmi.ip_data.cfg.timings.pixel_clock * 1000;
}
static void hdmi_compute_pll(struct omap_dss_device *dssdev, int phy, static void hdmi_compute_pll(struct omap_dss_device *dssdev, int phy,
struct hdmi_pll_info *pi) struct hdmi_pll_info *pi)
{ {
@ -550,7 +554,7 @@ static int hdmi_power_on_full(struct omap_dss_device *dssdev)
{ {
int r; int r;
struct omap_video_timings *p; struct omap_video_timings *p;
struct omap_overlay_manager *mgr = dssdev->output->manager; struct omap_overlay_manager *mgr = hdmi.output.manager;
unsigned long phy; unsigned long phy;
r = hdmi_power_on_core(dssdev); r = hdmi_power_on_core(dssdev);
@ -613,7 +617,7 @@ err_pll_enable:
static void hdmi_power_off_full(struct omap_dss_device *dssdev) static void hdmi_power_off_full(struct omap_dss_device *dssdev)
{ {
struct omap_overlay_manager *mgr = dssdev->output->manager; struct omap_overlay_manager *mgr = hdmi.output.manager;
dss_mgr_disable(mgr); dss_mgr_disable(mgr);
@ -653,6 +657,8 @@ void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev,
if (t != NULL) if (t != NULL)
hdmi.ip_data.cfg = *t; hdmi.ip_data.cfg = *t;
dispc_set_tv_pclk(t->timings.pixel_clock * 1000);
mutex_unlock(&hdmi.lock); mutex_unlock(&hdmi.lock);
} }
@ -700,7 +706,7 @@ bool omapdss_hdmi_detect(void)
r = hdmi_runtime_get(); r = hdmi_runtime_get();
BUG_ON(r); BUG_ON(r);
r = hdmi.ip_data.ops->detect(&hdmi.ip_data); r = gpio_get_value(hdmi.hpd_gpio);
hdmi_runtime_put(); hdmi_runtime_put();
mutex_unlock(&hdmi.lock); mutex_unlock(&hdmi.lock);
@ -710,7 +716,7 @@ bool omapdss_hdmi_detect(void)
int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev) int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev)
{ {
struct omap_dss_output *out = dssdev->output; struct omap_dss_device *out = &hdmi.output;
int r = 0; int r = 0;
DSSDBG("ENTER hdmi_display_enable\n"); DSSDBG("ENTER hdmi_display_enable\n");
@ -723,25 +729,15 @@ int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev)
goto err0; goto err0;
} }
hdmi.ip_data.hpd_gpio = hdmi.hpd_gpio;
r = omap_dss_start_device(dssdev);
if (r) {
DSSERR("failed to start device\n");
goto err0;
}
r = hdmi_power_on_full(dssdev); r = hdmi_power_on_full(dssdev);
if (r) { if (r) {
DSSERR("failed to power on device\n"); DSSERR("failed to power on device\n");
goto err1; goto err0;
} }
mutex_unlock(&hdmi.lock); mutex_unlock(&hdmi.lock);
return 0; return 0;
err1:
omap_dss_stop_device(dssdev);
err0: err0:
mutex_unlock(&hdmi.lock); mutex_unlock(&hdmi.lock);
return r; return r;
@ -755,8 +751,6 @@ void omapdss_hdmi_display_disable(struct omap_dss_device *dssdev)
hdmi_power_off_full(dssdev); hdmi_power_off_full(dssdev);
omap_dss_stop_device(dssdev);
mutex_unlock(&hdmi.lock); mutex_unlock(&hdmi.lock);
} }
@ -768,8 +762,6 @@ int omapdss_hdmi_core_enable(struct omap_dss_device *dssdev)
mutex_lock(&hdmi.lock); mutex_lock(&hdmi.lock);
hdmi.ip_data.hpd_gpio = hdmi.hpd_gpio;
r = hdmi_power_on_core(dssdev); r = hdmi_power_on_core(dssdev);
if (r) { if (r) {
DSSERR("failed to power on device\n"); DSSERR("failed to power on device\n");
@ -1035,20 +1027,21 @@ static int hdmi_probe_pdata(struct platform_device *pdev)
static void hdmi_init_output(struct platform_device *pdev) static void hdmi_init_output(struct platform_device *pdev)
{ {
struct omap_dss_output *out = &hdmi.output; struct omap_dss_device *out = &hdmi.output;
out->pdev = pdev; out->dev = &pdev->dev;
out->id = OMAP_DSS_OUTPUT_HDMI; out->id = OMAP_DSS_OUTPUT_HDMI;
out->type = OMAP_DISPLAY_TYPE_HDMI; out->output_type = OMAP_DISPLAY_TYPE_HDMI;
out->name = "hdmi.0"; out->name = "hdmi.0";
out->dispc_channel = OMAP_DSS_CHANNEL_DIGIT; out->dispc_channel = OMAP_DSS_CHANNEL_DIGIT;
out->owner = THIS_MODULE;
dss_register_output(out); dss_register_output(out);
} }
static void __exit hdmi_uninit_output(struct platform_device *pdev) static void __exit hdmi_uninit_output(struct platform_device *pdev)
{ {
struct omap_dss_output *out = &hdmi.output; struct omap_dss_device *out = &hdmi.output;
dss_unregister_output(out); dss_unregister_output(out);
} }
@ -1071,6 +1064,12 @@ static int omapdss_hdmihw_probe(struct platform_device *pdev)
if (IS_ERR(hdmi.ip_data.base_wp)) if (IS_ERR(hdmi.ip_data.base_wp))
return PTR_ERR(hdmi.ip_data.base_wp); return PTR_ERR(hdmi.ip_data.base_wp);
hdmi.ip_data.irq = platform_get_irq(pdev, 0);
if (hdmi.ip_data.irq < 0) {
DSSERR("platform_get_irq failed\n");
return -ENODEV;
}
r = hdmi_get_clocks(pdev); r = hdmi_get_clocks(pdev);
if (r) { if (r) {
DSSERR("can't get clocks\n"); DSSERR("can't get clocks\n");
@ -1094,15 +1093,19 @@ static int omapdss_hdmihw_probe(struct platform_device *pdev)
dss_debugfs_create_file("hdmi", hdmi_dump_regs); dss_debugfs_create_file("hdmi", hdmi_dump_regs);
r = hdmi_probe_pdata(pdev); if (pdev->dev.platform_data) {
if (r) { r = hdmi_probe_pdata(pdev);
hdmi_panel_exit(); if (r)
hdmi_uninit_output(pdev); goto err_probe;
pm_runtime_disable(&pdev->dev);
return r;
} }
return 0; return 0;
err_probe:
hdmi_panel_exit();
hdmi_uninit_output(pdev);
pm_runtime_disable(&pdev->dev);
return r;
} }
static int __exit hdmi_remove_child(struct device *dev, void *data) static int __exit hdmi_remove_child(struct device *dev, void *data)

Просмотреть файл

@ -50,6 +50,7 @@ static ssize_t manager_display_store(struct omap_overlay_manager *mgr,
int r = 0; int r = 0;
size_t len = size; size_t len = size;
struct omap_dss_device *dssdev = NULL; struct omap_dss_device *dssdev = NULL;
struct omap_dss_device *old_dssdev;
int match(struct omap_dss_device *dssdev, void *data) int match(struct omap_dss_device *dssdev, void *data)
{ {
@ -66,32 +67,44 @@ static ssize_t manager_display_store(struct omap_overlay_manager *mgr,
if (len > 0 && dssdev == NULL) if (len > 0 && dssdev == NULL)
return -EINVAL; return -EINVAL;
if (dssdev) if (dssdev) {
DSSDBG("display %s found\n", dssdev->name); DSSDBG("display %s found\n", dssdev->name);
if (mgr->output) { if (omapdss_device_is_connected(dssdev)) {
r = mgr->unset_output(mgr); DSSERR("new display is already connected\n");
if (r) { r = -EINVAL;
DSSERR("failed to unset current output\n"); goto put_device;
}
if (omapdss_device_is_enabled(dssdev)) {
DSSERR("new display is not disabled\n");
r = -EINVAL;
goto put_device; goto put_device;
} }
} }
if (dssdev) { old_dssdev = mgr->get_device(mgr);
struct omap_dss_output *out = dssdev->output; if (old_dssdev) {
if (omapdss_device_is_enabled(old_dssdev)) {
/* DSSERR("old display is not disabled\n");
* a registered device should have an output connected to it r = -EINVAL;
* already
*/
if (!out) {
DSSERR("device has no output connected to it\n");
goto put_device; goto put_device;
} }
r = mgr->set_output(mgr, out); old_dssdev->driver->disconnect(old_dssdev);
}
if (dssdev) {
r = dssdev->driver->connect(dssdev);
if (r) { if (r) {
DSSERR("failed to set manager output\n"); DSSERR("failed to connect new device\n");
goto put_device;
}
old_dssdev = mgr->get_device(mgr);
if (old_dssdev != dssdev) {
DSSERR("failed to connect device to this manager\n");
dssdev->driver->disconnect(dssdev);
goto put_device; goto put_device;
} }
@ -509,4 +522,6 @@ void dss_manager_kobj_uninit(struct omap_overlay_manager *mgr)
{ {
kobject_del(&mgr->kobj); kobject_del(&mgr->kobj);
kobject_put(&mgr->kobj); kobject_put(&mgr->kobj);
memset(&mgr->kobj, 0, sizeof(mgr->kobj));
} }

Просмотреть файл

@ -36,9 +36,9 @@
static int num_managers; static int num_managers;
static struct omap_overlay_manager *managers; static struct omap_overlay_manager *managers;
int dss_init_overlay_managers(struct platform_device *pdev) int dss_init_overlay_managers(void)
{ {
int i, r; int i;
num_managers = dss_feat_get_num_mgrs(); num_managers = dss_feat_get_num_mgrs();
@ -76,6 +76,17 @@ int dss_init_overlay_managers(struct platform_device *pdev)
dss_feat_get_supported_outputs(mgr->id); dss_feat_get_supported_outputs(mgr->id);
INIT_LIST_HEAD(&mgr->overlays); INIT_LIST_HEAD(&mgr->overlays);
}
return 0;
}
int dss_init_overlay_managers_sysfs(struct platform_device *pdev)
{
int i, r;
for (i = 0; i < num_managers; ++i) {
struct omap_overlay_manager *mgr = &managers[i];
r = dss_manager_kobj_init(mgr, pdev); r = dss_manager_kobj_init(mgr, pdev);
if (r) if (r)
@ -85,18 +96,22 @@ int dss_init_overlay_managers(struct platform_device *pdev)
return 0; return 0;
} }
void dss_uninit_overlay_managers(struct platform_device *pdev) void dss_uninit_overlay_managers(void)
{
kfree(managers);
managers = NULL;
num_managers = 0;
}
void dss_uninit_overlay_managers_sysfs(struct platform_device *pdev)
{ {
int i; int i;
for (i = 0; i < num_managers; ++i) { for (i = 0; i < num_managers; ++i) {
struct omap_overlay_manager *mgr = &managers[i]; struct omap_overlay_manager *mgr = &managers[i];
dss_manager_kobj_uninit(mgr); dss_manager_kobj_uninit(mgr);
} }
kfree(managers);
managers = NULL;
num_managers = 0;
} }
int omap_dss_get_num_overlay_managers(void) int omap_dss_get_num_overlay_managers(void)

Просмотреть файл

@ -27,7 +27,7 @@
static LIST_HEAD(output_list); static LIST_HEAD(output_list);
static DEFINE_MUTEX(output_lock); static DEFINE_MUTEX(output_lock);
int omapdss_output_set_device(struct omap_dss_output *out, int omapdss_output_set_device(struct omap_dss_device *out,
struct omap_dss_device *dssdev) struct omap_dss_device *dssdev)
{ {
int r; int r;
@ -41,7 +41,7 @@ int omapdss_output_set_device(struct omap_dss_output *out,
goto err; goto err;
} }
if (out->type != dssdev->type) { if (out->output_type != dssdev->type) {
DSSERR("output type and display type don't match\n"); DSSERR("output type and display type don't match\n");
r = -EINVAL; r = -EINVAL;
goto err; goto err;
@ -60,7 +60,7 @@ err:
} }
EXPORT_SYMBOL(omapdss_output_set_device); EXPORT_SYMBOL(omapdss_output_set_device);
int omapdss_output_unset_device(struct omap_dss_output *out) int omapdss_output_unset_device(struct omap_dss_device *out)
{ {
int r; int r;
@ -92,19 +92,19 @@ err:
} }
EXPORT_SYMBOL(omapdss_output_unset_device); EXPORT_SYMBOL(omapdss_output_unset_device);
void dss_register_output(struct omap_dss_output *out) void dss_register_output(struct omap_dss_device *out)
{ {
list_add_tail(&out->list, &output_list); list_add_tail(&out->list, &output_list);
} }
void dss_unregister_output(struct omap_dss_output *out) void dss_unregister_output(struct omap_dss_device *out)
{ {
list_del(&out->list); list_del(&out->list);
} }
struct omap_dss_output *omap_dss_get_output(enum omap_dss_output_id id) struct omap_dss_device *omap_dss_get_output(enum omap_dss_output_id id)
{ {
struct omap_dss_output *out; struct omap_dss_device *out;
list_for_each_entry(out, &output_list, list) { list_for_each_entry(out, &output_list, list) {
if (out->id == id) if (out->id == id)
@ -115,6 +115,56 @@ struct omap_dss_output *omap_dss_get_output(enum omap_dss_output_id id)
} }
EXPORT_SYMBOL(omap_dss_get_output); EXPORT_SYMBOL(omap_dss_get_output);
struct omap_dss_device *omap_dss_find_output(const char *name)
{
struct omap_dss_device *out;
list_for_each_entry(out, &output_list, list) {
if (strcmp(out->name, name) == 0)
return omap_dss_get_device(out);
}
return NULL;
}
EXPORT_SYMBOL(omap_dss_find_output);
struct omap_dss_device *omap_dss_find_output_by_node(struct device_node *node)
{
struct omap_dss_device *out;
list_for_each_entry(out, &output_list, list) {
if (out->dev->of_node == node)
return omap_dss_get_device(out);
}
return NULL;
}
EXPORT_SYMBOL(omap_dss_find_output_by_node);
struct omap_dss_device *omapdss_find_output_from_display(struct omap_dss_device *dssdev)
{
return omap_dss_get_device(dssdev->output);
}
EXPORT_SYMBOL(omapdss_find_output_from_display);
struct omap_overlay_manager *omapdss_find_mgr_from_display(struct omap_dss_device *dssdev)
{
struct omap_dss_device *out;
struct omap_overlay_manager *mgr;
out = omapdss_find_output_from_display(dssdev);
if (out == NULL)
return NULL;
mgr = out->manager;
omap_dss_put_device(out);
return mgr;
}
EXPORT_SYMBOL(omapdss_find_mgr_from_display);
static const struct dss_mgr_ops *dss_mgr_ops; static const struct dss_mgr_ops *dss_mgr_ops;
int dss_install_mgr_ops(const struct dss_mgr_ops *mgr_ops) int dss_install_mgr_ops(const struct dss_mgr_ops *mgr_ops)
@ -134,6 +184,20 @@ void dss_uninstall_mgr_ops(void)
} }
EXPORT_SYMBOL(dss_uninstall_mgr_ops); EXPORT_SYMBOL(dss_uninstall_mgr_ops);
int dss_mgr_connect(struct omap_overlay_manager *mgr,
struct omap_dss_device *dst)
{
return dss_mgr_ops->connect(mgr, dst);
}
EXPORT_SYMBOL(dss_mgr_connect);
void dss_mgr_disconnect(struct omap_overlay_manager *mgr,
struct omap_dss_device *dst)
{
dss_mgr_ops->disconnect(mgr, dst);
}
EXPORT_SYMBOL(dss_mgr_disconnect);
void dss_mgr_set_timings(struct omap_overlay_manager *mgr, void dss_mgr_set_timings(struct omap_overlay_manager *mgr,
const struct omap_video_timings *timings) const struct omap_video_timings *timings)
{ {

Просмотреть файл

@ -117,7 +117,7 @@ static struct {
int data_lines; int data_lines;
struct rfbi_timings intf_timings; struct rfbi_timings intf_timings;
struct omap_dss_output output; struct omap_dss_device output;
} rfbi; } rfbi;
static inline void rfbi_write_reg(const struct rfbi_reg idx, u32 val) static inline void rfbi_write_reg(const struct rfbi_reg idx, u32 val)
@ -312,7 +312,7 @@ static int rfbi_transfer_area(struct omap_dss_device *dssdev,
{ {
u32 l; u32 l;
int r; int r;
struct omap_overlay_manager *mgr = dssdev->output->manager; struct omap_overlay_manager *mgr = rfbi.output.manager;
u16 width = rfbi.timings.x_res; u16 width = rfbi.timings.x_res;
u16 height = rfbi.timings.y_res; u16 height = rfbi.timings.y_res;
@ -852,7 +852,7 @@ static void rfbi_dump_regs(struct seq_file *s)
static void rfbi_config_lcd_manager(struct omap_dss_device *dssdev) static void rfbi_config_lcd_manager(struct omap_dss_device *dssdev)
{ {
struct omap_overlay_manager *mgr = dssdev->output->manager; struct omap_overlay_manager *mgr = rfbi.output.manager;
struct dss_lcd_mgr_config mgr_config; struct dss_lcd_mgr_config mgr_config;
mgr_config.io_pad_mode = DSS_IO_PAD_MODE_RFBI; mgr_config.io_pad_mode = DSS_IO_PAD_MODE_RFBI;
@ -890,7 +890,7 @@ static void rfbi_config_lcd_manager(struct omap_dss_device *dssdev)
int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev) int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev)
{ {
struct omap_dss_output *out = dssdev->output; struct omap_dss_device *out = &rfbi.output;
int r; int r;
if (out == NULL || out->manager == NULL) { if (out == NULL || out->manager == NULL) {
@ -902,12 +902,6 @@ int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev)
if (r) if (r)
return r; return r;
r = omap_dss_start_device(dssdev);
if (r) {
DSSERR("failed to start device\n");
goto err0;
}
r = dss_mgr_register_framedone_handler(out->manager, r = dss_mgr_register_framedone_handler(out->manager,
framedone_callback, NULL); framedone_callback, NULL);
if (r) { if (r) {
@ -924,8 +918,6 @@ int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev)
return 0; return 0;
err1: err1:
omap_dss_stop_device(dssdev);
err0:
rfbi_runtime_put(); rfbi_runtime_put();
return r; return r;
} }
@ -933,11 +925,10 @@ EXPORT_SYMBOL(omapdss_rfbi_display_enable);
void omapdss_rfbi_display_disable(struct omap_dss_device *dssdev) void omapdss_rfbi_display_disable(struct omap_dss_device *dssdev)
{ {
struct omap_dss_output *out = dssdev->output; struct omap_dss_device *out = &rfbi.output;
dss_mgr_unregister_framedone_handler(out->manager, dss_mgr_unregister_framedone_handler(out->manager,
framedone_callback, NULL); framedone_callback, NULL);
omap_dss_stop_device(dssdev);
rfbi_runtime_put(); rfbi_runtime_put();
} }
@ -1022,20 +1013,21 @@ static int rfbi_probe_pdata(struct platform_device *rfbidev)
static void rfbi_init_output(struct platform_device *pdev) static void rfbi_init_output(struct platform_device *pdev)
{ {
struct omap_dss_output *out = &rfbi.output; struct omap_dss_device *out = &rfbi.output;
out->pdev = pdev; out->dev = &pdev->dev;
out->id = OMAP_DSS_OUTPUT_DBI; out->id = OMAP_DSS_OUTPUT_DBI;
out->type = OMAP_DISPLAY_TYPE_DBI; out->output_type = OMAP_DISPLAY_TYPE_DBI;
out->name = "rfbi.0"; out->name = "rfbi.0";
out->dispc_channel = OMAP_DSS_CHANNEL_LCD; out->dispc_channel = OMAP_DSS_CHANNEL_LCD;
out->owner = THIS_MODULE;
dss_register_output(out); dss_register_output(out);
} }
static void __exit rfbi_uninit_output(struct platform_device *pdev) static void __exit rfbi_uninit_output(struct platform_device *pdev)
{ {
struct omap_dss_output *out = &rfbi.output; struct omap_dss_device *out = &rfbi.output;
dss_unregister_output(out); dss_unregister_output(out);
} }
@ -1093,15 +1085,16 @@ static int omap_rfbihw_probe(struct platform_device *pdev)
rfbi_init_output(pdev); rfbi_init_output(pdev);
r = rfbi_probe_pdata(pdev); if (pdev->dev.platform_data) {
if (r) { r = rfbi_probe_pdata(pdev);
rfbi_uninit_output(pdev); if (r)
pm_runtime_disable(&pdev->dev); goto err_probe;
return r;
} }
return 0; return 0;
err_probe:
rfbi_uninit_output(pdev);
err_runtime_get: err_runtime_get:
pm_runtime_disable(&pdev->dev); pm_runtime_disable(&pdev->dev);
return r; return r;

Просмотреть файл

@ -31,6 +31,8 @@
#include "dss.h" #include "dss.h"
static struct { static struct {
struct platform_device *pdev;
bool update_enabled; bool update_enabled;
struct regulator *vdds_sdi_reg; struct regulator *vdds_sdi_reg;
@ -38,7 +40,7 @@ static struct {
struct omap_video_timings timings; struct omap_video_timings timings;
int datapairs; int datapairs;
struct omap_dss_output output; struct omap_dss_device output;
} sdi; } sdi;
struct sdi_clk_calc_ctx { struct sdi_clk_calc_ctx {
@ -109,7 +111,7 @@ static int sdi_calc_clock_div(unsigned long pclk,
static void sdi_config_lcd_manager(struct omap_dss_device *dssdev) static void sdi_config_lcd_manager(struct omap_dss_device *dssdev)
{ {
struct omap_overlay_manager *mgr = dssdev->output->manager; struct omap_overlay_manager *mgr = sdi.output.manager;
sdi.mgr_config.io_pad_mode = DSS_IO_PAD_MODE_BYPASS; sdi.mgr_config.io_pad_mode = DSS_IO_PAD_MODE_BYPASS;
@ -124,7 +126,7 @@ static void sdi_config_lcd_manager(struct omap_dss_device *dssdev)
int omapdss_sdi_display_enable(struct omap_dss_device *dssdev) int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
{ {
struct omap_dss_output *out = dssdev->output; struct omap_dss_device *out = &sdi.output;
struct omap_video_timings *t = &sdi.timings; struct omap_video_timings *t = &sdi.timings;
struct dss_clock_info dss_cinfo; struct dss_clock_info dss_cinfo;
struct dispc_clock_info dispc_cinfo; struct dispc_clock_info dispc_cinfo;
@ -136,12 +138,6 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
return -ENODEV; return -ENODEV;
} }
r = omap_dss_start_device(dssdev);
if (r) {
DSSERR("failed to start device\n");
goto err_start_dev;
}
r = regulator_enable(sdi.vdds_sdi_reg); r = regulator_enable(sdi.vdds_sdi_reg);
if (r) if (r)
goto err_reg_enable; goto err_reg_enable;
@ -213,15 +209,13 @@ err_calc_clock_div:
err_get_dispc: err_get_dispc:
regulator_disable(sdi.vdds_sdi_reg); regulator_disable(sdi.vdds_sdi_reg);
err_reg_enable: err_reg_enable:
omap_dss_stop_device(dssdev);
err_start_dev:
return r; return r;
} }
EXPORT_SYMBOL(omapdss_sdi_display_enable); EXPORT_SYMBOL(omapdss_sdi_display_enable);
void omapdss_sdi_display_disable(struct omap_dss_device *dssdev) void omapdss_sdi_display_disable(struct omap_dss_device *dssdev)
{ {
struct omap_overlay_manager *mgr = dssdev->output->manager; struct omap_overlay_manager *mgr = sdi.output.manager;
dss_mgr_disable(mgr); dss_mgr_disable(mgr);
@ -230,8 +224,6 @@ void omapdss_sdi_display_disable(struct omap_dss_device *dssdev)
dispc_runtime_put(); dispc_runtime_put();
regulator_disable(sdi.vdds_sdi_reg); regulator_disable(sdi.vdds_sdi_reg);
omap_dss_stop_device(dssdev);
} }
EXPORT_SYMBOL(omapdss_sdi_display_disable); EXPORT_SYMBOL(omapdss_sdi_display_disable);
@ -248,23 +240,25 @@ void omapdss_sdi_set_datapairs(struct omap_dss_device *dssdev, int datapairs)
} }
EXPORT_SYMBOL(omapdss_sdi_set_datapairs); EXPORT_SYMBOL(omapdss_sdi_set_datapairs);
static int sdi_init_display(struct omap_dss_device *dssdev) static int sdi_init_regulator(void)
{ {
DSSDBG("SDI init\n"); struct regulator *vdds_sdi;
if (sdi.vdds_sdi_reg == NULL) { if (sdi.vdds_sdi_reg)
struct regulator *vdds_sdi; return 0;
vdds_sdi = dss_get_vdds_sdi(); vdds_sdi = dss_get_vdds_sdi();
if (IS_ERR(vdds_sdi)) {
vdds_sdi = devm_regulator_get(&sdi.pdev->dev, "vdds_sdi");
if (IS_ERR(vdds_sdi)) { if (IS_ERR(vdds_sdi)) {
DSSERR("can't get VDDS_SDI regulator\n"); DSSERR("can't get VDDS_SDI regulator\n");
return PTR_ERR(vdds_sdi); return PTR_ERR(vdds_sdi);
} }
sdi.vdds_sdi_reg = vdds_sdi;
} }
sdi.vdds_sdi_reg = vdds_sdi;
return 0; return 0;
} }
@ -313,7 +307,7 @@ static int sdi_probe_pdata(struct platform_device *sdidev)
dss_copy_device_pdata(dssdev, plat_dssdev); dss_copy_device_pdata(dssdev, plat_dssdev);
r = sdi_init_display(dssdev); r = sdi_init_regulator();
if (r) { if (r) {
DSSERR("device %s init failed: %d\n", dssdev->name, r); DSSERR("device %s init failed: %d\n", dssdev->name, r);
dss_put_device(dssdev); dss_put_device(dssdev);
@ -341,20 +335,21 @@ static int sdi_probe_pdata(struct platform_device *sdidev)
static void sdi_init_output(struct platform_device *pdev) static void sdi_init_output(struct platform_device *pdev)
{ {
struct omap_dss_output *out = &sdi.output; struct omap_dss_device *out = &sdi.output;
out->pdev = pdev; out->dev = &pdev->dev;
out->id = OMAP_DSS_OUTPUT_SDI; out->id = OMAP_DSS_OUTPUT_SDI;
out->type = OMAP_DISPLAY_TYPE_SDI; out->output_type = OMAP_DISPLAY_TYPE_SDI;
out->name = "sdi.0"; out->name = "sdi.0";
out->dispc_channel = OMAP_DSS_CHANNEL_LCD; out->dispc_channel = OMAP_DSS_CHANNEL_LCD;
out->owner = THIS_MODULE;
dss_register_output(out); dss_register_output(out);
} }
static void __exit sdi_uninit_output(struct platform_device *pdev) static void __exit sdi_uninit_output(struct platform_device *pdev)
{ {
struct omap_dss_output *out = &sdi.output; struct omap_dss_device *out = &sdi.output;
dss_unregister_output(out); dss_unregister_output(out);
} }
@ -363,15 +358,21 @@ static int omap_sdi_probe(struct platform_device *pdev)
{ {
int r; int r;
sdi.pdev = pdev;
sdi_init_output(pdev); sdi_init_output(pdev);
r = sdi_probe_pdata(pdev); if (pdev->dev.platform_data) {
if (r) { r = sdi_probe_pdata(pdev);
sdi_uninit_output(pdev); if (r)
return r; goto err_probe;
} }
return 0; return 0;
err_probe:
sdi_uninit_output(pdev);
return r;
} }
static int __exit omap_sdi_remove(struct platform_device *pdev) static int __exit omap_sdi_remove(struct platform_device *pdev)

Просмотреть файл

@ -73,8 +73,6 @@ struct ti_hdmi_ip_ops {
int (*read_edid)(struct hdmi_ip_data *ip_data, u8 *edid, int len); int (*read_edid)(struct hdmi_ip_data *ip_data, u8 *edid, int len);
bool (*detect)(struct hdmi_ip_data *ip_data);
int (*pll_enable)(struct hdmi_ip_data *ip_data); int (*pll_enable)(struct hdmi_ip_data *ip_data);
void (*pll_disable)(struct hdmi_ip_data *ip_data); void (*pll_disable)(struct hdmi_ip_data *ip_data);
@ -155,19 +153,18 @@ struct hdmi_ip_data {
unsigned long core_av_offset; unsigned long core_av_offset;
unsigned long pll_offset; unsigned long pll_offset;
unsigned long phy_offset; unsigned long phy_offset;
int irq;
const struct ti_hdmi_ip_ops *ops; const struct ti_hdmi_ip_ops *ops;
struct hdmi_config cfg; struct hdmi_config cfg;
struct hdmi_pll_info pll_data; struct hdmi_pll_info pll_data;
struct hdmi_core_infoframe_avi avi_cfg; struct hdmi_core_infoframe_avi avi_cfg;
/* ti_hdmi_4xxx_ip private data. These should be in a separate struct */ /* ti_hdmi_4xxx_ip private data. These should be in a separate struct */
int hpd_gpio;
struct mutex lock; struct mutex lock;
}; };
int ti_hdmi_4xxx_phy_enable(struct hdmi_ip_data *ip_data); int ti_hdmi_4xxx_phy_enable(struct hdmi_ip_data *ip_data);
void ti_hdmi_4xxx_phy_disable(struct hdmi_ip_data *ip_data); void ti_hdmi_4xxx_phy_disable(struct hdmi_ip_data *ip_data);
int ti_hdmi_4xxx_read_edid(struct hdmi_ip_data *ip_data, u8 *edid, int len); int ti_hdmi_4xxx_read_edid(struct hdmi_ip_data *ip_data, u8 *edid, int len);
bool ti_hdmi_4xxx_detect(struct hdmi_ip_data *ip_data);
int ti_hdmi_4xxx_wp_video_start(struct hdmi_ip_data *ip_data); int ti_hdmi_4xxx_wp_video_start(struct hdmi_ip_data *ip_data);
void ti_hdmi_4xxx_wp_video_stop(struct hdmi_ip_data *ip_data); void ti_hdmi_4xxx_wp_video_stop(struct hdmi_ip_data *ip_data);
int ti_hdmi_4xxx_pll_enable(struct hdmi_ip_data *ip_data); int ti_hdmi_4xxx_pll_enable(struct hdmi_ip_data *ip_data);

Просмотреть файл

@ -28,7 +28,6 @@
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/string.h> #include <linux/string.h>
#include <linux/seq_file.h> #include <linux/seq_file.h>
#include <linux/gpio.h>
#if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO) #if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO)
#include <sound/asound.h> #include <sound/asound.h>
#include <sound/asoundef.h> #include <sound/asoundef.h>
@ -38,6 +37,9 @@
#include "dss.h" #include "dss.h"
#include "dss_features.h" #include "dss_features.h"
#define HDMI_IRQ_LINK_CONNECT (1 << 25)
#define HDMI_IRQ_LINK_DISCONNECT (1 << 26)
static inline void hdmi_write_reg(void __iomem *base_addr, static inline void hdmi_write_reg(void __iomem *base_addr,
const u16 idx, u32 val) const u16 idx, u32 val)
{ {
@ -233,36 +235,38 @@ void ti_hdmi_4xxx_pll_disable(struct hdmi_ip_data *ip_data)
hdmi_set_pll_pwr(ip_data, HDMI_PLLPWRCMD_ALLOFF); hdmi_set_pll_pwr(ip_data, HDMI_PLLPWRCMD_ALLOFF);
} }
static int hdmi_check_hpd_state(struct hdmi_ip_data *ip_data) static irqreturn_t hdmi_irq_handler(int irq, void *data)
{
bool hpd;
int r;
mutex_lock(&ip_data->lock);
hpd = gpio_get_value(ip_data->hpd_gpio);
if (hpd)
r = hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_TXON);
else
r = hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_LDOON);
if (r) {
DSSERR("Failed to %s PHY TX power\n",
hpd ? "enable" : "disable");
goto err;
}
err:
mutex_unlock(&ip_data->lock);
return r;
}
static irqreturn_t hpd_irq_handler(int irq, void *data)
{ {
struct hdmi_ip_data *ip_data = data; struct hdmi_ip_data *ip_data = data;
void __iomem *wp_base = hdmi_wp_base(ip_data);
u32 irqstatus;
hdmi_check_hpd_state(ip_data); irqstatus = hdmi_read_reg(wp_base, HDMI_WP_IRQSTATUS);
hdmi_write_reg(wp_base, HDMI_WP_IRQSTATUS, irqstatus);
/* flush posted write */
hdmi_read_reg(wp_base, HDMI_WP_IRQSTATUS);
if ((irqstatus & HDMI_IRQ_LINK_CONNECT) &&
irqstatus & HDMI_IRQ_LINK_DISCONNECT) {
/*
* If we get both connect and disconnect interrupts at the same
* time, turn off the PHY, clear interrupts, and restart, which
* raises connect interrupt if a cable is connected, or nothing
* if cable is not connected.
*/
hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_OFF);
hdmi_write_reg(wp_base, HDMI_WP_IRQSTATUS,
HDMI_IRQ_LINK_CONNECT | HDMI_IRQ_LINK_DISCONNECT);
/* flush posted write */
hdmi_read_reg(wp_base, HDMI_WP_IRQSTATUS);
hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_LDOON);
} else if (irqstatus & HDMI_IRQ_LINK_CONNECT) {
hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_TXON);
} else if (irqstatus & HDMI_IRQ_LINK_DISCONNECT) {
hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_LDOON);
}
return IRQ_HANDLED; return IRQ_HANDLED;
} }
@ -272,6 +276,12 @@ int ti_hdmi_4xxx_phy_enable(struct hdmi_ip_data *ip_data)
u16 r = 0; u16 r = 0;
void __iomem *phy_base = hdmi_phy_base(ip_data); void __iomem *phy_base = hdmi_phy_base(ip_data);
hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_IRQENABLE_CLR,
0xffffffff);
hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_IRQSTATUS,
HDMI_IRQ_LINK_CONNECT | HDMI_IRQ_LINK_DISCONNECT);
r = hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_LDOON); r = hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_LDOON);
if (r) if (r)
return r; return r;
@ -297,29 +307,23 @@ int ti_hdmi_4xxx_phy_enable(struct hdmi_ip_data *ip_data)
/* Write to phy address 3 to change the polarity control */ /* Write to phy address 3 to change the polarity control */
REG_FLD_MOD(phy_base, HDMI_TXPHY_PAD_CFG_CTRL, 0x1, 27, 27); REG_FLD_MOD(phy_base, HDMI_TXPHY_PAD_CFG_CTRL, 0x1, 27, 27);
r = request_threaded_irq(gpio_to_irq(ip_data->hpd_gpio), r = request_threaded_irq(ip_data->irq, NULL, hdmi_irq_handler,
NULL, hpd_irq_handler, IRQF_ONESHOT, "OMAP HDMI", ip_data);
IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING |
IRQF_ONESHOT, "hpd", ip_data);
if (r) { if (r) {
DSSERR("HPD IRQ request failed\n"); DSSERR("HDMI IRQ request failed\n");
hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_OFF); hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_OFF);
return r; return r;
} }
r = hdmi_check_hpd_state(ip_data); hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_IRQENABLE_SET,
if (r) { HDMI_IRQ_LINK_CONNECT | HDMI_IRQ_LINK_DISCONNECT);
free_irq(gpio_to_irq(ip_data->hpd_gpio), ip_data);
hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_OFF);
return r;
}
return 0; return 0;
} }
void ti_hdmi_4xxx_phy_disable(struct hdmi_ip_data *ip_data) void ti_hdmi_4xxx_phy_disable(struct hdmi_ip_data *ip_data)
{ {
free_irq(gpio_to_irq(ip_data->hpd_gpio), ip_data); free_irq(ip_data->irq, ip_data);
hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_OFF); hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_OFF);
} }
@ -476,11 +480,6 @@ int ti_hdmi_4xxx_read_edid(struct hdmi_ip_data *ip_data,
return l; return l;
} }
bool ti_hdmi_4xxx_detect(struct hdmi_ip_data *ip_data)
{
return gpio_get_value(ip_data->hpd_gpio);
}
static void hdmi_core_init(struct hdmi_core_video_config *video_cfg, static void hdmi_core_init(struct hdmi_core_video_config *video_cfg,
struct hdmi_core_infoframe_avi *avi_cfg, struct hdmi_core_infoframe_avi *avi_cfg,
struct hdmi_core_packet_enable_repeat *repeat_cfg) struct hdmi_core_packet_enable_repeat *repeat_cfg)

Просмотреть файл

@ -33,6 +33,7 @@
#define HDMI_WP_IRQSTATUS 0x28 #define HDMI_WP_IRQSTATUS 0x28
#define HDMI_WP_PWR_CTRL 0x40 #define HDMI_WP_PWR_CTRL 0x40
#define HDMI_WP_IRQENABLE_SET 0x2C #define HDMI_WP_IRQENABLE_SET 0x2C
#define HDMI_WP_IRQENABLE_CLR 0x30
#define HDMI_WP_VIDEO_CFG 0x50 #define HDMI_WP_VIDEO_CFG 0x50
#define HDMI_WP_VIDEO_SIZE 0x60 #define HDMI_WP_VIDEO_SIZE 0x60
#define HDMI_WP_VIDEO_TIMING_H 0x68 #define HDMI_WP_VIDEO_TIMING_H 0x68

Просмотреть файл

@ -304,7 +304,7 @@ static struct {
enum omap_dss_venc_type type; enum omap_dss_venc_type type;
bool invert_polarity; bool invert_polarity;
struct omap_dss_output output; struct omap_dss_device output;
} venc; } venc;
static inline void venc_write_reg(int idx, u32 val) static inline void venc_write_reg(int idx, u32 val)
@ -429,7 +429,7 @@ static const struct venc_config *venc_timings_to_config(
static int venc_power_on(struct omap_dss_device *dssdev) static int venc_power_on(struct omap_dss_device *dssdev)
{ {
struct omap_overlay_manager *mgr = dssdev->output->manager; struct omap_overlay_manager *mgr = venc.output.manager;
u32 l; u32 l;
int r; int r;
@ -480,7 +480,7 @@ err0:
static void venc_power_off(struct omap_dss_device *dssdev) static void venc_power_off(struct omap_dss_device *dssdev)
{ {
struct omap_overlay_manager *mgr = dssdev->output->manager; struct omap_overlay_manager *mgr = venc.output.manager;
venc_write_reg(VENC_OUTPUT_CONTROL, 0); venc_write_reg(VENC_OUTPUT_CONTROL, 0);
dss_set_dac_pwrdn_bgz(0); dss_set_dac_pwrdn_bgz(0);
@ -492,15 +492,9 @@ static void venc_power_off(struct omap_dss_device *dssdev)
venc_runtime_put(); venc_runtime_put();
} }
unsigned long venc_get_pixel_clock(void)
{
/* VENC Pixel Clock in Mhz */
return 13500000;
}
int omapdss_venc_display_enable(struct omap_dss_device *dssdev) int omapdss_venc_display_enable(struct omap_dss_device *dssdev)
{ {
struct omap_dss_output *out = dssdev->output; struct omap_dss_device *out = &venc.output;
int r; int r;
DSSDBG("venc_display_enable\n"); DSSDBG("venc_display_enable\n");
@ -513,23 +507,15 @@ int omapdss_venc_display_enable(struct omap_dss_device *dssdev)
goto err0; goto err0;
} }
r = omap_dss_start_device(dssdev);
if (r) {
DSSERR("failed to start device\n");
goto err0;
}
r = venc_power_on(dssdev); r = venc_power_on(dssdev);
if (r) if (r)
goto err1; goto err0;
venc.wss_data = 0; venc.wss_data = 0;
mutex_unlock(&venc.venc_lock); mutex_unlock(&venc.venc_lock);
return 0; return 0;
err1:
omap_dss_stop_device(dssdev);
err0: err0:
mutex_unlock(&venc.venc_lock); mutex_unlock(&venc.venc_lock);
return r; return r;
@ -543,8 +529,6 @@ void omapdss_venc_display_disable(struct omap_dss_device *dssdev)
venc_power_off(dssdev); venc_power_off(dssdev);
omap_dss_stop_device(dssdev);
mutex_unlock(&venc.venc_lock); mutex_unlock(&venc.venc_lock);
} }
@ -561,6 +545,8 @@ void omapdss_venc_set_timings(struct omap_dss_device *dssdev,
venc.timings = *timings; venc.timings = *timings;
dispc_set_tv_pclk(13500000);
mutex_unlock(&venc.venc_lock); mutex_unlock(&venc.venc_lock);
} }
@ -633,23 +619,22 @@ void omapdss_venc_invert_vid_out_polarity(struct omap_dss_device *dssdev,
mutex_unlock(&venc.venc_lock); mutex_unlock(&venc.venc_lock);
} }
static int venc_init_display(struct omap_dss_device *dssdev) static int venc_init_regulator(void)
{ {
DSSDBG("init_display\n"); struct regulator *vdda_dac;
if (venc.vdda_dac_reg == NULL) { if (venc.vdda_dac_reg != NULL)
struct regulator *vdda_dac; return 0;
vdda_dac = regulator_get(&venc.pdev->dev, "vdda_dac"); vdda_dac = devm_regulator_get(&venc.pdev->dev, "vdda_dac");
if (IS_ERR(vdda_dac)) { if (IS_ERR(vdda_dac)) {
DSSERR("can't get VDDA_DAC regulator\n"); DSSERR("can't get VDDA_DAC regulator\n");
return PTR_ERR(vdda_dac); return PTR_ERR(vdda_dac);
}
venc.vdda_dac_reg = vdda_dac;
} }
venc.vdda_dac_reg = vdda_dac;
return 0; return 0;
} }
@ -765,19 +750,16 @@ static int venc_probe_pdata(struct platform_device *vencdev)
if (!plat_dssdev) if (!plat_dssdev)
return 0; return 0;
r = venc_init_regulator();
if (r)
return r;
dssdev = dss_alloc_and_init_device(&vencdev->dev); dssdev = dss_alloc_and_init_device(&vencdev->dev);
if (!dssdev) if (!dssdev)
return -ENOMEM; return -ENOMEM;
dss_copy_device_pdata(dssdev, plat_dssdev); dss_copy_device_pdata(dssdev, plat_dssdev);
r = venc_init_display(dssdev);
if (r) {
DSSERR("device %s init failed: %d\n", dssdev->name, r);
dss_put_device(dssdev);
return r;
}
r = omapdss_output_set_device(&venc.output, dssdev); r = omapdss_output_set_device(&venc.output, dssdev);
if (r) { if (r) {
DSSERR("failed to connect output to new device: %s\n", DSSERR("failed to connect output to new device: %s\n",
@ -799,20 +781,21 @@ static int venc_probe_pdata(struct platform_device *vencdev)
static void venc_init_output(struct platform_device *pdev) static void venc_init_output(struct platform_device *pdev)
{ {
struct omap_dss_output *out = &venc.output; struct omap_dss_device *out = &venc.output;
out->pdev = pdev; out->dev = &pdev->dev;
out->id = OMAP_DSS_OUTPUT_VENC; out->id = OMAP_DSS_OUTPUT_VENC;
out->type = OMAP_DISPLAY_TYPE_VENC; out->output_type = OMAP_DISPLAY_TYPE_VENC;
out->name = "venc.0"; out->name = "venc.0";
out->dispc_channel = OMAP_DSS_CHANNEL_DIGIT; out->dispc_channel = OMAP_DSS_CHANNEL_DIGIT;
out->owner = THIS_MODULE;
dss_register_output(out); dss_register_output(out);
} }
static void __exit venc_uninit_output(struct platform_device *pdev) static void __exit venc_uninit_output(struct platform_device *pdev)
{ {
struct omap_dss_output *out = &venc.output; struct omap_dss_device *out = &venc.output;
dss_unregister_output(out); dss_unregister_output(out);
} }
@ -866,16 +849,17 @@ static int omap_venchw_probe(struct platform_device *pdev)
venc_init_output(pdev); venc_init_output(pdev);
r = venc_probe_pdata(pdev); if (pdev->dev.platform_data) {
if (r) { r = venc_probe_pdata(pdev);
venc_panel_exit(); if (r)
venc_uninit_output(pdev); goto err_probe;
pm_runtime_disable(&pdev->dev);
return r;
} }
return 0; return 0;
err_probe:
venc_panel_exit();
venc_uninit_output(pdev);
err_panel_init: err_panel_init:
err_runtime_get: err_runtime_get:
pm_runtime_disable(&pdev->dev); pm_runtime_disable(&pdev->dev);
@ -886,11 +870,6 @@ static int __exit omap_venchw_remove(struct platform_device *pdev)
{ {
dss_unregister_child_devices(&pdev->dev); dss_unregister_child_devices(&pdev->dev);
if (venc.vdda_dac_reg != NULL) {
regulator_put(venc.vdda_dac_reg);
venc.vdda_dac_reg = NULL;
}
venc_panel_exit(); venc_panel_exit();
venc_uninit_output(pdev); venc_uninit_output(pdev);

Просмотреть файл

@ -107,19 +107,19 @@ static int venc_panel_probe(struct omap_dss_device *dssdev)
dssdev->panel.timings = default_timings; dssdev->panel.timings = default_timings;
return device_create_file(&dssdev->dev, &dev_attr_output_type); return device_create_file(dssdev->dev, &dev_attr_output_type);
} }
static void venc_panel_remove(struct omap_dss_device *dssdev) static void venc_panel_remove(struct omap_dss_device *dssdev)
{ {
device_remove_file(&dssdev->dev, &dev_attr_output_type); device_remove_file(dssdev->dev, &dev_attr_output_type);
} }
static int venc_panel_enable(struct omap_dss_device *dssdev) static int venc_panel_enable(struct omap_dss_device *dssdev)
{ {
int r; int r;
dev_dbg(&dssdev->dev, "venc_panel_enable\n"); dev_dbg(dssdev->dev, "venc_panel_enable\n");
mutex_lock(&venc_panel.lock); mutex_lock(&venc_panel.lock);
@ -150,7 +150,7 @@ err:
static void venc_panel_disable(struct omap_dss_device *dssdev) static void venc_panel_disable(struct omap_dss_device *dssdev)
{ {
dev_dbg(&dssdev->dev, "venc_panel_disable\n"); dev_dbg(dssdev->dev, "venc_panel_disable\n");
mutex_lock(&venc_panel.lock); mutex_lock(&venc_panel.lock);
@ -167,7 +167,7 @@ end:
static void venc_panel_set_timings(struct omap_dss_device *dssdev, static void venc_panel_set_timings(struct omap_dss_device *dssdev,
struct omap_video_timings *timings) struct omap_video_timings *timings)
{ {
dev_dbg(&dssdev->dev, "venc_panel_set_timings\n"); dev_dbg(dssdev->dev, "venc_panel_set_timings\n");
mutex_lock(&venc_panel.lock); mutex_lock(&venc_panel.lock);
@ -180,21 +180,21 @@ static void venc_panel_set_timings(struct omap_dss_device *dssdev,
static int venc_panel_check_timings(struct omap_dss_device *dssdev, static int venc_panel_check_timings(struct omap_dss_device *dssdev,
struct omap_video_timings *timings) struct omap_video_timings *timings)
{ {
dev_dbg(&dssdev->dev, "venc_panel_check_timings\n"); dev_dbg(dssdev->dev, "venc_panel_check_timings\n");
return omapdss_venc_check_timings(dssdev, timings); return omapdss_venc_check_timings(dssdev, timings);
} }
static u32 venc_panel_get_wss(struct omap_dss_device *dssdev) static u32 venc_panel_get_wss(struct omap_dss_device *dssdev)
{ {
dev_dbg(&dssdev->dev, "venc_panel_get_wss\n"); dev_dbg(dssdev->dev, "venc_panel_get_wss\n");
return omapdss_venc_get_wss(dssdev); return omapdss_venc_get_wss(dssdev);
} }
static int venc_panel_set_wss(struct omap_dss_device *dssdev, u32 wss) static int venc_panel_set_wss(struct omap_dss_device *dssdev, u32 wss)
{ {
dev_dbg(&dssdev->dev, "venc_panel_set_wss\n"); dev_dbg(dssdev->dev, "venc_panel_set_wss\n");
return omapdss_venc_set_wss(dssdev, wss); return omapdss_venc_set_wss(dssdev, wss);
} }

Просмотреть файл

@ -770,12 +770,17 @@ int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg)
case OMAPFB_WAITFORVSYNC: case OMAPFB_WAITFORVSYNC:
DBG("ioctl WAITFORVSYNC\n"); DBG("ioctl WAITFORVSYNC\n");
if (!display || !display->output || !display->output->manager) {
if (!display) {
r = -EINVAL; r = -EINVAL;
break; break;
} }
mgr = display->output->manager; mgr = omapdss_find_mgr_from_display(display);
if (!mgr) {
r = -EINVAL;
break;
}
r = mgr->wait_for_vsync(mgr); r = mgr->wait_for_vsync(mgr);
break; break;

Просмотреть файл

@ -1853,6 +1853,8 @@ static void omapfb_free_resources(struct omapfb2_device *fbdev)
if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED)
dssdev->driver->disable(dssdev); dssdev->driver->disable(dssdev);
dssdev->driver->disconnect(dssdev);
omap_dss_put_device(dssdev); omap_dss_put_device(dssdev);
} }
@ -2363,27 +2365,26 @@ static int omapfb_init_connections(struct omapfb2_device *fbdev,
int i, r; int i, r;
struct omap_overlay_manager *mgr; struct omap_overlay_manager *mgr;
if (!def_dssdev->output) { r = def_dssdev->driver->connect(def_dssdev);
dev_err(fbdev->dev, "no output for the default display\n"); if (r) {
return -EINVAL; dev_err(fbdev->dev, "failed to connect default display\n");
return r;
} }
for (i = 0; i < fbdev->num_displays; ++i) { for (i = 0; i < fbdev->num_displays; ++i) {
struct omap_dss_device *dssdev = fbdev->displays[i].dssdev; struct omap_dss_device *dssdev = fbdev->displays[i].dssdev;
struct omap_dss_output *out = dssdev->output;
mgr = omap_dss_get_overlay_manager(out->dispc_channel); if (dssdev == def_dssdev)
if (!mgr || !out)
continue; continue;
if (mgr->output) /*
mgr->unset_output(mgr); * We don't care if the connect succeeds or not. We just want to
* connect as many displays as possible.
mgr->set_output(mgr, out); */
dssdev->driver->connect(dssdev);
} }
mgr = def_dssdev->output->manager; mgr = omapdss_find_mgr_from_display(def_dssdev);
if (!mgr) { if (!mgr) {
dev_err(fbdev->dev, "no ovl manager for the default display\n"); dev_err(fbdev->dev, "no ovl manager for the default display\n");
@ -2502,7 +2503,7 @@ static int omapfb_probe(struct platform_device *pdev)
if (def_display == NULL) { if (def_display == NULL) {
dev_err(fbdev->dev, "failed to find default display\n"); dev_err(fbdev->dev, "failed to find default display\n");
r = -EINVAL; r = -EPROBE_DEFER;
goto cleanup; goto cleanup;
} }

Просмотреть файл

@ -23,6 +23,8 @@
#include <linux/device.h> #include <linux/device.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <video/videomode.h>
#define DISPC_IRQ_FRAMEDONE (1 << 0) #define DISPC_IRQ_FRAMEDONE (1 << 0)
#define DISPC_IRQ_VSYNC (1 << 1) #define DISPC_IRQ_VSYNC (1 << 1)
#define DISPC_IRQ_EVSYNC_EVEN (1 << 2) #define DISPC_IRQ_EVSYNC_EVEN (1 << 2)
@ -365,6 +367,7 @@ struct omap_dss_board_info {
int num_devices; int num_devices;
struct omap_dss_device **devices; struct omap_dss_device **devices;
struct omap_dss_device *default_device; struct omap_dss_device *default_device;
const char *default_display_name;
int (*dsi_enable_pads)(int dsi_id, unsigned lane_mask); int (*dsi_enable_pads)(int dsi_id, unsigned lane_mask);
void (*dsi_disable_pads)(int dsi_id, unsigned lane_mask); void (*dsi_disable_pads)(int dsi_id, unsigned lane_mask);
int (*set_min_bus_tput)(struct device *dev, unsigned long r); int (*set_min_bus_tput)(struct device *dev, unsigned long r);
@ -512,7 +515,7 @@ struct omap_overlay_manager {
enum omap_dss_output_id supported_outputs; enum omap_dss_output_id supported_outputs;
/* dynamic fields */ /* dynamic fields */
struct omap_dss_output *output; struct omap_dss_device *output;
/* /*
* The following functions do not block: * The following functions do not block:
@ -526,7 +529,7 @@ struct omap_overlay_manager {
*/ */
int (*set_output)(struct omap_overlay_manager *mgr, int (*set_output)(struct omap_overlay_manager *mgr,
struct omap_dss_output *output); struct omap_dss_device *output);
int (*unset_output)(struct omap_overlay_manager *mgr); int (*unset_output)(struct omap_overlay_manager *mgr);
int (*set_manager_info)(struct omap_overlay_manager *mgr, int (*set_manager_info)(struct omap_overlay_manager *mgr,
@ -569,33 +572,22 @@ struct omap_dss_writeback_info {
u8 pre_mult_alpha; u8 pre_mult_alpha;
}; };
struct omap_dss_output {
struct list_head list;
const char *name;
/* display type supported by the output */
enum omap_display_type type;
/* DISPC channel for this output */
enum omap_channel dispc_channel;
/* output instance */
enum omap_dss_output_id id;
/* output's platform device pointer */
struct platform_device *pdev;
/* dynamic fields */
struct omap_overlay_manager *manager;
struct omap_dss_device *device;
};
struct omap_dss_device { struct omap_dss_device {
struct device dev; /* old device, to be removed */
struct device old_dev;
/* new device, pointer to panel device */
struct device *dev;
struct module *owner;
struct list_head panel_list;
/* alias in the form of "display%d" */
char alias[16];
enum omap_display_type type; enum omap_display_type type;
enum omap_display_type output_type;
/* obsolete, to be removed */ /* obsolete, to be removed */
enum omap_channel channel; enum omap_channel channel;
@ -616,9 +608,6 @@ struct omap_dss_device {
struct { struct {
int module; int module;
bool ext_te;
u8 ext_te_gpio;
} dsi; } dsi;
struct { struct {
@ -639,10 +628,6 @@ struct omap_dss_device {
struct rfbi_timings rfbi_timings; struct rfbi_timings rfbi_timings;
} ctrl; } ctrl;
int reset_gpio;
int max_backlight_level;
const char *name; const char *name;
/* used to match device to driver */ /* used to match device to driver */
@ -657,17 +642,26 @@ struct omap_dss_device {
enum omap_display_caps caps; enum omap_display_caps caps;
struct omap_dss_output *output; struct omap_dss_device *output;
enum omap_dss_display_state state; enum omap_dss_display_state state;
enum omap_dss_audio_state audio_state; enum omap_dss_audio_state audio_state;
/* platform specific */ /* OMAP DSS output specific fields */
int (*platform_enable)(struct omap_dss_device *dssdev);
void (*platform_disable)(struct omap_dss_device *dssdev); struct list_head list;
int (*set_backlight)(struct omap_dss_device *dssdev, int level);
int (*get_backlight)(struct omap_dss_device *dssdev); /* DISPC channel for this output */
enum omap_channel dispc_channel;
/* output instance */
enum omap_dss_output_id id;
/* dynamic fields */
struct omap_overlay_manager *manager;
struct omap_dss_device *device;
}; };
struct omap_dss_hdmi_data struct omap_dss_hdmi_data
@ -688,6 +682,9 @@ struct omap_dss_driver {
int (*probe)(struct omap_dss_device *); int (*probe)(struct omap_dss_device *);
void (*remove)(struct omap_dss_device *); void (*remove)(struct omap_dss_device *);
int (*connect)(struct omap_dss_device *dssdev);
void (*disconnect)(struct omap_dss_device *dssdev);
int (*enable)(struct omap_dss_device *display); int (*enable)(struct omap_dss_device *display);
void (*disable)(struct omap_dss_device *display); void (*disable)(struct omap_dss_device *display);
int (*run_test)(struct omap_dss_device *display, int test); int (*run_test)(struct omap_dss_device *display, int test);
@ -753,7 +750,10 @@ bool omapdss_is_initialized(void);
int omap_dss_register_driver(struct omap_dss_driver *); int omap_dss_register_driver(struct omap_dss_driver *);
void omap_dss_unregister_driver(struct omap_dss_driver *); void omap_dss_unregister_driver(struct omap_dss_driver *);
void omap_dss_get_device(struct omap_dss_device *dssdev); int omapdss_register_display(struct omap_dss_device *dssdev);
void omapdss_unregister_display(struct omap_dss_device *dssdev);
struct omap_dss_device *omap_dss_get_device(struct omap_dss_device *dssdev);
void omap_dss_put_device(struct omap_dss_device *dssdev); void omap_dss_put_device(struct omap_dss_device *dssdev);
#define for_each_dss_dev(d) while ((d = omap_dss_get_next_device(d)) != NULL) #define for_each_dss_dev(d) while ((d = omap_dss_get_next_device(d)) != NULL)
struct omap_dss_device *omap_dss_get_next_device(struct omap_dss_device *from); struct omap_dss_device *omap_dss_get_next_device(struct omap_dss_device *from);
@ -761,8 +761,10 @@ struct omap_dss_device *omap_dss_find_device(void *data,
int (*match)(struct omap_dss_device *dssdev, void *data)); int (*match)(struct omap_dss_device *dssdev, void *data));
const char *omapdss_get_default_display_name(void); const char *omapdss_get_default_display_name(void);
int omap_dss_start_device(struct omap_dss_device *dssdev); void videomode_to_omap_video_timings(const struct videomode *vm,
void omap_dss_stop_device(struct omap_dss_device *dssdev); struct omap_video_timings *ovt);
void omap_video_timings_to_videomode(const struct omap_video_timings *ovt,
struct videomode *vm);
int dss_feat_get_num_mgrs(void); int dss_feat_get_num_mgrs(void);
int dss_feat_get_num_ovls(void); int dss_feat_get_num_ovls(void);
@ -778,10 +780,15 @@ struct omap_overlay_manager *omap_dss_get_overlay_manager(int num);
int omap_dss_get_num_overlays(void); int omap_dss_get_num_overlays(void);
struct omap_overlay *omap_dss_get_overlay(int num); struct omap_overlay *omap_dss_get_overlay(int num);
struct omap_dss_output *omap_dss_get_output(enum omap_dss_output_id id); struct omap_dss_device *omap_dss_get_output(enum omap_dss_output_id id);
int omapdss_output_set_device(struct omap_dss_output *out, struct omap_dss_device *omap_dss_find_output(const char *name);
struct omap_dss_device *omap_dss_find_output_by_node(struct device_node *node);
int omapdss_output_set_device(struct omap_dss_device *out,
struct omap_dss_device *dssdev); struct omap_dss_device *dssdev);
int omapdss_output_unset_device(struct omap_dss_output *out); int omapdss_output_unset_device(struct omap_dss_device *out);
struct omap_dss_device *omapdss_find_output_from_display(struct omap_dss_device *dssdev);
struct omap_overlay_manager *omapdss_find_mgr_from_display(struct omap_dss_device *dssdev);
void omapdss_default_get_resolution(struct omap_dss_device *dssdev, void omapdss_default_get_resolution(struct omap_dss_device *dssdev,
u16 *xres, u16 *yres); u16 *xres, u16 *yres);
@ -832,7 +839,7 @@ int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi,
bool mem_to_mem); bool mem_to_mem);
#define to_dss_driver(x) container_of((x), struct omap_dss_driver, driver) #define to_dss_driver(x) container_of((x), struct omap_dss_driver, driver)
#define to_dss_device(x) container_of((x), struct omap_dss_device, dev) #define to_dss_device(x) container_of((x), struct omap_dss_device, old_dev)
void omapdss_dsi_vc_enable_hs(struct omap_dss_device *dssdev, int channel, void omapdss_dsi_vc_enable_hs(struct omap_dss_device *dssdev, int channel,
bool enable); bool enable);
@ -883,6 +890,11 @@ int omapdss_compat_init(void);
void omapdss_compat_uninit(void); void omapdss_compat_uninit(void);
struct dss_mgr_ops { struct dss_mgr_ops {
int (*connect)(struct omap_overlay_manager *mgr,
struct omap_dss_device *dst);
void (*disconnect)(struct omap_overlay_manager *mgr,
struct omap_dss_device *dst);
void (*start_update)(struct omap_overlay_manager *mgr); void (*start_update)(struct omap_overlay_manager *mgr);
int (*enable)(struct omap_overlay_manager *mgr); int (*enable)(struct omap_overlay_manager *mgr);
void (*disable)(struct omap_overlay_manager *mgr); void (*disable)(struct omap_overlay_manager *mgr);
@ -899,6 +911,10 @@ struct dss_mgr_ops {
int dss_install_mgr_ops(const struct dss_mgr_ops *mgr_ops); int dss_install_mgr_ops(const struct dss_mgr_ops *mgr_ops);
void dss_uninstall_mgr_ops(void); void dss_uninstall_mgr_ops(void);
int dss_mgr_connect(struct omap_overlay_manager *mgr,
struct omap_dss_device *dst);
void dss_mgr_disconnect(struct omap_overlay_manager *mgr,
struct omap_dss_device *dst);
void dss_mgr_set_timings(struct omap_overlay_manager *mgr, void dss_mgr_set_timings(struct omap_overlay_manager *mgr,
const struct omap_video_timings *timings); const struct omap_video_timings *timings);
void dss_mgr_set_lcd_config(struct omap_overlay_manager *mgr, void dss_mgr_set_lcd_config(struct omap_overlay_manager *mgr,
@ -910,4 +926,15 @@ int dss_mgr_register_framedone_handler(struct omap_overlay_manager *mgr,
void (*handler)(void *), void *data); void (*handler)(void *), void *data);
void dss_mgr_unregister_framedone_handler(struct omap_overlay_manager *mgr, void dss_mgr_unregister_framedone_handler(struct omap_overlay_manager *mgr,
void (*handler)(void *), void *data); void (*handler)(void *), void *data);
static inline bool omapdss_device_is_connected(struct omap_dss_device *dssdev)
{
return dssdev->output;
}
static inline bool omapdss_device_is_enabled(struct omap_dss_device *dssdev)
{
return dssdev->state == OMAP_DSS_DISPLAY_ACTIVE;
}
#endif #endif