Commit cc944c89 authored by Marc Kleine-Budde's avatar Marc Kleine-Budde

Merge branch 'can-add-support-for-rz-n1-sja1000-can-controller'

Biju Das says:

====================
Add support for RZ/N1 SJA1000 CAN controller

This patch series aims to add support for RZ/N1 SJA1000 CAN controller.

The SJA1000 CAN controller on RZ/N1 SoC has some differences compared
to others like it has no clock divider register (CDR) support and it has
no HW loopback (HW doesn't see tx messages on rx), so introduced a new
compatible 'renesas,rzn1-sja1000' to handle these differences.

v3->v4:
 * Updated bindings as per coding style used in example-schema.
 * Entire entry in properties compatible declared as enum. Also Descriptions
   do not bring any information,so removed it from compatible description.
 * Used decimal values in nxp,tx-output-mode enums.
 * Fixed indentaions in binding examples.
 * Removed clock-names from bindings, as it is single clock.
 * Optimized the code as per Vincent's suggestion.
 * Updated clock handling as per bindings.
v2->v3:
 * Added reg-io-width is a required property for technologic,sja1000 & renesas,rzn1-sja1000
 * Removed enum type from nxp,tx-output-config and updated the description
   for combination of TX0 and TX1.
 * Updated the example for technologic,sja1000
v1->v2:
 * Moved $ref: can-controller.yaml# to top along with if conditional to
  avoid multiple mapping issues with the if conditional in the subsequent
   patch.
 * Added an example for RZ/N1D SJA1000 usage.
 * Updated commit description for patch#2,#3 and #6
 * Removed the quirk macro SJA1000_NO_HW_LOOPBACK_QUIRK
 * Added prefix SJA1000_QUIRK_* for quirk macro.
 * Replaced of_device_get_match_data->device_get_match_data.
 * Added error handling on clk error path
 * Started using "devm_clk_get_optional_enabled" for clk get,prepare and enable.

Ref:
 [1] https://lore.kernel.org/linux-renesas-soc/20220701162320.102165-1-biju.das.jz@bp.renesas.com/T/#t
====================

Link: https://lore.kernel.org/all/20220710115248.190280-1-biju.das.jz@bp.renesas.com
[mkl: applying patches 1...5 only, as 6 depends
      devm_clk_get_optional_enabled(), which is not in
      net-next/master, yet]
Signed-off-by: default avatarMarc Kleine-Budde <mkl@pengutronix.de>
parents 8575f314 6d5fe107
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/net/can/nxp,sja1000.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Memory mapped SJA1000 CAN controller from NXP (formerly Philips)
maintainers:
- Wolfgang Grandegger <wg@grandegger.com>
properties:
compatible:
oneOf:
- enum:
- nxp,sja1000
- technologic,sja1000
- items:
- enum:
- renesas,r9a06g032-sja1000 # RZ/N1D
- renesas,r9a06g033-sja1000 # RZ/N1S
- const: renesas,rzn1-sja1000 # RZ/N1
reg:
maxItems: 1
interrupts:
maxItems: 1
clocks:
maxItems: 1
reg-io-width:
$ref: /schemas/types.yaml#/definitions/uint32
description: I/O register width (in bytes) implemented by this device
default: 1
enum: [ 1, 2, 4 ]
nxp,external-clock-frequency:
$ref: /schemas/types.yaml#/definitions/uint32
default: 16000000
description: |
Frequency of the external oscillator clock in Hz.
The internal clock frequency used by the SJA1000 is half of that value.
nxp,tx-output-mode:
$ref: /schemas/types.yaml#/definitions/uint32
enum: [ 0, 1, 2, 3 ]
default: 1
description: |
operation mode of the TX output control logic. Valid values are:
<0> : bi-phase output mode
<1> : normal output mode (default)
<2> : test output mode
<3> : clock output mode
nxp,tx-output-config:
$ref: /schemas/types.yaml#/definitions/uint32
default: 0x02
description: |
TX output pin configuration. Valid values are any one of the below
or combination of TX0 and TX1:
<0x01> : TX0 invert
<0x02> : TX0 pull-down (default)
<0x04> : TX0 pull-up
<0x06> : TX0 push-pull
<0x08> : TX1 invert
<0x10> : TX1 pull-down
<0x20> : TX1 pull-up
<0x30> : TX1 push-pull
nxp,clock-out-frequency:
$ref: /schemas/types.yaml#/definitions/uint32
description: |
clock frequency in Hz on the CLKOUT pin.
If not specified or if the specified value is 0, the CLKOUT pin
will be disabled.
nxp,no-comparator-bypass:
type: boolean
description: Allows to disable the CAN input comparator.
required:
- compatible
- reg
- interrupts
allOf:
- $ref: can-controller.yaml#
- if:
properties:
compatible:
contains:
enum:
- technologic,sja1000
- renesas,rzn1-sja1000
then:
required:
- reg-io-width
- if:
properties:
compatible:
contains:
const: renesas,rzn1-sja1000
then:
required:
- clocks
unevaluatedProperties: false
examples:
- |
can@1a000 {
compatible = "technologic,sja1000";
reg = <0x1a000 0x100>;
interrupts = <1>;
reg-io-width = <2>;
nxp,tx-output-config = <0x06>;
nxp,external-clock-frequency = <24000000>;
};
- |
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/clock/r9a06g032-sysctrl.h>
can@52104000 {
compatible = "renesas,r9a06g032-sja1000", "renesas,rzn1-sja1000";
reg = <0x52104000 0x800>;
reg-io-width = <4>;
interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&sysctrl R9A06G032_HCLK_CAN0>;
};
Memory mapped SJA1000 CAN controller from NXP (formerly Philips)
Required properties:
- compatible : should be one of "nxp,sja1000", "technologic,sja1000".
- reg : should specify the chip select, address offset and size required
to map the registers of the SJA1000. The size is usually 0x80.
- interrupts: property with a value describing the interrupt source
(number and sensitivity) required for the SJA1000.
Optional properties:
- reg-io-width : Specify the size (in bytes) of the IO accesses that
should be performed on the device. Valid value is 1, 2 or 4.
This property is ignored for technologic version.
Default to 1 (8 bits).
- nxp,external-clock-frequency : Frequency of the external oscillator
clock in Hz. Note that the internal clock frequency used by the
SJA1000 is half of that value. If not specified, a default value
of 16000000 (16 MHz) is used.
- nxp,tx-output-mode : operation mode of the TX output control logic:
<0x0> : bi-phase output mode
<0x1> : normal output mode (default)
<0x2> : test output mode
<0x3> : clock output mode
- nxp,tx-output-config : TX output pin configuration:
<0x01> : TX0 invert
<0x02> : TX0 pull-down (default)
<0x04> : TX0 pull-up
<0x06> : TX0 push-pull
<0x08> : TX1 invert
<0x10> : TX1 pull-down
<0x20> : TX1 pull-up
<0x30> : TX1 push-pull
- nxp,clock-out-frequency : clock frequency in Hz on the CLKOUT pin.
If not specified or if the specified value is 0, the CLKOUT pin
will be disabled.
- nxp,no-comparator-bypass : Allows to disable the CAN input comparator.
For further information, please have a look to the SJA1000 data sheet.
Examples:
can@3,100 {
compatible = "nxp,sja1000";
reg = <3 0x100 0x80>;
interrupts = <2 0>;
interrupt-parent = <&mpic>;
nxp,external-clock-frequency = <16000000>;
};
...@@ -183,8 +183,9 @@ static void chipset_init(struct net_device *dev) ...@@ -183,8 +183,9 @@ static void chipset_init(struct net_device *dev)
{ {
struct sja1000_priv *priv = netdev_priv(dev); struct sja1000_priv *priv = netdev_priv(dev);
/* set clock divider and output control register */ if (!(priv->flags & SJA1000_QUIRK_NO_CDR_REG))
priv->write_reg(priv, SJA1000_CDR, priv->cdr | CDR_PELICAN); /* set clock divider and output control register */
priv->write_reg(priv, SJA1000_CDR, priv->cdr | CDR_PELICAN);
/* set acceptance filter (accept all) */ /* set acceptance filter (accept all) */
priv->write_reg(priv, SJA1000_ACCC0, 0x00); priv->write_reg(priv, SJA1000_ACCC0, 0x00);
...@@ -209,7 +210,8 @@ static void sja1000_start(struct net_device *dev) ...@@ -209,7 +210,8 @@ static void sja1000_start(struct net_device *dev)
set_reset_mode(dev); set_reset_mode(dev);
/* Initialize chip if uninitialized at this stage */ /* Initialize chip if uninitialized at this stage */
if (!(priv->read_reg(priv, SJA1000_CDR) & CDR_PELICAN)) if (!(priv->flags & SJA1000_QUIRK_NO_CDR_REG ||
priv->read_reg(priv, SJA1000_CDR) & CDR_PELICAN))
chipset_init(dev); chipset_init(dev);
/* Clear error counters and error code capture */ /* Clear error counters and error code capture */
......
...@@ -145,7 +145,8 @@ ...@@ -145,7 +145,8 @@
/* /*
* Flags for sja1000priv.flags * Flags for sja1000priv.flags
*/ */
#define SJA1000_CUSTOM_IRQ_HANDLER 0x1 #define SJA1000_CUSTOM_IRQ_HANDLER BIT(0)
#define SJA1000_QUIRK_NO_CDR_REG BIT(1)
/* /*
* SJA1000 private data structure * SJA1000 private data structure
......
...@@ -31,7 +31,7 @@ MODULE_LICENSE("GPL v2"); ...@@ -31,7 +31,7 @@ MODULE_LICENSE("GPL v2");
struct sja1000_of_data { struct sja1000_of_data {
size_t priv_sz; size_t priv_sz;
int (*init)(struct sja1000_priv *priv, struct device_node *of); void (*init)(struct sja1000_priv *priv, struct device_node *of);
}; };
struct technologic_priv { struct technologic_priv {
...@@ -94,15 +94,13 @@ static void sp_technologic_write_reg16(const struct sja1000_priv *priv, ...@@ -94,15 +94,13 @@ static void sp_technologic_write_reg16(const struct sja1000_priv *priv,
spin_unlock_irqrestore(&tp->io_lock, flags); spin_unlock_irqrestore(&tp->io_lock, flags);
} }
static int sp_technologic_init(struct sja1000_priv *priv, struct device_node *of) static void sp_technologic_init(struct sja1000_priv *priv, struct device_node *of)
{ {
struct technologic_priv *tp = priv->priv; struct technologic_priv *tp = priv->priv;
priv->read_reg = sp_technologic_read_reg16; priv->read_reg = sp_technologic_read_reg16;
priv->write_reg = sp_technologic_write_reg16; priv->write_reg = sp_technologic_write_reg16;
spin_lock_init(&tp->io_lock); spin_lock_init(&tp->io_lock);
return 0;
} }
static void sp_populate(struct sja1000_priv *priv, static void sp_populate(struct sja1000_priv *priv,
...@@ -210,7 +208,6 @@ static int sp_probe(struct platform_device *pdev) ...@@ -210,7 +208,6 @@ static int sp_probe(struct platform_device *pdev)
struct resource *res_mem, *res_irq = NULL; struct resource *res_mem, *res_irq = NULL;
struct sja1000_platform_data *pdata; struct sja1000_platform_data *pdata;
struct device_node *of = pdev->dev.of_node; struct device_node *of = pdev->dev.of_node;
const struct of_device_id *of_id;
const struct sja1000_of_data *of_data = NULL; const struct sja1000_of_data *of_data = NULL;
size_t priv_sz = 0; size_t priv_sz = 0;
...@@ -243,11 +240,9 @@ static int sp_probe(struct platform_device *pdev) ...@@ -243,11 +240,9 @@ static int sp_probe(struct platform_device *pdev)
return -ENODEV; return -ENODEV;
} }
of_id = of_match_device(sp_of_table, &pdev->dev); of_data = device_get_match_data(&pdev->dev);
if (of_id && of_id->data) { if (of_data)
of_data = of_id->data;
priv_sz = of_data->priv_sz; priv_sz = of_data->priv_sz;
}
dev = alloc_sja1000dev(priv_sz); dev = alloc_sja1000dev(priv_sz);
if (!dev) if (!dev)
...@@ -269,11 +264,8 @@ static int sp_probe(struct platform_device *pdev) ...@@ -269,11 +264,8 @@ static int sp_probe(struct platform_device *pdev)
if (of) { if (of) {
sp_populate_of(priv, of); sp_populate_of(priv, of);
if (of_data && of_data->init) { if (of_data && of_data->init)
err = of_data->init(priv, of); of_data->init(priv, of);
if (err)
goto exit_free;
}
} else { } else {
sp_populate(priv, pdata, res_mem->flags); sp_populate(priv, pdata, res_mem->flags);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment