From e57a938d023cdf933731a77a350cfacadc37d3c4 Mon Sep 17 00:00:00 2001 From: Dominik Sliwa Date: Wed, 31 Jan 2018 17:43:22 +0100 Subject: can: mfd: apalis-tk1-k20:increased clock speed, zero copy Increased SPI speed for transfers and peripheral speed. Switch to cleaning IRQ flags on read, instead of separate write. Switched to zero-copy on SPI reads. Signed-off-by: Dominik Sliwa Acked-by: Marcel Ziswiler --- arch/arm/boot/dts/tegra124-apalis-v1.2-eval.dts | 6 +-- arch/arm/mach-tegra/board-apalis-tk1.c | 2 +- drivers/mfd/apalis-tk1-k20-ezp.h | 2 +- drivers/mfd/apalis-tk1-k20.c | 57 ++++--------------------- drivers/net/can/apalis-tk1-k20-can.c | 31 +------------- include/linux/mfd/apalis-tk1-k20.h | 4 +- 6 files changed, 18 insertions(+), 84 deletions(-) diff --git a/arch/arm/boot/dts/tegra124-apalis-v1.2-eval.dts b/arch/arm/boot/dts/tegra124-apalis-v1.2-eval.dts index 630f19f267d3..95f68ba532ed 100644 --- a/arch/arm/boot/dts/tegra124-apalis-v1.2-eval.dts +++ b/arch/arm/boot/dts/tegra124-apalis-v1.2-eval.dts @@ -136,14 +136,14 @@ /* SPI2: MCU SPI */ spi@7000d600 { status = "okay"; - spi-max-frequency = <12000000>; + spi-max-frequency = <102000000>; nvidia,polling-mode; nvidia,boost-reg-access; k20mcu: apalis-tk1-k20@1 { compatible = "toradex,apalis-tk1-k20"; reg = <1>; - spi-max-frequency = <6000000>; + spi-max-frequency = <10200000>; interrupt-parent =<&gpio>; interrupts = ; rst-gpio = <&gpio TEGRA_GPIO(BB, 6) GPIO_ACTIVE_HIGH>; @@ -174,7 +174,7 @@ spidev2: spidev@2 { compatible = "spidev"; reg = <2>; - spi-max-frequency = <2000000>; + spi-max-frequency = <3000000>; }; }; diff --git a/arch/arm/mach-tegra/board-apalis-tk1.c b/arch/arm/mach-tegra/board-apalis-tk1.c index 0677de795b35..e3cbfbc88d83 100644 --- a/arch/arm/mach-tegra/board-apalis-tk1.c +++ b/arch/arm/mach-tegra/board-apalis-tk1.c @@ -126,7 +126,7 @@ static __initdata struct tegra_clk_init_table apalis_tk1_clk_init_table[] = { { "i2c4", "pll_p", 3200000, false}, { "i2c5", "pll_p", 3200000, false}, { "sbc1", "pll_p", 25000000, false}, - { "sbc2", "clk_m", 24000000, false}, + { "sbc2", "pll_p", 104000000, false}, { "sbc3", "pll_p", 25000000, false}, { "sbc4", "pll_p", 25000000, false}, { "sbc5", "pll_p", 25000000, false}, diff --git a/drivers/mfd/apalis-tk1-k20-ezp.h b/drivers/mfd/apalis-tk1-k20-ezp.h index c8b0c518980a..92ab497dd5c7 100644 --- a/drivers/mfd/apalis-tk1-k20-ezp.h +++ b/drivers/mfd/apalis-tk1-k20-ezp.h @@ -37,7 +37,7 @@ #define APALIS_TK1_K20_EZP_STA_WEF BIT(6) #define APALIS_TK1_K20_EZP_STA_FS BIT(7) -#define APALIS_TK1_K20_EZP_MAX_SPEED 2000000 +#define APALIS_TK1_K20_EZP_MAX_SPEED 3000000 #define APALIS_TK1_K20_EZP_MAX_DATA 32 #define APALIS_TK1_K20_EZP_WRITE_SIZE 32 diff --git a/drivers/mfd/apalis-tk1-k20.c b/drivers/mfd/apalis-tk1-k20.c index 9befabd5d1df..84774538eb44 100644 --- a/drivers/mfd/apalis-tk1-k20.c +++ b/drivers/mfd/apalis-tk1-k20.c @@ -68,13 +68,12 @@ static int apalis_tk1_k20_spi_read(void *context, const void *reg, { unsigned char w[APALIS_TK1_K20_MAX_BULK] = {APALIS_TK1_K20_READ_INST, val_size, *((unsigned char *) reg)}; - unsigned char r[APALIS_TK1_K20_MAX_BULK]; unsigned char *p = val; struct device *dev = context; struct spi_device *spi = to_spi_device(dev); struct spi_transfer t = { .tx_buf = w, - .rx_buf = r, + .rx_buf = NULL, .len = 3, .cs_change = 0, .delay_usecs = 0, @@ -97,7 +96,8 @@ static int apalis_tk1_k20_spi_read(void *context, const void *reg, spi_message_add_tail(&t, &m); ret = spi_sync(spi, &m); /* no need to reinit the message*/ - t.len = 2; + t.len = 1; + t.rx_buf = p; /* just use the same transfer */ ret = spi_sync(spi, &m); @@ -108,56 +108,16 @@ static int apalis_tk1_k20_spi_read(void *context, const void *reg, spi_message_add_tail(&t, &m); ret = spi_sync(spi, &m); /* no need to reinit the message*/ - t.len = val_size + 1; + t.len = val_size; + t.rx_buf = p; /* just use the same transfer */ ret = spi_sync(spi, &m); -#endif - -#ifdef CONFIG_EXPERIMENTAL_K20_HSMODE - } else if ((val_size > 1) && (val_size < APALIS_TK1_K20_MAX_BULK)) { - spi_message_init(&m); - w[0] = APALIS_TK1_K20_BULK_READ_INST; - t.len = 3; - spi_message_add_tail(&t, &m); - ret = spi_sync(spi, &m); - - if (val_size == 2) { - ret = spi_sync(spi, &m); - } else { - transfer_count = val_size; - spi_message_init(&m); - ts[0].tx_buf = NULL; - ts[0].rx_buf = r; - ts[0].len = (transfer_count >= 4) ? 4 : transfer_count; - ts[0].cs_change = 0; - ts[0].delay_usecs = 2; - - spi_message_add_tail(&ts[i], &m); - /* - * decrease count but remember about an extra character - * at the transfer beginning - */ - transfer_count = transfer_count - ts[0].len + 1; - - for (i = 1; transfer_count > 0; i++) { - ts[i].tx_buf = NULL; - /* first entry in r is the status */ - ts[i].rx_buf = &r[(4 * i) - 1]; - ts[i].len = (transfer_count >= 4) ? - 4 : transfer_count; - ts[i].cs_change = 0; - ts[i].delay_usecs = 2; - spi_message_add_tail(&ts[i], &m); - transfer_count = transfer_count - ts[i].len; - } - ret = spi_sync(spi, &m); - } #endif } else { return -ENOTSUPP; } - +#if 0 if (r[0] == TK1_K20_SENTINEL) memcpy(p, &r[1], val_size); else { @@ -187,10 +147,11 @@ static int apalis_tk1_k20_spi_read(void *context, const void *reg, } return -EIO; } - +#endif return ret; } + static int apalis_tk1_k20_spi_write(void *context, const void *data, size_t count) { @@ -940,7 +901,7 @@ int apalis_tk1_k20_dev_init(struct device *dev) apalis_tk1_k20->irq_chip.name = dev_name(dev); apalis_tk1_k20->irq_chip.status_base = APALIS_TK1_K20_IRQREG; apalis_tk1_k20->irq_chip.mask_base = APALIS_TK1_K20_MSQREG; - apalis_tk1_k20->irq_chip.ack_base = APALIS_TK1_K20_IRQREG; + apalis_tk1_k20->irq_chip.ack_base = 0; apalis_tk1_k20->irq_chip.irq_reg_stride = 0; apalis_tk1_k20->irq_chip.num_regs = APALIS_TK1_K20_IRQ_REG_CNT; apalis_tk1_k20->irq_chip.irqs = apalis_tk1_k20->irqs; diff --git a/drivers/net/can/apalis-tk1-k20-can.c b/drivers/net/can/apalis-tk1-k20-can.c index 22437c48296f..5d0f5d764ceb 100644 --- a/drivers/net/can/apalis-tk1-k20-can.c +++ b/drivers/net/can/apalis-tk1-k20-can.c @@ -155,30 +155,11 @@ static void apalis_tk1_k20_can_hw_rx_frame(struct net_device *net, u8 *buf, apalis_tk1_k20_unlock(priv->apalis_tk1_k20); } -static u32 apalis_tk1_k20_can_available_rx_frames(struct net_device *net) -{ - u32 frame_cnt = 0; - struct apalis_tk1_k20_priv *priv = netdev_priv(net); - int ret; - - apalis_tk1_k20_lock(priv->apalis_tk1_k20); - - ret = apalis_tk1_k20_reg_read(priv->apalis_tk1_k20, - APALIS_TK1_K20_CAN_IN_BUF_CNT - + APALIS_TK1_K20_CAN_DEV_OFFSET( - priv->pdata->id), &frame_cnt); - apalis_tk1_k20_unlock(priv->apalis_tk1_k20); - - return (ret == 0) ? frame_cnt : 0; -} - static void apalis_tk1_k20_can_hw_rx(struct net_device *net, int buf_idx) { struct apalis_tk1_k20_priv *priv = netdev_priv(net); struct sk_buff *skb; struct can_frame *frame; - u8 available_frames = 0; - u8 buf[CAN_TRANSFER_BUF_LEN]; skb = alloc_can_skb(priv->net, &frame); if (!skb) { @@ -187,14 +168,7 @@ static void apalis_tk1_k20_can_hw_rx(struct net_device *net, int buf_idx) return; } - available_frames = apalis_tk1_k20_can_available_rx_frames(net); - - while ((available_frames > 0)) { - apalis_tk1_k20_can_hw_rx_frame(net, buf, buf_idx); - memcpy(&frame->can_id, buf + MB_EID_OFF, MB_EID_LEN); - /* Data length */ - frame->can_dlc = get_can_dlc(buf[MB_DLC_OFF]); - memcpy(frame->data, buf + CAN_HEADER_MAX_LEN, frame->can_dlc); + apalis_tk1_k20_can_hw_rx_frame(net, (unsigned char *)frame, buf_idx); priv->net->stats.rx_packets++; priv->net->stats.rx_bytes += frame->can_dlc; @@ -202,8 +176,7 @@ static void apalis_tk1_k20_can_hw_rx(struct net_device *net, int buf_idx) can_led_event(priv->net, CAN_LED_EVENT_RX); netif_rx_ni(skb); - available_frames--; - } + } static netdev_tx_t apalis_tk1_k20_can_hard_start_xmit(struct sk_buff *skb, diff --git a/include/linux/mfd/apalis-tk1-k20.h b/include/linux/mfd/apalis-tk1-k20.h index 1d0fdacac5b7..ca9025d63cb1 100644 --- a/include/linux/mfd/apalis-tk1-k20.h +++ b/include/linux/mfd/apalis-tk1-k20.h @@ -106,7 +106,7 @@ #define APALIS_TK1_K20_TSC_IRQ 4 #define APALIS_TK1_K20_GPIO_IRQ 5 -#define APALIS_TK1_K20_FW_VER 0x0B +#define APALIS_TK1_K20_FW_VER 0x0C #define FW_MINOR (APALIS_TK1_K20_FW_VER & 0x0F) #define FW_MAJOR ((APALIS_TK1_K20_FW_VER & 0xF0) >> 4) @@ -120,7 +120,7 @@ #define APALIS_TK1_CAN_CLK_UNIT 6250 -#define APALIS_TK1_K20_MAX_SPI_SPEED 6000000 +#define APALIS_TK1_K20_MAX_SPI_SPEED 12000000 struct apalis_tk1_k20_regmap { struct regmap *regmap; -- cgit v1.2.3