Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v1 3/3] reset: zx2967: add reset controller driver for ZTE's zx2967 family
From: Philipp Zabel @ 2017-01-16  9:58 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1484377530-30635-3-git-send-email-baoyou.xie@linaro.org>

On Sat, 2017-01-14 at 15:05 +0800, Baoyou Xie wrote:
> This patch adds reset controller driver for ZTE's zx2967 family.
> 
> Signed-off-by: Baoyou Xie <baoyou.xie@linaro.org>
> ---
>  drivers/reset/Kconfig        |   6 ++
>  drivers/reset/Makefile       |   1 +
>  drivers/reset/reset-zx2967.c | 136 +++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 143 insertions(+)
>  create mode 100644 drivers/reset/reset-zx2967.c
> 
> diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
> index 172dc96..972d077 100644
> --- a/drivers/reset/Kconfig
> +++ b/drivers/reset/Kconfig
> @@ -92,6 +92,12 @@ config RESET_ZYNQ
>  	help
>  	  This enables the reset controller driver for Xilinx Zynq SoCs.
>  
> +config RESET_ZX2967
> +	bool "ZX2967 Reset Driver"
> +	depends on ARCH_ZX || COMPILE_TEST
> +	help
> +	  This enables the reset controller driver for ZTE zx2967 family.
> +
>  source "drivers/reset/sti/Kconfig"
>  source "drivers/reset/hisilicon/Kconfig"
>  source "drivers/reset/tegra/Kconfig"
> diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile
> index 13b346e..807b77b 100644
> --- a/drivers/reset/Makefile
> +++ b/drivers/reset/Makefile
> @@ -14,3 +14,4 @@ obj-$(CONFIG_RESET_SUNXI) += reset-sunxi.o
>  obj-$(CONFIG_TI_SYSCON_RESET) += reset-ti-syscon.o
>  obj-$(CONFIG_RESET_UNIPHIER) += reset-uniphier.o
>  obj-$(CONFIG_RESET_ZYNQ) += reset-zynq.o
> +obj-$(CONFIG_RESET_ZX2967) += reset-zx2967.o
> diff --git a/drivers/reset/reset-zx2967.c b/drivers/reset/reset-zx2967.c
> new file mode 100644
> index 0000000..63f9c41
> --- /dev/null
> +++ b/drivers/reset/reset-zx2967.c
> @@ -0,0 +1,136 @@
> +/*
> + * ZTE's zx2967 family thermal sensor driver

This description is incorrect.

> + *
> + * Copyright (C) 2017 ZTE Ltd.
> + *
> + * Author: Baoyou Xie <baoyou.xie@linaro.org>
> + *
> + * License terms: GNU General Public License (GPL) version 2
> + */
> +
> +#include <linux/module.h>
> +#include <linux/of_address.h>
> +#include <linux/platform_device.h>
> +#include <linux/reset-controller.h>
> +
> +struct zx2967_reset {
> +	void __iomem			*reg_base;
> +	spinlock_t			lock;
> +	struct reset_controller_dev	rcdev;
> +};
> +
> +static int zx2967_reset_assert(struct reset_controller_dev *rcdev,
> +			   unsigned long id)
> +{
> +	struct zx2967_reset *reset = NULL;
> +	int bank = id / 32;
> +	int offset = id % 32;
> +	unsigned int reg;
> +	unsigned long flags;
> +
> +	reset = container_of(rcdev, struct zx2967_reset, rcdev);
> +
> +	spin_lock_irqsave(&reset->lock, flags);
> +
> +	reg = readl(reset->reg_base + (bank * 4));
> +	writel(reg & ~BIT(offset), reset->reg_base + (bank * 4));
> +	reg = readl(reset->reg_base + (bank * 4));
> +
> +	spin_unlock_irqrestore(&reset->lock, flags);
> +
> +	return 0;
> +}
> +
> +static int zx2967_reset_deassert(struct reset_controller_dev *rcdev,
> +			     unsigned long id)
> +{
> +	struct zx2967_reset *reset = NULL;
> +	int bank = id / 32;
> +	int offset = id % 32;
> +	unsigned int reg;
> +	unsigned long flags;
> +
> +	reset = container_of(rcdev, struct zx2967_reset, rcdev);
> +
> +	spin_lock_irqsave(&reset->lock, flags);
> +
> +	reg = readl(reset->reg_base + (bank * 4));
> +	writel(reg | BIT(offset), reset->reg_base + (bank * 4));
> +	reg = readl(reset->reg_base + (bank * 4));
> +
> +	spin_unlock_irqrestore(&reset->lock, flags);
> +
> +	return 0;
> +}
> +
> +static struct reset_control_ops zx2967_reset_ops = {
> +	.assert		= zx2967_reset_assert,
> +	.deassert	= zx2967_reset_deassert,
> +};
> +
> +static int zx2967_reset_probe(struct platform_device *pdev)
> +{
> +	struct zx2967_reset *reset;
> +	struct resource *res;
> +
> +	reset = devm_kzalloc(&pdev->dev, sizeof(*reset), GFP_KERNEL);
> +	if (!reset)
> +		return -ENOMEM;
> +
> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	reset->reg_base = devm_ioremap_resource(&pdev->dev, res);
> +	if (IS_ERR(reset->reg_base))
> +		return PTR_ERR(reset->reg_base);
> +
> +	spin_lock_init(&reset->lock);
> +
> +	reset->rcdev.owner = THIS_MODULE;
> +	reset->rcdev.nr_resets = resource_size(res) * 8;
> +	reset->rcdev.ops = &zx2967_reset_ops;
> +	reset->rcdev.of_node = pdev->dev.of_node;
> +
> +	dev_info(&pdev->dev, "reset controller cnt:%d",
> +		  reset->rcdev.nr_resets);
> +
> +	return reset_controller_register(&reset->rcdev);

As Shawn suggested, use the devm_ variant here. It allows you to drop
the remove function below.

> +}
> +
> +static int zx2967_reset_remove(struct platform_device *pdev)
> +{
> +	struct zx2967_reset *reset = platform_get_drvdata(pdev);
> +
> +	reset_controller_unregister(&reset->rcdev);
> +
> +	return 0;
> +}
> +
> +static const struct of_device_id zx2967_reset_dt_ids[] = {
> +	 { .compatible = "zte,zx296718-reset", },
> +	 {},
> +};
> +MODULE_DEVICE_TABLE(of, zx2967_reset_dt_ids);
> +
> +static struct platform_driver zx2967_reset_driver = {
> +	.probe	= zx2967_reset_probe,
> +	.remove	= zx2967_reset_remove,
> +	.driver = {
> +		.name		= "zx2967-reset",
> +		.of_match_table	= zx2967_reset_dt_ids,
> +	},
> +};
> +
> +static int __init zx2967_reset_init(void)
> +{
> +	return platform_driver_register(&zx2967_reset_driver);
> +}
> +arch_initcall(zx2967_reset_init);
> +
> +static void __exit zx2967_reset_exit(void)
> +{
> +	platform_driver_unregister(&zx2967_reset_driver);
> +}
> +module_exit(zx2967_reset_exit);
> +
> +MODULE_AUTHOR("Baoyou Xie <baoyou.xie@linaro.org>");
> +MODULE_DESCRIPTION("ZTE zx2967 Reset Controller Driver");
> +MODULE_LICENSE("GPL");

regards
Philipp

^ permalink raw reply

* [PATCH 09/10] ARM: dts: da850: add the SATA node
From: Bartosz Golaszewski @ 2017-01-16 10:03 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <4eb4ada8-1d2d-2fa1-7961-21da56ea0082@lechnology.com>

2017-01-13 20:36 GMT+01:00 David Lechner <david@lechnology.com>:
> On 01/13/2017 06:38 AM, Bartosz Golaszewski wrote:
>>
>> Add the SATA node to the da850 device tree.
>>
>> Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
>> ---
>>  arch/arm/boot/dts/da850.dtsi | 6 ++++++
>>  1 file changed, 6 insertions(+)
>>
>> diff --git a/arch/arm/boot/dts/da850.dtsi b/arch/arm/boot/dts/da850.dtsi
>> index 1f6a47d..f5086b1 100644
>> --- a/arch/arm/boot/dts/da850.dtsi
>> +++ b/arch/arm/boot/dts/da850.dtsi
>> @@ -427,6 +427,12 @@
>>                         phy-names = "usb-phy";
>>                         status = "disabled";
>>                 };
>> +               sata: ahci at 0x218000 {
>
>
> 0x needs to be omitted.
>
>         sata: ahci at 218000 {
>

Will fix in v2.

Thanks,
Bartosz Golaszewski

^ permalink raw reply

* [PATCH v2 0/11] Rockchip dw-mipi-dsi driver
From: Chris Zhong @ 2017-01-16 10:08 UTC (permalink / raw)
  To: linux-arm-kernel

Hi all

This patch serial is for RK3399 MIPI DSI. The MIPI DSI controller of
RK3399 is almost the same as RK3288, except a little bit of difference
in phy clock controlling and port id selection register.

And these patches also fixes some driver bugs; add the power domain
support.

they have been tested on rk3399 and rk3288 evb board.


Chris Zhong (7):
  dt-bindings: add rk3399 support for dw-mipi-rockchip
  drm/rockchip/dsi: dw-mipi: support RK3399 mipi dsi
  drm/rockchip/dsi: remove mode_valid function
  dt-bindings: add power domain node for dw-mipi-rockchip
  drm/rockchip/dsi: add dw-mipi power domain support
  drm/rockchip/dsi: fix phy clk lane stop state timeout
  drm/rockchip/dsi: fix insufficient bandwidth of some panel

Mark Yao (2):
  drm/rockchip/dsi: return probe defer if attach panel failed
  drm/rockchip/dsi: fix mipi display can't found at init time

xubilv (2):
  drm/rockchip/dsi: fix the issue can not send commands
  drm/rockchip/dsi: decrease the value of Ths-prepare

 .../display/rockchip/dw_mipi_dsi_rockchip.txt      |   7 +-
 drivers/gpu/drm/rockchip/dw-mipi-dsi.c             | 254 +++++++++++++--------
 2 files changed, 163 insertions(+), 98 deletions(-)

-- 
2.6.3

^ permalink raw reply

* [PATCH v2 01/11] dt-bindings: add rk3399 support for dw-mipi-rockchip
From: Chris Zhong @ 2017-01-16 10:08 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1484561311-494-1-git-send-email-zyw@rock-chips.com>

The dw-mipi-dsi of rk3399 is almost the same as rk3288, the rk3399 has
additional phy config clock.

Signed-off-by: Chris Zhong <zyw@rock-chips.com>
---

 .../devicetree/bindings/display/rockchip/dw_mipi_dsi_rockchip.txt     | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/display/rockchip/dw_mipi_dsi_rockchip.txt b/Documentation/devicetree/bindings/display/rockchip/dw_mipi_dsi_rockchip.txt
index 1753f0c..0f82568 100644
--- a/Documentation/devicetree/bindings/display/rockchip/dw_mipi_dsi_rockchip.txt
+++ b/Documentation/devicetree/bindings/display/rockchip/dw_mipi_dsi_rockchip.txt
@@ -5,10 +5,12 @@ Required properties:
 - #address-cells: Should be <1>.
 - #size-cells: Should be <0>.
 - compatible: "rockchip,rk3288-mipi-dsi", "snps,dw-mipi-dsi".
+	      "rockchip,rk3399-mipi-dsi", "snps,dw-mipi-dsi".
 - reg: Represent the physical address range of the controller.
 - interrupts: Represent the controller's interrupt to the CPU(s).
 - clocks, clock-names: Phandles to the controller's pll reference
-  clock(ref) and APB clock(pclk), as described in [1].
+  clock(ref) and APB clock(pclk). For RK3399, a phy config clock
+  (phy_cfg) is additional required. As described in [1].
 - rockchip,grf: this soc should set GRF regs to mux vopl/vopb.
 - ports: contain a port node with endpoint definitions as defined in [2].
   For vopb,set the reg = <0> and set the reg = <1> for vopl.
-- 
2.6.3

^ permalink raw reply related

* [PATCH v2 02/11] drm/rockchip/dsi: dw-mipi: support RK3399 mipi dsi
From: Chris Zhong @ 2017-01-16 10:08 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1484561311-494-1-git-send-email-zyw@rock-chips.com>

The vopb/vopl switch register of RK3399 mipi is different from RK3288,
the default setting for mipi dsi mode is different too, so add a
of_device_id structure to distinguish them, and make sure set the
correct mode before mipi phy init.

Signed-off-by: Chris Zhong <zyw@rock-chips.com>
Signed-off-by: Mark Yao <mark.yao@rock-chips.com>
---

 drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 101 ++++++++++++++++++++++++---------
 1 file changed, 74 insertions(+), 27 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
index d9aa382..04fd595 100644
--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
@@ -28,9 +28,17 @@
 
 #define DRIVER_NAME    "dw-mipi-dsi"
 
-#define GRF_SOC_CON6                    0x025c
-#define DSI0_SEL_VOP_LIT                (1 << 6)
-#define DSI1_SEL_VOP_LIT                (1 << 9)
+#define RK3288_GRF_SOC_CON6		0x025c
+#define RK3288_DSI0_SEL_VOP_LIT		BIT(6)
+#define RK3288_DSI1_SEL_VOP_LIT		BIT(9)
+
+#define RK3399_GRF_SOC_CON19		0x6250
+#define RK3399_DSI0_SEL_VOP_LIT		BIT(0)
+#define RK3399_DSI1_SEL_VOP_LIT		BIT(4)
+
+/* disable turnrequest, turndisable, forcetxstopmode, forcerxmode */
+#define RK3399_GRF_SOC_CON22		0x6258
+#define RK3399_GRF_DSI_MODE		0xffff0000
 
 #define DSI_VERSION			0x00
 #define DSI_PWR_UP			0x04
@@ -147,7 +155,6 @@
 #define LPRX_TO_CNT(p)			((p) & 0xffff)
 
 #define DSI_BTA_TO_CNT			0x8c
-
 #define DSI_LPCLK_CTRL			0x94
 #define AUTO_CLKLANE_CTRL		BIT(1)
 #define PHY_TXREQUESTCLKHS		BIT(0)
@@ -213,11 +220,11 @@
 
 #define HSFREQRANGE_SEL(val)	(((val) & 0x3f) << 1)
 
-#define INPUT_DIVIDER(val)	((val - 1) & 0x7f)
+#define INPUT_DIVIDER(val)	(((val) - 1) & 0x7f)
 #define LOW_PROGRAM_EN		0
 #define HIGH_PROGRAM_EN		BIT(7)
-#define LOOP_DIV_LOW_SEL(val)	((val - 1) & 0x1f)
-#define LOOP_DIV_HIGH_SEL(val)	(((val - 1) >> 5) & 0x1f)
+#define LOOP_DIV_LOW_SEL(val)	(((val) - 1) & 0x1f)
+#define LOOP_DIV_HIGH_SEL(val)	((((val) - 1) >> 5) & 0x1f)
 #define PLL_LOOP_DIV_EN		BIT(5)
 #define PLL_INPUT_DIV_EN	BIT(4)
 
@@ -263,6 +270,11 @@ enum {
 };
 
 struct dw_mipi_dsi_plat_data {
+	u32 dsi0_en_bit;
+	u32 dsi1_en_bit;
+	u32 grf_switch_reg;
+	u32 grf_dsi0_mode;
+	u32 grf_dsi0_mode_reg;
 	unsigned int max_data_lanes;
 	enum drm_mode_status (*mode_valid)(struct drm_connector *connector,
 					   struct drm_display_mode *mode);
@@ -279,6 +291,7 @@ struct dw_mipi_dsi {
 
 	struct clk *pllref_clk;
 	struct clk *pclk;
+	struct clk *phy_cfg_clk;
 
 	unsigned int lane_mbps; /* per lane */
 	u32 channel;
@@ -353,6 +366,7 @@ static inline struct dw_mipi_dsi *encoder_to_dsi(struct drm_encoder *encoder)
 {
 	return container_of(encoder, struct dw_mipi_dsi, encoder);
 }
+
 static inline void dsi_write(struct dw_mipi_dsi *dsi, u32 reg, u32 val)
 {
 	writel(val, dsi->base + reg);
@@ -364,7 +378,7 @@ static inline u32 dsi_read(struct dw_mipi_dsi *dsi, u32 reg)
 }
 
 static void dw_mipi_dsi_phy_write(struct dw_mipi_dsi *dsi, u8 test_code,
-				 u8 test_data)
+				  u8 test_data)
 {
 	/*
 	 * With the falling edge on TESTCLK, the TESTDIN[7:0] signal content
@@ -400,6 +414,14 @@ static int dw_mipi_dsi_phy_init(struct dw_mipi_dsi *dsi)
 
 	dsi_write(dsi, DSI_PWR_UP, POWERUP);
 
+	if (!IS_ERR(dsi->phy_cfg_clk)) {
+		ret = clk_prepare_enable(dsi->phy_cfg_clk);
+		if (ret) {
+			dev_err(dsi->dev, "Failed to enable phy_cfg_clk\n");
+			return ret;
+		}
+	}
+
 	dw_mipi_dsi_phy_write(dsi, 0x10, BYPASS_VCO_RANGE |
 					 VCO_RANGE_CON_SEL(vco) |
 					 VCO_IN_CAP_CON_LOW |
@@ -439,22 +461,23 @@ static int dw_mipi_dsi_phy_init(struct dw_mipi_dsi *dsi)
 	dsi_write(dsi, DSI_PHY_RSTZ, PHY_ENFORCEPLL | PHY_ENABLECLK |
 				     PHY_UNRSTZ | PHY_UNSHUTDOWNZ);
 
-
 	ret = readx_poll_timeout(readl, dsi->base + DSI_PHY_STATUS,
 				 val, val & LOCK, 1000, PHY_STATUS_TIMEOUT_US);
 	if (ret < 0) {
 		dev_err(dsi->dev, "failed to wait for phy lock state\n");
-		return ret;
+		goto phy_init_end;
 	}
 
 	ret = readx_poll_timeout(readl, dsi->base + DSI_PHY_STATUS,
 				 val, val & STOP_STATE_CLK_LANE, 1000,
 				 PHY_STATUS_TIMEOUT_US);
-	if (ret < 0) {
+	if (ret < 0)
 		dev_err(dsi->dev,
 			"failed to wait for phy clk lane stop state\n");
-		return ret;
-	}
+
+phy_init_end:
+	if (!IS_ERR(dsi->phy_cfg_clk))
+		clk_disable_unprepare(dsi->phy_cfg_clk);
 
 	return ret;
 }
@@ -512,7 +535,7 @@ static int dw_mipi_dsi_host_attach(struct mipi_dsi_host *host,
 
 	if (device->lanes > dsi->pdata->max_data_lanes) {
 		dev_err(dsi->dev, "the number of data lanes(%u) is too many\n",
-				device->lanes);
+			device->lanes);
 		return -EINVAL;
 	}
 
@@ -815,8 +838,8 @@ static void dw_mipi_dsi_clear_err(struct dw_mipi_dsi *dsi)
 }
 
 static void dw_mipi_dsi_encoder_mode_set(struct drm_encoder *encoder,
-					struct drm_display_mode *mode,
-					struct drm_display_mode *adjusted_mode)
+					 struct drm_display_mode *mode,
+					 struct drm_display_mode *adjusted_mode)
 {
 	struct dw_mipi_dsi *dsi = encoder_to_dsi(encoder);
 	int ret;
@@ -878,6 +901,7 @@ static void dw_mipi_dsi_encoder_disable(struct drm_encoder *encoder)
 static void dw_mipi_dsi_encoder_commit(struct drm_encoder *encoder)
 {
 	struct dw_mipi_dsi *dsi = encoder_to_dsi(encoder);
+	const struct dw_mipi_dsi_plat_data *pdata = dsi->pdata;
 	int mux = drm_of_encoder_active_endpoint_id(dsi->dev->of_node, encoder);
 	u32 val;
 
@@ -886,6 +910,10 @@ static void dw_mipi_dsi_encoder_commit(struct drm_encoder *encoder)
 		return;
 	}
 
+	if (pdata->grf_dsi0_mode_reg)
+		regmap_write(dsi->grf_regmap, pdata->grf_dsi0_mode_reg,
+			     pdata->grf_dsi0_mode);
+
 	dw_mipi_dsi_phy_init(dsi);
 	dw_mipi_dsi_wait_for_two_frames(dsi);
 
@@ -895,11 +923,11 @@ static void dw_mipi_dsi_encoder_commit(struct drm_encoder *encoder)
 	clk_disable_unprepare(dsi->pclk);
 
 	if (mux)
-		val = DSI0_SEL_VOP_LIT | (DSI0_SEL_VOP_LIT << 16);
+		val = pdata->dsi0_en_bit | (pdata->dsi0_en_bit << 16);
 	else
-		val = DSI0_SEL_VOP_LIT << 16;
+		val = pdata->dsi0_en_bit << 16;
 
-	regmap_write(dsi->grf_regmap, GRF_SOC_CON6, val);
+	regmap_write(dsi->grf_regmap, pdata->grf_switch_reg, val);
 	dev_dbg(dsi->dev, "vop %s output to dsi0\n", (mux) ? "LIT" : "BIG");
 }
 
@@ -931,7 +959,7 @@ dw_mipi_dsi_encoder_atomic_check(struct drm_encoder *encoder,
 	return 0;
 }
 
-static struct drm_encoder_helper_funcs
+static const struct drm_encoder_helper_funcs
 dw_mipi_dsi_encoder_helper_funcs = {
 	.commit = dw_mipi_dsi_encoder_commit,
 	.mode_set = dw_mipi_dsi_encoder_mode_set,
@@ -939,7 +967,7 @@ dw_mipi_dsi_encoder_helper_funcs = {
 	.atomic_check = dw_mipi_dsi_encoder_atomic_check,
 };
 
-static struct drm_encoder_funcs dw_mipi_dsi_encoder_funcs = {
+static const struct drm_encoder_funcs dw_mipi_dsi_encoder_funcs = {
 	.destroy = drm_encoder_cleanup,
 };
 
@@ -975,7 +1003,7 @@ static void dw_mipi_dsi_drm_connector_destroy(struct drm_connector *connector)
 	drm_connector_cleanup(connector);
 }
 
-static struct drm_connector_funcs dw_mipi_dsi_atomic_connector_funcs = {
+static const struct drm_connector_funcs dw_mipi_dsi_atomic_connector_funcs = {
 	.dpms = drm_atomic_helper_connector_dpms,
 	.fill_modes = drm_helper_probe_single_connector_modes,
 	.destroy = dw_mipi_dsi_drm_connector_destroy,
@@ -985,7 +1013,7 @@ static struct drm_connector_funcs dw_mipi_dsi_atomic_connector_funcs = {
 };
 
 static int dw_mipi_dsi_register(struct drm_device *drm,
-				      struct dw_mipi_dsi *dsi)
+				struct dw_mipi_dsi *dsi)
 {
 	struct drm_encoder *encoder = &dsi->encoder;
 	struct drm_connector *connector = &dsi->connector;
@@ -1006,14 +1034,14 @@ static int dw_mipi_dsi_register(struct drm_device *drm,
 	drm_encoder_helper_add(&dsi->encoder,
 			       &dw_mipi_dsi_encoder_helper_funcs);
 	ret = drm_encoder_init(drm, &dsi->encoder, &dw_mipi_dsi_encoder_funcs,
-			 DRM_MODE_ENCODER_DSI, NULL);
+			       DRM_MODE_ENCODER_DSI, NULL);
 	if (ret) {
 		dev_err(dev, "Failed to initialize encoder with drm\n");
 		return ret;
 	}
 
 	drm_connector_helper_add(connector,
-			&dw_mipi_dsi_connector_helper_funcs);
+				 &dw_mipi_dsi_connector_helper_funcs);
 
 	drm_connector_init(drm, &dsi->connector,
 			   &dw_mipi_dsi_atomic_connector_funcs,
@@ -1059,21 +1087,36 @@ static enum drm_mode_status rk3288_mipi_dsi_mode_valid(
 }
 
 static struct dw_mipi_dsi_plat_data rk3288_mipi_dsi_drv_data = {
+	.dsi0_en_bit = RK3288_DSI0_SEL_VOP_LIT,
+	.dsi1_en_bit = RK3288_DSI1_SEL_VOP_LIT,
+	.grf_switch_reg = RK3288_GRF_SOC_CON6,
 	.max_data_lanes = 4,
 	.mode_valid = rk3288_mipi_dsi_mode_valid,
 };
 
+static struct dw_mipi_dsi_plat_data rk3399_mipi_dsi_drv_data = {
+	.dsi0_en_bit = RK3399_DSI0_SEL_VOP_LIT,
+	.dsi1_en_bit = RK3399_DSI1_SEL_VOP_LIT,
+	.grf_switch_reg = RK3399_GRF_SOC_CON19,
+	.grf_dsi0_mode = RK3399_GRF_DSI_MODE,
+	.grf_dsi0_mode_reg = RK3399_GRF_SOC_CON22,
+	.max_data_lanes = 4,
+};
+
 static const struct of_device_id dw_mipi_dsi_dt_ids[] = {
 	{
 	 .compatible = "rockchip,rk3288-mipi-dsi",
 	 .data = &rk3288_mipi_dsi_drv_data,
+	}, {
+	 .compatible = "rockchip,rk3399-mipi-dsi",
+	 .data = &rk3399_mipi_dsi_drv_data,
 	},
 	{ /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, dw_mipi_dsi_dt_ids);
 
 static int dw_mipi_dsi_bind(struct device *dev, struct device *master,
-			     void *data)
+			    void *data)
 {
 	const struct of_device_id *of_id =
 			of_match_device(dw_mipi_dsi_dt_ids, dev);
@@ -1117,6 +1160,10 @@ static int dw_mipi_dsi_bind(struct device *dev, struct device *master,
 		return ret;
 	}
 
+	dsi->phy_cfg_clk = devm_clk_get(dev, "phy_cfg");
+	if (IS_ERR(dsi->phy_cfg_clk))
+		dev_dbg(dev, "have not phy_cfg_clk\n");
+
 	ret = clk_prepare_enable(dsi->pllref_clk);
 	if (ret) {
 		dev_err(dev, "%s: Failed to enable pllref_clk\n", __func__);
@@ -1141,7 +1188,7 @@ static int dw_mipi_dsi_bind(struct device *dev, struct device *master,
 }
 
 static void dw_mipi_dsi_unbind(struct device *dev, struct device *master,
-	void *data)
+			       void *data)
 {
 	struct dw_mipi_dsi *dsi = dev_get_drvdata(dev);
 
-- 
2.6.3

^ permalink raw reply related

* [PATCH v2 03/11] drm/rockchip/dsi: remove mode_valid function
From: Chris Zhong @ 2017-01-16 10:08 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1484561311-494-1-git-send-email-zyw@rock-chips.com>

The MIPI DSI do not need check the validity of resolution, the max
resolution should depend VOP. Hence, remove rk3288_mipi_dsi_mode_valid
here.

Signed-off-by: Chris Zhong <zyw@rock-chips.com>
---

 drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 39 ----------------------------------
 1 file changed, 39 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
index 04fd595..8f8d48a 100644
--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
@@ -276,8 +276,6 @@ struct dw_mipi_dsi_plat_data {
 	u32 grf_dsi0_mode;
 	u32 grf_dsi0_mode_reg;
 	unsigned int max_data_lanes;
-	enum drm_mode_status (*mode_valid)(struct drm_connector *connector,
-					   struct drm_display_mode *mode);
 };
 
 struct dw_mipi_dsi {
@@ -978,23 +976,8 @@ static int dw_mipi_dsi_connector_get_modes(struct drm_connector *connector)
 	return drm_panel_get_modes(dsi->panel);
 }
 
-static enum drm_mode_status dw_mipi_dsi_mode_valid(
-					struct drm_connector *connector,
-					struct drm_display_mode *mode)
-{
-	struct dw_mipi_dsi *dsi = con_to_dsi(connector);
-
-	enum drm_mode_status mode_status = MODE_OK;
-
-	if (dsi->pdata->mode_valid)
-		mode_status = dsi->pdata->mode_valid(connector, mode);
-
-	return mode_status;
-}
-
 static struct drm_connector_helper_funcs dw_mipi_dsi_connector_helper_funcs = {
 	.get_modes = dw_mipi_dsi_connector_get_modes,
-	.mode_valid = dw_mipi_dsi_mode_valid,
 };
 
 static void dw_mipi_dsi_drm_connector_destroy(struct drm_connector *connector)
@@ -1065,33 +1048,11 @@ static int rockchip_mipi_parse_dt(struct dw_mipi_dsi *dsi)
 	return 0;
 }
 
-static enum drm_mode_status rk3288_mipi_dsi_mode_valid(
-					struct drm_connector *connector,
-					struct drm_display_mode *mode)
-{
-	/*
-	 * The VID_PKT_SIZE field in the DSI_VID_PKT_CFG
-	 * register is 11-bit.
-	 */
-	if (mode->hdisplay > 0x7ff)
-		return MODE_BAD_HVALUE;
-
-	/*
-	 * The V_ACTIVE_LINES field in the DSI_VTIMING_CFG
-	 * register is 11-bit.
-	 */
-	if (mode->vdisplay > 0x7ff)
-		return MODE_BAD_VVALUE;
-
-	return MODE_OK;
-}
-
 static struct dw_mipi_dsi_plat_data rk3288_mipi_dsi_drv_data = {
 	.dsi0_en_bit = RK3288_DSI0_SEL_VOP_LIT,
 	.dsi1_en_bit = RK3288_DSI1_SEL_VOP_LIT,
 	.grf_switch_reg = RK3288_GRF_SOC_CON6,
 	.max_data_lanes = 4,
-	.mode_valid = rk3288_mipi_dsi_mode_valid,
 };
 
 static struct dw_mipi_dsi_plat_data rk3399_mipi_dsi_drv_data = {
-- 
2.6.3

^ permalink raw reply related

* [PATCH v2 04/11] dt-bindings: add power domain node for dw-mipi-rockchip
From: Chris Zhong @ 2017-01-16 10:08 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1484561311-494-1-git-send-email-zyw@rock-chips.com>

Signed-off-by: Chris Zhong <zyw@rock-chips.com>
Acked-by: Rob Herring <robh@kernel.org>
---

 .../devicetree/bindings/display/rockchip/dw_mipi_dsi_rockchip.txt      | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/Documentation/devicetree/bindings/display/rockchip/dw_mipi_dsi_rockchip.txt b/Documentation/devicetree/bindings/display/rockchip/dw_mipi_dsi_rockchip.txt
index 0f82568..188f6f7 100644
--- a/Documentation/devicetree/bindings/display/rockchip/dw_mipi_dsi_rockchip.txt
+++ b/Documentation/devicetree/bindings/display/rockchip/dw_mipi_dsi_rockchip.txt
@@ -15,6 +15,9 @@ Required properties:
 - ports: contain a port node with endpoint definitions as defined in [2].
   For vopb,set the reg = <0> and set the reg = <1> for vopl.
 
+Optional properties:
+- power-domains: a phandle to mipi dsi power domain node.
+
 [1] Documentation/devicetree/bindings/clock/clock-bindings.txt
 [2] Documentation/devicetree/bindings/media/video-interfaces.txt
 
-- 
2.6.3

^ permalink raw reply related

* [PATCH v2 05/11] drm/rockchip/dsi: add dw-mipi power domain support
From: Chris Zhong @ 2017-01-16 10:08 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1484561311-494-1-git-send-email-zyw@rock-chips.com>

Reference the power domain incase dw-mipi power down when
in use.

Signed-off-by: Chris Zhong <zyw@rock-chips.com>
---

 drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
index 8f8d48a..d2a3efb 100644
--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
@@ -12,6 +12,7 @@
 #include <linux/math64.h>
 #include <linux/module.h>
 #include <linux/of_device.h>
+#include <linux/pm_runtime.h>
 #include <linux/regmap.h>
 #include <linux/mfd/syscon.h>
 #include <drm/drm_atomic_helper.h>
@@ -291,6 +292,7 @@ struct dw_mipi_dsi {
 	struct clk *pclk;
 	struct clk *phy_cfg_clk;
 
+	int dpms_mode;
 	unsigned int lane_mbps; /* per lane */
 	u32 channel;
 	u32 lanes;
@@ -842,6 +844,9 @@ static void dw_mipi_dsi_encoder_mode_set(struct drm_encoder *encoder,
 	struct dw_mipi_dsi *dsi = encoder_to_dsi(encoder);
 	int ret;
 
+	if (dsi->dpms_mode == DRM_MODE_DPMS_ON)
+		return;
+
 	dsi->mode = adjusted_mode;
 
 	ret = dw_mipi_dsi_get_lane_bps(dsi);
@@ -853,6 +858,8 @@ static void dw_mipi_dsi_encoder_mode_set(struct drm_encoder *encoder,
 		return;
 	}
 
+	pm_runtime_get_sync(dsi->dev);
+
 	dw_mipi_dsi_init(dsi);
 	dw_mipi_dsi_dpi_config(dsi, mode);
 	dw_mipi_dsi_packet_handler_config(dsi);
@@ -874,6 +881,9 @@ static void dw_mipi_dsi_encoder_disable(struct drm_encoder *encoder)
 {
 	struct dw_mipi_dsi *dsi = encoder_to_dsi(encoder);
 
+	if (dsi->dpms_mode != DRM_MODE_DPMS_ON)
+		return;
+
 	drm_panel_disable(dsi->panel);
 
 	if (clk_prepare_enable(dsi->pclk)) {
@@ -893,7 +903,9 @@ static void dw_mipi_dsi_encoder_disable(struct drm_encoder *encoder)
 
 	dw_mipi_dsi_set_mode(dsi, DW_MIPI_DSI_CMD_MODE);
 	dw_mipi_dsi_disable(dsi);
+	pm_runtime_put(dsi->dev);
 	clk_disable_unprepare(dsi->pclk);
+	dsi->dpms_mode = DRM_MODE_DPMS_OFF;
 }
 
 static void dw_mipi_dsi_encoder_commit(struct drm_encoder *encoder)
@@ -927,6 +939,7 @@ static void dw_mipi_dsi_encoder_commit(struct drm_encoder *encoder)
 
 	regmap_write(dsi->grf_regmap, pdata->grf_switch_reg, val);
 	dev_dbg(dsi->dev, "vop %s output to dsi0\n", (mux) ? "LIT" : "BIG");
+	dsi->dpms_mode = DRM_MODE_DPMS_ON;
 }
 
 static int
@@ -1094,6 +1107,7 @@ static int dw_mipi_dsi_bind(struct device *dev, struct device *master,
 
 	dsi->dev = dev;
 	dsi->pdata = pdata;
+	dsi->dpms_mode = DRM_MODE_DPMS_OFF;
 
 	ret = rockchip_mipi_parse_dt(dsi);
 	if (ret)
@@ -1139,6 +1153,8 @@ static int dw_mipi_dsi_bind(struct device *dev, struct device *master,
 
 	dev_set_drvdata(dev, dsi);
 
+	pm_runtime_enable(dev);
+
 	dsi->dsi_host.ops = &dw_mipi_dsi_host_ops;
 	dsi->dsi_host.dev = dev;
 	return mipi_dsi_host_register(&dsi->dsi_host);
@@ -1154,6 +1170,7 @@ static void dw_mipi_dsi_unbind(struct device *dev, struct device *master,
 	struct dw_mipi_dsi *dsi = dev_get_drvdata(dev);
 
 	mipi_dsi_host_unregister(&dsi->dsi_host);
+	pm_runtime_disable(dev);
 	clk_disable_unprepare(dsi->pllref_clk);
 }
 
-- 
2.6.3

^ permalink raw reply related

* [PATCH v2 06/11] drm/rockchip/dsi: return probe defer if attach panel failed
From: Chris Zhong @ 2017-01-16 10:08 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1484561311-494-1-git-send-email-zyw@rock-chips.com>

From: Mark Yao <mark.yao@rock-chips.com>

Return -EINVAL would cause mipi dsi bad behavior, probe defer
to ensure mipi find the correct mode,

Signed-off-by: Mark Yao <mark.yao@rock-chips.com>
Signed-off-by: Chris Zhong <zyw@rock-chips.com>
---

 drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
index d2a3efb..5e3f031 100644
--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
@@ -549,10 +549,14 @@ static int dw_mipi_dsi_host_attach(struct mipi_dsi_host *host,
 	dsi->channel = device->channel;
 	dsi->format = device->format;
 	dsi->panel = of_drm_find_panel(device->dev.of_node);
-	if (dsi->panel)
-		return drm_panel_attach(dsi->panel, &dsi->connector);
+	if (!dsi->panel) {
+		DRM_ERROR("failed to find panel\n");
+		return -EPROBE_DEFER;
+	}
 
-	return -EINVAL;
+	drm_panel_attach(dsi->panel, &dsi->connector);
+
+	return 0;
 }
 
 static int dw_mipi_dsi_host_detach(struct mipi_dsi_host *host,
@@ -560,7 +564,8 @@ static int dw_mipi_dsi_host_detach(struct mipi_dsi_host *host,
 {
 	struct dw_mipi_dsi *dsi = host_to_dsi(host);
 
-	drm_panel_detach(dsi->panel);
+	if (dsi->panel)
+		drm_panel_detach(dsi->panel);
 
 	return 0;
 }
-- 
2.6.3

^ permalink raw reply related

* [PATCH v2 07/11] drm/rockchip/dsi: fix mipi display can't found at init time
From: Chris Zhong @ 2017-01-16 10:08 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1484561311-494-1-git-send-email-zyw@rock-chips.com>

From: Mark Yao <mark.yao@rock-chips.com>

The problem is that:
  mipi panel probe request mipi_dsi_host_register.
  mipi host attach is call from panel device, so the defer function
always can't works.

So at the first bind time, always can't found mipi panel.

Signed-off-by: Mark Yao <mark.yao@rock-chips.com>
Signed-off-by: Chris Zhong <zyw@rock-chips.com>
---

 drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 57 +++++++++++++++++++++++-----------
 1 file changed, 39 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
index 5e3f031..4ec82f6 100644
--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
@@ -551,11 +551,9 @@ static int dw_mipi_dsi_host_attach(struct mipi_dsi_host *host,
 	dsi->panel = of_drm_find_panel(device->dev.of_node);
 	if (!dsi->panel) {
 		DRM_ERROR("failed to find panel\n");
-		return -EPROBE_DEFER;
+		return -ENODEV;
 	}
 
-	drm_panel_attach(dsi->panel, &dsi->connector);
-
 	return 0;
 }
 
@@ -567,6 +565,7 @@ static int dw_mipi_dsi_host_detach(struct mipi_dsi_host *host,
 	if (dsi->panel)
 		drm_panel_detach(dsi->panel);
 
+	dsi->panel = NULL;
 	return 0;
 }
 
@@ -1048,6 +1047,8 @@ static int dw_mipi_dsi_register(struct drm_device *drm,
 			   &dw_mipi_dsi_atomic_connector_funcs,
 			   DRM_MODE_CONNECTOR_DSI);
 
+	drm_panel_attach(dsi->panel, &dsi->connector);
+
 	drm_mode_connector_attach_encoder(connector, encoder);
 
 	return 0;
@@ -1097,23 +1098,17 @@ MODULE_DEVICE_TABLE(of, dw_mipi_dsi_dt_ids);
 static int dw_mipi_dsi_bind(struct device *dev, struct device *master,
 			    void *data)
 {
-	const struct of_device_id *of_id =
-			of_match_device(dw_mipi_dsi_dt_ids, dev);
-	const struct dw_mipi_dsi_plat_data *pdata = of_id->data;
 	struct platform_device *pdev = to_platform_device(dev);
 	struct drm_device *drm = data;
-	struct dw_mipi_dsi *dsi;
+	struct dw_mipi_dsi *dsi = dev_get_drvdata(dev);
 	struct resource *res;
 	int ret;
 
-	dsi = devm_kzalloc(dev, sizeof(*dsi), GFP_KERNEL);
-	if (!dsi)
-		return -ENOMEM;
-
-	dsi->dev = dev;
-	dsi->pdata = pdata;
 	dsi->dpms_mode = DRM_MODE_DPMS_OFF;
 
+	if (!dsi->panel)
+		return -EPROBE_DEFER;
+
 	ret = rockchip_mipi_parse_dt(dsi);
 	if (ret)
 		return ret;
@@ -1160,9 +1155,7 @@ static int dw_mipi_dsi_bind(struct device *dev, struct device *master,
 
 	pm_runtime_enable(dev);
 
-	dsi->dsi_host.ops = &dw_mipi_dsi_host_ops;
-	dsi->dsi_host.dev = dev;
-	return mipi_dsi_host_register(&dsi->dsi_host);
+	return 0;
 
 err_pllref:
 	clk_disable_unprepare(dsi->pllref_clk);
@@ -1174,7 +1167,6 @@ static void dw_mipi_dsi_unbind(struct device *dev, struct device *master,
 {
 	struct dw_mipi_dsi *dsi = dev_get_drvdata(dev);
 
-	mipi_dsi_host_unregister(&dsi->dsi_host);
 	pm_runtime_disable(dev);
 	clk_disable_unprepare(dsi->pllref_clk);
 }
@@ -1186,11 +1178,40 @@ static const struct component_ops dw_mipi_dsi_ops = {
 
 static int dw_mipi_dsi_probe(struct platform_device *pdev)
 {
-	return component_add(&pdev->dev, &dw_mipi_dsi_ops);
+	struct device *dev = &pdev->dev;
+	const struct of_device_id *of_id =
+			of_match_device(dw_mipi_dsi_dt_ids, dev);
+	const struct dw_mipi_dsi_plat_data *pdata = of_id->data;
+	struct dw_mipi_dsi *dsi;
+	int ret;
+
+	dsi = devm_kzalloc(&pdev->dev, sizeof(*dsi), GFP_KERNEL);
+	if (!dsi)
+		return -ENOMEM;
+
+	dsi->dev = dev;
+	dsi->pdata = pdata;
+	dsi->dsi_host.ops = &dw_mipi_dsi_host_ops;
+	dsi->dsi_host.dev = &pdev->dev;
+
+	ret = mipi_dsi_host_register(&dsi->dsi_host);
+	if (ret)
+		return ret;
+
+	platform_set_drvdata(pdev, dsi);
+	ret = component_add(&pdev->dev, &dw_mipi_dsi_ops);
+	if (ret)
+		mipi_dsi_host_unregister(&dsi->dsi_host);
+
+	return ret;
 }
 
 static int dw_mipi_dsi_remove(struct platform_device *pdev)
 {
+	struct dw_mipi_dsi *dsi = dev_get_drvdata(&pdev->dev);
+
+	if (dsi)
+		mipi_dsi_host_unregister(&dsi->dsi_host);
 	component_del(&pdev->dev, &dw_mipi_dsi_ops);
 	return 0;
 }
-- 
2.6.3

^ permalink raw reply related

* [PATCH v2 08/11] drm/rockchip/dsi: fix the issue can not send commands
From: Chris Zhong @ 2017-01-16 10:08 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1484561311-494-1-git-send-email-zyw@rock-chips.com>

From: xubilv <xbl@rock-chips.com>

There is a bug in hdr_write function, the value from the caller will be
overwritten, it cause the mipi can not send the correct command. And the
MIPI_DSI_GENERIC_SHORT_WRITE_n_PARAM message type should be supported.

Signed-off-by: xubilv <xbl@rock-chips.com>
Signed-off-by: Chris Zhong <zyw@rock-chips.com>
---

 drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 26 +++++++++++++++++---------
 1 file changed, 17 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
index 4ec82f6..4a2691c 100644
--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
@@ -572,10 +572,12 @@ static int dw_mipi_dsi_host_detach(struct mipi_dsi_host *host,
 static int dw_mipi_dsi_gen_pkt_hdr_write(struct dw_mipi_dsi *dsi, u32 val)
 {
 	int ret;
+	u32 sts;
 
 	ret = readx_poll_timeout(readl, dsi->base + DSI_CMD_PKT_STATUS,
-				 val, !(val & GEN_CMD_FULL), 1000,
+				 sts, !(sts & GEN_CMD_FULL), 1000,
 				 CMD_PKT_STATUS_TIMEOUT_US);
+
 	if (ret < 0) {
 		dev_err(dsi->dev, "failed to get available command FIFO\n");
 		return ret;
@@ -584,8 +586,9 @@ static int dw_mipi_dsi_gen_pkt_hdr_write(struct dw_mipi_dsi *dsi, u32 val)
 	dsi_write(dsi, DSI_GEN_HDR, val);
 
 	ret = readx_poll_timeout(readl, dsi->base + DSI_CMD_PKT_STATUS,
-				 val, val & (GEN_CMD_EMPTY | GEN_PLD_W_EMPTY),
+				 sts, sts & (GEN_CMD_EMPTY | GEN_PLD_W_EMPTY),
 				 1000, CMD_PKT_STATUS_TIMEOUT_US);
+
 	if (ret < 0) {
 		dev_err(dsi->dev, "failed to write command FIFO\n");
 		return ret;
@@ -594,8 +597,8 @@ static int dw_mipi_dsi_gen_pkt_hdr_write(struct dw_mipi_dsi *dsi, u32 val)
 	return 0;
 }
 
-static int dw_mipi_dsi_dcs_short_write(struct dw_mipi_dsi *dsi,
-				       const struct mipi_dsi_msg *msg)
+static int dw_mipi_dsi_short_write(struct dw_mipi_dsi *dsi,
+				   const struct mipi_dsi_msg *msg)
 {
 	const u16 *tx_buf = msg->tx_buf;
 	u32 val = GEN_HDATA(*tx_buf) | GEN_HTYPE(msg->type);
@@ -609,13 +612,14 @@ static int dw_mipi_dsi_dcs_short_write(struct dw_mipi_dsi *dsi,
 	return dw_mipi_dsi_gen_pkt_hdr_write(dsi, val);
 }
 
-static int dw_mipi_dsi_dcs_long_write(struct dw_mipi_dsi *dsi,
-				      const struct mipi_dsi_msg *msg)
+static int dw_mipi_dsi_long_write(struct dw_mipi_dsi *dsi,
+				  const struct mipi_dsi_msg *msg)
 {
 	const u32 *tx_buf = msg->tx_buf;
 	int len = msg->tx_len, pld_data_bytes = sizeof(*tx_buf), ret;
 	u32 val = GEN_HDATA(msg->tx_len) | GEN_HTYPE(msg->type);
 	u32 remainder = 0;
+	u32 sts = 0;
 
 	if (msg->tx_len < 3) {
 		dev_err(dsi->dev, "wrong tx buf length %zu for long write\n",
@@ -635,7 +639,7 @@ static int dw_mipi_dsi_dcs_long_write(struct dw_mipi_dsi *dsi,
 		}
 
 		ret = readx_poll_timeout(readl, dsi->base + DSI_CMD_PKT_STATUS,
-					 val, !(val & GEN_PLD_W_FULL), 1000,
+					 sts, !(sts & GEN_PLD_W_FULL), 1000,
 					 CMD_PKT_STATUS_TIMEOUT_US);
 		if (ret < 0) {
 			dev_err(dsi->dev,
@@ -656,11 +660,15 @@ static ssize_t dw_mipi_dsi_host_transfer(struct mipi_dsi_host *host,
 	switch (msg->type) {
 	case MIPI_DSI_DCS_SHORT_WRITE:
 	case MIPI_DSI_DCS_SHORT_WRITE_PARAM:
+	case MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM:
+	case MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM:
+	case MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM:
 	case MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE:
-		ret = dw_mipi_dsi_dcs_short_write(dsi, msg);
+		ret = dw_mipi_dsi_short_write(dsi, msg);
 		break;
 	case MIPI_DSI_DCS_LONG_WRITE:
-		ret = dw_mipi_dsi_dcs_long_write(dsi, msg);
+	case MIPI_DSI_GENERIC_LONG_WRITE:
+		ret = dw_mipi_dsi_long_write(dsi, msg);
 		break;
 	default:
 		dev_err(dsi->dev, "unsupported message type\n");
-- 
2.6.3

^ permalink raw reply related

* [PATCH v2 09/11] drm/rockchip/dsi: decrease the value of Ths-prepare
From: Chris Zhong @ 2017-01-16 10:08 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1484561311-494-1-git-send-email-zyw@rock-chips.com>

From: xubilv <xbl@rock-chips.com>

Signed-off-by: xubilv <xbl@rock-chips.com>
Signed-off-by: Chris Zhong <zyw@rock-chips.com>
---

 drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
index 4a2691c..f50909e 100644
--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
@@ -455,7 +455,7 @@ static int dw_mipi_dsi_phy_init(struct dw_mipi_dsi *dsi)
 					 BANDGAP_SEL(BANDGAP_96_10));
 
 	dw_mipi_dsi_phy_write(dsi, 0x70, TLP_PROGRAM_EN | 0xf);
-	dw_mipi_dsi_phy_write(dsi, 0x71, THS_PRE_PROGRAM_EN | 0x55);
+	dw_mipi_dsi_phy_write(dsi, 0x71, THS_PRE_PROGRAM_EN | 0x2d);
 	dw_mipi_dsi_phy_write(dsi, 0x72, THS_ZERO_PROGRAM_EN | 0xa);
 
 	dsi_write(dsi, DSI_PHY_RSTZ, PHY_ENFORCEPLL | PHY_ENABLECLK |
-- 
2.6.3

^ permalink raw reply related

* [PATCH v2 10/11] drm/rockchip/dsi: fix phy clk lane stop state timeout
From: Chris Zhong @ 2017-01-16 10:08 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1484561311-494-1-git-send-email-zyw@rock-chips.com>

Before phy init, the detection of phy state should be controlled
manually. After that, we can switch the detection to hardward,
it is automatic. Hence move PHY_TXREQUESTCLKHS setting to the end
of phy init.

Signed-off-by: Chris Zhong <zyw@rock-chips.com>
---

 drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
index f50909e..9dfa73d 100644
--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
@@ -475,6 +475,8 @@ static int dw_mipi_dsi_phy_init(struct dw_mipi_dsi *dsi)
 		dev_err(dsi->dev,
 			"failed to wait for phy clk lane stop state\n");
 
+	dsi_write(dsi, DSI_LPCLK_CTRL, PHY_TXREQUESTCLKHS);
+
 phy_init_end:
 	if (!IS_ERR(dsi->phy_cfg_clk))
 		clk_disable_unprepare(dsi->phy_cfg_clk);
@@ -721,7 +723,6 @@ static void dw_mipi_dsi_init(struct dw_mipi_dsi *dsi)
 		  | PHY_RSTZ | PHY_SHUTDOWNZ);
 	dsi_write(dsi, DSI_CLKMGR_CFG, TO_CLK_DIVIDSION(10) |
 		  TX_ESC_CLK_DIVIDSION(7));
-	dsi_write(dsi, DSI_LPCLK_CTRL, PHY_TXREQUESTCLKHS);
 }
 
 static void dw_mipi_dsi_dpi_config(struct dw_mipi_dsi *dsi,
-- 
2.6.3

^ permalink raw reply related

* [PATCH v2 11/11] drm/rockchip/dsi: fix insufficient bandwidth of some panel
From: Chris Zhong @ 2017-01-16 10:08 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1484561311-494-1-git-send-email-zyw@rock-chips.com>

Set the lanes bps to 1 / 0.9 times of pclk, the margin is not enough
for some panel, it will cause the screen display is not normal, so
increases the badnwidth to 1 / 0.8.

Signed-off-by: Chris Zhong <zyw@rock-chips.com>

---

 drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
index 9dfa73d..5a973fe 100644
--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
@@ -501,8 +501,8 @@ static int dw_mipi_dsi_get_lane_bps(struct dw_mipi_dsi *dsi)
 
 	mpclk = DIV_ROUND_UP(dsi->mode->clock, MSEC_PER_SEC);
 	if (mpclk) {
-		/* take 1 / 0.9, since mbps must big than bandwidth of RGB */
-		tmp = mpclk * (bpp / dsi->lanes) * 10 / 9;
+		/* take 1 / 0.8, since mbps must big than bandwidth of RGB */
+		tmp = mpclk * (bpp / dsi->lanes) * 10 / 8;
 		if (tmp < max_mbps)
 			target_mbps = tmp;
 		else
-- 
2.6.3

^ permalink raw reply related

* [Question] A question about arm64 pte
From: Yisheng Xie @ 2017-01-16 10:08 UTC (permalink / raw)
  To: linux-arm-kernel

hi,
I have question about arm64 pte.

For arm64, PTE_WRITE?== PTE_DBM? is to mark whether the page is writable,
and PTE_DIRTY is to mark whether the page is dirty.
However, PTE_RDONLY is only cleared when both PTE_WRITE and PTE_DIRTY are set.

Is that means that the page is still writable when PTE_RDONLY is set with PTE_WRITE?
But in ARM Architecture Reference Manual for ARMv8,
when PTE_RDONLY is set(AP[2:1] = 0b1x), Acess from EL1 is Ready only?

so what is the really means of the PTE_RDONLY? could some one help to explain it?

Thanks
Yisheng Xie

^ permalink raw reply

* [PATCH] rtc: stm32: fix comparison warnings
From: Amelie Delaunay @ 2017-01-16 10:08 UTC (permalink / raw)
  To: linux-arm-kernel

This patches fixes comparison between signed and unsigned values as it
could produce an incorrect result when the signed value is converted to
unsigned:

drivers/rtc/rtc-stm32.c: In function 'stm32_rtc_valid_alrm':
drivers/rtc/rtc-stm32.c:404:21: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
  if ((((tm->tm_year > cur_year) &&
...

It also fixes comparison always true or false due to the fact that unsigned
value is compared against zero with >= or <:

drivers/rtc/rtc-stm32.c: In function 'stm32_rtc_init':
drivers/rtc/rtc-stm32.c:514:35: warning: comparison of unsigned expression >= 0 is always true [-Wtype-limits]
  for (pred_a = pred_a_max; pred_a >= 0; pred_a-- ) {

drivers/rtc/rtc-stm32.c:530:44: warning: comparison of unsigned expression < 0 is always false [-Wtype-limits]
     (rate - ((pred_a + 1) * (pred_s + 1)) < 0) ?

Fixes: 4e64350f42e2 ("rtc: add STM32 RTC driver")
Signed-off-by: Amelie Delaunay <amelie.delaunay@st.com>
---
 drivers/rtc/rtc-stm32.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/rtc/rtc-stm32.c b/drivers/rtc/rtc-stm32.c
index 03c97c1..bd57eb1 100644
--- a/drivers/rtc/rtc-stm32.c
+++ b/drivers/rtc/rtc-stm32.c
@@ -383,7 +383,7 @@ static int stm32_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
 
 static int stm32_rtc_valid_alrm(struct stm32_rtc *rtc, struct rtc_time *tm)
 {
-	unsigned int cur_day, cur_mon, cur_year, cur_hour, cur_min, cur_sec;
+	int cur_day, cur_mon, cur_year, cur_hour, cur_min, cur_sec;
 	unsigned int dr = readl_relaxed(rtc->base + STM32_RTC_DR);
 	unsigned int tr = readl_relaxed(rtc->base + STM32_RTC_TR);
 
@@ -509,7 +509,7 @@ static int stm32_rtc_init(struct platform_device *pdev,
 	pred_a_max = STM32_RTC_PRER_PRED_A >> STM32_RTC_PRER_PRED_A_SHIFT;
 	pred_s_max = STM32_RTC_PRER_PRED_S >> STM32_RTC_PRER_PRED_S_SHIFT;
 
-	for (pred_a = pred_a_max; pred_a >= 0; pred_a--) {
+	for (pred_a = pred_a_max; pred_a + 1 > 0; pred_a--) {
 		pred_s = (rate / (pred_a + 1)) - 1;
 
 		if (((pred_s + 1) * (pred_a + 1)) == rate)
@@ -525,7 +525,7 @@ static int stm32_rtc_init(struct platform_device *pdev,
 		pred_s = (rate / (pred_a + 1)) - 1;
 
 		dev_warn(&pdev->dev, "ck_rtc is %s\n",
-			 (rate - ((pred_a + 1) * (pred_s + 1)) < 0) ?
+			 (rate < ((pred_a + 1) * (pred_s + 1))) ?
 			 "fast" : "slow");
 	}
 
-- 
1.9.1

^ permalink raw reply related

* [PATCH 03/10] devicetree: bindings: add bindings for ahci-da850
From: Bartosz Golaszewski @ 2017-01-16 10:13 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <35ff358d-9b17-b2be-38d8-6a51cdddc1a1@lechnology.com>

2017-01-13 20:25 GMT+01:00 David Lechner <david@lechnology.com>:
> On 01/13/2017 06:37 AM, Bartosz Golaszewski wrote:
>>
>> Add DT bindings for the TI DA850 AHCI SATA controller.
>>
>> Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
>> ---
>>  .../devicetree/bindings/ata/ahci-da850.txt          | 21
>> +++++++++++++++++++++
>>  1 file changed, 21 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/ata/ahci-da850.txt
>>
>> diff --git a/Documentation/devicetree/bindings/ata/ahci-da850.txt
>> b/Documentation/devicetree/bindings/ata/ahci-da850.txt
>> new file mode 100644
>> index 0000000..d07c241
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/ata/ahci-da850.txt
>> @@ -0,0 +1,21 @@
>> +Device tree binding for the TI DA850 AHCI SATA Controller
>> +---------------------------------------------------------
>> +
>> +Required properties:
>> +  - compatible: must be "ti,da850-ahci"
>> +  - reg: physical base addresses and sizes of the controller's register
>> areas
>> +  - interrupts: interrupt specifier (refer to the interrupt binding)
>> +
>> +Optional properties:
>> +  - clocks: clock specifier (refer to the common clock binding)
>> +  - da850,clk_multiplier: the multiplier for the reference clock needed
>> +                          for 1.5GHz PLL output
>
>
> A clock multiplier property seems redundant if you are specifying a clock.
> It should be possible to get the rate from the clock to determine which
> multiplier is needed.
>

I probably should have named it differently. This is not a multiplier
of a clock derived from PLL0 or PLL1. Instead it's a value set by
writing to the Port PHY Control Register (MPY bits) of the SATA
controller that configures the multiplier for the external low-jitter
clock. On the lcdk the signals (REFCLKP, REFCLKN) are provided by
CDCM61001 (SATA OSCILLATOR component on the schematics).

I'll find a better name and comment the property accordingly.

FYI: the da850 platform does not use the common clock framework, so I
don't specify the clock property on the sata node in the device tree.
Instead I add the clock lookup entry in patch [01/10]. This is
transparent for AHCI which can get the clock as usual by calling
clk_get() in ahci_platform_get_resources().

Thanks,
Bartosz Golaszewski

^ permalink raw reply

* [PATCH 06/10] sata: ahci_da850: implement a softreset quirk
From: Bartosz Golaszewski @ 2017-01-16 10:17 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20170115231208.GD14446@mtj.duckdns.org>

2017-01-16 0:12 GMT+01:00 Tejun Heo <tj@kernel.org>:
> On Fri, Jan 13, 2017 at 01:38:00PM +0100, Bartosz Golaszewski wrote:
>> +static int ahci_da850_softreset(struct ata_link *link,
>> +                             unsigned int *class, unsigned long deadline)
>> +{
>> +     int pmp, ret;
>> +
>> +     pmp = sata_srst_pmp(link);
>> +
>> +     ret = ahci_do_softreset(link, class, pmp, deadline, ahci_check_ready);
>> +     if (pmp && ret == -EBUSY)
>> +             return ahci_do_softreset(link, class, 0,
>> +                                      deadline, ahci_check_ready);
>> +
>> +     return ret;
>> +}
>
> Please add some comments explaining what's going on.

Sure, I'll add some explanation in v2.

Thanks,
Bartosz Golaszewski

^ permalink raw reply

* [PATCH v2 0/4] Amlogic Meson SAR ADC support
From: Neil Armstrong @ 2017-01-16 10:18 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20170115224221.15510-1-martin.blumenstingl@googlemail.com>

On 01/15/2017 11:42 PM, Martin Blumenstingl wrote:
> This series add support for the SAR ADC on Amlogic Meson GXBB, GXL and
> GXM SoCs.
> The hardware on GXBB provides 10-bit ADC results, while GXL and GXM are
> providing 12-bit results. Support for older SoCs (Meson8b and Meson8)
> can be added with little effort, most of which is testing I guess (I
> don't have any pre-GXBB hardware so I can't say).
> 
> A new set of clocks had to be added to the GXBB clock controller (used
> by the GXBB/GXL/GXM SoCs) which are required to get the ADC working.
> 
> The ADC itself can sample multiple channels at the same time and allows
> capturing multiple samples (which can be used for filtering/averaging).
> The ADC results are stored inside a FIFO register. More details on what
> the driver supports (or doesn't) can be found in the description of
> patch #3.
> 
> The code is based on the public S805 (Meson8b) and S905 (GXBB)
> datasheets, as well as by reading (various versions of) the vendor
> driver and by inspecting the registers on the vendor kernels of my
> testing-hardware.
> 
> Typical use-cases for the ADC on the Meson GX SoCs are:
> - adc-keys ("ADC attached resistor ladder buttons")
> - SoC temperature measurement (not supported by this driver yet as
>   the system firmware does this already and provides the values via the
>   SCPI protocol)
> - "version-strapping" (different resistor values are used to indicate
>   the board-revision)
> - and of course typical ADC measurements
> 
> Thanks to Heiner Kallweit, Jonathan Cameron and Lars-Peter Clausen for
> reviewing this series and providing valuable input!
> 
> Changes since v1 (all changes are for patch #3, except where noted):
> - fix IRQ number in meson-gx.dtsi (thanks to Heiner Kallweit for
>   providing the correct value), affects patch #4
> - move the most used members of meson_saradc_priv to the beginning
> - remove unused struct member "completion" from meson_saradc_priv
> - use devm_kasprintf() instead of snprintf() + devm_kstrdup()
> - initialize indio_dev->dev.parent earlier in meson_saradc_probe()
> - moved meson_saradc_clear_fifo() logic to a separate function
> - add comment why a do ... while loop is required in
>   meson_saradc_wait_busy_clear()
> - remove SAR_ADC_NUM_CHANNELS and SAR_ADC_VALUE_MASK macros (each of them
>   was only used once and it's an unneeded level of abstraction)
> - fixed multiline comment syntax violations
> - dropped unneeded log messages during initialization
> - set iio_dev name to "meson-gxbb-saradc" or "meson-gxl-saradc"
> - use "indio_dev->dev.parent" in all kernel log calls (dev_warn/err/etc)
>   to make it show the OF node name (instead of the iio device name)
> - introduce struct meson_saradc_data to hold platform-specific
>   information (such as resolution in bits and the iio_dev name)
> 
> 
> Martin Blumenstingl (4):
>   Documentation: dt-bindings: add the Amlogic Meson SAR ADC
>     documentation
>   clk: gxbb: add the SAR ADC clocks and expose them
>   iio: adc: add a driver for the SAR ADC found in Amlogic Meson SoCs
>   ARM64: dts: meson: meson-gx: add the SAR ADC
> 
>  .../bindings/iio/adc/amlogic,meson-saradc.txt      |  31 +
>  arch/arm64/boot/dts/amlogic/meson-gx.dtsi          |   8 +
>  arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi        |  10 +
>  arch/arm64/boot/dts/amlogic/meson-gxl.dtsi         |  10 +
>  drivers/clk/meson/gxbb.c                           |  48 ++
>  drivers/clk/meson/gxbb.h                           |   9 +-
>  drivers/iio/adc/Kconfig                            |  12 +
>  drivers/iio/adc/Makefile                           |   1 +
>  drivers/iio/adc/meson_saradc.c                     | 893 +++++++++++++++++++++
>  include/dt-bindings/clock/gxbb-clkc.h              |   4 +
>  10 files changed, 1023 insertions(+), 3 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/iio/adc/amlogic,meson-saradc.txt
>  create mode 100644 drivers/iio/adc/meson_saradc.c
> 

Good work martin !

Tested on the P200 board with the resistor ladderred key matrix, patch will be posted shortly.

For all the serie :
Tested-by: Neil Armstrong <narmstrong@baylibre.com>

^ permalink raw reply

* [PATCH] ARM64: meson-gxbb-p200: add ADC laddered keys
From: Neil Armstrong @ 2017-01-16 10:22 UTC (permalink / raw)
  To: linux-arm-kernel

Add the 5 buttons connected to a resistor laddered matrix and sampled
by the SAR ADC channel 0.

Only the p200 board has these buttons, the P201 doesn't.

Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
 arch/arm64/boot/dts/amlogic/meson-gxbb-p200.dts | 50 +++++++++++++++++++++++++
 1 file changed, 50 insertions(+)

This patch depends on Martin Blumenstingl's sar adc patchset at [1].

[1] http://lkml.kernel.org/r/20170115224221.15510-1-martin.blumenstingl at googlemail.com

diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-p200.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-p200.dts
index af7b151..3051cc8 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-p200.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-p200.dts
@@ -45,6 +45,7 @@
 /dts-v1/;
 
 #include "meson-gxbb-p20x.dtsi"
+#include <dt-bindings/input/input.h>
 
 / {
 	compatible = "amlogic,p200", "amlogic,meson-gxbb";
@@ -58,6 +59,50 @@
 		 */
 		linux,usable-memory = <0x0 0x1000000 0x0 0x3f000000>;
 	};
+
+	avdd18_usb_adc: regulator-avdd18_usb_adc {
+		compatible = "regulator-fixed";
+		regulator-name = "AVDD18_USB_ADC";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+	};
+
+	adc_keys {
+		compatible = "adc-keys";
+		io-channels = <&saradc 0>;
+		io-channel-names = "buttons";
+		keyup-threshold-microvolt = <1800000>;
+
+		button-home {
+			label = "Home";
+			linux,code = <KEY_HOME>;
+			press-threshold-microvolt = <900000>; /* 50% */
+		};
+
+		button-esc {
+			label = "Esc";
+			linux,code = <KEY_ESC>;
+			press-threshold-microvolt = <684000>; /* 38% */
+		};
+
+		button-up {
+			label = "Volume Up";
+			linux,code = <KEY_VOLUMEUP>;
+			press-threshold-microvolt = <468000>; /* 26% */
+		};
+
+		button-down {
+			label = "Volume Down";
+			linux,code = <KEY_VOLUMEDOWN>;
+			press-threshold-microvolt = <252000>; /* 14% */
+		};
+
+		button-menu {
+			label = "Menu";
+			linux,code = <KEY_MENU>;
+			press-threshold-microvolt = <0>; /* 0% */
+		};
+	};
 };
 
 &i2c_B {
@@ -65,3 +110,8 @@
 	pinctrl-0 = <&i2c_b_pins>;
 	pinctrl-names = "default";
 };
+
+&saradc {
+	status = "okay";
+	vref-supply = <&avdd18_usb_adc>;
+};
-- 
1.9.1

^ permalink raw reply related

* [PATCH 09/37] PCI: dwc: designware: Parse *num-lanes* property in dw_pcie_setup_rc
From: Joao Pinto @ 2017-01-16 10:23 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <587C57FD.7050601@ti.com>


Hi,

?s 5:19 AM de 1/16/2017, Kishon Vijay Abraham I escreveu:
> Hi,
> 
> On Friday 13 January 2017 10:43 PM, Joao Pinto wrote:
>> Hi,
>>
>> ?s 10:25 AM de 1/12/2017, Kishon Vijay Abraham I escreveu:
>>> *num-lanes* dt property is parsed in dw_pcie_host_init. However
>>> *num-lanes* property is applicable to both root complex mode and
>>> endpoint mode. As a first step, move the parsing of this property
>>> outside dw_pcie_host_init. This is in preparation for splitting
>>> pcie-designware.c to pcie-designware.c and pcie-designware-host.c
>>>
>>> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
>>> ---
>>>  drivers/pci/dwc/pcie-designware.c |   18 +++++++++++-------
>>>  drivers/pci/dwc/pcie-designware.h |    1 -
>>>  2 files changed, 11 insertions(+), 8 deletions(-)
>>>
>>> diff --git a/drivers/pci/dwc/pcie-designware.c b/drivers/pci/dwc/pcie-designware.c
>>> index 00a0fdc..89cdb6b 100644
>>> --- a/drivers/pci/dwc/pcie-designware.c
>>> +++ b/drivers/pci/dwc/pcie-designware.c
>>> @@ -551,10 +551,6 @@ int dw_pcie_host_init(struct pcie_port *pp)
>>>  		}
>>>  	}
>>>  
>>> -	ret = of_property_read_u32(np, "num-lanes", &pci->lanes);
>>> -	if (ret)
>>> -		pci->lanes = 0;
>>> -
>>>  	ret = of_property_read_u32(np, "num-viewport", &pci->num_viewport);
>>>  	if (ret)
>>>  		pci->num_viewport = 2;
>>> @@ -751,18 +747,26 @@ static int dw_pcie_wr_conf(struct pci_bus *bus, u32 devfn,
>>>  
>>>  void dw_pcie_setup_rc(struct pcie_port *pp)
>>>  {
>>> +	int ret;
>>> +	u32 lanes;
>>>  	u32 val;
>>>  	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
>>> +	struct device *dev = pci->dev;
>>> +	struct device_node *np = dev->of_node;
>>>  
>>>  	/* get iATU unroll support */
>>>  	pci->iatu_unroll_enabled = dw_pcie_iatu_unroll_enabled(pci);
>>>  	dev_dbg(pci->dev, "iATU unroll: %s\n",
>>>  		pci->iatu_unroll_enabled ? "enabled" : "disabled");
>>>  
>>> +	ret = of_property_read_u32(np, "num-lanes", &lanes);
>>> +	if (ret)
>>> +		lanes = 0;
>>
>> You moved from host_init to root complex setup function, which in my opinion did
>> not improve (in this scope).
>>
>> I suggest that instead of making so much intermediary patches, which is nice to
>> understand your development sequence, but hard to review. Wouldn't be better to
>> condense some of the patches? We would have a cloear vision of the final product :)
> 
> I thought the other way. If squashing patches is easier to review, I'll do it.

I understand. To break it in small pieces is good to understand clearly what is
done and how was done, but I would break too much. That's a personal opinion of
course, lets see what others say :).

Thanks,
Joao

> 
> Btw, thanks for reviewing.
> 
> Cheers
> Kishon
> 

^ permalink raw reply

* [v2 2/3] ARM: dts: STM32 Add USB FS host mode support
From: Bruno Herrera @ 2017-01-16 10:26 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <f1fac058-6c03-595a-0d67-a89fcf70d7cc@st.com>

Hi Alex,

On Mon, Jan 16, 2017 at 6:57 AM, Alexandre Torgue
<alexandre.torgue@st.com> wrote:
> Hi Bruno,
>
> On 01/16/2017 03:09 AM, Bruno Herrera wrote:
>>
>> This patch adds the USB pins and nodes for USB HS/FS cores working at FS
>> speed,
>> using embedded PHY.
>>
>> Signed-off-by: Bruno Herrera <bruherrera@gmail.com>
>
>
> Sorry, but what is patch 1 & pacth 3 status ?

My bad, I'll add the status of the patch series version 3.
>
> For this one, can split it in 3 patches (one patch for SOC and one for each
> board) please.
>

No problem.
>
>
>> ---
>>  arch/arm/boot/dts/stm32f429-disco.dts | 30 ++++++++++++++++++++++++++++++
>>  arch/arm/boot/dts/stm32f429.dtsi      | 35
>> ++++++++++++++++++++++++++++++++++-
>>  arch/arm/boot/dts/stm32f469-disco.dts | 30 ++++++++++++++++++++++++++++++
>>  3 files changed, 94 insertions(+), 1 deletion(-)
>>
>> diff --git a/arch/arm/boot/dts/stm32f429-disco.dts
>> b/arch/arm/boot/dts/stm32f429-disco.dts
>> index 7d0415e..374c5ed 100644
>> --- a/arch/arm/boot/dts/stm32f429-disco.dts
>> +++ b/arch/arm/boot/dts/stm32f429-disco.dts
>> @@ -88,6 +88,16 @@
>>                         gpios = <&gpioa 0 0>;
>>                 };
>>         };
>> +
>> +       /* This turns on vbus for otg for host mode (dwc2) */
>> +       vcc5v_otg: vcc5v-otg-regulator {
>> +               compatible = "regulator-fixed";
>> +               gpio = <&gpioc 4 0>;
>> +               pinctrl-names = "default";
>> +               pinctrl-0 = <&usbotg_pwren_h>;
>> +               regulator-name = "vcc5_host1";
>> +               regulator-always-on;
>> +       };
>>  };
>>
>>  &clk_hse {
>> @@ -99,3 +109,23 @@
>>         pinctrl-names = "default";
>>         status = "okay";
>>  };
>> +
>> +&usbotg_hs {
>> +       compatible = "st,stm32-fsotg", "snps,dwc2";
>> +       dr_mode = "host";
>> +       pinctrl-0 = <&usbotg_fs_pins_b>;
>> +       pinctrl-names = "default";
>> +       status = "okay";
>> +};
>> +
>> +&pinctrl {
>> +       usb-host {
>> +               usbotg_pwren_h: usbotg-pwren-h {
>> +                       pins {
>> +                               pinmux = <STM32F429_PC4_FUNC_GPIO>;
>> +                               bias-disable;
>> +                               drive-push-pull;
>> +                       };
>> +               };
>> +       };
>> +};
>
>
> Pinctrl muxing has to be defined/declared in stm32f429.dtsi
>
This is board specific logic and it vary from board to board, should
it be defined here?
>
>
>> diff --git a/arch/arm/boot/dts/stm32f429.dtsi
>> b/arch/arm/boot/dts/stm32f429.dtsi
>> index e4dae0e..bc07aa8 100644
>> --- a/arch/arm/boot/dts/stm32f429.dtsi
>> +++ b/arch/arm/boot/dts/stm32f429.dtsi
>> @@ -206,7 +206,7 @@
>>                         reg = <0x40007000 0x400>;
>>                 };
>>
>> -               pin-controller {
>> +               pinctrl: pin-controller {
>>                         #address-cells = <1>;
>>                         #size-cells = <1>;
>>                         compatible = "st,stm32f429-pinctrl";
>> @@ -316,6 +316,30 @@
>>                                 };
>>                         };
>>
>> +                       usbotg_fs_pins_a: usbotg_fs at 0 {
>> +                               pins {
>> +                                       pinmux =
>> <STM32F429_PA10_FUNC_OTG_FS_ID>,
>> +
>> <STM32F429_PA11_FUNC_OTG_FS_DM>,
>> +
>> <STM32F429_PA12_FUNC_OTG_FS_DP>;
>> +                                       bias-disable;
>> +                                       drive-push-pull;
>> +                                       slew-rate = <2>;
>> +                               };
>> +                       };
>> +
>> +                       usbotg_fs_pins_b: usbotg_fs at 1 {
>> +                               pins {
>> +                                       pinmux =
>> <STM32F429_PB12_FUNC_OTG_HS_ID>,
>> +
>> <STM32F429_PB14_FUNC_OTG_HS_DM>,
>> +
>> <STM32F429_PB15_FUNC_OTG_HS_DP>;
>> +                                       bias-disable;
>> +                                       drive-push-pull;
>> +                                       slew-rate = <2>;
>> +                               };
>> +                       };
>> +
>> +
>> +
>>                         usbotg_hs_pins_a: usbotg_hs at 0 {
>>                                 pins {
>>                                         pinmux =
>> <STM32F429_PH4_FUNC_OTG_HS_ULPI_NXT>,
>> @@ -420,6 +444,15 @@
>>                         status = "disabled";
>>                 };
>>
>> +               usbotg_fs: usb at 50000000 {
>> +                       compatible = "st,stm32f4xx-fsotg", "snps,dwc2";
>> +                       reg = <0x50000000 0x40000>;
>> +                       interrupts = <67>;
>> +                       clocks = <&rcc 0 39>;
>> +                       clock-names = "otg";
>> +                       status = "disabled";
>> +               };
>> +
>>                 rng: rng at 50060800 {
>>                         compatible = "st,stm32-rng";
>>                         reg = <0x50060800 0x400>;
>> diff --git a/arch/arm/boot/dts/stm32f469-disco.dts
>> b/arch/arm/boot/dts/stm32f469-disco.dts
>> index 8877c00..8ae6763 100644
>> --- a/arch/arm/boot/dts/stm32f469-disco.dts
>> +++ b/arch/arm/boot/dts/stm32f469-disco.dts
>> @@ -68,6 +68,17 @@
>>         soc {
>>                 dma-ranges = <0xc0000000 0x0 0x10000000>;
>>         };
>> +
>> +       /* This turns on vbus for otg for host mode (dwc2) */
>> +       vcc5v_otg: vcc5v-otg-regulator {
>> +               compatible = "regulator-fixed";
>> +               enable-active-high;
>> +               gpio = <&gpiob 2 0>;
>> +               pinctrl-names = "default";
>> +               pinctrl-0 = <&usbotg_pwren_h>;
>> +               regulator-name = "vcc5_host1";
>> +               regulator-always-on;
>> +       };
>>  };
>>
>>  &rcc {
>> @@ -81,3 +92,22 @@
>>  &usart3 {
>>         status = "okay";
>>  };
>> +
>> +&usbotg_fs {
>> +       dr_mode = "host";
>> +       pinctrl-0 = <&usbotg_fs_pins_a>;
>> +       pinctrl-names = "default";
>> +       status = "okay";
>> +};
>> +
>> +&pinctrl {
>> +       usb-host {
>> +               usbotg_pwren_h: usbotg-pwren-h {
>> +                       pins {
>> +                               pinmux = <STM32F429_PB2_FUNC_GPIO>;
>> +                               bias-disable;
>> +                               drive-push-pull;
>> +                       };
>> +               };
>> +       };
>> +};
>
> Same. Note that if you have 2 configuration for one feature (like it is here
> for "usbotg_pwren_h"), you could index it. Not that I'm adding a dedidacted
> pinctroller for stm32f469.
>
Sorry, but I dont know what you mean by index here.
The usbotg_pwren_h (VBUS ENABLE) is attached in different port/pins
for each board.

Br.,


> Br
> Alex
>>
>>
>
>

^ permalink raw reply

* [RFT PATCH] ARM64: dts: meson-gxbb: Add reserved memory zone and usable memory range
From: Neil Armstrong @ 2017-01-16 10:26 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <612bc7bc-4ee4-51c0-d7ac-06151854ac03@suse.de>

On 01/15/2017 04:44 PM, Andreas F?rber wrote:
> Am 23.12.2016 um 10:42 schrieb Heinrich Schuchardt:
>> it really makes a difference if we write
>>
>>  	memory at 0 {
>>  		device_type = "memory";
>>  		linux,usable-memory = <0x0 0x1000000 0x0 0x7f000000>;
>>  	};
>>
>> or
>>
>>  	memory at 0 {
>>  		device_type = "memory";
>>  		reg = <0x0 0x1000000 0x0 0x7f000000>;
>>  	};
>>
>> The second version leads to failure of the Odroid C2.
>>
>> When I looked at /sys/firmware/fdt I saw this difference:
>>
>> --- fails
>> +++ works
>>
>>         memory at 0 {
>> -               device_type = "memory";
>>                 reg = <0x0 0x0 0x0 0x78000000>;
>> +               device_type = "memory";
>> +               linux,usable-memory = <0x0 0x1000000 0x0 0x7f000000>;
>>         };
>>
>> I found the following sentence in the NXP forum:
>> In case you want to overwrite the memory usage passed from u-boot, you
>> can use "linux,usable-memory".
>> https://community.nxp.com/thread/382284
> 
> The Odroid-C2 is in mainline U-Boot. Please submit a patch to U-Boot
> instead of forcing the creation of unnecessary new .dts files onto
> everyone due to hardcoded linux,usable-memory properties. In fact, it
> already reserves 0x1000000, so it seems you are merely using an older
> U-Boot.
> 
> http://git.denx.de/?p=u-boot.git;a=blob;f=arch/arm/mach-meson/board.c;h=f159cbf849f75ab046e6f3a025bbc97c0bcfd59d;hb=HEAD#l39
> 
> I would bet that the upper limit is unrelated here.
> 
> Regards,
> Andreas
> 

Hi Andreas,

I really disagree about relying on any work or properties added by any bootloader here, Amlogic SoCs has
a lot of u-boot version in the field, and the Odroid-C2 is part of this.

Even if Odroid-c2 is in mainline U-Boot or not, the mainline Linux kernel should work using
any U-boot version even with the one provided by Amlogic on their openlinux distribution channel.

Neil

^ permalink raw reply

* [PATCH] usb: gadget: udc: atmel: used managed kasprintf
From: Felipe Balbi @ 2017-01-16 10:27 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <063D6719AE5E284EB5DD2968C1650D6DB023508B@AcuExch.aculab.com>


Hi,

David Laight <David.Laight@ACULAB.COM> writes:
> From: Alexandre Belloni
>> Sent: 02 December 2016 16:19
>> On 02/12/2016 at 15:59:57 +0000, David Laight wrote :
>> > From: Alexandre Belloni
>> > > Sent: 01 December 2016 10:27
>> > > Use devm_kasprintf instead of simple kasprintf to free the allocated memory
>> > > when needed.
>> >
>> > s/when needed/when the device is freed/
>> >
>> > > Suggested-by: Peter Rosin <peda@axentia.se>
>> > > Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
>> > > ---
>> > >  drivers/usb/gadget/udc/atmel_usba_udc.c | 3 ++-
>> > >  1 file changed, 2 insertions(+), 1 deletion(-)
>> > >
>> > > diff --git a/drivers/usb/gadget/udc/atmel_usba_udc.c b/drivers/usb/gadget/udc/atmel_usba_udc.c
>> > > index 45bc997d0711..aec72fe8273c 100644
>> > > --- a/drivers/usb/gadget/udc/atmel_usba_udc.c
>> > > +++ b/drivers/usb/gadget/udc/atmel_usba_udc.c
>> > > @@ -1978,7 +1978,8 @@ static struct usba_ep * atmel_udc_of_init(struct platform_device *pdev,
>> > >  			dev_err(&pdev->dev, "of_probe: name error(%d)\n", ret);
>> > >  			goto err;
>> > >  		}
>> > > -		ep->ep.name = kasprintf(GFP_KERNEL, "ep%d", ep->index);
>> > > +		ep->ep.name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "ep%d",
>> > > +					     ep->index);
>> >
>> > Acually why bother mallocing such a small string at all.
>> > The maximum length is 12 bytes even if 'index' are unrestricted.
>> >
>> 
>> IIRC, using statically allocated string is failing somewhere is the USB
>> core but I don't remember all the details.
>
> I can't imagine that changing ep->ep.name from 'char *' to 'char [12]' would
> make any difference.

the actual name is managed by the UDC. Meaning, ep->ep.name should be a
pointer, but it could very well just point to ep->name which would be
char [12].

-- 
balbi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 832 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20170116/9893a195/attachment.sig>

^ permalink raw reply

* [PATCH 11/37] PCI: dwc: Split pcie-designware.c into host and core files
From: Joao Pinto @ 2017-01-16 10:27 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <587C586C.6070003@ti.com>


Hi,

?s 5:21 AM de 1/16/2017, Kishon Vijay Abraham I escreveu:
> Hi Joao,
> 
> On Friday 13 January 2017 10:19 PM, Joao Pinto wrote:
>> ?s 10:26 AM de 1/12/2017, Kishon Vijay Abraham I escreveu:
>>> Split pcie-designware.c into pcie-designware-host.c that contains
>>> the host specific parts of the driver and pcie-designware.c that
>>> contains the parts used by both host driver and endpoint driver.
>>>
>>> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
>>> ---
>>>  drivers/pci/dwc/Makefile               |    2 +-
>>>  drivers/pci/dwc/pcie-designware-host.c |  619 ++++++++++++++++++++++++++++++++
>>>  drivers/pci/dwc/pcie-designware.c      |  613 +------------------------------
>>>  drivers/pci/dwc/pcie-designware.h      |    8 +
>>>  4 files changed, 634 insertions(+), 608 deletions(-)
>>>  create mode 100644 drivers/pci/dwc/pcie-designware-host.c
>>>
>>> diff --git a/drivers/pci/dwc/Makefile b/drivers/pci/dwc/Makefile
>>> index 7d27c14..3b57e55 100644
>>> --- a/drivers/pci/dwc/Makefile
>>> +++ b/drivers/pci/dwc/Makefile
>>> @@ -1,4 +1,4 @@
>>
>> (snip...)
>>
>>> -static void dw_pcie_prog_outbound_atu(struct dw_pcie *pci, int index,
>>> -				      int type, u64 cpu_addr, u64 pci_addr,
>>> -				      u32 size)
>>> +void dw_pcie_prog_outbound_atu(struct dw_pcie *pci, int index, int type,
>>> +			       u64 cpu_addr, u64 pci_addr, u32 size)
>>>  {
>>>  	u32 retries, val;
>>>  
>>> @@ -186,220 +151,6 @@ static void dw_pcie_prog_outbound_atu(struct dw_pcie *pci, int index,
>>>  	dev_err(pci->dev, "iATU is not being enabled\n");
>>>  }
>>
>> Kishon, iATU only makes sense in The Root Complex (host), so it should be inside
>> the pcie-designware-host.
> 
> That is not true. Outbound ATU should be programmed to access host side buffers
> and inbound ATU should be programmed for the host to access EP mem space.

Sorry, I was not clear enough. What I was trying to suggest is, since the ATU
programming is done by the host, wouldn't be better to include it in the
pcie-designware-host? It is just an architectural detail.

> 
> Thanks
> Kishon
> 

^ 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