linux/drivers/clk/samsung/clk-exynos7885.c

// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (C) 2021 Dávid Virág <[email protected]>
 * Author: Dávid Virág <[email protected]>
 *
 * Common Clock Framework support for Exynos7885 SoC.
 */

#include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/of.h>
#include <linux/platform_device.h>

#include <dt-bindings/clock/exynos7885.h>

#include "clk.h"
#include "clk-exynos-arm64.h"

/* NOTE: Must be equal to the last clock ID increased by one */
#define CLKS_NR_TOP
#define CLKS_NR_CORE
#define CLKS_NR_PERI
#define CLKS_NR_FSYS

/* ---- CMU_TOP ------------------------------------------------------------- */

/* Register Offset definitions for CMU_TOP (0x12060000) */
#define PLL_LOCKTIME_PLL_SHARED0
#define PLL_LOCKTIME_PLL_SHARED1
#define PLL_CON0_PLL_SHARED0
#define PLL_CON0_PLL_SHARED1
#define CLK_CON_MUX_MUX_CLKCMU_CORE_BUS
#define CLK_CON_MUX_MUX_CLKCMU_CORE_CCI
#define CLK_CON_MUX_MUX_CLKCMU_CORE_G3D
#define CLK_CON_MUX_MUX_CLKCMU_FSYS_BUS
#define CLK_CON_MUX_MUX_CLKCMU_FSYS_MMC_CARD
#define CLK_CON_MUX_MUX_CLKCMU_FSYS_MMC_EMBD
#define CLK_CON_MUX_MUX_CLKCMU_FSYS_MMC_SDIO
#define CLK_CON_MUX_MUX_CLKCMU_FSYS_USB30DRD
#define CLK_CON_MUX_MUX_CLKCMU_PERI_BUS
#define CLK_CON_MUX_MUX_CLKCMU_PERI_SPI0
#define CLK_CON_MUX_MUX_CLKCMU_PERI_SPI1
#define CLK_CON_MUX_MUX_CLKCMU_PERI_UART0
#define CLK_CON_MUX_MUX_CLKCMU_PERI_UART1
#define CLK_CON_MUX_MUX_CLKCMU_PERI_UART2
#define CLK_CON_MUX_MUX_CLKCMU_PERI_USI0
#define CLK_CON_MUX_MUX_CLKCMU_PERI_USI1
#define CLK_CON_MUX_MUX_CLKCMU_PERI_USI2
#define CLK_CON_DIV_CLKCMU_CORE_BUS
#define CLK_CON_DIV_CLKCMU_CORE_CCI
#define CLK_CON_DIV_CLKCMU_CORE_G3D
#define CLK_CON_DIV_CLKCMU_FSYS_BUS
#define CLK_CON_DIV_CLKCMU_FSYS_MMC_CARD
#define CLK_CON_DIV_CLKCMU_FSYS_MMC_EMBD
#define CLK_CON_DIV_CLKCMU_FSYS_MMC_SDIO
#define CLK_CON_DIV_CLKCMU_FSYS_USB30DRD
#define CLK_CON_DIV_CLKCMU_PERI_BUS
#define CLK_CON_DIV_CLKCMU_PERI_SPI0
#define CLK_CON_DIV_CLKCMU_PERI_SPI1
#define CLK_CON_DIV_CLKCMU_PERI_UART0
#define CLK_CON_DIV_CLKCMU_PERI_UART1
#define CLK_CON_DIV_CLKCMU_PERI_UART2
#define CLK_CON_DIV_CLKCMU_PERI_USI0
#define CLK_CON_DIV_CLKCMU_PERI_USI1
#define CLK_CON_DIV_CLKCMU_PERI_USI2
#define CLK_CON_DIV_PLL_SHARED0_DIV2
#define CLK_CON_DIV_PLL_SHARED0_DIV3
#define CLK_CON_DIV_PLL_SHARED0_DIV4
#define CLK_CON_DIV_PLL_SHARED0_DIV5
#define CLK_CON_DIV_PLL_SHARED1_DIV2
#define CLK_CON_DIV_PLL_SHARED1_DIV3
#define CLK_CON_DIV_PLL_SHARED1_DIV4
#define CLK_CON_GAT_GATE_CLKCMUC_PERI_UART1
#define CLK_CON_GAT_GATE_CLKCMU_CORE_BUS
#define CLK_CON_GAT_GATE_CLKCMU_CORE_CCI
#define CLK_CON_GAT_GATE_CLKCMU_CORE_G3D
#define CLK_CON_GAT_GATE_CLKCMU_FSYS_BUS
#define CLK_CON_GAT_GATE_CLKCMU_FSYS_MMC_CARD
#define CLK_CON_GAT_GATE_CLKCMU_FSYS_MMC_EMBD
#define CLK_CON_GAT_GATE_CLKCMU_FSYS_MMC_SDIO
#define CLK_CON_GAT_GATE_CLKCMU_FSYS_USB30DRD
#define CLK_CON_GAT_GATE_CLKCMU_PERI_BUS
#define CLK_CON_GAT_GATE_CLKCMU_PERI_SPI0
#define CLK_CON_GAT_GATE_CLKCMU_PERI_SPI1
#define CLK_CON_GAT_GATE_CLKCMU_PERI_UART0
#define CLK_CON_GAT_GATE_CLKCMU_PERI_UART2
#define CLK_CON_GAT_GATE_CLKCMU_PERI_USI0
#define CLK_CON_GAT_GATE_CLKCMU_PERI_USI1
#define CLK_CON_GAT_GATE_CLKCMU_PERI_USI2

static const unsigned long top_clk_regs[] __initconst =;

static const struct samsung_pll_clock top_pll_clks[] __initconst =;

/* List of parent clocks for Muxes in CMU_TOP: for CMU_CORE */
PNAME(mout_core_bus_p)		=;
PNAME(mout_core_cci_p)		=;
PNAME(mout_core_g3d_p)		=;

/* List of parent clocks for Muxes in CMU_TOP: for CMU_PERI */
PNAME(mout_peri_bus_p)		=;
PNAME(mout_peri_spi0_p)		=;
PNAME(mout_peri_spi1_p)		=;
PNAME(mout_peri_uart0_p)	=;
PNAME(mout_peri_uart1_p)	=;
PNAME(mout_peri_uart2_p)	=;
PNAME(mout_peri_usi0_p)		=;
PNAME(mout_peri_usi1_p)		=;
PNAME(mout_peri_usi2_p)		=;

/* List of parent clocks for Muxes in CMU_TOP: for CMU_FSYS */
PNAME(mout_fsys_bus_p)		=;
PNAME(mout_fsys_mmc_card_p)	=;
PNAME(mout_fsys_mmc_embd_p)	=;
PNAME(mout_fsys_mmc_sdio_p)	=;
PNAME(mout_fsys_usb30drd_p)	=;

static const struct samsung_mux_clock top_mux_clks[] __initconst =;

static const struct samsung_div_clock top_div_clks[] __initconst =;

static const struct samsung_gate_clock top_gate_clks[] __initconst =;

static const struct samsung_cmu_info top_cmu_info __initconst =;

static void __init exynos7885_cmu_top_init(struct device_node *np)
{}

/* Register CMU_TOP early, as it's a dependency for other early domains */
CLK_OF_DECLARE(exynos7885_cmu_top, "samsung,exynos7885-cmu-top",
	       exynos7885_cmu_top_init);

/* ---- CMU_PERI ------------------------------------------------------------ */

/* Register Offset definitions for CMU_PERI (0x10010000) */
#define PLL_CON0_MUX_CLKCMU_PERI_BUS_USER
#define PLL_CON0_MUX_CLKCMU_PERI_SPI0_USER
#define PLL_CON0_MUX_CLKCMU_PERI_SPI1_USER
#define PLL_CON0_MUX_CLKCMU_PERI_UART0_USER
#define PLL_CON0_MUX_CLKCMU_PERI_UART1_USER
#define PLL_CON0_MUX_CLKCMU_PERI_UART2_USER
#define PLL_CON0_MUX_CLKCMU_PERI_USI0_USER
#define PLL_CON0_MUX_CLKCMU_PERI_USI1_USER
#define PLL_CON0_MUX_CLKCMU_PERI_USI2_USER
#define CLK_CON_GAT_GOUT_PERI_GPIO_TOP_PCLK
#define CLK_CON_GAT_GOUT_PERI_HSI2C_0_PCLK
#define CLK_CON_GAT_GOUT_PERI_HSI2C_1_PCLK
#define CLK_CON_GAT_GOUT_PERI_HSI2C_2_PCLK
#define CLK_CON_GAT_GOUT_PERI_HSI2C_3_PCLK
#define CLK_CON_GAT_GOUT_PERI_I2C_0_PCLK
#define CLK_CON_GAT_GOUT_PERI_I2C_1_PCLK
#define CLK_CON_GAT_GOUT_PERI_I2C_2_PCLK
#define CLK_CON_GAT_GOUT_PERI_I2C_3_PCLK
#define CLK_CON_GAT_GOUT_PERI_I2C_4_PCLK
#define CLK_CON_GAT_GOUT_PERI_I2C_5_PCLK
#define CLK_CON_GAT_GOUT_PERI_I2C_6_PCLK
#define CLK_CON_GAT_GOUT_PERI_I2C_7_PCLK
#define CLK_CON_GAT_GOUT_PERI_PWM_MOTOR_PCLK
#define CLK_CON_GAT_GOUT_PERI_SPI_0_PCLK
#define CLK_CON_GAT_GOUT_PERI_SPI_0_EXT_CLK
#define CLK_CON_GAT_GOUT_PERI_SPI_1_PCLK
#define CLK_CON_GAT_GOUT_PERI_SPI_1_EXT_CLK
#define CLK_CON_GAT_GOUT_PERI_UART_0_EXT_UCLK
#define CLK_CON_GAT_GOUT_PERI_UART_0_PCLK
#define CLK_CON_GAT_GOUT_PERI_UART_1_EXT_UCLK
#define CLK_CON_GAT_GOUT_PERI_UART_1_PCLK
#define CLK_CON_GAT_GOUT_PERI_UART_2_EXT_UCLK
#define CLK_CON_GAT_GOUT_PERI_UART_2_PCLK
#define CLK_CON_GAT_GOUT_PERI_USI0_PCLK
#define CLK_CON_GAT_GOUT_PERI_USI0_SCLK
#define CLK_CON_GAT_GOUT_PERI_USI1_PCLK
#define CLK_CON_GAT_GOUT_PERI_USI1_SCLK
#define CLK_CON_GAT_GOUT_PERI_USI2_PCLK
#define CLK_CON_GAT_GOUT_PERI_USI2_SCLK
#define CLK_CON_GAT_GOUT_PERI_MCT_PCLK
#define CLK_CON_GAT_GOUT_PERI_SYSREG_PERI_PCLK
#define CLK_CON_GAT_GOUT_PERI_WDT_CLUSTER0_PCLK
#define CLK_CON_GAT_GOUT_PERI_WDT_CLUSTER1_PCLK

static const unsigned long peri_clk_regs[] __initconst =;

/* List of parent clocks for Muxes in CMU_PERI */
PNAME(mout_peri_bus_user_p)	=;
PNAME(mout_peri_spi0_user_p)	=;
PNAME(mout_peri_spi1_user_p)	=;
PNAME(mout_peri_uart0_user_p)	=;
PNAME(mout_peri_uart1_user_p)	=;
PNAME(mout_peri_uart2_user_p)	=;
PNAME(mout_peri_usi0_user_p)	=;
PNAME(mout_peri_usi1_user_p)	=;
PNAME(mout_peri_usi2_user_p)	=;

static const struct samsung_mux_clock peri_mux_clks[] __initconst =;

static const struct samsung_gate_clock peri_gate_clks[] __initconst =;

static const struct samsung_cmu_info peri_cmu_info __initconst =;

static void __init exynos7885_cmu_peri_init(struct device_node *np)
{}

/* Register CMU_PERI early, as it's needed for MCT timer */
CLK_OF_DECLARE(exynos7885_cmu_peri, "samsung,exynos7885-cmu-peri",
	       exynos7885_cmu_peri_init);

/* ---- CMU_CORE ------------------------------------------------------------ */

/* Register Offset definitions for CMU_CORE (0x12000000) */
#define PLL_CON0_MUX_CLKCMU_CORE_BUS_USER
#define PLL_CON0_MUX_CLKCMU_CORE_CCI_USER
#define PLL_CON0_MUX_CLKCMU_CORE_G3D_USER
#define CLK_CON_MUX_MUX_CLK_CORE_GIC
#define CLK_CON_DIV_DIV_CLK_CORE_BUSP
#define CLK_CON_GAT_GOUT_CORE_CCI_550_ACLK
#define CLK_CON_GAT_GOUT_CORE_GIC400_CLK
#define CLK_CON_GAT_GOUT_CORE_TREX_D_CORE_ACLK
#define CLK_CON_GAT_GOUT_CORE_TREX_D_CORE_GCLK
#define CLK_CON_GAT_GOUT_CORE_TREX_D_CORE_PCLK
#define CLK_CON_GAT_GOUT_CORE_TREX_P_CORE_ACLK_P_CORE
#define CLK_CON_GAT_GOUT_CORE_TREX_P_CORE_CCLK_P_CORE
#define CLK_CON_GAT_GOUT_CORE_TREX_P_CORE_PCLK
#define CLK_CON_GAT_GOUT_CORE_TREX_P_CORE_PCLK_P_CORE

static const unsigned long core_clk_regs[] __initconst =;

/* List of parent clocks for Muxes in CMU_CORE */
PNAME(mout_core_bus_user_p)		=;
PNAME(mout_core_cci_user_p)		=;
PNAME(mout_core_g3d_user_p)		=;
PNAME(mout_core_gic_p)			=;

static const struct samsung_mux_clock core_mux_clks[] __initconst =;

static const struct samsung_div_clock core_div_clks[] __initconst =;

static const struct samsung_gate_clock core_gate_clks[] __initconst =;

static const struct samsung_cmu_info core_cmu_info __initconst =;

/* ---- CMU_FSYS ------------------------------------------------------------ */

/* Register Offset definitions for CMU_FSYS (0x13400000) */
#define PLL_CON0_MUX_CLKCMU_FSYS_BUS_USER
#define PLL_CON0_MUX_CLKCMU_FSYS_MMC_CARD_USER
#define PLL_CON0_MUX_CLKCMU_FSYS_MMC_EMBD_USER
#define PLL_CON0_MUX_CLKCMU_FSYS_MMC_SDIO_USER
#define PLL_CON0_MUX_CLKCMU_FSYS_USB30DRD_USER
#define CLK_CON_GAT_GOUT_FSYS_MMC_CARD_I_ACLK
#define CLK_CON_GAT_GOUT_FSYS_MMC_CARD_SDCLKIN
#define CLK_CON_GAT_GOUT_FSYS_MMC_EMBD_I_ACLK
#define CLK_CON_GAT_GOUT_FSYS_MMC_EMBD_SDCLKIN
#define CLK_CON_GAT_GOUT_FSYS_MMC_SDIO_I_ACLK
#define CLK_CON_GAT_GOUT_FSYS_MMC_SDIO_SDCLKIN

static const unsigned long fsys_clk_regs[] __initconst =;

/* List of parent clocks for Muxes in CMU_FSYS */
PNAME(mout_fsys_bus_user_p)		=;
PNAME(mout_fsys_mmc_card_user_p)	=;
PNAME(mout_fsys_mmc_embd_user_p)	=;
PNAME(mout_fsys_mmc_sdio_user_p)	=;
PNAME(mout_fsys_usb30drd_user_p)	=;

static const struct samsung_mux_clock fsys_mux_clks[] __initconst =;

static const struct samsung_gate_clock fsys_gate_clks[] __initconst =;

static const struct samsung_cmu_info fsys_cmu_info __initconst =;

/* ---- platform_driver ----------------------------------------------------- */

static int __init exynos7885_cmu_probe(struct platform_device *pdev)
{}

static const struct of_device_id exynos7885_cmu_of_match[] =;

static struct platform_driver exynos7885_cmu_driver __refdata =;

static int __init exynos7885_cmu_init(void)
{}
core_initcall(exynos7885_cmu_init);