All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC 00/21] Renesas r8a7795/Salvator-X HDMI output prototype
@ 2016-05-30 15:59 Ulrich Hecht
  2016-05-30 16:00 ` [RFC 01/21] drm: rcar-du: Remove i2c slave encoder interface for hdmi encoder Ulrich Hecht
                   ` (22 more replies)
  0 siblings, 23 replies; 34+ messages in thread
From: Ulrich Hecht @ 2016-05-30 15:59 UTC (permalink / raw)
  To: linux-renesas-soc, geert
  Cc: kuninori.morimoto.gx, laurent.pinchart, dri-devel, architt, vz,
	koji.matsuoka.xm, Ulrich Hecht

Hi!

This is a prototype of HDMI output support for the Renesas r8a7795 SoC and
Salvator-X board.  It is based on the renesas-devel-20160516-v4.6 tree and
includes the bridge API conversion patches to the adv7511 and rcar-du
drivers written by Archit Taneja.

The obvious issue with this series is the awkward binding of the dw-hdmi
bridge IP, which can be seen in the "drm: rcar-du: Add dw_hdmi driver
startup" patch.  Any comments on how to implement this interface properly
are much appreciated.

Functionally, this series works as expected on both connectors, but EDID
reading is currently broken.

CU
Uli


Archit Taneja (2):
  drm: rcar-du: Remove i2c slave encoder interface for hdmi encoder
  drm: i2c: adv7511: Convert to drm_bridge

Koji Matsuoka (12):
  media: vsp1: Set format to RPF input source
  drm: bridge/dw_hdmi: Fix R-Car Gen3 device support
  drm: rcar-du: Add R8A7795 device support
  drm: rcar-du: Add dw_hdmi driver startup
  drm: rcar-du: Add DPLL support
  drm: rcar-du: Fix display registers for R-Car Gen3
  drm: rcar-du: Fix VSP plane number per devices
  drm: rcar-du: Fix VSP feed plane number
  drm: rcar-du: Add pixel format support
  drm: rcar-du: Fix display max size to 4096x2160 size
  arm64: dts: salvator-x: Add DU pins, HDMI connectors and encoder
  arm64: configs: Enable R-Car DU related config

Kuninori Morimoto (1):
  arm64: defconfig: add VIDEO_RENESAS_FCP

Ulrich Hecht (5):
  v4l: vsp1: Change VSP1 LIF linebuffer FIFO
  pinctrl: sh-pfc: r8a7795: Add DU support
  pinctrl: sh-pfc: r8a7795: Add HDMI CEC support
  arm64: dts: r8a7795: Add HDMI encoder support
  arm64: dts: r8a7795: add HDMI support to DU

Vladimir Zapolskiy (1):
  drm: bridge/dw_hdmi: add dw hdmi i2c bus adapter support

 arch/arm64/boot/dts/renesas/r8a7795-salvator-x.dts | 107 +++++
 arch/arm64/boot/dts/renesas/r8a7795.dtsi           |  33 +-
 arch/arm64/configs/defconfig                       |  15 +
 drivers/gpu/drm/bridge/dw-hdmi.c                   | 489 +++++++++++++++++++--
 drivers/gpu/drm/i2c/adv7511.c                      | 224 ++++++----
 drivers/gpu/drm/rcar-du/Kconfig                    |   2 +
 drivers/gpu/drm/rcar-du/Makefile                   |   3 +-
 drivers/gpu/drm/rcar-du/rcar_du_crtc.c             |  97 +++-
 drivers/gpu/drm/rcar-du/rcar_du_crtc.h             |  12 +-
 drivers/gpu/drm/rcar-du/rcar_du_drv.c              |  20 +-
 drivers/gpu/drm/rcar-du/rcar_du_drv.h              |   6 +-
 drivers/gpu/drm/rcar-du/rcar_du_encoder.c          |  12 +-
 drivers/gpu/drm/rcar-du/rcar_du_encoder.h          |  13 +-
 drivers/gpu/drm/rcar-du/rcar_du_group.c            |   5 +
 drivers/gpu/drm/rcar-du/rcar_du_hdmicon.c          | 117 -----
 drivers/gpu/drm/rcar-du/rcar_du_hdmicon.h          |  31 --
 drivers/gpu/drm/rcar-du/rcar_du_hdmienc.c          | 260 ++++++++---
 drivers/gpu/drm/rcar-du/rcar_du_kms.c              |  68 ++-
 drivers/gpu/drm/rcar-du/rcar_du_kms.h              |   1 +
 drivers/gpu/drm/rcar-du/rcar_du_plane.c            |   8 +-
 drivers/gpu/drm/rcar-du/rcar_du_plane.h            |   7 +-
 drivers/gpu/drm/rcar-du/rcar_du_regs.h             |  19 +
 drivers/gpu/drm/rcar-du/rcar_du_vsp.c              |  51 ++-
 drivers/media/platform/vsp1/vsp1_drm.c             |   6 +
 drivers/media/platform/vsp1/vsp1_lif.c             |   6 +-
 drivers/pinctrl/sh-pfc/pfc-r8a7795.c               | 113 +++++
 include/drm/bridge/dw_hdmi.h                       |   9 +
 27 files changed, 1388 insertions(+), 346 deletions(-)
 delete mode 100644 drivers/gpu/drm/rcar-du/rcar_du_hdmicon.c
 delete mode 100644 drivers/gpu/drm/rcar-du/rcar_du_hdmicon.h

-- 
2.7.4

^ permalink raw reply	[flat|nested] 34+ messages in thread

* [RFC 01/21] drm: rcar-du: Remove i2c slave encoder interface for hdmi encoder
  2016-05-30 15:59 [RFC 00/21] Renesas r8a7795/Salvator-X HDMI output prototype Ulrich Hecht
@ 2016-05-30 16:00 ` Ulrich Hecht
  2016-05-30 16:00 ` [RFC 02/21] drm: i2c: adv7511: Convert to drm_bridge Ulrich Hecht
                   ` (21 subsequent siblings)
  22 siblings, 0 replies; 34+ messages in thread
From: Ulrich Hecht @ 2016-05-30 16:00 UTC (permalink / raw)
  To: linux-renesas-soc, geert
  Cc: kuninori.morimoto.gx, laurent.pinchart, dri-devel, architt, vz,
	koji.matsuoka.xm, Geert Uytterhoeven

From: Archit Taneja <architt@codeaurora.org>

The hdmi output in rcar-du uses the i2c slave encoder interface to link
to the adv7511 encoder chip. The kms driver creates encoder and connector
entities that internally uses the drm_encoder_slave_funcs ops provided by
the slave encoder driver.

Change the driver such that it expects a bridge entity instead of a slave
encoder. The hdmi connector code isn't needed anymore as we expect the
adv7511 bridge driver to create/manage the connector.

Note that the kms driver still expects a connector node for hdmi to be
present in DT. This node has no connection to the connector created
by the bridge driver.

Compile tested only.

Signed-off-by: Archit Taneja <architt@codeaurora.org>
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
 drivers/gpu/drm/rcar-du/Makefile          |   3 +-
 drivers/gpu/drm/rcar-du/rcar_du_encoder.c |   3 +-
 drivers/gpu/drm/rcar-du/rcar_du_encoder.h |   7 +-
 drivers/gpu/drm/rcar-du/rcar_du_hdmicon.c | 117 ------------------------------
 drivers/gpu/drm/rcar-du/rcar_du_hdmicon.h |  31 --------
 drivers/gpu/drm/rcar-du/rcar_du_hdmienc.c |  67 +++++------------
 6 files changed, 22 insertions(+), 206 deletions(-)
 delete mode 100644 drivers/gpu/drm/rcar-du/rcar_du_hdmicon.c
 delete mode 100644 drivers/gpu/drm/rcar-du/rcar_du_hdmicon.h

diff --git a/drivers/gpu/drm/rcar-du/Makefile b/drivers/gpu/drm/rcar-du/Makefile
index 827711e..2ade186 100644
--- a/drivers/gpu/drm/rcar-du/Makefile
+++ b/drivers/gpu/drm/rcar-du/Makefile
@@ -7,8 +7,7 @@ rcar-du-drm-y := rcar_du_crtc.o \
 		 rcar_du_plane.o \
 		 rcar_du_vgacon.o
 
-rcar-du-drm-$(CONFIG_DRM_RCAR_HDMI)	+= rcar_du_hdmicon.o \
-					   rcar_du_hdmienc.o
+rcar-du-drm-$(CONFIG_DRM_RCAR_HDMI)	+= rcar_du_hdmienc.o
 rcar-du-drm-$(CONFIG_DRM_RCAR_LVDS)	+= rcar_du_lvdsenc.o
 
 rcar-du-drm-$(CONFIG_DRM_RCAR_VSP)	+= rcar_du_vsp.o
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_encoder.c b/drivers/gpu/drm/rcar-du/rcar_du_encoder.c
index 4e939e4..1b16297 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_encoder.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_encoder.c
@@ -19,7 +19,6 @@
 
 #include "rcar_du_drv.h"
 #include "rcar_du_encoder.h"
-#include "rcar_du_hdmicon.h"
 #include "rcar_du_hdmienc.h"
 #include "rcar_du_kms.h"
 #include "rcar_du_lvdscon.h"
@@ -186,7 +185,7 @@ int rcar_du_encoder_init(struct rcar_du_device *rcdu,
 		break;
 
 	case DRM_MODE_ENCODER_TMDS:
-		ret = rcar_du_hdmi_connector_init(rcdu, renc);
+		/* connector managed by the bridge driver */
 		break;
 
 	default:
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_encoder.h b/drivers/gpu/drm/rcar-du/rcar_du_encoder.h
index 719b6f2a..dde523a 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_encoder.h
+++ b/drivers/gpu/drm/rcar-du/rcar_du_encoder.h
@@ -15,7 +15,6 @@
 #define __RCAR_DU_ENCODER_H__
 
 #include <drm/drm_crtc.h>
-#include <drm/drm_encoder_slave.h>
 
 struct rcar_du_device;
 struct rcar_du_hdmienc;
@@ -30,16 +29,16 @@ enum rcar_du_encoder_type {
 };
 
 struct rcar_du_encoder {
-	struct drm_encoder_slave slave;
+	struct drm_encoder base;
 	enum rcar_du_output output;
 	struct rcar_du_hdmienc *hdmi;
 	struct rcar_du_lvdsenc *lvds;
 };
 
 #define to_rcar_encoder(e) \
-	container_of(e, struct rcar_du_encoder, slave.base)
+	container_of(e, struct rcar_du_encoder, base)
 
-#define rcar_encoder_to_drm_encoder(e)	(&(e)->slave.base)
+#define rcar_encoder_to_drm_encoder(e)	(&(e)->base)
 
 struct rcar_du_connector {
 	struct drm_connector connector;
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_hdmicon.c b/drivers/gpu/drm/rcar-du/rcar_du_hdmicon.c
deleted file mode 100644
index 6c92714..0000000
--- a/drivers/gpu/drm/rcar-du/rcar_du_hdmicon.c
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * R-Car Display Unit HDMI Connector
- *
- * Copyright (C) 2014 Renesas Electronics Corporation
- *
- * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#include <drm/drmP.h>
-#include <drm/drm_atomic_helper.h>
-#include <drm/drm_crtc.h>
-#include <drm/drm_crtc_helper.h>
-#include <drm/drm_encoder_slave.h>
-
-#include "rcar_du_drv.h"
-#include "rcar_du_encoder.h"
-#include "rcar_du_hdmicon.h"
-#include "rcar_du_kms.h"
-
-#define to_slave_funcs(e)	(to_rcar_encoder(e)->slave.slave_funcs)
-
-static int rcar_du_hdmi_connector_get_modes(struct drm_connector *connector)
-{
-	struct rcar_du_connector *con = to_rcar_connector(connector);
-	struct drm_encoder *encoder = rcar_encoder_to_drm_encoder(con->encoder);
-	const struct drm_encoder_slave_funcs *sfuncs = to_slave_funcs(encoder);
-
-	if (sfuncs->get_modes == NULL)
-		return 0;
-
-	return sfuncs->get_modes(encoder, connector);
-}
-
-static int rcar_du_hdmi_connector_mode_valid(struct drm_connector *connector,
-					     struct drm_display_mode *mode)
-{
-	struct rcar_du_connector *con = to_rcar_connector(connector);
-	struct drm_encoder *encoder = rcar_encoder_to_drm_encoder(con->encoder);
-	const struct drm_encoder_slave_funcs *sfuncs = to_slave_funcs(encoder);
-
-	if (sfuncs->mode_valid == NULL)
-		return MODE_OK;
-
-	return sfuncs->mode_valid(encoder, mode);
-}
-
-static const struct drm_connector_helper_funcs connector_helper_funcs = {
-	.get_modes = rcar_du_hdmi_connector_get_modes,
-	.mode_valid = rcar_du_hdmi_connector_mode_valid,
-	.best_encoder = rcar_du_connector_best_encoder,
-};
-
-static enum drm_connector_status
-rcar_du_hdmi_connector_detect(struct drm_connector *connector, bool force)
-{
-	struct rcar_du_connector *con = to_rcar_connector(connector);
-	struct drm_encoder *encoder = rcar_encoder_to_drm_encoder(con->encoder);
-	const struct drm_encoder_slave_funcs *sfuncs = to_slave_funcs(encoder);
-
-	if (sfuncs->detect == NULL)
-		return connector_status_unknown;
-
-	return sfuncs->detect(encoder, connector);
-}
-
-static const struct drm_connector_funcs connector_funcs = {
-	.dpms = drm_atomic_helper_connector_dpms,
-	.reset = drm_atomic_helper_connector_reset,
-	.detect = rcar_du_hdmi_connector_detect,
-	.fill_modes = drm_helper_probe_single_connector_modes,
-	.destroy = drm_connector_cleanup,
-	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
-	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
-};
-
-int rcar_du_hdmi_connector_init(struct rcar_du_device *rcdu,
-				struct rcar_du_encoder *renc)
-{
-	struct drm_encoder *encoder = rcar_encoder_to_drm_encoder(renc);
-	struct rcar_du_connector *rcon;
-	struct drm_connector *connector;
-	int ret;
-
-	rcon = devm_kzalloc(rcdu->dev, sizeof(*rcon), GFP_KERNEL);
-	if (rcon == NULL)
-		return -ENOMEM;
-
-	connector = &rcon->connector;
-	connector->display_info.width_mm = 0;
-	connector->display_info.height_mm = 0;
-	connector->interlace_allowed = true;
-	connector->polled = DRM_CONNECTOR_POLL_HPD;
-
-	ret = drm_connector_init(rcdu->ddev, connector, &connector_funcs,
-				 DRM_MODE_CONNECTOR_HDMIA);
-	if (ret < 0)
-		return ret;
-
-	drm_connector_helper_add(connector, &connector_helper_funcs);
-
-	connector->dpms = DRM_MODE_DPMS_OFF;
-	drm_object_property_set_value(&connector->base,
-		rcdu->ddev->mode_config.dpms_property, DRM_MODE_DPMS_OFF);
-
-	ret = drm_mode_connector_attach_encoder(connector, encoder);
-	if (ret < 0)
-		return ret;
-
-	rcon->encoder = renc;
-
-	return 0;
-}
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_hdmicon.h b/drivers/gpu/drm/rcar-du/rcar_du_hdmicon.h
deleted file mode 100644
index 87daa94..0000000
--- a/drivers/gpu/drm/rcar-du/rcar_du_hdmicon.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * R-Car Display Unit HDMI Connector
- *
- * Copyright (C) 2014 Renesas Electronics Corporation
- *
- * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#ifndef __RCAR_DU_HDMICON_H__
-#define __RCAR_DU_HDMICON_H__
-
-struct rcar_du_device;
-struct rcar_du_encoder;
-
-#if IS_ENABLED(CONFIG_DRM_RCAR_HDMI)
-int rcar_du_hdmi_connector_init(struct rcar_du_device *rcdu,
-				struct rcar_du_encoder *renc);
-#else
-static inline int rcar_du_hdmi_connector_init(struct rcar_du_device *rcdu,
-					      struct rcar_du_encoder *renc)
-{
-	return -ENOSYS;
-}
-#endif
-
-#endif /* __RCAR_DU_HDMICON_H__ */
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_hdmienc.c b/drivers/gpu/drm/rcar-du/rcar_du_hdmienc.c
index 461662d..15d553a 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_hdmienc.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_hdmienc.c
@@ -16,7 +16,6 @@
 #include <drm/drmP.h>
 #include <drm/drm_crtc.h>
 #include <drm/drm_crtc_helper.h>
-#include <drm/drm_encoder_slave.h>
 
 #include "rcar_du_drv.h"
 #include "rcar_du_encoder.h"
@@ -25,20 +24,14 @@
 
 struct rcar_du_hdmienc {
 	struct rcar_du_encoder *renc;
-	struct device *dev;
 	bool enabled;
 };
 
 #define to_rcar_hdmienc(e)	(to_rcar_encoder(e)->hdmi)
-#define to_slave_funcs(e)	(to_rcar_encoder(e)->slave.slave_funcs)
 
 static void rcar_du_hdmienc_disable(struct drm_encoder *encoder)
 {
 	struct rcar_du_hdmienc *hdmienc = to_rcar_hdmienc(encoder);
-	const struct drm_encoder_slave_funcs *sfuncs = to_slave_funcs(encoder);
-
-	if (sfuncs->dpms)
-		sfuncs->dpms(encoder, DRM_MODE_DPMS_OFF);
 
 	if (hdmienc->renc->lvds)
 		rcar_du_lvdsenc_enable(hdmienc->renc->lvds, encoder->crtc,
@@ -50,15 +43,11 @@ static void rcar_du_hdmienc_disable(struct drm_encoder *encoder)
 static void rcar_du_hdmienc_enable(struct drm_encoder *encoder)
 {
 	struct rcar_du_hdmienc *hdmienc = to_rcar_hdmienc(encoder);
-	const struct drm_encoder_slave_funcs *sfuncs = to_slave_funcs(encoder);
 
 	if (hdmienc->renc->lvds)
 		rcar_du_lvdsenc_enable(hdmienc->renc->lvds, encoder->crtc,
 				       true);
 
-	if (sfuncs->dpms)
-		sfuncs->dpms(encoder, DRM_MODE_DPMS_ON);
-
 	hdmienc->enabled = true;
 }
 
@@ -67,18 +56,13 @@ static int rcar_du_hdmienc_atomic_check(struct drm_encoder *encoder,
 					struct drm_connector_state *conn_state)
 {
 	struct rcar_du_hdmienc *hdmienc = to_rcar_hdmienc(encoder);
-	const struct drm_encoder_slave_funcs *sfuncs = to_slave_funcs(encoder);
 	struct drm_display_mode *adjusted_mode = &crtc_state->adjusted_mode;
-	const struct drm_display_mode *mode = &crtc_state->mode;
 
 	if (hdmienc->renc->lvds)
 		rcar_du_lvdsenc_atomic_check(hdmienc->renc->lvds,
 					     adjusted_mode);
 
-	if (sfuncs->mode_fixup == NULL)
-		return 0;
-
-	return sfuncs->mode_fixup(encoder, mode, adjusted_mode) ? 0 : -EINVAL;
+	return 0;
 }
 
 static void rcar_du_hdmienc_mode_set(struct drm_encoder *encoder,
@@ -86,10 +70,6 @@ static void rcar_du_hdmienc_mode_set(struct drm_encoder *encoder,
 				     struct drm_display_mode *adjusted_mode)
 {
 	struct rcar_du_hdmienc *hdmienc = to_rcar_hdmienc(encoder);
-	const struct drm_encoder_slave_funcs *sfuncs = to_slave_funcs(encoder);
-
-	if (sfuncs->mode_set)
-		sfuncs->mode_set(encoder, mode, adjusted_mode);
 
 	rcar_du_crtc_route_output(encoder->crtc, hdmienc->renc->output);
 }
@@ -109,7 +89,6 @@ static void rcar_du_hdmienc_cleanup(struct drm_encoder *encoder)
 		rcar_du_hdmienc_disable(encoder);
 
 	drm_encoder_cleanup(encoder);
-	put_device(hdmienc->dev);
 }
 
 static const struct drm_encoder_funcs encoder_funcs = {
@@ -120,8 +99,7 @@ int rcar_du_hdmienc_init(struct rcar_du_device *rcdu,
 			 struct rcar_du_encoder *renc, struct device_node *np)
 {
 	struct drm_encoder *encoder = rcar_encoder_to_drm_encoder(renc);
-	struct drm_i2c_encoder_driver *driver;
-	struct i2c_client *i2c_slave;
+	struct drm_bridge *bridge;
 	struct rcar_du_hdmienc *hdmienc;
 	int ret;
 
@@ -129,44 +107,33 @@ int rcar_du_hdmienc_init(struct rcar_du_device *rcdu,
 	if (hdmienc == NULL)
 		return -ENOMEM;
 
-	/* Locate the slave I2C device and driver. */
-	i2c_slave = of_find_i2c_device_by_node(np);
-	if (!i2c_slave || !i2c_get_clientdata(i2c_slave)) {
-		dev_dbg(rcdu->dev,
-			"can't get I2C slave for %s, deferring probe\n",
+	/* Locate the DRM bridge from the HDMI encoder DT node. */
+	bridge = of_drm_find_bridge(np);
+	if (!bridge) {
+		dev_dbg(rcdu->dev, "can't get bridge for %s, deferring probe\n",
 			of_node_full_name(np));
 		return -EPROBE_DEFER;
 	}
 
-	hdmienc->dev = &i2c_slave->dev;
-
-	if (hdmienc->dev->driver == NULL) {
-		dev_dbg(rcdu->dev,
-			"I2C slave %s not probed yet, deferring probe\n",
-			dev_name(hdmienc->dev));
-		ret = -EPROBE_DEFER;
-		goto error;
-	}
-
-	/* Initialize the slave encoder. */
-	driver = to_drm_i2c_encoder_driver(to_i2c_driver(hdmienc->dev->driver));
-	ret = driver->encoder_init(i2c_slave, rcdu->ddev, &renc->slave);
-	if (ret < 0)
-		goto error;
-
 	ret = drm_encoder_init(rcdu->ddev, encoder, &encoder_funcs,
 			       DRM_MODE_ENCODER_TMDS, NULL);
 	if (ret < 0)
-		goto error;
+		return ret;
 
 	drm_encoder_helper_add(encoder, &encoder_helper_funcs);
 
 	renc->hdmi = hdmienc;
 	hdmienc->renc = renc;
 
-	return 0;
+	/* Link the bridge to the encoder. */
+	bridge->encoder = encoder;
+	encoder->bridge = bridge;
 
-error:
-	put_device(hdmienc->dev);
-	return ret;
+	ret = drm_bridge_attach(rcdu->ddev, bridge);
+	if (ret) {
+		drm_encoder_cleanup(encoder);
+		return ret;
+	}
+
+	return 0;
 }
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [RFC 02/21] drm: i2c: adv7511: Convert to drm_bridge
  2016-05-30 15:59 [RFC 00/21] Renesas r8a7795/Salvator-X HDMI output prototype Ulrich Hecht
  2016-05-30 16:00 ` [RFC 01/21] drm: rcar-du: Remove i2c slave encoder interface for hdmi encoder Ulrich Hecht
@ 2016-05-30 16:00 ` Ulrich Hecht
  2016-05-30 16:00 ` [RFC 03/21] media: vsp1: Set format to RPF input source Ulrich Hecht
                   ` (20 subsequent siblings)
  22 siblings, 0 replies; 34+ messages in thread
From: Ulrich Hecht @ 2016-05-30 16:00 UTC (permalink / raw)
  To: linux-renesas-soc, geert
  Cc: kuninori.morimoto.gx, laurent.pinchart, dri-devel, architt, vz,
	koji.matsuoka.xm, Laurent Pinchart, Geert Uytterhoeven

From: Archit Taneja <architt@codeaurora.org>

We don't want to use the old i2c slave encoder interface anymore.

Remove that and make the i2c driver create a drm_bridge entity instead.
Converting to bridges helps because the kms drivers don't need to
exract encoder slave ops from this driver and use it within their
own encoder/connector ops.

The driver now creates its own connector when a kms driver attaches
itself to the bridge. Therefore, kms drivers don't need to create
their own connectors anymore.

The old encoder slave ops are now used by the new bridge and connector
entities.

Signed-off-by: Archit Taneja <architt@codeaurora.org>
Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
 drivers/gpu/drm/i2c/adv7511.c | 224 ++++++++++++++++++++++++++++--------------
 1 file changed, 150 insertions(+), 74 deletions(-)

diff --git a/drivers/gpu/drm/i2c/adv7511.c b/drivers/gpu/drm/i2c/adv7511.c
index a02112b..a104b43 100644
--- a/drivers/gpu/drm/i2c/adv7511.c
+++ b/drivers/gpu/drm/i2c/adv7511.c
@@ -16,7 +16,8 @@
 #include <drm/drmP.h>
 #include <drm/drm_crtc_helper.h>
 #include <drm/drm_edid.h>
-#include <drm/drm_encoder_slave.h>
+#include <drm/drm_atomic.h>
+#include <drm/drm_atomic_helper.h>
 
 #include "adv7511.h"
 
@@ -36,7 +37,8 @@ struct adv7511 {
 	bool edid_read;
 
 	wait_queue_head_t wq;
-	struct drm_encoder *encoder;
+	struct drm_bridge bridge;
+	struct drm_connector connector;
 
 	bool embedded_sync;
 	enum adv7511_sync_polarity vsync_polarity;
@@ -48,11 +50,6 @@ struct adv7511 {
 	struct gpio_desc *gpio_pd;
 };
 
-static struct adv7511 *encoder_to_adv7511(struct drm_encoder *encoder)
-{
-	return to_encoder_slave(encoder)->slave_priv;
-}
-
 /* ADI recommended values for proper operation. */
 static const struct reg_sequence adv7511_fixed_registers[] = {
 	{ 0x98, 0x03 },
@@ -446,8 +443,8 @@ static int adv7511_irq_process(struct adv7511 *adv7511)
 	regmap_write(adv7511->regmap, ADV7511_REG_INT(0), irq0);
 	regmap_write(adv7511->regmap, ADV7511_REG_INT(1), irq1);
 
-	if (irq0 & ADV7511_INT0_HPD && adv7511->encoder)
-		drm_helper_hpd_irq_event(adv7511->encoder->dev);
+	if (irq0 & ADV7511_INT0_HPD && adv7511->bridge.dev)
+		drm_helper_hpd_irq_event(adv7511->bridge.dev);
 
 	if (irq0 & ADV7511_INT0_EDID_READY || irq1 & ADV7511_INT1_DDC_ERROR) {
 		adv7511->edid_read = true;
@@ -563,13 +560,12 @@ static int adv7511_get_edid_block(void *data, u8 *buf, unsigned int block,
 }
 
 /* -----------------------------------------------------------------------------
- * Encoder operations
+ * ADV75xx helpers
  */
 
-static int adv7511_get_modes(struct drm_encoder *encoder,
+static int adv7511_get_modes(struct adv7511 *adv7511,
 			     struct drm_connector *connector)
 {
-	struct adv7511 *adv7511 = encoder_to_adv7511(encoder);
 	struct edid *edid;
 	unsigned int count;
 
@@ -606,21 +602,9 @@ static int adv7511_get_modes(struct drm_encoder *encoder,
 	return count;
 }
 
-static void adv7511_encoder_dpms(struct drm_encoder *encoder, int mode)
-{
-	struct adv7511 *adv7511 = encoder_to_adv7511(encoder);
-
-	if (mode == DRM_MODE_DPMS_ON)
-		adv7511_power_on(adv7511);
-	else
-		adv7511_power_off(adv7511);
-}
-
 static enum drm_connector_status
-adv7511_encoder_detect(struct drm_encoder *encoder,
-		       struct drm_connector *connector)
+adv7511_detect(struct adv7511 *adv7511, struct drm_connector *connector)
 {
-	struct adv7511 *adv7511 = encoder_to_adv7511(encoder);
 	enum drm_connector_status status;
 	unsigned int val;
 	bool hpd;
@@ -644,7 +628,7 @@ adv7511_encoder_detect(struct drm_encoder *encoder,
 	if (status == connector_status_connected && hpd && adv7511->powered) {
 		regcache_mark_dirty(adv7511->regmap);
 		adv7511_power_on(adv7511);
-		adv7511_get_modes(encoder, connector);
+		adv7511_get_modes(adv7511, connector);
 		if (adv7511->status == connector_status_connected)
 			status = connector_status_disconnected;
 	} else {
@@ -658,8 +642,8 @@ adv7511_encoder_detect(struct drm_encoder *encoder,
 	return status;
 }
 
-static int adv7511_encoder_mode_valid(struct drm_encoder *encoder,
-				      struct drm_display_mode *mode)
+static int adv7511_mode_valid(struct adv7511 *adv7511,
+			      struct drm_display_mode *mode)
 {
 	if (mode->clock > 165000)
 		return MODE_CLOCK_HIGH;
@@ -667,11 +651,10 @@ static int adv7511_encoder_mode_valid(struct drm_encoder *encoder,
 	return MODE_OK;
 }
 
-static void adv7511_encoder_mode_set(struct drm_encoder *encoder,
-				     struct drm_display_mode *mode,
-				     struct drm_display_mode *adj_mode)
+static void adv7511_mode_set(struct adv7511 *adv7511,
+			     struct drm_display_mode *mode,
+			     struct drm_display_mode *adj_mode)
 {
-	struct adv7511 *adv7511 = encoder_to_adv7511(encoder);
 	unsigned int low_refresh_rate;
 	unsigned int hsync_polarity = 0;
 	unsigned int vsync_polarity = 0;
@@ -762,12 +745,122 @@ static void adv7511_encoder_mode_set(struct drm_encoder *encoder,
 	adv7511->f_tmds = mode->clock;
 }
 
-static const struct drm_encoder_slave_funcs adv7511_encoder_funcs = {
-	.dpms = adv7511_encoder_dpms,
-	.mode_valid = adv7511_encoder_mode_valid,
-	.mode_set = adv7511_encoder_mode_set,
-	.detect = adv7511_encoder_detect,
-	.get_modes = adv7511_get_modes,
+/* Connector funcs */
+static struct adv7511 *connector_to_adv7511(struct drm_connector *connector)
+{
+	return container_of(connector, struct adv7511, connector);
+}
+
+static int adv7511_connector_get_modes(struct drm_connector *connector)
+{
+	struct adv7511 *adv = connector_to_adv7511(connector);
+
+	return adv7511_get_modes(adv, connector);
+}
+
+static struct drm_encoder *
+adv7511_connector_best_encoder(struct drm_connector *connector)
+{
+	struct adv7511 *adv = connector_to_adv7511(connector);
+
+	return adv->bridge.encoder;
+}
+
+static enum drm_mode_status
+adv7511_connector_mode_valid(struct drm_connector *connector,
+			     struct drm_display_mode *mode)
+{
+	struct adv7511 *adv = connector_to_adv7511(connector);
+
+	return adv7511_mode_valid(adv, mode);
+}
+
+static struct drm_connector_helper_funcs adv7511_connector_helper_funcs = {
+	.get_modes = adv7511_connector_get_modes,
+	.best_encoder = adv7511_connector_best_encoder,
+	.mode_valid = adv7511_connector_mode_valid,
+};
+
+static enum drm_connector_status
+adv7511_connector_detect(struct drm_connector *connector, bool force)
+{
+	struct adv7511 *adv = connector_to_adv7511(connector);
+
+	return adv7511_detect(adv, connector);
+}
+
+static struct drm_connector_funcs adv7511_connector_funcs = {
+	.dpms = drm_atomic_helper_connector_dpms,
+	.fill_modes = drm_helper_probe_single_connector_modes,
+	.detect = adv7511_connector_detect,
+	.destroy = drm_connector_cleanup,
+	.reset = drm_atomic_helper_connector_reset,
+	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
+	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
+};
+
+/* Bridge funcs */
+static struct adv7511 *bridge_to_adv7511(struct drm_bridge *bridge)
+{
+	return container_of(bridge, struct adv7511, bridge);
+}
+
+static void adv7511_bridge_enable(struct drm_bridge *bridge)
+{
+	struct adv7511 *adv = bridge_to_adv7511(bridge);
+
+	adv7511_power_on(adv);
+}
+
+static void adv7511_bridge_disable(struct drm_bridge *bridge)
+{
+	struct adv7511 *adv = bridge_to_adv7511(bridge);
+
+	adv7511_power_off(adv);
+}
+
+static void adv7511_bridge_mode_set(struct drm_bridge *bridge,
+				    struct drm_display_mode *mode,
+				    struct drm_display_mode *adj_mode)
+{
+	struct adv7511 *adv = bridge_to_adv7511(bridge);
+
+	adv7511_mode_set(adv, mode, adj_mode);
+}
+
+static int adv7511_bridge_attach(struct drm_bridge *bridge)
+{
+	struct adv7511 *adv = bridge_to_adv7511(bridge);
+	int ret;
+
+	if (!bridge->encoder) {
+		DRM_ERROR("Parent encoder object not found");
+		return -ENODEV;
+	}
+
+	adv->connector.polled = DRM_CONNECTOR_POLL_HPD;
+
+	ret = drm_connector_init(bridge->dev, &adv->connector,
+				 &adv7511_connector_funcs,
+				 DRM_MODE_CONNECTOR_HDMIA);
+	if (ret) {
+		DRM_ERROR("Failed to initialize connector with drm\n");
+		return ret;
+	}
+	drm_connector_helper_add(&adv->connector,
+				 &adv7511_connector_helper_funcs);
+	drm_mode_connector_attach_encoder(&adv->connector, bridge->encoder);
+
+	drm_helper_hpd_irq_event(adv->connector.dev);
+
+	return ret;
+}
+
+static struct drm_bridge_funcs adv7511_bridge_funcs = {
+	.enable = adv7511_bridge_enable,
+	.disable = adv7511_bridge_disable,
+	.mode_set = adv7511_bridge_mode_set,
+	.attach = adv7511_bridge_attach,
 };
 
 /* -----------------------------------------------------------------------------
@@ -944,6 +1037,15 @@ static int adv7511_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
 
 	adv7511_set_link_config(adv7511, &link_config);
 
+	adv7511->bridge.funcs = &adv7511_bridge_funcs;
+	adv7511->bridge.of_node = dev->of_node;
+
+	ret = drm_bridge_add(&adv7511->bridge);
+	if (ret) {
+		dev_err(dev, "failed to add adv7511 bridge\n");
+		goto err_i2c_unregister_device;
+	}
+
 	return 0;
 
 err_i2c_unregister_device:
@@ -956,6 +1058,8 @@ static int adv7511_remove(struct i2c_client *i2c)
 {
 	struct adv7511 *adv7511 = i2c_get_clientdata(i2c);
 
+	drm_bridge_remove(&adv7511->bridge);
+
 	i2c_unregister_device(adv7511->i2c_edid);
 
 	kfree(adv7511->edid);
@@ -963,20 +1067,6 @@ static int adv7511_remove(struct i2c_client *i2c)
 	return 0;
 }
 
-static int adv7511_encoder_init(struct i2c_client *i2c, struct drm_device *dev,
-				struct drm_encoder_slave *encoder)
-{
-
-	struct adv7511 *adv7511 = i2c_get_clientdata(i2c);
-
-	encoder->slave_priv = adv7511;
-	encoder->slave_funcs = &adv7511_encoder_funcs;
-
-	adv7511->encoder = &encoder->base;
-
-	return 0;
-}
-
 static const struct i2c_device_id adv7511_i2c_ids[] = {
 	{ "adv7511", 0 },
 	{ "adv7511w", 0 },
@@ -993,31 +1083,17 @@ static const struct of_device_id adv7511_of_ids[] = {
 };
 MODULE_DEVICE_TABLE(of, adv7511_of_ids);
 
-static struct drm_i2c_encoder_driver adv7511_driver = {
-	.i2c_driver = {
-		.driver = {
-			.name = "adv7511",
-			.of_match_table = adv7511_of_ids,
-		},
-		.id_table = adv7511_i2c_ids,
-		.probe = adv7511_probe,
-		.remove = adv7511_remove,
+static struct i2c_driver adv7511_driver = {
+	.driver = {
+		.name = "adv7511",
+		.of_match_table = adv7511_of_ids,
 	},
-
-	.encoder_init = adv7511_encoder_init,
+	.id_table = adv7511_i2c_ids,
+	.probe = adv7511_probe,
+	.remove = adv7511_remove,
 };
 
-static int __init adv7511_init(void)
-{
-	return drm_i2c_encoder_register(THIS_MODULE, &adv7511_driver);
-}
-module_init(adv7511_init);
-
-static void __exit adv7511_exit(void)
-{
-	drm_i2c_encoder_unregister(&adv7511_driver);
-}
-module_exit(adv7511_exit);
+module_i2c_driver(adv7511_driver);
 
 MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
 MODULE_DESCRIPTION("ADV7511 HDMI transmitter driver");
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [RFC 03/21] media: vsp1: Set format to RPF input source
  2016-05-30 15:59 [RFC 00/21] Renesas r8a7795/Salvator-X HDMI output prototype Ulrich Hecht
  2016-05-30 16:00 ` [RFC 01/21] drm: rcar-du: Remove i2c slave encoder interface for hdmi encoder Ulrich Hecht
  2016-05-30 16:00 ` [RFC 02/21] drm: i2c: adv7511: Convert to drm_bridge Ulrich Hecht
@ 2016-05-30 16:00 ` Ulrich Hecht
  2016-05-30 16:00 ` [RFC 04/21] drm: bridge/dw_hdmi: add dw hdmi i2c bus adapter support Ulrich Hecht
                   ` (19 subsequent siblings)
  22 siblings, 0 replies; 34+ messages in thread
From: Ulrich Hecht @ 2016-05-30 16:00 UTC (permalink / raw)
  To: linux-renesas-soc, geert
  Cc: kuninori.morimoto.gx, laurent.pinchart, dri-devel, architt, vz,
	koji.matsuoka.xm, Geert Uytterhoeven

From: Koji Matsuoka <koji.matsuoka.xm@renesas.com>

The output format of the RPF must be unified in RGB or YCbCr by
specification of the H/W. To unify the output format in RGB in
driver, if the input format is YCbCr, the output format must be
converted to RGB by CSC (Color Space Conversion).
The driver is missing the format setting of the RPF input source,
so it does not pass through the process to enable the CSC.
This patch adds format setting of the RPF input source.

Signed-off-by: Koji Matsuoka <koji.matsuoka.xm@renesas.com>
[geert: Rebased, s/fmtinfo/rpf->fmtinfo]
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
 drivers/media/platform/vsp1/vsp1_drm.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/media/platform/vsp1/vsp1_drm.c b/drivers/media/platform/vsp1/vsp1_drm.c
index ff961b2..c5ee06b 100644
--- a/drivers/media/platform/vsp1/vsp1_drm.c
+++ b/drivers/media/platform/vsp1/vsp1_drm.c
@@ -383,6 +383,12 @@ static int vsp1_du_setup_rpf_pipe(struct vsp1_device *vsp1,
 
 	/* BRU sink, propagate the format from the RPF source. */
 	format.pad = bru_input;
+	format.format.code = rpf->fmtinfo->mbus;
+
+	ret = v4l2_subdev_call(&rpf->entity.subdev, pad, set_fmt, NULL,
+			       &format);
+	if (ret < 0)
+		return ret;
 
 	ret = v4l2_subdev_call(&vsp1->bru->entity.subdev, pad, set_fmt, NULL,
 			       &format);
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [RFC 04/21] drm: bridge/dw_hdmi: add dw hdmi i2c bus adapter support
  2016-05-30 15:59 [RFC 00/21] Renesas r8a7795/Salvator-X HDMI output prototype Ulrich Hecht
                   ` (2 preceding siblings ...)
  2016-05-30 16:00 ` [RFC 03/21] media: vsp1: Set format to RPF input source Ulrich Hecht
@ 2016-05-30 16:00 ` Ulrich Hecht
  2016-05-30 17:26     ` Vladimir Zapolskiy
  2016-05-30 16:00 ` [RFC 05/21] drm: bridge/dw_hdmi: Fix R-Car Gen3 device support Ulrich Hecht
                   ` (18 subsequent siblings)
  22 siblings, 1 reply; 34+ messages in thread
From: Ulrich Hecht @ 2016-05-30 16:00 UTC (permalink / raw)
  To: linux-renesas-soc, geert
  Cc: kuninori.morimoto.gx, laurent.pinchart, dri-devel, architt, vz,
	koji.matsuoka.xm, Vladimir Zapolskiy, Geert Uytterhoeven

From: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>

The change adds support of internal HDMI I2C master controller, this
subdevice is used by default, if "ddc-i2c-bus" DT property is omitted.

The main purpose of this functionality is to support reading EDID from
an HDMI monitor on boards, which don't have an I2C bus connected to
DDC pins.

Signed-off-by: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
Signed-off-by: Koji Matsuoka <koji.matsuoka.xm@renesas.com>
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
 drivers/gpu/drm/bridge/dw-hdmi.c | 331 ++++++++++++++++++++++++++++++++++++++-
 1 file changed, 325 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c
index c9d9412..1cfff2f 100644
--- a/drivers/gpu/drm/bridge/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/dw-hdmi.c
@@ -1,14 +1,15 @@
 /*
+ * DesignWare High-Definition Multimedia Interface (HDMI) driver
+ *
+ * Copyright (C) 2013-2015 Mentor Graphics Inc.
  * Copyright (C) 2011-2013 Freescale Semiconductor, Inc.
+ * Copyright (C) 2010, Guennadi Liakhovetski <g.liakhovetski at gmx.de>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
  *
- * Designware High-Definition Multimedia Interface (HDMI) driver
- *
- * Copyright (C) 2010, Guennadi Liakhovetski <g.liakhovetski@gmx.de>
  */
 #include <linux/module.h>
 #include <linux/irq.h>
@@ -31,6 +32,26 @@
 #include "dw-hdmi.h"
 #include "dw-hdmi-audio.h"
 
+/* HDMI_IH_I2CM_STAT0 and HDMI_IH_MUTE_I2CM_STAT0 register bits */
+#define HDMI_IH_I2CM_STAT0_ERROR		BIT(0)
+#define HDMI_IH_I2CM_STAT0_DONE			BIT(1)
+
+/* HDMI_I2CM_OPERATION register bits */
+#define HDMI_I2CM_OPERATION_READ		BIT(0)
+#define HDMI_I2CM_OPERATION_READ_EXT		BIT(1)
+#define HDMI_I2CM_OPERATION_WRITE		BIT(4)
+
+/* HDMI_I2CM_INT register bits */
+#define HDMI_I2CM_INT_DONE_MASK			BIT(2)
+#define HDMI_I2CM_INT_DONE_POL			BIT(3)
+
+/* HDMI_I2CM_CTLINT register bits */
+#define HDMI_I2CM_CTLINT_ARB_MASK		BIT(2)
+#define HDMI_I2CM_CTLINT_ARB_POL		BIT(3)
+#define HDMI_I2CM_CTLINT_NAC_MASK		BIT(6)
+#define HDMI_I2CM_CTLINT_NAC_POL		BIT(7)
+
+
 #define HDMI_EDID_LEN		512
 
 #define RGB			0
@@ -101,6 +122,17 @@ struct hdmi_data_info {
 	struct hdmi_vmode video_mode;
 };
 
+struct dw_hdmi_i2c {
+	struct i2c_adapter	adap;
+
+	spinlock_t		lock;
+	struct completion	cmp;
+	u8			stat;
+
+	u8			slave_reg;
+	bool			is_regaddr;
+};
+
 struct dw_hdmi {
 	struct drm_connector connector;
 	struct drm_encoder *encoder;
@@ -111,6 +143,7 @@ struct dw_hdmi {
 	struct device *dev;
 	struct clk *isfr_clk;
 	struct clk *iahb_clk;
+	struct dw_hdmi_i2c *i2c;
 
 	struct hdmi_data_info hdmi_data;
 	const struct dw_hdmi_plat_data *plat_data;
@@ -198,6 +231,242 @@ static void hdmi_mask_writeb(struct dw_hdmi *hdmi, u8 data, unsigned int reg,
 	hdmi_modb(hdmi, data << shift, mask, reg);
 }
 
+static void dw_hdmi_i2c_init(struct dw_hdmi *hdmi)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&hdmi->i2c->lock, flags);
+
+	/* Set Fast Mode speed */
+	hdmi_writeb(hdmi, 0x0b, HDMI_I2CM_DIV);
+
+	/* Software reset */
+	hdmi_writeb(hdmi, 0x00, HDMI_I2CM_SOFTRSTZ);
+
+	/* Set done, not acknowledged and arbitration interrupt polarities */
+	hdmi_writeb(hdmi, HDMI_I2CM_INT_DONE_POL, HDMI_I2CM_INT);
+	hdmi_writeb(hdmi, HDMI_I2CM_CTLINT_NAC_POL | HDMI_I2CM_CTLINT_ARB_POL,
+		    HDMI_I2CM_CTLINT);
+
+	/* Clear DONE and ERROR interrupts */
+	hdmi_writeb(hdmi, HDMI_IH_I2CM_STAT0_ERROR | HDMI_IH_I2CM_STAT0_DONE,
+		    HDMI_IH_I2CM_STAT0);
+
+	/* Mute DONE and ERROR interrupts */
+	hdmi_writeb(hdmi, HDMI_IH_I2CM_STAT0_ERROR | HDMI_IH_I2CM_STAT0_DONE,
+		    HDMI_IH_MUTE_I2CM_STAT0);
+
+	spin_unlock_irqrestore(&hdmi->i2c->lock, flags);
+}
+
+static int dw_hdmi_i2c_read(struct dw_hdmi *hdmi,
+			    unsigned char *buf, int length)
+{
+	int stat;
+	unsigned long flags;
+	struct dw_hdmi_i2c *i2c = hdmi->i2c;
+
+	spin_lock_irqsave(&i2c->lock, flags);
+
+	if (!i2c->is_regaddr) {
+		dev_dbg(hdmi->dev, "set read register address to 0\n");
+		i2c->slave_reg = 0x00;
+		i2c->is_regaddr = true;
+	}
+
+	while (length--) {
+		hdmi_writeb(hdmi, i2c->slave_reg++, HDMI_I2CM_ADDRESS);
+		hdmi_writeb(hdmi,
+			    HDMI_I2CM_OPERATION_READ, HDMI_I2CM_OPERATION);
+		i2c->stat = 0;
+
+		spin_unlock_irqrestore(&i2c->lock, flags);
+
+		stat = wait_for_completion_interruptible_timeout(&i2c->cmp,
+								 HZ / 10);
+		if (!stat)
+			return -ETIMEDOUT;
+		if (stat < 0)
+			return stat;
+
+		spin_lock_irqsave(&i2c->lock, flags);
+
+		/* Check for error condition on the bus */
+		if (i2c->stat & HDMI_IH_I2CM_STAT0_ERROR) {
+			spin_unlock_irqrestore(&i2c->lock, flags);
+			return -EIO;
+		}
+
+		*buf++ = hdmi_readb(hdmi, HDMI_I2CM_DATAI);
+	}
+
+	spin_unlock_irqrestore(&i2c->lock, flags);
+
+	return 0;
+}
+
+static int dw_hdmi_i2c_write(struct dw_hdmi *hdmi,
+				  unsigned char *buf, int length)
+{
+	int stat;
+	unsigned long flags;
+	struct dw_hdmi_i2c *i2c = hdmi->i2c;
+
+	spin_lock_irqsave(&i2c->lock, flags);
+
+	if (!i2c->is_regaddr) {
+		if (length) {
+			/* Use the first write byte as register address */
+			i2c->slave_reg = buf[0];
+			length--;
+			buf++;
+		} else {
+			dev_dbg(hdmi->dev, "set write register address to 0\n");
+			i2c->slave_reg = 0x00;
+		}
+		i2c->is_regaddr = true;
+	}
+
+	while (length--) {
+		hdmi_writeb(hdmi, *buf++, HDMI_I2CM_DATAO);
+		hdmi_writeb(hdmi, i2c->slave_reg++, HDMI_I2CM_ADDRESS);
+		hdmi_writeb(hdmi,
+			    HDMI_I2CM_OPERATION_WRITE, HDMI_I2CM_OPERATION);
+		i2c->stat = 0;
+
+		spin_unlock_irqrestore(&i2c->lock, flags);
+
+		stat = wait_for_completion_interruptible_timeout(&i2c->cmp,
+								 HZ / 10);
+		if (!stat)
+			return -ETIMEDOUT;
+		if (stat < 0)
+			return stat;
+
+		spin_lock_irqsave(&i2c->lock, flags);
+
+		/* Check for error condition on the bus */
+		if (i2c->stat & HDMI_IH_I2CM_STAT0_ERROR) {
+			spin_unlock_irqrestore(&i2c->lock, flags);
+			return -EIO;
+		}
+	}
+
+	spin_unlock_irqrestore(&i2c->lock, flags);
+
+	return 0;
+}
+
+static int dw_hdmi_i2c_xfer(struct i2c_adapter *adap,
+			    struct i2c_msg *msgs, int num)
+{
+	struct dw_hdmi *hdmi = i2c_get_adapdata(adap);
+	struct dw_hdmi_i2c *i2c = hdmi->i2c;
+
+	int i, ret;
+	u8 addr;
+	unsigned long flags;
+
+	dev_dbg(hdmi->dev, "xfer: num: %d, addr: 0x%x\n", num, msgs[0].addr);
+
+	spin_lock_irqsave(&i2c->lock, flags);
+
+	hdmi_writeb(hdmi, 0x00, HDMI_IH_MUTE_I2CM_STAT0);
+
+	/* Set slave device address from the first transaction */
+	addr = msgs[0].addr;
+	hdmi_writeb(hdmi, addr, HDMI_I2CM_SLAVE);
+
+	/* Set slave device register address on transfer */
+	i2c->is_regaddr = false;
+
+	spin_unlock_irqrestore(&i2c->lock, flags);
+
+	for (i = 0; i < num; i++) {
+		dev_dbg(hdmi->dev, "xfer: num: %d/%d, len: %d, flags: 0x%x\n",
+			i + 1, num, msgs[i].len, msgs[i].flags);
+
+		if (msgs[i].addr != addr) {
+			dev_warn(hdmi->dev,
+				 "unsupported transaction, changed slave address\n");
+			ret = -EOPNOTSUPP;
+			break;
+		}
+
+		if (msgs[i].len == 0) {
+			dev_dbg(hdmi->dev,
+				 "unsupported transaction %d/%d, no data\n",
+				 i + 1, num);
+			ret = -EOPNOTSUPP;
+			break;
+		}
+
+		if (msgs[i].flags & I2C_M_RD)
+			ret = dw_hdmi_i2c_read(hdmi, msgs[i].buf, msgs[i].len);
+		else
+			ret = dw_hdmi_i2c_write(hdmi, msgs[i].buf, msgs[i].len);
+
+		if (ret < 0)
+			break;
+	}
+
+	if (!ret)
+		ret = num;
+
+	spin_lock_irqsave(&i2c->lock, flags);
+
+	/* Mute DONE and ERROR interrupts */
+	hdmi_writeb(hdmi, HDMI_IH_I2CM_STAT0_ERROR | HDMI_IH_I2CM_STAT0_DONE,
+		    HDMI_IH_MUTE_I2CM_STAT0);
+
+	spin_unlock_irqrestore(&i2c->lock, flags);
+
+	return ret;
+}
+
+static u32 dw_hdmi_i2c_func(struct i2c_adapter *adapter)
+{
+	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
+}
+
+static struct i2c_algorithm dw_hdmi_algorithm = {
+	.master_xfer	= dw_hdmi_i2c_xfer,
+	.functionality	= dw_hdmi_i2c_func,
+};
+
+static struct i2c_adapter *dw_hdmi_i2c_adapter(struct dw_hdmi *hdmi)
+{
+	struct i2c_adapter *adap;
+	int ret;
+
+	hdmi->i2c = devm_kzalloc(hdmi->dev, sizeof(*hdmi->i2c), GFP_KERNEL);
+	if (!hdmi->i2c)
+		return ERR_PTR(-ENOMEM);
+
+	spin_lock_init(&hdmi->i2c->lock);
+	init_completion(&hdmi->i2c->cmp);
+
+	adap = &hdmi->i2c->adap;
+	adap->class = I2C_CLASS_DDC;
+	adap->owner = THIS_MODULE;
+	adap->dev.parent = hdmi->dev;
+	adap->algo = &dw_hdmi_algorithm;
+	strlcpy(adap->name, "DesignWare HDMI", sizeof(adap->name));
+	i2c_set_adapdata(adap, hdmi);
+
+	ret = i2c_add_adapter(adap);
+	if (ret) {
+		dev_warn(hdmi->dev, "cannot add %s I2C adapter\n", adap->name);
+		devm_kfree(hdmi->dev, hdmi->i2c);
+		hdmi->i2c = NULL;
+		return ERR_PTR(ret);
+	}
+
+	dev_info(hdmi->dev, "registered %s I2C bus driver\n", adap->name);
+
+	return adap;
+}
+
 static void hdmi_set_cts_n(struct dw_hdmi *hdmi, unsigned int cts,
 			   unsigned int n)
 {
@@ -1534,16 +1803,47 @@ static const struct drm_bridge_funcs dw_hdmi_bridge_funcs = {
 	.mode_set = dw_hdmi_bridge_mode_set,
 };
 
+static irqreturn_t dw_hdmi_i2c_irq(struct dw_hdmi *hdmi)
+{
+	struct dw_hdmi_i2c *i2c = hdmi->i2c;
+	unsigned long flags;
+
+	spin_lock_irqsave(&i2c->lock, flags);
+
+	i2c->stat = hdmi_readb(hdmi, HDMI_IH_I2CM_STAT0);
+	if (!i2c->stat) {
+		spin_unlock_irqrestore(&i2c->lock, flags);
+		return IRQ_NONE;
+	}
+
+	hdmi_writeb(hdmi, i2c->stat, HDMI_IH_I2CM_STAT0);
+	complete(&i2c->cmp);
+
+	dev_dbg(hdmi->dev, "i2cm_stat: 0x%02x, addr: 0x%02x, reg: 0x%02x\n",
+		i2c->stat, hdmi_readb(hdmi, HDMI_I2CM_SLAVE),
+		hdmi_readb(hdmi, HDMI_I2CM_ADDRESS));
+
+	spin_unlock_irqrestore(&i2c->lock, flags);
+
+	return IRQ_HANDLED;
+}
+
 static irqreturn_t dw_hdmi_hardirq(int irq, void *dev_id)
 {
 	struct dw_hdmi *hdmi = dev_id;
 	u8 intr_stat;
+	irqreturn_t ret = IRQ_NONE;
+
+	if (hdmi->i2c)
+		ret = dw_hdmi_i2c_irq(hdmi);
 
 	intr_stat = hdmi_readb(hdmi, HDMI_IH_PHY_STAT0);
-	if (intr_stat)
+	if (intr_stat) {
 		hdmi_writeb(hdmi, ~0, HDMI_IH_MUTE_PHY_STAT0);
+		return IRQ_WAKE_THREAD;
+	}
 
-	return intr_stat ? IRQ_WAKE_THREAD : IRQ_NONE;
+	return ret;
 }
 
 static irqreturn_t dw_hdmi_irq(int irq, void *dev_id)
@@ -1771,6 +2071,13 @@ int dw_hdmi_bind(struct device *dev, struct device *master,
 	 */
 	hdmi_init_clk_regenerator(hdmi);
 
+	/* If DDC bus is not specified, try to register HDMI I2C bus */
+	if (!hdmi->ddc) {
+		hdmi->ddc = dw_hdmi_i2c_adapter(hdmi);
+		if (IS_ERR(hdmi->ddc))
+			hdmi->ddc = NULL;
+	}
+
 	/*
 	 * Configure registers related to HDMI interrupt
 	 * generation before registering IRQ.
@@ -1811,11 +2118,18 @@ int dw_hdmi_bind(struct device *dev, struct device *master,
 		hdmi->audio = platform_device_register_full(&pdevinfo);
 	}
 
+	/* Unmute I2CM interrupts and reset HDMI DDC I2C master controller */
+	if (hdmi->i2c)
+		dw_hdmi_i2c_init(hdmi);
+
 	dev_set_drvdata(dev, hdmi);
 
 	return 0;
 
 err_iahb:
+	if (hdmi->i2c)
+		i2c_del_adapter(&hdmi->i2c->adap);
+
 	clk_disable_unprepare(hdmi->iahb_clk);
 err_isfr:
 	clk_disable_unprepare(hdmi->isfr_clk);
@@ -1839,13 +2153,18 @@ void dw_hdmi_unbind(struct device *dev, struct device *master, void *data)
 
 	clk_disable_unprepare(hdmi->iahb_clk);
 	clk_disable_unprepare(hdmi->isfr_clk);
-	i2c_put_adapter(hdmi->ddc);
+
+	if (hdmi->i2c)
+		i2c_del_adapter(&hdmi->i2c->adap);
+	else
+		i2c_put_adapter(hdmi->ddc);
 }
 EXPORT_SYMBOL_GPL(dw_hdmi_unbind);
 
 MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>");
 MODULE_AUTHOR("Andy Yan <andy.yan@rock-chips.com>");
 MODULE_AUTHOR("Yakir Yang <ykk@rock-chips.com>");
+MODULE_AUTHOR("Vladimir Zapolskiy <vladimir_zapolskiy at mentor.com>");
 MODULE_DESCRIPTION("DW HDMI transmitter driver");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("platform:dw-hdmi");
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [RFC 05/21] drm: bridge/dw_hdmi: Fix R-Car Gen3 device support
  2016-05-30 15:59 [RFC 00/21] Renesas r8a7795/Salvator-X HDMI output prototype Ulrich Hecht
                   ` (3 preceding siblings ...)
  2016-05-30 16:00 ` [RFC 04/21] drm: bridge/dw_hdmi: add dw hdmi i2c bus adapter support Ulrich Hecht
@ 2016-05-30 16:00 ` Ulrich Hecht
  2016-05-30 16:00 ` [RFC 06/21] drm: rcar-du: Add R8A7795 " Ulrich Hecht
                   ` (17 subsequent siblings)
  22 siblings, 0 replies; 34+ messages in thread
From: Ulrich Hecht @ 2016-05-30 16:00 UTC (permalink / raw)
  To: linux-renesas-soc, geert
  Cc: kuninori.morimoto.gx, laurent.pinchart, dri-devel, architt, vz,
	koji.matsuoka.xm, Geert Uytterhoeven

From: Koji Matsuoka <koji.matsuoka.xm@renesas.com>

Signed-off-by: Koji Matsuoka <koji.matsuoka.xm@renesas.com>
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
 drivers/gpu/drm/bridge/dw-hdmi.c | 158 ++++++++++++++++++++++++++++++---------
 include/drm/bridge/dw_hdmi.h     |   9 +++
 2 files changed, 131 insertions(+), 36 deletions(-)

diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c
index 1cfff2f..55e73e8 100644
--- a/drivers/gpu/drm/bridge/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/dw-hdmi.c
@@ -1,6 +1,7 @@
 /*
  * DesignWare High-Definition Multimedia Interface (HDMI) driver
  *
+ * Copyright (C) 2015 Renesas Electronics Corporation
  * Copyright (C) 2013-2015 Mentor Graphics Inc.
  * Copyright (C) 2011-2013 Freescale Semiconductor, Inc.
  * Copyright (C) 2010, Guennadi Liakhovetski <g.liakhovetski at gmx.de>
@@ -21,6 +22,7 @@
 #include <linux/of_device.h>
 #include <linux/spinlock.h>
 
+#include <drm/drm_atomic_helper.h>
 #include <drm/drm_of.h>
 #include <drm/drmP.h>
 #include <drm/drm_atomic_helper.h>
@@ -143,6 +145,7 @@ struct dw_hdmi {
 	struct device *dev;
 	struct clk *isfr_clk;
 	struct clk *iahb_clk;
+
 	struct dw_hdmi_i2c *i2c;
 
 	struct hdmi_data_info hdmi_data;
@@ -174,6 +177,11 @@ struct dw_hdmi {
 	unsigned int audio_cts;
 	unsigned int audio_n;
 	bool audio_enable;
+	int ratio;
+	bool interlaced;
+	bool isfr_use;
+	bool iahb_use;
+	int num;
 
 	void (*write)(struct dw_hdmi *hdmi, u8 val, int offset);
 	u8 (*read)(struct dw_hdmi *hdmi, int offset);
@@ -1008,6 +1016,7 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi, unsigned char prep,
 	const struct dw_hdmi_mpll_config *mpll_config = pdata->mpll_cfg;
 	const struct dw_hdmi_curr_ctrl *curr_ctrl = pdata->cur_ctr;
 	const struct dw_hdmi_phy_config *phy_config = pdata->phy_config;
+	const struct dw_hdmi_multi_div *multi_div = pdata->multi_div;
 
 	if (prep)
 		return -EINVAL;
@@ -1043,6 +1052,13 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi, unsigned char prep,
 		    phy_config->mpixelclock)
 			break;
 
+	if (hdmi->dev_type == RCAR_HDMI) {
+		for (; multi_div->mpixelclock != (~0UL); multi_div++)
+			if (hdmi->hdmi_data.video_mode.mpixelclock <=
+			    multi_div->mpixelclock)
+				break;
+	}
+
 	if (mpll_config->mpixelclock == ~0UL ||
 	    curr_ctrl->mpixelclock == ~0UL ||
 	    phy_config->mpixelclock == ~0UL) {
@@ -1051,6 +1067,13 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi, unsigned char prep,
 		return -EINVAL;
 	}
 
+	if ((multi_div->mpixelclock == ~0UL) &&
+		(hdmi->dev_type == RCAR_HDMI)) {
+		dev_err(hdmi->dev, "Pixel clock %d - unsupported by HDMI\n",
+			hdmi->hdmi_data.video_mode.mpixelclock);
+		return -EINVAL;
+	}
+
 	/* Enable csc path */
 	if (cscon)
 		val = HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_IN_PATH;
@@ -1077,21 +1100,27 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi, unsigned char prep,
 	hdmi_phy_test_clear(hdmi, 0);
 
 	hdmi_phy_i2c_write(hdmi, mpll_config->res[res_idx].cpce, 0x06);
-	hdmi_phy_i2c_write(hdmi, mpll_config->res[res_idx].gmp, 0x15);
+	if (hdmi->dev_type != RCAR_HDMI)
+		hdmi_phy_i2c_write(hdmi, mpll_config->res[res_idx].gmp, 0x15);
 
 	/* CURRCTRL */
 	hdmi_phy_i2c_write(hdmi, curr_ctrl->curr[res_idx], 0x10);
 
-	hdmi_phy_i2c_write(hdmi, 0x0000, 0x13);  /* PLLPHBYCTRL */
-	hdmi_phy_i2c_write(hdmi, 0x0006, 0x17);
-
-	hdmi_phy_i2c_write(hdmi, phy_config->term, 0x19);  /* TXTERM */
-	hdmi_phy_i2c_write(hdmi, phy_config->sym_ctr, 0x09); /* CKSYMTXCTRL */
-	hdmi_phy_i2c_write(hdmi, phy_config->vlev_ctr, 0x0E); /* VLEVCTRL */
+	if (hdmi->dev_type == RCAR_HDMI)
+		hdmi_phy_i2c_write(hdmi, multi_div->multi[res_idx], 0x11);
 
-	/* REMOVE CLK TERM */
-	hdmi_phy_i2c_write(hdmi, 0x8000, 0x05);  /* CKCALCTRL */
+	if (hdmi->dev_type != RCAR_HDMI) {
+		hdmi_phy_i2c_write(hdmi, 0x0000, 0x13);  /* PLLPHBYCTRL */
+		hdmi_phy_i2c_write(hdmi, 0x0006, 0x17);
 
+		hdmi_phy_i2c_write(hdmi, phy_config->term, 0x19);  /* TXTERM */
+		hdmi_phy_i2c_write(hdmi, phy_config->sym_ctr,
+						 0x09); /* CKSYMTXCTRL */
+		hdmi_phy_i2c_write(hdmi, phy_config->vlev_ctr,
+						 0x0E); /* VLEVCTRL */
+		/* REMOVE CLK TERM */
+		hdmi_phy_i2c_write(hdmi, 0x8000, 0x05);  /* CKCALCTRL */
+	}
 	dw_hdmi_phy_enable_powerdown(hdmi, false);
 
 	/* toggle TMDS enable */
@@ -1102,7 +1131,8 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi, unsigned char prep,
 	dw_hdmi_phy_gen2_txpwron(hdmi, 1);
 	dw_hdmi_phy_gen2_pddq(hdmi, 0);
 
-	if (hdmi->dev_type == RK3288_HDMI)
+	if ((hdmi->dev_type == RK3288_HDMI) ||
+		(hdmi->dev_type == RCAR_HDMI))
 		dw_hdmi_phy_enable_spare(hdmi, 1);
 
 	/*Wait for PHY PLL lock */
@@ -1791,6 +1821,16 @@ static const struct drm_connector_funcs dw_hdmi_atomic_connector_funcs = {
 	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
 };
 
+static struct drm_connector_funcs dw_hdmi_rcar_connector_funcs = {
+	.dpms = drm_atomic_helper_connector_dpms,
+	.fill_modes = drm_helper_probe_single_connector_modes,
+	.detect = dw_hdmi_connector_detect,
+	.destroy = dw_hdmi_connector_destroy,
+	.reset = drm_atomic_helper_connector_reset,
+	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
+	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
+};
+
 static const struct drm_connector_helper_funcs dw_hdmi_connector_helper_funcs = {
 	.get_modes = dw_hdmi_connector_get_modes,
 	.mode_valid = dw_hdmi_connector_mode_valid,
@@ -1940,16 +1980,23 @@ static int dw_hdmi_register(struct drm_device *drm, struct dw_hdmi *hdmi)
 	encoder->bridge = bridge;
 	hdmi->connector.polled = DRM_CONNECTOR_POLL_HPD;
 
+	if (hdmi->interlaced)
+		hdmi->connector.interlace_allowed = true;
+
 	drm_connector_helper_add(&hdmi->connector,
 				 &dw_hdmi_connector_helper_funcs);
 
 	if (drm_core_check_feature(drm, DRIVER_ATOMIC))
 		drm_connector_init(drm, &hdmi->connector,
-				   &dw_hdmi_atomic_connector_funcs,
+				   hdmi->dev_type == RCAR_HDMI ?
+					&dw_hdmi_rcar_connector_funcs :
+					&dw_hdmi_atomic_connector_funcs,
 				   DRM_MODE_CONNECTOR_HDMIA);
 	else
 		drm_connector_init(drm, &hdmi->connector,
-				   &dw_hdmi_connector_funcs,
+				   hdmi->dev_type == RCAR_HDMI ?
+					&dw_hdmi_rcar_connector_funcs :
+					&dw_hdmi_connector_funcs,
 				   DRM_MODE_CONNECTOR_HDMIA);
 
 	drm_mode_connector_attach_encoder(&hdmi->connector, encoder);
@@ -2006,6 +2053,11 @@ int dw_hdmi_bind(struct device *dev, struct device *master,
 		return -EINVAL;
 	}
 
+	if (of_property_read_u32(np, "interlaced", &val) == 0)
+		hdmi->interlaced = val;
+	else
+		hdmi->interlaced = false;
+
 	ddc_node = of_parse_phandle(np, "ddc-i2c-bus", 0);
 	if (ddc_node) {
 		hdmi->ddc = of_find_i2c_adapter_by_node(ddc_node);
@@ -2023,30 +2075,59 @@ int dw_hdmi_bind(struct device *dev, struct device *master,
 	if (IS_ERR(hdmi->regs))
 		return PTR_ERR(hdmi->regs);
 
-	hdmi->isfr_clk = devm_clk_get(hdmi->dev, "isfr");
-	if (IS_ERR(hdmi->isfr_clk)) {
-		ret = PTR_ERR(hdmi->isfr_clk);
-		dev_err(hdmi->dev, "Unable to get HDMI isfr clk: %d\n", ret);
-		return ret;
-	}
+	if (of_property_read_u32(np, "clock-isfr", &val) == 0)
+		hdmi->isfr_use = val;
+	else
+		hdmi->isfr_use = true;
 
-	ret = clk_prepare_enable(hdmi->isfr_clk);
-	if (ret) {
-		dev_err(hdmi->dev, "Cannot enable HDMI isfr clock: %d\n", ret);
-		return ret;
-	}
+	if (hdmi->isfr_use) {
+		if (of_property_read_u32(np, "hdmi-num", &val) == 0)
+			hdmi->num = val;
+		else
+			hdmi->num = -1;
+
+		if (hdmi->num > 1) {
+			char name[7];
+
+			sprintf(name, "isfr.%u", hdmi->plat_data->index);
+			hdmi->isfr_clk = devm_clk_get(hdmi->dev, name);
+		} else
+			hdmi->isfr_clk = devm_clk_get(hdmi->dev, "isfr");
+		if (IS_ERR(hdmi->isfr_clk)) {
+			ret = PTR_ERR(hdmi->isfr_clk);
+			dev_err(hdmi->dev,
+				 "Unable to get HDMI isfr clk: %d\n", ret);
+			return ret;
+		}
 
-	hdmi->iahb_clk = devm_clk_get(hdmi->dev, "iahb");
-	if (IS_ERR(hdmi->iahb_clk)) {
-		ret = PTR_ERR(hdmi->iahb_clk);
-		dev_err(hdmi->dev, "Unable to get HDMI iahb clk: %d\n", ret);
-		goto err_isfr;
+		ret = clk_prepare_enable(hdmi->isfr_clk);
+		if (ret) {
+			dev_err(hdmi->dev,
+				 "Cannot enable HDMI isfr clock: %d\n", ret);
+			return ret;
+		}
 	}
 
-	ret = clk_prepare_enable(hdmi->iahb_clk);
-	if (ret) {
-		dev_err(hdmi->dev, "Cannot enable HDMI iahb clock: %d\n", ret);
-		goto err_isfr;
+	if (of_property_read_u32(np, "clock-iahb", &val) == 0)
+		hdmi->iahb_use = val;
+	else
+		hdmi->iahb_use = true;
+
+	if (hdmi->iahb_use) {
+		hdmi->iahb_clk = devm_clk_get(hdmi->dev, "iahb");
+		if (IS_ERR(hdmi->iahb_clk)) {
+			ret = PTR_ERR(hdmi->iahb_clk);
+			dev_err(hdmi->dev,
+				 "Unable to get HDMI iahb clk: %d\n", ret);
+			goto err_isfr;
+		}
+
+		ret = clk_prepare_enable(hdmi->iahb_clk);
+		if (ret) {
+			dev_err(hdmi->dev,
+				 "Cannot enable HDMI iahb clock: %d\n", ret);
+			goto err_isfr;
+		}
 	}
 
 	/* Product and revision IDs */
@@ -2130,9 +2211,11 @@ err_iahb:
 	if (hdmi->i2c)
 		i2c_del_adapter(&hdmi->i2c->adap);
 
-	clk_disable_unprepare(hdmi->iahb_clk);
+	if (hdmi->iahb_use)
+		clk_disable_unprepare(hdmi->iahb_clk);
 err_isfr:
-	clk_disable_unprepare(hdmi->isfr_clk);
+	if (hdmi->isfr_use)
+		clk_disable_unprepare(hdmi->isfr_clk);
 
 	return ret;
 }
@@ -2151,8 +2234,11 @@ void dw_hdmi_unbind(struct device *dev, struct device *master, void *data)
 	hdmi->connector.funcs->destroy(&hdmi->connector);
 	hdmi->encoder->funcs->destroy(hdmi->encoder);
 
-	clk_disable_unprepare(hdmi->iahb_clk);
-	clk_disable_unprepare(hdmi->isfr_clk);
+	if (hdmi->iahb_use)
+		clk_disable_unprepare(hdmi->iahb_clk);
+
+	if (hdmi->isfr_use)
+		clk_disable_unprepare(hdmi->isfr_clk);
 
 	if (hdmi->i2c)
 		i2c_del_adapter(&hdmi->i2c->adap);
diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h
index bae79f3..a620cab 100644
--- a/include/drm/bridge/dw_hdmi.h
+++ b/include/drm/bridge/dw_hdmi.h
@@ -1,4 +1,5 @@
 /*
+ * Copyright (C) 2015 Renesas Electronics Corporation
  * Copyright (C) 2011 Freescale Semiconductor, Inc.
  *
  * This program is free software; you can redistribute it and/or modify
@@ -25,6 +26,7 @@ enum dw_hdmi_devtype {
 	IMX6Q_HDMI,
 	IMX6DL_HDMI,
 	RK3288_HDMI,
+	RCAR_HDMI,
 };
 
 struct dw_hdmi_mpll_config {
@@ -40,6 +42,11 @@ struct dw_hdmi_curr_ctrl {
 	u16 curr[DW_HDMI_RES_MAX];
 };
 
+struct dw_hdmi_multi_div {
+	unsigned long mpixelclock;
+	u16 multi[DW_HDMI_RES_MAX];
+};
+
 struct dw_hdmi_phy_config {
 	unsigned long mpixelclock;
 	u16 sym_ctr;    /*clock symbol and transmitter control*/
@@ -51,9 +58,11 @@ struct dw_hdmi_plat_data {
 	enum dw_hdmi_devtype dev_type;
 	const struct dw_hdmi_mpll_config *mpll_cfg;
 	const struct dw_hdmi_curr_ctrl *cur_ctr;
+	const struct dw_hdmi_multi_div *multi_div;
 	const struct dw_hdmi_phy_config *phy_config;
 	enum drm_mode_status (*mode_valid)(struct drm_connector *connector,
 					   struct drm_display_mode *mode);
+	u32 index;
 };
 
 void dw_hdmi_unbind(struct device *dev, struct device *master, void *data);
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [RFC 06/21] drm: rcar-du: Add R8A7795 device support
  2016-05-30 15:59 [RFC 00/21] Renesas r8a7795/Salvator-X HDMI output prototype Ulrich Hecht
                   ` (4 preceding siblings ...)
  2016-05-30 16:00 ` [RFC 05/21] drm: bridge/dw_hdmi: Fix R-Car Gen3 device support Ulrich Hecht
@ 2016-05-30 16:00 ` Ulrich Hecht
  2016-05-30 16:00 ` [RFC 07/21] drm: rcar-du: Add dw_hdmi driver startup Ulrich Hecht
                   ` (16 subsequent siblings)
  22 siblings, 0 replies; 34+ messages in thread
From: Ulrich Hecht @ 2016-05-30 16:00 UTC (permalink / raw)
  To: linux-renesas-soc, geert
  Cc: kuninori.morimoto.gx, laurent.pinchart, dri-devel, architt, vz,
	koji.matsuoka.xm, Geert Uytterhoeven

From: Koji Matsuoka <koji.matsuoka.xm@renesas.com>

Signed-off-by: Koji Matsuoka <koji.matsuoka.xm@renesas.com>
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
 drivers/gpu/drm/rcar-du/rcar_du_crtc.h |  4 +++-
 drivers/gpu/drm/rcar-du/rcar_du_drv.c  | 14 ++++++++++++--
 drivers/gpu/drm/rcar-du/rcar_du_drv.h  |  2 ++
 3 files changed, 17 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.h b/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
index 6f08b7e..459e539 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
+++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
@@ -1,7 +1,7 @@
 /*
  * rcar_du_crtc.h  --  R-Car Display Unit CRTCs
  *
- * Copyright (C) 2013-2014 Renesas Electronics Corporation
+ * Copyright (C) 2013-2015 Renesas Electronics Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
  *
@@ -61,6 +61,8 @@ enum rcar_du_output {
 	RCAR_DU_OUTPUT_DPAD1,
 	RCAR_DU_OUTPUT_LVDS0,
 	RCAR_DU_OUTPUT_LVDS1,
+	RCAR_DU_OUTPUT_HDMI0,
+	RCAR_DU_OUTPUT_HDMI1,
 	RCAR_DU_OUTPUT_TCON,
 	RCAR_DU_OUTPUT_MAX,
 };
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.c b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
index fb9242d..0a93d2a 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_drv.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
@@ -140,14 +140,24 @@ static const struct rcar_du_device_info rcar_du_r8a7795_info = {
 		  | RCAR_DU_FEATURE_VSP1_SOURCE,
 	.num_crtcs = 4,
 	.routes = {
-		/* R8A7795 has one RGB output, one LVDS output and two
-		 * (currently unsupported) HDMI outputs.
+		/* R8A7795 has one RGB output, two HDMI outputs and one
+		 * LVDS output.
 		 */
 		[RCAR_DU_OUTPUT_DPAD0] = {
 			.possible_crtcs = BIT(3),
 			.encoder_type = DRM_MODE_ENCODER_NONE,
 			.port = 0,
 		},
+		[RCAR_DU_OUTPUT_HDMI0] = {
+			.possible_crtcs = BIT(1),
+			.encoder_type = RCAR_DU_ENCODER_HDMI,
+			.port = 1,
+		},
+		[RCAR_DU_OUTPUT_HDMI1] = {
+			.possible_crtcs = BIT(2),
+			.encoder_type = RCAR_DU_ENCODER_HDMI,
+			.port = 2,
+		},
 		[RCAR_DU_OUTPUT_LVDS0] = {
 			.possible_crtcs = BIT(0),
 			.encoder_type = DRM_MODE_ENCODER_LVDS,
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.h b/drivers/gpu/drm/rcar-du/rcar_du_drv.h
index ed35467..d1d1d8d 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_drv.h
+++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.h
@@ -20,6 +20,7 @@
 #include "rcar_du_crtc.h"
 #include "rcar_du_group.h"
 #include "rcar_du_vsp.h"
+#include "rcar_du_encoder.h"
 
 struct clk;
 struct device;
@@ -31,6 +32,7 @@ struct rcar_du_lvdsenc;
 #define RCAR_DU_FEATURE_CRTC_IRQ_CLOCK	(1 << 0)	/* Per-CRTC IRQ and clock */
 #define RCAR_DU_FEATURE_EXT_CTRL_REGS	(1 << 1)	/* Has extended control registers */
 #define RCAR_DU_FEATURE_VSP1_SOURCE	(1 << 2)	/* Has inputs from VSP1 */
+#define RCAR_DU_FEATURE_GEN3_REGS	(1 << 3)	/* Use Gen3 registers */
 
 #define RCAR_DU_QUIRK_ALIGN_128B	(1 << 0)	/* Align pitches to 128 bytes */
 #define RCAR_DU_QUIRK_LVDS_LANES	(1 << 1)	/* LVDS lanes 1 and 3 inverted */
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [RFC 07/21] drm: rcar-du: Add dw_hdmi driver startup
  2016-05-30 15:59 [RFC 00/21] Renesas r8a7795/Salvator-X HDMI output prototype Ulrich Hecht
                   ` (5 preceding siblings ...)
  2016-05-30 16:00 ` [RFC 06/21] drm: rcar-du: Add R8A7795 " Ulrich Hecht
@ 2016-05-30 16:00 ` Ulrich Hecht
  2016-05-30 16:00 ` [RFC 08/21] drm: rcar-du: Add DPLL support Ulrich Hecht
                   ` (15 subsequent siblings)
  22 siblings, 0 replies; 34+ messages in thread
From: Ulrich Hecht @ 2016-05-30 16:00 UTC (permalink / raw)
  To: linux-renesas-soc, geert
  Cc: kuninori.morimoto.gx, laurent.pinchart, dri-devel, architt, vz,
	koji.matsuoka.xm, Geert Uytterhoeven

From: Koji Matsuoka <koji.matsuoka.xm@renesas.com>

The HDMI driver in the R-Car Gen3 uses dw_hdmi driver.

Signed-off-by: Koji Matsuoka <koji.matsuoka.xm@renesas.com>
[geert: Select DRM_DW_HDMI on non-r8a7795 to fix shmobile_defconfig build]
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
 drivers/gpu/drm/rcar-du/Kconfig           |   2 +
 drivers/gpu/drm/rcar-du/rcar_du_encoder.c |   9 +-
 drivers/gpu/drm/rcar-du/rcar_du_encoder.h |   6 +-
 drivers/gpu/drm/rcar-du/rcar_du_hdmienc.c | 225 +++++++++++++++++++++++++++---
 drivers/gpu/drm/rcar-du/rcar_du_kms.c     |   6 +-
 5 files changed, 227 insertions(+), 21 deletions(-)

diff --git a/drivers/gpu/drm/rcar-du/Kconfig b/drivers/gpu/drm/rcar-du/Kconfig
index 7fc3ca5..d7c7ffa 100644
--- a/drivers/gpu/drm/rcar-du/Kconfig
+++ b/drivers/gpu/drm/rcar-du/Kconfig
@@ -15,6 +15,8 @@ config DRM_RCAR_DU
 config DRM_RCAR_HDMI
 	bool "R-Car DU HDMI Encoder Support"
 	depends on DRM_RCAR_DU
+	depends on OF
+	select DRM_DW_HDMI
 	help
 	  Enable support for external HDMI encoders.
 
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_encoder.c b/drivers/gpu/drm/rcar-du/rcar_du_encoder.c
index 1b16297..5d64893 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_encoder.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_encoder.c
@@ -1,7 +1,7 @@
 /*
  * rcar_du_encoder.c  --  R-Car Display Unit Encoder
  *
- * Copyright (C) 2013-2014 Renesas Electronics Corporation
+ * Copyright (C) 2013-2015 Renesas Electronics Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
  *
@@ -118,7 +118,8 @@ int rcar_du_encoder_init(struct rcar_du_device *rcdu,
 			 enum rcar_du_encoder_type type,
 			 enum rcar_du_output output,
 			 struct device_node *enc_node,
-			 struct device_node *con_node)
+			 struct device_node *con_node,
+			 const char *device_name)
 {
 	struct rcar_du_encoder *renc;
 	struct drm_encoder *encoder;
@@ -162,8 +163,12 @@ int rcar_du_encoder_init(struct rcar_du_device *rcdu,
 		break;
 	}
 
+	renc->device_name = device_name;
+
 	if (type == RCAR_DU_ENCODER_HDMI) {
 		ret = rcar_du_hdmienc_init(rcdu, renc, enc_node);
+		if (of_device_is_compatible(enc_node, "rockchip,rcar-dw-hdmi"))
+			goto done;
 		if (ret < 0)
 			goto done;
 	} else {
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_encoder.h b/drivers/gpu/drm/rcar-du/rcar_du_encoder.h
index dde523a..51a4664 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_encoder.h
+++ b/drivers/gpu/drm/rcar-du/rcar_du_encoder.h
@@ -1,7 +1,7 @@
 /*
  * rcar_du_encoder.h  --  R-Car Display Unit Encoder
  *
- * Copyright (C) 2013-2014 Renesas Electronics Corporation
+ * Copyright (C) 2013-2015 Renesas Electronics Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
  *
@@ -33,6 +33,7 @@ struct rcar_du_encoder {
 	enum rcar_du_output output;
 	struct rcar_du_hdmienc *hdmi;
 	struct rcar_du_lvdsenc *lvds;
+	const char *device_name;
 };
 
 #define to_rcar_encoder(e) \
@@ -55,6 +56,7 @@ int rcar_du_encoder_init(struct rcar_du_device *rcdu,
 			 enum rcar_du_encoder_type type,
 			 enum rcar_du_output output,
 			 struct device_node *enc_node,
-			 struct device_node *con_node);
+			 struct device_node *con_node,
+			 const char *device_name);
 
 #endif /* __RCAR_DU_ENCODER_H__ */
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_hdmienc.c b/drivers/gpu/drm/rcar-du/rcar_du_hdmienc.c
index 15d553a..b8b89a0 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_hdmienc.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_hdmienc.c
@@ -1,7 +1,7 @@
 /*
  * R-Car Display Unit HDMI Encoder
  *
- * Copyright (C) 2014 Renesas Electronics Corporation
+ * Copyright (C) 2014-2015 Renesas Electronics Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
  *
@@ -13,10 +13,13 @@
 
 #include <linux/slab.h>
 
+#include <drm/bridge/dw_hdmi.h>
 #include <drm/drmP.h>
 #include <drm/drm_crtc.h>
 #include <drm/drm_crtc_helper.h>
 
+#include <linux/of_platform.h>
+
 #include "rcar_du_drv.h"
 #include "rcar_du_encoder.h"
 #include "rcar_du_hdmienc.h"
@@ -24,7 +27,9 @@
 
 struct rcar_du_hdmienc {
 	struct rcar_du_encoder *renc;
+	struct device *dev;
 	bool enabled;
+	unsigned int index;
 };
 
 #define to_rcar_hdmienc(e)	(to_rcar_encoder(e)->hdmi)
@@ -32,6 +37,10 @@ struct rcar_du_hdmienc {
 static void rcar_du_hdmienc_disable(struct drm_encoder *encoder)
 {
 	struct rcar_du_hdmienc *hdmienc = to_rcar_hdmienc(encoder);
+	const struct drm_bridge_funcs *bfuncs = encoder->bridge->funcs;
+
+	if ((bfuncs) && (bfuncs->post_disable))
+		bfuncs->post_disable(encoder->bridge);
 
 	if (hdmienc->renc->lvds)
 		rcar_du_lvdsenc_enable(hdmienc->renc->lvds, encoder->crtc,
@@ -43,10 +52,13 @@ static void rcar_du_hdmienc_disable(struct drm_encoder *encoder)
 static void rcar_du_hdmienc_enable(struct drm_encoder *encoder)
 {
 	struct rcar_du_hdmienc *hdmienc = to_rcar_hdmienc(encoder);
+	const struct drm_bridge_funcs *bfuncs = encoder->bridge->funcs;
 
 	if (hdmienc->renc->lvds)
 		rcar_du_lvdsenc_enable(hdmienc->renc->lvds, encoder->crtc,
 				       true);
+	if ((bfuncs) && (bfuncs->enable))
+		bfuncs->enable(encoder->bridge);
 
 	hdmienc->enabled = true;
 }
@@ -56,13 +68,19 @@ static int rcar_du_hdmienc_atomic_check(struct drm_encoder *encoder,
 					struct drm_connector_state *conn_state)
 {
 	struct rcar_du_hdmienc *hdmienc = to_rcar_hdmienc(encoder);
+	const struct drm_bridge_funcs *bfuncs = encoder->bridge->funcs;
 	struct drm_display_mode *adjusted_mode = &crtc_state->adjusted_mode;
+	const struct drm_display_mode *mode = &crtc_state->mode;
+	int ret = 0;
 
 	if (hdmienc->renc->lvds)
 		rcar_du_lvdsenc_atomic_check(hdmienc->renc->lvds,
 					     adjusted_mode);
 
-	return 0;
+	if ((bfuncs) && (bfuncs->mode_fixup))
+		ret = bfuncs->mode_fixup(encoder->bridge, mode,
+				 adjusted_mode) ? 0 : -EINVAL;
+	return ret;
 }
 
 static void rcar_du_hdmienc_mode_set(struct drm_encoder *encoder,
@@ -70,6 +88,10 @@ static void rcar_du_hdmienc_mode_set(struct drm_encoder *encoder,
 				     struct drm_display_mode *adjusted_mode)
 {
 	struct rcar_du_hdmienc *hdmienc = to_rcar_hdmienc(encoder);
+	const struct drm_bridge_funcs *bfuncs = encoder->bridge->funcs;
+
+	if ((bfuncs) && (bfuncs->mode_set))
+		bfuncs->mode_set(encoder->bridge, mode, adjusted_mode);
 
 	rcar_du_crtc_route_output(encoder->crtc, hdmienc->renc->output);
 }
@@ -95,24 +117,187 @@ static const struct drm_encoder_funcs encoder_funcs = {
 	.destroy = rcar_du_hdmienc_cleanup,
 };
 
+static const struct dw_hdmi_mpll_config rcar_du_hdmienc_mpll_cfg[] = {
+	{
+		44900000, {
+			{ 0x0003, 0x0000},
+			{ 0x0003, 0x0000},
+			{ 0x0003, 0x0000}
+		},
+	}, {
+		90000000, {
+			{ 0x0002, 0x0000},
+			{ 0x0002, 0x0000},
+			{ 0x0002, 0x0000}
+		},
+	}, {
+		182750000, {
+			{ 0x0001, 0x0000},
+			{ 0x0001, 0x0000},
+			{ 0x0001, 0x0000}
+		},
+	}, {
+		297000000, {
+			{ 0x0000, 0x0000},
+			{ 0x0000, 0x0000},
+			{ 0x0000, 0x0000}
+		},
+	}, {
+		~0UL, {
+			{ 0xFFFF, 0xFFFF },
+			{ 0xFFFF, 0xFFFF },
+			{ 0xFFFF, 0xFFFF },
+		},
+	}
+};
+static const struct dw_hdmi_curr_ctrl rcar_du_hdmienc_cur_ctr[] = {
+	/*      pixelclk    bpp8    bpp10   bpp12 */
+	{
+		35500000,  { 0x0344, 0x0000, 0x0000 },
+	}, {
+		44900000,  { 0x0285, 0x0000, 0x0000 },
+	}, {
+		71000000,  { 0x1184, 0x0000, 0x0000 },
+	}, {
+		90000000,  { 0x1144, 0x0000, 0x0000 },
+	}, {
+		140250000, { 0x20c4, 0x0000, 0x0000 },
+	}, {
+		182750000, { 0x2084, 0x0000, 0x0000 },
+	}, {
+		297000000, { 0x0084, 0x0000, 0x0000 },
+	}, {
+		~0UL,      { 0x0000, 0x0000, 0x0000 },
+	}
+};
+
+static const struct dw_hdmi_multi_div rcar_du_hdmienc_multi_div[] = {
+	/*      pixelclk    bpp8    bpp10   bpp12 */
+	{
+		35500000,  { 0x0328, 0x0000, 0x0000 },
+	}, {
+		44900000,  { 0x0128, 0x0000, 0x0000 },
+	}, {
+		71000000,  { 0x0314, 0x0000, 0x0000 },
+	}, {
+		90000000,  { 0x0114, 0x0000, 0x0000 },
+	}, {
+		140250000, { 0x030a, 0x0000, 0x0000 },
+	}, {
+		182750000, { 0x010a, 0x0000, 0x0000 },
+	}, {
+		281250000, { 0x0305, 0x0000, 0x0000 },
+	}, {
+		297000000, { 0x0105, 0x0000, 0x0000 },
+	}, {
+		~0UL,      { 0x0000, 0x0000, 0x0000 },
+	}
+};
+
+static const struct dw_hdmi_phy_config rcar_du_hdmienc_phy_config[] = {
+	/*pixelclk   symbol   term   vlev*/
+	{ 74250000,  0x8009, 0x0004, 0x0272},
+	{ 148500000, 0x802b, 0x0004, 0x028d},
+	{ 297000000, 0x8039, 0x0005, 0x028d},
+	{ ~0UL,	     0x0000, 0x0000, 0x0000}
+};
+
+static enum drm_mode_status
+rcar_du_hdmienc_mode_valid(struct drm_connector *connector,
+			    struct drm_display_mode *mode)
+{
+	return MODE_OK;
+}
+
+static const struct dw_hdmi_plat_data rcar_du_hdmienc_hdmi0_drv_data = {
+	.mode_valid = rcar_du_hdmienc_mode_valid,
+	.mpll_cfg   = rcar_du_hdmienc_mpll_cfg,
+	.cur_ctr    = rcar_du_hdmienc_cur_ctr,
+	.multi_div  = rcar_du_hdmienc_multi_div,
+	.phy_config = rcar_du_hdmienc_phy_config,
+	.dev_type   = RCAR_HDMI,
+	.index      = 0,
+};
+
+static const struct dw_hdmi_plat_data rcar_du_hdmienc_hdmi1_drv_data = {
+	.mode_valid = rcar_du_hdmienc_mode_valid,
+	.mpll_cfg   = rcar_du_hdmienc_mpll_cfg,
+	.cur_ctr    = rcar_du_hdmienc_cur_ctr,
+	.multi_div  = rcar_du_hdmienc_multi_div,
+	.phy_config = rcar_du_hdmienc_phy_config,
+	.dev_type   = RCAR_HDMI,
+	.index      = 1,
+};
+
+static const struct of_device_id rcar_du_hdmienc_dt_ids[] = {
+	{
+		.data = &rcar_du_hdmienc_hdmi0_drv_data
+	},
+	{
+		.data = &rcar_du_hdmienc_hdmi1_drv_data
+	},
+	{},
+};
+MODULE_DEVICE_TABLE(of, rcar_du_hdmienc_dt_ids);
+
 int rcar_du_hdmienc_init(struct rcar_du_device *rcdu,
 			 struct rcar_du_encoder *renc, struct device_node *np)
 {
 	struct drm_encoder *encoder = rcar_encoder_to_drm_encoder(renc);
-	struct drm_bridge *bridge;
 	struct rcar_du_hdmienc *hdmienc;
-	int ret;
+	struct resource *iores;
+	struct platform_device *pdev;
+	const struct dw_hdmi_plat_data *plat_data;
+	int ret, irq;
+	bool dw_hdmi_use = false;
+	struct drm_bridge *bridge = NULL;
 
 	hdmienc = devm_kzalloc(rcdu->dev, sizeof(*hdmienc), GFP_KERNEL);
 	if (hdmienc == NULL)
 		return -ENOMEM;
 
-	/* Locate the DRM bridge from the HDMI encoder DT node. */
-	bridge = of_drm_find_bridge(np);
-	if (!bridge) {
-		dev_dbg(rcdu->dev, "can't get bridge for %s, deferring probe\n",
-			of_node_full_name(np));
-		return -EPROBE_DEFER;
+	if (strcmp(renc->device_name, "rockchip,rcar-dw-hdmi") == 0)
+		dw_hdmi_use = true;
+
+	if (dw_hdmi_use) {
+		if (renc->output == RCAR_DU_OUTPUT_HDMI0)
+			hdmienc->index = 0;
+		else if (renc->output == RCAR_DU_OUTPUT_HDMI1)
+			hdmienc->index = 1;
+		else
+			return -EINVAL;
+
+		np = of_parse_phandle(rcdu->dev->of_node, "hdmi",
+						 hdmienc->index);
+		if (!np) {
+			dev_err(rcdu->dev, "hdmi node not found\n");
+			return -ENXIO;
+		}
+
+		pdev = of_find_device_by_node(np);
+		of_node_put(np);
+		if (!pdev)
+			return -ENXIO;
+
+		plat_data = rcar_du_hdmienc_dt_ids[hdmienc->index].data;
+		hdmienc->dev = &pdev->dev;
+
+		irq = platform_get_irq(pdev, 0);
+		if (irq < 0)
+			return irq;
+
+		iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+		if (!iores)
+			return -ENXIO;
+
+	} else {
+		/* Locate the DRM bridge from the HDMI encoder DT node. */
+		bridge = of_drm_find_bridge(np);
+		if (!bridge) {
+			dev_dbg(rcdu->dev, "can't get bridge for %s, deferring probe\n",
+				of_node_full_name(np));
+			return -EPROBE_DEFER;
+		}
 	}
 
 	ret = drm_encoder_init(rcdu->ddev, encoder, &encoder_funcs,
@@ -126,13 +311,21 @@ int rcar_du_hdmienc_init(struct rcar_du_device *rcdu,
 	hdmienc->renc = renc;
 
 	/* Link the bridge to the encoder. */
-	bridge->encoder = encoder;
-	encoder->bridge = bridge;
+	if (bridge) {
+		bridge->encoder = encoder;
+		encoder->bridge = bridge;
+	}
 
-	ret = drm_bridge_attach(rcdu->ddev, bridge);
-	if (ret) {
-		drm_encoder_cleanup(encoder);
-		return ret;
+	if (dw_hdmi_use)
+		ret = dw_hdmi_bind(rcdu->dev, NULL, rcdu->ddev, encoder,
+				iores, irq, plat_data);
+
+	if (bridge) {
+		ret = drm_bridge_attach(rcdu->ddev, bridge);
+		if (ret) {
+			drm_encoder_cleanup(encoder);
+			return ret;
+		}
 	}
 
 	return 0;
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_kms.c b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
index e70a4f3..baac8c9 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_kms.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
@@ -362,6 +362,7 @@ static int rcar_du_encoders_init_one(struct rcar_du_device *rcdu,
 	} encoders[] = {
 		{ "adi,adv7123", RCAR_DU_ENCODER_VGA },
 		{ "adi,adv7511w", RCAR_DU_ENCODER_HDMI },
+		{ "rockchip,rcar-dw-hdmi", RCAR_DU_ENCODER_HDMI },
 		{ "thine,thc63lvdm83d", RCAR_DU_ENCODER_LVDS },
 	};
 
@@ -372,6 +373,7 @@ static int rcar_du_encoders_init_one(struct rcar_du_device *rcdu,
 	struct device_node *entity_ep_node;
 	struct device_node *entity;
 	int ret;
+	const char *enc_name = NULL;
 
 	/*
 	 * Locate the connected entity and infer its type from the number of
@@ -423,6 +425,7 @@ static int rcar_du_encoders_init_one(struct rcar_du_device *rcdu,
 			if (of_device_is_compatible(encoder,
 						    encoders[i].compatible)) {
 				enc_type = encoders[i].type;
+				enc_name = encoders[i].compatible;
 				break;
 			}
 		}
@@ -443,7 +446,8 @@ static int rcar_du_encoders_init_one(struct rcar_du_device *rcdu,
 		connector = entity;
 	}
 
-	ret = rcar_du_encoder_init(rcdu, enc_type, output, encoder, connector);
+	ret = rcar_du_encoder_init(rcdu, enc_type, output, encoder, connector,
+					enc_name);
 	of_node_put(encoder);
 	of_node_put(connector);
 
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [RFC 08/21] drm: rcar-du: Add DPLL support
  2016-05-30 15:59 [RFC 00/21] Renesas r8a7795/Salvator-X HDMI output prototype Ulrich Hecht
                   ` (6 preceding siblings ...)
  2016-05-30 16:00 ` [RFC 07/21] drm: rcar-du: Add dw_hdmi driver startup Ulrich Hecht
@ 2016-05-30 16:00 ` Ulrich Hecht
  2016-05-30 16:12   ` Dirk Behme
  2016-05-30 16:00 ` [RFC 09/21] drm: rcar-du: Fix display registers for R-Car Gen3 Ulrich Hecht
                   ` (14 subsequent siblings)
  22 siblings, 1 reply; 34+ messages in thread
From: Ulrich Hecht @ 2016-05-30 16:00 UTC (permalink / raw)
  To: linux-renesas-soc, geert
  Cc: kuninori.morimoto.gx, laurent.pinchart, dri-devel, architt, vz,
	koji.matsuoka.xm, Geert Uytterhoeven

From: Koji Matsuoka <koji.matsuoka.xm@renesas.com>

Signed-off-by: Koji Matsuoka <koji.matsuoka.xm@renesas.com>
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
 drivers/gpu/drm/rcar-du/rcar_du_crtc.c  | 97 ++++++++++++++++++++++++++++++++-
 drivers/gpu/drm/rcar-du/rcar_du_crtc.h  |  8 +++
 drivers/gpu/drm/rcar-du/rcar_du_drv.c   |  1 +
 drivers/gpu/drm/rcar-du/rcar_du_drv.h   |  1 +
 drivers/gpu/drm/rcar-du/rcar_du_plane.h |  7 ++-
 drivers/gpu/drm/rcar-du/rcar_du_regs.h  | 19 +++++++
 6 files changed, 131 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
index 0d8bdda..e10943b 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
@@ -30,6 +30,12 @@
 #include "rcar_du_regs.h"
 #include "rcar_du_vsp.h"
 
+#define PRODUCT_REG	0xfff00044
+#define PRODUCT_H3_BIT	(0x4f << 8)
+#define PRODUCT_MASK	(0x7f << 8)
+#define CUT_ES1		(0x00)
+#define CUT_ES1_MASK	(0x000000ff)
+
 static u32 rcar_du_crtc_read(struct rcar_du_crtc *rcrtc, u32 reg)
 {
 	struct rcar_du_device *rcdu = rcrtc->group->dev;
@@ -106,14 +112,74 @@ static void rcar_du_crtc_put(struct rcar_du_crtc *rcrtc)
  * Hardware Setup
  */
 
+static void rcar_du_dpll_divider(struct dpll_info *dpll, unsigned int extclk,
+				 unsigned int mode_clock)
+{
+	unsigned long dpllclk;
+	unsigned long diff;
+	unsigned long n, m, fdpll;
+	bool match_flag = false;
+	bool clk_diff_set = true;
+
+	for (n = 39; n < 120; n++) {
+		for (m = 0; m < 4; m++) {
+			for (fdpll = 1; fdpll < 32; fdpll++) {
+				/* 1/2 (FRQSEL=1) for duty rate 50% */
+				dpllclk = extclk * (n + 1) / (m + 1)
+						 / (fdpll + 1) / 2;
+				if (dpllclk >= 400000000)
+					continue;
+
+				diff = abs((long)dpllclk - (long)mode_clock);
+				if (clk_diff_set ||
+					((diff == 0) || (dpll->diff > diff))) {
+					dpll->diff = diff;
+					dpll->n = n;
+					dpll->m = m;
+					dpll->fdpll = fdpll;
+					dpll->dpllclk = dpllclk;
+
+					if (clk_diff_set)
+						clk_diff_set = false;
+
+					if (diff == 0) {
+						match_flag = true;
+						break;
+					}
+				}
+			}
+			if (match_flag)
+				break;
+		}
+		if (match_flag)
+			break;
+	}
+}
+
 static void rcar_du_crtc_set_display_timing(struct rcar_du_crtc *rcrtc)
 {
 	const struct drm_display_mode *mode = &rcrtc->crtc.state->adjusted_mode;
+	struct rcar_du_device *rcdu = rcrtc->group->dev;
 	unsigned long mode_clock = mode->clock * 1000;
 	unsigned long clk;
 	u32 value;
 	u32 escr;
 	u32 div;
+	u32 dpll_reg = 0;
+	struct dpll_info *dpll;
+	void __iomem *product_reg;
+	bool h3_es1_workaround = false;
+
+	dpll = kzalloc(sizeof(*dpll), GFP_KERNEL);
+	if (dpll == NULL)
+		return;
+
+	/* DU2 DPLL Clock Select bit workaround in R-Car H3(ES1.0) */
+	product_reg = ioremap(PRODUCT_REG, 0x04);
+	if (((readl(product_reg) & PRODUCT_MASK) == PRODUCT_H3_BIT)
+		&& ((readl(product_reg) & CUT_ES1_MASK) == CUT_ES1))
+		h3_es1_workaround = true;
+	iounmap(product_reg);
 
 	/* Compute the clock divisor and select the internal or external dot
 	 * clock based on the requested frequency.
@@ -130,6 +196,15 @@ static void rcar_du_crtc_set_display_timing(struct rcar_du_crtc *rcrtc)
 		u32 extdiv;
 
 		extclk = clk_get_rate(rcrtc->extclock);
+
+		if (rcdu->info->dpll_ch & (0x01 << rcrtc->index)) {
+			rcar_du_dpll_divider(dpll, extclk, mode_clock);
+			extclk = dpll->dpllclk;
+			dev_dbg(rcrtc->group->dev->dev,
+				"dpllclk:%d, fdpll:%d, n:%d, m:%d, diff:%d\n",
+				 dpll->dpllclk, dpll->fdpll, dpll->n, dpll->m,
+				 dpll->diff);
+		}
 		extdiv = DIV_ROUND_CLOSEST(extclk, mode_clock);
 		extdiv = clamp(extdiv, 1U, 64U) - 1;
 
@@ -140,7 +215,27 @@ static void rcar_du_crtc_set_display_timing(struct rcar_du_crtc *rcrtc)
 		    abs((long)rate - (long)mode_clock)) {
 			dev_dbg(rcrtc->group->dev->dev,
 				"crtc%u: using external clock\n", rcrtc->index);
-			escr = extdiv | ESCR_DCLKSEL_DCLKIN;
+			if (rcdu->info->dpll_ch & (0x01 << rcrtc->index)) {
+				escr = ESCR_DCLKSEL_DCLKIN | 0x01;
+				dpll_reg =  DPLLCR_CODE | DPLLCR_M(dpll->m) |
+					DPLLCR_FDPLL(dpll->fdpll) |
+					DPLLCR_CLKE | DPLLCR_N(dpll->n) |
+					DPLLCR_STBY;
+
+				if (rcrtc->index == DU_CH_1)
+					dpll_reg |= (DPLLCR_PLCS1 |
+						 DPLLCR_INCS_DPLL01_DOTCLKIN13);
+				if (rcrtc->index == DU_CH_2) {
+					dpll_reg |= (DPLLCR_PLCS0 |
+						 DPLLCR_INCS_DPLL01_DOTCLKIN02);
+					if (h3_es1_workaround)
+						dpll_reg |=  (0x01 << 21);
+				}
+
+				rcar_du_group_write(rcrtc->group, DPLLCR,
+								  dpll_reg);
+			} else
+				escr = extdiv | ESCR_DCLKSEL_DCLKIN;
 		}
 	}
 
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.h b/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
index 459e539..9a56cc7 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
+++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
@@ -54,6 +54,14 @@ struct rcar_du_crtc {
 	struct rcar_du_vsp *vsp;
 };
 
+struct dpll_info {
+	unsigned int dpllclk;
+	unsigned int diff;
+	unsigned int fdpll;
+	unsigned int n;
+	unsigned int m;
+};
+
 #define to_rcar_crtc(c)	container_of(c, struct rcar_du_crtc, crtc)
 
 enum rcar_du_output {
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.c b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
index 0a93d2a..5ed0d61 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_drv.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
@@ -165,6 +165,7 @@ static const struct rcar_du_device_info rcar_du_r8a7795_info = {
 		},
 	},
 	.num_lvds = 1,
+	.dpll_ch =  BIT(1) | BIT(2),
 };
 
 static const struct of_device_id rcar_du_of_table[] = {
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.h b/drivers/gpu/drm/rcar-du/rcar_du_drv.h
index d1d1d8d..790829b 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_drv.h
+++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.h
@@ -69,6 +69,7 @@ struct rcar_du_device_info {
 	unsigned int num_crtcs;
 	struct rcar_du_output_routing routes[RCAR_DU_OUTPUT_MAX];
 	unsigned int num_lvds;
+	unsigned int dpll_ch;
 };
 
 #define RCAR_DU_MAX_CRTCS		4
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_plane.h b/drivers/gpu/drm/rcar-du/rcar_du_plane.h
index b18b7b2..47fad23 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_plane.h
+++ b/drivers/gpu/drm/rcar-du/rcar_du_plane.h
@@ -1,7 +1,7 @@
 /*
  * rcar_du_plane.h  --  R-Car Display Unit Planes
  *
- * Copyright (C) 2013-2014 Renesas Electronics Corporation
+ * Copyright (C) 2013-2015 Renesas Electronics Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
  *
@@ -34,6 +34,11 @@ enum rcar_du_plane_source {
 	RCAR_DU_PLANE_VSPD1,
 };
 
+#define DU_CH_0		0
+#define DU_CH_1		1
+#define DU_CH_2		2
+#define DU_CH_3		3
+
 struct rcar_du_plane {
 	struct drm_plane plane;
 	struct rcar_du_group *group;
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_regs.h b/drivers/gpu/drm/rcar-du/rcar_du_regs.h
index fedb016..7a34bf3 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_regs.h
+++ b/drivers/gpu/drm/rcar-du/rcar_du_regs.h
@@ -277,6 +277,25 @@
 #define DEFR10_TSEL_H3_TCON1	(0 << 1) /* DEFR102 register only (DU2/DU3) */
 #define DEFR10_DEFE10		(1 << 0)
 
+#define DPLLCR			0x20044
+#define DPLLCR_CODE		(0x95 << 24)
+#define DPLLCR_PLCS1		(1 << 23)
+#define DPLLCR_PLCS0		(1 << 20)
+#define DPLLCR_CLKE		(1 << 18)
+#define DPLLCR_FDPLL(n)		((n) << 12)	/* n=0 Setting prohibited */
+/* H'00 to H'26, H'78 to H'7F: Setting prohibited.*/
+#define DPLLCR_N(n)		((n) << 5)
+#define DPLLCR_M(n)		((n) << 3)
+#define DPLLCR_STBY		(1 << 2)
+#define DPLLCR_INCS_DPLL01_DOTCLKIN02	(0 << 0)
+#define DPLLCR_INCS_DPLL01_DOTCLKIN13	(1 << 1)
+
+#define DPLLC2R			0x20048
+#define DPLLC2R_CODE		(0x95 << 24)
+#define DPLLC2R_SELC		(1 << 12)
+#define DPLLC2R_M(n)		((n) << 8)
+#define DPLLC2R_FDPLL(n)	((n) << 0)	/* n=0 Setting prohibited */
+
 /* -----------------------------------------------------------------------------
  * Display Timing Generation Registers
  */
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [RFC 09/21] drm: rcar-du: Fix display registers for R-Car Gen3
  2016-05-30 15:59 [RFC 00/21] Renesas r8a7795/Salvator-X HDMI output prototype Ulrich Hecht
                   ` (7 preceding siblings ...)
  2016-05-30 16:00 ` [RFC 08/21] drm: rcar-du: Add DPLL support Ulrich Hecht
@ 2016-05-30 16:00 ` Ulrich Hecht
  2016-05-30 16:00 ` [RFC 10/21] drm: rcar-du: Fix VSP plane number per devices Ulrich Hecht
                   ` (13 subsequent siblings)
  22 siblings, 0 replies; 34+ messages in thread
From: Ulrich Hecht @ 2016-05-30 16:00 UTC (permalink / raw)
  To: linux-renesas-soc, geert
  Cc: kuninori.morimoto.gx, laurent.pinchart, dri-devel, architt, vz,
	koji.matsuoka.xm, Geert Uytterhoeven

From: Koji Matsuoka <koji.matsuoka.xm@renesas.com>

Signed-off-by: Koji Matsuoka <koji.matsuoka.xm@renesas.com>
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
 drivers/gpu/drm/rcar-du/rcar_du_drv.c   | 3 ++-
 drivers/gpu/drm/rcar-du/rcar_du_group.c | 5 +++++
 drivers/gpu/drm/rcar-du/rcar_du_plane.c | 4 +++-
 3 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.c b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
index 5ed0d61..3907461 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_drv.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
@@ -137,7 +137,8 @@ static const struct rcar_du_device_info rcar_du_r8a7795_info = {
 	.gen = 3,
 	.features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
 		  | RCAR_DU_FEATURE_EXT_CTRL_REGS
-		  | RCAR_DU_FEATURE_VSP1_SOURCE,
+		  | RCAR_DU_FEATURE_VSP1_SOURCE
+		  | RCAR_DU_FEATURE_GEN3_REGS,
 	.num_crtcs = 4,
 	.routes = {
 		/* R8A7795 has one RGB output, two HDMI outputs and one
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_group.c b/drivers/gpu/drm/rcar-du/rcar_du_group.c
index 33b2fc5..55dd3bd 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_group.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_group.c
@@ -101,6 +101,11 @@ static void rcar_du_group_setup(struct rcar_du_group *rgrp)
 	rcar_du_group_write(rgrp, DEFR5, DEFR5_CODE | DEFR5_DEFE5);
 
 	rcar_du_group_setup_pins(rgrp);
+	if (rcdu->info->gen == 3) {
+		rcar_du_group_write(rgrp, DEFR6, DEFR6_CODE |
+					  DEFR6_ODPM22_DISP);
+		rcar_du_group_write(rgrp, DEFR10, DEFR10_CODE | DEFR10_DEFE10);
+	}
 
 	if (rcar_du_has(rgrp->dev, RCAR_DU_FEATURE_EXT_CTRL_REGS)) {
 		rcar_du_group_setup_defr8(rgrp);
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_plane.c b/drivers/gpu/drm/rcar-du/rcar_du_plane.c
index 8460ae1..8d5e59b 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_plane.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_plane.c
@@ -458,6 +458,7 @@ static void rcar_du_plane_setup_format_gen2(struct rcar_du_group *rgrp,
 					    unsigned int index,
 					    const struct rcar_du_plane_state *state)
 {
+	struct rcar_du_device *rcdu = rgrp->dev;
 	u32 ddcr2 = PnDDCR2_CODE;
 	u32 ddcr4;
 
@@ -484,7 +485,8 @@ static void rcar_du_plane_setup_format_gen2(struct rcar_du_group *rgrp,
 		}
 	}
 
-	rcar_du_plane_write(rgrp, index, PnDDCR2, ddcr2);
+	if (!rcar_du_has(rcdu, RCAR_DU_FEATURE_GEN3_REGS))
+		rcar_du_plane_write(rgrp, index, PnDDCR2, ddcr2);
 
 	ddcr4 = state->format->edf | PnDDCR4_CODE;
 	if (state->source != RCAR_DU_PLANE_MEMORY)
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [RFC 10/21] drm: rcar-du: Fix VSP plane number per devices
  2016-05-30 15:59 [RFC 00/21] Renesas r8a7795/Salvator-X HDMI output prototype Ulrich Hecht
                   ` (8 preceding siblings ...)
  2016-05-30 16:00 ` [RFC 09/21] drm: rcar-du: Fix display registers for R-Car Gen3 Ulrich Hecht
@ 2016-05-30 16:00 ` Ulrich Hecht
  2016-05-30 16:00 ` [RFC 11/21] drm: rcar-du: Fix VSP feed plane number Ulrich Hecht
                   ` (12 subsequent siblings)
  22 siblings, 0 replies; 34+ messages in thread
From: Ulrich Hecht @ 2016-05-30 16:00 UTC (permalink / raw)
  To: linux-renesas-soc, geert
  Cc: kuninori.morimoto.gx, laurent.pinchart, dri-devel, architt, vz,
	koji.matsuoka.xm, Geert Uytterhoeven

From: Koji Matsuoka <koji.matsuoka.xm@renesas.com>

Signed-off-by: Koji Matsuoka <koji.matsuoka.xm@renesas.com>
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
 drivers/gpu/drm/rcar-du/rcar_du_drv.c | 2 ++
 drivers/gpu/drm/rcar-du/rcar_du_drv.h | 3 ++-
 drivers/gpu/drm/rcar-du/rcar_du_vsp.c | 2 +-
 3 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.c b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
index 3907461..26fd3ba 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_drv.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
@@ -108,6 +108,7 @@ static const struct rcar_du_device_info rcar_du_r8a7791_info = {
 		},
 	},
 	.num_lvds = 1,
+	.vsp_num = 4,
 };
 
 static const struct rcar_du_device_info rcar_du_r8a7794_info = {
@@ -167,6 +168,7 @@ static const struct rcar_du_device_info rcar_du_r8a7795_info = {
 	},
 	.num_lvds = 1,
 	.dpll_ch =  BIT(1) | BIT(2),
+	.vsp_num = 5,
 };
 
 static const struct of_device_id rcar_du_of_table[] = {
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.h b/drivers/gpu/drm/rcar-du/rcar_du_drv.h
index 790829b..6413b7e 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_drv.h
+++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.h
@@ -70,12 +70,13 @@ struct rcar_du_device_info {
 	struct rcar_du_output_routing routes[RCAR_DU_OUTPUT_MAX];
 	unsigned int num_lvds;
 	unsigned int dpll_ch;
+	unsigned int vsp_num;
 };
 
 #define RCAR_DU_MAX_CRTCS		4
 #define RCAR_DU_MAX_GROUPS		DIV_ROUND_UP(RCAR_DU_MAX_CRTCS, 2)
 #define RCAR_DU_MAX_LVDS		2
-#define RCAR_DU_MAX_VSPS		4
+#define RCAR_DU_MAX_VSPS		5
 
 struct rcar_du_device {
 	struct device *dev;
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
index 4927fb3..89176e6 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
@@ -349,7 +349,7 @@ int rcar_du_vsp_init(struct rcar_du_vsp *vsp)
 	 /* The VSP2D (Gen3) has 5 RPFs, but the VSP1D (Gen2) is limited to
 	  * 4 RPFs.
 	  */
-	vsp->num_planes = rcdu->info->gen >= 3 ? 5 : 4;
+	vsp->num_planes = rcdu->info->vsp_num;
 
 	vsp->planes = devm_kcalloc(rcdu->dev, vsp->num_planes,
 				   sizeof(*vsp->planes), GFP_KERNEL);
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [RFC 11/21] drm: rcar-du: Fix VSP feed plane number
  2016-05-30 15:59 [RFC 00/21] Renesas r8a7795/Salvator-X HDMI output prototype Ulrich Hecht
                   ` (9 preceding siblings ...)
  2016-05-30 16:00 ` [RFC 10/21] drm: rcar-du: Fix VSP plane number per devices Ulrich Hecht
@ 2016-05-30 16:00 ` Ulrich Hecht
  2016-05-30 16:00 ` [RFC 12/21] drm: rcar-du: Add pixel format support Ulrich Hecht
                   ` (11 subsequent siblings)
  22 siblings, 0 replies; 34+ messages in thread
From: Ulrich Hecht @ 2016-05-30 16:00 UTC (permalink / raw)
  To: linux-renesas-soc, geert
  Cc: kuninori.morimoto.gx, laurent.pinchart, dri-devel, architt, vz,
	koji.matsuoka.xm, Geert Uytterhoeven

From: Koji Matsuoka <koji.matsuoka.xm@renesas.com>

VSP feeds plane1 and plane3 with R-Car Gen3.

Signed-off-by: Koji Matsuoka <koji.matsuoka.xm@renesas.com>
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
 drivers/gpu/drm/rcar-du/rcar_du_plane.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/rcar-du/rcar_du_plane.c b/drivers/gpu/drm/rcar-du/rcar_du_plane.c
index 8d5e59b..027c4cfb 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_plane.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_plane.c
@@ -489,7 +489,9 @@ static void rcar_du_plane_setup_format_gen2(struct rcar_du_group *rgrp,
 		rcar_du_plane_write(rgrp, index, PnDDCR2, ddcr2);
 
 	ddcr4 = state->format->edf | PnDDCR4_CODE;
-	if (state->source != RCAR_DU_PLANE_MEMORY)
+
+	if ((state->source != RCAR_DU_PLANE_MEMORY)
+		&& (!rcar_du_has(rcdu, RCAR_DU_FEATURE_GEN3_REGS)))
 		ddcr4 |= PnDDCR4_VSPS;
 
 	rcar_du_plane_write(rgrp, index, PnDDCR4, ddcr4);
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [RFC 12/21] drm: rcar-du: Add pixel format support
  2016-05-30 15:59 [RFC 00/21] Renesas r8a7795/Salvator-X HDMI output prototype Ulrich Hecht
                   ` (10 preceding siblings ...)
  2016-05-30 16:00 ` [RFC 11/21] drm: rcar-du: Fix VSP feed plane number Ulrich Hecht
@ 2016-05-30 16:00 ` Ulrich Hecht
  2016-05-30 16:00 ` [RFC 13/21] drm: rcar-du: Fix display max size to 4096x2160 size Ulrich Hecht
                   ` (10 subsequent siblings)
  22 siblings, 0 replies; 34+ messages in thread
From: Ulrich Hecht @ 2016-05-30 16:00 UTC (permalink / raw)
  To: linux-renesas-soc, geert
  Cc: kuninori.morimoto.gx, laurent.pinchart, dri-devel, architt, vz,
	koji.matsuoka.xm, Geert Uytterhoeven

From: Koji Matsuoka <koji.matsuoka.xm@renesas.com>

This patch supports pixel format of RGB332, ARGB4444, XRGB4444,
BGR888, RGB888, BGRA8888, BGRX8888, YVYU and NV61.
VYUY format is not supported by H/W.

Signed-off-by: Koji Matsuoka <koji.matsuoka.xm@renesas.com>
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
 drivers/gpu/drm/rcar-du/rcar_du_kms.c | 58 +++++++++++++++++++++++++++++++++--
 drivers/gpu/drm/rcar-du/rcar_du_kms.h |  1 +
 drivers/gpu/drm/rcar-du/rcar_du_vsp.c | 49 +++++++++++++++++++++++++++++
 3 files changed, 106 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/rcar-du/rcar_du_kms.c b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
index baac8c9..a8c59c3 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_kms.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
@@ -95,6 +95,40 @@ static const struct rcar_du_format_info rcar_du_format_infos[] = {
 		.planes = 2,
 		.pnmr = PnMR_SPIM_TP_OFF | PnMR_DDDF_YC,
 		.edf = PnDDCR4_EDF_NONE,
+	}, {
+		.fourcc = DRM_FORMAT_NV61,
+		.bpp = 16,
+		.planes = 2,
+		.pnmr = PnMR_SPIM_TP_OFF | PnMR_DDDF_YC,
+		.edf = PnDDCR4_EDF_NONE,
+	},
+};
+
+static const struct rcar_du_format_info rcar_vsp_format_infos[] = {
+	{
+		.fourcc = DRM_FORMAT_RGB332,
+		.bpp = 8,
+	}, {
+		.fourcc = DRM_FORMAT_ARGB4444,
+		.bpp = 16,
+	}, {
+		.fourcc = DRM_FORMAT_XRGB4444,
+		.bpp = 16,
+	}, {
+		.fourcc = DRM_FORMAT_BGR888,
+		.bpp = 24,
+	}, {
+		.fourcc = DRM_FORMAT_RGB888,
+		.bpp = 24,
+	}, {
+		.fourcc = DRM_FORMAT_BGRA8888,
+		.bpp = 32,
+	}, {
+		.fourcc = DRM_FORMAT_BGRX8888,
+		.bpp = 32,
+	}, {
+		.fourcc = DRM_FORMAT_YVYU,
+		.bpp = 16,
 	},
 	/* The following formats are not supported on Gen2 and thus have no
 	 * associated .pnmr or .edf settings.
@@ -142,6 +176,18 @@ const struct rcar_du_format_info *rcar_du_format_info(u32 fourcc)
 	return NULL;
 }
 
+const struct rcar_du_format_info *rcar_vsp_format_info(u32 fourcc)
+{
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(rcar_vsp_format_infos); ++i) {
+		if (rcar_vsp_format_infos[i].fourcc == fourcc)
+			return &rcar_vsp_format_infos[i];
+	}
+
+	return NULL;
+}
+
 /* -----------------------------------------------------------------------------
  * Frame buffer
  */
@@ -178,6 +224,15 @@ rcar_du_fb_create(struct drm_device *dev, struct drm_file *file_priv,
 	unsigned int i;
 
 	format = rcar_du_format_info(mode_cmd->pixel_format);
+
+	if (rcar_du_has(rcdu, RCAR_DU_FEATURE_VSP1_SOURCE) &&
+		(format == NULL)) {
+		format = rcar_vsp_format_info(mode_cmd->pixel_format);
+	}
+
+	if (rcar_du_has(rcdu, RCAR_DU_FEATURE_VSP1_SOURCE) && (format != NULL))
+		goto done;
+
 	if (format == NULL) {
 		dev_dbg(dev->dev, "unsupported pixel format %08x\n",
 			mode_cmd->pixel_format);
@@ -210,7 +265,7 @@ rcar_du_fb_create(struct drm_device *dev, struct drm_file *file_priv,
 			return ERR_PTR(-EINVAL);
 		}
 	}
-
+done:
 	return drm_fb_cma_create(dev, file_priv, mode_cmd);
 }
 
@@ -278,7 +333,6 @@ static void rcar_du_atomic_work(struct work_struct *work)
 {
 	struct rcar_du_commit *commit =
 		container_of(work, struct rcar_du_commit, work);
-
 	rcar_du_atomic_complete(commit);
 }
 
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_kms.h b/drivers/gpu/drm/rcar-du/rcar_du_kms.h
index 07951d5..10eb51a 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_kms.h
+++ b/drivers/gpu/drm/rcar-du/rcar_du_kms.h
@@ -30,6 +30,7 @@ struct rcar_du_format_info {
 };
 
 const struct rcar_du_format_info *rcar_du_format_info(u32 fourcc);
+const struct rcar_du_format_info *rcar_vsp_format_info(u32 fourcc);
 
 int rcar_du_modeset_init(struct rcar_du_device *rcdu);
 
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
index 89176e6..94e9181 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
@@ -143,6 +143,28 @@ static const u32 formats_v4l2[] = {
 	V4L2_PIX_FMT_YVU444M,
 };
 
+static const u32 formats_xlate[][2] = {
+	{ DRM_FORMAT_RGB332, V4L2_PIX_FMT_RGB332 },
+	{ DRM_FORMAT_ARGB4444, V4L2_PIX_FMT_ARGB444 },
+	{ DRM_FORMAT_XRGB4444, V4L2_PIX_FMT_XRGB444 },
+	{ DRM_FORMAT_ARGB1555, V4L2_PIX_FMT_ARGB555 },
+	{ DRM_FORMAT_XRGB1555, V4L2_PIX_FMT_XRGB555 },
+	{ DRM_FORMAT_RGB565, V4L2_PIX_FMT_RGB565 },
+	{ DRM_FORMAT_BGR888, V4L2_PIX_FMT_RGB24 },
+	{ DRM_FORMAT_RGB888, V4L2_PIX_FMT_BGR24 },
+	{ DRM_FORMAT_BGRA8888, V4L2_PIX_FMT_ARGB32 },
+	{ DRM_FORMAT_BGRX8888, V4L2_PIX_FMT_XRGB32 },
+	{ DRM_FORMAT_ARGB8888, V4L2_PIX_FMT_ABGR32 },
+	{ DRM_FORMAT_XRGB8888, V4L2_PIX_FMT_XBGR32 },
+	{ DRM_FORMAT_UYVY, V4L2_PIX_FMT_UYVY },
+	{ DRM_FORMAT_YUYV, V4L2_PIX_FMT_YUYV },
+	{ DRM_FORMAT_YVYU, V4L2_PIX_FMT_YVYU },
+	{ DRM_FORMAT_NV12, V4L2_PIX_FMT_NV12M },
+	{ DRM_FORMAT_NV21, V4L2_PIX_FMT_NV21M },
+	{ DRM_FORMAT_NV16, V4L2_PIX_FMT_NV16M },
+	{ DRM_FORMAT_NV61, V4L2_PIX_FMT_NV61M },
+};
+
 static void rcar_du_vsp_plane_setup(struct rcar_du_vsp_plane *plane)
 {
 	struct rcar_du_vsp_plane_state *state =
@@ -202,6 +224,11 @@ static int rcar_du_vsp_plane_atomic_check(struct drm_plane *plane,
 	}
 
 	rstate->format = rcar_du_format_info(state->fb->pixel_format);
+
+	if (rcar_du_has(rcdu, RCAR_DU_FEATURE_VSP1_SOURCE) &&
+			 (rstate->format == NULL))
+		rstate->format = rcar_vsp_format_info(state->fb->pixel_format);
+
 	if (rstate->format == NULL) {
 		dev_dbg(rcdu->dev, "%s: unsupported format %08x\n", __func__,
 			state->fb->pixel_format);
@@ -320,6 +347,28 @@ static const struct drm_plane_funcs rcar_du_vsp_plane_funcs = {
 	.atomic_get_property = rcar_du_vsp_plane_atomic_get_property,
 };
 
+static const uint32_t formats[] = {
+	DRM_FORMAT_RGB332,
+	DRM_FORMAT_ARGB4444,
+	DRM_FORMAT_XRGB4444,
+	DRM_FORMAT_ARGB1555,
+	DRM_FORMAT_XRGB1555,
+	DRM_FORMAT_RGB565,
+	DRM_FORMAT_BGR888,
+	DRM_FORMAT_RGB888,
+	DRM_FORMAT_BGRA8888,
+	DRM_FORMAT_BGRX8888,
+	DRM_FORMAT_ARGB8888,
+	DRM_FORMAT_XRGB8888,
+	DRM_FORMAT_UYVY,
+	DRM_FORMAT_YUYV,
+	DRM_FORMAT_YVYU,
+	DRM_FORMAT_NV12,
+	DRM_FORMAT_NV21,
+	DRM_FORMAT_NV16,
+	DRM_FORMAT_NV61,
+};
+
 int rcar_du_vsp_init(struct rcar_du_vsp *vsp)
 {
 	struct rcar_du_device *rcdu = vsp->dev;
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [RFC 13/21] drm: rcar-du: Fix display max size to 4096x2160 size
  2016-05-30 15:59 [RFC 00/21] Renesas r8a7795/Salvator-X HDMI output prototype Ulrich Hecht
                   ` (11 preceding siblings ...)
  2016-05-30 16:00 ` [RFC 12/21] drm: rcar-du: Add pixel format support Ulrich Hecht
@ 2016-05-30 16:00 ` Ulrich Hecht
  2016-05-30 16:00 ` [RFC 14/21] v4l: vsp1: Change VSP1 LIF linebuffer FIFO Ulrich Hecht
                   ` (9 subsequent siblings)
  22 siblings, 0 replies; 34+ messages in thread
From: Ulrich Hecht @ 2016-05-30 16:00 UTC (permalink / raw)
  To: linux-renesas-soc, geert
  Cc: kuninori.morimoto.gx, laurent.pinchart, dri-devel, architt, vz,
	koji.matsuoka.xm, Geert Uytterhoeven

From: Koji Matsuoka <koji.matsuoka.xm@renesas.com>

Signed-off-by: Koji Matsuoka <koji.matsuoka.xm@renesas.com>
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
 drivers/gpu/drm/rcar-du/rcar_du_kms.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/rcar-du/rcar_du_kms.c b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
index a8c59c3..d6d9acb 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_kms.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
@@ -611,8 +611,8 @@ int rcar_du_modeset_init(struct rcar_du_device *rcdu)
 
 	dev->mode_config.min_width = 0;
 	dev->mode_config.min_height = 0;
-	dev->mode_config.max_width = 4095;
-	dev->mode_config.max_height = 2047;
+	dev->mode_config.max_width = 4096;
+	dev->mode_config.max_height = 2160;
 	dev->mode_config.funcs = &rcar_du_mode_config_funcs;
 
 	rcdu->num_crtcs = rcdu->info->num_crtcs;
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [RFC 14/21] v4l: vsp1: Change VSP1 LIF linebuffer FIFO
  2016-05-30 15:59 [RFC 00/21] Renesas r8a7795/Salvator-X HDMI output prototype Ulrich Hecht
                   ` (12 preceding siblings ...)
  2016-05-30 16:00 ` [RFC 13/21] drm: rcar-du: Fix display max size to 4096x2160 size Ulrich Hecht
@ 2016-05-30 16:00 ` Ulrich Hecht
  2022-04-21 16:12     ` Eugeniu Rosca
  2016-05-30 16:00 ` [RFC 15/21] pinctrl: sh-pfc: r8a7795: Add DU support Ulrich Hecht
                   ` (8 subsequent siblings)
  22 siblings, 1 reply; 34+ messages in thread
From: Ulrich Hecht @ 2016-05-30 16:00 UTC (permalink / raw)
  To: linux-renesas-soc, geert
  Cc: kuninori.morimoto.gx, laurent.pinchart, dri-devel, architt, vz,
	koji.matsuoka.xm, Ulrich Hecht, Takashi Saito,
	Geert Uytterhoeven

This patch changes to VSPD hardware recommended value.
Purpose is highest pixel clock without underruns.
In the default R-Car Linux BSP config this value is
wrong and therefore there are many underruns.

Signed-off-by: Takashi Saito <takashi.saitou.ry@renesas.com>
Signed-off-by: Koji Matsuoka <koji.matsuoka.xm@renesas.com>
Signed-off-by: Ulrich Hecht <ulrich.hecht+renesas@gmail.com>
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
 drivers/media/platform/vsp1/vsp1_lif.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/media/platform/vsp1/vsp1_lif.c b/drivers/media/platform/vsp1/vsp1_lif.c
index 60d26b6..b34e80f 100644
--- a/drivers/media/platform/vsp1/vsp1_lif.c
+++ b/drivers/media/platform/vsp1/vsp1_lif.c
@@ -126,9 +126,9 @@ static void lif_configure(struct vsp1_entity *entity,
 {
 	const struct v4l2_mbus_framefmt *format;
 	struct vsp1_lif *lif = to_lif(&entity->subdev);
-	unsigned int hbth = 1300;
-	unsigned int obth = 400;
-	unsigned int lbth = 200;
+	unsigned int hbth = 0;
+	unsigned int obth = 3000;
+	unsigned int lbth = 0;
 
 	format = vsp1_entity_get_pad_format(&lif->entity, lif->entity.config,
 					    LIF_PAD_SOURCE);
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [RFC 15/21] pinctrl: sh-pfc: r8a7795: Add DU support
  2016-05-30 15:59 [RFC 00/21] Renesas r8a7795/Salvator-X HDMI output prototype Ulrich Hecht
                   ` (13 preceding siblings ...)
  2016-05-30 16:00 ` [RFC 14/21] v4l: vsp1: Change VSP1 LIF linebuffer FIFO Ulrich Hecht
@ 2016-05-30 16:00 ` Ulrich Hecht
  2016-05-30 16:00 ` [RFC 16/21] pinctrl: sh-pfc: r8a7795: Add HDMI CEC support Ulrich Hecht
                   ` (7 subsequent siblings)
  22 siblings, 0 replies; 34+ messages in thread
From: Ulrich Hecht @ 2016-05-30 16:00 UTC (permalink / raw)
  To: linux-renesas-soc, geert
  Cc: kuninori.morimoto.gx, laurent.pinchart, dri-devel, architt, vz,
	koji.matsuoka.xm, Ulrich Hecht, Geert Uytterhoeven

Adds DU pinmux support to r8a7795 SoC.
Based on work by Takeshi Kihara.

Signed-off-by: Ulrich Hecht <ulrich.hecht+renesas@gmail.com>
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
 drivers/pinctrl/sh-pfc/pfc-r8a7795.c | 86 ++++++++++++++++++++++++++++++++++++
 1 file changed, 86 insertions(+)

diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7795.c b/drivers/pinctrl/sh-pfc/pfc-r8a7795.c
index 44632b1..66cee18 100644
--- a/drivers/pinctrl/sh-pfc/pfc-r8a7795.c
+++ b/drivers/pinctrl/sh-pfc/pfc-r8a7795.c
@@ -1654,6 +1654,74 @@ static const unsigned int canfd1_data_mux[] = {
 	CANFD1_TX_MARK,         CANFD1_RX_MARK,
 };
 
+/* - DU --------------------------------------------------------------------- */
+static const unsigned int du_rgb888_pins[] = {
+	/* R[7:0] */
+	RCAR_GP_PIN(0, 15), RCAR_GP_PIN(0, 14), RCAR_GP_PIN(0, 13),
+	RCAR_GP_PIN(0, 12), RCAR_GP_PIN(0, 11), RCAR_GP_PIN(0, 10),
+	RCAR_GP_PIN(0, 9),  RCAR_GP_PIN(3, 8),
+
+	/* G[7:0] */
+	RCAR_GP_PIN(1, 15), RCAR_GP_PIN(1, 14), RCAR_GP_PIN(1, 13),
+	RCAR_GP_PIN(1, 12), RCAR_GP_PIN(1, 19), RCAR_GP_PIN(1, 18),
+	RCAR_GP_PIN(1, 17), RCAR_GP_PIN(1, 16),
+
+	/* B[7:0] */
+	RCAR_GP_PIN(1, 7),  RCAR_GP_PIN(1, 6),  RCAR_GP_PIN(1, 5),
+	RCAR_GP_PIN(1, 4),  RCAR_GP_PIN(1, 3),  RCAR_GP_PIN(1, 2),
+	RCAR_GP_PIN(1, 1),  RCAR_GP_PIN(1, 0),
+};
+static const unsigned int du_rgb888_mux[] = {
+	DU_DR7_MARK, DU_DR6_MARK, DU_DR5_MARK, DU_DR4_MARK,
+	DU_DR3_MARK, DU_DR2_MARK, DU_DR1_MARK, DU_DR0_MARK,
+	DU_DG7_MARK, DU_DG6_MARK, DU_DG5_MARK, DU_DG4_MARK,
+	DU_DG3_MARK, DU_DG2_MARK, DU_DG1_MARK, DU_DG0_MARK,
+	DU_DB7_MARK, DU_DB6_MARK, DU_DB5_MARK, DU_DB4_MARK,
+	DU_DB3_MARK, DU_DB2_MARK, DU_DB1_MARK, DU_DB0_MARK,
+};
+static const unsigned int du_clk_out_0_pins[] = {
+	/* CLKOUT */
+	RCAR_GP_PIN(1, 27),
+};
+static const unsigned int du_clk_out_0_mux[] = {
+	DU_DOTCLKOUT0_MARK
+};
+static const unsigned int du_clk_out_1_pins[] = {
+	/* CLKOUT */
+	RCAR_GP_PIN(2, 3),
+};
+static const unsigned int du_clk_out_1_mux[] = {
+	DU_DOTCLKOUT1_MARK
+};
+static const unsigned int du_sync_pins[] = {
+	/* EXVSYNC/VSYNC, EXHSYNC/HSYNC */
+	RCAR_GP_PIN(2, 5), RCAR_GP_PIN(2, 4),
+};
+static const unsigned int du_sync_mux[] = {
+	DU_EXVSYNC_DU_VSYNC_MARK, DU_EXHSYNC_DU_HSYNC_MARK
+};
+static const unsigned int du_oddf_pins[] = {
+	/* EXDISP/EXODDF/EXCDE */
+	RCAR_GP_PIN(2, 2),
+};
+static const unsigned int du_oddf_mux[] = {
+	DU_EXODDF_DU_ODDF_DISP_CDE_MARK,
+};
+static const unsigned int du_cde_pins[] = {
+	/* CDE */
+	RCAR_GP_PIN(2, 0),
+};
+static const unsigned int du_cde_mux[] = {
+	DU_CDE_MARK,
+};
+static const unsigned int du_disp_pins[] = {
+	/* DISP */
+	RCAR_GP_PIN(2, 1),
+};
+static const unsigned int du_disp_mux[] = {
+	DU_DISP_MARK,
+};
+
 /* - HSCIF0 ----------------------------------------------------------------- */
 static const unsigned int hscif0_data_pins[] = {
 	/* RX, TX */
@@ -3346,6 +3414,13 @@ static const struct sh_pfc_pin_group pinmux_groups[] = {
 	SH_PFC_PIN_GROUP(canfd0_data_a),
 	SH_PFC_PIN_GROUP(canfd0_data_b),
 	SH_PFC_PIN_GROUP(canfd1_data),
+	SH_PFC_PIN_GROUP(du_rgb888),
+	SH_PFC_PIN_GROUP(du_clk_out_0),
+	SH_PFC_PIN_GROUP(du_clk_out_1),
+	SH_PFC_PIN_GROUP(du_sync),
+	SH_PFC_PIN_GROUP(du_oddf),
+	SH_PFC_PIN_GROUP(du_cde),
+	SH_PFC_PIN_GROUP(du_disp),
 	SH_PFC_PIN_GROUP(hscif0_data),
 	SH_PFC_PIN_GROUP(hscif0_clk),
 	SH_PFC_PIN_GROUP(hscif0_ctrl),
@@ -3575,6 +3650,16 @@ static const struct sh_pfc_pin_group pinmux_groups[] = {
 	SH_PFC_PIN_GROUP(usb2),
 };
 
+static const char * const du_groups[] = {
+	"du_rgb888",
+	"du_clk_out_0",
+	"du_clk_out_1",
+	"du_sync",
+	"du_oddf",
+	"du_cde",
+	"du_disp",
+};
+
 static const char * const audio_clk_groups[] = {
 	"audio_clk_a_a",
 	"audio_clk_a_b",
@@ -3972,6 +4057,7 @@ static const struct sh_pfc_function pinmux_functions[] = {
 	SH_PFC_FUNCTION(can_clk),
 	SH_PFC_FUNCTION(canfd0),
 	SH_PFC_FUNCTION(canfd1),
+	SH_PFC_FUNCTION(du),
 	SH_PFC_FUNCTION(hscif0),
 	SH_PFC_FUNCTION(hscif1),
 	SH_PFC_FUNCTION(hscif2),
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [RFC 16/21] pinctrl: sh-pfc: r8a7795: Add HDMI CEC support
  2016-05-30 15:59 [RFC 00/21] Renesas r8a7795/Salvator-X HDMI output prototype Ulrich Hecht
                   ` (14 preceding siblings ...)
  2016-05-30 16:00 ` [RFC 15/21] pinctrl: sh-pfc: r8a7795: Add DU support Ulrich Hecht
@ 2016-05-30 16:00 ` Ulrich Hecht
  2016-05-30 16:00 ` [RFC 17/21] arm64: dts: r8a7795: Add HDMI encoder support Ulrich Hecht
                   ` (6 subsequent siblings)
  22 siblings, 0 replies; 34+ messages in thread
From: Ulrich Hecht @ 2016-05-30 16:00 UTC (permalink / raw)
  To: linux-renesas-soc, geert
  Cc: kuninori.morimoto.gx, laurent.pinchart, dri-devel, architt, vz,
	koji.matsuoka.xm, Ulrich Hecht, Geert Uytterhoeven

Adds DU pinmux support to r8a7795 SoC.
Based on work by Takeshi Kihara.

Signed-off-by: Ulrich Hecht <ulrich.hecht+renesas@gmail.com>
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
 drivers/pinctrl/sh-pfc/pfc-r8a7795.c | 27 +++++++++++++++++++++++++++
 1 file changed, 27 insertions(+)

diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7795.c b/drivers/pinctrl/sh-pfc/pfc-r8a7795.c
index 66cee18..515b88f 100644
--- a/drivers/pinctrl/sh-pfc/pfc-r8a7795.c
+++ b/drivers/pinctrl/sh-pfc/pfc-r8a7795.c
@@ -1721,6 +1721,21 @@ static const unsigned int du_disp_pins[] = {
 static const unsigned int du_disp_mux[] = {
 	DU_DISP_MARK,
 };
+/* - HDMI ------------------------------------------------------------------- */
+static const unsigned int hdmi0_cec_pins[] = {
+	/* HDMI0_CEC */
+	RCAR_GP_PIN(7, 2),
+};
+static const unsigned int hdmi0_cec_mux[] = {
+	HDMI0_CEC_MARK,
+};
+static const unsigned int hdmi1_cec_pins[] = {
+	/* HDMI0_CEC */
+	RCAR_GP_PIN(7, 3),
+};
+static const unsigned int hdmi1_cec_mux[] = {
+	HDMI1_CEC_MARK,
+};
 
 /* - HSCIF0 ----------------------------------------------------------------- */
 static const unsigned int hscif0_data_pins[] = {
@@ -3421,6 +3436,8 @@ static const struct sh_pfc_pin_group pinmux_groups[] = {
 	SH_PFC_PIN_GROUP(du_oddf),
 	SH_PFC_PIN_GROUP(du_cde),
 	SH_PFC_PIN_GROUP(du_disp),
+	SH_PFC_PIN_GROUP(hdmi0_cec),
+	SH_PFC_PIN_GROUP(hdmi1_cec),
 	SH_PFC_PIN_GROUP(hscif0_data),
 	SH_PFC_PIN_GROUP(hscif0_clk),
 	SH_PFC_PIN_GROUP(hscif0_ctrl),
@@ -3660,6 +3677,14 @@ static const char * const du_groups[] = {
 	"du_disp",
 };
 
+static const char * const hdmi0_groups[] = {
+	"hdmi0_cec",
+};
+
+static const char * const hdmi1_groups[] = {
+	"hdmi1_cec",
+};
+
 static const char * const audio_clk_groups[] = {
 	"audio_clk_a_a",
 	"audio_clk_a_b",
@@ -4058,6 +4083,8 @@ static const struct sh_pfc_function pinmux_functions[] = {
 	SH_PFC_FUNCTION(canfd0),
 	SH_PFC_FUNCTION(canfd1),
 	SH_PFC_FUNCTION(du),
+	SH_PFC_FUNCTION(hdmi0),
+	SH_PFC_FUNCTION(hdmi1),
 	SH_PFC_FUNCTION(hscif0),
 	SH_PFC_FUNCTION(hscif1),
 	SH_PFC_FUNCTION(hscif2),
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [RFC 17/21] arm64: dts: r8a7795: Add HDMI encoder support
  2016-05-30 15:59 [RFC 00/21] Renesas r8a7795/Salvator-X HDMI output prototype Ulrich Hecht
                   ` (15 preceding siblings ...)
  2016-05-30 16:00 ` [RFC 16/21] pinctrl: sh-pfc: r8a7795: Add HDMI CEC support Ulrich Hecht
@ 2016-05-30 16:00 ` Ulrich Hecht
  2016-05-30 16:00 ` [RFC 18/21] arm64: dts: salvator-x: Add DU pins, HDMI connectors and encoder Ulrich Hecht
                   ` (5 subsequent siblings)
  22 siblings, 0 replies; 34+ messages in thread
From: Ulrich Hecht @ 2016-05-30 16:00 UTC (permalink / raw)
  To: linux-renesas-soc, geert
  Cc: kuninori.morimoto.gx, laurent.pinchart, dri-devel, architt, vz,
	koji.matsuoka.xm, Ulrich Hecht, Geert Uytterhoeven

Based on work by  Koji Matsuoka.

Signed-off-by: Ulrich Hecht <ulrich.hecht+renesas@gmail.com>
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
 arch/arm64/boot/dts/renesas/r8a7795.dtsi | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/arch/arm64/boot/dts/renesas/r8a7795.dtsi b/arch/arm64/boot/dts/renesas/r8a7795.dtsi
index c9919d2..fcad91a 100644
--- a/arch/arm64/boot/dts/renesas/r8a7795.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a7795.dtsi
@@ -1587,5 +1587,21 @@
 				};
 			};
 		};
+
+		hdmi0: hdmi0@fead0000 {
+			compatible = "renesas,hdmi";
+			reg = <0 0xfead0000 0 0x10000>;
+			interrupts = <0 389 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 729>;
+			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+		};
+
+		hdmi1: hdmi1@feae0000 {
+			compatible = "renesas,hdmi";
+			reg = <0 0xfeae0000 0 0x10000>;
+			interrupts = <0 436 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 728>;
+			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+		};
 	};
 };
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [RFC 18/21] arm64: dts: salvator-x: Add DU pins, HDMI connectors and encoder
  2016-05-30 15:59 [RFC 00/21] Renesas r8a7795/Salvator-X HDMI output prototype Ulrich Hecht
                   ` (16 preceding siblings ...)
  2016-05-30 16:00 ` [RFC 17/21] arm64: dts: r8a7795: Add HDMI encoder support Ulrich Hecht
@ 2016-05-30 16:00 ` Ulrich Hecht
  2016-05-30 16:00 ` [RFC 19/21] arm64: configs: Enable R-Car DU related config Ulrich Hecht
                   ` (4 subsequent siblings)
  22 siblings, 0 replies; 34+ messages in thread
From: Ulrich Hecht @ 2016-05-30 16:00 UTC (permalink / raw)
  To: linux-renesas-soc, geert
  Cc: kuninori.morimoto.gx, laurent.pinchart, dri-devel, architt, vz,
	koji.matsuoka.xm, Ulrich Hecht, Geert Uytterhoeven

From: Koji Matsuoka <koji.matsuoka.xm@renesas.com>

Based on work by Koji Matsuoka.

Signed-off-by: Ulrich Hecht <ulrich.hecht+renesas@gmail.com>
[geert: Re-add removed extal_clk]
[geert: Modify existing du node instead of moving it around]
[geert: Use generic pinctrl properties]
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
 arch/arm64/boot/dts/renesas/r8a7795-salvator-x.dts | 107 +++++++++++++++++++++
 1 file changed, 107 insertions(+)

diff --git a/arch/arm64/boot/dts/renesas/r8a7795-salvator-x.dts b/arch/arm64/boot/dts/renesas/r8a7795-salvator-x.dts
index f8e4e33..c09ead3 100644
--- a/arch/arm64/boot/dts/renesas/r8a7795-salvator-x.dts
+++ b/arch/arm64/boot/dts/renesas/r8a7795-salvator-x.dts
@@ -169,17 +169,119 @@
 			};
 		};
 	};
+
+	hdmi0-encoder {
+		compatible = "rockchip,rcar-dw-hdmi";
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			port@0 {
+				reg = <0>;
+				rcar_dw_hdmi0_in: endpoint {
+					remote-endpoint = <&du_out_hdmi0>;
+				};
+			};
+			port@1 {
+				reg = <1>;
+				rcar_dw_hdmi0_out: endpoint {
+					remote-endpoint = <&hdmi0_con>;
+				};
+			};
+		};
+	};
+
+	hdmi0-out {
+		compatible = "hdmi-connector";
+		type = "a";
+
+		port {
+			hdmi0_con: endpoint {
+				remote-endpoint = <&rcar_dw_hdmi0_out>;
+			};
+		};
+	};
+
+	hdmi1-encoder {
+		compatible = "rockchip,rcar-dw-hdmi";
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			port@0 {
+				reg = <0>;
+				rcar_dw_hdmi1_in: endpoint {
+					remote-endpoint = <&du_out_hdmi1>;
+				};
+			};
+			port@1 {
+				reg = <1>;
+				rcar_dw_hdmi1_out: endpoint {
+					remote-endpoint = <&hdmi1_con>;
+				};
+			};
+		};
+	};
+
+	hdmi1-out {
+		compatible = "hdmi-connector";
+		type = "a";
+
+		port {
+			hdmi1_con: endpoint {
+				remote-endpoint = <&rcar_dw_hdmi1_out>;
+			};
+		};
+	};
+
+	programable_clk0: clock_out0 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <148500000>;
+	};
+
+	x21_clk: x21-clock {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <33000000>;
+	};
+
+	x22_clk: x22-clock {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <33000000>;
+	};
+
+	programable_clk1: clock_out1 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <108000000>;
+	};
 };
 
 &du {
+	pinctrl-0 = <&du_pins>;
+	pinctrl-names = "default";
 	status = "okay";
 
+	backlight = <&gpio6 7 GPIO_ACTIVE_HIGH>;
+
 	ports {
 		port@0 {
 			endpoint {
 				remote-endpoint = <&adv7123_in>;
 			};
 		};
+		port@1 {
+			endpoint {
+				remote-endpoint = <&rcar_dw_hdmi0_in>;
+			};
+		};
+		port@2 {
+			endpoint {
+				remote-endpoint = <&rcar_dw_hdmi1_in>;
+			};
+		};
 	};
 };
 
@@ -256,6 +358,11 @@
 		groups = "usb2";
 		function = "usb2";
 	};
+
+	du_pins: du {
+		groups = "du_rgb888", "du_sync", "du_clk_out_0", "du_disp";
+		function = "du";
+	};
 };
 
 &scif1 {
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [RFC 19/21] arm64: configs: Enable R-Car DU related config
  2016-05-30 15:59 [RFC 00/21] Renesas r8a7795/Salvator-X HDMI output prototype Ulrich Hecht
                   ` (17 preceding siblings ...)
  2016-05-30 16:00 ` [RFC 18/21] arm64: dts: salvator-x: Add DU pins, HDMI connectors and encoder Ulrich Hecht
@ 2016-05-30 16:00 ` Ulrich Hecht
  2016-05-30 16:00 ` [RFC 20/21] arm64: dts: r8a7795: add HDMI support to DU Ulrich Hecht
                   ` (3 subsequent siblings)
  22 siblings, 0 replies; 34+ messages in thread
From: Ulrich Hecht @ 2016-05-30 16:00 UTC (permalink / raw)
  To: linux-renesas-soc, geert
  Cc: kuninori.morimoto.gx, laurent.pinchart, dri-devel, architt, vz,
	koji.matsuoka.xm, Geert Uytterhoeven

From: Koji Matsuoka <koji.matsuoka.xm@renesas.com>

Signed-off-by: Koji Matsuoka <koji.matsuoka.xm@renesas.com>
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
 arch/arm64/configs/defconfig | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index aa47366..fc10983 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -212,6 +212,20 @@ CONFIG_REGULATOR_HI655X=y
 CONFIG_REGULATOR_QCOM_SMD_RPM=y
 CONFIG_REGULATOR_QCOM_SPMI=y
 CONFIG_REGULATOR_S2MPS11=y
+CONFIG_MEDIA_SUPPORT=y
+CONFIG_MEDIA_CAMERA_SUPPORT=y
+CONFIG_MEDIA_CONTROLLER=y
+CONFIG_VIDEO_V4L2_SUBDEV_API=y
+CONFIG_V4L_PLATFORM_DRIVERS=y
+CONFIG_SOC_CAMERA=y
+CONFIG_SOC_CAMERA_PLATFORM=y
+CONFIG_V4L_MEM2MEM_DRIVERS=y
+CONFIG_VIDEO_RENESAS_VSP1=y
+CONFIG_DRM=y
+CONFIG_DRM_RCAR_DU=y
+CONFIG_DRM_RCAR_HDMI=y
+CONFIG_DRM_RCAR_LVDS=y
+CONFIG_DRM_RCAR_VSP=y
 CONFIG_FB=y
 CONFIG_FB_ARMCLCD=y
 CONFIG_FRAMEBUFFER_CONSOLE=y
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [RFC 20/21] arm64: dts: r8a7795: add HDMI support to DU
  2016-05-30 15:59 [RFC 00/21] Renesas r8a7795/Salvator-X HDMI output prototype Ulrich Hecht
                   ` (18 preceding siblings ...)
  2016-05-30 16:00 ` [RFC 19/21] arm64: configs: Enable R-Car DU related config Ulrich Hecht
@ 2016-05-30 16:00 ` Ulrich Hecht
  2016-05-30 16:00 ` [RFC 21/21] arm64: defconfig: add VIDEO_RENESAS_FCP Ulrich Hecht
                   ` (2 subsequent siblings)
  22 siblings, 0 replies; 34+ messages in thread
From: Ulrich Hecht @ 2016-05-30 16:00 UTC (permalink / raw)
  To: linux-renesas-soc, geert
  Cc: kuninori.morimoto.gx, laurent.pinchart, dri-devel, architt, vz,
	koji.matsuoka.xm, Ulrich Hecht, Geert Uytterhoeven

Signed-off-by: Ulrich Hecht <ulrich.hecht+renesas@gmail.com>
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
 arch/arm64/boot/dts/renesas/r8a7795.dtsi | 17 +++++++++++++++--
 1 file changed, 15 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/renesas/r8a7795.dtsi b/arch/arm64/boot/dts/renesas/r8a7795.dtsi
index fcad91a..6e0737b 100644
--- a/arch/arm64/boot/dts/renesas/r8a7795.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a7795.dtsi
@@ -1555,12 +1555,25 @@
 				 <&cpg CPG_MOD 723>,
 				 <&cpg CPG_MOD 722>,
 				 <&cpg CPG_MOD 721>,
-				 <&cpg CPG_MOD 727>;
-			clock-names = "du.0", "du.1", "du.2", "du.3", "lvds.0";
+				 <&cpg CPG_MOD 727>,
+				 <&cpg CPG_MOD 729>,
+				 <&cpg CPG_MOD 728>,
+				 <&programable_clk0>,
+				 <&x21_clk>,
+				 <&x22_clk>,
+				 <&programable_clk1>;
+			clock-names = "du.0", "du.1", "du.2", "du.3", "lvds.0",
+				      "isfr.0", "isfr.1", "dclkin.0",
+				      "dclkin.1", "dclkin.2", "dclkin.3";
 			status = "disabled";
 
 			vsps = <&vspd0 &vspd1 &vspd2 &vspd3>;
 
+			hdmi = <&hdmi0 &hdmi1>;
+			interlaced = <1>;
+			clock-iahb = <0>;
+			hdmi-num = <2>;
+
 			ports {
 				#address-cells = <1>;
 				#size-cells = <0>;
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [RFC 21/21] arm64: defconfig: add VIDEO_RENESAS_FCP
  2016-05-30 15:59 [RFC 00/21] Renesas r8a7795/Salvator-X HDMI output prototype Ulrich Hecht
                   ` (19 preceding siblings ...)
  2016-05-30 16:00 ` [RFC 20/21] arm64: dts: r8a7795: add HDMI support to DU Ulrich Hecht
@ 2016-05-30 16:00 ` Ulrich Hecht
  2016-05-30 17:29   ` Geert Uytterhoeven
  2016-05-31  8:10 ` Ulrich Hecht
  22 siblings, 0 replies; 34+ messages in thread
From: Ulrich Hecht @ 2016-05-30 16:00 UTC (permalink / raw)
  To: linux-renesas-soc, geert
  Cc: kuninori.morimoto.gx, laurent.pinchart, dri-devel, architt, vz,
	koji.matsuoka.xm, Geert Uytterhoeven

From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>

DRM_RCAR_VSP requests VIDEO_RENESAS_VSP1, and VIDEO_RENESAS_VSP1 requests
VIDEO_RENESAS_FCP. But VIDEO_RENESAS_FCP is not set on defconfig.
This patch adds it. Otherwise kernel goes to Oops.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
 arch/arm64/configs/defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index fc10983..bc9bfff 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -220,6 +220,7 @@ CONFIG_V4L_PLATFORM_DRIVERS=y
 CONFIG_SOC_CAMERA=y
 CONFIG_SOC_CAMERA_PLATFORM=y
 CONFIG_V4L_MEM2MEM_DRIVERS=y
+CONFIG_VIDEO_RENESAS_FCP=y
 CONFIG_VIDEO_RENESAS_VSP1=y
 CONFIG_DRM=y
 CONFIG_DRM_RCAR_DU=y
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* Re: [RFC 08/21] drm: rcar-du: Add DPLL support
  2016-05-30 16:00 ` [RFC 08/21] drm: rcar-du: Add DPLL support Ulrich Hecht
@ 2016-05-30 16:12   ` Dirk Behme
  0 siblings, 0 replies; 34+ messages in thread
From: Dirk Behme @ 2016-05-30 16:12 UTC (permalink / raw)
  To: Ulrich Hecht, linux-renesas-soc, geert
  Cc: kuninori.morimoto.gx, laurent.pinchart, dri-devel, architt, vz,
	koji.matsuoka.xm, Geert Uytterhoeven

On 30.05.2016 18:00, Ulrich Hecht wrote:
> From: Koji Matsuoka <koji.matsuoka.xm@renesas.com>
>
> Signed-off-by: Koji Matsuoka <koji.matsuoka.xm@renesas.com>
> Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
> ---
>   drivers/gpu/drm/rcar-du/rcar_du_crtc.c  | 97 ++++++++++++++++++++++++++++++++-
>   drivers/gpu/drm/rcar-du/rcar_du_crtc.h  |  8 +++
>   drivers/gpu/drm/rcar-du/rcar_du_drv.c   |  1 +
>   drivers/gpu/drm/rcar-du/rcar_du_drv.h   |  1 +
>   drivers/gpu/drm/rcar-du/rcar_du_plane.h |  7 ++-
>   drivers/gpu/drm/rcar-du/rcar_du_regs.h  | 19 +++++++
>   6 files changed, 131 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> index 0d8bdda..e10943b 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> @@ -30,6 +30,12 @@
>   #include "rcar_du_regs.h"
>   #include "rcar_du_vsp.h"
>
> +#define PRODUCT_REG	0xfff00044
> +#define PRODUCT_H3_BIT	(0x4f << 8)
> +#define PRODUCT_MASK	(0x7f << 8)
> +#define CUT_ES1		(0x00)
> +#define CUT_ES1_MASK	(0x000000ff)


NACK for the hard coded register.

We've already discussed this in the thread

https://www.mail-archive.com/linux-renesas-soc@vger.kernel.org/msg04008.html

and found that this isn't ready this way:

https://www.mail-archive.com/linux-renesas-soc@vger.kernel.org/msg04079.html

Best regards

Dirk



>   static u32 rcar_du_crtc_read(struct rcar_du_crtc *rcrtc, u32 reg)
>   {
>   	struct rcar_du_device *rcdu = rcrtc->group->dev;
> @@ -106,14 +112,74 @@ static void rcar_du_crtc_put(struct rcar_du_crtc *rcrtc)
>    * Hardware Setup
>    */
>
> +static void rcar_du_dpll_divider(struct dpll_info *dpll, unsigned int extclk,
> +				 unsigned int mode_clock)
> +{
> +	unsigned long dpllclk;
> +	unsigned long diff;
> +	unsigned long n, m, fdpll;
> +	bool match_flag = false;
> +	bool clk_diff_set = true;
> +
> +	for (n = 39; n < 120; n++) {
> +		for (m = 0; m < 4; m++) {
> +			for (fdpll = 1; fdpll < 32; fdpll++) {
> +				/* 1/2 (FRQSEL=1) for duty rate 50% */
> +				dpllclk = extclk * (n + 1) / (m + 1)
> +						 / (fdpll + 1) / 2;
> +				if (dpllclk >= 400000000)
> +					continue;
> +
> +				diff = abs((long)dpllclk - (long)mode_clock);
> +				if (clk_diff_set ||
> +					((diff == 0) || (dpll->diff > diff))) {
> +					dpll->diff = diff;
> +					dpll->n = n;
> +					dpll->m = m;
> +					dpll->fdpll = fdpll;
> +					dpll->dpllclk = dpllclk;
> +
> +					if (clk_diff_set)
> +						clk_diff_set = false;
> +
> +					if (diff == 0) {
> +						match_flag = true;
> +						break;
> +					}
> +				}
> +			}
> +			if (match_flag)
> +				break;
> +		}
> +		if (match_flag)
> +			break;
> +	}
> +}
> +
>   static void rcar_du_crtc_set_display_timing(struct rcar_du_crtc *rcrtc)
>   {
>   	const struct drm_display_mode *mode = &rcrtc->crtc.state->adjusted_mode;
> +	struct rcar_du_device *rcdu = rcrtc->group->dev;
>   	unsigned long mode_clock = mode->clock * 1000;
>   	unsigned long clk;
>   	u32 value;
>   	u32 escr;
>   	u32 div;
> +	u32 dpll_reg = 0;
> +	struct dpll_info *dpll;
> +	void __iomem *product_reg;
> +	bool h3_es1_workaround = false;
> +
> +	dpll = kzalloc(sizeof(*dpll), GFP_KERNEL);
> +	if (dpll == NULL)
> +		return;
> +
> +	/* DU2 DPLL Clock Select bit workaround in R-Car H3(ES1.0) */
> +	product_reg = ioremap(PRODUCT_REG, 0x04);
> +	if (((readl(product_reg) & PRODUCT_MASK) == PRODUCT_H3_BIT)
> +		&& ((readl(product_reg) & CUT_ES1_MASK) == CUT_ES1))
> +		h3_es1_workaround = true;
> +	iounmap(product_reg);
>
>   	/* Compute the clock divisor and select the internal or external dot
>   	 * clock based on the requested frequency.
> @@ -130,6 +196,15 @@ static void rcar_du_crtc_set_display_timing(struct rcar_du_crtc *rcrtc)
>   		u32 extdiv;
>
>   		extclk = clk_get_rate(rcrtc->extclock);
> +
> +		if (rcdu->info->dpll_ch & (0x01 << rcrtc->index)) {
> +			rcar_du_dpll_divider(dpll, extclk, mode_clock);
> +			extclk = dpll->dpllclk;
> +			dev_dbg(rcrtc->group->dev->dev,
> +				"dpllclk:%d, fdpll:%d, n:%d, m:%d, diff:%d\n",
> +				 dpll->dpllclk, dpll->fdpll, dpll->n, dpll->m,
> +				 dpll->diff);
> +		}
>   		extdiv = DIV_ROUND_CLOSEST(extclk, mode_clock);
>   		extdiv = clamp(extdiv, 1U, 64U) - 1;
>
> @@ -140,7 +215,27 @@ static void rcar_du_crtc_set_display_timing(struct rcar_du_crtc *rcrtc)
>   		    abs((long)rate - (long)mode_clock)) {
>   			dev_dbg(rcrtc->group->dev->dev,
>   				"crtc%u: using external clock\n", rcrtc->index);
> -			escr = extdiv | ESCR_DCLKSEL_DCLKIN;
> +			if (rcdu->info->dpll_ch & (0x01 << rcrtc->index)) {
> +				escr = ESCR_DCLKSEL_DCLKIN | 0x01;
> +				dpll_reg =  DPLLCR_CODE | DPLLCR_M(dpll->m) |
> +					DPLLCR_FDPLL(dpll->fdpll) |
> +					DPLLCR_CLKE | DPLLCR_N(dpll->n) |
> +					DPLLCR_STBY;
> +
> +				if (rcrtc->index == DU_CH_1)
> +					dpll_reg |= (DPLLCR_PLCS1 |
> +						 DPLLCR_INCS_DPLL01_DOTCLKIN13);
> +				if (rcrtc->index == DU_CH_2) {
> +					dpll_reg |= (DPLLCR_PLCS0 |
> +						 DPLLCR_INCS_DPLL01_DOTCLKIN02);
> +					if (h3_es1_workaround)
> +						dpll_reg |=  (0x01 << 21);
> +				}
> +
> +				rcar_du_group_write(rcrtc->group, DPLLCR,
> +								  dpll_reg);
> +			} else
> +				escr = extdiv | ESCR_DCLKSEL_DCLKIN;
>   		}
>   	}
>
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.h b/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
> index 459e539..9a56cc7 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
> @@ -54,6 +54,14 @@ struct rcar_du_crtc {
>   	struct rcar_du_vsp *vsp;
>   };
>
> +struct dpll_info {
> +	unsigned int dpllclk;
> +	unsigned int diff;
> +	unsigned int fdpll;
> +	unsigned int n;
> +	unsigned int m;
> +};
> +
>   #define to_rcar_crtc(c)	container_of(c, struct rcar_du_crtc, crtc)
>
>   enum rcar_du_output {
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.c b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
> index 0a93d2a..5ed0d61 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_drv.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
> @@ -165,6 +165,7 @@ static const struct rcar_du_device_info rcar_du_r8a7795_info = {
>   		},
>   	},
>   	.num_lvds = 1,
> +	.dpll_ch =  BIT(1) | BIT(2),
>   };
>
>   static const struct of_device_id rcar_du_of_table[] = {
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.h b/drivers/gpu/drm/rcar-du/rcar_du_drv.h
> index d1d1d8d..790829b 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_drv.h
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.h
> @@ -69,6 +69,7 @@ struct rcar_du_device_info {
>   	unsigned int num_crtcs;
>   	struct rcar_du_output_routing routes[RCAR_DU_OUTPUT_MAX];
>   	unsigned int num_lvds;
> +	unsigned int dpll_ch;
>   };
>
>   #define RCAR_DU_MAX_CRTCS		4
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_plane.h b/drivers/gpu/drm/rcar-du/rcar_du_plane.h
> index b18b7b2..47fad23 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_plane.h
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_plane.h
> @@ -1,7 +1,7 @@
>   /*
>    * rcar_du_plane.h  --  R-Car Display Unit Planes
>    *
> - * Copyright (C) 2013-2014 Renesas Electronics Corporation
> + * Copyright (C) 2013-2015 Renesas Electronics Corporation
>    *
>    * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
>    *
> @@ -34,6 +34,11 @@ enum rcar_du_plane_source {
>   	RCAR_DU_PLANE_VSPD1,
>   };
>
> +#define DU_CH_0		0
> +#define DU_CH_1		1
> +#define DU_CH_2		2
> +#define DU_CH_3		3
> +
>   struct rcar_du_plane {
>   	struct drm_plane plane;
>   	struct rcar_du_group *group;
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_regs.h b/drivers/gpu/drm/rcar-du/rcar_du_regs.h
> index fedb016..7a34bf3 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_regs.h
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_regs.h
> @@ -277,6 +277,25 @@
>   #define DEFR10_TSEL_H3_TCON1	(0 << 1) /* DEFR102 register only (DU2/DU3) */
>   #define DEFR10_DEFE10		(1 << 0)
>
> +#define DPLLCR			0x20044
> +#define DPLLCR_CODE		(0x95 << 24)
> +#define DPLLCR_PLCS1		(1 << 23)
> +#define DPLLCR_PLCS0		(1 << 20)
> +#define DPLLCR_CLKE		(1 << 18)
> +#define DPLLCR_FDPLL(n)		((n) << 12)	/* n=0 Setting prohibited */
> +/* H'00 to H'26, H'78 to H'7F: Setting prohibited.*/
> +#define DPLLCR_N(n)		((n) << 5)
> +#define DPLLCR_M(n)		((n) << 3)
> +#define DPLLCR_STBY		(1 << 2)
> +#define DPLLCR_INCS_DPLL01_DOTCLKIN02	(0 << 0)
> +#define DPLLCR_INCS_DPLL01_DOTCLKIN13	(1 << 1)
> +
> +#define DPLLC2R			0x20048
> +#define DPLLC2R_CODE		(0x95 << 24)
> +#define DPLLC2R_SELC		(1 << 12)
> +#define DPLLC2R_M(n)		((n) << 8)
> +#define DPLLC2R_FDPLL(n)	((n) << 0)	/* n=0 Setting prohibited */
> +
>   /* -----------------------------------------------------------------------------
>    * Display Timing Generation Registers
>    */
>

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [RFC 04/21] drm: bridge/dw_hdmi: add dw hdmi i2c bus adapter support
  2016-05-30 16:00 ` [RFC 04/21] drm: bridge/dw_hdmi: add dw hdmi i2c bus adapter support Ulrich Hecht
@ 2016-05-30 17:26     ` Vladimir Zapolskiy
  0 siblings, 0 replies; 34+ messages in thread
From: Vladimir Zapolskiy @ 2016-05-30 17:26 UTC (permalink / raw)
  To: Ulrich Hecht, linux-renesas-soc, geert
  Cc: kuninori.morimoto.gx, laurent.pinchart, dri-devel, architt, vz,
	koji.matsuoka.xm, Geert Uytterhoeven

Hi Ulrich,

On 30.05.2016 19:00, Ulrich Hecht wrote:
> From: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
> 
> The change adds support of internal HDMI I2C master controller, this
> subdevice is used by default, if "ddc-i2c-bus" DT property is omitted.
> 
> The main purpose of this functionality is to support reading EDID from
> an HDMI monitor on boards, which don't have an I2C bus connected to
> DDC pins.
> 
> Signed-off-by: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
> Signed-off-by: Koji Matsuoka <koji.matsuoka.xm@renesas.com>
> Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
> ---

thank you for pushing it, this is v3 of the change, right?

I think it might be better to consider to take the latest v5, it has
updated documentation notes, various improvements based on review from
Russell King, Doug Anderson and Philipp Zabel:

  http://www.spinics.net/lists/arm-kernel/msg447954.html

Still you may find it a bit outdated and it may require rebase, the change
was based on v4.3.0-rc3. Please let me know, if I can provide you support
of any kind regarding the change.

--
With best wishes,
Vladimir

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [RFC 04/21] drm: bridge/dw_hdmi: add dw hdmi i2c bus adapter support
@ 2016-05-30 17:26     ` Vladimir Zapolskiy
  0 siblings, 0 replies; 34+ messages in thread
From: Vladimir Zapolskiy @ 2016-05-30 17:26 UTC (permalink / raw)
  To: Ulrich Hecht, linux-renesas-soc, geert
  Cc: kuninori.morimoto.gx, laurent.pinchart, dri-devel, architt, vz,
	koji.matsuoka.xm, Geert Uytterhoeven

Hi Ulrich,

On 30.05.2016 19:00, Ulrich Hecht wrote:
> From: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
> 
> The change adds support of internal HDMI I2C master controller, this
> subdevice is used by default, if "ddc-i2c-bus" DT property is omitted.
> 
> The main purpose of this functionality is to support reading EDID from
> an HDMI monitor on boards, which don't have an I2C bus connected to
> DDC pins.
> 
> Signed-off-by: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
> Signed-off-by: Koji Matsuoka <koji.matsuoka.xm@renesas.com>
> Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
> ---

thank you for pushing it, this is v3 of the change, right?

I think it might be better to consider to take the latest v5, it has
updated documentation notes, various improvements based on review from
Russell King, Doug Anderson and Philipp Zabel:

  http://www.spinics.net/lists/arm-kernel/msg447954.html

Still you may find it a bit outdated and it may require rebase, the change
was based on v4.3.0-rc3. Please let me know, if I can provide you support
of any kind regarding the change.

--
With best wishes,
Vladimir

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [RFC 00/21] Renesas r8a7795/Salvator-X HDMI output prototype
  2016-05-30 15:59 [RFC 00/21] Renesas r8a7795/Salvator-X HDMI output prototype Ulrich Hecht
@ 2016-05-30 17:29   ` Geert Uytterhoeven
  2016-05-30 16:00 ` [RFC 02/21] drm: i2c: adv7511: Convert to drm_bridge Ulrich Hecht
                     ` (21 subsequent siblings)
  22 siblings, 0 replies; 34+ messages in thread
From: Geert Uytterhoeven @ 2016-05-30 17:29 UTC (permalink / raw)
  To: Ulrich Hecht
  Cc: linux-renesas-soc, Kuninori Morimoto, Laurent Pinchart,
	DRI Development, Archit Taneja, vz, Koji Matsuoka

Hi Uli,

On Mon, May 30, 2016 at 5:59 PM, Ulrich Hecht
<ulrich.hecht+renesas@gmail.com> wrote:
> This is a prototype of HDMI output support for the Renesas r8a7795 SoC and
> Salvator-X board.  It is based on the renesas-devel-20160516-v4.6 tree and
> includes the bridge API conversion patches to the adv7511 and rcar-du
> drivers written by Archit Taneja.
>
> The obvious issue with this series is the awkward binding of the dw-hdmi
> bridge IP, which can be seen in the "drm: rcar-du: Add dw_hdmi driver
> startup" patch.  Any comments on how to implement this interface properly
> are much appreciated.
>
> Functionally, this series works as expected on both connectors, but EDID
> reading is currently broken.

JFTR, I don't think any of these patches should carry my SoB.
Adding them when importing your previous version into a topic branch
was a mistake on my side.

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [RFC 00/21] Renesas r8a7795/Salvator-X HDMI output prototype
@ 2016-05-30 17:29   ` Geert Uytterhoeven
  0 siblings, 0 replies; 34+ messages in thread
From: Geert Uytterhoeven @ 2016-05-30 17:29 UTC (permalink / raw)
  To: Ulrich Hecht
  Cc: Kuninori Morimoto, Koji Matsuoka, DRI Development, vz,
	linux-renesas-soc, Laurent Pinchart

Hi Uli,

On Mon, May 30, 2016 at 5:59 PM, Ulrich Hecht
<ulrich.hecht+renesas@gmail.com> wrote:
> This is a prototype of HDMI output support for the Renesas r8a7795 SoC and
> Salvator-X board.  It is based on the renesas-devel-20160516-v4.6 tree and
> includes the bridge API conversion patches to the adv7511 and rcar-du
> drivers written by Archit Taneja.
>
> The obvious issue with this series is the awkward binding of the dw-hdmi
> bridge IP, which can be seen in the "drm: rcar-du: Add dw_hdmi driver
> startup" patch.  Any comments on how to implement this interface properly
> are much appreciated.
>
> Functionally, this series works as expected on both connectors, but EDID
> reading is currently broken.

JFTR, I don't think any of these patches should carry my SoB.
Adding them when importing your previous version into a topic branch
was a mistake on my side.

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [RFC 00/21] Renesas r8a7795/Salvator-X HDMI output prototype
  2016-05-30 15:59 [RFC 00/21] Renesas r8a7795/Salvator-X HDMI output prototype Ulrich Hecht
                   ` (21 preceding siblings ...)
  2016-05-30 17:29   ` Geert Uytterhoeven
@ 2016-05-31  8:10 ` Ulrich Hecht
  22 siblings, 0 replies; 34+ messages in thread
From: Ulrich Hecht @ 2016-05-31  8:10 UTC (permalink / raw)
  To: linux-renesas-soc, Geert Uytterhoeven
  Cc: Kuninori Morimoto, Laurent, dri-devel, architt, vz,
	Koji Matsuoka, Ulrich Hecht

On Mon, May 30, 2016 at 5:59 PM, Ulrich Hecht
<ulrich.hecht+renesas@gmail.com> wrote:
> Hi!
>
> This is a prototype of HDMI output support for the Renesas r8a7795 SoC and
> Salvator-X board.  It is based on the renesas-devel-20160516-v4.6 tree and

Actually, it is based on renesas-drivers-2016-05-17-
v4.6, sorry for the confusion.

CU
Uli

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [RFC 14/21] v4l: vsp1: Change VSP1 LIF linebuffer FIFO
  2016-05-30 16:00 ` [RFC 14/21] v4l: vsp1: Change VSP1 LIF linebuffer FIFO Ulrich Hecht
@ 2022-04-21 16:12     ` Eugeniu Rosca
  0 siblings, 0 replies; 34+ messages in thread
From: Eugeniu Rosca @ 2022-04-21 16:12 UTC (permalink / raw)
  To: Ulrich Hecht, laurent.pinchart, linux-renesas-soc
  Cc: geert, kuninori.morimoto.gx, dri-devel, architt, vz,
	koji.matsuoka.xm, Takashi Saito, Geert Uytterhoeven,
	Michael Rodin, Eugeniu Rosca, Eugeniu Rosca

Dear Uli,
Dear Laurent,
Dear Renesas community,

On Mo, Mai 30, 2016 at 06:00:13 +0200, Ulrich Hecht wrote:
> This patch changes to VSPD hardware recommended value.
> Purpose is highest pixel clock without underruns.
> In the default R-Car Linux BSP config this value is
> wrong and therefore there are many underruns.
> 
> Signed-off-by: Takashi Saito <takashi.saitou.ry@renesas.com>
> Signed-off-by: Koji Matsuoka <koji.matsuoka.xm@renesas.com>
> Signed-off-by: Ulrich Hecht <ulrich.hecht+renesas@gmail.com>
> Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
> ---
>  drivers/media/platform/vsp1/vsp1_lif.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)

Apologize for reviving this very old thread.

We've been struggling with very rare and difficult to reproduce
display flickering occurrences and, after significant amount of
troubleshooting and debugging, with some support from Renesas,
we've been able to identify that those flicker issues are caused
by VSPD underruns.

What we've also learned is that one possible root-cause for seeing
VSPD underruns is having wrong QoS settings in DBSC (set in ATF).

What was particularly helpful in identifying the underruns themselves
is Renesas BSP commit [1], whose discussions we were unable to track
on linux-renesas-soc LKML.

My question is very simple. Since the meat of the Renesas patch [1]
is basically a printk in the interrupt context and an array storing
the total number of underruns occurred since startup, would you be
willing to review the refactored version of this patch on LKML?

In that case, we'll definitely invest some time to upstream it.

Thank you for your attention and feedback.

[1] https://github.com/renesas-rcar/linux-bsp/commit/12ea79975a10f
    ("v4l: vsp1: Add underrun debug messege option")

Best regards,
Eugeniu

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [RFC 14/21] v4l: vsp1: Change VSP1 LIF linebuffer FIFO
@ 2022-04-21 16:12     ` Eugeniu Rosca
  0 siblings, 0 replies; 34+ messages in thread
From: Eugeniu Rosca @ 2022-04-21 16:12 UTC (permalink / raw)
  To: Ulrich Hecht, laurent.pinchart, linux-renesas-soc
  Cc: architt, Takashi Saito, Geert Uytterhoeven, kuninori.morimoto.gx,
	Eugeniu Rosca, Michael Rodin, koji.matsuoka.xm, dri-devel, vz,
	geert, Eugeniu Rosca

Dear Uli,
Dear Laurent,
Dear Renesas community,

On Mo, Mai 30, 2016 at 06:00:13 +0200, Ulrich Hecht wrote:
> This patch changes to VSPD hardware recommended value.
> Purpose is highest pixel clock without underruns.
> In the default R-Car Linux BSP config this value is
> wrong and therefore there are many underruns.
> 
> Signed-off-by: Takashi Saito <takashi.saitou.ry@renesas.com>
> Signed-off-by: Koji Matsuoka <koji.matsuoka.xm@renesas.com>
> Signed-off-by: Ulrich Hecht <ulrich.hecht+renesas@gmail.com>
> Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
> ---
>  drivers/media/platform/vsp1/vsp1_lif.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)

Apologize for reviving this very old thread.

We've been struggling with very rare and difficult to reproduce
display flickering occurrences and, after significant amount of
troubleshooting and debugging, with some support from Renesas,
we've been able to identify that those flicker issues are caused
by VSPD underruns.

What we've also learned is that one possible root-cause for seeing
VSPD underruns is having wrong QoS settings in DBSC (set in ATF).

What was particularly helpful in identifying the underruns themselves
is Renesas BSP commit [1], whose discussions we were unable to track
on linux-renesas-soc LKML.

My question is very simple. Since the meat of the Renesas patch [1]
is basically a printk in the interrupt context and an array storing
the total number of underruns occurred since startup, would you be
willing to review the refactored version of this patch on LKML?

In that case, we'll definitely invest some time to upstream it.

Thank you for your attention and feedback.

[1] https://github.com/renesas-rcar/linux-bsp/commit/12ea79975a10f
    ("v4l: vsp1: Add underrun debug messege option")

Best regards,
Eugeniu

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [RFC 14/21] v4l: vsp1: Change VSP1 LIF linebuffer FIFO
  2022-04-21 16:12     ` Eugeniu Rosca
@ 2022-04-21 16:33       ` Laurent Pinchart
  -1 siblings, 0 replies; 34+ messages in thread
From: Laurent Pinchart @ 2022-04-21 16:33 UTC (permalink / raw)
  To: Eugeniu Rosca
  Cc: Ulrich Hecht, linux-renesas-soc, geert, kuninori.morimoto.gx,
	dri-devel, architt, vz, koji.matsuoka.xm, Takashi Saito,
	Geert Uytterhoeven, Michael Rodin, Eugeniu Rosca

Hi Eugeniu,

On Thu, Apr 21, 2022 at 06:12:59PM +0200, Eugeniu Rosca wrote:
> Dear Uli,
> Dear Laurent,
> Dear Renesas community,
> 
> On Mo, Mai 30, 2016 at 06:00:13 +0200, Ulrich Hecht wrote:
> > This patch changes to VSPD hardware recommended value.
> > Purpose is highest pixel clock without underruns.
> > In the default R-Car Linux BSP config this value is
> > wrong and therefore there are many underruns.
> > 
> > Signed-off-by: Takashi Saito <takashi.saitou.ry@renesas.com>
> > Signed-off-by: Koji Matsuoka <koji.matsuoka.xm@renesas.com>
> > Signed-off-by: Ulrich Hecht <ulrich.hecht+renesas@gmail.com>
> > Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
> > ---
> >  drivers/media/platform/vsp1/vsp1_lif.c | 6 +++---
> >  1 file changed, 3 insertions(+), 3 deletions(-)
> 
> Apologize for reviving this very old thread.
> 
> We've been struggling with very rare and difficult to reproduce
> display flickering occurrences and, after significant amount of
> troubleshooting and debugging, with some support from Renesas,
> we've been able to identify that those flicker issues are caused
> by VSPD underruns.
> 
> What we've also learned is that one possible root-cause for seeing
> VSPD underruns is having wrong QoS settings in DBSC (set in ATF).
> 
> What was particularly helpful in identifying the underruns themselves
> is Renesas BSP commit [1], whose discussions we were unable to track
> on linux-renesas-soc LKML.
> 
> My question is very simple. Since the meat of the Renesas patch [1]
> is basically a printk in the interrupt context and an array storing
> the total number of underruns occurred since startup, would you be
> willing to review the refactored version of this patch on LKML?
> 
> In that case, we'll definitely invest some time to upstream it.

Absolutely ! I'm all for helping debugging.

> Thank you for your attention and feedback.
> 
> [1] https://github.com/renesas-rcar/linux-bsp/commit/12ea79975a10f
>     ("v4l: vsp1: Add underrun debug messege option")

-- 
Regards,

Laurent Pinchart

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [RFC 14/21] v4l: vsp1: Change VSP1 LIF linebuffer FIFO
@ 2022-04-21 16:33       ` Laurent Pinchart
  0 siblings, 0 replies; 34+ messages in thread
From: Laurent Pinchart @ 2022-04-21 16:33 UTC (permalink / raw)
  To: Eugeniu Rosca
  Cc: architt, Takashi Saito, Geert Uytterhoeven, kuninori.morimoto.gx,
	Eugeniu Rosca, Michael Rodin, koji.matsuoka.xm, dri-devel, vz,
	linux-renesas-soc, geert, Ulrich Hecht

Hi Eugeniu,

On Thu, Apr 21, 2022 at 06:12:59PM +0200, Eugeniu Rosca wrote:
> Dear Uli,
> Dear Laurent,
> Dear Renesas community,
> 
> On Mo, Mai 30, 2016 at 06:00:13 +0200, Ulrich Hecht wrote:
> > This patch changes to VSPD hardware recommended value.
> > Purpose is highest pixel clock without underruns.
> > In the default R-Car Linux BSP config this value is
> > wrong and therefore there are many underruns.
> > 
> > Signed-off-by: Takashi Saito <takashi.saitou.ry@renesas.com>
> > Signed-off-by: Koji Matsuoka <koji.matsuoka.xm@renesas.com>
> > Signed-off-by: Ulrich Hecht <ulrich.hecht+renesas@gmail.com>
> > Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
> > ---
> >  drivers/media/platform/vsp1/vsp1_lif.c | 6 +++---
> >  1 file changed, 3 insertions(+), 3 deletions(-)
> 
> Apologize for reviving this very old thread.
> 
> We've been struggling with very rare and difficult to reproduce
> display flickering occurrences and, after significant amount of
> troubleshooting and debugging, with some support from Renesas,
> we've been able to identify that those flicker issues are caused
> by VSPD underruns.
> 
> What we've also learned is that one possible root-cause for seeing
> VSPD underruns is having wrong QoS settings in DBSC (set in ATF).
> 
> What was particularly helpful in identifying the underruns themselves
> is Renesas BSP commit [1], whose discussions we were unable to track
> on linux-renesas-soc LKML.
> 
> My question is very simple. Since the meat of the Renesas patch [1]
> is basically a printk in the interrupt context and an array storing
> the total number of underruns occurred since startup, would you be
> willing to review the refactored version of this patch on LKML?
> 
> In that case, we'll definitely invest some time to upstream it.

Absolutely ! I'm all for helping debugging.

> Thank you for your attention and feedback.
> 
> [1] https://github.com/renesas-rcar/linux-bsp/commit/12ea79975a10f
>     ("v4l: vsp1: Add underrun debug messege option")

-- 
Regards,

Laurent Pinchart

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [RFC 14/21] v4l: vsp1: Change VSP1 LIF linebuffer FIFO
  2022-04-21 16:33       ` Laurent Pinchart
@ 2022-04-26  9:20         ` Eugeniu Rosca
  -1 siblings, 0 replies; 34+ messages in thread
From: Eugeniu Rosca @ 2022-04-26  9:20 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Eugeniu Rosca, Ulrich Hecht, linux-renesas-soc, geert,
	kuninori.morimoto.gx, dri-devel, architt, vz, koji.matsuoka.xm,
	Takashi Saito, Geert Uytterhoeven, Michael Rodin, Eugeniu Rosca

Hi Laurent,

On Do, Apr 21, 2022 at 07:33:18 +0300, Laurent Pinchart wrote:
> On Thu, Apr 21, 2022 at 06:12:59PM +0200, Eugeniu Rosca wrote:
> > Since the meat of the Renesas patch [1]
> > is basically a printk in the interrupt context and an array storing
> > the total number of underruns occurred since startup, would you be
> > willing to review the refactored version of this patch on LKML?
> > 
> > In that case, we'll definitely invest some time to upstream it.
> 
> Absolutely ! I'm all for helping debugging.

Thanks for the quick reply. I have submitted a proposal at [*] and
I look forward to any thoughts/criticism/counter-proposals. TIA.

[*] https://lore.kernel.org/linux-renesas-soc/1650962227-14281-1-git-send-email-erosca@de.adit-jv.com

Best Regards,
Eugeniu

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [RFC 14/21] v4l: vsp1: Change VSP1 LIF linebuffer FIFO
@ 2022-04-26  9:20         ` Eugeniu Rosca
  0 siblings, 0 replies; 34+ messages in thread
From: Eugeniu Rosca @ 2022-04-26  9:20 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: architt, Takashi Saito, Geert Uytterhoeven, kuninori.morimoto.gx,
	Eugeniu Rosca, Michael Rodin, koji.matsuoka.xm, dri-devel, vz,
	linux-renesas-soc, geert, Ulrich Hecht, Eugeniu Rosca

Hi Laurent,

On Do, Apr 21, 2022 at 07:33:18 +0300, Laurent Pinchart wrote:
> On Thu, Apr 21, 2022 at 06:12:59PM +0200, Eugeniu Rosca wrote:
> > Since the meat of the Renesas patch [1]
> > is basically a printk in the interrupt context and an array storing
> > the total number of underruns occurred since startup, would you be
> > willing to review the refactored version of this patch on LKML?
> > 
> > In that case, we'll definitely invest some time to upstream it.
> 
> Absolutely ! I'm all for helping debugging.

Thanks for the quick reply. I have submitted a proposal at [*] and
I look forward to any thoughts/criticism/counter-proposals. TIA.

[*] https://lore.kernel.org/linux-renesas-soc/1650962227-14281-1-git-send-email-erosca@de.adit-jv.com

Best Regards,
Eugeniu

^ permalink raw reply	[flat|nested] 34+ messages in thread

end of thread, other threads:[~2022-04-27  7:12 UTC | newest]

Thread overview: 34+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-05-30 15:59 [RFC 00/21] Renesas r8a7795/Salvator-X HDMI output prototype Ulrich Hecht
2016-05-30 16:00 ` [RFC 01/21] drm: rcar-du: Remove i2c slave encoder interface for hdmi encoder Ulrich Hecht
2016-05-30 16:00 ` [RFC 02/21] drm: i2c: adv7511: Convert to drm_bridge Ulrich Hecht
2016-05-30 16:00 ` [RFC 03/21] media: vsp1: Set format to RPF input source Ulrich Hecht
2016-05-30 16:00 ` [RFC 04/21] drm: bridge/dw_hdmi: add dw hdmi i2c bus adapter support Ulrich Hecht
2016-05-30 17:26   ` Vladimir Zapolskiy
2016-05-30 17:26     ` Vladimir Zapolskiy
2016-05-30 16:00 ` [RFC 05/21] drm: bridge/dw_hdmi: Fix R-Car Gen3 device support Ulrich Hecht
2016-05-30 16:00 ` [RFC 06/21] drm: rcar-du: Add R8A7795 " Ulrich Hecht
2016-05-30 16:00 ` [RFC 07/21] drm: rcar-du: Add dw_hdmi driver startup Ulrich Hecht
2016-05-30 16:00 ` [RFC 08/21] drm: rcar-du: Add DPLL support Ulrich Hecht
2016-05-30 16:12   ` Dirk Behme
2016-05-30 16:00 ` [RFC 09/21] drm: rcar-du: Fix display registers for R-Car Gen3 Ulrich Hecht
2016-05-30 16:00 ` [RFC 10/21] drm: rcar-du: Fix VSP plane number per devices Ulrich Hecht
2016-05-30 16:00 ` [RFC 11/21] drm: rcar-du: Fix VSP feed plane number Ulrich Hecht
2016-05-30 16:00 ` [RFC 12/21] drm: rcar-du: Add pixel format support Ulrich Hecht
2016-05-30 16:00 ` [RFC 13/21] drm: rcar-du: Fix display max size to 4096x2160 size Ulrich Hecht
2016-05-30 16:00 ` [RFC 14/21] v4l: vsp1: Change VSP1 LIF linebuffer FIFO Ulrich Hecht
2022-04-21 16:12   ` Eugeniu Rosca
2022-04-21 16:12     ` Eugeniu Rosca
2022-04-21 16:33     ` Laurent Pinchart
2022-04-21 16:33       ` Laurent Pinchart
2022-04-26  9:20       ` Eugeniu Rosca
2022-04-26  9:20         ` Eugeniu Rosca
2016-05-30 16:00 ` [RFC 15/21] pinctrl: sh-pfc: r8a7795: Add DU support Ulrich Hecht
2016-05-30 16:00 ` [RFC 16/21] pinctrl: sh-pfc: r8a7795: Add HDMI CEC support Ulrich Hecht
2016-05-30 16:00 ` [RFC 17/21] arm64: dts: r8a7795: Add HDMI encoder support Ulrich Hecht
2016-05-30 16:00 ` [RFC 18/21] arm64: dts: salvator-x: Add DU pins, HDMI connectors and encoder Ulrich Hecht
2016-05-30 16:00 ` [RFC 19/21] arm64: configs: Enable R-Car DU related config Ulrich Hecht
2016-05-30 16:00 ` [RFC 20/21] arm64: dts: r8a7795: add HDMI support to DU Ulrich Hecht
2016-05-30 16:00 ` [RFC 21/21] arm64: defconfig: add VIDEO_RENESAS_FCP Ulrich Hecht
2016-05-30 17:29 ` [RFC 00/21] Renesas r8a7795/Salvator-X HDMI output prototype Geert Uytterhoeven
2016-05-30 17:29   ` Geert Uytterhoeven
2016-05-31  8:10 ` Ulrich Hecht

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.