aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsaturneric <[email protected]>2025-11-24 10:47:44 +0000
committersaturneric <[email protected]>2025-11-24 10:47:44 +0000
commita373ff64031a27afece24210bd3d53bb912563fd (patch)
tree44926a9a3f926febaf968d910db8102f60cf7d63
parentrefactor(dts): solve node conflicts (diff)
downloadkernel-linux-6.18.y.tar.gz
kernel-linux-6.18.y.zip
fix(driver): sync specific drivers from rpi upstreamlinux-6.18.y
-rw-r--r--drivers/clk/clk-rp1.c2092
-rw-r--r--drivers/gpio/gpio-brcmstb.c152
-rw-r--r--drivers/gpio/gpio-mmio.c159
-rw-r--r--drivers/pinctrl/pinctrl-rp1.c713
-rw-r--r--include/linux/gpio/generic.h1
5 files changed, 1677 insertions, 1440 deletions
diff --git a/drivers/clk/clk-rp1.c b/drivers/clk/clk-rp1.c
index c19043a90c70..ab74f20d4e5b 100644
--- a/drivers/clk/clk-rp1.c
+++ b/drivers/clk/clk-rp1.c
@@ -1,284 +1,289 @@
-// SPDX-License-Identifier: GPL-2.0+
+// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2023 Raspberry Pi Ltd.
*
* Clock driver for RP1 PCIe multifunction chip.
*/
+#include <linux/bitfield.h>
#include <linux/clk-provider.h>
-#include <linux/clkdev.h>
-#include <linux/clk.h>
-#include <linux/debugfs.h>
-#include <linux/delay.h>
-#include <linux/io.h>
+#include <linux/regmap.h>
#include <linux/math64.h>
#include <linux/module.h>
-#include <linux/of_device.h>
#include <linux/platform_device.h>
-#include <linux/rp1_platform.h>
-#include <linux/slab.h>
+#include <linux/units.h>
-#include <asm/div64.h>
+#include <dt-bindings/clock/raspberrypi,rp1-clocks.h>
-#include <dt-bindings/clock/rp1.h>
+#define PLL_SYS_OFFSET 0x08000
+#define PLL_SYS_CS (PLL_SYS_OFFSET + 0x00)
+#define PLL_SYS_PWR (PLL_SYS_OFFSET + 0x04)
+#define PLL_SYS_FBDIV_INT (PLL_SYS_OFFSET + 0x08)
+#define PLL_SYS_FBDIV_FRAC (PLL_SYS_OFFSET + 0x0c)
+#define PLL_SYS_PRIM (PLL_SYS_OFFSET + 0x10)
+#define PLL_SYS_SEC (PLL_SYS_OFFSET + 0x14)
-#define PLL_SYS_CS 0x08000
-#define PLL_SYS_PWR 0x08004
-#define PLL_SYS_FBDIV_INT 0x08008
-#define PLL_SYS_FBDIV_FRAC 0x0800c
-#define PLL_SYS_PRIM 0x08010
-#define PLL_SYS_SEC 0x08014
+#define PLL_AUDIO_OFFSET 0x0c000
+#define PLL_AUDIO_CS (PLL_AUDIO_OFFSET + 0x00)
+#define PLL_AUDIO_PWR (PLL_AUDIO_OFFSET + 0x04)
+#define PLL_AUDIO_FBDIV_INT (PLL_AUDIO_OFFSET + 0x08)
+#define PLL_AUDIO_FBDIV_FRAC (PLL_AUDIO_OFFSET + 0x0c)
+#define PLL_AUDIO_PRIM (PLL_AUDIO_OFFSET + 0x10)
+#define PLL_AUDIO_SEC (PLL_AUDIO_OFFSET + 0x14)
+#define PLL_AUDIO_TERN (PLL_AUDIO_OFFSET + 0x18)
-#define PLL_AUDIO_CS 0x0c000
-#define PLL_AUDIO_PWR 0x0c004
-#define PLL_AUDIO_FBDIV_INT 0x0c008
-#define PLL_AUDIO_FBDIV_FRAC 0x0c00c
-#define PLL_AUDIO_PRIM 0x0c010
-#define PLL_AUDIO_SEC 0x0c014
-#define PLL_AUDIO_TERN 0x0c018
+#define PLL_VIDEO_OFFSET 0x10000
+#define PLL_VIDEO_CS (PLL_VIDEO_OFFSET + 0x00)
+#define PLL_VIDEO_PWR (PLL_VIDEO_OFFSET + 0x04)
+#define PLL_VIDEO_FBDIV_INT (PLL_VIDEO_OFFSET + 0x08)
+#define PLL_VIDEO_FBDIV_FRAC (PLL_VIDEO_OFFSET + 0x0c)
+#define PLL_VIDEO_PRIM (PLL_VIDEO_OFFSET + 0x10)
+#define PLL_VIDEO_SEC (PLL_VIDEO_OFFSET + 0x14)
-#define PLL_VIDEO_CS 0x10000
-#define PLL_VIDEO_PWR 0x10004
-#define PLL_VIDEO_FBDIV_INT 0x10008
-#define PLL_VIDEO_FBDIV_FRAC 0x1000c
-#define PLL_VIDEO_PRIM 0x10010
-#define PLL_VIDEO_SEC 0x10014
+#define GPCLK_OE_CTRL 0x00000
-#define GPCLK_OE_CTRL 0x00000
+#define CLK_SYS_OFFSET 0x00014
+#define CLK_SYS_CTRL (CLK_SYS_OFFSET + 0x00)
+#define CLK_SYS_DIV_INT (CLK_SYS_OFFSET + 0x04)
+#define CLK_SYS_SEL (CLK_SYS_OFFSET + 0x0c)
-#define CLK_SYS_CTRL 0x00014
-#define CLK_SYS_DIV_INT 0x00018
-#define CLK_SYS_SEL 0x00020
+#define CLK_SLOW_OFFSET 0x00024
+#define CLK_SLOW_SYS_CTRL (CLK_SLOW_OFFSET + 0x00)
+#define CLK_SLOW_SYS_DIV_INT (CLK_SLOW_OFFSET + 0x04)
+#define CLK_SLOW_SYS_SEL (CLK_SLOW_OFFSET + 0x0c)
-#define CLK_SLOW_SYS_CTRL 0x00024
-#define CLK_SLOW_SYS_DIV_INT 0x00028
-#define CLK_SLOW_SYS_SEL 0x00030
+#define CLK_DMA_OFFSET 0x00044
+#define CLK_DMA_CTRL (CLK_DMA_OFFSET + 0x00)
+#define CLK_DMA_DIV_INT (CLK_DMA_OFFSET + 0x04)
+#define CLK_DMA_SEL (CLK_DMA_OFFSET + 0x0c)
-#define CLK_DMA_CTRL 0x00044
-#define CLK_DMA_DIV_INT 0x00048
-#define CLK_DMA_SEL 0x00050
+#define CLK_UART_OFFSET 0x00054
+#define CLK_UART_CTRL (CLK_UART_OFFSET + 0x00)
+#define CLK_UART_DIV_INT (CLK_UART_OFFSET + 0x04)
+#define CLK_UART_SEL (CLK_UART_OFFSET + 0x0c)
-#define CLK_UART_CTRL 0x00054
-#define CLK_UART_DIV_INT 0x00058
-#define CLK_UART_SEL 0x00060
+#define CLK_ETH_OFFSET 0x00064
+#define CLK_ETH_CTRL (CLK_ETH_OFFSET + 0x00)
+#define CLK_ETH_DIV_INT (CLK_ETH_OFFSET + 0x04)
+#define CLK_ETH_SEL (CLK_ETH_OFFSET + 0x0c)
-#define CLK_ETH_CTRL 0x00064
-#define CLK_ETH_DIV_INT 0x00068
-#define CLK_ETH_SEL 0x00070
+#define CLK_PWM0_OFFSET 0x00074
+#define CLK_PWM0_CTRL (CLK_PWM0_OFFSET + 0x00)
+#define CLK_PWM0_DIV_INT (CLK_PWM0_OFFSET + 0x04)
+#define CLK_PWM0_DIV_FRAC (CLK_PWM0_OFFSET + 0x08)
+#define CLK_PWM0_SEL (CLK_PWM0_OFFSET + 0x0c)
-#define CLK_PWM0_CTRL 0x00074
-#define CLK_PWM0_DIV_INT 0x00078
-#define CLK_PWM0_DIV_FRAC 0x0007c
-#define CLK_PWM0_SEL 0x00080
+#define CLK_PWM1_OFFSET 0x00084
+#define CLK_PWM1_CTRL (CLK_PWM1_OFFSET + 0x00)
+#define CLK_PWM1_DIV_INT (CLK_PWM1_OFFSET + 0x04)
+#define CLK_PWM1_DIV_FRAC (CLK_PWM1_OFFSET + 0x08)
+#define CLK_PWM1_SEL (CLK_PWM1_OFFSET + 0x0c)
-#define CLK_PWM1_CTRL 0x00084
-#define CLK_PWM1_DIV_INT 0x00088
-#define CLK_PWM1_DIV_FRAC 0x0008c
-#define CLK_PWM1_SEL 0x00090
+#define CLK_AUDIO_IN_OFFSET 0x00094
+#define CLK_AUDIO_IN_CTRL (CLK_AUDIO_IN_OFFSET + 0x00)
+#define CLK_AUDIO_IN_DIV_INT (CLK_AUDIO_IN_OFFSET + 0x04)
+#define CLK_AUDIO_IN_SEL (CLK_AUDIO_IN_OFFSET + 0x0c)
-#define CLK_AUDIO_IN_CTRL 0x00094
-#define CLK_AUDIO_IN_DIV_INT 0x00098
-#define CLK_AUDIO_IN_SEL 0x000a0
+#define CLK_AUDIO_OUT_OFFSET 0x000a4
+#define CLK_AUDIO_OUT_CTRL (CLK_AUDIO_OUT_OFFSET + 0x00)
+#define CLK_AUDIO_OUT_DIV_INT (CLK_AUDIO_OUT_OFFSET + 0x04)
+#define CLK_AUDIO_OUT_SEL (CLK_AUDIO_OUT_OFFSET + 0x0c)
-#define CLK_AUDIO_OUT_CTRL 0x000a4
-#define CLK_AUDIO_OUT_DIV_INT 0x000a8
-#define CLK_AUDIO_OUT_SEL 0x000b0
+#define CLK_I2S_OFFSET 0x000b4
+#define CLK_I2S_CTRL (CLK_I2S_OFFSET + 0x00)
+#define CLK_I2S_DIV_INT (CLK_I2S_OFFSET + 0x04)
+#define CLK_I2S_SEL (CLK_I2S_OFFSET + 0x0c)
-#define CLK_I2S_CTRL 0x000b4
-#define CLK_I2S_DIV_INT 0x000b8
-#define CLK_I2S_SEL 0x000c0
+#define CLK_MIPI0_CFG_OFFSET 0x000c4
+#define CLK_MIPI0_CFG_CTRL (CLK_MIPI0_CFG_OFFSET + 0x00)
+#define CLK_MIPI0_CFG_DIV_INT (CLK_MIPI0_CFG_OFFSET + 0x04)
+#define CLK_MIPI0_CFG_SEL (CLK_MIPI0_CFG_OFFSET + 0x0c)
-#define CLK_MIPI0_CFG_CTRL 0x000c4
-#define CLK_MIPI0_CFG_DIV_INT 0x000c8
-#define CLK_MIPI0_CFG_SEL 0x000d0
+#define CLK_MIPI1_CFG_OFFSET 0x000d4
+#define CLK_MIPI1_CFG_CTRL (CLK_MIPI1_CFG_OFFSET + 0x00)
+#define CLK_MIPI1_CFG_DIV_INT (CLK_MIPI1_CFG_OFFSET + 0x04)
+#define CLK_MIPI1_CFG_SEL (CLK_MIPI1_CFG_OFFSET + 0x0c)
-#define CLK_MIPI1_CFG_CTRL 0x000d4
-#define CLK_MIPI1_CFG_DIV_INT 0x000d8
-#define CLK_MIPI1_CFG_SEL 0x000e0
+#define CLK_PCIE_AUX_OFFSET 0x000e4
+#define CLK_PCIE_AUX_CTRL (CLK_PCIE_AUX_OFFSET + 0x00)
+#define CLK_PCIE_AUX_DIV_INT (CLK_PCIE_AUX_OFFSET + 0x04)
+#define CLK_PCIE_AUX_SEL (CLK_PCIE_AUX_OFFSET + 0x0c)
-#define CLK_PCIE_AUX_CTRL 0x000e4
-#define CLK_PCIE_AUX_DIV_INT 0x000e8
-#define CLK_PCIE_AUX_SEL 0x000f0
+#define CLK_USBH0_MICROFRAME_OFFSET 0x000f4
+#define CLK_USBH0_MICROFRAME_CTRL (CLK_USBH0_MICROFRAME_OFFSET + 0x00)
+#define CLK_USBH0_MICROFRAME_DIV_INT (CLK_USBH0_MICROFRAME_OFFSET + 0x04)
+#define CLK_USBH0_MICROFRAME_SEL (CLK_USBH0_MICROFRAME_OFFSET + 0x0c)
-#define CLK_USBH0_MICROFRAME_CTRL 0x000f4
-#define CLK_USBH0_MICROFRAME_DIV_INT 0x000f8
-#define CLK_USBH0_MICROFRAME_SEL 0x00100
+#define CLK_USBH1_MICROFRAME_OFFSET 0x00104
+#define CLK_USBH1_MICROFRAME_CTRL (CLK_USBH1_MICROFRAME_OFFSET + 0x00)
+#define CLK_USBH1_MICROFRAME_DIV_INT (CLK_USBH1_MICROFRAME_OFFSET + 0x04)
+#define CLK_USBH1_MICROFRAME_SEL (CLK_USBH1_MICROFRAME_OFFSET + 0x0c)
-#define CLK_USBH1_MICROFRAME_CTRL 0x00104
-#define CLK_USBH1_MICROFRAME_DIV_INT 0x00108
-#define CLK_USBH1_MICROFRAME_SEL 0x00110
+#define CLK_USBH0_SUSPEND_OFFSET 0x00114
+#define CLK_USBH0_SUSPEND_CTRL (CLK_USBH0_SUSPEND_OFFSET + 0x00)
+#define CLK_USBH0_SUSPEND_DIV_INT (CLK_USBH0_SUSPEND_OFFSET + 0x04)
+#define CLK_USBH0_SUSPEND_SEL (CLK_USBH0_SUSPEND_OFFSET + 0x0c)
-#define CLK_USBH0_SUSPEND_CTRL 0x00114
-#define CLK_USBH0_SUSPEND_DIV_INT 0x00118
-#define CLK_USBH0_SUSPEND_SEL 0x00120
+#define CLK_USBH1_SUSPEND_OFFSET 0x00124
+#define CLK_USBH1_SUSPEND_CTRL (CLK_USBH1_SUSPEND_OFFSET + 0x00)
+#define CLK_USBH1_SUSPEND_DIV_INT (CLK_USBH1_SUSPEND_OFFSET + 0x04)
+#define CLK_USBH1_SUSPEND_SEL (CLK_USBH1_SUSPEND_OFFSET + 0x0c)
-#define CLK_USBH1_SUSPEND_CTRL 0x00124
-#define CLK_USBH1_SUSPEND_DIV_INT 0x00128
-#define CLK_USBH1_SUSPEND_SEL 0x00130
+#define CLK_ETH_TSU_OFFSET 0x00134
+#define CLK_ETH_TSU_CTRL (CLK_ETH_TSU_OFFSET + 0x00)
+#define CLK_ETH_TSU_DIV_INT (CLK_ETH_TSU_OFFSET + 0x04)
+#define CLK_ETH_TSU_SEL (CLK_ETH_TSU_OFFSET + 0x0c)
-#define CLK_ETH_TSU_CTRL 0x00134
-#define CLK_ETH_TSU_DIV_INT 0x00138
-#define CLK_ETH_TSU_SEL 0x00140
+#define CLK_ADC_OFFSET 0x00144
+#define CLK_ADC_CTRL (CLK_ADC_OFFSET + 0x00)
+#define CLK_ADC_DIV_INT (CLK_ADC_OFFSET + 0x04)
+#define CLK_ADC_SEL (CLK_ADC_OFFSET + 0x0c)
-#define CLK_ADC_CTRL 0x00144
-#define CLK_ADC_DIV_INT 0x00148
-#define CLK_ADC_SEL 0x00150
+#define CLK_SDIO_TIMER_OFFSET 0x00154
+#define CLK_SDIO_TIMER_CTRL (CLK_SDIO_TIMER_OFFSET + 0x00)
+#define CLK_SDIO_TIMER_DIV_INT (CLK_SDIO_TIMER_OFFSET + 0x04)
+#define CLK_SDIO_TIMER_SEL (CLK_SDIO_TIMER_OFFSET + 0x0c)
-#define CLK_SDIO_TIMER_CTRL 0x00154
-#define CLK_SDIO_TIMER_DIV_INT 0x00158
-#define CLK_SDIO_TIMER_SEL 0x00160
+#define CLK_SDIO_ALT_SRC_OFFSET 0x00164
+#define CLK_SDIO_ALT_SRC_CTRL (CLK_SDIO_ALT_SRC_OFFSET + 0x00)
+#define CLK_SDIO_ALT_SRC_DIV_INT (CLK_SDIO_ALT_SRC_OFFSET + 0x04)
+#define CLK_SDIO_ALT_SRC_SEL (CLK_SDIO_ALT_SRC_OFFSET + 0x0c)
-#define CLK_SDIO_ALT_SRC_CTRL 0x00164
-#define CLK_SDIO_ALT_SRC_DIV_INT 0x00168
-#define CLK_SDIO_ALT_SRC_SEL 0x00170
+#define CLK_GP0_OFFSET 0x00174
+#define CLK_GP0_CTRL (CLK_GP0_OFFSET + 0x00)
+#define CLK_GP0_DIV_INT (CLK_GP0_OFFSET + 0x04)
+#define CLK_GP0_DIV_FRAC (CLK_GP0_OFFSET + 0x08)
+#define CLK_GP0_SEL (CLK_GP0_OFFSET + 0x0c)
-#define CLK_GP0_CTRL 0x00174
-#define CLK_GP0_DIV_INT 0x00178
-#define CLK_GP0_DIV_FRAC 0x0017c
-#define CLK_GP0_SEL 0x00180
+#define CLK_GP1_OFFSET 0x00184
+#define CLK_GP1_CTRL (CLK_GP1_OFFSET + 0x00)
+#define CLK_GP1_DIV_INT (CLK_GP1_OFFSET + 0x04)
+#define CLK_GP1_DIV_FRAC (CLK_GP1_OFFSET + 0x08)
+#define CLK_GP1_SEL (CLK_GP1_OFFSET + 0x0c)
-#define CLK_GP1_CTRL 0x00184
-#define CLK_GP1_DIV_INT 0x00188
-#define CLK_GP1_DIV_FRAC 0x0018c
-#define CLK_GP1_SEL 0x00190
+#define CLK_GP2_OFFSET 0x00194
+#define CLK_GP2_CTRL (CLK_GP2_OFFSET + 0x00)
+#define CLK_GP2_DIV_INT (CLK_GP2_OFFSET + 0x04)
+#define CLK_GP2_DIV_FRAC (CLK_GP2_OFFSET + 0x08)
+#define CLK_GP2_SEL (CLK_GP2_OFFSET + 0x0c)
-#define CLK_GP2_CTRL 0x00194
-#define CLK_GP2_DIV_INT 0x00198
-#define CLK_GP2_DIV_FRAC 0x0019c
-#define CLK_GP2_SEL 0x001a0
+#define CLK_GP3_OFFSET 0x001a4
+#define CLK_GP3_CTRL (CLK_GP3_OFFSET + 0x00)
+#define CLK_GP3_DIV_INT (CLK_GP3_OFFSET + 0x04)
+#define CLK_GP3_DIV_FRAC (CLK_GP3_OFFSET + 0x08)
+#define CLK_GP3_SEL (CLK_GP3_OFFSET + 0x0c)
-#define CLK_GP3_CTRL 0x001a4
-#define CLK_GP3_DIV_INT 0x001a8
-#define CLK_GP3_DIV_FRAC 0x001ac
-#define CLK_GP3_SEL 0x001b0
+#define CLK_GP4_OFFSET 0x001b4
+#define CLK_GP4_CTRL (CLK_GP4_OFFSET + 0x00)
+#define CLK_GP4_DIV_INT (CLK_GP4_OFFSET + 0x04)
+#define CLK_GP4_DIV_FRAC (CLK_GP4_OFFSET + 0x08)
+#define CLK_GP4_SEL (CLK_GP4_OFFSET + 0x0c)
-#define CLK_GP4_CTRL 0x001b4
-#define CLK_GP4_DIV_INT 0x001b8
-#define CLK_GP4_DIV_FRAC 0x001bc
-#define CLK_GP4_SEL 0x001c0
+#define CLK_GP5_OFFSET 0x001c4
+#define CLK_GP5_CTRL (CLK_GP5_OFFSET + 0x00)
+#define CLK_GP5_DIV_INT (CLK_GP5_OFFSET + 0x04)
+#define CLK_GP5_DIV_FRAC (CLK_GP5_OFFSET + 0x08)
+#define CLK_GP5_SEL (CLK_GP5_OFFSET + 0x0c)
-#define CLK_GP5_CTRL 0x001c4
-#define CLK_GP5_DIV_INT 0x001c8
-#define CLK_GP5_DIV_FRAC 0x001cc
-#define CLK_GP5_SEL 0x001d0
+#define CLK_SYS_RESUS_CTRL 0x0020c
-#define CLK_SYS_RESUS_CTRL 0x0020c
+#define CLK_SLOW_SYS_RESUS_CTRL 0x00214
-#define CLK_SLOW_SYS_RESUS_CTRL 0x00214
+#define FC0_OFFSET 0x0021c
+#define FC0_REF_KHZ (FC0_OFFSET + 0x00)
+#define FC0_MIN_KHZ (FC0_OFFSET + 0x04)
+#define FC0_MAX_KHZ (FC0_OFFSET + 0x08)
+#define FC0_DELAY (FC0_OFFSET + 0x0c)
+#define FC0_INTERVAL (FC0_OFFSET + 0x10)
+#define FC0_SRC (FC0_OFFSET + 0x14)
+#define FC0_STATUS (FC0_OFFSET + 0x18)
+#define FC0_RESULT (FC0_OFFSET + 0x1c)
+#define FC_SIZE 0x20
+#define FC_COUNT 8
+#define FC_NUM(idx, off) ((idx) * 32 + (off))
-#define FC0_REF_KHZ 0x0021c
-#define FC0_MIN_KHZ 0x00220
-#define FC0_MAX_KHZ 0x00224
-#define FC0_DELAY 0x00228
-#define FC0_INTERVAL 0x0022c
-#define FC0_SRC 0x00230
-#define FC0_STATUS 0x00234
-#define FC0_RESULT 0x00238
-#define FC_SIZE 0x20
-#define FC_COUNT 8
-#define FC_NUM(idx, off) ((idx) * 32 + (off))
+#define AUX_SEL 1
-#define AUX_SEL 1
+#define VIDEO_CLOCKS_OFFSET 0x4000
+#define VIDEO_CLK_VEC_CTRL (VIDEO_CLOCKS_OFFSET + 0x0000)
+#define VIDEO_CLK_VEC_DIV_INT (VIDEO_CLOCKS_OFFSET + 0x0004)
+#define VIDEO_CLK_VEC_SEL (VIDEO_CLOCKS_OFFSET + 0x000c)
+#define VIDEO_CLK_DPI_CTRL (VIDEO_CLOCKS_OFFSET + 0x0010)
+#define VIDEO_CLK_DPI_DIV_INT (VIDEO_CLOCKS_OFFSET + 0x0014)
+#define VIDEO_CLK_DPI_SEL (VIDEO_CLOCKS_OFFSET + 0x001c)
+#define VIDEO_CLK_MIPI0_DPI_CTRL (VIDEO_CLOCKS_OFFSET + 0x0020)
+#define VIDEO_CLK_MIPI0_DPI_DIV_INT (VIDEO_CLOCKS_OFFSET + 0x0024)
+#define VIDEO_CLK_MIPI0_DPI_DIV_FRAC (VIDEO_CLOCKS_OFFSET + 0x0028)
+#define VIDEO_CLK_MIPI0_DPI_SEL (VIDEO_CLOCKS_OFFSET + 0x002c)
+#define VIDEO_CLK_MIPI1_DPI_CTRL (VIDEO_CLOCKS_OFFSET + 0x0030)
+#define VIDEO_CLK_MIPI1_DPI_DIV_INT (VIDEO_CLOCKS_OFFSET + 0x0034)
+#define VIDEO_CLK_MIPI1_DPI_DIV_FRAC (VIDEO_CLOCKS_OFFSET + 0x0038)
+#define VIDEO_CLK_MIPI1_DPI_SEL (VIDEO_CLOCKS_OFFSET + 0x003c)
-#define VIDEO_CLOCKS_OFFSET 0x4000
-#define VIDEO_CLK_VEC_CTRL (VIDEO_CLOCKS_OFFSET + 0x0000)
-#define VIDEO_CLK_VEC_DIV_INT (VIDEO_CLOCKS_OFFSET + 0x0004)
-#define VIDEO_CLK_VEC_SEL (VIDEO_CLOCKS_OFFSET + 0x000c)
-#define VIDEO_CLK_DPI_CTRL (VIDEO_CLOCKS_OFFSET + 0x0010)
-#define VIDEO_CLK_DPI_DIV_INT (VIDEO_CLOCKS_OFFSET + 0x0014)
-#define VIDEO_CLK_DPI_SEL (VIDEO_CLOCKS_OFFSET + 0x001c)
-#define VIDEO_CLK_MIPI0_DPI_CTRL (VIDEO_CLOCKS_OFFSET + 0x0020)
-#define VIDEO_CLK_MIPI0_DPI_DIV_INT (VIDEO_CLOCKS_OFFSET + 0x0024)
-#define VIDEO_CLK_MIPI0_DPI_DIV_FRAC (VIDEO_CLOCKS_OFFSET + 0x0028)
-#define VIDEO_CLK_MIPI0_DPI_SEL (VIDEO_CLOCKS_OFFSET + 0x002c)
-#define VIDEO_CLK_MIPI1_DPI_CTRL (VIDEO_CLOCKS_OFFSET + 0x0030)
-#define VIDEO_CLK_MIPI1_DPI_DIV_INT (VIDEO_CLOCKS_OFFSET + 0x0034)
-#define VIDEO_CLK_MIPI1_DPI_DIV_FRAC (VIDEO_CLOCKS_OFFSET + 0x0038)
-#define VIDEO_CLK_MIPI1_DPI_SEL (VIDEO_CLOCKS_OFFSET + 0x003c)
+#define DIV_INT_8BIT_MAX GENMASK(7, 0) /* max divide for most clocks */
+#define DIV_INT_16BIT_MAX GENMASK(15, 0) /* max divide for GPx, PWM */
+#define DIV_INT_24BIT_MAX GENMASK(23, 0) /* max divide for CLK_SYS */
-#define DIV_INT_8BIT_MAX 0x000000ffu /* max divide for most clocks */
-#define DIV_INT_16BIT_MAX 0x0000ffffu /* max divide for GPx, PWM */
-#define DIV_INT_24BIT_MAX 0x00ffffffu /* max divide for CLK_SYS */
+#define FC0_STATUS_DONE BIT(4)
+#define FC0_STATUS_RUNNING BIT(8)
+#define FC0_RESULT_FRAC_SHIFT 5
-#define FC0_STATUS_DONE BIT(4)
-#define FC0_STATUS_RUNNING BIT(8)
-#define FC0_RESULT_FRAC_SHIFT 5
+#define PLL_PRIM_DIV1_MASK GENMASK(18, 16)
+#define PLL_PRIM_DIV2_MASK GENMASK(14, 12)
-#define PLL_PRIM_DIV1_SHIFT 16
-#define PLL_PRIM_DIV1_MASK 0x00070000
-#define PLL_PRIM_DIV2_SHIFT 12
-#define PLL_PRIM_DIV2_MASK 0x00007000
+#define PLL_SEC_DIV_MASK GENMASK(12, 8)
-#define PLL_SEC_DIV_SHIFT 8
-#define PLL_SEC_DIV_WIDTH 5
-#define PLL_SEC_DIV_MASK 0x00001f00
+#define PLL_CS_LOCK BIT(31)
+#define PLL_CS_REFDIV_MASK BIT(1)
-#define PLL_CS_LOCK BIT(31)
-#define PLL_CS_REFDIV_SHIFT 0
+#define PLL_PWR_PD BIT(0)
+#define PLL_PWR_DACPD BIT(1)
+#define PLL_PWR_DSMPD BIT(2)
+#define PLL_PWR_POSTDIVPD BIT(3)
+#define PLL_PWR_4PHASEPD BIT(4)
+#define PLL_PWR_VCOPD BIT(5)
+#define PLL_PWR_MASK GENMASK(5, 0)
-#define PLL_PWR_PD BIT(0)
-#define PLL_PWR_DACPD BIT(1)
-#define PLL_PWR_DSMPD BIT(2)
-#define PLL_PWR_POSTDIVPD BIT(3)
-#define PLL_PWR_4PHASEPD BIT(4)
-#define PLL_PWR_VCOPD BIT(5)
-#define PLL_PWR_MASK 0x0000003f
-
-#define PLL_SEC_RST BIT(16)
-#define PLL_SEC_IMPL BIT(31)
+#define PLL_SEC_RST BIT(16)
+#define PLL_SEC_IMPL BIT(31)
/* PLL phase output for both PRI and SEC */
-#define PLL_PH_EN BIT(4)
-#define PLL_PH_PHASE_SHIFT 0
+#define PLL_PH_EN BIT(4)
+#define PLL_PH_PHASE_SHIFT 0
-#define RP1_PLL_PHASE_0 0
-#define RP1_PLL_PHASE_90 1
-#define RP1_PLL_PHASE_180 2
-#define RP1_PLL_PHASE_270 3
+#define RP1_PLL_PHASE_0 0
+#define RP1_PLL_PHASE_90 1
+#define RP1_PLL_PHASE_180 2
+#define RP1_PLL_PHASE_270 3
/* Clock fields for all clocks */
-#define CLK_CTRL_ENABLE BIT(11)
-#define CLK_CTRL_AUXSRC_MASK 0x000003e0
-#define CLK_CTRL_AUXSRC_SHIFT 5
-#define CLK_CTRL_SRC_SHIFT 0
-#define CLK_DIV_FRAC_BITS 16
-
-#define KHz 1000
-#define MHz (KHz * KHz)
-#define LOCK_TIMEOUT_NS 100000000
-#define FC_TIMEOUT_NS 100000000
-
-#define MAX_CLK_PARENTS 16
+#define CLK_CTRL_ENABLE BIT(11)
+#define CLK_CTRL_AUXSRC_MASK GENMASK(9, 5)
+#define CLK_CTRL_SRC_SHIFT 0
+#define CLK_DIV_FRAC_BITS 16
-#define MEASURE_CLOCK_RATE
-const char * const fc0_ref_clk_name = "clk_slow_sys";
+#define LOCK_TIMEOUT_US 100000
+#define LOCK_POLL_DELAY_US 5
-#define ABS_DIFF(a, b) ((a) > (b) ? (a) - (b) : (b) - (a))
-#define DIV_NEAREST(a, b) (((a) + ((b) >> 1)) / (b))
-#define DIV_U64_NEAREST(a, b) div_u64(((a) + ((b) >> 1)), (b))
-
-/*
- * Names of the reference clock for the pll cores. This name must match
- * the DT reference clock-output-name.
- */
-static const char *const ref_clock = "xosc";
+#define MAX_CLK_PARENTS 16
+#define PLL_DIV_INVALID 19
/*
* Secondary PLL channel output divider table.
- * Divider values range from 8 to 19.
- * Invalid values default to 19
+ * Divider values range from 8 to 19, where
+ * 19 means invalid.
*/
static const struct clk_div_table pll_sec_div_table[] = {
- { 0x00, 19 },
- { 0x01, 19 },
- { 0x02, 19 },
- { 0x03, 19 },
- { 0x04, 19 },
- { 0x05, 19 },
- { 0x06, 19 },
- { 0x07, 19 },
- { 0x08, 8 },
- { 0x09, 9 },
+ { 0x00, PLL_DIV_INVALID },
+ { 0x01, PLL_DIV_INVALID },
+ { 0x02, PLL_DIV_INVALID },
+ { 0x03, PLL_DIV_INVALID },
+ { 0x04, PLL_DIV_INVALID },
+ { 0x05, PLL_DIV_INVALID },
+ { 0x06, PLL_DIV_INVALID },
+ { 0x07, PLL_DIV_INVALID },
+ { 0x08, 8 },
+ { 0x09, 9 },
{ 0x0a, 10 },
{ 0x0b, 11 },
{ 0x0c, 12 },
@@ -288,25 +293,26 @@ static const struct clk_div_table pll_sec_div_table[] = {
{ 0x10, 16 },
{ 0x11, 17 },
{ 0x12, 18 },
- { 0x13, 19 },
- { 0x14, 19 },
- { 0x15, 19 },
- { 0x16, 19 },
- { 0x17, 19 },
- { 0x18, 19 },
- { 0x19, 19 },
- { 0x1a, 19 },
- { 0x1b, 19 },
- { 0x1c, 19 },
- { 0x1d, 19 },
- { 0x1e, 19 },
- { 0x1f, 19 },
+ { 0x13, PLL_DIV_INVALID },
+ { 0x14, PLL_DIV_INVALID },
+ { 0x15, PLL_DIV_INVALID },
+ { 0x16, PLL_DIV_INVALID },
+ { 0x17, PLL_DIV_INVALID },
+ { 0x18, PLL_DIV_INVALID },
+ { 0x19, PLL_DIV_INVALID },
+ { 0x1a, PLL_DIV_INVALID },
+ { 0x1b, PLL_DIV_INVALID },
+ { 0x1c, PLL_DIV_INVALID },
+ { 0x1d, PLL_DIV_INVALID },
+ { 0x1e, PLL_DIV_INVALID },
+ { 0x1f, PLL_DIV_INVALID },
{ 0 }
};
struct rp1_clockman {
struct device *dev;
void __iomem *regs;
+ struct regmap *regmap;
spinlock_t regs_lock; /* spinlock for all clocks */
/* Must be last */
@@ -314,47 +320,33 @@ struct rp1_clockman {
};
struct rp1_pll_core_data {
- const char *name;
u32 cs_reg;
u32 pwr_reg;
u32 fbdiv_int_reg;
u32 fbdiv_frac_reg;
- unsigned long flags;
u32 fc0_src;
};
struct rp1_pll_data {
- const char *name;
- const char *source_pll;
u32 ctrl_reg;
- unsigned long flags;
u32 fc0_src;
};
struct rp1_pll_ph_data {
- const char *name;
- const char *source_pll;
unsigned int phase;
unsigned int fixed_divider;
u32 ph_reg;
- unsigned long flags;
u32 fc0_src;
};
struct rp1_pll_divider_data {
- const char *name;
- const char *source_pll;
u32 sec_reg;
- unsigned long flags;
u32 fc0_src;
};
struct rp1_clock_data {
- const char *name;
- const char *const parents[MAX_CLK_PARENTS];
int num_std_parents;
int num_aux_parents;
- unsigned long flags;
u32 oe_mask;
u32 clk_src_mask;
u32 ctrl_reg;
@@ -366,94 +358,40 @@ struct rp1_clock_data {
u32 fc0_src;
};
-struct rp1_pll_core {
+struct rp1_clk_desc {
+ struct clk_hw *(*clk_register)(struct rp1_clockman *clockman,
+ struct rp1_clk_desc *desc);
+ const void *data;
struct clk_hw hw;
struct rp1_clockman *clockman;
- const struct rp1_pll_core_data *data;
unsigned long cached_rate;
-};
-
-struct rp1_pll {
- struct clk_hw hw;
struct clk_divider div;
};
-static inline
-void clockman_write(struct rp1_clockman *clockman, u32 reg, u32 val)
-{
- writel(val, clockman->regs + reg);
-}
+static struct rp1_clk_desc *clk_audio_core;
+static struct rp1_clk_desc *clk_audio;
+static struct rp1_clk_desc *clk_i2s;
+static struct clk_hw *clk_xosc;
-static inline u32 clockman_read(struct rp1_clockman *clockman, u32 reg)
+static inline void clockman_write(struct rp1_clockman *clockman, u32 reg,
+ u32 val)
{
- return readl(clockman->regs + reg);
+ regmap_write(clockman->regmap, reg, val);
}
-#ifdef MEASURE_CLOCK_RATE
-static unsigned long clockman_measure_clock(struct rp1_clockman *clockman,
- const char *clk_name,
- unsigned int fc0_src)
+static inline u32 clockman_read(struct rp1_clockman *clockman, u32 reg)
{
- struct clk *ref_clk = __clk_lookup(fc0_ref_clk_name);
- unsigned long result;
- ktime_t timeout;
- unsigned int fc_idx, fc_offset, fc_src;
-
- fc_idx = fc0_src / 32;
- fc_src = fc0_src % 32;
-
- /* fc_src == 0 is invalid. */
- if (!fc_src || fc_idx >= FC_COUNT)
- return 0;
-
- fc_offset = fc_idx * FC_SIZE;
-
- /* Ensure the frequency counter is idle. */
- timeout = ktime_add_ns(ktime_get(), FC_TIMEOUT_NS);
- while (clockman_read(clockman, fc_offset + FC0_STATUS) & FC0_STATUS_RUNNING) {
- if (ktime_after(ktime_get(), timeout)) {
- dev_err(clockman->dev, "%s: FC0 busy timeout\n",
- clk_name);
- return 0;
- }
- cpu_relax();
- }
-
- spin_lock(&clockman->regs_lock);
- clockman_write(clockman, fc_offset + FC0_REF_KHZ,
- clk_get_rate(ref_clk) / KHz);
- clockman_write(clockman, fc_offset + FC0_MIN_KHZ, 0);
- clockman_write(clockman, fc_offset + FC0_MAX_KHZ, 0x1ffffff);
- clockman_write(clockman, fc_offset + FC0_INTERVAL, 8);
- clockman_write(clockman, fc_offset + FC0_DELAY, 7);
- clockman_write(clockman, fc_offset + FC0_SRC, fc_src);
- spin_unlock(&clockman->regs_lock);
+ u32 val;
- /* Ensure the frequency counter is idle. */
- timeout = ktime_add_ns(ktime_get(), FC_TIMEOUT_NS);
- while (!(clockman_read(clockman, fc_offset + FC0_STATUS) & FC0_STATUS_DONE)) {
- if (ktime_after(ktime_get(), timeout)) {
- dev_err(clockman->dev, "%s: FC0 wait timeout\n",
- clk_name);
- return 0;
- }
- cpu_relax();
- }
-
- result = clockman_read(clockman, fc_offset + FC0_RESULT);
-
- /* Disable FC0 */
- spin_lock(&clockman->regs_lock);
- clockman_write(clockman, fc_offset + FC0_SRC, 0);
- spin_unlock(&clockman->regs_lock);
+ regmap_read(clockman->regmap, reg, &val);
- return result;
+ return val;
}
-#endif
static int rp1_pll_core_is_on(struct clk_hw *hw)
{
- struct rp1_pll_core *pll_core = container_of(hw, struct rp1_pll_core, hw);
+ struct rp1_clk_desc *pll_core =
+ container_of(hw, struct rp1_clk_desc, hw);
struct rp1_clockman *clockman = pll_core->clockman;
const struct rp1_pll_core_data *data = pll_core->data;
u32 pwr = clockman_read(clockman, data->pwr_reg);
@@ -463,11 +401,12 @@ static int rp1_pll_core_is_on(struct clk_hw *hw)
static int rp1_pll_core_on(struct clk_hw *hw)
{
- struct rp1_pll_core *pll_core = container_of(hw, struct rp1_pll_core, hw);
+ struct rp1_clk_desc *pll_core =
+ container_of(hw, struct rp1_clk_desc, hw);
struct rp1_clockman *clockman = pll_core->clockman;
const struct rp1_pll_core_data *data = pll_core->data;
- u32 fbdiv_frac;
- ktime_t timeout;
+ u32 fbdiv_frac, val;
+ int ret;
spin_lock(&clockman->regs_lock);
@@ -476,7 +415,7 @@ static int rp1_pll_core_on(struct clk_hw *hw)
clockman_write(clockman, data->pwr_reg, PLL_PWR_MASK);
clockman_write(clockman, data->fbdiv_int_reg, 20);
clockman_write(clockman, data->fbdiv_frac_reg, 0);
- clockman_write(clockman, data->cs_reg, 1 << PLL_CS_REFDIV_SHIFT);
+ clockman_write(clockman, data->cs_reg, PLL_CS_REFDIV_MASK);
}
/* Come out of reset. */
@@ -485,22 +424,20 @@ static int rp1_pll_core_on(struct clk_hw *hw)
spin_unlock(&clockman->regs_lock);
/* Wait for the PLL to lock. */
- timeout = ktime_add_ns(ktime_get(), LOCK_TIMEOUT_NS);
- while (!(clockman_read(clockman, data->cs_reg) & PLL_CS_LOCK)) {
- if (ktime_after(ktime_get(), timeout)) {
- dev_err(clockman->dev, "%s: can't lock PLL\n",
- clk_hw_get_name(hw));
- return -ETIMEDOUT;
- }
- cpu_relax();
- }
+ ret = regmap_read_poll_timeout(clockman->regmap, data->cs_reg, val,
+ val & PLL_CS_LOCK, LOCK_POLL_DELAY_US,
+ LOCK_TIMEOUT_US);
+ if (ret)
+ dev_err(clockman->dev, "%s: can't lock PLL\n",
+ clk_hw_get_name(hw));
- return 0;
+ return ret;
}
static void rp1_pll_core_off(struct clk_hw *hw)
{
- struct rp1_pll_core *pll_core = container_of(hw, struct rp1_pll_core, hw);
+ struct rp1_clk_desc *pll_core =
+ container_of(hw, struct rp1_clk_desc, hw);
struct rp1_clockman *clockman = pll_core->clockman;
const struct rp1_pll_core_data *data = pll_core->data;
@@ -514,13 +451,14 @@ static inline unsigned long get_pll_core_divider(struct clk_hw *hw,
unsigned long parent_rate,
u32 *div_int, u32 *div_frac)
{
- unsigned long calc_rate;
u32 fbdiv_int, fbdiv_frac;
+ unsigned long calc_rate;
+ u64 shifted_fbdiv_int;
u64 div_fp64; /* 32.32 fixed point fraction. */
/* Factor of reference clock to VCO frequency. */
div_fp64 = (u64)(rate) << 32;
- div_fp64 = DIV_U64_NEAREST(div_fp64, parent_rate);
+ div_fp64 = DIV_ROUND_CLOSEST_ULL(div_fp64, parent_rate);
/* Round the fractional component at 24 bits. */
div_fp64 += 1 << (32 - 24 - 1);
@@ -528,8 +466,10 @@ static inline unsigned long get_pll_core_divider(struct clk_hw *hw,
fbdiv_int = div_fp64 >> 32;
fbdiv_frac = (div_fp64 >> (32 - 24)) & 0xffffff;
- calc_rate =
- ((u64)parent_rate * (((u64)fbdiv_int << 24) + fbdiv_frac) + (1 << 23)) >> 24;
+ shifted_fbdiv_int = (u64)fbdiv_int << 24;
+ calc_rate = (u64)parent_rate * (shifted_fbdiv_int + fbdiv_frac);
+ calc_rate += BIT(23);
+ calc_rate >>= 24;
*div_int = fbdiv_int;
*div_frac = fbdiv_frac;
@@ -537,25 +477,22 @@ static inline unsigned long get_pll_core_divider(struct clk_hw *hw,
return calc_rate;
}
-static int rp1_pll_core_set_rate(struct clk_hw *hw,
- unsigned long rate, unsigned long parent_rate)
+static int rp1_pll_core_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
{
- struct rp1_pll_core *pll_core = container_of(hw, struct rp1_pll_core, hw);
+ struct rp1_clk_desc *pll_core =
+ container_of(hw, struct rp1_clk_desc, hw);
struct rp1_clockman *clockman = pll_core->clockman;
const struct rp1_pll_core_data *data = pll_core->data;
u32 fbdiv_int, fbdiv_frac;
- // todo: is this needed??
- //rp1_pll_off(hw);
-
/* Disable dividers to start with. */
spin_lock(&clockman->regs_lock);
clockman_write(clockman, data->fbdiv_int_reg, 0);
clockman_write(clockman, data->fbdiv_frac_reg, 0);
spin_unlock(&clockman->regs_lock);
- get_pll_core_divider(hw, rate, parent_rate,
- &fbdiv_int, &fbdiv_frac);
+ get_pll_core_divider(hw, rate, parent_rate, &fbdiv_int, &fbdiv_frac);
spin_lock(&clockman->regs_lock);
clockman_write(clockman, data->pwr_reg, fbdiv_frac ? 0 : PLL_PWR_DSMPD);
@@ -564,13 +501,14 @@ static int rp1_pll_core_set_rate(struct clk_hw *hw,
spin_unlock(&clockman->regs_lock);
/* Check that reference frequency is no greater than VCO / 16. */
- BUG_ON(parent_rate > (rate / 16));
+ if (WARN_ON_ONCE(parent_rate > (rate / 16)))
+ return -ERANGE;
spin_lock(&clockman->regs_lock);
/* Don't need to divide ref unless parent_rate > (output freq / 16) */
clockman_write(clockman, data->cs_reg,
clockman_read(clockman, data->cs_reg) |
- (1 << PLL_CS_REFDIV_SHIFT));
+ PLL_CS_REFDIV_MASK);
spin_unlock(&clockman->regs_lock);
return 0;
@@ -579,16 +517,21 @@ static int rp1_pll_core_set_rate(struct clk_hw *hw,
static unsigned long rp1_pll_core_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
- struct rp1_pll_core *pll_core = container_of(hw, struct rp1_pll_core, hw);
+ struct rp1_clk_desc *pll_core =
+ container_of(hw, struct rp1_clk_desc, hw);
struct rp1_clockman *clockman = pll_core->clockman;
const struct rp1_pll_core_data *data = pll_core->data;
u32 fbdiv_int, fbdiv_frac;
unsigned long calc_rate;
+ u64 shifted_fbdiv_int;
fbdiv_int = clockman_read(clockman, data->fbdiv_int_reg);
fbdiv_frac = clockman_read(clockman, data->fbdiv_frac_reg);
- calc_rate =
- ((u64)parent_rate * (((u64)fbdiv_int << 24) + fbdiv_frac) + (1 << 23)) >> 24;
+
+ shifted_fbdiv_int = (u64)fbdiv_int << 24;
+ calc_rate = (u64)parent_rate * (shifted_fbdiv_int + fbdiv_frac);
+ calc_rate += BIT(23);
+ calc_rate >>= 24;
return calc_rate;
}
@@ -597,10 +540,11 @@ static int rp1_pll_core_determine_rate(struct clk_hw *hw,
struct clk_rate_request *req)
{
u32 fbdiv_int, fbdiv_frac;
- long calc_rate;
- return get_pll_core_divider(hw, rate, *parent_rate,
- &fbdiv_int, &fbdiv_frac);
+ req->rate = get_pll_core_divider(hw, req->rate, req->best_parent_rate,
+ &fbdiv_int, &fbdiv_frac);
+
+ return 0;
}
static void get_pll_prim_dividers(unsigned long rate, unsigned long parent_rate,
@@ -608,14 +552,14 @@ static void get_pll_prim_dividers(unsigned long rate, unsigned long parent_rate,
{
unsigned int div1, div2;
unsigned int best_div1 = 7, best_div2 = 7;
- unsigned long best_rate_diff =
- ABS_DIFF(DIV_ROUND_CLOSEST(parent_rate, best_div1 * best_div2), rate);
- long rate_diff, calc_rate;
+ unsigned long best_rate_diff = abs_diff(
+ DIV_ROUND_CLOSEST(parent_rate, best_div1 * best_div2), rate);
+ unsigned long rate_diff, calc_rate;
for (div1 = 1; div1 <= 7; div1++) {
for (div2 = 1; div2 <= div1; div2++) {
calc_rate = DIV_ROUND_CLOSEST(parent_rate, div1 * div2);
- rate_diff = ABS_DIFF(calc_rate, rate);
+ rate_diff = abs_diff(calc_rate, rate);
if (calc_rate == rate) {
best_div1 = div1;
@@ -634,46 +578,44 @@ done:
*divider2 = best_div2;
}
-static int rp1_pll_set_rate(struct clk_hw *hw,
- unsigned long rate, unsigned long parent_rate)
+static int rp1_pll_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
{
- struct rp1_pll *pll = container_of(hw, struct rp1_pll, hw);
+ struct rp1_clk_desc *pll = container_of(hw, struct rp1_clk_desc, hw);
struct rp1_clockman *clockman = pll->clockman;
const struct rp1_pll_data *data = pll->data;
+
u32 prim, prim_div1, prim_div2;
get_pll_prim_dividers(rate, parent_rate, &prim_div1, &prim_div2);
spin_lock(&clockman->regs_lock);
prim = clockman_read(clockman, data->ctrl_reg);
- prim = set_register_field(prim, prim_div1, PLL_PRIM_DIV1_MASK,
- PLL_PRIM_DIV1_SHIFT);
- prim = set_register_field(prim, prim_div2, PLL_PRIM_DIV2_MASK,
- PLL_PRIM_DIV2_SHIFT);
+ prim &= ~PLL_PRIM_DIV1_MASK;
+ prim |= FIELD_PREP(PLL_PRIM_DIV1_MASK, prim_div1);
+ prim &= ~PLL_PRIM_DIV2_MASK;
+ prim |= FIELD_PREP(PLL_PRIM_DIV2_MASK, prim_div2);
clockman_write(clockman, data->ctrl_reg, prim);
spin_unlock(&clockman->regs_lock);
-#ifdef MEASURE_CLOCK_RATE
- clockman_measure_clock(clockman, data->name, data->fc0_src);
-#endif
return 0;
}
static unsigned long rp1_pll_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
- struct rp1_pll *pll = container_of(hw, struct rp1_pll, hw);
+ struct rp1_clk_desc *pll = container_of(hw, struct rp1_clk_desc, hw);
struct rp1_clockman *clockman = pll->clockman;
const struct rp1_pll_data *data = pll->data;
u32 prim, prim_div1, prim_div2;
prim = clockman_read(clockman, data->ctrl_reg);
- prim_div1 = (prim & PLL_PRIM_DIV1_MASK) >> PLL_PRIM_DIV1_SHIFT;
- prim_div2 = (prim & PLL_PRIM_DIV2_MASK) >> PLL_PRIM_DIV2_SHIFT;
+ prim_div1 = FIELD_GET(PLL_PRIM_DIV1_MASK, prim);
+ prim_div2 = FIELD_GET(PLL_PRIM_DIV2_MASK, prim);
if (!prim_div1 || !prim_div2) {
dev_err(clockman->dev, "%s: (%s) zero divider value\n",
- __func__, data->name);
+ __func__, clk_hw_get_name(hw));
return 0;
}
@@ -683,50 +625,35 @@ static unsigned long rp1_pll_recalc_rate(struct clk_hw *hw,
static int rp1_pll_determine_rate(struct clk_hw *hw,
struct clk_rate_request *req)
{
+ struct clk_hw *clk_audio_hw = &clk_audio->hw;
u32 div1, div2;
- get_pll_prim_dividers(rate, *parent_rate, &div1, &div2);
+ if (hw == clk_audio_hw && clk_audio->cached_rate == req->rate)
+ req->best_parent_rate = clk_audio_core->cached_rate;
+
+ get_pll_prim_dividers(req->rate, req->best_parent_rate, &div1, &div2);
req->rate = DIV_ROUND_CLOSEST(req->best_parent_rate, div1 * div2);
return 0;
}
-static void rp1_pll_debug_init(struct clk_hw *hw,
- struct dentry *dentry)
-{
- struct rp1_pll *pll = container_of(hw, struct rp1_pll, hw);
- struct rp1_clockman *clockman = pll->clockman;
- const struct rp1_pll_data *data = pll->data;
- struct debugfs_reg32 *regs;
-
- regs = devm_kcalloc(clockman->dev, 1, sizeof(*regs), GFP_KERNEL);
- if (!regs)
- return;
-
- regs[0].name = "prim";
- regs[0].offset = data->ctrl_reg;
-
- rp1_debugfs_regset(clockman, 0, regs, 1, dentry);
-}
-
static int rp1_pll_ph_is_on(struct clk_hw *hw)
{
- struct rp1_pll_ph *pll = container_of(hw, struct rp1_pll_ph, hw);
- struct rp1_clockman *clockman = pll->clockman;
- const struct rp1_pll_ph_data *data = pll->data;
+ struct rp1_clk_desc *pll_ph = container_of(hw, struct rp1_clk_desc, hw);
+ struct rp1_clockman *clockman = pll_ph->clockman;
+ const struct rp1_pll_ph_data *data = pll_ph->data;
return !!(clockman_read(clockman, data->ph_reg) & PLL_PH_EN);
}
static int rp1_pll_ph_on(struct clk_hw *hw)
{
- struct rp1_pll_ph *pll_ph = container_of(hw, struct rp1_pll_ph, hw);
+ struct rp1_clk_desc *pll_ph = container_of(hw, struct rp1_clk_desc, hw);
struct rp1_clockman *clockman = pll_ph->clockman;
const struct rp1_pll_ph_data *data = pll_ph->data;
u32 ph_reg;
- /* todo: ensure pri/sec is enabled! */
spin_lock(&clockman->regs_lock);
ph_reg = clockman_read(clockman, data->ph_reg);
ph_reg |= data->phase << PLL_PH_PHASE_SHIFT;
@@ -734,15 +661,12 @@ static int rp1_pll_ph_on(struct clk_hw *hw)
clockman_write(clockman, data->ph_reg, ph_reg);
spin_unlock(&clockman->regs_lock);
-#ifdef MEASURE_CLOCK_RATE
- clockman_measure_clock(clockman, data->name, data->fc0_src);
-#endif
return 0;
}
static void rp1_pll_ph_off(struct clk_hw *hw)
{
- struct rp1_pll_ph *pll_ph = container_of(hw, struct rp1_pll_ph, hw);
+ struct rp1_clk_desc *pll_ph = container_of(hw, struct rp1_clk_desc, hw);
struct rp1_clockman *clockman = pll_ph->clockman;
const struct rp1_pll_ph_data *data = pll_ph->data;
@@ -752,28 +676,10 @@ static void rp1_pll_ph_off(struct clk_hw *hw)
spin_unlock(&clockman->regs_lock);
}
-static int rp1_pll_ph_set_rate(struct clk_hw *hw,
- unsigned long rate, unsigned long parent_rate)
-{
- struct rp1_pll_ph *pll_ph = container_of(hw, struct rp1_pll_ph, hw);
- const struct rp1_pll_ph_data *data = pll_ph->data;
- struct rp1_clockman *clockman = pll_ph->clockman;
-
- /* Nothing really to do here! */
- WARN_ON(data->fixed_divider != 1 && data->fixed_divider != 2);
- WARN_ON(rate != parent_rate / data->fixed_divider);
-
-#ifdef MEASURE_CLOCK_RATE
- if (rp1_pll_ph_is_on(hw))
- clockman_measure_clock(clockman, data->name, data->fc0_src);
-#endif
- return 0;
-}
-
static unsigned long rp1_pll_ph_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
- struct rp1_pll_ph *pll_ph = container_of(hw, struct rp1_pll_ph, hw);
+ struct rp1_clk_desc *pll_ph = container_of(hw, struct rp1_clk_desc, hw);
const struct rp1_pll_ph_data *data = pll_ph->data;
return parent_rate / data->fixed_divider;
@@ -782,7 +688,7 @@ static unsigned long rp1_pll_ph_recalc_rate(struct clk_hw *hw,
static int rp1_pll_ph_determine_rate(struct clk_hw *hw,
struct clk_rate_request *req)
{
- struct rp1_pll_ph *pll_ph = container_of(hw, struct rp1_pll_ph, hw);
+ struct rp1_clk_desc *pll_ph = container_of(hw, struct rp1_clk_desc, hw);
const struct rp1_pll_ph_data *data = pll_ph->data;
req->rate = req->best_parent_rate / data->fixed_divider;
@@ -790,27 +696,10 @@ static int rp1_pll_ph_determine_rate(struct clk_hw *hw,
return 0;
}
-static void rp1_pll_ph_debug_init(struct clk_hw *hw,
- struct dentry *dentry)
-{
- struct rp1_pll_ph *pll_ph = container_of(hw, struct rp1_pll_ph, hw);
- const struct rp1_pll_ph_data *data = pll_ph->data;
- struct rp1_clockman *clockman = pll_ph->clockman;
- struct debugfs_reg32 *regs;
-
- regs = devm_kcalloc(clockman->dev, 1, sizeof(*regs), GFP_KERNEL);
- if (!regs)
- return;
-
- regs[0].name = "ph_reg";
- regs[0].offset = data->ph_reg;
-
- rp1_debugfs_regset(clockman, 0, regs, 1, dentry);
-}
-
static int rp1_pll_divider_is_on(struct clk_hw *hw)
{
- struct rp1_pll *divider = container_of(hw, struct rp1_pll, div.hw);
+ struct rp1_clk_desc *divider =
+ container_of(hw, struct rp1_clk_desc, div.hw);
struct rp1_clockman *clockman = divider->clockman;
const struct rp1_pll_data *data = divider->data;
@@ -819,7 +708,8 @@ static int rp1_pll_divider_is_on(struct clk_hw *hw)
static int rp1_pll_divider_on(struct clk_hw *hw)
{
- struct rp1_pll *divider = container_of(hw, struct rp1_pll, div.hw);
+ struct rp1_clk_desc *divider =
+ container_of(hw, struct rp1_clk_desc, div.hw);
struct rp1_clockman *clockman = divider->clockman;
const struct rp1_pll_data *data = divider->data;
@@ -830,15 +720,13 @@ static int rp1_pll_divider_on(struct clk_hw *hw)
clockman_read(clockman, data->ctrl_reg) & ~PLL_SEC_RST);
spin_unlock(&clockman->regs_lock);
-#ifdef MEASURE_CLOCK_RATE
- clockman_measure_clock(clockman, data->name, data->fc0_src);
-#endif
return 0;
}
static void rp1_pll_divider_off(struct clk_hw *hw)
{
- struct rp1_pll *divider = container_of(hw, struct rp1_pll, div.hw);
+ struct rp1_clk_desc *divider =
+ container_of(hw, struct rp1_clk_desc, div.hw);
struct rp1_clockman *clockman = divider->clockman;
const struct rp1_pll_data *data = divider->data;
@@ -848,11 +736,11 @@ static void rp1_pll_divider_off(struct clk_hw *hw)
spin_unlock(&clockman->regs_lock);
}
-static int rp1_pll_divider_set_rate(struct clk_hw *hw,
- unsigned long rate,
+static int rp1_pll_divider_set_rate(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate)
{
- struct rp1_pll *divider = container_of(hw, struct rp1_pll, div.hw);
+ struct rp1_clk_desc *divider =
+ container_of(hw, struct rp1_clk_desc, div.hw);
struct rp1_clockman *clockman = divider->clockman;
const struct rp1_pll_data *data = divider->data;
u32 div, sec;
@@ -862,21 +750,20 @@ static int rp1_pll_divider_set_rate(struct clk_hw *hw,
spin_lock(&clockman->regs_lock);
sec = clockman_read(clockman, data->ctrl_reg);
- sec = set_register_field(sec, div, PLL_SEC_DIV_MASK, PLL_SEC_DIV_SHIFT);
+ sec &= ~PLL_SEC_DIV_MASK;
+ sec |= FIELD_PREP(PLL_SEC_DIV_MASK, div);
/* Must keep the divider in reset to change the value. */
sec |= PLL_SEC_RST;
clockman_write(clockman, data->ctrl_reg, sec);
- // todo: must sleep 10 pll vco cycles
+ /* must sleep 10 pll vco cycles */
+ ndelay(div64_ul(10ULL * div * NSEC_PER_SEC, parent_rate));
+
sec &= ~PLL_SEC_RST;
clockman_write(clockman, data->ctrl_reg, sec);
spin_unlock(&clockman->regs_lock);
-#ifdef MEASURE_CLOCK_RATE
- if (rp1_pll_divider_is_on(hw))
- clockman_measure_clock(clockman, data->name, data->fc0_src);
-#endif
return 0;
}
@@ -894,26 +781,9 @@ static int rp1_pll_divider_determine_rate(struct clk_hw *hw,
return 0;
}
-static void rp1_pll_divider_debug_init(struct clk_hw *hw, struct dentry *dentry)
-{
- struct rp1_pll *divider = container_of(hw, struct rp1_pll, div.hw);
- struct rp1_clockman *clockman = divider->clockman;
- const struct rp1_pll_data *data = divider->data;
- struct debugfs_reg32 *regs;
-
- regs = devm_kcalloc(clockman->dev, 1, sizeof(*regs), GFP_KERNEL);
- if (!regs)
- return;
-
- regs[0].name = "sec";
- regs[0].offset = data->ctrl_reg;
-
- rp1_debugfs_regset(clockman, 0, regs, 1, dentry);
-}
-
static int rp1_clock_is_on(struct clk_hw *hw)
{
- struct rp1_clock *clock = container_of(hw, struct rp1_clock, hw);
+ struct rp1_clk_desc *clock = container_of(hw, struct rp1_clk_desc, hw);
struct rp1_clockman *clockman = clock->clockman;
const struct rp1_clock_data *data = clock->data;
@@ -923,17 +793,17 @@ static int rp1_clock_is_on(struct clk_hw *hw)
static unsigned long rp1_clock_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
- struct rp1_clock *clock = container_of(hw, struct rp1_clock, hw);
+ struct rp1_clk_desc *clock = container_of(hw, struct rp1_clk_desc, hw);
struct rp1_clockman *clockman = clock->clockman;
const struct rp1_clock_data *data = clock->data;
u64 calc_rate;
u64 div;
-
u32 frac;
div = clockman_read(clockman, data->div_int_reg);
frac = (data->div_frac_reg != 0) ?
- clockman_read(clockman, data->div_frac_reg) : 0;
+ clockman_read(clockman, data->div_frac_reg) :
+ 0;
/* If the integer portion of the divider is 0, treat it as 2^16 */
if (!div)
@@ -949,38 +819,39 @@ static unsigned long rp1_clock_recalc_rate(struct clk_hw *hw,
static int rp1_clock_on(struct clk_hw *hw)
{
- struct rp1_clock *clock = container_of(hw, struct rp1_clock, hw);
+ struct rp1_clk_desc *clock = container_of(hw, struct rp1_clk_desc, hw);
struct rp1_clockman *clockman = clock->clockman;
const struct rp1_clock_data *data = clock->data;
spin_lock(&clockman->regs_lock);
clockman_write(clockman, data->ctrl_reg,
- clockman_read(clockman, data->ctrl_reg) | CLK_CTRL_ENABLE);
+ clockman_read(clockman, data->ctrl_reg) |
+ CLK_CTRL_ENABLE);
/* If this is a GPCLK, turn on the output-enable */
if (data->oe_mask)
clockman_write(clockman, GPCLK_OE_CTRL,
- clockman_read(clockman, GPCLK_OE_CTRL) | data->oe_mask);
+ clockman_read(clockman, GPCLK_OE_CTRL) |
+ data->oe_mask);
spin_unlock(&clockman->regs_lock);
-#ifdef MEASURE_CLOCK_RATE
- clockman_measure_clock(clockman, data->name, data->fc0_src);
-#endif
return 0;
}
static void rp1_clock_off(struct clk_hw *hw)
{
- struct rp1_clock *clock = container_of(hw, struct rp1_clock, hw);
+ struct rp1_clk_desc *clock = container_of(hw, struct rp1_clk_desc, hw);
struct rp1_clockman *clockman = clock->clockman;
const struct rp1_clock_data *data = clock->data;
spin_lock(&clockman->regs_lock);
clockman_write(clockman, data->ctrl_reg,
- clockman_read(clockman, data->ctrl_reg) & ~CLK_CTRL_ENABLE);
+ clockman_read(clockman, data->ctrl_reg) &
+ ~CLK_CTRL_ENABLE);
/* If this is a GPCLK, turn off the output-enable */
if (data->oe_mask)
clockman_write(clockman, GPCLK_OE_CTRL,
- clockman_read(clockman, GPCLK_OE_CTRL) & ~data->oe_mask);
+ clockman_read(clockman, GPCLK_OE_CTRL) &
+ ~data->oe_mask);
spin_unlock(&clockman->regs_lock);
}
@@ -1002,14 +873,13 @@ static u32 rp1_clock_choose_div(unsigned long rate, unsigned long parent_rate,
*/
if (data->div_frac_reg) {
div = (u64)parent_rate << CLK_DIV_FRAC_BITS;
- div = DIV_U64_NEAREST(div, rate);
+ div = DIV_ROUND_CLOSEST_ULL(div, rate);
} else {
- div = DIV_U64_NEAREST(parent_rate, rate);
+ div = DIV_ROUND_CLOSEST_ULL(parent_rate, rate);
div <<= CLK_DIV_FRAC_BITS;
}
- div = clamp(div,
- 1ull << CLK_DIV_FRAC_BITS,
+ div = clamp(div, 1ull << CLK_DIV_FRAC_BITS,
(u64)data->div_int_max << CLK_DIV_FRAC_BITS);
return div;
@@ -1017,7 +887,7 @@ static u32 rp1_clock_choose_div(unsigned long rate, unsigned long parent_rate,
static u8 rp1_clock_get_parent(struct clk_hw *hw)
{
- struct rp1_clock *clock = container_of(hw, struct rp1_clock, hw);
+ struct rp1_clk_desc *clock = container_of(hw, struct rp1_clk_desc, hw);
struct rp1_clockman *clockman = clock->clockman;
const struct rp1_clock_data *data = clock->data;
u32 sel, ctrl;
@@ -1043,7 +913,7 @@ static u8 rp1_clock_get_parent(struct clk_hw *hw)
* the AUXSRC register field.
*/
ctrl = clockman_read(clockman, data->ctrl_reg);
- parent = (ctrl & CLK_CTRL_AUXSRC_MASK) >> CLK_CTRL_AUXSRC_SHIFT;
+ parent = FIELD_GET(CLK_CTRL_AUXSRC_MASK, ctrl);
parent += data->num_std_parents;
}
@@ -1052,7 +922,7 @@ static u8 rp1_clock_get_parent(struct clk_hw *hw)
static int rp1_clock_set_parent(struct clk_hw *hw, u8 index)
{
- struct rp1_clock *clock = container_of(hw, struct rp1_clock, hw);
+ struct rp1_clk_desc *clock = container_of(hw, struct rp1_clk_desc, hw);
struct rp1_clockman *clockman = clock->clockman;
const struct rp1_clock_data *data = clock->data;
u32 ctrl, sel;
@@ -1062,63 +932,53 @@ static int rp1_clock_set_parent(struct clk_hw *hw, u8 index)
if (index >= data->num_std_parents) {
/* This is an aux source request */
- if (index >= data->num_std_parents + data->num_aux_parents)
+ if (index >= data->num_std_parents + data->num_aux_parents) {
+ spin_unlock(&clockman->regs_lock);
return -EINVAL;
+ }
/* Select parent from aux list */
- ctrl = set_register_field(ctrl, index - data->num_std_parents,
- CLK_CTRL_AUXSRC_MASK,
- CLK_CTRL_AUXSRC_SHIFT);
+ ctrl &= ~CLK_CTRL_AUXSRC_MASK;
+ ctrl |= FIELD_PREP(CLK_CTRL_AUXSRC_MASK,
+ index - data->num_std_parents);
/* Set src to aux list */
- ctrl = set_register_field(ctrl, AUX_SEL, data->clk_src_mask,
- CLK_CTRL_SRC_SHIFT);
+ ctrl &= ~data->clk_src_mask;
+ ctrl |= (AUX_SEL << CLK_CTRL_SRC_SHIFT) & data->clk_src_mask;
} else {
- ctrl = set_register_field(ctrl, index, data->clk_src_mask,
- CLK_CTRL_SRC_SHIFT);
+ ctrl &= ~data->clk_src_mask;
+ ctrl |= (index << CLK_CTRL_SRC_SHIFT) & data->clk_src_mask;
}
clockman_write(clockman, data->ctrl_reg, ctrl);
spin_unlock(&clockman->regs_lock);
sel = rp1_clock_get_parent(hw);
- WARN(sel != index, "(%s): Parent index req %u returned back %u\n",
- data->name, index, sel);
+ if (sel != index)
+ return -EINVAL;
return 0;
}
-static int rp1_clock_set_rate_and_parent(struct clk_hw *hw,
- unsigned long rate,
- unsigned long parent_rate,
- u8 parent)
+static int rp1_clock_set_rate_and_parent(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate, u8 parent)
{
- struct rp1_clock *clock = container_of(hw, struct rp1_clock, hw);
+ struct rp1_clk_desc *clock = container_of(hw, struct rp1_clk_desc, hw);
struct rp1_clockman *clockman = clock->clockman;
const struct rp1_clock_data *data = clock->data;
u32 div = rp1_clock_choose_div(rate, parent_rate, data);
- WARN(rate > 4000000000ll, "rate is -ve (%d)\n", (int)rate);
-
- if (WARN(!div,
- "clk divider calculated as 0! (%s, rate %ld, parent rate %ld)\n",
- data->name, rate, parent_rate))
- div = 1 << CLK_DIV_FRAC_BITS;
-
spin_lock(&clockman->regs_lock);
clockman_write(clockman, data->div_int_reg, div >> CLK_DIV_FRAC_BITS);
if (data->div_frac_reg)
- clockman_write(clockman, data->div_frac_reg, div << (32 - CLK_DIV_FRAC_BITS));
+ clockman_write(clockman, data->div_frac_reg,
+ div << (32 - CLK_DIV_FRAC_BITS));
spin_unlock(&clockman->regs_lock);
if (parent != 0xff)
- rp1_clock_set_parent(hw, parent);
+ return rp1_clock_set_parent(hw, parent);
-#ifdef MEASURE_CLOCK_RATE
- if (rp1_clock_is_on(hw))
- clockman_measure_clock(clockman, data->name, data->fc0_src);
-#endif
return 0;
}
@@ -1128,23 +988,99 @@ static int rp1_clock_set_rate(struct clk_hw *hw, unsigned long rate,
return rp1_clock_set_rate_and_parent(hw, rate, parent_rate, 0xff);
}
-static void rp1_clock_choose_div_and_prate(struct clk_hw *hw,
- int parent_idx,
+static unsigned long calc_core_pll_rate(struct clk_hw *pll_hw,
+ unsigned long target_rate,
+ int *pdiv_prim, int *pdiv_clk)
+{
+ static const int prim_divs[] = {
+ 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 14, 15,
+ 16, 18, 20, 21, 24, 25, 28, 30, 35, 36, 42, 49,
+ };
+ const unsigned long xosc_rate = clk_hw_get_rate(clk_xosc);
+ const unsigned long core_min = xosc_rate * 16;
+ const unsigned long core_max = 2400000000;
+ int best_div_prim = 1, best_div_clk = 1;
+ unsigned long best_rate = core_max + 1;
+ unsigned long core_rate = 0;
+ int div_int, div_frac;
+ u64 div;
+ int i;
+
+ /* Given the target rate, choose a set of divisors/multipliers */
+ for (i = 0; i < ARRAY_SIZE(prim_divs); i++) {
+ int div_prim = prim_divs[i];
+ int div_clk;
+
+ for (div_clk = 1; div_clk <= 256; div_clk++) {
+ core_rate = target_rate * div_clk * div_prim;
+ if (core_rate >= core_min) {
+ if (core_rate < best_rate) {
+ best_rate = core_rate;
+ best_div_prim = div_prim;
+ best_div_clk = div_clk;
+ }
+ break;
+ }
+ }
+ }
+
+ if (best_rate < core_max) {
+ div = ((best_rate << 24) + xosc_rate / 2) / xosc_rate;
+ div_int = div >> 24;
+ div_frac = div % (1 << 24);
+ core_rate = (xosc_rate * ((div_int << 24) + div_frac) +
+ (1 << 23)) >>
+ 24;
+ } else {
+ core_rate = 0;
+ }
+
+ if (pdiv_prim)
+ *pdiv_prim = best_div_prim;
+ if (pdiv_clk)
+ *pdiv_clk = best_div_clk;
+
+ return core_rate;
+}
+
+static void rp1_clock_choose_div_and_prate(struct clk_hw *hw, int parent_idx,
unsigned long rate,
unsigned long *prate,
unsigned long *calc_rate)
{
- struct rp1_clock *clock = container_of(hw, struct rp1_clock, hw);
+ struct rp1_clk_desc *clock = container_of(hw, struct rp1_clk_desc, hw);
const struct rp1_clock_data *data = clock->data;
struct clk_hw *clk_audio_hw = &clk_audio->hw;
struct clk_hw *clk_i2s_hw = &clk_i2s->hw;
struct clk_hw *parent;
u32 div;
u64 tmp;
- int i;
parent = clk_hw_get_parent_by_index(hw, parent_idx);
+ if (hw == clk_i2s_hw && clk_i2s->cached_rate == rate &&
+ parent == clk_audio_hw) {
+ *prate = clk_audio->cached_rate;
+ *calc_rate = rate;
+ return;
+ }
+
+ if (hw == clk_i2s_hw && parent == clk_audio_hw) {
+ unsigned long core_rate, audio_rate, i2s_rate;
+ int div_prim, div_clk;
+
+ core_rate =
+ calc_core_pll_rate(parent, rate, &div_prim, &div_clk);
+ audio_rate = DIV_ROUND_CLOSEST(core_rate, div_prim);
+ i2s_rate = DIV_ROUND_CLOSEST(audio_rate, div_clk);
+ clk_audio_core->cached_rate = core_rate;
+ clk_audio->cached_rate = audio_rate;
+ clk_i2s->cached_rate = i2s_rate;
+ *prate = audio_rate;
+ *calc_rate = i2s_rate;
+ return;
+ }
+
*prate = clk_hw_get_rate(parent);
div = rp1_clock_choose_div(rate, *prate, data);
@@ -1156,14 +1092,13 @@ static void rp1_clock_choose_div_and_prate(struct clk_hw *hw,
/* Recalculate to account for rounding errors */
tmp = (u64)*prate << CLK_DIV_FRAC_BITS;
tmp = div_u64(tmp, div);
+
/*
* Prevent overclocks - if all parent choices result in
* a downstream clock in excess of the maximum, then the
- * call to set the clock will fail. But due to round-to-
- * nearest in the PLL core (which has 24 fractional bits),
- * it's expedient to tolerate a tiny error (1Hz/33MHz).
+ * call to set the clock will fail.
*/
- if (tmp > clock->data->max_freq + (clock->data->max_freq >> 25))
+ if (tmp > data->max_freq)
*calc_rate = 0;
else
*calc_rate = tmp;
@@ -1209,11 +1144,11 @@ static int rp1_clock_determine_rate(struct clk_hw *hw,
rp1_clock_choose_div_and_prate(hw, i, req->rate, &prate,
&calc_rate);
- if (ABS_DIFF(calc_rate, req->rate) < best_rate_diff) {
+ if (abs_diff(calc_rate, req->rate) < best_rate_diff) {
best_parent = parent;
best_prate = prate;
best_rate = calc_rate;
- best_rate_diff = ABS_DIFF(calc_rate, req->rate);
+ best_rate_diff = abs_diff(calc_rate, req->rate);
if (best_rate_diff == 0)
break;
@@ -1230,28 +1165,55 @@ static int rp1_clock_determine_rate(struct clk_hw *hw,
return 0;
}
+static int rp1_varsrc_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct rp1_clk_desc *clock = container_of(hw, struct rp1_clk_desc, hw);
+
+ /*
+ * "varsrc" exists purely to let clock dividers know the frequency
+ * of an externally-managed clock source (such as MIPI DSI byte-clock)
+ * which may change at run-time as a side-effect of some other driver.
+ */
+ clock->cached_rate = rate;
+ return 0;
+}
+
+static unsigned long rp1_varsrc_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct rp1_clk_desc *clock = container_of(hw, struct rp1_clk_desc, hw);
+
+ return clock->cached_rate;
+}
+
+static int rp1_varsrc_determine_rate(struct clk_hw *hw,
+ struct clk_rate_request *req)
+{
+ return 0;
+}
+
static const struct clk_ops rp1_pll_core_ops = {
.is_prepared = rp1_pll_core_is_on,
.prepare = rp1_pll_core_on,
.unprepare = rp1_pll_core_off,
.set_rate = rp1_pll_core_set_rate,
.recalc_rate = rp1_pll_core_recalc_rate,
- .round_rate = rp1_pll_core_round_rate,
+ .determine_rate = rp1_pll_core_determine_rate,
};
static const struct clk_ops rp1_pll_ops = {
.set_rate = rp1_pll_set_rate,
.recalc_rate = rp1_pll_recalc_rate,
- .round_rate = rp1_pll_round_rate,
+ .determine_rate = rp1_pll_determine_rate,
};
static const struct clk_ops rp1_pll_ph_ops = {
.is_prepared = rp1_pll_ph_is_on,
.prepare = rp1_pll_ph_on,
.unprepare = rp1_pll_ph_off,
- .set_rate = rp1_pll_ph_set_rate,
.recalc_rate = rp1_pll_ph_recalc_rate,
- .round_rate = rp1_pll_ph_round_rate,
+ .determine_rate = rp1_pll_ph_determine_rate,
};
static const struct clk_ops rp1_pll_divider_ops = {
@@ -1260,7 +1222,7 @@ static const struct clk_ops rp1_pll_divider_ops = {
.unprepare = rp1_pll_divider_off,
.set_rate = rp1_pll_divider_set_rate,
.recalc_rate = rp1_pll_divider_recalc_rate,
- .round_rate = rp1_pll_divider_round_rate,
+ .determine_rate = rp1_pll_divider_determine_rate,
};
static const struct clk_ops rp1_clk_ops = {
@@ -1273,367 +1235,786 @@ static const struct clk_ops rp1_clk_ops = {
.set_rate_and_parent = rp1_clock_set_rate_and_parent,
.set_rate = rp1_clock_set_rate,
.determine_rate = rp1_clock_determine_rate,
- .debug_init = rp1_clk_debug_init,
+};
+
+static const struct clk_ops rp1_varsrc_ops = {
+ .set_rate = rp1_varsrc_set_rate,
+ .recalc_rate = rp1_varsrc_recalc_rate,
+ .determine_rate = rp1_varsrc_determine_rate,
};
static struct clk_hw *rp1_register_pll(struct rp1_clockman *clockman,
- const void *data)
+ struct rp1_clk_desc *desc)
{
- const struct rp1_pll_data *pll_data = data;
- struct rp1_pll *pll;
- struct clk_init_data init;
int ret;
- memset(&init, 0, sizeof(init));
+ desc->clockman = clockman;
- init.parent_names = &pll_data->source_pll;
- init.num_parents = 1;
- init.name = pll_data->name;
- init.ops = &rp1_pll_ops;
- init.flags = pll_data->flags;
+ ret = devm_clk_hw_register(clockman->dev, &desc->hw);
+ if (ret)
+ return ERR_PTR(ret);
- pll = kzalloc(sizeof(*pll), GFP_KERNEL);
- if (!pll)
- return NULL;
+ return &desc->hw;
+}
- pll->clockman = clockman;
- pll->data = pll_data;
- pll->hw.init = &init;
+static struct clk_hw *rp1_register_pll_divider(struct rp1_clockman *clockman,
+ struct rp1_clk_desc *desc)
+{
+ const struct rp1_pll_data *divider_data = desc->data;
+ int ret;
- ret = devm_clk_hw_register(clockman->dev, &pll->hw);
- if (ret) {
- kfree(pll);
- return NULL;
- }
+ desc->div.reg = clockman->regs + divider_data->ctrl_reg;
+ desc->div.shift = __ffs(PLL_SEC_DIV_MASK);
+ desc->div.width = __ffs(~(PLL_SEC_DIV_MASK >> desc->div.shift));
+ desc->div.flags = CLK_DIVIDER_ROUND_CLOSEST;
+ desc->div.lock = &clockman->regs_lock;
+ desc->div.hw.init = desc->hw.init;
+ desc->div.table = pll_sec_div_table;
+
+ desc->clockman = clockman;
- return &pll->hw;
+ ret = devm_clk_hw_register(clockman->dev, &desc->div.hw);
+ if (ret)
+ return ERR_PTR(ret);
+
+ return &desc->div.hw;
}
-static struct clk_hw *rp1_register_pll_ph(struct rp1_clockman *clockman,
- const void *data)
+static struct clk_hw *rp1_register_clock(struct rp1_clockman *clockman,
+ struct rp1_clk_desc *desc)
{
- const struct rp1_pll_ph_data *ph_data = data;
- struct rp1_pll_ph *ph;
- struct clk_init_data init;
+ const struct rp1_clock_data *clock_data = desc->data;
int ret;
- memset(&init, 0, sizeof(init));
+ if (WARN_ON_ONCE(MAX_CLK_PARENTS < clock_data->num_std_parents +
+ clock_data->num_aux_parents))
+ return ERR_PTR(-EINVAL);
- /* All of the PLLs derive from the external oscillator. */
- init.parent_names = &ph_data->source_pll;
- init.num_parents = 1;
- init.name = ph_data->name;
- init.ops = &rp1_pll_ph_ops;
- init.flags = ph_data->flags;
+ /* There must be a gap for the AUX selector */
+ if (WARN_ON_ONCE(clock_data->num_std_parents > AUX_SEL &&
+ desc->hw.init->parent_data[AUX_SEL].index != -1))
+ return ERR_PTR(-EINVAL);
- ph = kzalloc(sizeof(*ph), GFP_KERNEL);
- if (!ph)
- return NULL;
+ desc->clockman = clockman;
- ph->clockman = clockman;
- ph->data = ph_data;
- ph->hw.init = &init;
+ ret = devm_clk_hw_register(clockman->dev, &desc->hw);
+ if (ret)
+ return ERR_PTR(ret);
+
+ return &desc->hw;
+}
+
+/* Assignment helper macros for different clock types. */
+#define _REGISTER(f, ...) { .clk_register = f, __VA_ARGS__ }
- ret = devm_clk_hw_register(clockman->dev, &ph->hw);
- if (ret) {
- kfree(ph);
- return NULL;
+#define CLK_DATA(type, ...) \
+ .data = &(struct type) \
+ { \
+ __VA_ARGS__ \
}
- return &ph->hw;
-}
+#define REGISTER_PLL(...) _REGISTER(&rp1_register_pll, __VA_ARGS__)
-static struct clk_hw *rp1_register_pll_divider(struct rp1_clockman *clockman,
- const void *data)
-{
- const struct rp1_pll_data *divider_data = data;
- struct rp1_pll *divider;
- struct clk_init_data init;
- int ret;
+#define REGISTER_PLL_DIV(...) _REGISTER(&rp1_register_pll_divider, __VA_ARGS__)
- memset(&init, 0, sizeof(init));
+#define REGISTER_CLK(...) _REGISTER(&rp1_register_clock, __VA_ARGS__)
- init.parent_names = &divider_data->source_pll;
- init.num_parents = 1;
- init.name = divider_data->name;
- init.ops = &rp1_pll_divider_ops;
- init.flags = divider_data->flags;
+static struct rp1_clk_desc pll_sys_core_desc =
+ REGISTER_PLL(.hw.init = CLK_HW_INIT_PARENTS_DATA(
+ "pll_sys_core",
+ (const struct clk_parent_data[]){ { .index = 0 } },
+ &rp1_pll_core_ops, CLK_IS_CRITICAL),
+ CLK_DATA(rp1_pll_core_data, .cs_reg = PLL_SYS_CS,
+ .pwr_reg = PLL_SYS_PWR,
+ .fbdiv_int_reg = PLL_SYS_FBDIV_INT,
+ .fbdiv_frac_reg = PLL_SYS_FBDIV_FRAC, ));
- divider = devm_kzalloc(clockman->dev, sizeof(*divider), GFP_KERNEL);
- if (!divider)
- return NULL;
+static struct rp1_clk_desc pll_audio_core_desc =
+ REGISTER_PLL(.hw.init = CLK_HW_INIT_PARENTS_DATA(
+ "pll_audio_core",
+ (const struct clk_parent_data[]){ { .index = 0 } },
+ &rp1_pll_core_ops, CLK_IS_CRITICAL),
+ CLK_DATA(rp1_pll_core_data, .cs_reg = PLL_AUDIO_CS,
+ .pwr_reg = PLL_AUDIO_PWR,
+ .fbdiv_int_reg = PLL_AUDIO_FBDIV_INT,
+ .fbdiv_frac_reg = PLL_AUDIO_FBDIV_FRAC, ));
- divider->div.reg = clockman->regs + divider_data->ctrl_reg;
- divider->div.shift = PLL_SEC_DIV_SHIFT;
- divider->div.width = PLL_SEC_DIV_WIDTH;
- divider->div.flags = CLK_DIVIDER_ROUND_CLOSEST;
- divider->div.lock = &clockman->regs_lock;
- divider->div.hw.init = &init;
- divider->div.table = pll_sec_div_table;
+static struct rp1_clk_desc pll_video_core_desc =
+ REGISTER_PLL(.hw.init = CLK_HW_INIT_PARENTS_DATA(
+ "pll_video_core",
+ (const struct clk_parent_data[]){ { .index = 0 } },
+ &rp1_pll_core_ops, CLK_IS_CRITICAL),
+ CLK_DATA(rp1_pll_core_data, .cs_reg = PLL_VIDEO_CS,
+ .pwr_reg = PLL_VIDEO_PWR,
+ .fbdiv_int_reg = PLL_VIDEO_FBDIV_INT,
+ .fbdiv_frac_reg = PLL_VIDEO_FBDIV_FRAC, ));
- divider->clockman = clockman;
- divider->data = divider_data;
+static struct rp1_clk_desc pll_sys_desc =
+ REGISTER_PLL(.hw.init = CLK_HW_INIT_PARENTS_DATA(
+ "pll_sys",
+ (const struct clk_parent_data[]){
+ { .hw = &pll_sys_core_desc.hw } },
+ &rp1_pll_ops, 0),
+ CLK_DATA(rp1_pll_data, .ctrl_reg = PLL_SYS_PRIM,
+ .fc0_src = FC_NUM(0, 2), ));
- ret = devm_clk_hw_register(clockman->dev, &divider->div.hw);
- if (ret)
- return ERR_PTR(ret);
+static struct rp1_clk_desc pll_audio_desc =
+ REGISTER_PLL(.hw.init = CLK_HW_INIT_PARENTS_DATA(
+ "pll_audio",
+ (const struct clk_parent_data[]){
+ { .hw = &pll_audio_core_desc.hw } },
+ &rp1_pll_ops, CLK_SET_RATE_PARENT),
+ CLK_DATA(rp1_pll_data, .ctrl_reg = PLL_AUDIO_PRIM,
+ .fc0_src = FC_NUM(4, 2), ));
- return &divider->div.hw;
-}
+static struct rp1_clk_desc pll_video_desc =
+ REGISTER_PLL(.hw.init = CLK_HW_INIT_PARENTS_DATA(
+ "pll_video",
+ (const struct clk_parent_data[]){
+ { .hw = &pll_video_core_desc.hw } },
+ &rp1_pll_ops, 0),
+ CLK_DATA(rp1_pll_data, .ctrl_reg = PLL_VIDEO_PRIM,
+ .fc0_src = FC_NUM(3, 2), ));
-static struct clk_hw *rp1_register_clock(struct rp1_clockman *clockman,
- const void *data)
-{
- const struct rp1_clock_data *clock_data = data;
- struct rp1_clock *clock;
- struct clk_init_data init;
- int ret;
+static struct rp1_clk_desc pll_sys_sec_desc =
+ REGISTER_PLL_DIV(.hw.init = CLK_HW_INIT_PARENTS_DATA(
+ "pll_sys_sec",
+ (const struct clk_parent_data[]){
+ { .hw = &pll_sys_core_desc.hw } },
+ &rp1_pll_divider_ops, 0),
+ CLK_DATA(rp1_pll_data, .ctrl_reg = PLL_SYS_SEC,
+ .fc0_src = FC_NUM(2, 2), ));
- BUG_ON(MAX_CLK_PARENTS <
- clock_data->num_std_parents + clock_data->num_aux_parents);
- /* There must be a gap for the AUX selector */
- BUG_ON((clock_data->num_std_parents > AUX_SEL) &&
- strcmp("-", clock_data->parents[AUX_SEL]));
+static struct rp1_clk_desc pll_video_sec_desc =
+ REGISTER_PLL_DIV(.hw.init = CLK_HW_INIT_PARENTS_DATA(
+ "pll_video_sec",
+ (const struct clk_parent_data[]){
+ { .hw = &pll_video_core_desc.hw } },
+ &rp1_pll_divider_ops, 0),
+ CLK_DATA(rp1_pll_data, .ctrl_reg = PLL_VIDEO_SEC,
+ .fc0_src = FC_NUM(5, 3), ));
- memset(&init, 0, sizeof(init));
- init.parent_names = clock_data->parents;
- init.num_parents =
- clock_data->num_std_parents + clock_data->num_aux_parents;
- init.name = clock_data->name;
- init.flags = clock_data->flags;
- init.ops = &rp1_clk_ops;
+static const struct clk_parent_data clk_eth_tsu_parents[] = {
+ { .index = 0 }, { .hw = &pll_video_sec_desc.hw },
+ { .index = -1 }, { .index = -1 },
+ { .index = -1 }, { .index = -1 },
+ { .index = -1 }, { .index = -1 },
+};
- clock = devm_kzalloc(clockman->dev, sizeof(*clock), GFP_KERNEL);
- if (!clock)
- return NULL;
+static struct rp1_clk_desc clk_eth_tsu_desc =
+ REGISTER_CLK(.hw.init = CLK_HW_INIT_PARENTS_DATA("clk_eth_tsu",
+ clk_eth_tsu_parents,
+ &rp1_clk_ops, 0),
+ CLK_DATA(rp1_clock_data, .num_std_parents = 0,
+ .num_aux_parents = 8,
+ .ctrl_reg = CLK_ETH_TSU_CTRL,
+ .div_int_reg = CLK_ETH_TSU_DIV_INT,
+ .sel_reg = CLK_ETH_TSU_SEL,
+ .div_int_max = DIV_INT_8BIT_MAX,
+ .max_freq = 50 * HZ_PER_MHZ,
+ .fc0_src = FC_NUM(5, 7), ));
- clock->clockman = clockman;
- clock->data = clock_data;
- clock->hw.init = &init;
+static const struct clk_parent_data clk_eth_parents[] = {
+ { .hw = &pll_sys_sec_desc.div.hw },
+ { .hw = &pll_sys_desc.hw },
+ { .hw = &pll_video_sec_desc.hw },
+};
- ret = devm_clk_hw_register(clockman->dev, &clock->hw);
- if (ret)
- return ERR_PTR(ret);
+static struct rp1_clk_desc clk_eth_desc =
+ REGISTER_CLK(.hw.init = CLK_HW_INIT_PARENTS_DATA(
+ "clk_eth", clk_eth_parents, &rp1_clk_ops, 0),
+ CLK_DATA(rp1_clock_data, .num_std_parents = 0,
+ .num_aux_parents = 3, .ctrl_reg = CLK_ETH_CTRL,
+ .div_int_reg = CLK_ETH_DIV_INT,
+ .sel_reg = CLK_ETH_SEL,
+ .div_int_max = DIV_INT_8BIT_MAX,
+ .max_freq = 125 * HZ_PER_MHZ,
+ .fc0_src = FC_NUM(4, 6), ));
- return &clock->hw;
-}
+static const struct clk_parent_data clk_sys_parents[] = {
+ { .index = 0 },
+ { .index = -1 },
+ { .hw = &pll_sys_desc.hw },
+};
-static struct clk_hw *rp1_register_varsrc(struct rp1_clockman *clockman,
- const void *data)
-{
- const char *name = *(char const * const *)data;
- struct rp1_varsrc *clock;
- struct clk_init_data init;
- int ret;
+static struct rp1_clk_desc clk_sys_desc =
+ REGISTER_CLK(.hw.init = CLK_HW_INIT_PARENTS_DATA(
+ "clk_sys", clk_sys_parents, &rp1_clk_ops,
+ CLK_IS_CRITICAL),
+ CLK_DATA(rp1_clock_data, .num_std_parents = 3,
+ .num_aux_parents = 0, .ctrl_reg = CLK_SYS_CTRL,
+ .div_int_reg = CLK_SYS_DIV_INT,
+ .sel_reg = CLK_SYS_SEL,
+ .div_int_max = DIV_INT_24BIT_MAX,
+ .max_freq = 200 * HZ_PER_MHZ,
+ .fc0_src = FC_NUM(0, 4), .clk_src_mask = 0x3, ));
- memset(&init, 0, sizeof(init));
- init.parent_names = &ref_clock;
- init.num_parents = 1;
- init.name = name;
- init.ops = &rp1_varsrc_ops;
+static struct rp1_clk_desc pll_sys_pri_ph_desc =
+ REGISTER_PLL(.hw.init = CLK_HW_INIT_PARENTS_DATA(
+ "pll_sys_pri_ph",
+ (const struct clk_parent_data[]){
+ { .hw = &pll_sys_desc.hw } },
+ &rp1_pll_ph_ops, 0),
+ CLK_DATA(rp1_pll_ph_data, .ph_reg = PLL_SYS_PRIM,
+ .fixed_divider = 2, .phase = RP1_PLL_PHASE_0,
+ .fc0_src = FC_NUM(1, 2), ));
- clock = devm_kzalloc(clockman->dev, sizeof(*clock), GFP_KERNEL);
- if (!clock)
- return NULL;
+static struct rp1_clk_desc pll_audio_pri_ph_desc =
+ REGISTER_PLL(.hw.init = CLK_HW_INIT_PARENTS_DATA(
+ "pll_audio_pri_ph",
+ (const struct clk_parent_data[]){
+ { .hw = &pll_audio_desc.hw } },
+ &rp1_pll_ph_ops, 0),
+ CLK_DATA(rp1_pll_ph_data, .ph_reg = PLL_AUDIO_PRIM,
+ .fixed_divider = 2, .phase = RP1_PLL_PHASE_0,
+ .fc0_src = FC_NUM(5, 1), ));
- clock->clockman = clockman;
- clock->hw.init = &init;
+static struct rp1_clk_desc pll_video_pri_ph_desc =
+ REGISTER_PLL(.hw.init = CLK_HW_INIT_PARENTS_DATA(
+ "pll_video_pri_ph",
+ (const struct clk_parent_data[]){
+ { .hw = &pll_video_desc.hw } },
+ &rp1_pll_ph_ops, 0),
+ CLK_DATA(rp1_pll_ph_data, .ph_reg = PLL_VIDEO_PRIM,
+ .fixed_divider = 2, .phase = RP1_PLL_PHASE_0,
+ .fc0_src = FC_NUM(4, 3), ));
- ret = devm_clk_hw_register(clockman->dev, &clock->hw);
- if (ret)
- return ERR_PTR(ret);
+static struct rp1_clk_desc pll_audio_sec_desc =
+ REGISTER_PLL_DIV(.hw.init = CLK_HW_INIT_PARENTS_DATA(
+ "pll_audio_sec",
+ (const struct clk_parent_data[]){
+ { .hw = &pll_audio_core_desc.hw } },
+ &rp1_pll_divider_ops, 0),
+ CLK_DATA(rp1_pll_data, .ctrl_reg = PLL_AUDIO_SEC,
+ .fc0_src = FC_NUM(6, 2), ));
- return &clock->hw;
-}
+static struct rp1_clk_desc pll_audio_tern_desc =
+ REGISTER_PLL_DIV(.hw.init = CLK_HW_INIT_PARENTS_DATA(
+ "pll_audio_tern",
+ (const struct clk_parent_data[]){
+ { .hw = &pll_audio_core_desc.hw } },
+ &rp1_pll_divider_ops, 0),
+ CLK_DATA(rp1_pll_data, .ctrl_reg = PLL_AUDIO_TERN,
+ .fc0_src = FC_NUM(6, 2), ));
-struct rp1_clk_desc {
- struct clk_hw *(*clk_register)(struct rp1_clockman *clockman,
- const void *data);
- const void *data;
+static struct rp1_clk_desc clk_slow_sys_desc =
+ REGISTER_CLK(.hw.init = CLK_HW_INIT_PARENTS_DATA(
+ "clk_slow_sys",
+ (const struct clk_parent_data[]){ { .index = 0 } },
+ &rp1_clk_ops, CLK_IS_CRITICAL),
+ CLK_DATA(rp1_clock_data, .num_std_parents = 1,
+ .num_aux_parents = 0,
+ .ctrl_reg = CLK_SLOW_SYS_CTRL,
+ .div_int_reg = CLK_SLOW_SYS_DIV_INT,
+ .sel_reg = CLK_SLOW_SYS_SEL,
+ .div_int_max = DIV_INT_8BIT_MAX,
+ .max_freq = 50 * HZ_PER_MHZ,
+ .fc0_src = FC_NUM(1, 4), .clk_src_mask = 0x1, ));
+
+static const struct clk_parent_data clk_dma_parents[] = {
+ { .hw = &pll_sys_pri_ph_desc.hw },
+ { .hw = &pll_video_desc.hw },
+ { .index = 0 },
};
-/* Assignment helper macros for different clock types. */
-#define _REGISTER(f, ...) { .clk_register = f, .data = __VA_ARGS__ }
+static struct rp1_clk_desc clk_dma_desc =
+ REGISTER_CLK(.hw.init = CLK_HW_INIT_PARENTS_DATA(
+ "clk_dma", clk_dma_parents, &rp1_clk_ops, 0),
+ CLK_DATA(rp1_clock_data, .num_std_parents = 0,
+ .num_aux_parents = 3, .ctrl_reg = CLK_DMA_CTRL,
+ .div_int_reg = CLK_DMA_DIV_INT,
+ .sel_reg = CLK_DMA_SEL,
+ .div_int_max = DIV_INT_8BIT_MAX,
+ .max_freq = 100 * HZ_PER_MHZ,
+ .fc0_src = FC_NUM(2, 2), ));
-#define REGISTER_PLL_CORE(...) _REGISTER(&rp1_register_pll_core, \
- &(struct rp1_pll_core_data) \
- {__VA_ARGS__})
+static const struct clk_parent_data clk_uart_parents[] = {
+ { .hw = &pll_sys_pri_ph_desc.hw },
+ { .hw = &pll_video_desc.hw },
+ { .index = 0 },
+};
-#define REGISTER_PLL(...) _REGISTER(&rp1_register_pll, \
- &(struct rp1_pll_data) \
- {__VA_ARGS__})
+static struct rp1_clk_desc clk_uart_desc =
+ REGISTER_CLK(.hw.init = CLK_HW_INIT_PARENTS_DATA(
+ "clk_uart", clk_uart_parents, &rp1_clk_ops, 0),
+ CLK_DATA(rp1_clock_data, .num_std_parents = 0,
+ .num_aux_parents = 3, .ctrl_reg = CLK_UART_CTRL,
+ .div_int_reg = CLK_UART_DIV_INT,
+ .sel_reg = CLK_UART_SEL,
+ .div_int_max = DIV_INT_8BIT_MAX,
+ .max_freq = 100 * HZ_PER_MHZ,
+ .fc0_src = FC_NUM(6, 7), ));
-#define REGISTER_PLL_PH(...) _REGISTER(&rp1_register_pll_ph, \
- &(struct rp1_pll_ph_data) \
- {__VA_ARGS__})
+static const struct clk_parent_data clk_pwm0_parents[] = {
+ { .index = -1 },
+ { .hw = &pll_video_sec_desc.hw },
+ { .index = 0 },
+};
-#define REGISTER_PLL_DIV(...) _REGISTER(&rp1_register_pll_divider, \
- &(struct rp1_pll_data) \
- {__VA_ARGS__})
+static struct rp1_clk_desc clk_pwm0_desc =
+ REGISTER_CLK(.hw.init = CLK_HW_INIT_PARENTS_DATA(
+ "clk_pwm0", clk_pwm0_parents, &rp1_clk_ops, 0),
+ CLK_DATA(rp1_clock_data, .num_std_parents = 0,
+ .num_aux_parents = 3, .ctrl_reg = CLK_PWM0_CTRL,
+ .div_int_reg = CLK_PWM0_DIV_INT,
+ .div_frac_reg = CLK_PWM0_DIV_FRAC,
+ .sel_reg = CLK_PWM0_SEL,
+ .div_int_max = DIV_INT_16BIT_MAX,
+ .max_freq = 76800 * HZ_PER_KHZ,
+ .fc0_src = FC_NUM(0, 5), ));
-#define REGISTER_CLK(...) _REGISTER(&rp1_register_clock, \
- __VA_ARGS__)
+static const struct clk_parent_data clk_pwm1_parents[] = {
+ { .index = -1 },
+ { .hw = &pll_video_sec_desc.hw },
+ { .index = 0 },
+};
-static struct rp1_clk_desc pll_sys_core_desc = REGISTER_PLL(
- .hw.init = CLK_HW_INIT_PARENTS_DATA(
- "pll_sys_core",
- (const struct clk_parent_data[]) { { .index = 0 } },
- &rp1_pll_core_ops,
- CLK_IS_CRITICAL
- ),
- CLK_DATA(rp1_pll_core_data,
- .cs_reg = PLL_SYS_CS,
- .pwr_reg = PLL_SYS_PWR,
- .fbdiv_int_reg = PLL_SYS_FBDIV_INT,
- .fbdiv_frac_reg = PLL_SYS_FBDIV_FRAC,
- )
-);
+static struct rp1_clk_desc clk_pwm1_desc =
+ REGISTER_CLK(.hw.init = CLK_HW_INIT_PARENTS_DATA(
+ "clk_pwm1", clk_pwm1_parents, &rp1_clk_ops, 0),
+ CLK_DATA(rp1_clock_data, .num_std_parents = 0,
+ .num_aux_parents = 3, .ctrl_reg = CLK_PWM1_CTRL,
+ .div_int_reg = CLK_PWM1_DIV_INT,
+ .div_frac_reg = CLK_PWM1_DIV_FRAC,
+ .sel_reg = CLK_PWM1_SEL,
+ .div_int_max = DIV_INT_16BIT_MAX,
+ .max_freq = 76800 * HZ_PER_KHZ,
+ .fc0_src = FC_NUM(1, 5), ));
-static struct rp1_clk_desc pll_audio_core_desc = REGISTER_PLL(
- .hw.init = CLK_HW_INIT_PARENTS_DATA(
- "pll_audio_core",
- (const struct clk_parent_data[]) { { .index = 0 } },
- &rp1_pll_core_ops,
- CLK_IS_CRITICAL
- ),
- CLK_DATA(rp1_pll_core_data,
- .cs_reg = PLL_AUDIO_CS,
- .pwr_reg = PLL_AUDIO_PWR,
- .fbdiv_int_reg = PLL_AUDIO_FBDIV_INT,
- .fbdiv_frac_reg = PLL_AUDIO_FBDIV_FRAC,
- )
-);
+static const struct clk_parent_data clk_audio_in_parents[] = {
+ { .index = -1 }, { .index = -1 },
+ { .index = -1 }, { .hw = &pll_video_sec_desc.hw },
+ { .index = 0 },
+};
-static struct rp1_clk_desc pll_video_core_desc = REGISTER_PLL(
- .hw.init = CLK_HW_INIT_PARENTS_DATA(
- "pll_video_core",
- (const struct clk_parent_data[]) { { .index = 0 } },
- &rp1_pll_core_ops,
- CLK_IS_CRITICAL
- ),
- CLK_DATA(rp1_pll_core_data,
- .cs_reg = PLL_VIDEO_CS,
- .pwr_reg = PLL_VIDEO_PWR,
- .fbdiv_int_reg = PLL_VIDEO_FBDIV_INT,
- .fbdiv_frac_reg = PLL_VIDEO_FBDIV_FRAC,
- )
-);
+static struct rp1_clk_desc clk_audio_in_desc =
+ REGISTER_CLK(.hw.init = CLK_HW_INIT_PARENTS_DATA("clk_audio_in",
+ clk_audio_in_parents,
+ &rp1_clk_ops, 0),
+ CLK_DATA(rp1_clock_data, .num_std_parents = 0,
+ .num_aux_parents = 5,
+ .ctrl_reg = CLK_AUDIO_IN_CTRL,
+ .div_int_reg = CLK_AUDIO_IN_DIV_INT,
+ .sel_reg = CLK_AUDIO_IN_SEL,
+ .div_int_max = DIV_INT_8BIT_MAX,
+ .max_freq = 76800 * HZ_PER_KHZ,
+ .fc0_src = FC_NUM(2, 5), ));
-static struct rp1_clk_desc pll_sys_desc = REGISTER_PLL(
- .hw.init = CLK_HW_INIT_PARENTS_DATA(
- "pll_sys",
- (const struct clk_parent_data[]) {
- { .hw = &pll_sys_core_desc.hw }
- },
- &rp1_pll_ops,
- 0
- ),
- CLK_DATA(rp1_pll_data,
- .ctrl_reg = PLL_SYS_PRIM,
- .fc0_src = FC_NUM(0, 2),
- )
-);
+static const struct clk_parent_data clk_audio_out_parents[] = {
+ { .index = -1 },
+ { .index = -1 },
+ { .hw = &pll_video_sec_desc.hw },
+ { .index = 0 },
+};
+
+static struct rp1_clk_desc clk_audio_out_desc =
+ REGISTER_CLK(.hw.init = CLK_HW_INIT_PARENTS_DATA("clk_audio_out",
+ clk_audio_out_parents,
+ &rp1_clk_ops, 0),
+ CLK_DATA(rp1_clock_data, .num_std_parents = 0,
+ .num_aux_parents = 4,
+ .ctrl_reg = CLK_AUDIO_OUT_CTRL,
+ .div_int_reg = CLK_AUDIO_OUT_DIV_INT,
+ .sel_reg = CLK_AUDIO_OUT_SEL,
+ .div_int_max = DIV_INT_8BIT_MAX,
+ .max_freq = 153600 * HZ_PER_KHZ,
+ .fc0_src = FC_NUM(3, 5), ));
+
+static const struct clk_parent_data clk_i2s_parents[] = {
+ { .index = 0 },
+ { .hw = &pll_audio_desc.hw },
+ { .hw = &pll_audio_sec_desc.hw },
+};
-static struct rp1_clk_desc pll_sys_sec_desc = REGISTER_PLL_DIV(
- .hw.init = CLK_HW_INIT_PARENTS_DATA(
- "pll_sys_sec",
- (const struct clk_parent_data[]) {
- { .hw = &pll_sys_core_desc.hw }
- },
- &rp1_pll_divider_ops,
- 0
- ),
- CLK_DATA(rp1_pll_data,
- .ctrl_reg = PLL_SYS_SEC,
- .fc0_src = FC_NUM(2, 2),
- )
-);
+static struct rp1_clk_desc clk_i2s_desc =
+ REGISTER_CLK(.hw.init = CLK_HW_INIT_PARENTS_DATA(
+ "clk_i2s", clk_i2s_parents, &rp1_clk_ops,
+ CLK_SET_RATE_PARENT),
+ CLK_DATA(rp1_clock_data, .num_std_parents = 0,
+ .num_aux_parents = 3, .ctrl_reg = CLK_I2S_CTRL,
+ .div_int_reg = CLK_I2S_DIV_INT,
+ .sel_reg = CLK_I2S_SEL,
+ .div_int_max = DIV_INT_8BIT_MAX,
+ .max_freq = 50 * HZ_PER_MHZ,
+ .fc0_src = FC_NUM(4, 4), ));
-static struct rp1_clk_desc clk_eth_tsu_desc = REGISTER_CLK(
- .hw.init = CLK_HW_INIT_PARENTS_DATA(
- "clk_eth_tsu",
- (const struct clk_parent_data[]) { { .index = 0 } },
- &rp1_clk_ops,
- 0
- ),
- CLK_DATA(rp1_clock_data,
- .num_std_parents = 0,
- .num_aux_parents = 1,
- .ctrl_reg = CLK_ETH_TSU_CTRL,
- .div_int_reg = CLK_ETH_TSU_DIV_INT,
- .sel_reg = CLK_ETH_TSU_SEL,
- .div_int_max = DIV_INT_8BIT_MAX,
- .max_freq = 50 * HZ_PER_MHZ,
- .fc0_src = FC_NUM(5, 7),
- )
-);
+static struct rp1_clk_desc clk_mipi0_cfg_desc =
+ REGISTER_CLK(.hw.init = CLK_HW_INIT_PARENTS_DATA(
+ "clk_mipi0_cfg",
+ (const struct clk_parent_data[]){ { .index = 0 } },
+ &rp1_clk_ops, 0),
+ CLK_DATA(rp1_clock_data, .num_std_parents = 0,
+ .num_aux_parents = 1,
+ .ctrl_reg = CLK_MIPI0_CFG_CTRL,
+ .div_int_reg = CLK_MIPI0_CFG_DIV_INT,
+ .sel_reg = CLK_MIPI0_CFG_SEL,
+ .div_int_max = DIV_INT_8BIT_MAX,
+ .max_freq = 50 * HZ_PER_MHZ,
+ .fc0_src = FC_NUM(4, 5), ));
-static const struct clk_parent_data clk_eth_parents[] = {
- { .hw = &pll_sys_sec_desc.div.hw },
+static struct rp1_clk_desc clk_mipi1_cfg_desc =
+ REGISTER_CLK(.hw.init = CLK_HW_INIT_PARENTS_DATA(
+ "clk_mipi1_cfg",
+ (const struct clk_parent_data[]){ { .index = 0 } },
+ &rp1_clk_ops, 0),
+ CLK_DATA(rp1_clock_data, .num_std_parents = 0,
+ .num_aux_parents = 1,
+ .ctrl_reg = CLK_MIPI1_CFG_CTRL,
+ .div_int_reg = CLK_MIPI1_CFG_DIV_INT,
+ .sel_reg = CLK_MIPI1_CFG_SEL,
+ .div_int_max = DIV_INT_8BIT_MAX,
+ .max_freq = 50 * HZ_PER_MHZ,
+ .fc0_src = FC_NUM(5, 6), .clk_src_mask = 0x1, ));
+
+static struct rp1_clk_desc clk_adc_desc =
+ REGISTER_CLK(.hw.init = CLK_HW_INIT_PARENTS_DATA(
+ "clk_adc",
+ (const struct clk_parent_data[]){ { .index = 0 } },
+ &rp1_clk_ops, 0),
+ CLK_DATA(rp1_clock_data, .num_std_parents = 0,
+ .num_aux_parents = 1, .ctrl_reg = CLK_ADC_CTRL,
+ .div_int_reg = CLK_ADC_DIV_INT,
+ .sel_reg = CLK_ADC_SEL,
+ .div_int_max = DIV_INT_8BIT_MAX,
+ .max_freq = 50 * HZ_PER_MHZ,
+ .fc0_src = FC_NUM(5, 5), ));
+
+static struct rp1_clk_desc clk_sdio_timer_desc =
+ REGISTER_CLK(.hw.init = CLK_HW_INIT_PARENTS_DATA(
+ "clk_sdio_timer",
+ (const struct clk_parent_data[]){ { .index = 0 } },
+ &rp1_clk_ops, 0),
+ CLK_DATA(rp1_clock_data, .num_std_parents = 0,
+ .num_aux_parents = 1,
+ .ctrl_reg = CLK_SDIO_TIMER_CTRL,
+ .div_int_reg = CLK_SDIO_TIMER_DIV_INT,
+ .sel_reg = CLK_SDIO_TIMER_SEL,
+ .div_int_max = DIV_INT_8BIT_MAX,
+ .max_freq = 50 * HZ_PER_MHZ,
+ .fc0_src = FC_NUM(3, 4), ));
+
+static struct rp1_clk_desc clk_sdio_alt_src_desc =
+ REGISTER_CLK(.hw.init = CLK_HW_INIT_PARENTS_DATA(
+ "clk_sdio_alt_src",
+ (const struct clk_parent_data[]){
+ { .hw = &pll_sys_desc.hw } },
+ &rp1_clk_ops, 0),
+ CLK_DATA(rp1_clock_data, .num_std_parents = 0,
+ .num_aux_parents = 1,
+ .ctrl_reg = CLK_SDIO_ALT_SRC_CTRL,
+ .div_int_reg = CLK_SDIO_ALT_SRC_DIV_INT,
+ .sel_reg = CLK_SDIO_ALT_SRC_SEL,
+ .div_int_max = DIV_INT_8BIT_MAX,
+ .max_freq = 200 * HZ_PER_MHZ,
+ .fc0_src = FC_NUM(5, 4), ));
+
+static const struct clk_parent_data clk_dpi_parents[] = {
{ .hw = &pll_sys_desc.hw },
+ { .hw = &pll_video_sec_desc.hw },
+ { .hw = &pll_video_desc.hw },
+ { .index = -1 },
+ { .index = -1 },
+ { .index = -1 },
+ { .index = -1 },
+ { .index = -1 },
};
-static struct rp1_clk_desc clk_eth_desc = REGISTER_CLK(
- .hw.init = CLK_HW_INIT_PARENTS_DATA(
- "clk_eth",
- clk_eth_parents,
- &rp1_clk_ops,
- 0
- ),
- CLK_DATA(rp1_clock_data,
- .num_std_parents = 0,
- .num_aux_parents = 2,
- .ctrl_reg = CLK_ETH_CTRL,
- .div_int_reg = CLK_ETH_DIV_INT,
- .sel_reg = CLK_ETH_SEL,
- .div_int_max = DIV_INT_8BIT_MAX,
- .max_freq = 125 * HZ_PER_MHZ,
- .fc0_src = FC_NUM(4, 6),
- )
-);
+static struct rp1_clk_desc clk_dpi_desc = REGISTER_CLK(
+ .hw.init = CLK_HW_INIT_PARENTS_DATA(
+ "clk_dpi", clk_dpi_parents, &rp1_clk_ops,
+ CLK_SET_RATE_NO_REPARENT /* Let DPI driver set parent */
+ ),
+ CLK_DATA(rp1_clock_data, .num_std_parents = 0,
+ .num_aux_parents = 8, .ctrl_reg = VIDEO_CLK_DPI_CTRL,
+ .div_int_reg = VIDEO_CLK_DPI_DIV_INT,
+ .sel_reg = VIDEO_CLK_DPI_SEL,
+ .div_int_max = DIV_INT_8BIT_MAX,
+ .max_freq = 200 * HZ_PER_MHZ,
+ .fc0_src = FC_NUM(1, 6), ));
-static const struct clk_parent_data clk_sys_parents[] = {
+static const struct clk_parent_data clk_gp0_parents[] = {
{ .index = 0 },
{ .index = -1 },
+ { .index = -1 },
+ { .index = -1 },
+ { .index = -1 },
+ { .index = -1 },
+ { .hw = &pll_sys_desc.hw },
+ { .index = -1 },
+ { .index = -1 },
+ { .index = -1 },
+ { .hw = &clk_i2s_desc.hw },
+ { .hw = &clk_adc_desc.hw },
+ { .index = -1 },
+ { .index = -1 },
+ { .index = -1 },
+ { .hw = &clk_sys_desc.hw },
+};
+
+static struct rp1_clk_desc clk_gp0_desc =
+ REGISTER_CLK(.hw.init = CLK_HW_INIT_PARENTS_DATA(
+ "clk_gp0", clk_gp0_parents, &rp1_clk_ops, 0),
+ CLK_DATA(rp1_clock_data, .num_std_parents = 0,
+ .num_aux_parents = 16, .oe_mask = BIT(0),
+ .ctrl_reg = CLK_GP0_CTRL,
+ .div_int_reg = CLK_GP0_DIV_INT,
+ .div_frac_reg = CLK_GP0_DIV_FRAC,
+ .sel_reg = CLK_GP0_SEL,
+ .div_int_max = DIV_INT_16BIT_MAX,
+ .max_freq = 100 * HZ_PER_MHZ,
+ .fc0_src = FC_NUM(0, 1), ));
+
+static const struct clk_parent_data clk_gp1_parents[] = {
+ { .hw = &clk_sdio_timer_desc.hw },
+ { .index = -1 },
+ { .index = -1 },
+ { .index = -1 },
+ { .index = -1 },
+ { .index = -1 },
+ { .hw = &pll_sys_pri_ph_desc.hw },
+ { .index = -1 },
+ { .index = -1 },
+ { .index = -1 },
+ { .hw = &clk_adc_desc.hw },
+ { .hw = &clk_dpi_desc.hw },
+ { .hw = &clk_pwm0_desc.hw },
+ { .index = -1 },
+ { .index = -1 },
+ { .index = -1 },
+};
+
+static struct rp1_clk_desc clk_gp1_desc =
+ REGISTER_CLK(.hw.init = CLK_HW_INIT_PARENTS_DATA(
+ "clk_gp1", clk_gp1_parents, &rp1_clk_ops, 0),
+ CLK_DATA(rp1_clock_data, .num_std_parents = 0,
+ .num_aux_parents = 16, .oe_mask = BIT(1),
+ .ctrl_reg = CLK_GP1_CTRL,
+ .div_int_reg = CLK_GP1_DIV_INT,
+ .div_frac_reg = CLK_GP1_DIV_FRAC,
+ .sel_reg = CLK_GP1_SEL,
+ .div_int_max = DIV_INT_16BIT_MAX,
+ .max_freq = 100 * HZ_PER_MHZ,
+ .fc0_src = FC_NUM(1, 1), ));
+
+static struct rp1_clk_desc clksrc_mipi0_dsi_byteclk_desc =
+ REGISTER_CLK(.hw.init = CLK_HW_INIT_PARENTS_DATA(
+ "clksrc_mipi0_dsi_byteclk",
+ (const struct clk_parent_data[]){ { .index = 0 } },
+ &rp1_varsrc_ops, 0),
+ CLK_DATA(rp1_clock_data, .num_std_parents = 1,
+ .num_aux_parents = 0, ));
+
+static struct rp1_clk_desc clksrc_mipi1_dsi_byteclk_desc =
+ REGISTER_CLK(.hw.init = CLK_HW_INIT_PARENTS_DATA(
+ "clksrc_mipi1_dsi_byteclk",
+ (const struct clk_parent_data[]){ { .index = 0 } },
+ &rp1_varsrc_ops, 0),
+ CLK_DATA(rp1_clock_data, .num_std_parents = 1,
+ .num_aux_parents = 0, ));
+
+static const struct clk_parent_data clk_mipi0_dpi_parents[] = {
+ { .hw = &pll_sys_desc.hw },
+ { .hw = &pll_video_sec_desc.hw },
+ { .hw = &pll_video_desc.hw },
+ { .hw = &clksrc_mipi0_dsi_byteclk_desc.hw },
+ { .index = -1 },
+ { .index = -1 },
+ { .index = -1 },
+ { .index = -1 },
+};
+
+static struct rp1_clk_desc clk_mipi0_dpi_desc = REGISTER_CLK(
+ .hw.init = CLK_HW_INIT_PARENTS_DATA(
+ "clk_mipi0_dpi", clk_mipi0_dpi_parents, &rp1_clk_ops,
+ CLK_SET_RATE_NO_REPARENT /* Let DSI driver set parent */
+ ),
+ CLK_DATA(rp1_clock_data, .num_std_parents = 0,
+ .num_aux_parents = 8,
+ .ctrl_reg = VIDEO_CLK_MIPI0_DPI_CTRL,
+ .div_int_reg = VIDEO_CLK_MIPI0_DPI_DIV_INT,
+ .div_frac_reg = VIDEO_CLK_MIPI0_DPI_DIV_FRAC,
+ .sel_reg = VIDEO_CLK_MIPI0_DPI_SEL,
+ .div_int_max = DIV_INT_8BIT_MAX,
+ .max_freq = 200 * HZ_PER_MHZ,
+ .fc0_src = FC_NUM(2, 6), ));
+
+static const struct clk_parent_data clk_mipi1_dpi_parents[] = {
{ .hw = &pll_sys_desc.hw },
+ { .hw = &pll_video_sec_desc.hw },
+ { .hw = &pll_video_desc.hw },
+ { .hw = &clksrc_mipi1_dsi_byteclk_desc.hw },
+ { .index = -1 },
+ { .index = -1 },
+ { .index = -1 },
+ { .index = -1 },
};
-static struct rp1_clk_desc clk_sys_desc = REGISTER_CLK(
- .hw.init = CLK_HW_INIT_PARENTS_DATA(
- "clk_sys",
- clk_sys_parents,
- &rp1_clk_ops,
- CLK_IS_CRITICAL
- ),
- CLK_DATA(rp1_clock_data,
- .num_std_parents = 3,
- .num_aux_parents = 0,
- .ctrl_reg = CLK_SYS_CTRL,
- .div_int_reg = CLK_SYS_DIV_INT,
- .sel_reg = CLK_SYS_SEL,
- .div_int_max = DIV_INT_24BIT_MAX,
- .max_freq = 200 * HZ_PER_MHZ,
- .fc0_src = FC_NUM(0, 4),
- .clk_src_mask = 0x3,
- )
-);
+static struct rp1_clk_desc clk_mipi1_dpi_desc = REGISTER_CLK(
+ .hw.init = CLK_HW_INIT_PARENTS_DATA(
+ "clk_mipi1_dpi", clk_mipi1_dpi_parents, &rp1_clk_ops,
+ CLK_SET_RATE_NO_REPARENT /* Let DSI driver set parent */
+ ),
+ CLK_DATA(rp1_clock_data, .num_std_parents = 0,
+ .num_aux_parents = 8,
+ .ctrl_reg = VIDEO_CLK_MIPI1_DPI_CTRL,
+ .div_int_reg = VIDEO_CLK_MIPI1_DPI_DIV_INT,
+ .div_frac_reg = VIDEO_CLK_MIPI1_DPI_DIV_FRAC,
+ .sel_reg = VIDEO_CLK_MIPI1_DPI_SEL,
+ .div_int_max = DIV_INT_8BIT_MAX,
+ .max_freq = 200 * HZ_PER_MHZ,
+ .fc0_src = FC_NUM(3, 6), ));
+
+static const struct clk_parent_data clk_gp2_parents[] = {
+ { .hw = &clk_sdio_alt_src_desc.hw },
+ { .index = -1 },
+ { .index = -1 },
+ { .index = -1 },
+ { .index = -1 },
+ { .index = -1 },
+ { .hw = &pll_sys_sec_desc.hw },
+ { .index = -1 },
+ { .hw = &pll_video_desc.hw },
+ { .hw = &clk_audio_in_desc.hw },
+ { .hw = &clk_dpi_desc.hw },
+ { .hw = &clk_pwm0_desc.hw },
+ { .hw = &clk_pwm1_desc.hw },
+ { .hw = &clk_mipi0_dpi_desc.hw },
+ { .hw = &clk_mipi1_cfg_desc.hw },
+ { .hw = &clk_sys_desc.hw },
+};
+
+static struct rp1_clk_desc clk_gp2_desc =
+ REGISTER_CLK(.hw.init = CLK_HW_INIT_PARENTS_DATA(
+ "clk_gp2", clk_gp2_parents, &rp1_clk_ops, 0),
+ CLK_DATA(rp1_clock_data, .num_std_parents = 0,
+ .num_aux_parents = 16, .oe_mask = BIT(2),
+ .ctrl_reg = CLK_GP2_CTRL,
+ .div_int_reg = CLK_GP2_DIV_INT,
+ .div_frac_reg = CLK_GP2_DIV_FRAC,
+ .sel_reg = CLK_GP2_SEL,
+ .div_int_max = DIV_INT_16BIT_MAX,
+ .max_freq = 100 * HZ_PER_MHZ,
+ .fc0_src = FC_NUM(2, 1), ));
+
+static const struct clk_parent_data clk_gp3_parents[] = {
+ { .index = 0 },
+ { .index = -1 },
+ { .index = -1 },
+ { .index = -1 },
+ { .index = -1 },
+ { .index = -1 },
+ { .index = -1 },
+ { .index = -1 },
+ { .hw = &pll_video_pri_ph_desc.hw },
+ { .hw = &clk_audio_out_desc.hw },
+ { .index = -1 },
+ { .index = -1 },
+ { .hw = &clk_mipi1_dpi_desc.hw },
+ { .index = -1 },
+ { .index = -1 },
+ { .index = -1 },
+};
-static struct rp1_clk_desc pll_sys_pri_ph_desc = REGISTER_PLL(
- .hw.init = CLK_HW_INIT_PARENTS_DATA(
- "pll_sys_pri_ph",
- (const struct clk_parent_data[]) {
- { .hw = &pll_sys_desc.hw }
- },
- &rp1_pll_ph_ops,
- 0
- ),
- CLK_DATA(rp1_pll_ph_data,
- .ph_reg = PLL_SYS_PRIM,
- .fixed_divider = 2,
- .phase = RP1_PLL_PHASE_0,
- .fc0_src = FC_NUM(1, 2),
- )
-);
+static struct rp1_clk_desc clk_gp3_desc =
+ REGISTER_CLK(.hw.init = CLK_HW_INIT_PARENTS_DATA(
+ "clk_gp3", clk_gp3_parents, &rp1_clk_ops, 0),
+ CLK_DATA(rp1_clock_data, .num_std_parents = 0,
+ .num_aux_parents = 16, .oe_mask = BIT(3),
+ .ctrl_reg = CLK_GP3_CTRL,
+ .div_int_reg = CLK_GP3_DIV_INT,
+ .div_frac_reg = CLK_GP3_DIV_FRAC,
+ .sel_reg = CLK_GP3_SEL,
+ .div_int_max = DIV_INT_16BIT_MAX,
+ .max_freq = 100 * HZ_PER_MHZ,
+ .fc0_src = FC_NUM(3, 1), ));
+
+static const struct clk_parent_data clk_gp4_parents[] = {
+ { .index = 0 },
+ { .index = -1 },
+ { .index = -1 },
+ { .index = -1 },
+ { .index = -1 },
+ { .index = -1 },
+ { .index = -1 },
+ { .hw = &pll_video_sec_desc.hw },
+ { .index = -1 },
+ { .index = -1 },
+ { .index = -1 },
+ { .hw = &clk_mipi0_cfg_desc.hw },
+ { .hw = &clk_uart_desc.hw },
+ { .index = -1 },
+ { .index = -1 },
+ { .hw = &clk_sys_desc.hw },
+};
+
+static struct rp1_clk_desc clk_gp4_desc =
+ REGISTER_CLK(.hw.init = CLK_HW_INIT_PARENTS_DATA(
+ "clk_gp4", clk_gp4_parents, &rp1_clk_ops, 0),
+ CLK_DATA(rp1_clock_data, .num_std_parents = 0,
+ .num_aux_parents = 16, .oe_mask = BIT(4),
+ .ctrl_reg = CLK_GP4_CTRL,
+ .div_int_reg = CLK_GP4_DIV_INT,
+ .div_frac_reg = CLK_GP4_DIV_FRAC,
+ .sel_reg = CLK_GP4_SEL,
+ .div_int_max = DIV_INT_16BIT_MAX,
+ .max_freq = 100 * HZ_PER_MHZ,
+ .fc0_src = FC_NUM(4, 1), ));
+
+static const struct clk_parent_data clk_vec_parents[] = {
+ { .hw = &pll_sys_pri_ph_desc.hw },
+ { .hw = &pll_video_sec_desc.hw },
+ { .hw = &pll_video_desc.hw },
+ { .index = -1 },
+ { .index = -1 },
+ { .index = -1 },
+ { .index = -1 },
+ { .index = -1 },
+};
+
+static struct rp1_clk_desc clk_vec_desc = REGISTER_CLK(
+ .hw.init = CLK_HW_INIT_PARENTS_DATA(
+ "clk_vec", clk_vec_parents, &rp1_clk_ops,
+ CLK_SET_RATE_NO_REPARENT /* Let VEC driver set parent */
+ ),
+ CLK_DATA(rp1_clock_data, .num_std_parents = 0,
+ .num_aux_parents = 8, .ctrl_reg = VIDEO_CLK_VEC_CTRL,
+ .div_int_reg = VIDEO_CLK_VEC_DIV_INT,
+ .sel_reg = VIDEO_CLK_VEC_SEL,
+ .div_int_max = DIV_INT_8BIT_MAX,
+ .max_freq = 108 * HZ_PER_MHZ,
+ .fc0_src = FC_NUM(0, 6), ));
+
+static const struct clk_parent_data clk_gp5_parents[] = {
+ { .index = 0 },
+ { .index = -1 },
+ { .index = -1 },
+ { .index = -1 },
+ { .index = -1 },
+ { .index = -1 },
+ { .index = -1 },
+ { .hw = &pll_video_sec_desc.hw },
+ { .hw = &clk_eth_tsu_desc.hw },
+ { .index = -1 },
+ { .hw = &clk_vec_desc.hw },
+ { .index = -1 },
+ { .index = -1 },
+ { .index = -1 },
+ { .index = -1 },
+ { .index = -1 },
+};
+
+static struct rp1_clk_desc clk_gp5_desc =
+ REGISTER_CLK(.hw.init = CLK_HW_INIT_PARENTS_DATA(
+ "clk_gp5", clk_gp5_parents, &rp1_clk_ops, 0),
+ CLK_DATA(rp1_clock_data, .num_std_parents = 0,
+ .num_aux_parents = 16, .oe_mask = BIT(5),
+ .ctrl_reg = CLK_GP5_CTRL,
+ .div_int_reg = CLK_GP5_DIV_INT,
+ .div_frac_reg = CLK_GP5_DIV_FRAC,
+ .sel_reg = CLK_GP5_SEL,
+ .div_int_max = DIV_INT_16BIT_MAX,
+ .max_freq = 100 * HZ_PER_MHZ,
+ .fc0_src = FC_NUM(5, 1), ));
static struct rp1_clk_desc *const clk_desc_array[] = {
[RP1_PLL_SYS_CORE] = &pll_sys_core_desc,
@@ -1645,6 +2026,38 @@ static struct rp1_clk_desc *const clk_desc_array[] = {
[RP1_CLK_SYS] = &clk_sys_desc,
[RP1_PLL_SYS_PRI_PH] = &pll_sys_pri_ph_desc,
[RP1_PLL_SYS_SEC] = &pll_sys_sec_desc,
+ [RP1_PLL_AUDIO] = &pll_audio_desc,
+ [RP1_PLL_VIDEO] = &pll_video_desc,
+ [RP1_PLL_AUDIO_PRI_PH] = &pll_audio_pri_ph_desc,
+ [RP1_PLL_VIDEO_PRI_PH] = &pll_video_pri_ph_desc,
+ [RP1_PLL_AUDIO_SEC] = &pll_audio_sec_desc,
+ [RP1_PLL_VIDEO_SEC] = &pll_video_sec_desc,
+ [RP1_PLL_AUDIO_TERN] = &pll_audio_tern_desc,
+ [RP1_CLK_SLOW_SYS] = &clk_slow_sys_desc,
+ [RP1_CLK_DMA] = &clk_dma_desc,
+ [RP1_CLK_UART] = &clk_uart_desc,
+ [RP1_CLK_PWM0] = &clk_pwm0_desc,
+ [RP1_CLK_PWM1] = &clk_pwm1_desc,
+ [RP1_CLK_AUDIO_IN] = &clk_audio_in_desc,
+ [RP1_CLK_AUDIO_OUT] = &clk_audio_out_desc,
+ [RP1_CLK_I2S] = &clk_i2s_desc,
+ [RP1_CLK_MIPI0_CFG] = &clk_mipi0_cfg_desc,
+ [RP1_CLK_MIPI1_CFG] = &clk_mipi1_cfg_desc,
+ [RP1_CLK_ADC] = &clk_adc_desc,
+ [RP1_CLK_SDIO_TIMER] = &clk_sdio_timer_desc,
+ [RP1_CLK_SDIO_ALT_SRC] = &clk_sdio_alt_src_desc,
+ [RP1_CLK_GP0] = &clk_gp0_desc,
+ [RP1_CLK_GP1] = &clk_gp1_desc,
+ [RP1_CLK_GP2] = &clk_gp2_desc,
+ [RP1_CLK_GP3] = &clk_gp3_desc,
+ [RP1_CLK_GP4] = &clk_gp4_desc,
+ [RP1_CLK_GP5] = &clk_gp5_desc,
+ [RP1_CLK_VEC] = &clk_vec_desc,
+ [RP1_CLK_DPI] = &clk_dpi_desc,
+ [RP1_CLK_MIPI0_DPI] = &clk_mipi0_dpi_desc,
+ [RP1_CLK_MIPI1_DPI] = &clk_mipi1_dpi_desc,
+ [RP1_CLK_MIPI0_DSI_BYTECLOCK] = &clksrc_mipi0_dsi_byteclk_desc,
+ [RP1_CLK_MIPI1_DSI_BYTECLOCK] = &clksrc_mipi1_dsi_byteclk_desc,
};
static const struct regmap_range rp1_reg_ranges[] = {
@@ -1676,9 +2089,11 @@ static const struct regmap_range rp1_reg_ranges[] = {
regmap_reg_range(CLK_MIPI1_CFG_SEL, CLK_MIPI1_CFG_SEL),
regmap_reg_range(CLK_PCIE_AUX_CTRL, CLK_PCIE_AUX_DIV_INT),
regmap_reg_range(CLK_PCIE_AUX_SEL, CLK_PCIE_AUX_SEL),
- regmap_reg_range(CLK_USBH0_MICROFRAME_CTRL, CLK_USBH0_MICROFRAME_DIV_INT),
+ regmap_reg_range(CLK_USBH0_MICROFRAME_CTRL,
+ CLK_USBH0_MICROFRAME_DIV_INT),
regmap_reg_range(CLK_USBH0_MICROFRAME_SEL, CLK_USBH0_MICROFRAME_SEL),
- regmap_reg_range(CLK_USBH1_MICROFRAME_CTRL, CLK_USBH1_MICROFRAME_DIV_INT),
+ regmap_reg_range(CLK_USBH1_MICROFRAME_CTRL,
+ CLK_USBH1_MICROFRAME_DIV_INT),
regmap_reg_range(CLK_USBH1_MICROFRAME_SEL, CLK_USBH1_MICROFRAME_SEL),
regmap_reg_range(CLK_USBH0_SUSPEND_CTRL, CLK_USBH0_SUSPEND_DIV_INT),
regmap_reg_range(CLK_USBH0_SUSPEND_SEL, CLK_USBH0_SUSPEND_SEL),
@@ -1723,31 +2138,32 @@ static const struct regmap_config rp1_clk_regmap_cfg = {
static int rp1_clk_probe(struct platform_device *pdev)
{
- const struct rp1_clk_desc *desc;
+ const size_t asize = ARRAY_SIZE(clk_desc_array);
+ struct rp1_clk_desc *desc;
struct device *dev = &pdev->dev;
struct rp1_clockman *clockman;
- struct resource *res;
struct clk_hw **hws;
- const size_t asize = ARRAY_SIZE(clk_desc_array);
- u32 chip_id, platform;
unsigned int i;
- int ret;
clockman = devm_kzalloc(dev, struct_size(clockman, onecell.hws, asize),
GFP_KERNEL);
if (!clockman)
return -ENOMEM;
- rp1_get_platform(&chip_id, &platform);
-
spin_lock_init(&clockman->regs_lock);
clockman->dev = dev;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- clockman->regs = devm_ioremap_resource(&pdev->dev, res);
+
+ clockman->regs = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(clockman->regs))
return PTR_ERR(clockman->regs);
- platform_set_drvdata(pdev, clockman);
+ clockman->regmap =
+ devm_regmap_init_mmio(dev, clockman->regs, &rp1_clk_regmap_cfg);
+ if (IS_ERR(clockman->regmap)) {
+ dev_err_probe(dev, PTR_ERR(clockman->regmap),
+ "could not init clock regmap\n");
+ return PTR_ERR(clockman->regmap);
+ }
clockman->onecell.num = asize;
hws = clockman->onecell.hws;
@@ -1758,6 +2174,11 @@ static int rp1_clk_probe(struct platform_device *pdev)
hws[i] = desc->clk_register(clockman, desc);
}
+ clk_audio_core = &pll_audio_core_desc;
+ clk_audio = &pll_audio_desc;
+ clk_i2s = &clk_i2s_desc;
+ clk_xosc = clk_hw_get_parent_by_index(&clk_i2s->hw, 0);
+
platform_set_drvdata(pdev, clockman);
return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get,
@@ -1778,12 +2199,9 @@ static struct platform_driver rp1_clk_driver = {
.probe = rp1_clk_probe,
};
-static int __init __rp1_clk_driver_init(void)
-{
- return platform_driver_register(&rp1_clk_driver);
-}
-postcore_initcall(__rp1_clk_driver_init);
+module_platform_driver(rp1_clk_driver);
MODULE_AUTHOR("Naushir Patuck <[email protected]>");
+MODULE_AUTHOR("Andrea della Porta <[email protected]>");
MODULE_DESCRIPTION("RP1 clock driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/gpio/gpio-brcmstb.c b/drivers/gpio/gpio-brcmstb.c
index db3f079fe695..a078de2b807d 100644
--- a/drivers/gpio/gpio-brcmstb.c
+++ b/drivers/gpio/gpio-brcmstb.c
@@ -24,16 +24,16 @@ enum gio_reg_index {
NUMBER_OF_GIO_REGISTERS
};
-#define GIO_BANK_SIZE (NUMBER_OF_GIO_REGISTERS * sizeof(u32))
-#define GIO_BANK_OFF(bank, off) (((bank) * GIO_BANK_SIZE) + (off * sizeof(u32)))
-#define GIO_ODEN(bank) GIO_BANK_OFF(bank, GIO_REG_ODEN)
-#define GIO_DATA(bank) GIO_BANK_OFF(bank, GIO_REG_DATA)
-#define GIO_IODIR(bank) GIO_BANK_OFF(bank, GIO_REG_IODIR)
-#define GIO_EC(bank) GIO_BANK_OFF(bank, GIO_REG_EC)
-#define GIO_EI(bank) GIO_BANK_OFF(bank, GIO_REG_EI)
-#define GIO_MASK(bank) GIO_BANK_OFF(bank, GIO_REG_MASK)
-#define GIO_LEVEL(bank) GIO_BANK_OFF(bank, GIO_REG_LEVEL)
-#define GIO_STAT(bank) GIO_BANK_OFF(bank, GIO_REG_STAT)
+#define GIO_BANK_SIZE (NUMBER_OF_GIO_REGISTERS * sizeof(u32))
+#define GIO_BANK_OFF(bank, off) (((bank) * GIO_BANK_SIZE) + (off * sizeof(u32)))
+#define GIO_ODEN(bank) GIO_BANK_OFF(bank, GIO_REG_ODEN)
+#define GIO_DATA(bank) GIO_BANK_OFF(bank, GIO_REG_DATA)
+#define GIO_IODIR(bank) GIO_BANK_OFF(bank, GIO_REG_IODIR)
+#define GIO_EC(bank) GIO_BANK_OFF(bank, GIO_REG_EC)
+#define GIO_EI(bank) GIO_BANK_OFF(bank, GIO_REG_EI)
+#define GIO_MASK(bank) GIO_BANK_OFF(bank, GIO_REG_MASK)
+#define GIO_LEVEL(bank) GIO_BANK_OFF(bank, GIO_REG_LEVEL)
+#define GIO_STAT(bank) GIO_BANK_OFF(bank, GIO_REG_STAT)
struct brcmstb_gpio_bank {
struct list_head node;
@@ -56,10 +56,10 @@ struct brcmstb_gpio_priv {
int parent_wake_irq;
};
-#define MAX_GPIO_PER_BANK 32
-#define GPIO_BANK(gpio) ((gpio) >> 5)
+#define MAX_GPIO_PER_BANK 32
+#define GPIO_BANK(gpio) ((gpio) >> 5)
/* assumes MAX_GPIO_PER_BANK is a multiple of 2 */
-#define GPIO_BIT(gpio) ((gpio) & (MAX_GPIO_PER_BANK - 1))
+#define GPIO_BIT(gpio) ((gpio) & (MAX_GPIO_PER_BANK - 1))
static inline struct brcmstb_gpio_priv *
brcmstb_gpio_gc_to_priv(struct gpio_chip *gc)
@@ -73,8 +73,10 @@ __brcmstb_gpio_get_active_irqs(struct brcmstb_gpio_bank *bank)
{
void __iomem *reg_base = bank->parent_priv->reg_base;
- return gpio_generic_read_reg(&bank->chip, reg_base + GIO_STAT(bank->id)) &
- gpio_generic_read_reg(&bank->chip, reg_base + GIO_MASK(bank->id));
+ return gpio_generic_read_reg(&bank->chip,
+ reg_base + GIO_STAT(bank->id)) &
+ gpio_generic_read_reg(&bank->chip,
+ reg_base + GIO_MASK(bank->id));
}
static unsigned long
@@ -96,7 +98,7 @@ static int brcmstb_gpio_hwirq_to_offset(irq_hw_number_t hwirq,
}
static void brcmstb_gpio_set_imask(struct brcmstb_gpio_bank *bank,
- unsigned int hwirq, bool enable)
+ unsigned int hwirq, bool enable)
{
struct brcmstb_gpio_priv *priv = bank->parent_priv;
u32 mask = BIT(brcmstb_gpio_hwirq_to_offset(hwirq, bank));
@@ -110,8 +112,8 @@ static void brcmstb_gpio_set_imask(struct brcmstb_gpio_bank *bank,
imask |= mask;
else
imask &= ~mask;
- gpio_generic_write_reg(&bank->chip,
- priv->reg_base + GIO_MASK(bank->id), imask);
+ gpio_generic_write_reg(&bank->chip, priv->reg_base + GIO_MASK(bank->id),
+ imask);
}
static int brcmstb_gpio_to_irq(struct gpio_chip *gc, unsigned offset)
@@ -150,8 +152,8 @@ static void brcmstb_gpio_irq_ack(struct irq_data *d)
struct brcmstb_gpio_priv *priv = bank->parent_priv;
u32 mask = BIT(brcmstb_gpio_hwirq_to_offset(d->hwirq, bank));
- gpio_generic_write_reg(&bank->chip,
- priv->reg_base + GIO_STAT(bank->id), mask);
+ gpio_generic_write_reg(&bank->chip, priv->reg_base + GIO_STAT(bank->id),
+ mask);
}
static int brcmstb_gpio_irq_set_type(struct irq_data *d, unsigned int type)
@@ -187,7 +189,7 @@ static int brcmstb_gpio_irq_set_type(struct irq_data *d, unsigned int type)
break;
case IRQ_TYPE_EDGE_BOTH:
level = 0;
- edge_config = 0; /* don't care, but want known value */
+ edge_config = 0; /* don't care, but want known value */
edge_insensitive = mask;
break;
default:
@@ -196,18 +198,20 @@ static int brcmstb_gpio_irq_set_type(struct irq_data *d, unsigned int type)
guard(gpio_generic_lock_irqsave)(&bank->chip);
- iedge_config = gpio_generic_read_reg(&bank->chip,
- priv->reg_base + GIO_EC(bank->id)) & ~mask;
- iedge_insensitive = gpio_generic_read_reg(&bank->chip,
- priv->reg_base + GIO_EI(bank->id)) & ~mask;
+ iedge_config = gpio_generic_read_reg(
+ &bank->chip, priv->reg_base + GIO_EC(bank->id)) &
+ ~mask;
+ iedge_insensitive =
+ gpio_generic_read_reg(&bank->chip,
+ priv->reg_base + GIO_EI(bank->id)) &
+ ~mask;
ilevel = gpio_generic_read_reg(&bank->chip,
- priv->reg_base + GIO_LEVEL(bank->id)) & ~mask;
+ priv->reg_base + GIO_LEVEL(bank->id)) &
+ ~mask;
- gpio_generic_write_reg(&bank->chip,
- priv->reg_base + GIO_EC(bank->id),
+ gpio_generic_write_reg(&bank->chip, priv->reg_base + GIO_EC(bank->id),
iedge_config | edge_config);
- gpio_generic_write_reg(&bank->chip,
- priv->reg_base + GIO_EI(bank->id),
+ gpio_generic_write_reg(&bank->chip, priv->reg_base + GIO_EI(bank->id),
iedge_insensitive | edge_insensitive);
gpio_generic_write_reg(&bank->chip,
priv->reg_base + GIO_LEVEL(bank->id),
@@ -217,7 +221,7 @@ static int brcmstb_gpio_irq_set_type(struct irq_data *d, unsigned int type)
}
static int brcmstb_gpio_priv_set_wake(struct brcmstb_gpio_priv *priv,
- unsigned int enable)
+ unsigned int enable)
{
int ret = 0;
@@ -273,9 +277,10 @@ static void brcmstb_gpio_irq_bank_handler(struct brcmstb_gpio_bank *bank)
for_each_set_bit(offset, &status, 32) {
if (offset >= bank->width)
- dev_warn(&priv->pdev->dev,
- "IRQ for invalid GPIO (bank=%d, offset=%d)\n",
- bank->id, offset);
+ dev_warn(
+ &priv->pdev->dev,
+ "IRQ for invalid GPIO (bank=%d, offset=%d)\n",
+ bank->id, offset);
generic_handle_domain_irq(domain, hwbase + offset);
}
}
@@ -297,8 +302,9 @@ static void brcmstb_gpio_irq_handler(struct irq_desc *desc)
chained_irq_exit(chip, desc);
}
-static struct brcmstb_gpio_bank *brcmstb_gpio_hwirq_to_bank(
- struct brcmstb_gpio_priv *priv, irq_hw_number_t hwirq)
+static struct brcmstb_gpio_bank *
+brcmstb_gpio_hwirq_to_bank(struct brcmstb_gpio_priv *priv,
+ irq_hw_number_t hwirq)
{
struct brcmstb_gpio_bank *bank;
int i = 0;
@@ -319,9 +325,8 @@ static struct brcmstb_gpio_bank *brcmstb_gpio_hwirq_to_bank(
static struct lock_class_key brcmstb_gpio_irq_lock_class;
static struct lock_class_key brcmstb_gpio_irq_request_class;
-
static int brcmstb_gpio_irq_map(struct irq_domain *d, unsigned int irq,
- irq_hw_number_t hwirq)
+ irq_hw_number_t hwirq)
{
struct brcmstb_gpio_priv *priv = d->host_data;
struct brcmstb_gpio_bank *bank =
@@ -332,8 +337,8 @@ static int brcmstb_gpio_irq_map(struct irq_domain *d, unsigned int irq,
if (!bank)
return -EINVAL;
- dev_dbg(&pdev->dev, "Mapping irq %d for gpio line %d (bank %d)\n",
- irq, (int)hwirq, bank->id);
+ dev_dbg(&pdev->dev, "Mapping irq %d for gpio line %d (bank %d)\n", irq,
+ (int)hwirq, bank->id);
ret = irq_set_chip_data(irq, &bank->chip.gc);
if (ret < 0)
return ret;
@@ -358,15 +363,17 @@ static const struct irq_domain_ops brcmstb_gpio_irq_domain_ops = {
/* Make sure that the number of banks matches up between properties */
static int brcmstb_gpio_sanity_check_banks(struct device *dev,
- struct device_node *np, struct resource *res)
+ struct device_node *np,
+ struct resource *res)
{
int res_num_banks = resource_size(res) / GIO_BANK_SIZE;
int num_banks =
of_property_count_u32_elems(np, "brcm,gpio-bank-widths");
if (res_num_banks != num_banks) {
- dev_err(dev, "Mismatch in banks: res had %d, bank-widths had %d\n",
- res_num_banks, num_banks);
+ dev_err(dev,
+ "Mismatch in banks: res had %d, bank-widths had %d\n",
+ res_num_banks, num_banks);
return -EINVAL;
} else {
return 0;
@@ -400,7 +407,8 @@ static void brcmstb_gpio_remove(struct platform_device *pdev)
}
static int brcmstb_gpio_of_xlate(struct gpio_chip *gc,
- const struct of_phandle_args *gpiospec, u32 *flags)
+ const struct of_phandle_args *gpiospec,
+ u32 *flags)
{
struct brcmstb_gpio_priv *priv = brcmstb_gpio_gc_to_priv(gc);
struct brcmstb_gpio_bank *bank = gpiochip_get_data(gc);
@@ -419,7 +427,8 @@ static int brcmstb_gpio_of_xlate(struct gpio_chip *gc,
return -EINVAL;
if (unlikely(offset >= bank->width)) {
- dev_warn_ratelimited(&priv->pdev->dev,
+ dev_warn_ratelimited(
+ &priv->pdev->dev,
"Received request for invalid GPIO offset %d\n",
gpiospec->args[0]);
}
@@ -432,14 +441,15 @@ static int brcmstb_gpio_of_xlate(struct gpio_chip *gc,
/* priv->parent_irq and priv->num_gpios must be set before calling */
static int brcmstb_gpio_irq_setup(struct platform_device *pdev,
- struct brcmstb_gpio_priv *priv)
+ struct brcmstb_gpio_priv *priv)
{
struct device *dev = &pdev->dev;
struct device_node *np = dev->of_node;
int err;
- priv->irq_domain = irq_domain_create_linear(dev_fwnode(dev), priv->num_gpios,
- &brcmstb_gpio_irq_domain_ops, priv);
+ priv->irq_domain =
+ irq_domain_create_linear(dev_fwnode(dev), priv->num_gpios,
+ &brcmstb_gpio_irq_domain_ops, priv);
if (!priv->irq_domain) {
dev_err(dev, "Couldn't allocate IRQ domain\n");
return -ENXIO;
@@ -449,7 +459,8 @@ static int brcmstb_gpio_irq_setup(struct platform_device *pdev,
priv->parent_wake_irq = platform_get_irq(pdev, 1);
if (priv->parent_wake_irq < 0) {
priv->parent_wake_irq = 0;
- dev_warn(dev,
+ dev_warn(
+ dev,
"Couldn't get wake IRQ - GPIOs will not be able to wake from sleep");
} else {
/*
@@ -460,8 +471,8 @@ static int brcmstb_gpio_irq_setup(struct platform_device *pdev,
device_wakeup_enable(dev);
err = devm_request_irq(dev, priv->parent_wake_irq,
brcmstb_gpio_wake_irq_handler,
- IRQF_SHARED,
- "brcmstb-gpio-wake", priv);
+ IRQF_SHARED, "brcmstb-gpio-wake",
+ priv);
if (err < 0) {
dev_err(dev, "Couldn't request wake IRQ");
@@ -498,8 +509,9 @@ static void brcmstb_gpio_bank_save(struct brcmstb_gpio_priv *priv,
unsigned int i;
for (i = 0; i < GIO_REG_STAT; i++)
- bank->saved_regs[i] = gpio_generic_read_reg(&bank->chip,
- priv->reg_base + GIO_BANK_OFF(bank->id, i));
+ bank->saved_regs[i] = gpio_generic_read_reg(
+ &bank->chip,
+ priv->reg_base + GIO_BANK_OFF(bank->id, i));
}
static void brcmstb_gpio_quiesce(struct device *dev, bool save)
@@ -540,9 +552,9 @@ static void brcmstb_gpio_bank_restore(struct brcmstb_gpio_priv *priv,
unsigned int i;
for (i = 0; i < GIO_REG_STAT; i++)
- gpio_generic_write_reg(&bank->chip,
- priv->reg_base + GIO_BANK_OFF(bank->id, i),
- bank->saved_regs[i]);
+ gpio_generic_write_reg(
+ &bank->chip, priv->reg_base + GIO_BANK_OFF(bank->id, i),
+ bank->saved_regs[i]);
}
static int brcmstb_gpio_suspend(struct device *dev)
@@ -573,12 +585,12 @@ static int brcmstb_gpio_resume(struct device *dev)
}
#else
-#define brcmstb_gpio_suspend NULL
-#define brcmstb_gpio_resume NULL
+#define brcmstb_gpio_suspend NULL
+#define brcmstb_gpio_resume NULL
#endif /* CONFIG_PM_SLEEP */
static const struct dev_pm_ops brcmstb_gpio_pm_ops = {
- .suspend_noirq = brcmstb_gpio_suspend,
+ .suspend_noirq = brcmstb_gpio_suspend,
.resume_noirq = brcmstb_gpio_resume,
};
@@ -633,7 +645,7 @@ static int brcmstb_gpio_probe(struct platform_device *pdev)
flags = GPIO_GENERIC_BIG_ENDIAN_BYTE_ORDER;
#endif
if (of_property_read_bool(np, "brcm,gpio-direct"))
- flags |= BGPIOF_REG_DIRECT;
+ flags |= GPIO_GENERIC_REG_DIRECT;
of_property_for_each_u32(np, "brcm,gpio-bank-widths", bank_width) {
struct brcmstb_gpio_bank *bank;
@@ -674,7 +686,7 @@ static int brcmstb_gpio_probe(struct platform_device *pdev)
* and direction bits have 0 = output and 1 = input
*/
- config = (struct gpio_generic_chip_config) {
+ config = (struct gpio_generic_chip_config){
.dev = dev,
.sz = 4,
.dat = reg_base + GIO_DATA(bank->id),
@@ -684,14 +696,15 @@ static int brcmstb_gpio_probe(struct platform_device *pdev)
err = gpio_generic_chip_init(&bank->chip, &config);
if (err) {
- dev_err(dev, "failed to initialize generic GPIO chip\n");
+ dev_err(dev,
+ "failed to initialize generic GPIO chip\n");
goto fail;
}
gc->owner = THIS_MODULE;
gc->label = devm_kasprintf(dev, GFP_KERNEL, "gpio-brcmstb@%zx",
(size_t)res->start +
- GIO_BANK_OFF(bank->id, 0));
+ GIO_BANK_OFF(bank->id, 0));
if (!gc->label) {
err = -ENOMEM;
goto fail;
@@ -710,14 +723,17 @@ static int brcmstb_gpio_probe(struct platform_device *pdev)
* Mask all interrupts by default, since wakeup interrupts may
* be retained from S5 cold boot
*/
- need_wakeup_event |= !!__brcmstb_gpio_get_active_irqs(bank);
- gpio_generic_write_reg(&bank->chip,
- reg_base + GIO_MASK(bank->id), 0);
+ if (priv->parent_irq > 0) {
+ need_wakeup_event |=
+ !!__brcmstb_gpio_get_active_irqs(bank);
+ gpio_generic_write_reg(
+ &bank->chip, reg_base + GIO_MASK(bank->id), 0);
+ }
err = gpiochip_add_data(gc, bank);
if (err) {
dev_err(dev, "Could not add gpiochip for bank %d\n",
- bank->id);
+ bank->id);
goto fail;
}
num_gpios += gc->ngpio;
@@ -744,7 +760,7 @@ static int brcmstb_gpio_probe(struct platform_device *pdev)
return 0;
fail:
- (void) brcmstb_gpio_remove(pdev);
+ (void)brcmstb_gpio_remove(pdev);
return err;
}
diff --git a/drivers/gpio/gpio-mmio.c b/drivers/gpio/gpio-mmio.c
index 960ef1d4681e..9f6b7fcd4f3f 100644
--- a/drivers/gpio/gpio-mmio.c
+++ b/drivers/gpio/gpio-mmio.c
@@ -247,21 +247,22 @@ static int bgpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
static int bgpio_set_direct(struct gpio_chip *gc, unsigned int gpio, int val)
{
+ struct gpio_generic_chip *chip = to_gpio_generic_chip(gc);
unsigned long mask = bgpio_line2mask(gc, gpio);
unsigned long flags;
- raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
+ raw_spin_lock_irqsave(&chip->lock, flags);
- gc->bgpio_data = gc->read_reg(gc->reg_dat);
+ chip->sdata = chip->read_reg(chip->reg_dat);
if (val)
- gc->bgpio_data |= mask;
+ chip->sdata |= mask;
else
- gc->bgpio_data &= ~mask;
+ chip->sdata &= ~mask;
- gc->write_reg(gc->reg_dat, gc->bgpio_data);
+ chip->write_reg(chip->reg_dat, chip->sdata);
- raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
+ raw_spin_unlock_irqrestore(&chip->lock, flags);
return 0;
}
@@ -298,8 +299,8 @@ static int bgpio_set_set(struct gpio_chip *gc, unsigned int gpio, int val)
return 0;
}
-static void bgpio_multiple_get_masks(struct gpio_chip *gc,
- unsigned long *mask, unsigned long *bits,
+static void bgpio_multiple_get_masks(struct gpio_chip *gc, unsigned long *mask,
+ unsigned long *bits,
unsigned long *set_mask,
unsigned long *clear_mask)
{
@@ -338,7 +339,7 @@ static void bgpio_set_multiple_single_reg(struct gpio_chip *gc,
}
static int bgpio_set_multiple(struct gpio_chip *gc, unsigned long *mask,
- unsigned long *bits)
+ unsigned long *bits)
{
struct gpio_generic_chip *chip = to_gpio_generic_chip(gc);
@@ -374,29 +375,30 @@ static int bgpio_set_multiple_with_clear(struct gpio_chip *gc,
return 0;
}
-static int bgpio_set_multiple_direct(struct gpio_chip *gc,
- unsigned long *mask,
- unsigned long *bits)
+static int bgpio_set_multiple_direct(struct gpio_chip *gc, unsigned long *mask,
+ unsigned long *bits)
{
+ struct gpio_generic_chip *chip = to_gpio_generic_chip(gc);
unsigned long flags;
unsigned long set_mask, clear_mask;
- raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
+ raw_spin_lock_irqsave(&chip->lock, flags);
bgpio_multiple_get_masks(gc, mask, bits, &set_mask, &clear_mask);
- gc->bgpio_data = gc->read_reg(gc->reg_dat);
+ chip->sdata = chip->read_reg(chip->reg_dat);
- gc->bgpio_data |= set_mask;
- gc->bgpio_data &= ~clear_mask;
+ chip->sdata |= set_mask;
+ chip->sdata &= ~clear_mask;
- gc->write_reg(gc->reg_dat, gc->bgpio_data);
+ chip->write_reg(chip->reg_dat, chip->sdata);
- raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
+ raw_spin_unlock_irqrestore(&chip->lock, flags);
return 0;
}
-static int bgpio_dir_return(struct gpio_chip *gc, unsigned int gpio, bool dir_out)
+static int bgpio_dir_return(struct gpio_chip *gc, unsigned int gpio,
+ bool dir_out)
{
struct gpio_generic_chip *chip = to_gpio_generic_chip(gc);
@@ -419,8 +421,7 @@ static int bgpio_simple_dir_in(struct gpio_chip *gc, unsigned int gpio)
return bgpio_dir_return(gc, gpio, false);
}
-static int bgpio_dir_out_err(struct gpio_chip *gc, unsigned int gpio,
- int val)
+static int bgpio_dir_out_err(struct gpio_chip *gc, unsigned int gpio, int val)
{
return -EINVAL;
}
@@ -454,23 +455,24 @@ static int bgpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
static int bgpio_dir_in_direct(struct gpio_chip *gc, unsigned int gpio)
{
+ struct gpio_generic_chip *chip = to_gpio_generic_chip(gc);
unsigned long flags;
- raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
+ raw_spin_lock_irqsave(&chip->lock, flags);
- if (gc->reg_dir_in)
- gc->bgpio_dir = ~gc->read_reg(gc->reg_dir_in);
- if (gc->reg_dir_out)
- gc->bgpio_dir = gc->read_reg(gc->reg_dir_out);
+ if (chip->reg_dir_in)
+ chip->sdir = ~chip->read_reg(chip->reg_dir_in);
+ if (chip->reg_dir_out)
+ chip->sdir = chip->read_reg(chip->reg_dir_out);
- gc->bgpio_dir &= ~bgpio_line2mask(gc, gpio);
+ chip->sdir &= ~bgpio_line2mask(gc, gpio);
- if (gc->reg_dir_in)
- gc->write_reg(gc->reg_dir_in, ~gc->bgpio_dir);
- if (gc->reg_dir_out)
- gc->write_reg(gc->reg_dir_out, gc->bgpio_dir);
+ if (chip->reg_dir_in)
+ chip->write_reg(chip->reg_dir_in, ~chip->sdir);
+ if (chip->reg_dir_out)
+ chip->write_reg(chip->reg_dir_out, chip->sdir);
- raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
+ raw_spin_unlock_irqrestore(&chip->lock, flags);
return 0;
}
@@ -487,13 +489,15 @@ static int bgpio_get_dir(struct gpio_chip *gc, unsigned int gpio)
}
if (chip->reg_dir_out) {
- if (chip->read_reg(chip->reg_dir_out) & bgpio_line2mask(gc, gpio))
+ if (chip->read_reg(chip->reg_dir_out) &
+ bgpio_line2mask(gc, gpio))
return GPIO_LINE_DIRECTION_OUT;
return GPIO_LINE_DIRECTION_IN;
}
if (chip->reg_dir_in)
- if (!(chip->read_reg(chip->reg_dir_in) & bgpio_line2mask(gc, gpio)))
+ if (!(chip->read_reg(chip->reg_dir_in) &
+ bgpio_line2mask(gc, gpio)))
return GPIO_LINE_DIRECTION_OUT;
return GPIO_LINE_DIRECTION_IN;
@@ -519,23 +523,24 @@ static void bgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
static void bgpio_dir_out_direct(struct gpio_chip *gc, unsigned int gpio,
int val)
{
+ struct gpio_generic_chip *chip = to_gpio_generic_chip(gc);
unsigned long flags;
- raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
+ raw_spin_lock_irqsave(&chip->lock, flags);
- if (gc->reg_dir_in)
- gc->bgpio_dir = ~gc->read_reg(gc->reg_dir_in);
- if (gc->reg_dir_out)
- gc->bgpio_dir = gc->read_reg(gc->reg_dir_out);
+ if (chip->reg_dir_in)
+ chip->sdir = ~chip->read_reg(chip->reg_dir_in);
+ if (chip->reg_dir_out)
+ chip->sdir = chip->read_reg(chip->reg_dir_out);
- gc->bgpio_dir |= bgpio_line2mask(gc, gpio);
+ chip->sdir |= bgpio_line2mask(gc, gpio);
- if (gc->reg_dir_in)
- gc->write_reg(gc->reg_dir_in, ~gc->bgpio_dir);
- if (gc->reg_dir_out)
- gc->write_reg(gc->reg_dir_out, gc->bgpio_dir);
+ if (chip->reg_dir_in)
+ chip->write_reg(chip->reg_dir_in, ~chip->sdir);
+ if (chip->reg_dir_out)
+ chip->write_reg(chip->reg_dir_out, chip->sdir);
- raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
+ raw_spin_unlock_irqrestore(&chip->lock, flags);
}
static int bgpio_dir_out_dir_first(struct gpio_chip *gc, unsigned int gpio,
@@ -571,30 +576,29 @@ static int bgpio_dir_out_val_first_direct(struct gpio_chip *gc,
}
static int bgpio_setup_accessors(struct device *dev,
- struct gpio_generic_chip *chip,
- bool byte_be)
+ struct gpio_generic_chip *chip, bool byte_be)
{
switch (chip->bits) {
case 8:
- chip->read_reg = bgpio_read8;
- chip->write_reg = bgpio_write8;
+ chip->read_reg = bgpio_read8;
+ chip->write_reg = bgpio_write8;
break;
case 16:
if (byte_be) {
- chip->read_reg = bgpio_read16be;
- chip->write_reg = bgpio_write16be;
+ chip->read_reg = bgpio_read16be;
+ chip->write_reg = bgpio_write16be;
} else {
- chip->read_reg = bgpio_read16;
- chip->write_reg = bgpio_write16;
+ chip->read_reg = bgpio_read16;
+ chip->write_reg = bgpio_write16;
}
break;
case 32:
if (byte_be) {
- chip->read_reg = bgpio_read32be;
- chip->write_reg = bgpio_write32be;
+ chip->read_reg = bgpio_read32be;
+ chip->write_reg = bgpio_write32be;
} else {
- chip->read_reg = bgpio_read32;
- chip->write_reg = bgpio_write32;
+ chip->read_reg = bgpio_read32;
+ chip->write_reg = bgpio_write32;
}
break;
#if BITS_PER_LONG >= 64
@@ -604,8 +608,8 @@ static int bgpio_setup_accessors(struct device *dev,
"64 bit big endian byte order unsupported\n");
return -EINVAL;
} else {
- chip->read_reg = bgpio_read64;
- chip->write_reg = bgpio_write64;
+ chip->read_reg = bgpio_read64;
+ chip->write_reg = bgpio_write64;
}
break;
#endif /* BITS_PER_LONG >= 64 */
@@ -660,7 +664,7 @@ static int bgpio_setup_io(struct gpio_generic_chip *chip,
} else if (cfg->flags & GPIO_GENERIC_NO_OUTPUT) {
gc->set = bgpio_set_none;
gc->set_multiple = NULL;
- } else if (flags & BGPIOF_REG_DIRECT) {
+ } else if (cfg->flags & GPIO_GENERIC_REG_DIRECT) {
gc->set = bgpio_set_direct;
gc->set_multiple = bgpio_set_multiple_direct;
} else {
@@ -699,11 +703,21 @@ static int bgpio_setup_direction(struct gpio_generic_chip *chip,
if (cfg->dirout || cfg->dirin) {
chip->reg_dir_out = cfg->dirout;
chip->reg_dir_in = cfg->dirin;
- if (cfg->flags & GPIO_GENERIC_NO_SET_ON_INPUT)
- gc->direction_output = bgpio_dir_out_dir_first;
- else
- gc->direction_output = bgpio_dir_out_val_first;
- gc->direction_input = bgpio_dir_in;
+ if (cfg->flags & GPIO_GENERIC_REG_DIRECT) {
+ if (cfg->flags & GPIO_GENERIC_NO_SET_ON_INPUT)
+ gc->direction_output =
+ bgpio_dir_out_dir_first_direct;
+ else
+ gc->direction_output =
+ bgpio_dir_out_val_first_direct;
+ gc->direction_input = bgpio_dir_in_direct;
+ } else {
+ if (cfg->flags & GPIO_GENERIC_NO_SET_ON_INPUT)
+ gc->direction_output = bgpio_dir_out_dir_first;
+ else
+ gc->direction_output = bgpio_dir_out_val_first;
+ gc->direction_input = bgpio_dir_in;
+ }
gc->get_direction = bgpio_get_dir;
} else {
if (cfg->flags & GPIO_GENERIC_NO_OUTPUT)
@@ -787,7 +801,7 @@ int gpio_generic_chip_init(struct gpio_generic_chip *chip,
chip->sdata = chip->read_reg(chip->reg_dat);
if (gc->set == bgpio_set_set &&
- !(flags & GPIO_GENERIC_UNREADABLE_REG_SET))
+ !(flags & GPIO_GENERIC_UNREADABLE_REG_SET))
chip->sdata = chip->read_reg(chip->reg_set);
if (flags & GPIO_GENERIC_UNREADABLE_REG_DIR)
@@ -818,8 +832,7 @@ EXPORT_SYMBOL_GPL(gpio_generic_chip_init);
#if IS_ENABLED(CONFIG_GPIO_GENERIC_PLATFORM)
-static void __iomem *bgpio_map(struct platform_device *pdev,
- const char *name,
+static void __iomem *bgpio_map(struct platform_device *pdev, const char *name,
resource_size_t sane_sz)
{
struct resource *r;
@@ -841,7 +854,7 @@ static const struct of_device_id bgpio_of_match[] = {
{ .compatible = "wd,mbl-gpio" },
{ .compatible = "ni,169445-nand-gpio" },
{ .compatible = "intel,ixp4xx-expansion-bus-mmio-gpio" },
- { }
+ {}
};
MODULE_DEVICE_TABLE(of, bgpio_of_match);
@@ -898,7 +911,7 @@ static int bgpio_pdev_probe(struct platform_device *pdev)
if (device_property_read_bool(dev, "no-output"))
flags |= GPIO_GENERIC_NO_OUTPUT;
- config = (struct gpio_generic_chip_config) {
+ config = (struct gpio_generic_chip_config){
.dev = dev,
.sz = sz,
.dat = dat,
@@ -932,10 +945,10 @@ static int bgpio_pdev_probe(struct platform_device *pdev)
static const struct platform_device_id bgpio_id_table[] = {
{
- .name = "basic-mmio-gpio",
- .driver_data = 0,
+ .name = "basic-mmio-gpio",
+ .driver_data = 0,
},
- { }
+ {}
};
MODULE_DEVICE_TABLE(platform, bgpio_id_table);
diff --git a/drivers/pinctrl/pinctrl-rp1.c b/drivers/pinctrl/pinctrl-rp1.c
index ddc92e79b05b..08d435a6798d 100644
--- a/drivers/pinctrl/pinctrl-rp1.c
+++ b/drivers/pinctrl/pinctrl-rp1.c
@@ -37,116 +37,114 @@
#include "pinctrl-utils.h"
#define MODULE_NAME "pinctrl-rp1"
-#define RP1_NUM_GPIOS 54
-#define RP1_NUM_BANKS 3
+#define RP1_NUM_GPIOS 54
+#define RP1_NUM_BANKS 3
-#define RP1_RW_OFFSET 0x0000
-#define RP1_XOR_OFFSET 0x1000
-#define RP1_SET_OFFSET 0x2000
-#define RP1_CLR_OFFSET 0x3000
+#define RP1_RW_OFFSET 0x0000
+#define RP1_XOR_OFFSET 0x1000
+#define RP1_SET_OFFSET 0x2000
+#define RP1_CLR_OFFSET 0x3000
-#define RP1_GPIO_STATUS 0x0000
-#define RP1_GPIO_CTRL 0x0004
+#define RP1_GPIO_STATUS 0x0000
+#define RP1_GPIO_CTRL 0x0004
-#define RP1_GPIO_PCIE_INTE 0x011c
-#define RP1_GPIO_PCIE_INTS 0x0124
+#define RP1_GPIO_PCIE_INTE 0x011c
+#define RP1_GPIO_PCIE_INTS 0x0124
-#define RP1_GPIO_EVENTS_SHIFT_RAW 20
-#define RP1_GPIO_STATUS_FALLING BIT(20)
-#define RP1_GPIO_STATUS_RISING BIT(21)
-#define RP1_GPIO_STATUS_LOW BIT(22)
-#define RP1_GPIO_STATUS_HIGH BIT(23)
+#define RP1_GPIO_EVENTS_SHIFT_RAW 20
+#define RP1_GPIO_STATUS_FALLING BIT(20)
+#define RP1_GPIO_STATUS_RISING BIT(21)
+#define RP1_GPIO_STATUS_LOW BIT(22)
+#define RP1_GPIO_STATUS_HIGH BIT(23)
-#define RP1_GPIO_EVENTS_SHIFT_FILTERED 24
-#define RP1_GPIO_STATUS_F_FALLING BIT(24)
-#define RP1_GPIO_STATUS_F_RISING BIT(25)
-#define RP1_GPIO_STATUS_F_LOW BIT(26)
-#define RP1_GPIO_STATUS_F_HIGH BIT(27)
+#define RP1_GPIO_EVENTS_SHIFT_FILTERED 24
+#define RP1_GPIO_STATUS_F_FALLING BIT(24)
+#define RP1_GPIO_STATUS_F_RISING BIT(25)
+#define RP1_GPIO_STATUS_F_LOW BIT(26)
+#define RP1_GPIO_STATUS_F_HIGH BIT(27)
-#define RP1_GPIO_CTRL_FUNCSEL_LSB 0
-#define RP1_GPIO_CTRL_FUNCSEL_MASK 0x0000001f
-#define RP1_GPIO_CTRL_OUTOVER_LSB 12
-#define RP1_GPIO_CTRL_OUTOVER_MASK 0x00003000
-#define RP1_GPIO_CTRL_OEOVER_LSB 14
-#define RP1_GPIO_CTRL_OEOVER_MASK 0x0000c000
-#define RP1_GPIO_CTRL_INOVER_LSB 16
-#define RP1_GPIO_CTRL_INOVER_MASK 0x00030000
-#define RP1_GPIO_CTRL_IRQEN_FALLING BIT(20)
-#define RP1_GPIO_CTRL_IRQEN_RISING BIT(21)
-#define RP1_GPIO_CTRL_IRQEN_LOW BIT(22)
-#define RP1_GPIO_CTRL_IRQEN_HIGH BIT(23)
-#define RP1_GPIO_CTRL_IRQEN_F_FALLING BIT(24)
-#define RP1_GPIO_CTRL_IRQEN_F_RISING BIT(25)
-#define RP1_GPIO_CTRL_IRQEN_F_LOW BIT(26)
-#define RP1_GPIO_CTRL_IRQEN_F_HIGH BIT(27)
-#define RP1_GPIO_CTRL_IRQRESET BIT(28)
-#define RP1_GPIO_CTRL_IRQOVER_LSB 30
-#define RP1_GPIO_CTRL_IRQOVER_MASK 0xc0000000
+#define RP1_GPIO_CTRL_FUNCSEL_LSB 0
+#define RP1_GPIO_CTRL_FUNCSEL_MASK 0x0000001f
+#define RP1_GPIO_CTRL_OUTOVER_LSB 12
+#define RP1_GPIO_CTRL_OUTOVER_MASK 0x00003000
+#define RP1_GPIO_CTRL_OEOVER_LSB 14
+#define RP1_GPIO_CTRL_OEOVER_MASK 0x0000c000
+#define RP1_GPIO_CTRL_INOVER_LSB 16
+#define RP1_GPIO_CTRL_INOVER_MASK 0x00030000
+#define RP1_GPIO_CTRL_IRQEN_FALLING BIT(20)
+#define RP1_GPIO_CTRL_IRQEN_RISING BIT(21)
+#define RP1_GPIO_CTRL_IRQEN_LOW BIT(22)
+#define RP1_GPIO_CTRL_IRQEN_HIGH BIT(23)
+#define RP1_GPIO_CTRL_IRQEN_F_FALLING BIT(24)
+#define RP1_GPIO_CTRL_IRQEN_F_RISING BIT(25)
+#define RP1_GPIO_CTRL_IRQEN_F_LOW BIT(26)
+#define RP1_GPIO_CTRL_IRQEN_F_HIGH BIT(27)
+#define RP1_GPIO_CTRL_IRQRESET BIT(28)
+#define RP1_GPIO_CTRL_IRQOVER_LSB 30
+#define RP1_GPIO_CTRL_IRQOVER_MASK 0xc0000000
-#define RP1_INT_EDGE_FALLING BIT(0)
-#define RP1_INT_EDGE_RISING BIT(1)
-#define RP1_INT_LEVEL_LOW BIT(2)
-#define RP1_INT_LEVEL_HIGH BIT(3)
-#define RP1_INT_MASK 0xf
+#define RP1_INT_EDGE_FALLING BIT(0)
+#define RP1_INT_EDGE_RISING BIT(1)
+#define RP1_INT_LEVEL_LOW BIT(2)
+#define RP1_INT_LEVEL_HIGH BIT(3)
+#define RP1_INT_MASK 0xf
-#define RP1_INT_EDGE_BOTH (RP1_INT_EDGE_FALLING | \
- RP1_INT_EDGE_RISING)
-#define RP1_PUD_OFF 0
-#define RP1_PUD_DOWN 1
-#define RP1_PUD_UP 2
+#define RP1_INT_EDGE_BOTH (RP1_INT_EDGE_FALLING | RP1_INT_EDGE_RISING)
+#define RP1_PUD_OFF 0
+#define RP1_PUD_DOWN 1
+#define RP1_PUD_UP 2
-#define RP1_FSEL_COUNT 9
+#define RP1_FSEL_COUNT 9
-#define RP1_FSEL_ALT0 0x00
-#define RP1_FSEL_GPIO 0x05
-#define RP1_FSEL_NONE 0x09
-#define RP1_FSEL_NONE_HW 0x1f
+#define RP1_FSEL_ALT0 0x00
+#define RP1_FSEL_GPIO 0x05
+#define RP1_FSEL_NONE 0x09
+#define RP1_FSEL_NONE_HW 0x1f
-#define RP1_DIR_OUTPUT 0
-#define RP1_DIR_INPUT 1
+#define RP1_DIR_OUTPUT 0
+#define RP1_DIR_INPUT 1
-#define RP1_OUTOVER_PERI 0
-#define RP1_OUTOVER_INVPERI 1
-#define RP1_OUTOVER_LOW 2
-#define RP1_OUTOVER_HIGH 3
+#define RP1_OUTOVER_PERI 0
+#define RP1_OUTOVER_INVPERI 1
+#define RP1_OUTOVER_LOW 2
+#define RP1_OUTOVER_HIGH 3
-#define RP1_OEOVER_PERI 0
-#define RP1_OEOVER_INVPERI 1
-#define RP1_OEOVER_DISABLE 2
-#define RP1_OEOVER_ENABLE 3
+#define RP1_OEOVER_PERI 0
+#define RP1_OEOVER_INVPERI 1
+#define RP1_OEOVER_DISABLE 2
+#define RP1_OEOVER_ENABLE 3
-#define RP1_INOVER_PERI 0
-#define RP1_INOVER_INVPERI 1
-#define RP1_INOVER_LOW 2
-#define RP1_INOVER_HIGH 3
+#define RP1_INOVER_PERI 0
+#define RP1_INOVER_INVPERI 1
+#define RP1_INOVER_LOW 2
+#define RP1_INOVER_HIGH 3
-#define RP1_RIO_OUT 0x00
-#define RP1_RIO_OE 0x04
-#define RP1_RIO_IN 0x08
+#define RP1_RIO_OUT 0x00
+#define RP1_RIO_OE 0x04
+#define RP1_RIO_IN 0x08
-#define RP1_PAD_SLEWFAST_MASK 0x00000001
-#define RP1_PAD_SLEWFAST_LSB 0
-#define RP1_PAD_SCHMITT_MASK 0x00000002
-#define RP1_PAD_SCHMITT_LSB 1
-#define RP1_PAD_PULL_MASK 0x0000000c
-#define RP1_PAD_PULL_LSB 2
-#define RP1_PAD_DRIVE_MASK 0x00000030
-#define RP1_PAD_DRIVE_LSB 4
-#define RP1_PAD_IN_ENABLE_MASK 0x00000040
-#define RP1_PAD_IN_ENABLE_LSB 6
-#define RP1_PAD_OUT_DISABLE_MASK 0x00000080
-#define RP1_PAD_OUT_DISABLE_LSB 7
+#define RP1_PAD_SLEWFAST_MASK 0x00000001
+#define RP1_PAD_SLEWFAST_LSB 0
+#define RP1_PAD_SCHMITT_MASK 0x00000002
+#define RP1_PAD_SCHMITT_LSB 1
+#define RP1_PAD_PULL_MASK 0x0000000c
+#define RP1_PAD_PULL_LSB 2
+#define RP1_PAD_DRIVE_MASK 0x00000030
+#define RP1_PAD_DRIVE_LSB 4
+#define RP1_PAD_IN_ENABLE_MASK 0x00000040
+#define RP1_PAD_IN_ENABLE_LSB 6
+#define RP1_PAD_OUT_DISABLE_MASK 0x00000080
+#define RP1_PAD_OUT_DISABLE_LSB 7
-#define RP1_PAD_DRIVE_2MA 0x00000000
-#define RP1_PAD_DRIVE_4MA 0x00000010
-#define RP1_PAD_DRIVE_8MA 0x00000020
-#define RP1_PAD_DRIVE_12MA 0x00000030
+#define RP1_PAD_DRIVE_2MA 0x00000000
+#define RP1_PAD_DRIVE_4MA 0x00000010
+#define RP1_PAD_DRIVE_8MA 0x00000020
+#define RP1_PAD_DRIVE_12MA 0x00000030
-#define FLD_GET(r, f) (((r) & (f ## _MASK)) >> (f ## _LSB))
-#define FLD_SET(r, f, v) r = (((r) & ~(f ## _MASK)) | ((v) << (f ## _LSB)))
+#define FLD_GET(r, f) (((r) & (f##_MASK)) >> (f##_LSB))
+#define FLD_SET(r, f, v) r = (((r) & ~(f##_MASK)) | ((v) << (f##_LSB)))
-#define FUNC(f) \
- [func_##f] = #f
+#define FUNC(f) [func_##f] = #f
#define RP1_MAX_FSEL 8
#define PIN(i, f0, f1, f2, f3, f4, f5, f6, f7, f8) \
[i] = { \
@@ -163,16 +161,10 @@
}, \
}
-#define LEGACY_MAP(n, f0, f1, f2, f3, f4, f5) \
- [n] = { \
- func_gpio, \
- func_gpio, \
- func_##f5, \
- func_##f4, \
- func_##f0, \
- func_##f1, \
- func_##f2, \
- func_##f3, \
+#define LEGACY_MAP(n, f0, f1, f2, f3, f4, f5) \
+ [n] = { \
+ func_gpio, func_gpio, func_##f5, func_##f4, \
+ func_##f0, func_##f1, func_##f2, func_##f3, \
}
struct rp1_iobank_desc {
@@ -290,192 +282,64 @@ struct rp1_pinctrl {
const struct rp1_iobank_desc rp1_iobanks[RP1_NUM_BANKS] = {
/* gpio inte ints rio pads */
- { 0, 28, 0x0000, 0x011c, 0x0124, 0x0000, 0x0004 },
- { 28, 6, 0x4000, 0x411c, 0x4124, 0x4000, 0x4004 },
+ { 0, 28, 0x0000, 0x011c, 0x0124, 0x0000, 0x0004 },
+ { 28, 6, 0x4000, 0x411c, 0x4124, 0x4000, 0x4004 },
{ 34, 20, 0x8000, 0x811c, 0x8124, 0x8000, 0x8004 },
};
/* pins are just named GPIO0..GPIO53 */
#define RP1_GPIO_PIN(a) PINCTRL_PIN(a, "gpio" #a)
static struct pinctrl_pin_desc rp1_gpio_pins[] = {
- RP1_GPIO_PIN(0),
- RP1_GPIO_PIN(1),
- RP1_GPIO_PIN(2),
- RP1_GPIO_PIN(3),
- RP1_GPIO_PIN(4),
- RP1_GPIO_PIN(5),
- RP1_GPIO_PIN(6),
- RP1_GPIO_PIN(7),
- RP1_GPIO_PIN(8),
- RP1_GPIO_PIN(9),
- RP1_GPIO_PIN(10),
- RP1_GPIO_PIN(11),
- RP1_GPIO_PIN(12),
- RP1_GPIO_PIN(13),
- RP1_GPIO_PIN(14),
- RP1_GPIO_PIN(15),
- RP1_GPIO_PIN(16),
- RP1_GPIO_PIN(17),
- RP1_GPIO_PIN(18),
- RP1_GPIO_PIN(19),
- RP1_GPIO_PIN(20),
- RP1_GPIO_PIN(21),
- RP1_GPIO_PIN(22),
- RP1_GPIO_PIN(23),
- RP1_GPIO_PIN(24),
- RP1_GPIO_PIN(25),
- RP1_GPIO_PIN(26),
- RP1_GPIO_PIN(27),
- RP1_GPIO_PIN(28),
- RP1_GPIO_PIN(29),
- RP1_GPIO_PIN(30),
- RP1_GPIO_PIN(31),
- RP1_GPIO_PIN(32),
- RP1_GPIO_PIN(33),
- RP1_GPIO_PIN(34),
- RP1_GPIO_PIN(35),
- RP1_GPIO_PIN(36),
- RP1_GPIO_PIN(37),
- RP1_GPIO_PIN(38),
- RP1_GPIO_PIN(39),
- RP1_GPIO_PIN(40),
- RP1_GPIO_PIN(41),
- RP1_GPIO_PIN(42),
- RP1_GPIO_PIN(43),
- RP1_GPIO_PIN(44),
- RP1_GPIO_PIN(45),
- RP1_GPIO_PIN(46),
- RP1_GPIO_PIN(47),
- RP1_GPIO_PIN(48),
- RP1_GPIO_PIN(49),
- RP1_GPIO_PIN(50),
- RP1_GPIO_PIN(51),
- RP1_GPIO_PIN(52),
- RP1_GPIO_PIN(53),
+ RP1_GPIO_PIN(0), RP1_GPIO_PIN(1), RP1_GPIO_PIN(2), RP1_GPIO_PIN(3),
+ RP1_GPIO_PIN(4), RP1_GPIO_PIN(5), RP1_GPIO_PIN(6), RP1_GPIO_PIN(7),
+ RP1_GPIO_PIN(8), RP1_GPIO_PIN(9), RP1_GPIO_PIN(10), RP1_GPIO_PIN(11),
+ RP1_GPIO_PIN(12), RP1_GPIO_PIN(13), RP1_GPIO_PIN(14), RP1_GPIO_PIN(15),
+ RP1_GPIO_PIN(16), RP1_GPIO_PIN(17), RP1_GPIO_PIN(18), RP1_GPIO_PIN(19),
+ RP1_GPIO_PIN(20), RP1_GPIO_PIN(21), RP1_GPIO_PIN(22), RP1_GPIO_PIN(23),
+ RP1_GPIO_PIN(24), RP1_GPIO_PIN(25), RP1_GPIO_PIN(26), RP1_GPIO_PIN(27),
+ RP1_GPIO_PIN(28), RP1_GPIO_PIN(29), RP1_GPIO_PIN(30), RP1_GPIO_PIN(31),
+ RP1_GPIO_PIN(32), RP1_GPIO_PIN(33), RP1_GPIO_PIN(34), RP1_GPIO_PIN(35),
+ RP1_GPIO_PIN(36), RP1_GPIO_PIN(37), RP1_GPIO_PIN(38), RP1_GPIO_PIN(39),
+ RP1_GPIO_PIN(40), RP1_GPIO_PIN(41), RP1_GPIO_PIN(42), RP1_GPIO_PIN(43),
+ RP1_GPIO_PIN(44), RP1_GPIO_PIN(45), RP1_GPIO_PIN(46), RP1_GPIO_PIN(47),
+ RP1_GPIO_PIN(48), RP1_GPIO_PIN(49), RP1_GPIO_PIN(50), RP1_GPIO_PIN(51),
+ RP1_GPIO_PIN(52), RP1_GPIO_PIN(53),
};
/* one pin per group */
-static const char * const rp1_gpio_groups[] = {
- "gpio0",
- "gpio1",
- "gpio2",
- "gpio3",
- "gpio4",
- "gpio5",
- "gpio6",
- "gpio7",
- "gpio8",
- "gpio9",
- "gpio10",
- "gpio11",
- "gpio12",
- "gpio13",
- "gpio14",
- "gpio15",
- "gpio16",
- "gpio17",
- "gpio18",
- "gpio19",
- "gpio20",
- "gpio21",
- "gpio22",
- "gpio23",
- "gpio24",
- "gpio25",
- "gpio26",
- "gpio27",
- "gpio28",
- "gpio29",
- "gpio30",
- "gpio31",
- "gpio32",
- "gpio33",
- "gpio34",
- "gpio35",
- "gpio36",
- "gpio37",
- "gpio38",
- "gpio39",
- "gpio40",
- "gpio41",
- "gpio42",
- "gpio43",
- "gpio44",
- "gpio45",
- "gpio46",
- "gpio47",
- "gpio48",
- "gpio49",
- "gpio50",
- "gpio51",
- "gpio52",
- "gpio53",
+static const char *const rp1_gpio_groups[] = {
+ "gpio0", "gpio1", "gpio2", "gpio3", "gpio4", "gpio5", "gpio6",
+ "gpio7", "gpio8", "gpio9", "gpio10", "gpio11", "gpio12", "gpio13",
+ "gpio14", "gpio15", "gpio16", "gpio17", "gpio18", "gpio19", "gpio20",
+ "gpio21", "gpio22", "gpio23", "gpio24", "gpio25", "gpio26", "gpio27",
+ "gpio28", "gpio29", "gpio30", "gpio31", "gpio32", "gpio33", "gpio34",
+ "gpio35", "gpio36", "gpio37", "gpio38", "gpio39", "gpio40", "gpio41",
+ "gpio42", "gpio43", "gpio44", "gpio45", "gpio46", "gpio47", "gpio48",
+ "gpio49", "gpio50", "gpio51", "gpio52", "gpio53",
};
-static const char * const rp1_func_names[] = {
- FUNC(alt0),
- FUNC(alt1),
- FUNC(alt2),
- FUNC(alt3),
- FUNC(alt4),
- FUNC(gpio),
- FUNC(alt6),
- FUNC(alt7),
- FUNC(alt8),
- FUNC(none),
- FUNC(aaud),
- FUNC(dcd0),
- FUNC(dpi),
- FUNC(dsi0_te_ext),
- FUNC(dsi1_te_ext),
- FUNC(dsr0),
- FUNC(dtr0),
- FUNC(gpclk0),
- FUNC(gpclk1),
- FUNC(gpclk2),
- FUNC(gpclk3),
- FUNC(gpclk4),
- FUNC(gpclk5),
- FUNC(i2c0),
- FUNC(i2c1),
- FUNC(i2c2),
- FUNC(i2c3),
- FUNC(i2c4),
- FUNC(i2c5),
- FUNC(i2c6),
- FUNC(i2s0),
- FUNC(i2s1),
- FUNC(i2s2),
- FUNC(ir),
- FUNC(mic),
- FUNC(pcie_clkreq_n),
- FUNC(pio),
- FUNC(proc_rio),
- FUNC(pwm0),
- FUNC(pwm1),
- FUNC(ri0),
- FUNC(sd0),
- FUNC(sd1),
- FUNC(spi0),
- FUNC(spi1),
- FUNC(spi2),
- FUNC(spi3),
- FUNC(spi4),
- FUNC(spi5),
- FUNC(spi6),
- FUNC(spi7),
- FUNC(spi8),
- FUNC(uart0),
- FUNC(uart1),
- FUNC(uart2),
- FUNC(uart3),
- FUNC(uart4),
- FUNC(uart5),
- FUNC(vbus0),
- FUNC(vbus1),
- FUNC(vbus2),
- FUNC(vbus3),
- [func_invalid] = "?"
+static const char *const rp1_func_names[] = {
+ FUNC(alt0), FUNC(alt1), FUNC(alt2),
+ FUNC(alt3), FUNC(alt4), FUNC(gpio),
+ FUNC(alt6), FUNC(alt7), FUNC(alt8),
+ FUNC(none), FUNC(aaud), FUNC(dcd0),
+ FUNC(dpi), FUNC(dsi0_te_ext), FUNC(dsi1_te_ext),
+ FUNC(dsr0), FUNC(dtr0), FUNC(gpclk0),
+ FUNC(gpclk1), FUNC(gpclk2), FUNC(gpclk3),
+ FUNC(gpclk4), FUNC(gpclk5), FUNC(i2c0),
+ FUNC(i2c1), FUNC(i2c2), FUNC(i2c3),
+ FUNC(i2c4), FUNC(i2c5), FUNC(i2c6),
+ FUNC(i2s0), FUNC(i2s1), FUNC(i2s2),
+ FUNC(ir), FUNC(mic), FUNC(pcie_clkreq_n),
+ FUNC(pio), FUNC(proc_rio), FUNC(pwm0),
+ FUNC(pwm1), FUNC(ri0), FUNC(sd0),
+ FUNC(sd1), FUNC(spi0), FUNC(spi1),
+ FUNC(spi2), FUNC(spi3), FUNC(spi4),
+ FUNC(spi5), FUNC(spi6), FUNC(spi7),
+ FUNC(spi8), FUNC(uart0), FUNC(uart1),
+ FUNC(uart2), FUNC(uart3), FUNC(uart4),
+ FUNC(uart5), FUNC(vbus0), FUNC(vbus1),
+ FUNC(vbus2), FUNC(vbus3), [func_invalid] = "?"
};
static const struct rp1_pin_funcs rp1_gpio_pin_funcs[] = {
@@ -566,7 +430,7 @@ static const u8 legacy_fsel_map[][8] = {
LEGACY_MAP(27, sd0, _, dpi, _, _, _),
};
-static const char * const irq_type_names[] = {
+static const char *const irq_type_names[] = {
[IRQ_TYPE_NONE] = "none",
[IRQ_TYPE_EDGE_RISING] = "edge-rising",
[IRQ_TYPE_EDGE_FALLING] = "edge-falling",
@@ -577,13 +441,17 @@ static const char * const irq_type_names[] = {
static bool persist_gpio_outputs = true;
module_param(persist_gpio_outputs, bool, 0644);
-MODULE_PARM_DESC(persist_gpio_outputs, "Enable GPIO_OUT persistence when pin is freed");
+MODULE_PARM_DESC(persist_gpio_outputs,
+ "Enable GPIO_OUT persistence when pin is freed");
static bool pace_pin_updates = true;
module_param(pace_pin_updates, bool, 0644);
-MODULE_PARM_DESC(pace_pin_updates, "Update pin states with guaranteed monotonicity if PCIe ASPM is enabled");
+MODULE_PARM_DESC(
+ pace_pin_updates,
+ "Update pin states with guaranteed monotonicity if PCIe ASPM is enabled");
-static inline void rp1_pin_writel(u32 val, void __iomem *dummy, void __iomem *reg)
+static inline void rp1_pin_writel(u32 val, void __iomem *dummy,
+ void __iomem *reg)
{
unsigned long flags;
@@ -615,9 +483,8 @@ static inline u32 rp1_pin_readl(const void __iomem *ioaddr)
return readl(ioaddr);
}
-static int rp1_pinconf_set(struct pinctrl_dev *pctldev,
- unsigned int offset, unsigned long *configs,
- unsigned int num_configs);
+static int rp1_pinconf_set(struct pinctrl_dev *pctldev, unsigned int offset,
+ unsigned long *configs, unsigned int num_configs);
static struct rp1_pin_info *rp1_get_pin(struct gpio_chip *chip,
unsigned int offset)
@@ -696,14 +563,16 @@ static void rp1_set_fsel(struct rp1_pin_info *pin, u32 fsel)
static int rp1_get_dir(struct rp1_pin_info *pin)
{
return !(rp1_pin_readl(pin->rio + RP1_RIO_OE) & (1 << pin->offset)) ?
- RP1_DIR_INPUT : RP1_DIR_OUTPUT;
+ RP1_DIR_INPUT :
+ RP1_DIR_OUTPUT;
}
static void rp1_set_dir(struct rp1_pin_info *pin, bool is_input)
{
int offset = is_input ? RP1_CLR_OFFSET : RP1_SET_OFFSET;
- rp1_pin_writel(1 << pin->offset, pin->dummy, pin->rio + RP1_RIO_OE + offset);
+ rp1_pin_writel(1 << pin->offset, pin->dummy,
+ pin->rio + RP1_RIO_OE + offset);
}
static int rp1_get_value(struct rp1_pin_info *pin)
@@ -715,7 +584,8 @@ static void rp1_set_value(struct rp1_pin_info *pin, int value)
{
/* Assume the pin is already an output */
rp1_pin_writel(1 << pin->offset, pin->dummy,
- pin->rio + RP1_RIO_OUT + (value ? RP1_SET_OFFSET : RP1_CLR_OFFSET));
+ pin->rio + RP1_RIO_OUT +
+ (value ? RP1_SET_OFFSET : RP1_CLR_OFFSET));
}
static int rp1_gpio_get(struct gpio_chip *chip, unsigned offset)
@@ -749,9 +619,8 @@ static int rp1_gpio_get_direction(struct gpio_chip *chip, unsigned int offset)
fsel = rp1_get_fsel(pin);
if (fsel != RP1_FSEL_GPIO)
return -EINVAL;
- return (rp1_get_dir(pin) == RP1_DIR_OUTPUT) ?
- GPIO_LINE_DIRECTION_OUT :
- GPIO_LINE_DIRECTION_IN;
+ return (rp1_get_dir(pin) == RP1_DIR_OUTPUT) ? GPIO_LINE_DIRECTION_OUT :
+ GPIO_LINE_DIRECTION_IN;
}
static int rp1_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
@@ -785,7 +654,7 @@ static int rp1_gpio_set_config(struct gpio_chip *gc, unsigned offset,
unsigned long configs[] = { config };
return rp1_pinconf_set(pc->pctl_dev, offset, configs,
- ARRAY_SIZE(configs));
+ ARRAY_SIZE(configs));
}
static const struct gpio_chip rp1_gpio_chip = {
@@ -825,12 +694,13 @@ static void rp1_gpio_irq_handler(struct irq_desc *desc)
ints = readl(pc->gpio_base + bank->ints_offset);
for_each_set_bit(b, &ints, 32) {
- struct rp1_pin_info *pin = rp1_get_pin(chip, bank->min_gpio + b);
+ struct rp1_pin_info *pin =
+ rp1_get_pin(chip, bank->min_gpio + b);
writel(RP1_GPIO_CTRL_IRQRESET,
pin->gpio + RP1_SET_OFFSET + RP1_GPIO_CTRL);
generic_handle_irq(irq_find_mapping(pc->gpio_chip.irq.domain,
- bank->min_gpio + b));
+ bank->min_gpio + b));
}
chained_irq_exit(host_chip, desc);
@@ -897,7 +767,7 @@ static int rp1_irq_set_type(struct rp1_pin_info *pin, unsigned int type)
pin->gpio + RP1_CLR_OFFSET + RP1_GPIO_CTRL);
/* Clear any latched events */
writel(RP1_GPIO_CTRL_IRQRESET,
- pin->gpio + RP1_SET_OFFSET + RP1_GPIO_CTRL);
+ pin->gpio + RP1_SET_OFFSET + RP1_GPIO_CTRL);
/* Enable the events that are needed */
writel(irq_flags << RP1_GPIO_EVENTS_SHIFT_RAW,
pin->gpio + RP1_SET_OFFSET + RP1_GPIO_CTRL);
@@ -938,10 +808,12 @@ static void rp1_gpio_irq_ack(struct irq_data *data)
struct rp1_pin_info *pin = rp1_get_pin(chip, gpio);
/* Clear any latched events */
- writel(RP1_GPIO_CTRL_IRQRESET, pin->gpio + RP1_SET_OFFSET + RP1_GPIO_CTRL);
+ writel(RP1_GPIO_CTRL_IRQRESET,
+ pin->gpio + RP1_SET_OFFSET + RP1_GPIO_CTRL);
}
-static int rp1_gpio_irq_set_affinity(struct irq_data *data, const struct cpumask *dest, bool force)
+static int rp1_gpio_irq_set_affinity(struct irq_data *data,
+ const struct cpumask *dest, bool force)
{
struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
struct rp1_pinctrl *pc = gpiochip_get_data(chip);
@@ -959,7 +831,8 @@ static int rp1_gpio_irq_set_affinity(struct irq_data *data, const struct cpumask
}
if (parent_data && parent_data->chip->irq_set_affinity)
- return parent_data->chip->irq_set_affinity(parent_data, dest, force);
+ return parent_data->chip->irq_set_affinity(parent_data, dest,
+ force);
return -EINVAL;
}
@@ -999,8 +872,7 @@ static enum funcs rp1_get_fsel_func(unsigned pin, unsigned fsel)
}
static int rp1_pctl_get_group_pins(struct pinctrl_dev *pctldev,
- unsigned selector,
- const unsigned **pins,
+ unsigned selector, const unsigned **pins,
unsigned *num_pins)
{
*pins = &rp1_gpio_pins[selector].number;
@@ -1010,8 +882,7 @@ static int rp1_pctl_get_group_pins(struct pinctrl_dev *pctldev,
}
static void rp1_pctl_pin_dbg_show(struct pinctrl_dev *pctldev,
- struct seq_file *s,
- unsigned offset)
+ struct seq_file *s, unsigned offset)
{
struct rp1_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
struct gpio_chip *chip = &pc->gpio_chip;
@@ -1023,8 +894,7 @@ static void rp1_pctl_pin_dbg_show(struct pinctrl_dev *pctldev,
seq_printf(s, "function %s (%s) in %s; irq %d (%s)",
rp1_func_names[fsel], rp1_func_names[func],
- value ? "hi" : "lo",
- irq, irq_type_names[pin->irq_type]);
+ value ? "hi" : "lo", irq, irq_type_names[pin->irq_type]);
}
static void rp1_pctl_dt_free_map(struct pinctrl_dev *pctldev,
@@ -1057,14 +927,14 @@ static int rp1_pctl_legacy_map_func(struct rp1_pinctrl *pc,
} else if (fnum < 2) {
func = func_gpio;
} else {
- dev_err(pc->dev, "%pOF: invalid brcm,pins value %d\n",
- np, pin);
+ dev_err(pc->dev, "%pOF: invalid brcm,pins value %d\n", np, pin);
return -EINVAL;
}
if (func == func_invalid) {
- dev_err(pc->dev, "%pOF: brcm,function %d not supported on pin %d\n",
- np, fnum, pin);
+ dev_err(pc->dev,
+ "%pOF: brcm,function %d not supported on pin %d\n", np,
+ fnum, pin);
}
map->type = PIN_MAP_TYPE_MUX_GROUP;
@@ -1133,7 +1003,8 @@ static int rp1_pctl_dt_node_to_map(struct pinctrl_dev *pctldev,
pins = of_find_property(np, "brcm,pins", NULL);
if (!pins) /* Assume generic bindings in this node */
- return pinconf_generic_dt_node_to_map_all(pctldev, np, map, num_maps);
+ return pinconf_generic_dt_node_to_map_all(pctldev, np, map,
+ num_maps);
funcs = of_find_property(np, "brcm,function", NULL);
if (!funcs)
@@ -1141,7 +1012,8 @@ static int rp1_pctl_dt_node_to_map(struct pinctrl_dev *pctldev,
pulls = of_find_property(np, "brcm,pull", NULL);
if (!pulls)
- pinconf_generic_parse_dt_config(np, pctldev, &configs, &num_configs);
+ pinconf_generic_parse_dt_config(np, pctldev, &configs,
+ &num_configs);
if (!function && !funcs && !num_configs && !pulls) {
dev_err(pc->dev,
@@ -1156,14 +1028,13 @@ static int rp1_pctl_dt_node_to_map(struct pinctrl_dev *pctldev,
if (num_funcs > 1 && num_funcs != num_pins) {
dev_err(pc->dev,
- "%pOF: brcm,function must have 1 or %d entries\n",
- np, num_pins);
+ "%pOF: brcm,function must have 1 or %d entries\n", np,
+ num_pins);
return -EINVAL;
}
if (num_pulls > 1 && num_pulls != num_pins) {
- dev_err(pc->dev,
- "%pOF: brcm,pull must have 1 or %d entries\n",
+ dev_err(pc->dev, "%pOF: brcm,pull must have 1 or %d entries\n",
np, num_pins);
return -EINVAL;
}
@@ -1185,37 +1056,35 @@ static int rp1_pctl_dt_node_to_map(struct pinctrl_dev *pctldev,
if (err)
goto out;
if (num_funcs) {
- err = of_property_read_u32_index(np, "brcm,function",
- (num_funcs > 1) ? i : 0,
- &func);
+ err = of_property_read_u32_index(
+ np, "brcm,function", (num_funcs > 1) ? i : 0,
+ &func);
if (err)
goto out;
- err = rp1_pctl_legacy_map_func(pc, np, pin, func,
- maps, num_maps);
+ err = rp1_pctl_legacy_map_func(pc, np, pin, func, maps,
+ num_maps);
} else if (function) {
- err = pinctrl_utils_add_map_mux(pctldev, &maps,
- &reserved_maps, num_maps,
- rp1_gpio_groups[pin],
- function);
+ err = pinctrl_utils_add_map_mux(
+ pctldev, &maps, &reserved_maps, num_maps,
+ rp1_gpio_groups[pin], function);
}
if (err)
goto out;
if (num_pulls) {
- err = of_property_read_u32_index(np, "brcm,pull",
- (num_pulls > 1) ? i : 0,
- &pull);
+ err = of_property_read_u32_index(
+ np, "brcm,pull", (num_pulls > 1) ? i : 0,
+ &pull);
if (err)
goto out;
- err = rp1_pctl_legacy_map_pull(pc, np, pin, pull,
- maps, num_maps);
+ err = rp1_pctl_legacy_map_pull(pc, np, pin, pull, maps,
+ num_maps);
} else if (num_configs) {
- err = pinctrl_utils_add_map_configs(pctldev, &maps,
- &reserved_maps, num_maps,
- rp1_gpio_groups[pin],
- configs, num_configs,
- PIN_MAP_TYPE_CONFIGS_PIN);
+ err = pinctrl_utils_add_map_configs(
+ pctldev, &maps, &reserved_maps, num_maps,
+ rp1_gpio_groups[pin], configs, num_configs,
+ PIN_MAP_TYPE_CONFIGS_PIN);
}
if (err)
@@ -1268,8 +1137,8 @@ static const char *rp1_pmx_get_function_name(struct pinctrl_dev *pctldev,
static int rp1_pmx_get_function_groups(struct pinctrl_dev *pctldev,
unsigned selector,
- const char * const **groups,
- unsigned * const num_groups)
+ const char *const **groups,
+ unsigned *const num_groups)
{
/* every pin can do every function */
*groups = rp1_gpio_groups;
@@ -1315,8 +1184,7 @@ static void rp1_pmx_gpio_disable_free(struct pinctrl_dev *pctldev,
static int rp1_pmx_gpio_set_direction(struct pinctrl_dev *pctldev,
struct pinctrl_gpio_range *range,
- unsigned offset,
- bool input)
+ unsigned offset, bool input)
{
struct rp1_pin_info *pin = rp1_get_pin_pctl(pctldev, offset);
@@ -1470,14 +1338,17 @@ static int rp1_pinconf_get(struct pinctrl_dev *pctldev, unsigned offset,
}
break;
case PIN_CONFIG_BIAS_DISABLE:
- arg = ((padctrl & RP1_PAD_PULL_MASK) == (RP1_PUD_OFF << RP1_PAD_PULL_LSB));
+ arg = ((padctrl & RP1_PAD_PULL_MASK) ==
+ (RP1_PUD_OFF << RP1_PAD_PULL_LSB));
break;
case PIN_CONFIG_BIAS_PULL_DOWN:
- arg = ((padctrl & RP1_PAD_PULL_MASK) == (RP1_PUD_DOWN << RP1_PAD_PULL_LSB));
+ arg = ((padctrl & RP1_PAD_PULL_MASK) ==
+ (RP1_PUD_DOWN << RP1_PAD_PULL_LSB));
break;
case PIN_CONFIG_BIAS_PULL_UP:
- arg = ((padctrl & RP1_PAD_PULL_MASK) == (RP1_PUD_UP << RP1_PAD_PULL_LSB));
+ arg = ((padctrl & RP1_PAD_PULL_MASK) ==
+ (RP1_PUD_UP << RP1_PAD_PULL_LSB));
break;
default:
return -ENOTSUPP;
@@ -1514,100 +1385,7 @@ static const struct of_device_id rp1_pinctrl_match[] = {
.compatible = "raspberrypi,rp1-gpio",
.data = &rp1_pinconf_ops,
},
- {},
-};
-MODULE_DEVICE_TABLE(of, rp1_pinctrl_match);
-
-static struct rp1_pinctrl rp1_pinctrl_data = {};
-
-static const struct regmap_range rp1_gpio_reg_ranges[] = {
- /* BANK 0 */
- regmap_reg_range(0x2004, 0x20dc),
- regmap_reg_range(0x3004, 0x30dc),
- regmap_reg_range(0x0004, 0x00dc),
- regmap_reg_range(0x0124, 0x0124),
- regmap_reg_range(0x211c, 0x211c),
- regmap_reg_range(0x311c, 0x311c),
- /* BANK 1 */
- regmap_reg_range(0x6004, 0x602c),
- regmap_reg_range(0x7004, 0x702c),
- regmap_reg_range(0x4004, 0x402c),
- regmap_reg_range(0x4124, 0x4124),
- regmap_reg_range(0x611c, 0x611c),
- regmap_reg_range(0x711c, 0x711c),
- /* BANK 2 */
- regmap_reg_range(0xa004, 0xa09c),
- regmap_reg_range(0xb004, 0xb09c),
- regmap_reg_range(0x8004, 0x809c),
- regmap_reg_range(0x8124, 0x8124),
- regmap_reg_range(0xa11c, 0xa11c),
- regmap_reg_range(0xb11c, 0xb11c),
-};
-
-static const struct regmap_range rp1_rio_reg_ranges[] = {
- /* BANK 0 */
- regmap_reg_range(0x2000, 0x2004),
- regmap_reg_range(0x3000, 0x3004),
- regmap_reg_range(0x0004, 0x0008),
- /* BANK 1 */
- regmap_reg_range(0x6000, 0x6004),
- regmap_reg_range(0x7000, 0x7004),
- regmap_reg_range(0x4004, 0x4008),
- /* BANK 2 */
- regmap_reg_range(0xa000, 0xa004),
- regmap_reg_range(0xb000, 0xb004),
- regmap_reg_range(0x8004, 0x8008),
-};
-
-static const struct regmap_range rp1_pads_reg_ranges[] = {
- /* BANK 0 */
- regmap_reg_range(0x0004, 0x0070),
- /* BANK 1 */
- regmap_reg_range(0x4004, 0x4018),
- /* BANK 2 */
- regmap_reg_range(0x8004, 0x8050),
-};
-
-static const struct regmap_access_table rp1_gpio_reg_table = {
- .yes_ranges = rp1_gpio_reg_ranges,
- .n_yes_ranges = ARRAY_SIZE(rp1_gpio_reg_ranges),
-};
-
-static const struct regmap_access_table rp1_rio_reg_table = {
- .yes_ranges = rp1_rio_reg_ranges,
- .n_yes_ranges = ARRAY_SIZE(rp1_rio_reg_ranges),
-};
-
-static const struct regmap_access_table rp1_pads_reg_table = {
- .yes_ranges = rp1_pads_reg_ranges,
- .n_yes_ranges = ARRAY_SIZE(rp1_pads_reg_ranges),
-};
-
-static const struct regmap_config rp1_pinctrl_gpio_regmap_cfg = {
- .reg_bits = 32,
- .val_bits = 32,
- .reg_stride = 4,
- .rd_table = &rp1_gpio_reg_table,
- .name = "rp1-gpio",
- .max_register = 0xb11c,
-};
-
-static const struct regmap_config rp1_pinctrl_rio_regmap_cfg = {
- .reg_bits = 32,
- .val_bits = 32,
- .reg_stride = 4,
- .rd_table = &rp1_rio_reg_table,
- .name = "rp1-rio",
- .max_register = 0xb004,
-};
-
-static const struct regmap_config rp1_pinctrl_pads_regmap_cfg = {
- .reg_bits = 32,
- .val_bits = 32,
- .reg_stride = 4,
- .rd_table = &rp1_pads_reg_table,
- .name = "rp1-pads",
- .max_register = 0x8050,
+ {}
};
static inline void __iomem *devm_auto_iomap(struct platform_device *pdev,
@@ -1662,32 +1440,42 @@ static int rp1_pinctrl_probe(struct platform_device *pdev)
pc->gpio_chip = rp1_gpio_chip;
pc->gpio_chip.parent = dev;
- pc->gpio_base = devm_platform_ioremap_resource(pdev, 0);
- if (IS_ERR(pc->gpio_base))
- return dev_err_probe(dev, PTR_ERR(pc->gpio_base), "could not get GPIO IO memory\n");
-
- pc->rio_base = devm_platform_ioremap_resource(pdev, 1);
- if (IS_ERR(pc->rio_base))
- return dev_err_probe(dev, PTR_ERR(pc->rio_base), "could not get RIO IO memory\n");
-
- pc->pads_base = devm_platform_ioremap_resource(pdev, 2);
- if (IS_ERR(pc->pads_base))
- return dev_err_probe(dev, PTR_ERR(pc->pads_base), "could not get PADS IO memory\n");
-
- gpio_regmap = devm_regmap_init_mmio(dev, pc->gpio_base,
- &rp1_pinctrl_gpio_regmap_cfg);
- if (IS_ERR(gpio_regmap))
- return dev_err_probe(dev, PTR_ERR(gpio_regmap), "could not init GPIO regmap\n");
-
- rio_regmap = devm_regmap_init_mmio(dev, pc->rio_base,
- &rp1_pinctrl_rio_regmap_cfg);
- if (IS_ERR(rio_regmap))
- return dev_err_probe(dev, PTR_ERR(rio_regmap), "could not init RIO regmap\n");
-
- pads_regmap = devm_regmap_init_mmio(dev, pc->pads_base,
- &rp1_pinctrl_pads_regmap_cfg);
- if (IS_ERR(pads_regmap))
- return dev_err_probe(dev, PTR_ERR(pads_regmap), "could not init PADS regmap\n");
+ /*
+ * Workaround for the vagaries of PCIe on BCM2712
+ *
+ * If the link to RP1 is in L1, then the BRCMSTB RC will buffer many
+ * outbound writes - and generate write responses for them, despite the
+ * fact that the link is not yet active. This has the effect of compressing
+ * multiple writes to GPIOs together, destroying any pacing that an application
+ * may require in the 1-10us range.
+ *
+ * The RC Slot Control configuration register is special. It emits a
+ * MsgD for every write to it, will stall further writes until the message
+ * goes out on the wire. This can be (ab)used to force CPU stalls when the
+ * link is inactive, at the cost of a small amount of downstream bandwidth
+ * and some 200ns of added latency for each write.
+ *
+ * Several back-to-back configuration writes are necessary to "fill the pipe",
+ * otherwise the outbound MAC can consume a pending MMIO write and reorder
+ * it with respect to the config writes - undoing the intent.
+ *
+ * of_iomap() is used directly here as the address overlaps with the RC driver's
+ * usage.
+ */
+ rp1_node = of_find_node_by_name(NULL, "rp1");
+ if (!rp1_node)
+ dev_err(&pdev->dev, "failed to find RP1 DT node\n");
+ else if (pace_pin_updates &&
+ of_device_is_compatible(rp1_node->parent,
+ "brcm,bcm2712-pcie")) {
+ pc->dummy_base = of_iomap(rp1_node->parent, 0);
+ if (IS_ERR(pc->dummy_base)) {
+ dev_warn(
+ &pdev->dev,
+ "could not map bcm2712 root complex registers\n");
+ pc->dummy_base = NULL;
+ }
+ }
for (i = 0; i < RP1_NUM_BANKS; i++) {
const struct rp1_iobank_desc *bank = &rp1_iobanks[i];
@@ -1705,10 +1493,11 @@ static int rp1_pinctrl_probe(struct platform_device *pdev)
j * sizeof(u32) * 2;
pin->inte = pc->gpio_base + bank->inte_offset;
pin->ints = pc->gpio_base + bank->ints_offset;
- pin->rio = pc->rio_base + bank->rio_offset;
- pin->pad = pc->pads_base + bank->pads_offset +
- j * sizeof(u32);
- pin->dummy = pc->dummy_base ? pc->dummy_base + 0xc0 : NULL;
+ pin->rio = pc->rio_base + bank->rio_offset;
+ pin->pad = pc->pads_base + bank->pads_offset +
+ j * sizeof(u32);
+ pin->dummy = pc->dummy_base ? pc->dummy_base + 0xc0 :
+ NULL;
}
raw_spin_lock_init(&pc->irq_lock[i]);
diff --git a/include/linux/gpio/generic.h b/include/linux/gpio/generic.h
index ff566dc9c3cb..e3625f4cb933 100644
--- a/include/linux/gpio/generic.h
+++ b/include/linux/gpio/generic.h
@@ -18,6 +18,7 @@ struct device;
#define GPIO_GENERIC_NO_SET_ON_INPUT BIT(6)
#define GPIO_GENERIC_PINCTRL_BACKEND BIT(7) /* Call pinctrl direction setters */
#define GPIO_GENERIC_NO_INPUT BIT(8) /* only output */
+#define GPIO_GENERIC_REG_DIRECT BIT(15) /* ignore shadow registers */
/**
* struct gpio_generic_chip_config - Generic GPIO chip configuration data