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

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

Merge tag 'drm-vc4-next-2016-05-02' of https://github.com/anholt/linux into drm-next

This pull request brings in DPI panel support, gamma ramp support, and
render nodes for vc4.

* tag 'drm-vc4-next-2016-05-02' of https://github.com/anholt/linux:
  drm/vc4: Add missing render node support
  drm/vc4: Add support for gamma ramps.
  drm/vc4: Fix NULL deref in HDMI init error path
  drm/vc4: Add DPI driver
  drm: Add an encoder and connector type enum for DPI.
parents 2b8f01f1 0cd3e274
Loading
Loading
Loading
Loading
+36 −0
Original line number Diff line number Diff line
@@ -35,12 +35,22 @@ Optional properties for HDMI:
		  as an interrupt/status bit in the HDMI controller
		  itself).  See bindings/pinctrl/brcm,bcm2835-gpio.txt

Required properties for DPI:
- compatible:	Should be "brcm,bcm2835-dpi"
- reg:		Physical base address and length of the registers
- clocks:	a) core: The core clock the unit runs on
		b) pixel: The pixel clock that feeds the pixelvalve
- port:		Port node with a single endpoint connecting to the panel
		  device, as defined in [1]

Required properties for V3D:
- compatible:	Should be "brcm,bcm2835-v3d"
- reg:		Physical base address and length of the V3D's registers
- interrupts:	The interrupt number
		  See bindings/interrupt-controller/brcm,bcm2835-armctrl-ic.txt

[1] Documentation/devicetree/bindings/media/video-interfaces.txt

Example:
pixelvalve@7e807000 {
	compatible = "brcm,bcm2835-pixelvalve2";
@@ -66,6 +76,22 @@ hdmi: hdmi@7e902000 {
	clock-names = "pixel", "hdmi";
};

dpi: dpi@7e208000 {
	compatible = "brcm,bcm2835-dpi";
	reg = <0x7e208000 0x8c>;
	clocks = <&clocks BCM2835_CLOCK_VPU>,
	         <&clocks BCM2835_CLOCK_DPI>;
	clock-names = "core", "pixel";
	#address-cells = <1>;
	#size-cells = <0>;

	port {
		dpi_out: endpoint@0 {
			remote-endpoint = <&panel_in>;
		};
	};
};

v3d: v3d@7ec00000 {
	compatible = "brcm,bcm2835-v3d";
	reg = <0x7ec00000 0x1000>;
@@ -75,3 +101,13 @@ v3d: v3d@7ec00000 {
vc4: gpu {
	compatible = "brcm,bcm2835-vc4";
};

panel: panel {
	compatible = "ontat,yx700wv03", "simple-panel";

	port {
		panel_in: endpoint {
			remote-endpoint = <&dpi_out>;
		};
	};
};
+2 −0
Original line number Diff line number Diff line
@@ -168,6 +168,7 @@ static struct drm_conn_prop_enum_list drm_connector_enum_list[] = {
	{ DRM_MODE_CONNECTOR_eDP, "eDP" },
	{ DRM_MODE_CONNECTOR_VIRTUAL, "Virtual" },
	{ DRM_MODE_CONNECTOR_DSI, "DSI" },
	{ DRM_MODE_CONNECTOR_DPI, "DPI" },
};

static const struct drm_prop_enum_list drm_encoder_enum_list[] = {
@@ -179,6 +180,7 @@ static const struct drm_prop_enum_list drm_encoder_enum_list[] = {
	{ DRM_MODE_ENCODER_VIRTUAL, "Virtual" },
	{ DRM_MODE_ENCODER_DSI, "DSI" },
	{ DRM_MODE_ENCODER_DPMST, "DP MST" },
	{ DRM_MODE_ENCODER_DPI, "DPI" },
};

static const struct drm_prop_enum_list drm_subpixel_enum_list[] = {
+1 −0
Original line number Diff line number Diff line
@@ -5,6 +5,7 @@ config DRM_VC4
	select DRM_KMS_HELPER
	select DRM_KMS_CMA_HELPER
	select DRM_GEM_CMA_HELPER
	select DRM_PANEL
	help
	  Choose this option if you have a system that has a Broadcom
	  VC4 GPU, such as the Raspberry Pi or other BCM2708/BCM2835.
+1 −0
Original line number Diff line number Diff line
@@ -7,6 +7,7 @@ vc4-y := \
	vc4_bo.o \
	vc4_crtc.o \
	vc4_drv.o \
	vc4_dpi.o \
	vc4_kms.o \
	vc4_gem.o \
	vc4_hdmi.o \
+58 −0
Original line number Diff line number Diff line
@@ -49,6 +49,10 @@ struct vc4_crtc {
	/* Which HVS channel we're using for our CRTC. */
	int channel;

	u8 lut_r[256];
	u8 lut_g[256];
	u8 lut_b[256];

	struct drm_pending_vblank_event *event;
};

@@ -147,6 +151,46 @@ static void vc4_crtc_destroy(struct drm_crtc *crtc)
	drm_crtc_cleanup(crtc);
}

static void
vc4_crtc_lut_load(struct drm_crtc *crtc)
{
	struct drm_device *dev = crtc->dev;
	struct vc4_dev *vc4 = to_vc4_dev(dev);
	struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
	u32 i;

	/* The LUT memory is laid out with each HVS channel in order,
	 * each of which takes 256 writes for R, 256 for G, then 256
	 * for B.
	 */
	HVS_WRITE(SCALER_GAMADDR,
		  SCALER_GAMADDR_AUTOINC |
		  (vc4_crtc->channel * 3 * crtc->gamma_size));

	for (i = 0; i < crtc->gamma_size; i++)
		HVS_WRITE(SCALER_GAMDATA, vc4_crtc->lut_r[i]);
	for (i = 0; i < crtc->gamma_size; i++)
		HVS_WRITE(SCALER_GAMDATA, vc4_crtc->lut_g[i]);
	for (i = 0; i < crtc->gamma_size; i++)
		HVS_WRITE(SCALER_GAMDATA, vc4_crtc->lut_b[i]);
}

static void
vc4_crtc_gamma_set(struct drm_crtc *crtc, u16 *r, u16 *g, u16 *b,
		   uint32_t start, uint32_t size)
{
	struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
	u32 i;

	for (i = start; i < start + size; i++) {
		vc4_crtc->lut_r[i] = r[i] >> 8;
		vc4_crtc->lut_g[i] = g[i] >> 8;
		vc4_crtc->lut_b[i] = b[i] >> 8;
	}

	vc4_crtc_lut_load(crtc);
}

static u32 vc4_get_fifo_full_level(u32 format)
{
	static const u32 fifo_len_bytes = 64;
@@ -260,8 +304,14 @@ static void vc4_crtc_mode_set_nofb(struct drm_crtc *crtc)

	HVS_WRITE(SCALER_DISPBKGNDX(vc4_crtc->channel),
		  SCALER_DISPBKGND_AUTOHS |
		  SCALER_DISPBKGND_GAMMA |
		  (interlace ? SCALER_DISPBKGND_INTERLACE : 0));

	/* Reload the LUT, since the SRAMs would have been disabled if
	 * all CRTCs had SCALER_DISPBKGND_GAMMA unset at once.
	 */
	vc4_crtc_lut_load(crtc);

	if (debug_dump_regs) {
		DRM_INFO("CRTC %d regs after:\n", drm_crtc_index(crtc));
		vc4_crtc_dump_regs(vc4_crtc);
@@ -613,6 +663,7 @@ static const struct drm_crtc_funcs vc4_crtc_funcs = {
	.reset = drm_atomic_helper_crtc_reset,
	.atomic_duplicate_state = vc4_crtc_duplicate_state,
	.atomic_destroy_state = vc4_crtc_destroy_state,
	.gamma_set = vc4_crtc_gamma_set,
};

static const struct drm_crtc_helper_funcs vc4_crtc_helper_funcs = {
@@ -711,6 +762,7 @@ static int vc4_crtc_bind(struct device *dev, struct device *master, void *data)
	primary_plane->crtc = crtc;
	vc4->crtc[drm_crtc_index(crtc)] = vc4_crtc;
	vc4_crtc->channel = vc4_crtc->data->hvs_channel;
	drm_mode_crtc_set_gamma_size(crtc, ARRAY_SIZE(vc4_crtc->lut_r));

	/* Set up some arbitrary number of planes.  We're not limited
	 * by a set number of physical registers, just the space in
@@ -751,6 +803,12 @@ static int vc4_crtc_bind(struct device *dev, struct device *master, void *data)

	vc4_set_crtc_possible_masks(drm, crtc);

	for (i = 0; i < crtc->gamma_size; i++) {
		vc4_crtc->lut_r[i] = i;
		vc4_crtc->lut_g[i] = i;
		vc4_crtc->lut_b[i] = i;
	}

	platform_set_drvdata(pdev, vc4_crtc);

	return 0;
Loading