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

Commit 7249e3d6 authored by Dave Airlie's avatar Dave Airlie
Browse files

Merge tag 'sunxi-drm-for-4.13' of...

Merge tag 'sunxi-drm-for-4.13' of https://git.kernel.org/pub/scm/linux/kernel/git/mripard/linux into drm-next

sun4i-drm changes for 4.13

An unusually big pull request for this merge window, with three notable
features:
  - V3s display engine support. This is especially notable because it uses
    a different display engine used on the newer Allwinner SoCs (H3, A64
    and the likes) that will be quite easily supported now.
  - HDMI support for the old Allwinner SoCs. This is enabled only on the
    A10s for now, but should be really easy to extend to deal with A10, A20
    and A31
  - Preliminary work to deal with dual-pipeline SoCs (A10, A20, A31, H3,
    etc.). It currently ignores the second pipeline, but we can use the
    dual-pipelines bindings. This will be useful to enable the display
    pipeline while we work on the dual-pipeline.

* tag 'sunxi-drm-for-4.13' of https://git.kernel.org/pub/scm/linux/kernel/git/mripard/linux: (27 commits)
  drm/sun4i: Add compatible for the A10s pipeline
  drm/sun4i: Add HDMI support
  dt-bindings: display: sun4i: Add allwinner,tcon-channel property
  dt-bindings: display: sun4i: Add HDMI display bindings
  drm/sun4i: Ignore the generic connectors for components
  drm/sun4i: tcon: multiply the vtotal when not in interlace
  drm/sun4i: tcon: Change vertical total size computation inconsistency
  drm/sun4i: tcon: Fix tcon channel 1 backporch calculation
  drm/sun4i: tcon: Switch mux on only for composite
  drm/sun4i: tcon: Move the muxing out of the mode set function
  drm/sun4i: tcon: Add channel debug
  drm/sun4i: tcon: add support for V3s TCON
  drm/sun4i: Add compatible string for V3s display engine
  drm/sun4i: add support for Allwinner DE2 mixers
  drm/sun4i: add a Kconfig option for sun4i-backend
  drm/sun4i: abstract a engine type
  drm/sun4i: return only planes for layers created
  dt-bindings: add bindings for DE2 on V3s SoC
  drm/sun4i: backend: Clarify sun4i_backend_layer_enable debug message
  drm/sun4i: Set TCON clock inside sun4i_tconX_mode_set
  ...
parents 04d4fb5f 110d33dd
Loading
Loading
Loading
Loading
+121 −6
Original line number Diff line number Diff line
@@ -4,6 +4,44 @@ Allwinner A10 Display Pipeline
The Allwinner A10 Display pipeline is composed of several components
that are going to be documented below:

For the input port of all components up to the TCON in the display
pipeline, if there are multiple components, the local endpoint IDs
must correspond to the index of the upstream block. For example, if
the remote endpoint is Frontend 1, then the local endpoint ID must
be 1.

Conversely, for the output ports of the same group, the remote endpoint
ID must be the index of the local hardware block. If the local backend
is backend 1, then the remote endpoint ID must be 1.

HDMI Encoder
------------

The HDMI Encoder supports the HDMI video and audio outputs, and does
CEC. It is one end of the pipeline.

Required properties:
  - compatible: value must be one of:
    * allwinner,sun5i-a10s-hdmi
  - reg: base address and size of memory-mapped region
  - interrupts: interrupt associated to this IP
  - clocks: phandles to the clocks feeding the HDMI encoder
    * ahb: the HDMI interface clock
    * mod: the HDMI module clock
    * pll-0: the first video PLL
    * pll-1: the second video PLL
  - clock-names: the clock names mentioned above
  - dmas: phandles to the DMA channels used by the HDMI encoder
    * ddc-tx: The channel for DDC transmission
    * ddc-rx: The channel for DDC reception
    * audio-tx: The channel used for audio transmission
  - dma-names: the channel names mentioned above

  - ports: A ports node with endpoint definitions as defined in
    Documentation/devicetree/bindings/media/video-interfaces.txt. The
    first port should be the input endpoint. The second should be the
    output, usually to an HDMI connector.

TV Encoder
----------

@@ -31,6 +69,7 @@ Required properties:
   * allwinner,sun6i-a31-tcon
   * allwinner,sun6i-a31s-tcon
   * allwinner,sun8i-a33-tcon
   * allwinner,sun8i-v3s-tcon
 - reg: base address and size of memory-mapped region
 - interrupts: interrupt associated to this IP
 - clocks: phandles to the clocks feeding the TCON. Three are needed:
@@ -47,12 +86,15 @@ Required properties:
  Documentation/devicetree/bindings/media/video-interfaces.txt. The
  first port should be the input endpoint, the second one the output

  The output should have two endpoints. The first is the block
  connected to the TCON channel 0 (usually a panel or a bridge), the
  second the block connected to the TCON channel 1 (usually the TV
  encoder)
  The output may have multiple endpoints. The TCON has two channels,
  usually with the first channel being used for the panels interfaces
  (RGB, LVDS, etc.), and the second being used for the outputs that
  require another controller (TV Encoder, HDMI, etc.). The endpoints
  will take an extra property, allwinner,tcon-channel, to specify the
  channel the endpoint is associated to. If that property is not
  present, the endpoint number will be used as the channel number.

On SoCs other than the A33, there is one more clock required:
On SoCs other than the A33 and V3s, there is one more clock required:
   - 'tcon-ch1': The clock driving the TCON channel 1

DRC
@@ -138,6 +180,26 @@ Required properties:
  Documentation/devicetree/bindings/media/video-interfaces.txt. The
  first port should be the input endpoints, the second one the outputs

Display Engine 2.0 Mixer
------------------------

The DE2 mixer have many functionalities, currently only layer blending is
supported.

Required properties:
  - compatible: value must be one of:
    * allwinner,sun8i-v3s-de2-mixer
  - reg: base address and size of the memory-mapped region.
  - clocks: phandles to the clocks feeding the mixer
    * bus: the mixer interface clock
    * mod: the mixer module clock
  - clock-names: the clock names mentioned above
  - resets: phandles to the reset controllers driving the mixer

- ports: A ports node with endpoint definitions as defined in
  Documentation/devicetree/bindings/media/video-interfaces.txt. The
  first port should be the input endpoints, the second one the output


Display Engine Pipeline
-----------------------
@@ -148,13 +210,15 @@ extra node.

Required properties:
  - compatible: value must be one of:
    * allwinner,sun5i-a10s-display-engine
    * allwinner,sun5i-a13-display-engine
    * allwinner,sun6i-a31-display-engine
    * allwinner,sun6i-a31s-display-engine
    * allwinner,sun8i-a33-display-engine
    * allwinner,sun8i-v3s-display-engine

  - allwinner,pipelines: list of phandle to the display engine
    frontends available.
    frontends (DE 1.0) or mixers (DE 2.0) available.

Example:

@@ -173,6 +237,57 @@ panel: panel {
	};
};

connector {
	compatible = "hdmi-connector";
	type = "a";

	port {
		hdmi_con_in: endpoint {
			remote-endpoint = <&hdmi_out_con>;
		};
	};
};

hdmi: hdmi@01c16000 {
	compatible = "allwinner,sun5i-a10s-hdmi";
	reg = <0x01c16000 0x1000>;
	interrupts = <58>;
	clocks = <&ccu CLK_AHB_HDMI>, <&ccu CLK_HDMI>,
		 <&ccu CLK_PLL_VIDEO0_2X>,
		 <&ccu CLK_PLL_VIDEO1_2X>;
	clock-names = "ahb", "mod", "pll-0", "pll-1";
	dmas = <&dma SUN4I_DMA_NORMAL 16>,
	       <&dma SUN4I_DMA_NORMAL 16>,
	       <&dma SUN4I_DMA_DEDICATED 24>;
	dma-names = "ddc-tx", "ddc-rx", "audio-tx";
	status = "disabled";

	ports {
		#address-cells = <1>;
		#size-cells = <0>;

		port@0 {
			#address-cells = <1>;
			#size-cells = <0>;
			reg = <0>;

			hdmi_in_tcon0: endpoint {
				remote-endpoint = <&tcon0_out_hdmi>;
			};
		};

		port@1 {
			#address-cells = <1>;
			#size-cells = <0>;
			reg = <1>;

			hdmi_out_con: endpoint {
				remote-endpoint = <&hdmi_con_in>;
			};
		};
	};
};

tve0: tv-encoder@01c0a000 {
	compatible = "allwinner,sun4i-a10-tv-encoder";
	reg = <0x01c0a000 0x1000>;
+28 −0
Original line number Diff line number Diff line
@@ -12,3 +12,31 @@ config DRM_SUN4I
	  Choose this option if you have an Allwinner SoC with a
	  Display Engine. If M is selected the module will be called
	  sun4i-drm.

config DRM_SUN4I_HDMI
       tristate "Allwinner A10 HDMI Controller Support"
       depends on DRM_SUN4I
       default DRM_SUN4I
       help
	  Choose this option if you have an Allwinner SoC with an HDMI
	  controller.

config DRM_SUN4I_BACKEND
	tristate "Support for Allwinner A10 Display Engine Backend"
	depends on DRM_SUN4I
	default DRM_SUN4I
	help
	  Choose this option if you have an Allwinner SoC with the
	  original Allwinner Display Engine, which has a backend to
	  do some alpha blending and feed graphics to TCON. If M is
	  selected the module will be called sun4i-backend.

config DRM_SUN8I_MIXER
	tristate "Support for Allwinner Display Engine 2.0 Mixer"
	depends on DRM_SUN4I
	default MACH_SUN8I
	help
	  Choose this option if you have an Allwinner SoC with the
	  Allwinner Display Engine 2.0, which has a mixer to do some
	  graphics mixture and feed graphics to TCON, If M is
	  selected the module will be called sun8i-mixer.
+12 −2
Original line number Diff line number Diff line
sun4i-drm-y += sun4i_drv.o
sun4i-drm-y += sun4i_framebuffer.o

sun4i-drm-hdmi-y += sun4i_hdmi_enc.o
sun4i-drm-hdmi-y += sun4i_hdmi_ddc_clk.o
sun4i-drm-hdmi-y += sun4i_hdmi_tmds_clk.o

sun4i-tcon-y += sun4i_tcon.o
sun4i-tcon-y += sun4i_rgb.o
sun4i-tcon-y += sun4i_dotclock.o
sun4i-tcon-y += sun4i_crtc.o
sun4i-tcon-y += sun4i_layer.o

sun4i-backend-y += sun4i_backend.o sun4i_layer.o

sun8i-mixer-y += sun8i_mixer.o sun8i_layer.o

obj-$(CONFIG_DRM_SUN4I)		+= sun4i-drm.o sun4i-tcon.o
obj-$(CONFIG_DRM_SUN4I)		+= sun4i_backend.o
obj-$(CONFIG_DRM_SUN4I)		+= sun6i_drc.o
obj-$(CONFIG_DRM_SUN4I)		+= sun4i_tv.o

obj-$(CONFIG_DRM_SUN4I_BACKEND)		+= sun4i-backend.o
obj-$(CONFIG_DRM_SUN4I_HDMI)	+= sun4i-drm-hdmi.o
obj-$(CONFIG_DRM_SUN8I_MIXER)		+= sun8i-mixer.o
+89 −33
Original line number Diff line number Diff line
@@ -19,10 +19,14 @@
#include <drm/drm_plane_helper.h>

#include <linux/component.h>
#include <linux/list.h>
#include <linux/of_graph.h>
#include <linux/reset.h>

#include "sun4i_backend.h"
#include "sun4i_drv.h"
#include "sun4i_layer.h"
#include "sunxi_engine.h"

static const u32 sunxi_rgb2yuv_coef[12] = {
	0x00000107, 0x00000204, 0x00000064, 0x00000108,
@@ -30,58 +34,55 @@ static const u32 sunxi_rgb2yuv_coef[12] = {
	0x000001c1, 0x00003e88, 0x00003fb8, 0x00000808
};

void sun4i_backend_apply_color_correction(struct sun4i_backend *backend)
static void sun4i_backend_apply_color_correction(struct sunxi_engine *engine)
{
	int i;

	DRM_DEBUG_DRIVER("Applying RGB to YUV color correction\n");

	/* Set color correction */
	regmap_write(backend->regs, SUN4I_BACKEND_OCCTL_REG,
	regmap_write(engine->regs, SUN4I_BACKEND_OCCTL_REG,
		     SUN4I_BACKEND_OCCTL_ENABLE);

	for (i = 0; i < 12; i++)
		regmap_write(backend->regs, SUN4I_BACKEND_OCRCOEF_REG(i),
		regmap_write(engine->regs, SUN4I_BACKEND_OCRCOEF_REG(i),
			     sunxi_rgb2yuv_coef[i]);
}
EXPORT_SYMBOL(sun4i_backend_apply_color_correction);

void sun4i_backend_disable_color_correction(struct sun4i_backend *backend)
static void sun4i_backend_disable_color_correction(struct sunxi_engine *engine)
{
	DRM_DEBUG_DRIVER("Disabling color correction\n");

	/* Disable color correction */
	regmap_update_bits(backend->regs, SUN4I_BACKEND_OCCTL_REG,
	regmap_update_bits(engine->regs, SUN4I_BACKEND_OCCTL_REG,
			   SUN4I_BACKEND_OCCTL_ENABLE, 0);
}
EXPORT_SYMBOL(sun4i_backend_disable_color_correction);

void sun4i_backend_commit(struct sun4i_backend *backend)
static void sun4i_backend_commit(struct sunxi_engine *engine)
{
	DRM_DEBUG_DRIVER("Committing changes\n");

	regmap_write(backend->regs, SUN4I_BACKEND_REGBUFFCTL_REG,
	regmap_write(engine->regs, SUN4I_BACKEND_REGBUFFCTL_REG,
		     SUN4I_BACKEND_REGBUFFCTL_AUTOLOAD_DIS |
		     SUN4I_BACKEND_REGBUFFCTL_LOADCTL);
}
EXPORT_SYMBOL(sun4i_backend_commit);

void sun4i_backend_layer_enable(struct sun4i_backend *backend,
				int layer, bool enable)
{
	u32 val;

	DRM_DEBUG_DRIVER("Enabling layer %d\n", layer);
	DRM_DEBUG_DRIVER("%sabling layer %d\n", enable ? "En" : "Dis",
			 layer);

	if (enable)
		val = SUN4I_BACKEND_MODCTL_LAY_EN(layer);
	else
		val = 0;

	regmap_update_bits(backend->regs, SUN4I_BACKEND_MODCTL_REG,
	regmap_update_bits(backend->engine.regs, SUN4I_BACKEND_MODCTL_REG,
			   SUN4I_BACKEND_MODCTL_LAY_EN(layer), val);
}
EXPORT_SYMBOL(sun4i_backend_layer_enable);

static int sun4i_backend_drm_format_to_layer(struct drm_plane *plane,
					     u32 format, u32 *mode)
@@ -141,33 +142,33 @@ int sun4i_backend_update_layer_coord(struct sun4i_backend *backend,
	if (plane->type == DRM_PLANE_TYPE_PRIMARY) {
		DRM_DEBUG_DRIVER("Primary layer, updating global size W: %u H: %u\n",
				 state->crtc_w, state->crtc_h);
		regmap_write(backend->regs, SUN4I_BACKEND_DISSIZE_REG,
		regmap_write(backend->engine.regs, SUN4I_BACKEND_DISSIZE_REG,
			     SUN4I_BACKEND_DISSIZE(state->crtc_w,
						   state->crtc_h));
	}

	/* Set the line width */
	DRM_DEBUG_DRIVER("Layer line width: %d bits\n", fb->pitches[0] * 8);
	regmap_write(backend->regs, SUN4I_BACKEND_LAYLINEWIDTH_REG(layer),
	regmap_write(backend->engine.regs,
		     SUN4I_BACKEND_LAYLINEWIDTH_REG(layer),
		     fb->pitches[0] * 8);

	/* Set height and width */
	DRM_DEBUG_DRIVER("Layer size W: %u H: %u\n",
			 state->crtc_w, state->crtc_h);
	regmap_write(backend->regs, SUN4I_BACKEND_LAYSIZE_REG(layer),
	regmap_write(backend->engine.regs, SUN4I_BACKEND_LAYSIZE_REG(layer),
		     SUN4I_BACKEND_LAYSIZE(state->crtc_w,
					   state->crtc_h));

	/* Set base coordinates */
	DRM_DEBUG_DRIVER("Layer coordinates X: %d Y: %d\n",
			 state->crtc_x, state->crtc_y);
	regmap_write(backend->regs, SUN4I_BACKEND_LAYCOOR_REG(layer),
	regmap_write(backend->engine.regs, SUN4I_BACKEND_LAYCOOR_REG(layer),
		     SUN4I_BACKEND_LAYCOOR(state->crtc_x,
					   state->crtc_y));

	return 0;
}
EXPORT_SYMBOL(sun4i_backend_update_layer_coord);

int sun4i_backend_update_layer_formats(struct sun4i_backend *backend,
				       int layer, struct drm_plane *plane)
@@ -182,7 +183,7 @@ int sun4i_backend_update_layer_formats(struct sun4i_backend *backend,
		interlaced = plane->state->crtc->state->adjusted_mode.flags
			& DRM_MODE_FLAG_INTERLACE;

	regmap_update_bits(backend->regs, SUN4I_BACKEND_MODCTL_REG,
	regmap_update_bits(backend->engine.regs, SUN4I_BACKEND_MODCTL_REG,
			   SUN4I_BACKEND_MODCTL_ITLMOD_EN,
			   interlaced ? SUN4I_BACKEND_MODCTL_ITLMOD_EN : 0);

@@ -196,12 +197,12 @@ int sun4i_backend_update_layer_formats(struct sun4i_backend *backend,
		return ret;
	}

	regmap_update_bits(backend->regs, SUN4I_BACKEND_ATTCTL_REG1(layer),
	regmap_update_bits(backend->engine.regs,
			   SUN4I_BACKEND_ATTCTL_REG1(layer),
			   SUN4I_BACKEND_ATTCTL_REG1_LAY_FBFMT, val);

	return 0;
}
EXPORT_SYMBOL(sun4i_backend_update_layer_formats);

int sun4i_backend_update_layer_buffer(struct sun4i_backend *backend,
				      int layer, struct drm_plane *plane)
@@ -229,19 +230,19 @@ int sun4i_backend_update_layer_buffer(struct sun4i_backend *backend,
	/* Write the 32 lower bits of the address (in bits) */
	lo_paddr = paddr << 3;
	DRM_DEBUG_DRIVER("Setting address lower bits to 0x%x\n", lo_paddr);
	regmap_write(backend->regs, SUN4I_BACKEND_LAYFB_L32ADD_REG(layer),
	regmap_write(backend->engine.regs,
		     SUN4I_BACKEND_LAYFB_L32ADD_REG(layer),
		     lo_paddr);

	/* And the upper bits */
	hi_paddr = paddr >> 29;
	DRM_DEBUG_DRIVER("Setting address high bits to 0x%x\n", hi_paddr);
	regmap_update_bits(backend->regs, SUN4I_BACKEND_LAYFB_H4ADD_REG,
	regmap_update_bits(backend->engine.regs, SUN4I_BACKEND_LAYFB_H4ADD_REG,
			   SUN4I_BACKEND_LAYFB_H4ADD_MSK(layer),
			   SUN4I_BACKEND_LAYFB_H4ADD(layer, hi_paddr));

	return 0;
}
EXPORT_SYMBOL(sun4i_backend_update_layer_buffer);

static int sun4i_backend_init_sat(struct device *dev) {
	struct sun4i_backend *backend = dev_get_drvdata(dev);
@@ -288,6 +289,52 @@ static int sun4i_backend_free_sat(struct device *dev) {
	return 0;
}

/*
 * The display backend can take video output from the display frontend, or
 * the display enhancement unit on the A80, as input for one it its layers.
 * This relationship within the display pipeline is encoded in the device
 * tree with of_graph, and we use it here to figure out which backend, if
 * there are 2 or more, we are currently probing. The number would be in
 * the "reg" property of the upstream output port endpoint.
 */
static int sun4i_backend_of_get_id(struct device_node *node)
{
	struct device_node *port, *ep;
	int ret = -EINVAL;

	/* input is port 0 */
	port = of_graph_get_port_by_id(node, 0);
	if (!port)
		return -EINVAL;

	/* try finding an upstream endpoint */
	for_each_available_child_of_node(port, ep) {
		struct device_node *remote;
		u32 reg;

		remote = of_parse_phandle(ep, "remote-endpoint", 0);
		if (!remote)
			continue;

		ret = of_property_read_u32(remote, "reg", &reg);
		if (ret)
			continue;

		ret = reg;
	}

	of_node_put(port);

	return ret;
}

static const struct sunxi_engine_ops sun4i_backend_engine_ops = {
	.commit				= sun4i_backend_commit,
	.layers_init			= sun4i_layers_init,
	.apply_color_correction		= sun4i_backend_apply_color_correction,
	.disable_color_correction	= sun4i_backend_disable_color_correction,
};

static struct regmap_config sun4i_backend_regmap_config = {
	.reg_bits	= 32,
	.val_bits	= 32,
@@ -310,18 +357,23 @@ static int sun4i_backend_bind(struct device *dev, struct device *master,
	if (!backend)
		return -ENOMEM;
	dev_set_drvdata(dev, backend);
	drv->backend = backend;

	backend->engine.node = dev->of_node;
	backend->engine.ops = &sun4i_backend_engine_ops;
	backend->engine.id = sun4i_backend_of_get_id(dev->of_node);
	if (backend->engine.id < 0)
		return backend->engine.id;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	regs = devm_ioremap_resource(dev, res);
	if (IS_ERR(regs))
		return PTR_ERR(regs);

	backend->regs = devm_regmap_init_mmio(dev, regs,
	backend->engine.regs = devm_regmap_init_mmio(dev, regs,
						     &sun4i_backend_regmap_config);
	if (IS_ERR(backend->regs)) {
		dev_err(dev, "Couldn't create the backend0 regmap\n");
		return PTR_ERR(backend->regs);
	if (IS_ERR(backend->engine.regs)) {
		dev_err(dev, "Couldn't create the backend regmap\n");
		return PTR_ERR(backend->engine.regs);
	}

	backend->reset = devm_reset_control_get(dev, NULL);
@@ -369,16 +421,18 @@ static int sun4i_backend_bind(struct device *dev, struct device *master,
		}
	}

	list_add_tail(&backend->engine.list, &drv->engine_list);

	/* Reset the registers */
	for (i = 0x800; i < 0x1000; i += 4)
		regmap_write(backend->regs, i, 0);
		regmap_write(backend->engine.regs, i, 0);

	/* Disable registers autoloading */
	regmap_write(backend->regs, SUN4I_BACKEND_REGBUFFCTL_REG,
	regmap_write(backend->engine.regs, SUN4I_BACKEND_REGBUFFCTL_REG,
		     SUN4I_BACKEND_REGBUFFCTL_AUTOLOAD_DIS);

	/* Enable the backend */
	regmap_write(backend->regs, SUN4I_BACKEND_MODCTL_REG,
	regmap_write(backend->engine.regs, SUN4I_BACKEND_MODCTL_REG,
		     SUN4I_BACKEND_MODCTL_DEBE_EN |
		     SUN4I_BACKEND_MODCTL_START_CTL);

@@ -400,6 +454,8 @@ static void sun4i_backend_unbind(struct device *dev, struct device *master,
{
	struct sun4i_backend *backend = dev_get_drvdata(dev);

	list_del(&backend->engine.list);

	if (of_device_is_compatible(dev->of_node,
				    "allwinner,sun8i-a33-display-backend"))
		sun4i_backend_free_sat(dev);
+10 −5
Original line number Diff line number Diff line
@@ -14,9 +14,13 @@
#define _SUN4I_BACKEND_H_

#include <linux/clk.h>
#include <linux/list.h>
#include <linux/of.h>
#include <linux/regmap.h>
#include <linux/reset.h>

#include "sunxi_engine.h"

#define SUN4I_BACKEND_MODCTL_REG		0x800
#define SUN4I_BACKEND_MODCTL_LINE_SEL			BIT(29)
#define SUN4I_BACKEND_MODCTL_ITLMOD_EN			BIT(28)
@@ -139,7 +143,7 @@
#define SUN4I_BACKEND_PIPE_OFF(p)		(0x5000 + (0x400 * (p)))

struct sun4i_backend {
	struct regmap		*regs;
	struct sunxi_engine	engine;

	struct reset_control	*reset;

@@ -151,10 +155,11 @@ struct sun4i_backend {
	struct reset_control	*sat_reset;
};

void sun4i_backend_apply_color_correction(struct sun4i_backend *backend);
void sun4i_backend_disable_color_correction(struct sun4i_backend *backend);

void sun4i_backend_commit(struct sun4i_backend *backend);
static inline struct sun4i_backend *
engine_to_sun4i_backend(struct sunxi_engine *engine)
{
	return container_of(engine, struct sun4i_backend, engine);
}

void sun4i_backend_layer_enable(struct sun4i_backend *backend,
				int layer, bool enable);
Loading