diff options
author | David S. Miller <davem@davemloft.net> | 2016-03-10 12:41:33 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-03-10 12:41:33 -0500 |
commit | 798fee48035f0c5fc6787767ff9e27de7e1a4fbb (patch) | |
tree | 0d9181a5d0ff6a6bf879dfb869e231b44b046303 | |
parent | cdc4e47da8f4c32eeb6b2061a8a834f4362a12b7 (diff) | |
parent | e481ab23c57b37c989fa27e0a6b3e941a908775a (diff) |
Merge tag 'linux-can-next-for-4.6-20160310' of git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can-next
Marc Kleine-Budde says:
====================
pull-request: can-next 2016-03-10
this is a pull request of 5 patch for net-next/master.
Marek Vasut contributes 4 patches for the ifi CAN driver, which makes
it work on real hardware. There is one patch by Ramesh Shanmugasundaram
for the rcar_can driver that adds support for the 3rd generation IP
core.
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | Documentation/devicetree/bindings/net/can/rcar_can.txt | 11 | ||||
-rw-r--r-- | drivers/net/can/Kconfig | 2 | ||||
-rw-r--r-- | drivers/net/can/ifi_canfd/ifi_canfd.c | 97 | ||||
-rw-r--r-- | drivers/net/can/rcar_can.c | 1 |
4 files changed, 75 insertions, 36 deletions
diff --git a/Documentation/devicetree/bindings/net/can/rcar_can.txt b/Documentation/devicetree/bindings/net/can/rcar_can.txt index 65edc055722f..8d40ab27bc8c 100644 --- a/Documentation/devicetree/bindings/net/can/rcar_can.txt +++ b/Documentation/devicetree/bindings/net/can/rcar_can.txt @@ -9,8 +9,10 @@ Required properties: "renesas,can-r8a7792" if CAN controller is a part of R8A7792 SoC. "renesas,can-r8a7793" if CAN controller is a part of R8A7793 SoC. "renesas,can-r8a7794" if CAN controller is a part of R8A7794 SoC. + "renesas,can-r8a7795" if CAN controller is a part of R8A7795 SoC. "renesas,rcar-gen1-can" for a generic R-Car Gen1 compatible device. "renesas,rcar-gen2-can" for a generic R-Car Gen2 compatible device. + "renesas,rcar-gen3-can" for a generic R-Car Gen3 compatible device. When compatible with the generic version, nodes must list the SoC-specific version corresponding to the platform first followed by the generic version. @@ -22,6 +24,15 @@ Required properties: - pinctrl-0: pin control group to be used for this controller. - pinctrl-names: must be "default". +Required properties for "renesas,can-r8a7795" compatible: +In R8A7795 SoC, "clkp2" can be CANFD clock. This is a div6 clock and can be +used by both CAN and CAN FD controller at the same time. It needs to be scaled +to maximum frequency if any of these controllers use it. This is done using +the below properties. + +- assigned-clocks: phandle of clkp2(CANFD) clock. +- assigned-clock-rates: maximum frequency of this clock. + Optional properties: - renesas,can-clock-select: R-Car CAN Clock Source Select. Valid values are: <0x0> (default) : Peripheral clock (clkp1) diff --git a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig index 164ccdeca663..0d40aef928e2 100644 --- a/drivers/net/can/Kconfig +++ b/drivers/net/can/Kconfig @@ -106,7 +106,7 @@ config CAN_JANZ_ICAN3 config CAN_RCAR tristate "Renesas R-Car CAN controller" - depends on ARM + depends on ARCH_RENESAS || ARM ---help--- Say Y here if you want to use CAN controller found on Renesas R-Car SoCs. diff --git a/drivers/net/can/ifi_canfd/ifi_canfd.c b/drivers/net/can/ifi_canfd/ifi_canfd.c index 0d1c164374b7..a1bd54ffd31e 100644 --- a/drivers/net/can/ifi_canfd/ifi_canfd.c +++ b/drivers/net/can/ifi_canfd/ifi_canfd.c @@ -135,8 +135,12 @@ #define IFI_CANFD_RXFIFO_ID 0x6c #define IFI_CANFD_RXFIFO_ID_ID_OFFSET 0 -#define IFI_CANFD_RXFIFO_ID_ID_STD_MASK 0x3ff -#define IFI_CANFD_RXFIFO_ID_ID_XTD_MASK 0x1fffffff +#define IFI_CANFD_RXFIFO_ID_ID_STD_MASK CAN_SFF_MASK +#define IFI_CANFD_RXFIFO_ID_ID_STD_OFFSET 0 +#define IFI_CANFD_RXFIFO_ID_ID_STD_WIDTH 10 +#define IFI_CANFD_RXFIFO_ID_ID_XTD_MASK CAN_EFF_MASK +#define IFI_CANFD_RXFIFO_ID_ID_XTD_OFFSET 11 +#define IFI_CANFD_RXFIFO_ID_ID_XTD_WIDTH 18 #define IFI_CANFD_RXFIFO_ID_IDE BIT(29) #define IFI_CANFD_RXFIFO_DATA 0x70 /* 0x70..0xac */ @@ -156,8 +160,12 @@ #define IFI_CANFD_TXFIFO_ID 0xbc #define IFI_CANFD_TXFIFO_ID_ID_OFFSET 0 -#define IFI_CANFD_TXFIFO_ID_ID_STD_MASK 0x3ff -#define IFI_CANFD_TXFIFO_ID_ID_XTD_MASK 0x1fffffff +#define IFI_CANFD_TXFIFO_ID_ID_STD_MASK CAN_SFF_MASK +#define IFI_CANFD_TXFIFO_ID_ID_STD_OFFSET 0 +#define IFI_CANFD_TXFIFO_ID_ID_STD_WIDTH 10 +#define IFI_CANFD_TXFIFO_ID_ID_XTD_MASK CAN_EFF_MASK +#define IFI_CANFD_TXFIFO_ID_ID_XTD_OFFSET 11 +#define IFI_CANFD_TXFIFO_ID_ID_XTD_WIDTH 18 #define IFI_CANFD_TXFIFO_ID_IDE BIT(29) #define IFI_CANFD_TXFIFO_DATA 0xc0 /* 0xb0..0xfc */ @@ -229,10 +237,20 @@ static void ifi_canfd_read_fifo(struct net_device *ndev) rxid = readl(priv->base + IFI_CANFD_RXFIFO_ID); id = (rxid >> IFI_CANFD_RXFIFO_ID_ID_OFFSET); - if (id & IFI_CANFD_RXFIFO_ID_IDE) + if (id & IFI_CANFD_RXFIFO_ID_IDE) { id &= IFI_CANFD_RXFIFO_ID_ID_XTD_MASK; - else + /* + * In case the Extended ID frame is received, the standard + * and extended part of the ID are swapped in the register, + * so swap them back to obtain the correct ID. + */ + id = (id >> IFI_CANFD_RXFIFO_ID_ID_XTD_OFFSET) | + ((id & IFI_CANFD_RXFIFO_ID_ID_STD_MASK) << + IFI_CANFD_RXFIFO_ID_ID_XTD_WIDTH); + id |= CAN_EFF_FLAG; + } else { id &= IFI_CANFD_RXFIFO_ID_ID_STD_MASK; + } cf->can_id = id; if (rxdlc & IFI_CANFD_RXFIFO_DLC_ESI) { @@ -514,25 +532,25 @@ static irqreturn_t ifi_canfd_isr(int irq, void *dev_id) static const struct can_bittiming_const ifi_canfd_bittiming_const = { .name = KBUILD_MODNAME, - .tseg1_min = 2, /* Time segment 1 = prop_seg + phase_seg1 */ + .tseg1_min = 1, /* Time segment 1 = prop_seg + phase_seg1 */ .tseg1_max = 64, - .tseg2_min = 1, /* Time segment 2 = phase_seg2 */ - .tseg2_max = 16, + .tseg2_min = 2, /* Time segment 2 = phase_seg2 */ + .tseg2_max = 64, .sjw_max = 16, - .brp_min = 1, - .brp_max = 1024, + .brp_min = 2, + .brp_max = 256, .brp_inc = 1, }; static const struct can_bittiming_const ifi_canfd_data_bittiming_const = { .name = KBUILD_MODNAME, - .tseg1_min = 2, /* Time segment 1 = prop_seg + phase_seg1 */ - .tseg1_max = 16, - .tseg2_min = 1, /* Time segment 2 = phase_seg2 */ - .tseg2_max = 8, - .sjw_max = 4, - .brp_min = 1, - .brp_max = 32, + .tseg1_min = 1, /* Time segment 1 = prop_seg + phase_seg1 */ + .tseg1_max = 64, + .tseg2_min = 2, /* Time segment 2 = phase_seg2 */ + .tseg2_max = 64, + .sjw_max = 16, + .brp_min = 2, + .brp_max = 256, .brp_inc = 1, }; @@ -545,32 +563,34 @@ static void ifi_canfd_set_bittiming(struct net_device *ndev) u32 noniso_arg = 0; u32 time_off; - if (priv->can.ctrlmode & CAN_CTRLMODE_FD_NON_ISO) { + if ((priv->can.ctrlmode & CAN_CTRLMODE_FD) && + !(priv->can.ctrlmode & CAN_CTRLMODE_FD_NON_ISO)) { + time_off = IFI_CANFD_TIME_SJW_OFF_ISO; + } else { noniso_arg = IFI_CANFD_TIME_SET_TIMEB_BOSCH | IFI_CANFD_TIME_SET_TIMEA_BOSCH | IFI_CANFD_TIME_SET_PRESC_BOSCH | IFI_CANFD_TIME_SET_SJW_BOSCH; time_off = IFI_CANFD_TIME_SJW_OFF_BOSCH; - } else { - time_off = IFI_CANFD_TIME_SJW_OFF_ISO; } /* Configure bit timing */ - brp = bt->brp - 1; + brp = bt->brp - 2; sjw = bt->sjw - 1; tseg1 = bt->prop_seg + bt->phase_seg1 - 1; - tseg2 = bt->phase_seg2 - 1; + tseg2 = bt->phase_seg2 - 2; writel((tseg2 << IFI_CANFD_TIME_TIMEB_OFF) | (tseg1 << IFI_CANFD_TIME_TIMEA_OFF) | (brp << IFI_CANFD_TIME_PRESCALE_OFF) | - (sjw << time_off), + (sjw << time_off) | + noniso_arg, priv->base + IFI_CANFD_TIME); /* Configure data bit timing */ - brp = dbt->brp - 1; + brp = dbt->brp - 2; sjw = dbt->sjw - 1; tseg1 = dbt->prop_seg + dbt->phase_seg1 - 1; - tseg2 = dbt->phase_seg2 - 1; + tseg2 = dbt->phase_seg2 - 2; writel((tseg2 << IFI_CANFD_TIME_TIMEB_OFF) | (tseg1 << IFI_CANFD_TIME_TIMEA_OFF) | (brp << IFI_CANFD_TIME_PRESCALE_OFF) | @@ -747,8 +767,7 @@ static netdev_tx_t ifi_canfd_start_xmit(struct sk_buff *skb, { struct ifi_canfd_priv *priv = netdev_priv(ndev); struct canfd_frame *cf = (struct canfd_frame *)skb->data; - u32 txst, txid; - u32 txdlc = 0; + u32 txst, txid, txdlc; int i; if (can_dropped_invalid_skb(ndev, skb)) @@ -766,17 +785,25 @@ static netdev_tx_t ifi_canfd_start_xmit(struct sk_buff *skb, if (cf->can_id & CAN_EFF_FLAG) { txid = cf->can_id & CAN_EFF_MASK; + /* + * In case the Extended ID frame is transmitted, the + * standard and extended part of the ID are swapped + * in the register, so swap them back to send the + * correct ID. + */ + txid = (txid >> IFI_CANFD_TXFIFO_ID_ID_XTD_WIDTH) | + ((txid & IFI_CANFD_TXFIFO_ID_ID_XTD_MASK) << + IFI_CANFD_TXFIFO_ID_ID_XTD_OFFSET); txid |= IFI_CANFD_TXFIFO_ID_IDE; } else { txid = cf->can_id & CAN_SFF_MASK; } - if (priv->can.ctrlmode & (CAN_CTRLMODE_FD | CAN_CTRLMODE_FD_NON_ISO)) { - if (can_is_canfd_skb(skb)) { - txdlc |= IFI_CANFD_TXFIFO_DLC_EDL; - if (cf->flags & CANFD_BRS) - txdlc |= IFI_CANFD_TXFIFO_DLC_BRS; - } + txdlc = can_len2dlc(cf->len); + if ((priv->can.ctrlmode & CAN_CTRLMODE_FD) && can_is_canfd_skb(skb)) { + txdlc |= IFI_CANFD_TXFIFO_DLC_EDL; + if (cf->flags & CANFD_BRS) + txdlc |= IFI_CANFD_TXFIFO_DLC_BRS; } if (cf->can_id & CAN_RTR_FLAG) @@ -847,7 +874,7 @@ static int ifi_canfd_plat_probe(struct platform_device *pdev) priv->can.state = CAN_STATE_STOPPED; - priv->can.clock.freq = readl(addr + IFI_CANFD_SYSCLOCK); + priv->can.clock.freq = readl(addr + IFI_CANFD_CANCLOCK); priv->can.bittiming_const = &ifi_canfd_bittiming_const; priv->can.data_bittiming_const = &ifi_canfd_data_bittiming_const; diff --git a/drivers/net/can/rcar_can.c b/drivers/net/can/rcar_can.c index ad3d2e0cb191..788459f6bf5c 100644 --- a/drivers/net/can/rcar_can.c +++ b/drivers/net/can/rcar_can.c @@ -906,6 +906,7 @@ static const struct of_device_id rcar_can_of_table[] __maybe_unused = { { .compatible = "renesas,can-r8a7791" }, { .compatible = "renesas,rcar-gen1-can" }, { .compatible = "renesas,rcar-gen2-can" }, + { .compatible = "renesas,rcar-gen3-can" }, { } }; MODULE_DEVICE_TABLE(of, rcar_can_of_table); |