mirror of https://gitee.com/openkylin/linux.git
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>
This commit is contained in:
parent
a3857f89dd
commit
30b79eb1f9
|
@ -4,6 +4,7 @@ menu "Xilinx SoC drivers"
|
|||
config XILINX_VCU
|
||||
tristate "Xilinx VCU logicoreIP Init"
|
||||
depends on HAS_IOMEM
|
||||
select REGMAP_MMIO
|
||||
help
|
||||
Provides the driver to enable and disable the isolation between the
|
||||
processing system and programmable logic part by using the logicoreIP
|
||||
|
|
|
@ -10,39 +10,12 @@
|
|||
#include <linux/device.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/mfd/syscon.h>
|
||||
#include <linux/mfd/syscon/xlnx-vcu.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/platform_device.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
|
||||
#include <linux/regmap.h>
|
||||
|
||||
/* vcu slcr registers, bitmask and shift */
|
||||
#define VCU_PLL_CTRL 0x24
|
||||
|
@ -106,11 +79,20 @@ struct xvcu_device {
|
|||
struct device *dev;
|
||||
struct clk *pll_ref;
|
||||
struct clk *aclk;
|
||||
void __iomem *logicore_reg_ba;
|
||||
struct regmap *logicore_reg_ba;
|
||||
void __iomem *vcu_slcr_ba;
|
||||
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
|
||||
* @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;
|
||||
const struct xvcu_pll_cfg *found = NULL;
|
||||
|
||||
inte = xvcu_read(xvcu->logicore_reg_ba, VCU_PLL_CLK);
|
||||
deci = xvcu_read(xvcu->logicore_reg_ba, VCU_PLL_CLK_DEC);
|
||||
coreclk = xvcu_read(xvcu->logicore_reg_ba, VCU_CORE_CLK) * MHZ;
|
||||
mcuclk = xvcu_read(xvcu->logicore_reg_ba, VCU_MCU_CLK) * MHZ;
|
||||
regmap_read(xvcu->logicore_reg_ba, VCU_PLL_CLK, &inte);
|
||||
regmap_read(xvcu->logicore_reg_ba, VCU_PLL_CLK_DEC, &deci);
|
||||
regmap_read(xvcu->logicore_reg_ba, VCU_CORE_CLK, &coreclk);
|
||||
coreclk *= MHZ;
|
||||
regmap_read(xvcu->logicore_reg_ba, VCU_MCU_CLK, &mcuclk);
|
||||
mcuclk *= MHZ;
|
||||
if (!mcuclk || !coreclk) {
|
||||
dev_err(xvcu->dev, "Invalid mcu and core clock data\n");
|
||||
return -EINVAL;
|
||||
|
@ -498,6 +482,7 @@ static int xvcu_probe(struct platform_device *pdev)
|
|||
{
|
||||
struct resource *res;
|
||||
struct xvcu_device *xvcu;
|
||||
void __iomem *regs;
|
||||
int ret;
|
||||
|
||||
xvcu = devm_kzalloc(&pdev->dev, sizeof(*xvcu), GFP_KERNEL);
|
||||
|
@ -518,17 +503,32 @@ static int xvcu_probe(struct platform_device *pdev)
|
|||
return -ENOMEM;
|
||||
}
|
||||
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "logicore");
|
||||
if (!res) {
|
||||
dev_err(&pdev->dev, "get logicore memory resource failed.\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
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");
|
||||
|
||||
xvcu->logicore_reg_ba = devm_ioremap(&pdev->dev, res->start,
|
||||
resource_size(res));
|
||||
if (!xvcu->logicore_reg_ba) {
|
||||
dev_err(&pdev->dev, "logicore register mapping failed.\n");
|
||||
return -ENOMEM;
|
||||
res = platform_get_resource_byname(pdev,
|
||||
IORESOURCE_MEM, "logicore");
|
||||
if (!res) {
|
||||
dev_err(&pdev->dev, "get logicore memory resource failed.\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
regs = devm_ioremap(&pdev->dev, res->start, resource_size(res));
|
||||
if (!regs) {
|
||||
dev_err(&pdev->dev, "logicore register mapping failed.\n");
|
||||
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");
|
||||
|
@ -560,7 +560,7 @@ static int xvcu_probe(struct platform_device *pdev)
|
|||
* Bit 0 : Gasket isolation
|
||||
* 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 */
|
||||
ret = xvcu_set_pll(xvcu);
|
||||
|
@ -597,7 +597,7 @@ static int xvcu_remove(struct platform_device *pdev)
|
|||
return -ENODEV;
|
||||
|
||||
/* 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->aclk);
|
||||
|
|
|
@ -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 */
|
Loading…
Reference in New Issue