* Re: [PATCH v2] watchdog: imx2_wdg: Alow ping on suspend
From: Alistair @ 2022-01-27 10:35 UTC (permalink / raw)
To: Guenter Roeck, linux-arm-kernel, shawnguo,
Linux Kernel Mailing List, s.hauer, linux-watchdog, wim
Cc: devicetree, festevam, linux-imx, Rob Herring, kernel
In-Reply-To: <1a8ee480-b066-8da9-cd63-079e07b7d88a@roeck-us.net>
On Tue, 25 Jan 2022, at 2:21 AM, Guenter Roeck wrote:
> On 1/24/22 04:00, Alistair Francis wrote:
> > The i.MX watchdog cannot be disabled by softwrae once it has been
>
> s/softwrae/software/
>
> > enabled. This means that it can't be stopped before suspend.
> >
> > For systems that enter low power mode this is fine, as the watchdog will
> > be automatically stopped by hardwrae in low power mode. Not all i.MX
>
> s/hardwrae/hardware/
>
> > platforms support low power mode in the mainline kernel. For example the
> > i.MX7D does not enter low power mode and so will be rebooted 2 minutes
> > after entering freeze or mem sleep states.
>
> I don't think "mem" adds any value here. Just make it sleep states.
>
> >
> > This patch introduces a device tree property "fsl,ping-during-suspend"
> > that can be used to enable ping on suspend support for these systems.
> >
> > Signed-off-by: Alistair Francis <alistair@alistair23.me>
> > ---
>
> Change log goes here.
>
> > drivers/watchdog/imx2_wdt.c | 27 ++++++++++++++++++++-------
> > 1 file changed, 20 insertions(+), 7 deletions(-)
> >
> > diff --git a/drivers/watchdog/imx2_wdt.c b/drivers/watchdog/imx2_wdt.c
> > index 51bfb796898b..d0c5d47ddede 100644
> > --- a/drivers/watchdog/imx2_wdt.c
> > +++ b/drivers/watchdog/imx2_wdt.c
> > @@ -66,6 +66,7 @@ struct imx2_wdt_device {
> > struct watchdog_device wdog;
> > bool ext_reset;
> > bool clk_is_on;
>
> I don't see the purpose of this variable. Unless I am missing something is is set
> but never used.
clk_is_on is used in imx2_wdt_ping(), it disables the access if
the clock isn't running.
>
> > + bool no_ping;
> > };
> >
> > static bool nowayout = WATCHDOG_NOWAYOUT;
> > @@ -312,12 +313,18 @@ static int __init imx2_wdt_probe(struct platform_device *pdev)
> >
> > wdev->ext_reset = of_property_read_bool(dev->of_node,
> > "fsl,ext-reset-output");
> > + /*
> > + * The i.MX7D doesn't support low power mode, so we need to ping the watchdog
> > + * during suspend.
> > + */
> > + wdev->no_ping = !of_device_is_compatible(dev->of_node, "fsl,imx7d-wdt");
>
> This is ok as long as there is only a single chip requiring this change.
> If there are more, the 'data' field in struct of_device_id should be used
> instead.
I only know of one now, so this should be fine then.
Alistair
>
> > platform_set_drvdata(pdev, wdog);
> > watchdog_set_drvdata(wdog, wdev);
> > watchdog_set_nowayout(wdog, nowayout);
> > watchdog_set_restart_priority(wdog, 128);
> > watchdog_init_timeout(wdog, timeout, dev);
> > - watchdog_stop_ping_on_suspend(wdog);
> > + if (wdev->no_ping)
> > + watchdog_stop_ping_on_suspend(wdog);
> >
> > if (imx2_wdt_is_running(wdev)) {
> > imx2_wdt_set_timeout(wdog, wdog->timeout);
> > @@ -366,9 +373,11 @@ static int __maybe_unused imx2_wdt_suspend(struct device *dev)
> > imx2_wdt_ping(wdog);
> > }
> >
> > - clk_disable_unprepare(wdev->clk);
> > + if (wdev->no_ping) {
> > + clk_disable_unprepare(wdev->clk);
> >
> > - wdev->clk_is_on = false;
> > + wdev->clk_is_on = false;
> > + }
> >
> > return 0;
> > }
> > @@ -380,11 +389,14 @@ static int __maybe_unused imx2_wdt_resume(struct device *dev)
> > struct imx2_wdt_device *wdev = watchdog_get_drvdata(wdog);
> > int ret;
> >
> > - ret = clk_prepare_enable(wdev->clk);
> > - if (ret)
> > - return ret;
> > + if (wdev->no_ping) {
> > + ret = clk_prepare_enable(wdev->clk);
> >
> > - wdev->clk_is_on = true;
> > + if (ret)
> > + return ret;
> > +
> > + wdev->clk_is_on = true;
> > + }
> >
> > if (watchdog_active(wdog) && !imx2_wdt_is_running(wdev)) {
> > /*
> > @@ -407,6 +419,7 @@ static SIMPLE_DEV_PM_OPS(imx2_wdt_pm_ops, imx2_wdt_suspend,
> >
> > static const struct of_device_id imx2_wdt_dt_ids[] = {
> > { .compatible = "fsl,imx21-wdt", },
> > + { .compatible = "fsl,imx7d-wdt", },
> > { /* sentinel */ }
> > };
> > MODULE_DEVICE_TABLE(of, imx2_wdt_dt_ids);
>
>
^ permalink raw reply
* Re: [PATCH v1, 7/8] media: uapi: Init VP9 stateless decode params
From: AngeloGioacchino Del Regno @ 2022-01-27 10:35 UTC (permalink / raw)
To: Yunfei Dong, Alexandre Courbot, Hans Verkuil, Tzung-Bi Shih,
Tiffany Lin, Andrew-CT Chen, Mauro Carvalho Chehab, Rob Herring,
Matthias Brugger, Tomasz Figa
Cc: George Sun, Xiaoyong Lu, Hsin-Yi Wang, Fritz Koenig,
Dafna Hirschfeld, Benjamin Gaignard, Daniel Vetter, dri-devel,
Irui Wang, Steve Cho, linux-media, devicetree, linux-kernel,
linux-arm-kernel, srv_heupstream, linux-mediatek,
Project_Global_Chrome_Upstream_Group
In-Reply-To: <20220127025544.10854-8-yunfei.dong@mediatek.com>
Il 27/01/22 03:55, Yunfei Dong ha scritto:
> Init some of VP9 frame decode params to default value.
>
> Signed-off-by: Yunfei Dong <yunfei.dong@mediatek.com>
Hello Yunfei,
This patch is not strictly related to MediaTek SoCs, since it's
modfying v4l2-core.
Can you please send this patch separately?
Thanks,
Angelo
> ---
> drivers/media/v4l2-core/v4l2-ctrls-core.c | 8 ++++++++
> 1 file changed, 8 insertions(+)
>
> diff --git a/drivers/media/v4l2-core/v4l2-ctrls-core.c b/drivers/media/v4l2-core/v4l2-ctrls-core.c
> index 54abe5245dcc..b25c77b8a445 100644
> --- a/drivers/media/v4l2-core/v4l2-ctrls-core.c
> +++ b/drivers/media/v4l2-core/v4l2-ctrls-core.c
> @@ -112,6 +112,7 @@ static void std_init_compound(const struct v4l2_ctrl *ctrl, u32 idx,
> struct v4l2_ctrl_mpeg2_picture *p_mpeg2_picture;
> struct v4l2_ctrl_mpeg2_quantisation *p_mpeg2_quant;
> struct v4l2_ctrl_vp8_frame *p_vp8_frame;
> + struct v4l2_ctrl_vp9_frame *p_vp9_frame;
> struct v4l2_ctrl_fwht_params *p_fwht_params;
> void *p = ptr.p + idx * ctrl->elem_size;
>
> @@ -152,6 +153,13 @@ static void std_init_compound(const struct v4l2_ctrl *ctrl, u32 idx,
> p_vp8_frame = p;
> p_vp8_frame->num_dct_parts = 1;
> break;
> + case V4L2_CTRL_TYPE_VP9_FRAME:
> + p_vp9_frame = p;
> + p_vp9_frame->profile = 0;
> + p_vp9_frame->bit_depth = 8;
> + p_vp9_frame->flags |= V4L2_VP9_FRAME_FLAG_X_SUBSAMPLING |
> + V4L2_VP9_FRAME_FLAG_Y_SUBSAMPLING;
> + break;
> case V4L2_CTRL_TYPE_FWHT_PARAMS:
> p_fwht_params = p;
> p_fwht_params->version = V4L2_FWHT_VERSION;
>
^ permalink raw reply
* Re: [PATCH v15 10/12] drm/mediatek: add DSC support for mediatek-drm
From: AngeloGioacchino Del Regno @ 2022-01-27 10:27 UTC (permalink / raw)
To: jason-jh.lin, Rob Herring, Matthias Brugger, Chun-Kuang Hu,
Philipp Zabel
Cc: Maxime Coquelin, David Airlie, Daniel Vetter, Alexandre Torgue,
hsinyi, fshao, moudy.ho, roy-cw.yeh, CK Hu, Fabien Parent,
Jitao shi, nancy.lin, singo.chang, devicetree, linux-stm32,
linux-arm-kernel, linux-mediatek, linux-kernel
In-Reply-To: <20220126071932.32615-11-jason-jh.lin@mediatek.com>
Il 26/01/22 08:19, jason-jh.lin ha scritto:
> DSC is designed for real-time systems with real-time compression,
> transmission, decompression and display.
> The DSC standard is a specification of the algorithms used for
> compressing and decompressing image display streams, including
> the specification of the syntax and semantics of the compressed
> video bit stream.
>
> Signed-off-by: jason-jh.lin <jason-jh.lin@mediatek.com>
> Reviewed-by: Chun-Kuang Hu <chunkuang.hu@kernel.org>
Acked-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
^ permalink raw reply
* Re: [PATCH v3 6/6] RISC-V: Do not use cpumask data structure for hartid bitmap
From: Andreas Schwab @ 2022-01-27 10:17 UTC (permalink / raw)
To: Geert Uytterhoeven
Cc: Atish Patra, Jessica Clarke, Atish Patra,
Linux Kernel Mailing List, Anup Patel, Albert Ou, Damien Le Moal,
devicetree, Jisheng Zhang, Krzysztof Kozlowski, linux-riscv,
Palmer Dabbelt, Paul Walmsley, Rob Herring
In-Reply-To: <CAMuHMdXyjSrXNCAO8V8pajXW5ts29p==p2J1HnPPoo3-8osKbA@mail.gmail.com>
On Jan 27 2022, Geert Uytterhoeven wrote:
> Hi Atish,
>
> On Thu, Jan 27, 2022 at 9:48 AM Geert Uytterhoeven <geert@linux-m68k.org> wrote:
>> On Thu, Jan 27, 2022 at 2:02 AM Atish Patra <atishp@atishpatra.org> wrote:
> > Ahh yes. hmask will be incorrect if the bootcpu(cpu 0) is a higher
>> > hartid and it is trying to do a remote tlb flush/IPI
>> > to lower the hartid. We should generate the hartid array before the loop.
>> >
>> > Can you try this diff ? It seems to work for me during multiple boot
>> > cycle on the unleashed.
>> >
>> > You can find the patch here as well
>> > https://github.com/atishp04/linux/commits/v5.17-rc1
>>
>> Thanks, that fixes the issue for me.
>>
>> > --- a/arch/riscv/kernel/sbi.c
>> > +++ b/arch/riscv/kernel/sbi.c
>
>> > @@ -345,13 +368,21 @@ static int __sbi_rfence_v02(int fid, const
>> > struct cpumask *cpu_mask,
>> > unsigned long arg4, unsigned long arg5)
>> > {
>> > unsigned long hartid, cpuid, hmask = 0, hbase = 0;
>> > - int result;
>> > + int result, index = 0, max_index = 0;
>> > + unsigned long hartid_arr[NR_CPUS] = {0};
>>
>> That's up to 256 bytes on the stack. And more if the maximum
>> number of cores is increased.
>
> I.e. 4 KiB with the proposed increase to 256 CPUs, as mentioned in
And those 4K need to be cleared each time the function is called, even
if there is only a small number of cpus.
--
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510 2552 DF73 E780 A9DA AEC1
"And now for something completely different."
^ permalink raw reply
* Re: [PATCH] arm64: dts: mt8195: add gce node
From: AngeloGioacchino Del Regno @ 2022-01-27 10:24 UTC (permalink / raw)
To: jason-jh.lin, Rob Herring, Linus Walleij, Matthias Brugger,
Paolo Bonzini, Sean Christopherson, maciej.szmigiero,
David Matlack, Jing Zhang, Marc Zyngier, Bartosz Golaszewski,
Sean Wang, Tinghan Shen
Cc: devicetree, linux-arm-kernel, linux-mediatek, linux-kernel,
Project_Global_Chrome_Upstream_Group, ryder.lee, wenst,
chunfeng.yun, Seiya Wang, moudy.ho, roy-cw.yeh, nancy.lin,
singo.chang, Macpaul.Lin
In-Reply-To: <20220126090109.32143-1-jason-jh.lin@mediatek.com>
Il 26/01/22 10:01, jason-jh.lin ha scritto:
> Add gce node and gce alias on mt8195 dts file.
>
> Signed-off-by: jason-jh.lin <jason-jh.lin@mediatek.com>
> ---
> This patch is based on [1]
>
> [1] arm64: dts: Add mediatek SoC mt8195 and evaluation board
> - https://patchwork.kernel.org/project/linux-mediatek/patch/20220112114724.1953-4-tinghan.shen@mediatek.com/
> ---
> arch/arm64/boot/dts/mediatek/mt8195.dtsi | 22 ++++++++++++++++++++++
> 1 file changed, 22 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/mediatek/mt8195.dtsi b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
> index a363e82f6988..d778ca598d18 100644
> --- a/arch/arm64/boot/dts/mediatek/mt8195.dtsi
> +++ b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
> @@ -6,6 +6,7 @@
>
> /dts-v1/;
> #include <dt-bindings/clock/mt8195-clk.h>
> +#include <dt-bindings/gce/mt8195-gce.h>
> #include <dt-bindings/interrupt-controller/arm-gic.h>
> #include <dt-bindings/interrupt-controller/irq.h>
> #include <dt-bindings/phy/phy.h>
> @@ -18,6 +19,11 @@
> #address-cells = <2>;
> #size-cells = <2>;
>
> + aliases {
> + gce0 = &gce0;
> + gce1 = &gce1;
> + };
> +
> cpus {
> #address-cells = <1>;
> #size-cells = <0>;
> @@ -367,6 +373,22 @@
> assigned-clock-parents = <&topckgen CLK_TOP_ULPOSC1_D10>;
> };
>
> + gce0: mdp_mailbox@10320000 {
Just "mailbox" is fine.
gce0: mailbox@10320000 {
> + compatible = "mediatek,mt8195-gce";
> + reg = <0 0x10320000 0 0x4000>;
> + interrupts = <GIC_SPI 226 IRQ_TYPE_LEVEL_HIGH 0>;
> + #mbox-cells = <2>;
> + clocks = <&infracfg_ao CLK_INFRA_AO_GCE>;
> + };
> +
> + gce1: disp_mailbox@10330000 {
Same here, please.
After that,
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
> + compatible = "mediatek,mt8195-gce";
> + reg = <0 0x10330000 0 0x4000>;
> + interrupts = <GIC_SPI 228 IRQ_TYPE_LEVEL_HIGH 0>;
> + #mbox-cells = <2>;
> + clocks = <&infracfg_ao CLK_INFRA_AO_GCE2>;
> + };
> +
> scp_adsp: clock-controller@10720000 {
> compatible = "mediatek,mt8195-scp_adsp";
> reg = <0 0x10720000 0 0x1000>;
>
^ permalink raw reply
* [PATCH net-next 7/7] net: lan966x: Implement get_ts_info
From: Horatiu Vultur @ 2022-01-27 10:23 UTC (permalink / raw)
To: netdev, devicetree, linux-kernel
Cc: davem, kuba, robh+dt, UNGLinuxDriver, linux, richardcochran,
f.fainelli, vivien.didelot, vladimir.oltean, andrew,
Horatiu Vultur
In-Reply-To: <20220127102333.987195-1-horatiu.vultur@microchip.com>
Implement the function get_ts_info in ethtool_ops which is needed to get
the HW capabilities for timestamping.
Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com>
---
.../microchip/lan966x/lan966x_ethtool.c | 36 +++++++++++++++++++
1 file changed, 36 insertions(+)
diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_ethtool.c b/drivers/net/ethernet/microchip/lan966x/lan966x_ethtool.c
index 614f12c2fe6a..1dd12e0c3b58 100644
--- a/drivers/net/ethernet/microchip/lan966x/lan966x_ethtool.c
+++ b/drivers/net/ethernet/microchip/lan966x/lan966x_ethtool.c
@@ -545,6 +545,41 @@ static int lan966x_set_pauseparam(struct net_device *dev,
return phylink_ethtool_set_pauseparam(port->phylink, pause);
}
+static int lan966x_get_ts_info(struct net_device *dev,
+ struct ethtool_ts_info *info)
+{
+ struct lan966x_port *port = netdev_priv(dev);
+ struct lan966x *lan966x = port->lan966x;
+ struct lan966x_phc *phc;
+
+ if (!lan966x->ptp)
+ return ethtool_op_get_ts_info(dev, info);
+
+ phc = &lan966x->phc[LAN966X_PHC_PORT];
+
+ info->phc_index = phc->clock ? ptp_clock_index(phc->clock) : -1;
+ if (info->phc_index == -1) {
+ info->so_timestamping |= SOF_TIMESTAMPING_TX_SOFTWARE |
+ SOF_TIMESTAMPING_RX_SOFTWARE |
+ SOF_TIMESTAMPING_SOFTWARE;
+ return 0;
+ }
+ info->so_timestamping |= SOF_TIMESTAMPING_TX_SOFTWARE |
+ SOF_TIMESTAMPING_RX_SOFTWARE |
+ SOF_TIMESTAMPING_SOFTWARE |
+ SOF_TIMESTAMPING_TX_HARDWARE |
+ SOF_TIMESTAMPING_RX_HARDWARE |
+ SOF_TIMESTAMPING_RAW_HARDWARE;
+ info->tx_types = BIT(HWTSTAMP_TX_OFF) | BIT(HWTSTAMP_TX_ON) |
+ BIT(HWTSTAMP_TX_ONESTEP_SYNC);
+ info->rx_filters = BIT(HWTSTAMP_FILTER_NONE) |
+ BIT(HWTSTAMP_FILTER_PTP_V2_EVENT) |
+ BIT(HWTSTAMP_FILTER_PTP_V2_L2_EVENT) |
+ BIT(HWTSTAMP_FILTER_PTP_V2_L4_EVENT);
+
+ return 0;
+}
+
const struct ethtool_ops lan966x_ethtool_ops = {
.get_link_ksettings = lan966x_get_link_ksettings,
.set_link_ksettings = lan966x_set_link_ksettings,
@@ -556,6 +591,7 @@ const struct ethtool_ops lan966x_ethtool_ops = {
.get_eth_mac_stats = lan966x_get_eth_mac_stats,
.get_rmon_stats = lan966x_get_eth_rmon_stats,
.get_link = ethtool_op_get_link,
+ .get_ts_info = lan966x_get_ts_info,
};
static void lan966x_check_stats_work(struct work_struct *work)
--
2.33.0
^ permalink raw reply related
* [PATCH net-next 6/7] net: lan966x: Add support for ptp interrupts
From: Horatiu Vultur @ 2022-01-27 10:23 UTC (permalink / raw)
To: netdev, devicetree, linux-kernel
Cc: davem, kuba, robh+dt, UNGLinuxDriver, linux, richardcochran,
f.fainelli, vivien.didelot, vladimir.oltean, andrew,
Horatiu Vultur
In-Reply-To: <20220127102333.987195-1-horatiu.vultur@microchip.com>
When doing 2-step timestamping the HW will generate a interrupt when it
managed to timestamp a frame. It is the SW responsibility to read it
from the FIFO. This patch adds support for this.
Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com>
---
.../ethernet/microchip/lan966x/lan966x_main.c | 11 ++
.../ethernet/microchip/lan966x/lan966x_main.h | 2 +
.../ethernet/microchip/lan966x/lan966x_ptp.c | 117 ++++++++++++++++++
3 files changed, 130 insertions(+)
diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_main.c b/drivers/net/ethernet/microchip/lan966x/lan966x_main.c
index 3c19763118ea..e62758bcb998 100644
--- a/drivers/net/ethernet/microchip/lan966x/lan966x_main.c
+++ b/drivers/net/ethernet/microchip/lan966x/lan966x_main.c
@@ -957,6 +957,17 @@ static int lan966x_probe(struct platform_device *pdev)
return dev_err_probe(&pdev->dev, err, "Unable to use ana irq");
}
+ lan966x->ptp_irq = platform_get_irq_byname(pdev, "ptp");
+ if (lan966x->ptp_irq > 0) {
+ err = devm_request_threaded_irq(&pdev->dev, lan966x->ptp_irq, NULL,
+ lan966x_ptp_irq_handler, IRQF_ONESHOT,
+ "ptp irq", lan966x);
+ if (err)
+ return dev_err_probe(&pdev->dev, err, "Unable to use ptp irq");
+
+ lan966x->ptp = 1;
+ }
+
/* init switch */
lan966x_init(lan966x);
lan966x_stats_init(lan966x);
diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_main.h b/drivers/net/ethernet/microchip/lan966x/lan966x_main.h
index 03c6a4f34ae2..026474c609ea 100644
--- a/drivers/net/ethernet/microchip/lan966x/lan966x_main.h
+++ b/drivers/net/ethernet/microchip/lan966x/lan966x_main.h
@@ -131,6 +131,7 @@ struct lan966x {
/* interrupts */
int xtr_irq;
int ana_irq;
+ int ptp_irq;
/* worqueue for fdb */
struct workqueue_struct *fdb_work;
@@ -276,6 +277,7 @@ int lan966x_ptp_txtstamp_request(struct lan966x_port *port,
struct sk_buff *skb);
void lan966x_ptp_txtstamp_release(struct lan966x_port *port,
struct sk_buff *skb);
+irqreturn_t lan966x_ptp_irq_handler(int irq, void *args);
static inline void __iomem *lan_addr(void __iomem *base[],
int id, int tinst, int tcnt,
diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_ptp.c b/drivers/net/ethernet/microchip/lan966x/lan966x_ptp.c
index ba65604aef48..4d1f9e476634 100644
--- a/drivers/net/ethernet/microchip/lan966x/lan966x_ptp.c
+++ b/drivers/net/ethernet/microchip/lan966x/lan966x_ptp.c
@@ -216,6 +216,123 @@ void lan966x_ptp_txtstamp_release(struct lan966x_port *port,
spin_unlock_irqrestore(&lan966x->ptp_ts_id_lock, flags);
}
+static void lan966x_get_hwtimestamp(struct lan966x *lan966x,
+ struct timespec64 *ts,
+ u32 nsec)
+{
+ /* Read current PTP time to get seconds */
+ unsigned long flags;
+ u32 curr_nsec;
+
+ spin_lock_irqsave(&lan966x->ptp_clock_lock, flags);
+
+ lan_rmw(PTP_PIN_CFG_PIN_ACTION_SET(PTP_PIN_ACTION_SAVE) |
+ PTP_PIN_CFG_PIN_DOM_SET(LAN966X_PHC_PORT) |
+ PTP_PIN_CFG_PIN_SYNC_SET(0),
+ PTP_PIN_CFG_PIN_ACTION |
+ PTP_PIN_CFG_PIN_DOM |
+ PTP_PIN_CFG_PIN_SYNC,
+ lan966x, PTP_PIN_CFG(TOD_ACC_PIN));
+
+ ts->tv_sec = lan_rd(lan966x, PTP_TOD_SEC_LSB(TOD_ACC_PIN));
+ curr_nsec = lan_rd(lan966x, PTP_TOD_NSEC(TOD_ACC_PIN));
+
+ ts->tv_nsec = nsec;
+
+ /* Sec has incremented since the ts was registered */
+ if (curr_nsec < nsec)
+ ts->tv_sec--;
+
+ spin_unlock_irqrestore(&lan966x->ptp_clock_lock, flags);
+}
+
+irqreturn_t lan966x_ptp_irq_handler(int irq, void *args)
+{
+ int budget = LAN966X_MAX_PTP_ID;
+ struct lan966x *lan966x = args;
+
+ while (budget--) {
+ struct sk_buff *skb, *skb_tmp, *skb_match = NULL;
+ struct skb_shared_hwtstamps shhwtstamps;
+ struct lan966x_port *port;
+ struct timespec64 ts;
+ unsigned long flags;
+ u32 val, id, txport;
+ u32 delay;
+
+ val = lan_rd(lan966x, PTP_TWOSTEP_CTRL);
+
+ /* Check if a timestamp can be retrieved */
+ if (!(val & PTP_TWOSTEP_CTRL_VLD))
+ break;
+
+ WARN_ON(val & PTP_TWOSTEP_CTRL_OVFL);
+
+ if (!(val & PTP_TWOSTEP_CTRL_STAMP_TX))
+ continue;
+
+ /* Retrieve the ts Tx port */
+ txport = PTP_TWOSTEP_CTRL_STAMP_PORT_GET(val);
+
+ /* Retrieve its associated skb */
+ port = lan966x->ports[txport];
+
+ /* Retrieve the delay */
+ delay = lan_rd(lan966x, PTP_TWOSTEP_STAMP);
+ delay = PTP_TWOSTEP_STAMP_STAMP_NSEC_GET(delay);
+
+ /* Get next timestamp from fifo, which needs to be the
+ * rx timestamp which represents the id of the frame
+ */
+ lan_rmw(PTP_TWOSTEP_CTRL_NXT_SET(1),
+ PTP_TWOSTEP_CTRL_NXT,
+ lan966x, PTP_TWOSTEP_CTRL);
+
+ val = lan_rd(lan966x, PTP_TWOSTEP_CTRL);
+
+ /* Check if a timestamp can be retried */
+ if (!(val & PTP_TWOSTEP_CTRL_VLD))
+ break;
+
+ /* Read RX timestamping to get the ID */
+ id = lan_rd(lan966x, PTP_TWOSTEP_STAMP);
+
+ spin_lock_irqsave(&port->tx_skbs.lock, flags);
+ skb_queue_walk_safe(&port->tx_skbs, skb, skb_tmp) {
+ if (LAN966X_SKB_CB(skb)->ts_id != id)
+ continue;
+
+ __skb_unlink(skb, &port->tx_skbs);
+ skb_match = skb;
+ break;
+ }
+ spin_unlock_irqrestore(&port->tx_skbs.lock, flags);
+
+ /* Next ts */
+ lan_rmw(PTP_TWOSTEP_CTRL_NXT_SET(1),
+ PTP_TWOSTEP_CTRL_NXT,
+ lan966x, PTP_TWOSTEP_CTRL);
+
+ if (WARN_ON(!skb_match))
+ continue;
+
+ spin_lock(&lan966x->ptp_ts_id_lock);
+ lan966x->ptp_skbs--;
+ spin_unlock(&lan966x->ptp_ts_id_lock);
+
+ /* Get the h/w timestamp */
+ lan966x_get_hwtimestamp(lan966x, &ts, delay);
+
+ /* Set the timestamp into the skb */
+ shhwtstamps.hwtstamp = ktime_set(ts.tv_sec, ts.tv_nsec);
+ skb_tstamp_tx(skb_match, &shhwtstamps);
+
+ dev_kfree_skb_any(skb_match);
+ }
+
+ return IRQ_HANDLED;
+}
+
static int lan966x_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
{
struct lan966x_phc *phc = container_of(ptp, struct lan966x_phc, info);
--
2.33.0
^ permalink raw reply related
* [PATCH net-next 3/7] net: lan966x: Add support for ptp clocks
From: Horatiu Vultur @ 2022-01-27 10:23 UTC (permalink / raw)
To: netdev, devicetree, linux-kernel
Cc: davem, kuba, robh+dt, UNGLinuxDriver, linux, richardcochran,
f.fainelli, vivien.didelot, vladimir.oltean, andrew,
Horatiu Vultur
In-Reply-To: <20220127102333.987195-1-horatiu.vultur@microchip.com>
The lan966x has 3 PHC. Enable each of them, for now all the
timestamping is happening on the first PHC.
Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com>
---
.../net/ethernet/microchip/lan966x/Makefile | 3 +-
.../ethernet/microchip/lan966x/lan966x_main.c | 8 +
.../ethernet/microchip/lan966x/lan966x_main.h | 20 ++
.../ethernet/microchip/lan966x/lan966x_ptp.c | 287 ++++++++++++++++++
4 files changed, 317 insertions(+), 1 deletion(-)
create mode 100644 drivers/net/ethernet/microchip/lan966x/lan966x_ptp.c
diff --git a/drivers/net/ethernet/microchip/lan966x/Makefile b/drivers/net/ethernet/microchip/lan966x/Makefile
index 040cfff9f577..a9ffc719aa0e 100644
--- a/drivers/net/ethernet/microchip/lan966x/Makefile
+++ b/drivers/net/ethernet/microchip/lan966x/Makefile
@@ -7,4 +7,5 @@ obj-$(CONFIG_LAN966X_SWITCH) += lan966x-switch.o
lan966x-switch-objs := lan966x_main.o lan966x_phylink.o lan966x_port.o \
lan966x_mac.o lan966x_ethtool.o lan966x_switchdev.o \
- lan966x_vlan.o lan966x_fdb.o lan966x_mdb.o
+ lan966x_vlan.o lan966x_fdb.o lan966x_mdb.o \
+ lan966x_ptp.o
diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_main.c b/drivers/net/ethernet/microchip/lan966x/lan966x_main.c
index 2853e8f7fb39..ee3505318c5c 100644
--- a/drivers/net/ethernet/microchip/lan966x/lan966x_main.c
+++ b/drivers/net/ethernet/microchip/lan966x/lan966x_main.c
@@ -932,8 +932,15 @@ static int lan966x_probe(struct platform_device *pdev)
if (err)
goto cleanup_ports;
+ err = lan966x_ptp_init(lan966x);
+ if (err)
+ goto cleanup_fdb;
+
return 0;
+cleanup_fdb:
+ lan966x_fdb_deinit(lan966x);
+
cleanup_ports:
fwnode_handle_put(portnp);
@@ -959,6 +966,7 @@ static int lan966x_remove(struct platform_device *pdev)
lan966x_mac_purge_entries(lan966x);
lan966x_mdb_deinit(lan966x);
lan966x_fdb_deinit(lan966x);
+ lan966x_ptp_deinit(lan966x);
return 0;
}
diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_main.h b/drivers/net/ethernet/microchip/lan966x/lan966x_main.h
index 99c6d0a9f946..c77a91aa24e7 100644
--- a/drivers/net/ethernet/microchip/lan966x/lan966x_main.h
+++ b/drivers/net/ethernet/microchip/lan966x/lan966x_main.h
@@ -8,6 +8,7 @@
#include <linux/jiffies.h>
#include <linux/phy.h>
#include <linux/phylink.h>
+#include <linux/ptp_clock_kernel.h>
#include <net/switchdev.h>
#include "lan966x_regs.h"
@@ -50,6 +51,9 @@
#define LAN966X_SPEED_100 2
#define LAN966X_SPEED_10 3
+#define LAN966X_PHC_COUNT 3
+#define LAN966X_PHC_PORT 0
+
/* MAC table entry types.
* ENTRYTYPE_NORMAL is subject to aging.
* ENTRYTYPE_LOCKED is not subject to aging.
@@ -70,6 +74,14 @@ struct lan966x_stat_layout {
char name[ETH_GSTRING_LEN];
};
+struct lan966x_phc {
+ struct ptp_clock *clock;
+ struct ptp_clock_info info;
+ struct hwtstamp_config hwtstamp_config;
+ struct lan966x *lan966x;
+ u8 index;
+};
+
struct lan966x {
struct device *dev;
@@ -113,6 +125,11 @@ struct lan966x {
/* mdb */
struct list_head mdb_entries;
struct list_head pgid_entries;
+
+ /* ptp */
+ bool ptp;
+ struct lan966x_phc phc[LAN966X_PHC_COUNT];
+ spinlock_t ptp_clock_lock; /* lock for phc */
};
struct lan966x_port_config {
@@ -228,6 +245,9 @@ int lan966x_handle_port_mdb_del(struct lan966x_port *port,
void lan966x_mdb_erase_entries(struct lan966x *lan966x, u16 vid);
void lan966x_mdb_write_entries(struct lan966x *lan966x, u16 vid);
+int lan966x_ptp_init(struct lan966x *lan966x);
+void lan966x_ptp_deinit(struct lan966x *lan966x);
+
static inline void __iomem *lan_addr(void __iomem *base[],
int id, int tinst, int tcnt,
int gbase, int ginst,
diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_ptp.c b/drivers/net/ethernet/microchip/lan966x/lan966x_ptp.c
new file mode 100644
index 000000000000..69d8f43e2b1b
--- /dev/null
+++ b/drivers/net/ethernet/microchip/lan966x/lan966x_ptp.c
@@ -0,0 +1,287 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+#include <linux/ptp_classify.h>
+
+#include "lan966x_main.h"
+
+#define LAN966X_MAX_PTP_ID 512
+
+/* Represents 1ppm adjustment in 2^59 format with 6.037735849ns as reference
+ * The value is calculated as following: (1/1000000)/((2^-59)/6.037735849)
+ */
+#define LAN966X_1PPM_FORMAT 3480517749723LL
+
+/* Represents 1ppb adjustment in 2^29 format with 6.037735849ns as reference
+ * The value is calculated as following: (1/1000000000)/((2^59)/6.037735849)
+ */
+#define LAN966X_1PPB_FORMAT 3480517749LL
+
+#define TOD_ACC_PIN 0x5
+
+enum {
+ PTP_PIN_ACTION_IDLE = 0,
+ PTP_PIN_ACTION_LOAD,
+ PTP_PIN_ACTION_SAVE,
+ PTP_PIN_ACTION_CLOCK,
+ PTP_PIN_ACTION_DELTA,
+ PTP_PIN_ACTION_TOD
+};
+
+static u64 lan966x_ptp_get_nominal_value(void)
+{
+ u64 res = 0x304d2df1;
+
+ res <<= 32;
+ return res;
+}
+
+static int lan966x_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
+{
+ struct lan966x_phc *phc = container_of(ptp, struct lan966x_phc, info);
+ struct lan966x *lan966x = phc->lan966x;
+ unsigned long flags;
+ bool neg_adj = 0;
+ u64 tod_inc;
+ u64 ref;
+
+ if (!scaled_ppm)
+ return 0;
+
+ if (scaled_ppm < 0) {
+ neg_adj = 1;
+ scaled_ppm = -scaled_ppm;
+ }
+
+ tod_inc = lan966x_ptp_get_nominal_value();
+
+ /* The multiplication is split in 2 separate additions because of
+ * overflow issues. If scaled_ppm with 16bit fractional part was bigger
+ * than 20ppm then we got overflow.
+ */
+ ref = LAN966X_1PPM_FORMAT * (scaled_ppm >> 16);
+ ref += (LAN966X_1PPM_FORMAT * (0xffff & scaled_ppm)) >> 16;
+ tod_inc = neg_adj ? tod_inc - ref : tod_inc + ref;
+
+ spin_lock_irqsave(&lan966x->ptp_clock_lock, flags);
+
+ lan_rmw(PTP_DOM_CFG_CLKCFG_DIS_SET(1 << BIT(phc->index)),
+ PTP_DOM_CFG_CLKCFG_DIS,
+ lan966x, PTP_DOM_CFG);
+
+ lan_wr((u32)tod_inc & 0xFFFFFFFF, lan966x,
+ PTP_CLK_PER_CFG(phc->index, 0));
+ lan_wr((u32)(tod_inc >> 32), lan966x,
+ PTP_CLK_PER_CFG(phc->index, 1));
+
+ lan_rmw(PTP_DOM_CFG_CLKCFG_DIS_SET(0),
+ PTP_DOM_CFG_CLKCFG_DIS,
+ lan966x, PTP_DOM_CFG);
+
+ spin_unlock_irqrestore(&lan966x->ptp_clock_lock, flags);
+
+ return 0;
+}
+
+static int lan966x_ptp_settime64(struct ptp_clock_info *ptp,
+ const struct timespec64 *ts)
+{
+ struct lan966x_phc *phc = container_of(ptp, struct lan966x_phc, info);
+ struct lan966x *lan966x = phc->lan966x;
+ unsigned long flags;
+
+ spin_lock_irqsave(&lan966x->ptp_clock_lock, flags);
+
+ /* Must be in IDLE mode before the time can be loaded */
+ lan_rmw(PTP_PIN_CFG_PIN_ACTION_SET(PTP_PIN_ACTION_IDLE) |
+ PTP_PIN_CFG_PIN_DOM_SET(phc->index) |
+ PTP_PIN_CFG_PIN_SYNC_SET(0),
+ PTP_PIN_CFG_PIN_ACTION |
+ PTP_PIN_CFG_PIN_DOM |
+ PTP_PIN_CFG_PIN_SYNC,
+ lan966x, PTP_PIN_CFG(TOD_ACC_PIN));
+
+ /* Set new value */
+ lan_wr(PTP_TOD_SEC_MSB_TOD_SEC_MSB_SET(upper_32_bits(ts->tv_sec)),
+ lan966x, PTP_TOD_SEC_MSB(TOD_ACC_PIN));
+ lan_wr(lower_32_bits(ts->tv_sec),
+ lan966x, PTP_TOD_SEC_LSB(TOD_ACC_PIN));
+ lan_wr(ts->tv_nsec, lan966x, PTP_TOD_NSEC(TOD_ACC_PIN));
+
+ /* Apply new values */
+ lan_rmw(PTP_PIN_CFG_PIN_ACTION_SET(PTP_PIN_ACTION_LOAD) |
+ PTP_PIN_CFG_PIN_DOM_SET(phc->index) |
+ PTP_PIN_CFG_PIN_SYNC_SET(0),
+ PTP_PIN_CFG_PIN_ACTION |
+ PTP_PIN_CFG_PIN_DOM |
+ PTP_PIN_CFG_PIN_SYNC,
+ lan966x, PTP_PIN_CFG(TOD_ACC_PIN));
+
+ spin_unlock_irqrestore(&lan966x->ptp_clock_lock, flags);
+
+ return 0;
+}
+
+static int lan966x_ptp_gettime64(struct ptp_clock_info *ptp,
+ struct timespec64 *ts)
+{
+ struct lan966x_phc *phc = container_of(ptp, struct lan966x_phc, info);
+ struct lan966x *lan966x = phc->lan966x;
+ unsigned long flags;
+ time64_t s;
+ s64 ns;
+
+ spin_lock_irqsave(&lan966x->ptp_clock_lock, flags);
+
+ lan_rmw(PTP_PIN_CFG_PIN_ACTION_SET(PTP_PIN_ACTION_SAVE) |
+ PTP_PIN_CFG_PIN_DOM_SET(phc->index) |
+ PTP_PIN_CFG_PIN_SYNC_SET(0),
+ PTP_PIN_CFG_PIN_ACTION |
+ PTP_PIN_CFG_PIN_DOM |
+ PTP_PIN_CFG_PIN_SYNC,
+ lan966x, PTP_PIN_CFG(TOD_ACC_PIN));
+
+ s = lan_rd(lan966x, PTP_TOD_SEC_MSB(TOD_ACC_PIN));
+ s <<= 32;
+ s |= lan_rd(lan966x, PTP_TOD_SEC_LSB(TOD_ACC_PIN));
+ ns = lan_rd(lan966x, PTP_TOD_NSEC(TOD_ACC_PIN));
+ ns &= PTP_TOD_NSEC_TOD_NSEC;
+
+ spin_unlock_irqrestore(&lan966x->ptp_clock_lock, flags);
+
+ /* Deal with negative values */
+ if ((ns & 0xFFFFFFF0) == 0x3FFFFFF0) {
+ s--;
+ ns &= 0xf;
+ ns += 999999984;
+ }
+
+ set_normalized_timespec64(ts, s, ns);
+ return 0;
+}
+
+static int lan966x_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta)
+{
+ struct lan966x_phc *phc = container_of(ptp, struct lan966x_phc, info);
+ struct lan966x *lan966x = phc->lan966x;
+
+ if (delta > -(NSEC_PER_SEC / 2) && delta < (NSEC_PER_SEC / 2)) {
+ unsigned long flags;
+
+ spin_lock_irqsave(&lan966x->ptp_clock_lock, flags);
+
+ /* Must be in IDLE mode before the time can be loaded */
+ lan_rmw(PTP_PIN_CFG_PIN_ACTION_SET(PTP_PIN_ACTION_IDLE) |
+ PTP_PIN_CFG_PIN_DOM_SET(phc->index) |
+ PTP_PIN_CFG_PIN_SYNC_SET(0),
+ PTP_PIN_CFG_PIN_ACTION |
+ PTP_PIN_CFG_PIN_DOM |
+ PTP_PIN_CFG_PIN_SYNC,
+ lan966x, PTP_PIN_CFG(TOD_ACC_PIN));
+
+ lan_wr(PTP_TOD_NSEC_TOD_NSEC_SET(delta),
+ lan966x, PTP_TOD_NSEC(TOD_ACC_PIN));
+
+ /* Adjust time with the value of PTP_TOD_NSEC */
+ lan_rmw(PTP_PIN_CFG_PIN_ACTION_SET(PTP_PIN_ACTION_DELTA) |
+ PTP_PIN_CFG_PIN_DOM_SET(phc->index) |
+ PTP_PIN_CFG_PIN_SYNC_SET(0),
+ PTP_PIN_CFG_PIN_ACTION |
+ PTP_PIN_CFG_PIN_DOM |
+ PTP_PIN_CFG_PIN_SYNC,
+ lan966x, PTP_PIN_CFG(TOD_ACC_PIN));
+
+ spin_unlock_irqrestore(&lan966x->ptp_clock_lock, flags);
+ } else {
+ /* Fall back using lan966x_ptp_settime64 which is not exact */
+ struct timespec64 ts;
+ u64 now;
+
+ lan966x_ptp_gettime64(ptp, &ts);
+
+ now = ktime_to_ns(timespec64_to_ktime(ts));
+ ts = ns_to_timespec64(now + delta);
+
+ lan966x_ptp_settime64(ptp, &ts);
+ }
+
+ return 0;
+}
+
+static struct ptp_clock_info lan966x_ptp_clock_info = {
+ .owner = THIS_MODULE,
+ .name = "lan966x ptp",
+ .max_adj = 200000,
+ .gettime64 = lan966x_ptp_gettime64,
+ .settime64 = lan966x_ptp_settime64,
+ .adjtime = lan966x_ptp_adjtime,
+ .adjfine = lan966x_ptp_adjfine,
+};
+
+static int lan966x_ptp_phc_init(struct lan966x *lan966x,
+ int index,
+ struct ptp_clock_info *clock_info)
+{
+ struct lan966x_phc *phc = &lan966x->phc[index];
+
+ phc->info = *clock_info;
+ phc->clock = ptp_clock_register(&phc->info, lan966x->dev);
+ if (IS_ERR(phc->clock))
+ return PTR_ERR(phc->clock);
+
+ phc->index = index;
+ phc->lan966x = lan966x;
+
+ /* PTP Rx stamping is always enabled. */
+ phc->hwtstamp_config.rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT;
+
+ return 0;
+}
+
+int lan966x_ptp_init(struct lan966x *lan966x)
+{
+ u64 tod_adj = lan966x_ptp_get_nominal_value();
+ int err, i;
+
+ if (!lan966x->ptp)
+ return 0;
+
+ for (i = 0; i < LAN966X_PHC_COUNT; ++i) {
+ err = lan966x_ptp_phc_init(lan966x, i, &lan966x_ptp_clock_info);
+ if (err)
+ return err;
+ }
+
+ spin_lock_init(&lan966x->ptp_clock_lock);
+
+ /* Disable master counters */
+ lan_wr(PTP_DOM_CFG_ENA_SET(0), lan966x, PTP_DOM_CFG);
+
+ /* Configure the nominal TOD increment per clock cycle */
+ lan_rmw(PTP_DOM_CFG_CLKCFG_DIS_SET(0x7),
+ PTP_DOM_CFG_CLKCFG_DIS,
+ lan966x, PTP_DOM_CFG);
+
+ for (i = 0; i < LAN966X_PHC_COUNT; ++i) {
+ lan_wr((u32)tod_adj & 0xFFFFFFFF, lan966x,
+ PTP_CLK_PER_CFG(i, 0));
+ lan_wr((u32)(tod_adj >> 32), lan966x,
+ PTP_CLK_PER_CFG(i, 1));
+ }
+
+ lan_rmw(PTP_DOM_CFG_CLKCFG_DIS_SET(0),
+ PTP_DOM_CFG_CLKCFG_DIS,
+ lan966x, PTP_DOM_CFG);
+
+ /* Enable master counters */
+ lan_wr(PTP_DOM_CFG_ENA_SET(0x7), lan966x, PTP_DOM_CFG);
+
+ return 0;
+}
+
+void lan966x_ptp_deinit(struct lan966x *lan966x)
+{
+ int i;
+
+ for (i = 0; i < LAN966X_PHC_COUNT; ++i)
+ ptp_clock_unregister(lan966x->phc[i].clock);
+}
--
2.33.0
^ permalink raw reply related
* [PATCH net-next 5/7] net: lan966x: Update extraction/injection for timestamping
From: Horatiu Vultur @ 2022-01-27 10:23 UTC (permalink / raw)
To: netdev, devicetree, linux-kernel
Cc: davem, kuba, robh+dt, UNGLinuxDriver, linux, richardcochran,
f.fainelli, vivien.didelot, vladimir.oltean, andrew,
Horatiu Vultur
In-Reply-To: <20220127102333.987195-1-horatiu.vultur@microchip.com>
Update both the extraction and injection to do timestamping of the
frames. The extraction is always doing the timestamping while for
injection is doing the timestamping only if it is configured.
Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com>
---
.../ethernet/microchip/lan966x/lan966x_main.c | 51 ++++++-
.../ethernet/microchip/lan966x/lan966x_main.h | 20 +++
.../ethernet/microchip/lan966x/lan966x_ptp.c | 141 ++++++++++++++++++
3 files changed, 207 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_main.c b/drivers/net/ethernet/microchip/lan966x/lan966x_main.c
index c62615b9d101..3c19763118ea 100644
--- a/drivers/net/ethernet/microchip/lan966x/lan966x_main.c
+++ b/drivers/net/ethernet/microchip/lan966x/lan966x_main.c
@@ -202,7 +202,7 @@ static int lan966x_port_ifh_xmit(struct sk_buff *skb,
val = lan_rd(lan966x, QS_INJ_STATUS);
if (!(QS_INJ_STATUS_FIFO_RDY_GET(val) & BIT(grp)) ||
(QS_INJ_STATUS_WMARK_REACHED_GET(val) & BIT(grp)))
- return NETDEV_TX_BUSY;
+ goto err;
/* Write start of frame */
lan_wr(QS_INJ_CTRL_GAP_SIZE_SET(1) |
@@ -214,7 +214,7 @@ static int lan966x_port_ifh_xmit(struct sk_buff *skb,
/* Wait until the fifo is ready */
err = lan966x_port_inj_ready(lan966x, grp);
if (err)
- return NETDEV_TX_BUSY;
+ goto err;
lan_wr((__force u32)ifh[i], lan966x, QS_INJ_WR(grp));
}
@@ -226,7 +226,7 @@ static int lan966x_port_ifh_xmit(struct sk_buff *skb,
/* Wait until the fifo is ready */
err = lan966x_port_inj_ready(lan966x, grp);
if (err)
- return NETDEV_TX_BUSY;
+ goto err;
lan_wr(((u32 *)skb->data)[i], lan966x, QS_INJ_WR(grp));
}
@@ -236,7 +236,7 @@ static int lan966x_port_ifh_xmit(struct sk_buff *skb,
/* Wait until the fifo is ready */
err = lan966x_port_inj_ready(lan966x, grp);
if (err)
- return NETDEV_TX_BUSY;
+ goto err;
lan_wr(0, lan966x, QS_INJ_WR(grp));
++i;
@@ -256,8 +256,19 @@ static int lan966x_port_ifh_xmit(struct sk_buff *skb,
dev->stats.tx_packets++;
dev->stats.tx_bytes += skb->len;
+ if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP &&
+ LAN966X_SKB_CB(skb)->rew_op == IFH_REW_OP_TWO_STEP_PTP)
+ return NETDEV_TX_OK;
+
dev_consume_skb_any(skb);
return NETDEV_TX_OK;
+
+err:
+ if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP &&
+ LAN966X_SKB_CB(skb)->rew_op == IFH_REW_OP_TWO_STEP_PTP)
+ lan966x_ptp_txtstamp_release(port, skb);
+
+ return NETDEV_TX_BUSY;
}
static void lan966x_ifh_set_bypass(void *ifh, u64 bypass)
@@ -290,10 +301,23 @@ static void lan966x_ifh_set_vid(void *ifh, u64 vid)
IFH_POS_TCI, IFH_LEN * 4, PACK, 0);
}
+static void lan966x_ifh_set_rew_op(void *ifh, u64 rew_op)
+{
+ packing(ifh, &rew_op, IFH_POS_REW_CMD + IFH_WID_REW_CMD - 1,
+ IFH_POS_REW_CMD, IFH_LEN * 4, PACK, 0);
+}
+
+static void lan966x_ifh_set_timestamp(void *ifh, u64 timestamp)
+{
+ packing(ifh, ×tamp, IFH_POS_TIMESTAMP + IFH_WID_TIMESTAMP - 1,
+ IFH_POS_TIMESTAMP, IFH_LEN * 4, PACK, 0);
+}
+
static int lan966x_port_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct lan966x_port *port = netdev_priv(dev);
__be32 ifh[IFH_LEN];
+ int err;
memset(ifh, 0x0, sizeof(__be32) * IFH_LEN);
@@ -303,6 +327,15 @@ static int lan966x_port_xmit(struct sk_buff *skb, struct net_device *dev)
lan966x_ifh_set_ipv(ifh, skb->priority >= 7 ? 0x7 : skb->priority);
lan966x_ifh_set_vid(ifh, skb_vlan_tag_get(skb));
+ if (port->lan966x->ptp && skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) {
+ err = lan966x_ptp_txtstamp_request(port, skb);
+ if (err)
+ return err;
+
+ lan966x_ifh_set_rew_op(ifh, LAN966X_SKB_CB(skb)->rew_op);
+ lan966x_ifh_set_timestamp(ifh, LAN966X_SKB_CB(skb)->ts_id);
+ }
+
return lan966x_port_ifh_xmit(skb, ifh, dev);
}
@@ -453,6 +486,12 @@ static void lan966x_ifh_get_len(void *ifh, u64 *len)
IFH_POS_LEN, IFH_LEN * 4, UNPACK, 0);
}
+static void lan966x_ifh_get_timestamp(void *ifh, u64 *timestamp)
+{
+ packing(ifh, timestamp, IFH_POS_TIMESTAMP + IFH_WID_TIMESTAMP - 1,
+ IFH_POS_TIMESTAMP, IFH_LEN * 4, UNPACK, 0);
+}
+
static irqreturn_t lan966x_xtr_irq_handler(int irq, void *args)
{
struct lan966x *lan966x = args;
@@ -462,10 +501,10 @@ static irqreturn_t lan966x_xtr_irq_handler(int irq, void *args)
return IRQ_NONE;
do {
+ u64 src_port, len, timestamp;
struct net_device *dev;
struct sk_buff *skb;
int sz = 0, buf_len;
- u64 src_port, len;
u32 ifh[IFH_LEN];
u32 *buf;
u32 val;
@@ -480,6 +519,7 @@ static irqreturn_t lan966x_xtr_irq_handler(int irq, void *args)
lan966x_ifh_get_src_port(ifh, &src_port);
lan966x_ifh_get_len(ifh, &len);
+ lan966x_ifh_get_timestamp(ifh, ×tamp);
WARN_ON(src_port >= lan966x->num_phys_ports);
@@ -520,6 +560,7 @@ static irqreturn_t lan966x_xtr_irq_handler(int irq, void *args)
*buf = val;
}
+ lan966x_ptp_rxtstamp(lan966x, skb, timestamp);
skb->protocol = eth_type_trans(skb, dev);
if (lan966x->bridge_mask & BIT(src_port))
diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_main.h b/drivers/net/ethernet/microchip/lan966x/lan966x_main.h
index 55fa5e56b8d1..03c6a4f34ae2 100644
--- a/drivers/net/ethernet/microchip/lan966x/lan966x_main.h
+++ b/drivers/net/ethernet/microchip/lan966x/lan966x_main.h
@@ -86,6 +86,16 @@ struct lan966x_phc {
u8 index;
};
+struct lan966x_skb_cb {
+ u8 rew_op;
+ u16 ts_id;
+ unsigned long jiffies;
+};
+
+#define LAN966X_PTP_TIMEOUT msecs_to_jiffies(10)
+#define LAN966X_SKB_CB(skb) \
+ ((struct lan966x_skb_cb *)((skb)->cb))
+
struct lan966x {
struct device *dev;
@@ -134,7 +144,9 @@ struct lan966x {
bool ptp;
struct lan966x_phc phc[LAN966X_PHC_COUNT];
spinlock_t ptp_clock_lock; /* lock for phc */
+ spinlock_t ptp_ts_id_lock; /* lock for ts_id */
struct mutex ptp_lock; /* lock for ptp interface state */
+ u16 ptp_skbs;
};
struct lan966x_port_config {
@@ -166,6 +178,8 @@ struct lan966x_port {
struct fwnode_handle *fwnode;
u8 ptp_cmd;
+ u16 ts_id;
+ struct sk_buff_head tx_skbs;
};
extern const struct phylink_mac_ops lan966x_phylink_mac_ops;
@@ -256,6 +270,12 @@ int lan966x_ptp_init(struct lan966x *lan966x);
void lan966x_ptp_deinit(struct lan966x *lan966x);
int lan966x_ptp_hwtstamp_set(struct lan966x_port *port, struct ifreq *ifr);
int lan966x_ptp_hwtstamp_get(struct lan966x_port *port, struct ifreq *ifr);
+void lan966x_ptp_rxtstamp(struct lan966x *lan966x, struct sk_buff *skb,
+ u64 timestamp);
+int lan966x_ptp_txtstamp_request(struct lan966x_port *port,
+ struct sk_buff *skb);
+void lan966x_ptp_txtstamp_release(struct lan966x_port *port,
+ struct sk_buff *skb);
static inline void __iomem *lan_addr(void __iomem *base[],
int id, int tinst, int tcnt,
diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_ptp.c b/drivers/net/ethernet/microchip/lan966x/lan966x_ptp.c
index 9ff4d3fca5a1..ba65604aef48 100644
--- a/drivers/net/ethernet/microchip/lan966x/lan966x_ptp.c
+++ b/drivers/net/ethernet/microchip/lan966x/lan966x_ptp.c
@@ -119,6 +119,103 @@ int lan966x_ptp_hwtstamp_get(struct lan966x_port *port, struct ifreq *ifr)
sizeof(phc->hwtstamp_config)) ? -EFAULT : 0;
}
+static int lan966x_ptp_classify(struct lan966x_port *port, struct sk_buff *skb)
+{
+ struct ptp_header *header;
+ u8 msgtype;
+ int type;
+
+ if (port->ptp_cmd == IFH_REW_OP_NOOP)
+ return IFH_REW_OP_NOOP;
+
+ type = ptp_classify_raw(skb);
+ if (type == PTP_CLASS_NONE)
+ return IFH_REW_OP_NOOP;
+
+ header = ptp_parse_header(skb, type);
+ if (!header)
+ return IFH_REW_OP_NOOP;
+
+ if (port->ptp_cmd == IFH_REW_OP_TWO_STEP_PTP)
+ return IFH_REW_OP_TWO_STEP_PTP;
+
+ /* If it is sync and run 1 step then set the correct operation,
+ * otherwise run as 2 step
+ */
+ msgtype = ptp_get_msgtype(header, type);
+ if ((msgtype & 0xf) == 0)
+ return IFH_REW_OP_ONE_STEP_PTP;
+
+ return IFH_REW_OP_TWO_STEP_PTP;
+}
+
+static void lan966x_ptp_txtstamp_old_release(struct lan966x_port *port)
+{
+ struct sk_buff *skb, *skb_tmp;
+ unsigned long flags;
+
+ spin_lock_irqsave(&port->tx_skbs.lock, flags);
+ skb_queue_walk_safe(&port->tx_skbs, skb, skb_tmp) {
+ if time_after(LAN966X_SKB_CB(skb)->jiffies + LAN966X_PTP_TIMEOUT,
+ jiffies)
+ break;
+
+ __skb_unlink(skb, &port->tx_skbs);
+ dev_kfree_skb_any(skb);
+ }
+ spin_unlock_irqrestore(&port->tx_skbs.lock, flags);
+}
+
+int lan966x_ptp_txtstamp_request(struct lan966x_port *port,
+ struct sk_buff *skb)
+{
+ struct lan966x *lan966x = port->lan966x;
+ unsigned long flags;
+ u8 rew_op;
+
+ rew_op = lan966x_ptp_classify(port, skb);
+ LAN966X_SKB_CB(skb)->rew_op = rew_op;
+
+ if (rew_op != IFH_REW_OP_TWO_STEP_PTP)
+ return 0;
+
+ lan966x_ptp_txtstamp_old_release(port);
+
+ spin_lock_irqsave(&lan966x->ptp_ts_id_lock, flags);
+ if (lan966x->ptp_skbs == LAN966X_MAX_PTP_ID) {
+ spin_unlock_irqrestore(&lan966x->ptp_ts_id_lock, flags);
+ return -EBUSY;
+ }
+
+ skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
+
+ skb_queue_tail(&port->tx_skbs, skb);
+ LAN966X_SKB_CB(skb)->ts_id = port->ts_id;
+ LAN966X_SKB_CB(skb)->jiffies = jiffies;
+
+ lan966x->ptp_skbs++;
+ port->ts_id++;
+ if (port->ts_id == LAN966X_MAX_PTP_ID)
+ port->ts_id = 0;
+
+ spin_unlock_irqrestore(&lan966x->ptp_ts_id_lock, flags);
+
+ return 0;
+}
+
+void lan966x_ptp_txtstamp_release(struct lan966x_port *port,
+ struct sk_buff *skb)
+{
+ struct lan966x *lan966x = port->lan966x;
+ unsigned long flags;
+
+ spin_lock_irqsave(&lan966x->ptp_ts_id_lock, flags);
+ port->ts_id--;
+ lan966x->ptp_skbs--;
+ skb_unlink(skb, &port->tx_skbs);
+ spin_unlock_irqrestore(&lan966x->ptp_ts_id_lock, flags);
+}
+
static int lan966x_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
{
struct lan966x_phc *phc = container_of(ptp, struct lan966x_phc, info);
@@ -324,6 +421,7 @@ static int lan966x_ptp_phc_init(struct lan966x *lan966x,
int lan966x_ptp_init(struct lan966x *lan966x)
{
u64 tod_adj = lan966x_ptp_get_nominal_value();
+ struct lan966x_port *port;
int err, i;
if (!lan966x->ptp)
@@ -336,6 +434,7 @@ int lan966x_ptp_init(struct lan966x *lan966x)
}
spin_lock_init(&lan966x->ptp_clock_lock);
+ spin_lock_init(&lan966x->ptp_ts_id_lock);
mutex_init(&lan966x->ptp_lock);
/* Disable master counters */
@@ -360,13 +459,55 @@ int lan966x_ptp_init(struct lan966x *lan966x)
/* Enable master counters */
lan_wr(PTP_DOM_CFG_ENA_SET(0x7), lan966x, PTP_DOM_CFG);
+ for (i = 0; i < lan966x->num_phys_ports; i++) {
+ port = lan966x->ports[i];
+ if (!port)
+ continue;
+
+ skb_queue_head_init(&port->tx_skbs);
+ }
+
return 0;
}
void lan966x_ptp_deinit(struct lan966x *lan966x)
{
+ struct lan966x_port *port;
int i;
+ for (i = 0; i < lan966x->num_phys_ports; i++) {
+ port = lan966x->ports[i];
+ if (!port)
+ continue;
+
+ skb_queue_purge(&port->tx_skbs);
+ }
+
for (i = 0; i < LAN966X_PHC_COUNT; ++i)
ptp_clock_unregister(lan966x->phc[i].clock);
}
+
+void lan966x_ptp_rxtstamp(struct lan966x *lan966x, struct sk_buff *skb,
+ u64 timestamp)
+{
+ struct skb_shared_hwtstamps *shhwtstamps;
+ struct lan966x_phc *phc;
+ struct timespec64 ts;
+ u64 full_ts_in_ns;
+
+ if (!lan966x->ptp)
+ return;
+
+ phc = &lan966x->phc[LAN966X_PHC_PORT];
+ lan966x_ptp_gettime64(&phc->info, &ts);
+
+ /* Drop the sub-ns precision */
+ timestamp = timestamp >> 2;
+ if (ts.tv_nsec < timestamp)
+ ts.tv_sec--;
+ ts.tv_nsec = timestamp;
+ full_ts_in_ns = ktime_set(ts.tv_sec, ts.tv_nsec);
+
+ shhwtstamps = skb_hwtstamps(skb);
+ shhwtstamps->hwtstamp = full_ts_in_ns;
+}
--
2.33.0
^ permalink raw reply related
* [PATCH net-next 4/7] net: lan966x: Implement SIOCSHWTSTAMP and SIOCGHWTSTAMP
From: Horatiu Vultur @ 2022-01-27 10:23 UTC (permalink / raw)
To: netdev, devicetree, linux-kernel
Cc: davem, kuba, robh+dt, UNGLinuxDriver, linux, richardcochran,
f.fainelli, vivien.didelot, vladimir.oltean, andrew,
Horatiu Vultur
In-Reply-To: <20220127102333.987195-1-horatiu.vultur@microchip.com>
Implement the ioctl callbacks SIOCSHWTSTAMP and SIOCGHWTSTAMP to allow
to configure the ports to enable/disable timestamping. The HW is capable
to run both 1-step timestamping and 2-step timestamping.
Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com>
---
.../ethernet/microchip/lan966x/lan966x_main.c | 18 ++++
.../ethernet/microchip/lan966x/lan966x_main.h | 9 ++
.../ethernet/microchip/lan966x/lan966x_ptp.c | 85 +++++++++++++++++++
3 files changed, 112 insertions(+)
diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_main.c b/drivers/net/ethernet/microchip/lan966x/lan966x_main.c
index ee3505318c5c..c62615b9d101 100644
--- a/drivers/net/ethernet/microchip/lan966x/lan966x_main.c
+++ b/drivers/net/ethernet/microchip/lan966x/lan966x_main.c
@@ -351,6 +351,23 @@ static int lan966x_port_get_parent_id(struct net_device *dev,
return 0;
}
+static int lan966x_port_ioctl(struct net_device *dev, struct ifreq *ifr,
+ int cmd)
+{
+ struct lan966x_port *port = netdev_priv(dev);
+
+ if (!phy_has_hwtstamp(dev->phydev) && port->lan966x->ptp) {
+ switch (cmd) {
+ case SIOCSHWTSTAMP:
+ return lan966x_ptp_hwtstamp_set(port, ifr);
+ case SIOCGHWTSTAMP:
+ return lan966x_ptp_hwtstamp_get(port, ifr);
+ }
+ }
+
+ return phy_mii_ioctl(dev->phydev, ifr, cmd);
+}
+
static const struct net_device_ops lan966x_port_netdev_ops = {
.ndo_open = lan966x_port_open,
.ndo_stop = lan966x_port_stop,
@@ -361,6 +378,7 @@ static const struct net_device_ops lan966x_port_netdev_ops = {
.ndo_get_stats64 = lan966x_stats_get,
.ndo_set_mac_address = lan966x_port_set_mac_address,
.ndo_get_port_parent_id = lan966x_port_get_parent_id,
+ .ndo_eth_ioctl = lan966x_port_ioctl,
};
bool lan966x_netdevice_check(const struct net_device *dev)
diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_main.h b/drivers/net/ethernet/microchip/lan966x/lan966x_main.h
index c77a91aa24e7..55fa5e56b8d1 100644
--- a/drivers/net/ethernet/microchip/lan966x/lan966x_main.h
+++ b/drivers/net/ethernet/microchip/lan966x/lan966x_main.h
@@ -54,6 +54,10 @@
#define LAN966X_PHC_COUNT 3
#define LAN966X_PHC_PORT 0
+#define IFH_REW_OP_NOOP 0x0
+#define IFH_REW_OP_ONE_STEP_PTP 0x3
+#define IFH_REW_OP_TWO_STEP_PTP 0x4
+
/* MAC table entry types.
* ENTRYTYPE_NORMAL is subject to aging.
* ENTRYTYPE_LOCKED is not subject to aging.
@@ -130,6 +134,7 @@ struct lan966x {
bool ptp;
struct lan966x_phc phc[LAN966X_PHC_COUNT];
spinlock_t ptp_clock_lock; /* lock for phc */
+ struct mutex ptp_lock; /* lock for ptp interface state */
};
struct lan966x_port_config {
@@ -159,6 +164,8 @@ struct lan966x_port {
struct phylink *phylink;
struct phy *serdes;
struct fwnode_handle *fwnode;
+
+ u8 ptp_cmd;
};
extern const struct phylink_mac_ops lan966x_phylink_mac_ops;
@@ -247,6 +254,8 @@ void lan966x_mdb_write_entries(struct lan966x *lan966x, u16 vid);
int lan966x_ptp_init(struct lan966x *lan966x);
void lan966x_ptp_deinit(struct lan966x *lan966x);
+int lan966x_ptp_hwtstamp_set(struct lan966x_port *port, struct ifreq *ifr);
+int lan966x_ptp_hwtstamp_get(struct lan966x_port *port, struct ifreq *ifr);
static inline void __iomem *lan_addr(void __iomem *base[],
int id, int tinst, int tcnt,
diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_ptp.c b/drivers/net/ethernet/microchip/lan966x/lan966x_ptp.c
index 69d8f43e2b1b..9ff4d3fca5a1 100644
--- a/drivers/net/ethernet/microchip/lan966x/lan966x_ptp.c
+++ b/drivers/net/ethernet/microchip/lan966x/lan966x_ptp.c
@@ -35,6 +35,90 @@ static u64 lan966x_ptp_get_nominal_value(void)
return res;
}
+int lan966x_ptp_hwtstamp_set(struct lan966x_port *port, struct ifreq *ifr)
+{
+ struct lan966x *lan966x = port->lan966x;
+ bool l2 = false, l4 = false;
+ struct hwtstamp_config cfg;
+ struct lan966x_phc *phc;
+
+ /* For now don't allow to run ptp on ports that are part of a bridge,
+ * because in case of transparent clock the HW will still forward the
+ * frames, so there would be duplicate frames
+ */
+ if (lan966x->bridge_mask & BIT(port->chip_port))
+ return -EINVAL;
+
+ if (copy_from_user(&cfg, ifr->ifr_data, sizeof(cfg)))
+ return -EFAULT;
+
+ switch (cfg.tx_type) {
+ case HWTSTAMP_TX_ON:
+ port->ptp_cmd = IFH_REW_OP_TWO_STEP_PTP;
+ break;
+ case HWTSTAMP_TX_ONESTEP_SYNC:
+ port->ptp_cmd = IFH_REW_OP_ONE_STEP_PTP;
+ break;
+ case HWTSTAMP_TX_OFF:
+ port->ptp_cmd = IFH_REW_OP_NOOP;
+ break;
+ default:
+ return -ERANGE;
+ }
+
+ mutex_lock(&lan966x->ptp_lock);
+
+ switch (cfg.rx_filter) {
+ case HWTSTAMP_FILTER_NONE:
+ break;
+ case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
+ case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
+ case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
+ l4 = true;
+ break;
+ case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
+ case HWTSTAMP_FILTER_PTP_V2_L2_SYNC:
+ case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ:
+ l2 = true;
+ break;
+ case HWTSTAMP_FILTER_PTP_V2_EVENT:
+ case HWTSTAMP_FILTER_PTP_V2_SYNC:
+ case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
+ l2 = true;
+ l4 = true;
+ break;
+ default:
+ mutex_unlock(&lan966x->ptp_lock);
+ return -ERANGE;
+ }
+
+ if (l2 && l4)
+ cfg.rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT;
+ else if (l2)
+ cfg.rx_filter = HWTSTAMP_FILTER_PTP_V2_L2_EVENT;
+ else if (l4)
+ cfg.rx_filter = HWTSTAMP_FILTER_PTP_V2_L4_EVENT;
+ else
+ cfg.rx_filter = HWTSTAMP_FILTER_NONE;
+
+ /* Commit back the result & save it */
+ phc = &lan966x->phc[LAN966X_PHC_PORT];
+ memcpy(&phc->hwtstamp_config, &cfg, sizeof(cfg));
+ mutex_unlock(&lan966x->ptp_lock);
+
+ return copy_to_user(ifr->ifr_data, &cfg, sizeof(cfg)) ? -EFAULT : 0;
+}
+
+int lan966x_ptp_hwtstamp_get(struct lan966x_port *port, struct ifreq *ifr)
+{
+ struct lan966x *lan966x = port->lan966x;
+ struct lan966x_phc *phc;
+
+ phc = &lan966x->phc[LAN966X_PHC_PORT];
+ return copy_to_user(ifr->ifr_data, &phc->hwtstamp_config,
+ sizeof(phc->hwtstamp_config)) ? -EFAULT : 0;
+}
+
static int lan966x_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
{
struct lan966x_phc *phc = container_of(ptp, struct lan966x_phc, info);
@@ -252,6 +336,7 @@ int lan966x_ptp_init(struct lan966x *lan966x)
}
spin_lock_init(&lan966x->ptp_clock_lock);
+ mutex_init(&lan966x->ptp_lock);
/* Disable master counters */
lan_wr(PTP_DOM_CFG_ENA_SET(0), lan966x, PTP_DOM_CFG);
--
2.33.0
^ permalink raw reply related
* [PATCH net-next 2/7] net: lan966x: Add registers that are use for ptp functionality
From: Horatiu Vultur @ 2022-01-27 10:23 UTC (permalink / raw)
To: netdev, devicetree, linux-kernel
Cc: davem, kuba, robh+dt, UNGLinuxDriver, linux, richardcochran,
f.fainelli, vivien.didelot, vladimir.oltean, andrew,
Horatiu Vultur
In-Reply-To: <20220127102333.987195-1-horatiu.vultur@microchip.com>
This patch adds the registers that will be used to configure the PHC in
the HW.
Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com>
---
.../ethernet/microchip/lan966x/lan966x_main.c | 1 +
.../ethernet/microchip/lan966x/lan966x_regs.h | 103 ++++++++++++++++++
2 files changed, 104 insertions(+)
diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_main.c b/drivers/net/ethernet/microchip/lan966x/lan966x_main.c
index 1f60fd125a1d..2853e8f7fb39 100644
--- a/drivers/net/ethernet/microchip/lan966x/lan966x_main.c
+++ b/drivers/net/ethernet/microchip/lan966x/lan966x_main.c
@@ -44,6 +44,7 @@ static const struct lan966x_main_io_resource lan966x_main_iomap[] = {
{ TARGET_ORG, 0, 1 }, /* 0xe2000000 */
{ TARGET_GCB, 0x4000, 1 }, /* 0xe2004000 */
{ TARGET_QS, 0x8000, 1 }, /* 0xe2008000 */
+ { TARGET_PTP, 0xc000, 1 }, /* 0xe200c000 */
{ TARGET_CHIP_TOP, 0x10000, 1 }, /* 0xe2010000 */
{ TARGET_REW, 0x14000, 1 }, /* 0xe2014000 */
{ TARGET_SYS, 0x28000, 1 }, /* 0xe2028000 */
diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_regs.h b/drivers/net/ethernet/microchip/lan966x/lan966x_regs.h
index 797560172aca..37a5d7e63cb6 100644
--- a/drivers/net/ethernet/microchip/lan966x/lan966x_regs.h
+++ b/drivers/net/ethernet/microchip/lan966x/lan966x_regs.h
@@ -19,6 +19,7 @@ enum lan966x_target {
TARGET_DEV = 13,
TARGET_GCB = 27,
TARGET_ORG = 36,
+ TARGET_PTP = 41,
TARGET_QS = 42,
TARGET_QSYS = 46,
TARGET_REW = 47,
@@ -559,6 +560,108 @@ enum lan966x_target {
#define DEV_PCS1G_STICKY_LINK_DOWN_STICKY_GET(x)\
FIELD_GET(DEV_PCS1G_STICKY_LINK_DOWN_STICKY, x)
+/* PTP:PTP_CFG:PTP_DOM_CFG */
+#define PTP_DOM_CFG __REG(TARGET_PTP, 0, 1, 512, 0, 1, 16, 12, 0, 1, 4)
+
+#define PTP_DOM_CFG_ENA GENMASK(11, 9)
+#define PTP_DOM_CFG_ENA_SET(x)\
+ FIELD_PREP(PTP_DOM_CFG_ENA, x)
+#define PTP_DOM_CFG_ENA_GET(x)\
+ FIELD_GET(PTP_DOM_CFG_ENA, x)
+
+#define PTP_DOM_CFG_CLKCFG_DIS GENMASK(2, 0)
+#define PTP_DOM_CFG_CLKCFG_DIS_SET(x)\
+ FIELD_PREP(PTP_DOM_CFG_CLKCFG_DIS, x)
+#define PTP_DOM_CFG_CLKCFG_DIS_GET(x)\
+ FIELD_GET(PTP_DOM_CFG_CLKCFG_DIS, x)
+
+/* PTP:PTP_TOD_DOMAINS:CLK_PER_CFG */
+#define PTP_CLK_PER_CFG(g, r) __REG(TARGET_PTP, 0, 1, 528, g, 3, 28, 0, r, 2, 4)
+
+/* PTP:PTP_PINS:PTP_PIN_CFG */
+#define PTP_PIN_CFG(g) __REG(TARGET_PTP, 0, 1, 0, g, 8, 64, 0, 0, 1, 4)
+
+#define PTP_PIN_CFG_PIN_ACTION GENMASK(29, 27)
+#define PTP_PIN_CFG_PIN_ACTION_SET(x)\
+ FIELD_PREP(PTP_PIN_CFG_PIN_ACTION, x)
+#define PTP_PIN_CFG_PIN_ACTION_GET(x)\
+ FIELD_GET(PTP_PIN_CFG_PIN_ACTION, x)
+
+#define PTP_PIN_CFG_PIN_SYNC GENMASK(26, 25)
+#define PTP_PIN_CFG_PIN_SYNC_SET(x)\
+ FIELD_PREP(PTP_PIN_CFG_PIN_SYNC, x)
+#define PTP_PIN_CFG_PIN_SYNC_GET(x)\
+ FIELD_GET(PTP_PIN_CFG_PIN_SYNC, x)
+
+#define PTP_PIN_CFG_PIN_DOM GENMASK(17, 16)
+#define PTP_PIN_CFG_PIN_DOM_SET(x)\
+ FIELD_PREP(PTP_PIN_CFG_PIN_DOM, x)
+#define PTP_PIN_CFG_PIN_DOM_GET(x)\
+ FIELD_GET(PTP_PIN_CFG_PIN_DOM, x)
+
+/* PTP:PTP_PINS:PTP_TOD_SEC_MSB */
+#define PTP_TOD_SEC_MSB(g) __REG(TARGET_PTP, 0, 1, 0, g, 8, 64, 4, 0, 1, 4)
+
+#define PTP_TOD_SEC_MSB_TOD_SEC_MSB GENMASK(15, 0)
+#define PTP_TOD_SEC_MSB_TOD_SEC_MSB_SET(x)\
+ FIELD_PREP(PTP_TOD_SEC_MSB_TOD_SEC_MSB, x)
+#define PTP_TOD_SEC_MSB_TOD_SEC_MSB_GET(x)\
+ FIELD_GET(PTP_TOD_SEC_MSB_TOD_SEC_MSB, x)
+
+/* PTP:PTP_PINS:PTP_TOD_SEC_LSB */
+#define PTP_TOD_SEC_LSB(g) __REG(TARGET_PTP, 0, 1, 0, g, 8, 64, 8, 0, 1, 4)
+
+/* PTP:PTP_PINS:PTP_TOD_NSEC */
+#define PTP_TOD_NSEC(g) __REG(TARGET_PTP, 0, 1, 0, g, 8, 64, 12, 0, 1, 4)
+
+#define PTP_TOD_NSEC_TOD_NSEC GENMASK(29, 0)
+#define PTP_TOD_NSEC_TOD_NSEC_SET(x)\
+ FIELD_PREP(PTP_TOD_NSEC_TOD_NSEC, x)
+#define PTP_TOD_NSEC_TOD_NSEC_GET(x)\
+ FIELD_GET(PTP_TOD_NSEC_TOD_NSEC, x)
+
+/* PTP:PTP_TS_FIFO:PTP_TWOSTEP_CTRL */
+#define PTP_TWOSTEP_CTRL __REG(TARGET_PTP, 0, 1, 612, 0, 1, 12, 0, 0, 1, 4)
+
+#define PTP_TWOSTEP_CTRL_NXT BIT(11)
+#define PTP_TWOSTEP_CTRL_NXT_SET(x)\
+ FIELD_PREP(PTP_TWOSTEP_CTRL_NXT, x)
+#define PTP_TWOSTEP_CTRL_NXT_GET(x)\
+ FIELD_GET(PTP_TWOSTEP_CTRL_NXT, x)
+
+#define PTP_TWOSTEP_CTRL_VLD BIT(10)
+#define PTP_TWOSTEP_CTRL_VLD_SET(x)\
+ FIELD_PREP(PTP_TWOSTEP_CTRL_VLD, x)
+#define PTP_TWOSTEP_CTRL_VLD_GET(x)\
+ FIELD_GET(PTP_TWOSTEP_CTRL_VLD, x)
+
+#define PTP_TWOSTEP_CTRL_STAMP_TX BIT(9)
+#define PTP_TWOSTEP_CTRL_STAMP_TX_SET(x)\
+ FIELD_PREP(PTP_TWOSTEP_CTRL_STAMP_TX, x)
+#define PTP_TWOSTEP_CTRL_STAMP_TX_GET(x)\
+ FIELD_GET(PTP_TWOSTEP_CTRL_STAMP_TX, x)
+
+#define PTP_TWOSTEP_CTRL_STAMP_PORT GENMASK(8, 1)
+#define PTP_TWOSTEP_CTRL_STAMP_PORT_SET(x)\
+ FIELD_PREP(PTP_TWOSTEP_CTRL_STAMP_PORT, x)
+#define PTP_TWOSTEP_CTRL_STAMP_PORT_GET(x)\
+ FIELD_GET(PTP_TWOSTEP_CTRL_STAMP_PORT, x)
+
+#define PTP_TWOSTEP_CTRL_OVFL BIT(0)
+#define PTP_TWOSTEP_CTRL_OVFL_SET(x)\
+ FIELD_PREP(PTP_TWOSTEP_CTRL_OVFL, x)
+#define PTP_TWOSTEP_CTRL_OVFL_GET(x)\
+ FIELD_GET(PTP_TWOSTEP_CTRL_OVFL, x)
+
+/* PTP:PTP_TS_FIFO:PTP_TWOSTEP_STAMP */
+#define PTP_TWOSTEP_STAMP __REG(TARGET_PTP, 0, 1, 612, 0, 1, 12, 4, 0, 1, 4)
+
+#define PTP_TWOSTEP_STAMP_STAMP_NSEC GENMASK(31, 2)
+#define PTP_TWOSTEP_STAMP_STAMP_NSEC_SET(x)\
+ FIELD_PREP(PTP_TWOSTEP_STAMP_STAMP_NSEC, x)
+#define PTP_TWOSTEP_STAMP_STAMP_NSEC_GET(x)\
+ FIELD_GET(PTP_TWOSTEP_STAMP_STAMP_NSEC, x)
+
/* DEVCPU_QS:XTR:XTR_GRP_CFG */
#define QS_XTR_GRP_CFG(r) __REG(TARGET_QS, 0, 1, 0, 0, 1, 36, 0, r, 2, 4)
--
2.33.0
^ permalink raw reply related
* [PATCH net-next 1/7] dt-bindings: net: lan966x: Extend with the ptp interrupt
From: Horatiu Vultur @ 2022-01-27 10:23 UTC (permalink / raw)
To: netdev, devicetree, linux-kernel
Cc: davem, kuba, robh+dt, UNGLinuxDriver, linux, richardcochran,
f.fainelli, vivien.didelot, vladimir.oltean, andrew,
Horatiu Vultur
In-Reply-To: <20220127102333.987195-1-horatiu.vultur@microchip.com>
Extend dt-bindings for lan966x with ptp interrupt. This is generated
when doing 2-step timestamping and the timestamp can be read from the
FIFO.
Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com>
---
.../devicetree/bindings/net/microchip,lan966x-switch.yaml | 2 ++
1 file changed, 2 insertions(+)
diff --git a/Documentation/devicetree/bindings/net/microchip,lan966x-switch.yaml b/Documentation/devicetree/bindings/net/microchip,lan966x-switch.yaml
index e79e4e166ad8..13812768b923 100644
--- a/Documentation/devicetree/bindings/net/microchip,lan966x-switch.yaml
+++ b/Documentation/devicetree/bindings/net/microchip,lan966x-switch.yaml
@@ -38,6 +38,7 @@ properties:
- description: register based extraction
- description: frame dma based extraction
- description: analyzer interrupt
+ - description: ptp interrupt
interrupt-names:
minItems: 1
@@ -45,6 +46,7 @@ properties:
- const: xtr
- const: fdma
- const: ana
+ - const: ptp
resets:
items:
--
2.33.0
^ permalink raw reply related
* [PATCH net-next 0/7] net: lan966x: Add PTP Hardward Clock support
From: Horatiu Vultur @ 2022-01-27 10:23 UTC (permalink / raw)
To: netdev, devicetree, linux-kernel
Cc: davem, kuba, robh+dt, UNGLinuxDriver, linux, richardcochran,
f.fainelli, vivien.didelot, vladimir.oltean, andrew,
Horatiu Vultur
This patch series adds support for PTP Hardware Clock (PHC) for lan966x.
The switch supports both PTP 1-step and 2-step modes.
Horatiu Vultur (7):
dt-bindings: net: lan966x: Extend with the ptp interrupt
net: lan966x: Add registers that are use for ptp functionality
net: lan966x: Add support for ptp clocks
net: lan966x: Implement SIOCSHWTSTAMP and SIOCGHWTSTAMP
net: lan966x: Update extraction/injection for timestamping
net: lan966x: Add support for ptp interrupts
net: lan966x: Implement get_ts_info
.../net/microchip,lan966x-switch.yaml | 2 +
.../net/ethernet/microchip/lan966x/Makefile | 3 +-
.../microchip/lan966x/lan966x_ethtool.c | 36 +
.../ethernet/microchip/lan966x/lan966x_main.c | 89 ++-
.../ethernet/microchip/lan966x/lan966x_main.h | 51 ++
.../ethernet/microchip/lan966x/lan966x_ptp.c | 630 ++++++++++++++++++
.../ethernet/microchip/lan966x/lan966x_regs.h | 103 +++
7 files changed, 908 insertions(+), 6 deletions(-)
create mode 100644 drivers/net/ethernet/microchip/lan966x/lan966x_ptp.c
--
2.33.0
^ permalink raw reply
* Re: [PATCH v3 6/6] RISC-V: Do not use cpumask data structure for hartid bitmap
From: Ron Economos @ 2022-01-27 9:56 UTC (permalink / raw)
To: Atish Patra, Geert Uytterhoeven
Cc: Jessica Clarke, Atish Patra, Linux Kernel Mailing List,
Anup Patel, Albert Ou, Damien Le Moal, devicetree, Jisheng Zhang,
Krzysztof Kozlowski, linux-riscv, Palmer Dabbelt, Paul Walmsley,
Rob Herring
In-Reply-To: <CAOnJCU+AVS5Js4ZXmUubTqwU5Ye-9_z8onEE1mwhvCsOXchFBg@mail.gmail.com>
On 1/26/22 17:01, Atish Patra wrote:
> On Wed, Jan 26, 2022 at 1:10 AM Geert Uytterhoeven <geert@linux-m68k.org> wrote:
>> Hi Atish,
>>
>> On Wed, Jan 26, 2022 at 9:28 AM Geert Uytterhoeven <geert@linux-m68k.org> wrote:
>>> On Wed, Jan 26, 2022 at 3:21 AM Atish Patra <atishp@atishpatra.org> wrote:
>>>> On Tue, Jan 25, 2022 at 2:26 PM Jessica Clarke <jrtc27@jrtc27.com> wrote:
>>>>> On 20 Jan 2022, at 09:09, Atish Patra <atishp@rivosinc.com> wrote:
>>>>>> Currently, SBI APIs accept a hartmask that is generated from struct
>>>>>> cpumask. Cpumask data structure can hold upto NR_CPUs value. Thus, it
>>>>>> is not the correct data structure for hartids as it can be higher
>>>>>> than NR_CPUs for platforms with sparse or discontguous hartids.
>>>>>>
>>>>>> Remove all association between hartid mask and struct cpumask.
>>>>>>
>>>>>> Reviewed-by: Anup Patel <anup@brainfault.org> (For Linux RISC-V changes)
>>>>>> Acked-by: Anup Patel <anup@brainfault.org> (For KVM RISC-V changes)
>>>>>> Signed-off-by: Atish Patra <atishp@rivosinc.com>
>>>> I am yet to reproduce it on my end.
>>>> @Geert Uytterhoeven: can you please try the below diff on your end.
>>> Unfortunately it doesn't fix the issue for me.
>>>
>>> /me debugging...
>> Found it: after this commit, the SBI_EXT_RFENCE_REMOTE_FENCE_I and
>> SBI_EXT_RFENCE_REMOTE_SFENCE_VMA ecalls are now called with
>> hmask = 0x8000000000000001 and hbase = 1 instead of hmask = 3 and
>> hbase = 0.
>>
>> cpuid 1 maps to hartid 0
>> cpuid 0 maps to hartid 1
>>
>> __sbi_rfence_v02:364: cpuid 1 hartid 0
>> __sbi_rfence_v02:377: hartid 0 hbase 1
>> hmask |= 1UL << (hartid - hbase);
>>
>> oops
>>
>> __sbi_rfence_v02_call:303: SBI_EXT_RFENCE_REMOTE_FENCE_I hmask
>> 8000000000000001 hbase 1
>>
> Ahh yes. hmask will be incorrect if the bootcpu(cpu 0) is a higher
> hartid and it is trying to do a remote tlb flush/IPI
> to lower the hartid. We should generate the hartid array before the loop.
>
> Can you try this diff ? It seems to work for me during multiple boot
> cycle on the unleashed.
>
> You can find the patch here as well
> https://github.com/atishp04/linux/commits/v5.17-rc1
>
> --------------------------------------------------------------------------------------------------------------------------------
> diff --git a/arch/riscv/kernel/sbi.c b/arch/riscv/kernel/sbi.c
> index f72527fcb347..4ebeb5813edc 100644
> --- a/arch/riscv/kernel/sbi.c
> +++ b/arch/riscv/kernel/sbi.c
> @@ -8,6 +8,8 @@
> #include <linux/init.h>
> #include <linux/pm.h>
> #include <linux/reboot.h>
> +#include <linux/sort.h>
> +
> #include <asm/sbi.h>
> #include <asm/smp.h>
>
> @@ -85,7 +87,7 @@ static unsigned long
> __sbi_v01_cpumask_to_hartmask(const struct cpumask *cpu_mas
> pr_warn("Unable to send any request to hartid > BITS_PER_LONG for
> SBI v0.1\n");
> break;
> }
> - hmask |= 1 << hartid;
> + hmask |= 1UL << hartid;
> }
>
> return hmask;
> @@ -160,7 +162,7 @@ static int __sbi_send_ipi_v01(const struct cpumask
> *cpu_mask)
> {
> unsigned long hart_mask;
>
> - if (!cpu_mask)
> + if (!cpu_mask || cpumask_empty(cpu_mask))
> cpu_mask = cpu_online_mask;
> hart_mask = __sbi_v01_cpumask_to_hartmask(cpu_mask);
>
> @@ -176,7 +178,7 @@ static int __sbi_rfence_v01(int fid, const struct
> cpumask *cpu_mask,
> int result = 0;
> unsigned long hart_mask;
>
> - if (!cpu_mask)
> + if (!cpu_mask || cpumask_empty(cpu_mask))
> cpu_mask = cpu_online_mask;
> hart_mask = __sbi_v01_cpumask_to_hartmask(cpu_mask);
>
> @@ -236,6 +238,18 @@ static int __sbi_rfence_v01(int fid, const struct
> cpumask *cpu_mask,
> static void sbi_set_power_off(void) {}
> #endif /* CONFIG_RISCV_SBI_V01 */
>
> +static int cmp_ulong(const void *A, const void *B)
> +{
> + const unsigned long *a = A, *b = B;
> +
> + if (*a < *b)
> + return -1;
> + else if (*a > *b)
> + return 1;
> + else
> + return 0;
> +}
> +
> static void __sbi_set_timer_v02(uint64_t stime_value)
> {
> #if __riscv_xlen == 32
> @@ -251,13 +265,22 @@ static int __sbi_send_ipi_v02(const struct
> cpumask *cpu_mask)
> {
> unsigned long hartid, cpuid, hmask = 0, hbase = 0;
> struct sbiret ret = {0};
> - int result;
> + int result, index = 0, max_index = 0;
> + unsigned long hartid_arr[NR_CPUS] = {0};
>
> - if (!cpu_mask)
> + if (!cpu_mask || cpumask_empty(cpu_mask))
> cpu_mask = cpu_online_mask;
>
> for_each_cpu(cpuid, cpu_mask) {
> hartid = cpuid_to_hartid_map(cpuid);
> + hartid_arr[index] = hartid;
> + index++;
> + }
> +
> + max_index = index;
> + sort(hartid_arr, max_index, sizeof(unsigned long), cmp_ulong, NULL);
> + for (index = 0; index < max_index; index++) {
> + hartid = hartid_arr[index];
> if (hmask && ((hbase + BITS_PER_LONG) <= hartid)) {
> ret = sbi_ecall(SBI_EXT_IPI, SBI_EXT_IPI_SEND_IPI,
> hmask, hbase, 0, 0, 0, 0);
> @@ -345,13 +368,21 @@ static int __sbi_rfence_v02(int fid, const
> struct cpumask *cpu_mask,
> unsigned long arg4, unsigned long arg5)
> {
> unsigned long hartid, cpuid, hmask = 0, hbase = 0;
> - int result;
> + int result, index = 0, max_index = 0;
> + unsigned long hartid_arr[NR_CPUS] = {0};
>
> - if (!cpu_mask)
> + if (!cpu_mask || cpumask_empty(cpu_mask))
> cpu_mask = cpu_online_mask;
>
> for_each_cpu(cpuid, cpu_mask) {
> hartid = cpuid_to_hartid_map(cpuid);
> + hartid_arr[index] = hartid;
> + index++;
> + }
> + max_index = index;
> + sort(hartid_arr, max_index, sizeof(unsigned long), cmp_ulong, NULL);
> + for (index = 0; index < max_index; index++) {
> + hartid = hartid_arr[index];
> if (hmask && ((hbase + BITS_PER_LONG) <= hartid)) {
> result = __sbi_rfence_v02_call(fid, hmask, hbase,
> start, size, arg4, arg5);
>
> --------------------------------------------------------------------------------------------------------------------------------
Works good here. No systemd segfaults on Unmatched.
Tested-by: Ron Economos <re@w6rz.net>
^ permalink raw reply
* Re: [PATCH 3/3] arm64: dts: rockchip: add Quartz64-A sdmmc1 node
From: Heiko Stübner @ 2022-01-27 10:15 UTC (permalink / raw)
To: Johan Jonker, Peter Geis
Cc: Rob Herring, devicetree, arm-mail-list,
open list:ARM/Rockchip SoC..., Linux Kernel Mailing List
In-Reply-To: <CAMdYzYrKq==Bs0aonrJBC+W2c4nQ8cUn2dn_Se4WDaRCkT6SYg@mail.gmail.com>
Am Donnerstag, 27. Januar 2022, 10:55:13 CET schrieb Peter Geis:
> On Thu, Jan 27, 2022 at 1:18 AM Johan Jonker <jbx6244@gmail.com> wrote:
> >
> >
> >
> > On 1/27/22 02:00, Peter Geis wrote:
> > > The sdmmc1 node on Quartz64-A supports the optional wifi module from
> > > Pine64.
> > > Add the sdmmc1 node and requisite sdio_pwrseq to enable wifi support on
> > > the Quartz64-A.
> > >
> > > Signed-off-by: Peter Geis <pgwipeout@gmail.com>
> > > ---
> > > .../boot/dts/rockchip/rk3566-quartz64-a.dts | 45 +++++++++++++++++++
> > > 1 file changed, 45 insertions(+)
> > >
> > > diff --git a/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts b/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
> > > index 33c2c18caaa9..1d73ac6557c5 100644
> > > --- a/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
> > > +++ b/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
> > > @@ -91,6 +91,18 @@ simple-audio-card,codec {
> > > };
> > > };
> > >
> > > + sdio_pwrseq: sdio-pwrseq {
> >
> > > + status = "okay";
> >
> > When a node is not previously disabled, then there's no need for "okay".
>
> Thanks, this is here in case an end user wants to easily hack the
> board to use this for other purposes.
but please drop it here as well.
A user "hacking" a devicetree should be able to also just _add_
a status "disabled" :-) .
^ permalink raw reply
* Re: [PATCH] arm64: dts: meson-sm1-odroid: use correct enable-gpio pin for tf-io regulator
From: Neil Armstrong @ 2022-01-27 10:15 UTC (permalink / raw)
To: Lutz Koschorreck, Rob Herring, Kevin Hilman, Jerome Brunet,
Martin Blumenstingl
Cc: devicetree, linux-arm-kernel, linux-amlogic, linux-kernel
In-Reply-To: <20220126234325.GA7363@odroid-VirtualBox>
Hi,
On 27/01/2022 00:43, Lutz Koschorreck wrote:
> The interrupt pin of the external ethernet phy is used, instead of the
> enable-gpio pin of the tf-io regulator. The GPIOE_2 pin is located in
> the gpio_ao bank.
> Using open drain prevents reboot issues.
>
> This causes phy interrupt problems at system startup.
> [ 76.645190] irq 36: nobody cared (try booting with the "irqpoll" option)
> [ 76.649617] CPU: 0 PID: 1416 Comm: irq/36-0.0:00 Not tainted 5.16.0 #2
> [ 76.649629] Hardware name: Hardkernel ODROID-HC4 (DT)
> [ 76.649635] Call trace:
> [ 76.649638] dump_backtrace+0x0/0x1c8
> [ 76.649658] show_stack+0x14/0x60
> [ 76.649667] dump_stack_lvl+0x64/0x7c
> [ 76.649676] dump_stack+0x14/0x2c
> [ 76.649683] __report_bad_irq+0x38/0xe8
> [ 76.649695] note_interrupt+0x220/0x3a0
> [ 76.649704] handle_irq_event_percpu+0x58/0x88
> [ 76.649713] handle_irq_event+0x44/0xd8
> [ 76.649721] handle_fasteoi_irq+0xa8/0x130
> [ 76.649730] generic_handle_domain_irq+0x38/0x58
> [ 76.649738] gic_handle_irq+0x9c/0xb8
> [ 76.649747] call_on_irq_stack+0x28/0x38
> [ 76.649755] do_interrupt_handler+0x7c/0x80
> [ 76.649763] el1_interrupt+0x34/0x80
> [ 76.649772] el1h_64_irq_handler+0x14/0x20
> [ 76.649781] el1h_64_irq+0x74/0x78
> [ 76.649788] irq_finalize_oneshot.part.56+0x68/0xf8
> [ 76.649796] irq_thread_fn+0x5c/0x98
> [ 76.649804] irq_thread+0x13c/0x260
> [ 76.649812] kthread+0x144/0x178
> [ 76.649822] ret_from_fork+0x10/0x20
> [ 76.649830] handlers:
> [ 76.653170] [<0000000025a6cd31>] irq_default_primary_handler threaded [<0000000093580eb7>] phy_interrupt
> [ 76.661256] Disabling IRQ #36
>
> Fixes: 1f80a5cf74a6 ("arm64: dts: meson-sm1-odroid: add missing enable gpio and supply for tf_io regulator")
>
> Signed-off-by: Lutz Koschorreck <theleks@ko-hh.de>
> ---
> arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi b/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi
> index 0bd1e98a0eef..ddb1b345397f 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi
> +++ b/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi
> @@ -48,7 +48,7 @@ tf_io: gpio-regulator-tf_io {
> regulator-max-microvolt = <3300000>;
> vin-supply = <&vcc_5v>;
>
> - enable-gpio = <&gpio GPIOE_2 GPIO_ACTIVE_HIGH>;
> + enable-gpio = <&gpio_ao GPIOE_2 GPIO_OPEN_DRAIN>;
Wow, indeed it's not the right GPIO chip... my bad.
> enable-active-high;
> regulator-always-on;
>
Concerning the GPIO_OPEN_DRAIN, it's right since the line has a pull-up, does it really fix reboot issues ?
Anyway, can you split the changes ? First for gpio_ao, second for GPIO_OPEN_DRAIN ?
Neil
^ permalink raw reply
* Re: [PATCH v2 3/3] drm/panel: Add MIPI DBI compatible SPI driver
From: Maxime Ripard @ 2022-01-27 10:04 UTC (permalink / raw)
To: Noralf Trønnes
Cc: robh+dt, thierry.reding, sam, dave.stevenson, david, devicetree,
dri-devel
In-Reply-To: <20220125175700.37408-4-noralf@tronnes.org>
[-- Attachment #1: Type: text/plain, Size: 6661 bytes --]
On Tue, Jan 25, 2022 at 06:57:00PM +0100, Noralf Trønnes wrote:
> Add a driver that will work with most MIPI DBI compatible SPI panels.
> This avoids adding a driver for every new MIPI DBI compatible controller
> that is to be used by Linux. The 'compatible' Device Tree property with
> a '.bin' suffix will be used to load a firmware file that contains the
> controller configuration.
>
> Example (driver will load sainsmart18.bin):
>
> display@0 {
> compatible = "sainsmart18", "panel-mipi-dbi-spi";
> reg = <0>;
> reset-gpios = <&gpio 25 0>;
> dc-gpios = <&gpio 24 0>;
> };
>
> v2:
> - Drop model property and use compatible instead (Rob)
> - Add wiki entry in MAINTAINERS
>
> Signed-off-by: Noralf Trønnes <noralf@tronnes.org>
> ---
> MAINTAINERS | 8 +
> drivers/gpu/drm/panel/Kconfig | 11 +
> drivers/gpu/drm/panel/Makefile | 1 +
> drivers/gpu/drm/panel/panel-mipi-dbi.c | 394 +++++++++++++++++++++++++
> 4 files changed, 414 insertions(+)
> create mode 100644 drivers/gpu/drm/panel/panel-mipi-dbi.c
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index d03ad8da1f36..8baa98723bdc 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -6047,6 +6047,14 @@ T: git git://anongit.freedesktop.org/drm/drm-misc
> F: Documentation/devicetree/bindings/display/multi-inno,mi0283qt.txt
> F: drivers/gpu/drm/tiny/mi0283qt.c
>
> +DRM DRIVER FOR MIPI DBI compatible panels
> +M: Noralf Trønnes <noralf@tronnes.org>
> +S: Maintained
> +W: https://github.com/notro/panel-mipi-dbi/wiki
> +T: git git://anongit.freedesktop.org/drm/drm-misc
> +F: Documentation/devicetree/bindings/display/panel/panel-mipi-dbi-spi.yaml
> +F: drivers/gpu/drm/panel/panel-mipi-dbi.c
> +
> DRM DRIVER FOR MSM ADRENO GPU
> M: Rob Clark <robdclark@gmail.com>
> M: Sean Paul <sean@poorly.run>
> diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
> index 434c2861bb40..1851cda5f877 100644
> --- a/drivers/gpu/drm/panel/Kconfig
> +++ b/drivers/gpu/drm/panel/Kconfig
> @@ -274,6 +274,17 @@ config DRM_PANEL_LG_LG4573
> Say Y here if you want to enable support for LG4573 RGB panel.
> To compile this driver as a module, choose M here.
>
> +config DRM_PANEL_MIPI_DBI
> + tristate "MIPI DBI compatible panel"
> + depends on SPI
> + depends on BACKLIGHT_CLASS_DEVICE
> + depends on DRM_KMS_HELPER
> + select DRM_KMS_CMA_HELPER
> + select DRM_MIPI_DBI
> + help
> + Say Y here if you want to enable support for MIPI DBI compatible panels.
> + To compile this driver as a module, choose M here.
> +
> config DRM_PANEL_NEC_NL8048HL11
> tristate "NEC NL8048HL11 RGB panel"
> depends on GPIOLIB && OF && SPI
> diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile
> index d99fbbce49d1..a90c30459964 100644
> --- a/drivers/gpu/drm/panel/Makefile
> +++ b/drivers/gpu/drm/panel/Makefile
> @@ -25,6 +25,7 @@ obj-$(CONFIG_DRM_PANEL_LEADTEK_LTK050H3146W) += panel-leadtek-ltk050h3146w.o
> obj-$(CONFIG_DRM_PANEL_LEADTEK_LTK500HD1829) += panel-leadtek-ltk500hd1829.o
> obj-$(CONFIG_DRM_PANEL_LG_LB035Q02) += panel-lg-lb035q02.o
> obj-$(CONFIG_DRM_PANEL_LG_LG4573) += panel-lg-lg4573.o
> +obj-$(CONFIG_DRM_PANEL_MIPI_DBI) += panel-mipi-dbi.o
> obj-$(CONFIG_DRM_PANEL_NEC_NL8048HL11) += panel-nec-nl8048hl11.o
> obj-$(CONFIG_DRM_PANEL_NOVATEK_NT35510) += panel-novatek-nt35510.o
> obj-$(CONFIG_DRM_PANEL_NOVATEK_NT35950) += panel-novatek-nt35950.o
> diff --git a/drivers/gpu/drm/panel/panel-mipi-dbi.c b/drivers/gpu/drm/panel/panel-mipi-dbi.c
> new file mode 100644
> index 000000000000..6e3dc2de21d2
> --- /dev/null
> +++ b/drivers/gpu/drm/panel/panel-mipi-dbi.c
> @@ -0,0 +1,394 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * DRM driver for MIPI DBI compatible display panels
> + *
> + * Copyright 2022 Noralf Trønnes
> + */
> +
> +#include <linux/backlight.h>
> +#include <linux/delay.h>
> +#include <linux/firmware.h>
> +#include <linux/gpio/consumer.h>
> +#include <linux/module.h>
> +#include <linux/property.h>
> +#include <linux/regulator/consumer.h>
> +#include <linux/spi/spi.h>
> +
> +#include <drm/drm_atomic_helper.h>
> +#include <drm/drm_drv.h>
> +#include <drm/drm_fb_helper.h>
> +#include <drm/drm_gem_atomic_helper.h>
> +#include <drm/drm_gem_cma_helper.h>
> +#include <drm/drm_managed.h>
> +#include <drm/drm_mipi_dbi.h>
> +#include <drm/drm_modeset_helper.h>
> +#include <video/mipi_display.h>
> +
> +static const u8 panel_mipi_dbi_magic[15] = { 'M', 'I', 'P', 'I', ' ', 'D', 'B', 'I',
> + 0, 0, 0, 0, 0, 0, 0 };
> +
> +/*
> + * The display panel configuration is stored in a firmware file. The Device Tree 'compatible'
> + * property value with a '.bin' suffix is passed to request_firmware() to fetch this file.
> + */
> +struct panel_mipi_dbi_config {
> + /* Magic string: panel_mipi_dbi_magic */
> + u8 magic[15];
> +
> + /* Config file format version */
> + u8 file_format_version;
> +
> + /* Width in pixels */
> + __be16 width;
> + /* Height in pixels */
> + __be16 height;
> +
> + /* Width in millimeters (optional) */
> + __be16 width_mm;
> + /* Height in millimeters (optional) */
> + __be16 height_mm;
> +
> + /* X-axis panel offset */
> + __be16 x_offset;
> + /* Y-axis panel offset */
> + __be16 y_offset;
> +
> + /* 4 pad bytes, must be zero */
> + u8 pad[4];
> +
> + /*
> + * Optional MIPI commands to execute when the display pipeline is enabled.
> + * This can be used to configure the display controller.
> + *
> + * The commands are stored in a byte array with the format:
> + * command, num_parameters, [ parameter, ...], command, ...
> + *
> + * Some commands require a pause before the next command can be received.
> + * Inserting a delay in the command sequence is done by using the NOP command with one
> + * parameter: delay in miliseconds (the No Operation command is part of the MIPI Display
> + * Command Set where it has no parameters).
> + *
> + * Example:
> + * command 0x11
> + * sleep 120ms
> + * command 0xb1 parameters 0x01, 0x2c, 0x2d
> + * command 0x29
> + *
> + * Byte sequence:
> + * 0x11 0x00
> + * 0x00 0x01 0x78
> + * 0xb1 0x03 0x01 0x2c 0x2d
> + * 0x29 0x00
> + */
> + u8 commands[];
> +};
I'm not really a fan of parsing raw data in the kernel. I guess we can't
really avoid the introduction of a special case to sleep, but we already
have dt properties for all of the other properties (but X and Y offset,
maybe?)
Maybe we should use those instead?
Maxime
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply
* Re: [PATCH v3 6/6] RISC-V: Do not use cpumask data structure for hartid bitmap
From: Geert Uytterhoeven @ 2022-01-27 10:03 UTC (permalink / raw)
To: Atish Patra
Cc: Jessica Clarke, Atish Patra, Linux Kernel Mailing List,
Anup Patel, Albert Ou, Damien Le Moal, devicetree, Jisheng Zhang,
Krzysztof Kozlowski, linux-riscv, Palmer Dabbelt, Paul Walmsley,
Rob Herring
In-Reply-To: <CAMuHMdWsX-Pg3B1=KRf9hz1JrPAbydBrANTXg4q5CFJCqHJAoA@mail.gmail.com>
Hi Atish,
On Thu, Jan 27, 2022 at 9:48 AM Geert Uytterhoeven <geert@linux-m68k.org> wrote:
> On Thu, Jan 27, 2022 at 2:02 AM Atish Patra <atishp@atishpatra.org> wrote:
> Ahh yes. hmask will be incorrect if the bootcpu(cpu 0) is a higher
> > hartid and it is trying to do a remote tlb flush/IPI
> > to lower the hartid. We should generate the hartid array before the loop.
> >
> > Can you try this diff ? It seems to work for me during multiple boot
> > cycle on the unleashed.
> >
> > You can find the patch here as well
> > https://github.com/atishp04/linux/commits/v5.17-rc1
>
> Thanks, that fixes the issue for me.
>
> > --- a/arch/riscv/kernel/sbi.c
> > +++ b/arch/riscv/kernel/sbi.c
> > @@ -345,13 +368,21 @@ static int __sbi_rfence_v02(int fid, const
> > struct cpumask *cpu_mask,
> > unsigned long arg4, unsigned long arg5)
> > {
> > unsigned long hartid, cpuid, hmask = 0, hbase = 0;
> > - int result;
> > + int result, index = 0, max_index = 0;
> > + unsigned long hartid_arr[NR_CPUS] = {0};
>
> That's up to 256 bytes on the stack. And more if the maximum
> number of cores is increased.
I.e. 4 KiB with the proposed increase to 256 CPUs, as mentioned in
https://lore.kernel.org/all/CAAhSdy2xTW0FkwvS2dExOb7q1dVruFfTP_Vh_jWju+yi7thCeA@mail.gmail.com/
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply
* Re: [PATCH v3] arm64: dts: renesas: add MOST device
From: Geert Uytterhoeven @ 2022-01-27 10:00 UTC (permalink / raw)
To: Nikita Yushchenko
Cc: Magnus Damm, Rob Herring, Linux-Renesas,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
Linux Kernel Mailing List
In-Reply-To: <20220120051559.746322-1-nikita.yoush@cogentembedded.com>
On Thu, Jan 20, 2022 at 6:16 AM Nikita Yushchenko
<nikita.yoush@cogentembedded.com> wrote:
> This patch adds mlp device to dtsi files for R-Car Gen3 SoCs that have
> it.
>
> Signed-off-by: Nikita Yushchenko <nikita.yoush@cogentembedded.com>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
i.e. will queue in renesas-devel for v5.18.
Note that as this device has no DT binding documentation, and the driver
is under staging, this can not be considered stable.
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply
* Re: [PATCH 3/3] arm64: dts: rockchip: add Quartz64-A sdmmc1 node
From: Peter Geis @ 2022-01-27 9:55 UTC (permalink / raw)
To: Johan Jonker
Cc: Rob Herring, Heiko Stuebner, devicetree, arm-mail-list,
open list:ARM/Rockchip SoC..., Linux Kernel Mailing List
In-Reply-To: <07281029-0efd-0a74-0d96-92e3dcf5bbb7@gmail.com>
On Thu, Jan 27, 2022 at 1:18 AM Johan Jonker <jbx6244@gmail.com> wrote:
>
>
>
> On 1/27/22 02:00, Peter Geis wrote:
> > The sdmmc1 node on Quartz64-A supports the optional wifi module from
> > Pine64.
> > Add the sdmmc1 node and requisite sdio_pwrseq to enable wifi support on
> > the Quartz64-A.
> >
> > Signed-off-by: Peter Geis <pgwipeout@gmail.com>
> > ---
> > .../boot/dts/rockchip/rk3566-quartz64-a.dts | 45 +++++++++++++++++++
> > 1 file changed, 45 insertions(+)
> >
> > diff --git a/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts b/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
> > index 33c2c18caaa9..1d73ac6557c5 100644
> > --- a/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
> > +++ b/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
> > @@ -91,6 +91,18 @@ simple-audio-card,codec {
> > };
> > };
> >
> > + sdio_pwrseq: sdio-pwrseq {
>
> > + status = "okay";
>
> When a node is not previously disabled, then there's no need for "okay".
Thanks, this is here in case an end user wants to easily hack the
board to use this for other purposes.
>
> > + compatible = "mmc-pwrseq-simple";
> > + clocks = <&rk817 1>;
> > + clock-names = "ext_clock";
> > + pinctrl-names = "default";
> > + pinctrl-0 = <&wifi_enable_h>;
> > + reset-gpios = <&gpio2 RK_PC2 GPIO_ACTIVE_LOW>;
> > + post-power-on-delay-ms = <100>;
> > + power-off-delay-us = <5000000>;
> > + };
> > +
> > vcc12v_dcin: vcc12v_dcin {
> > compatible = "regulator-fixed";
> > regulator-name = "vcc12v_dcin";
> > @@ -147,6 +159,17 @@ vcc_sys: vcc_sys {
> > regulator-max-microvolt = <4400000>;
> > vin-supply = <&vbus>;
> > };
> > +
> > + /* sourced from vcc_sys, sdio module operates internally at 3.3v */
> > + vcc_wl: vcc_wl {
> > + compatible = "regulator-fixed";
> > + regulator-name = "vcc_wl";
> > + regulator-always-on;
> > + regulator-boot-on;
> > + regulator-min-microvolt = <3300000>;
> > + regulator-max-microvolt = <3300000>;
> > + vin-supply = <&vcc_sys>;
> > + };
> > };
> >
> > &cpu0 {
> > @@ -475,6 +498,12 @@ pmic_int_l: pmic-int-l {
> > };
> > };
> >
> > + sdio-pwrseq {
> > + wifi_enable_h: wifi-enable-h {
> > + rockchip,pins = <2 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>;
> > + };
> > + };
> > +
> > vcc_sd {
> > vcc_sd_h: vcc-sd-h {
> > rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>;
> > @@ -516,6 +545,22 @@ &sdmmc0 {
> > status = "okay";
> > };
> >
> > +&sdmmc1 {
> > + bus-width = <4>;
> > + cap-sd-highspeed;
> > + cap-sdio-irq;
>
> > + disable-wp;
>
> From mmc-controller.yaml:
>
> disable-wp:
> $ref: /schemas/types.yaml#/definitions/flag
> description:
> When set, no physical write-protect line is present. This
> property should only be specified when the controller has a
> dedicated write-protect detection logic. If a GPIO is always used
> for the write-protect detection logic, it is sufficient to not
> specify the wp-gpios property in the absence of a write-protect
> line. Not used in combination with eMMC or SDIO.
Appreciate it, I will drop this.
>
> > + keep-power-in-suspend;
> > + mmc-pwrseq = <&sdio_pwrseq>;
> > + non-removable;
> > + pinctrl-names = "default";
> > + pinctrl-0 = <&sdmmc1_bus4 &sdmmc1_cmd &sdmmc1_clk>;
> > + sd-uhs-sdr104;
> > + vmmc-supply = <&vcc_wl>;
> > + vqmmc-supply = <&vcc_1v8>;
> > + status = "okay";
> > +};
> > +
> > &spdif {
> > status = "okay";
> > };
^ permalink raw reply
* Re: [PATCH 2/3] arm64: dts: rockchip: add Quartz64-A pmu_io_domains
From: Peter Geis @ 2022-01-27 9:52 UTC (permalink / raw)
To: Johan Jonker
Cc: Rob Herring, Heiko Stuebner, devicetree, arm-mail-list,
open list:ARM/Rockchip SoC..., Linux Kernel Mailing List
In-Reply-To: <e2479729-154a-122f-f2e0-89b62ffe2c8d@gmail.com>
On Thu, Jan 27, 2022 at 12:57 AM Johan Jonker <jbx6244@gmail.com> wrote:
>
> Hi Peter,
Good Morning,
The Rockchip schematics IO Power Domain Map is rarely *if ever* 100%
accurate, you need to check the actual schematic for ground truth.
>
> On 1/27/22 02:00, Peter Geis wrote:
> > Several io power domains on the Quartz64-A operate at 1.8v.
> > Add the pmu_io_domains definition to enable support for this.
> > This permits the enablement of the following features:
> > sdio - wifi support
> > sdhci - mmc-hs200-1_8v
> >
> > Signed-off-by: Peter Geis <pgwipeout@gmail.com>
> > ---
> > arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts | 13 +++++++++++++
> > 1 file changed, 13 insertions(+)
> >
> > diff --git a/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts b/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
> > index d9eb92d59099..33c2c18caaa9 100644
> > --- a/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
> > +++ b/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
> > @@ -482,6 +482,19 @@ vcc_sd_h: vcc-sd-h {
> > };
> > };
> >
>
> https://files.pine64.org/doc/quartz64/Quartz64_model-A_schematic_v2.0_20210427.pdf
>
> Could you check with the IO Power Domain Map?
>
> > +&pmu_io_domains {
> > + pmuio1-supply = <&vcc3v3_pmu>;
> VCC3V3_PMU
>
> > + pmuio2-supply = <&vcc3v3_pmu>;
> VCC3V3_PMU
>
> > + vccio1-supply = <&vccio_acodec>;
> VCCIO_ACODEC
>
> > + vccio2-supply = <&vcc_1v8>;
> VCC_1V8
>
> > + vccio3-supply = <&vccio_sd>;
> VCCIO_SD
>
> > + vccio4-supply = <&vcc_1v8>;
> ==> VCC1V8_PMU
Page 16 of the schematic, VCCIO4 is tied to VCC_1V8 via R1519
>
> > + vccio5-supply = <&vcc_3v3>;
> ==> VCC_1V8
Page 20 of the schematic, VCCIO5 is tied to VCC_3V3 via R1800
>
> > + vccio6-supply = <&vcc1v8_dvp>;
> VCC1V8_DVP
>
> > + vccio7-supply = <&vcc_3v3>;
> VCC_3V3
>
> > + status = "okay";
> > +};
> > +
> > &sdhci {
> > bus-width = <8>;
> > mmc-hs200-1_8v;
Thanks for double checking,
Peter
^ permalink raw reply
* Re: [PATCH v2 1/3] dt-bindings: display: add bindings for MIPI DBI compatible SPI panels
From: Maxime Ripard @ 2022-01-27 9:37 UTC (permalink / raw)
To: Noralf Trønnes
Cc: robh+dt, thierry.reding, sam, dave.stevenson, david, devicetree,
dri-devel
In-Reply-To: <20220125175700.37408-2-noralf@tronnes.org>
[-- Attachment #1: Type: text/plain, Size: 2325 bytes --]
Hi,
On Tue, Jan 25, 2022 at 06:56:58PM +0100, Noralf Trønnes wrote:
> Add binding for MIPI DBI compatible SPI panels.
>
> v2:
> - Fix path for panel-common.yaml
> - Use unevaluatedProperties
> - Drop properties which are in the allOf section
> - Drop model property (Rob)
>
> Signed-off-by: Noralf Trønnes <noralf@tronnes.org>
> ---
> .../display/panel/panel-mipi-dbi-spi.yaml | 59 +++++++++++++++++++
> 1 file changed, 59 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/display/panel/panel-mipi-dbi-spi.yaml
>
> diff --git a/Documentation/devicetree/bindings/display/panel/panel-mipi-dbi-spi.yaml b/Documentation/devicetree/bindings/display/panel/panel-mipi-dbi-spi.yaml
> new file mode 100644
> index 000000000000..b7cbeea0f8aa
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/display/panel/panel-mipi-dbi-spi.yaml
> @@ -0,0 +1,59 @@
> +# SPDX-License-Identifier: GPL-2.0-only
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/display/panel/panel-mipi-dbi-spi.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: MIPI DBI SPI Panels Device Tree Bindings
> +
> +maintainers:
> + - Noralf Trønnes <noralf@tronnes.org>
> +
> +description:
> + This binding is for display panels using a MIPI DBI controller
> + in SPI mode.
> +
> +allOf:
> + - $ref: panel-common.yaml#
> + - $ref: /schemas/spi/spi-peripheral-props.yaml#
> +
> +properties:
> + compatible:
> + const: panel-mipi-dbi-spi
You need contains here, otherwise it will error out if you have two compatibles.
> + write-only:
> + type: boolean
> + description:
> + Controller is not readable (ie. MISO is not wired up).
> +
> + dc-gpios:
> + maxItems: 1
> + description: |
> + Controller data/command selection (D/CX) in 4-line SPI mode.
> + If not set, the controller is in 3-line SPI mode.
> +
> +required:
> + - compatible
> + - reg
> +
> +unevaluatedProperties: false
> +
> +examples:
> + - |
> + #include <dt-bindings/gpio/gpio.h>
> +
> + spi {
> + #address-cells = <1>;
> + #size-cells = <0>;
> +
> + display@0{
> + compatible = "panel-mipi-dbi-spi";
We should have two compatibles in the example too
Maxime
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply
* Re: [PATCH 1/3] dt-bindings: display: add bindings for MIPI DBI compatible SPI panels
From: Maxime Ripard @ 2022-01-27 9:36 UTC (permalink / raw)
To: Rob Herring
Cc: Noralf Trønnes, thierry.reding, sam, dave.stevenson, david,
devicetree, dri-devel
In-Reply-To: <CAL_JsqLiw42zfaRPmszs2bmGbAcL5STSTVUtP0PyWnm=CaG8ug@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 1749 bytes --]
Hi Rob,
On Mon, Jan 24, 2022 at 10:42:37AM -0600, Rob Herring wrote:
> On Mon, Jan 24, 2022 at 10:28 AM Noralf Trønnes <noralf@tronnes.org> wrote:
> >
> >
> >
> > Den 24.01.2022 17.08, skrev Rob Herring:
> > > On Sun, Jan 23, 2022 at 11:25 AM Noralf Trønnes <noralf@tronnes.org> wrote:
> > >>
> > >> Add binding for MIPI DBI compatible SPI panels.
> > >
> > > I'm sure we already have MIPI DBI panels. What's this for?
> > >
> >
> > It aims to use one driver to cover all MIPI DBI panels where the
> > controller setup is loaded from userspace in a firmware file.
>
> What's the solution when the user wants a splash screen in the
> bootloader and also wants multiple panels supported?
>
> Also, 1 driver doesn't dictate 1 compatible. A one to many
> relationship is fine and makes the decision entirely the OS's.
>
> > The cover
> > letter points to the discussion where Maxime proposed this:
> >
> > https://lore.kernel.org/dri-devel/20211129093946.xhp22mvdut3m67sc@houat/
>
> The proposal there is:
>
> > compatible = "panel-spi";
> > model = "panel-from-random-place-42";
>
> The same thing can be accomplished with this:
>
> compatible = "panel-from-random-place-42", "panel-spi";
>
> What's the advantage of hijacking 'model'?
So, the main issue is that a panel is essentially two things: a
controller and the actual panel.
The controller has an initialization sequence of its own, and part of it
is parameters to match the panel.
So you can have identical controllers that won't have the same
initialization sequence because they don't have the same panel.
I was assuming that a compatible would be more about the controller, so
we needed something else, thus "model"
Maxime
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply
* Re: [PATCH 0/2] Add pwrap node for MediaTek MT8192 SoC and mt6359 node for MediaTek PMIC MT6359
From: Macpaul Lin @ 2022-01-27 9:36 UTC (permalink / raw)
To: Hui-Liu Liu, lee.jones, robh+dt, matthias.bgg, lgirdwood, broonie,
eddie.huang, a.zummo, alexandre.belloni, fshao
Cc: srv_heupstream, zhiyong.tao, hsin-hsiung.wang, sean.wang,
yuchen.huang, wen.su, devicetree, linux-arm-kernel,
linux-mediatek, linux-kernel, linux-rtc,
Project_Global_Chrome_Upstream_Group, Fabien Parent, Macpaul Lin,
Wens Tsai, Pablo Sun
In-Reply-To: <20220127063145.13413-1-hui.liu@mediatek.com>
On 1/27/22 2:31 PM, Hui-Liu Liu wrote:
> This pathset add pwrap node to SoC MT8192, and add PMIC MT6359 related nodes.
> MT6359 is the primary PMIC for MT8192 and probably other SoCs.
>
> The series[1] and series[2] send by Hsin-Hsiung will continue to upstream in this pathset afterwards.
>
> [1] https://patchwork.kernel.org/project/linux-mediatek/patch/1615563286-22126-6-git-send-email-hsin-hsiung.wang@mediatek.com/
> [2] https://patchwork.kernel.org/project/linux-mediatek/patch/1622011927-359-9-git-send-email-hsin-hsiung.wang@mediatek.com/
>
> Hui Liu (2):
> arm64: dts: mt8192: add PWRAP node
> arm64: dts: mt6359: add PMIC MT6359 related nodes
>
> arch/arm64/boot/dts/mediatek/mt6359.dtsi | 298 ++++++++++++++++++++
> arch/arm64/boot/dts/mediatek/mt8192-evb.dts | 1 +
> arch/arm64/boot/dts/mediatek/mt8192.dtsi | 12 +
> 3 files changed, 311 insertions(+)
> create mode 100644 arch/arm64/boot/dts/mediatek/mt6359.dtsi
>
> --
> 2.25.1
>
>
This patchset is based on [1]
[1] arm64: dts: Add mediatek SoC mt8195 and evaluation board
-
https://patchwork.kernel.org/project/linux-mediatek/patch/20220112114724.1953-4-tinghan.shen@mediatek.com/
I've tested this patch set build pass with [1] for both mt8192 and
mt8195 platform on linux-5.17-rc1.
Reviewed-by: Macpaul Lin <macpaul.lin@mediatek.com>
Regards,
Macpaul Lin
^ permalink raw reply
* Re: [PATCH 2/2] arm64: dts: mt6359: add PMIC MT6359 related nodes
From: Macpaul Lin @ 2022-01-27 9:33 UTC (permalink / raw)
To: Hui-Liu Liu, lee.jones, robh+dt, matthias.bgg, lgirdwood, broonie,
eddie.huang, a.zummo, alexandre.belloni, fshao
Cc: srv_heupstream, zhiyong.tao, hsin-hsiung.wang, sean.wang,
yuchen.huang, wen.su, devicetree, linux-arm-kernel,
linux-mediatek, linux-kernel, linux-rtc,
Project_Global_Chrome_Upstream_Group, Fabien Parent, Macpaul Lin,
Pablo Sun, Rex-BC Chen
In-Reply-To: <20220127063145.13413-3-hui.liu@mediatek.com>
On 1/27/22 2:31 PM, Hui-Liu Liu wrote:
> From: Hui Liu <hui.liu@mediatek.com>
>
> Add MT6359 node.
>
> Signed-off-by: Hui Liu <hui.liu@mediatek.com>
> ---
> arch/arm64/boot/dts/mediatek/mt6359.dtsi | 298 ++++++++++++++++++++
> arch/arm64/boot/dts/mediatek/mt8192-evb.dts | 1 +
> 2 files changed, 299 insertions(+)
> create mode 100644 arch/arm64/boot/dts/mediatek/mt6359.dtsi
>
> diff --git a/arch/arm64/boot/dts/mediatek/mt6359.dtsi b/arch/arm64/boot/dts/mediatek/mt6359.dtsi
> new file mode 100644
> index 000000000000..df3e822232d3
> --- /dev/null
> +++ b/arch/arm64/boot/dts/mediatek/mt6359.dtsi
> @@ -0,0 +1,298 @@
> +// SPDX-License-Identifier: (GPL-2.0 OR MIT)
> +/*
> + * Copyright (C) 2022 MediaTek Inc.
> + */
> +
> +&pwrap {
> + pmic: pmic {
> + compatible = "mediatek,mt6359";
> + interrupt-controller;
> + #interrupt-cells = <2>;
> +
> + mt6359codec: mt6359codec {
> + };
> +
> + regulators {
> + mt6359_vs1_buck_reg: buck_vs1 {
> + regulator-name = "vs1";
> + regulator-min-microvolt = <800000>;
> + regulator-max-microvolt = <2200000>;
> + regulator-enable-ramp-delay = <0>;
> + regulator-always-on;
> + };
> + mt6359_vgpu11_buck_reg: buck_vgpu11 {
> + regulator-name = "vgpu11";
> + regulator-min-microvolt = <400000>;
> + regulator-max-microvolt = <1193750>;
> + regulator-ramp-delay = <5000>;
> + regulator-enable-ramp-delay = <200>;
> + regulator-allowed-modes = <0 1 2>;
> + };
> + mt6359_vmodem_buck_reg: buck_vmodem {
> + regulator-name = "vmodem";
> + regulator-min-microvolt = <400000>;
> + regulator-max-microvolt = <1100000>;
> + regulator-ramp-delay = <10760>;
> + regulator-enable-ramp-delay = <200>;
> + };
> + mt6359_vpu_buck_reg: buck_vpu {
> + regulator-name = "vpu";
> + regulator-min-microvolt = <400000>;
> + regulator-max-microvolt = <1193750>;
> + regulator-ramp-delay = <5000>;
> + regulator-enable-ramp-delay = <200>;
> + regulator-allowed-modes = <0 1 2>;
> + };
> + mt6359_vcore_buck_reg: buck_vcore {
> + regulator-name = "vcore";
> + regulator-min-microvolt = <400000>;
> + regulator-max-microvolt = <1300000>;
> + regulator-ramp-delay = <5000>;
> + regulator-enable-ramp-delay = <200>;
> + regulator-allowed-modes = <0 1 2>;
> + };
> + mt6359_vs2_buck_reg: buck_vs2 {
> + regulator-name = "vs2";
> + regulator-min-microvolt = <800000>;
> + regulator-max-microvolt = <1600000>;
> + regulator-enable-ramp-delay = <0>;
> + regulator-always-on;
> + };
> + mt6359_vpa_buck_reg: buck_vpa {
> + regulator-name = "vpa";
> + regulator-min-microvolt = <500000>;
> + regulator-max-microvolt = <3650000>;
> + regulator-enable-ramp-delay = <300>;
> + };
> + mt6359_vproc2_buck_reg: buck_vproc2 {
> + regulator-name = "vproc2";
> + regulator-min-microvolt = <400000>;
> + regulator-max-microvolt = <1193750>;
> + regulator-ramp-delay = <7500>;
> + regulator-enable-ramp-delay = <200>;
> + regulator-allowed-modes = <0 1 2>;
> + };
> + mt6359_vproc1_buck_reg: buck_vproc1 {
> + regulator-name = "vproc1";
> + regulator-min-microvolt = <400000>;
> + regulator-max-microvolt = <1193750>;
> + regulator-ramp-delay = <7500>;
> + regulator-enable-ramp-delay = <200>;
> + regulator-allowed-modes = <0 1 2>;
> + };
> + mt6359_vcore_sshub_buck_reg: buck_vcore_sshub {
> + regulator-name = "vcore_sshub";
> + regulator-min-microvolt = <400000>;
> + regulator-max-microvolt = <1193750>;
> + };
> + mt6359_vgpu11_sshub_buck_reg: buck_vgpu11_sshub {
> + regulator-name = "vgpu11_sshub";
> + regulator-min-microvolt = <400000>;
> + regulator-max-microvolt = <1193750>;
> + };
> + mt6359_vaud18_ldo_reg: ldo_vaud18 {
> + regulator-name = "vaud18";
> + regulator-min-microvolt = <1800000>;
> + regulator-max-microvolt = <1800000>;
> + regulator-enable-ramp-delay = <240>;
> + };
> + mt6359_vsim1_ldo_reg: ldo_vsim1 {
> + regulator-name = "vsim1";
> + regulator-min-microvolt = <1700000>;
> + regulator-max-microvolt = <3100000>;
> + };
> + mt6359_vibr_ldo_reg: ldo_vibr {
> + regulator-name = "vibr";
> + regulator-min-microvolt = <1200000>;
> + regulator-max-microvolt = <3300000>;
> + };
> + mt6359_vrf12_ldo_reg: ldo_vrf12 {
> + regulator-name = "vrf12";
> + regulator-min-microvolt = <1100000>;
> + regulator-max-microvolt = <1300000>;
> + };
> + mt6359_vusb_ldo_reg: ldo_vusb {
> + regulator-name = "vusb";
> + regulator-min-microvolt = <3000000>;
> + regulator-max-microvolt = <3000000>;
> + regulator-enable-ramp-delay = <960>;
> + regulator-always-on;
> + };
> + mt6359_vsram_proc2_ldo_reg: ldo_vsram_proc2 {
> + regulator-name = "vsram_proc2";
> + regulator-min-microvolt = <500000>;
> + regulator-max-microvolt = <1293750>;
> + regulator-ramp-delay = <7500>;
> + regulator-enable-ramp-delay = <240>;
> + regulator-always-on;
> + };
> + mt6359_vio18_ldo_reg: ldo_vio18 {
> + regulator-name = "vio18";
> + regulator-min-microvolt = <1700000>;
> + regulator-max-microvolt = <1900000>;
> + regulator-enable-ramp-delay = <960>;
> + regulator-always-on;
> + };
> + mt6359_vcamio_ldo_reg: ldo_vcamio {
> + regulator-name = "vcamio";
> + regulator-min-microvolt = <1700000>;
> + regulator-max-microvolt = <1900000>;
> + };
> + mt6359_vcn18_ldo_reg: ldo_vcn18 {
> + regulator-name = "vcn18";
> + regulator-min-microvolt = <1800000>;
> + regulator-max-microvolt = <1800000>;
> + regulator-enable-ramp-delay = <240>;
> + };
> + mt6359_vfe28_ldo_reg: ldo_vfe28 {
> + regulator-name = "vfe28";
> + regulator-min-microvolt = <2800000>;
> + regulator-max-microvolt = <2800000>;
> + regulator-enable-ramp-delay = <120>;
> + };
> + mt6359_vcn13_ldo_reg: ldo_vcn13 {
> + regulator-name = "vcn13";
> + regulator-min-microvolt = <900000>;
> + regulator-max-microvolt = <1300000>;
> + };
> + mt6359_vcn33_1_bt_ldo_reg: ldo_vcn33_1_bt {
> + regulator-name = "vcn33_1_bt";
> + regulator-min-microvolt = <2800000>;
> + regulator-max-microvolt = <3500000>;
> + };
> + mt6359_vcn33_1_wifi_ldo_reg: ldo_vcn33_1_wifi {
> + regulator-name = "vcn33_1_wifi";
> + regulator-min-microvolt = <2800000>;
> + regulator-max-microvolt = <3500000>;
> + };
> + mt6359_vaux18_ldo_reg: ldo_vaux18 {
> + regulator-name = "vaux18";
> + regulator-min-microvolt = <1800000>;
> + regulator-max-microvolt = <1800000>;
> + regulator-enable-ramp-delay = <240>;
> + regulator-always-on;
> + };
> + mt6359_vsram_others_ldo_reg: ldo_vsram_others {
> + regulator-name = "vsram_others";
> + regulator-min-microvolt = <500000>;
> + regulator-max-microvolt = <1293750>;
> + regulator-ramp-delay = <5000>;
> + regulator-enable-ramp-delay = <240>;
> + };
> + mt6359_vefuse_ldo_reg: ldo_vefuse {
> + regulator-name = "vefuse";
> + regulator-min-microvolt = <1700000>;
> + regulator-max-microvolt = <2000000>;
> + };
> + mt6359_vxo22_ldo_reg: ldo_vxo22 {
> + regulator-name = "vxo22";
> + regulator-min-microvolt = <1800000>;
> + regulator-max-microvolt = <2200000>;
> + regulator-always-on;
> + };
> + mt6359_vrfck_ldo_reg: ldo_vrfck {
> + regulator-name = "vrfck";
> + regulator-min-microvolt = <1500000>;
> + regulator-max-microvolt = <1700000>;
> + };
> + mt6359_vrfck_1_ldo_reg: ldo_vrfck_1 {
> + regulator-name = "vrfck";
> + regulator-min-microvolt = <1240000>;
> + regulator-max-microvolt = <1600000>;
> + };
> + mt6359_vbif28_ldo_reg: ldo_vbif28 {
> + regulator-name = "vbif28";
> + regulator-min-microvolt = <2800000>;
> + regulator-max-microvolt = <2800000>;
> + regulator-enable-ramp-delay = <240>;
> + };
> + mt6359_vio28_ldo_reg: ldo_vio28 {
> + regulator-name = "vio28";
> + regulator-min-microvolt = <2800000>;
> + regulator-max-microvolt = <3300000>;
> + regulator-always-on;
> + };
> + mt6359_vemc_ldo_reg: ldo_vemc {
> + regulator-name = "vemc";
> + regulator-min-microvolt = <2900000>;
> + regulator-max-microvolt = <3300000>;
> + };
> + mt6359_vemc_1_ldo_reg: ldo_vemc_1 {
> + regulator-name = "vemc";
> + regulator-min-microvolt = <2500000>;
> + regulator-max-microvolt = <3300000>;
> + };
> + mt6359_vcn33_2_bt_ldo_reg: ldo_vcn33_2_bt {
> + regulator-name = "vcn33_2_bt";
> + regulator-min-microvolt = <2800000>;
> + regulator-max-microvolt = <3500000>;
> + };
> + mt6359_vcn33_2_wifi_ldo_reg: ldo_vcn33_2_wifi {
> + regulator-name = "vcn33_2_wifi";
> + regulator-min-microvolt = <2800000>;
> + regulator-max-microvolt = <3500000>;
> + };
> + mt6359_va12_ldo_reg: ldo_va12 {
> + regulator-name = "va12";
> + regulator-min-microvolt = <1200000>;
> + regulator-max-microvolt = <1300000>;
> + regulator-always-on;
> + };
> + mt6359_va09_ldo_reg: ldo_va09 {
> + regulator-name = "va09";
> + regulator-min-microvolt = <800000>;
> + regulator-max-microvolt = <1200000>;
> + };
> + mt6359_vrf18_ldo_reg: ldo_vrf18 {
> + regulator-name = "vrf18";
> + regulator-min-microvolt = <1700000>;
> + regulator-max-microvolt = <1810000>;
> + };
> + mt6359_vsram_md_ldo_reg: ldo_vsram_md {
> + regulator-name = "vsram_md";
> + regulator-min-microvolt = <500000>;
> + regulator-max-microvolt = <1293750>;
> + regulator-ramp-delay = <10760>;
> + regulator-enable-ramp-delay = <240>;
> + };
> + mt6359_vufs_ldo_reg: ldo_vufs {
> + regulator-name = "vufs";
> + regulator-min-microvolt = <1700000>;
> + regulator-max-microvolt = <1900000>;
> + };
> + mt6359_vm18_ldo_reg: ldo_vm18 {
> + regulator-name = "vm18";
> + regulator-min-microvolt = <1700000>;
> + regulator-max-microvolt = <1900000>;
> + regulator-always-on;
> + };
> + mt6359_vbbck_ldo_reg: ldo_vbbck {
> + regulator-name = "vbbck";
> + regulator-min-microvolt = <1100000>;
> + regulator-max-microvolt = <1200000>;
> + };
> + mt6359_vsram_proc1_ldo_reg: ldo_vsram_proc1 {
> + regulator-name = "vsram_proc1";
> + regulator-min-microvolt = <500000>;
> + regulator-max-microvolt = <1293750>;
> + regulator-ramp-delay = <7500>;
> + regulator-enable-ramp-delay = <240>;
> + regulator-always-on;
> + };
> + mt6359_vsim2_ldo_reg: ldo_vsim2 {
> + regulator-name = "vsim2";
> + regulator-min-microvolt = <1700000>;
> + regulator-max-microvolt = <3100000>;
> + };
> + mt6359_vsram_others_sshub_ldo: ldo_vsram_others_sshub {
> + regulator-name = "vsram_others_sshub";
> + regulator-min-microvolt = <500000>;
> + regulator-max-microvolt = <1293750>;
> + };
> + };
> +
> + mt6359rtc: mt6359rtc {
> + compatible = "mediatek,mt6358-rtc";
> + };
> + };
> +};
> diff --git a/arch/arm64/boot/dts/mediatek/mt8192-evb.dts b/arch/arm64/boot/dts/mediatek/mt8192-evb.dts
> index 0205837fa698..808be492e970 100644
> --- a/arch/arm64/boot/dts/mediatek/mt8192-evb.dts
> +++ b/arch/arm64/boot/dts/mediatek/mt8192-evb.dts
> @@ -5,6 +5,7 @@
> */
> /dts-v1/;
> #include "mt8192.dtsi"
> +#include "mt6359.dtsi"
>
> / {
> model = "MediaTek MT8192 evaluation board";
>
Reviewed-by: Macpaul Lin Lincpaul.lin@mediatek.com>
Regards,
Macpaul Lin
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox