devicetree.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v5 1/3] nvmem: sunxi-sid: read NVMEM size from device compatible
@ 2017-02-27 19:27 Icenowy Zheng
       [not found] ` <20170227192715.50198-1-icenowy-ymACFijhrKM@public.gmane.org>
  0 siblings, 1 reply; 8+ messages in thread
From: Icenowy Zheng @ 2017-02-27 19:27 UTC (permalink / raw)
  To: Srinivas Kandagatla, Maxime Ripard, Rob Herring, Chen-Yu Tsai
  Cc: devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Icenowy Zheng

Sometimes the SID device have more memory address space than the real
NVMEM size (for the registers used to read/write the SID).

Fetch the NVMEM size from device compatible, rather than the memory
address space's length, in order to prepare for adding some
registers-based read support.

Signed-off-by: Icenowy Zheng <icenowy-ymACFijhrKM@public.gmane.org>
Acked-by: Maxime Ripard <maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
---
Changes in v4:
- Added Maxime's ACK.

 drivers/nvmem/sunxi_sid.c | 27 +++++++++++++++++++++++----
 1 file changed, 23 insertions(+), 4 deletions(-)

diff --git a/drivers/nvmem/sunxi_sid.c b/drivers/nvmem/sunxi_sid.c
index 1567ccca8de3..69524b67007f 100644
--- a/drivers/nvmem/sunxi_sid.c
+++ b/drivers/nvmem/sunxi_sid.c
@@ -20,6 +20,7 @@
 #include <linux/module.h>
 #include <linux/nvmem-provider.h>
 #include <linux/of.h>
+#include <linux/of_device.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <linux/random.h>
@@ -32,6 +33,10 @@ static struct nvmem_config econfig = {
 	.owner = THIS_MODULE,
 };
 
+struct sunxi_sid_cfg {
+	u32	size;
+};
+
 struct sunxi_sid {
 	void __iomem		*base;
 };
@@ -72,18 +77,24 @@ static int sunxi_sid_probe(struct platform_device *pdev)
 	struct sunxi_sid *sid;
 	int ret, i, size;
 	char *randomness;
+	const struct sunxi_sid_cfg *cfg;
 
 	sid = devm_kzalloc(dev, sizeof(*sid), GFP_KERNEL);
 	if (!sid)
 		return -ENOMEM;
 
+	cfg = of_device_get_match_data(dev);
+	if (!cfg)
+		return -EINVAL;
+
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	sid->base = devm_ioremap_resource(dev, res);
 	if (IS_ERR(sid->base))
 		return PTR_ERR(sid->base);
 
-	size = resource_size(res) - 1;
-	econfig.size = resource_size(res);
+	size = cfg->size;
+
+	econfig.size = size;
 	econfig.dev = dev;
 	econfig.reg_read = sunxi_sid_read;
 	econfig.priv = sid;
@@ -119,9 +130,17 @@ static int sunxi_sid_remove(struct platform_device *pdev)
 	return nvmem_unregister(nvmem);
 }
 
+static const struct sunxi_sid_cfg sun4i_a10_cfg = {
+	.size = 0x10,
+};
+
+static const struct sunxi_sid_cfg sun7i_a20_cfg = {
+	.size = 0x200,
+};
+
 static const struct of_device_id sunxi_sid_of_match[] = {
-	{ .compatible = "allwinner,sun4i-a10-sid" },
-	{ .compatible = "allwinner,sun7i-a20-sid" },
+	{ .compatible = "allwinner,sun4i-a10-sid", .data = &sun4i_a10_cfg },
+	{ .compatible = "allwinner,sun7i-a20-sid", .data = &sun7i_a20_cfg },
 	{/* sentinel */},
 };
 MODULE_DEVICE_TABLE(of, sunxi_sid_of_match);
-- 
2.11.1

^ permalink raw reply related	[flat|nested] 8+ messages in thread
* Re: [PATCH v5 2/3] nvmem: sunxi-sid: add support for H3's SID controller
@ 2017-03-03 10:22 Icenowy Zheng
  0 siblings, 0 replies; 8+ messages in thread
From: Icenowy Zheng @ 2017-03-03 10:22 UTC (permalink / raw)
  To: Srinivas Kandagatla
  Cc: Rob Herring, Maxime Ripard, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Chen-Yu Tsai


2017年3月3日 18:18于 Srinivas Kandagatla <srinivas.kandagatla-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>写道:
>
>
>
> On 27/02/17 19:27, Icenowy Zheng wrote: 
> > The H3 SoC have a bigger SID controller, which has its direct read 
> > address at 0x200 position in the SID block, not 0x0. 
> > 
> > Also, H3 SID controller has some silicon bug that makes the direct read 
> > value wrong at cold boot, add code to workaround the bug. (This bug has 
> > already been fixed on A64 and later SoCs) 
> > 
> > Signed-off-by: Icenowy Zheng <icenowy-ymACFijhrKM@public.gmane.org> 
> > --- 
> > Changes in v5: 
> > - Removed some bits in binding documentation. 
> > - Removed some default values in cfg struct. 
> > 
> > Changes in v4: 
> > - Use readl_poll_timeout. 
> > - Do register offset in sunxi_sid_read. 
> > - Merge SUN8I_SID_OP_LOCK and SUN8I_SID_LOCK_SHIFT into one macro. 
> > - Drop the result of register-based read operation. 
> > 
> >  .../bindings/nvmem/allwinner,sunxi-sid.txt         |  6 ++- 
> >  drivers/nvmem/sunxi_sid.c                          | 62 ++++++++++++++++++++++ 
> >  2 files changed, 67 insertions(+), 1 deletion(-) 
>
>
>
> I will queue this and 1/3 patch for next cycle, but the dts patch has to 
> go via arm-soc tree. 

Thanks! ;-)

And I think Maxime can merge 3/3.

>
> Thanks, 
> srini 
> > 
> > diff --git a/Documentation/devicetree/bindings/nvmem/allwinner,sunxi-sid.txt b/Documentation/devicetree/bindings/nvmem/allwinner,sunxi-sid.txt 
> > index d543ed3f5363..ef06d061913c 100644 
> > --- a/Documentation/devicetree/bindings/nvmem/allwinner,sunxi-sid.txt 
> > +++ b/Documentation/devicetree/bindings/nvmem/allwinner,sunxi-sid.txt 
> > @@ -1,7 +1,11 @@ 
> >  Allwinner sunxi-sid 
> > 
> >  Required properties: 
> > -- compatible: "allwinner,sun4i-a10-sid" or "allwinner,sun7i-a20-sid" 
> > +- compatible: Should be one of the following: 
> > +  "allwinner,sun4i-a10-sid" 
> > +  "allwinner,sun7i-a20-sid" 
> > +  "allwinner,sun8i-h3-sid" 
> > + 
> >  - reg: Should contain registers location and length 
> > 
> >  = Data cells = 
> > diff --git a/drivers/nvmem/sunxi_sid.c b/drivers/nvmem/sunxi_sid.c 
> > index 69524b67007f..0d6648be93b8 100644 
> > --- a/drivers/nvmem/sunxi_sid.c 
> > +++ b/drivers/nvmem/sunxi_sid.c 
> > @@ -17,6 +17,7 @@ 
> > 
> >  #include <linux/device.h> 
> >  #include <linux/io.h> 
> > +#include <linux/iopoll.h> 
> >  #include <linux/module.h> 
> >  #include <linux/nvmem-provider.h> 
> >  #include <linux/of.h> 
> > @@ -25,6 +26,15 @@ 
> >  #include <linux/slab.h> 
> >  #include <linux/random.h> 
> > 
> > +/* Registers and special values for doing register-based SID readout on H3 */ 
> > +#define SUN8I_SID_PRCTL 0x40 
> > +#define SUN8I_SID_RDKEY 0x60 
> > + 
> > +#define SUN8I_SID_OFFSET_MASK 0x1FF 
> > +#define SUN8I_SID_OFFSET_SHIFT 16 
> > +#define SUN8I_SID_OP_LOCK (0xAC << 8) 
> > +#define SUN8I_SID_READ BIT(1) 
> > + 
> >  static struct nvmem_config econfig = { 
> >  .name = "sunxi-sid", 
> >  .read_only = true, 
> > @@ -34,11 +44,14 @@ static struct nvmem_config econfig = { 
> >  }; 
> > 
> >  struct sunxi_sid_cfg { 
> > + u32 value_offset; 
> >  u32 size; 
> > + bool need_register_readout; 
> >  }; 
> > 
> >  struct sunxi_sid { 
> >  void __iomem *base; 
> > + u32 value_offset; 
> >  }; 
> > 
> >  /* We read the entire key, due to a 32 bit read alignment requirement. Since we 
> > @@ -63,12 +76,36 @@ static int sunxi_sid_read(void *context, unsigned int offset, 
> >  struct sunxi_sid *sid = context; 
> >  u8 *buf = val; 
> > 
> > + /* Offset the read operation to the real position of SID */ 
> > + offset += sid->value_offset; 
> > + 
> >  while (bytes--) 
> >  *buf++ = sunxi_sid_read_byte(sid, offset++); 
> > 
> >  return 0; 
> >  } 
> > 
> > +static int sun8i_sid_register_readout(const struct sunxi_sid *sid, 
> > +       const unsigned int word) 
> > +{ 
> > + u32 reg_val; 
> > + int ret; 
> > + 
> > + /* Set word, lock access, and set read command */ 
> > + reg_val = (word & SUN8I_SID_OFFSET_MASK) 
> > +   << SUN8I_SID_OFFSET_SHIFT; 
> > + reg_val |= SUN8I_SID_OP_LOCK | SUN8I_SID_READ; 
> > + writel(reg_val, sid->base + SUN8I_SID_PRCTL); 
> > + 
> > + ret = readl_poll_timeout(sid->base + SUN8I_SID_PRCTL, reg_val, 
> > + !(reg_val & SUN8I_SID_READ), 100, 250000); 
> > + if (ret) 
> > + return ret; 
> > + 
> > + writel(0, sid->base + SUN8I_SID_PRCTL); 
> > + return 0; 
> > +} 
> > + 
> >  static int sunxi_sid_probe(struct platform_device *pdev) 
> >  { 
> >  struct device *dev = &pdev->dev; 
> > @@ -86,6 +123,7 @@ static int sunxi_sid_probe(struct platform_device *pdev) 
> >  cfg = of_device_get_match_data(dev); 
> >  if (!cfg) 
> >  return -EINVAL; 
> > + sid->value_offset = cfg->value_offset; 
> > 
> >  res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 
> >  sid->base = devm_ioremap_resource(dev, res); 
> > @@ -94,6 +132,23 @@ static int sunxi_sid_probe(struct platform_device *pdev) 
> > 
> >  size = cfg->size; 
> > 
> > + if (cfg->need_register_readout) { 
> > + /* 
> > + * H3's SID controller have a bug that the value at 0x200 
> > + * offset is not the correct value when the hardware is reseted. 
> > + * However, after doing a register-based read operation, the 
> > + * value become right. 
> > + * Do a full read operation here, but ignore its value 
> > + * (as it's more fast to read by direct MMIO value than 
> > + * with registers) 
> > + */ 
> > + for (i = 0; i < (size >> 2); i++) { 
> > + ret = sun8i_sid_register_readout(sid, i); 
> > + if (ret) 
> > + return ret; 
> > + } 
> > + } 
> > + 
> >  econfig.size = size; 
> >  econfig.dev = dev; 
> >  econfig.reg_read = sunxi_sid_read; 
> > @@ -138,9 +193,16 @@ static const struct sunxi_sid_cfg sun7i_a20_cfg = { 
> >  .size = 0x200, 
> >  }; 
> > 
> > +static const struct sunxi_sid_cfg sun8i_h3_cfg = { 
> > + .value_offset = 0x200, 
> > + .size = 0x100, 
> > + .need_register_readout = true, 
> > +}; 
> > + 
> >  static const struct of_device_id sunxi_sid_of_match[] = { 
> >  { .compatible = "allwinner,sun4i-a10-sid", .data = &sun4i_a10_cfg }, 
> >  { .compatible = "allwinner,sun7i-a20-sid", .data = &sun7i_a20_cfg }, 
> > + { .compatible = "allwinner,sun8i-h3-sid", .data = &sun8i_h3_cfg }, 
> >  {/* sentinel */}, 
> >  }; 
> >  MODULE_DEVICE_TABLE(of, sunxi_sid_of_match); 
> > 

-- 
You received this message because you are subscribed to the Google Groups "linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit https://groups.google.com/d/optout.

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

end of thread, other threads:[~2017-03-03 10:22 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-02-27 19:27 [PATCH v5 1/3] nvmem: sunxi-sid: read NVMEM size from device compatible Icenowy Zheng
     [not found] ` <20170227192715.50198-1-icenowy-ymACFijhrKM@public.gmane.org>
2017-02-27 19:27   ` [PATCH v5 2/3] nvmem: sunxi-sid: add support for H3's SID controller Icenowy Zheng
     [not found]     ` <20170227192715.50198-2-icenowy-ymACFijhrKM@public.gmane.org>
2017-02-28  6:42       ` Maxime Ripard
2017-02-28  8:35         ` Icenowy Zheng
     [not found]           ` <630891488270931-rwkuSX3kbspxpj1cXAZ9Bg@public.gmane.org>
2017-02-28  9:25             ` Maxime Ripard
2017-03-03 10:18     ` Srinivas Kandagatla
2017-02-27 19:27   ` [PATCH v5 3/3] ARM: dts: sun8i: enable SID on Allwinner H3 SoC Icenowy Zheng
  -- strict thread matches above, loose matches on Subject: below --
2017-03-03 10:22 [PATCH v5 2/3] nvmem: sunxi-sid: add support for H3's SID controller Icenowy Zheng

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).