Commit 51b5760e authored by Suman Anna's avatar Suman Anna Committed by Nishanth Menon
Browse files

soc: ti: pruss: Add pruss_cfg_read()/update(), pruss_cfg_get_gpmux()/set_gpmux() APIs



Add two new generic API pruss_cfg_read() and pruss_cfg_update() to
the PRUSS platform driver to read and program respectively a register
within the PRUSS CFG sub-module represented by a syscon driver. These
APIs are internal to PRUSS driver.

Add two new helper functions pruss_cfg_get_gpmux() & pruss_cfg_set_gpmux()
to get and set the GP MUX mode for programming the PRUSS internal wrapper
mux functionality as needed by usecases.

Various useful registers and macros for certain register bit-fields and
their values have also been added.

Signed-off-by: default avatarSuman Anna <s-anna@ti.com>
Co-developed-by: default avatarGrzegorz Jaszczyk <grzegorz.jaszczyk@linaro.org>
Signed-off-by: default avatarGrzegorz Jaszczyk <grzegorz.jaszczyk@linaro.org>
Signed-off-by: default avatarPuranjay Mohan <p-mohan@ti.com>
Reviewed-by: default avatarRoger Quadros <rogerq@kernel.org>
Reviewed-by: default avatarTony Lindgren <tony@atomide.com>
Reviewed-by: default avatarSimon Horman <simon.horman@corigine.com>
Acked-by: default avatarMathieu Poirier <mathieu.poirier@linaro.org>
Signed-off-by: default avatarMD Danish Anwar <danishanwar@ti.com>
Link: https://lore.kernel.org/r/20230414045542.3249939-4-danishanwar@ti.com


Signed-off-by: default avatarNishanth Menon <nm@ti.com>
parent b789ca1e
Loading
Loading
Loading
Loading
+45 −0
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@
#include <linux/regmap.h>
#include <linux/remoteproc.h>
#include <linux/slab.h>
#include "pruss.h"

/**
 * struct pruss_private_data - PRUSS driver private data
@@ -168,6 +169,50 @@ int pruss_release_mem_region(struct pruss *pruss,
}
EXPORT_SYMBOL_GPL(pruss_release_mem_region);

/**
 * pruss_cfg_get_gpmux() - get the current GPMUX value for a PRU device
 * @pruss: pruss instance
 * @pru_id: PRU identifier (0-1)
 * @mux: pointer to store the current mux value into
 *
 * Return: 0 on success, or an error code otherwise
 */
int pruss_cfg_get_gpmux(struct pruss *pruss, enum pruss_pru_id pru_id, u8 *mux)
{
	int ret;
	u32 val;

	if (pru_id >= PRUSS_NUM_PRUS || !mux)
		return -EINVAL;

	ret = pruss_cfg_read(pruss, PRUSS_CFG_GPCFG(pru_id), &val);
	if (!ret)
		*mux = (u8)((val & PRUSS_GPCFG_PRU_MUX_SEL_MASK) >>
			    PRUSS_GPCFG_PRU_MUX_SEL_SHIFT);
	return ret;
}
EXPORT_SYMBOL_GPL(pruss_cfg_get_gpmux);

/**
 * pruss_cfg_set_gpmux() - set the GPMUX value for a PRU device
 * @pruss: pruss instance
 * @pru_id: PRU identifier (0-1)
 * @mux: new mux value for PRU
 *
 * Return: 0 on success, or an error code otherwise
 */
int pruss_cfg_set_gpmux(struct pruss *pruss, enum pruss_pru_id pru_id, u8 mux)
{
	if (mux >= PRUSS_GP_MUX_SEL_MAX ||
	    pru_id >= PRUSS_NUM_PRUS)
		return -EINVAL;

	return pruss_cfg_update(pruss, PRUSS_CFG_GPCFG(pru_id),
				PRUSS_GPCFG_PRU_MUX_SEL_MASK,
				(u32)mux << PRUSS_GPCFG_PRU_MUX_SEL_SHIFT);
}
EXPORT_SYMBOL_GPL(pruss_cfg_set_gpmux);

static void pruss_of_free_clk_provider(void *data)
{
	struct device_node *clk_mux_np = data;

drivers/soc/ti/pruss.h

0 → 100644
+88 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * PRU-ICSS Subsystem user interfaces
 *
 * Copyright (C) 2015-2023 Texas Instruments Incorporated - http://www.ti.com
 *	MD Danish Anwar <danishanwar@ti.com>
 */

#ifndef _SOC_TI_PRUSS_H_
#define _SOC_TI_PRUSS_H_

#include <linux/bits.h>
#include <linux/regmap.h>

/*
 * PRU_ICSS_CFG registers
 * SYSCFG, ISRP, ISP, IESP, IECP, SCRP applicable on AMxxxx devices only
 */
#define PRUSS_CFG_REVID         0x00
#define PRUSS_CFG_SYSCFG        0x04
#define PRUSS_CFG_GPCFG(x)      (0x08 + (x) * 4)
#define PRUSS_CFG_CGR           0x10
#define PRUSS_CFG_ISRP          0x14
#define PRUSS_CFG_ISP           0x18
#define PRUSS_CFG_IESP          0x1C
#define PRUSS_CFG_IECP          0x20
#define PRUSS_CFG_SCRP          0x24
#define PRUSS_CFG_PMAO          0x28
#define PRUSS_CFG_MII_RT        0x2C
#define PRUSS_CFG_IEPCLK        0x30
#define PRUSS_CFG_SPP           0x34
#define PRUSS_CFG_PIN_MX        0x40

/* PRUSS_GPCFG register bits */
#define PRUSS_GPCFG_PRU_GPI_MODE_MASK           GENMASK(1, 0)
#define PRUSS_GPCFG_PRU_GPI_MODE_SHIFT          0

#define PRUSS_GPCFG_PRU_MUX_SEL_SHIFT           26
#define PRUSS_GPCFG_PRU_MUX_SEL_MASK            GENMASK(29, 26)

/* PRUSS_MII_RT register bits */
#define PRUSS_MII_RT_EVENT_EN                   BIT(0)

/* PRUSS_SPP register bits */
#define PRUSS_SPP_XFER_SHIFT_EN                 BIT(1)
#define PRUSS_SPP_PRU1_PAD_HP_EN                BIT(0)
#define PRUSS_SPP_RTU_XFR_SHIFT_EN              BIT(3)

/**
 * pruss_cfg_read() - read a PRUSS CFG sub-module register
 * @pruss: the pruss instance handle
 * @reg: register offset within the CFG sub-module
 * @val: pointer to return the value in
 *
 * Reads a given register within the PRUSS CFG sub-module and
 * returns it through the passed-in @val pointer
 *
 * Return: 0 on success, or an error code otherwise
 */
static int pruss_cfg_read(struct pruss *pruss, unsigned int reg, unsigned int *val)
{
	if (IS_ERR_OR_NULL(pruss))
		return -EINVAL;

	return regmap_read(pruss->cfg_regmap, reg, val);
}

/**
 * pruss_cfg_update() - configure a PRUSS CFG sub-module register
 * @pruss: the pruss instance handle
 * @reg: register offset within the CFG sub-module
 * @mask: bit mask to use for programming the @val
 * @val: value to write
 *
 * Programs a given register within the PRUSS CFG sub-module
 *
 * Return: 0 on success, or an error code otherwise
 */
static int pruss_cfg_update(struct pruss *pruss, unsigned int reg,
			    unsigned int mask, unsigned int val)
{
	if (IS_ERR_OR_NULL(pruss))
		return -EINVAL;

	return regmap_update_bits(pruss->cfg_regmap, reg, mask, val);
}

#endif  /* _SOC_TI_PRUSS_H_ */
+32 −0
Original line number Diff line number Diff line
@@ -14,6 +14,24 @@
#include <linux/types.h>
#include <linux/err.h>

/*
 * enum pruss_gp_mux_sel - PRUSS GPI/O Mux modes for the
 * PRUSS_GPCFG0/1 registers
 *
 * NOTE: The below defines are the most common values, but there
 * are some exceptions like on 66AK2G, where the RESERVED and MII2
 * values are interchanged. Also, this bit-field does not exist on
 * AM335x SoCs
 */
enum pruss_gp_mux_sel {
	PRUSS_GP_MUX_SEL_GP,
	PRUSS_GP_MUX_SEL_ENDAT,
	PRUSS_GP_MUX_SEL_RESERVED,
	PRUSS_GP_MUX_SEL_SD,
	PRUSS_GP_MUX_SEL_MII2,
	PRUSS_GP_MUX_SEL_MAX,
};

/*
 * enum pruss_mem - PRUSS memory range identifiers
 */
@@ -66,6 +84,8 @@ int pruss_request_mem_region(struct pruss *pruss, enum pruss_mem mem_id,
			     struct pruss_mem_region *region);
int pruss_release_mem_region(struct pruss *pruss,
			     struct pruss_mem_region *region);
int pruss_cfg_get_gpmux(struct pruss *pruss, enum pruss_pru_id pru_id, u8 *mux);
int pruss_cfg_set_gpmux(struct pruss *pruss, enum pruss_pru_id pru_id, u8 mux);

#else

@@ -89,6 +109,18 @@ static inline int pruss_release_mem_region(struct pruss *pruss,
	return -EOPNOTSUPP;
}

static inline int pruss_cfg_get_gpmux(struct pruss *pruss,
				      enum pruss_pru_id pru_id, u8 *mux)
{
	return ERR_PTR(-EOPNOTSUPP);
}

static inline int pruss_cfg_set_gpmux(struct pruss *pruss,
				      enum pruss_pru_id pru_id, u8 mux)
{
	return ERR_PTR(-EOPNOTSUPP);
}

#endif /* CONFIG_TI_PRUSS */

#endif	/* _PRUSS_DRIVER_H_ */