From 9be0bf00a167e549e07e25f75b45c4e1c8fce6e2 Mon Sep 17 00:00:00 2001 From: Martin Ayotte Date: Wed, 19 Apr 2017 17:33:23 -0400 Subject: [PATCH] add rccu/rpio patches from Icenowy --- .../sun50iw2-dev/add_sun50i_a64_rccu.patch | 404 ++++++++++++++++++ .../sun50iw2-dev/add_sun50i_a64_rpio.patch | 215 ++++++++++ 2 files changed, 619 insertions(+) create mode 100644 patch/kernel/sun50iw2-dev/add_sun50i_a64_rccu.patch create mode 100644 patch/kernel/sun50iw2-dev/add_sun50i_a64_rpio.patch diff --git a/patch/kernel/sun50iw2-dev/add_sun50i_a64_rccu.patch b/patch/kernel/sun50iw2-dev/add_sun50i_a64_rccu.patch new file mode 100644 index 000000000..1ad041f64 --- /dev/null +++ b/patch/kernel/sun50iw2-dev/add_sun50i_a64_rccu.patch @@ -0,0 +1,404 @@ +diff --git a/drivers/clk/sunxi-ng/Kconfig b/drivers/clk/sunxi-ng/Kconfig +index 8af8f4be8e3b..fbd3f8cd5c22 100644 +--- a/drivers/clk/sunxi-ng/Kconfig ++++ b/drivers/clk/sunxi-ng/Kconfig +@@ -151,4 +151,10 @@ config SUN9I_A80_CCU + default MACH_SUN9I + depends on MACH_SUN9I || COMPILE_TEST + ++config SUN8I_R_CCU ++ bool "Support for Allwinner SoCs' PRCM CCUs" ++ select SUNXI_CCU_DIV ++ select SUNXI_CCU_GATE ++ default MACH_SUN8I || (ARCH_SUNXI && ARM64) ++ + endif +diff --git a/drivers/clk/sunxi-ng/Makefile b/drivers/clk/sunxi-ng/Makefile +index 6feaac0c5600..0ec02fe14c50 100644 +--- a/drivers/clk/sunxi-ng/Makefile ++++ b/drivers/clk/sunxi-ng/Makefile +@@ -25,6 +25,7 @@ obj-$(CONFIG_SUN8I_A23_CCU) += ccu-sun8i-a23.o + obj-$(CONFIG_SUN8I_A33_CCU) += ccu-sun8i-a33.o + obj-$(CONFIG_SUN8I_H3_CCU) += ccu-sun8i-h3.o + obj-$(CONFIG_SUN8I_V3S_CCU) += ccu-sun8i-v3s.o ++obj-$(CONFIG_SUN8I_R_CCU) += ccu-sun8i-r.o + obj-$(CONFIG_SUN9I_A80_CCU) += ccu-sun9i-a80.o + obj-$(CONFIG_SUN9I_A80_CCU) += ccu-sun9i-a80-de.o + obj-$(CONFIG_SUN9I_A80_CCU) += ccu-sun9i-a80-usb.o +diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-r.c b/drivers/clk/sunxi-ng/ccu-sun8i-r.c +new file mode 100644 +index 000000000000..0d027d53dbdf +--- /dev/null ++++ b/drivers/clk/sunxi-ng/ccu-sun8i-r.c +@@ -0,0 +1,213 @@ ++/* ++ * Copyright (c) 2016 Icenowy Zheng ++ * ++ * This software is licensed under the terms of the GNU General Public ++ * License version 2, as published by the Free Software Foundation, and ++ * may be copied, distributed, and modified under those terms. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#include ++#include ++#include ++ ++#include "ccu_common.h" ++#include "ccu_reset.h" ++ ++#include "ccu_div.h" ++#include "ccu_gate.h" ++#include "ccu_mp.h" ++#include "ccu_nm.h" ++ ++#include "ccu-sun8i-r.h" ++ ++static const char * const ar100_parents[] = { "osc32k", "osc24M", ++ "pll-periph0", "iosc" }; ++ ++static struct ccu_div ar100_clk = { ++ .div = _SUNXI_CCU_DIV_FLAGS(4, 2, CLK_DIVIDER_POWER_OF_TWO), ++ ++ .mux = { ++ .shift = 16, ++ .width = 2, ++ ++ .variable_prediv = { ++ .index = 2, ++ .shift = 8, ++ .width = 5, ++ }, ++ }, ++ ++ .common = { ++ .reg = 0x00, ++ .features = CCU_FEATURE_VARIABLE_PREDIV, ++ .hw.init = CLK_HW_INIT_PARENTS("ar100", ++ ar100_parents, ++ &ccu_div_ops, ++ 0), ++ }, ++}; ++ ++static CLK_FIXED_FACTOR(ahb0_clk, "ahb0", "ar100", 1, 1, 0); ++ ++static struct ccu_div apb0_clk = { ++ .div = _SUNXI_CCU_DIV_FLAGS(0, 2, CLK_DIVIDER_POWER_OF_TWO), ++ ++ .common = { ++ .reg = 0x0c, ++ .hw.init = CLK_HW_INIT("apb0", ++ "ahb0", ++ &ccu_div_ops, ++ 0), ++ }, ++}; ++ ++static SUNXI_CCU_GATE(apb0_pio_clk, "apb0-pio", "apb0", ++ 0x28, BIT(0), 0); ++static SUNXI_CCU_GATE(apb0_ir_clk, "apb0-ir", "apb0", ++ 0x28, BIT(1), 0); ++static SUNXI_CCU_GATE(apb0_timer_clk, "apb0-timer", "apb0", ++ 0x28, BIT(2), 0); ++static SUNXI_CCU_GATE(apb0_rsb_clk, "apb0-rsb", "apb0", ++ 0x28, BIT(3), 0); ++static SUNXI_CCU_GATE(apb0_uart_clk, "apb0-uart", "apb0", ++ 0x28, BIT(4), 0); ++static SUNXI_CCU_GATE(apb0_i2c_clk, "apb0-i2c", "apb0", ++ 0x28, BIT(6), 0); ++static SUNXI_CCU_GATE(apb0_twd_clk, "apb0-twd", "apb0", ++ 0x28, BIT(7), 0); ++ ++static const char * const r_mod0_default_parents[] = { "osc32K", "osc24M" }; ++static SUNXI_CCU_MP_WITH_MUX_GATE(ir_clk, "ir", ++ r_mod0_default_parents, 0x54, ++ 0, 4, /* M */ ++ 16, 2, /* P */ ++ 24, 2, /* mux */ ++ BIT(31), /* gate */ ++ 0); ++ ++static struct ccu_common *sun8i_h3_r_ccu_clks[] = { ++ &ar100_clk.common, ++ &apb0_clk.common, ++ &apb0_pio_clk.common, ++ &apb0_ir_clk.common, ++ &apb0_timer_clk.common, ++ &apb0_uart_clk.common, ++ &apb0_i2c_clk.common, ++ &apb0_twd_clk.common, ++ &ir_clk.common, ++}; ++ ++static struct ccu_common *sun50i_a64_r_ccu_clks[] = { ++ &ar100_clk.common, ++ &apb0_clk.common, ++ &apb0_pio_clk.common, ++ &apb0_ir_clk.common, ++ &apb0_timer_clk.common, ++ &apb0_rsb_clk.common, ++ &apb0_uart_clk.common, ++ &apb0_i2c_clk.common, ++ &apb0_twd_clk.common, ++ &ir_clk.common, ++}; ++ ++static struct clk_hw_onecell_data sun8i_h3_r_hw_clks = { ++ .hws = { ++ [CLK_AR100] = &ar100_clk.common.hw, ++ [CLK_AHB0] = &ahb0_clk.hw, ++ [CLK_APB0] = &apb0_clk.common.hw, ++ [CLK_APB0_PIO] = &apb0_pio_clk.common.hw, ++ [CLK_APB0_IR] = &apb0_ir_clk.common.hw, ++ [CLK_APB0_TIMER] = &apb0_timer_clk.common.hw, ++ [CLK_APB0_UART] = &apb0_uart_clk.common.hw, ++ [CLK_APB0_I2C] = &apb0_i2c_clk.common.hw, ++ [CLK_APB0_TWD] = &apb0_twd_clk.common.hw, ++ [CLK_IR] = &ir_clk.common.hw, ++ }, ++ .num = CLK_NUMBER, ++}; ++ ++static struct clk_hw_onecell_data sun50i_a64_r_hw_clks = { ++ .hws = { ++ [CLK_AR100] = &ar100_clk.common.hw, ++ [CLK_AHB0] = &ahb0_clk.hw, ++ [CLK_APB0] = &apb0_clk.common.hw, ++ [CLK_APB0_PIO] = &apb0_pio_clk.common.hw, ++ [CLK_APB0_IR] = &apb0_ir_clk.common.hw, ++ [CLK_APB0_TIMER] = &apb0_timer_clk.common.hw, ++ [CLK_APB0_RSB] = &apb0_rsb_clk.common.hw, ++ [CLK_APB0_UART] = &apb0_uart_clk.common.hw, ++ [CLK_APB0_I2C] = &apb0_i2c_clk.common.hw, ++ [CLK_APB0_TWD] = &apb0_twd_clk.common.hw, ++ [CLK_IR] = &ir_clk.common.hw, ++ }, ++ .num = CLK_NUMBER, ++}; ++ ++static struct ccu_reset_map sun8i_h3_r_ccu_resets[] = { ++ [RST_APB0_IR] = { 0xb0, BIT(1) }, ++ [RST_APB0_TIMER] = { 0xb0, BIT(2) }, ++ [RST_APB0_UART] = { 0xb0, BIT(4) }, ++ [RST_APB0_I2C] = { 0xb0, BIT(6) }, ++}; ++ ++static struct ccu_reset_map sun50i_a64_r_ccu_resets[] = { ++ [RST_APB0_IR] = { 0xb0, BIT(1) }, ++ [RST_APB0_TIMER] = { 0xb0, BIT(2) }, ++ [RST_APB0_RSB] = { 0xb0, BIT(3) }, ++ [RST_APB0_UART] = { 0xb0, BIT(4) }, ++ [RST_APB0_I2C] = { 0xb0, BIT(6) }, ++}; ++ ++static const struct sunxi_ccu_desc sun8i_h3_r_ccu_desc = { ++ .ccu_clks = sun8i_h3_r_ccu_clks, ++ .num_ccu_clks = ARRAY_SIZE(sun8i_h3_r_ccu_clks), ++ ++ .hw_clks = &sun8i_h3_r_hw_clks, ++ ++ .resets = sun8i_h3_r_ccu_resets, ++ .num_resets = ARRAY_SIZE(sun8i_h3_r_ccu_resets), ++}; ++ ++static const struct sunxi_ccu_desc sun50i_a64_r_ccu_desc = { ++ .ccu_clks = sun50i_a64_r_ccu_clks, ++ .num_ccu_clks = ARRAY_SIZE(sun50i_a64_r_ccu_clks), ++ ++ .hw_clks = &sun50i_a64_r_hw_clks, ++ ++ .resets = sun50i_a64_r_ccu_resets, ++ .num_resets = ARRAY_SIZE(sun50i_a64_r_ccu_resets), ++}; ++ ++static void __init sunxi_r_ccu_init(struct device_node *node, ++ const struct sunxi_ccu_desc *desc) ++{ ++ void __iomem *reg; ++ ++ reg = of_io_request_and_map(node, 0, of_node_full_name(node)); ++ if (IS_ERR(reg)) { ++ pr_err("%s: Could not map the clock registers\n", ++ of_node_full_name(node)); ++ return; ++ } ++ ++ sunxi_ccu_probe(node, reg, desc); ++} ++ ++static void __init sun8i_h3_r_ccu_setup(struct device_node *node) ++{ ++ sunxi_r_ccu_init(node, &sun8i_h3_r_ccu_desc); ++} ++CLK_OF_DECLARE(sun8i_h3_r_ccu, "allwinner,sun8i-h3-r-ccu", ++ sun8i_h3_r_ccu_setup); ++ ++static void __init sun50i_a64_r_ccu_setup(struct device_node *node) ++{ ++ sunxi_r_ccu_init(node, &sun50i_a64_r_ccu_desc); ++} ++CLK_OF_DECLARE(sun50i_a64_r_ccu, "allwinner,sun50i-a64-r-ccu", ++ sun50i_a64_r_ccu_setup); +diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-r.h b/drivers/clk/sunxi-ng/ccu-sun8i-r.h +new file mode 100644 +index 000000000000..eaa431fd1d8f +--- /dev/null ++++ b/drivers/clk/sunxi-ng/ccu-sun8i-r.h +@@ -0,0 +1,27 @@ ++/* ++ * Copyright 2016 Icenowy ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#ifndef _CCU_SUN8I_R_H ++#define _CCU_SUN8I_R_H_ ++ ++#include ++#include ++ ++/* AHB/APB bus clocks are not exported */ ++#define CLK_AHB0 1 ++#define CLK_APB0 2 ++ ++#define CLK_NUMBER (CLK_APB0_TWD + 1) ++ ++#endif /* _CCU_SUN8I_R_H */ +diff --git a/include/dt-bindings/clock/sun8i-r-ccu.h b/include/dt-bindings/clock/sun8i-r-ccu.h +new file mode 100644 +index 000000000000..779d20aa0d05 +--- /dev/null ++++ b/include/dt-bindings/clock/sun8i-r-ccu.h +@@ -0,0 +1,59 @@ ++/* ++ * Copyright (c) 2016 Icenowy Zheng ++ * ++ * This file is dual-licensed: you can use it either under the terms ++ * of the GPL or the X11 license, at your option. Note that this dual ++ * licensing only applies to this file, and not this project as a ++ * whole. ++ * ++ * a) This file is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation; either version 2 of the ++ * License, or (at your option) any later version. ++ * ++ * This file is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * Or, alternatively, ++ * ++ * b) Permission is hereby granted, free of charge, to any person ++ * obtaining a copy of this software and associated documentation ++ * files (the "Software"), to deal in the Software without ++ * restriction, including without limitation the rights to use, ++ * copy, modify, merge, publish, distribute, sublicense, and/or ++ * sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following ++ * conditions: ++ * ++ * The above copyright notice and this permission notice shall be ++ * included in all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES ++ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND ++ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT ++ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, ++ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING ++ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR ++ * OTHER DEALINGS IN THE SOFTWARE. ++ */ ++ ++#ifndef _DT_BINDINGS_CLK_SUN8I_R_CCU_H_ ++#define _DT_BINDINGS_CLK_SUN8I_R_CCU_H_ ++ ++#define CLK_AR100 0 ++ ++#define CLK_APB0_PIO 3 ++#define CLK_APB0_IR 4 ++#define CLK_APB0_TIMER 5 ++#define CLK_APB0_RSB 6 ++#define CLK_APB0_UART 7 ++/* 8 is reserved for CLK_APB0_W1 on A31 */ ++#define CLK_APB0_I2C 9 ++#define CLK_APB0_TWD 10 ++ ++#define CLK_IR 11 ++ ++#endif /* _DT_BINDINGS_CLK_SUN8I_R_CCU_H_ */ +diff --git a/include/dt-bindings/reset/sun8i-r-ccu.h b/include/dt-bindings/reset/sun8i-r-ccu.h +new file mode 100644 +index 000000000000..4ba64f3d6fc9 +--- /dev/null ++++ b/include/dt-bindings/reset/sun8i-r-ccu.h +@@ -0,0 +1,53 @@ ++/* ++ * Copyright (C) 2016 Icenowy Zheng ++ * ++ * This file is dual-licensed: you can use it either under the terms ++ * of the GPL or the X11 license, at your option. Note that this dual ++ * licensing only applies to this file, and not this project as a ++ * whole. ++ * ++ * a) This file is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation; either version 2 of the ++ * License, or (at your option) any later version. ++ * ++ * This file is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * Or, alternatively, ++ * ++ * b) Permission is hereby granted, free of charge, to any person ++ * obtaining a copy of this software and associated documentation ++ * files (the "Software"), to deal in the Software without ++ * restriction, including without limitation the rights to use, ++ * copy, modify, merge, publish, distribute, sublicense, and/or ++ * sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following ++ * conditions: ++ * ++ * The above copyright notice and this permission notice shall be ++ * included in all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES ++ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND ++ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT ++ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, ++ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING ++ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR ++ * OTHER DEALINGS IN THE SOFTWARE. ++ */ ++ ++#ifndef _DT_BINDINGS_RST_SUN8I_R_CCU_H_ ++#define _DT_BINDINGS_RST_SUN8I_R_CCU_H_ ++ ++#define RST_APB0_IR 0 ++#define RST_APB0_TIMER 1 ++#define RST_APB0_RSB 2 ++#define RST_APB0_UART 3 ++/* 4 is reserved for RST_APB0_W1 on A31 */ ++#define RST_APB0_I2C 5 ++ ++#endif /* _DT_BINDINGS_RST_SUN8I_R_CCU_H_ */ + diff --git a/patch/kernel/sun50iw2-dev/add_sun50i_a64_rpio.patch b/patch/kernel/sun50iw2-dev/add_sun50i_a64_rpio.patch new file mode 100644 index 000000000..bb97e7aa6 --- /dev/null +++ b/patch/kernel/sun50iw2-dev/add_sun50i_a64_rpio.patch @@ -0,0 +1,215 @@ +diff --git a/drivers/pinctrl/sunxi/Kconfig b/drivers/pinctrl/sunxi/Kconfig +index a84bfa7f3c05..a0c419ac2a3b 100644 +--- a/drivers/pinctrl/sunxi/Kconfig ++++ b/drivers/pinctrl/sunxi/Kconfig +@@ -68,6 +68,10 @@ config PINCTRL_SUN50I_A64 + def_bool ARM64 && ARCH_SUNXI + select PINCTRL_SUNXI + ++config PINCTRL_SUN50I_A64_R ++ def_bool ARM64 && ARCH_SUNXI ++ select PINCTRL_SUNXI ++ + config PINCTRL_SUN50I_H5 + def_bool ARM64 && ARCH_SUNXI + select PINCTRL_SUNXI +diff --git a/drivers/pinctrl/sunxi/Makefile b/drivers/pinctrl/sunxi/Makefile +index 04ccb88ebd5f..df4ccd6cd44c 100644 +--- a/drivers/pinctrl/sunxi/Makefile ++++ b/drivers/pinctrl/sunxi/Makefile +@@ -11,6 +11,7 @@ obj-$(CONFIG_PINCTRL_SUN8I_A23) += pinctrl-sun8i-a23.o + obj-$(CONFIG_PINCTRL_SUN8I_A23_R) += pinctrl-sun8i-a23-r.o + obj-$(CONFIG_PINCTRL_SUN8I_A33) += pinctrl-sun8i-a33.o + obj-$(CONFIG_PINCTRL_SUN50I_A64) += pinctrl-sun50i-a64.o ++obj-$(CONFIG_PINCTRL_SUN50I_A64_R) += pinctrl-sun50i-a64-r.o + obj-$(CONFIG_PINCTRL_SUN8I_A83T) += pinctrl-sun8i-a83t.o + obj-$(CONFIG_PINCTRL_SUN8I_H3) += pinctrl-sun8i-h3.o + obj-$(CONFIG_PINCTRL_SUN8I_H3_R) += pinctrl-sun8i-h3-r.o +diff --git a/drivers/pinctrl/sunxi/pinctrl-sun50i-a64-r.c b/drivers/pinctrl/sunxi/pinctrl-sun50i-a64-r.c +new file mode 100644 +index 000000000000..415870e82cbf +--- /dev/null ++++ b/drivers/pinctrl/sunxi/pinctrl-sun50i-a64-r.c +@@ -0,0 +1,125 @@ ++/* ++ * Allwinner A64 SoCs special pins pinctrl driver. ++ * ++ * Based on pinctrl-sun8i-a23-r.c ++ * ++ * Copyright (C) 2016 Icenowy Zheng ++ * Icenowy Zheng ++ * ++ * Copyright (C) 2014 Chen-Yu Tsai ++ * Chen-Yu Tsai ++ * ++ * Copyright (C) 2014 Boris Brezillon ++ * Boris Brezillon ++ * ++ * Copyright (C) 2014 Maxime Ripard ++ * Maxime Ripard ++ * ++ * This file is licensed under the terms of the GNU General Public ++ * License version 2. This program is licensed "as is" without any ++ * warranty of any kind, whether express or implied. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include "pinctrl-sunxi.h" ++ ++static const struct sunxi_desc_pin sun50i_a64_r_pins[] = { ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 0), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "s_rsb"), /* SCK */ ++ SUNXI_FUNCTION(0x3, "s_i2c"), /* SCK */ ++ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 0)), /* PL_EINT0 */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 1), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "s_rsb"), /* SDA */ ++ SUNXI_FUNCTION(0x3, "s_i2c"), /* SDA */ ++ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 1)), /* PL_EINT1 */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 2), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "s_uart"), /* TX */ ++ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 2)), /* PL_EINT2 */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 3), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "s_uart"), /* RX */ ++ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 3)), /* PL_EINT3 */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 4), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "s_jtag"), /* MS */ ++ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 4)), /* PL_EINT4 */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 5), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "s_jtag"), /* CK */ ++ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 5)), /* PL_EINT5 */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 6), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "s_jtag"), /* DO */ ++ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 6)), /* PL_EINT6 */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 7), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "s_jtag"), /* DI */ ++ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 7)), /* PL_EINT7 */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 8), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "s_i2c"), /* SCK */ ++ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 8)), /* PL_EINT8 */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 9), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "s_i2c"), /* SDA */ ++ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 9)), /* PL_EINT9 */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 10), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "s_pwm"), ++ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 10)), /* PL_EINT10 */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 11), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "s_cir_rx"), ++ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 11)), /* PL_EINT11 */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 12), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 12)), /* PL_EINT12 */ ++}; ++ ++static const struct sunxi_pinctrl_desc sun50i_a64_r_pinctrl_data = { ++ .pins = sun50i_a64_r_pins, ++ .npins = ARRAY_SIZE(sun50i_a64_r_pins), ++ .pin_base = PL_BASE, ++ .irq_banks = 1, ++}; ++ ++static int sun50i_a64_r_pinctrl_probe(struct platform_device *pdev) ++{ ++ return sunxi_pinctrl_init(pdev, ++ &sun50i_a64_r_pinctrl_data); ++} ++ ++static const struct of_device_id sun50i_a64_r_pinctrl_match[] = { ++ { .compatible = "allwinner,sun50i-a64-r-pinctrl", }, ++ {} ++}; ++ ++static struct platform_driver sun50i_a64_r_pinctrl_driver = { ++ .probe = sun50i_a64_r_pinctrl_probe, ++ .driver = { ++ .name = "sun50i-a64-r-pinctrl", ++ .of_match_table = sun50i_a64_r_pinctrl_match, ++ }, ++}; ++builtin_platform_driver(sun50i_a64_r_pinctrl_driver); +diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi +index 02c0385..c0773d8 100644 +--- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi ++++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi +@@ -43,8 +43,10 @@ + */ + + #include ++#include + #include + #include ++#include + + / { + interrupt-parent = <&gic>; +@@ -98,6 +100,13 @@ + clock-output-names = "osc32k"; + }; + ++ osc32000: osc32000_clk { ++ #clock-cells = <0>; ++ compatible = "fixed-clock"; ++ clock-frequency = <32000>; ++ clock-output-names = "osc32000"; ++ }; ++ + psci { + compatible = "arm,psci-0.2"; + method = "smc"; +@@ -306,6 +315,27 @@ + }; + }; + ++ r_ccu: clock@1f01400 { ++ compatible = "allwinner,sun50i-a64-r-ccu"; ++ reg = <0x01f01400 0x100>; ++ clocks = <&osc24M>, <&osc32k>, <&osc32000>; ++ clock-names = "hosc", "losc", "iosc"; ++ #clock-cells = <1>; ++ #reset-cells = <1>; ++ }; ++ ++ r_pio: pinctrl@1f02c00 { ++ compatible = "allwinner,sun50i-a64-r-pinctrl"; ++ reg = <0x01f02c00 0x400>; ++ interrupts = ; ++ clocks = <&r_ccu CLK_APB0_PIO>, <&osc24M>, <&osc32k>; ++ clock-names = "apb", "hosc", "losc"; ++ gpio-controller; ++ #gpio-cells = <3>; ++ interrupt-controller; ++ #interrupt-cells = <3>; ++ }; ++ + uart0: serial@1c28000 { + compatible = "snps,dw-apb-uart"; + reg = <0x01c28000 0x400>;