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

Commit e1474e7b authored by Dave Airlie's avatar Dave Airlie
Browse files

Merge branch 'drm-sti-next-atomic-2015-08-11' of...

Merge branch 'drm-sti-next-atomic-2015-08-11' of http://git.linaro.org/people/benjamin.gaignard/kernel into drm-next

This serie of patches fix minor bugs around how driver sub-components are
bind and planes z-ordering.
The main part is about atomic support: using more atomic helpers allow us
to simplify the code (~300 lines removed) and to ahve a better match between
drm concepts (planes and crtc) and hardware split.

[airlied: fixed up conflict in atomic code]

* 'drm-sti-next-atomic-2015-08-11' of http://git.linaro.org/people/benjamin.gaignard/kernel:
  drm/sti: atomic crtc/plane update
  drm/sti: rename files and functions
  drm/sti: code clean up
  drm/sti: fix dynamic z-ordering
  drm: sti: fix sub-components bind
parents 1ce4200d 29d1dc62
Loading
Loading
Loading
Loading
+35 −37
Original line number Diff line number Diff line
@@ -52,10 +52,9 @@ STMicroelectronics stih4xx platforms
    See ../reset/reset.txt for details.
  - reset-names: names of the resets listed in resets property in the same
    order.
  - ranges: to allow probing of subdevices

- sti-hdmi: hdmi output block
  must be a child of sti-tvout
  must be a child of sti-display-subsystem
  Required properties:
  - compatible: "st,stih<chip>-hdmi";
  - reg: Physical base address of the IP registers and length of memory mapped region.
@@ -72,7 +71,7 @@ STMicroelectronics stih4xx platforms

sti-hda:
  Required properties:
  must be a child of sti-tvout
  must be a child of sti-display-subsystem
  - compatible: "st,stih<chip>-hda"
  - reg: Physical base address of the IP registers and length of memory mapped region.
  - reg-names: names of the mapped memory regions listed in regs property in
@@ -85,7 +84,7 @@ sti-hda:

sti-dvo:
  Required properties:
  must be a child of sti-tvout
  must be a child of sti-display-subsystem
  - compatible: "st,stih<chip>-dvo"
  - reg: Physical base address of the IP registers and length of memory mapped region.
  - reg-names: names of the mapped memory regions listed in regs property in
@@ -195,7 +194,7 @@ Example:
			reg-names	= "tvout-reg", "hda-reg", "syscfg";
			reset-names     = "tvout";
			resets          = <&softreset STIH416_HDTVOUT_SOFTRESET>;
			ranges;
		};

		sti-hdmi@fe85c000 {
			compatible	= "st,stih416-hdmi";
@@ -227,7 +226,6 @@ Example:
			pinctrl-0	= <&pinctrl_dvo>;
			sti,panel	= <&panel_dvo>;
		};
		};

		sti-hqvdp@9c000000 {
				compatible	= "st,stih407-hqvdp";
+3 −4
Original line number Diff line number Diff line
sticompositor-y := \
	sti_layer.o \
	sti_mixer.o \
	sti_gdp.o \
	sti_vid.o \
	sti_cursor.o \
	sti_compositor.o \
	sti_drm_crtc.o \
	sti_drm_plane.o
	sti_crtc.o \
	sti_plane.o

stihdmi-y := sti_hdmi.o \
	sti_hdmi_tx3g0c55phy.o \
@@ -24,4 +23,4 @@ obj-$(CONFIG_DRM_STI) = \
	sticompositor.o \
	sti_hqvdp.o \
	stidvo.o \
	sti_drm_drv.o
	sti_drv.o
+68 −73
Original line number Diff line number Diff line
@@ -14,10 +14,12 @@
#include <drm/drmP.h>

#include "sti_compositor.h"
#include "sti_drm_crtc.h"
#include "sti_drm_drv.h"
#include "sti_drm_plane.h"
#include "sti_crtc.h"
#include "sti_cursor.h"
#include "sti_drv.h"
#include "sti_gdp.h"
#include "sti_plane.h"
#include "sti_vid.h"
#include "sti_vtg.h"

/*
@@ -31,7 +33,7 @@ struct sti_compositor_data stih407_compositor_data = {
			{STI_GPD_SUBDEV, (int)STI_GDP_1, 0x200},
			{STI_GPD_SUBDEV, (int)STI_GDP_2, 0x300},
			{STI_GPD_SUBDEV, (int)STI_GDP_3, 0x400},
			{STI_VID_SUBDEV, (int)STI_VID_0, 0x700},
			{STI_VID_SUBDEV, (int)STI_HQVDP_0, 0x700},
			{STI_MIXER_MAIN_SUBDEV, STI_MIXER_MAIN, 0xC00},
			{STI_MIXER_AUX_SUBDEV, STI_MIXER_AUX, 0xD00},
	},
@@ -53,14 +55,29 @@ struct sti_compositor_data stih416_compositor_data = {
	},
};

static int sti_compositor_init_subdev(struct sti_compositor *compo,
		struct sti_compositor_subdev_descriptor *desc,
		unsigned int array_size)
static int sti_compositor_bind(struct device *dev,
			       struct device *master,
			       void *data)
{
	unsigned int i, mixer_id = 0, layer_id = 0;
	struct sti_compositor *compo = dev_get_drvdata(dev);
	struct drm_device *drm_dev = data;
	unsigned int i, mixer_id = 0, vid_id = 0, crtc_id = 0;
	struct sti_private *dev_priv = drm_dev->dev_private;
	struct drm_plane *cursor = NULL;
	struct drm_plane *primary = NULL;
	struct sti_compositor_subdev_descriptor *desc = compo->data.subdev_desc;
	unsigned int array_size = compo->data.nb_subdev;

	dev_priv->compo = compo;

	/* Register mixer subdev and video subdev first */
	for (i = 0; i < array_size; i++) {
		switch (desc[i].type) {
		case STI_VID_SUBDEV:
			compo->vid[vid_id++] =
			    sti_vid_create(compo->dev, desc[i].id,
					   compo->regs + desc[i].offset);
			break;
		case STI_MIXER_MAIN_SUBDEV:
		case STI_MIXER_AUX_SUBDEV:
			compo->mixer[mixer_id++] =
@@ -68,83 +85,68 @@ static int sti_compositor_init_subdev(struct sti_compositor *compo,
					     compo->regs + desc[i].offset);
			break;
		case STI_GPD_SUBDEV:
		case STI_VID_SUBDEV:
		case STI_CURSOR_SUBDEV:
			compo->layer[layer_id++] =
			    sti_layer_create(compo->dev, desc[i].id,
					     compo->regs + desc[i].offset);
			/* Nothing to do, wait for the second round */
			break;
		default:
			DRM_ERROR("Unknow subdev compoment type\n");
			return 1;
		}

	}
	compo->nb_mixers = mixer_id;
	compo->nb_layers = layer_id;

	return 0;
	}

static int sti_compositor_bind(struct device *dev, struct device *master,
	void *data)
{
	struct sti_compositor *compo = dev_get_drvdata(dev);
	struct drm_device *drm_dev = data;
	unsigned int i, crtc = 0, plane = 0;
	struct sti_drm_private *dev_priv = drm_dev->dev_private;
	struct drm_plane *cursor = NULL;
	struct drm_plane *primary = NULL;

	dev_priv->compo = compo;

	for (i = 0; i < compo->nb_layers; i++) {
		if (compo->layer[i]) {
			enum sti_layer_desc desc = compo->layer[i]->desc;
			enum sti_layer_type type = desc & STI_LAYER_TYPE_MASK;
	/* Register the other subdevs, create crtc and planes */
	for (i = 0; i < array_size; i++) {
		enum drm_plane_type plane_type = DRM_PLANE_TYPE_OVERLAY;

			if (crtc < compo->nb_mixers)
		if (crtc_id < mixer_id)
			plane_type = DRM_PLANE_TYPE_PRIMARY;

			switch (type) {
			case STI_CUR:
				cursor = sti_drm_plane_init(drm_dev,
						compo->layer[i],
						1, DRM_PLANE_TYPE_CURSOR);
		switch (desc[i].type) {
		case STI_MIXER_MAIN_SUBDEV:
		case STI_MIXER_AUX_SUBDEV:
		case STI_VID_SUBDEV:
			/* Nothing to do, already done at the first round */
			break;
		case STI_CURSOR_SUBDEV:
			cursor = sti_cursor_create(drm_dev, compo->dev,
						   desc[i].id,
						   compo->regs + desc[i].offset,
						   1);
			if (!cursor) {
				DRM_ERROR("Can't create CURSOR plane\n");
				break;
			}
			break;
			case STI_GDP:
			case STI_VID:
				primary = sti_drm_plane_init(drm_dev,
						compo->layer[i],
						(1 << compo->nb_mixers) - 1,
		case STI_GPD_SUBDEV:
			primary = sti_gdp_create(drm_dev, compo->dev,
						 desc[i].id,
						 compo->regs + desc[i].offset,
						 (1 << mixer_id) - 1,
						 plane_type);
				plane++;
			if (!primary) {
				DRM_ERROR("Can't create GDP plane\n");
				break;
			case STI_BCK:
			case STI_VDP:
			}
			break;
		default:
			DRM_ERROR("Unknown subdev compoment type\n");
			return 1;
		}

		/* The first planes are reserved for primary planes*/
			if (crtc < compo->nb_mixers && primary) {
				sti_drm_crtc_init(drm_dev, compo->mixer[crtc],
		if (crtc_id < mixer_id && primary) {
			sti_crtc_init(drm_dev, compo->mixer[crtc_id],
				      primary, cursor);
				crtc++;
			crtc_id++;
			cursor = NULL;
			primary = NULL;
		}
	}
	}

	drm_vblank_init(drm_dev, crtc);
	drm_vblank_init(drm_dev, crtc_id);
	/* Allow usage of vblank without having to call drm_irq_install */
	drm_dev->irq_enabled = 1;

	DRM_DEBUG_DRIVER("Initialized %d DRM CRTC(s) and %d DRM plane(s)\n",
			 crtc, plane);
	DRM_DEBUG_DRIVER("DRM plane(s) for VID/VDP not created yet\n");

	return 0;
}

@@ -179,7 +181,6 @@ static int sti_compositor_probe(struct platform_device *pdev)
	struct device_node *vtg_np;
	struct sti_compositor *compo;
	struct resource *res;
	int err;

	compo = devm_kzalloc(dev, sizeof(*compo), GFP_KERNEL);
	if (!compo) {
@@ -187,7 +188,7 @@ static int sti_compositor_probe(struct platform_device *pdev)
		return -ENOMEM;
	}
	compo->dev = dev;
	compo->vtg_vblank_nb.notifier_call = sti_drm_crtc_vblank_cb;
	compo->vtg_vblank_nb.notifier_call = sti_crtc_vblank_cb;

	/* populate data structure depending on compatibility */
	BUG_ON(!of_match_node(compositor_of_match, np)->data);
@@ -251,12 +252,6 @@ static int sti_compositor_probe(struct platform_device *pdev)
	if (vtg_np)
		compo->vtg_aux = of_vtg_find(vtg_np);

	/* Initialize compositor subdevices */
	err = sti_compositor_init_subdev(compo, compo->data.subdev_desc,
					 compo->data.nb_subdev);
	if (err)
		return err;

	platform_set_drvdata(pdev, compo);

	return component_add(&pdev->dev, &sti_compositor_ops);
+4 −8
Original line number Diff line number Diff line
@@ -12,13 +12,13 @@
#include <linux/clk.h>
#include <linux/kernel.h>

#include "sti_layer.h"
#include "sti_mixer.h"
#include "sti_plane.h"

#define WAIT_NEXT_VSYNC_MS      50 /*ms*/

#define STI_MAX_LAYER 8
#define STI_MAX_MIXER 2
#define STI_MAX_VID   1

enum sti_compositor_subdev_type {
	STI_MIXER_MAIN_SUBDEV,
@@ -59,11 +59,9 @@ struct sti_compositor_data {
 * @rst_main: reset control of the main path
 * @rst_aux: reset control of the aux path
 * @mixer: array of mixers
 * @vid: array of vids
 * @vtg_main: vtg for main data path
 * @vtg_aux: vtg for auxillary data path
 * @layer: array of layers
 * @nb_mixers: number of mixers for this compositor
 * @nb_layers: number of layers (GDP,VID,...) for this compositor
 * @vtg_vblank_nb: callback for VTG VSYNC notification
 */
struct sti_compositor {
@@ -77,11 +75,9 @@ struct sti_compositor {
	struct reset_control *rst_main;
	struct reset_control *rst_aux;
	struct sti_mixer *mixer[STI_MAX_MIXER];
	struct sti_vid *vid[STI_MAX_VID];
	struct sti_vtg *vtg_main;
	struct sti_vtg *vtg_aux;
	struct sti_layer *layer[STI_MAX_LAYER];
	int nb_mixers;
	int nb_layers;
	struct notifier_block vtg_vblank_nb;
};

+135 −78
Original line number Diff line number Diff line
@@ -15,22 +15,20 @@
#include <drm/drm_plane_helper.h>

#include "sti_compositor.h"
#include "sti_drm_drv.h"
#include "sti_drm_crtc.h"
#include "sti_crtc.h"
#include "sti_drv.h"
#include "sti_vid.h"
#include "sti_vtg.h"

static void sti_drm_crtc_dpms(struct drm_crtc *crtc, int mode)
{
	DRM_DEBUG_KMS("\n");
}

static void sti_drm_crtc_prepare(struct drm_crtc *crtc)
static void sti_crtc_enable(struct drm_crtc *crtc)
{
	struct sti_mixer *mixer = to_sti_mixer(crtc);
	struct device *dev = mixer->dev;
	struct sti_compositor *compo = dev_get_drvdata(dev);

	mixer->enabled = true;
	DRM_DEBUG_DRIVER("\n");

	mixer->status = STI_MIXER_READY;

	/* Prepare and enable the compo IP clock */
	if (mixer->id == STI_MIXER_MAIN) {
@@ -41,36 +39,19 @@ static void sti_drm_crtc_prepare(struct drm_crtc *crtc)
			DRM_INFO("Failed to prepare/enable compo_aux clk\n");
	}

	sti_mixer_clear_all_layers(mixer);
	drm_crtc_vblank_on(crtc);
}

static void sti_drm_crtc_commit(struct drm_crtc *crtc)
static void sti_crtc_disabling(struct drm_crtc *crtc)
{
	struct sti_mixer *mixer = to_sti_mixer(crtc);
	struct device *dev = mixer->dev;
	struct sti_compositor *compo = dev_get_drvdata(dev);
	struct sti_layer *layer;

	if ((!mixer || !compo)) {
		DRM_ERROR("Can not find mixer or compositor)\n");
		return;
	}

	/* get GDP which is reserved to the CRTC FB */
	layer = to_sti_layer(crtc->primary);
	if (layer)
		sti_layer_commit(layer);
	else
		DRM_ERROR("Can not find CRTC dedicated plane (GDP0)\n");

	/* Enable layer on mixer */
	if (sti_mixer_set_layer_status(mixer, layer, true))
		DRM_ERROR("Can not enable layer at mixer\n");
	DRM_DEBUG_DRIVER("\n");

	drm_crtc_vblank_on(crtc);
	mixer->status = STI_MIXER_DISABLING;
}

static bool sti_drm_crtc_mode_fixup(struct drm_crtc *crtc,
static bool sti_crtc_mode_fixup(struct drm_crtc *crtc,
				const struct drm_display_mode *mode,
				struct drm_display_mode *adjusted_mode)
{
@@ -79,7 +60,7 @@ static bool sti_drm_crtc_mode_fixup(struct drm_crtc *crtc,
}

static int
sti_drm_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode)
sti_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode)
{
	struct sti_mixer *mixer = to_sti_mixer(crtc);
	struct device *dev = mixer->dev;
@@ -122,22 +103,19 @@ sti_drm_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode)

	res = sti_mixer_active_video_area(mixer, &crtc->mode);
	if (res) {
		DRM_ERROR("Can not set active video area\n");
		DRM_ERROR("Can't set active video area\n");
		return -EINVAL;
	}

	return res;
}

static void sti_drm_crtc_disable(struct drm_crtc *crtc)
static void sti_crtc_disable(struct drm_crtc *crtc)
{
	struct sti_mixer *mixer = to_sti_mixer(crtc);
	struct device *dev = mixer->dev;
	struct sti_compositor *compo = dev_get_drvdata(dev);

	if (!mixer->enabled)
		return;

	DRM_DEBUG_KMS("CRTC:%d (%s)\n", crtc->base.id, sti_mixer_to_str(mixer));

	/* Disable Background */
@@ -154,17 +132,17 @@ static void sti_drm_crtc_disable(struct drm_crtc *crtc)
		clk_disable_unprepare(compo->clk_compo_aux);
	}

	mixer->enabled = false;
	mixer->status = STI_MIXER_DISABLED;
}

static void
sti_drm_crtc_mode_set_nofb(struct drm_crtc *crtc)
sti_crtc_mode_set_nofb(struct drm_crtc *crtc)
{
	sti_drm_crtc_prepare(crtc);
	sti_drm_crtc_mode_set(crtc, &crtc->state->adjusted_mode);
	sti_crtc_enable(crtc);
	sti_crtc_mode_set(crtc, &crtc->state->adjusted_mode);
}

static void sti_drm_atomic_begin(struct drm_crtc *crtc,
static void sti_crtc_atomic_begin(struct drm_crtc *crtc,
				  struct drm_crtc_state *old_crtc_state)
{
	struct sti_mixer *mixer = to_sti_mixer(crtc);
@@ -179,31 +157,93 @@ static void sti_drm_atomic_begin(struct drm_crtc *crtc,
	}
}

static void sti_drm_atomic_flush(struct drm_crtc *crtc,
static void sti_crtc_atomic_flush(struct drm_crtc *crtc,
				  struct drm_crtc_state *old_crtc_state)
{
	struct drm_device *drm_dev = crtc->dev;
	struct sti_mixer *mixer = to_sti_mixer(crtc);
	struct sti_compositor *compo = dev_get_drvdata(mixer->dev);
	struct drm_plane *p;

	DRM_DEBUG_DRIVER("\n");

	/* perform plane actions */
	list_for_each_entry(p, &drm_dev->mode_config.plane_list, head) {
		struct sti_plane *plane = to_sti_plane(p);

		switch (plane->status) {
		case STI_PLANE_UPDATED:
			/* update planes tag as updated */
			DRM_DEBUG_DRIVER("update plane %s\n",
					 sti_plane_to_str(plane));

			if (sti_mixer_set_plane_depth(mixer, plane)) {
				DRM_ERROR("Cannot set plane %s depth\n",
					  sti_plane_to_str(plane));
				break;
			}

			if (sti_mixer_set_plane_status(mixer, plane, true)) {
				DRM_ERROR("Cannot enable plane %s at mixer\n",
					  sti_plane_to_str(plane));
				break;
			}

			/* if plane is HQVDP_0 then commit the vid[0] */
			if (plane->desc == STI_HQVDP_0)
				sti_vid_commit(compo->vid[0], p->state);

			plane->status = STI_PLANE_READY;

			break;
		case STI_PLANE_DISABLING:
			/* disabling sequence for planes tag as disabling */
			DRM_DEBUG_DRIVER("disable plane %s from mixer\n",
					 sti_plane_to_str(plane));

			if (sti_mixer_set_plane_status(mixer, plane, false)) {
				DRM_ERROR("Cannot disable plane %s at mixer\n",
					  sti_plane_to_str(plane));
				continue;
			}

			if (plane->desc == STI_CURSOR)
				/* tag plane status for disabled */
				plane->status = STI_PLANE_DISABLED;
			else
				/* tag plane status for flushing */
				plane->status = STI_PLANE_FLUSHING;

			/* if plane is HQVDP_0 then disable the vid[0] */
			if (plane->desc == STI_HQVDP_0)
				sti_vid_disable(compo->vid[0]);

			break;
		default:
			/* Other status case are not handled */
			break;
		}
	}
}

static struct drm_crtc_helper_funcs sti_crtc_helper_funcs = {
	.dpms = sti_drm_crtc_dpms,
	.prepare = sti_drm_crtc_prepare,
	.commit = sti_drm_crtc_commit,
	.mode_fixup = sti_drm_crtc_mode_fixup,
	.enable = sti_crtc_enable,
	.disable = sti_crtc_disabling,
	.mode_fixup = sti_crtc_mode_fixup,
	.mode_set = drm_helper_crtc_mode_set,
	.mode_set_nofb = sti_drm_crtc_mode_set_nofb,
	.mode_set_nofb = sti_crtc_mode_set_nofb,
	.mode_set_base = drm_helper_crtc_mode_set_base,
	.disable = sti_drm_crtc_disable,
	.atomic_begin = sti_drm_atomic_begin,
	.atomic_flush = sti_drm_atomic_flush,
	.atomic_begin = sti_crtc_atomic_begin,
	.atomic_flush = sti_crtc_atomic_flush,
};

static void sti_drm_crtc_destroy(struct drm_crtc *crtc)
static void sti_crtc_destroy(struct drm_crtc *crtc)
{
	DRM_DEBUG_KMS("\n");
	drm_crtc_cleanup(crtc);
}

static int sti_drm_crtc_set_property(struct drm_crtc *crtc,
static int sti_crtc_set_property(struct drm_crtc *crtc,
				 struct drm_property *property,
				 uint64_t val)
{
@@ -211,7 +251,7 @@ static int sti_drm_crtc_set_property(struct drm_crtc *crtc,
	return 0;
}

int sti_drm_crtc_vblank_cb(struct notifier_block *nb,
int sti_crtc_vblank_cb(struct notifier_block *nb,
		       unsigned long event, void *data)
{
	struct drm_device *drm_dev;
@@ -219,7 +259,7 @@ int sti_drm_crtc_vblank_cb(struct notifier_block *nb,
		container_of(nb, struct sti_compositor, vtg_vblank_nb);
	int *crtc = data;
	unsigned long flags;
	struct sti_drm_private *priv;
	struct sti_private *priv;

	drm_dev = compo->mixer[*crtc]->drm_crtc.dev;
	priv = drm_dev->dev_private;
@@ -241,15 +281,32 @@ int sti_drm_crtc_vblank_cb(struct notifier_block *nb,
	}
	spin_unlock_irqrestore(&drm_dev->event_lock, flags);

	if (compo->mixer[*crtc]->status == STI_MIXER_DISABLING) {
		struct drm_plane *p;

		/* Disable mixer only if all overlay planes (GDP and VDP)
		 * are disabled */
		list_for_each_entry(p, &drm_dev->mode_config.plane_list, head) {
			struct sti_plane *plane = to_sti_plane(p);

			if ((plane->desc & STI_PLANE_TYPE_MASK) <= STI_VDP)
				if (plane->status != STI_PLANE_DISABLED)
					return 0;
		}
		sti_crtc_disable(&compo->mixer[*crtc]->drm_crtc);
	}

int sti_drm_crtc_enable_vblank(struct drm_device *dev, int crtc)
	return 0;
}

int sti_crtc_enable_vblank(struct drm_device *dev, int crtc)
{
	struct sti_drm_private *dev_priv = dev->dev_private;
	struct sti_private *dev_priv = dev->dev_private;
	struct sti_compositor *compo = dev_priv->compo;
	struct notifier_block *vtg_vblank_nb = &compo->vtg_vblank_nb;

	DRM_DEBUG_DRIVER("\n");

	if (sti_vtg_register_client(crtc == STI_MIXER_MAIN ?
			compo->vtg_main : compo->vtg_aux,
			vtg_vblank_nb, crtc)) {
@@ -259,11 +316,11 @@ int sti_drm_crtc_enable_vblank(struct drm_device *dev, int crtc)

	return 0;
}
EXPORT_SYMBOL(sti_drm_crtc_enable_vblank);
EXPORT_SYMBOL(sti_crtc_enable_vblank);

void sti_drm_crtc_disable_vblank(struct drm_device *dev, int crtc)
void sti_crtc_disable_vblank(struct drm_device *drm_dev, int crtc)
{
	struct sti_drm_private *priv = dev->dev_private;
	struct sti_private *priv = drm_dev->dev_private;
	struct sti_compositor *compo = priv->compo;
	struct notifier_block *vtg_vblank_nb = &compo->vtg_vblank_nb;

@@ -275,23 +332,23 @@ void sti_drm_crtc_disable_vblank(struct drm_device *dev, int crtc)

	/* free the resources of the pending requests */
	if (compo->mixer[crtc]->pending_event) {
		drm_vblank_put(dev, crtc);
		drm_vblank_put(drm_dev, crtc);
		compo->mixer[crtc]->pending_event = NULL;
	}
}
EXPORT_SYMBOL(sti_drm_crtc_disable_vblank);
EXPORT_SYMBOL(sti_crtc_disable_vblank);

static struct drm_crtc_funcs sti_crtc_funcs = {
	.set_config = drm_atomic_helper_set_config,
	.page_flip = drm_atomic_helper_page_flip,
	.destroy = sti_drm_crtc_destroy,
	.set_property = sti_drm_crtc_set_property,
	.destroy = sti_crtc_destroy,
	.set_property = sti_crtc_set_property,
	.reset = drm_atomic_helper_crtc_reset,
	.atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
	.atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
};

bool sti_drm_crtc_is_main(struct drm_crtc *crtc)
bool sti_crtc_is_main(struct drm_crtc *crtc)
{
	struct sti_mixer *mixer = to_sti_mixer(crtc);

@@ -300,9 +357,9 @@ bool sti_drm_crtc_is_main(struct drm_crtc *crtc)

	return false;
}
EXPORT_SYMBOL(sti_drm_crtc_is_main);
EXPORT_SYMBOL(sti_crtc_is_main);

int sti_drm_crtc_init(struct drm_device *drm_dev, struct sti_mixer *mixer,
int sti_crtc_init(struct drm_device *drm_dev, struct sti_mixer *mixer,
		  struct drm_plane *primary, struct drm_plane *cursor)
{
	struct drm_crtc *crtc = &mixer->drm_crtc;
@@ -311,7 +368,7 @@ int sti_drm_crtc_init(struct drm_device *drm_dev, struct sti_mixer *mixer,
	res = drm_crtc_init_with_planes(drm_dev, crtc, primary, cursor,
					&sti_crtc_funcs);
	if (res) {
		DRM_ERROR("Can not initialze CRTC\n");
		DRM_ERROR("Can't initialze CRTC\n");
		return -EINVAL;
	}

Loading