Devicetree
 help / color / mirror / Atom feed
* [PATCH 07/12] dt-bindings: tc358754: add DT bindings
From: Maciej Purski @ 2018-05-28  9:47 UTC (permalink / raw)
  To: linux-kernel, linux-arm-kernel, linux-samsung-soc, devicetree,
	dri-devel
  Cc: David Airlie, Rob Herring, Mark Rutland, Thierry Reding,
	Kukjin Kim, Krzysztof Kozlowski, Archit Taneja, Andrzej Hajda,
	Laurent Pinchart, Inki Dae, Joonyoung Shim, Seung-Woo Kim,
	Kyungmin Park, Marek Szyprowski, Bartlomiej Zolnierkiewicz,
	Maciej Purski
In-Reply-To: <1527500833-16005-1-git-send-email-m.purski@samsung.com>

The patch adds bindings to Toshiba DSI/LVDS bridge TC358764.
Bindings describe power supplies, reset gpio and video interfaces.

Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
Signed-off-by: Maciej Purski <m.purski@samsung.com>
---
 .../bindings/display/bridge/toshiba,tc358764.txt   | 42 ++++++++++++++++++++++
 1 file changed, 42 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/display/bridge/toshiba,tc358764.txt

diff --git a/Documentation/devicetree/bindings/display/bridge/toshiba,tc358764.txt b/Documentation/devicetree/bindings/display/bridge/toshiba,tc358764.txt
new file mode 100644
index 0000000..d09bdc2
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/bridge/toshiba,tc358764.txt
@@ -0,0 +1,42 @@
+TC358764 MIPI-DSI to LVDS panel bridge
+
+Required properties:
+  - compatible: "toshiba,tc358764"
+  - reg: the virtual channel number of a DSI peripheral
+  - vddc-supply: core voltage supply
+  - vddio-supply: I/O voltage supply
+  - vddmipi-supply: MIPI voltage supply
+  - vddlvds133-supply: LVDS1 3.3V voltage supply
+  - vddlvds112-supply: LVDS1 1.2V voltage supply
+  - reset-gpios: a GPIO spec for the reset pin
+
+The device node can contain zero to two 'port' child nodes, each with one
+child
+'endpoint' node, according to the bindings defined in [1].
+The following are properties specific to those nodes.
+
+port:
+  - reg: (required) can be 0 for DSI port or 1 for LVDS port;
+
+[1]: Documentation/devicetree/bindings/media/video-interfaces.txt
+
+Example:
+
+	bridge@0 {
+		reg = <0>;
+		compatible = "toshiba,tc358764";
+		vddc-supply = <&vcc_1v2_reg>;
+		vddio-supply = <&vcc_1v8_reg>;
+		vddmipi-supply = <&vcc_1v2_reg>;
+		vddlvds133-supply = <&vcc_3v3_reg>;
+		vddlvds112-supply = <&vcc_1v2_reg>;
+		reset-gpios = <&gpd1 6 GPIO_ACTIVE_LOW>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		port@1 {
+			reg = <1>;
+			lvds_ep: endpoint {
+				remote-endpoint = <&panel_ep>;
+			};
+		};
+	};
-- 
2.7.4

^ permalink raw reply related

* [PATCH 06/12] drm/panel: add support for BOE HV070WSA-100 panel to simple-panel
From: Maciej Purski @ 2018-05-28  9:47 UTC (permalink / raw)
  To: linux-kernel, linux-arm-kernel, linux-samsung-soc, devicetree,
	dri-devel
  Cc: David Airlie, Rob Herring, Mark Rutland, Thierry Reding,
	Kukjin Kim, Krzysztof Kozlowski, Archit Taneja, Andrzej Hajda,
	Laurent Pinchart, Inki Dae, Joonyoung Shim, Seung-Woo Kim,
	Kyungmin Park, Marek Szyprowski, Bartlomiej Zolnierkiewicz,
	Maciej Purski
In-Reply-To: <1527500833-16005-1-git-send-email-m.purski@samsung.com>

The patch adds support for BOE HV070WSA-100 WSVGA 7.01 inch panel
in panel-simple driver. The panel is used in Exynos5250-arndale boards.

Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
Signed-off-by: Maciej Purski <m.purski@samsung.com>
---
 drivers/gpu/drm/panel/panel-simple.c | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c
index cbf1ab4..d5da58d 100644
--- a/drivers/gpu/drm/panel/panel-simple.c
+++ b/drivers/gpu/drm/panel/panel-simple.c
@@ -745,6 +745,28 @@ static const struct panel_desc avic_tm070ddh03 = {
 	},
 };
 
+static const struct drm_display_mode boe_hv070wsa_mode = {
+	.clock = 40800,
+	.hdisplay = 1024,
+	.hsync_start = 1024 + 90,
+	.hsync_end = 1024 + 90 + 90,
+	.htotal = 1024 + 90 + 90 + 90,
+	.vdisplay = 600,
+	.vsync_start = 600 + 3,
+	.vsync_end = 600 + 3 + 4,
+	.vtotal = 600 + 3 + 4 + 3,
+	.vrefresh = 60,
+};
+
+static const struct panel_desc boe_hv070wsa = {
+	.modes = &boe_hv070wsa_mode,
+	.num_modes = 1,
+	.size = {
+		.width = 154,
+		.height = 90,
+	},
+};
+
 static const struct drm_display_mode boe_nv101wxmn51_modes[] = {
 	{
 		.clock = 71900,
@@ -2113,6 +2135,9 @@ static const struct of_device_id platform_of_match[] = {
 		.compatible = "avic,tm070ddh03",
 		.data = &avic_tm070ddh03,
 	}, {
+		.compatible = "boe,hv070wsa-100",
+		.data = &boe_hv070wsa
+	}, {
 		.compatible = "boe,nv101wxmn51",
 		.data = &boe_nv101wxmn51,
 	}, {
-- 
2.7.4

^ permalink raw reply related

* [PATCH 05/12] panel/hv070wsa-100: add DT bindings
From: Maciej Purski @ 2018-05-28  9:47 UTC (permalink / raw)
  To: linux-kernel, linux-arm-kernel, linux-samsung-soc, devicetree,
	dri-devel
  Cc: Mark Rutland, Maciej Purski, Archit Taneja, Joonyoung Shim,
	Bartlomiej Zolnierkiewicz, David Airlie, Seung-Woo Kim,
	Krzysztof Kozlowski, Inki Dae, Andrzej Hajda, Kyungmin Park,
	Rob Herring, Thierry Reding, Kukjin Kim, Marek Szyprowski,
	Laurent Pinchart
In-Reply-To: <1527500833-16005-1-git-send-email-m.purski@samsung.com>

The patch adds bindings to BOE HV070-WSA WSVGA panel.
Bindings are compatible with simple panel bindings.

Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
Signed-off-by: Maciej Purski <m.purski@samsung.com>
---
 .../devicetree/bindings/display/panel/boe,hv070wsa-100.txt         | 7 +++++++
 1 file changed, 7 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/display/panel/boe,hv070wsa-100.txt

diff --git a/Documentation/devicetree/bindings/display/panel/boe,hv070wsa-100.txt b/Documentation/devicetree/bindings/display/panel/boe,hv070wsa-100.txt
new file mode 100644
index 0000000..bfc20ac
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/panel/boe,hv070wsa-100.txt
@@ -0,0 +1,7 @@
+BOE HV070WSA-100 7.01" WSVGA TFT LCD panel
+
+Required properties:
+- compatible: should be "boe,hv070wsa-100"
+
+This binding is compatible with the simple-panel binding, which is specified
+in simple-panel.txt in this directory.
-- 
2.7.4

^ permalink raw reply related

* [PATCH 04/12] drm/exynos: add non-panel path to exynos_dsi_enable()
From: Maciej Purski @ 2018-05-28  9:47 UTC (permalink / raw)
  To: linux-kernel, linux-arm-kernel, linux-samsung-soc, devicetree,
	dri-devel
  Cc: David Airlie, Rob Herring, Mark Rutland, Thierry Reding,
	Kukjin Kim, Krzysztof Kozlowski, Archit Taneja, Andrzej Hajda,
	Laurent Pinchart, Inki Dae, Joonyoung Shim, Seung-Woo Kim,
	Kyungmin Park, Marek Szyprowski, Bartlomiej Zolnierkiewicz,
	Maciej Purski
In-Reply-To: <1527500833-16005-1-git-send-email-m.purski@samsung.com>

As DSIM can now have a bridge connected as a peripheral, it should be
possible to successfully enable exynos_dsi, when there is no panel
provided.

Signed-off-by: Maciej Purski <m.purski@samsung.com>
---
 drivers/gpu/drm/exynos/exynos_drm_dsi.c | 27 +++++++++++++--------------
 1 file changed, 13 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
index 8957faf..7d92e50 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
@@ -1382,27 +1382,26 @@ static void exynos_dsi_enable(struct drm_encoder *encoder)
 	if (dsi->state & DSIM_STATE_ENABLED)
 		return;
 
-	pm_runtime_get_sync(dsi->dev);
-
-	dsi->state |= DSIM_STATE_ENABLED;
-
-	ret = drm_panel_prepare(dsi->panel);
-	if (ret < 0) {
-		dsi->state &= ~DSIM_STATE_ENABLED;
-		return;
+	if (dsi->panel) {
+		ret = drm_panel_prepare(dsi->panel);
+		if (ret < 0) {
+			return;
+		}
 	}
 
 	exynos_dsi_set_display_mode(dsi);
 	exynos_dsi_set_display_enable(dsi, true);
 
-	ret = drm_panel_enable(dsi->panel);
-	if (ret < 0) {
-		dsi->state &= ~DSIM_STATE_ENABLED;
-		exynos_dsi_set_display_enable(dsi, false);
-		drm_panel_unprepare(dsi->panel);
-		return;
+	if (dsi->panel) {
+		ret = drm_panel_enable(dsi->panel);
+		if (ret < 0) {
+			exynos_dsi_set_display_enable(dsi, false);
+			drm_panel_unprepare(dsi->panel);
+			return;
+		}
 	}
 
+	dsi->state |= DSIM_STATE_ENABLED;
 	dsi->state |= DSIM_STATE_VIDOUT_AVAILABLE;
 }
 
-- 
2.7.4

^ permalink raw reply related

* [PATCH 03/12] drm/exynos: move connector creation to attach callback
From: Maciej Purski @ 2018-05-28  9:47 UTC (permalink / raw)
  To: linux-kernel, linux-arm-kernel, linux-samsung-soc, devicetree,
	dri-devel
  Cc: David Airlie, Rob Herring, Mark Rutland, Thierry Reding,
	Kukjin Kim, Krzysztof Kozlowski, Archit Taneja, Andrzej Hajda,
	Laurent Pinchart, Inki Dae, Joonyoung Shim, Seung-Woo Kim,
	Kyungmin Park, Marek Szyprowski, Bartlomiej Zolnierkiewicz,
	Maciej Purski
In-Reply-To: <1527500833-16005-1-git-send-email-m.purski@samsung.com>

The current implementation assumes that the only possible peripheral
device for DSIM is a panel. Using an output bridge should also be
possible.

If an output bridge in available, don't create a new connector.
Instead add bridge to DSIM encdoer in dsi_host_attach().

Signed-off-by: Maciej Purski <m.purski@samsung.com>
---
 drivers/gpu/drm/exynos/exynos_drm_dsi.c | 35 +++++++++++++++++++++------------
 1 file changed, 22 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
index 94460b0..8957faf 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
@@ -1498,7 +1498,28 @@ static int exynos_dsi_host_attach(struct mipi_dsi_host *host,
 				  struct mipi_dsi_device *device)
 {
 	struct exynos_dsi *dsi = host_to_dsi(host);
-	struct drm_device *drm = dsi->connector.dev;
+	struct drm_encoder *encoder = &dsi->encoder;
+	struct drm_device *drm = encoder->dev;
+	struct drm_bridge *out_bridge;
+
+	out_bridge  = of_drm_find_bridge(device->dev.of_node);
+	if (out_bridge) {
+		drm_bridge_attach(encoder, out_bridge, NULL);
+	} else {
+		int ret = exynos_dsi_create_connector(encoder);
+
+		if (ret) {
+			DRM_ERROR("failed to create connector ret = %d\n", ret);
+			drm_encoder_cleanup(encoder);
+			return ret;
+		}
+
+		dsi->panel = of_drm_find_panel(device->dev.of_node);
+		if (dsi->panel) {
+			drm_panel_attach(dsi->panel, &dsi->connector);
+			dsi->connector.status = connector_status_connected;
+		}
+	}
 
 	/*
 	 * This is a temporary solution and should be made by more generic way.
@@ -1517,11 +1538,6 @@ static int exynos_dsi_host_attach(struct mipi_dsi_host *host,
 	dsi->lanes = device->lanes;
 	dsi->format = device->format;
 	dsi->mode_flags = device->mode_flags;
-	dsi->panel = of_drm_find_panel(device->dev.of_node);
-	if (dsi->panel) {
-		drm_panel_attach(dsi->panel, &dsi->connector);
-		dsi->connector.status = connector_status_connected;
-	}
 	exynos_drm_crtc_get_by_type(drm, EXYNOS_DISPLAY_TYPE_LCD)->i80_mode =
 			!(dsi->mode_flags & MIPI_DSI_MODE_VIDEO);
 
@@ -1650,13 +1666,6 @@ static int exynos_dsi_bind(struct device *dev, struct device *master,
 	if (ret < 0)
 		return ret;
 
-	ret = exynos_dsi_create_connector(encoder);
-	if (ret) {
-		DRM_ERROR("failed to create connector ret = %d\n", ret);
-		drm_encoder_cleanup(encoder);
-		return ret;
-	}
-
 	if (dsi->mic_bridge_node) {
 		mic_bridge = of_drm_find_bridge(dsi->mic_bridge_node);
 		if (mic_bridge)
-- 
2.7.4

^ permalink raw reply related

* [PATCH 02/12] drm/exynos: move pm_runtime_get_sync() to exynos_dsi_init()
From: Maciej Purski @ 2018-05-28  9:47 UTC (permalink / raw)
  To: linux-kernel, linux-arm-kernel, linux-samsung-soc, devicetree,
	dri-devel
  Cc: David Airlie, Rob Herring, Mark Rutland, Thierry Reding,
	Kukjin Kim, Krzysztof Kozlowski, Archit Taneja, Andrzej Hajda,
	Laurent Pinchart, Inki Dae, Joonyoung Shim, Seung-Woo Kim,
	Kyungmin Park, Marek Szyprowski, Bartlomiej Zolnierkiewicz,
	Maciej Purski
In-Reply-To: <1527500833-16005-1-git-send-email-m.purski@samsung.com>

In order to allow bridge drivers to use DSI transfers in their
pre_enable callbacks, pm_runtime_get_sync() should be performed before
exynos_dsi_enable(). DSIM_STATE_ENABLED flag now should not guard
from calling dsi_host_transfer() before enabling.

Signed-off-by: Maciej Purski <m.purski@samsung.com>
---
 drivers/gpu/drm/exynos/exynos_drm_dsi.c | 6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
index 9599e6b..94460b0 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
@@ -1312,6 +1312,7 @@ static int exynos_dsi_init(struct exynos_dsi *dsi)
 {
 	const struct exynos_dsi_driver_data *driver_data = dsi->driver_data;
 
+	pm_runtime_get_sync(dsi->dev);
 	exynos_dsi_reset(dsi);
 	exynos_dsi_enable_irq(dsi);
 
@@ -1388,7 +1389,6 @@ static void exynos_dsi_enable(struct drm_encoder *encoder)
 	ret = drm_panel_prepare(dsi->panel);
 	if (ret < 0) {
 		dsi->state &= ~DSIM_STATE_ENABLED;
-		pm_runtime_put_sync(dsi->dev);
 		return;
 	}
 
@@ -1400,7 +1400,6 @@ static void exynos_dsi_enable(struct drm_encoder *encoder)
 		dsi->state &= ~DSIM_STATE_ENABLED;
 		exynos_dsi_set_display_enable(dsi, false);
 		drm_panel_unprepare(dsi->panel);
-		pm_runtime_put_sync(dsi->dev);
 		return;
 	}
 
@@ -1566,9 +1565,6 @@ static ssize_t exynos_dsi_host_transfer(struct mipi_dsi_host *host,
 	struct exynos_dsi_transfer xfer;
 	int ret;
 
-	if (!(dsi->state & DSIM_STATE_ENABLED))
-		return -EINVAL;
-
 	if (!(dsi->state & DSIM_STATE_INITIALIZED)) {
 		ret = exynos_dsi_init(dsi);
 		if (ret)
-- 
2.7.4

^ permalink raw reply related

* [PATCH 01/12] drm/exynos: rename "bridge_node" to "mic_bridge_node"
From: Maciej Purski @ 2018-05-28  9:47 UTC (permalink / raw)
  To: linux-kernel, linux-arm-kernel, linux-samsung-soc, devicetree,
	dri-devel
  Cc: David Airlie, Rob Herring, Mark Rutland, Thierry Reding,
	Kukjin Kim, Krzysztof Kozlowski, Archit Taneja, Andrzej Hajda,
	Laurent Pinchart, Inki Dae, Joonyoung Shim, Seung-Woo Kim,
	Kyungmin Park, Marek Szyprowski, Bartlomiej Zolnierkiewicz,
	Maciej Purski
In-Reply-To: <1527500833-16005-1-git-send-email-m.purski@samsung.com>

When adding support for peripheral out bridges, the "bridge" name
becomes imprecise as it refers to a different device than the
"out_bridge".

Signed-off-by: Maciej Purski <m.purski@samsung.com>
---
 drivers/gpu/drm/exynos/exynos_drm_dsi.c | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
index eae44fd..9599e6b 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
@@ -279,7 +279,7 @@ struct exynos_dsi {
 	struct list_head transfer_list;
 
 	const struct exynos_dsi_driver_data *driver_data;
-	struct device_node *bridge_node;
+	struct device_node *mic_bridge_node;
 };
 
 #define host_to_dsi(host) container_of(host, struct exynos_dsi, dsi_host)
@@ -1631,7 +1631,7 @@ static int exynos_dsi_parse_dt(struct exynos_dsi *dsi)
 	if (ret < 0)
 		return ret;
 
-	dsi->bridge_node = of_graph_get_remote_node(node, DSI_PORT_IN, 0);
+	dsi->mic_bridge_node = of_graph_get_remote_node(node, DSI_PORT_IN, 0);
 
 	return 0;
 }
@@ -1642,7 +1642,7 @@ static int exynos_dsi_bind(struct device *dev, struct device *master,
 	struct drm_encoder *encoder = dev_get_drvdata(dev);
 	struct exynos_dsi *dsi = encoder_to_dsi(encoder);
 	struct drm_device *drm_dev = data;
-	struct drm_bridge *bridge;
+	struct drm_bridge *mic_bridge;
 	int ret;
 
 	drm_encoder_init(drm_dev, encoder, &exynos_dsi_encoder_funcs,
@@ -1661,10 +1661,10 @@ static int exynos_dsi_bind(struct device *dev, struct device *master,
 		return ret;
 	}
 
-	if (dsi->bridge_node) {
-		bridge = of_drm_find_bridge(dsi->bridge_node);
-		if (bridge)
-			drm_bridge_attach(encoder, bridge, NULL);
+	if (dsi->mic_bridge_node) {
+		mic_bridge = of_drm_find_bridge(dsi->mic_bridge_node);
+		if (mic_bridge)
+			drm_bridge_attach(encoder, mic_bridge, NULL);
 	}
 
 	return mipi_dsi_host_register(&dsi->dsi_host);
@@ -1783,7 +1783,7 @@ static int exynos_dsi_remove(struct platform_device *pdev)
 {
 	struct exynos_dsi *dsi = platform_get_drvdata(pdev);
 
-	of_node_put(dsi->bridge_node);
+	of_node_put(dsi->mic_bridge_node);
 
 	pm_runtime_disable(&pdev->dev);
 
-- 
2.7.4

^ permalink raw reply related

* [PATCH 00/12] Add TOSHIBA TC358764 DSI/LVDS bridge driver
From: Maciej Purski @ 2018-05-28  9:47 UTC (permalink / raw)
  To: linux-kernel, linux-arm-kernel, linux-samsung-soc, devicetree,
	dri-devel
  Cc: David Airlie, Rob Herring, Mark Rutland, Thierry Reding,
	Kukjin Kim, Krzysztof Kozlowski, Archit Taneja, Andrzej Hajda,
	Laurent Pinchart, Inki Dae, Joonyoung Shim, Seung-Woo Kim,
	Kyungmin Park, Marek Szyprowski, Bartlomiej Zolnierkiewicz,
	Maciej Purski
In-Reply-To: <CGME20180528094721eucas1p22b90fd838ce00f029fec7f5241cc06b5@eucas1p2.samsung.com>

Hi all,

this patchset is a next attempt to add the tc358764 driver.
The previous one can be found here:

https://lists.freedesktop.org/archives/dri-devel/2014-February/053705.html

Back then, TC358764 was added as a panel driver.

The bridge is supposed to be a DSI peripheral. Currently exynos_dsi accepts only panels
as its peripherals. Therefore, some logic in exynos_dsi had to be ammended. That is implemented
in first 4 patches.

Apart from the driver this patchset adds support for BOE HV070WSA-100 panel, which is used by
TC358764 and dts nodes to exynos5250.dtsi and exynos5250-arndale.dtsi.

Best regards,

Maciej Purski

Maciej Purski (12):
  drm/exynos: rename "bridge_node" to "mic_bridge_node"
  drm/exynos: move pm_runtime_get_sync() to exynos_dsi_init()
  drm/exynos: move connector creation to attach callback
  drm/exynos: add non-panel path to exynos_dsi_enable()
  panel/hv070wsa-100: add DT bindings
  drm/panel: add support for BOE HV070WSA-100 panel to simple-panel
  dt-bindings: tc358754: add DT bindings
  drm/bridge: tc358764: Add DSI to LVDS bridge driver
  ARM: dts: exynos5250: add mipi-phy node
  ARM: dts: exynos5250: add DSI node
  ARM: dts: exynos5250-arndale: add display regulators
  ARM: dts: exynos5250-arndale: add dsi and panel nodes

 .../bindings/display/bridge/toshiba,tc358764.txt   |  42 ++
 .../bindings/display/panel/boe,hv070wsa-100.txt    |   7 +
 arch/arm/boot/dts/exynos5250-arndale.dts           |  63 +++
 arch/arm/boot/dts/exynos5250.dtsi                  |  20 +
 drivers/gpu/drm/bridge/Kconfig                     |   7 +
 drivers/gpu/drm/bridge/Makefile                    |   1 +
 drivers/gpu/drm/bridge/tc358764.c                  | 547 +++++++++++++++++++++
 drivers/gpu/drm/exynos/exynos_drm_dsi.c            |  84 ++--
 drivers/gpu/drm/panel/panel-simple.c               |  25 +
 9 files changed, 756 insertions(+), 40 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/display/bridge/toshiba,tc358764.txt
 create mode 100644 Documentation/devicetree/bindings/display/panel/boe,hv070wsa-100.txt
 create mode 100644 drivers/gpu/drm/bridge/tc358764.c

-- 
2.7.4

^ permalink raw reply

* Re: [PATCH 6/9] ARM: dts: wheat: Drop MTD partitioning from DT
From: Simon Horman @ 2018-05-28  9:36 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	Geert Uytterhoeven, Wolfram Sang, Richard Weinberger,
	Boris Brezillon, Linux-Renesas, Marek Vasut, Laurent Pinchart,
	Linux ARM, Marek Vasut
In-Reply-To: <CAMuHMdXYyN=XY6nb9RVEE+t0NeoSPhTh6fUk-9YWdFzAE1FfPA@mail.gmail.com>

On Mon, May 28, 2018 at 10:54:57AM +0200, Geert Uytterhoeven wrote:
> Hi Simon,
> 
> On Mon, May 28, 2018 at 10:41 AM, Simon Horman <horms@verge.net.au> wrote:
> > On Thu, May 24, 2018 at 04:52:59PM +0200, Marek Vasut wrote:
> >> On 05/23/2018 08:25 AM, Geert Uytterhoeven wrote:
> >> > On Wed, May 23, 2018 at 12:01 AM, Marek Vasut <marek.vasut@gmail.com> wrote:
> >> >> On 05/22/2018 04:43 PM, Geert Uytterhoeven wrote:
> >> >>> On Tue, May 22, 2018 at 2:02 PM, Marek Vasut <marek.vasut@gmail.com> wrote:
> >> >>>> Drop the MTD partitioning from DT, since it does not describe HW
> >> >>>> and to give way to a more flexible kernel command line partition
> >> >>>> passing.
> >> >>>>
> >> >>>> To retain the original partitioning, assure you have enabled
> >> >>>> CONFIG_MTD_CMDLINE_PARTS in your kernel config and add the
> >> >>>> following to your kernel command line:
> >> >>>>
> >> >>>>   mtdparts=spi0.0:256k@0(loader),4096k(user),-(flash)
> >> >>>
> >> >>> I think the "@0" can be dropped, as it's optional?
> >> >>> 4m?
> >> >>
> >> >> My take on this is that the loader is actually at offset 0x0 of the MTD
> >> >> device and we explicitly state that in the mtdparts to anchor the first
> >> >> partition within the MTD device and all the other partitions are at
> >> >> offset +(sum of the sizes of all partitions listed before the current
> >> >> one) relative to that first partition.
> >> >
> >> > Where is this explicitly states for the first partition?
> >> >
> >> >> Removing the @0 feels fragile at best and it seems to depend on the
> >> >> current behavior of the code.
> >> >
> >> > Better, it also depends on the documented behavior:
> >> >
> >> > Documentation/admin-guide/kernel-parameters.txt refers to
> >> > drivers/mtd/cmdlinepart.c, which states:
> >> >
> >> >  * <offset>  := standard linux memsize
> >> >  *              if omitted the part will immediately follow the previous part
> >> >  *              or 0 if the first part
> >> >
> >> > None of the examples listed there or under the MTD_CMDLINE_PARTS Kconfig
> >> > help text, or in a defconfig bundled with the kernel, use @0 for the first
> >> > partition.
> >>
> >> I think this is exceptionally fragile and dangerous to depend on this,
> >> but so be it.
> >
> > Could you respin with this change?
> >
> > I would also like to ask for another change, in light of recent
> > feedback from Olof Johansson ("Re: [GIT PULL] Renesas ARM64 Based SoC DT
> > Updates for v4.18").
> >
> > Please consolidate the dts patches into a single patch?
> 
> I think it's better to keep them split, as each commit description mentions
> what needs to be passed on the kernel command line for the corresponding
> board.
> 
> Combining it in a single patch makes it much harder to extract this information.
> Unless you're fine with a list:
> 
>    koelsch: ...
>    wheat: mtdparts=spi0.0:256k@0(loader),4096k(user),-(flash)

Lets try a list.

^ permalink raw reply

* Re: [PATCH 13/15] arm: dts: r8a7743: Add missing OPP properties for CPUs
From: Simon Horman @ 2018-05-28  9:23 UTC (permalink / raw)
  To: Viresh Kumar
  Cc: arm, Magnus Damm, Rob Herring, Mark Rutland, Vincent Guittot,
	ionela.voinescu, Daniel Lezcano, chris.redpath, linux-renesas-soc,
	devicetree, linux-kernel, Biju Das
In-Reply-To: <5821a6dbe413b5a217ca1e24ddf8ebfa63ba6ef0.1527244201.git.viresh.kumar@linaro.org>

[Cc Biju Das]

On Fri, May 25, 2018 at 04:01:59PM +0530, Viresh Kumar wrote:
> The OPP properties, like "operating-points", should either be present
> for all the CPUs of a cluster or none. If these are present only for a
> subset of CPUs of a cluster then things will start falling apart as soon
> as the CPUs are brought online in a different order. For example, this
> will happen because the operating system looks for such properties in
> the CPU node it is trying to bring up, so that it can create an OPP
> table.
> 
> Add such missing properties.
> 
> Fix other missing property (clock latency) as well to make it all
> work.
> 
> Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>

Thanks, this looks good to me and it looks like it should have:

Fixes: 0417814ea140 ("ARM: dts: r8a7743: Add OPP table for frequency scaling")

Biju, as the author of the above patch could you take a look over this fix?

> ---
>  arch/arm/boot/dts/r8a7743.dtsi | 9 +++++++++
>  1 file changed, 9 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/r8a7743.dtsi b/arch/arm/boot/dts/r8a7743.dtsi
> index 142949d7066f..e4fb31c4f0ee 100644
> --- a/arch/arm/boot/dts/r8a7743.dtsi
> +++ b/arch/arm/boot/dts/r8a7743.dtsi
> @@ -98,8 +98,17 @@
>  			reg = <1>;
>  			clock-frequency = <1500000000>;
>  			clocks = <&cpg CPG_CORE R8A7743_CLK_Z>;
> +			clock-latency = <300000>; /* 300 us */
>  			power-domains = <&sysc R8A7743_PD_CA15_CPU1>;
>  			next-level-cache = <&L2_CA15>;
> +
> +			/* kHz - uV - OPPs unknown yet */
> +			operating-points = <1500000 1000000>,
> +					   <1312500 1000000>,
> +					   <1125000 1000000>,
> +					   < 937500 1000000>,
> +					   < 750000 1000000>,
> +					   < 375000 1000000>;
>  		};
>  
>  		L2_CA15: cache-controller-0 {
> -- 
> 2.15.0.194.g9af6a3dea062
> 

^ permalink raw reply

* Re: [PATCH v7 3/5] ARM: dts: Renesas R9A06G032 base device tree file
From: Simon Horman @ 2018-05-28  9:15 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: Michel Pollet, Linux-Renesas, Phil Edworthy, Michel Pollet,
	Michael Turquette, Stephen Boyd, Rob Herring, Mark Rutland,
	Geert Uytterhoeven, linux-clk,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	Linux Kernel Mailing List
In-Reply-To: <CAMuHMdW5VvZ-wbO7TuZC2z+KFPLq_PhBGe3WbAeES-nezb7tmQ@mail.gmail.com>

On Fri, May 25, 2018 at 11:27:46AM +0200, Geert Uytterhoeven wrote:
> Hi Michel,
> 
> On Thu, May 24, 2018 at 11:28 AM, Michel Pollet
> <michel.pollet@bp.renesas.com> wrote:
> > This adds the Renesas R9A06G032 bare bone support.
> >
> > This currently only handles generic parts (gic, architected timer)
> > and a UART.
> >
> > Signed-off-by: Michel Pollet <michel.pollet@bp.renesas.com>
> 
> Thanks for your patch!
> 
> > --- /dev/null
> > +++ b/arch/arm/boot/dts/r9a06g032.dtsi
> 
> > +       soc {
> > +               compatible = "simple-bus";
> > +               #address-cells = <1>;
> > +               #size-cells = <1>;
> > +               interrupt-parent = <&gic>;
> > +               ranges;
> > +
> > +               sysctrl: sysctrl@4000c000 {
> 
> system-controller@
> 
> > +                       compatible = "renesas,r9a06g032-sysctrl";
> > +                       reg = <0x4000c000 0x1000>;
> > +                       status = "okay";
> > +                       #clock-cells = <1>;
> > +               };
> 
> With the minor nit above resolved, and pending acceptance of the
> sysctrl bindings:
> 
> Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>

Thanks. I have marked this patch, and the following one, as deferred
pending acceptance of those bindings. Please repost or otherwise ping me
once that has happened.

^ permalink raw reply

* Re: [PATCH v2 10/11] arm64: dts: r8a77965-salvator-x: Enable DU external clocks and HDMI
From: Geert Uytterhoeven @ 2018-05-28  9:06 UTC (permalink / raw)
  To: Kieran Bingham, Kuninori Morimoto
  Cc: Mark Rutland,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	Simon Horman, Catalin Marinas, Magnus Damm, open list,
	DRI Development, Linux-Renesas, Rob Herring, Laurent Pinchart,
	Will Deacon, moderated list:ARM64 PORT (AARCH64 ARCHITECTURE)
In-Reply-To: <20180427165722.19445-11-kieran.bingham+renesas@ideasonboard.com>

Hi Kieran, Morimoto-san,

On Fri, Apr 27, 2018 at 6:57 PM, Kieran Bingham
<kieran.bingham+renesas@ideasonboard.com> wrote:
> The DU1 external dot clock is provided by the fixed frequency clock
> generator X21, while the DU0 and DU3 clocks are provided by the
> programmable Versaclock5 clock generator.
>
> Enable the clocks, and the HDMI encoder for the M3-N Salvator-X board
> and hook it up to the HDMI connector.
>
> Based on patches from Takeshi Kihara <takeshi.kihara.df@renesas.com>
>
> Signed-off-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
>
> ---
> v2:
>  - Remove LVDS clocks from DU node
>  - Merge DU Clocks and HDMI enablement
> ---
>  .../boot/dts/renesas/r8a77965-salvator-x.dts  | 28 +++++++++++++++++++
>  1 file changed, 28 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/renesas/r8a77965-salvator-x.dts b/arch/arm64/boot/dts/renesas/r8a77965-salvator-x.dts
> index 75d890d91df9..340a3c72b65a 100644
> --- a/arch/arm64/boot/dts/renesas/r8a77965-salvator-x.dts
> +++ b/arch/arm64/boot/dts/renesas/r8a77965-salvator-x.dts
> @@ -19,3 +19,31 @@
>                 reg = <0x0 0x48000000 0x0 0x78000000>;
>         };
>  };
> +
> +&du {
> +       clocks = <&cpg CPG_MOD 724>,
> +                <&cpg CPG_MOD 723>,
> +                <&cpg CPG_MOD 721>,
> +                <&versaclock5 1>,
> +                <&x21_clk>,
> +                <&versaclock5 2>;
> +       clock-names = "du.0", "du.1", "du.3",
> +                     "dclkin.0", "dclkin.1", "dclkin.3";
> +};
> +
> +&hdmi0 {
> +       status = "okay";
> +
> +       ports {
> +               port@1 {
> +                       reg = <1>;
> +                       rcar_dw_hdmi0_out: endpoint {
> +                               remote-endpoint = <&hdmi0_con>;
> +                       };
> +               };
> +       };
> +};
> +
> +&hdmi0_con {
> +       remote-endpoint = <&rcar_dw_hdmi0_out>;
> +};

I think the hdmi0 and hdmi0_con parts can be moved to salvator-common.dtsi.
Can we do that now (with stubs?), or does this have to wait until r8a77965 has
received HDMI sound support?

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

* [PATCH v2 6/6] regulator: bd71837: BD71837 PMIC regulator driver
From: Matti Vaittinen @ 2018-05-28  9:01 UTC (permalink / raw)
  To: mturquette, sboyd, robh+dt, mark.rutland, lee.jones, lgirdwood,
	broonie, mazziesaccount
  Cc: linux-clk, devicetree, linux-kernel, mikko.mutanen,
	heikki.haikola

Support for controlling the 8 bucks and 7 LDOs the PMIC contains.

Signed-off-by: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
---
 drivers/regulator/Kconfig             |  11 +
 drivers/regulator/Makefile            |   1 +
 drivers/regulator/bd71837-regulator.c | 678 ++++++++++++++++++++++++++++++++++
 3 files changed, 690 insertions(+)
 create mode 100644 drivers/regulator/bd71837-regulator.c

diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 097f61784a7d..139f4b53fea0 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -180,6 +180,17 @@ config REGULATOR_BCM590XX
 	  BCM590xx PMUs. This will enable support for the software
 	  controllable LDO/Switching regulators.
 
+config REGULATOR_BD71837
+	tristate "ROHM BD71837 Power Regulator"
+	depends on MFD_BD71837
+	help
+	  This driver supports voltage regulators on ROHM BD71837 PMIC.
+	  This will enable support for the software controllable buck
+	  and LDO regulators.
+
+	  This driver can also be built as a module. If so, the module
+	  will be called bd71837-regulator.
+
 config REGULATOR_BD9571MWV
 	tristate "ROHM BD9571MWV Regulators"
 	depends on MFD_BD9571MWV
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index 590674fbecd7..1b4d8ec416c2 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -27,6 +27,7 @@ obj-$(CONFIG_REGULATOR_AS3711) += as3711-regulator.o
 obj-$(CONFIG_REGULATOR_AS3722) += as3722-regulator.o
 obj-$(CONFIG_REGULATOR_AXP20X) += axp20x-regulator.o
 obj-$(CONFIG_REGULATOR_BCM590XX) += bcm590xx-regulator.o
+obj-$(CONFIG_REGULATOR_BD71837) += bd71837-regulator.o
 obj-$(CONFIG_REGULATOR_BD9571MWV) += bd9571mwv-regulator.o
 obj-$(CONFIG_REGULATOR_DA903X)	+= da903x.o
 obj-$(CONFIG_REGULATOR_DA9052)	+= da9052-regulator.o
diff --git a/drivers/regulator/bd71837-regulator.c b/drivers/regulator/bd71837-regulator.c
new file mode 100644
index 000000000000..227a952e49cb
--- /dev/null
+++ b/drivers/regulator/bd71837-regulator.c
@@ -0,0 +1,678 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright (C) 2018 ROHM Semiconductors */
+/*
+ * bd71837-regulator.c ROHM BD71837MWV regulator driver
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/gpio.h>
+#include <linux/mfd/bd71837.h>
+#include <linux/regulator/of_regulator.h>
+
+struct bd71837_pmic {
+	struct regulator_desc descs[BD71837_REGULATOR_CNT];
+	struct bd71837 *mfd;
+	struct platform_device *pdev;
+	struct regulator_dev *rdev[BD71837_REGULATOR_CNT];
+	struct mutex mtx;
+};
+
+/*
+ * BUCK1/2/3/4
+ * BUCK1RAMPRATE[1:0] BUCK1 DVS ramp rate setting
+ * 00: 10.00mV/usec 10mV 1uS
+ * 01: 5.00mV/usec	10mV 2uS
+ * 10: 2.50mV/usec	10mV 4uS
+ * 11: 1.25mV/usec	10mV 8uS
+ */
+static int bd71837_buck1234_set_ramp_delay(struct regulator_dev *rdev,
+					   int ramp_delay)
+{
+	struct bd71837_pmic *pmic = rdev_get_drvdata(rdev);
+	struct bd71837 *mfd = pmic->mfd;
+	int id = rdev->desc->id;
+	unsigned int ramp_value = BUCK1_RAMPRATE_10P00MV;
+
+	dev_dbg(&(pmic->pdev->dev), "Buck[%d] Set Ramp = %d\n", id + 1,
+		ramp_delay);
+	switch (ramp_delay) {
+	case 1 ... 1250:
+		ramp_value = BUCK1_RAMPRATE_1P25MV;
+		break;
+	case 1251 ... 2500:
+		ramp_value = BUCK1_RAMPRATE_2P50MV;
+		break;
+	case 2501 ... 5000:
+		ramp_value = BUCK1_RAMPRATE_5P00MV;
+		break;
+	case 5001 ... 10000:
+		ramp_value = BUCK1_RAMPRATE_10P00MV;
+		break;
+	default:
+		ramp_value = BUCK1_RAMPRATE_10P00MV;
+		dev_err(&pmic->pdev->dev,
+			"%s: ramp_delay: %d not supported, setting 10000mV//us\n",
+			rdev->desc->name, ramp_delay);
+	}
+
+	return regmap_update_bits(mfd->regmap, BD71837_REG_BUCK1_CTRL + id,
+				  BUCK1_RAMPRATE_MASK, ramp_value << 6);
+}
+
+static int bd71837_regulator_set_regmap(struct regulator_dev *rdev, int set)
+{
+	int ret = -EINVAL;
+	struct bd71837_pmic *pmic = rdev->reg_data;
+
+	/* According to the data sheet we must not change regulator voltage
+	 * when it is enabled. Thus we need to check if regulator is enabled
+	 * before changing the voltage. This mutex is used to avoid race where
+	 * we might enable regulator after it's state has been checked but
+	 * before the voltage is changed
+	 */
+	mutex_lock(&pmic->mtx);
+	if (!set)
+		ret = regulator_disable_regmap(rdev);
+	else
+		ret = regulator_enable_regmap(rdev);
+	mutex_unlock(&pmic->mtx);
+
+	return ret;
+}
+
+static int bd71837_regulator_enable_regmap(struct regulator_dev *rdev)
+{
+	return bd71837_regulator_set_regmap(rdev, 1);
+}
+
+static int bd71837_regulator_disable_regmap(struct regulator_dev *rdev)
+{
+	return bd71837_regulator_set_regmap(rdev, 0);
+}
+
+static int bd71837_regulator_set_voltage_sel_regmap(struct regulator_dev *rdev,
+						    unsigned int sel)
+{
+	int ret;
+	struct bd71837_pmic *pmic = rdev->reg_data;
+
+	/* According to the data sheet we must not change regulator voltage
+	 * when it is enabled. Error out if regulator is enabled.
+	 */
+	mutex_lock(&pmic->mtx);
+	ret = regulator_is_enabled_regmap(rdev);
+	if (!ret)
+		ret = regulator_set_voltage_sel_regmap(rdev, sel);
+	else if (ret == 1)
+		ret = -EBUSY;
+	mutex_unlock(&pmic->mtx);
+	return ret;
+}
+
+static struct regulator_ops bd71837_ldo_regulator_ops = {
+	.enable = bd71837_regulator_enable_regmap,
+	.disable = bd71837_regulator_disable_regmap,
+	.is_enabled = regulator_is_enabled_regmap,
+	.list_voltage = regulator_list_voltage_linear_range,
+	.set_voltage_sel = bd71837_regulator_set_voltage_sel_regmap,
+	.get_voltage_sel = regulator_get_voltage_sel_regmap,
+};
+
+static struct regulator_ops bd71837_ldo_regulator_nolinear_ops = {
+	.enable = bd71837_regulator_enable_regmap,
+	.disable = bd71837_regulator_disable_regmap,
+	.is_enabled = regulator_is_enabled_regmap,
+	.list_voltage = regulator_list_voltage_table,
+	.set_voltage_sel = bd71837_regulator_set_voltage_sel_regmap,
+	.get_voltage_sel = regulator_get_voltage_sel_regmap,
+};
+
+static struct regulator_ops bd71837_buck_regulator_ops = {
+	.enable = bd71837_regulator_enable_regmap,
+	.disable = bd71837_regulator_disable_regmap,
+	.is_enabled = regulator_is_enabled_regmap,
+	.list_voltage = regulator_list_voltage_linear_range,
+	.set_voltage_sel = bd71837_regulator_set_voltage_sel_regmap,
+	.get_voltage_sel = regulator_get_voltage_sel_regmap,
+	.set_voltage_time_sel = regulator_set_voltage_time_sel,
+};
+
+static struct regulator_ops bd71837_buck_regulator_nolinear_ops = {
+	.enable = bd71837_regulator_enable_regmap,
+	.disable = bd71837_regulator_disable_regmap,
+	.is_enabled = regulator_is_enabled_regmap,
+	.list_voltage = regulator_list_voltage_table,
+	.set_voltage_sel = bd71837_regulator_set_voltage_sel_regmap,
+	.get_voltage_sel = regulator_get_voltage_sel_regmap,
+	.set_voltage_time_sel = regulator_set_voltage_time_sel,
+};
+
+static struct regulator_ops bd71837_buck1234_regulator_ops = {
+	.enable = bd71837_regulator_enable_regmap,
+	.disable = bd71837_regulator_disable_regmap,
+	.is_enabled = regulator_is_enabled_regmap,
+	.list_voltage = regulator_list_voltage_linear_range,
+	.set_voltage_sel = bd71837_regulator_set_voltage_sel_regmap,
+	.get_voltage_sel = regulator_get_voltage_sel_regmap,
+	.set_voltage_time_sel = regulator_set_voltage_time_sel,
+	.set_ramp_delay = bd71837_buck1234_set_ramp_delay,
+};
+
+/*
+ * BUCK1/2/3/4
+ * 0.70 to 1.30V (10mV step)
+ */
+static const struct regulator_linear_range bd71837_buck1234_voltage_ranges[] = {
+	REGULATOR_LINEAR_RANGE(700000, 0x00, 0x3C, 10000),
+	REGULATOR_LINEAR_RANGE(1300000, 0x3D, 0x3F, 0),
+};
+
+/*
+ * BUCK5
+ * 0.9V to 1.35V ()
+ */
+static const struct regulator_linear_range bd71837_buck5_voltage_ranges[] = {
+	REGULATOR_LINEAR_RANGE(700000, 0x00, 0x03, 100000),
+	REGULATOR_LINEAR_RANGE(1050000, 0x04, 0x05, 50000),
+	REGULATOR_LINEAR_RANGE(1200000, 0x06, 0x07, 150000),
+};
+
+/*
+ * BUCK6
+ * 3.0V to 3.3V (step 100mV)
+ */
+static const struct regulator_linear_range bd71837_buck6_voltage_ranges[] = {
+	REGULATOR_LINEAR_RANGE(3000000, 0x00, 0x03, 100000),
+};
+
+/*
+ * BUCK7
+ * 000 = 1.605V
+ * 001 = 1.695V
+ * 010 = 1.755V
+ * 011 = 1.8V (Initial)
+ * 100 = 1.845V
+ * 101 = 1.905V
+ * 110 = 1.95V
+ * 111 = 1.995V
+ */
+static const unsigned int buck_7_volts[] = {
+	1605000, 1695000, 1755000, 1800000, 1845000, 1905000, 1950000, 1995000
+};
+
+/*
+ * BUCK8
+ * 0.8V to 1.40V (step 10mV)
+ */
+static const struct regulator_linear_range bd71837_buck8_voltage_ranges[] = {
+	REGULATOR_LINEAR_RANGE(800000, 0x00, 0x3C, 10000),
+	REGULATOR_LINEAR_RANGE(1400000, 0x3D, 0x3F, 0),
+};
+
+/*
+ * LDO1
+ * 3.0 to 3.3V (100mV step)
+ */
+static const struct regulator_linear_range bd71837_ldo1_voltage_ranges[] = {
+	REGULATOR_LINEAR_RANGE(3000000, 0x00, 0x03, 100000),
+};
+
+/*
+ * LDO2
+ * 0.8 or 0.9V
+ */
+const unsigned int ldo_2_volts[] = {
+	900000, 800000
+};
+
+/*
+ * LDO3
+ * 1.8 to 3.3V (100mV step)
+ */
+static const struct regulator_linear_range bd71837_ldo3_voltage_ranges[] = {
+	REGULATOR_LINEAR_RANGE(1800000, 0x00, 0x0F, 100000),
+};
+
+/*
+ * LDO4
+ * 0.9 to 1.8V (100mV step)
+ */
+static const struct regulator_linear_range bd71837_ldo4_voltage_ranges[] = {
+	REGULATOR_LINEAR_RANGE(900000, 0x00, 0x09, 100000),
+	REGULATOR_LINEAR_RANGE(1800000, 0x0A, 0x0F, 0),
+};
+
+/*
+ * LDO5
+ * 1.8 to 3.3V (100mV step)
+ */
+static const struct regulator_linear_range bd71837_ldo5_voltage_ranges[] = {
+	REGULATOR_LINEAR_RANGE(1800000, 0x00, 0x0F, 100000),
+};
+
+/*
+ * LDO6
+ * 0.9 to 1.8V (100mV step)
+ */
+static const struct regulator_linear_range bd71837_ldo6_voltage_ranges[] = {
+	REGULATOR_LINEAR_RANGE(900000, 0x00, 0x09, 100000),
+	REGULATOR_LINEAR_RANGE(1800000, 0x0A, 0x0F, 0),
+};
+
+/*
+ * LDO7
+ * 1.8 to 3.3V (100mV step)
+ */
+static const struct regulator_linear_range bd71837_ldo7_voltage_ranges[] = {
+	REGULATOR_LINEAR_RANGE(1800000, 0x00, 0x0F, 100000),
+};
+
+static const struct regulator_desc bd71837_regulators[] = {
+	{
+	 .name = "buck1",
+	 .of_match = of_match_ptr("BUCK1"),
+	 .regulators_node = of_match_ptr("regulators"),
+	 .id = BD71837_BUCK1,
+	 .ops = &bd71837_buck1234_regulator_ops,
+	 .type = REGULATOR_VOLTAGE,
+	 .n_voltages = BD71837_BUCK1_VOLTAGE_NUM,
+	 .linear_ranges = bd71837_buck1234_voltage_ranges,
+	 .n_linear_ranges = ARRAY_SIZE(bd71837_buck1234_voltage_ranges),
+	 .vsel_reg = BD71837_REG_BUCK1_VOLT_RUN,
+	 .vsel_mask = BUCK1_RUN_MASK,
+	 .enable_reg = BD71837_REG_BUCK1_CTRL,
+	 .enable_mask = BD71837_BUCK_EN,
+	 .owner = THIS_MODULE,
+	 },
+	{
+	 .name = "buck2",
+	 .of_match = of_match_ptr("BUCK2"),
+	 .regulators_node = of_match_ptr("regulators"),
+	 .id = BD71837_BUCK2,
+	 .ops = &bd71837_buck1234_regulator_ops,
+	 .type = REGULATOR_VOLTAGE,
+	 .n_voltages = BD71837_BUCK2_VOLTAGE_NUM,
+	 .linear_ranges = bd71837_buck1234_voltage_ranges,
+	 .n_linear_ranges = ARRAY_SIZE(bd71837_buck1234_voltage_ranges),
+	 .vsel_reg = BD71837_REG_BUCK2_VOLT_RUN,
+	 .vsel_mask = BUCK2_RUN_MASK,
+	 .enable_reg = BD71837_REG_BUCK2_CTRL,
+	 .enable_mask = BD71837_BUCK_EN,
+	 .owner = THIS_MODULE,
+	 },
+	{
+	 .name = "buck3",
+	 .of_match = of_match_ptr("BUCK3"),
+	 .regulators_node = of_match_ptr("regulators"),
+	 .id = BD71837_BUCK3,
+	 .ops = &bd71837_buck1234_regulator_ops,
+	 .type = REGULATOR_VOLTAGE,
+	 .n_voltages = BD71837_BUCK3_VOLTAGE_NUM,
+	 .linear_ranges = bd71837_buck1234_voltage_ranges,
+	 .n_linear_ranges = ARRAY_SIZE(bd71837_buck1234_voltage_ranges),
+	 .vsel_reg = BD71837_REG_BUCK3_VOLT_RUN,
+	 .vsel_mask = BUCK3_RUN_MASK,
+	 .enable_reg = BD71837_REG_BUCK3_CTRL,
+	 .enable_mask = BD71837_BUCK_EN,
+	 .owner = THIS_MODULE,
+	 },
+	{
+	 .name = "buck4",
+	 .of_match = of_match_ptr("BUCK4"),
+	 .regulators_node = of_match_ptr("regulators"),
+	 .id = BD71837_BUCK4,
+	 .ops = &bd71837_buck1234_regulator_ops,
+	 .type = REGULATOR_VOLTAGE,
+	 .n_voltages = BD71837_BUCK4_VOLTAGE_NUM,
+	 .linear_ranges = bd71837_buck1234_voltage_ranges,
+	 .n_linear_ranges = ARRAY_SIZE(bd71837_buck1234_voltage_ranges),
+	 .vsel_reg = BD71837_REG_BUCK4_VOLT_RUN,
+	 .vsel_mask = BUCK4_RUN_MASK,
+	 .enable_reg = BD71837_REG_BUCK4_CTRL,
+	 .enable_mask = BD71837_BUCK_EN,
+	 .owner = THIS_MODULE,
+	 },
+	{
+	 .name = "buck5",
+	 .of_match = of_match_ptr("BUCK5"),
+	 .regulators_node = of_match_ptr("regulators"),
+	 .id = BD71837_BUCK5,
+	 .ops = &bd71837_buck_regulator_ops,
+	 .type = REGULATOR_VOLTAGE,
+	 .n_voltages = BD71837_BUCK5_VOLTAGE_NUM,
+	 .linear_ranges = bd71837_buck5_voltage_ranges,
+	 .n_linear_ranges = ARRAY_SIZE(bd71837_buck5_voltage_ranges),
+	 .vsel_reg = BD71837_REG_BUCK5_VOLT,
+	 .vsel_mask = BUCK5_MASK,
+	 .enable_reg = BD71837_REG_BUCK5_CTRL,
+	 .enable_mask = BD71837_BUCK_EN,
+	 .owner = THIS_MODULE,
+	 },
+	{
+	 .name = "buck6",
+	 .of_match = of_match_ptr("BUCK6"),
+	 .regulators_node = of_match_ptr("regulators"),
+	 .id = BD71837_BUCK6,
+	 .ops = &bd71837_buck_regulator_ops,
+	 .type = REGULATOR_VOLTAGE,
+	 .n_voltages = BD71837_BUCK6_VOLTAGE_NUM,
+	 .linear_ranges = bd71837_buck6_voltage_ranges,
+	 .n_linear_ranges = ARRAY_SIZE(bd71837_buck6_voltage_ranges),
+	 .vsel_reg = BD71837_REG_BUCK6_VOLT,
+	 .vsel_mask = BUCK6_MASK,
+	 .enable_reg = BD71837_REG_BUCK6_CTRL,
+	 .enable_mask = BD71837_BUCK_EN,
+	 .owner = THIS_MODULE,
+	 },
+	{
+	 .name = "buck7",
+	 .of_match = of_match_ptr("BUCK7"),
+	 .regulators_node = of_match_ptr("regulators"),
+	 .id = BD71837_BUCK7,
+	 .ops = &bd71837_buck_regulator_nolinear_ops,
+	 .type = REGULATOR_VOLTAGE,
+	 .volt_table = &buck_7_volts[0],
+	 .n_voltages = ARRAY_SIZE(buck_7_volts),
+	 .vsel_reg = BD71837_REG_BUCK7_VOLT,
+	 .vsel_mask = BUCK7_MASK,
+	 .enable_reg = BD71837_REG_BUCK7_CTRL,
+	 .enable_mask = BD71837_BUCK_EN,
+	 .owner = THIS_MODULE,
+	 },
+	{
+	 .name = "buck8",
+	 .of_match = of_match_ptr("BUCK8"),
+	 .regulators_node = of_match_ptr("regulators"),
+	 .id = BD71837_BUCK8,
+	 .ops = &bd71837_buck_regulator_ops,
+	 .type = REGULATOR_VOLTAGE,
+	 .n_voltages = BD71837_BUCK8_VOLTAGE_NUM,
+	 .linear_ranges = bd71837_buck8_voltage_ranges,
+	 .n_linear_ranges = ARRAY_SIZE(bd71837_buck8_voltage_ranges),
+	 .vsel_reg = BD71837_REG_BUCK8_VOLT,
+	 .vsel_mask = BUCK8_MASK,
+	 .enable_reg = BD71837_REG_BUCK8_CTRL,
+	 .enable_mask = BD71837_BUCK_EN,
+	 .owner = THIS_MODULE,
+	 },
+	{
+	 .name = "ldo1",
+	 .of_match = of_match_ptr("LDO1"),
+	 .regulators_node = of_match_ptr("regulators"),
+	 .id = BD71837_LDO1,
+	 .ops = &bd71837_ldo_regulator_ops,
+	 .type = REGULATOR_VOLTAGE,
+	 .n_voltages = BD71837_LDO1_VOLTAGE_NUM,
+	 .linear_ranges = bd71837_ldo1_voltage_ranges,
+	 .n_linear_ranges = ARRAY_SIZE(bd71837_ldo1_voltage_ranges),
+	 .vsel_reg = BD71837_REG_LDO1_VOLT,
+	 .vsel_mask = LDO1_MASK,
+	 .enable_reg = BD71837_REG_LDO1_VOLT,
+	 .enable_mask = BD71837_LDO_EN,
+	 .owner = THIS_MODULE,
+	 },
+	{
+	 .name = "ldo2",
+	 .of_match = of_match_ptr("LDO2"),
+	 .regulators_node = of_match_ptr("regulators"),
+	 .id = BD71837_LDO2,
+	 .ops = &bd71837_ldo_regulator_nolinear_ops,
+	 .type = REGULATOR_VOLTAGE,
+	 .volt_table = &ldo_2_volts[0],
+	 .vsel_reg = BD71837_REG_LDO2_VOLT,
+	 .vsel_mask = LDO2_MASK,
+	 .n_voltages = ARRAY_SIZE(ldo_2_volts),
+	 .n_voltages = BD71837_LDO2_VOLTAGE_NUM,
+	 .enable_reg = BD71837_REG_LDO2_VOLT,
+	 .enable_mask = BD71837_LDO_EN,
+	 .owner = THIS_MODULE,
+	 },
+	{
+	 .name = "ldo3",
+	 .of_match = of_match_ptr("LDO3"),
+	 .regulators_node = of_match_ptr("regulators"),
+	 .id = BD71837_LDO3,
+	 .ops = &bd71837_ldo_regulator_ops,
+	 .type = REGULATOR_VOLTAGE,
+	 .n_voltages = BD71837_LDO3_VOLTAGE_NUM,
+	 .linear_ranges = bd71837_ldo3_voltage_ranges,
+	 .n_linear_ranges = ARRAY_SIZE(bd71837_ldo3_voltage_ranges),
+	 .vsel_reg = BD71837_REG_LDO3_VOLT,
+	 .vsel_mask = LDO3_MASK,
+	 .enable_reg = BD71837_REG_LDO3_VOLT,
+	 .enable_mask = BD71837_LDO_EN,
+	 .owner = THIS_MODULE,
+	 },
+	{
+	 .name = "ldo4",
+	 .of_match = of_match_ptr("LDO4"),
+	 .regulators_node = of_match_ptr("regulators"),
+	 .id = BD71837_LDO4,
+	 .ops = &bd71837_ldo_regulator_ops,
+	 .type = REGULATOR_VOLTAGE,
+	 .n_voltages = BD71837_LDO4_VOLTAGE_NUM,
+	 .linear_ranges = bd71837_ldo4_voltage_ranges,
+	 .n_linear_ranges = ARRAY_SIZE(bd71837_ldo4_voltage_ranges),
+	 .vsel_reg = BD71837_REG_LDO4_VOLT,
+	 .vsel_mask = LDO4_MASK,
+	 .enable_reg = BD71837_REG_LDO4_VOLT,
+	 .enable_mask = BD71837_LDO_EN,
+	 .owner = THIS_MODULE,
+	 },
+	{
+	 .name = "ldo5",
+	 .of_match = of_match_ptr("LDO5"),
+	 .regulators_node = of_match_ptr("regulators"),
+	 .id = BD71837_LDO5,
+	 .ops = &bd71837_ldo_regulator_ops,
+	 .type = REGULATOR_VOLTAGE,
+	 .n_voltages = BD71837_LDO5_VOLTAGE_NUM,
+	 .linear_ranges = bd71837_ldo5_voltage_ranges,
+	 .n_linear_ranges = ARRAY_SIZE(bd71837_ldo5_voltage_ranges),
+	 /* LDO5 is supplied by buck6 */
+	 .supply_name = "buck6",
+	 .vsel_reg = BD71837_REG_LDO5_VOLT,
+	 .vsel_mask = LDO5_MASK,
+	 .enable_reg = BD71837_REG_LDO5_VOLT,
+	 .enable_mask = BD71837_LDO_EN,
+	 .owner = THIS_MODULE,
+	 },
+	{
+	 .name = "ldo6",
+	 .of_match = of_match_ptr("LDO6"),
+	 .regulators_node = of_match_ptr("regulators"),
+	 .id = BD71837_LDO6,
+	 .ops = &bd71837_ldo_regulator_ops,
+	 .type = REGULATOR_VOLTAGE,
+	 .n_voltages = BD71837_LDO6_VOLTAGE_NUM,
+	 .linear_ranges = bd71837_ldo6_voltage_ranges,
+	 .n_linear_ranges = ARRAY_SIZE(bd71837_ldo6_voltage_ranges),
+	 /* LDO6 is supplied by buck7 */
+	 .supply_name = "buck7",
+	 .vsel_reg = BD71837_REG_LDO6_VOLT,
+	 .vsel_mask = LDO6_MASK,
+	 .enable_reg = BD71837_REG_LDO6_VOLT,
+	 .enable_mask = BD71837_LDO_EN,
+	 .owner = THIS_MODULE,
+	 },
+	{
+	 .name = "ldo7",
+	 .of_match = of_match_ptr("LDO7"),
+	 .regulators_node = of_match_ptr("regulators"),
+	 .id = BD71837_LDO7,
+	 .ops = &bd71837_ldo_regulator_ops,
+	 .type = REGULATOR_VOLTAGE,
+	 .n_voltages = BD71837_LDO7_VOLTAGE_NUM,
+	 .linear_ranges = bd71837_ldo7_voltage_ranges,
+	 .n_linear_ranges = ARRAY_SIZE(bd71837_ldo7_voltage_ranges),
+	 .vsel_reg = BD71837_REG_LDO7_VOLT,
+	 .vsel_mask = LDO7_MASK,
+	 .enable_reg = BD71837_REG_LDO7_VOLT,
+	 .enable_mask = BD71837_LDO_EN,
+	 .owner = THIS_MODULE,
+	 },
+};
+
+struct reg_init {
+	unsigned int reg;
+	unsigned int mask;
+};
+
+static int bd71837_probe(struct platform_device *pdev)
+{
+	struct bd71837_pmic *pmic;
+	struct bd71837_board *pdata;
+	struct regulator_config config = { 0 };
+	struct reg_init pmic_regulator_inits[] = {
+		{
+		 .reg = BD71837_REG_BUCK1_CTRL,
+		 .mask = BD71837_BUCK_SEL,
+		}, {
+		 .reg = BD71837_REG_BUCK2_CTRL,
+		 .mask = BD71837_BUCK_SEL,
+		}, {
+		 .reg = BD71837_REG_BUCK3_CTRL,
+		 .mask = BD71837_BUCK_SEL,
+		}, {
+		 .reg = BD71837_REG_BUCK4_CTRL,
+		 .mask = BD71837_BUCK_SEL,
+		}, {
+		 .reg = BD71837_REG_BUCK5_CTRL,
+		 .mask = BD71837_BUCK_SEL,
+		}, {
+		 .reg = BD71837_REG_BUCK6_CTRL,
+		 .mask = BD71837_BUCK_SEL,
+		}, {
+		 .reg = BD71837_REG_BUCK7_CTRL,
+		 .mask = BD71837_BUCK_SEL,
+		}, {
+		 .reg = BD71837_REG_BUCK8_CTRL,
+		 .mask = BD71837_BUCK_SEL,
+		}, {
+		 .reg = BD71837_REG_LDO1_VOLT,
+		 .mask = BD71837_LDO_SEL,
+		}, {
+		 .reg = BD71837_REG_LDO2_VOLT,
+		 .mask = BD71837_LDO_SEL,
+		}, {
+		 .reg = BD71837_REG_LDO3_VOLT,
+		 .mask = BD71837_LDO_SEL,
+		}, {
+		 .reg = BD71837_REG_LDO4_VOLT,
+		 .mask = BD71837_LDO_SEL,
+		}, {
+		 .reg = BD71837_REG_LDO5_VOLT,
+		 .mask = BD71837_LDO_SEL,
+		}, {
+		 .reg = BD71837_REG_LDO6_VOLT,
+		 .mask = BD71837_LDO_SEL,
+		}, {
+		 .reg = BD71837_REG_LDO7_VOLT,
+		 .mask = BD71837_LDO_SEL,
+		}
+	};
+
+	int i, err;
+
+	pmic = devm_kzalloc(&pdev->dev, sizeof(struct bd71837_pmic),
+			    GFP_KERNEL);
+	if (!pmic)
+		return -ENOMEM;
+
+	mutex_init(&pmic->mtx);
+
+	memcpy(pmic->descs, bd71837_regulators, sizeof(pmic->descs));
+
+	pmic->pdev = pdev;
+	pmic->mfd = dev_get_drvdata(pdev->dev.parent);
+
+	if (!pmic->mfd) {
+		dev_err(&pdev->dev, "No MFD driver data\n");
+		err = -EINVAL;
+		goto err;
+	}
+	platform_set_drvdata(pdev, pmic);
+	pdata = dev_get_platdata(pmic->mfd->dev);
+
+	/* Register LOCK release */
+	err = regmap_update_bits(pmic->mfd->regmap, BD71837_REG_REGLOCK,
+				 (REGLOCK_PWRSEQ | REGLOCK_VREG), 0);
+	if (err) {
+		dev_err(&pmic->pdev->dev, "Failed to unlock PMIC (%d)\n", err);
+		goto err;
+	} else {
+		dev_dbg(&pmic->pdev->dev, "%s: Unlocked lock register 0x%x\n",
+			__func__, BD71837_REG_REGLOCK);
+	}
+
+	for (i = 0; i < ARRAY_SIZE(pmic_regulator_inits); i++) {
+
+		struct regulator_desc *desc;
+		struct regulator_dev *rdev;
+		uint32_t val;
+
+		desc = &pmic->descs[i];
+
+		if (pdata)
+			config.init_data = pdata->init_data[i];
+
+		config.dev = pdev->dev.parent;
+		config.driver_data = pmic;
+		config.regmap = pmic->mfd->regmap;
+
+		rdev = devm_regulator_register(&pdev->dev, desc, &config);
+		if (IS_ERR(rdev)) {
+			dev_err(pmic->mfd->dev,
+				"failed to register %s regulator\n",
+				desc->name);
+			err = PTR_ERR(rdev);
+			goto err;
+		}
+		/* Regulator register gets the regulator constraints and
+		 * applies them (set_machine_constraints). This should have
+		 * turned the control register(s) to correct values and we
+		 * can now switch the control from PMIC state machine to the
+		 * register interface
+		 */
+		err = regmap_update_bits(pmic->mfd->regmap,
+					 pmic_regulator_inits[i].reg,
+					 pmic_regulator_inits[i].mask,
+					 0xFFFFFFFF);
+		if (err) {
+			dev_err(&pmic->pdev->dev,
+				"Failed to write BUCK/LDO SEL bit for (%s)\n",
+				desc->name);
+			goto err;
+		}
+
+		pmic->rdev[i] = rdev;
+	}
+
+	return 0;
+
+err:
+	return err;
+}
+
+static struct platform_driver bd71837_regulator = {
+	.driver = {
+		   .name = "bd71837-pmic",
+		   .owner = THIS_MODULE,
+		   },
+	.probe = bd71837_probe,
+};
+
+module_platform_driver(bd71837_regulator);
+
+MODULE_AUTHOR("Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>");
+MODULE_DESCRIPTION("BD71837 voltage regulator driver");
+MODULE_LICENSE("GPL");
-- 
2.14.3

^ permalink raw reply related

* [PATCH v2 5/6] clk: bd71837: Add driver for BD71837 PMIC clock
From: Matti Vaittinen @ 2018-05-28  9:01 UTC (permalink / raw)
  To: mturquette, sboyd, robh+dt, mark.rutland, lee.jones, lgirdwood,
	broonie, mazziesaccount
  Cc: linux-clk, devicetree, linux-kernel, mikko.mutanen,
	heikki.haikola

Support BD71837 gateable 32768 Hz clock.

Signed-off-by: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
---
 drivers/clk/Kconfig       |   9 +++
 drivers/clk/Makefile      |   1 +
 drivers/clk/clk-bd71837.c | 154 ++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 164 insertions(+)
 create mode 100644 drivers/clk/clk-bd71837.c

diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index 41492e980ef4..4b045699bb5e 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -279,6 +279,15 @@ config COMMON_CLK_STM32H7
 	---help---
 	  Support for stm32h7 SoC family clocks
 
+config COMMON_CLK_BD71837
+	tristate "Clock driver for ROHM BD71837 PMIC MFD"
+	depends on MFD_BD71837
+	depends on I2C=y
+	depends on OF
+	help
+	  This driver supports ROHM BD71837 PMIC clock.
+
+
 source "drivers/clk/bcm/Kconfig"
 source "drivers/clk/hisilicon/Kconfig"
 source "drivers/clk/imgtec/Kconfig"
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index de6d06ac790b..8393c4af7d5a 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -21,6 +21,7 @@ endif
 obj-$(CONFIG_MACH_ASM9260)		+= clk-asm9260.o
 obj-$(CONFIG_COMMON_CLK_AXI_CLKGEN)	+= clk-axi-clkgen.o
 obj-$(CONFIG_ARCH_AXXIA)		+= clk-axm5516.o
+obj-$(CONFIG_COMMON_CLK_BD71837)	+= clk-bd71837.o
 obj-$(CONFIG_COMMON_CLK_CDCE706)	+= clk-cdce706.o
 obj-$(CONFIG_COMMON_CLK_CDCE925)	+= clk-cdce925.o
 obj-$(CONFIG_ARCH_CLPS711X)		+= clk-clps711x.o
diff --git a/drivers/clk/clk-bd71837.c b/drivers/clk/clk-bd71837.c
new file mode 100644
index 000000000000..632b8c28c9e2
--- /dev/null
+++ b/drivers/clk/clk-bd71837.c
@@ -0,0 +1,154 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright (C) 2018 ROHM Semiconductors */
+/*
+ * bd71837.c  --  ROHM BD71837MWV clock driver
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/mfd/bd71837.h>
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+
+static int bd71837_clk_enable(struct clk_hw *hw);
+static void bd71837_clk_disable(struct clk_hw *hw);
+static int bd71837_clk_is_enabled(struct clk_hw *hw);
+
+struct bd71837_clk {
+	struct clk_hw hw;
+	uint8_t reg;
+	uint8_t mask;
+	unsigned long rate;
+	struct platform_device *pdev;
+	struct bd71837 *mfd;
+};
+
+static unsigned long bd71837_clk_recalc_rate(struct clk_hw *hw,
+					     unsigned long parent_rate);
+
+static const struct clk_ops bd71837_clk_ops = {
+	.recalc_rate = &bd71837_clk_recalc_rate,
+	.prepare = &bd71837_clk_enable,
+	.unprepare = &bd71837_clk_disable,
+	.is_prepared = &bd71837_clk_is_enabled,
+};
+
+static int bd71837_clk_set(struct clk_hw *hw, int status)
+{
+	struct bd71837_clk *c = container_of(hw, struct bd71837_clk, hw);
+
+	return bd71837_update_bits(c->mfd, c->reg, c->mask, status);
+}
+
+static void bd71837_clk_disable(struct clk_hw *hw)
+{
+	int rv;
+	struct bd71837_clk *c = container_of(hw, struct bd71837_clk, hw);
+
+	rv = bd71837_clk_set(hw, 0);
+	if (rv)
+		dev_err(&c->pdev->dev, "Failed to disable 32K clk (%d)\n", rv);
+}
+
+static int bd71837_clk_enable(struct clk_hw *hw)
+{
+	return bd71837_clk_set(hw, 1);
+}
+
+static int bd71837_clk_is_enabled(struct clk_hw *hw)
+{
+	struct bd71837_clk *c = container_of(hw, struct bd71837_clk, hw);
+
+	return c->mask & bd71837_reg_read(c->mfd, c->reg);
+
+}
+
+static unsigned long bd71837_clk_recalc_rate(struct clk_hw *hw,
+					     unsigned long parent_rate)
+{
+	struct bd71837_clk *c = container_of(hw, struct bd71837_clk, hw);
+
+	return c->rate;
+}
+
+static int bd71837_clk_probe(struct platform_device *pdev)
+{
+	struct bd71837_clk *c;
+	int rval = -ENOMEM;
+	struct bd71837 *mfd = dev_get_drvdata(pdev->dev.parent);
+	const char *errstr = "memory allocation for bd71837 data failed";
+	struct clk_init_data init = {
+		.name = "bd71837-32k-out",
+		.ops = &bd71837_clk_ops,
+	};
+
+	c = kzalloc(sizeof(struct bd71837_clk), GFP_KERNEL);
+	if (!c)
+		goto err_out;
+
+	c->reg = BD71837_REG_OUT32K;
+	c->mask = BD71837_OUT32K_EN;
+	c->rate = BD71837_CLK_RATE;
+	c->mfd = mfd;
+	c->pdev = pdev;
+
+	if (pdev->dev.of_node)
+		of_property_read_string_index(pdev->dev.of_node,
+					      "clock-output-names", 0,
+					      &init.name);
+
+	c->hw.init = &init;
+
+	errstr = "failed to register 32K clk";
+	rval = clk_hw_register(&pdev->dev, &c->hw);
+	if (rval)
+		goto err_free;
+
+	errstr = "failed to register clkdev for bd71837";
+	rval = clk_hw_register_clkdev(&c->hw, init.name, NULL);
+	if (rval)
+		goto err_unregister;
+
+	platform_set_drvdata(pdev, c);
+	dev_dbg(&pdev->dev, "bd71837_clk successfully probed\n");
+
+	return 0;
+
+err_unregister:
+	clk_hw_unregister(&c->hw);
+err_free:
+	kfree(c);
+err_out:
+	dev_err(&pdev->dev, "%s\n", errstr);
+	return rval;
+}
+
+static int bd71837_clk_remove(struct platform_device *pdev)
+{
+	struct bd71837_clk *c = platform_get_drvdata(pdev);
+
+	if (c) {
+		clk_hw_unregister(&c->hw);
+		kfree(c);
+		platform_set_drvdata(pdev, NULL);
+	}
+	return 0;
+}
+
+static struct platform_driver bd71837_clk = {
+	.driver = {
+		.name = "bd71837-clk",
+	},
+	.probe = bd71837_clk_probe,
+	.remove = bd71837_clk_remove,
+};
+
+module_platform_driver(bd71837_clk);
+
+MODULE_AUTHOR("Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>");
+MODULE_DESCRIPTION("BD71837 chip clk driver");
+MODULE_LICENSE("GPL");
-- 
2.14.3

^ permalink raw reply related

* [PATCH v2 4/6] clk: bd71837: Devicetree bindings for ROHM BD71837 PMIC
From: Matti Vaittinen @ 2018-05-28  9:01 UTC (permalink / raw)
  To: mturquette, sboyd, robh+dt, mark.rutland, lee.jones, lgirdwood,
	broonie, mazziesaccount
  Cc: linux-clk, devicetree, linux-kernel, mikko.mutanen,
	heikki.haikola

Document devicetree bindings for ROHM BD71837 PMIC clock output.

Signed-off-by: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
---
 .../bindings/clock/rohm,bd71837-clock.txt          | 37 ++++++++++++++++++++++
 1 file changed, 37 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/rohm,bd71837-clock.txt

diff --git a/Documentation/devicetree/bindings/clock/rohm,bd71837-clock.txt b/Documentation/devicetree/bindings/clock/rohm,bd71837-clock.txt
new file mode 100644
index 000000000000..9759fd145781
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/rohm,bd71837-clock.txt
@@ -0,0 +1,37 @@
+ROHM BD71837 Power Management Integrated Circuit clock bindings
+
+BD71837 clock node should be sub node of the BD71837 MFD node.
+See BD71837 MFD bindings at
+Documentation/devicetree/bindings/mfd/rohm,bd71837-pmic.txt
+
+Required properties:
+- compatible		: Should be "rohm,bd71837-clk"
+- clock-frequency	: Should be 32768
+- #clock-cells		: Should be 0
+
+Optional properties:
+- clock-output-names	: Should contain name for output clock.
+  Name "bd71837-32k-out" is used if this is not given.
+
+
+Example:
+
+pmic: bd71837@4b {
+	compatible = "rohm,bd71837";
+	#address-cells = <1>;
+	#size-cells = <0>;
+	reg = <0x4b>;
+	interrupt-parent = <&gpio1>;
+	interrupts = <29 GPIO_ACTIVE_LOW>;
+	interrupt-names = "irq";
+	#interrupt-cells = <1>;
+	interrupt-controller;
+
+	/* Clock node */
+	clk: bd71837-32k-out {
+		compatible = "rohm,bd71837-clk";
+		#clock-cells = <0>;
+		clock-frequency  = <32768>;
+		clock-output-names = "bd71837-32k-out";
+	};
+};
-- 
2.14.3

^ permalink raw reply related

* [PATCH v2 3/6] regulator: bd71837: Devicetree bindings for BD71837 regulators
From: Matti Vaittinen @ 2018-05-28  9:01 UTC (permalink / raw)
  To: mturquette, sboyd, robh+dt, mark.rutland, lee.jones, lgirdwood,
	broonie, mazziesaccount
  Cc: linux-clk, devicetree, linux-kernel, mikko.mutanen,
	heikki.haikola

Document devicetree bindings for ROHM BD71837 PMIC regulators.

Signed-off-by: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
---
 .../bindings/regulator/rohm,bd71837-regulator.txt  | 126 +++++++++++++++++++++
 1 file changed, 126 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/regulator/rohm,bd71837-regulator.txt

diff --git a/Documentation/devicetree/bindings/regulator/rohm,bd71837-regulator.txt b/Documentation/devicetree/bindings/regulator/rohm,bd71837-regulator.txt
new file mode 100644
index 000000000000..4edf3137d9f7
--- /dev/null
+++ b/Documentation/devicetree/bindings/regulator/rohm,bd71837-regulator.txt
@@ -0,0 +1,126 @@
+ROHM BD71837 Power Management Integrated Circuit (PMIC) regulator bindings
+
+BD71837MWV is a programmable Power Management
+IC (PMIC) for powering single-core, dual-core, and
+quad-core SoC’s such as NXP-i.MX 8M. It is optimized
+for low BOM cost and compact solution footprint. It
+integrates 8 Buck regulators and 7 LDO’s to provide all
+the power rails required by the SoC and the commonly
+used peripherals.
+
+Required properties:
+ - regulator-name: should be "buck1", ..., "buck8" and "ldo1", ..., "ldo7"
+
+List of regulators provided by this controller. BD71837 regulators node
+should be sub node of the BD71837 MFD node. See BD71837 MFD bindings at
+Documentation/devicetree/bindings/mfd/rohm,bd71837-pmic.txt
+Regulator nodes should be named to BUCK_<number> and LDO_<number>. The
+definition for each of these nodes is defined using the standard
+binding for regulators at
+Documentation/devicetree/bindings/regulator/regulator.txt.
+Note that if BD71837 starts at RUN state you probably want to use
+regulator-boot-on at least for BUCK6 and BUCK7 so that those are not
+disabled by driver at startup. LDO5 and LDO6 are supplied by those and
+if they are disabled at startup the voltage monitoring for LDO5/LDO6 will
+cause PMIC to reset.
+
+The valid names for regulator nodes are:
+BUCK1, BUCK2, BUCK3, BUCK4, BUCK5, BUCK6, BUCK7, BUCK8
+LDO1, LDO2, LDO3, LDO4, LDO5, LDO6, LDO7
+
+Optional properties:
+- Any optional property defined in bindings/regulator/regulator.txt
+
+Example:
+regulators {
+	buck1: BUCK1 {
+		regulator-name = "buck1";
+		regulator-min-microvolt = <700000>;
+		regulator-max-microvolt = <1300000>;
+		regulator-boot-on;
+		regulator-ramp-delay = <1250>;
+	};
+	buck2: BUCK2 {
+		regulator-name = "buck2";
+		regulator-min-microvolt = <700000>;
+		regulator-max-microvolt = <1300000>;
+		regulator-boot-on;
+		regulator-always-on;
+		regulator-ramp-delay = <1250>;
+	};
+	buck3: BUCK3 {
+		regulator-name = "buck3";
+		regulator-min-microvolt = <700000>;
+		regulator-max-microvolt = <1300000>;
+		regulator-boot-on;
+	};
+	buck4: BUCK4 {
+		regulator-name = "buck4";
+		regulator-min-microvolt = <700000>;
+		regulator-max-microvolt = <1300000>;
+		regulator-boot-on;
+	};
+	buck5: BUCK5 {
+		regulator-name = "buck5";
+		regulator-min-microvolt = <700000>;
+		regulator-max-microvolt = <1350000>;
+		regulator-boot-on;
+	};
+	buck6: BUCK6 {
+		regulator-name = "buck6";
+		regulator-min-microvolt = <3000000>;
+		regulator-max-microvolt = <3300000>;
+		regulator-boot-on;
+	};
+	buck7: BUCK7 {
+		regulator-name = "buck7";
+		regulator-min-microvolt = <1605000>;
+		regulator-max-microvolt = <1995000>;
+		regulator-boot-on;
+	};
+	buck8: BUCK8 {
+		regulator-name = "buck8";
+		regulator-min-microvolt = <800000>;
+		regulator-max-microvolt = <1400000>;
+	};
+
+	ldo1: LDO1 {
+		regulator-name = "ldo1";
+		regulator-min-microvolt = <3000000>;
+		regulator-max-microvolt = <3300000>;
+		regulator-boot-on;
+	};
+	ldo2: LDO2 {
+		regulator-name = "ldo2";
+		regulator-min-microvolt = <900000>;
+		regulator-max-microvolt = <900000>;
+		regulator-boot-on;
+	};
+	ldo3: LDO3 {
+		regulator-name = "ldo3";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <3300000>;
+	};
+	ldo4: LDO4 {
+		regulator-name = "ldo4";
+		regulator-min-microvolt = <900000>;
+		regulator-max-microvolt = <1800000>;
+	};
+	ldo5: LDO5 {
+		regulator-name = "ldo5";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <3300000>;
+	};
+	ldo6: LDO6 {
+		regulator-name = "ldo6";
+		regulator-min-microvolt = <900000>;
+		regulator-max-microvolt = <1800000>;
+	};
+	ldo7_reg: LDO7 {
+		regulator-name = "ldo7";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <3300000>;
+	};
+};
+
+
-- 
2.14.3

^ permalink raw reply related

* [PATCH v2 2/6] mfd: bd71837: Devicetree bindings for ROHM BD71837 PMIC
From: Matti Vaittinen @ 2018-05-28  9:00 UTC (permalink / raw)
  To: mturquette, sboyd, robh+dt, mark.rutland, lee.jones, lgirdwood,
	broonie, mazziesaccount
  Cc: linux-clk, devicetree, linux-kernel, mikko.mutanen,
	heikki.haikola

Document devicetree bindings for ROHM BD71837 PMIC MFD.

Signed-off-by: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
---
 .../devicetree/bindings/mfd/rohm,bd71837-pmic.txt  | 52 ++++++++++++++++++++++
 1 file changed, 52 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mfd/rohm,bd71837-pmic.txt

diff --git a/Documentation/devicetree/bindings/mfd/rohm,bd71837-pmic.txt b/Documentation/devicetree/bindings/mfd/rohm,bd71837-pmic.txt
new file mode 100644
index 000000000000..bbc46d38b162
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/rohm,bd71837-pmic.txt
@@ -0,0 +1,52 @@
+* ROHM BD71837 Power Management Integrated Circuit bindings
+
+BD71837MWV is a programmable Power Management IC for powering single-core,
+dual-core, and quad-core SoC’s such as NXP-i.MX 8M. It is optimized for
+low BOM cost and compact solution footprint. It integrates 8 Buck
+egulators and 7 LDO’s to provide all the power rails required by the SoC and
+the commonly used peripherals.
+
+Required properties:
+ - compatible		: Should be "rohm,bd71837".
+ - reg			: I2C slave address.
+ - interrupt-parent	: Phandle to the parent interrupt controller.
+ - interrupts		: The interrupt line the device is connected to.
+ - interrupt-controller	: Marks the device node as an interrupt controller.
+ - #interrupt-cells	: The number of cells to describe an IRQ, should be 1 or 2.
+			    The first cell is the IRQ number.
+			    The second cell if present is the flags, encoded as trigger
+			    masks from ../interrupt-controller/interrupts.txt.
+ - regulators:		: List of child nodes that specify the regulators
+			  Please see ../regulator/rohm,bd71837-regulator.txt
+ - clock:		: Please see ../clock/rohm,bd71837-clock.txt
+
+Example:
+
+	pmic: bd71837@4b {
+		compatible = "rohm,bd71837";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg = <0x4b>;
+		interrupt-parent = <&gpio1>;
+		interrupts = <29 GPIO_ACTIVE_LOW>;
+		interrupt-names = "irq";
+		#interrupt-cells = <1>;
+		interrupt-controller;
+
+		regulators {
+			buck1: BUCK1 {
+				regulator-name = "buck1";
+				regulator-min-microvolt = <700000>;
+				regulator-max-microvolt = <1300000>;
+				regulator-boot-on;
+				regulator-ramp-delay = <1250>;
+			};
+			...
+		};
+		clk: bd71837-32k-out {
+			compatible = "rohm,bd71837-clk";
+			#clock-cells = <0>;
+			clock-frequency = <32768>;
+			clock-output-names = "bd71837-32k-out";
+		};
+	};
-- 
2.14.3

^ permalink raw reply related

* [PATCH v2 1/6] mfd: bd71837: mfd driver for ROHM BD71837 PMIC
From: Matti Vaittinen @ 2018-05-28  9:00 UTC (permalink / raw)
  To: mturquette, sboyd, robh+dt, mark.rutland, lee.jones, lgirdwood,
	broonie, mazziesaccount
  Cc: linux-clk, devicetree, linux-kernel, mikko.mutanen,
	heikki.haikola

ROHM BD71837 PMIC MFD driver providing interrupts and support
for two subsystems:
- clk
- Regulators

Signed-off-by: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
---
 drivers/mfd/Kconfig         |  13 ++
 drivers/mfd/Makefile        |   1 +
 drivers/mfd/bd71837.c       | 238 +++++++++++++++++++++++++++++++++
 include/linux/mfd/bd71837.h | 316 ++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 568 insertions(+)
 create mode 100644 drivers/mfd/bd71837.c
 create mode 100644 include/linux/mfd/bd71837.h

diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index b860eb5aa194..7aa05fc9ed8e 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -1787,6 +1787,19 @@ config MFD_STW481X
 	  in various ST Microelectronics and ST-Ericsson embedded
 	  Nomadik series.
 
+config MFD_BD71837
+	bool "BD71837 Power Management chip"
+	depends on I2C=y
+	depends on OF
+	select REGMAP_I2C
+	select REGMAP_IRQ
+	select MFD_CORE
+	help
+	  Select this option to get support for the ROHM BD71837
+	  Power Management chips. BD71837 is designed to power processors like
+	  NXP i.MX8. It contains 8 BUCK outputs and 7 LDOs, voltage monitoring
+	  and emergency shut down as well as 32,768KHz clock output.
+
 config MFD_STM32_LPTIMER
 	tristate "Support for STM32 Low-Power Timer"
 	depends on (ARCH_STM32 && OF) || COMPILE_TEST
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index e9fd20dba18d..09dc9eb3782c 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -227,4 +227,5 @@ obj-$(CONFIG_MFD_STM32_TIMERS) 	+= stm32-timers.o
 obj-$(CONFIG_MFD_MXS_LRADC)     += mxs-lradc.o
 obj-$(CONFIG_MFD_SC27XX_PMIC)	+= sprd-sc27xx-spi.o
 obj-$(CONFIG_RAVE_SP_CORE)	+= rave-sp.o
+obj-$(CONFIG_MFD_BD71837)	+= bd71837.o
 
diff --git a/drivers/mfd/bd71837.c b/drivers/mfd/bd71837.c
new file mode 100644
index 000000000000..3b738243b405
--- /dev/null
+++ b/drivers/mfd/bd71837.c
@@ -0,0 +1,238 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright (C) 2018 ROHM Semiconductors */
+/*
+ * bd71837.c  --  ROHM BD71837MWV mfd driver
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/irqdomain.h>
+#include <linux/gpio.h>
+#include <linux/regmap.h>
+#include <linux/of_device.h>
+#include <linux/of_gpio.h>
+#include <linux/mfd/core.h>
+#include <linux/mfd/bd71837.h>
+
+/* bd71837 multi function cells */
+static struct mfd_cell bd71837_mfd_cells[] = {
+	{
+		.name = "bd71837-clk",
+		.of_compatible = "rohm,bd71837-clk",
+	}, {
+		.name = "bd71837-pmic",
+	},
+};
+
+static const struct regmap_irq bd71837_irqs[] = {
+	[BD71837_INT_SWRST] = {
+		.mask = BD71837_INT_SWRST_MASK,
+	},
+	[BD71837_INT_PWRBTN_S] = {
+		.mask = BD71837_INT_PWRBTN_S_MASK,
+	},
+	[BD71837_INT_PWRBTN_L] = {
+		.mask = BD71837_INT_PWRBTN_L_MASK,
+	},
+	[BD71837_INT_PWRBTN] = {
+		.mask = BD71837_INT_PWRBTN_MASK,
+	},
+	[BD71837_INT_WDOG] = {
+		.mask = BD71837_INT_WDOG_MASK,
+	},
+	[BD71837_INT_ON_REQ] = {
+		.mask = BD71837_INT_ON_REQ_MASK,
+	},
+	[BD71837_INT_STBY_REQ] = {
+		.mask = BD71837_INT_STBY_REQ_MASK,
+	},
+};
+
+static struct regmap_irq_chip bd71837_irq_chip = {
+	.name = "bd71837-irq",
+	.irqs = bd71837_irqs,
+	.num_irqs = ARRAY_SIZE(bd71837_irqs),
+	.num_regs = 1,
+	.irq_reg_stride = 1,
+	.status_base = BD71837_REG_IRQ,
+	.mask_base = BD71837_REG_MIRQ,
+	.mask_invert = false,
+};
+
+static int bd71837_irq_exit(struct bd71837 *bd71837)
+{
+	if (bd71837->chip_irq > 0)
+		regmap_del_irq_chip(bd71837->chip_irq, bd71837->irq_data);
+	return 0;
+}
+
+static const struct regmap_range pmic_status_range = {
+	.range_min = BD71837_REG_IRQ,
+	.range_max = BD71837_REG_POW_STATE,
+};
+
+static const struct regmap_access_table volatile_regs = {
+	.yes_ranges = &pmic_status_range,
+	.n_yes_ranges = 1,
+};
+
+static const struct regmap_config bd71837_regmap_config = {
+	.reg_bits = 8,
+	.val_bits = 8,
+	.volatile_table = &volatile_regs,
+	.max_register = BD71837_MAX_REGISTER - 1,
+	.cache_type = REGCACHE_RBTREE,
+};
+
+#ifdef CONFIG_OF
+static const struct of_device_id bd71837_of_match[] = {
+	{ .compatible = "rohm,bd71837", .data = (void *)0},
+	{ },
+};
+MODULE_DEVICE_TABLE(of, bd71837_of_match);
+
+static int bd71837_parse_dt(struct i2c_client *client, struct bd71837_board **b)
+{
+	struct device_node *np = client->dev.of_node;
+	struct bd71837_board *board_info;
+	unsigned int prop;
+	int r;
+	int rv = -ENOMEM;
+
+	board_info = devm_kzalloc(&client->dev, sizeof(*board_info),
+			GFP_KERNEL);
+	if (!board_info)
+		goto err_out;
+
+	if (client->irq) {
+		dev_dbg(&client->dev, "Got irq %d\n", client->irq);
+		board_info->gpio_intr = client->irq;
+	} else {
+		dev_err(&client->dev, "no pmic intr pin available\n");
+		rv = -ENOENT;
+		goto err_intr;
+	}
+	r = of_property_read_u32(np, "irq_base", &prop);
+	if (!r)
+		board_info->irq_base = prop;
+	else
+		board_info->irq_base = 0;
+
+	rv = 0;
+	*b = board_info;
+	if (0) {
+err_intr:
+		devm_kfree(&client->dev, board_info);
+err_out:
+		dev_err(&client->dev, "failed to parse device-tree (%d)\n", rv);
+	}
+	return rv;
+}
+#endif //CONFIG_OF
+
+static int bd71837_i2c_probe(struct i2c_client *i2c,
+			    const struct i2c_device_id *id)
+{
+	struct bd71837 *bd71837;
+	struct bd71837_board *pmic_plat_data;
+	int ret = -EINVAL;
+
+	pmic_plat_data = dev_get_platdata(&i2c->dev);
+
+	if (!pmic_plat_data && i2c->dev.of_node)
+		ret = bd71837_parse_dt(i2c, &pmic_plat_data);
+
+	if (!pmic_plat_data)
+		return ret;
+
+	bd71837 = devm_kzalloc(&i2c->dev, sizeof(struct bd71837), GFP_KERNEL);
+	if (bd71837 == NULL)
+		return -ENOMEM;
+
+	bd71837->of_plat_data = pmic_plat_data;
+	i2c_set_clientdata(i2c, bd71837);
+	bd71837->dev = &i2c->dev;
+	bd71837->i2c_client = i2c;
+	bd71837->chip_irq = pmic_plat_data->gpio_intr;
+
+	bd71837->regmap = devm_regmap_init_i2c(i2c, &bd71837_regmap_config);
+	if (IS_ERR(bd71837->regmap)) {
+		ret = PTR_ERR(bd71837->regmap);
+		dev_err(&i2c->dev, "regmap initialization failed: %d\n", ret);
+		goto err_out;
+	}
+
+	ret = bd71837_reg_read(bd71837, BD71837_REG_REV);
+	if (ret < 0) {
+		dev_err(bd71837->dev,
+			"%s(): Read BD71837_REG_DEVICE failed!\n", __func__);
+		goto err_out;
+	}
+
+	ret = regmap_add_irq_chip(bd71837->regmap, bd71837->chip_irq,
+		IRQF_ONESHOT, 0,
+		&bd71837_irq_chip, &bd71837->irq_data);
+	if (ret < 0) {
+		dev_err(bd71837->dev, "Failed to add irq_chip %d\n", ret);
+		goto err_out;
+	}
+
+	ret = mfd_add_devices(bd71837->dev, PLATFORM_DEVID_AUTO,
+			      bd71837_mfd_cells, ARRAY_SIZE(bd71837_mfd_cells),
+			      NULL, 0,
+			      regmap_irq_get_domain(bd71837->irq_data));
+	if (ret)
+		regmap_del_irq_chip(bd71837->chip_irq, bd71837->irq_data);
+err_out:
+
+	return ret;
+}
+
+static int bd71837_i2c_remove(struct i2c_client *i2c)
+{
+	struct bd71837 *bd71837 = i2c_get_clientdata(i2c);
+
+	bd71837_irq_exit(bd71837);
+	mfd_remove_devices(bd71837->dev);
+
+	return 0;
+}
+
+static const struct i2c_device_id bd71837_i2c_id[] = {
+	{ .name = "bd71837", },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, bd71837_i2c_id);
+
+static struct i2c_driver bd71837_i2c_driver = {
+	.driver = {
+		.name = "bd71837-mfd",
+		.owner = THIS_MODULE,
+		.of_match_table = of_match_ptr(bd71837_of_match),
+	},
+	.probe = bd71837_i2c_probe,
+	.remove = bd71837_i2c_remove,
+	.id_table = bd71837_i2c_id,
+};
+
+static int __init bd71837_i2c_init(void)
+{
+	return i2c_add_driver(&bd71837_i2c_driver);
+}
+/* init early so consumer devices can complete system boot */
+subsys_initcall(bd71837_i2c_init);
+
+static void __exit bd71837_i2c_exit(void)
+{
+	i2c_del_driver(&bd71837_i2c_driver);
+}
+module_exit(bd71837_i2c_exit);
+
+MODULE_AUTHOR("Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>");
+MODULE_DESCRIPTION("BD71837 chip multi-function driver");
+MODULE_LICENSE("GPL");
diff --git a/include/linux/mfd/bd71837.h b/include/linux/mfd/bd71837.h
new file mode 100644
index 000000000000..ba9be05cc61e
--- /dev/null
+++ b/include/linux/mfd/bd71837.h
@@ -0,0 +1,316 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright (C) 2018 ROHM Semiconductors */
+
+/*
+ * ROHM BD71837MWV header file
+ */
+
+#ifndef __LINUX_MFD_BD71837_H__
+#define __LINUX_MFD_BD71837_H__
+
+#include <linux/regmap.h>
+
+enum {
+	BD71837_BUCK1	=	0,
+	BD71837_BUCK2,
+	BD71837_BUCK3,
+	BD71837_BUCK4,
+	BD71837_BUCK5,
+	BD71837_BUCK6,
+	BD71837_BUCK7,
+	BD71837_BUCK8,
+	BD71837_LDO1,
+	BD71837_LDO2,
+	BD71837_LDO3,
+	BD71837_LDO4,
+	BD71837_LDO5,
+	BD71837_LDO6,
+	BD71837_LDO7,
+	BD71837_REGULATOR_CNT,
+};
+
+#define BD71837_SUPPLY_STATE_ENABLED	0x1
+
+#define BD71837_BUCK1_VOLTAGE_NUM	0x40
+#define BD71837_BUCK2_VOLTAGE_NUM	0x40
+#define BD71837_BUCK3_VOLTAGE_NUM	0x40
+#define BD71837_BUCK4_VOLTAGE_NUM	0x40
+
+#define BD71837_BUCK5_VOLTAGE_NUM	0x08
+#define BD71837_BUCK6_VOLTAGE_NUM	0x04
+#define BD71837_BUCK7_VOLTAGE_NUM	0x08
+#define BD71837_BUCK8_VOLTAGE_NUM	0x40
+
+#define BD71837_LDO1_VOLTAGE_NUM	0x04
+#define BD71837_LDO2_VOLTAGE_NUM	0x02
+#define BD71837_LDO3_VOLTAGE_NUM	0x10
+#define BD71837_LDO4_VOLTAGE_NUM	0x10
+#define BD71837_LDO5_VOLTAGE_NUM	0x10
+#define BD71837_LDO6_VOLTAGE_NUM	0x10
+#define BD71837_LDO7_VOLTAGE_NUM	0x10
+
+enum {
+	BD71837_REG_REV                = 0x00,
+	BD71837_REG_SWRESET            = 0x01,
+	BD71837_REG_I2C_DEV            = 0x02,
+	BD71837_REG_PWRCTRL0           = 0x03,
+	BD71837_REG_PWRCTRL1           = 0x04,
+	BD71837_REG_BUCK1_CTRL         = 0x05,
+	BD71837_REG_BUCK2_CTRL         = 0x06,
+	BD71837_REG_BUCK3_CTRL         = 0x07,
+	BD71837_REG_BUCK4_CTRL         = 0x08,
+	BD71837_REG_BUCK5_CTRL         = 0x09,
+	BD71837_REG_BUCK6_CTRL         = 0x0A,
+	BD71837_REG_BUCK7_CTRL         = 0x0B,
+	BD71837_REG_BUCK8_CTRL         = 0x0C,
+	BD71837_REG_BUCK1_VOLT_RUN     = 0x0D,
+	BD71837_REG_BUCK1_VOLT_IDLE    = 0x0E,
+	BD71837_REG_BUCK1_VOLT_SUSP    = 0x0F,
+	BD71837_REG_BUCK2_VOLT_RUN     = 0x10,
+	BD71837_REG_BUCK2_VOLT_IDLE    = 0x11,
+	BD71837_REG_BUCK3_VOLT_RUN     = 0x12,
+	BD71837_REG_BUCK4_VOLT_RUN     = 0x13,
+	BD71837_REG_BUCK5_VOLT         = 0x14,
+	BD71837_REG_BUCK6_VOLT         = 0x15,
+	BD71837_REG_BUCK7_VOLT         = 0x16,
+	BD71837_REG_BUCK8_VOLT         = 0x17,
+	BD71837_REG_LDO1_VOLT          = 0x18,
+	BD71837_REG_LDO2_VOLT          = 0x19,
+	BD71837_REG_LDO3_VOLT          = 0x1A,
+	BD71837_REG_LDO4_VOLT          = 0x1B,
+	BD71837_REG_LDO5_VOLT          = 0x1C,
+	BD71837_REG_LDO6_VOLT          = 0x1D,
+	BD71837_REG_LDO7_VOLT          = 0x1E,
+	BD71837_REG_TRANS_COND0        = 0x1F,
+	BD71837_REG_TRANS_COND1        = 0x20,
+	BD71837_REG_VRFAULTEN          = 0x21,
+	BD71837_REG_MVRFLTMASK0        = 0x22,
+	BD71837_REG_MVRFLTMASK1        = 0x23,
+	BD71837_REG_MVRFLTMASK2        = 0x24,
+	BD71837_REG_RCVCFG             = 0x25,
+	BD71837_REG_RCVNUM             = 0x26,
+	BD71837_REG_PWRONCONFIG0       = 0x27,
+	BD71837_REG_PWRONCONFIG1       = 0x28,
+	BD71837_REG_RESETSRC           = 0x29,
+	BD71837_REG_MIRQ               = 0x2A,
+	BD71837_REG_IRQ                = 0x2B,
+	BD71837_REG_IN_MON             = 0x2C,
+	BD71837_REG_POW_STATE          = 0x2D,
+	BD71837_REG_OUT32K             = 0x2E,
+	BD71837_REG_REGLOCK            = 0x2F,
+	BD71837_REG_OTPVER             = 0xFF,
+	BD71837_MAX_REGISTER           = 0x100,
+};
+
+#define REGLOCK_PWRSEQ	0x1
+#define REGLOCK_VREG	0x10
+
+/* Generic BUCK control masks */
+#define BD71837_BUCK_SEL	0x02
+#define BD71837_BUCK_EN		0x01
+#define BD71837_BUCK_RUN_ON	0x04
+
+/* Generic LDO masks */
+#define BD71837_LDO_SEL		0x80
+#define BD71837_LDO_EN		0x40
+
+/* BD71837_REG_BUCK1_CTRL bits */
+#define BUCK1_RAMPRATE_MASK	0xC0
+#define BUCK1_RAMPRATE_10P00MV	0x0
+#define BUCK1_RAMPRATE_5P00MV	0x1
+#define BUCK1_RAMPRATE_2P50MV	0x2
+#define BUCK1_RAMPRATE_1P25MV	0x3
+
+/* BD71837_REG_BUCK2_CTRL bits */
+#define BUCK2_RAMPRATE_MASK	0xC0
+#define BUCK2_RAMPRATE_10P00MV	0x0
+#define BUCK2_RAMPRATE_5P00MV	0x1
+#define BUCK2_RAMPRATE_2P50MV	0x2
+#define BUCK2_RAMPRATE_1P25MV	0x3
+
+/* BD71837_REG_BUCK3_CTRL bits */
+#define BUCK3_RAMPRATE_MASK	0xC0
+#define BUCK3_RAMPRATE_10P00MV	0x0
+#define BUCK3_RAMPRATE_5P00MV	0x1
+#define BUCK3_RAMPRATE_2P50MV	0x2
+#define BUCK3_RAMPRATE_1P25MV	0x3
+
+/* BD71837_REG_BUCK4_CTRL bits */
+#define BUCK4_RAMPRATE_MASK	0xC0
+#define BUCK4_RAMPRATE_10P00MV	0x0
+#define BUCK4_RAMPRATE_5P00MV	0x1
+#define BUCK4_RAMPRATE_2P50MV	0x2
+#define BUCK4_RAMPRATE_1P25MV	0x3
+
+/* BD71837_REG_BUCK1_VOLT_RUN bits */
+#define BUCK1_RUN_MASK		0x3F
+#define BUCK1_RUN_DEFAULT	0x14
+
+/* BD71837_REG_BUCK1_VOLT_SUSP bits */
+#define BUCK1_SUSP_MASK		0x3F
+#define BUCK1_SUSP_DEFAULT	0x14
+
+/* BD71837_REG_BUCK1_VOLT_IDLE bits */
+#define BUCK1_IDLE_MASK		0x3F
+#define BUCK1_IDLE_DEFAULT	0x14
+
+/* BD71837_REG_BUCK2_VOLT_RUN bits */
+#define BUCK2_RUN_MASK		0x3F
+#define BUCK2_RUN_DEFAULT	0x1E
+
+/* BD71837_REG_BUCK2_VOLT_IDLE bits */
+#define BUCK2_IDLE_MASK		0x3F
+#define BUCK2_IDLE_DEFAULT	0x14
+
+/* BD71837_REG_BUCK3_VOLT_RUN bits */
+#define BUCK3_RUN_MASK		0x3F
+#define BUCK3_RUN_DEFAULT	0x1E
+
+/* BD71837_REG_BUCK4_VOLT_RUN bits */
+#define BUCK4_RUN_MASK		0x3F
+#define BUCK4_RUN_DEFAULT	0x1E
+
+/* BD71837_REG_BUCK5_VOLT bits */
+#define BUCK5_MASK		0x07
+#define BUCK5_DEFAULT		0x02
+
+/* BD71837_REG_BUCK6_VOLT bits */
+#define BUCK6_MASK		0x03
+#define BUCK6_DEFAULT		0x03
+
+/* BD71837_REG_BUCK7_VOLT bits */
+#define BUCK7_MASK		0x07
+#define BUCK7_DEFAULT		0x03
+
+/* BD71837_REG_BUCK8_VOLT bits */
+#define BUCK8_MASK		0x3F
+#define BUCK8_DEFAULT		0x1E
+
+/* BD71837_REG_IRQ bits */
+#define IRQ_SWRST		0x40
+#define IRQ_PWRON_S		0x20
+#define IRQ_PWRON_L		0x10
+#define IRQ_PWRON		0x08
+#define IRQ_WDOG		0x04
+#define IRQ_ON_REQ		0x02
+#define IRQ_STBY_REQ		0x01
+
+/* BD71837_REG_OUT32K bits */
+#define BD71837_OUT32K_EN	0x01
+
+/* BD71837 gated clock rate */
+#define BD71837_CLK_RATE 32768
+
+/* BD71837 irqs */
+enum {
+	BD71837_INT_STBY_REQ,
+	BD71837_INT_ON_REQ,
+	BD71837_INT_WDOG,
+	BD71837_INT_PWRBTN,
+	BD71837_INT_PWRBTN_L,
+	BD71837_INT_PWRBTN_S,
+	BD71837_INT_SWRST
+};
+
+/* BD71837 interrupt masks */
+#define BD71837_INT_SWRST_MASK		0x40
+#define BD71837_INT_PWRBTN_S_MASK	0x20
+#define BD71837_INT_PWRBTN_L_MASK	0x10
+#define BD71837_INT_PWRBTN_MASK		0x8
+#define BD71837_INT_WDOG_MASK		0x4
+#define BD71837_INT_ON_REQ_MASK		0x2
+#define BD71837_INT_STBY_REQ_MASK	0x1
+
+/* BD71837_REG_LDO1_VOLT bits */
+#define LDO1_MASK		0x03
+
+/* BD71837_REG_LDO1_VOLT bits */
+#define LDO2_MASK		0x20
+
+/* BD71837_REG_LDO3_VOLT bits */
+#define LDO3_MASK		0x0F
+
+/* BD71837_REG_LDO4_VOLT bits */
+#define LDO4_MASK		0x0F
+
+/* BD71837_REG_LDO5_VOLT bits */
+#define LDO5_MASK		0x0F
+
+/* BD71837_REG_LDO6_VOLT bits */
+#define LDO6_MASK		0x0F
+
+/* BD71837_REG_LDO7_VOLT bits */
+#define LDO7_MASK		0x0F
+
+struct bd71837;
+struct bd71837_pmic;
+struct bd71837_clk;
+
+/*
+ * Board platform data may be used to initialize regulators.
+ */
+
+struct bd71837_board {
+	struct regulator_init_data *init_data[BD71837_REGULATOR_CNT];
+	int	gpio_intr;
+	int	irq_base;
+};
+
+struct bd71837 {
+	struct device *dev;
+	struct i2c_client *i2c_client;
+	struct regmap *regmap;
+	unsigned long int id;
+
+	int chip_irq;
+	struct regmap_irq_chip_data *irq_data;
+
+	struct bd71837_pmic *pmic;
+	struct bd71837_clk *clk;
+
+	struct bd71837_board *of_plat_data;
+};
+
+static inline unsigned long int bd71837_chip_id(struct bd71837 *bd71837)
+{
+	return bd71837->id;
+}
+
+/*
+ * bd71837 sub-driver chip access routines
+ */
+
+static inline int bd71837_reg_read(struct bd71837 *bd71837, u8 reg)
+{
+	int r, val;
+
+	r = regmap_read(bd71837->regmap, reg, &val);
+	if (r < 0)
+		return r;
+	return val;
+}
+
+static inline int bd71837_reg_write(struct bd71837 *bd71837, u8 reg,
+		unsigned int val)
+{
+	return regmap_write(bd71837->regmap, reg, val);
+}
+
+static inline int bd71837_set_bits(struct bd71837 *bd71837, u8 reg,	u8 mask)
+{
+	return regmap_update_bits(bd71837->regmap, reg, mask, mask);
+}
+
+static inline int bd71837_clear_bits(struct bd71837 *bd71837, u8 reg,
+		u8 mask)
+{
+	return regmap_update_bits(bd71837->regmap, reg, mask, 0);
+}
+
+static inline int bd71837_update_bits(struct bd71837 *bd71837, u8 reg,
+					   u8 mask, u8 val)
+{
+	return regmap_update_bits(bd71837->regmap, reg, mask, val);
+}
+
+#endif /* __LINUX_MFD_BD71837_H__ */
-- 
2.14.3

^ permalink raw reply related

* [PATCH v2 0/6] mfd/regulator/clk: bd71837: ROHM BD71837 PMIC driver
From: Matti Vaittinen @ 2018-05-28  9:00 UTC (permalink / raw)
  To: mturquette, sboyd, robh+dt, mark.rutland, lee.jones, lgirdwood,
	broonie, mazziesaccount
  Cc: linux-clk, devicetree, linux-kernel, mikko.mutanen,
	heikki.haikola

Patch series adding support for ROHM BD71837 PMIC.

BD71837 is a programmable Power Management IC for powering single-core,
dual-core, and quad-core SoC’s such as NXP-i.MX 8M. It is optimized for
low BOM cost and compact solution footprint. It integrates 8 buck
regulators and 7 LDO’s to provide all the power rails required by the
SoC and the commonly used peripherals.

The driver aims to not limit the usage of PMIC. Thus the buck and LDO
naming is generic and not tied to any specific purposes. However there
is following limitations which make it mostly suitable for use cases
where the processor where PMIC driver is running is powered by the PMIC:

- The PMIC is not re-initialized if it resets. PMIC may reset as a
  result of voltage monitoring (over/under voltage) or due to reset
  request. Driver is only initializing PMIC at probe. This is not
  problem as long as processor controlling PMIC is powered by PMIC.

- The PMIC internal state machine is ignored by driver. Driver assumes
  the PMIC is wired so that it is always in "run" state when controlled
  by the driver.

Changelog v2
Based on feedback from Mark Brown
- Squashed code and buildfile changes to same patch
- Fixed some styling issues
- Changed SPDX comments to CPP style
- Error out if voltage is changed when regulator is enabled instead of
  Disabling the regulator for duration of change
- Use devm_regulator_register
- Remove compatible usage from regulators - use parent dev for config
- Add a note about using regulator-boot-on for BUCK6 and 7
- fixed warnings from kbuild test robot

patch 1: 
        MFD driver and definitions bringing interrupt support and
        enabling clk and regulator subsystems.
Patches 2, 3 and 4:
        device tree binding documents.
Patch 5:
        clock subsystem and support for gated clock.
Patch 6:
        regulator driver supporting 8 bucks and 7 LDOs.

This patch series is based on for-mfd-next

---

Matti Vaittinen (6):
  mfd: bd71837: mfd driver for ROHM BD71837 PMIC
  mfd: bd71837: Devicetree bindings for ROHM BD71837 PMIC
  regulator: bd71837: Devicetree bindings for BD71837 regulators
  clk: bd71837: Devicetree bindings for ROHM BD71837 PMIC
  clk: bd71837: Add driver for BD71837 PMIC clock
  regulator: bd71837: BD71837 PMIC regulator driver

 .../bindings/clock/rohm,bd71837-clock.txt          |  37 ++
 .../devicetree/bindings/mfd/rohm,bd71837-pmic.txt  |  52 ++
 .../bindings/regulator/rohm,bd71837-regulator.txt  | 126 ++++
 drivers/clk/Kconfig                                |   9 +
 drivers/clk/Makefile                               |   1 +
 drivers/clk/clk-bd71837.c                          | 154 +++++
 drivers/mfd/Kconfig                                |  13 +
 drivers/mfd/Makefile                               |   1 +
 drivers/mfd/bd71837.c                              | 238 ++++++++
 drivers/regulator/Kconfig                          |  11 +
 drivers/regulator/Makefile                         |   1 +
 drivers/regulator/bd71837-regulator.c              | 678 +++++++++++++++++++++
 include/linux/mfd/bd71837.h                        | 316 ++++++++++
 13 files changed, 1637 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/rohm,bd71837-clock.txt
 create mode 100644 Documentation/devicetree/bindings/mfd/rohm,bd71837-pmic.txt
 create mode 100644 Documentation/devicetree/bindings/regulator/rohm,bd71837-regulator.txt
 create mode 100644 drivers/clk/clk-bd71837.c
 create mode 100644 drivers/mfd/bd71837.c
 create mode 100644 drivers/regulator/bd71837-regulator.c
 create mode 100644 include/linux/mfd/bd71837.h

-- 
2.14.3

^ permalink raw reply

* Re: [PATCH 6/9] ARM: dts: wheat: Drop MTD partitioning from DT
From: Geert Uytterhoeven @ 2018-05-28  8:54 UTC (permalink / raw)
  To: Simon Horman
  Cc: open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	Geert Uytterhoeven, Wolfram Sang, Richard Weinberger,
	Boris Brezillon, Linux-Renesas, Marek Vasut, Laurent Pinchart,
	Linux ARM, Marek Vasut
In-Reply-To: <20180528084135.q5xng5eaypprsypr@verge.net.au>

Hi Simon,

On Mon, May 28, 2018 at 10:41 AM, Simon Horman <horms@verge.net.au> wrote:
> On Thu, May 24, 2018 at 04:52:59PM +0200, Marek Vasut wrote:
>> On 05/23/2018 08:25 AM, Geert Uytterhoeven wrote:
>> > On Wed, May 23, 2018 at 12:01 AM, Marek Vasut <marek.vasut@gmail.com> wrote:
>> >> On 05/22/2018 04:43 PM, Geert Uytterhoeven wrote:
>> >>> On Tue, May 22, 2018 at 2:02 PM, Marek Vasut <marek.vasut@gmail.com> wrote:
>> >>>> Drop the MTD partitioning from DT, since it does not describe HW
>> >>>> and to give way to a more flexible kernel command line partition
>> >>>> passing.
>> >>>>
>> >>>> To retain the original partitioning, assure you have enabled
>> >>>> CONFIG_MTD_CMDLINE_PARTS in your kernel config and add the
>> >>>> following to your kernel command line:
>> >>>>
>> >>>>   mtdparts=spi0.0:256k@0(loader),4096k(user),-(flash)
>> >>>
>> >>> I think the "@0" can be dropped, as it's optional?
>> >>> 4m?
>> >>
>> >> My take on this is that the loader is actually at offset 0x0 of the MTD
>> >> device and we explicitly state that in the mtdparts to anchor the first
>> >> partition within the MTD device and all the other partitions are at
>> >> offset +(sum of the sizes of all partitions listed before the current
>> >> one) relative to that first partition.
>> >
>> > Where is this explicitly states for the first partition?
>> >
>> >> Removing the @0 feels fragile at best and it seems to depend on the
>> >> current behavior of the code.
>> >
>> > Better, it also depends on the documented behavior:
>> >
>> > Documentation/admin-guide/kernel-parameters.txt refers to
>> > drivers/mtd/cmdlinepart.c, which states:
>> >
>> >  * <offset>  := standard linux memsize
>> >  *              if omitted the part will immediately follow the previous part
>> >  *              or 0 if the first part
>> >
>> > None of the examples listed there or under the MTD_CMDLINE_PARTS Kconfig
>> > help text, or in a defconfig bundled with the kernel, use @0 for the first
>> > partition.
>>
>> I think this is exceptionally fragile and dangerous to depend on this,
>> but so be it.
>
> Could you respin with this change?
>
> I would also like to ask for another change, in light of recent
> feedback from Olof Johansson ("Re: [GIT PULL] Renesas ARM64 Based SoC DT
> Updates for v4.18").
>
> Please consolidate the dts patches into a single patch?

I think it's better to keep them split, as each commit description mentions
what needs to be passed on the kernel command line for the corresponding
board.

Combining it in a single patch makes it much harder to extract this information.
Unless you're fine with a list:

   koelsch: ...
   wheat: mtdparts=spi0.0:256k@0(loader),4096k(user),-(flash)

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

* Re: [PATCH 06/15] arm: dts: sun: Add missing cooling device properties for CPUs
From: Maxime Ripard @ 2018-05-28  8:44 UTC (permalink / raw)
  To: Viresh Kumar
  Cc: arm, Rob Herring, Mark Rutland, Chen-Yu Tsai, Vincent Guittot,
	ionela.voinescu, Daniel Lezcano, chris.redpath, devicetree,
	linux-arm-kernel, linux-kernel
In-Reply-To: <eded393f4b508a1f377f9af6859a3b82a6787e1c.1527244201.git.viresh.kumar@linaro.org>

[-- Attachment #1: Type: text/plain, Size: 1020 bytes --]

Hi,

On Fri, May 25, 2018 at 04:01:52PM +0530, Viresh Kumar wrote:
> The cooling device properties, like "#cooling-cells" and
> "dynamic-power-coefficient", should either be present for all the CPUs
> of a cluster or none. If these are present only for a subset of CPUs of
> a cluster then things will start falling apart as soon as the CPUs are
> brought online in a different order. For example, this will happen
> because the operating system looks for such properties in the CPU node
> it is trying to bring up, so that it can register a cooling device.
> 
> Add such missing properties.
> 
> Fix other missing properties (clocks, OPP, clock latency) as well to
> make it all work.
> 
> Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>

The prefix should be sunxi and not sun, but it looks good to me
otherwise.

Let me know what your preferred merge method is.

Maxime

-- 
Maxime Ripard, Bootlin (formerly Free Electrons)
Embedded Linux and Kernel engineering
https://bootlin.com

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply

* Re: [PATCH 6/9] ARM: dts: wheat: Drop MTD partitioning from DT
From: Simon Horman @ 2018-05-28  8:41 UTC (permalink / raw)
  To: Marek Vasut
  Cc: open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	Geert Uytterhoeven, Wolfram Sang, Richard Weinberger,
	Linux-Renesas, Boris Brezillon, Geert Uytterhoeven,
	Laurent Pinchart, Linux ARM, Marek Vasut
In-Reply-To: <7e1563c3-3e13-235b-3071-c3936502530f@gmail.com>

On Thu, May 24, 2018 at 04:52:59PM +0200, Marek Vasut wrote:
> On 05/23/2018 08:25 AM, Geert Uytterhoeven wrote:
> > Hi Marek,
> > 
> > On Wed, May 23, 2018 at 12:01 AM, Marek Vasut <marek.vasut@gmail.com> wrote:
> >> On 05/22/2018 04:43 PM, Geert Uytterhoeven wrote:
> >>> On Tue, May 22, 2018 at 2:02 PM, Marek Vasut <marek.vasut@gmail.com> wrote:
> >>>> Drop the MTD partitioning from DT, since it does not describe HW
> >>>> and to give way to a more flexible kernel command line partition
> >>>> passing.
> >>>>
> >>>> To retain the original partitioning, assure you have enabled
> >>>> CONFIG_MTD_CMDLINE_PARTS in your kernel config and add the
> >>>> following to your kernel command line:
> >>>>
> >>>>   mtdparts=spi0.0:256k@0(loader),4096k(user),-(flash)
> >>>
> >>> I think the "@0" can be dropped, as it's optional?
> >>> 4m?
> >>
> >> My take on this is that the loader is actually at offset 0x0 of the MTD
> >> device and we explicitly state that in the mtdparts to anchor the first
> >> partition within the MTD device and all the other partitions are at
> >> offset +(sum of the sizes of all partitions listed before the current
> >> one) relative to that first partition.
> > 
> > Where is this explicitly states for the first partition?
> > 
> >> Removing the @0 feels fragile at best and it seems to depend on the
> >> current behavior of the code.
> > 
> > Better, it also depends on the documented behavior:
> > 
> > Documentation/admin-guide/kernel-parameters.txt refers to
> > drivers/mtd/cmdlinepart.c, which states:
> > 
> >  * <offset>  := standard linux memsize
> >  *              if omitted the part will immediately follow the previous part
> >  *              or 0 if the first part
> > 
> > None of the examples listed there or under the MTD_CMDLINE_PARTS Kconfig
> > help text, or in a defconfig bundled with the kernel, use @0 for the first
> > partition.
> 
> I think this is exceptionally fragile and dangerous to depend on this,
> but so be it.

Could you respin with this change?

I would also like to ask for another change, in light of recent
feedback from Olof Johansson ("Re: [GIT PULL] Renesas ARM64 Based SoC DT
Updates for v4.18").

Please consolidate the dts patches into a single patch?

I have applied the defconfig patch, so there is no need to repost that one.

^ permalink raw reply

* Re: [PATCH 1/9] ARM: shmobile: defconfig: Enable MTD command line partition parsing
From: Simon Horman @ 2018-05-28  8:40 UTC (permalink / raw)
  To: Marek Vasut
  Cc: devicetree, Geert Uytterhoeven, Wolfram Sang, linux-renesas-soc,
	Laurent Pinchart, linux-arm-kernel, Marek Vasut
In-Reply-To: <20180522120257.13232-1-marek.vasut+renesas@gmail.com>

On Tue, May 22, 2018 at 02:02:49PM +0200, Marek Vasut wrote:
> In preparation for removing MTD partitioning from the DTs and moving
> it over to kernel command line partition parsing, enable the support
> for kernel command line MTD partition parsing.
> 
> The argument for not having MTD partitions in the DT is the same as
> for not having hard drive partitions in DT, neither describes the
> hardware itself, so it shouldn't be in the DT. Furthermore, kernel
> command line MTD partition passing allows greater flexibility in
> case someone decided to repartition the flash, which is well in the
> realm of possibility with these systems.
> 
> Signed-off-by: Marek Vasut <marek.vasut+renesas@gmail.com>

Thanks, applied.

^ permalink raw reply

* Re: [PATCH v4 5/6] spi: at91-usart: add driver for at91-usart as spi
From: Andy Shevchenko @ 2018-05-28  8:21 UTC (permalink / raw)
  To: Radu Pirea
  Cc: Mark Brown, Nicolas Ferre, alexandre.belloni, Lee Jones,
	Richard Genoud, Rob Herring, Mark Rutland, Greg Kroah-Hartman,
	linux-spi, linux-arm Mailing List, Linux Kernel Mailing List,
	devicetree, open list:SERIAL DRIVERS
In-Reply-To: <20180525171941.26766-6-radu.pirea@microchip.com>

On Fri, May 25, 2018 at 8:19 PM, Radu Pirea <radu.pirea@microchip.com> wrote:
> This is the driver for at91-usart in spi mode. The USART IP can be configured
> to work in many modes and one of them is SPI.
>
> The driver was tested on sama5d3-xplained and sama5d4-xplained boards with
> enc28j60 ethernet controller as slave.

> +#include <linux/of_gpio.h>

What is the use of it?

> +#define US_INIT                        (US_MR_SPI_MASTER | US_MR_CHRL | US_MR_CLKO | \
> +                               US_MR_WRDBT)

Don't split lines like this, it's hard to read.

#define FOO \
 (BAR1 | BAR2)

I think I already told this to someone recently, maybe to you.

> +/* Register access macros */
> +#define spi_readl(port, reg) \
> +       readl_relaxed((port)->regs + US_##reg)
> +#define spi_writel(port, reg, value) \
> +       writel_relaxed((value), (port)->regs + US_##reg)
> +
> +#define spi_readb(port, reg) \
> +       readb_relaxed((port)->regs + US_##reg)
> +#define spi_writeb(port, reg, value) \
> +       writeb_relaxed((value), (port)->regs + US_##reg)

Names are too generic. You better to use the same prefix as for the
rest, i.e. at91_spi_

> +       /*used in interrupt to protect data reading*/

Comment style.

You need to read some existing code, perhaps, to see how it's done.

> +static inline void at91_usart_spi_tx(struct at91_usart_spi *aus)
> +{
> +       unsigned int len = aus->current_transfer->len;
> +       unsigned int remaining = aus->current_tx_remaining_bytes;
> +       const u8  *tx_buf = aus->current_transfer->tx_buf;
> +

> +       if (remaining)
> +               if (at91_usart_spi_tx_ready(aus)) {

if (x) {
 if (y) {
...
 }
}

is equivalent to if (x && y) {}.

Though, considering your intention here, I would rather go with better
pattern, i.e.

if (!remaining)
 return;

> +                       spi_writeb(aus, THR, tx_buf[len - remaining]);
> +                       aus->current_tx_remaining_bytes--;
> +               }
> +}
> +
> +static inline void at91_usart_spi_rx(struct at91_usart_spi *aus)
> +{

> +       if (remaining) {
> +               rx_buf[len - remaining] = spi_readb(aus, RHR);
> +               aus->current_rx_remaining_bytes--;
> +       }

Ditto.

> +}


> +static int at91_usart_gpio_setup(struct platform_device *pdev)
> +{

> +       struct device_node      *np = pdev->dev.parent->of_node;

Your driver is not OF specific as far as I can see. Drop all these
device_node stuff and change API calls respectively.

> +       int                     i;

> +       int                     ret = 0;
> +       int                     nb = 0;

What happened to indentation?

Redundnant assignment for both.

> +       if (!np)
> +               return -EINVAL;
> +
> +       nb = of_gpio_named_count(np, "cs-gpios");
> +       for (i = 0; i < nb; i++) {
> +               int cs_gpio = of_get_named_gpio(np, "cs-gpios", i);
> +
> +               if (cs_gpio < 0)
> +                       return cs_gpio;
> +
> +               if (gpio_is_valid(cs_gpio)) {
> +                       ret = devm_gpio_request_one(&pdev->dev, cs_gpio,
> +                                                   GPIOF_DIR_OUT,
> +                                                   dev_name(&pdev->dev));
> +                       if (ret)
> +                               return ret;
> +               }
> +       }
> +
> +       return 0;
> +}
> +
> +static int at91_usart_spi_probe(struct platform_device *pdev)
> +{

> +       regs = platform_get_resource(to_platform_device(pdev->dev.parent),
> +                                    IORESOURCE_MEM, 0);
> +       if (!regs)
> +               return -EINVAL;

This looks weird. Supply resource to _this_ device in your MFD code.

> +       dev_info(&pdev->dev,
> +                "Atmel USART SPI Controller version 0x%x at 0x%08lx (irq %d)\n",
> +                spi_readl(aus, VERSION),
> +                (unsigned long)regs->start, irq);

I think I already told you, don't use explicit casting when print.
If it wasn't you, do you homework then. But above is no go.

> +       return 0;

> +static struct platform_driver at91_usart_spi_driver = {
> +       .driver = {
> +               .name = "at91_usart_spi",

> +               .of_match_table = of_match_ptr(at91_usart_spi_dt_ids),

Drop of_match_ptr(). It's not needed.

> +       },
> +       .probe = at91_usart_spi_probe,

> +       .remove = at91_usart_spi_remove, };

Already told ya, split lines correctly.

-- 
With Best Regards,
Andy Shevchenko

^ permalink raw reply

* Re: [PATCH 09/11] misc: throttler: Add core support for non-thermal throttling
From: Greg Kroah-Hartman @ 2018-05-28  8:08 UTC (permalink / raw)
  To: Matthias Kaehlcke
  Cc: MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Arnd Bergmann,
	Rob Herring, Mark Rutland, linux-pm, devicetree, linux-kernel,
	Brian Norris, Douglas Anderson
In-Reply-To: <20180525203043.249193-10-mka@chromium.org>

On Fri, May 25, 2018 at 01:30:41PM -0700, Matthias Kaehlcke wrote:
> diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
> index 20be70c3f118..01a1714dd2ad 100644
> --- a/drivers/misc/Makefile
> +++ b/drivers/misc/Makefile
> @@ -57,3 +57,4 @@ obj-$(CONFIG_ASPEED_LPC_SNOOP)	+= aspeed-lpc-snoop.o
>  obj-$(CONFIG_PCI_ENDPOINT_TEST)	+= pci_endpoint_test.o
>  obj-$(CONFIG_OCXL)		+= ocxl/
>  obj-$(CONFIG_MISC_RTSX)		+= cardreader/
> +obj-y				+= throttler/

Shouldn't you depend on a Kconfig option to traverse into this
directory?

> diff --git a/drivers/misc/throttler/Kconfig b/drivers/misc/throttler/Kconfig
> new file mode 100644
> index 000000000000..ef8388f6bc0a
> --- /dev/null
> +++ b/drivers/misc/throttler/Kconfig
> @@ -0,0 +1,13 @@
> +menuconfig THROTTLER
> +	bool "Throttler support"
> +	default n

the default is always 'n' no need to say it again here :)

> +	depends on OF
> +	select CPU_FREQ
> +	select PM_DEVFREQ
> +	help
> +	  This option enables core support for non-thermal throttling of CPUs
> +	  and devfreq devices.
> +
> +	  Note that you also need a event monitor module usually called
> +	  *_throttler.
> +
> diff --git a/drivers/misc/throttler/Makefile b/drivers/misc/throttler/Makefile
> new file mode 100644
> index 000000000000..c8d920cee315
> --- /dev/null
> +++ b/drivers/misc/throttler/Makefile
> @@ -0,0 +1 @@
> +obj-$(CONFIG_THROTTLER)		+= core.o
> diff --git a/drivers/misc/throttler/core.c b/drivers/misc/throttler/core.c
> new file mode 100644
> index 000000000000..c058d03212b8
> --- /dev/null
> +++ b/drivers/misc/throttler/core.c
> @@ -0,0 +1,373 @@
> +/*
> + * Core code for non-thermal throttling
> + *
> + * Copyright (C) 2018 Google, Inc.
> + *
> + * This software is licensed under the terms of the GNU General Public
> + * License version 2, as published by the Free Software Foundation, and
> + * may be copied, distributed, and modified under those terms.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + */

Please just use a single SPDX line, like checkpatch.pl would have warned
you about.  No need for the full verbous license boiler-plate text here
at all.

thanks,

greg k-h

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox