1
0
Fork 0

soc: xilinx: vcu: use vcu-settings syscon registers

Switch the "logicoreip" registers to the new xlnx,vcu-settings binding
to be able to read the settings if the settings are specified in a
separate device tree node that is shared with other drivers.

If the driver is not able to find a node with the new binding, fall back
to check for the logicore register bank to be backwards compatible.

Signed-off-by: Michael Tretter <m.tretter@pengutronix.de>
Reviewed-by: Hyun Kwon <hyun.kwon@xilinx.com>
Link: https://lore.kernel.org/r/20201109134818.4159342-4-m.tretter@pengutronix.de
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
zero-sugar-mainline-defconfig
Michael Tretter 2020-11-09 14:48:17 +01:00 committed by Michal Simek
parent a3857f89dd
commit 30b79eb1f9
3 changed files with 86 additions and 47 deletions

View File

@ -4,6 +4,7 @@ menu "Xilinx SoC drivers"
config XILINX_VCU config XILINX_VCU
tristate "Xilinx VCU logicoreIP Init" tristate "Xilinx VCU logicoreIP Init"
depends on HAS_IOMEM depends on HAS_IOMEM
select REGMAP_MMIO
help help
Provides the driver to enable and disable the isolation between the Provides the driver to enable and disable the isolation between the
processing system and programmable logic part by using the logicoreIP processing system and programmable logic part by using the logicoreIP

View File

@ -10,39 +10,12 @@
#include <linux/device.h> #include <linux/device.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/mfd/syscon.h>
#include <linux/mfd/syscon/xlnx-vcu.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/of_platform.h> #include <linux/of_platform.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/regmap.h>
/* Address map for different registers implemented in the VCU LogiCORE IP. */
#define VCU_ECODER_ENABLE 0x00
#define VCU_DECODER_ENABLE 0x04
#define VCU_MEMORY_DEPTH 0x08
#define VCU_ENC_COLOR_DEPTH 0x0c
#define VCU_ENC_VERTICAL_RANGE 0x10
#define VCU_ENC_FRAME_SIZE_X 0x14
#define VCU_ENC_FRAME_SIZE_Y 0x18
#define VCU_ENC_COLOR_FORMAT 0x1c
#define VCU_ENC_FPS 0x20
#define VCU_MCU_CLK 0x24
#define VCU_CORE_CLK 0x28
#define VCU_PLL_BYPASS 0x2c
#define VCU_ENC_CLK 0x30
#define VCU_PLL_CLK 0x34
#define VCU_ENC_VIDEO_STANDARD 0x38
#define VCU_STATUS 0x3c
#define VCU_AXI_ENC_CLK 0x40
#define VCU_AXI_DEC_CLK 0x44
#define VCU_AXI_MCU_CLK 0x48
#define VCU_DEC_VIDEO_STANDARD 0x4c
#define VCU_DEC_FRAME_SIZE_X 0x50
#define VCU_DEC_FRAME_SIZE_Y 0x54
#define VCU_DEC_FPS 0x58
#define VCU_BUFFER_B_FRAME 0x5c
#define VCU_WPP_EN 0x60
#define VCU_PLL_CLK_DEC 0x64
#define VCU_GASKET_INIT 0x74
#define VCU_GASKET_VALUE 0x03
/* vcu slcr registers, bitmask and shift */ /* vcu slcr registers, bitmask and shift */
#define VCU_PLL_CTRL 0x24 #define VCU_PLL_CTRL 0x24
@ -106,11 +79,20 @@ struct xvcu_device {
struct device *dev; struct device *dev;
struct clk *pll_ref; struct clk *pll_ref;
struct clk *aclk; struct clk *aclk;
void __iomem *logicore_reg_ba; struct regmap *logicore_reg_ba;
void __iomem *vcu_slcr_ba; void __iomem *vcu_slcr_ba;
u32 coreclk; u32 coreclk;
}; };
static struct regmap_config vcu_settings_regmap_config = {
.name = "regmap",
.reg_bits = 32,
.val_bits = 32,
.reg_stride = 4,
.max_register = 0xfff,
.cache_type = REGCACHE_NONE,
};
/** /**
* struct xvcu_pll_cfg - Helper data * struct xvcu_pll_cfg - Helper data
* @fbdiv: The integer portion of the feedback divider to the PLL * @fbdiv: The integer portion of the feedback divider to the PLL
@ -300,10 +282,12 @@ static int xvcu_set_vcu_pll_info(struct xvcu_device *xvcu)
int ret, i; int ret, i;
const struct xvcu_pll_cfg *found = NULL; const struct xvcu_pll_cfg *found = NULL;
inte = xvcu_read(xvcu->logicore_reg_ba, VCU_PLL_CLK); regmap_read(xvcu->logicore_reg_ba, VCU_PLL_CLK, &inte);
deci = xvcu_read(xvcu->logicore_reg_ba, VCU_PLL_CLK_DEC); regmap_read(xvcu->logicore_reg_ba, VCU_PLL_CLK_DEC, &deci);
coreclk = xvcu_read(xvcu->logicore_reg_ba, VCU_CORE_CLK) * MHZ; regmap_read(xvcu->logicore_reg_ba, VCU_CORE_CLK, &coreclk);
mcuclk = xvcu_read(xvcu->logicore_reg_ba, VCU_MCU_CLK) * MHZ; coreclk *= MHZ;
regmap_read(xvcu->logicore_reg_ba, VCU_MCU_CLK, &mcuclk);
mcuclk *= MHZ;
if (!mcuclk || !coreclk) { if (!mcuclk || !coreclk) {
dev_err(xvcu->dev, "Invalid mcu and core clock data\n"); dev_err(xvcu->dev, "Invalid mcu and core clock data\n");
return -EINVAL; return -EINVAL;
@ -498,6 +482,7 @@ static int xvcu_probe(struct platform_device *pdev)
{ {
struct resource *res; struct resource *res;
struct xvcu_device *xvcu; struct xvcu_device *xvcu;
void __iomem *regs;
int ret; int ret;
xvcu = devm_kzalloc(&pdev->dev, sizeof(*xvcu), GFP_KERNEL); xvcu = devm_kzalloc(&pdev->dev, sizeof(*xvcu), GFP_KERNEL);
@ -518,19 +503,34 @@ static int xvcu_probe(struct platform_device *pdev)
return -ENOMEM; return -ENOMEM;
} }
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "logicore"); xvcu->logicore_reg_ba =
syscon_regmap_lookup_by_compatible("xlnx,vcu-settings");
if (IS_ERR(xvcu->logicore_reg_ba)) {
dev_info(&pdev->dev,
"could not find xlnx,vcu-settings: trying direct register access\n");
res = platform_get_resource_byname(pdev,
IORESOURCE_MEM, "logicore");
if (!res) { if (!res) {
dev_err(&pdev->dev, "get logicore memory resource failed.\n"); dev_err(&pdev->dev, "get logicore memory resource failed.\n");
return -ENODEV; return -ENODEV;
} }
xvcu->logicore_reg_ba = devm_ioremap(&pdev->dev, res->start, regs = devm_ioremap(&pdev->dev, res->start, resource_size(res));
resource_size(res)); if (!regs) {
if (!xvcu->logicore_reg_ba) {
dev_err(&pdev->dev, "logicore register mapping failed.\n"); dev_err(&pdev->dev, "logicore register mapping failed.\n");
return -ENOMEM; return -ENOMEM;
} }
xvcu->logicore_reg_ba =
devm_regmap_init_mmio(&pdev->dev, regs,
&vcu_settings_regmap_config);
if (IS_ERR(xvcu->logicore_reg_ba)) {
dev_err(&pdev->dev, "failed to init regmap\n");
return PTR_ERR(xvcu->logicore_reg_ba);
}
}
xvcu->aclk = devm_clk_get(&pdev->dev, "aclk"); xvcu->aclk = devm_clk_get(&pdev->dev, "aclk");
if (IS_ERR(xvcu->aclk)) { if (IS_ERR(xvcu->aclk)) {
dev_err(&pdev->dev, "Could not get aclk clock\n"); dev_err(&pdev->dev, "Could not get aclk clock\n");
@ -560,7 +560,7 @@ static int xvcu_probe(struct platform_device *pdev)
* Bit 0 : Gasket isolation * Bit 0 : Gasket isolation
* Bit 1 : put VCU out of reset * Bit 1 : put VCU out of reset
*/ */
xvcu_write(xvcu->logicore_reg_ba, VCU_GASKET_INIT, VCU_GASKET_VALUE); regmap_write(xvcu->logicore_reg_ba, VCU_GASKET_INIT, VCU_GASKET_VALUE);
/* Do the PLL Settings based on the ref clk,core and mcu clk freq */ /* Do the PLL Settings based on the ref clk,core and mcu clk freq */
ret = xvcu_set_pll(xvcu); ret = xvcu_set_pll(xvcu);
@ -597,7 +597,7 @@ static int xvcu_remove(struct platform_device *pdev)
return -ENODEV; return -ENODEV;
/* Add the the Gasket isolation and put the VCU in reset. */ /* Add the the Gasket isolation and put the VCU in reset. */
xvcu_write(xvcu->logicore_reg_ba, VCU_GASKET_INIT, 0); regmap_write(xvcu->logicore_reg_ba, VCU_GASKET_INIT, 0);
clk_disable_unprepare(xvcu->pll_ref); clk_disable_unprepare(xvcu->pll_ref);
clk_disable_unprepare(xvcu->aclk); clk_disable_unprepare(xvcu->aclk);

View File

@ -0,0 +1,38 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (C) 2020 Pengutronix, Michael Tretter <kernel@pengutronix.de>
*/
#ifndef __XLNX_VCU_H
#define __XLNX_VCU_H
#define VCU_ECODER_ENABLE 0x00
#define VCU_DECODER_ENABLE 0x04
#define VCU_MEMORY_DEPTH 0x08
#define VCU_ENC_COLOR_DEPTH 0x0c
#define VCU_ENC_VERTICAL_RANGE 0x10
#define VCU_ENC_FRAME_SIZE_X 0x14
#define VCU_ENC_FRAME_SIZE_Y 0x18
#define VCU_ENC_COLOR_FORMAT 0x1c
#define VCU_ENC_FPS 0x20
#define VCU_MCU_CLK 0x24
#define VCU_CORE_CLK 0x28
#define VCU_PLL_BYPASS 0x2c
#define VCU_ENC_CLK 0x30
#define VCU_PLL_CLK 0x34
#define VCU_ENC_VIDEO_STANDARD 0x38
#define VCU_STATUS 0x3c
#define VCU_AXI_ENC_CLK 0x40
#define VCU_AXI_DEC_CLK 0x44
#define VCU_AXI_MCU_CLK 0x48
#define VCU_DEC_VIDEO_STANDARD 0x4c
#define VCU_DEC_FRAME_SIZE_X 0x50
#define VCU_DEC_FRAME_SIZE_Y 0x54
#define VCU_DEC_FPS 0x58
#define VCU_BUFFER_B_FRAME 0x5c
#define VCU_WPP_EN 0x60
#define VCU_PLL_CLK_DEC 0x64
#define VCU_GASKET_INIT 0x74
#define VCU_GASKET_VALUE 0x03
#endif /* __XLNX_VCU_H */