All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Heiko Stübner" <heiko@sntech.de>
To: David Wu <wdc@rock-chips.com>
Cc: linus.walleij@linaro.org, huangtao@rock-chips.com,
	zyw@rock-chips.com, cf@rock-chips.com, xjq@rock-chips.com,
	linux-arm-kernel@lists.infradead.org,
	linux-rockchip@lists.infradead.org, linux-gpio@vger.kernel.org,
	linux-kernel@vger.kernel.org, David Wu <david.wu@rock-chips.com>
Subject: Re: [PATCH v2] pinctrl: rockchip: add support for the rk3399
Date: Thu, 28 Jan 2016 17:56:45 +0100	[thread overview]
Message-ID: <7536813.E6m4KCLL9V@diego> (raw)
In-Reply-To: <1452152498-21780-1-git-send-email-wdc@rock-chips.com>

Hi David,

Am Donnerstag, 7. Januar 2016, 15:41:38 schrieb David Wu:
> From: David Wu <david.wu@rock-chips.com>
> 
> The pinctrl of rk3399 is much different from other's,
> especially the 3bits of drive strength.
> 
> Signed-off-by: David Wu <david.wu@rock-chips.com>
> ---
> change from v1:
> - need spin_unlock_irqrestore for set drive default case
> 
>  .../bindings/pinctrl/rockchip,pinctrl.txt          |   1 +
>  drivers/pinctrl/pinctrl-rockchip.c                 | 339
> ++++++++++++++++++++- 2 files changed, 326 insertions(+), 14 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/pinctrl/rockchip,pinctrl.txt
> b/Documentation/devicetree/bindings/pinctrl/rockchip,pinctrl.txt index
> 391ef4b..3bb9456 100644
> --- a/Documentation/devicetree/bindings/pinctrl/rockchip,pinctrl.txt
> +++ b/Documentation/devicetree/bindings/pinctrl/rockchip,pinctrl.txt
> @@ -22,6 +22,7 @@ Required properties for iomux controller:
>    - compatible: one of "rockchip,rk2928-pinctrl",
> "rockchip,rk3066a-pinctrl" "rockchip,rk3066b-pinctrl",
> "rockchip,rk3188-pinctrl"
>  		       "rockchip,rk3288-pinctrl", "rockchip,rk3368-pinctrl"
> +		       "rockchip,rk3399-pinctrl"
>    - rockchip,grf: phandle referencing a syscon providing the
>  	 "general register files"
> 
> diff --git a/drivers/pinctrl/pinctrl-rockchip.c
> b/drivers/pinctrl/pinctrl-rockchip.c index a065112..9d61c6e 100644
> --- a/drivers/pinctrl/pinctrl-rockchip.c
> +++ b/drivers/pinctrl/pinctrl-rockchip.c

[...]

> @@ -685,19 +821,60 @@ static int rockchip_get_drive_perpin(struct
> rockchip_pin_bank *bank, struct rockchip_pin_ctrl *ctrl = info->ctrl;
>  	struct regmap *regmap;
>  	int reg, ret;
> -	u32 data;
> +	u32 data, temp, rmask_bits;
>  	u8 bit;
> +	int drv_type = bank->drv[pin_num / 8].drv_type;
> 
>  	ctrl->drv_calc_reg(bank, pin_num, &regmap, &reg, &bit);
> 
> +	switch (drv_type) {
> +	case DRV_TYPE_IO_1V8_3V0_AUTO:
> +	case DRV_TYPE_IO_3V3_ONLY:
> +		if (RK3399_DRV_3BITS_PER_PIN + bit >= 16) {

According to the doc excerpts, wouldn't the big special handling only be 
necessary for for gpio3b5 alone (+ other banks) ... i.e. the one setting being 
split over both registers?
If so I think doing something like the following might be easier to 
understand? Same of course for the set-counterpart. [Beware if I missed up the 
indices somewhere :-) ]

rmask_bits = RK3399_DRV_3BITS_PER_PIN;
switch(bit) {
case 0 ... 12:
	/* regular case, nothing to do */
	break;
case 15:
	/* drive-strength offset is special, as it is spread over 2 registers */
	ret = regmap_read(regmap, reg, &data);
	if (ret)
		return ret;

	ret = regmap_read(regmap, reg + 0x4, &temp);
	if (ret)
		return ret;

	/*
	 * the bit data[15] contains bit 0 of the value
	 * while temp[1:0] containts bits 2 and 1
	 */
	data >>= 15;
	temp &= 0x3;
	temp <<= 1;
	data |= temp;

	return rockchip_perpin_drv_list[drv_type][data];
case 18 ... 21:
	/* setting fully enclosed in the second register */
	rmask_bits = RK3399_DRV_3BITS_PER_PIN;
	reg += 4;
	bit -= 18;
}

> +			/* need to read regs twice */
> +			ret = regmap_read(regmap, reg, &temp);
> +			if (ret)
> +				return ret;
> +
> +			temp >>= bit;
> +			rmask_bits = 16 - bit;
> +			temp &= (1 << rmask_bits) - 1;
> +
> +			reg = reg + 0x4;
> +			ret = regmap_read(regmap, reg, &data);
> +			if (ret)
> +				return ret;
> +
> +			rmask_bits = RK3399_DRV_3BITS_PER_PIN
> +				+ bit - 16;
> +			data &= (1 << rmask_bits) - 1;
> +			data <<= 16 - bit;
> +			data |= temp;
> +
> +			return rockchip_perpin_drv_list[drv_type][data];
> +		}
> +
> +		rmask_bits = RK3399_DRV_3BITS_PER_PIN;
> +		break;
> +	case DRV_TYPE_IO_DEFAULT:
> +	case DRV_TYPE_IO_1V8_OR_3V0:
> +	case DRV_TYPE_IO_1V8_ONLY:
> +		rmask_bits = RK3288_DRV_BITS_PER_PIN;
> +		break;
> +	default:
> +		dev_err(info->dev, "unsupported pinctrl drive type: %d\n",
> +			drv_type);
> +		return -EINVAL;
> +	}
> +
>  	ret = regmap_read(regmap, reg, &data);
>  	if (ret)
>  		return ret;
> 
>  	data >>= bit;
> -	data &= (1 << RK3288_DRV_BITS_PER_PIN) - 1;
> +	data &= (1 << rmask_bits) - 1;
> 
> -	return rockchip_perpin_drv_list[data];
> +	return rockchip_perpin_drv_list[drv_type][data];
>  }
> 
>  static int rockchip_set_drive_perpin(struct rockchip_pin_bank *bank,

[...]

> @@ -729,8 +913,45 @@ static int rockchip_set_drive_perpin(struct
> rockchip_pin_bank *bank,
> 
>  	spin_lock_irqsave(&bank->slock, flags);
> 
> +	switch (drv_type) {
> +	case DRV_TYPE_IO_1V8_3V0_AUTO:
> +	case DRV_TYPE_IO_3V3_ONLY:
> +		if (RK3399_DRV_3BITS_PER_PIN + bit >= 16) {
> +			/* need to write regs twice */
> +			rmask_bits = 16 - bit;
> +			/* enable the write to the equivalent lower bits */
> +			data = ((1 << rmask_bits) - 1) << (bit + 16);
> +			rmask = data | (data >> 16);
> +			ret &= (1 << rmask_bits) - 1;
> +			data |= (ret << bit);
> +
> +			ret = regmap_update_bits(regmap, reg, rmask, data);
> +			if (ret)
> +				return ret;
> +
> +			ret = i >> rmask_bits;
> +			rmask_bits = RK3399_DRV_3BITS_PER_PIN + bit - 16;
> +			reg = reg + 0x4;
> +			bit = 0;

Apart from a change similar to the above, should the setting maybe also 
directly return and not depend on the final write?

> +		} else {
> +			rmask_bits = RK3399_DRV_3BITS_PER_PIN;
> +		}
> +		break;
> +	case DRV_TYPE_IO_DEFAULT:
> +	case DRV_TYPE_IO_1V8_OR_3V0:
> +	case DRV_TYPE_IO_1V8_ONLY:
> +		rmask_bits = RK3288_DRV_BITS_PER_PIN;
> +		break;
> +	default:
> +		spin_unlock_irqrestore(&bank->slock, flags);
> +		dev_err(info->dev, "unsupported pinctrl drive type: %d\n",
> +			drv_type);
> +		return -EINVAL;
> +
> +	}
> +
>  	/* enable the write to the equivalent lower bits */
> -	data = ((1 << RK3288_DRV_BITS_PER_PIN) - 1) << (bit + 16);
> +	data = ((1 << rmask_bits) - 1) << (bit + 16);
>  	rmask = data | (data >> 16);
>  	data |= (ret << bit);
> 

[...]

> @@ -2208,6 +2461,62 @@ static struct rockchip_pin_ctrl rk3368_pin_ctrl = {
>  		.drv_calc_reg		= rk3368_calc_drv_reg_and_bit,
>  };
> 
> +static struct rockchip_pin_bank rk3399_pin_banks[] = {
> +	PIN_BANK_IOMUX_DRV_FLAGS_OFFSET(0, 32, "gpio0", IOMUX_SOURCE_PMU,
> +					IOMUX_SOURCE_PMU,
> +					IOMUX_SOURCE_PMU,
> +					IOMUX_SOURCE_PMU,
> +					DRV_TYPE_IO_1V8_ONLY,
> +					DRV_TYPE_IO_1V8_ONLY,
> +					0,
> +					0,

DRV_TYPE_IO_DEFAULT instead of 0 please.


WARNING: multiple messages have this Message-ID (diff)
From: heiko@sntech.de (Heiko Stübner)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v2] pinctrl: rockchip: add support for the rk3399
Date: Thu, 28 Jan 2016 17:56:45 +0100	[thread overview]
Message-ID: <7536813.E6m4KCLL9V@diego> (raw)
In-Reply-To: <1452152498-21780-1-git-send-email-wdc@rock-chips.com>

Hi David,

Am Donnerstag, 7. Januar 2016, 15:41:38 schrieb David Wu:
> From: David Wu <david.wu@rock-chips.com>
> 
> The pinctrl of rk3399 is much different from other's,
> especially the 3bits of drive strength.
> 
> Signed-off-by: David Wu <david.wu@rock-chips.com>
> ---
> change from v1:
> - need spin_unlock_irqrestore for set drive default case
> 
>  .../bindings/pinctrl/rockchip,pinctrl.txt          |   1 +
>  drivers/pinctrl/pinctrl-rockchip.c                 | 339
> ++++++++++++++++++++- 2 files changed, 326 insertions(+), 14 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/pinctrl/rockchip,pinctrl.txt
> b/Documentation/devicetree/bindings/pinctrl/rockchip,pinctrl.txt index
> 391ef4b..3bb9456 100644
> --- a/Documentation/devicetree/bindings/pinctrl/rockchip,pinctrl.txt
> +++ b/Documentation/devicetree/bindings/pinctrl/rockchip,pinctrl.txt
> @@ -22,6 +22,7 @@ Required properties for iomux controller:
>    - compatible: one of "rockchip,rk2928-pinctrl",
> "rockchip,rk3066a-pinctrl" "rockchip,rk3066b-pinctrl",
> "rockchip,rk3188-pinctrl"
>  		       "rockchip,rk3288-pinctrl", "rockchip,rk3368-pinctrl"
> +		       "rockchip,rk3399-pinctrl"
>    - rockchip,grf: phandle referencing a syscon providing the
>  	 "general register files"
> 
> diff --git a/drivers/pinctrl/pinctrl-rockchip.c
> b/drivers/pinctrl/pinctrl-rockchip.c index a065112..9d61c6e 100644
> --- a/drivers/pinctrl/pinctrl-rockchip.c
> +++ b/drivers/pinctrl/pinctrl-rockchip.c

[...]

> @@ -685,19 +821,60 @@ static int rockchip_get_drive_perpin(struct
> rockchip_pin_bank *bank, struct rockchip_pin_ctrl *ctrl = info->ctrl;
>  	struct regmap *regmap;
>  	int reg, ret;
> -	u32 data;
> +	u32 data, temp, rmask_bits;
>  	u8 bit;
> +	int drv_type = bank->drv[pin_num / 8].drv_type;
> 
>  	ctrl->drv_calc_reg(bank, pin_num, &regmap, &reg, &bit);
> 
> +	switch (drv_type) {
> +	case DRV_TYPE_IO_1V8_3V0_AUTO:
> +	case DRV_TYPE_IO_3V3_ONLY:
> +		if (RK3399_DRV_3BITS_PER_PIN + bit >= 16) {

According to the doc excerpts, wouldn't the big special handling only be 
necessary for for gpio3b5 alone (+ other banks) ... i.e. the one setting being 
split over both registers?
If so I think doing something like the following might be easier to 
understand? Same of course for the set-counterpart. [Beware if I missed up the 
indices somewhere :-) ]

rmask_bits = RK3399_DRV_3BITS_PER_PIN;
switch(bit) {
case 0 ... 12:
	/* regular case, nothing to do */
	break;
case 15:
	/* drive-strength offset is special, as it is spread over 2 registers */
	ret = regmap_read(regmap, reg, &data);
	if (ret)
		return ret;

	ret = regmap_read(regmap, reg + 0x4, &temp);
	if (ret)
		return ret;

	/*
	 * the bit data[15] contains bit 0 of the value
	 * while temp[1:0] containts bits 2 and 1
	 */
	data >>= 15;
	temp &= 0x3;
	temp <<= 1;
	data |= temp;

	return rockchip_perpin_drv_list[drv_type][data];
case 18 ... 21:
	/* setting fully enclosed in the second register */
	rmask_bits = RK3399_DRV_3BITS_PER_PIN;
	reg += 4;
	bit -= 18;
}

> +			/* need to read regs twice */
> +			ret = regmap_read(regmap, reg, &temp);
> +			if (ret)
> +				return ret;
> +
> +			temp >>= bit;
> +			rmask_bits = 16 - bit;
> +			temp &= (1 << rmask_bits) - 1;
> +
> +			reg = reg + 0x4;
> +			ret = regmap_read(regmap, reg, &data);
> +			if (ret)
> +				return ret;
> +
> +			rmask_bits = RK3399_DRV_3BITS_PER_PIN
> +				+ bit - 16;
> +			data &= (1 << rmask_bits) - 1;
> +			data <<= 16 - bit;
> +			data |= temp;
> +
> +			return rockchip_perpin_drv_list[drv_type][data];
> +		}
> +
> +		rmask_bits = RK3399_DRV_3BITS_PER_PIN;
> +		break;
> +	case DRV_TYPE_IO_DEFAULT:
> +	case DRV_TYPE_IO_1V8_OR_3V0:
> +	case DRV_TYPE_IO_1V8_ONLY:
> +		rmask_bits = RK3288_DRV_BITS_PER_PIN;
> +		break;
> +	default:
> +		dev_err(info->dev, "unsupported pinctrl drive type: %d\n",
> +			drv_type);
> +		return -EINVAL;
> +	}
> +
>  	ret = regmap_read(regmap, reg, &data);
>  	if (ret)
>  		return ret;
> 
>  	data >>= bit;
> -	data &= (1 << RK3288_DRV_BITS_PER_PIN) - 1;
> +	data &= (1 << rmask_bits) - 1;
> 
> -	return rockchip_perpin_drv_list[data];
> +	return rockchip_perpin_drv_list[drv_type][data];
>  }
> 
>  static int rockchip_set_drive_perpin(struct rockchip_pin_bank *bank,

[...]

> @@ -729,8 +913,45 @@ static int rockchip_set_drive_perpin(struct
> rockchip_pin_bank *bank,
> 
>  	spin_lock_irqsave(&bank->slock, flags);
> 
> +	switch (drv_type) {
> +	case DRV_TYPE_IO_1V8_3V0_AUTO:
> +	case DRV_TYPE_IO_3V3_ONLY:
> +		if (RK3399_DRV_3BITS_PER_PIN + bit >= 16) {
> +			/* need to write regs twice */
> +			rmask_bits = 16 - bit;
> +			/* enable the write to the equivalent lower bits */
> +			data = ((1 << rmask_bits) - 1) << (bit + 16);
> +			rmask = data | (data >> 16);
> +			ret &= (1 << rmask_bits) - 1;
> +			data |= (ret << bit);
> +
> +			ret = regmap_update_bits(regmap, reg, rmask, data);
> +			if (ret)
> +				return ret;
> +
> +			ret = i >> rmask_bits;
> +			rmask_bits = RK3399_DRV_3BITS_PER_PIN + bit - 16;
> +			reg = reg + 0x4;
> +			bit = 0;

Apart from a change similar to the above, should the setting maybe also 
directly return and not depend on the final write?

> +		} else {
> +			rmask_bits = RK3399_DRV_3BITS_PER_PIN;
> +		}
> +		break;
> +	case DRV_TYPE_IO_DEFAULT:
> +	case DRV_TYPE_IO_1V8_OR_3V0:
> +	case DRV_TYPE_IO_1V8_ONLY:
> +		rmask_bits = RK3288_DRV_BITS_PER_PIN;
> +		break;
> +	default:
> +		spin_unlock_irqrestore(&bank->slock, flags);
> +		dev_err(info->dev, "unsupported pinctrl drive type: %d\n",
> +			drv_type);
> +		return -EINVAL;
> +
> +	}
> +
>  	/* enable the write to the equivalent lower bits */
> -	data = ((1 << RK3288_DRV_BITS_PER_PIN) - 1) << (bit + 16);
> +	data = ((1 << rmask_bits) - 1) << (bit + 16);
>  	rmask = data | (data >> 16);
>  	data |= (ret << bit);
> 

[...]

> @@ -2208,6 +2461,62 @@ static struct rockchip_pin_ctrl rk3368_pin_ctrl = {
>  		.drv_calc_reg		= rk3368_calc_drv_reg_and_bit,
>  };
> 
> +static struct rockchip_pin_bank rk3399_pin_banks[] = {
> +	PIN_BANK_IOMUX_DRV_FLAGS_OFFSET(0, 32, "gpio0", IOMUX_SOURCE_PMU,
> +					IOMUX_SOURCE_PMU,
> +					IOMUX_SOURCE_PMU,
> +					IOMUX_SOURCE_PMU,
> +					DRV_TYPE_IO_1V8_ONLY,
> +					DRV_TYPE_IO_1V8_ONLY,
> +					0,
> +					0,

DRV_TYPE_IO_DEFAULT instead of 0 please.

  parent reply	other threads:[~2016-01-28 16:56 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-01-05 12:30 [PATCH] pinctrl: rockchip: add support for the rk3399 David Wu
2016-01-05 12:30 ` David Wu
2016-01-07  7:41 ` [PATCH v2] " David Wu
2016-01-07  7:41   ` David Wu
2016-01-27 14:02   ` Linus Walleij
2016-01-27 14:02     ` Linus Walleij
2016-01-27 14:10     ` Heiko Stübner
2016-01-27 14:10       ` Heiko Stübner
2016-01-28 16:56   ` Heiko Stübner [this message]
2016-01-28 16:56     ` Heiko Stübner
2016-01-29 11:35     ` David.Wu
2016-01-29 11:35       ` David.Wu
2016-01-29 11:35       ` David.Wu
2016-01-30 11:31 ` [PATCH v3 0/2] add pinctrl support for rk3399 David Wu
2016-01-30 11:31   ` David Wu
2016-01-30 11:31   ` [PATCH v3 1/2] pinctrl: rockchip: add support for the rk3399 David Wu
2016-01-30 11:31     ` David Wu
2016-01-30 11:31   ` [PATCH v3 2/2] dt-bindings: rockchip-pinctrl: Support the RK3399 SoCs compatible David Wu
2016-01-30 11:31     ` David Wu
2016-01-30 12:16     ` Heiko Stuebner
2016-01-30 12:16       ` Heiko Stuebner
2016-02-01  2:35       ` David.Wu
2016-02-01  2:35         ` David.Wu
2016-02-01  2:35         ` David.Wu
2016-02-11 13:52       ` Linus Walleij
2016-02-11 13:52         ` Linus Walleij

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=7536813.E6m4KCLL9V@diego \
    --to=heiko@sntech.de \
    --cc=cf@rock-chips.com \
    --cc=david.wu@rock-chips.com \
    --cc=huangtao@rock-chips.com \
    --cc=linus.walleij@linaro.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-gpio@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-rockchip@lists.infradead.org \
    --cc=wdc@rock-chips.com \
    --cc=xjq@rock-chips.com \
    --cc=zyw@rock-chips.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.