Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * Copyright (c) 2017 Samsung Electronics Co., Ltd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  * Author: Marek Szyprowski <m.szyprowski@samsung.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  * Common Clock Framework support for Exynos4412 ISP module.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <dt-bindings/clock/exynos4.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/clk-provider.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/pm_runtime.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include "clk.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) /* Exynos4x12 specific registers, which belong to ISP power domain */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #define E4X12_DIV_ISP0		0x0300
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #define E4X12_DIV_ISP1		0x0304
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #define E4X12_GATE_ISP0		0x0800
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #define E4X12_GATE_ISP1		0x0804
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26)  * Support for CMU save/restore across system suspends
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) static struct samsung_clk_reg_dump *exynos4x12_save_isp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) static const unsigned long exynos4x12_clk_isp_save[] __initconst = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 	E4X12_DIV_ISP0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 	E4X12_DIV_ISP1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 	E4X12_GATE_ISP0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 	E4X12_GATE_ISP1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) static struct samsung_div_clock exynos4x12_isp_div_clks[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 	DIV(CLK_ISP_DIV_ISP0, "div_isp0", "aclk200", E4X12_DIV_ISP0, 0, 3),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 	DIV(CLK_ISP_DIV_ISP1, "div_isp1", "aclk200", E4X12_DIV_ISP0, 4, 3),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 	DIV(CLK_ISP_DIV_MCUISP0, "div_mcuisp0", "aclk400_mcuisp",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 	    E4X12_DIV_ISP1, 4, 3),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 	DIV(CLK_ISP_DIV_MCUISP1, "div_mcuisp1", "div_mcuisp0",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 	    E4X12_DIV_ISP1, 8, 3),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	DIV(0, "div_mpwm", "div_isp1", E4X12_DIV_ISP1, 0, 3),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) static struct samsung_gate_clock exynos4x12_isp_gate_clks[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 	GATE(CLK_ISP_FIMC_ISP, "isp", "aclk200", E4X12_GATE_ISP0, 0, 0, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 	GATE(CLK_ISP_FIMC_DRC, "drc", "aclk200", E4X12_GATE_ISP0, 1, 0, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 	GATE(CLK_ISP_FIMC_FD, "fd", "aclk200", E4X12_GATE_ISP0, 2, 0, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 	GATE(CLK_ISP_FIMC_LITE0, "lite0", "aclk200", E4X12_GATE_ISP0, 3, 0, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	GATE(CLK_ISP_FIMC_LITE1, "lite1", "aclk200", E4X12_GATE_ISP0, 4, 0, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	GATE(CLK_ISP_MCUISP, "mcuisp", "aclk200", E4X12_GATE_ISP0, 5, 0, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	GATE(CLK_ISP_GICISP, "gicisp", "aclk200", E4X12_GATE_ISP0, 7, 0, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 	GATE(CLK_ISP_SMMU_ISP, "smmu_isp", "aclk200", E4X12_GATE_ISP0, 8, 0, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	GATE(CLK_ISP_SMMU_DRC, "smmu_drc", "aclk200", E4X12_GATE_ISP0, 9, 0, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	GATE(CLK_ISP_SMMU_FD, "smmu_fd", "aclk200", E4X12_GATE_ISP0, 10, 0, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	GATE(CLK_ISP_SMMU_LITE0, "smmu_lite0", "aclk200", E4X12_GATE_ISP0, 11,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	     0, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	GATE(CLK_ISP_SMMU_LITE1, "smmu_lite1", "aclk200", E4X12_GATE_ISP0, 12,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 	     0, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	GATE(CLK_ISP_PPMUISPMX, "ppmuispmx", "aclk200", E4X12_GATE_ISP0, 20,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	     0, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	GATE(CLK_ISP_PPMUISPX, "ppmuispx", "aclk200", E4X12_GATE_ISP0, 21,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	     0, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	GATE(CLK_ISP_MCUCTL_ISP, "mcuctl_isp", "aclk200", E4X12_GATE_ISP0, 23,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	     0, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	GATE(CLK_ISP_MPWM_ISP, "mpwm_isp", "aclk200", E4X12_GATE_ISP0, 24,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	     0, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	GATE(CLK_ISP_I2C0_ISP, "i2c0_isp", "aclk200", E4X12_GATE_ISP0, 25,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	     0, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	GATE(CLK_ISP_I2C1_ISP, "i2c1_isp", "aclk200", E4X12_GATE_ISP0, 26,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	     0, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	GATE(CLK_ISP_MTCADC_ISP, "mtcadc_isp", "aclk200", E4X12_GATE_ISP0, 27,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	     0, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	GATE(CLK_ISP_PWM_ISP, "pwm_isp", "aclk200", E4X12_GATE_ISP0, 28, 0, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	GATE(CLK_ISP_WDT_ISP, "wdt_isp", "aclk200", E4X12_GATE_ISP0, 30, 0, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	GATE(CLK_ISP_UART_ISP, "uart_isp", "aclk200", E4X12_GATE_ISP0, 31,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	     0, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	GATE(CLK_ISP_ASYNCAXIM, "asyncaxim", "aclk200", E4X12_GATE_ISP1, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	     0, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	GATE(CLK_ISP_SMMU_ISPCX, "smmu_ispcx", "aclk200", E4X12_GATE_ISP1, 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	     0, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	GATE(CLK_ISP_SPI0_ISP, "spi0_isp", "aclk200", E4X12_GATE_ISP1, 12,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	     0, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	GATE(CLK_ISP_SPI1_ISP, "spi1_isp", "aclk200", E4X12_GATE_ISP1, 13,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	     0, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) static int __maybe_unused exynos4x12_isp_clk_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	struct samsung_clk_provider *ctx = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	samsung_clk_save(ctx->reg_base, exynos4x12_save_isp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 			 ARRAY_SIZE(exynos4x12_clk_isp_save));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) static int __maybe_unused exynos4x12_isp_clk_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	struct samsung_clk_provider *ctx = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	samsung_clk_restore(ctx->reg_base, exynos4x12_save_isp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 			    ARRAY_SIZE(exynos4x12_clk_isp_save));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) static int __init exynos4x12_isp_clk_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	struct samsung_clk_provider *ctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	struct device *dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	struct device_node *np = dev->of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 	struct resource *res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	void __iomem *reg_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	reg_base = devm_ioremap_resource(dev, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	if (IS_ERR(reg_base)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 		dev_err(dev, "failed to map registers\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 		return PTR_ERR(reg_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	exynos4x12_save_isp = samsung_clk_alloc_reg_dump(exynos4x12_clk_isp_save,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 					ARRAY_SIZE(exynos4x12_clk_isp_save));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	if (!exynos4x12_save_isp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 	ctx = samsung_clk_init(np, reg_base, CLK_NR_ISP_CLKS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	ctx->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	platform_set_drvdata(pdev, ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	pm_runtime_set_active(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 	pm_runtime_enable(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	pm_runtime_get_sync(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	samsung_clk_register_div(ctx, exynos4x12_isp_div_clks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 				 ARRAY_SIZE(exynos4x12_isp_div_clks));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	samsung_clk_register_gate(ctx, exynos4x12_isp_gate_clks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 				  ARRAY_SIZE(exynos4x12_isp_gate_clks));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	samsung_clk_of_add_provider(np, ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	pm_runtime_put(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) static const struct of_device_id exynos4x12_isp_clk_of_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 	{ .compatible = "samsung,exynos4412-isp-clock", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	{ },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) static const struct dev_pm_ops exynos4x12_isp_pm_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	SET_RUNTIME_PM_OPS(exynos4x12_isp_clk_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 			   exynos4x12_isp_clk_resume, NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	SET_LATE_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 				     pm_runtime_force_resume)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) static struct platform_driver exynos4x12_isp_clk_driver __refdata = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	.driver	= {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 		.name = "exynos4x12-isp-clk",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 		.of_match_table = exynos4x12_isp_clk_of_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 		.suppress_bind_attrs = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 		.pm = &exynos4x12_isp_pm_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 	.probe = exynos4x12_isp_clk_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) static int __init exynos4x12_isp_clk_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 	return platform_driver_register(&exynos4x12_isp_clk_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) core_initcall(exynos4x12_isp_clk_init);