Skip to content

Commit

Permalink
Merge tag 'zynqmp-soc-for-v5.11-v2' of https://github.com/Xilinx/linu…
Browse files Browse the repository at this point in the history
…x-xlnx into arm/drivers

arm64: soc: ZynqMP SoC changes for v5.11 v2

- Small alignments in Xilinx Firmware driver
- Exposing syscon interface for VCU driver

* tag 'zynqmp-soc-for-v5.11-v2' of https://github.com/Xilinx/linux-xlnx:
  firmware: xilinx: Properly align function parameter
  firmware: xilinx: Add a blank line after function declaration
  firmware: xilinx: Remove additional newline
  firmware: xilinx: Fix kernel-doc warnings
  firmware: xlnx-zynqmp: fix compilation warning
  soc: xilinx: vcu: add missing register NUM_CORE
  soc: xilinx: vcu: use vcu-settings syscon registers
  dt-bindings: soc: xlnx: extract xlnx, vcu-settings to separate binding
  soc: xilinx: vcu: drop useless success message

Link: https://lore.kernel.org/r/71d38756-4456-29fc-26a3-341e1d09aafe@monstr.eu
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
  • Loading branch information
Arnd Bergmann committed Dec 9, 2020
2 parents 694a5b5 + 311c252 commit 629c962
Show file tree
Hide file tree
Showing 7 changed files with 186 additions and 84 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/soc/xilinx/xlnx,vcu-settings.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#

title: Xilinx VCU Settings

maintainers:
- Michael Tretter <kernel@pengutronix.de>

description: |
The Xilinx VCU Settings provides information about the configuration of the
video codec unit.
properties:
compatible:
items:
- const: xlnx,vcu-settings
- const: syscon

reg:
maxItems: 1

required:
- compatible
- reg

examples:
- |
xlnx_vcu: vcu@a0041000 {
compatible = "xlnx,vcu-settings", "syscon";
reg = <0x0 0xa0041000 0x0 0x1000>;
};
9 changes: 2 additions & 7 deletions Documentation/devicetree/bindings/soc/xilinx/xlnx,vcu.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,15 @@ Required properties:
- compatible: shall be one of:
"xlnx,vcu"
"xlnx,vcu-logicoreip-1.0"
- reg, reg-names: There are two sets of registers need to provide.
1. vcu slcr
2. Logicore
reg-names should contain name for the each register sequence.
- reg : The base offset and size of the VCU_PL_SLCR register space.
- clocks: phandle for aclk and pll_ref clocksource
- clock-names: The identification string, "aclk", is always required for
the axi clock. "pll_ref" is required for pll.
Example:

xlnx_vcu: vcu@a0040000 {
compatible = "xlnx,vcu-logicoreip-1.0";
reg = <0x0 0xa0040000 0x0 0x1000>,
<0x0 0xa0041000 0x0 0x1000>;
reg-names = "vcu_slcr", "logicore";
reg = <0x0 0xa0040000 0x0 0x1000>;
clocks = <&si570_1>, <&clkc 71>;
clock-names = "pll_ref", "aclk";
};
46 changes: 23 additions & 23 deletions drivers/firmware/xilinx/zynqmp.c
Original file line number Diff line number Diff line change
Expand Up @@ -585,13 +585,13 @@ EXPORT_SYMBOL_GPL(zynqmp_pm_get_pll_frac_data);
/**
* zynqmp_pm_set_sd_tapdelay() - Set tap delay for the SD device
*
* @node_id Node ID of the device
* @type Type of tap delay to set (input/output)
* @value Value to set fot the tap delay
* @node_id: Node ID of the device
* @type: Type of tap delay to set (input/output)
* @value: Value to set fot the tap delay
*
* This function sets input/output tap delay for the SD device.
*
* @return Returns status, either success or error+reason
* Return: Returns status, either success or error+reason
*/
int zynqmp_pm_set_sd_tapdelay(u32 node_id, u32 type, u32 value)
{
Expand All @@ -603,12 +603,12 @@ EXPORT_SYMBOL_GPL(zynqmp_pm_set_sd_tapdelay);
/**
* zynqmp_pm_sd_dll_reset() - Reset DLL logic
*
* @node_id Node ID of the device
* @type Reset type
* @node_id: Node ID of the device
* @type: Reset type
*
* This function resets DLL logic for the SD device.
*
* @return Returns status, either success or error+reason
* Return: Returns status, either success or error+reason
*/
int zynqmp_pm_sd_dll_reset(u32 node_id, u32 type)
{
Expand All @@ -619,12 +619,12 @@ EXPORT_SYMBOL_GPL(zynqmp_pm_sd_dll_reset);

/**
* zynqmp_pm_write_ggs() - PM API for writing global general storage (ggs)
* @index GGS register index
* @value Register value to be written
* @index: GGS register index
* @value: Register value to be written
*
* This function writes value to GGS register.
*
* @return Returns status, either success or error+reason
* Return: Returns status, either success or error+reason
*/
int zynqmp_pm_write_ggs(u32 index, u32 value)
{
Expand All @@ -635,12 +635,12 @@ EXPORT_SYMBOL_GPL(zynqmp_pm_write_ggs);

/**
* zynqmp_pm_write_ggs() - PM API for reading global general storage (ggs)
* @index GGS register index
* @value Register value to be written
* @index: GGS register index
* @value: Register value to be written
*
* This function returns GGS register value.
*
* @return Returns status, either success or error+reason
* Return: Returns status, either success or error+reason
*/
int zynqmp_pm_read_ggs(u32 index, u32 *value)
{
Expand All @@ -652,12 +652,12 @@ EXPORT_SYMBOL_GPL(zynqmp_pm_read_ggs);
/**
* zynqmp_pm_write_pggs() - PM API for writing persistent global general
* storage (pggs)
* @index PGGS register index
* @value Register value to be written
* @index: PGGS register index
* @value: Register value to be written
*
* This function writes value to PGGS register.
*
* @return Returns status, either success or error+reason
* Return: Returns status, either success or error+reason
*/
int zynqmp_pm_write_pggs(u32 index, u32 value)
{
Expand All @@ -669,12 +669,12 @@ EXPORT_SYMBOL_GPL(zynqmp_pm_write_pggs);
/**
* zynqmp_pm_write_pggs() - PM API for reading persistent global general
* storage (pggs)
* @index PGGS register index
* @value Register value to be written
* @index: PGGS register index
* @value: Register value to be written
*
* This function returns PGGS register value.
*
* @return Returns status, either success or error+reason
* Return: Returns status, either success or error+reason
*/
int zynqmp_pm_read_pggs(u32 index, u32 *value)
{
Expand All @@ -685,12 +685,12 @@ EXPORT_SYMBOL_GPL(zynqmp_pm_read_pggs);

/**
* zynqmp_pm_set_boot_health_status() - PM API for setting healthy boot status
* @value Status value to be written
* @value: Status value to be written
*
* This function sets healthy bit value to indicate boot health status
* to firmware.
*
* @return Returns status, either success or error+reason
* Return: Returns status, either success or error+reason
*/
int zynqmp_pm_set_boot_health_status(u32 value)
{
Expand Down Expand Up @@ -785,10 +785,10 @@ EXPORT_SYMBOL_GPL(zynqmp_pm_fpga_get_status);
* zynqmp_pm_init_finalize() - PM call to inform firmware that the caller
* master has initialized its own power management
*
* Return: Returns status, either success or error+reason
*
* This API function is to be used for notify the power management controller
* about the completed power management initialization.
*
* Return: Returns status, either success or error+reason
*/
int zynqmp_pm_init_finalize(void)
{
Expand Down
1 change: 1 addition & 0 deletions drivers/soc/xilinx/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
96 changes: 47 additions & 49 deletions drivers/soc/xilinx/xlnx_vcu.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand All @@ -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");

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 = 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;
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");
Expand Down Expand Up @@ -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);
Expand All @@ -571,8 +571,6 @@ static int xvcu_probe(struct platform_device *pdev)

dev_set_drvdata(&pdev->dev, xvcu);

dev_info(&pdev->dev, "%s: Probed successfully\n", __func__);

return 0;

error_pll_ref:
Expand All @@ -599,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);
Expand Down
Loading

0 comments on commit 629c962

Please sign in to comment.