Re: [PATCH v3 43/44] dt: document HiSilicon SPMI controller and mfd/regulator properties

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, Aug 18, 2020 at 11:13:51AM +0200, Mauro Carvalho Chehab wrote:
> Em Mon, 17 Aug 2020 14:12:11 -0600
> Rob Herring <robh@xxxxxxxxxx> escreveu:
> 
> > On Mon, Aug 17, 2020 at 09:11:02AM +0200, Mauro Carvalho Chehab wrote:
> > > Add documentation for the properties needed by the HiSilicon
> > > 6421v600 driver, and by the SPMI controller used to access
> > > the chipset.
> > > 
> > > Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@xxxxxxxxxx>
> > > ---
> > >  .../mfd/hisilicon,hi6421-spmi-pmic.yaml       | 182 ++++++++++++++++++
> > >  .../spmi/hisilicon,hisi-spmi-controller.yaml  |  54 ++++++
> > >  2 files changed, 236 insertions(+)
> > >  create mode 100644 Documentation/devicetree/bindings/mfd/hisilicon,hi6421-spmi-pmic.yaml
> > >  create mode 100644 Documentation/devicetree/bindings/spmi/hisilicon,hisi-spmi-controller.yaml
> > > 
> > > diff --git a/Documentation/devicetree/bindings/mfd/hisilicon,hi6421-spmi-pmic.yaml b/Documentation/devicetree/bindings/mfd/hisilicon,hi6421-spmi-pmic.yaml
> > > new file mode 100644
> > > index 000000000000..95494114554d
> > > --- /dev/null
> > > +++ b/Documentation/devicetree/bindings/mfd/hisilicon,hi6421-spmi-pmic.yaml
> > > @@ -0,0 +1,182 @@
> > > +# SPDX-License-Identifier: GPL-2.0
> > > +%YAML 1.2
> > > +---
> > > +$id: http://devicetree.org/schemas/mfd/hisilicon,hi6421-spmi-pmic.yaml#
> > > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > > +
> > > +title: HiSilicon 6421v600 SPMI PMIC
> > > +
> > > +maintainers:
> > > +  - Mauro Carvalho Chehab <mchehab+huawei@xxxxxxxxxx>
> > > +
> > > +description: |
> > > +  HiSilicon 6421v600 uses a MIPI System Power Management (SPMI) bus in order
> > > +  to provide interrupts and power supply.
> > > +
> > > +  The GPIO and interrupt settings are represented as part of the top-level PMIC
> > > +  node.
> > > +
> > > +  The SPMI controller part is provided by
> > > +  Documentation/devicetree/bindings/spmi/hisilicon,hisi-spmi-controller.yaml.
> > > +
> > > +properties:
> > > +  $nodename:
> > > +    pattern: "pmic@[0-9a-f]"
> > > +
> > > +  compatible:
> > > +    const: hisilicon,hi6421-spmi-pmic  
> > 
> > -spmi-pmic is redundant. Can the hi6421 be anything else?
> 
> There are other HiSilicom 6421 variants that don't use SPMI bus:
> 
> 	Documentation/devicetree/bindings/mfd/hi6421.txt:       "hisilicon,hi6421-pmic";
> 	Documentation/devicetree/bindings/mfd/hi6421.txt:       "hisilicon,hi6421v530-pmic";
> 
> The DT file on Kernel 4.9 uses hi6421v600 (although the schematics
> from 96boards name it as hi6421v610).
> 
> While I don't mind much,would prefer to keep "spmi" on its name, in order
> to distinguish this one from the non-spmi variants.

Fine, though since probing is bus specific it works fine if the same 
compatible is used with different buses. Devices with multiple bus 
options are pretty common.


> Maybe we use this for compatible:
> 
> 	hisilicon,hi6421v600-spmi

Okay.

> > > +  reg:
> > > +    maxItems: 1
> > > +
> > > +  spmi-channel:
> > > +    description: number of the SPMI channel where the PMIC is connected  
> > 
> > This looks like a common (to SPMI), but it's not something defined in 
> > spmi.txt 
> 
> This one is not part of the SPMI core. It is stored inside a private 
> structure inside at the HiSilicon spmi controller driver. It is stored 
> there as ctrl_dev->channel, and it is used to calculate the register offset
> for readl():
> 
> 	offset  = SPMI_APB_SPMI_STATUS_BASE_ADDR;
> 	offset += SPMI_CHANNEL_OFFSET * ctrl_dev->channel + SPMI_SLAVE_OFFSET * sid;
> 	do {
> 		status = readl(base + offset);
> 	...
> 
> The SPMI bus is somewhat similar to I2C: it is a 2-wire serial bus
> with up to 16 devices connected to it.
> 
> Now, most modern I2C chipsets provide multiple independent I2C
> channels, on different pins. Also, on some chipsets, certain
> GPIO pins can be used either as GPIO or as I2C.
> 
> I strongly suspect that this is the case here: according with
> the Hikey 970 schematics:
> 
> 	https://www.96boards.org/documentation/consumer/hikey/hikey970/hardware-docs/files/hikey970-schematics.pdf
> 
> The pins used by SPMI clock/data can also be used as GPIO.
> 
> While I don't have access to the datasheets for Kirin 970 (or any other
> chipsets on this board), for me, it sounds that different GPIO pins
> are allowed to use SPMI. The "spmi-channel" property specifies
> what pins will be used for SPMI, among the ones that are
> compatible with MIPI SPMI specs.

Based on this, I think it should be called 'hisilicon,spmi-channel' as 
it is vendor specific. 


> > (which should ideally be converted to schema first). 
> 
> I can try porting spmi schema to yaml on a separate patch,
> and submit it independently of this series.
> 
> > Minimally, 
> > it needs a better explanation and determination if it should be common 
> > or is HiSilicon specific.
> 
> What about:
> 
>   spmi-channel:
>     description: |
>       number of the SPMI channel at the HiSilicon SoC that will
>       be used for the MIPI SPMI controller.
> 
> > 
> > > +
> > > +  '#interrupt-cells':
> > > +    const: 2
> > > +
> > > +  interrupt-controller:
> > > +    description:
> > > +      Identify that the PMIC is capable of behaving as an interrupt controller.  
> > 
> > No need to redefine common properties if nothing specific to this device 
> > to say. Just:
> > 
> > interrupt-controller: true
> 
> Ok.
> 
> > 
> > > +
> > > +  gpios:
> > > +    maxItems: 1
> > > +
> > > +  irq-num:
> > > +    description: Interrupt request number
> > > +
> > > +  'irq-array':
> > > +    description: Interrupt request array
> > > +
> > > +  'irq-mask-addr':
> > > +    description: Address for the interrupt request mask
> > > +
> > > +  'irq-addr':
> > > +    description: Address for the interrupt request  
> > 
> > What's all these non-standard interrupt properties?
> 
> After doing a deeper look at the code which handles IRQs on this PMIC,
> I'm considering to get rid of two properties: irq-num and irq-array.
> 
> See, the code does this:
> 
> 	/* During probe time */
> 	pmic->irqs = devm_kzalloc(dev, pmic->irqnum * sizeof(int), GFP_KERNEL);
> 
> 	/* While handling IRQs */
> 	for (i = 0; i < pmic->irqarray; i++) {
> 		pending = hi6421_spmi_pmic_read(pmic, (i + pmic->irq_addr));
> 		pending &= 0xff;
> 
> 		for_each_set_bit(offset, &pending, 8)
> 			generic_handle_irq(pmic->irqs[offset + i * 8]);
> 
> 	}
> 
> Right now, Hikey 970 sets:
> 
> 	irq-num = <16>;
> 	irq-array = <2>;
> 	irq-mask-addr = <0x202>;
> 	irq-addr = <0x212>;
> 
> From the above code, it sounds to me that irq-array is the number of
> bytes used for IRQ, while irq-num is the number of bits. E. g:
> 
> 	irq_num =  irqarray * 8;
> 
> So, we can get rid of at least one of them.
> 
> Going further, the code provides an special treatment for some IRQs:
> 
> 	#define HISI_IRQ_KEY_NUM		0
> 	#define HISI_IRQ_KEY_VALUE		0xc0
> 	#define HISI_IRQ_KEY_DOWN		7
> 	#define HISI_IRQ_KEY_UP			6
> 
> 	for (i = 0; i < pmic->irqarray; i++) {
> 		pending = hi6421_spmi_pmic_read(pmic, (i + pmic->irq_addr));
> 
> 	...
> 		/* solve powerkey order */
> 		if ((i == HISI_IRQ_KEY_NUM) &&
> 		    ((pending & HISI_IRQ_KEY_VALUE) == HISI_IRQ_KEY_VALUE)) {
> 			generic_handle_irq(pmic->irqs[HISI_IRQ_KEY_DOWN]);
> 			generic_handle_irq(pmic->irqs[HISI_IRQ_KEY_UP]);
> 			pending &= (~HISI_IRQ_KEY_VALUE);
> 		}
> 
> As the values for HISI_IRQ_KEY_DOWN and HISI_IRQ_KEY_UP don't
> depend on irqarray, it sounds to me that this is actually hardcoded 
> for irqarray == 2.
> 
> So, I'll just get rid of those, replacing them by some defines inside
> the code. If needed later, this patch can always be reverted.
> 
> > > +  'irq-mask-addr':
> > > +    description: Address for the interrupt request mask
> > > +
> > > +  'irq-addr':
> > > +    description: Address for the interrupt request  
> 
> Those two seems more standard to me: irq-mask-addr is the address to
> enable/disable IRQs, while irq-addr is where the pending IRQs are
> stored.
> 
> What would be the standard way to specify them both?
> 
> > > +
> > > +  regulators:
> > > +    type: object  
> > 
> > additionalProperties: false
> > 
> > > +
> > > +    properties:
> > > +      '#address-cells':
> > > +        const: 1
> > > +
> > > +      '#size-cells':
> > > +        const: 0
> > > +
> > > +    patternProperties:
> > > +      '^ldo@[0-9]+$':  
> > 
> > Unit-addresses are hex.
> >
> > Also, doesn't match the example.
> 
> True. This should be, instead:
> 
> 	patternProperties:
>           '^ldo[0-9]+@[0-9a-f]+$':  
> 
> The name part of the property would better to stay in decimal,
> as it makes a in order to match the public schematics:
> 
> 	https://www.96boards.org/documentation/consumer/hikey/hikey970/hardware-docs/files/hikey970-schematics.pdf
> 
> Using decimal values, the dmesg matches the schematics helps a lot when
> dealing issues related to PM, as the names of the LDO lines will match
> page 12 the schematics:
> 
> 	ldo3: 1500 <--> 2000 mV at 1800 mV normal 
> 	ldo4: 1725 <--> 1900 mV at 1800 mV normal idle 
> 	ldo9: 1750 <--> 3300 mV at 2950 mV normal idle 
> 	ldo15: 1800 <--> 3000 mV at 2950 mV normal idle 
> 	ldo16: 1800 <--> 3000 mV at 2950 mV normal idle 
> 	ldo17: 2500 <--> 3300 mV at 2500 mV normal idle 
> 	ldo33: 2500 <--> 3300 mV at 2500 mV normal 
> 	ldo34: 2600 <--> 3300 mV at 2600 mV normal 
> 	ldo4: disabling
> 	ldo33: disabling
> 
> So, from above, looking at the datasheet, it is clear that
> ldo33 - e. g. PCIe Switch VDD25 - is disabled.

Makes sense.

> > > +        type: object
> > > +
> > > +        $ref: "/schemas/regulator/regulator.yaml#"
> > > +
> > > +        properties:
> > > +          reg:
> > > +            description: Enable register.
> > > +  
> > 
> > > +          '#address-cells':
> > > +            const: 1
> > > +
> > > +          '#size-cells':
> > > +            const: 0  
> > 
> > No child nodes, you don't need these.
> 
> It is needed. However, this is at the second file of the DT.
> 
> See, as SPMI is actually a bus, the entire DT setting has 3
> parts:
>   - the SPMI controller;
>   - the PMICs;
>   - the regulators.
> 
> A complete example is:
> 
> 	spmi: spmi@fff24000 {
> 		compatible = "hisilicon,spmi-controller";
> 		#address-cells = <2>;
> 		#size-cells = <0>;
> 		status = "ok";
> 		reg = <0x0 0xfff24000 0x0 0x1000>;
> 		spmi-channel = <2>;
> 
> 		pmic: pmic@0 {
> 			compatible = "hisilicon,hi6421-spmi-pmic";
> 			slave_id = <0>;
> 			reg = <0 SPMI_USID>;
> 
> 			#interrupt-cells = <2>;
> 			interrupt-controller;
> 			gpios = <&gpio28 0 0>;
> 			irq-mask-addr = <0x202>;
> 			irq-addr = <0x212>;
> 
> 			regulators {
> 				#address-cells = <1>;
> 				#size-cells = <0>;
> 
> 				ldo3: ldo3@16 {
> 					reg = <0x16>;
> 					vsel-reg = <0x51>;
> 
> 					regulator-name = "ldo3";
> 					regulator-min-microvolt = <1500000>;
> 					regulator-max-microvolt = <2000000>;
> 					regulator-boot-on;
> 
> 					enable-mask = <0x01>;
> 
> 					voltage-table = <1500000>, <1550000>,
> 							<1600000>, <1650000>,
> 							<1700000>, <1725000>,
> 							<1750000>, <1775000>,
> 							<1800000>, <1825000>,
> 							<1850000>, <1875000>,
> 							<1900000>, <1925000>,
> 							<1950000>, <2000000>;
> 					off-on-delay-us = <20000>;
> 					startup-delay-us = <120>;
> 				};
> 				...
> 			};
> 		};
> 	};
> 
> The child nodes are at the regulator DT properties.
> 
> Well, I can drop those from here, adding them only at the regulator's
> part, using "bus { ... };".
> 
> > > +
> > > +          vsel-reg:
> > > +            description: Voltage selector register.  
> > 
> > 'reg' can have multiple entries if you want.
> 
> Yes, I know. I was in doubt if I should either place vsel-reg on
> a separate property or together with reg. I ended keeping it
> in separate on the submitted patch series.
> 
> What makes more sense?

Really, not putting it in DT. Like other things, it's fixed for the 
chip.


> > > +
> > > +          enable-mask:
> > > +            description: Bitmask used to enable the regulator.  
> > 
> > But if there's a shared enable reg, then you shouldn't have duplicate 
> > addresses (same 'reg' value in multiple nodes).
> 
> At least for the LDOs supported on HiKey 970, values for
> "reg" and "vsel-reg" are unique: each LDO has their own.
> 
> Right now, enable-mask is 0x01 for all LDOs at the Hikey 970
> DTS. However, only 8 LDOs are currently present at the DTS. From
> the schematics, it sounds that HiSilicon 6421v600 supports
> at least 37 lines. I've no idea if enable-mask remains the same
> for the other ones, nor if "reg" and "vsel-reg" won't be
> unique in the general case.
> 
> > These perhaps should be driver data rather than in DT as it's all fixed 
> > for this chip. We don't try to parameterize everything in DT.
> 
> I considered that. However, I've no idea about the values and
> ranges for the other 29 LDOs. So, without knowing better about
> this silicon, I prefer to keep those at DT.
> 
> > 
> > > +
> > > +          voltage-table:
> > > +            description: Table with the selector items for the voltage regulator.
> > > +            minItems: 2
> > > +            maxItems: 16  
> > 
> > Needs a type $ref.
> 
> Ok. I'll add:
> 
> 		$ref: /schemas/types.yaml#/definitions/uint32
> 
> > > +
> > > +          off-on-delay-us:
> > > +            description: Time required for changing state to enabled in microseconds.
> > > +
> > > +          startup-delay-us:
> > > +            description: Startup time in microseconds.
> > > +
> > > +          idle-mode-mask:
> > > +            description: Bitmask used to put the regulator on idle mode.
> > > +
> > > +          eco-microamp:
> > > +            description: Maximum current while on idle mode.
> > > +
> > > +        required:
> > > +          - reg
> > > +          - vsel-reg
> > > +          - enable-mask
> > > +          - voltage-table
> > > +          - off-on-delay-us
> > > +          - startup-delay-us
> > > +
> > > +required:
> > > +  - compatible
> > > +  - reg
> > > +  - regulators  
> > 
> > Add:
> > 
> > additionalProperties: false
> 
> Ok.
> 
> > 
> > > +
> > > +examples:
> > > +  - |
> > > +    /* pmic properties */
> > > +
> > > +    pmic: pmic@0 {
> > > +      compatible = "hisilicon,hi6421-spmi-pmic";
> > > +      slave_id = <0>;  
> > 
> > Not documented. I believe this is part of 'reg'.
> 
> Good point. I'll double-check this one, but I guess you're right.
> 
> > 
> > > +      reg = <0 0>;
> > > +
> > > +      #interrupt-cells = <2>;
> > > +      interrupt-controller;
> > > +      gpios = <&gpio28 0 0>;
> > > +      irq-num = <16>;
> > > +      irq-array = <2>;
> > > +      irq-mask-addr = <0x202 2>;
> > > +      irq-addr = <0x212 2>;
> > > +
> > > +      #address-cells = <1>;
> > > +      #size-cells = <0>;
> > > +
> > > +      regulators {
> > > +          #address-cells = <1>;
> > > +          #size-cells = <0>;
> > > +
> > > +        ldo3: ldo3@16 {
> > > +          reg = <0x16>;
> > > +          vsel-reg = <0x51>;
> > > +
> > > +          regulator-name = "ldo3";
> > > +          regulator-min-microvolt = <1500000>;
> > > +          regulator-max-microvolt = <2000000>;
> > > +          regulator-boot-on;
> > > +
> > > +          enable-mask = <0x01>;
> > > +
> > > +          voltage-table = <1500000>, <1550000>, <1600000>, <1650000>,
> > > +                          <1700000>, <1725000>, <1750000>, <1775000>,
> > > +                          <1800000>, <1825000>, <1850000>, <1875000>,
> > > +                          <1900000>, <1925000>, <1950000>, <2000000>;
> > > +          off-on-delay-us = <20000>;
> > > +          startup-delay-us = <120>;
> > > +        };
> > > +
> > > +        ldo4: ldo4@17 { /* 40 PIN */
> > > +          reg = <0x17>;
> > > +          vsel-reg = <0x52>;
> > > +
> > > +          regulator-name = "ldo4";
> > > +          regulator-min-microvolt = <1725000>;
> > > +          regulator-max-microvolt = <1900000>;
> > > +          regulator-boot-on;
> > > +
> > > +          enable-mask = <0x01>;
> > > +          idle-mode-mask = <0x10>;
> > > +          eco-microamp = <10000>;
> > > +
> > > +          hi6421-vsel = <0x52 0x07>;  
> > 
> > Not documented.
> 
> This is a left-over. I dropped this one, in favor of "vsel-reg"
> (plus a mask for the voltage-table size).
> 
> > 
> > > +          voltage-table = <1725000>, <1750000>, <1775000>, <1800000>,
> > > +                          <1825000>, <1850000>, <1875000>, <1900000>;
> > > +          off-on-delay-us = <20000>;
> > > +          startup-delay-us = <120>;
> > > +        };
> > > +      };
> > > +    };
> > > diff --git a/Documentation/devicetree/bindings/spmi/hisilicon,hisi-spmi-controller.yaml b/Documentation/devicetree/bindings/spmi/hisilicon,hisi-spmi-controller.yaml
> > > new file mode 100644
> > > index 000000000000..5aeb2ae12024
> > > --- /dev/null
> > > +++ b/Documentation/devicetree/bindings/spmi/hisilicon,hisi-spmi-controller.yaml
> > > @@ -0,0 +1,54 @@
> > > +# SPDX-License-Identifier: GPL-2.0
> > > +%YAML 1.2
> > > +---
> > > +$id: http://devicetree.org/schemas/spmi/hisilicon,hisi-spmi-controller.yaml#
> > > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > > +
> > > +title: HiSilicon SPMI controller
> > > +
> > > +maintainers:
> > > +  - Mauro Carvalho Chehab <mchehab+huawei@xxxxxxxxxx>
> > > +
> > > +description: |
> > > +  The HiSilicon SPMI controller is found on some Kirin-based designs.
> > > +  It is a MIPI System Power Management (SPMI) controller.
> > > +
> > > +  The PMIC part is provided by
> > > +  Documentation/devicetree/bindings/mfd/hisilicon,hi6421-spmi-pmic.yaml.
> > > +
> > > +properties:
> > > +  $nodename:
> > > +    pattern: "spmi@[0-9a-f]"
> > > +
> > > +  compatible:
> > > +    const: hisilicon,spmi-controller  
> > 
> > Needs an SoC specific compatible.
> 
> What about:
> 	hisilicon,kirin970-spmi-controller 

Is 'kirin970' really the SoC name? The older ones are all 'hi[0-9]+'.

> 
> > 
> > > +
> > > +  reg:
> > > +    maxItems: 1
> > > +
> > > +  "#address-cells":
> > > +    const: 2
> > > +
> > > +  "#size-cells":
> > > +    const: 0
> > > +
> > > +  spmi-channel:
> > > +    description: number of the SPMI channel where the PMIC is connected
> > > +
> > > +patternProperties:
> > > +  "^pmic@[0-9a-f]$":
> > > +    $ref: "/schemas/mfd/hisilicon,hi6421-spmi-pmic.yaml#"
> > > +
> > > +examples:
> > > +  - |
> > > +    spmi: spmi@fff24000 {
> > > +      compatible = "hisilicon,spmi-controller";
> > > +      #address-cells = <2>;
> > > +      #size-cells = <0>;
> > > +      status = "ok";
> > > +      reg = <0x0 0xfff24000 0x0 0x1000>;
> > > +      spmi-channel = <2>;  
> > 
> > Does this go in the SPMI controller or child (pmic)?
> 
> Those belong to the SPMI controller. Maybe I did some mess trying to
> split up DT in order to place the Kirin970 SPMI bus controller on
> one file, and the HiSilicon 6421v600 on another one.
> 
> I ended needing to duplicate some things, as otherwise the DT checks fail.
> 
> Basically, the full DT is:
> 
> 	spmi: spmi@fff24000 {
> 		/* Kirin 970 SPMI controller props */
> 
> 		pmic: pmic@0 {
> 			/* HiSilicon 6421v600 PMIC props */
> 
> 			regulators {
> 				ldo3: ldo3@16 {
> 					/* HiSilicon 6421v600 ldo3 regulator props */
> 				};
> 				ldo4: ldo3@17 {
> 					/* HiSilicon 6421v600 ldo4 regulator props */
> 				};
> 				...
> 				ldo34: ldo3@33 {
> 					/* HiSilicon 6421v600 ldo34 regulator props */
> 				};
> 			};
> 		};
> 	};
> 
> Thanks,
> Mauro



[Index of Archives]     [Device Tree Compilter]     [Device Tree Spec]     [Linux Driver Backports]     [Video for Linux]     [Linux USB Devel]     [Linux PCI Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [XFree86]     [Yosemite Backpacking]


  Powered by Linux