* [PATCH 1/4] dt-bindings: i3c: Add AST2600 i3c controller
2023-02-16 7:41 [PATCH 0/4] i3c: Add support for ast2600 i3c controller Jeremy Kerr
@ 2023-02-16 7:41 ` Jeremy Kerr
2023-02-16 8:24 ` Krzysztof Kozlowski
2023-02-16 13:58 ` Rob Herring
2023-02-16 7:41 ` [PATCH 2/4] i3c: dw: Add platform operations Jeremy Kerr
` (3 subsequent siblings)
4 siblings, 2 replies; 10+ messages in thread
From: Jeremy Kerr @ 2023-02-16 7:41 UTC (permalink / raw)
To: linux-i3c
Cc: Alexandre Belloni, Vitor Soares, linux-aspeed, devicetree,
Rob Herring, Krzysztof Kozlowski, Dylan Hung, Joel Stanley,
Andrew Jeffery
Add a devicetree binding for the ast2600 i3c controller hardware. This
is heavily based on the designware i3c core, plus a reset facility
and two platform-specific properties:
- sda-pullup-ohms: to specify the value of the configurable pullup
resistors on the SDA line
- aspeed,global-regs: to reference the (ast2600-specific) i3c global
register block, and the device index to use within it.
Signed-off-by: Jeremy Kerr <jk@codeconstruct.com.au>
---
changes from RFC:
- add vendor prefix to global-regs properties
- add item description on global-regs property
- drop global reg node from example
---
.../bindings/i3c/aspeed,ast2600-i3c.yaml | 73 +++++++++++++++++++
1 file changed, 73 insertions(+)
create mode 100644 Documentation/devicetree/bindings/i3c/aspeed,ast2600-i3c.yaml
diff --git a/Documentation/devicetree/bindings/i3c/aspeed,ast2600-i3c.yaml b/Documentation/devicetree/bindings/i3c/aspeed,ast2600-i3c.yaml
new file mode 100644
index 000000000000..920428f243b5
--- /dev/null
+++ b/Documentation/devicetree/bindings/i3c/aspeed,ast2600-i3c.yaml
@@ -0,0 +1,73 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/i3c/aspeed,ast2600-i3c.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: ASPEED AST2600 i3c controller
+
+maintainers:
+ - Jeremy Kerr <jk@codeconstruct.com.au>
+
+allOf:
+ - $ref: i3c.yaml#
+
+properties:
+ compatible:
+ const: aspeed,ast2600-i3c
+
+ reg:
+ maxItems: 1
+
+ clocks:
+ maxItems: 1
+
+ resets:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ sda-pullup-ohms:
+ enum: [545, 750, 2000]
+ default: 2000
+ description: |
+ Value to configure SDA pullup resistor, in Ohms.
+
+ aspeed,global-regs:
+ $ref: /schemas/types.yaml#/definitions/phandle-array
+ items:
+ - items:
+ - description: phandle to i3c global register syscon node
+ - description: index of this i3c controller in the global register set
+ description: |
+ A (phandle, controller index) reference to the i3c global register set
+ used for this device.
+
+required:
+ - compatible
+ - reg
+ - clocks
+ - interrupts
+ - aspeed,global-regs
+
+unevaluatedProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/clock/ast2600-clock.h>
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+ i3c-master@2000 {
+ compatible = "aspeed,ast2600-i3c";
+ reg = <0x2000 0x1000>;
+ #address-cells = <3>;
+ #size-cells = <0>;
+ clocks = <&syscon ASPEED_CLK_GATE_I3C0CLK>;
+ resets = <&syscon ASPEED_RESET_I3C0>;
+ aspeed,global-regs = <&i3c_global 0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i3c1_default>;
+ interrupts = <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>;
+ };
+...
--
2.39.1
--
linux-i3c mailing list
linux-i3c@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-i3c
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH 1/4] dt-bindings: i3c: Add AST2600 i3c controller
2023-02-16 7:41 ` [PATCH 1/4] dt-bindings: i3c: Add AST2600 " Jeremy Kerr
@ 2023-02-16 8:24 ` Krzysztof Kozlowski
2023-02-16 13:58 ` Rob Herring
1 sibling, 0 replies; 10+ messages in thread
From: Krzysztof Kozlowski @ 2023-02-16 8:24 UTC (permalink / raw)
To: Jeremy Kerr, linux-i3c
Cc: Alexandre Belloni, Vitor Soares, linux-aspeed, devicetree,
Rob Herring, Krzysztof Kozlowski, Dylan Hung, Joel Stanley,
Andrew Jeffery
On 16/02/2023 08:41, Jeremy Kerr wrote:
> Add a devicetree binding for the ast2600 i3c controller hardware. This
> is heavily based on the designware i3c core, plus a reset facility
> and two platform-specific properties:
>
> - sda-pullup-ohms: to specify the value of the configurable pullup
> resistors on the SDA line
>
> - aspeed,global-regs: to reference the (ast2600-specific) i3c global
> register block, and the device index to use within it.
>
> Signed-off-by: Jeremy Kerr <jk@codeconstruct.com.au>
>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Best regards,
Krzysztof
--
linux-i3c mailing list
linux-i3c@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-i3c
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 1/4] dt-bindings: i3c: Add AST2600 i3c controller
2023-02-16 7:41 ` [PATCH 1/4] dt-bindings: i3c: Add AST2600 " Jeremy Kerr
2023-02-16 8:24 ` Krzysztof Kozlowski
@ 2023-02-16 13:58 ` Rob Herring
1 sibling, 0 replies; 10+ messages in thread
From: Rob Herring @ 2023-02-16 13:58 UTC (permalink / raw)
To: Jeremy Kerr
Cc: Alexandre Belloni, Krzysztof Kozlowski, linux-i3c, Joel Stanley,
devicetree, Rob Herring, Vitor Soares, Dylan Hung, linux-aspeed,
Andrew Jeffery
On Thu, 16 Feb 2023 15:41:52 +0800, Jeremy Kerr wrote:
> Add a devicetree binding for the ast2600 i3c controller hardware. This
> is heavily based on the designware i3c core, plus a reset facility
> and two platform-specific properties:
>
> - sda-pullup-ohms: to specify the value of the configurable pullup
> resistors on the SDA line
>
> - aspeed,global-regs: to reference the (ast2600-specific) i3c global
> register block, and the device index to use within it.
>
> Signed-off-by: Jeremy Kerr <jk@codeconstruct.com.au>
>
> ---
> changes from RFC:
> - add vendor prefix to global-regs properties
> - add item description on global-regs property
> - drop global reg node from example
> ---
> .../bindings/i3c/aspeed,ast2600-i3c.yaml | 73 +++++++++++++++++++
> 1 file changed, 73 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/i3c/aspeed,ast2600-i3c.yaml
>
My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
on your patch (DT_CHECKER_FLAGS is new in v5.13):
yamllint warnings/errors:
dtschema/dtc warnings/errors:
Error: Documentation/devicetree/bindings/i3c/aspeed,ast2600-i3c.example.dts:30.31-32 syntax error
FATAL ERROR: Unable to parse input tree
make[1]: *** [scripts/Makefile.lib:434: Documentation/devicetree/bindings/i3c/aspeed,ast2600-i3c.example.dtb] Error 1
make[1]: *** Waiting for unfinished jobs....
make: *** [Makefile:1508: dt_binding_check] Error 2
doc reference errors (make refcheckdocs):
See https://patchwork.ozlabs.org/project/devicetree-bindings/patch/82d750f53df622d8986e9a07053c7ee27dee61a2.1676532146.git.jk@codeconstruct.com.au
The base for the series is generally the latest rc1. A different dependency
should be noted in *this* patch.
If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:
pip3 install dtschema --upgrade
Please check and re-submit after running the above command yourself. Note
that DT_SCHEMA_FILES can be set to your schema file to speed up checking
your schema. However, it must be unset to test all examples with your schema.
--
linux-i3c mailing list
linux-i3c@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-i3c
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 2/4] i3c: dw: Add platform operations
2023-02-16 7:41 [PATCH 0/4] i3c: Add support for ast2600 i3c controller Jeremy Kerr
2023-02-16 7:41 ` [PATCH 1/4] dt-bindings: i3c: Add AST2600 " Jeremy Kerr
@ 2023-02-16 7:41 ` Jeremy Kerr
2023-02-16 15:04 ` Ben Dooks
2023-02-16 7:41 ` [PATCH 3/4] i3c: dw: Add AST2600 platform ops Jeremy Kerr
` (2 subsequent siblings)
4 siblings, 1 reply; 10+ messages in thread
From: Jeremy Kerr @ 2023-02-16 7:41 UTC (permalink / raw)
To: linux-i3c
Cc: Alexandre Belloni, Vitor Soares, linux-aspeed, devicetree,
Rob Herring, Krzysztof Kozlowski, Dylan Hung, Joel Stanley,
Andrew Jeffery
The dw i3c core can be integrated into various SoC devices. Platforms
that use this core may need a little configuration that is specific to
that platform.
Add a little infrastructure to allow platform-specific behaviour: a bit
of data on struct dw_i3c_master, and two hooks to the probe and init
calls to enable this.
A future change will add new platform support that uses these hooks.
Signed-off-by: Jeremy Kerr <jk@codeconstruct.com.au>
---
drivers/i3c/master/dw-i3c-master.c | 42 +++++++++++++++++++++++++-----
1 file changed, 36 insertions(+), 6 deletions(-)
diff --git a/drivers/i3c/master/dw-i3c-master.c b/drivers/i3c/master/dw-i3c-master.c
index d73d57362b3b..49b891449222 100644
--- a/drivers/i3c/master/dw-i3c-master.c
+++ b/drivers/i3c/master/dw-i3c-master.c
@@ -241,6 +241,17 @@ struct dw_i3c_master {
char version[5];
char type[5];
u8 addrs[MAX_DEVS];
+
+ /* platform-specific data */
+ const struct dw_i3c_platform_ops *platform_ops;
+ union {
+ } pdata;
+
+};
+
+struct dw_i3c_platform_ops {
+ int (*probe)(struct dw_i3c_master *i3c, struct platform_device *pdev);
+ int (*init)(struct dw_i3c_master *i3c);
};
struct dw_i3c_i2c_dev_data {
@@ -612,6 +623,12 @@ static int dw_i3c_master_bus_init(struct i3c_master_controller *m)
u32 thld_ctrl;
int ret;
+ if (master->platform_ops && master->platform_ops->init) {
+ ret = master->platform_ops->init(master);
+ if (ret)
+ return ret;
+ }
+
switch (bus->mode) {
case I3C_BUS_MODE_MIXED_FAST:
case I3C_BUS_MODE_MIXED_LIMITED:
@@ -1128,8 +1145,15 @@ static const struct i3c_master_controller_ops dw_mipi_i3c_ops = {
.i2c_xfers = dw_i3c_master_i2c_xfers,
};
+static const struct of_device_id dw_i3c_master_of_match[] = {
+ { .compatible = "snps,dw-i3c-master-1.00a", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, dw_i3c_master_of_match);
+
static int dw_i3c_probe(struct platform_device *pdev)
{
+ const struct of_device_id *match;
struct dw_i3c_master *master;
int ret, irq;
@@ -1181,6 +1205,18 @@ static int dw_i3c_probe(struct platform_device *pdev)
master->maxdevs = ret >> 16;
master->free_pos = GENMASK(master->maxdevs - 1, 0);
+ /* match any platform-specific ops */
+ match = of_match_node(dw_i3c_master_of_match, pdev->dev.of_node);
+ if (match && match->data)
+ master->platform_ops = match->data;
+
+ /* platform-specific probe */
+ if (master->platform_ops && master->platform_ops->probe) {
+ ret = master->platform_ops->probe(master, pdev);
+ if (ret)
+ goto err_assert_rst;
+ }
+
ret = i3c_master_register(&master->base, &pdev->dev,
&dw_mipi_i3c_ops, false);
if (ret)
@@ -1213,12 +1249,6 @@ static int dw_i3c_remove(struct platform_device *pdev)
return 0;
}
-static const struct of_device_id dw_i3c_master_of_match[] = {
- { .compatible = "snps,dw-i3c-master-1.00a", },
- {},
-};
-MODULE_DEVICE_TABLE(of, dw_i3c_master_of_match);
-
static struct platform_driver dw_i3c_driver = {
.probe = dw_i3c_probe,
.remove = dw_i3c_remove,
--
2.39.1
--
linux-i3c mailing list
linux-i3c@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-i3c
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH 2/4] i3c: dw: Add platform operations
2023-02-16 7:41 ` [PATCH 2/4] i3c: dw: Add platform operations Jeremy Kerr
@ 2023-02-16 15:04 ` Ben Dooks
2023-02-17 9:43 ` Jeremy Kerr
0 siblings, 1 reply; 10+ messages in thread
From: Ben Dooks @ 2023-02-16 15:04 UTC (permalink / raw)
To: Jeremy Kerr, linux-i3c
Cc: Alexandre Belloni, Vitor Soares, linux-aspeed, devicetree,
Rob Herring, Krzysztof Kozlowski, Dylan Hung, Joel Stanley,
Andrew Jeffery
On 16/02/2023 07:41, Jeremy Kerr wrote:
> The dw i3c core can be integrated into various SoC devices. Platforms
> that use this core may need a little configuration that is specific to
> that platform.
>
> Add a little infrastructure to allow platform-specific behaviour: a bit
> of data on struct dw_i3c_master, and two hooks to the probe and init
> calls to enable this.
>
> A future change will add new platform support that uses these hooks.
>
> Signed-off-by: Jeremy Kerr <jk@codeconstruct.com.au>
> ---
> drivers/i3c/master/dw-i3c-master.c | 42 +++++++++++++++++++++++++-----
> 1 file changed, 36 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/i3c/master/dw-i3c-master.c b/drivers/i3c/master/dw-i3c-master.c
> index d73d57362b3b..49b891449222 100644
> --- a/drivers/i3c/master/dw-i3c-master.c
> +++ b/drivers/i3c/master/dw-i3c-master.c
> @@ -241,6 +241,17 @@ struct dw_i3c_master {
> char version[5];
> char type[5];
> u8 addrs[MAX_DEVS];
> +
> + /* platform-specific data */
> + const struct dw_i3c_platform_ops *platform_ops;
> + union {
> + } pdata;
> +
> +};
> +
> +struct dw_i3c_platform_ops {
> + int (*probe)(struct dw_i3c_master *i3c, struct platform_device *pdev);
> + int (*init)(struct dw_i3c_master *i3c);
> };
Given the comment below having this and the main probe defined in a
header so users can just call in and we don't have to change the
main code here every time someone comes up with their own
special way of handing this?
> struct dw_i3c_i2c_dev_data {
> @@ -612,6 +623,12 @@ static int dw_i3c_master_bus_init(struct i3c_master_controller *m)
> u32 thld_ctrl;
> int ret;
>
> + if (master->platform_ops && master->platform_ops->init) {
> + ret = master->platform_ops->init(master);
> + if (ret)
> + return ret;
> + }
I'd rather have a "default" set of ops than have all this checking for
NULL pointers all over the place.
> +
> switch (bus->mode) {
> case I3C_BUS_MODE_MIXED_FAST:
> case I3C_BUS_MODE_MIXED_LIMITED:
> @@ -1128,8 +1145,15 @@ static const struct i3c_master_controller_ops dw_mipi_i3c_ops = {
> .i2c_xfers = dw_i3c_master_i2c_xfers,
> };
>
> +static const struct of_device_id dw_i3c_master_of_match[] = {
> + { .compatible = "snps,dw-i3c-master-1.00a", },
> + {},
> +};
> +MODULE_DEVICE_TABLE(of, dw_i3c_master_of_match);
> +
> static int dw_i3c_probe(struct platform_device *pdev)
> {
> + const struct of_device_id *match;
> struct dw_i3c_master *master;
> int ret, irq;
>
> @@ -1181,6 +1205,18 @@ static int dw_i3c_probe(struct platform_device *pdev)
> master->maxdevs = ret >> 16;
> master->free_pos = GENMASK(master->maxdevs - 1, 0);
>
> + /* match any platform-specific ops */
> + match = of_match_node(dw_i3c_master_of_match, pdev->dev.of_node);
> + if (match && match->data)
> + master->platform_ops = match->data;
I'm sure there's a of_device_get_match_data() which would have
both removed hte need to move the match table around and the
call to of_match_node().
> +
> + /* platform-specific probe */
> + if (master->platform_ops && master->platform_ops->probe) {
> + ret = master->platform_ops->probe(master, pdev);
> + if (ret)
> + goto err_assert_rst;
> + }
> +
> ret = i3c_master_register(&master->base, &pdev->dev,
> &dw_mipi_i3c_ops, false);
> if (ret)
> @@ -1213,12 +1249,6 @@ static int dw_i3c_remove(struct platform_device *pdev)
> return 0;
> }
>
> -static const struct of_device_id dw_i3c_master_of_match[] = {
> - { .compatible = "snps,dw-i3c-master-1.00a", },
> - {},
> -};
> -MODULE_DEVICE_TABLE(of, dw_i3c_master_of_match);
> -
> static struct platform_driver dw_i3c_driver = {
> .probe = dw_i3c_probe,
> .remove = dw_i3c_remove,
--
linux-i3c mailing list
linux-i3c@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-i3c
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 2/4] i3c: dw: Add platform operations
2023-02-16 15:04 ` Ben Dooks
@ 2023-02-17 9:43 ` Jeremy Kerr
0 siblings, 0 replies; 10+ messages in thread
From: Jeremy Kerr @ 2023-02-17 9:43 UTC (permalink / raw)
To: Ben Dooks, linux-i3c
Cc: Alexandre Belloni, Vitor Soares, linux-aspeed, devicetree,
Rob Herring, Krzysztof Kozlowski, Dylan Hung, Joel Stanley,
Andrew Jeffery
Hi Ben,
Thanks for taking a look at the patch. My responses inline (just
re-ordered, simple stuff first)
> > struct dw_i3c_i2c_dev_data {
> > @@ -612,6 +623,12 @@ static int dw_i3c_master_bus_init(struct i3c_master_controller *m)
> > u32 thld_ctrl;
> > int ret;
> >
> > + if (master->platform_ops && master->platform_ops->init) {
> > + ret = master->platform_ops->init(master);
> > + if (ret)
> > + return ret;
> > + }
>
> I'd rather have a "default" set of ops than have all this checking for
> NULL pointers all over the place.
Yep, that's a better structure, changed for v2.
> > @@ -1181,6 +1205,18 @@ static int dw_i3c_probe(struct platform_device *pdev)
> > master->maxdevs = ret >> 16;
> > master->free_pos = GENMASK(master->maxdevs - 1, 0);
> >
> > + /* match any platform-specific ops */
> > + match = of_match_node(dw_i3c_master_of_match, pdev->dev.of_node);
> > + if (match && match->data)
> > + master->platform_ops = match->data;
>
> I'm sure there's a of_device_get_match_data() which would have
> both removed hte need to move the match table around and the
> call to of_match_node().
That's the one I was looking for! Thanks for the pointer, I have updated
in v2.
> > @@ -241,6 +241,17 @@ struct dw_i3c_master {
> > char version[5];
> > char type[5];
> > u8 addrs[MAX_DEVS];
> > +
> > + /* platform-specific data */
> > + const struct dw_i3c_platform_ops *platform_ops;
> > + union {
> > + } pdata;
> > +
> > +};
> > +
> > +struct dw_i3c_platform_ops {
> > + int (*probe)(struct dw_i3c_master *i3c, struct platform_device *pdev);
> > + int (*init)(struct dw_i3c_master *i3c);
> > };
>
> Given the comment below having this and the main probe defined in a
> header so users can just call in and we don't have to change the
> main code here every time someone comes up with their own
> special way of handing this?
I'm not sure I 100% understand the intention here - is it that we'd
split the platform-specific code into entirely new drivers, and have
those call into dw_i3c_probe() (presumably doing a bit of custom init
either before or after that call)?
If so: I think the platform support should stay fairly minimal, so I'm
not sure that warrants a new driver for each instance. In the ast2600
case it's just a couple of extra reg writes in the i3c init path. I'd be
reluctant to split that out completely at this stage - but if this does
grow, we can certainly reconsider.
Also, I'd like to allow for the case where the platform-specific parts
may access the fields of struct dw_i3c_master; with this approach we
don't need to expose that struct outside of the single driver.
Cheers,
Jeremy
--
linux-i3c mailing list
linux-i3c@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-i3c
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 3/4] i3c: dw: Add AST2600 platform ops
2023-02-16 7:41 [PATCH 0/4] i3c: Add support for ast2600 i3c controller Jeremy Kerr
2023-02-16 7:41 ` [PATCH 1/4] dt-bindings: i3c: Add AST2600 " Jeremy Kerr
2023-02-16 7:41 ` [PATCH 2/4] i3c: dw: Add platform operations Jeremy Kerr
@ 2023-02-16 7:41 ` Jeremy Kerr
2023-02-16 7:41 ` [PATCH 4/4] i3c: dw: Add compatible string for ASPEED AST2600 BMC platform Jeremy Kerr
2023-03-01 1:04 ` [PATCH 0/4] i3c: Add support for ast2600 i3c controller Joel Stanley
4 siblings, 0 replies; 10+ messages in thread
From: Jeremy Kerr @ 2023-02-16 7:41 UTC (permalink / raw)
To: linux-i3c
Cc: Alexandre Belloni, Vitor Soares, linux-aspeed, devicetree,
Rob Herring, Krzysztof Kozlowski, Dylan Hung, Joel Stanley,
Andrew Jeffery
Now that we have platform-specific hooks for the dw i3c driver, add
platform support for the ASPEED AST2600 SoC.
The AST2600 has a small set of "i3c global" registers, providing
platform-level i3c configuration outside of the i3c core.
For the ast2600, we need a couple of extra setup operations:
- on probe: find the i3c global register set and parse the SDA pullup
resistor values
- on init: set the pullups accordingly, and set the i3c instance IDs
Signed-off-by: Jeremy Kerr <jk@codeconstruct.com.au>
---
drivers/i3c/master/dw-i3c-master.c | 122 +++++++++++++++++++++++++++++
1 file changed, 122 insertions(+)
diff --git a/drivers/i3c/master/dw-i3c-master.c b/drivers/i3c/master/dw-i3c-master.c
index 49b891449222..9be3348cba0e 100644
--- a/drivers/i3c/master/dw-i3c-master.c
+++ b/drivers/i3c/master/dw-i3c-master.c
@@ -16,8 +16,10 @@
#include <linux/iopoll.h>
#include <linux/list.h>
#include <linux/module.h>
+#include <linux/mfd/syscon.h>
#include <linux/of.h>
#include <linux/platform_device.h>
+#include <linux/regmap.h>
#include <linux/reset.h>
#include <linux/slab.h>
@@ -201,6 +203,28 @@
#define XFER_TIMEOUT (msecs_to_jiffies(1000))
+/* AST2600-specific global register set */
+#define AST2600_I3CG_REG0(idx) (((idx) * 4 * 4) + 0x10)
+#define AST2600_I3CG_REG1(idx) (((idx) * 4 * 4) + 0x14)
+
+#define AST2600_I3CG_REG0_SDA_PULLUP_EN_MASK GENMASK(29, 28)
+#define AST2600_I3CG_REG0_SDA_PULLUP_EN_2K (0x0 << 28)
+#define AST2600_I3CG_REG0_SDA_PULLUP_EN_750 (0x2 << 28)
+
+#define AST2600_I3CG_REG1_I2C_MODE BIT(0)
+#define AST2600_I3CG_REG1_TEST_MODE BIT(1)
+#define AST2600_I3CG_REG1_ACT_MODE_MASK GENMASK(3, 2)
+#define AST2600_I3CG_REG1_ACT_MODE(x) (((x) << 2) & AST2600_I3CG_REG1_ACT_MODE_MASK)
+#define AST2600_I3CG_REG1_PENDING_INT_MASK GENMASK(7, 4)
+#define AST2600_I3CG_REG1_PENDING_INT(x) (((x) << 4) & AST2600_I3CG_REG1_PENDING_INT_MASK)
+#define AST2600_I3CG_REG1_SA_MASK GENMASK(14, 8)
+#define AST2600_I3CG_REG1_SA(x) (((x) << 8) & AST2600_I3CG_REG1_SA_MASK)
+#define AST2600_I3CG_REG1_SA_EN BIT(15)
+#define AST2600_I3CG_REG1_INST_ID_MASK GENMASK(19, 16)
+#define AST2600_I3CG_REG1_INST_ID(x) (((x) << 16) & AST2600_I3CG_REG1_INST_ID_MASK)
+
+#define AST2600_DEFAULT_SDA_PULLUP_OHMS 2000
+
struct dw_i3c_master_caps {
u8 cmdfifodepth;
u8 datafifodepth;
@@ -224,6 +248,12 @@ struct dw_i3c_xfer {
struct dw_i3c_cmd cmds[];
};
+struct pdata_ast2600 {
+ struct regmap *global_regs;
+ unsigned int global_idx;
+ unsigned int sda_pullup;
+};
+
struct dw_i3c_master {
struct i3c_master_controller base;
u16 maxdevs;
@@ -245,6 +275,7 @@ struct dw_i3c_master {
/* platform-specific data */
const struct dw_i3c_platform_ops *platform_ops;
union {
+ struct pdata_ast2600 ast2600;
} pdata;
};
@@ -1145,6 +1176,97 @@ static const struct i3c_master_controller_ops dw_mipi_i3c_ops = {
.i2c_xfers = dw_i3c_master_i2c_xfers,
};
+/* hardware-specific ops */
+
+static int ast2600_i3c_pullup_to_reg(unsigned int ohms, u32 *regp)
+{
+ u32 reg;
+
+ switch (ohms) {
+ case 2000:
+ reg = AST2600_I3CG_REG0_SDA_PULLUP_EN_2K;
+ break;
+ case 750:
+ reg = AST2600_I3CG_REG0_SDA_PULLUP_EN_750;
+ break;
+ case 545:
+ reg = AST2600_I3CG_REG0_SDA_PULLUP_EN_2K |
+ AST2600_I3CG_REG0_SDA_PULLUP_EN_750;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if (regp)
+ *regp = reg;
+
+ return 0;
+}
+
+static int ast2600_i3c_probe(struct dw_i3c_master *master,
+ struct platform_device *pdev)
+{
+ struct pdata_ast2600 *pdata = &master->pdata.ast2600;
+ struct device_node *np = pdev->dev.of_node;
+ struct of_phandle_args gspec;
+ int rc;
+
+ rc = of_parse_phandle_with_fixed_args(np, "aspeed,global-regs", 1, 0,
+ &gspec);
+ if (rc)
+ return -ENODEV;
+
+ pdata->global_regs = syscon_node_to_regmap(gspec.np);
+ of_node_put(gspec.np);
+
+ if (IS_ERR(pdata->global_regs))
+ return PTR_ERR(pdata->global_regs);
+
+ pdata->global_idx = gspec.args[0];
+
+ rc = of_property_read_u32(np, "sda-pullup-ohms", &pdata->sda_pullup);
+ if (rc)
+ pdata->sda_pullup = AST2600_DEFAULT_SDA_PULLUP_OHMS;
+
+ rc = ast2600_i3c_pullup_to_reg(pdata->sda_pullup, NULL);
+ if (rc)
+ dev_err(&master->base.dev, "invalid sda-pullup value %d\n",
+ pdata->sda_pullup);
+
+ return rc;
+}
+
+static int ast2600_i3c_init(struct dw_i3c_master *master)
+{
+ struct pdata_ast2600 *pdata = &master->pdata.ast2600;
+ u32 reg = 0;
+ int rc;
+
+ /* reg0: set SDA pullup values */
+ rc = ast2600_i3c_pullup_to_reg(pdata->sda_pullup, ®);
+ if (rc)
+ return rc;
+
+ rc = regmap_write(pdata->global_regs,
+ AST2600_I3CG_REG0(pdata->global_idx), reg);
+ if (rc)
+ return rc;
+
+ /* reg1: set up the instance id, but leave everything else disabled,
+ * as it's all for client mode
+ */
+ reg = AST2600_I3CG_REG1_INST_ID(pdata->global_idx);
+ rc = regmap_write(pdata->global_regs,
+ AST2600_I3CG_REG1(pdata->global_idx), reg);
+
+ return rc;
+}
+
+static const struct dw_i3c_platform_ops ast2600_platform_ops = {
+ .probe = ast2600_i3c_probe,
+ .init = ast2600_i3c_init,
+};
+
static const struct of_device_id dw_i3c_master_of_match[] = {
{ .compatible = "snps,dw-i3c-master-1.00a", },
{},
--
2.39.1
--
linux-i3c mailing list
linux-i3c@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-i3c
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 4/4] i3c: dw: Add compatible string for ASPEED AST2600 BMC platform
2023-02-16 7:41 [PATCH 0/4] i3c: Add support for ast2600 i3c controller Jeremy Kerr
` (2 preceding siblings ...)
2023-02-16 7:41 ` [PATCH 3/4] i3c: dw: Add AST2600 platform ops Jeremy Kerr
@ 2023-02-16 7:41 ` Jeremy Kerr
2023-03-01 1:04 ` [PATCH 0/4] i3c: Add support for ast2600 i3c controller Joel Stanley
4 siblings, 0 replies; 10+ messages in thread
From: Jeremy Kerr @ 2023-02-16 7:41 UTC (permalink / raw)
To: linux-i3c
Cc: Alexandre Belloni, Vitor Soares, linux-aspeed, devicetree,
Rob Herring, Krzysztof Kozlowski, Dylan Hung, Joel Stanley,
Andrew Jeffery
Now that we have platform-specific code for the ast2600, enable it
through a new compatible string.
Signed-off-by: Jeremy Kerr <jk@codeconstruct.com.au>
---
drivers/i3c/master/dw-i3c-master.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/i3c/master/dw-i3c-master.c b/drivers/i3c/master/dw-i3c-master.c
index 9be3348cba0e..5ac226e0c558 100644
--- a/drivers/i3c/master/dw-i3c-master.c
+++ b/drivers/i3c/master/dw-i3c-master.c
@@ -1269,6 +1269,7 @@ static const struct dw_i3c_platform_ops ast2600_platform_ops = {
static const struct of_device_id dw_i3c_master_of_match[] = {
{ .compatible = "snps,dw-i3c-master-1.00a", },
+ { .compatible = "aspeed,ast2600-i3c", .data = &ast2600_platform_ops },
{},
};
MODULE_DEVICE_TABLE(of, dw_i3c_master_of_match);
--
2.39.1
--
linux-i3c mailing list
linux-i3c@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-i3c
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH 0/4] i3c: Add support for ast2600 i3c controller
2023-02-16 7:41 [PATCH 0/4] i3c: Add support for ast2600 i3c controller Jeremy Kerr
` (3 preceding siblings ...)
2023-02-16 7:41 ` [PATCH 4/4] i3c: dw: Add compatible string for ASPEED AST2600 BMC platform Jeremy Kerr
@ 2023-03-01 1:04 ` Joel Stanley
4 siblings, 0 replies; 10+ messages in thread
From: Joel Stanley @ 2023-03-01 1:04 UTC (permalink / raw)
To: Jeremy Kerr
Cc: linux-i3c, Alexandre Belloni, Vitor Soares, linux-aspeed,
devicetree, Rob Herring, Krzysztof Kozlowski, Dylan Hung,
Andrew Jeffery
On Thu, 16 Feb 2023 at 07:42, Jeremy Kerr <jk@codeconstruct.com.au> wrote:
>
> The AST2600 SoC hardware includes a set of i3c controllers, based on the
> designware i3c core, plus some global registers for SoC integration.
>
> This series adds support for these i3c controllers, through the existing
> dw i3c master controller driver, by adding a set of platform-specific
> hooks to handle the global register configuration. This also gives us a
> way to add any future hardware-specific behaviours.
>
> We also need a DT binding to describe the ast2600-specific hardware.
> Since this involves new (mandatory) properties, I have added this as a
> separate binding rather than add a new compat string to the dw binding.
>
> The dt-binding example depends on a prior submission to the dt binding
> headers:
>
> https://lore.kernel.org/linux-devicetree/cover.1676294433.git.jk@codeconstruct.com.au/
>
> Full support for the global regmap will land with this queued mfd change:
>
> https://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd.git/commit/?id=cf2271843de835839e91c5c036492a87085af756
>
> Of course, any queries/comments/etc are most welcome.
Reviewed-by: Joel Stanley <joel@jms.id.au>
>
> Cheers,
>
>
> Jeremy
>
> Jeremy Kerr (4):
> dt-bindings: i3c: Add AST2600 i3c controller
> i3c: dw: Add platform operations
> i3c: dw: Add AST2600 platform ops
> i3c: dw: Add compatible string for ASPEED AST2600 BMC platform
>
> .../bindings/i3c/aspeed,ast2600-i3c.yaml | 73 ++++++++
> drivers/i3c/master/dw-i3c-master.c | 165 +++++++++++++++++-
> 2 files changed, 232 insertions(+), 6 deletions(-)
> create mode 100644 Documentation/devicetree/bindings/i3c/aspeed,ast2600-i3c.yaml
>
> --
> 2.39.1
>
--
linux-i3c mailing list
linux-i3c@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-i3c
^ permalink raw reply [flat|nested] 10+ messages in thread