From patchwork Wed Sep 5 02:12:10 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peng Fan X-Patchwork-Id: 966168 X-Patchwork-Delegate: sbabic@denx.de Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=nxp.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=nxp.com header.i=@nxp.com header.b="S4iosRwH"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 424nTj0pxgz9s3Z for ; Wed, 5 Sep 2018 12:19:53 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id CCBCBC21DFB; Wed, 5 Sep 2018 02:17:49 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=BAD_ENC_HEADER, SPF_HELO_PASS, T_DKIM_INVALID autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id EFC1EC21F05; Wed, 5 Sep 2018 02:08:07 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 77879C21EAE; Wed, 5 Sep 2018 02:08:05 +0000 (UTC) Received: from EUR01-DB5-obe.outbound.protection.outlook.com (mail-db5eur01on0075.outbound.protection.outlook.com [104.47.2.75]) by lists.denx.de (Postfix) with ESMTPS id CE20CC21EAE for ; Wed, 5 Sep 2018 02:07:44 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nxp.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=36qEXddkzBLYBBo8RpHiPM6ANL3x+mCOfLBJ4JBjOvw=; b=S4iosRwHIlHv6GFwvRolbT6w0pc8u5khXuqyyRQ5uibF/UYhdlMSpgGS43Cvw4iEPzzUod8AqyBznz9GO79dYRxfacq3GljrWkVGwrhBZYx7eta97ujdd/j3D573mTFCLHBSCNoTvrRwXwzxUwHHHSUKoSictIrL3OTqLIMGZdE= Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=peng.fan@nxp.com; Received: from linux-u7w5.ap.freescale.net.net (92.121.68.129) by VI1PR04MB4496.eurprd04.prod.outlook.com (2603:10a6:803:69::28) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.1101.18; Wed, 5 Sep 2018 02:07:40 +0000 From: Peng Fan To: sbabic@denx.de Date: Wed, 5 Sep 2018 10:12:10 +0800 Message-Id: <20180905021219.12828-24-peng.fan@nxp.com> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20180905021219.12828-1-peng.fan@nxp.com> References: <20180905021219.12828-1-peng.fan@nxp.com> MIME-Version: 1.0 X-Originating-IP: [92.121.68.129] X-ClientProxiedBy: HK0PR03CA0022.apcprd03.prod.outlook.com (2603:1096:203:2e::34) To VI1PR04MB4496.eurprd04.prod.outlook.com (2603:10a6:803:69::28) X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 9cfdcf34-bb92-4f48-caeb-08d612d45db2 X-MS-Office365-Filtering-HT: Tenant X-Microsoft-Antispam: BCL:0; PCL:0; RULEID:(7020095)(4652040)(8989137)(4534165)(4627221)(201703031133081)(201702281549075)(8990107)(5600074)(711020)(4618075)(2017052603328)(7153060)(7193020); SRVR:VI1PR04MB4496; X-Microsoft-Exchange-Diagnostics: 1; VI1PR04MB4496; 3:fWE5IOa3jRCbQR28GgKFClA3RRbB4BgJzqWOh8JXI/sYY/1hT+RcLPj5ObzlR1215tC3YOwGmeB+8nIGPzAuJZtrqFEdpIuWAG2W9A8sy2dBaGTjVAgGdR6qp6UXZ/dKmO3K13tDOCMHHCBttGcuRcAWCcBt1jMnip/d3QEOELpaNzude2pKTwHtXuXgohjmR3mIW3LzE9l3t9Z/ogh2FcX8Uks+EpbJo8mIi+eWDQG9I++/sHB5JtBAlVXANIin; 25:44ExAcFXcc5T5huD1p4RjkSCgy6z5G8ouCk/jyDymbq5i8nqK6onIrqyXqfiVsionVDH3N0R5usuR6VPDanI3gK6u8+pu20lFWJS4HkG0QGexTbCFQmdSbSe+HsgYwoqVxCA8l1OSgmjxL3GulDgTFVxTaIJkwMo58B1QBlHgBpy4SF5B9qOOkszfCNLgJnbalHG+fOpiUX1ExsRO5iqLmXM8vFmd4u3rk2sYWDz7c6f8JV/8Jd61GD9wbfRmohpO+0BSDpAfX9RHVFkkzJcX85lpT7NFTt2DpUiqWiHs+Awa9QSFsAMeBjzj80qI7U2CpTfnbZdhNy/ZX28TxyXAQ==; 31:jwhQ127COo73w8FB6KbymIzdJFJ2+rJ1If1DI0rNVbqAa3LPqFCDQGQxYizPgqTrhpSe90I0OMOs7q1NfCItFyU0cgDX3jd2wAsWGLVz8HGE9FswaRkEKFFxWsq+xmSm8nzGGQ57Bwpd6qr7yNJ3+DLPdVXmH0XSqr7ySc7GdZQDyX2NIwHHvJ/COZu2yXOMGjGuMHGTKeim7T0xR6/yoMbPcwYuVV3WhYJ+nWJhgqg= X-MS-TrafficTypeDiagnostic: VI1PR04MB4496: X-Microsoft-Exchange-Diagnostics: 1; VI1PR04MB4496; 20:ssgp0UJyTAz1IRbBV/O2H0sWowepB2r2hj/DzwHgZcSFbIVWlHR7mtLfB3PHrnNGJJ+KH9T/PCYZIlkROpDi4OiAq3FqPaHatl2ludpVKypCwwG7BNHvceaMuYnerIQLDgbh/HkrVe73mTFx8UvtAYfCkN304EIlwecoCWk7dw1xsCSfKxoRAAYjEEdELmmL6PNfVcK6se9fp3P8rqPe5Al2IM92SbaJ8srJdGmQ51fUloh4/h82EZXrhAcT6pIv1x6sxA9Hlf6UTg4U9x2kK8/XRaW3gVWWggdNltd0duFwwf2206tR5zqQ5aikYMjNmahThuk8G3NcDIzmG/5iPlGzu9AtN6MTvzL6CzifWYiQgFnQmi6pWuGst9Ds3Gy20cVonEHMOiSv8xSoZwO//6VHW8ihasW6h1WlMZNW3C42NthduwEL4KNpd03UbUXLe9o1D6rOKFKQLan6mkoVBv52UmwYOspXRrxWpUrFOEcpgr22axkH7rEoNLszVZ9Y; 4:V+mr0ANjfik+wRA7QR24ATiGvJXqLF9a3DHBlIekoV7TLis/HNPtd/j6JPra62yuEaL0H1ojUu1y57FMcN/Kp+L+wrKg1F/5JGyaE9Z48lbse5+GRoWRsfTANZKnrcwYruMNk7v7JMwcAoza96uvPP3SDxrxqvwcnv2h4eRKVkq1ga/D17nm8wDOPA5zIPN32xk/pALYsDpf6IUm2H5+OHtQANzDhwkhQF4Dm5YK4Z1LXoqadeyWZWsITBiV3XXX36OkftTk4y8LBFf7rFnoz/43myCX0bRAAMG0hbxKLtCSXofl2Bd/YLjeycm7KW7G X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(185117386973197); X-MS-Exchange-SenderADCheck: 1 X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(8211001083)(6040522)(2401047)(5005006)(8121501046)(823301075)(93006095)(93001095)(3231311)(944501410)(52105095)(3002001)(10201501046)(6055026)(149027)(150027)(6041310)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123560045)(20161123562045)(20161123558120)(20161123564045)(201708071742011)(7699016); SRVR:VI1PR04MB4496; BCL:0; PCL:0; RULEID:; SRVR:VI1PR04MB4496; X-Forefront-PRVS: 078693968A X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10009020)(396003)(366004)(136003)(376002)(346002)(39860400002)(189003)(199004)(11346002)(305945005)(25786009)(7736002)(386003)(8936002)(478600001)(26005)(36756003)(6116002)(1076002)(3846002)(476003)(446003)(81166006)(575784001)(50226002)(86362001)(6506007)(47776003)(50466002)(48376002)(8676002)(2616005)(81156014)(956004)(16526019)(186003)(16586007)(66066001)(53936002)(316002)(4326008)(76176011)(68736007)(5660300001)(6512007)(2361001)(51416003)(486006)(106356001)(97736004)(105586002)(6666003)(6486002)(6916009)(44832011)(2351001)(2906002)(52116002); DIR:OUT; SFP:1101; SCL:1; SRVR:VI1PR04MB4496; H:linux-u7w5.ap.freescale.net.net; FPR:; SPF:None; LANG:en; PTR:InfoNoRecords; MX:1; A:1; Received-SPF: None (protection.outlook.com: nxp.com does not designate permitted sender hosts) X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; VI1PR04MB4496; 23:Sw1yEaIUuQHfLuG5JZNAH+08bihR1ifB3U0ZrPEd7?= mQteqS3fb0ZKPfboHNarOCwFp/8pubftE03ks0PdD8qp7GByEToJz8Wcsmt1jPaVHaogZ6oM6dr+V1C8BA5tNJbVXFjqTw9j1IZgGXEpAE8Htt3rQOafT0O/RAY6E8rZwOlANAVGTT8pGKmYKQ/ghRD2kxU+/ZfPqu4XfFFd1E0/nhsW8rEJ2THVO/e6KZzdpfHHwco/k31/2MhVoE+gVoYeGeQeof1hhmA94M8FevNRooAAuJjiI8Zedle7GE/QlBxUwcAQin70xhapjooQETNQAg9LvynTatnHOhjBxSxaDm0D8/UdVlAbYXGqsRs75Npqvvd/3zt2I+lCKeZj4WOgLIw/9AA2AwzxAu9m81qIanE5UI6fQMDRbcJlKoLQkYqGZnzkJd8Q09mxe8PWl9W4bKN38P09WJSfEwTfyWGihptpXOAWIAugfO2M2lN+e2R1YFYmb61U/4Ki/iD7Hp0maYK01mhtwLiSCAjwTNDiZzFWJzZe265BN/Flaprtn2Y1p2amh22slqu4D1O6Jo+ThBCMgratPHlXZQHdcvRbDuntLsUShbyCqkNOMhM4samww5hbjQT4/ZIqIAM2bWbFPtTIf9V4OnIXf8jULoNWjLlqRwM+wT9thMNXPQTtzOYcP5yvZtHtTcWx4ynqoPO71OHapkSoNU7ny41ogpmgvZFj4TmFQCIVYq8MG0gE7s1gUuLJTJTUn7+uksak4NlMQ35PxRntuj+GiFHcRA2U0XIoqmxyEKrcRQZKqNIM3Y27uVqD32x96IG0+nonIacXtR88EoP2nu6mnEAwTJQNVdoukRKdRZIvrrzo5JVTX8hf0ByO7w9XxM0ftYMnUUUo4ne+TDCQx6g0glVLKn6qcVVyBsF5a8bUTJBnh5j/UeOijPMbze1Gg55ktnTOmO2n73nPv4RmLMFOBwmaGczU4hJmi+yZ7Q9iI+y5wZZKHBVPMeUqNIAgVqyu/REK5SttlG6NJRgot7/f1S807mbL7iyefP4u6O+iKvK5KqOVaqiMcY7sKEIpmXmTRraSSPVVVWyhn/2Fl93HKNcasZI7+7+vV1N3GO20+tf1CC+c68jSYPsdw+tJiLvcvkelXCjgOtmjYammJ3HHOfkEiVe0e0Y/e28tS1OEj/yKB+Qks0cL6n/v/JwqTwqH7bKZEJ6cUbrRhuBXHdzSwNited228HyfddUc2Xa1FwaFBfOBGZx9dy7iAeUYceW2YmDvSxJ X-Microsoft-Antispam-Message-Info: 4rTaHCDMg3CvmqtwM02SWsM0NW783/v+YB6DkSGXrxITZtgFvzgXPUC9cHyXli0ej+TGp84J5HbgufXkav8+aJO2tX2IR415jnDace2cwf+EhJY/f00k3weqkKe9GZLdThQgKV1OijVIDfV7fyCyqgPQnaB3UJl6TVxEVKrnakdyasdf2RtH1t9spdao/lJFjjYNSDkP7Xl4LLcgHceCTgyvdp+r39j3Xty2TsgiseqVIpW7udxcEf0rirNqUUaNjynI8QLSnWew1bxDS+7/dGjAvfo8PD7gXCFQRjWlDWyrCedwasU9Ys7tQrdchVhHTeM83E+v/wmFVv8YkElhIr4Ftlha5W3wcngqnZKDFJs= X-Microsoft-Exchange-Diagnostics: 1; VI1PR04MB4496; 6:0GSIaa9ncW7ThOwOnZYDACP7P76zmw2WdcjJAl4iS8hmQzmrnFxnj5fpgZgUlkRniLV0+LoYGVufaHXMnXo5E8Jx2KW5P/TBI7n5HjdHF2ngyzWgJYRkzNTS19nN9txyqbxTFpDdB7Qb3HtUnYrWaWHUryy+IUmdVCBj2OgDiSGw7XHf0eD4goOXpOfjd5IJqyb6sQBpz8XC+gszciI0yBXnBN8+leFNiMghig/7FmIrOF5OhVE+xj/T5GRg1Brj9ZkBqziDHMcpMrGqv6xxuuUHcl/POyUIqF9W1VA+Hrl3owG7/0CofRJ997zbaVBzib1PbJJkAHHQf+TPHiwnapd1vGLxjbkSkwiaTiTFdZJVZhwimZJ/tB7id7dIsB//dDLVIHFHoprMELVV+Pm3T5kqNH05MIynSTH9gKJahyze91MttoGms1Mz/HElKVmltY7NXGwzA6Lig0hvI0ddDQ==; 5:p59Zqhf+q2k5V6EsWE1FW/EoUZINZrjT4yr9VZy+Am6rvInNwzCbDM5dyYNlqSnGIb8uPysC3i4n9y9UZdqM8gxakBDQbBdi6fU5JnMvUi7D/hMkXqjcwbeM147kh2GQ0AQ/mhZGvwE0H8MQnKrBitTnxXs07+eTNFaX7FyBggU=; 7:mql0dqJ0cH6unISuiktGKHoE9aZnw1rUpAy+8Y+eKuXa9atZmGq82/2d26nX09pX1uxFgFaSkYKyll3IWFz2ZyLMO3w5z0AEgKmV2ifPRV+3zNqnjvpsT5IoKPTMFki58C6QSjggT5+U95tWefQURUONNPtLpEvVuzQppHCneTHQXwJGIgFKLiEbG1niOu+htdyrQZSeSbkMsNIisWd3zWYlBNty5bf7tXTa2MJoOppDAoytTN9IrPyks55aNZmR SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-OriginatorOrg: nxp.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 05 Sep 2018 02:07:40.8712 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 9cfdcf34-bb92-4f48-caeb-08d612d45db2 X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 686ea1d3-bc2b-4c6f-a92c-d99c5c301635 X-MS-Exchange-Transport-CrossTenantHeadersStamped: VI1PR04MB4496 Cc: fabio.estevam@nxp.com, u-boot@lists.denx.de Subject: [U-Boot] [PATCH V4 23/32] pinctrl: Add pinctrl driver for i.MX8 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" Add pinctrl driver for i.MX8. The pads configuration is controlled by SCU, so need to ask SCU to configure pads through scfw API. Add pinctrl-scu to invoke sc_pad_set to configue pads. Add a new flag IMX8_USE_SCU to differentiate i.MX8 from other platforms which could directly configure pads from Acore side. Add CONFIG_PINCTRL_IMX8 as the built gate. Signed-off-by: Peng Fan --- drivers/pinctrl/nxp/Kconfig | 18 ++++ drivers/pinctrl/nxp/Makefile | 2 + drivers/pinctrl/nxp/pinctrl-imx.c | 209 ++++++++++++++++++++----------------- drivers/pinctrl/nxp/pinctrl-imx.h | 16 +++ drivers/pinctrl/nxp/pinctrl-imx8.c | 40 +++++++ drivers/pinctrl/nxp/pinctrl-scu.c | 66 ++++++++++++ 6 files changed, 258 insertions(+), 93 deletions(-) create mode 100644 drivers/pinctrl/nxp/pinctrl-imx8.c create mode 100644 drivers/pinctrl/nxp/pinctrl-scu.c diff --git a/drivers/pinctrl/nxp/Kconfig b/drivers/pinctrl/nxp/Kconfig index b668359a0b..449ad47ebc 100644 --- a/drivers/pinctrl/nxp/Kconfig +++ b/drivers/pinctrl/nxp/Kconfig @@ -1,6 +1,9 @@ config PINCTRL_IMX bool +config PINCTRL_IMX_SCU + bool + config PINCTRL_IMX5 bool "IMX5 pinctrl driver" depends on ARCH_MX5 && PINCTRL_FULL @@ -56,3 +59,18 @@ config PINCTRL_IMX7ULP is different from the linux one, this is a simple implementation, only parses the 'fsl,pins' property and configure related registers. + +config PINCTRL_IMX8 + bool "IMX8 pinctrl driver" + depends on ARCH_IMX8 && PINCTRL_FULL + select DEVRES + select PINCTRL_IMX + select PINCTRL_IMX_SCU + help + Say Y here to enable the imx8 pinctrl driver + + This provides a simple pinctrl driver for i.MX8 SoC familiy. + This feature depends on device tree configuration. This driver + is different from the linux one, this is a simple implementation, + only parses the 'fsl,pins' property and configure related + registers. diff --git a/drivers/pinctrl/nxp/Makefile b/drivers/pinctrl/nxp/Makefile index c763948376..310b3b3a2e 100644 --- a/drivers/pinctrl/nxp/Makefile +++ b/drivers/pinctrl/nxp/Makefile @@ -3,3 +3,5 @@ obj-$(CONFIG_PINCTRL_IMX5) += pinctrl-imx5.o obj-$(CONFIG_PINCTRL_IMX6) += pinctrl-imx6.o obj-$(CONFIG_PINCTRL_IMX7) += pinctrl-imx7.o obj-$(CONFIG_PINCTRL_IMX7ULP) += pinctrl-imx7ulp.o +obj-$(CONFIG_PINCTRL_IMX_SCU) += pinctrl-scu.o +obj-$(CONFIG_PINCTRL_IMX8) += pinctrl-imx8.o diff --git a/drivers/pinctrl/nxp/pinctrl-imx.c b/drivers/pinctrl/nxp/pinctrl-imx.c index 36e1e8983c..04ea82aba5 100644 --- a/drivers/pinctrl/nxp/pinctrl-imx.c +++ b/drivers/pinctrl/nxp/pinctrl-imx.c @@ -28,7 +28,9 @@ static int imx_pinctrl_set_state(struct udevice *dev, struct udevice *config) dev_dbg(dev, "%s: %s\n", __func__, config->name); - if (info->flags & SHARE_MUX_CONF_REG) + if (info->flags & IMX8_USE_SCU) + pin_size = SHARE_IMX8_PIN_SIZE; + else if (info->flags & SHARE_MUX_CONF_REG) pin_size = SHARE_FSL_PIN_SIZE; else pin_size = FSL_PIN_SIZE; @@ -58,112 +60,127 @@ static int imx_pinctrl_set_state(struct udevice *dev, struct udevice *config) npins = size / pin_size; - /* - * Refer to linux documentation for details: - * Documentation/devicetree/bindings/pinctrl/fsl,imx-pinctrl.txt - */ - for (i = 0; i < npins; i++) { - mux_reg = pin_data[j++]; - - if (!(info->flags & ZERO_OFFSET_VALID) && !mux_reg) - mux_reg = -1; - - if (info->flags & SHARE_MUX_CONF_REG) { - conf_reg = mux_reg; - } else { - conf_reg = pin_data[j++]; - if (!(info->flags & ZERO_OFFSET_VALID) && !conf_reg) - conf_reg = -1; - } + if (info->flags & IMX8_USE_SCU) { + imx_pinctrl_scu_conf_pins(info, pin_data, npins); + } else { + /* + * Refer to linux documentation for details: + * Documentation/devicetree/bindings/pinctrl/fsl,imx-pinctrl.txt + */ + for (i = 0; i < npins; i++) { + mux_reg = pin_data[j++]; - if ((mux_reg == -1) || (conf_reg == -1)) { - dev_err(dev, "Error mux_reg or conf_reg\n"); - devm_kfree(dev, pin_data); - return -EINVAL; - } + if (!(info->flags & ZERO_OFFSET_VALID) && !mux_reg) + mux_reg = -1; - input_reg = pin_data[j++]; - mux_mode = pin_data[j++]; - input_val = pin_data[j++]; - config_val = pin_data[j++]; + if (info->flags & SHARE_MUX_CONF_REG) { + conf_reg = mux_reg; + } else { + conf_reg = pin_data[j++]; + if (!(info->flags & ZERO_OFFSET_VALID) && + !conf_reg) + conf_reg = -1; + } - dev_dbg(dev, "mux_reg 0x%x, conf_reg 0x%x, input_reg 0x%x, " - "mux_mode 0x%x, input_val 0x%x, config_val 0x%x\n", - mux_reg, conf_reg, input_reg, mux_mode, input_val, - config_val); + if ((mux_reg == -1) || (conf_reg == -1)) { + dev_err(dev, "Error mux_reg or conf_reg\n"); + devm_kfree(dev, pin_data); + return -EINVAL; + } - if (config_val & IMX_PAD_SION) - mux_mode |= IOMUXC_CONFIG_SION; + input_reg = pin_data[j++]; + mux_mode = pin_data[j++]; + input_val = pin_data[j++]; + config_val = pin_data[j++]; - config_val &= ~IMX_PAD_SION; + dev_dbg(dev, "mux_reg 0x%x, conf_reg 0x%x, " + "input_reg 0x%x, mux_mode 0x%x, " + "input_val 0x%x, config_val 0x%x\n", + mux_reg, conf_reg, input_reg, mux_mode, + input_val, config_val); - /* Set Mux */ - if (info->flags & SHARE_MUX_CONF_REG) { - clrsetbits_le32(info->base + mux_reg, info->mux_mask, - mux_mode << mux_shift); - } else { - writel(mux_mode, info->base + mux_reg); - } + if (config_val & IMX_PAD_SION) + mux_mode |= IOMUXC_CONFIG_SION; - dev_dbg(dev, "write mux: offset 0x%x val 0x%x\n", mux_reg, - mux_mode); + config_val &= ~IMX_PAD_SION; - /* - * Set select input - * - * If the select input value begins with 0xff, it's a quirky - * select input and the value should be interpreted as below. - * 31 23 15 7 0 - * | 0xff | shift | width | select | - * It's used to work around the problem that the select - * input for some pin is not implemented in the select - * input register but in some general purpose register. - * We encode the select input value, width and shift of - * the bit field into input_val cell of pin function ID - * in device tree, and then decode them here for setting - * up the select input bits in general purpose register. - */ + /* Set Mux */ + if (info->flags & SHARE_MUX_CONF_REG) { + clrsetbits_le32(info->base + mux_reg, + info->mux_mask, + mux_mode << mux_shift); + } else { + writel(mux_mode, info->base + mux_reg); + } + + dev_dbg(dev, "write mux: offset 0x%x val 0x%x\n", + mux_reg, mux_mode); - if (input_val >> 24 == 0xff) { - u32 val = input_val; - u8 select = val & 0xff; - u8 width = (val >> 8) & 0xff; - u8 shift = (val >> 16) & 0xff; - u32 mask = ((1 << width) - 1) << shift; - /* - * The input_reg[i] here is actually some IOMUXC general - * purpose register, not regular select input register. - */ - val = readl(info->base + input_reg); - val &= ~mask; - val |= select << shift; - writel(val, info->base + input_reg); - } else if (input_reg) { /* - * Regular select input register can never be at offset - * 0, and we only print register value for regular case. + * Set select input + * + * If the select input value begins with 0xff, + * it's a quirky select input and the value should + * be interpreted as below. + * 31 23 15 7 0 + * | 0xff | shift | width | select | + * It's used to work around the problem that the + * select input for some pin is not implemented in + * the select input register but in some general + * purpose register. We encode the select input + * value, width and shift of the bit field into + * input_val cell of pin function ID in device tree, + * and then decode them here for setting up the select + * input bits in general purpose register. */ - if (info->input_sel_base) - writel(input_val, info->input_sel_base + - input_reg); - else - writel(input_val, info->base + input_reg); - - dev_dbg(dev, "select_input: offset 0x%x val 0x%x\n", - input_reg, input_val); - } - /* Set config */ - if (!(config_val & IMX_NO_PAD_CTL)) { - if (info->flags & SHARE_MUX_CONF_REG) { - clrsetbits_le32(info->base + conf_reg, - ~info->mux_mask, config_val); - } else { - writel(config_val, info->base + conf_reg); + if (input_val >> 24 == 0xff) { + u32 val = input_val; + u8 select = val & 0xff; + u8 width = (val >> 8) & 0xff; + u8 shift = (val >> 16) & 0xff; + u32 mask = ((1 << width) - 1) << shift; + /* + * The input_reg[i] here is actually some + * IOMUXC general purpose register, not + * regular select input register. + */ + val = readl(info->base + input_reg); + val &= ~mask; + val |= select << shift; + writel(val, info->base + input_reg); + } else if (input_reg) { + /* + * Regular select input register can never be + * at offset 0, and we only print register + * value for regular case. + */ + if (info->input_sel_base) + writel(input_val, + info->input_sel_base + + input_reg); + else + writel(input_val, + info->base + input_reg); + + dev_dbg(dev, "select_input: offset 0x%x val " + "0x%x\n", input_reg, input_val); } - dev_dbg(dev, "write config: offset 0x%x val 0x%x\n", - conf_reg, config_val); + /* Set config */ + if (!(config_val & IMX_NO_PAD_CTL)) { + if (info->flags & SHARE_MUX_CONF_REG) { + clrsetbits_le32(info->base + conf_reg, + ~info->mux_mask, + config_val); + } else { + writel(config_val, + info->base + conf_reg); + } + + dev_dbg(dev, "write config: offset 0x%x val " + "0x%x\n", conf_reg, config_val); + } } } @@ -193,6 +210,9 @@ int imx_pinctrl_probe(struct udevice *dev, priv->dev = dev; priv->info = info; + if (info->flags & IMX8_USE_SCU) + return 0; + addr = fdtdec_get_addr_size(gd->fdt_blob, dev_of_offset(dev), "reg", &size); @@ -238,6 +258,9 @@ int imx_pinctrl_remove(struct udevice *dev) struct imx_pinctrl_priv *priv = dev_get_priv(dev); struct imx_pinctrl_soc_info *info = priv->info; + if (info->flags & IMX8_USE_SCU) + return 0; + if (info->input_sel_base) unmap_sysmem(info->input_sel_base); if (info->base) diff --git a/drivers/pinctrl/nxp/pinctrl-imx.h b/drivers/pinctrl/nxp/pinctrl-imx.h index b0032455b7..947975ee72 100644 --- a/drivers/pinctrl/nxp/pinctrl-imx.h +++ b/drivers/pinctrl/nxp/pinctrl-imx.h @@ -40,13 +40,29 @@ extern const struct pinctrl_ops imx_pinctrl_ops; #define FSL_PIN_SIZE 24 #define SHARE_FSL_PIN_SIZE 20 +/* Each pin on imx8qm/qxp consists of 2 u32 PIN_FUNC_ID and 1 u32 CONFIG */ +#define SHARE_IMX8_PIN_SIZE 12 + #define SHARE_MUX_CONF_REG 0x1 #define ZERO_OFFSET_VALID 0x2 #define CONFIG_IBE_OBE 0x4 +#define IMX8_USE_SCU 0x8 #define IOMUXC_CONFIG_SION (0x1 << 4) int imx_pinctrl_probe(struct udevice *dev, struct imx_pinctrl_soc_info *info); int imx_pinctrl_remove(struct udevice *dev); + +#ifdef CONFIG_PINCTRL_IMX_SCU +int imx_pinctrl_scu_conf_pins(struct imx_pinctrl_soc_info *info, + u32 *pin_data, int npins); +#else +static inline int imx_pinctrl_scu_conf_pins(struct imx_pinctrl_soc_info *info, + u32 *pin_data, int npins) +{ + return 0; +} +#endif + #endif /* __DRIVERS_PINCTRL_IMX_H */ diff --git a/drivers/pinctrl/nxp/pinctrl-imx8.c b/drivers/pinctrl/nxp/pinctrl-imx8.c new file mode 100644 index 0000000000..0738da0ebe --- /dev/null +++ b/drivers/pinctrl/nxp/pinctrl-imx8.c @@ -0,0 +1,40 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2018 NXP + */ + +#include +#include +#include + +#include "pinctrl-imx.h" + +DECLARE_GLOBAL_DATA_PTR; + +static struct imx_pinctrl_soc_info imx8_pinctrl_soc_info = { + .flags = IMX8_USE_SCU, +}; + +static int imx8_pinctrl_probe(struct udevice *dev) +{ + struct imx_pinctrl_soc_info *info = + (struct imx_pinctrl_soc_info *)dev_get_driver_data(dev); + + return imx_pinctrl_probe(dev, info); +} + +static const struct udevice_id imx8_pinctrl_match[] = { + { .compatible = "fsl,imx8qxp-iomuxc", .data = (ulong)&imx8_pinctrl_soc_info }, + { /* sentinel */ } +}; + +U_BOOT_DRIVER(imx8_pinctrl) = { + .name = "imx8_pinctrl", + .id = UCLASS_PINCTRL, + .of_match = of_match_ptr(imx8_pinctrl_match), + .probe = imx8_pinctrl_probe, + .remove = imx_pinctrl_remove, + .priv_auto_alloc_size = sizeof(struct imx_pinctrl_priv), + .ops = &imx_pinctrl_ops, + .flags = DM_FLAG_PRE_RELOC, +}; diff --git a/drivers/pinctrl/nxp/pinctrl-scu.c b/drivers/pinctrl/nxp/pinctrl-scu.c new file mode 100644 index 0000000000..aa11075e0a --- /dev/null +++ b/drivers/pinctrl/nxp/pinctrl-scu.c @@ -0,0 +1,66 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2018 NXP + */ + +#include +#include +#include +#include +#include +#include + +#include "pinctrl-imx.h" + +#define PADRING_IFMUX_EN_SHIFT 31 +#define PADRING_IFMUX_EN_MASK BIT(31) +#define PADRING_GP_EN_SHIFT 30 +#define PADRING_GP_EN_MASK BIT(30) +#define PADRING_IFMUX_SHIFT 27 +#define PADRING_IFMUX_MASK GENMASK(29, 27) + +static int imx_pinconf_scu_set(struct imx_pinctrl_soc_info *info, u32 pad, + u32 mux, u32 val) +{ + int ret; + + /* + * Mux should be done in pmx set, but we do not have a good api + * to handle that in scfw, so config it in pad conf func + */ + + val |= PADRING_IFMUX_EN_MASK; + val |= PADRING_GP_EN_MASK; + val |= (mux << PADRING_IFMUX_SHIFT) & PADRING_IFMUX_MASK; + + ret = sc_pad_set(-1, pad, val); + if (ret) + printf("%s %d\n", __func__, ret); + + return 0; +} + +int imx_pinctrl_scu_conf_pins(struct imx_pinctrl_soc_info *info, u32 *pin_data, + int npins) +{ + int pin_id, mux, config_val; + int i, j = 0; + int ret; + + /* + * Refer to linux documentation for details: + * Documentation/devicetree/bindings/pinctrl/fsl,imx-pinctrl.txt + */ + for (i = 0; i < npins; i++) { + pin_id = pin_data[j++]; + mux = pin_data[j++]; + config_val = pin_data[j++]; + + ret = imx_pinconf_scu_set(info, pin_id, mux, config_val); + if (ret) + printf("Set pin %d, mux %d, val %d, error\n", pin_id, + mux, config_val); + } + + return 0; +}