From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id DA508C61DA3 for ; Thu, 26 Jan 2023 18:12:12 +0000 (UTC) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 69870856E9; Thu, 26 Jan 2023 19:12:10 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="GWOSAxhi"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 25ABB856C7; Thu, 26 Jan 2023 19:11:33 +0100 (CET) Received: from mail-ed1-x533.google.com (mail-ed1-x533.google.com [IPv6:2a00:1450:4864:20::533]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id B541685524 for ; Thu, 26 Jan 2023 19:11:18 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=jbx6244@gmail.com Received: by mail-ed1-x533.google.com with SMTP id y19so2651293edc.2 for ; Thu, 26 Jan 2023 10:11:18 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:in-reply-to:from:content-language :references:cc:to:subject:user-agent:mime-version:date:message-id :from:to:cc:subject:date:message-id:reply-to; bh=F77ms5/eNh8470pAXh7RMnh0cIgoON1yFzwW2s0Xeu0=; b=GWOSAxhig1xIxSoQlMw+h806RysfTYek8EK+v5yQahMdltObKGERbYfzd4Q1wDN2WI G50JAuGr0gm4m+nnWQls9FbG+RmBEKQ3GG3KA8KU2pgKr2LI1TKuyWw2vPFGUHkhgIcu zTFr5rgpR7dpBSUj1KPneQvdIaUFc9H9jT/nGMHHQjZnXvBnF89tebwCSFZ7UNmgY4L4 8IAtDr9H2HNdSz1sZaatQ1JqbuWd7DUS3g6dFHr96RHg9POvmwUbcF9pYYIhNNxuGNy9 RY+Cn+4gcO3+isDoiDVaxMYE+y0qXjK5tAQdY3fgIYlAiDnm35jaDlzfBCXsF7z7Iqlo d0Jw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:in-reply-to:from:content-language :references:cc:to:subject:user-agent:mime-version:date:message-id :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=F77ms5/eNh8470pAXh7RMnh0cIgoON1yFzwW2s0Xeu0=; b=dlxNSfyCBpiGSse2tKQl0oGBr5rDVIWbPoo7OpWXUkHx8HmiwiypSdH9cOmNp+WXzB CzFZ/MdmjnbxD1OPZs7WYD+SrUlP61OBd4tuBLs9XWvUM+9zbjkq6uZ3+b65ZWBJ3t/q TfQ3YWH9/RQvDJqqhhmTu1TYdXj3lU6VwGgcmcRpPgsl56SV9KYMeHigCBmRuv1AUTz1 NfC2G8d+L3dw+gJ8UKxJkeT3kFA+f4RrynpzhNxSNnp8SRRWemhqyep0xro0gJO7ZbSJ qXZYea5E+RBaJk6J46vFzRVNbR0xvdOmalYbE5y3vh18DqwYbxfXMJOIoFGuxzfNx3sS 50HQ== X-Gm-Message-State: AO0yUKVZe57Afb41W3asW0CMydf8829pFOQpQUDNyb7E6Jrz1F/9qCTQ JG38ZSAkJgpAMmt9KTFQhD4= X-Google-Smtp-Source: AK7set+EpTo3A7jMq1RtU7t2+7xwglSXxJ3eqVSR7JAJqUZ0L8flMjyiN2GqufhX9ICyrj9L62V8yg== X-Received: by 2002:aa7:d899:0:b0:4a1:a308:8b8f with SMTP id u25-20020aa7d899000000b004a1a3088b8fmr192814edq.20.1674756677991; Thu, 26 Jan 2023 10:11:17 -0800 (PST) Received: from [192.168.2.1] (81-204-249-205.fixed.kpn.net. [81.204.249.205]) by smtp.gmail.com with ESMTPSA id a6-20020a509b46000000b0049e65e4ff20sm1088644edj.14.2023.01.26.10.11.16 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 26 Jan 2023 10:11:17 -0800 (PST) Message-ID: Date: Thu, 26 Jan 2023 19:11:15 +0100 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.3.0 Subject: Re: [PATCH 5/5] gpio/rockchip: rk_gpio support v2 gpio controller To: Chris Morgan , Chris Morgan Cc: Quentin Schulz , u-boot@lists.denx.de, sjg@chromium.org, philipp.tomsich@vrull.eu, kever.yang@rock-chips.com, chenjh@rock-chips.com, pgwipeout@gmail.com, Heiko Stuebner References: <20230105153428.392250-1-macroalpha82@gmail.com> <20230105153428.392250-6-macroalpha82@gmail.com> <6d8ad8f7-8319-7844-9535-b6982dfa2de3@theobroma-systems.com> <63d2a634.4a0a0220.79a2f.28cb@mx.google.com> Content-Language: en-US From: Johan Jonker In-Reply-To: <63d2a634.4a0a0220.79a2f.28cb@mx.google.com> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 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" X-Virus-Scanned: clamav-milter 0.103.6 at phobos.denx.de X-Virus-Status: Clean On 1/26/23 17:11, Chris Morgan wrote: > On Thu, Jan 19, 2023 at 12:21:02PM -0600, Chris Morgan wrote: >> On Thu, Jan 05, 2023 at 07:01:40PM +0100, Quentin Schulz wrote: >>> Hi Chris, >>> >>> Cc'ing the new mail address of Heiko so he receives this mail :) >>> >>> On 1/5/23 16:34, Chris Morgan wrote: >>>> From: Chris Morgan >>>> >>>> Add support for the newer GPIO controller used by the rk356x series, >>>> as well as the pinctrl device for the rk356x series. The GPIOv2 >>>> controller has a write enable bit for some registers which differs >>>> from the older versions of the GPIO controller. >>>> >>>> Adapted from Peter Geis's gitlab located here: >>>> https://urldefense.com/v3/__https://gitlab.com/pgwipeout/u-boot-quartz64/-/commit/1a84cc483d0979fa00c6f7d6c76d870c25ab3cbd__;!!OOPJP91ZZw!i7xaxb0VOR6CU_lauUnYs4-WlEgdGZCaETaNwp--V4jwJoQguyPr07GTOXDhDNNYL4vYLzae_eObZKZUYUAm4pVFA6vGK-JnXjIz$ >>>> >>>> Signed-off-by: Chris Morgan >>>> --- >>>> arch/arm/include/asm/arch-rockchip/gpio.h | 38 ++ >>>> drivers/gpio/Kconfig | 13 + >>>> drivers/gpio/rk_gpio.c | 103 +++- >>>> drivers/pinctrl/rockchip/Makefile | 1 + >>>> drivers/pinctrl/rockchip/pinctrl-rk3568.c | 453 ++++++++++++++++++ >>>> .../pinctrl/rockchip/pinctrl-rockchip-core.c | 12 +- >>>> drivers/pinctrl/rockchip/pinctrl-rockchip.h | 42 ++ >>>> 7 files changed, 635 insertions(+), 27 deletions(-) >>>> create mode 100644 drivers/pinctrl/rockchip/pinctrl-rk3568.c >>>> >>>> diff --git a/arch/arm/include/asm/arch-rockchip/gpio.h b/arch/arm/include/asm/arch-rockchip/gpio.h >>>> index 1aaec5faec..29120ceaf3 100644 >>>> --- a/arch/arm/include/asm/arch-rockchip/gpio.h >>>> +++ b/arch/arm/include/asm/arch-rockchip/gpio.h >>>> @@ -6,6 +6,7 @@ >>>> #ifndef _ASM_ARCH_GPIO_H >>>> #define _ASM_ARCH_GPIO_H >>>> +#ifndef CONFIG_ROCKCHIP_GPIO_V2 >>>> struct rockchip_gpio_regs { >>>> u32 swport_dr; >>>> u32 swport_ddr; >>>> @@ -22,7 +23,44 @@ struct rockchip_gpio_regs { >>>> u32 reserved1[(0x60 - 0x54) / 4]; >>>> u32 ls_sync; >>>> }; >>>> + >>>> check_member(rockchip_gpio_regs, ls_sync, 0x60); >>>> +#else >>>> +struct rockchip_gpio_regs { >>>> + u32 swport_dr_l; /* ADDRESS OFFSET: 0x0000 */ >>>> + u32 swport_dr_h; /* ADDRESS OFFSET: 0x0004 */ >>>> + u32 swport_ddr_l; /* ADDRESS OFFSET: 0x0008 */ >>>> + u32 swport_ddr_h; /* ADDRESS OFFSET: 0x000c */ >>>> + u32 int_en_l; /* ADDRESS OFFSET: 0x0010 */ >>>> + u32 int_en_h; /* ADDRESS OFFSET: 0x0014 */ >>>> + u32 int_mask_l; /* ADDRESS OFFSET: 0x0018 */ >>>> + u32 int_mask_h; /* ADDRESS OFFSET: 0x001c */ >>>> + u32 int_type_l; /* ADDRESS OFFSET: 0x0020 */ >>>> + u32 int_type_h; /* ADDRESS OFFSET: 0x0024 */ >>>> + u32 int_polarity_l; /* ADDRESS OFFSET: 0x0028 */ >>>> + u32 int_polarity_h; /* ADDRESS OFFSET: 0x002c */ >>>> + u32 int_bothedge_l; /* ADDRESS OFFSET: 0x0030 */ >>>> + u32 int_bothedge_h; /* ADDRESS OFFSET: 0x0034 */ >>>> + u32 debounce_l; /* ADDRESS OFFSET: 0x0038 */ >>>> + u32 debounce_h; /* ADDRESS OFFSET: 0x003c */ >>>> + u32 dbclk_div_en_l; /* ADDRESS OFFSET: 0x0040 */ >>>> + u32 dbclk_div_en_h; /* ADDRESS OFFSET: 0x0044 */ >>>> + u32 dbclk_div_con; /* ADDRESS OFFSET: 0x0048 */ >>>> + u32 reserved004c; /* ADDRESS OFFSET: 0x004c */ >>>> + u32 int_status; /* ADDRESS OFFSET: 0x0050 */ >>>> + u32 reserved0054; /* ADDRESS OFFSET: 0x0054 */ >>>> + u32 int_rawstatus; /* ADDRESS OFFSET: 0x0058 */ >>>> + u32 reserved005c; /* ADDRESS OFFSET: 0x005c */ >>>> + u32 port_eoi_l; /* ADDRESS OFFSET: 0x0060 */ >>>> + u32 port_eoi_h; /* ADDRESS OFFSET: 0x0064 */ >>>> + u32 reserved0068[2]; /* ADDRESS OFFSET: 0x0068 */ >>>> + u32 ext_port; /* ADDRESS OFFSET: 0x0070 */ >>>> + u32 reserved0074; /* ADDRESS OFFSET: 0x0074 */ >>>> + u32 ver_id; /* ADDRESS OFFSET: 0x0078 */ >>>> +}; >>>> + >>>> +check_member(rockchip_gpio_regs, ver_id, 0x0078); >>>> +#endif >>>> enum gpio_pu_pd { >>>> GPIO_PULL_NORMAL = 0, >>>> diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig >>>> index ff87fbfb39..bd7422a0b3 100644 >>>> --- a/drivers/gpio/Kconfig >>>> +++ b/drivers/gpio/Kconfig >>>> @@ -340,6 +340,19 @@ config ROCKCHIP_GPIO >>>> The GPIOs for a device are defined in the device tree with one node >>>> for each bank. >>>> +config ROCKCHIP_GPIO_V2 >>>> + bool "Rockchip GPIO driver version 2.0" >>>> + depends on ROCKCHIP_GPIO >>> >>> I would make ROCKCHIP_GPIO and ROCKCHIP_GPIO_V2 incompatible with each >>> other, otherwise ROCKCHIP_GPIO represents both the GPIO controller and the >>> v1, but not v1 if v2 is selected. That's a bit confusing to me. >>> >>> [...] In Linux they think it is better to use one common fall back string . compatible = "rockchip,rk3568-gpio-bank", "rockchip,gpio-bank"; >>>> @@ -142,19 +171,49 @@ static int rockchip_gpio_probe(struct udevice *dev) >>>> { >>>> struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); >>>> struct rockchip_gpio_priv *priv = dev_get_priv(dev); >>>> - char *end; >>>> - int ret; >>>> + struct rockchip_pinctrl_priv *pctrl_priv; >>>> + struct rockchip_pin_bank *bank; >>>> + char *end = NULL; >>>> + static int gpio; >>>> + int id = -1, ret; >>>> priv->regs = dev_read_addr_ptr(dev); >>>> ret = uclass_first_device_err(UCLASS_PINCTRL, &priv->pinctrl); >>>> - if (ret) >>>> + if (ret) { >>>> + dev_err(dev, "failed to get pinctrl device %d\n", ret); >>>> return ret; >>>> + } >>>> + >>>> + pctrl_priv = dev_get_priv(priv->pinctrl); >>>> + if (!pctrl_priv) { >>>> + dev_err(dev, "failed to get pinctrl priv\n"); >>>> + return -EINVAL; >>>> + } >>>> - uc_priv->gpio_count = ROCKCHIP_GPIOS_PER_BANK; >>>> end = strrchr(dev->name, '@'); Question for the Rockchip U-boot maintainers: Would you like to keep this method for backward compatibillity together with "gpio-ranges"? All dtsi files must be changed first! >>>> - priv->bank = trailing_strtoln(dev->name, end); >>>> - priv->name[0] = 'A' + priv->bank; >>>> - uc_priv->bank_name = priv->name; >>>> + if (end) >>>> + id = trailing_strtoln(dev->name, end); >>>> + else >>>> + dev_read_alias_seq(dev, &id); >>>> + >>>> + if (id < 0) >>>> + id = gpio++; >>>> + >>> >>> NACK. This does not work. >>> >>> This means that the gpio bank detection depends on: >>> 1) the index of the alias (no guarantee it's stable/not overwritten by a >>> board dts), >>> 2) if no support for aliases (e.g. in TPL/SPL) or the alias does not exist, >>> the probe order of the GPIO controller device will define its bank. This is >>> somewhat working in the Linux kernel by chance but does NOT work in U-Boot >>> (devices are probed only when used, so you could very well have gpio4 >>> controller probed before gpio0 and then gpio4 would represent bank 0 and >>> then gpio0 represent bank 1). >>> >>> Yes, the current code will not work for "newer" DTS and needs to be adapted >>> (FWIW, it does not work on PX30 already because the node name is gpio@addr >>> instead of gpioX@addr), but the Linux kernel implementation (the one used >>> above) is not correct and should not be used. >>> >>> I've two suggestions: >>> 1) a rockchip,gpio-controller-bank = <0>; property in the -u-boot.dtsi for >>> each gpio-controller and then you get the index from there in the driver, >>> 2) get the register address of the node of the device you're currently >>> probing and maintain a mapping of which address maps to which bank, >>> >>> We could also start a discussion with upstream Linux to see what they would >>> like to go for so we don't have two different implementations. >> >> I see RFC patches for Linux to use a property called "gpio-ranges". >> I'll wait for that to gain traction as a solution before I resubmit >> this so that Linux/U-Boot use roughly the same method (assuming >> Johan doesn't beat me to the punch, since it's his Linux patches >> I'm following). >> >> Thank you. > > I see the mainline patches that Johan Jonker put together have been > acked. Johan, are you going to also include these in U-Boot or would > you like for me to try my hand at it here as part of this series? If you have the time... As you are already touching gpio with a common fall back string then it's best you do that in separate patch series. Mind it involves a lot of dtsi changes before this can be merged. Moving gpio nodes to root must also make it work both full U-boot and SPL reduced DT and with platdata if possible. Johan > > Thank you. > >> >>> >>>> + if (id >= pctrl_priv->ctrl->nr_banks) { >>>> + dev_err(dev, "bank id invalid\n"); >>>> + return -EINVAL; >>>> + } >>>> + >>>> + bank = &pctrl_priv->ctrl->pin_banks[id]; >>>> + if (bank->bank_num != id) { >>>> + dev_err(dev, "bank id mismatch with pinctrl\n"); >>>> + return -EINVAL; >>>> + } >>>> + >>>> + priv->bank = bank->bank_num; >>>> + uc_priv->gpio_count = bank->nr_pins; >>>> + uc_priv->gpio_base = bank->pin_base; >>>> + uc_priv->bank_name = bank->name; >>>> return 0; >>>> } >>>> diff --git a/drivers/pinctrl/rockchip/Makefile b/drivers/pinctrl/rockchip/Makefile >>>> index 7d03f8101d..c78fc2c331 100644 >>>> --- a/drivers/pinctrl/rockchip/Makefile >>>> +++ b/drivers/pinctrl/rockchip/Makefile >>>> @@ -14,4 +14,5 @@ obj-$(CONFIG_ROCKCHIP_RK3308) += pinctrl-rk3308.o >>>> obj-$(CONFIG_ROCKCHIP_RK3328) += pinctrl-rk3328.o >>>> obj-$(CONFIG_ROCKCHIP_RK3368) += pinctrl-rk3368.o >>>> obj-$(CONFIG_ROCKCHIP_RK3399) += pinctrl-rk3399.o >>>> +obj-$(CONFIG_ROCKCHIP_RK3568) += pinctrl-rk3568.o >>>> obj-$(CONFIG_ROCKCHIP_RV1108) += pinctrl-rv1108.o >>>> diff --git a/drivers/pinctrl/rockchip/pinctrl-rk3568.c b/drivers/pinctrl/rockchip/pinctrl-rk3568.c >>>> new file mode 100644 >>>> index 0000000000..dce1c1e7ee >>>> --- /dev/null >>>> +++ b/drivers/pinctrl/rockchip/pinctrl-rk3568.c >>>> @@ -0,0 +1,453 @@ >>>> +// SPDX-License-Identifier: GPL-2.0+ >>>> +/* >>>> + * (C) Copyright 2020 Rockchip Electronics Co., Ltd >>>> + */ >>>> + >>>> +#include >>>> +#include >>>> +#include >>>> +#include >>>> +#include >>>> + >>>> +#include "pinctrl-rockchip.h" >>>> + >>>> +static struct rockchip_mux_route_data rk3568_mux_route_data[] = { >>>> + /* CAN0 IO mux selection M0 */ >>>> + MR_TOPGRF(RK_GPIO0, RK_PB3, RK_FUNC_2, 0x0300, RK_GENMASK_VAL(0, 0, 0)), >>>> + /* CAN0 IO mux selection M1 */ >>>> + MR_TOPGRF(RK_GPIO2, RK_PA1, RK_FUNC_4, 0x0300, RK_GENMASK_VAL(0, 0, 1)), >>>> + /* CAN1 IO mux selection M0 */ >>>> + MR_TOPGRF(RK_GPIO1, RK_PA1, RK_FUNC_3, 0x0300, RK_GENMASK_VAL(2, 2, 0)), >>>> + /* CAN1 IO mux selection M1 */ >>>> + MR_TOPGRF(RK_GPIO4, RK_PC3, RK_FUNC_3, 0x0300, RK_GENMASK_VAL(2, 2, 1)), >>>> + /* CAN2 IO mux selection M0 */ >>>> + MR_TOPGRF(RK_GPIO4, RK_PB5, RK_FUNC_3, 0x0300, RK_GENMASK_VAL(4, 4, 0)), >>>> + /* CAN2 IO mux selection M1 */ >>>> + MR_TOPGRF(RK_GPIO2, RK_PB2, RK_FUNC_4, 0x0300, RK_GENMASK_VAL(4, 4, 1)), >>>> + /* EDPDP_HPDIN IO mux selection M0 */ >>>> + MR_TOPGRF(RK_GPIO4, RK_PC4, RK_FUNC_1, 0x0300, RK_GENMASK_VAL(6, 6, 0)), >>>> + /* EDPDP_HPDIN IO mux selection M1 */ >>>> + MR_TOPGRF(RK_GPIO0, RK_PC2, RK_FUNC_2, 0x0300, RK_GENMASK_VAL(6, 6, 1)), >>>> + /* GMAC1 IO mux selection M0 */ >>>> + MR_TOPGRF(RK_GPIO3, RK_PB1, RK_FUNC_3, 0x0300, RK_GENMASK_VAL(8, 8, 0)), >>>> + /* GMAC1 IO mux selection M1 */ >>>> + MR_TOPGRF(RK_GPIO4, RK_PA7, RK_FUNC_3, 0x0300, RK_GENMASK_VAL(8, 8, 1)), >>>> + /* HDMITX IO mux selection M0 */ >>>> + MR_TOPGRF(RK_GPIO4, RK_PD1, RK_FUNC_1, 0x0300, RK_GENMASK_VAL(10, 10, 0)), >>>> + /* HDMITX IO mux selection M1 */ >>>> + MR_TOPGRF(RK_GPIO0, RK_PC7, RK_FUNC_1, 0x0300, RK_GENMASK_VAL(10, 10, 1)), >>>> + /* I2C2 IO mux selection M0 */ >>>> + MR_TOPGRF(RK_GPIO0, RK_PB6, RK_FUNC_1, 0x0300, RK_GENMASK_VAL(14, 14, 0)), >>>> + /* I2C2 IO mux selection M1 */ >>>> + MR_TOPGRF(RK_GPIO4, RK_PB4, RK_FUNC_1, 0x0300, RK_GENMASK_VAL(14, 14, 1)), >>>> + /* I2C3 IO mux selection M0 */ >>>> + MR_TOPGRF(RK_GPIO1, RK_PA0, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(0, 0, 0)), >>>> + /* I2C3 IO mux selection M1 */ >>>> + MR_TOPGRF(RK_GPIO3, RK_PB6, RK_FUNC_4, 0x0304, RK_GENMASK_VAL(0, 0, 1)), >>>> + /* I2C4 IO mux selection M0 */ >>>> + MR_TOPGRF(RK_GPIO4, RK_PB2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(2, 2, 0)), >>>> + /* I2C4 IO mux selection M1 */ >>>> + MR_TOPGRF(RK_GPIO2, RK_PB1, RK_FUNC_2, 0x0304, RK_GENMASK_VAL(2, 2, 1)), >>>> + /* I2C5 IO mux selection M0 */ >>>> + MR_TOPGRF(RK_GPIO3, RK_PB4, RK_FUNC_4, 0x0304, RK_GENMASK_VAL(4, 4, 0)), >>>> + /* I2C5 IO mux selection M1 */ >>>> + MR_TOPGRF(RK_GPIO4, RK_PD0, RK_FUNC_2, 0x0304, RK_GENMASK_VAL(4, 4, 1)), >>>> + /* PWM4 IO mux selection M0 */ >>>> + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(6, 6, 0)), >>>> + /* PWM4 IO mux selection M1 */ >>>> + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(6, 6, 1)), >>>> + /* PWM5 IO mux selection M0 */ >>>> + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(8, 8, 0)), >>>> + /* PWM5 IO mux selection M1 */ >>>> + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(8, 8, 1)), >>>> + /* PWM6 IO mux selection M0 */ >>>> + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(10, 10, 0)), >>>> + /* PWM6 IO mux selection M1 */ >>>> + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(10, 10, 1)), >>>> + /* PWM7 IO mux selection M0 */ >>>> + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(12, 12, 0)), >>>> + /* PWM7 IO mux selection M1 */ >>>> + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(12, 12, 1)), >>>> + /* PWM8 IO mux selection M0 */ >>>> + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(14, 14, 0)), >>>> + /* PWM8 IO mux selection M1 */ >>>> + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(14, 14, 1)), >>>> + /* PWM9 IO mux selection M0 */ >>>> + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(0, 0, 0)), >>>> + /* PWM9 IO mux selection M1 */ >>>> + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(0, 0, 1)), >>>> + /* PWM10 IO mux selection M0 */ >>>> + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(2, 2, 0)), >>>> + /* PWM10 IO mux selection M1 */ >>>> + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(2, 2, 1)), >>>> + /* PWM11 IO mux selection M0 */ >>>> + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(4, 4, 0)), >>>> + /* PWM11 IO mux selection M1 */ >>>> + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(4, 4, 1)), >>>> + /* PWM12 IO mux selection M0 */ >>>> + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(6, 6, 0)), >>>> + /* PWM12 IO mux selection M1 */ >>>> + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(6, 6, 1)), >>>> + /* PWM13 IO mux selection M0 */ >>>> + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(8, 8, 0)), >>>> + /* PWM13 IO mux selection M1 */ >>>> + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(8, 8, 1)), >>>> + /* PWM14 IO mux selection M0 */ >>>> + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(10, 10, 0)), >>>> + /* PWM14 IO mux selection M1 */ >>>> + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(10, 10, 1)), >>>> + /* PWM15 IO mux selection M0 */ >>>> + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(12, 12, 0)), >>>> + /* PWM15 IO mux selection M1 */ >>>> + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(12, 12, 1)), >>>> + /* SDMMC2 IO mux selection M0 */ >>>> + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_3, 0x0308, RK_GENMASK_VAL(14, 14, 0)), >>>> + /* SDMMC2 IO mux selection M1 */ >>>> + MR_TOPGRF(RK_GPIO3, RK_PA5, RK_FUNC_5, 0x0308, RK_GENMASK_VAL(14, 14, 1)), >>>> + /* SPI0 IO mux selection M0 */ >>>> + MR_TOPGRF(RK_GPIO0, RK_PB5, RK_FUNC_2, 0x030c, RK_GENMASK_VAL(0, 0, 0)), >>>> + /* SPI0 IO mux selection M1 */ >>>> + MR_TOPGRF(RK_GPIO2, RK_PD3, RK_FUNC_3, 0x030c, RK_GENMASK_VAL(0, 0, 1)), >>>> + /* SPI1 IO mux selection M0 */ >>>> + MR_TOPGRF(RK_GPIO2, RK_PB5, RK_FUNC_3, 0x030c, RK_GENMASK_VAL(2, 2, 0)), >>>> + /* SPI1 IO mux selection M1 */ >>>> + MR_TOPGRF(RK_GPIO3, RK_PC3, RK_FUNC_3, 0x030c, RK_GENMASK_VAL(2, 2, 1)), >>>> + /* SPI2 IO mux selection M0 */ >>>> + MR_TOPGRF(RK_GPIO2, RK_PC1, RK_FUNC_4, 0x030c, RK_GENMASK_VAL(4, 4, 0)), >>>> + /* SPI2 IO mux selection M1 */ >>>> + MR_TOPGRF(RK_GPIO3, RK_PA0, RK_FUNC_3, 0x030c, RK_GENMASK_VAL(4, 4, 1)), >>>> + /* SPI3 IO mux selection M0 */ >>>> + MR_TOPGRF(RK_GPIO4, RK_PB3, RK_FUNC_4, 0x030c, RK_GENMASK_VAL(6, 6, 0)), >>>> + /* SPI3 IO mux selection M1 */ >>>> + MR_TOPGRF(RK_GPIO4, RK_PC2, RK_FUNC_2, 0x030c, RK_GENMASK_VAL(6, 6, 1)), >>>> + /* UART1 IO mux selection M0 */ >>>> + MR_TOPGRF(RK_GPIO2, RK_PB4, RK_FUNC_2, 0x030c, RK_GENMASK_VAL(8, 8, 0)), >>>> + /* UART1 IO mux selection M1 */ >>>> + MR_TOPGRF(RK_GPIO0, RK_PD1, RK_FUNC_1, 0x030c, RK_GENMASK_VAL(8, 8, 1)), >>>> + /* UART2 IO mux selection M0 */ >>>> + MR_TOPGRF(RK_GPIO0, RK_PD1, RK_FUNC_1, 0x030c, RK_GENMASK_VAL(10, 10, 0)), >>>> + /* UART2 IO mux selection M1 */ >>>> + MR_TOPGRF(RK_GPIO1, RK_PD5, RK_FUNC_2, 0x030c, RK_GENMASK_VAL(10, 10, 1)), >>>> + /* UART3 IO mux selection M0 */ >>>> + MR_TOPGRF(RK_GPIO1, RK_PA1, RK_FUNC_2, 0x030c, RK_GENMASK_VAL(12, 12, 0)), >>>> + /* UART3 IO mux selection M1 */ >>>> + MR_TOPGRF(RK_GPIO3, RK_PB7, RK_FUNC_4, 0x030c, RK_GENMASK_VAL(12, 12, 1)), >>>> + /* UART4 IO mux selection M0 */ >>>> + MR_TOPGRF(RK_GPIO1, RK_PA6, RK_FUNC_2, 0x030c, RK_GENMASK_VAL(14, 14, 0)), >>>> + /* UART4 IO mux selection M1 */ >>>> + MR_TOPGRF(RK_GPIO3, RK_PB2, RK_FUNC_4, 0x030c, RK_GENMASK_VAL(14, 14, 1)), >>>> + /* UART5 IO mux selection M0 */ >>>> + MR_TOPGRF(RK_GPIO2, RK_PA2, RK_FUNC_3, 0x0310, RK_GENMASK_VAL(0, 0, 0)), >>>> + /* UART5 IO mux selection M1 */ >>>> + MR_TOPGRF(RK_GPIO3, RK_PC2, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(0, 0, 1)), >>>> + /* UART6 IO mux selection M0 */ >>>> + MR_TOPGRF(RK_GPIO2, RK_PA4, RK_FUNC_3, 0x0310, RK_GENMASK_VAL(2, 2, 0)), >>>> + /* UART6 IO mux selection M1 */ >>>> + MR_TOPGRF(RK_GPIO1, RK_PD5, RK_FUNC_3, 0x0310, RK_GENMASK_VAL(2, 2, 1)), >>>> + /* UART7 IO mux selection M0 */ >>>> + MR_TOPGRF(RK_GPIO2, RK_PA6, RK_FUNC_3, 0x0310, RK_GENMASK_VAL(5, 4, 0)), >>>> + /* UART7 IO mux selection M1 */ >>>> + MR_TOPGRF(RK_GPIO3, RK_PC4, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(5, 4, 1)), >>>> + /* UART7 IO mux selection M2 */ >>>> + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0310, RK_GENMASK_VAL(5, 4, 2)), >>>> + /* UART8 IO mux selection M0 */ >>>> + MR_TOPGRF(RK_GPIO2, RK_PC5, RK_FUNC_3, 0x0310, RK_GENMASK_VAL(6, 6, 0)), >>>> + /* UART8 IO mux selection M1 */ >>>> + MR_TOPGRF(RK_GPIO2, RK_PD7, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(6, 6, 1)), >>>> + /* UART9 IO mux selection M0 */ >>>> + MR_TOPGRF(RK_GPIO2, RK_PB0, RK_FUNC_3, 0x0310, RK_GENMASK_VAL(9, 8, 0)), >>>> + /* UART9 IO mux selection M1 */ >>>> + MR_TOPGRF(RK_GPIO4, RK_PC5, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(9, 8, 1)), >>>> + /* UART9 IO mux selection M2 */ >>>> + MR_TOPGRF(RK_GPIO4, RK_PA4, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(9, 8, 2)), >>>> + /* I2S1 IO mux selection M0 */ >>>> + MR_TOPGRF(RK_GPIO1, RK_PA2, RK_FUNC_1, 0x0310, RK_GENMASK_VAL(11, 10, 0)), >>>> + /* I2S1 IO mux selection M1 */ >>>> + MR_TOPGRF(RK_GPIO3, RK_PC6, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(11, 10, 1)), >>>> + /* I2S1 IO mux selection M2 */ >>>> + MR_TOPGRF(RK_GPIO2, RK_PD0, RK_FUNC_5, 0x0310, RK_GENMASK_VAL(11, 10, 2)), >>>> + /* I2S2 IO mux selection M0 */ >>>> + MR_TOPGRF(RK_GPIO2, RK_PC1, RK_FUNC_1, 0x0310, RK_GENMASK_VAL(12, 12, 0)), >>>> + /* I2S2 IO mux selection M1 */ >>>> + MR_TOPGRF(RK_GPIO4, RK_PB6, RK_FUNC_5, 0x0310, RK_GENMASK_VAL(12, 12, 1)), >>>> + /* I2S3 IO mux selection M0 */ >>>> + MR_TOPGRF(RK_GPIO3, RK_PA2, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(14, 14, 0)), >>>> + /* I2S3 IO mux selection M1 */ >>>> + MR_TOPGRF(RK_GPIO4, RK_PC2, RK_FUNC_5, 0x0310, RK_GENMASK_VAL(14, 14, 1)), >>>> + /* PDM IO mux selection M0 */ >>>> + MR_TOPGRF(RK_GPIO1, RK_PA6, RK_FUNC_3, 0x0314, RK_GENMASK_VAL(0, 0, 0)), >>>> + /* PDM IO mux selection M1 */ >>>> + MR_TOPGRF(RK_GPIO3, RK_PD6, RK_FUNC_5, 0x0314, RK_GENMASK_VAL(0, 0, 1)), >>>> + /* PCIE20 IO mux selection M0 */ >>>> + MR_TOPGRF(RK_GPIO0, RK_PA5, RK_FUNC_3, 0x0314, RK_GENMASK_VAL(3, 2, 0)), >>>> + /* PCIE20 IO mux selection M1 */ >>>> + MR_TOPGRF(RK_GPIO2, RK_PD0, RK_FUNC_4, 0x0314, RK_GENMASK_VAL(3, 2, 1)), >>>> + /* PCIE20 IO mux selection M2 */ >>>> + MR_TOPGRF(RK_GPIO1, RK_PB0, RK_FUNC_4, 0x0314, RK_GENMASK_VAL(3, 2, 2)), >>>> + /* PCIE30X1 IO mux selection M0 */ >>>> + MR_TOPGRF(RK_GPIO0, RK_PA4, RK_FUNC_3, 0x0314, RK_GENMASK_VAL(5, 4, 0)), >>>> + /* PCIE30X1 IO mux selection M1 */ >>>> + MR_TOPGRF(RK_GPIO2, RK_PD2, RK_FUNC_4, 0x0314, RK_GENMASK_VAL(5, 4, 1)), >>>> + /* PCIE30X1 IO mux selection M2 */ >>>> + MR_TOPGRF(RK_GPIO1, RK_PA5, RK_FUNC_4, 0x0314, RK_GENMASK_VAL(5, 4, 2)), >>>> + /* PCIE30X2 IO mux selection M0 */ >>>> + MR_TOPGRF(RK_GPIO0, RK_PA6, RK_FUNC_2, 0x0314, RK_GENMASK_VAL(7, 6, 0)), >>>> + /* PCIE30X2 IO mux selection M1 */ >>>> + MR_TOPGRF(RK_GPIO2, RK_PD4, RK_FUNC_4, 0x0314, RK_GENMASK_VAL(7, 6, 1)), >>>> + /* PCIE30X2 IO mux selection M2 */ >>>> + MR_TOPGRF(RK_GPIO4, RK_PC2, RK_FUNC_4, 0x0314, RK_GENMASK_VAL(7, 6, 2)), >>>> +}; >>>> + >>>> +static int rk3568_set_mux(struct rockchip_pin_bank *bank, int pin, int mux) >>>> +{ >>>> + struct rockchip_pinctrl_priv *priv = bank->priv; >>>> + int iomux_num = (pin / 8); >>>> + struct regmap *regmap; >>>> + int reg, ret, mask; >>>> + u8 bit; >>>> + u32 data; >>>> + >>>> + debug("setting mux of GPIO%d-%d to %d\n", bank->bank_num, pin, mux); >>>> + >>>> + if (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU) >>>> + regmap = priv->regmap_pmu; >>>> + else >>>> + regmap = priv->regmap_base; >>>> + >>>> + reg = bank->iomux[iomux_num].offset; >>>> + if ((pin % 8) >= 4) >>>> + reg += 0x4; >>>> + bit = (pin % 4) * 4; >>>> + mask = 0xf; >>>> + >>>> + data = (mask << (bit + 16)); >>>> + data |= (mux & mask) << bit; >>>> + ret = regmap_write(regmap, reg, data); >>>> + >>>> + return ret; >>>> +} >>>> + >>>> +#define RK3568_PULL_PMU_OFFSET 0x20 >>>> +#define RK3568_PULL_GRF_OFFSET 0x80 >>>> +#define RK3568_PULL_BITS_PER_PIN 2 >>>> +#define RK3568_PULL_PINS_PER_REG 8 >>>> +#define RK3568_PULL_BANK_STRIDE 0x10 >>>> + >>>> +static void rk3568_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, >>>> + int pin_num, struct regmap **regmap, >>>> + int *reg, u8 *bit) >>>> +{ >>>> + struct rockchip_pinctrl_priv *info = bank->priv; >>>> + >>>> + if (bank->bank_num == 0) { >>>> + *regmap = info->regmap_pmu; >>>> + *reg = RK3568_PULL_PMU_OFFSET; >>>> + *reg += bank->bank_num * RK3568_PULL_BANK_STRIDE; >>>> + } else { >>>> + *regmap = info->regmap_base; >>>> + *reg = RK3568_PULL_GRF_OFFSET; >>>> + *reg += (bank->bank_num - 1) * RK3568_PULL_BANK_STRIDE; >>>> + } >>>> + >>>> + *reg += ((pin_num / RK3568_PULL_PINS_PER_REG) * 4); >>>> + *bit = (pin_num % RK3568_PULL_PINS_PER_REG); >>>> + *bit *= RK3568_PULL_BITS_PER_PIN; >>>> +} >>>> + >>>> +#define RK3568_DRV_PMU_OFFSET 0x70 >>>> +#define RK3568_DRV_GRF_OFFSET 0x200 >>>> +#define RK3568_DRV_BITS_PER_PIN 8 >>>> +#define RK3568_DRV_PINS_PER_REG 2 >>>> +#define RK3568_DRV_BANK_STRIDE 0x40 >>>> + >>>> +static void rk3568_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, >>>> + int pin_num, struct regmap **regmap, >>>> + int *reg, u8 *bit) >>>> +{ >>>> + struct rockchip_pinctrl_priv *info = bank->priv; >>>> + >>>> + /* The first 32 pins of the first bank are located in PMU */ >>>> + if (bank->bank_num == 0) { >>>> + *regmap = info->regmap_pmu; >>>> + *reg = RK3568_DRV_PMU_OFFSET; >>>> + } else { >>>> + *regmap = info->regmap_base; >>>> + *reg = RK3568_DRV_GRF_OFFSET; >>>> + *reg += (bank->bank_num - 1) * RK3568_DRV_BANK_STRIDE; >>>> + } >>>> + >>>> + *reg += ((pin_num / RK3568_DRV_PINS_PER_REG) * 4); >>>> + *bit = (pin_num % RK3568_DRV_PINS_PER_REG); >>>> + *bit *= RK3568_DRV_BITS_PER_PIN; >>>> +} >>>> + >>>> +#define RK3568_SCHMITT_BITS_PER_PIN 2 >>>> +#define RK3568_SCHMITT_PINS_PER_REG 8 >>>> +#define RK3568_SCHMITT_BANK_STRIDE 0x10 >>>> +#define RK3568_SCHMITT_GRF_OFFSET 0xc0 >>>> +#define RK3568_SCHMITT_PMUGRF_OFFSET 0x30 >>>> + >>>> +static int rk3568_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank, >>>> + int pin_num, struct regmap **regmap, >>>> + int *reg, u8 *bit) >>>> +{ >>>> + struct rockchip_pinctrl_priv *info = bank->priv; >>>> + >>>> + if (bank->bank_num == 0) { >>>> + *regmap = info->regmap_pmu; >>>> + *reg = RK3568_SCHMITT_PMUGRF_OFFSET; >>>> + } else { >>>> + *regmap = info->regmap_base; >>>> + *reg = RK3568_SCHMITT_GRF_OFFSET; >>>> + *reg += (bank->bank_num - 1) * RK3568_SCHMITT_BANK_STRIDE; >>>> + } >>>> + >>>> + *reg += ((pin_num / RK3568_SCHMITT_PINS_PER_REG) * 4); >>>> + *bit = pin_num % RK3568_SCHMITT_PINS_PER_REG; >>>> + *bit *= RK3568_SCHMITT_BITS_PER_PIN; >>>> + >>>> + return 0; >>>> +} >>>> + >>>> +static int rk3568_set_pull(struct rockchip_pin_bank *bank, >>>> + int pin_num, int pull) >>>> +{ >>>> + struct regmap *regmap; >>>> + int reg, ret; >>>> + u8 bit, type; >>>> + u32 data; >>>> + >>>> + if (pull == PIN_CONFIG_BIAS_PULL_PIN_DEFAULT) >>>> + return -EOPNOTSUPP; >>>> + >>>> + rk3568_calc_pull_reg_and_bit(bank, pin_num, ®map, ®, &bit); >>>> + type = bank->pull_type[pin_num / 8]; >>>> + ret = rockchip_translate_pull_value(type, pull); >>>> + if (ret < 0) { >>>> + debug("unsupported pull setting %d\n", pull); >>>> + return ret; >>>> + } >>>> + >>>> + /* enable the write to the equivalent lower bits */ >>>> + data = ((1 << ROCKCHIP_PULL_BITS_PER_PIN) - 1) << (bit + 16); >>>> + >>>> + data |= (ret << bit); >>>> + ret = regmap_write(regmap, reg, data); >>>> + >>>> + return ret; >>>> +} >>>> + >>>> +static int rk3568_set_drive(struct rockchip_pin_bank *bank, >>>> + int pin_num, int strength) >>>> +{ >>>> + struct regmap *regmap; >>>> + int reg; >>>> + u32 data; >>>> + u8 bit; >>>> + int drv = (1 << (strength + 1)) - 1; >>>> + int ret = 0; >>>> + >>>> + rk3568_calc_drv_reg_and_bit(bank, pin_num, ®map, ®, &bit); >>>> + >>>> + /* enable the write to the equivalent lower bits */ >>>> + data = ((1 << RK3568_DRV_BITS_PER_PIN) - 1) << (bit + 16); >>>> + data |= (drv << bit); >>>> + >>>> + ret = regmap_write(regmap, reg, data); >>>> + if (ret) >>>> + return ret; >>>> + >>>> + if (bank->bank_num == 1 && pin_num == 21) >>>> + reg = 0x0840; >>>> + else if (bank->bank_num == 2 && pin_num == 2) >>>> + reg = 0x0844; >>>> + else if (bank->bank_num == 2 && pin_num == 8) >>>> + reg = 0x0848; >>>> + else if (bank->bank_num == 3 && pin_num == 0) >>>> + reg = 0x084c; >>>> + else if (bank->bank_num == 3 && pin_num == 6) >>>> + reg = 0x0850; >>>> + else if (bank->bank_num == 4 && pin_num == 0) >>>> + reg = 0x0854; >>>> + else >>>> + return 0; >>>> + >>>> + data = ((1 << RK3568_DRV_BITS_PER_PIN) - 1) << 16; >>>> + data |= drv; >>>> + >>>> + return regmap_write(regmap, reg, data); >>>> +} >>>> + >>>> +static int rk3568_set_schmitt(struct rockchip_pin_bank *bank, >>>> + int pin_num, int enable) >>>> +{ >>>> + struct regmap *regmap; >>>> + int reg; >>>> + u32 data; >>>> + u8 bit; >>>> + >>>> + rk3568_calc_schmitt_reg_and_bit(bank, pin_num, ®map, ®, &bit); >>>> + >>>> + /* enable the write to the equivalent lower bits */ >>>> + data = ((1 << RK3568_SCHMITT_BITS_PER_PIN) - 1) << (bit + 16); >>>> + data |= (enable << bit); >>>> + >>>> + return regmap_write(regmap, reg, data); >>>> +} >>>> + >>>> +static struct rockchip_pin_bank rk3568_pin_banks[] = { >>>> + PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT, >>>> + IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT, >>>> + IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT, >>>> + IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT), >>>> + PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", IOMUX_WIDTH_4BIT, >>>> + IOMUX_WIDTH_4BIT, >>>> + IOMUX_WIDTH_4BIT, >>>> + IOMUX_WIDTH_4BIT), >>>> + PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", IOMUX_WIDTH_4BIT, >>>> + IOMUX_WIDTH_4BIT, >>>> + IOMUX_WIDTH_4BIT, >>>> + IOMUX_WIDTH_4BIT), >>>> + PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", IOMUX_WIDTH_4BIT, >>>> + IOMUX_WIDTH_4BIT, >>>> + IOMUX_WIDTH_4BIT, >>>> + IOMUX_WIDTH_4BIT), >>>> + PIN_BANK_IOMUX_FLAGS(4, 32, "gpio4", IOMUX_WIDTH_4BIT, >>>> + IOMUX_WIDTH_4BIT, >>>> + IOMUX_WIDTH_4BIT, >>>> + IOMUX_WIDTH_4BIT), >>>> +}; >>>> + >>>> +static const struct rockchip_pin_ctrl rk3568_pin_ctrl = { >>>> + .pin_banks = rk3568_pin_banks, >>>> + .nr_banks = ARRAY_SIZE(rk3568_pin_banks), >>>> + .nr_pins = 160, >>>> + .grf_mux_offset = 0x0, >>>> + .pmu_mux_offset = 0x0, >>>> + .iomux_routes = rk3568_mux_route_data, >>>> + .niomux_routes = ARRAY_SIZE(rk3568_mux_route_data), >>>> + .set_mux = rk3568_set_mux, >>>> + .set_pull = rk3568_set_pull, >>>> + .set_drive = rk3568_set_drive, >>>> + .set_schmitt = rk3568_set_schmitt, >>>> +}; >>>> + >>>> +static const struct udevice_id rk3568_pinctrl_ids[] = { >>>> + { >>>> + .compatible = "rockchip,rk3568-pinctrl", >>>> + .data = (ulong)&rk3568_pin_ctrl >>>> + }, >>>> + { } >>>> +}; >>>> + >>>> +U_BOOT_DRIVER(pinctrl_rk3568) = { >>>> + .name = "rockchip_rk3568_pinctrl", >>>> + .id = UCLASS_PINCTRL, >>>> + .of_match = rk3568_pinctrl_ids, >>>> + .priv_auto = sizeof(struct rockchip_pinctrl_priv), >>>> + .ops = &rockchip_pinctrl_ops, >>>> +#if !IS_ENABLED(CONFIG_OF_PLATDATA) >>>> + .bind = dm_scan_fdt_dev, >>>> +#endif >>>> + .probe = rockchip_pinctrl_probe, >>>> +}; >>>> diff --git a/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c b/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c >>>> index 630513ba3a..5f0016ff60 100644 >>>> --- a/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c >>>> +++ b/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c >>>> @@ -400,7 +400,7 @@ static int rockchip_pinctrl_set_state(struct udevice *dev, >>>> int prop_len, param; >>>> const u32 *data; >>>> ofnode node; >>>> -#ifdef CONFIG_OF_LIVE >>>> +#if CONFIG_IS_ENABLED(OF_LIVE) >>> >>> Not sure this is really related or not, would be better in its own commit I >>> believe. >>> >>>> const struct device_node *np; >>>> struct property *pp; >>>> #else >>>> @@ -440,7 +440,7 @@ static int rockchip_pinctrl_set_state(struct udevice *dev, >>>> node = ofnode_get_by_phandle(conf); >>>> if (!ofnode_valid(node)) >>>> return -ENODEV; >>>> -#ifdef CONFIG_OF_LIVE >>>> +#if CONFIG_IS_ENABLED(OF_LIVE) >>>> np = ofnode_to_np(node); >>>> for (pp = np->properties; pp; pp = pp->next) { >>>> prop_name = pp->name; >>>> @@ -515,13 +515,15 @@ static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data(struct udevice *d >>>> /* preset iomux offset value, set new start value */ >>>> if (iom->offset >= 0) { >>>> - if (iom->type & IOMUX_SOURCE_PMU) >>>> + if ((iom->type & IOMUX_SOURCE_PMU) || \ >>>> + (iom->type & IOMUX_L_SOURCE_PMU)) >>> >>> nitpick: Could be if (iom->type & (IOMUX_SOURCE_PMU | IOMUX_L_SOURCE_PMU)) >>> instead. >>> >>>> pmu_offs = iom->offset; >>>> else >>>> grf_offs = iom->offset; >>>> } else { /* set current iomux offset */ >>>> - iom->offset = (iom->type & IOMUX_SOURCE_PMU) ? >>>> - pmu_offs : grf_offs; >>>> + iom->offset = ((iom->type & IOMUX_SOURCE_PMU) || >>>> + (iom->type & IOMUX_L_SOURCE_PMU)) ? >>> >>> Ditto. >>> >>> Cheers, >>> Quentin