From patchwork Wed Apr 10 17:12:30 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Th=C3=A9o_Lebrun?= X-Patchwork-Id: 787719 Received: from relay5-d.mail.gandi.net (relay5-d.mail.gandi.net [217.70.183.197]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 63C5417BB2F; Wed, 10 Apr 2024 17:12:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.70.183.197 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712769158; cv=none; b=ILEppKxCh5MiWfGwkJBvL7OP6TlxbpQrvPeAm0mO0gMfeXT4/dkbAYLSJDYVdir7P3fxybw+tOatcKCUtGVy47GuKpA2HcG9ZpiCb8GadmyNfBazyRxyA/FtH2bd5AAcLunGNP0E3C9ZkdOm/e9ut+tj56rZiRNa9kwUM8yWliM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712769158; c=relaxed/simple; bh=Or291JUs24MEUn69d+XwauX2nPmZNlD7rIxIXrFHe1c=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=HX6lHKOMVy6HQ3cdKBVL16FkxB1WTGBXm7Gc1A+/ckD1Wzf+dstNNa9LeIs95YivrqIjhPOIwjAzsa0xCCsxuk/3mgFkIloOPuj/AdHFfwxAGVOH9gk9lJgPDrNvo+mTb8QXl8y5DVJJWvpnF2hNn4F0XjV3SZV3vkQwdMcmif0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=J2Ssnzcm; arc=none smtp.client-ip=217.70.183.197 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="J2Ssnzcm" Received: by mail.gandi.net (Postfix) with ESMTPSA id 0F3731C0009; Wed, 10 Apr 2024 17:12:33 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1712769153; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=ly+UQbnGLVNX/Ag4mEzSfzNVkLxnGyHhNenCfFPJ9mc=; b=J2Ssnzcm4DdjcFwztGM0r7y5ZeQCnf9WLKKEPZ2CDOoY+oFjgHn8Watlw9qZReaI7jBC4k 15Ev/J4lvLOi/C2+rZxvKdNvPHA5k2RpGOZAiYM5QJ0vtx8IMN0R4VzGn77TOePt6fx0KA gfi6a+mCeXJzIEDVzh7E1hh3VzB5xDuSuLs1Fsv0Zw+O9n4BXAxo87ekAfU0O2MEZm81/D IVFalwxe+LO1dCfCAVB+KOet4XOEQotu9F6bgMN/CZtK9h0v/4TcWoOdJQTeED2lAw3cnV SetGrI3kiAYv1xBXtfUD+7AZh5TdeU7Fh0n1wqlhnQkXslEoAQXKR6vCqytbEw== From: =?utf-8?q?Th=C3=A9o_Lebrun?= Date: Wed, 10 Apr 2024 19:12:30 +0200 Subject: [PATCH 01/11] dt-bindings: soc: mobileye: add EyeQ5 OLB system controller Precedence: bulk X-Mailing-List: linux-gpio@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240410-mbly-olb-v1-1-335e496d7be3@bootlin.com> References: <20240410-mbly-olb-v1-0-335e496d7be3@bootlin.com> In-Reply-To: <20240410-mbly-olb-v1-0-335e496d7be3@bootlin.com> To: Rob Herring , Krzysztof Kozlowski , Conor Dooley , Michael Turquette , Stephen Boyd , Philipp Zabel , Linus Walleij Cc: linux-mips@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-clk@vger.kernel.org, linux-gpio@vger.kernel.org, Vladimir Kondratiev , Gregory CLEMENT , Thomas Petazzoni , Tawfik Bayouk , =?utf-8?q?Th=C3=A9o_Lebrun?= X-Mailer: b4 0.13.0 X-GND-Sasl: theo.lebrun@bootlin.com Add documentation to describe the "Other Logic Block" syscon. Signed-off-by: Théo Lebrun --- .../bindings/soc/mobileye/mobileye,eyeq5-olb.yaml | 125 +++++++++++++++++++++ MAINTAINERS | 1 + 2 files changed, 126 insertions(+) diff --git a/Documentation/devicetree/bindings/soc/mobileye/mobileye,eyeq5-olb.yaml b/Documentation/devicetree/bindings/soc/mobileye/mobileye,eyeq5-olb.yaml new file mode 100644 index 000000000000..c4e33a167fab --- /dev/null +++ b/Documentation/devicetree/bindings/soc/mobileye/mobileye,eyeq5-olb.yaml @@ -0,0 +1,125 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/soc/mobileye/mobileye,eyeq5-olb.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Mobileye EyeQ SoC system controller + +maintainers: + - Grégory Clement + - Théo Lebrun + - Vladimir Kondratiev + +description: + OLB ("Other Logic Block") is a hardware block grouping smaller blocks. Clocks, + resets, pinctrl are being handled from here. EyeQ5 and EyeQ6L host a single + instance. EyeQ6H hosts seven instances. + +properties: + compatible: + items: + - enum: + - mobileye,eyeq5-olb + - mobileye,eyeq6l-olb + - mobileye,eyeq6h-olb + - const: syscon + - const: simple-mfd + + reg: + maxItems: 1 + + '#address-cells': + const: 1 + + '#size-cells': + const: 1 + + ranges: true + +patternProperties: + '^clock-controller@[0-9a-f]+$': + $ref: /schemas/clock/mobileye,eyeq5-clk.yaml# + + '^reset-controller@[0-9a-f]+$': + $ref: /schemas/reset/mobileye,eyeq5-reset.yaml# + + '^pinctrl@[0-9a-f]+$': + $ref: /schemas/pinctrl/mobileye,eyeq5-pinctrl.yaml# + +required: + - compatible + - reg + - '#address-cells' + - '#size-cells' + - ranges + +additionalProperties: false + +examples: + - | + soc { + #address-cells = <2>; + #size-cells = <2>; + + system-controller@e00000 { + compatible = "mobileye,eyeq5-olb", "syscon", "simple-mfd"; + reg = <0x0 0xe00000 0x0 0x400>; + ranges = <0x0 0x0 0xe00000 0x400>; + #address-cells = <1>; + #size-cells = <1>; + + reset-controller@e00000 { + compatible = "mobileye,eyeq5-reset"; + reg = <0x000 0x0c>, <0x200 0x34>, <0x120 0x04>; + reg-names = "d0", "d1", "d2"; + #reset-cells = <2>; + }; + + clock-controller@e0002c { + compatible = "mobileye,eyeq5-clk"; + reg = <0x02c 0x50>, <0x11c 0x04>; + reg-names = "plls", "ospi"; + #clock-cells = <1>; + clocks = <&xtal>; + clock-names = "ref"; + }; + + pinctrl@e000b0 { + compatible = "mobileye,eyeq5-pinctrl"; + reg = <0x0b0 0x30>; + + uart2_pins: uart2-pins { + function = "uart2"; + pins = "PB8", "PB9"; + }; + }; + }; + }; + - | + soc { + #address-cells = <2>; + #size-cells = <2>; + + system-controller@d2003000 { + compatible = "mobileye,eyeq6h-olb", "syscon", "simple-mfd"; + reg = <0x0 0xd2003000 0x0 0x1000>; + ranges = <0x0 0x0 0xd2003000 0x1000>; + #address-cells = <1>; + #size-cells = <1>; + + reset-controller@d2003000 { + compatible = "mobileye,eyeq6h-acc-reset"; + reg = <0x0 0x3c>; + #reset-cells = <1>; + }; + + clock-controller@d2003040 { + compatible = "mobileye,eyeq6h-acc-clk"; + reg = <0x40 0x38>; + #clock-cells = <1>; + clocks = <&xtal>; + clock-names = "ref"; + }; + }; + }; diff --git a/MAINTAINERS b/MAINTAINERS index aa3b947fb080..30dfbee84007 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -14926,6 +14926,7 @@ M: Théo Lebrun L: linux-mips@vger.kernel.org S: Maintained F: Documentation/devicetree/bindings/mips/mobileye.yaml +F: Documentation/devicetree/bindings/soc/mobileye/ F: arch/mips/boot/dts/mobileye/ F: arch/mips/configs/eyeq5_defconfig F: arch/mips/mobileye/board-epm5.its.S From patchwork Wed Apr 10 17:12:31 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Th=C3=A9o_Lebrun?= X-Patchwork-Id: 788095 Received: from relay5-d.mail.gandi.net (relay5-d.mail.gandi.net [217.70.183.197]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4259217BB30; Wed, 10 Apr 2024 17:12:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.70.183.197 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712769159; cv=none; b=jDemgfJu4JpeaKBRM99toWzrIiaTKMyM8j1Nb9pZAI1YtIT0SkVR0P39XWQzj8vBUR7vjyGuNmlzkZXw50hMyLUxDk0rds6QpKQMyemTnw985gZw4Or+80LgMin2SNC4xAS9bjtGboBvFj8aNGRMwhB0OJ0Tt4fHdeDRduLvzaw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712769159; c=relaxed/simple; bh=c+IFxwQfthW/nqRziH56DeSWLrMbg5sRJ/KRQ1A0kQE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=jvq4VkTIhzRkdjoMLJGUBEyUERihO+ntbRNmMlKR8XQvdG6dTEg5CD2vu1gEMOYJy27zmPQnxRdN7wiUaK3PRsTud1fuGto3K08AnK0mtIuXBpFhtt+OYRsUWXZsRGFNMkP/h6oxKMLZFhUMFezRxm9cZwANeGx8B/aTGti8LJU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=cN7RmgcG; arc=none smtp.client-ip=217.70.183.197 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="cN7RmgcG" Received: by mail.gandi.net (Postfix) with ESMTPSA id C51251C0002; Wed, 10 Apr 2024 17:12:33 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1712769154; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=3rXMr8mwJCHqbdg+nZTnRhhVEsvK2g8zb+kr2700fN8=; b=cN7RmgcGveDOP6X6p+9gUFdwZv655Qq0diqOgTgOKrR1e3MYYsHpFdqStpi8OzVKBQhGUy L8Lwudexe3EB35yCp6Y40yvdCq9Dc2AbE/4piY2GKx+EHLl/CJ8DlaNFBdppnupLGrGd8D 0iDYCzIskgNC2UMrmRSoV+uM9bxkGl3hPxW96L2A0AoDEz0CGwFun7FW1e7YbChJDKJ4tR eoYlvJxAjgCL5O7oOjRNNgDmIrrZYwlVgtJaeit5uX86MFuN/AnqMGEPXMGlCV6fEco0Ph lAUAbY77/R5EMGoExZYA8OL6f7mmktqiRTtvaY72C3XQo78dgCPY0LH42c5hUw== From: =?utf-8?q?Th=C3=A9o_Lebrun?= Date: Wed, 10 Apr 2024 19:12:31 +0200 Subject: [PATCH 02/11] dt-bindings: clock: mobileye,eyeq5-clk: add EyeQ6L and EyeQ6H Precedence: bulk X-Mailing-List: linux-gpio@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240410-mbly-olb-v1-2-335e496d7be3@bootlin.com> References: <20240410-mbly-olb-v1-0-335e496d7be3@bootlin.com> In-Reply-To: <20240410-mbly-olb-v1-0-335e496d7be3@bootlin.com> To: Rob Herring , Krzysztof Kozlowski , Conor Dooley , Michael Turquette , Stephen Boyd , Philipp Zabel , Linus Walleij Cc: linux-mips@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-clk@vger.kernel.org, linux-gpio@vger.kernel.org, Vladimir Kondratiev , Gregory CLEMENT , Thomas Petazzoni , Tawfik Bayouk , =?utf-8?q?Th=C3=A9o_Lebrun?= X-Mailer: b4 0.13.0 X-GND-Sasl: theo.lebrun@bootlin.com Add bindings describing EyeQ6L and EyeQ6H clock controllers. Add constants to index clocks. Bindings are conditional for two reasons: - Some compatibles expose a single clock; they do not take clock cells. - All compatibles take a PLLs resource, not all take others (aimed at divider clocks). Those that only take a resource for PLLs do not require named resources. Signed-off-by: Théo Lebrun --- .../bindings/clock/mobileye,eyeq5-clk.yaml | 103 ++++++++++++++++++--- MAINTAINERS | 2 + include/dt-bindings/clock/mobileye,eyeq5-clk.h | 21 +++++ 3 files changed, 113 insertions(+), 13 deletions(-) diff --git a/Documentation/devicetree/bindings/clock/mobileye,eyeq5-clk.yaml b/Documentation/devicetree/bindings/clock/mobileye,eyeq5-clk.yaml index 2d4f2cde1e58..a1651fcce258 100644 --- a/Documentation/devicetree/bindings/clock/mobileye,eyeq5-clk.yaml +++ b/Documentation/devicetree/bindings/clock/mobileye,eyeq5-clk.yaml @@ -4,12 +4,13 @@ $id: http://devicetree.org/schemas/clock/mobileye,eyeq5-clk.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# -title: Mobileye EyeQ5 clock controller +title: Mobileye EyeQ clock controller description: - The EyeQ5 clock controller handles 10 read-only PLLs derived from the main - crystal clock. It also exposes one divider clock, a child of one of the PLLs. - Its registers live in a shared region called OLB. + EyeQ clock controllers expose read-only PLLs derived from main crystal clock. + Some also expose divider clocks, children of specific PLLs. Its registers + live in a shared region called OLB. EyeQ5 and EyeQ6L have a single OLB + instance while EyeQ6H have seven, leading to seven clock controllers. maintainers: - Grégory Clement @@ -18,18 +19,23 @@ maintainers: properties: compatible: - const: mobileye,eyeq5-clk + enum: + - mobileye,eyeq5-clk + - mobileye,eyeq6l-clk + - mobileye,eyeq6h-central-clk + - mobileye,eyeq6h-west-clk + - mobileye,eyeq6h-east-clk + - mobileye,eyeq6h-south-clk + - mobileye,eyeq6h-ddr0-clk + - mobileye,eyeq6h-ddr1-clk + - mobileye,eyeq6h-acc-clk - reg: - maxItems: 2 + reg: true - reg-names: - items: - - const: plls - - const: ospi + reg-names: true "#clock-cells": - const: 1 + enum: [0, 1] clocks: maxItems: 1 @@ -43,9 +49,80 @@ properties: required: - compatible - reg - - reg-names - "#clock-cells" - clocks - clock-names +allOf: + # "mobileye,eyeq5-clk" provides: + # - PLLs and, + # - One divider clock related to ospi. + - if: + properties: + compatible: + const: mobileye,eyeq5-clk + then: + properties: + reg: + minItems: 2 + maxItems: 2 + reg-names: + minItems: 2 + maxItems: 2 + items: + enum: [ plls, ospi ] + required: + - reg-names + + # "mobileye,eyeq6h-south-clk" provides: + # - PLLs and, + # - Four divider clocks related to emmc, ospi and tsu. + - if: + properties: + compatible: + const: mobileye,eyeq6h-south-clk + then: + properties: + reg: + minItems: 4 + maxItems: 4 + reg-names: + minItems: 4 + maxItems: 4 + items: + enum: [ plls, emmc, ospi, tsu ] + required: + - reg-names + + # Other compatibles only provide PLLs. Do not ask for named resources. + - if: + not: + required: + - reg-names + then: + properties: + reg: + minItems: 1 + maxItems: 1 + reg-names: false + + # Some compatibles provide a single clock; they do not take a clock cell. + - if: + properties: + compatible: + enum: + - mobileye,eyeq6h-central-clk + - mobileye,eyeq6h-west-clk + - mobileye,eyeq6h-east-clk + - mobileye,eyeq6h-ddr0-clk + - mobileye,eyeq6h-ddr1-clk + then: + properties: + "#clock-cells": + const: 0 + else: + properties: + "#clock-cells": + const: 1 + additionalProperties: false diff --git a/MAINTAINERS b/MAINTAINERS index 30dfbee84007..f5a488331b38 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -14925,11 +14925,13 @@ M: Gregory CLEMENT M: Théo Lebrun L: linux-mips@vger.kernel.org S: Maintained +F: Documentation/devicetree/bindings/clock/mobileye,eyeq5-clk.yaml F: Documentation/devicetree/bindings/mips/mobileye.yaml F: Documentation/devicetree/bindings/soc/mobileye/ F: arch/mips/boot/dts/mobileye/ F: arch/mips/configs/eyeq5_defconfig F: arch/mips/mobileye/board-epm5.its.S +F: include/dt-bindings/clock/mobileye,eyeq5-clk.h MODULE SUPPORT M: Luis Chamberlain diff --git a/include/dt-bindings/clock/mobileye,eyeq5-clk.h b/include/dt-bindings/clock/mobileye,eyeq5-clk.h index 26d8930335e4..b433c1772c28 100644 --- a/include/dt-bindings/clock/mobileye,eyeq5-clk.h +++ b/include/dt-bindings/clock/mobileye,eyeq5-clk.h @@ -19,4 +19,25 @@ #define EQ5C_DIV_OSPI 10 +#define EQ6LC_PLL_DDR 0 +#define EQ6LC_PLL_CPU 1 +#define EQ6LC_PLL_PER 2 +#define EQ6LC_PLL_VDI 3 + +#define EQ6HC_SOUTH_PLL_VDI 0 +#define EQ6HC_SOUTH_PLL_PCIE 1 +#define EQ6HC_SOUTH_PLL_PER 2 +#define EQ6HC_SOUTH_PLL_ISP 3 + +#define EQ6HC_SOUTH_DIV_EMMC 4 +#define EQ6HC_SOUTH_DIV_OSPI_REF 5 +#define EQ6HC_SOUTH_DIV_OSPI_SYS 6 +#define EQ6HC_SOUTH_DIV_TSU 7 + +#define EQ6HC_ACC_PLL_XNN 0 +#define EQ6HC_ACC_PLL_VMP 1 +#define EQ6HC_ACC_PLL_PMA 2 +#define EQ6HC_ACC_PLL_MPC 3 +#define EQ6HC_ACC_PLL_NOC 4 + #endif From patchwork Wed Apr 10 17:12:32 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Th=C3=A9o_Lebrun?= X-Patchwork-Id: 787718 Received: from relay5-d.mail.gandi.net (relay5-d.mail.gandi.net [217.70.183.197]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 27DEF17BB31; Wed, 10 Apr 2024 17:12:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.70.183.197 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712769160; cv=none; b=Qc3QTIFCSl4hum9oxdf77Z5nlW15l4F1V24Xj/9M6Ft8PvStHDHzkpShe6/7th5ynAIlQAFiNXOfrv1riPuNlsgZIdJLh50n9ky4UTIODOEXZY/e4+JlcHSJz6UNjhckZgqtSmtn5KF64+m0CwRXq9BBnJodS3SfCVZdsfQJybE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712769160; c=relaxed/simple; bh=n8+PgA6bKd1Vx6o5AWLgi+oPwHeHl2ofK6gyj4tm/3A=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=uQJAPO/MizySk0bElc5OtaIbb7OgPn7r8A7Vd4BK6vp6sXuiFATlhlGr44op2ppFRW5rDgiQeoGK7dZW0ieAXr4rjZ1HezVMkYjz5CBpIsaoKHQWTmH8OwYM3LhiGd7c7FCWrbxaeEsYqyrXY0JXd+d11n4Q7Prhs5n888S2CV4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=m8nsTqX4; arc=none smtp.client-ip=217.70.183.197 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="m8nsTqX4" Received: by mail.gandi.net (Postfix) with ESMTPSA id 8E0011C0006; Wed, 10 Apr 2024 17:12:34 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1712769155; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=iLiIWhcHooUzKzHOFOzpwEPH4xnOlgJV8b8vLeV+y90=; b=m8nsTqX4kErAAO5ExQcAzioUdq/G1DgrE410JGDs/3UB2RpKjOoEGXmVRrzyxtXXZBZt// ecs8RUJ0ehmL8Z0pVSY1DWY3D8k0M0WY+1CsLOlpLQaK6a78WlOz/UpCs+i+DePjGu0mrJ tddwEfwh32X3U63K4HCrLH2Vh5LiwspE5sdXhZEFu7+jacbXqF8Y7SFfRLi9Dhg5ke7o6w ev4O8OAmS9O6KK8I/Xm3LebUZdzxow7wCMUyNd5W13s37E077pwzP6/wbP2tfNQJGVy9o9 E9f7ac3fdwClONnI5T3xsNmjXV6XAM7xgRBKmP0OcDFmfcvGK+xU2VJdNZucRw== From: =?utf-8?q?Th=C3=A9o_Lebrun?= Date: Wed, 10 Apr 2024 19:12:32 +0200 Subject: [PATCH 03/11] dt-bindings: reset: mobileye,eyeq5-reset: add EyeQ6L and EyeQ6H Precedence: bulk X-Mailing-List: linux-gpio@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240410-mbly-olb-v1-3-335e496d7be3@bootlin.com> References: <20240410-mbly-olb-v1-0-335e496d7be3@bootlin.com> In-Reply-To: <20240410-mbly-olb-v1-0-335e496d7be3@bootlin.com> To: Rob Herring , Krzysztof Kozlowski , Conor Dooley , Michael Turquette , Stephen Boyd , Philipp Zabel , Linus Walleij Cc: linux-mips@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-clk@vger.kernel.org, linux-gpio@vger.kernel.org, Vladimir Kondratiev , Gregory CLEMENT , Thomas Petazzoni , Tawfik Bayouk , =?utf-8?q?Th=C3=A9o_Lebrun?= X-Mailer: b4 0.13.0 X-GND-Sasl: theo.lebrun@bootlin.com Add bindings for EyeQ6L and EyeQ6H reset controllers. Some controllers host a single domain, meaning a single cell is enough. We do not enforce reg-names for such nodes. Signed-off-by: Théo Lebrun --- .../bindings/reset/mobileye,eyeq5-reset.yaml | 88 ++++++++++++++++++---- MAINTAINERS | 1 + 2 files changed, 74 insertions(+), 15 deletions(-) diff --git a/Documentation/devicetree/bindings/reset/mobileye,eyeq5-reset.yaml b/Documentation/devicetree/bindings/reset/mobileye,eyeq5-reset.yaml index 062b4518347b..799bcf15bed9 100644 --- a/Documentation/devicetree/bindings/reset/mobileye,eyeq5-reset.yaml +++ b/Documentation/devicetree/bindings/reset/mobileye,eyeq5-reset.yaml @@ -4,11 +4,13 @@ $id: http://devicetree.org/schemas/reset/mobileye,eyeq5-reset.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# -title: Mobileye EyeQ5 reset controller +title: Mobileye EyeQ reset controller description: - The EyeQ5 reset driver handles three reset domains. Its registers live in a - shared region called OLB. + EyeQ reset controller handles one or more reset domains. They live in shared + regions called OLB. EyeQ5 and EyeQ6L host one OLB each, each with one reset + instance. EyeQ6H hosts 7 OLB regions; three of those (west, east, + accelerator) host reset controllers. West and east are duplicates. maintainers: - Grégory Clement @@ -17,27 +19,83 @@ maintainers: properties: compatible: - const: mobileye,eyeq5-reset + enum: + - mobileye,eyeq5-reset + - mobileye,eyeq6l-reset + - mobileye,eyeq6h-we-reset + - mobileye,eyeq6h-acc-reset - reg: - maxItems: 3 + reg: true - reg-names: - items: - - const: d0 - - const: d1 - - const: d2 + reg-names: true "#reset-cells": - const: 2 description: - The first cell is the domain (0 to 2 inclusive) and the second one is the - reset index inside that domain. + First cell is domain, second is reset index inside that domain. If + controller has a single domain, first cell is implicitly zero. + enum: [ 1, 2 ] required: - compatible - reg - - reg-names - "#reset-cells" +allOf: + # EyeQ5 and EyeQ6L have multiple domains, other compatibles have one. + # Multiple domains means named resources and two reset cells. + # Single domain means a single unnamed resource and one reset cell. + - if: + properties: + compatible: + enum: + - mobileye,eyeq5-reset + - mobileye,eyeq6l-reset + then: + properties: + "#reset-cells": + const: 2 + required: + - reg-names + else: + properties: + reg: + maxItems: 1 + reg-names: false + "#reset-cells": + const: 1 + + # EyeQ5 has three domains. + - if: + properties: + compatible: + contains: + const: mobileye,eyeq5-reset + then: + properties: + reg: + minItems: 3 + maxItems: 3 + reg-names: + minItems: 3 + maxItems: 3 + items: + enum: [ d0, d1, d2 ] + + # EyeQ6L has two domains. + - if: + properties: + compatible: + contains: + const: mobileye,eyeq6l-reset + then: + properties: + reg: + minItems: 2 + maxItems: 2 + reg-names: + minItems: 2 + maxItems: 2 + items: + enum: [ d0, d1 ] + additionalProperties: false diff --git a/MAINTAINERS b/MAINTAINERS index f5a488331b38..42553da10be9 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -14927,6 +14927,7 @@ L: linux-mips@vger.kernel.org S: Maintained F: Documentation/devicetree/bindings/clock/mobileye,eyeq5-clk.yaml F: Documentation/devicetree/bindings/mips/mobileye.yaml +F: Documentation/devicetree/bindings/reset/mobileye,eyeq5-reset.yaml F: Documentation/devicetree/bindings/soc/mobileye/ F: arch/mips/boot/dts/mobileye/ F: arch/mips/configs/eyeq5_defconfig From patchwork Wed Apr 10 17:12:33 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Th=C3=A9o_Lebrun?= X-Patchwork-Id: 788094 Received: from relay5-d.mail.gandi.net (relay5-d.mail.gandi.net [217.70.183.197]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BC88617BB2E; Wed, 10 Apr 2024 17:12:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.70.183.197 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712769160; cv=none; b=fsn5m19lOj7nlFyFXKZNix5eu3nx7q++nCAHjez9ir38BT2SdYN5afvTBceFuzYW9EuACq/nrsB8FnpLjeel9+FQ3VbO19TDrCqHewSFrOFOA8pABxRxCNd491pnyw0nvN3GKcdleEpf/9ubaZK0GlCIzz8+1vifU/2gB0uFrGk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712769160; c=relaxed/simple; bh=qy/BC7EhDliYH0sA8fccO7bozWLbpErUVkxPvBBH8yY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ryIdk4q/H6PexIkoant3BUF6sVOG5BgUWhHR/W8AuZvnY6Tg95g/mq9dhH3A6ZkwfCKufqgQIfGLin/du81de9ZrjdO7bO02J/1vUUj1nphV1HbCu5wkG0ZwW0jSEnn2iPLIiwnPBgyaSvnbeaKf+o5HyIKFbPnBZHUeUcruiZg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=gZlV6OYK; arc=none smtp.client-ip=217.70.183.197 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="gZlV6OYK" Received: by mail.gandi.net (Postfix) with ESMTPSA id 57BAF1C000A; Wed, 10 Apr 2024 17:12:35 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1712769156; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=TFeZNmNWSruVbVOlxmosbNjPRa+XfQDOejg7IP8V8PM=; b=gZlV6OYKFLf4iq9pUPekA5Xe4V3qJ3L4j/YVFuMk4IH/39ZSd/XbRBBlCvqGTlmjiCs+F4 9ZyDmvYaX/Q4GWpK3jj+FqAGwOwA+9UUwTOUHxELyV07HPHpVskWl2O+Kzqgc451+CVXci MStsT73PoEnKdoCN0Saf3b6AscWB29aIrTyexJOJA832EbkF5usq2ZKbWAQDG+4ZTzJ+55 aASCvTkGAzLjiPeZjMz7qxGPr675v/hzlFEDoZkUJZaoJSyhVLAc49t6i1LcZxyKY9lNmm BP3bgvhoGHkRL3pMlCo9e0wEDgFbTETShJ9RhgX58ayy7nf1ojnoUuJzXtU+2w== From: =?utf-8?q?Th=C3=A9o_Lebrun?= Date: Wed, 10 Apr 2024 19:12:33 +0200 Subject: [PATCH 04/11] clk: divider: Introduce CLK_DIVIDER_EVEN_INTEGERS flag Precedence: bulk X-Mailing-List: linux-gpio@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240410-mbly-olb-v1-4-335e496d7be3@bootlin.com> References: <20240410-mbly-olb-v1-0-335e496d7be3@bootlin.com> In-Reply-To: <20240410-mbly-olb-v1-0-335e496d7be3@bootlin.com> To: Rob Herring , Krzysztof Kozlowski , Conor Dooley , Michael Turquette , Stephen Boyd , Philipp Zabel , Linus Walleij Cc: linux-mips@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-clk@vger.kernel.org, linux-gpio@vger.kernel.org, Vladimir Kondratiev , Gregory CLEMENT , Thomas Petazzoni , Tawfik Bayouk , =?utf-8?q?Th=C3=A9o_Lebrun?= X-Mailer: b4 0.13.0 X-GND-Sasl: theo.lebrun@bootlin.com Add CLK_DIVIDER_EVEN_INTEGERS flag to support divisor of 2, 4, 6, etc. The same divisor can be done using a table, which would be big and wasteful for a clock dividor of width 8 (256 entries). Require increasing flags size from u8 to u16 because CLK_DIVIDER_EVEN_INTEGERS is the eighth flag. Signed-off-by: Théo Lebrun --- drivers/clk/clk-divider.c | 12 +++++++++--- include/linux/clk-provider.h | 11 +++++++---- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/drivers/clk/clk-divider.c b/drivers/clk/clk-divider.c index a2c2b5203b0a..b6654c5c36d2 100644 --- a/drivers/clk/clk-divider.c +++ b/drivers/clk/clk-divider.c @@ -72,6 +72,8 @@ static unsigned int _get_maxdiv(const struct clk_div_table *table, u8 width, return clk_div_mask(width); if (flags & CLK_DIVIDER_POWER_OF_TWO) return 1 << clk_div_mask(width); + if (flags & CLK_DIVIDER_EVEN_INTEGERS) + return 2 * (clk_div_mask(width) + 1); if (table) return _get_table_maxdiv(table, width); return clk_div_mask(width) + 1; @@ -97,6 +99,8 @@ static unsigned int _get_div(const struct clk_div_table *table, return 1 << val; if (flags & CLK_DIVIDER_MAX_AT_ZERO) return val ? val : clk_div_mask(width) + 1; + if (flags & CLK_DIVIDER_EVEN_INTEGERS) + return 2 * (val + 1); if (table) return _get_table_div(table, val); return val + 1; @@ -122,6 +126,8 @@ static unsigned int _get_val(const struct clk_div_table *table, return __ffs(div); if (flags & CLK_DIVIDER_MAX_AT_ZERO) return (div == clk_div_mask(width) + 1) ? 0 : div; + if (flags & CLK_DIVIDER_EVEN_INTEGERS) + return (div >> 1) - 1; if (table) return _get_table_val(table, div); return div - 1; @@ -538,7 +544,7 @@ struct clk_hw *__clk_hw_register_divider(struct device *dev, struct device_node *np, const char *name, const char *parent_name, const struct clk_hw *parent_hw, const struct clk_parent_data *parent_data, unsigned long flags, - void __iomem *reg, u8 shift, u8 width, u8 clk_divider_flags, + void __iomem *reg, u8 shift, u8 width, u16 clk_divider_flags, const struct clk_div_table *table, spinlock_t *lock) { struct clk_divider *div; @@ -610,7 +616,7 @@ EXPORT_SYMBOL_GPL(__clk_hw_register_divider); struct clk *clk_register_divider_table(struct device *dev, const char *name, const char *parent_name, unsigned long flags, void __iomem *reg, u8 shift, u8 width, - u8 clk_divider_flags, const struct clk_div_table *table, + u16 clk_divider_flags, const struct clk_div_table *table, spinlock_t *lock) { struct clk_hw *hw; @@ -664,7 +670,7 @@ struct clk_hw *__devm_clk_hw_register_divider(struct device *dev, struct device_node *np, const char *name, const char *parent_name, const struct clk_hw *parent_hw, const struct clk_parent_data *parent_data, unsigned long flags, - void __iomem *reg, u8 shift, u8 width, u8 clk_divider_flags, + void __iomem *reg, u8 shift, u8 width, u16 clk_divider_flags, const struct clk_div_table *table, spinlock_t *lock) { struct clk_hw **ptr, *hw; diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h index 4a537260f655..cb348e502e41 100644 --- a/include/linux/clk-provider.h +++ b/include/linux/clk-provider.h @@ -675,13 +675,15 @@ struct clk_div_table { * CLK_DIVIDER_BIG_ENDIAN - By default little endian register accesses are used * for the divider register. Setting this flag makes the register accesses * big endian. + * CLK_DIVIDER_EVEN_INTEGERS - clock divisor is 2, 4, 6, 8, 10, etc. + * Formula is 2 * (value read from hardware + 1). */ struct clk_divider { struct clk_hw hw; void __iomem *reg; u8 shift; u8 width; - u8 flags; + u16 flags; const struct clk_div_table *table; spinlock_t *lock; }; @@ -697,6 +699,7 @@ struct clk_divider { #define CLK_DIVIDER_READ_ONLY BIT(5) #define CLK_DIVIDER_MAX_AT_ZERO BIT(6) #define CLK_DIVIDER_BIG_ENDIAN BIT(7) +#define CLK_DIVIDER_EVEN_INTEGERS BIT(8) extern const struct clk_ops clk_divider_ops; extern const struct clk_ops clk_divider_ro_ops; @@ -726,18 +729,18 @@ struct clk_hw *__clk_hw_register_divider(struct device *dev, struct device_node *np, const char *name, const char *parent_name, const struct clk_hw *parent_hw, const struct clk_parent_data *parent_data, unsigned long flags, - void __iomem *reg, u8 shift, u8 width, u8 clk_divider_flags, + void __iomem *reg, u8 shift, u8 width, u16 clk_divider_flags, const struct clk_div_table *table, spinlock_t *lock); struct clk_hw *__devm_clk_hw_register_divider(struct device *dev, struct device_node *np, const char *name, const char *parent_name, const struct clk_hw *parent_hw, const struct clk_parent_data *parent_data, unsigned long flags, - void __iomem *reg, u8 shift, u8 width, u8 clk_divider_flags, + void __iomem *reg, u8 shift, u8 width, u16 clk_divider_flags, const struct clk_div_table *table, spinlock_t *lock); struct clk *clk_register_divider_table(struct device *dev, const char *name, const char *parent_name, unsigned long flags, void __iomem *reg, u8 shift, u8 width, - u8 clk_divider_flags, const struct clk_div_table *table, + u16 clk_divider_flags, const struct clk_div_table *table, spinlock_t *lock); /** * clk_register_divider - register a divider clock with the clock framework From patchwork Wed Apr 10 17:12:34 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Th=C3=A9o_Lebrun?= X-Patchwork-Id: 787717 Received: from relay5-d.mail.gandi.net (relay5-d.mail.gandi.net [217.70.183.197]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 62EDF17F366; Wed, 10 Apr 2024 17:12:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.70.183.197 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712769162; cv=none; b=NPdtR+SRiJqeoq675GVuPzeZk6LHDAOZ3/WB7DbqsDC8bfTftqA4jBQe8PYRQd2m+GvFLAX0FC0JsKkZcKBEEGgLI2hIvH90HlemrzV9bdQU6Ez5lh5YcT9DPWp9lqII62CS61G+vBtLmXIW6wPw21Kf4YpwyGYNLbMQO3ipRcU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712769162; c=relaxed/simple; bh=ESW7k04bOah5gJzElrHGNSP1+hSPZzg7NelHWdPldCs=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ZZvlxPMyX/TWlR20jz6mJCKc1xm8A8bsHN7/GsD0vVrGqGSChSxePDdY8kwzlI/eKX+pEv1UPYnrxVXm5XOqRj7M40ZpiO8OJ9csyKhRADBYtF+LvGTblAzmkgiKGL3gECEMNi2otE8z+D0naPH1AIPs0Z1Un85twpUJl6nfGlE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=OeQYQyur; arc=none smtp.client-ip=217.70.183.197 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="OeQYQyur" Received: by mail.gandi.net (Postfix) with ESMTPSA id 1763C1C000B; Wed, 10 Apr 2024 17:12:36 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1712769156; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=F3BqGEUn2EmB2IwhPjvDlmPWipGAcZkNTnmyUxCGE3o=; b=OeQYQyurEe0wdA5JCyKiAcgm5pO40eJaXH/qaEO9RX2B/L8ZFHAkqALehBajIFWoCWVebX 0y46BqtA5Y+BwJN/JrQq5PDyF3tkyPusKCkIgG2FbbYWOsByzg0gFSDmPCPVlKJJFuIdX+ 3sg7ViUfBGoQ83zbiWbbg6ZBDUT+wrGv80aN28SXPpFGLxQfR1smJGl3hWsG+8baH8aGuz mavVkFhtSmrnsEN/5E9nz+BSC17SH9ixXf8aB128wG9phDjKzOpyFQJmU/8sI1u6Y31IcH 81baQYS3o+YMrp5grvs6u/ZAPJEtWddZUf28CRAF4gsQK2RWEZqG6mX+ux3zZw== From: =?utf-8?q?Th=C3=A9o_Lebrun?= Date: Wed, 10 Apr 2024 19:12:34 +0200 Subject: [PATCH 05/11] clk: eyeq: add driver Precedence: bulk X-Mailing-List: linux-gpio@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240410-mbly-olb-v1-5-335e496d7be3@bootlin.com> References: <20240410-mbly-olb-v1-0-335e496d7be3@bootlin.com> In-Reply-To: <20240410-mbly-olb-v1-0-335e496d7be3@bootlin.com> To: Rob Herring , Krzysztof Kozlowski , Conor Dooley , Michael Turquette , Stephen Boyd , Philipp Zabel , Linus Walleij Cc: linux-mips@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-clk@vger.kernel.org, linux-gpio@vger.kernel.org, Vladimir Kondratiev , Gregory CLEMENT , Thomas Petazzoni , Tawfik Bayouk , =?utf-8?q?Th=C3=A9o_Lebrun?= X-Mailer: b4 0.13.0 X-GND-Sasl: theo.lebrun@bootlin.com Add Mobileye EyeQ5, EyeQ6L and EyeQ6H clock controller driver. It is both a platform driver and a hook onto of_clk_init() used for clocks required early (GIC timer, UARTs). For some compatible, it is both at the same time. eqc_init() initialises early PLLs and stores clock array in a static linked list. It marks other clocks as deferred. eqc_probe() retrieves the clock array and adds all remaining clocks. It exposes read-only PLLs derived from the main crystal on board. It also exposes another type of clocks: divider clocks. They always have even divisors and have one PLL as parent. Signed-off-by: Théo Lebrun --- MAINTAINERS | 1 + drivers/clk/Kconfig | 11 + drivers/clk/Makefile | 1 + drivers/clk/clk-eyeq.c | 644 +++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 657 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 42553da10be9..33168ebf3cc5 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -14932,6 +14932,7 @@ F: Documentation/devicetree/bindings/soc/mobileye/ F: arch/mips/boot/dts/mobileye/ F: arch/mips/configs/eyeq5_defconfig F: arch/mips/mobileye/board-epm5.its.S +F: drivers/clk/clk-eyeq5.c F: include/dt-bindings/clock/mobileye,eyeq5-clk.h MODULE SUPPORT diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index 50af5fc7f570..1eb6e70977a3 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -218,6 +218,17 @@ config COMMON_CLK_EN7523 This driver provides the fixed clocks and gates present on Airoha ARM silicon. +config COMMON_CLK_EYEQ + bool "Clock driver for the Mobileye EyeQ platform" + depends on OF || COMPILE_TEST + depends on MACH_EYEQ5 || MACH_EYEQ6H || COMPILE_TEST + default MACH_EYEQ5 || MACH_EYEQ6H + help + This driver provides clocks found on Mobileye EyeQ5, EyeQ6L and Eye6H + SoCs. Controllers live in shared register regions called OLB. Driver + provides read-only PLLs, derived from the main crystal clock (which + must be constant). It also exposes some divider clocks. + config COMMON_CLK_FSL_FLEXSPI tristate "Clock driver for FlexSPI on Layerscape SoCs" depends on ARCH_LAYERSCAPE || COMPILE_TEST diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index 14fa8d4ecc1f..52de92309aa8 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -32,6 +32,7 @@ obj-$(CONFIG_ARCH_CLPS711X) += clk-clps711x.o obj-$(CONFIG_COMMON_CLK_CS2000_CP) += clk-cs2000-cp.o obj-$(CONFIG_ARCH_SPARX5) += clk-sparx5.o obj-$(CONFIG_COMMON_CLK_EN7523) += clk-en7523.o +obj-$(CONFIG_COMMON_CLK_EYEQ) += clk-eyeq.o obj-$(CONFIG_COMMON_CLK_FIXED_MMIO) += clk-fixed-mmio.o obj-$(CONFIG_COMMON_CLK_FSL_FLEXSPI) += clk-fsl-flexspi.o obj-$(CONFIG_COMMON_CLK_FSL_SAI) += clk-fsl-sai.o diff --git a/drivers/clk/clk-eyeq.c b/drivers/clk/clk-eyeq.c new file mode 100644 index 000000000000..bb2535010ae6 --- /dev/null +++ b/drivers/clk/clk-eyeq.c @@ -0,0 +1,644 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * PLL clock driver for the Mobileye EyeQ5, EyeQ6L and EyeQ6H platforms. + * + * This controller handles read-only PLLs, all derived from the same main + * crystal clock. It also exposes divider clocks, those are children to PLLs. + * Parent clock is expected to be constant. This driver's registers live in + * a shared region called OLB. Some PLLs are initialised early by of_clk_init(). + * + * We use eqc_ as prefix, as-in "EyeQ Clock", but way shorter. + * + * Copyright (C) 2024 Mobileye Vision Technologies Ltd. + */ + +#define pr_fmt(fmt) "clk-eyeq: " fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define EQC_MAX_DIV_COUNT 4 + +/* In frac mode, it enables fractional noise canceling DAC. Else, no function. */ +#define PCSR0_DAC_EN BIT(0) +/* Fractional or integer mode */ +#define PCSR0_DSM_EN BIT(1) +#define PCSR0_PLL_EN BIT(2) +/* All clocks output held at 0 */ +#define PCSR0_FOUTPOSTDIV_EN BIT(3) +#define PCSR0_POST_DIV1 GENMASK(6, 4) +#define PCSR0_POST_DIV2 GENMASK(9, 7) +#define PCSR0_REF_DIV GENMASK(15, 10) +#define PCSR0_INTIN GENMASK(27, 16) +#define PCSR0_BYPASS BIT(28) +/* Bits 30..29 are reserved */ +#define PCSR0_PLL_LOCKED BIT(31) + +#define PCSR1_RESET BIT(0) +#define PCSR1_SSGC_DIV GENMASK(4, 1) +/* Spread amplitude (% = 0.1 * SPREAD[4:0]) */ +#define PCSR1_SPREAD GENMASK(9, 5) +#define PCSR1_DIS_SSCG BIT(10) +/* Down-spread or center-spread */ +#define PCSR1_DOWN_SPREAD BIT(11) +#define PCSR1_FRAC_IN GENMASK(31, 12) + +/* + * Driver might register clock provider from eqc_init() if PLLs are required + * early (before platform bus is ready). Store struct eqc_priv inside linked + * list to pass clock provider from eqc_init() to eqc_probe() and register + * remaining clocks from platform device probe. + * + * Clock provider is NOT created by eqc_init() if no early clock is required. + * Store as linked list because EyeQ6H has multiple clock controller instances. + * Matching is done based on devicetree node pointer. + */ +static DEFINE_SPINLOCK(eqc_list_slock); +static LIST_HEAD(eqc_list); + +struct eqc_pll { + unsigned int index; + const char *name; + u32 reg64; +}; + +/* + * Divider clock. Divider is 2*(v+1), with v the register value. + * Min divider is 2, max is 2*(2^width). + */ +struct eqc_div { + unsigned int index; + const char *name; + unsigned int parent; + const char *resource_name; + u8 shift; + u8 width; +}; + +struct eqc_match_data { + unsigned int early_pll_count; + const struct eqc_pll *early_plls; + + unsigned int pll_count; + const struct eqc_pll *plls; + + unsigned int div_count; + const struct eqc_div *divs; +}; + +struct eqc_priv { + struct clk_hw_onecell_data *cells; + const struct eqc_match_data *data; + void __iomem *base_plls; + struct device_node *np; + struct list_head list; +}; + +static int eqc_pll_parse_registers(u32 r0, u32 r1, unsigned long *mult, + unsigned long *div, unsigned long *acc) +{ + if (r0 & PCSR0_BYPASS) { + *mult = 1; + *div = 1; + *acc = 0; + return 0; + } + + if (!(r0 & PCSR0_PLL_LOCKED)) + return -EINVAL; + + *mult = FIELD_GET(PCSR0_INTIN, r0); + *div = FIELD_GET(PCSR0_REF_DIV, r0); + if (r0 & PCSR0_FOUTPOSTDIV_EN) + *div *= FIELD_GET(PCSR0_POST_DIV1, r0) * FIELD_GET(PCSR0_POST_DIV2, r0); + + /* Fractional mode, in 2^20 (0x100000) parts. */ + if (r0 & PCSR0_DSM_EN) { + *div *= 0x100000; + *mult = *mult * 0x100000 + FIELD_GET(PCSR1_FRAC_IN, r1); + } + + if (!*mult || !*div) + return -EINVAL; + + /* Spread spectrum. */ + if (!(r1 & (PCSR1_RESET | PCSR1_DIS_SSCG))) { + /* + * Spread is 1/1000 parts of frequency, accuracy is half of + * that. To get accuracy, convert to ppb (parts per billion). + */ + u32 spread = FIELD_GET(PCSR1_SPREAD, r1); + + *acc = spread * 500000; + if (r1 & PCSR1_DOWN_SPREAD) { + /* + * Downspreading: the central frequency is half a + * spread lower. + */ + *mult *= 2000 - spread; + *div *= 2000; + } + } else { + *acc = 0; + } + + return 0; +} + +static unsigned int eqc_compute_clock_count(const struct eqc_match_data *data) +{ + unsigned int i, nb_clks = 0; + + for (i = 0; i < data->early_pll_count; i++) + if (data->early_plls[i].index >= nb_clks) + nb_clks = data->early_plls[i].index + 1; + for (i = 0; i < data->pll_count; i++) + if (data->plls[i].index >= nb_clks) + nb_clks = data->plls[i].index + 1; + for (i = 0; i < data->div_count; i++) + if (data->divs[i].index >= nb_clks) + nb_clks = data->divs[i].index + 1; + + /* We expect the biggest clock index to be 1 below the clock count. */ + WARN_ON(nb_clks != data->early_pll_count + data->pll_count + data->div_count); + + return nb_clks; +} + +static int eqc_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + void __iomem *div_resources[EQC_MAX_DIV_COUNT]; + struct device_node *np = dev->of_node; + const struct eqc_match_data *data; + struct eqc_priv *priv = NULL; + struct clk_hw *hw; + unsigned int i; + + data = device_get_match_data(dev); + if (!data) + return -ENODEV; + + if (data->early_pll_count) { + /* Device got inited early. Retrieve clock provider from list. */ + struct eqc_priv *entry; + + spin_lock(&eqc_list_slock); + list_for_each_entry(entry, &eqc_list, list) { + if (entry->np == np) { + priv = entry; + break; + } + } + spin_unlock(&eqc_list_slock); + + if (!priv) + return -ENODEV; + } else { + /* Device did NOT get init early. Do it now. */ + unsigned int nb_clks; + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + priv->np = np; + priv->data = data; + + nb_clks = eqc_compute_clock_count(data); + priv->cells = devm_kzalloc(dev, struct_size(priv->cells, hws, nb_clks), + GFP_KERNEL); + if (!priv->cells) + return -ENOMEM; + + priv->cells->num = nb_clks; + + /* + * We expect named resources if divider clocks are present. + * Else, we only expect one resource. + */ + if (data->div_count) + priv->base_plls = devm_platform_ioremap_resource_byname(pdev, "plls"); + else + priv->base_plls = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(priv->base_plls)) + return PTR_ERR(priv->base_plls); + } + + for (i = 0; i < data->pll_count; i++) { + const struct eqc_pll *pll = &data->plls[i]; + unsigned long mult, div, acc; + u32 r0, r1; + u64 val; + int ret; + + val = readq(priv->base_plls + pll->reg64); + r0 = val; + r1 = val >> 32; + + ret = eqc_pll_parse_registers(r0, r1, &mult, &div, &acc); + if (ret) { + dev_warn(dev, "failed parsing state of %s\n", pll->name); + priv->cells->hws[pll->index] = ERR_PTR(ret); + continue; + } + + hw = clk_hw_register_fixed_factor_with_accuracy_fwname(dev, + dev->of_node, pll->name, "ref", 0, mult, div, acc); + priv->cells->hws[pll->index] = hw; + if (IS_ERR(hw)) + dev_warn(dev, "failed registering %s: %pe\n", pll->name, hw); + } + + BUG_ON(ARRAY_SIZE(div_resources) < data->div_count); + + for (i = 0; i < data->div_count; i++) { + const struct eqc_div *div = &data->divs[i]; + void __iomem *base = NULL; + struct clk_hw *parent; + unsigned int j; + + /* + * Multiple divider clocks can request the same resource. Store + * resource pointers during probe(). For each divider clock, + * check if previous clocks referenced the same resource name. + * + * See EQ6HC_SOUTH_DIV_OSPI_REF and EQ6HC_SOUTH_DIV_OSPI_SYS. + */ + for (j = 0; j < i; j++) { + if (strcmp(data->divs[j].resource_name, div->resource_name) == 0) { + base = div_resources[j]; + break; + } + } + + /* Resource is first encountered. */ + if (!base) { + base = devm_platform_ioremap_resource_byname(pdev, div->resource_name); + if (IS_ERR(base)) { + dev_warn(dev, "failed to iomap resource for %s\n", div->name); + priv->cells->hws[div->index] = base; + continue; + } + } + + div_resources[i] = base; + + parent = priv->cells->hws[div->parent]; + hw = clk_hw_register_divider_table_parent_hw(dev, div->name, + parent, 0, base, div->shift, div->width, + CLK_DIVIDER_EVEN_INTEGERS, NULL, NULL); + priv->cells->hws[div->index] = hw; + if (IS_ERR(hw)) + dev_warn(dev, "failed registering %s: %pe\n", + div->name, hw); + } + + /* Clock provider has not been registered by eqc_init(). Do it now. */ + if (data->early_pll_count == 0) { + /* When providing a single clock, require no cell. */ + if (priv->cells->num == 1) + return devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get, + priv->cells->hws); + else + return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, + priv->cells); + } + + return 0; +} + +/* Required early for GIC timer (pll-cpu) and UARTs (pll-per). */ +static const struct eqc_pll eqc_eyeq5_early_plls[] = { + { .index = EQ5C_PLL_CPU, .name = "pll-cpu", .reg64 = 0x00, }, + { .index = EQ5C_PLL_PER, .name = "pll-per", .reg64 = 0x30, }, +}; + +static const struct eqc_pll eqc_eyeq5_plls[] = { + { .index = EQ5C_PLL_VMP, .name = "pll-vmp", .reg64 = 0x08, }, + { .index = EQ5C_PLL_PMA, .name = "pll-pma", .reg64 = 0x10, }, + { .index = EQ5C_PLL_VDI, .name = "pll-vdi", .reg64 = 0x18, }, + { .index = EQ5C_PLL_DDR0, .name = "pll-ddr0", .reg64 = 0x20, }, + { .index = EQ5C_PLL_PCI, .name = "pll-pci", .reg64 = 0x28, }, + { .index = EQ5C_PLL_PMAC, .name = "pll-pmac", .reg64 = 0x38, }, + { .index = EQ5C_PLL_MPC, .name = "pll-mpc", .reg64 = 0x40, }, + { .index = EQ5C_PLL_DDR1, .name = "pll-ddr1", .reg64 = 0x48, }, +}; + +static const struct eqc_div eqc_eyeq5_divs[] = { + { + .index = EQ5C_DIV_OSPI, + .name = "div-ospi", + .parent = EQ5C_PLL_PER, + .resource_name = "ospi", + .shift = 0, + .width = 4, + }, +}; + +static const struct eqc_match_data eqc_eyeq5_match_data = { + .early_pll_count = ARRAY_SIZE(eqc_eyeq5_early_plls), + .early_plls = eqc_eyeq5_early_plls, + + .pll_count = ARRAY_SIZE(eqc_eyeq5_plls), + .plls = eqc_eyeq5_plls, + + .div_count = ARRAY_SIZE(eqc_eyeq5_divs), + .divs = eqc_eyeq5_divs, +}; + +static const struct eqc_pll eqc_eyeq6l_plls[] = { + { .index = EQ6LC_PLL_DDR, .name = "pll-ddr", .reg64 = 0x2C }, + { .index = EQ6LC_PLL_CPU, .name = "pll-cpu", .reg64 = 0x34 }, /* also acc */ + { .index = EQ6LC_PLL_PER, .name = "pll-per", .reg64 = 0x3C }, + { .index = EQ6LC_PLL_VDI, .name = "pll-vdi", .reg64 = 0x44 }, +}; + +static const struct eqc_match_data eqc_eyeq6l_match_data = { + .pll_count = ARRAY_SIZE(eqc_eyeq6l_plls), + .plls = eqc_eyeq6l_plls, +}; + +/* Required early for GIC timer. */ +static const struct eqc_pll eqc_eyeq6h_central_early_plls[] = { + { .index = 0, .name = "pll-cpu", .reg64 = 0x00 }, +}; + +static const struct eqc_match_data eqc_eyeq6h_central_match_data = { + .early_pll_count = ARRAY_SIZE(eqc_eyeq6h_central_early_plls), + .early_plls = eqc_eyeq6h_central_early_plls, +}; + +/* Required early for UART. */ +static const struct eqc_pll eqc_eyeq6h_west_early_plls[] = { + { .index = 0, .name = "pll-west", .reg64 = 0x00 }, +}; + +static const struct eqc_match_data eqc_eyeq6h_west_match_data = { + .early_pll_count = ARRAY_SIZE(eqc_eyeq6h_west_early_plls), + .early_plls = eqc_eyeq6h_west_early_plls, +}; + +static const struct eqc_pll eqc_eyeq6h_east_plls[] = { + { .index = 0, .name = "pll-east", .reg64 = 0x00 }, +}; + +static const struct eqc_match_data eqc_eyeq6h_east_match_data = { + .pll_count = ARRAY_SIZE(eqc_eyeq6h_east_plls), + .plls = eqc_eyeq6h_east_plls, +}; + +static const struct eqc_pll eqc_eyeq6h_south_plls[] = { + { .index = EQ6HC_SOUTH_PLL_VDI, .name = "pll-vdi", .reg64 = 0x00 }, + { .index = EQ6HC_SOUTH_PLL_PCIE, .name = "pll-pcie", .reg64 = 0x08 }, + { .index = EQ6HC_SOUTH_PLL_PER, .name = "pll-per", .reg64 = 0x10 }, + { .index = EQ6HC_SOUTH_PLL_ISP, .name = "pll-isp", .reg64 = 0x18 }, +}; + +static const struct eqc_div eqc_eyeq6h_south_divs[] = { + { + .index = EQ6HC_SOUTH_DIV_EMMC, + .name = "div-emmc", + .parent = EQ6HC_SOUTH_PLL_PER, + .resource_name = "emmc", + .shift = 4, + .width = 4, + }, + { + .index = EQ6HC_SOUTH_DIV_OSPI_REF, + .name = "div-ospi-ref", + .parent = EQ6HC_SOUTH_PLL_PER, + .resource_name = "ospi", + .shift = 4, + .width = 4, + }, + { + .index = EQ6HC_SOUTH_DIV_OSPI_SYS, + .name = "div-ospi-sys", + .parent = EQ6HC_SOUTH_PLL_PER, + .resource_name = "ospi", + .shift = 8, + .width = 1, + }, + { + .index = EQ6HC_SOUTH_DIV_TSU, + .name = "div-tsu", + .parent = EQ6HC_SOUTH_PLL_PCIE, + .resource_name = "tsu", + .shift = 4, + .width = 8, + }, +}; + +static const struct eqc_match_data eqc_eyeq6h_south_match_data = { + .pll_count = ARRAY_SIZE(eqc_eyeq6h_south_plls), + .plls = eqc_eyeq6h_south_plls, + + .div_count = ARRAY_SIZE(eqc_eyeq6h_south_divs), + .divs = eqc_eyeq6h_south_divs, +}; + +static const struct eqc_pll eqc_eyeq6h_ddr0_plls[] = { + { .index = 0, .name = "pll-ddr0", .reg64 = 0x00 }, +}; + +static const struct eqc_match_data eqc_eyeq6h_ddr0_match_data = { + .pll_count = ARRAY_SIZE(eqc_eyeq6h_ddr0_plls), + .plls = eqc_eyeq6h_ddr0_plls, +}; + +static const struct eqc_pll eqc_eyeq6h_ddr1_plls[] = { + { .index = 0, .name = "pll-ddr1", .reg64 = 0x00 }, +}; + +static const struct eqc_match_data eqc_eyeq6h_ddr1_match_data = { + .pll_count = ARRAY_SIZE(eqc_eyeq6h_ddr1_plls), + .plls = eqc_eyeq6h_ddr1_plls, +}; + +static const struct eqc_pll eqc_eyeq6h_acc_plls[] = { + { .index = EQ6HC_ACC_PLL_XNN, .name = "pll-xnn", .reg64 = 0x00 }, + { .index = EQ6HC_ACC_PLL_VMP, .name = "pll-vmp", .reg64 = 0x10 }, + { .index = EQ6HC_ACC_PLL_PMA, .name = "pll-pma", .reg64 = 0x1C }, + { .index = EQ6HC_ACC_PLL_MPC, .name = "pll-mpc", .reg64 = 0x28 }, + { .index = EQ6HC_ACC_PLL_NOC, .name = "pll-noc", .reg64 = 0x30 }, +}; + +static const struct eqc_match_data eqc_eyeq6h_acc_match_data = { + .pll_count = ARRAY_SIZE(eqc_eyeq6h_acc_plls), + .plls = eqc_eyeq6h_acc_plls, +}; + +static const struct of_device_id eqc_match_table[] = { + { .compatible = "mobileye,eyeq5-clk", .data = &eqc_eyeq5_match_data }, + { .compatible = "mobileye,eyeq6l-clk", .data = &eqc_eyeq6l_match_data }, + { .compatible = "mobileye,eyeq6h-central-clk", .data = &eqc_eyeq6h_central_match_data }, + { .compatible = "mobileye,eyeq6h-west-clk", .data = &eqc_eyeq6h_west_match_data }, + { .compatible = "mobileye,eyeq6h-east-clk", .data = &eqc_eyeq6h_east_match_data }, + { .compatible = "mobileye,eyeq6h-south-clk", .data = &eqc_eyeq6h_south_match_data }, + { .compatible = "mobileye,eyeq6h-ddr0-clk", .data = &eqc_eyeq6h_ddr0_match_data }, + { .compatible = "mobileye,eyeq6h-ddr1-clk", .data = &eqc_eyeq6h_ddr1_match_data }, + { .compatible = "mobileye,eyeq6h-acc-clk", .data = &eqc_eyeq6h_acc_match_data }, + {} +}; +MODULE_DEVICE_TABLE(of, eqc_match_table); + +static struct platform_driver eqc_driver = { + .probe = eqc_probe, + .driver = { + .name = "clk-eyeq", + .of_match_table = eqc_match_table, + }, +}; +builtin_platform_driver(eqc_driver); + +static void __init eqc_init(struct device_node *np) +{ + const struct eqc_match_data *data; + unsigned int nb_clks = 0; + struct eqc_priv *priv; + unsigned int i; + int ret; + + data = of_match_node(eqc_match_table, np)->data; + + /* No reason to early init this clock provider. Do it at probe. */ + if (data->early_pll_count == 0) + return; + + priv = kzalloc(sizeof(*priv), GFP_KERNEL); + if (!priv) { + ret = -ENOMEM; + goto err; + } + + priv->np = np; + priv->data = data; + + nb_clks = eqc_compute_clock_count(data); + priv->cells = kzalloc(struct_size(priv->cells, hws, nb_clks), GFP_KERNEL); + if (!priv->cells) { + ret = -ENOMEM; + goto err; + } + + priv->cells->num = nb_clks; + + /* + * Mark non-early clocks as deferred; they'll be registered at platform + * device probe. + */ + for (i = 0; i < data->pll_count; i++) + priv->cells->hws[data->plls[i].index] = ERR_PTR(-EPROBE_DEFER); + for (i = 0; i < data->div_count; i++) + priv->cells->hws[data->divs[i].index] = ERR_PTR(-EPROBE_DEFER); + + /* + * We expect named resources if divider clocks are present. + * Else, we only expect one resource. + */ + if (data->div_count) + ret = of_property_match_string(np, "reg-names", "plls"); + else + ret = 0; + if (ret < 0) + goto err; + + priv->base_plls = of_iomap(np, ret); + if (!priv->base_plls) { + ret = -ENODEV; + goto err; + } + + for (i = 0; i < data->early_pll_count; i++) { + const struct eqc_pll *pll = &data->early_plls[i]; + unsigned long mult, div, acc; + struct clk_hw *hw; + u32 r0, r1; + u64 val; + + val = readq(priv->base_plls + pll->reg64); + r0 = val; + r1 = val >> 32; + + ret = eqc_pll_parse_registers(r0, r1, &mult, &div, &acc); + if (ret) { + pr_err("failed parsing state of %s\n", pll->name); + goto err; + } + + hw = clk_hw_register_fixed_factor_with_accuracy_fwname(NULL, + np, pll->name, "ref", 0, mult, div, acc); + priv->cells->hws[pll->index] = hw; + if (IS_ERR(hw)) { + pr_err("failed registering %s: %pe\n", pll->name, hw); + ret = PTR_ERR(hw); + goto err; + } + } + + /* When providing a single clock, require no cell. */ + if (nb_clks == 1) + ret = of_clk_add_hw_provider(np, of_clk_hw_simple_get, priv->cells->hws); + else + ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, priv->cells); + if (ret) { + pr_err("failed registering clk provider: %d\n", ret); + goto err; + } + + spin_lock(&eqc_list_slock); + list_add_tail(&priv->list, &eqc_list); + spin_unlock(&eqc_list_slock); + + return; + +err: + /* + * We are doomed. The system will not be able to boot. + * + * Let's still try to be good citizens by freeing resources and print + * a last error message that might help debugging. + */ + + if (priv && priv->cells) { + of_clk_del_provider(np); + + for (i = 0; i < data->early_pll_count; i++) { + const struct eqc_pll *pll = &data->early_plls[i]; + struct clk_hw *hw = priv->cells->hws[pll->index]; + + if (!IS_ERR_OR_NULL(hw)) + clk_hw_unregister_fixed_factor(hw); + } + + kfree(priv->cells); + } + + kfree(priv); + + pr_err("failed clk init: %d\n", ret); +} + +CLK_OF_DECLARE_DRIVER(eqc_eyeq5, "mobileye,eyeq5-clk", eqc_init); +CLK_OF_DECLARE_DRIVER(eqc_eyeq6h_central, "mobileye,eyeq6h-central-clk", eqc_init); +CLK_OF_DECLARE_DRIVER(eqc_eyeq6h_west, "mobileye,eyeq6h-west-clk", eqc_init); From patchwork Wed Apr 10 17:12:35 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Th=C3=A9o_Lebrun?= X-Patchwork-Id: 788093 Received: from relay5-d.mail.gandi.net (relay5-d.mail.gandi.net [217.70.183.197]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 29C6D17F378; Wed, 10 Apr 2024 17:12:38 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.70.183.197 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712769162; cv=none; b=oN+TcoQBLQPRwMtYss3FKzAW70hZDTihEgQRX4nKudFIKmG2jwNMEwp96B/Gh58U4ofcOLXGYZq9YqF6+dH3hc2R2MquOP5MGME2Hp+z3QVV7KmBVNDa37WD4pEv2dqBlD6z9gHJO9JxVcFZos3Es8OrMnPNtuIAFELVTRnP2UE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712769162; c=relaxed/simple; bh=ncjuiruGK7KVZynliMCN40InmP0Dyuxd8Sbe5b0jHKE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=YgNagmEYPmE2RX4IJX/LRdCgAUHtYO1gz3tvJZLdK2onxJHQluA5bRLJRxUWh9vz30DjYBR6cmp4c9DAgO7tsPjTh62CWgE+SCkkSYZzP46UvhocYCTcFAxbqT+ZbXDknSgLfZj1Tc1pqdVtRcnRURYekVWrHzf2/AFsEDKk3jQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=Y3StIyf5; arc=none smtp.client-ip=217.70.183.197 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="Y3StIyf5" Received: by mail.gandi.net (Postfix) with ESMTPSA id D56601C0004; Wed, 10 Apr 2024 17:12:36 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1712769157; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=pUUIwlAbbXnFukNZQdVdHo6dl+nUqCJC6HGy9p3cg/g=; b=Y3StIyf5yJddskzCK2gxo3UqKUDu7LuGkUGHMMGQ9qOOwwv+M7rq+q+r549vwWceoIRzpY 6WtJJ9tKs4utcyDCV7rVnnPFscaqB2NbCl4kV+PEIBYvqzAxuuKef2eiDCRaKCjC/bhZP5 dzkoChF3Wy4k/ygjNoBl86yjK5y/D5ZUMZCA9Na8l80H66TAjTCWkRd2YCScAX3M6ss5YS 3hZvW6Wf6fuqGreW+zJQ4rqmwXK+6fV17wMQ1WRNMH6L1Hks9ouIlZj5coNBOninNwGHtG Oh9IAHrVfhdpyTk185ZcStNgvRxt2apnSYEVCpd9xSoJwB6MKzaMNPFJDypZYw== From: =?utf-8?q?Th=C3=A9o_Lebrun?= Date: Wed, 10 Apr 2024 19:12:35 +0200 Subject: [PATCH 06/11] reset: eyeq: add platform driver Precedence: bulk X-Mailing-List: linux-gpio@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240410-mbly-olb-v1-6-335e496d7be3@bootlin.com> References: <20240410-mbly-olb-v1-0-335e496d7be3@bootlin.com> In-Reply-To: <20240410-mbly-olb-v1-0-335e496d7be3@bootlin.com> To: Rob Herring , Krzysztof Kozlowski , Conor Dooley , Michael Turquette , Stephen Boyd , Philipp Zabel , Linus Walleij Cc: linux-mips@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-clk@vger.kernel.org, linux-gpio@vger.kernel.org, Vladimir Kondratiev , Gregory CLEMENT , Thomas Petazzoni , Tawfik Bayouk , =?utf-8?q?Th=C3=A9o_Lebrun?= X-Mailer: b4 0.13.0 X-GND-Sasl: theo.lebrun@bootlin.com Add Mobileye EyeQ reset controller driver, for EyeQ5, EyeQ6L and EyeQ6H SoCs. Instances belong to a shared register region called OLB. There is one OLB instance for EyeQ5 and EyeQ6L. There are seven OLB instances on EyeQ6H; three have a reset controller embedded: - West and east get handled by the same compatible. - Acc is another one. Each instance vary in the number and types of reset domains. Signed-off-by: Théo Lebrun --- MAINTAINERS | 1 + drivers/reset/Kconfig | 13 ++ drivers/reset/Makefile | 1 + drivers/reset/reset-eyeq.c | 543 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 558 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 33168ebf3cc5..724f20ea0411 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -14933,6 +14933,7 @@ F: arch/mips/boot/dts/mobileye/ F: arch/mips/configs/eyeq5_defconfig F: arch/mips/mobileye/board-epm5.its.S F: drivers/clk/clk-eyeq5.c +F: drivers/reset/reset-eyeq5.c F: include/dt-bindings/clock/mobileye,eyeq5-clk.h MODULE SUPPORT diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig index 85b27c42cf65..18ee99ed8ecc 100644 --- a/drivers/reset/Kconfig +++ b/drivers/reset/Kconfig @@ -66,6 +66,19 @@ config RESET_BRCMSTB_RESCAL This enables the RESCAL reset controller for SATA, PCIe0, or PCIe1 on BCM7216. +config RESET_EYEQ + bool "Mobileye EyeQ reset controller" + depends on MFD_SYSCON + depends on MACH_EYEQ5 || MACH_EYEQ6H || COMPILE_TEST + default MACH_EYEQ5 || MACH_EYEQ6H + help + This enables the Mobileye EyeQ reset controller, used in EyeQ5, EyeQ6L + and EyeQ6H SoCs. + + It has one or more domains, with a varying number of resets in each. + Registers are located in a shared register region called OLB. EyeQ6H + has multiple reset instances. + config RESET_GPIO tristate "GPIO reset controller" help diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile index fd8b49fa46fc..a4e6fea29800 100644 --- a/drivers/reset/Makefile +++ b/drivers/reset/Makefile @@ -11,6 +11,7 @@ obj-$(CONFIG_RESET_BCM6345) += reset-bcm6345.o obj-$(CONFIG_RESET_BERLIN) += reset-berlin.o obj-$(CONFIG_RESET_BRCMSTB) += reset-brcmstb.o obj-$(CONFIG_RESET_BRCMSTB_RESCAL) += reset-brcmstb-rescal.o +obj-$(CONFIG_RESET_EYEQ) += reset-eyeq.o obj-$(CONFIG_RESET_GPIO) += reset-gpio.o obj-$(CONFIG_RESET_HSDK) += reset-hsdk.o obj-$(CONFIG_RESET_IMX7) += reset-imx7.o diff --git a/drivers/reset/reset-eyeq.c b/drivers/reset/reset-eyeq.c new file mode 100644 index 000000000000..b86930145256 --- /dev/null +++ b/drivers/reset/reset-eyeq.c @@ -0,0 +1,543 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Reset driver for the Mobileye EyeQ5, EyeQ6L and EyeQ6H platforms. + * + * Controllers live in a shared register region called OLB. EyeQ5 and EyeQ6L + * have a single OLB instance for a single reset controller. EyeQ6H has seven + * OLB instances; three host reset controllers. + * + * Each reset controller has one or more domain. Domains are of a given type + * (see enum eqr_domain_type), with a valid offset mask (up to 32 resets per + * domain). + * + * Domain types define expected behavior: one-register-per-reset, + * one-bit-per-reset, status detection method, busywait duration, etc. + * + * We use eqr_ as prefix, as-in "EyeQ Reset", but way shorter. + * + * Known resets in EyeQ5 domain 0 (type EQR_EYEQ5_SARCR): + * 3. CAN0 4. CAN1 5. CAN2 6. SPI0 + * 7. SPI1 8. SPI2 9. SPI3 10. UART0 + * 11. UART1 12. UART2 13. I2C0 14. I2C1 + * 15. I2C2 16. I2C3 17. I2C4 18. TIMER0 + * 19. TIMER1 20. TIMER2 21. TIMER3 22. TIMER4 + * 23. WD0 24. EXT0 25. EXT1 26. GPIO + * 27. WD1 + * + * Known resets in EyeQ5 domain 1 (type EQR_EYEQ5_ACRP): + * 0. VMP0 1. VMP1 2. VMP2 3. VMP3 + * 4. PMA0 5. PMA1 6. PMAC0 7. PMAC1 + * 8. MPC0 9. MPC1 10. MPC2 11. MPC3 + * 12. MPC4 + * + * Known resets in EyeQ5 domain 2 (type EQR_EYEQ5_PCIE): + * 0. PCIE0_CORE 1. PCIE0_APB 2. PCIE0_LINK_AXI 3. PCIE0_LINK_MGMT + * 4. PCIE0_LINK_HOT 5. PCIE0_LINK_PIPE 6. PCIE1_CORE 7. PCIE1_APB + * 8. PCIE1_LINK_AXI 9. PCIE1_LINK_MGMT 10. PCIE1_LINK_HOT 11. PCIE1_LINK_PIPE + * 12. MULTIPHY 13. MULTIPHY_APB 15. PCIE0_LINK_MGMT 16. PCIE1_LINK_MGMT + * 17. PCIE0_LINK_PM 18. PCIE1_LINK_PM + * + * Known resets in EyeQ6L domain 0 (type EQR_EYEQ5_SARCR): + * 0. SPI0 1. SPI1 2. UART0 3. I2C0 + * 4. I2C1 5. TIMER0 6. TIMER1 7. TIMER2 + * 8. TIMER3 9. WD0 10. WD1 11. EXT0 + * 12. EXT1 13. GPIO + * + * Known resets in EyeQ6L domain 1 (type EQR_EYEQ5_ACRP): + * 0. VMP0 1. VMP1 2. VMP2 3. VMP3 + * 4. PMA0 5. PMA1 6. PMAC0 7. PMAC1 + * 8. MPC0 9. MPC1 10. MPC2 11. MPC3 + * 12. MPC4 + * + * Known resets in EyeQ6H west/east (type EQR_EYEQ6H_SARCR): + * 0. CAN 1. SPI0 2. SPI1 3. UART0 + * 4. UART1 5. I2C0 6. I2C1 7. -hole- + * 8. TIMER0 9. TIMER1 10. WD 11. EXT TIMER + * 12. GPIO + * + * Known resets in EyeQ6H acc (type EQR_EYEQ5_ACRP): + * 1. XNN0 2. XNN1 3. XNN2 4. XNN3 + * 5. VMP0 6. VMP1 7. VMP2 8. VMP3 + * 9. PMA0 10. PMA1 11. MPC0 12. MPC1 + * 13. MPC2 14. MPC3 15. PERIPH + * + * Abbreviations: + * - PMA: Programmable Macro Array + * - MPC: Multi-threaded Processing Clusters + * - VMP: Vector Microcode Processors + * + * Copyright (C) 2024 Mobileye Vision Technologies Ltd. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * A reset ID, as returned by eqr_of_xlate, is a (domain, offset) pair. + * Low byte is domain, rest is offset. + */ +#define ID_DOMAIN_MASK GENMASK(7, 0) +#define ID_OFFSET_MASK GENMASK(31, 8) + +enum eqr_domain_type { + EQR_EYEQ5_SARCR, + EQR_EYEQ5_ACRP, + EQR_EYEQ5_PCIE, + EQR_EYEQ6H_SARCR, +}; + +/* + * Domain type EQR_EYEQ5_SARCR register offsets. + */ +#define EQR_EYEQ5_SARCR_REQUEST (0x004) +#define EQR_EYEQ5_SARCR_STATUS (0x008) + +/* + * Domain type EQR_EYEQ5_ACRP register masks. + * Registers are: base + 4 * offset. + */ +#define EQR_EYEQ5_ACRP_PD_REQ BIT(0) +#define EQR_EYEQ5_ACRP_ST_POWER_DOWN BIT(27) +#define EQR_EYEQ5_ACRP_ST_ACTIVE BIT(29) + +/* + * Domain type EQR_EYEQ6H_SARCR register offsets. + */ +#define EQR_EYEQ6H_SARCR_RST_REQUEST (0x004) +#define EQR_EYEQ6H_SARCR_CLK_STATUS (0x008) +#define EQR_EYEQ6H_SARCR_RST_STATUS (0x00C) +#define EQR_EYEQ6H_SARCR_CLK_REQUEST (0x010) + +struct eqr_busy_wait_timings { + unsigned long sleep_us; + unsigned long timeout_us; +}; + +static const struct eqr_busy_wait_timings eqr_timings[] = { + [EQR_EYEQ5_SARCR] = {1, 10}, + [EQR_EYEQ5_ACRP] = {1, 40 * USEC_PER_MSEC}, /* LBIST implies long timeout. */ + /* EQR_EYEQ5_PCIE does no busy waiting. */ + [EQR_EYEQ6H_SARCR] = {1, 400}, +}; + +#define EQR_MAX_DOMAIN_COUNT 3 + +struct eqr_domain_descriptor { + const char *resource_name; + enum eqr_domain_type type; + u32 valid_mask; +}; + +struct eqr_match_data { + unsigned int domain_count; + const struct eqr_domain_descriptor *domains; +}; + +struct eqr_private { + struct mutex mutexes[EQR_MAX_DOMAIN_COUNT]; + void __iomem *bases[EQR_MAX_DOMAIN_COUNT]; + const struct eqr_match_data *data; + struct reset_controller_dev rcdev; +}; + +#define rcdev_to_priv(rcdev) container_of(rcdev, struct eqr_private, rcdev) + +static u32 eqr_double_readl(void __iomem *addr_a, void __iomem *addr_b, + u32 *dest_a, u32 *dest_b) +{ + *dest_a = readl(addr_a); + *dest_b = readl(addr_b); + return 0; /* read_poll_timeout() op argument must return something. */ +} + +static int eqr_busy_wait_locked(struct eqr_private *priv, struct device *dev, + u32 domain, u32 offset, bool assert) +{ + enum eqr_domain_type domain_type = priv->data->domains[domain].type; + unsigned long sleep_us, timeout_us; + u32 val, mask, val0, val1; + void __iomem *base, *reg; + int ret; + + lockdep_assert_held(&priv->mutexes[domain]); + + base = priv->bases[domain]; + sleep_us = eqr_timings[domain_type].sleep_us; + timeout_us = eqr_timings[domain_type].timeout_us; + + switch (domain_type) { + case EQR_EYEQ5_SARCR: + reg = base + EQR_EYEQ5_SARCR_STATUS; + mask = BIT(offset); + + ret = readl_poll_timeout(reg, val, !(val & mask) == assert, + sleep_us, timeout_us); + break; + + case EQR_EYEQ5_ACRP: + reg = base + 4 * offset; + if (assert) + mask = EQR_EYEQ5_ACRP_ST_POWER_DOWN; + else + mask = EQR_EYEQ5_ACRP_ST_ACTIVE; + + ret = readl_poll_timeout(reg, val, !!(val & mask), + sleep_us, timeout_us); + break; + + case EQR_EYEQ5_PCIE: + ret = 0; /* No busy waiting. */ + break; + + case EQR_EYEQ6H_SARCR: + /* + * Wait until both bits change: + * readl(base + EQR_EYEQ6H_SARCR_RST_STATUS) & BIT(offset) + * readl(base + EQR_EYEQ6H_SARCR_CLK_STATUS) & BIT(offset) + */ + mask = BIT(offset); + ret = read_poll_timeout(eqr_double_readl, val, + (!(val0 & mask) == assert) && + (!(val1 & mask) == assert), + sleep_us, timeout_us, false, + base + EQR_EYEQ6H_SARCR_RST_STATUS, + base + EQR_EYEQ6H_SARCR_CLK_STATUS, + &val0, &val1); + break; + + default: + WARN_ON(1); + ret = -EINVAL; + break; + } + + if (ret == -ETIMEDOUT) + dev_dbg(dev, "%u-%u: timeout\n", domain, offset); + return ret; +} + +static void eqr_assert_locked(struct eqr_private *priv, u32 domain, + u32 offset) +{ + enum eqr_domain_type domain_type = priv->data->domains[domain].type; + void __iomem *base, *reg; + u32 val; + + lockdep_assert_held(&priv->mutexes[domain]); + + base = priv->bases[domain]; + + switch (domain_type) { + case EQR_EYEQ5_SARCR: + reg = base + EQR_EYEQ5_SARCR_REQUEST; + writel(readl(reg) & ~BIT(offset), reg); + break; + + case EQR_EYEQ5_ACRP: + reg = base + 4 * offset; + writel(readl(reg) | EQR_EYEQ5_ACRP_PD_REQ, reg); + break; + + case EQR_EYEQ5_PCIE: + writel(readl(base) & ~BIT(offset), base); + break; + + case EQR_EYEQ6H_SARCR: + val = readl(base + EQR_EYEQ6H_SARCR_RST_REQUEST); + val &= ~BIT(offset); + writel(val, base + EQR_EYEQ6H_SARCR_RST_REQUEST); + writel(val, base + EQR_EYEQ6H_SARCR_CLK_REQUEST); + break; + + default: + WARN_ON(1); + break; + } +} + +static int eqr_assert(struct reset_controller_dev *rcdev, unsigned long id) +{ + struct eqr_private *priv = rcdev_to_priv(rcdev); + u32 domain = FIELD_GET(ID_DOMAIN_MASK, id); + u32 offset = FIELD_GET(ID_OFFSET_MASK, id); + + dev_dbg(rcdev->dev, "%u-%u: assert request\n", domain, offset); + + guard(mutex)(&priv->mutexes[domain]); + eqr_assert_locked(priv, domain, offset); + return eqr_busy_wait_locked(priv, rcdev->dev, domain, offset, true); +} + +static void eqr_deassert_locked(struct eqr_private *priv, u32 domain, + u32 offset) +{ + enum eqr_domain_type domain_type = priv->data->domains[domain].type; + void __iomem *base, *reg; + u32 val; + + lockdep_assert_held(&priv->mutexes[domain]); + + base = priv->bases[domain]; + + switch (domain_type) { + case EQR_EYEQ5_SARCR: + reg = base + EQR_EYEQ5_SARCR_REQUEST; + writel(readl(reg) | BIT(offset), reg); + break; + + case EQR_EYEQ5_ACRP: + reg = base + 4 * offset; + writel(readl(reg) & ~EQR_EYEQ5_ACRP_PD_REQ, reg); + break; + + case EQR_EYEQ5_PCIE: + writel(readl(base) | BIT(offset), base); + break; + + case EQR_EYEQ6H_SARCR: + val = readl(base + EQR_EYEQ6H_SARCR_RST_REQUEST); + val |= BIT(offset); + writel(val, base + EQR_EYEQ6H_SARCR_RST_REQUEST); + writel(val, base + EQR_EYEQ6H_SARCR_CLK_REQUEST); + break; + + default: + WARN_ON(1); + break; + } +} + +static int eqr_deassert(struct reset_controller_dev *rcdev, unsigned long id) +{ + struct eqr_private *priv = rcdev_to_priv(rcdev); + u32 domain = FIELD_GET(ID_DOMAIN_MASK, id); + u32 offset = FIELD_GET(ID_OFFSET_MASK, id); + + dev_dbg(rcdev->dev, "%u-%u: deassert request\n", domain, offset); + + guard(mutex)(&priv->mutexes[domain]); + eqr_deassert_locked(priv, domain, offset); + return eqr_busy_wait_locked(priv, rcdev->dev, domain, offset, false); +} + +static int eqr_status(struct reset_controller_dev *rcdev, unsigned long id) +{ + u32 domain = FIELD_GET(ID_DOMAIN_MASK, id); + struct eqr_private *priv = rcdev_to_priv(rcdev); + enum eqr_domain_type domain_type = priv->data->domains[domain].type; + u32 offset = FIELD_GET(ID_OFFSET_MASK, id); + void __iomem *base, *reg; + + dev_dbg(rcdev->dev, "%u-%u: status request\n", domain, offset); + + guard(mutex)(&priv->mutexes[domain]); + + base = priv->bases[domain]; + + switch (domain_type) { + case EQR_EYEQ5_SARCR: + reg = base + EQR_EYEQ5_SARCR_STATUS; + return !(readl(reg) & BIT(offset)); + case EQR_EYEQ5_ACRP: + reg = base + 4 * offset; + return !(readl(reg) & EQR_EYEQ5_ACRP_ST_ACTIVE); + case EQR_EYEQ5_PCIE: + return !(readl(base) & BIT(offset)); + case EQR_EYEQ6H_SARCR: + reg = base + EQR_EYEQ6H_SARCR_RST_STATUS; + return !(readl(reg) & BIT(offset)); + default: + return -EINVAL; + } +} + +static const struct reset_control_ops eqr_ops = { + .assert = eqr_assert, + .deassert = eqr_deassert, + .status = eqr_status, +}; + +static int eqr_of_xlate(struct reset_controller_dev *rcdev, + const struct of_phandle_args *reset_spec) +{ + struct eqr_private *priv = rcdev_to_priv(rcdev); + u32 domain, offset; + + /* Args count is expected to be 1 iff domain count is 1. */ + if (reset_spec->args_count == 1) { + WARN_ON(priv->data->domain_count > 1); + domain = 0; + offset = reset_spec->args[0]; + } else if (reset_spec->args_count == 2) { + WARN_ON(priv->data->domain_count < 2); + domain = reset_spec->args[0]; + offset = reset_spec->args[1]; + } else { + return -EINVAL; + } + + if (domain >= priv->data->domain_count || offset > 31 || + !(priv->data->domains[domain].valid_mask & BIT(offset))) { + dev_err(rcdev->dev, "%u-%u: invalid reset\n", domain, offset); + return -EINVAL; + } + + return FIELD_PREP(ID_DOMAIN_MASK, domain) | FIELD_PREP(ID_OFFSET_MASK, offset); +} + +static int eqr_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + struct eqr_private *priv; + unsigned int i; + int ret; + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + priv->data = device_get_match_data(dev); + if (!priv->data) + return -ENODEV; + + priv->rcdev.ops = &eqr_ops; + priv->rcdev.owner = THIS_MODULE; + priv->rcdev.dev = dev; + priv->rcdev.of_node = np; + priv->rcdev.of_xlate = eqr_of_xlate; + + if (priv->data->domain_count == 1) { + priv->rcdev.of_reset_n_cells = 1; + + /* Single domain means single unnamed resource. Ignore resource name. */ + priv->bases[0] = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(priv->bases[0])) + return PTR_ERR(priv->bases[0]); + } else { + priv->rcdev.of_reset_n_cells = 2; + + /* Multiple domains means named resources. */ + for (i = 0; i < priv->data->domain_count; i++) { + const char *res_name = priv->data->domains[i].resource_name; + + priv->bases[i] = devm_platform_ioremap_resource_byname(pdev, res_name); + if (IS_ERR(priv->bases[i])) + return PTR_ERR(priv->bases[i]); + } + } + + for (i = 0; i < priv->data->domain_count; i++) + mutex_init(&priv->mutexes[i]); + + priv->rcdev.nr_resets = 0; + for (i = 0; i < priv->data->domain_count; i++) + priv->rcdev.nr_resets += hweight32(priv->data->domains[i].valid_mask); + + ret = devm_reset_controller_register(dev, &priv->rcdev); + if (ret) + return dev_err_probe(dev, ret, "failed registering reset controller\n"); + + return 0; +} + +static const struct eqr_domain_descriptor eqr_eyeq5_domains[] = { + { + .resource_name = "d0", + .type = EQR_EYEQ5_SARCR, + .valid_mask = 0xFFFFFF8, + }, + { + .resource_name = "d1", + .type = EQR_EYEQ5_ACRP, + .valid_mask = 0x0001FFF, + }, + { + .resource_name = "d2", + .type = EQR_EYEQ5_PCIE, + .valid_mask = 0x007BFFF, + }, +}; + +static const struct eqr_match_data eqr_eyeq5_data = { + .domain_count = ARRAY_SIZE(eqr_eyeq5_domains), + .domains = eqr_eyeq5_domains, +}; + +static const struct eqr_domain_descriptor eqr_eyeq6l_domains[] = { + { + .resource_name = "d0", + .type = EQR_EYEQ5_SARCR, + .valid_mask = 0x3FFF, + }, + { + .resource_name = "d1", + .type = EQR_EYEQ5_ACRP, + .valid_mask = 0x00FF, + }, +}; + +static const struct eqr_match_data eqr_eyeq6l_data = { + .domain_count = ARRAY_SIZE(eqr_eyeq6l_domains), + .domains = eqr_eyeq6l_domains, +}; + +/* West and east OLBs each have an instance. */ +static const struct eqr_domain_descriptor eqr_eyeq6h_we_domains[] = { + { + .type = EQR_EYEQ6H_SARCR, + .valid_mask = 0x1F7F, + }, +}; + +static const struct eqr_match_data eqr_eyeq6h_we_data = { + .domain_count = ARRAY_SIZE(eqr_eyeq6h_we_domains), + .domains = eqr_eyeq6h_we_domains, +}; + +static const struct eqr_domain_descriptor eqr_eyeq6h_acc_domains[] = { + { + .type = EQR_EYEQ5_ACRP, + .valid_mask = 0x7FFF, + }, +}; + +static const struct eqr_match_data eqr_eyeq6h_acc_data = { + .domain_count = ARRAY_SIZE(eqr_eyeq6h_acc_domains), + .domains = eqr_eyeq6h_acc_domains, +}; + +static const struct of_device_id eqr_match_table[] = { + { .compatible = "mobileye,eyeq5-reset", .data = &eqr_eyeq5_data }, + { .compatible = "mobileye,eyeq6l-reset", .data = &eqr_eyeq6l_data }, + { .compatible = "mobileye,eyeq6h-we-reset", .data = &eqr_eyeq6h_we_data }, + { .compatible = "mobileye,eyeq6h-acc-reset", .data = &eqr_eyeq6h_acc_data }, + {} +}; + +static struct platform_driver eqr_driver = { + .probe = eqr_probe, + .driver = { + .name = "eyeq5-reset", + .of_match_table = eqr_match_table, + }, +}; +builtin_platform_driver(eqr_driver); From patchwork Wed Apr 10 17:12:36 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Th=C3=A9o_Lebrun?= X-Patchwork-Id: 787715 Received: from relay5-d.mail.gandi.net (relay5-d.mail.gandi.net [217.70.183.197]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E27F117F392; Wed, 10 Apr 2024 17:12:39 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.70.183.197 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712769165; cv=none; b=ZOODOm8QH1cdyDCMmBHkXq6AtzAzrlCszUEZgH4oLN05MOWYyQVV8QGhKzxUM4FYHZ7/aoDG1neDPU81qS0T/dII+3m742Be09hMSOFtDqBwlEkWzXlLgf/CudnYi1YDJLuu1QjYZOoSwNoy3ojvTX3z+Q7YG32SdcCTC5Am0KU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712769165; c=relaxed/simple; bh=3Au8wB17RAoXtsjRHEF1jN6BfBa+st2YYzr2OS+ooWM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=T12DgazU70If37piZWbb0MVISEkSpE+AaYUnkK8wSTdllBls9mbxpdG+1JBYQTYlL7j7dGFC8hv7jKyEeEsYWNUjAaDtCvjFUJEI05Gm5Bd9jhtncVRt1zlpXJsao7yp1Ko6609UNNBluNP9dbWEOk7BCTXfF/2jPV2oQ2ECZ4s= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=Sx9JzVa1; arc=none smtp.client-ip=217.70.183.197 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="Sx9JzVa1" Received: by mail.gandi.net (Postfix) with ESMTPSA id 972831C000D; Wed, 10 Apr 2024 17:12:37 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1712769158; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=zfLlor1xaCp1w8OTca4EvPsTR/uzHR1DlZe8GP4b4Jw=; b=Sx9JzVa1BkBLppYP/Peygx9S504ZSLPukDmkE18ZRhjdQ1iPVdG4UvXUwd3Q28dqwgnKGD FwE7IMb/Q/DYi0Pkr+cIwR/zvJ9UdxCGIAwxbwxtnKLJYf2Ewu0xlIjt4My75tj4Zmj61o 5JGxPCEudho1rD2/Gv18XTRtiO4YsCQ9uP1PwEvbwb+yhOhxRhJNrnptXuCte3Hi4WUK54 NnyJXoCU3+g2lw0RJB4FtAneuUgol83q5OENHAdF/4ICqe8mL2lRfjeXLC+budToVmTWza 4ot2pGHVa2X2seaaqHNB8tIQ5FuvyooSpV2HIxmgKezIQ4xC13CUU0UUbZpDUg== From: =?utf-8?q?Th=C3=A9o_Lebrun?= Date: Wed, 10 Apr 2024 19:12:36 +0200 Subject: [PATCH 07/11] pinctrl: eyeq5: add platform driver Precedence: bulk X-Mailing-List: linux-gpio@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240410-mbly-olb-v1-7-335e496d7be3@bootlin.com> References: <20240410-mbly-olb-v1-0-335e496d7be3@bootlin.com> In-Reply-To: <20240410-mbly-olb-v1-0-335e496d7be3@bootlin.com> To: Rob Herring , Krzysztof Kozlowski , Conor Dooley , Michael Turquette , Stephen Boyd , Philipp Zabel , Linus Walleij Cc: linux-mips@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-clk@vger.kernel.org, linux-gpio@vger.kernel.org, Vladimir Kondratiev , Gregory CLEMENT , Thomas Petazzoni , Tawfik Bayouk , =?utf-8?q?Th=C3=A9o_Lebrun?= X-Mailer: b4 0.13.0 X-GND-Sasl: theo.lebrun@bootlin.com Add the Mobileye EyeQ5 pin controller driver. It belongs to a syscon region called OLB. Existing pins and their function live statically in the driver code rather than in the devicetree, see compatible match data. Reviewed-by: Linus Walleij Signed-off-by: Théo Lebrun --- MAINTAINERS | 2 + drivers/pinctrl/Kconfig | 14 + drivers/pinctrl/Makefile | 1 + drivers/pinctrl/pinctrl-eyeq5.c | 579 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 596 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 724f20ea0411..5cede8039c1b 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -14927,12 +14927,14 @@ L: linux-mips@vger.kernel.org S: Maintained F: Documentation/devicetree/bindings/clock/mobileye,eyeq5-clk.yaml F: Documentation/devicetree/bindings/mips/mobileye.yaml +F: Documentation/devicetree/bindings/pinctrl/mobileye,eyeq5-pinctrl.yaml F: Documentation/devicetree/bindings/reset/mobileye,eyeq5-reset.yaml F: Documentation/devicetree/bindings/soc/mobileye/ F: arch/mips/boot/dts/mobileye/ F: arch/mips/configs/eyeq5_defconfig F: arch/mips/mobileye/board-epm5.its.S F: drivers/clk/clk-eyeq5.c +F: drivers/pinctrl/pinctrl-eyeq5.c F: drivers/reset/reset-eyeq5.c F: include/dt-bindings/clock/mobileye,eyeq5-clk.h diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index d45657aa986a..b266326372e2 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -213,6 +213,20 @@ config PINCTRL_EQUILIBRIUM desired pin functions, configure GPIO attributes for LGM SoC pins. Pin muxing and pin config settings are retrieved from device tree. +config PINCTRL_EYEQ5 + bool "Mobileye EyeQ5 pinctrl driver" + depends on MACH_EYEQ5 || COMPILE_TEST + select PINMUX + select GENERIC_PINCONF + select MFD_SYSCON + default MACH_EYEQ5 + help + Pin controller driver for the Mobileye EyeQ5 platform. It does both + pin config & pin muxing. It does not handle GPIO. + + Pin muxing supports two functions for each pin: first is GPIO, second + is pin-dependent. Pin config is about bias & drive strength. + config PINCTRL_GEMINI bool depends on ARCH_GEMINI diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile index 2152539b53d5..6113e980cdb2 100644 --- a/drivers/pinctrl/Makefile +++ b/drivers/pinctrl/Makefile @@ -23,6 +23,7 @@ obj-$(CONFIG_PINCTRL_DA850_PUPD) += pinctrl-da850-pupd.o obj-$(CONFIG_PINCTRL_DA9062) += pinctrl-da9062.o obj-$(CONFIG_PINCTRL_DIGICOLOR) += pinctrl-digicolor.o obj-$(CONFIG_PINCTRL_EQUILIBRIUM) += pinctrl-equilibrium.o +obj-$(CONFIG_PINCTRL_EYEQ5) += pinctrl-eyeq5.o obj-$(CONFIG_PINCTRL_GEMINI) += pinctrl-gemini.o obj-$(CONFIG_PINCTRL_INGENIC) += pinctrl-ingenic.o obj-$(CONFIG_PINCTRL_K210) += pinctrl-k210.o diff --git a/drivers/pinctrl/pinctrl-eyeq5.c b/drivers/pinctrl/pinctrl-eyeq5.c new file mode 100644 index 000000000000..3228fc2a026e --- /dev/null +++ b/drivers/pinctrl/pinctrl-eyeq5.c @@ -0,0 +1,579 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Pinctrl driver for the Mobileye EyeQ5 platform. + * + * The registers are located in a syscon region called OLB. There are two pin + * banks, each being controlled by 5 registers (see enum eq5p_regs) for + * pull-down, pull-up, drive strength and muxing. + * + * For each pin, muxing is between two functions: (0) GPIO or (1) another one + * that is pin-dependent. Functions are declared statically in this driver. + * + * We create pinctrl groups that are 1:1 equivalent to pins: each group has a + * single pin, and its index/selector is the pin number. + * + * We use eq5p_ as prefix, as-in "EyeQ5 Pinctrl", but way shorter. + * + * Copyright (C) 2024 Mobileye Vision Technologies Ltd. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "core.h" +#include "pinctrl-utils.h" + +struct eq5p_pinctrl { + struct pinctrl_desc desc; + void __iomem *base; +}; + +enum eq5p_bank { + EQ5P_BANK_A, + EQ5P_BANK_B, + + EQ5P_BANK_COUNT, +}; + +enum eq5p_regs { + EQ5P_PD, + EQ5P_PU, + EQ5P_DS_LOW, + EQ5P_DS_HIGH, + EQ5P_IOCR, + + EQ5P_REG_COUNT, +}; + +static const unsigned int eq5p_regs[EQ5P_BANK_COUNT][EQ5P_REG_COUNT] = { + [EQ5P_BANK_A] = {0x010, 0x014, 0x020, 0x024, 0x000}, + [EQ5P_BANK_B] = {0x018, 0x01C, 0x028, 0x02C, 0x004}, +}; + +/* + * Drive strength; two bits per pin. + */ +#define EQ5P_DS_MASK GENMASK(1, 0) + +/* + * Comments to the right of each pin are the "signal name" in the datasheet. + */ +static const struct pinctrl_pin_desc eq5p_pins[] = { + /* Bank A */ + PINCTRL_PIN(0, "PA0"), /* A0_TIMER0_CK */ + PINCTRL_PIN(1, "PA1"), /* A1_TIMER0_EOC */ + PINCTRL_PIN(2, "PA2"), /* A2_TIMER1_CK */ + PINCTRL_PIN(3, "PA3"), /* A3_TIMER1_EOC */ + PINCTRL_PIN(4, "PA4"), /* A4_TIMER2_CK */ + PINCTRL_PIN(5, "PA5"), /* A5_TIMER2_EOC */ + PINCTRL_PIN(6, "PA6"), /* A6_TIMER5_EXT_INCAP1 */ + PINCTRL_PIN(7, "PA7"), /* A7_TIMER5_EXT_INCAP2 */ + PINCTRL_PIN(8, "PA8"), /* A8_TIMER5_EXT_OUTCMP1 */ + PINCTRL_PIN(9, "PA9"), /* A9_TIMER5_EXT_OUTCMP2 */ + PINCTRL_PIN(10, "PA10"), /* A10_UART_0_TX */ + PINCTRL_PIN(11, "PA11"), /* A11_UART_0_RX */ + PINCTRL_PIN(12, "PA12"), /* A12_UART_1_TX */ + PINCTRL_PIN(13, "PA13"), /* A13_UART_1_RX */ + PINCTRL_PIN(14, "PA14"), /* A14_CAN_0_TX */ + PINCTRL_PIN(15, "PA15"), /* A15_CAN_0_RX */ + PINCTRL_PIN(16, "PA16"), /* A16_CAN_1_TX */ + PINCTRL_PIN(17, "PA17"), /* A17_CAN_1_RX */ + PINCTRL_PIN(18, "PA18"), /* A18_SPI_0_DO */ + PINCTRL_PIN(19, "PA19"), /* A19_SPI_0_DI */ + PINCTRL_PIN(20, "PA20"), /* A20_SPI_0_CK */ + PINCTRL_PIN(21, "PA21"), /* A21_SPI_0_CS0 */ + PINCTRL_PIN(22, "PA22"), /* A22_SPI_0_CS1 */ + PINCTRL_PIN(23, "PA23"), /* A23_SPI_1_DO */ + PINCTRL_PIN(24, "PA24"), /* A24_SPI_1_DI */ + PINCTRL_PIN(25, "PA25"), /* A25_SPI_1_CK */ + PINCTRL_PIN(26, "PA26"), /* A26_SPI_1_CS0 */ + PINCTRL_PIN(27, "PA27"), /* A27_SPI_1_CS1 */ + PINCTRL_PIN(28, "PA28"), /* A28_REF_CLK0 */ + +#define EQ5P_PIN_OFFSET_BANK_B 29 + + /* Bank B */ + PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 0, "PB0"), /* B0_TIMER3_CK */ + PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 1, "PB1"), /* B1_TIMER3_EOC */ + PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 2, "PB2"), /* B2_TIMER4_CK */ + PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 3, "PB3"), /* B3_TIMER4_EOC */ + PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 4, "PB4"), /* B4_TIMER6_EXT_INCAP1 */ + PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 5, "PB5"), /* B5_TIMER6_EXT_INCAP2 */ + PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 6, "PB6"), /* B6_TIMER6_EXT_OUTCMP1 */ + PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 7, "PB7"), /* B7_TIMER6_EXT_OUTCMP2 */ + PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 8, "PB8"), /* B8_UART_2_TX */ + PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 9, "PB9"), /* B9_UART_2_RX */ + PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 10, "PB10"), /* B10_CAN_2_TX */ + PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 11, "PB11"), /* B11_CAN_2_RX */ + PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 12, "PB12"), /* B12_SPI_2_DO */ + PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 13, "PB13"), /* B13_SPI_2_DI */ + PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 14, "PB14"), /* B14_SPI_2_CK */ + PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 15, "PB15"), /* B15_SPI_2_CS0 */ + PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 16, "PB16"), /* B16_SPI_2_CS1 */ + PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 17, "PB17"), /* B17_SPI_3_DO */ + PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 18, "PB18"), /* B18_SPI_3_DI */ + PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 19, "PB19"), /* B19_SPI_3_CK */ + PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 20, "PB20"), /* B20_SPI_3_CS0 */ + PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 21, "PB21"), /* B21_SPI_3_CS1 */ + PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 22, "PB22"), /* B22_MCLK0 */ +}; + +static const char * const gpio_groups[] = { + /* Bank A */ + "PA0", "PA1", "PA2", "PA3", "PA4", "PA5", "PA6", "PA7", + "PA8", "PA9", "PA10", "PA11", "PA12", "PA13", "PA14", "PA15", + "PA16", "PA17", "PA18", "PA19", "PA20", "PA21", "PA22", "PA23", + "PA24", "PA25", "PA26", "PA27", "PA28", + + /* Bank B */ + "PB0", "PB1", "PB2", "PB3", "PB4", "PB5", "PB6", "PB7", + "PB8", "PB9", "PB10", "PB11", "PB12", "PB13", "PB14", "PB15", + "PB16", "PB17", "PB18", "PB19", "PB20", "PB21", "PB22", +}; + +/* Groups of functions on bank A */ +static const char * const timer0_groups[] = { "PA0", "PA1" }; +static const char * const timer1_groups[] = { "PA2", "PA3" }; +static const char * const timer2_groups[] = { "PA4", "PA5" }; +static const char * const timer5_groups[] = { "PA6", "PA7", "PA8", "PA9" }; +static const char * const uart0_groups[] = { "PA10", "PA11" }; +static const char * const uart1_groups[] = { "PA12", "PA13" }; +static const char * const can0_groups[] = { "PA14", "PA15" }; +static const char * const can1_groups[] = { "PA16", "PA17" }; +static const char * const spi0_groups[] = { "PA18", "PA19", "PA20", "PA21", "PA22" }; +static const char * const spi1_groups[] = { "PA23", "PA24", "PA25", "PA26", "PA27" }; +static const char * const refclk0_groups[] = { "PA28" }; + +/* Groups of functions on bank B */ +static const char * const timer3_groups[] = { "PB0", "PB1" }; +static const char * const timer4_groups[] = { "PB2", "PB3" }; +static const char * const timer6_groups[] = { "PB4", "PB5", "PB6", "PB7" }; +static const char * const uart2_groups[] = { "PB8", "PB9" }; +static const char * const can2_groups[] = { "PB10", "PB11" }; +static const char * const spi2_groups[] = { "PB12", "PB13", "PB14", "PB15", "PB16" }; +static const char * const spi3_groups[] = { "PB17", "PB18", "PB19", "PB20", "PB21" }; +static const char * const mclk0_groups[] = { "PB22" }; + +static const struct pinfunction eq5p_functions[] = { + /* GPIO having a fixed index is depended upon, see GPIO_FUNC_SELECTOR. */ + PINCTRL_PINFUNCTION("gpio", gpio_groups, ARRAY_SIZE(gpio_groups)), +#define GPIO_FUNC_SELECTOR 0 + + /* Bank A functions */ + PINCTRL_PINFUNCTION("timer0", timer0_groups, ARRAY_SIZE(timer0_groups)), + PINCTRL_PINFUNCTION("timer1", timer1_groups, ARRAY_SIZE(timer1_groups)), + PINCTRL_PINFUNCTION("timer2", timer2_groups, ARRAY_SIZE(timer2_groups)), + PINCTRL_PINFUNCTION("timer5", timer5_groups, ARRAY_SIZE(timer5_groups)), + PINCTRL_PINFUNCTION("uart0", uart0_groups, ARRAY_SIZE(uart0_groups)), + PINCTRL_PINFUNCTION("uart1", uart1_groups, ARRAY_SIZE(uart1_groups)), + PINCTRL_PINFUNCTION("can0", can0_groups, ARRAY_SIZE(can0_groups)), + PINCTRL_PINFUNCTION("can1", can1_groups, ARRAY_SIZE(can1_groups)), + PINCTRL_PINFUNCTION("spi0", spi0_groups, ARRAY_SIZE(spi0_groups)), + PINCTRL_PINFUNCTION("spi1", spi1_groups, ARRAY_SIZE(spi1_groups)), + PINCTRL_PINFUNCTION("refclk0", refclk0_groups, ARRAY_SIZE(refclk0_groups)), + + /* Bank B functions */ + PINCTRL_PINFUNCTION("timer3", timer3_groups, ARRAY_SIZE(timer3_groups)), + PINCTRL_PINFUNCTION("timer4", timer4_groups, ARRAY_SIZE(timer4_groups)), + PINCTRL_PINFUNCTION("timer6", timer6_groups, ARRAY_SIZE(timer6_groups)), + PINCTRL_PINFUNCTION("uart2", uart2_groups, ARRAY_SIZE(uart2_groups)), + PINCTRL_PINFUNCTION("can2", can2_groups, ARRAY_SIZE(can2_groups)), + PINCTRL_PINFUNCTION("spi2", spi2_groups, ARRAY_SIZE(spi2_groups)), + PINCTRL_PINFUNCTION("spi3", spi3_groups, ARRAY_SIZE(spi3_groups)), + PINCTRL_PINFUNCTION("mclk0", mclk0_groups, ARRAY_SIZE(mclk0_groups)), +}; + +static void eq5p_update_bits(const struct eq5p_pinctrl *pctrl, + enum eq5p_bank bank, enum eq5p_regs reg, + u32 mask, u32 val) +{ + void __iomem *ptr = pctrl->base + eq5p_regs[bank][reg]; + + writel((readl(ptr) & ~mask) | (val & mask), ptr); +} + +static bool eq5p_test_bit(const struct eq5p_pinctrl *pctrl, + enum eq5p_bank bank, enum eq5p_regs reg, int offset) +{ + u32 val = readl(pctrl->base + eq5p_regs[bank][reg]); + + if (WARN_ON(offset > 31)) + return false; + + return (val & BIT(offset)) != 0; +} + +static enum eq5p_bank eq5p_pin_to_bank(unsigned int pin) +{ + if (pin < EQ5P_PIN_OFFSET_BANK_B) + return EQ5P_BANK_A; + else + return EQ5P_BANK_B; +} + +static unsigned int eq5p_pin_to_offset(unsigned int pin) +{ + if (pin < EQ5P_PIN_OFFSET_BANK_B) + return pin; + else + return pin - EQ5P_PIN_OFFSET_BANK_B; +} + +static int eq5p_pinctrl_get_groups_count(struct pinctrl_dev *pctldev) +{ + return ARRAY_SIZE(eq5p_pins); +} + +static const char *eq5p_pinctrl_get_group_name(struct pinctrl_dev *pctldev, + unsigned int selector) +{ + return pctldev->desc->pins[selector].name; +} + +static int eq5p_pinctrl_get_group_pins(struct pinctrl_dev *pctldev, + unsigned int selector, + const unsigned int **pins, + unsigned int *num_pins) +{ + *pins = &pctldev->desc->pins[selector].number; + *num_pins = 1; + return 0; +} + +static int eq5p_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin, + unsigned long *config) +{ + enum pin_config_param param = pinconf_to_config_param(*config); + struct eq5p_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); + unsigned int offset = eq5p_pin_to_offset(pin); + enum eq5p_bank bank = eq5p_pin_to_bank(pin); + u32 val_ds, arg; + bool pd, pu; + + pd = eq5p_test_bit(pctrl, bank, EQ5P_PD, offset); + pu = eq5p_test_bit(pctrl, bank, EQ5P_PU, offset); + + switch (param) { + case PIN_CONFIG_BIAS_DISABLE: + arg = !(pd || pu); + break; + case PIN_CONFIG_BIAS_PULL_DOWN: + arg = pd; + break; + case PIN_CONFIG_BIAS_PULL_UP: + arg = pu; + break; + case PIN_CONFIG_DRIVE_STRENGTH: + offset *= 2; /* two bits per pin */ + if (offset >= 32) { + val_ds = readl(pctrl->base + eq5p_regs[bank][EQ5P_DS_HIGH]); + offset -= 32; + } else { + val_ds = readl(pctrl->base + eq5p_regs[bank][EQ5P_DS_LOW]); + } + arg = (val_ds >> offset) & EQ5P_DS_MASK; + break; + default: + return -ENOTSUPP; + } + + *config = pinconf_to_config_packed(param, arg); + return 0; +} + +static void eq5p_pinctrl_pin_dbg_show(struct pinctrl_dev *pctldev, + struct seq_file *s, + unsigned int pin) +{ + struct eq5p_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); + const char *pin_name = pctrl->desc.pins[pin].name; + unsigned int offset = eq5p_pin_to_offset(pin); + enum eq5p_bank bank = eq5p_pin_to_bank(pin); + const char *func_name, *bias; + unsigned long ds_config; + u32 drive_strength; + bool pd, pu; + int i, j; + + /* + * First, let's get the function name. All pins have only two functions: + * GPIO (IOCR == 0) and something else (IOCR == 1). + */ + if (eq5p_test_bit(pctrl, bank, EQ5P_IOCR, offset)) { + func_name = NULL; + for (i = 0; i < ARRAY_SIZE(eq5p_functions); i++) { + if (i == GPIO_FUNC_SELECTOR) + continue; + + for (j = 0; j < eq5p_functions[i].ngroups; j++) { + /* Groups and pins are the same thing for us. */ + const char *x = eq5p_functions[i].groups[j]; + + if (strcmp(x, pin_name) == 0) { + func_name = eq5p_functions[i].name; + break; + } + } + + if (func_name) + break; + } + + /* + * We have not found the function attached to this pin, this + * should never occur as all pins have exactly two functions. + */ + if (!func_name) + func_name = "unknown"; + } else { + func_name = eq5p_functions[GPIO_FUNC_SELECTOR].name; + } + + /* Second, we retrieve the bias. */ + pd = eq5p_test_bit(pctrl, bank, EQ5P_PD, offset); + pu = eq5p_test_bit(pctrl, bank, EQ5P_PU, offset); + if (pd && pu) + bias = "both"; + else if (pd && !pu) + bias = "pulldown"; + else if (!pd && pu) + bias = "pullup"; + else + bias = "none"; + + /* Third, we get the drive strength. */ + ds_config = pinconf_to_config_packed(PIN_CONFIG_DRIVE_STRENGTH, 0); + eq5p_pinconf_get(pctldev, pin, &ds_config); + drive_strength = pinconf_to_config_argument(ds_config); + + seq_printf(s, "function=%s bias=%s drive_strength=%d", + func_name, bias, drive_strength); +} + +static const struct pinctrl_ops eq5p_pinctrl_ops = { + .get_groups_count = eq5p_pinctrl_get_groups_count, + .get_group_name = eq5p_pinctrl_get_group_name, + .get_group_pins = eq5p_pinctrl_get_group_pins, + .pin_dbg_show = eq5p_pinctrl_pin_dbg_show, + .dt_node_to_map = pinconf_generic_dt_node_to_map_pin, + .dt_free_map = pinctrl_utils_free_map, +}; + +static int eq5p_pinmux_get_functions_count(struct pinctrl_dev *pctldev) +{ + return ARRAY_SIZE(eq5p_functions); +} + +static const char *eq5p_pinmux_get_function_name(struct pinctrl_dev *pctldev, + unsigned int selector) +{ + return eq5p_functions[selector].name; +} + +static int eq5p_pinmux_get_function_groups(struct pinctrl_dev *pctldev, + unsigned int selector, + const char * const **groups, + unsigned int *num_groups) +{ + *groups = eq5p_functions[selector].groups; + *num_groups = eq5p_functions[selector].ngroups; + return 0; +} + +static int eq5p_pinmux_set_mux(struct pinctrl_dev *pctldev, + unsigned int func_selector, unsigned int pin) +{ + struct eq5p_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); + const char *func_name = eq5p_functions[func_selector].name; + const char *group_name = pctldev->desc->pins[pin].name; + bool is_gpio = func_selector == GPIO_FUNC_SELECTOR; + unsigned int offset = eq5p_pin_to_offset(pin); + enum eq5p_bank bank = eq5p_pin_to_bank(pin); + u32 mask, val; + + dev_dbg(pctldev->dev, "func=%s group=%s\n", func_name, group_name); + + mask = BIT(offset); + val = is_gpio ? 0 : mask; + eq5p_update_bits(pctrl, bank, EQ5P_IOCR, mask, val); + return 0; +} + +static int eq5p_pinmux_gpio_request_enable(struct pinctrl_dev *pctldev, + struct pinctrl_gpio_range *range, + unsigned int pin) +{ + /* Pin numbers and group selectors are the same thing in our case. */ + return eq5p_pinmux_set_mux(pctldev, GPIO_FUNC_SELECTOR, pin); +} + +static const struct pinmux_ops eq5p_pinmux_ops = { + .get_functions_count = eq5p_pinmux_get_functions_count, + .get_function_name = eq5p_pinmux_get_function_name, + .get_function_groups = eq5p_pinmux_get_function_groups, + .set_mux = eq5p_pinmux_set_mux, + .gpio_request_enable = eq5p_pinmux_gpio_request_enable, + .strict = true, +}; + +static int eq5p_pinconf_set_drive_strength(struct pinctrl_dev *pctldev, + unsigned int pin, u32 arg) +{ + struct eq5p_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); + unsigned int offset = eq5p_pin_to_offset(pin); + enum eq5p_bank bank = eq5p_pin_to_bank(pin); + unsigned int reg; + u32 mask, val; + + if (arg & ~EQ5P_DS_MASK) { + dev_err(pctldev->dev, "Unsupported drive strength: %u\n", arg); + return -EINVAL; + } + + offset *= 2; /* two bits per pin */ + + if (offset >= 32) { + reg = EQ5P_DS_HIGH; + offset -= 32; + } else { + reg = EQ5P_DS_LOW; + } + + mask = EQ5P_DS_MASK << offset; + val = arg << offset; + eq5p_update_bits(pctrl, bank, reg, mask, val); + return 0; +} + +static int eq5p_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin, + unsigned long *configs, unsigned int num_configs) +{ + struct eq5p_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); + const char *pin_name = pctldev->desc->pins[pin].name; + unsigned int offset = eq5p_pin_to_offset(pin); + enum eq5p_bank bank = eq5p_pin_to_bank(pin); + struct device *dev = pctldev->dev; + u32 val = BIT(offset); + unsigned int i; + + for (i = 0; i < num_configs; i++) { + enum pin_config_param param = pinconf_to_config_param(configs[i]); + u32 arg = pinconf_to_config_argument(configs[i]); + + switch (param) { + case PIN_CONFIG_BIAS_DISABLE: + dev_dbg(dev, "pin=%s bias_disable\n", pin_name); + + eq5p_update_bits(pctrl, bank, EQ5P_PD, val, 0); + eq5p_update_bits(pctrl, bank, EQ5P_PU, val, 0); + break; + + case PIN_CONFIG_BIAS_PULL_DOWN: + dev_dbg(dev, "pin=%s bias_pull_down arg=%u\n", + pin_name, arg); + + if (arg == 0) /* cannot connect to GND */ + return -ENOTSUPP; + + eq5p_update_bits(pctrl, bank, EQ5P_PD, val, val); + eq5p_update_bits(pctrl, bank, EQ5P_PU, val, 0); + break; + + case PIN_CONFIG_BIAS_PULL_UP: + dev_dbg(dev, "pin=%s bias_pull_up arg=%u\n", + pin_name, arg); + + if (arg == 0) /* cannot connect to VDD */ + return -ENOTSUPP; + + eq5p_update_bits(pctrl, bank, EQ5P_PD, val, 0); + eq5p_update_bits(pctrl, bank, EQ5P_PU, val, val); + break; + + case PIN_CONFIG_DRIVE_STRENGTH: + dev_dbg(dev, "pin=%s drive_strength arg=%u\n", + pin_name, arg); + + eq5p_pinconf_set_drive_strength(pctldev, pin, arg); + break; + + default: + dev_err(dev, "Unsupported pinconf %u\n", param); + return -ENOTSUPP; + } + } + + return 0; +} + +static const struct pinconf_ops eq5p_pinconf_ops = { + .is_generic = true, + .pin_config_get = eq5p_pinconf_get, + .pin_config_set = eq5p_pinconf_set, + /* Pins and groups are equivalent in this driver. */ + .pin_config_group_get = eq5p_pinconf_get, + .pin_config_group_set = eq5p_pinconf_set, +}; + +static int eq5p_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct pinctrl_dev *pctldev; + struct eq5p_pinctrl *pctrl; + int ret; + + pctrl = devm_kzalloc(dev, sizeof(*pctrl), GFP_KERNEL); + if (!pctrl) + return -ENOMEM; + + pctrl->base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(pctrl->base)) + return PTR_ERR(pctrl->base); + + pctrl->desc.name = dev_name(dev); + pctrl->desc.pins = eq5p_pins; + pctrl->desc.npins = ARRAY_SIZE(eq5p_pins); + pctrl->desc.pctlops = &eq5p_pinctrl_ops; + pctrl->desc.pmxops = &eq5p_pinmux_ops; + pctrl->desc.confops = &eq5p_pinconf_ops; + pctrl->desc.owner = THIS_MODULE; + + ret = devm_pinctrl_register_and_init(dev, &pctrl->desc, pctrl, &pctldev); + if (ret) + return dev_err_probe(dev, ret, "failed registering pinctrl device\n"); + + ret = pinctrl_enable(pctldev); + if (ret) + return dev_err_probe(dev, ret, "failed enabling pinctrl device\n"); + + return 0; +} + +static const struct of_device_id eq5p_match[] = { + { .compatible = "mobileye,eyeq5-pinctrl" }, + {} +}; +MODULE_DEVICE_TABLE(of, eq5p_match); + +static struct platform_driver eq5p_driver = { + .driver = { + .name = "eyeq5-pinctrl", + .of_match_table = eq5p_match, + }, + .probe = eq5p_probe, +}; +builtin_platform_driver(eq5p_driver); From patchwork Wed Apr 10 17:12:37 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Th=C3=A9o_Lebrun?= X-Patchwork-Id: 787716 Received: from relay5-d.mail.gandi.net (relay5-d.mail.gandi.net [217.70.183.197]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A1F9C1802AD; Wed, 10 Apr 2024 17:12:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.70.183.197 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712769163; cv=none; b=uGVmUCyLtIBTcL5h3uI3IAlf4erdEIWd9NDfG9KFIZEc1yZePE8UWYsy2Vr/VNPd3XTd4RgAF7EuKKwxI3LXGgEEVSfASDSGFFEAZgbL0tclMO/FhhfPYLWuVc2BD6o/dTaY5LGrSuAPIO6WviNZUtnYFh6NAxOtuqOjXdQ7E8E= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712769163; c=relaxed/simple; bh=o9k4BScWsxqBPVgu+3mmJq0aPMvXBAfbm0qYGfu1fLg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=IgtJZHy/t10MoMPkYYdEzY8/EKOcLU+yAHJQstI68Kz+NF2NyzxbdeDVqKtysbsEyfSfUS1hRdthiHqkTQxXFjLnbKnP6dB8C2mf4oGFv/QhWRbmR86KFZZ8zneRuDEvK+fZL7AKntA32VNuonnVBOQLIA+ih0Spm2wc4SAmcW0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=R4ND5J3M; arc=none smtp.client-ip=217.70.183.197 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="R4ND5J3M" Received: by mail.gandi.net (Postfix) with ESMTPSA id 6888C1C0007; Wed, 10 Apr 2024 17:12:38 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1712769159; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=66C0T2c7fJuRVzdHb/PD9nAE/qTXLvKb4vCjmWufhEA=; b=R4ND5J3MOocn1Y5Swu1Yjv1jUaZ+5T+3g3r4+q1Q1UyJ33aFztG4l/tgk/kejAS+iVf8Gn c1wY9JLJvbVozMksp5gqBvCe5C4yG8Maum6TTR35tM0xsUS2Nk33K+xLOGjU33L6R8MOHG LoAuvSIJ+ayGZCQ9WMaKVCs+fyMISLjUz+lG4LMv4OYA2IPjW/D7ScJYnc55lCHh/WHuin l3TPUTpaA26JJLqfZjAXLBeUJwUlaPurUbj5wKZrYuYCuDmbdSAOPGPSTU77HJBdtaEuI1 0xZR5y2a9H1kA8xk6bF7d4UZgQYEyAFJu2YVwqhmOXI4NaCfhnZ4iD///A6BRA== From: =?utf-8?q?Th=C3=A9o_Lebrun?= Date: Wed, 10 Apr 2024 19:12:37 +0200 Subject: [PATCH 08/11] MIPS: mobileye: eyeq5: add OLB syscon node Precedence: bulk X-Mailing-List: linux-gpio@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240410-mbly-olb-v1-8-335e496d7be3@bootlin.com> References: <20240410-mbly-olb-v1-0-335e496d7be3@bootlin.com> In-Reply-To: <20240410-mbly-olb-v1-0-335e496d7be3@bootlin.com> To: Rob Herring , Krzysztof Kozlowski , Conor Dooley , Michael Turquette , Stephen Boyd , Philipp Zabel , Linus Walleij Cc: linux-mips@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-clk@vger.kernel.org, linux-gpio@vger.kernel.org, Vladimir Kondratiev , Gregory CLEMENT , Thomas Petazzoni , Tawfik Bayouk , =?utf-8?q?Th=C3=A9o_Lebrun?= X-Mailer: b4 0.13.0 X-GND-Sasl: theo.lebrun@bootlin.com The OLB ("Other Logic Block") is a syscon region hosting clock, reset and pin controllers. It contains registers such as I2C speed mode that need to be accessible by other nodes. Signed-off-by: Théo Lebrun --- arch/mips/boot/dts/mobileye/eyeq5.dtsi | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/arch/mips/boot/dts/mobileye/eyeq5.dtsi b/arch/mips/boot/dts/mobileye/eyeq5.dtsi index 6cc5980e2fa1..e82d2a57f6da 100644 --- a/arch/mips/boot/dts/mobileye/eyeq5.dtsi +++ b/arch/mips/boot/dts/mobileye/eyeq5.dtsi @@ -100,6 +100,14 @@ uart2: serial@a00000 { clock-names = "uartclk", "apb_pclk"; }; + olb: system-controller@e00000 { + compatible = "mobileye,eyeq5-olb", "syscon", "simple-mfd"; + reg = <0 0xe00000 0x0 0x400>; + ranges = <0x0 0x0 0xe00000 0x400>; + #address-cells = <1>; + #size-cells = <1>; + }; + gic: interrupt-controller@140000 { compatible = "mti,gic"; reg = <0x0 0x140000 0x0 0x20000>; From patchwork Wed Apr 10 17:12:38 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Th=C3=A9o_Lebrun?= X-Patchwork-Id: 788092 Received: from relay5-d.mail.gandi.net (relay5-d.mail.gandi.net [217.70.183.197]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5ACAE1802CF; Wed, 10 Apr 2024 17:12:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.70.183.197 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712769164; cv=none; b=lQIeElpJLW81KlJAC74aY0M4KHtWe/O5q1rgxhkVhRwXowiQUY/U5SHgIuzmRIM5igbFw2ZTv4EZj3D2BJoMai/MLR48YlfTMwjjED4uINrMlOIFr8iEP+csmBvaD/7C6I8YJjxg3GCs62glKzOn2xas6e/wLkzpy/M/m/WFqg0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712769164; c=relaxed/simple; bh=tK4x4KGtYIXb7OTHT3sFaJe5r/9OUZNpPI5rSRlDXrg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=aKr9bbtP1Q2YWE/qKqPx2a8MOo5mUePAEPOUTSGaqPS//D2PVtLYib0e6R48rFQiTD5wXHv2udTUm/6XJCIEn2aS+BvBf32QmxbRCxLvDsF9gHu7RbgDrfY/rgkhWfU46kJ6+Cu+tIQ+jQJESE1IQSbqR9/2H7FvSlxyV20A9ls= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=QnLZmGdY; arc=none smtp.client-ip=217.70.183.197 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="QnLZmGdY" Received: by mail.gandi.net (Postfix) with ESMTPSA id 1EECF1C0003; Wed, 10 Apr 2024 17:12:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1712769159; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=v1HP/zKCNKZ7DKj4WcSicb0WzfIqg8843dS/QsXReo0=; b=QnLZmGdYMJNdAORkiGHekpfa4TbTh+82EGVGVE2FPFE2W/5tYDYJHfWzVKpkiRHBFCDKNS IIgXUNEa5rROqVjaXndaO/rvnHdYvVMeNFplNWge8yGgTYhJ5SDiGr1TKOC8C513K/w3Kg /t17i2PLcCqUFL2B/MMnRSWG51dx+znBay/2IzN/c7NdyEifvJ8nykBOrjN3koCe2Haoqe 0t8kwgNoVF08jH94j6R9bzNEWqpBQf8dqbprgLfTl5Mmby9xhTFvEEyhFIotLQM+k0yJyO GJpmCgxnP9R4gPPJHLSJXWPNe4KIDMNcbBkg8aU2DJH/JUH5O+m3ri0XckICfg== From: =?utf-8?q?Th=C3=A9o_Lebrun?= Date: Wed, 10 Apr 2024 19:12:38 +0200 Subject: [PATCH 09/11] MIPS: mobileye: eyeq5: use OLB clocks controller node Precedence: bulk X-Mailing-List: linux-gpio@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240410-mbly-olb-v1-9-335e496d7be3@bootlin.com> References: <20240410-mbly-olb-v1-0-335e496d7be3@bootlin.com> In-Reply-To: <20240410-mbly-olb-v1-0-335e496d7be3@bootlin.com> To: Rob Herring , Krzysztof Kozlowski , Conor Dooley , Michael Turquette , Stephen Boyd , Philipp Zabel , Linus Walleij Cc: linux-mips@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-clk@vger.kernel.org, linux-gpio@vger.kernel.org, Vladimir Kondratiev , Gregory CLEMENT , Thomas Petazzoni , Tawfik Bayouk , =?utf-8?q?Th=C3=A9o_Lebrun?= X-Mailer: b4 0.13.0 X-GND-Sasl: theo.lebrun@bootlin.com We add the clock controller inside the OLB syscon region and remove previous fixed devicetree nodes representing PLLs exposed by the clock controller. Signed-off-by: Théo Lebrun --- .../{eyeq5-fixed-clocks.dtsi => eyeq5-clocks.dtsi} | 54 +++++++--------------- arch/mips/boot/dts/mobileye/eyeq5.dtsi | 11 ++++- 2 files changed, 26 insertions(+), 39 deletions(-) diff --git a/arch/mips/boot/dts/mobileye/eyeq5-fixed-clocks.dtsi b/arch/mips/boot/dts/mobileye/eyeq5-clocks.dtsi similarity index 88% rename from arch/mips/boot/dts/mobileye/eyeq5-fixed-clocks.dtsi rename to arch/mips/boot/dts/mobileye/eyeq5-clocks.dtsi index 78f5533a95c6..aa6db704a786 100644 --- a/arch/mips/boot/dts/mobileye/eyeq5-fixed-clocks.dtsi +++ b/arch/mips/boot/dts/mobileye/eyeq5-clocks.dtsi @@ -3,42 +3,20 @@ * Copyright 2023 Mobileye Vision Technologies Ltd. */ +#include + / { /* Fixed clock */ - pll_cpu: pll-cpu { - compatible = "fixed-clock"; - #clock-cells = <0>; - clock-frequency = <1500000000>; - }; - - pll_vdi: pll-vdi { - compatible = "fixed-clock"; - #clock-cells = <0>; - clock-frequency = <1280000000>; - }; - - pll_per: pll-per { - compatible = "fixed-clock"; - #clock-cells = <0>; - clock-frequency = <2000000000>; - }; - - pll_ddr0: pll-ddr0 { - compatible = "fixed-clock"; - #clock-cells = <0>; - clock-frequency = <1857210000>; - }; - - pll_ddr1: pll-ddr1 { + xtal: xtal { compatible = "fixed-clock"; #clock-cells = <0>; - clock-frequency = <1857210000>; + clock-frequency = <30000000>; }; /* PLL_CPU derivatives */ occ_cpu: occ-cpu { compatible = "fixed-factor-clock"; - clocks = <&pll_cpu>; + clocks = <&clocks EQ5C_PLL_CPU>; #clock-cells = <0>; clock-div = <1>; clock-mult = <1>; @@ -101,7 +79,7 @@ mem_clk: mem-clk { }; occ_isram: occ-isram { compatible = "fixed-factor-clock"; - clocks = <&pll_cpu>; + clocks = <&clocks EQ5C_PLL_CPU>; #clock-cells = <0>; clock-div = <2>; clock-mult = <1>; @@ -115,7 +93,7 @@ isram_clk: isram-clk { /* gate ClkRstGen_isram */ }; occ_dbu: occ-dbu { compatible = "fixed-factor-clock"; - clocks = <&pll_cpu>; + clocks = <&clocks EQ5C_PLL_CPU>; #clock-cells = <0>; clock-div = <10>; clock-mult = <1>; @@ -130,7 +108,7 @@ si_dbu_tp_pclk: si-dbu-tp-pclk { /* gate ClkRstGen_dbu */ /* PLL_VDI derivatives */ occ_vdi: occ-vdi { compatible = "fixed-factor-clock"; - clocks = <&pll_vdi>; + clocks = <&clocks EQ5C_PLL_VDI>; #clock-cells = <0>; clock-div = <2>; clock-mult = <1>; @@ -144,7 +122,7 @@ vdi_clk: vdi-clk { /* gate ClkRstGen_vdi */ }; occ_can_ser: occ-can-ser { compatible = "fixed-factor-clock"; - clocks = <&pll_vdi>; + clocks = <&clocks EQ5C_PLL_VDI>; #clock-cells = <0>; clock-div = <16>; clock-mult = <1>; @@ -158,7 +136,7 @@ can_ser_clk: can-ser-clk { /* gate ClkRstGen_can_ser */ }; i2c_ser_clk: i2c-ser-clk { compatible = "fixed-factor-clock"; - clocks = <&pll_vdi>; + clocks = <&clocks EQ5C_PLL_VDI>; #clock-cells = <0>; clock-div = <20>; clock-mult = <1>; @@ -166,7 +144,7 @@ i2c_ser_clk: i2c-ser-clk { /* PLL_PER derivatives */ occ_periph: occ-periph { compatible = "fixed-factor-clock"; - clocks = <&pll_per>; + clocks = <&clocks EQ5C_PLL_PER>; #clock-cells = <0>; clock-div = <16>; clock-mult = <1>; @@ -225,7 +203,7 @@ gpio_clk: gpio-clk { }; emmc_sys_clk: emmc-sys-clk { compatible = "fixed-factor-clock"; - clocks = <&pll_per>; + clocks = <&clocks EQ5C_PLL_PER>; #clock-cells = <0>; clock-div = <10>; clock-mult = <1>; @@ -233,7 +211,7 @@ emmc_sys_clk: emmc-sys-clk { }; ccf_ctrl_clk: ccf-ctrl-clk { compatible = "fixed-factor-clock"; - clocks = <&pll_per>; + clocks = <&clocks EQ5C_PLL_PER>; #clock-cells = <0>; clock-div = <4>; clock-mult = <1>; @@ -241,7 +219,7 @@ ccf_ctrl_clk: ccf-ctrl-clk { }; occ_mjpeg_core: occ-mjpeg-core { compatible = "fixed-factor-clock"; - clocks = <&pll_per>; + clocks = <&clocks EQ5C_PLL_PER>; #clock-cells = <0>; clock-div = <2>; clock-mult = <1>; @@ -265,7 +243,7 @@ mjpeg_core_clk: mjpeg-core-clk { /* gate ClkRstGen_mjpeg_gen */ }; fcmu_a_clk: fcmu-a-clk { compatible = "fixed-factor-clock"; - clocks = <&pll_per>; + clocks = <&clocks EQ5C_PLL_PER>; #clock-cells = <0>; clock-div = <20>; clock-mult = <1>; @@ -273,7 +251,7 @@ fcmu_a_clk: fcmu-a-clk { }; occ_pci_sys: occ-pci-sys { compatible = "fixed-factor-clock"; - clocks = <&pll_per>; + clocks = <&clocks EQ5C_PLL_PER>; #clock-cells = <0>; clock-div = <8>; clock-mult = <1>; diff --git a/arch/mips/boot/dts/mobileye/eyeq5.dtsi b/arch/mips/boot/dts/mobileye/eyeq5.dtsi index e82d2a57f6da..1a65b43e13b1 100644 --- a/arch/mips/boot/dts/mobileye/eyeq5.dtsi +++ b/arch/mips/boot/dts/mobileye/eyeq5.dtsi @@ -5,7 +5,7 @@ #include -#include "eyeq5-fixed-clocks.dtsi" +#include "eyeq5-clocks.dtsi" / { #address-cells = <2>; @@ -106,6 +106,15 @@ olb: system-controller@e00000 { ranges = <0x0 0x0 0xe00000 0x400>; #address-cells = <1>; #size-cells = <1>; + + clocks: clock-controller@e0002c { + compatible = "mobileye,eyeq5-clk"; + reg = <0x02c 0x50>, <0x11c 0x04>; + reg-names = "plls", "ospi"; + #clock-cells = <1>; + clocks = <&xtal>; + clock-names = "ref"; + }; }; gic: interrupt-controller@140000 { From patchwork Wed Apr 10 17:12:39 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Th=C3=A9o_Lebrun?= X-Patchwork-Id: 787714 Received: from relay5-d.mail.gandi.net (relay5-d.mail.gandi.net [217.70.183.197]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5C87417BB2F; Wed, 10 Apr 2024 17:12:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.70.183.197 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712769166; cv=none; b=B72xwCGXDvciG+AEC2383yXIgsLc24NoNIbO4gW2M642B/s3Cbchlf665FCNxWsgaDbdVPAGakVi+sFntNopebCav13YHyZ2IUv6Fo3DnIyVImllQh8DCqqpOnTSIRVxFzObgyGWyXU+625uc1t9s+FAfbuOeekinuNTQw44f34= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712769166; c=relaxed/simple; bh=iYXkDLoD8tDRrp2wziiqK4v0tn/tz7yfQG4GHparyXk=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=h2OXSHfUNFJO4BPfsswKVx25PHtFhZTMav++ECouMbPoDUwpwaO1cembLf313akq7QbSrsoP077D+HBlSuINjGwkGLgZHvzM/2LMt2BEjBp2zxnCY+iA1BfbEO7TZZIzXeDXFTMwQKAvoTb12VESWg1WtxRFUHCZLIGOKmJ/7JY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=F0we+2Nu; arc=none smtp.client-ip=217.70.183.197 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="F0we+2Nu" Received: by mail.gandi.net (Postfix) with ESMTPSA id E2AD31C0002; Wed, 10 Apr 2024 17:12:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1712769160; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=PWM4le1lg+zZj5aG6IIDSjSmOtDGbtS+zl6wlgbWlYY=; b=F0we+2Nuahdvvbrm+10soAPPj5HBUwnbQ8lkPeCBfl9Isv6zFPaN8Ts4CHzfrWc65IU96g 3t9gMyZJxwF8+sbXDbFR5YAtMOoYW8FK7r8PjOtfte+FmxSodzVXDxGkq/TjgWqby9muT8 ptyM/zN5+D9bz/MMkp6nYYfX2jrjhpTOGC7bNYm7fWE2uAMHw3Ykx/8/XHxEpOx/dkR9pS P2aUkgLnZ9vAHVLxLyG64T2leax+bFiAFoKC6CZOEI49590kttqCcy2+KfbtnSmSgUkVaQ DFIc/Y51QsYkKKK5sibsZvGknXqKxVW5XW9fS9y4RCLyqId+3M+8W3o7CnXeYQ== From: =?utf-8?q?Th=C3=A9o_Lebrun?= Date: Wed, 10 Apr 2024 19:12:39 +0200 Subject: [PATCH 10/11] MIPS: mobileye: eyeq5: add OLB reset controller node Precedence: bulk X-Mailing-List: linux-gpio@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240410-mbly-olb-v1-10-335e496d7be3@bootlin.com> References: <20240410-mbly-olb-v1-0-335e496d7be3@bootlin.com> In-Reply-To: <20240410-mbly-olb-v1-0-335e496d7be3@bootlin.com> To: Rob Herring , Krzysztof Kozlowski , Conor Dooley , Michael Turquette , Stephen Boyd , Philipp Zabel , Linus Walleij Cc: linux-mips@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-clk@vger.kernel.org, linux-gpio@vger.kernel.org, Vladimir Kondratiev , Gregory CLEMENT , Thomas Petazzoni , Tawfik Bayouk , =?utf-8?q?Th=C3=A9o_Lebrun?= X-Mailer: b4 0.13.0 X-GND-Sasl: theo.lebrun@bootlin.com Add devicetree node for the reset controller on Mobileye EyeQ5. It appears as a subnode to the OLB syscon as its registers are located in this shared register region. Signed-off-by: Théo Lebrun --- arch/mips/boot/dts/mobileye/eyeq5.dtsi | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/arch/mips/boot/dts/mobileye/eyeq5.dtsi b/arch/mips/boot/dts/mobileye/eyeq5.dtsi index 1a65b43e13b1..76935f237ab5 100644 --- a/arch/mips/boot/dts/mobileye/eyeq5.dtsi +++ b/arch/mips/boot/dts/mobileye/eyeq5.dtsi @@ -78,6 +78,7 @@ uart0: serial@800000 { interrupts = ; clocks = <&uart_clk>, <&occ_periph>; clock-names = "uartclk", "apb_pclk"; + resets = <&reset 0 10>; }; uart1: serial@900000 { @@ -88,6 +89,7 @@ uart1: serial@900000 { interrupts = ; clocks = <&uart_clk>, <&occ_periph>; clock-names = "uartclk", "apb_pclk"; + resets = <&reset 0 11>; }; uart2: serial@a00000 { @@ -98,6 +100,7 @@ uart2: serial@a00000 { interrupts = ; clocks = <&uart_clk>, <&occ_periph>; clock-names = "uartclk", "apb_pclk"; + resets = <&reset 0 12>; }; olb: system-controller@e00000 { @@ -107,6 +110,13 @@ olb: system-controller@e00000 { #address-cells = <1>; #size-cells = <1>; + reset: reset-controller@e00000 { + compatible = "mobileye,eyeq5-reset"; + reg = <0x000 0x0c>, <0x200 0x34>, <0x120 0x04>; + reg-names = "d0", "d1", "d2"; + #reset-cells = <2>; + }; + clocks: clock-controller@e0002c { compatible = "mobileye,eyeq5-clk"; reg = <0x02c 0x50>, <0x11c 0x04>; From patchwork Wed Apr 10 17:12:40 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Th=C3=A9o_Lebrun?= X-Patchwork-Id: 788091 Received: from relay5-d.mail.gandi.net (relay5-d.mail.gandi.net [217.70.183.197]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C50C2180A8B; Wed, 10 Apr 2024 17:12:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.70.183.197 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712769166; cv=none; b=MAUgYuSFZLuTWADLw4SXTEI74LohAP/5L+RLJrNexKhxV9C7YvyQRTAG77aXie5Qpy5UqhlkV539ZEOyaLS02zdi4PMocTjOaZGn4ZADGSMKhAcLYajWyfyjN0fJ4KGWLr/5RXbAkad/9p91cyzaydHR1Vvjsc/wAuUTyBoOXxU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712769166; c=relaxed/simple; bh=AAJTdXRM0Re+DCVXVGJxubzVOx467C+c5nb+jYksNi8=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ua40sB7Ks4Ok3eS96LhiviZlSAJ9j6cxVf3C1qg59OXb0snQ+Ngr/admRQ+2B4GidQmXUFdmgKhisPfPaeeXnE1ZbXxfTlMUpew6bU5K9NE2PXru6bz6hf69o9CUe+8hC1R5ZxpTnL5+8R1Hhbz9OUbEWW3osTWy7AnulbxzWkI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=Db6XtEfI; arc=none smtp.client-ip=217.70.183.197 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="Db6XtEfI" Received: by mail.gandi.net (Postfix) with ESMTPSA id A27741C0006; Wed, 10 Apr 2024 17:12:40 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1712769161; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=aqd7RNSKgF1eQYnYzns3slAE3h9undBdrUHi47AKr1g=; b=Db6XtEfI1VNXOTKGHX5TiSDo8IpjTBzCnMEDn6OIWcE3KF4w7GjzOQZjgKryUFpQGdcK/U 5+o9JFuI4e8/SBlrRF0VkrMxLvS1Bq4J86KO9D9+pDDbYuEeJ9qzoU/kLhBubIIbC/vCCc NDAfvYP9KSdsLsIGPQYdTze7yCNsvIYaupZNS+doig7rVg7wEw7JW/9qx4qgjDdBBewOSf W3O6cqt65iRQa+jh4+Is6eKdFpYdLq4NsP0It8LrAIR9pjD2ErWN5vZHISmwgO7Q7he5OS WTk763qWWlyAJhDf+rgUyakXNDQDaDjqbrM4DIDeWwNlb7SQZqggKSIxD3qOLg== From: =?utf-8?q?Th=C3=A9o_Lebrun?= Date: Wed, 10 Apr 2024 19:12:40 +0200 Subject: [PATCH 11/11] MIPS: mobileye: eyeq5: add pinctrl node & pinmux function nodes Precedence: bulk X-Mailing-List: linux-gpio@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240410-mbly-olb-v1-11-335e496d7be3@bootlin.com> References: <20240410-mbly-olb-v1-0-335e496d7be3@bootlin.com> In-Reply-To: <20240410-mbly-olb-v1-0-335e496d7be3@bootlin.com> To: Rob Herring , Krzysztof Kozlowski , Conor Dooley , Michael Turquette , Stephen Boyd , Philipp Zabel , Linus Walleij Cc: linux-mips@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-clk@vger.kernel.org, linux-gpio@vger.kernel.org, Vladimir Kondratiev , Gregory CLEMENT , Thomas Petazzoni , Tawfik Bayouk , =?utf-8?q?Th=C3=A9o_Lebrun?= X-Mailer: b4 0.13.0 X-GND-Sasl: theo.lebrun@bootlin.com Pins on this platform have two functions: GPIO or something-else. We create function nodes for each something-else based on functions. UART nodes are present in the platform devicetree. Add pinctrl to them now that the pin controller is supported. Acked-by: Linus Walleij Signed-off-by: Théo Lebrun --- arch/mips/boot/dts/mobileye/eyeq5-pins.dtsi | 125 ++++++++++++++++++++++++++++ arch/mips/boot/dts/mobileye/eyeq5.dtsi | 13 +++ 2 files changed, 138 insertions(+) diff --git a/arch/mips/boot/dts/mobileye/eyeq5-pins.dtsi b/arch/mips/boot/dts/mobileye/eyeq5-pins.dtsi new file mode 100644 index 000000000000..42acda13e57a --- /dev/null +++ b/arch/mips/boot/dts/mobileye/eyeq5-pins.dtsi @@ -0,0 +1,125 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) + +/* + * Default pin configuration for Mobileye EyeQ5 boards. We mostly create one + * pin configuration node per function. + */ + +&pinctrl { + timer0_pins: timer0-pins { + function = "timer0"; + pins = "PA0", "PA1"; + }; + timer1_pins: timer1-pins { + function = "timer1"; + pins = "PA2", "PA3"; + }; + timer2_pins: timer2-pins { + function = "timer2"; + pins = "PA4", "PA5"; + }; + pps0_pins: pps0-pin { + function = "timer2"; + pins = "PA4"; + }; + pps1_pins: pps1-pin { + function = "timer2"; + pins = "PA5"; + }; + timer5_ext_pins: timer5-ext-pins { + function = "timer5"; + pins = "PA6", "PA7", "PA8", "PA9"; + }; + timer5_ext_input_pins: timer5-ext-input-pins { + function = "timer5"; + pins = "PA6", "PA7"; + }; + timer5_ext_incap_a_pins: timer5-ext-incap-a-pin { + function = "timer5"; + pins = "PA6"; + }; + timer5_ext_incap_b_pins: timer5-ext-incap-b-pin { + function = "timer5"; + pins = "PA7"; + }; + can0_pins: can0-pins { + function = "can0"; + pins = "PA14", "PA15"; + }; + can1_pins: can1-pins { + function = "can1"; + pins = "PA16", "PA17"; + }; + uart0_pins: uart0-pins { + function = "uart0"; + pins = "PA10", "PA11"; + }; + uart1_pins: uart1-pins { + function = "uart1"; + pins = "PA12", "PA13"; + }; + spi0_pins: spi0-pins { + function = "spi0"; + pins = "PA18", "PA19", "PA20", "PA21", "PA22"; + }; + spi1_pins: spi1-pins { + function = "spi1"; + pins = "PA23", "PA24", "PA25", "PA26", "PA27"; + }; + spi1_slave_pins: spi1-slave-pins { + function = "spi1"; + pins = "PA24", "PA25", "PA26"; + }; + refclk0_pins: refclk0-pin { + function = "refclk0"; + pins = "PA28"; + }; + timer3_pins: timer3-pins { + function = "timer3"; + pins = "PB0", "PB1"; + }; + timer4_pins: timer4-pins { + function = "timer4"; + pins = "PB2", "PB3"; + }; + timer6_ext_pins: timer6-ext-pins { + function = "timer6"; + pins = "PB4", "PB5", "PB6", "PB7"; + }; + timer6_ext_input_pins: timer6-ext-input-pins { + function = "timer6"; + pins = "PB4", "PB5"; + }; + timer6_ext_incap_a_pins: timer6-ext-incap-a-pin { + function = "timer6"; + pins = "PB4"; + }; + timer6_ext_incap_b_pins: timer6-ext-incap-b-pin { + function = "timer6"; + pins = "PB5"; + }; + can2_pins: can2-pins { + function = "can2"; + pins = "PB10", "PB11"; + }; + uart2_pins: uart2-pins { + function = "uart2"; + pins = "PB8", "PB9"; + }; + spi2_pins: spi2-pins { + function = "spi2"; + pins = "PB12", "PB13", "PB14", "PB15", "PB16"; + }; + spi3_pins: spi3-pins { + function = "spi3"; + pins = "PB17", "PB18", "PB19", "PB20", "PB21"; + }; + spi3_slave_pins: spi3-slave-pins { + function = "spi3"; + pins = "PB18", "PB19", "PB20"; + }; + mclk0_pins: mclk0-pin { + function = "mclk0"; + pins = "PB22"; + }; +}; diff --git a/arch/mips/boot/dts/mobileye/eyeq5.dtsi b/arch/mips/boot/dts/mobileye/eyeq5.dtsi index 76935f237ab5..8d4f65ec912d 100644 --- a/arch/mips/boot/dts/mobileye/eyeq5.dtsi +++ b/arch/mips/boot/dts/mobileye/eyeq5.dtsi @@ -79,6 +79,8 @@ uart0: serial@800000 { clocks = <&uart_clk>, <&occ_periph>; clock-names = "uartclk", "apb_pclk"; resets = <&reset 0 10>; + pinctrl-names = "default"; + pinctrl-0 = <&uart0_pins>; }; uart1: serial@900000 { @@ -90,6 +92,8 @@ uart1: serial@900000 { clocks = <&uart_clk>, <&occ_periph>; clock-names = "uartclk", "apb_pclk"; resets = <&reset 0 11>; + pinctrl-names = "default"; + pinctrl-0 = <&uart1_pins>; }; uart2: serial@a00000 { @@ -101,6 +105,8 @@ uart2: serial@a00000 { clocks = <&uart_clk>, <&occ_periph>; clock-names = "uartclk", "apb_pclk"; resets = <&reset 0 12>; + pinctrl-names = "default"; + pinctrl-0 = <&uart2_pins>; }; olb: system-controller@e00000 { @@ -125,6 +131,11 @@ clocks: clock-controller@e0002c { clocks = <&xtal>; clock-names = "ref"; }; + + pinctrl: pinctrl@e000b0 { + compatible = "mobileye,eyeq5-pinctrl"; + reg = <0x0b0 0x30>; + }; }; gic: interrupt-controller@140000 { @@ -149,3 +160,5 @@ timer { }; }; }; + +#include "eyeq5-pins.dtsi"