Received: by 2002:a05:7412:bb8d:b0:d7:7d3a:4fe2 with SMTP id js13csp501108rdb; Tue, 15 Aug 2023 03:35:54 -0700 (PDT) X-Google-Smtp-Source: AGHT+IESLQxK+aCyxLnWrqnKpM49J7BfI0+Qz71DRQaKn45muQ0SJFUmoD1B8aa4xDIrwuzmsoSC X-Received: by 2002:a17:907:801f:b0:992:b3a3:81f9 with SMTP id ft31-20020a170907801f00b00992b3a381f9mr8292758ejc.71.1692095753957; Tue, 15 Aug 2023 03:35:53 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1692095753; cv=none; d=google.com; s=arc-20160816; b=j0ew9abn8Y8E4BOgCITQk1tDDd1QV+Fh1YaBg2jMTA4aCoEX6uGdTULIwbcSFs/8Bi tKaAEYTPTFWRLd/wU2OB0ofoPDANeZO7qrlfq5lmvGOtCJbP3/fpBs0vhzmOSx1lyGOc c8aS51y3a8royRwK3400rj8HO6rOjQ3/wN0TUPZehcJAZKq4ztG8EX87fo0IdKvpJ/LG 0VBafzMa91/FTARjJAqZ4qfE0iqUTxApYbvqXGGlSiZbcQpjJkpMAMkYZsQyCrhFp7ii ygAykAweBsN2vGwlIKu7jvcWBrWE+Y4QojRkikGBxkMDeVtwlOX3JEXiqSZY/QnICICx q0Ag== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:in-reply-to:from :references:cc:to:content-language:subject:user-agent:mime-version :date:message-id:dkim-signature; bh=ON+/twk2K9H2eM6UytkkEwr9FAFAo3ZZ7Kpv1yEgp8w=; fh=5wEcC6R/3r2ZJpcBIRPsjyxBXwaTZBeCTMhjhA0eoeE=; b=r4ugOXNmpTJ9NlxDF6rB22D67hzwXVFP1RZld3KVUQNJvGn/iBCoK4bukghquin9qA 9aKvNmVZe4CKFua5xtND994gqyrKUWZWbS2qTyfMect0FKNbSAZR3WQgFduxRLpReS2Z LCgx1qbfDlMc4U43sJlBDP9F+mrEktvY2U5+rkvjtC/Rbh4zoYZt+DizgQ8QuI03ZZkg zH7q+hj9rjx6sUbZdsebtC/B3JmldUfnXxAGdyC92GgnMmBZdQwXmxcGIkLsX5jhpj0K JwimewEhqrQhAWbuMdvXwDXAMqyXjnBfGW5mufCLPJ0jpk7A+IU6coGhOu6Fz7/vUPmf 8Eug== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=kpaw+EHE; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id g5-20020a170906394500b0099bc5e44abcsi9376630eje.676.2023.08.15.03.35.20; Tue, 15 Aug 2023 03:35:53 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=kpaw+EHE; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236371AbjHOKPT (ORCPT + 99 others); Tue, 15 Aug 2023 06:15:19 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39690 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235048AbjHOKOv (ORCPT ); Tue, 15 Aug 2023 06:14:51 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 23750E7C; Tue, 15 Aug 2023 03:14:49 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 931BC65469; Tue, 15 Aug 2023 10:14:48 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 5031AC433C7; Tue, 15 Aug 2023 10:14:43 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1692094487; bh=fFuLt2KZ7JLXQTOznYRH3Fe4CCINQT1f2ml875TiBy8=; h=Date:Subject:To:Cc:References:From:In-Reply-To:From; b=kpaw+EHEme5rDzK1dgv91QpoGVWz4NbrF/h/rt1qFvpGbkctddNQqHBcXEUeC3IGU w6OxpuJIYJ73b/tkACtnwaHpLbJAZ1n2aEWzL26US4lZuNNi9RxBVzW2HI2zwaLx1m dRtV3ws2nopFlnpyP3u2+uqcwQLZShmxWmtBy5FNUBo79schNTjakAJnHQlB2ci4MC 4mzzewBnJsTHtRTjEuwFo4TabRWvMaI0mNlR2+eO+eB74E/OJW21bDrOhoaMw56IxP lGu4IYgTeFex/kLltR4/K3X4gigEqvUIAR6oR6Tl8zcdo3dwmtHa45oXnKcHO/kjVF TpmBJKjcmz+PQ== Message-ID: Date: Tue, 15 Aug 2023 13:14:40 +0300 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.14.0 Subject: Re: [PATCH v4 3/5] net: ti: icss-iep: Add IEP driver Content-Language: en-US To: "Anwar, Md Danish" , MD Danish Anwar , Randy Dunlap , Simon Horman , Vignesh Raghavendra , Andrew Lunn , Richard Cochran , Conor Dooley , Krzysztof Kozlowski , Rob Herring , Paolo Abeni , Jakub Kicinski , Eric Dumazet , "David S. Miller" Cc: nm@ti.com, srk@ti.com, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, netdev@vger.kernel.org, linux-omap@vger.kernel.org, linux-arm-kernel@lists.infradead.org References: <20230814100847.3531480-1-danishanwar@ti.com> <20230814100847.3531480-4-danishanwar@ti.com> From: Roger Quadros In-Reply-To: Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-3.2 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,NICE_REPLY_A, RCVD_IN_DNSWL_BLOCKED,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On 15/08/2023 13:07, Anwar, Md Danish wrote: > Hi Roger, > > On 8/15/2023 3:11 PM, Roger Quadros wrote: >> Hi Danish, >> >> On 14/08/2023 13:08, MD Danish Anwar wrote: >>> From: Roger Quadros >>> >>> Add a driver for Industrial Ethernet Peripheral (IEP) block of PRUSS to >>> support timestamping of ethernet packets and thus support PTP and PPS >>> for PRU ethernet ports. >>> >>> Signed-off-by: Roger Quadros >>> Signed-off-by: Lokesh Vutla >>> Signed-off-by: Murali Karicheri >>> Signed-off-by: Vignesh Raghavendra >>> Signed-off-by: MD Danish Anwar >>> --- >>>   drivers/net/ethernet/ti/Kconfig          |  11 + >>>   drivers/net/ethernet/ti/Makefile         |   1 + >>>   drivers/net/ethernet/ti/icssg/icss_iep.c | 921 +++++++++++++++++++++++ >>>   drivers/net/ethernet/ti/icssg/icss_iep.h |  38 + >>>   4 files changed, 971 insertions(+) >>>   create mode 100644 drivers/net/ethernet/ti/icssg/icss_iep.c >>>   create mode 100644 drivers/net/ethernet/ti/icssg/icss_iep.h >>> >>> diff --git a/drivers/net/ethernet/ti/Kconfig b/drivers/net/ethernet/ti/Kconfig >>> index 63e510b6860f..1af5a90720ec 100644 >>> --- a/drivers/net/ethernet/ti/Kconfig >>> +++ b/drivers/net/ethernet/ti/Kconfig >>> @@ -196,4 +196,15 @@ config TI_ICSSG_PRUETH >>>         to support the Ethernet operation. Currently, it supports Ethernet >>>         with 1G and 100M link speed. >>>   +config TI_ICSS_IEP >>> +    tristate "TI PRU ICSS IEP driver" >>> +    depends on TI_PRUSS >>> +    default TI_PRUSS >>> +    help >>> +      This driver enables support for the PRU-ICSS Industrial Ethernet >>> +      Peripheral within a PRU-ICSS subsystem present on various TI SoCs. >>> + >>> +      To compile this driver as a module, choose M here. The module >>> +      will be called icss_iep. >>> + >>>   endif # NET_VENDOR_TI >>> diff --git a/drivers/net/ethernet/ti/Makefile b/drivers/net/ethernet/ti/Makefile >>> index 9176d79c36e1..34fd7a716ba6 100644 >>> --- a/drivers/net/ethernet/ti/Makefile >>> +++ b/drivers/net/ethernet/ti/Makefile >>> @@ -38,3 +38,4 @@ icssg-prueth-y := k3-cppi-desc-pool.o \ >>>             icssg/icssg_mii_cfg.o \ >>>             icssg/icssg_stats.o \ >>>             icssg/icssg_ethtool.o >>> +obj-$(CONFIG_TI_ICSS_IEP) += icssg/icss_iep.o >>> diff --git a/drivers/net/ethernet/ti/icssg/icss_iep.c b/drivers/net/ethernet/ti/icssg/icss_iep.c >>> new file mode 100644 >>> index 000000000000..d123b8ba3f31 >>> --- /dev/null >>> +++ b/drivers/net/ethernet/ti/icssg/icss_iep.c >>> @@ -0,0 +1,921 @@ >>> +// SPDX-License-Identifier: GPL-2.0 >>> + >>> +/* Texas Instruments ICSSG Industrial Ethernet Peripheral (IEP) Driver >>> + * >>> + * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com >>> + * >>> + */ >>> + >>> +#include >>> +#include >>> +#include >>> +#include >>> +#include >>> +#include >>> +#include >>> +#include >>> +#include >>> +#include >>> +#include >>> + >>> +#include "icss_iep.h" >>> + >>> +#define IEP_MAX_DEF_INC        0xf >>> +#define IEP_MAX_COMPEN_INC        0xfff >>> +#define IEP_MAX_COMPEN_COUNT    0xffffff >>> + >>> +#define IEP_GLOBAL_CFG_CNT_ENABLE    BIT(0) >>> +#define IEP_GLOBAL_CFG_DEFAULT_INC_MASK        GENMASK(7, 4) >>> +#define IEP_GLOBAL_CFG_DEFAULT_INC_SHIFT    4 >>> +#define IEP_GLOBAL_CFG_COMPEN_INC_MASK        GENMASK(19, 8) >>> +#define IEP_GLOBAL_CFG_COMPEN_INC_SHIFT        8 >>> + >>> +#define IEP_GLOBAL_STATUS_CNT_OVF    BIT(0) >>> + >>> +#define IEP_CMP_CFG_SHADOW_EN        BIT(17) >>> +#define IEP_CMP_CFG_CMP0_RST_CNT_EN    BIT(0) >>> +#define IEP_CMP_CFG_CMP_EN(cmp)        (GENMASK(16, 1) & (1 << ((cmp) + 1))) >>> + >>> +#define IEP_CMP_STATUS(cmp)        (1 << (cmp)) >>> + >>> +#define IEP_SYNC_CTRL_SYNC_EN        BIT(0) >>> +#define IEP_SYNC_CTRL_SYNC_N_EN(n)    (GENMASK(2, 1) & (BIT(1) << (n))) >>> + >>> +#define IEP_MIN_CMP    0 >>> +#define IEP_MAX_CMP    15 >>> + >>> +#define ICSS_IEP_64BIT_COUNTER_SUPPORT        BIT(0) >>> +#define ICSS_IEP_SLOW_COMPEN_REG_SUPPORT    BIT(1) >>> +#define ICSS_IEP_SHADOW_MODE_SUPPORT        BIT(2) >>> + >>> +#define LATCH_INDEX(ts_index)            ((ts_index) + 6) >>> +#define IEP_CAP_CFG_CAPNR_1ST_EVENT_EN(n)    BIT(LATCH_INDEX(n)) >>> +#define IEP_CAP_CFG_CAP_ASYNC_EN(n)        BIT(LATCH_INDEX(n) + 10) >>> + >>> +enum { >>> +    ICSS_IEP_GLOBAL_CFG_REG, >>> +    ICSS_IEP_GLOBAL_STATUS_REG, >>> +    ICSS_IEP_COMPEN_REG, >>> +    ICSS_IEP_SLOW_COMPEN_REG, >>> +    ICSS_IEP_COUNT_REG0, >>> +    ICSS_IEP_COUNT_REG1, >>> +    ICSS_IEP_CAPTURE_CFG_REG, >>> +    ICSS_IEP_CAPTURE_STAT_REG, >>> + >>> +    ICSS_IEP_CAP6_RISE_REG0, >>> +    ICSS_IEP_CAP6_RISE_REG1, >>> + >>> +    ICSS_IEP_CAP7_RISE_REG0, >>> +    ICSS_IEP_CAP7_RISE_REG1, >>> + >>> +    ICSS_IEP_CMP_CFG_REG, >>> +    ICSS_IEP_CMP_STAT_REG, >>> +    ICSS_IEP_CMP0_REG0, >>> +    ICSS_IEP_CMP0_REG1, >>> +    ICSS_IEP_CMP1_REG0, >>> +    ICSS_IEP_CMP1_REG1, >>> + >>> +    ICSS_IEP_CMP8_REG0, >>> +    ICSS_IEP_CMP8_REG1, >>> +    ICSS_IEP_SYNC_CTRL_REG, >>> +    ICSS_IEP_SYNC0_STAT_REG, >>> +    ICSS_IEP_SYNC1_STAT_REG, >>> +    ICSS_IEP_SYNC_PWIDTH_REG, >>> +    ICSS_IEP_SYNC0_PERIOD_REG, >>> +    ICSS_IEP_SYNC1_DELAY_REG, >>> +    ICSS_IEP_SYNC_START_REG, >>> +    ICSS_IEP_MAX_REGS, >>> +}; >>> + >>> +/** >>> + * struct icss_iep_plat_data - Plat data to handle SoC variants >>> + * @config: Regmap configuration data >>> + * @reg_offs: register offsets to capture offset differences across SoCs >>> + * @flags: Flags to represent IEP properties >>> + */ >>> +struct icss_iep_plat_data { >>> +    struct regmap_config *config; >>> +    u32 reg_offs[ICSS_IEP_MAX_REGS]; >>> +    u32 flags; >>> +}; >>> + >>> +struct icss_iep { >>> +    struct device *dev; >>> +    void __iomem *base; >>> +    const struct icss_iep_plat_data *plat_data; >>> +    struct regmap *map; >>> +    struct device_node *client_np; >>> +    unsigned long refclk_freq; >>> +    int clk_tick_time;    /* one refclk tick time in ns */ >>> +    struct ptp_clock_info ptp_info; >>> +    struct ptp_clock *ptp_clock; >>> +    struct mutex ptp_clk_mutex;    /* PHC access serializer */ >>> +    spinlock_t irq_lock; /* CMP IRQ vs icss_iep_ptp_enable access */ >>> +    u32 def_inc; >>> +    s16 slow_cmp_inc; >>> +    u32 slow_cmp_count; >>> +    const struct icss_iep_clockops *ops; >>> +    void *clockops_data; >>> +    u32 cycle_time_ns; >>> +    u32 perout_enabled; >>> +    bool pps_enabled; >>> +    int cap_cmp_irq; >>> +    u64 period; >>> +    u32 latch_enable; >>> +}; >>> + >> >> Where is the comment you agreed to add on why we are using readl/writel >> instead of regmap in certain areas? >> > > We agreed to add comment on why we are using readl/writel instead of regmap in the documentation of the readl / writel helper APIs (icss_iep_readl / writel ). But Andrew asked me to drop those helper APIs, so I dropped them. Now no helper APIs are there and we are directly using readl / writel in total 8 places. Previously with the helper APIs, there was a way to document the use of readl / writel before the declaration of heper APIs. Now with no helper APIs, I couldn't find a good place to add this documentation as all 8 instances using readl / writel seems similar. So I dropped it. Please limit your reply to around 80 columns wide. https://people.kernel.org/tglx/notes-about-netiquette You don't have to put the comment everywhere you use readl/writel but you need to put it at least once hopefully just before icss_iep_gettime() so future readers of this code know the reasoning why we are not using regmap API throughout. > >>> +/** >>> + * icss_iep_get_count_hi() - Get the upper 32 bit IEP counter >>> + * @iep: Pointer to structure representing IEP. >>> + * >>> + * Return: upper 32 bit IEP counter >>> + */ >>> +int icss_iep_get_count_hi(struct icss_iep *iep) >>> +{ >>> +    u32 val = 0; >>> + >>> +    if (iep && (iep->plat_data->flags & ICSS_IEP_64BIT_COUNTER_SUPPORT)) >>> +        val = readl(iep->base + iep->plat_data->reg_offs[ICSS_IEP_COUNT_REG1]); >>> + >>> +    return val; >>> +} >>> +EXPORT_SYMBOL_GPL(icss_iep_get_count_hi); >>> + >>> +/** >>> + * icss_iep_get_count_low() - Get the lower 32 bit IEP counter >>> + * @iep: Pointer to structure representing IEP. >>> + * >>> + * Return: lower 32 bit IEP counter >>> + */ >>> +int icss_iep_get_count_low(struct icss_iep *iep) >>> +{ >>> +    u32 val = 0; >>> + >>> +    if (iep) >>> +        val = readl(iep->base + iep->plat_data->reg_offs[ICSS_IEP_COUNT_REG0]); >>> + >>> +    return val; >>> +} >>> +EXPORT_SYMBOL_GPL(icss_iep_get_count_low); >>> + >>> +/** >>> + * icss_iep_get_ptp_clock_idx() - Get PTP clock index using IEP driver >>> + * @iep: Pointer to structure representing IEP. >>> + * >>> + * Return: PTP clock index, -1 if not registered >>> + */ >>> +int icss_iep_get_ptp_clock_idx(struct icss_iep *iep) >>> +{ >>> +    if (!iep || !iep->ptp_clock) >>> +        return -1; >>> +    return ptp_clock_index(iep->ptp_clock); >>> +} >>> +EXPORT_SYMBOL_GPL(icss_iep_get_ptp_clock_idx); >>> + >>> +static void icss_iep_set_counter(struct icss_iep *iep, u64 ns) >>> +{ >>> +    if (iep->plat_data->flags & ICSS_IEP_64BIT_COUNTER_SUPPORT) >>> +        writel(upper_32_bits(ns), iep->base + >>> +               iep->plat_data->reg_offs[ICSS_IEP_COUNT_REG1]); >>> +    writel(upper_32_bits(ns), iep->base + iep->plat_data->reg_offs[ICSS_IEP_COUNT_REG0]); >>> +} >>> + >>> +static void icss_iep_update_to_next_boundary(struct icss_iep *iep, u64 start_ns); >>> + >>> +static void icss_iep_settime(struct icss_iep *iep, u64 ns) >>> +{ >>> +    unsigned long flags; >>> + >>> +    if (iep->ops && iep->ops->settime) { >>> +        iep->ops->settime(iep->clockops_data, ns); >>> +        return; >>> +    } >>> + >>> +    spin_lock_irqsave(&iep->irq_lock, flags); >>> +    if (iep->pps_enabled || iep->perout_enabled) >>> +        writel(0, iep->base + iep->plat_data->reg_offs[ICSS_IEP_SYNC_CTRL_REG]); >>> + >>> +    icss_iep_set_counter(iep, ns); >>> + >>> +    if (iep->pps_enabled || iep->perout_enabled) { >>> +        icss_iep_update_to_next_boundary(iep, ns); >>> +        writel(IEP_SYNC_CTRL_SYNC_N_EN(0) | IEP_SYNC_CTRL_SYNC_EN, >>> +               iep->base + iep->plat_data->reg_offs[ICSS_IEP_SYNC_CTRL_REG]); >>> +    } >>> +    spin_unlock_irqrestore(&iep->irq_lock, flags); >>> +} >>> + >>> +static u64 icss_iep_gettime(struct icss_iep *iep, >>> +                struct ptp_system_timestamp *sts) >>> +{ >>> +    u32 ts_hi = 0, ts_lo; >>> +    unsigned long flags; >>> + >>> +    if (iep->ops && iep->ops->gettime) >>> +        return iep->ops->gettime(iep->clockops_data, sts); >>> + >>> +    /* use local_irq_x() to make it work for both RT/non-RT */ >>> +    local_irq_save(flags); >>> + >>> +    /* no need to play with hi-lo, hi is latched when lo is read */ >>> +    ptp_read_system_prets(sts); >>> +    ts_lo = readl(iep->base + iep->plat_data->reg_offs[ICSS_IEP_COUNT_REG0]); >>> +    ptp_read_system_postts(sts); >>> +    if (iep->plat_data->flags & ICSS_IEP_64BIT_COUNTER_SUPPORT) >>> +        ts_hi = readl(iep->base + iep->plat_data->reg_offs[ICSS_IEP_COUNT_REG1]); >>> + >>> +    local_irq_restore(flags); >>> + >>> +    return (u64)ts_lo | (u64)ts_hi << 32; >>> +} >>> + >>> +static void icss_iep_enable(struct icss_iep *iep) >>> +{ >>> +    regmap_update_bits(iep->map, ICSS_IEP_GLOBAL_CFG_REG, >>> +               IEP_GLOBAL_CFG_CNT_ENABLE, >>> +               IEP_GLOBAL_CFG_CNT_ENABLE); >>> +} >>> + >> >> > -- cheers, -roger