Skip to content

Commit 51b5760

Browse files
sumanannanmenon
authored andcommitted
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: Suman Anna <s-anna@ti.com> Co-developed-by: Grzegorz Jaszczyk <grzegorz.jaszczyk@linaro.org> Signed-off-by: Grzegorz Jaszczyk <grzegorz.jaszczyk@linaro.org> Signed-off-by: Puranjay Mohan <p-mohan@ti.com> Reviewed-by: Roger Quadros <rogerq@kernel.org> Reviewed-by: Tony Lindgren <tony@atomide.com> Reviewed-by: Simon Horman <simon.horman@corigine.com> Acked-by: Mathieu Poirier <mathieu.poirier@linaro.org> Signed-off-by: MD Danish Anwar <danishanwar@ti.com> Link: https://lore.kernel.org/r/20230414045542.3249939-4-danishanwar@ti.com Signed-off-by: Nishanth Menon <nm@ti.com>
1 parent b789ca1 commit 51b5760

3 files changed

Lines changed: 165 additions & 0 deletions

File tree

drivers/soc/ti/pruss.c

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include <linux/regmap.h>
2222
#include <linux/remoteproc.h>
2323
#include <linux/slab.h>
24+
#include "pruss.h"
2425

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

172+
/**
173+
* pruss_cfg_get_gpmux() - get the current GPMUX value for a PRU device
174+
* @pruss: pruss instance
175+
* @pru_id: PRU identifier (0-1)
176+
* @mux: pointer to store the current mux value into
177+
*
178+
* Return: 0 on success, or an error code otherwise
179+
*/
180+
int pruss_cfg_get_gpmux(struct pruss *pruss, enum pruss_pru_id pru_id, u8 *mux)
181+
{
182+
int ret;
183+
u32 val;
184+
185+
if (pru_id >= PRUSS_NUM_PRUS || !mux)
186+
return -EINVAL;
187+
188+
ret = pruss_cfg_read(pruss, PRUSS_CFG_GPCFG(pru_id), &val);
189+
if (!ret)
190+
*mux = (u8)((val & PRUSS_GPCFG_PRU_MUX_SEL_MASK) >>
191+
PRUSS_GPCFG_PRU_MUX_SEL_SHIFT);
192+
return ret;
193+
}
194+
EXPORT_SYMBOL_GPL(pruss_cfg_get_gpmux);
195+
196+
/**
197+
* pruss_cfg_set_gpmux() - set the GPMUX value for a PRU device
198+
* @pruss: pruss instance
199+
* @pru_id: PRU identifier (0-1)
200+
* @mux: new mux value for PRU
201+
*
202+
* Return: 0 on success, or an error code otherwise
203+
*/
204+
int pruss_cfg_set_gpmux(struct pruss *pruss, enum pruss_pru_id pru_id, u8 mux)
205+
{
206+
if (mux >= PRUSS_GP_MUX_SEL_MAX ||
207+
pru_id >= PRUSS_NUM_PRUS)
208+
return -EINVAL;
209+
210+
return pruss_cfg_update(pruss, PRUSS_CFG_GPCFG(pru_id),
211+
PRUSS_GPCFG_PRU_MUX_SEL_MASK,
212+
(u32)mux << PRUSS_GPCFG_PRU_MUX_SEL_SHIFT);
213+
}
214+
EXPORT_SYMBOL_GPL(pruss_cfg_set_gpmux);
215+
171216
static void pruss_of_free_clk_provider(void *data)
172217
{
173218
struct device_node *clk_mux_np = data;

drivers/soc/ti/pruss.h

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
/* SPDX-License-Identifier: GPL-2.0-only */
2+
/*
3+
* PRU-ICSS Subsystem user interfaces
4+
*
5+
* Copyright (C) 2015-2023 Texas Instruments Incorporated - http://www.ti.com
6+
* MD Danish Anwar <danishanwar@ti.com>
7+
*/
8+
9+
#ifndef _SOC_TI_PRUSS_H_
10+
#define _SOC_TI_PRUSS_H_
11+
12+
#include <linux/bits.h>
13+
#include <linux/regmap.h>
14+
15+
/*
16+
* PRU_ICSS_CFG registers
17+
* SYSCFG, ISRP, ISP, IESP, IECP, SCRP applicable on AMxxxx devices only
18+
*/
19+
#define PRUSS_CFG_REVID 0x00
20+
#define PRUSS_CFG_SYSCFG 0x04
21+
#define PRUSS_CFG_GPCFG(x) (0x08 + (x) * 4)
22+
#define PRUSS_CFG_CGR 0x10
23+
#define PRUSS_CFG_ISRP 0x14
24+
#define PRUSS_CFG_ISP 0x18
25+
#define PRUSS_CFG_IESP 0x1C
26+
#define PRUSS_CFG_IECP 0x20
27+
#define PRUSS_CFG_SCRP 0x24
28+
#define PRUSS_CFG_PMAO 0x28
29+
#define PRUSS_CFG_MII_RT 0x2C
30+
#define PRUSS_CFG_IEPCLK 0x30
31+
#define PRUSS_CFG_SPP 0x34
32+
#define PRUSS_CFG_PIN_MX 0x40
33+
34+
/* PRUSS_GPCFG register bits */
35+
#define PRUSS_GPCFG_PRU_GPI_MODE_MASK GENMASK(1, 0)
36+
#define PRUSS_GPCFG_PRU_GPI_MODE_SHIFT 0
37+
38+
#define PRUSS_GPCFG_PRU_MUX_SEL_SHIFT 26
39+
#define PRUSS_GPCFG_PRU_MUX_SEL_MASK GENMASK(29, 26)
40+
41+
/* PRUSS_MII_RT register bits */
42+
#define PRUSS_MII_RT_EVENT_EN BIT(0)
43+
44+
/* PRUSS_SPP register bits */
45+
#define PRUSS_SPP_XFER_SHIFT_EN BIT(1)
46+
#define PRUSS_SPP_PRU1_PAD_HP_EN BIT(0)
47+
#define PRUSS_SPP_RTU_XFR_SHIFT_EN BIT(3)
48+
49+
/**
50+
* pruss_cfg_read() - read a PRUSS CFG sub-module register
51+
* @pruss: the pruss instance handle
52+
* @reg: register offset within the CFG sub-module
53+
* @val: pointer to return the value in
54+
*
55+
* Reads a given register within the PRUSS CFG sub-module and
56+
* returns it through the passed-in @val pointer
57+
*
58+
* Return: 0 on success, or an error code otherwise
59+
*/
60+
static int pruss_cfg_read(struct pruss *pruss, unsigned int reg, unsigned int *val)
61+
{
62+
if (IS_ERR_OR_NULL(pruss))
63+
return -EINVAL;
64+
65+
return regmap_read(pruss->cfg_regmap, reg, val);
66+
}
67+
68+
/**
69+
* pruss_cfg_update() - configure a PRUSS CFG sub-module register
70+
* @pruss: the pruss instance handle
71+
* @reg: register offset within the CFG sub-module
72+
* @mask: bit mask to use for programming the @val
73+
* @val: value to write
74+
*
75+
* Programs a given register within the PRUSS CFG sub-module
76+
*
77+
* Return: 0 on success, or an error code otherwise
78+
*/
79+
static int pruss_cfg_update(struct pruss *pruss, unsigned int reg,
80+
unsigned int mask, unsigned int val)
81+
{
82+
if (IS_ERR_OR_NULL(pruss))
83+
return -EINVAL;
84+
85+
return regmap_update_bits(pruss->cfg_regmap, reg, mask, val);
86+
}
87+
88+
#endif /* _SOC_TI_PRUSS_H_ */

include/linux/pruss_driver.h

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,24 @@
1414
#include <linux/types.h>
1515
#include <linux/err.h>
1616

17+
/*
18+
* enum pruss_gp_mux_sel - PRUSS GPI/O Mux modes for the
19+
* PRUSS_GPCFG0/1 registers
20+
*
21+
* NOTE: The below defines are the most common values, but there
22+
* are some exceptions like on 66AK2G, where the RESERVED and MII2
23+
* values are interchanged. Also, this bit-field does not exist on
24+
* AM335x SoCs
25+
*/
26+
enum pruss_gp_mux_sel {
27+
PRUSS_GP_MUX_SEL_GP,
28+
PRUSS_GP_MUX_SEL_ENDAT,
29+
PRUSS_GP_MUX_SEL_RESERVED,
30+
PRUSS_GP_MUX_SEL_SD,
31+
PRUSS_GP_MUX_SEL_MII2,
32+
PRUSS_GP_MUX_SEL_MAX,
33+
};
34+
1735
/*
1836
* enum pruss_mem - PRUSS memory range identifiers
1937
*/
@@ -66,6 +84,8 @@ int pruss_request_mem_region(struct pruss *pruss, enum pruss_mem mem_id,
6684
struct pruss_mem_region *region);
6785
int pruss_release_mem_region(struct pruss *pruss,
6886
struct pruss_mem_region *region);
87+
int pruss_cfg_get_gpmux(struct pruss *pruss, enum pruss_pru_id pru_id, u8 *mux);
88+
int pruss_cfg_set_gpmux(struct pruss *pruss, enum pruss_pru_id pru_id, u8 mux);
6989

7090
#else
7191

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

112+
static inline int pruss_cfg_get_gpmux(struct pruss *pruss,
113+
enum pruss_pru_id pru_id, u8 *mux)
114+
{
115+
return ERR_PTR(-EOPNOTSUPP);
116+
}
117+
118+
static inline int pruss_cfg_set_gpmux(struct pruss *pruss,
119+
enum pruss_pru_id pru_id, u8 mux)
120+
{
121+
return ERR_PTR(-EOPNOTSUPP);
122+
}
123+
92124
#endif /* CONFIG_TI_PRUSS */
93125

94126
#endif /* _PRUSS_DRIVER_H_ */

0 commit comments

Comments
 (0)