Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8e980455 authored by Jean-Christophe PLAGNIOL-VILLARD's avatar Jean-Christophe PLAGNIOL-VILLARD
Browse files

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
parents a66e62ae 595470a7
Loading
Loading
Loading
Loading
+39 −7
Original line number Diff line number Diff line
@@ -40,7 +40,7 @@ struct omap_crtc {
	 * mgr->id.)  Eventually this will be replaced w/ something
	 * more common-panel-framework-y
	 */
	struct omap_overlay_manager mgr;
	struct omap_overlay_manager *mgr;

	struct omap_video_timings timings;
	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
 */

/* ovl-mgr-id -> crtc */
static struct omap_crtc *omap_crtcs[8];

/* 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)
{
}
@@ -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,
		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);
	omap_crtc->timings = *timings;
	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,
		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);
	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 = {
		.connect = omap_crtc_connect,
		.disconnect = omap_crtc_disconnect,
		.start_update = omap_crtc_start_update,
		.enable = omap_crtc_enable,
		.disable = omap_crtc_disable,
@@ -569,7 +596,7 @@ static void omap_crtc_pre_apply(struct omap_drm_apply *apply)
	} else {
		if (encoder) {
			omap_encoder_set_enabled(encoder, false);
			omap_encoder_update(encoder, &omap_crtc->mgr,
			omap_encoder_update(encoder, omap_crtc->mgr,
					&omap_crtc->timings);
			omap_encoder_set_enabled(encoder, true);
			omap_crtc->full_update = false;
@@ -595,6 +622,11 @@ static const char *channel_names[] = {
		[OMAP_DSS_CHANNEL_LCD2] = "lcd2",
};

void omap_crtc_pre_init(void)
{
	dss_install_mgr_ops(&mgr_ops);
}

/* initialize crtc */
struct drm_crtc *omap_crtc_init(struct drm_device *dev,
		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);

	/* temporary: */
	omap_crtc->mgr.id = channel;

	dss_install_mgr_ops(&mgr_ops);
	omap_crtc->mgr = omap_dss_get_overlay_manager(channel);

	/* TODO: fix hard-coded setup.. add properties! */
	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_crtcs[channel] = omap_crtc;

	return crtc;

fail:
+19 −2
Original line number Diff line number Diff line
@@ -97,6 +97,9 @@ static int omap_modeset_init(struct drm_device *dev)
	int num_mgrs = dss_feat_get_num_mgrs();
	int num_crtcs;
	int i, id = 0;
	int r;

	omap_crtc_pre_init();

	drm_mode_config_init(dev);

@@ -116,6 +119,7 @@ static int omap_modeset_init(struct drm_device *dev)
		struct drm_connector *connector;
		struct drm_encoder *encoder;
		enum omap_channel channel;
		struct omap_overlay_manager *mgr;

		if (!dssdev->driver) {
			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;
		}

		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);

		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
		 * 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
		 * 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 omap_dss_device *dssdev =
					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: */
		encoder->possible_crtcs = 0;
@@ -259,9 +274,11 @@ static int omap_modeset_init(struct drm_device *dev)
			supported_outputs =
				dss_feat_get_supported_outputs(crtc_channel);

			if (supported_outputs & dssdev->output->id)
			if (supported_outputs & output->id)
				encoder->possible_crtcs |= (1 << id);
		}

		omap_dss_put_device(output);
	}

	DBG("registered %d planes, %d crtcs, %d encoders and %d connectors\n",
+1 −0
Original line number Diff line number Diff line
@@ -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);
int omap_crtc_apply(struct drm_crtc *crtc,
		struct omap_drm_apply *apply);
void omap_crtc_pre_init(void);
struct drm_crtc *omap_crtc_init(struct drm_device *dev,
		struct drm_plane *plane, enum omap_channel channel, int id);

+8 −8
Original line number Diff line number Diff line
@@ -510,7 +510,7 @@ static int acx_panel_probe(struct omap_dss_device *dssdev)
	int max_brightness, brightness;
	struct backlight_properties props;

	dev_dbg(&dssdev->dev, "%s\n", __func__);
	dev_dbg(dssdev->dev, "%s\n", __func__);

	if (!panel_data)
		return -EINVAL;
@@ -519,7 +519,7 @@ static int acx_panel_probe(struct omap_dss_device *dssdev)
	dssdev->panel.timings = acx_panel_timings;

	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");
		if (r)
			return r;
@@ -538,7 +538,7 @@ static int acx_panel_probe(struct omap_dss_device *dssdev)

	r = panel_detect(md);
	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))
			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;

	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);
	backlight_device_unregister(md->bl_dev);
	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);
	int r;

	dev_dbg(&dssdev->dev, "%s\n", __func__);
	dev_dbg(dssdev->dev, "%s\n", __func__);

	if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
		return 0;
@@ -667,7 +667,7 @@ static void acx_panel_power_off(struct omap_dss_device *dssdev)
	struct acx565akm_device *md = &acx_dev;
	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)
		return;
@@ -704,7 +704,7 @@ static int acx_panel_enable(struct omap_dss_device *dssdev)
{
	int r;

	dev_dbg(&dssdev->dev, "%s\n", __func__);
	dev_dbg(dssdev->dev, "%s\n", __func__);
	r = acx_panel_power_on(dssdev);

	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)
{
	dev_dbg(&dssdev->dev, "%s\n", __func__);
	dev_dbg(dssdev->dev, "%s\n", __func__);
	acx_panel_power_off(dssdev);
	dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
}
+13 −13
Original line number Diff line number Diff line
@@ -536,7 +536,7 @@ static int generic_dpi_panel_power_on(struct omap_dss_device *dssdev)
{
	int r, i;
	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;

	if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
@@ -567,7 +567,7 @@ static int generic_dpi_panel_power_on(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_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;
	int i;

@@ -593,7 +593,7 @@ static int generic_dpi_panel_probe(struct omap_dss_device *dssdev)
	struct panel_drv_data *drv_data = NULL;
	int i, r;

	dev_dbg(&dssdev->dev, "probe\n");
	dev_dbg(dssdev->dev, "probe\n");

	if (!panel_data || !panel_data->name)
		return -EINVAL;
@@ -609,7 +609,7 @@ static int generic_dpi_panel_probe(struct omap_dss_device *dssdev)
		return -EINVAL;

	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] ?
				GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW,
				"panel gpio");
@@ -619,7 +619,7 @@ static int generic_dpi_panel_probe(struct omap_dss_device *dssdev)

	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)
		return -ENOMEM;

@@ -628,21 +628,21 @@ static int generic_dpi_panel_probe(struct omap_dss_device *dssdev)

	mutex_init(&drv_data->lock);

	dev_set_drvdata(&dssdev->dev, drv_data);
	dev_set_drvdata(dssdev->dev, drv_data);

	return 0;
}

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)
{
	struct panel_drv_data *drv_data = dev_get_drvdata(&dssdev->dev);
	struct panel_drv_data *drv_data = dev_get_drvdata(dssdev->dev);
	int r;

	mutex_lock(&drv_data->lock);
@@ -660,7 +660,7 @@ static int generic_dpi_panel_enable(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);

@@ -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,
		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);

@@ -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,
		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);

@@ -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,
		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;

	mutex_lock(&drv_data->lock);
Loading