All of lore.kernel.org
 help / color / mirror / Atom feed
* [U-Boot] [PATCH 1/1] reset: sti: add deassert counter in reset channel descriptor
@ 2017-05-18  7:58 patrice.chotard at st.com
  2017-05-22 20:26 ` Simon Glass
  2017-06-06  0:21 ` [U-Boot] [U-Boot, " Tom Rini
  0 siblings, 2 replies; 3+ messages in thread
From: patrice.chotard at st.com @ 2017-05-18  7:58 UTC (permalink / raw)
  To: u-boot

From: Patrice Chotard <patrice.chotard@st.com>

This deassert counter allow to manage "shared" reset lines
encountered in some specific case. On STiH410 SoC, DWC3,
EHCI and OHCI are all using a respective PHY, but all of
these PHYs shared a "global" reset.

Currently, during command "usb stop", all host controller are
stopped (XHCI, EHCI and OHCI). XHCI is first shutdowned, which
means that PHY global reset is asserted. Then EHCI is shutdowned,
but its PHY reset has already been asserted which make handshake()
call failed in ehci_shutdown().

This counter allows to really assert a reset lines only when the
"last" user is asserting it.

Signed-off-by: Patrice Chotard <patrice.chotard@st.com>
---
 drivers/reset/sti-reset.c | 41 ++++++++++++++++++++++++++++++-----------
 1 file changed, 30 insertions(+), 11 deletions(-)

diff --git a/drivers/reset/sti-reset.c b/drivers/reset/sti-reset.c
index 0c32a3d..a79708c 100644
--- a/drivers/reset/sti-reset.c
+++ b/drivers/reset/sti-reset.c
@@ -30,6 +30,8 @@ struct sti_reset {
  * @reset_bit: Bit number in reset register.
  * @ack_offset: Ack reset register offset in syscon bank.
  * @ack_bit: Bit number in Ack reset register.
+ * @deassert_cnt: incremented when reset is deasserted, reset can only be
+ *                asserted when equal to 0
  */
 
 struct syscfg_reset_channel_data {
@@ -38,6 +40,7 @@ struct syscfg_reset_channel_data {
 	int reset_bit;
 	int ack_offset;
 	int ack_bit;
+	int deassert_cnt;
 };
 
 /**
@@ -54,7 +57,7 @@ struct syscfg_reset_controller_data {
 	bool wait_for_ack;
 	bool active_low;
 	int nr_channels;
-	const struct syscfg_reset_channel_data *channels;
+	struct syscfg_reset_channel_data *channels;
 };
 
 /* STiH407 Peripheral powerdown definitions. */
@@ -102,7 +105,7 @@ static const char stih407_lpm[] = "st,stih407-lpm-syscfg";
 #define SYSSTAT_4520	0x820
 #define SYSCFG_4002	0x8
 
-static const struct syscfg_reset_channel_data stih407_powerdowns[] = {
+static struct syscfg_reset_channel_data stih407_powerdowns[] = {
 	[STIH407_EMISS_POWERDOWN] = STIH407_PDN_0(1),
 	[STIH407_NAND_POWERDOWN] = STIH407_PDN_0(0),
 	[STIH407_USB3_POWERDOWN] = STIH407_PDN_1(6),
@@ -122,7 +125,7 @@ static const struct syscfg_reset_channel_data stih407_powerdowns[] = {
 
 #define LPM_SYSCFG_1	0x4	/* Softreset IRB & SBC UART */
 
-static const struct syscfg_reset_channel_data stih407_softresets[] = {
+static struct syscfg_reset_channel_data stih407_softresets[] = {
 	[STIH407_ETH1_SOFTRESET] = STIH407_SRST_SBC(SYSCFG_4002, 4),
 	[STIH407_MMC1_SOFTRESET] = STIH407_SRST_CORE(SYSCFG_5132, 3),
 	[STIH407_USB2_PORT0_SOFTRESET] = STIH407_SRST_CORE(SYSCFG_5132, 28),
@@ -161,7 +164,7 @@ static const struct syscfg_reset_channel_data stih407_softresets[] = {
 /* PicoPHY reset/control */
 #define SYSCFG_5061	0x0f4
 
-static const struct syscfg_reset_channel_data stih407_picophyresets[] = {
+static struct syscfg_reset_channel_data stih407_picophyresets[] = {
 	[STIH407_PICOPHY0_RESET] = STIH407_SRST_CORE(SYSCFG_5061, 5),
 	[STIH407_PICOPHY1_RESET] = STIH407_SRST_CORE(SYSCFG_5061, 6),
 	[STIH407_PICOPHY2_RESET] = STIH407_SRST_CORE(SYSCFG_5061, 7),
@@ -223,7 +226,7 @@ static int sti_reset_program_hw(struct reset_ctl *reset_ctl, int assert)
 	struct udevice *dev = reset_ctl->dev;
 	struct syscfg_reset_controller_data *reset_desc =
 		(struct syscfg_reset_controller_data *)(dev->driver_data);
-	struct syscfg_reset_channel_data ch;
+	struct syscfg_reset_channel_data *ch;
 	phys_addr_t base;
 	u32 ctrl_val = reset_desc->active_low ? !assert : !!assert;
 	void __iomem *reg;
@@ -235,19 +238,35 @@ static int sti_reset_program_hw(struct reset_ctl *reset_ctl, int assert)
 	/* get reset sysconf register base address */
 	base = sti_reset_get_regmap(reset_desc->channels[reset_ctl->id].compatible);
 
-	ch = reset_desc->channels[reset_ctl->id];
-	reg = (void __iomem *)base + ch.reset_offset;
+	ch = &reset_desc->channels[reset_ctl->id];
+
+	/* check the deassert counter to assert reset when it reaches 0 */
+	if (!assert) {
+		ch->deassert_cnt++;
+		if (ch->deassert_cnt > 1)
+			return 0;
+	} else {
+		if (ch->deassert_cnt > 0) {
+			ch->deassert_cnt--;
+			if (ch->deassert_cnt > 0)
+				return 0;
+		} else
+			error("Reset balancing error: reset_ctl=%p dev=%p id=%lu\n",
+			      reset_ctl, reset_ctl->dev, reset_ctl->id);
+	}
+
+	reg = (void __iomem *)base + ch->reset_offset;
 
 	if (ctrl_val)
-		generic_set_bit(ch.reset_bit, reg);
+		generic_set_bit(ch->reset_bit, reg);
 	else
-		generic_clear_bit(ch.reset_bit, reg);
+		generic_clear_bit(ch->reset_bit, reg);
 
 	if (!reset_desc->wait_for_ack)
 		return 0;
 
-	reg = (void __iomem *)base + ch.ack_offset;
-	if (wait_for_bit(__func__, reg, BIT(ch.ack_bit), ctrl_val,
+	reg = (void __iomem *)base + ch->ack_offset;
+	if (wait_for_bit(__func__, reg, BIT(ch->ack_bit), ctrl_val,
 			 1000, false)) {
 		error("Stuck on waiting ack reset_ctl=%p dev=%p id=%lu\n",
 		      reset_ctl, reset_ctl->dev, reset_ctl->id);
-- 
1.9.1

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

* [U-Boot] [PATCH 1/1] reset: sti: add deassert counter in reset channel descriptor
  2017-05-18  7:58 [U-Boot] [PATCH 1/1] reset: sti: add deassert counter in reset channel descriptor patrice.chotard at st.com
@ 2017-05-22 20:26 ` Simon Glass
  2017-06-06  0:21 ` [U-Boot] [U-Boot, " Tom Rini
  1 sibling, 0 replies; 3+ messages in thread
From: Simon Glass @ 2017-05-22 20:26 UTC (permalink / raw)
  To: u-boot

On 18 May 2017 at 01:58,  <patrice.chotard@st.com> wrote:
> From: Patrice Chotard <patrice.chotard@st.com>
>
> This deassert counter allow to manage "shared" reset lines
> encountered in some specific case. On STiH410 SoC, DWC3,
> EHCI and OHCI are all using a respective PHY, but all of
> these PHYs shared a "global" reset.
>
> Currently, during command "usb stop", all host controller are
> stopped (XHCI, EHCI and OHCI). XHCI is first shutdowned, which
> means that PHY global reset is asserted. Then EHCI is shutdowned,
> but its PHY reset has already been asserted which make handshake()
> call failed in ehci_shutdown().
>
> This counter allows to really assert a reset lines only when the
> "last" user is asserting it.
>
> Signed-off-by: Patrice Chotard <patrice.chotard@st.com>
> ---
>  drivers/reset/sti-reset.c | 41 ++++++++++++++++++++++++++++++-----------
>  1 file changed, 30 insertions(+), 11 deletions(-)
>

Reviewed-by: Simon Glass <sjg@chromium.org>

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

* [U-Boot] [U-Boot, 1/1] reset: sti: add deassert counter in reset channel descriptor
  2017-05-18  7:58 [U-Boot] [PATCH 1/1] reset: sti: add deassert counter in reset channel descriptor patrice.chotard at st.com
  2017-05-22 20:26 ` Simon Glass
@ 2017-06-06  0:21 ` Tom Rini
  1 sibling, 0 replies; 3+ messages in thread
From: Tom Rini @ 2017-06-06  0:21 UTC (permalink / raw)
  To: u-boot

On Thu, May 18, 2017 at 09:58:00AM +0200, Patrice Chotard wrote:

> From: Patrice Chotard <patrice.chotard@st.com>
> 
> This deassert counter allow to manage "shared" reset lines
> encountered in some specific case. On STiH410 SoC, DWC3,
> EHCI and OHCI are all using a respective PHY, but all of
> these PHYs shared a "global" reset.
> 
> Currently, during command "usb stop", all host controller are
> stopped (XHCI, EHCI and OHCI). XHCI is first shutdowned, which
> means that PHY global reset is asserted. Then EHCI is shutdowned,
> but its PHY reset has already been asserted which make handshake()
> call failed in ehci_shutdown().
> 
> This counter allows to really assert a reset lines only when the
> "last" user is asserting it.
> 
> Signed-off-by: Patrice Chotard <patrice.chotard@st.com>
> Reviewed-by: Simon Glass <sjg@chromium.org>

Applied to u-boot/master, thanks!

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20170605/6c43643d/attachment.sig>

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

end of thread, other threads:[~2017-06-06  0:21 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-05-18  7:58 [U-Boot] [PATCH 1/1] reset: sti: add deassert counter in reset channel descriptor patrice.chotard at st.com
2017-05-22 20:26 ` Simon Glass
2017-06-06  0:21 ` [U-Boot] [U-Boot, " Tom Rini

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.