Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

i2c: move nordic IPs to sda-gpios, scl-gpios #31965

Merged

Conversation

mbolivar-nordic
Copy link
Contributor

Nordic pinmuxing for I2C SDA and SCL pins is done with sda-pin and scl-pin DTS properties. Move these to a more idiomatic sda-gpios and scl-gpios style instead.

A prototypical example for how the devicetree should be updated is:

 &i2c1 {
 	compatible = "nordic,nrf-twim";
 	status = "okay";
-	sda-pin = <41>;
-	scl-pin = <11>;
+	sda-gpios = <&gpio1 9 0>;
+	scl-gpios = <&gpio0 11 0>;
 };

The old properties continue to be supported, but are now deprecated. Move in-tree boards and sample overlays to the new style.

@mbolivar-nordic
Copy link
Contributor Author

mbolivar-nordic commented Feb 4, 2021

@pabigot @anangl this is picking up where we left off in #30769.

I'm only doing TWI and TWIM for now to keep this relatively small since it's the first one.

I've discussed with @carlescufi and I can commit to updating all of the following properties for Zephyr 2.6 in this and follow-up PRs:

  • nordic,nrf-i2s: sck-pin, lrck-pin, sdout-pin, sdin-pin, mck-pin
  • nordic,nrf-pdm: clk-pin, din-pin
  • nordic,nrf-pwm: ch0-pin, ch1-pin, ch2-pin, ch3-pin
  • nordic,nrf-qdec: a-pin, b-pin, led-pin, enable-pin
  • nordic,nrf-qspi: sck-pin, csn-pins, io-pins
  • nordic,nrf-spi: sck-pin, mosi-pin, miso-pin
  • nordic,nrf-spim: sck-pin, mosi-pin, miso-pin
  • nordic,nrf-spis: csn-pin, sck-pin, mosi-pin, miso-pin
  • nordic,nrf-twi: sda-pin, scl-pin
  • nordic,nrf-twim: sda-pin, scl-pin
  • nordic,nrf-twis: sda-pin, scl-pin
  • nordic,nrf-uart: tx-pin, rx-pin, rts-pin, cts-pin
  • nordic,nrf-uarte: tx-pin, rx-pin, rts-pin, cts-pin

Copy link
Collaborator

@pabigot pabigot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall this looks like a great start to standardizing Nordic pin specification, just wondering if one piece needs to be pulled out.

soc/arm/nordic_nrf/soc_nrf_common.h Outdated Show resolved Hide resolved
Copy link
Collaborator

@avisconti avisconti left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The idea looks good, and goes in the direction of having a more standard way to define gpios for I2C. So it is clear from the documentation how, let's say, P0.3 or P1.9 is transalted. Nevertheless it is difficult to me to review all the DTS change, as they are too many.

@mbolivar-nordic
Copy link
Contributor Author

Rebased onto #32001.

@mbolivar-nordic mbolivar-nordic force-pushed the dt-move-nrf-pin-to-gpios branch 2 times, most recently from a1fa309 to c80b1e9 Compare February 10, 2021 06:49
@mbolivar-nordic mbolivar-nordic force-pushed the dt-move-nrf-pin-to-gpios branch 2 times, most recently from ae47040 to 97958d9 Compare February 15, 2021 02:13
@mbolivar-nordic mbolivar-nordic added the DNM This PR should not be merged (Do Not Merge) label Feb 15, 2021
@mbolivar-nordic
Copy link
Contributor Author

mbolivar-nordic commented Feb 15, 2021

Seeing if temporarily increasing the buildkite parallelism will avoid CI timeouts. DNM since that patch should not be merged.

@mbolivar-nordic mbolivar-nordic force-pushed the dt-move-nrf-pin-to-gpios branch 2 times, most recently from 134f2c8 to 3b9cf3b Compare February 24, 2021 01:14
@mbolivar-nordic
Copy link
Contributor Author

Added a missing include to the TWI driver and rebased.

@mbolivar-nordic
Copy link
Contributor Author

Remaining CI failures are due to #32619 as far as I can tell.

Add some helper macros that will be convenient to use from device
drivers for accessing and error checking pin mux information in the
devicetree:

- NRF_DT_PSEL(): get a PSEL value out of the DT from either a
  'foo-pin' or a 'foo-gpios' style property.

- NRF_DT_PSEL_CHECK_NOT_BOTH(), NRF_DT_PSEL_CHECK_EXACTLY_ONE():
  helpers for checking that a given devicetree is OK according to
  different criteria for setting PSEL properties (NAND or XOR on
  whether the properties exist, respectively).

See comments in the patch for more details.

Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
Deprecate the scl-pin and sda-pin properties in the devicetree.
Provide new scl-gpios and sda-gpios properties instead.

This lets the user specify SCL and SDA like this:

   &i2c0 {
         scl-gpios = <&gpio0 1 0>;
         sda-gpios = <&gpio1 4 0>;
   };

Instead of having to use:

   &i2c0 {
         scl-pin = <1>;
         sda-pin = <36>;
   };

Provide error checking and understandable error messages for invalid
configurations.

Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
Move the BOARD.dts files for Nordic-based boards to use the new I2C
devicetree properties for specifying the SDA and SCL pins.

This was done with a script.

Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
Use tabs.

Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
I only see one sample with an overlay using the now legacy sda-pin and
scl-pin properties. Move it to the new style.

Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
@mbolivar-nordic
Copy link
Contributor Author

mbolivar-nordic commented Feb 25, 2021

All of the remaining CI failures contain the same message and look like timing nondeterminism to me:

    Assertion failed at WEST_TOPDIR/zephyr/tests/net/socket/select/src/main.c:101: test_select: (tstamp <= FUZZ is false)

I'm going to consider this green CI and will work with @carlescufi to get this merged tomorrow after removing the DNM patch increasing the bitkeeper parallelism.

Hopefully this is it; thanks to everyone who reviewed.

@mbolivar-nordic mbolivar-nordic removed the DNM This PR should not be merged (Do Not Merge) label Mar 1, 2021
@carlescufi carlescufi merged commit 01bb08e into zephyrproject-rtos:master Mar 1, 2021
@mnkp
Copy link
Member

mnkp commented Apr 13, 2021

The PR has been merged, so following is just for the record. I believe the implementation presented in this PR does not follow Linux device tree specification.

The -gpios properties are meant to be used for pins controlled by the GPIO module only. This is documented in "Specifying GPIO information for devices".

Pins controlled by other hardware modules, i2c, uart, spi, etc. should use pinctrl-bindings. Unfortunately, it doesn't seem to be a good match for requirements imposed by the Nordic HAL so the now deprecated -pin properties might have been a better choice.

In general it's important to be able to distinguish if the pin is controlled by the the hardware module, e.g. i2c, spi or the GPIO module since there exist configurations when the same pin e.g. SS pin of the SPI bus is switched at runtime between SPI and GPIO hardware module. DT node describing such configuration would contain both: pinctrl- and -gpios properties.

@mbolivar-nordic
Copy link
Contributor Author

@mnkp I'm working through all of our bindings during this release to move them to foo-gpios, so I would like to know more about what a better way might be. Note that @anangl is also following this approach in #34251. I think we need to converge on the right approach quickly if possible.

However, I think it's important to be able to specify a GPIO controller phandle, pin, and flags.

For some additional relevant background, I tried to get a build system target merged which produced a report of which pins were used by which peripherals in #24132. That used the existing foo-pin properties, but it was rejected as insufficiently generic to go upstream, and I was under the impression that we would have to do something like this PR to get this feature merged on top of it.

I think a real phandle is also important so the I2C -> GPIO device dependency is tracked in things like DT_REQUIRES_DEP_ORDS().

A pin number is important for obvious reasons.

As for flags, I was planning on replacing things like our miso-pull-up property with the relevant GPIO flags.

Unfortunately, it doesn't seem to be a good match for requirements imposed by the Nordic HAL

These are not simply HAL requirements. Each peripheral has registers which are programmed with the port and pin to use which were the actual foo-pin values, so a SPI peripheral has a PSEL.MOSI register, and so forth.

This PR's approach of converting a phandle and pin to the value that goes into these registers is more readable. I am trying to avoid past support problems with people who didn't get how to encode and decode the foo-pin properties, which after all are exposing raw register values.

Beyond these PSEL.MOSI style registers, the pins themselves are configured using the GPIO registers.

I can rename these properties to something that's more appropriate than scl-gpios, etc. if you can suggest an alternative, but given the above I think the general approach is sound. However I haven't followed the pinctrl discussion and I may have missed something; I'll read through your reference and see what I can come up with.

@mnkp
Copy link
Member

mnkp commented Apr 15, 2021

At first short introduction to the Linux pinctrl DT bindings. The Linux description of pin controller node in DT was developed around the notion that the SoC has a dedicated pin controller block, most SoCs do, that has its own register address and its main purpose is to route signals between pins and different SoC peripherals. It quickly become clear that the actual hardware design of pin muxing in SoCs put on the market by different vendors differs so much that it's not feasible to have one way to describe pin controller nodes in DT. That's why Linux pinctrl bindings make recommendations, show how to describe typical hardware but officially leave the actual implementation in the hands of the developer.

That is, it's OK to have vendor specific implementation.

About the only requirement that Linux DT imposes is that pin configuration on the client side, e.g. I2C module, will be defined using pinctrl-n properties. From the binding document

Required properties:
pinctrl-0:	List of phandles, each pointing at a pin configuration
		node. These referenced pin configuration nodes must be child
		nodes of the pin controller that they configure.

It would be nice to have it done this way also for Nordic but it's not that easy and probably it's not worth it.

For me it's fine if those families, like Nordic or SiLabs, that don't actually have pin controller hardware module use a vendor specific approach. The drawback here is that they will never have support for the official Zephyr pinctrl API. But surely they could have a vendor specific one.

That said, the -gpios properties are used in DT exclusively to describe pins connected to / owned by the GPIO driver, so whatever way we come up with we should not use those to connect pins with other peripherals.

However, I think it's important to be able to specify a GPIO controller phandle, pin, and flags.

Yes, sounds good. I believe we should use whatever is easiest, most natural for the user.

For some additional relevant background, I tried to get a build system target merged which produced a report of which pins were used by which peripherals in #24132. That used the existing foo-pin properties, but it was rejected as insufficiently generic to go upstream, and I was under the impression that we would have to do something like this PR to get this feature merged on top of it.

That looks good, it would be great to have it supported on all the platforms. However, a general solution won't be easy. Likely, the implementation would always need to be family specific.

@mbolivar-nordic
Copy link
Contributor Author

The drawback here is that they will never have support for the official Zephyr pinctrl API. But surely they could have a vendor specific one.

Tagging @carlescufi and @anangl on this feedback from @mnkp about the scl-gpios, sda-gpios approach I have taken for TWIM etc. and we are taking on I2S and other peripherals.

I think this is a rather serious drawback and we need to rethink our approach.

@mbolivar-nordic
Copy link
Contributor Author

About the only requirement that Linux DT imposes is that pin configuration on the client side, e.g. I2C module, will be defined using pinctrl-n properties. [...] It would be nice to have it done this way also for Nordic but it's not that easy and probably it's not worth it.

@mnkp Just throwing an idea out here to check my understanding. What's wrong with something like this?

i2c0: i2c@40003000 {
	compatible = "nordic,nrf-twi";
	/* ... */

	pinctrl-0 = <&i2c0_pinctrl>;
	i2c0_pinctrl: pinctrl {
		sda-gpios = <&gpio0 26 0x0>;
		scl-gpios = <&gpio0 27 0x0>;
	};
};

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

9 participants