^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Xilinx VCU Init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2016 - 2017 Xilinx, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Contacts Dhaval Shah <dshah@xilinx.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/of_platform.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) /* Address map for different registers implemented in the VCU LogiCORE IP. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #define VCU_ECODER_ENABLE 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #define VCU_DECODER_ENABLE 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #define VCU_MEMORY_DEPTH 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #define VCU_ENC_COLOR_DEPTH 0x0c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #define VCU_ENC_VERTICAL_RANGE 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #define VCU_ENC_FRAME_SIZE_X 0x14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define VCU_ENC_FRAME_SIZE_Y 0x18
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define VCU_ENC_COLOR_FORMAT 0x1c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define VCU_ENC_FPS 0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define VCU_MCU_CLK 0x24
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define VCU_CORE_CLK 0x28
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define VCU_PLL_BYPASS 0x2c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define VCU_ENC_CLK 0x30
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define VCU_PLL_CLK 0x34
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define VCU_ENC_VIDEO_STANDARD 0x38
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define VCU_STATUS 0x3c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define VCU_AXI_ENC_CLK 0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define VCU_AXI_DEC_CLK 0x44
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define VCU_AXI_MCU_CLK 0x48
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define VCU_DEC_VIDEO_STANDARD 0x4c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define VCU_DEC_FRAME_SIZE_X 0x50
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define VCU_DEC_FRAME_SIZE_Y 0x54
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define VCU_DEC_FPS 0x58
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define VCU_BUFFER_B_FRAME 0x5c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define VCU_WPP_EN 0x60
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define VCU_PLL_CLK_DEC 0x64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define VCU_GASKET_INIT 0x74
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define VCU_GASKET_VALUE 0x03
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) /* vcu slcr registers, bitmask and shift */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define VCU_PLL_CTRL 0x24
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define VCU_PLL_CTRL_RESET_MASK 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define VCU_PLL_CTRL_RESET_SHIFT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define VCU_PLL_CTRL_BYPASS_MASK 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define VCU_PLL_CTRL_BYPASS_SHIFT 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define VCU_PLL_CTRL_FBDIV_MASK 0x7f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define VCU_PLL_CTRL_FBDIV_SHIFT 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define VCU_PLL_CTRL_POR_IN_MASK 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define VCU_PLL_CTRL_POR_IN_SHIFT 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define VCU_PLL_CTRL_PWR_POR_MASK 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define VCU_PLL_CTRL_PWR_POR_SHIFT 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define VCU_PLL_CTRL_CLKOUTDIV_MASK 0x03
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define VCU_PLL_CTRL_CLKOUTDIV_SHIFT 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define VCU_PLL_CTRL_DEFAULT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define VCU_PLL_DIV2 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define VCU_PLL_CFG 0x28
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define VCU_PLL_CFG_RES_MASK 0x0f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #define VCU_PLL_CFG_RES_SHIFT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #define VCU_PLL_CFG_CP_MASK 0x0f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #define VCU_PLL_CFG_CP_SHIFT 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define VCU_PLL_CFG_LFHF_MASK 0x03
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define VCU_PLL_CFG_LFHF_SHIFT 10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define VCU_PLL_CFG_LOCK_CNT_MASK 0x03ff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define VCU_PLL_CFG_LOCK_CNT_SHIFT 13
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define VCU_PLL_CFG_LOCK_DLY_MASK 0x7f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #define VCU_PLL_CFG_LOCK_DLY_SHIFT 25
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #define VCU_ENC_CORE_CTRL 0x30
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #define VCU_ENC_MCU_CTRL 0x34
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #define VCU_DEC_CORE_CTRL 0x38
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #define VCU_DEC_MCU_CTRL 0x3c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #define VCU_PLL_DIVISOR_MASK 0x3f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #define VCU_PLL_DIVISOR_SHIFT 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #define VCU_SRCSEL_MASK 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #define VCU_SRCSEL_SHIFT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) #define VCU_SRCSEL_PLL 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #define VCU_PLL_STATUS 0x60
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) #define VCU_PLL_STATUS_LOCK_STATUS_MASK 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) #define MHZ 1000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) #define FVCO_MIN (1500U * MHZ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) #define FVCO_MAX (3000U * MHZ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) #define DIVISOR_MIN 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) #define DIVISOR_MAX 63
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) #define FRAC 100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) #define LIMIT (10 * MHZ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) * struct xvcu_device - Xilinx VCU init device structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) * @dev: Platform device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) * @pll_ref: pll ref clock source
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) * @aclk: axi clock source
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) * @logicore_reg_ba: logicore reg base address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) * @vcu_slcr_ba: vcu_slcr Register base address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) * @coreclk: core clock frequency
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) struct xvcu_device {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) struct clk *pll_ref;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) struct clk *aclk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) void __iomem *logicore_reg_ba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) void __iomem *vcu_slcr_ba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) u32 coreclk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) * struct xvcu_pll_cfg - Helper data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) * @fbdiv: The integer portion of the feedback divider to the PLL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) * @cp: PLL charge pump control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) * @res: PLL loop filter resistor control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) * @lfhf: PLL loop filter high frequency capacitor control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) * @lock_dly: Lock circuit configuration settings for lock windowsize
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) * @lock_cnt: Lock circuit counter setting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) struct xvcu_pll_cfg {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) u32 fbdiv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) u32 cp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) u32 res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) u32 lfhf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) u32 lock_dly;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) u32 lock_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) static const struct xvcu_pll_cfg xvcu_pll_cfg[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) { 25, 3, 10, 3, 63, 1000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) { 26, 3, 10, 3, 63, 1000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) { 27, 4, 6, 3, 63, 1000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) { 28, 4, 6, 3, 63, 1000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) { 29, 4, 6, 3, 63, 1000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) { 30, 4, 6, 3, 63, 1000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) { 31, 6, 1, 3, 63, 1000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) { 32, 6, 1, 3, 63, 1000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) { 33, 4, 10, 3, 63, 1000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) { 34, 5, 6, 3, 63, 1000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) { 35, 5, 6, 3, 63, 1000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) { 36, 5, 6, 3, 63, 1000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) { 37, 5, 6, 3, 63, 1000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) { 38, 5, 6, 3, 63, 975 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) { 39, 3, 12, 3, 63, 950 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) { 40, 3, 12, 3, 63, 925 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) { 41, 3, 12, 3, 63, 900 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) { 42, 3, 12, 3, 63, 875 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) { 43, 3, 12, 3, 63, 850 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) { 44, 3, 12, 3, 63, 850 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) { 45, 3, 12, 3, 63, 825 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) { 46, 3, 12, 3, 63, 800 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) { 47, 3, 12, 3, 63, 775 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) { 48, 3, 12, 3, 63, 775 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) { 49, 3, 12, 3, 63, 750 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) { 50, 3, 12, 3, 63, 750 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) { 51, 3, 2, 3, 63, 725 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) { 52, 3, 2, 3, 63, 700 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) { 53, 3, 2, 3, 63, 700 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) { 54, 3, 2, 3, 63, 675 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) { 55, 3, 2, 3, 63, 675 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) { 56, 3, 2, 3, 63, 650 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) { 57, 3, 2, 3, 63, 650 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) { 58, 3, 2, 3, 63, 625 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) { 59, 3, 2, 3, 63, 625 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) { 60, 3, 2, 3, 63, 625 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) { 61, 3, 2, 3, 63, 600 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) { 62, 3, 2, 3, 63, 600 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) { 63, 3, 2, 3, 63, 600 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) { 64, 3, 2, 3, 63, 600 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) { 65, 3, 2, 3, 63, 600 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) { 66, 3, 2, 3, 63, 600 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) { 67, 3, 2, 3, 63, 600 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) { 68, 3, 2, 3, 63, 600 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) { 69, 3, 2, 3, 63, 600 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) { 70, 3, 2, 3, 63, 600 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) { 71, 3, 2, 3, 63, 600 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) { 72, 3, 2, 3, 63, 600 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) { 73, 3, 2, 3, 63, 600 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) { 74, 3, 2, 3, 63, 600 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) { 75, 3, 2, 3, 63, 600 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) { 76, 3, 2, 3, 63, 600 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) { 77, 3, 2, 3, 63, 600 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) { 78, 3, 2, 3, 63, 600 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) { 79, 3, 2, 3, 63, 600 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) { 80, 3, 2, 3, 63, 600 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) { 81, 3, 2, 3, 63, 600 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) { 82, 3, 2, 3, 63, 600 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) { 83, 4, 2, 3, 63, 600 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) { 84, 4, 2, 3, 63, 600 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) { 85, 4, 2, 3, 63, 600 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) { 86, 4, 2, 3, 63, 600 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) { 87, 4, 2, 3, 63, 600 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) { 88, 4, 2, 3, 63, 600 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) { 89, 4, 2, 3, 63, 600 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) { 90, 4, 2, 3, 63, 600 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) { 91, 4, 2, 3, 63, 600 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) { 92, 4, 2, 3, 63, 600 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) { 93, 4, 2, 3, 63, 600 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) { 94, 4, 2, 3, 63, 600 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) { 95, 4, 2, 3, 63, 600 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) { 96, 4, 2, 3, 63, 600 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) { 97, 4, 2, 3, 63, 600 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) { 98, 4, 2, 3, 63, 600 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) { 99, 4, 2, 3, 63, 600 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) { 100, 4, 2, 3, 63, 600 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) { 101, 4, 2, 3, 63, 600 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) { 102, 4, 2, 3, 63, 600 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) { 103, 5, 2, 3, 63, 600 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) { 104, 5, 2, 3, 63, 600 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) { 105, 5, 2, 3, 63, 600 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) { 106, 5, 2, 3, 63, 600 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) { 107, 3, 4, 3, 63, 600 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) { 108, 3, 4, 3, 63, 600 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) { 109, 3, 4, 3, 63, 600 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) { 110, 3, 4, 3, 63, 600 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) { 111, 3, 4, 3, 63, 600 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) { 112, 3, 4, 3, 63, 600 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) { 113, 3, 4, 3, 63, 600 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) { 114, 3, 4, 3, 63, 600 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) { 115, 3, 4, 3, 63, 600 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) { 116, 3, 4, 3, 63, 600 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) { 117, 3, 4, 3, 63, 600 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) { 118, 3, 4, 3, 63, 600 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) { 119, 3, 4, 3, 63, 600 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) { 120, 3, 4, 3, 63, 600 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) { 121, 3, 4, 3, 63, 600 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) { 122, 3, 4, 3, 63, 600 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) { 123, 3, 4, 3, 63, 600 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) { 124, 3, 4, 3, 63, 600 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) { 125, 3, 4, 3, 63, 600 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) * xvcu_read - Read from the VCU register space
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) * @iomem: vcu reg space base address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) * @offset: vcu reg offset from base
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) * Return: Returns 32bit value from VCU register specified
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) static inline u32 xvcu_read(void __iomem *iomem, u32 offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) return ioread32(iomem + offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) * xvcu_write - Write to the VCU register space
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) * @iomem: vcu reg space base address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) * @offset: vcu reg offset from base
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) * @value: Value to write
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) static inline void xvcu_write(void __iomem *iomem, u32 offset, u32 value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) iowrite32(value, iomem + offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) * xvcu_write_field_reg - Write to the vcu reg field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) * @iomem: vcu reg space base address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) * @offset: vcu reg offset from base
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) * @field: vcu reg field to write to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) * @mask: vcu reg mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) * @shift: vcu reg number of bits to shift the bitfield
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) static void xvcu_write_field_reg(void __iomem *iomem, int offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) u32 field, u32 mask, int shift)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) u32 val = xvcu_read(iomem, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) val &= ~(mask << shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) val |= (field & mask) << shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) xvcu_write(iomem, offset, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) * xvcu_set_vcu_pll_info - Set the VCU PLL info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) * @xvcu: Pointer to the xvcu_device structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) * Programming the VCU PLL based on the user configuration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) * (ref clock freq, core clock freq, mcu clock freq).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) * Core clock frequency has higher priority than mcu clock frequency
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) * Errors in following cases
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) * - When mcu or clock clock get from logicoreIP is 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) * - When VCU PLL DIV related bits value other than 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) * - When proper data not found for given data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) * - When sis570_1 clocksource related operation failed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) * Return: Returns status, either success or error+reason
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) static int xvcu_set_vcu_pll_info(struct xvcu_device *xvcu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) u32 refclk, coreclk, mcuclk, inte, deci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) u32 divisor_mcu, divisor_core, fvco;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) u32 clkoutdiv, vcu_pll_ctrl, pll_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) u32 cfg_val, mod, ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) int ret, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) const struct xvcu_pll_cfg *found = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) inte = xvcu_read(xvcu->logicore_reg_ba, VCU_PLL_CLK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) deci = xvcu_read(xvcu->logicore_reg_ba, VCU_PLL_CLK_DEC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) coreclk = xvcu_read(xvcu->logicore_reg_ba, VCU_CORE_CLK) * MHZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) mcuclk = xvcu_read(xvcu->logicore_reg_ba, VCU_MCU_CLK) * MHZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) if (!mcuclk || !coreclk) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) dev_err(xvcu->dev, "Invalid mcu and core clock data\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) refclk = (inte * MHZ) + (deci * (MHZ / FRAC));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) dev_dbg(xvcu->dev, "Ref clock from logicoreIP is %uHz\n", refclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) dev_dbg(xvcu->dev, "Core clock from logicoreIP is %uHz\n", coreclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) dev_dbg(xvcu->dev, "Mcu clock from logicoreIP is %uHz\n", mcuclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) clk_disable_unprepare(xvcu->pll_ref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) ret = clk_set_rate(xvcu->pll_ref, refclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) dev_warn(xvcu->dev, "failed to set logicoreIP refclk rate\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) ret = clk_prepare_enable(xvcu->pll_ref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) dev_err(xvcu->dev, "failed to enable pll_ref clock source\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) refclk = clk_get_rate(xvcu->pll_ref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) * The divide-by-2 should be always enabled (==1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) * to meet the timing in the design.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) * Otherwise, it's an error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) vcu_pll_ctrl = xvcu_read(xvcu->vcu_slcr_ba, VCU_PLL_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) clkoutdiv = vcu_pll_ctrl >> VCU_PLL_CTRL_CLKOUTDIV_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) clkoutdiv = clkoutdiv & VCU_PLL_CTRL_CLKOUTDIV_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) if (clkoutdiv != 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) dev_err(xvcu->dev, "clkoutdiv value is invalid\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) for (i = ARRAY_SIZE(xvcu_pll_cfg) - 1; i >= 0; i--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) const struct xvcu_pll_cfg *cfg = &xvcu_pll_cfg[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) fvco = cfg->fbdiv * refclk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) if (fvco >= FVCO_MIN && fvco <= FVCO_MAX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) pll_clk = fvco / VCU_PLL_DIV2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) if (fvco % VCU_PLL_DIV2 != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) pll_clk++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) mod = pll_clk % coreclk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) if (mod < LIMIT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) divisor_core = pll_clk / coreclk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) } else if (coreclk - mod < LIMIT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) divisor_core = pll_clk / coreclk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) divisor_core++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) if (divisor_core >= DIVISOR_MIN &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) divisor_core <= DIVISOR_MAX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) found = cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) divisor_mcu = pll_clk / mcuclk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) mod = pll_clk % mcuclk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) if (mcuclk - mod < LIMIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) divisor_mcu++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) if (!found) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) dev_err(xvcu->dev, "Invalid clock combination.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) xvcu->coreclk = pll_clk / divisor_core;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) mcuclk = pll_clk / divisor_mcu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) dev_dbg(xvcu->dev, "Actual Ref clock freq is %uHz\n", refclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) dev_dbg(xvcu->dev, "Actual Core clock freq is %uHz\n", xvcu->coreclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) dev_dbg(xvcu->dev, "Actual Mcu clock freq is %uHz\n", mcuclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) vcu_pll_ctrl &= ~(VCU_PLL_CTRL_FBDIV_MASK << VCU_PLL_CTRL_FBDIV_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) vcu_pll_ctrl |= (found->fbdiv & VCU_PLL_CTRL_FBDIV_MASK) <<
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) VCU_PLL_CTRL_FBDIV_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) vcu_pll_ctrl &= ~(VCU_PLL_CTRL_POR_IN_MASK <<
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) VCU_PLL_CTRL_POR_IN_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) vcu_pll_ctrl |= (VCU_PLL_CTRL_DEFAULT & VCU_PLL_CTRL_POR_IN_MASK) <<
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) VCU_PLL_CTRL_POR_IN_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) vcu_pll_ctrl &= ~(VCU_PLL_CTRL_PWR_POR_MASK <<
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) VCU_PLL_CTRL_PWR_POR_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) vcu_pll_ctrl |= (VCU_PLL_CTRL_DEFAULT & VCU_PLL_CTRL_PWR_POR_MASK) <<
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) VCU_PLL_CTRL_PWR_POR_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) xvcu_write(xvcu->vcu_slcr_ba, VCU_PLL_CTRL, vcu_pll_ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) /* Set divisor for the core and mcu clock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) ctrl = xvcu_read(xvcu->vcu_slcr_ba, VCU_ENC_CORE_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) ctrl &= ~(VCU_PLL_DIVISOR_MASK << VCU_PLL_DIVISOR_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) ctrl |= (divisor_core & VCU_PLL_DIVISOR_MASK) <<
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) VCU_PLL_DIVISOR_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) ctrl &= ~(VCU_SRCSEL_MASK << VCU_SRCSEL_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) ctrl |= (VCU_SRCSEL_PLL & VCU_SRCSEL_MASK) << VCU_SRCSEL_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) xvcu_write(xvcu->vcu_slcr_ba, VCU_ENC_CORE_CTRL, ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) ctrl = xvcu_read(xvcu->vcu_slcr_ba, VCU_DEC_CORE_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) ctrl &= ~(VCU_PLL_DIVISOR_MASK << VCU_PLL_DIVISOR_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) ctrl |= (divisor_core & VCU_PLL_DIVISOR_MASK) <<
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) VCU_PLL_DIVISOR_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) ctrl &= ~(VCU_SRCSEL_MASK << VCU_SRCSEL_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) ctrl |= (VCU_SRCSEL_PLL & VCU_SRCSEL_MASK) << VCU_SRCSEL_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) xvcu_write(xvcu->vcu_slcr_ba, VCU_DEC_CORE_CTRL, ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) ctrl = xvcu_read(xvcu->vcu_slcr_ba, VCU_ENC_MCU_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) ctrl &= ~(VCU_PLL_DIVISOR_MASK << VCU_PLL_DIVISOR_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) ctrl |= (divisor_mcu & VCU_PLL_DIVISOR_MASK) << VCU_PLL_DIVISOR_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) ctrl &= ~(VCU_SRCSEL_MASK << VCU_SRCSEL_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) ctrl |= (VCU_SRCSEL_PLL & VCU_SRCSEL_MASK) << VCU_SRCSEL_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) xvcu_write(xvcu->vcu_slcr_ba, VCU_ENC_MCU_CTRL, ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) ctrl = xvcu_read(xvcu->vcu_slcr_ba, VCU_DEC_MCU_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) ctrl &= ~(VCU_PLL_DIVISOR_MASK << VCU_PLL_DIVISOR_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) ctrl |= (divisor_mcu & VCU_PLL_DIVISOR_MASK) << VCU_PLL_DIVISOR_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) ctrl &= ~(VCU_SRCSEL_MASK << VCU_SRCSEL_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) ctrl |= (VCU_SRCSEL_PLL & VCU_SRCSEL_MASK) << VCU_SRCSEL_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) xvcu_write(xvcu->vcu_slcr_ba, VCU_DEC_MCU_CTRL, ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) /* Set RES, CP, LFHF, LOCK_CNT and LOCK_DLY cfg values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) cfg_val = (found->res << VCU_PLL_CFG_RES_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) (found->cp << VCU_PLL_CFG_CP_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) (found->lfhf << VCU_PLL_CFG_LFHF_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) (found->lock_cnt << VCU_PLL_CFG_LOCK_CNT_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) (found->lock_dly << VCU_PLL_CFG_LOCK_DLY_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) xvcu_write(xvcu->vcu_slcr_ba, VCU_PLL_CFG, cfg_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) * xvcu_set_pll - PLL init sequence
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) * @xvcu: Pointer to the xvcu_device structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) * Call the api to set the PLL info and once that is done then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) * init the PLL sequence to make the PLL stable.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) * Return: Returns status, either success or error+reason
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) static int xvcu_set_pll(struct xvcu_device *xvcu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) u32 lock_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) unsigned long timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) ret = xvcu_set_vcu_pll_info(xvcu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) dev_err(xvcu->dev, "failed to set pll info\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) xvcu_write_field_reg(xvcu->vcu_slcr_ba, VCU_PLL_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 1, VCU_PLL_CTRL_BYPASS_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) VCU_PLL_CTRL_BYPASS_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) xvcu_write_field_reg(xvcu->vcu_slcr_ba, VCU_PLL_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 1, VCU_PLL_CTRL_RESET_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) VCU_PLL_CTRL_RESET_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) xvcu_write_field_reg(xvcu->vcu_slcr_ba, VCU_PLL_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 0, VCU_PLL_CTRL_RESET_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) VCU_PLL_CTRL_RESET_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) * Defined the timeout for the max time to wait the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) * PLL_STATUS to be locked.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) timeout = jiffies + msecs_to_jiffies(2000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) lock_status = xvcu_read(xvcu->vcu_slcr_ba, VCU_PLL_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) if (lock_status & VCU_PLL_STATUS_LOCK_STATUS_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) xvcu_write_field_reg(xvcu->vcu_slcr_ba, VCU_PLL_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 0, VCU_PLL_CTRL_BYPASS_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) VCU_PLL_CTRL_BYPASS_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) } while (!time_after(jiffies, timeout));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) /* PLL is not locked even after the timeout of the 2sec */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) dev_err(xvcu->dev, "PLL is not locked\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) return -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) * xvcu_probe - Probe existence of the logicoreIP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) * and initialize PLL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) * @pdev: Pointer to the platform_device structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) * Return: Returns 0 on success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) * Negative error code otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) static int xvcu_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) struct resource *res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) struct xvcu_device *xvcu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) xvcu = devm_kzalloc(&pdev->dev, sizeof(*xvcu), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) if (!xvcu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) xvcu->dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "vcu_slcr");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) if (!res) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) dev_err(&pdev->dev, "get vcu_slcr memory resource failed.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) xvcu->vcu_slcr_ba = devm_ioremap(&pdev->dev, res->start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) resource_size(res));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) if (!xvcu->vcu_slcr_ba) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) dev_err(&pdev->dev, "vcu_slcr register mapping failed.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "logicore");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) if (!res) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) dev_err(&pdev->dev, "get logicore memory resource failed.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) xvcu->logicore_reg_ba = devm_ioremap(&pdev->dev, res->start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) resource_size(res));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) if (!xvcu->logicore_reg_ba) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) dev_err(&pdev->dev, "logicore register mapping failed.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) xvcu->aclk = devm_clk_get(&pdev->dev, "aclk");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) if (IS_ERR(xvcu->aclk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) dev_err(&pdev->dev, "Could not get aclk clock\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) return PTR_ERR(xvcu->aclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) xvcu->pll_ref = devm_clk_get(&pdev->dev, "pll_ref");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) if (IS_ERR(xvcu->pll_ref)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) dev_err(&pdev->dev, "Could not get pll_ref clock\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) return PTR_ERR(xvcu->pll_ref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) ret = clk_prepare_enable(xvcu->aclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) dev_err(&pdev->dev, "aclk clock enable failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) ret = clk_prepare_enable(xvcu->pll_ref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) dev_err(&pdev->dev, "pll_ref clock enable failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) goto error_aclk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) * Do the Gasket isolation and put the VCU out of reset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) * Bit 0 : Gasket isolation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) * Bit 1 : put VCU out of reset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) xvcu_write(xvcu->logicore_reg_ba, VCU_GASKET_INIT, VCU_GASKET_VALUE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) /* Do the PLL Settings based on the ref clk,core and mcu clk freq */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) ret = xvcu_set_pll(xvcu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) dev_err(&pdev->dev, "Failed to set the pll\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) goto error_pll_ref;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) dev_set_drvdata(&pdev->dev, xvcu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) dev_info(&pdev->dev, "%s: Probed successfully\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) error_pll_ref:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) clk_disable_unprepare(xvcu->pll_ref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) error_aclk:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) clk_disable_unprepare(xvcu->aclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) * xvcu_remove - Insert gasket isolation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) * and disable the clock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) * @pdev: Pointer to the platform_device structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) * Return: Returns 0 on success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) * Negative error code otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) static int xvcu_remove(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) struct xvcu_device *xvcu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) xvcu = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) if (!xvcu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) /* Add the the Gasket isolation and put the VCU in reset. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) xvcu_write(xvcu->logicore_reg_ba, VCU_GASKET_INIT, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) clk_disable_unprepare(xvcu->pll_ref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) clk_disable_unprepare(xvcu->aclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) static const struct of_device_id xvcu_of_id_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) { .compatible = "xlnx,vcu" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) { .compatible = "xlnx,vcu-logicoreip-1.0" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) MODULE_DEVICE_TABLE(of, xvcu_of_id_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) static struct platform_driver xvcu_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) .name = "xilinx-vcu",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) .of_match_table = xvcu_of_id_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) .probe = xvcu_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) .remove = xvcu_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) module_platform_driver(xvcu_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) MODULE_AUTHOR("Dhaval Shah <dshah@xilinx.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) MODULE_DESCRIPTION("Xilinx VCU init Driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) MODULE_LICENSE("GPL v2");