Lines Matching +full:pruss +full:- +full:mii
1 // SPDX-License-Identifier: GPL-2.0-only
3 * PRU-ICSS platform driver for various TI SoCs
5 * Copyright (C) 2014-2020 Texas Instruments Incorporated - http://www.ti.com/
7 * Suman Anna <s-anna@ti.com>
9 * Tero Kristo <t-kristo@ti.com>
12 #include <linux/clk-provider.h>
13 #include <linux/dma-mapping.h>
26 #include "pruss.h"
29 * struct pruss_private_data - PRUSS driver private data
30 * @has_no_sharedram: flag to indicate the absence of PRUSS Shared Data RAM
31 * @has_core_mux_clock: flag to indicate the presence of PRUSS core clock
39 * pruss_get() - get the pruss for a given PRU remoteproc
42 * Finds the parent pruss device for a PRU given the @rproc handle of the
43 * PRU remote processor. This function increments the pruss device's refcount,
44 * so always use pruss_put() to decrement it back once pruss isn't needed
51 * Return: pruss handle on success, and an ERR_PTR on failure using one
53 * -EINVAL if invalid parameter
54 * -ENODEV if PRU device or PRUSS device is not found
56 struct pruss *pruss_get(struct rproc *rproc) in pruss_get()
58 struct pruss *pruss; in pruss_get() local
63 return ERR_PTR(-EINVAL); in pruss_get()
65 dev = &rproc->dev; in pruss_get()
68 if (!dev->parent || !is_pru_rproc(dev->parent)) in pruss_get()
69 return ERR_PTR(-ENODEV); in pruss_get()
71 ppdev = to_platform_device(dev->parent->parent); in pruss_get()
72 pruss = platform_get_drvdata(ppdev); in pruss_get()
73 if (!pruss) in pruss_get()
74 return ERR_PTR(-ENODEV); in pruss_get()
76 get_device(pruss->dev); in pruss_get()
78 return pruss; in pruss_get()
83 * pruss_put() - decrement pruss device's usecount
84 * @pruss: pruss handle
87 * after the PRUSS is used, and only if the pruss_get() succeeds.
89 void pruss_put(struct pruss *pruss) in pruss_put() argument
91 if (IS_ERR_OR_NULL(pruss)) in pruss_put()
94 put_device(pruss->dev); in pruss_put()
99 * pruss_request_mem_region() - request a memory resource
100 * @pruss: the pruss instance
112 int pruss_request_mem_region(struct pruss *pruss, enum pruss_mem mem_id, in pruss_request_mem_region() argument
115 if (!pruss || !region || mem_id >= PRUSS_MEM_MAX) in pruss_request_mem_region()
116 return -EINVAL; in pruss_request_mem_region()
118 mutex_lock(&pruss->lock); in pruss_request_mem_region()
120 if (pruss->mem_in_use[mem_id]) { in pruss_request_mem_region()
121 mutex_unlock(&pruss->lock); in pruss_request_mem_region()
122 return -EBUSY; in pruss_request_mem_region()
125 *region = pruss->mem_regions[mem_id]; in pruss_request_mem_region()
126 pruss->mem_in_use[mem_id] = region; in pruss_request_mem_region()
128 mutex_unlock(&pruss->lock); in pruss_request_mem_region()
135 * pruss_release_mem_region() - release a memory resource
136 * @pruss: the pruss instance
145 int pruss_release_mem_region(struct pruss *pruss, in pruss_release_mem_region() argument
150 if (!pruss || !region) in pruss_release_mem_region()
151 return -EINVAL; in pruss_release_mem_region()
153 mutex_lock(&pruss->lock); in pruss_release_mem_region()
157 if (pruss->mem_in_use[id] == region) in pruss_release_mem_region()
162 mutex_unlock(&pruss->lock); in pruss_release_mem_region()
163 return -EINVAL; in pruss_release_mem_region()
166 pruss->mem_in_use[id] = NULL; in pruss_release_mem_region()
168 mutex_unlock(&pruss->lock); in pruss_release_mem_region()
175 * pruss_cfg_get_gpmux() - get the current GPMUX value for a PRU device
176 * @pruss: pruss instance
177 * @pru_id: PRU identifier (0-1)
182 int pruss_cfg_get_gpmux(struct pruss *pruss, enum pruss_pru_id pru_id, u8 *mux) in pruss_cfg_get_gpmux() argument
188 return -EINVAL; in pruss_cfg_get_gpmux()
190 ret = pruss_cfg_read(pruss, PRUSS_CFG_GPCFG(pru_id), &val); in pruss_cfg_get_gpmux()
199 * pruss_cfg_set_gpmux() - set the GPMUX value for a PRU device
200 * @pruss: pruss instance
201 * @pru_id: PRU identifier (0-1)
206 int pruss_cfg_set_gpmux(struct pruss *pruss, enum pruss_pru_id pru_id, u8 mux) in pruss_cfg_set_gpmux() argument
210 return -EINVAL; in pruss_cfg_set_gpmux()
212 return pruss_cfg_update(pruss, PRUSS_CFG_GPCFG(pru_id), in pruss_cfg_set_gpmux()
219 * pruss_cfg_gpimode() - set the GPI mode of the PRU
220 * @pruss: the pruss instance handle
221 * @pru_id: id of the PRU core within the PRUSS
229 int pruss_cfg_gpimode(struct pruss *pruss, enum pruss_pru_id pru_id, in pruss_cfg_gpimode() argument
233 return -EINVAL; in pruss_cfg_gpimode()
235 return pruss_cfg_update(pruss, PRUSS_CFG_GPCFG(pru_id), in pruss_cfg_gpimode()
242 * pruss_cfg_miirt_enable() - Enable/disable MII RT Events
243 * @pruss: the pruss instance
246 * Enable/disable the MII RT Events for the PRUSS.
250 int pruss_cfg_miirt_enable(struct pruss *pruss, bool enable) in pruss_cfg_miirt_enable() argument
254 return pruss_cfg_update(pruss, PRUSS_CFG_MII_RT, in pruss_cfg_miirt_enable()
260 * pruss_cfg_xfr_enable() - Enable/disable XIN XOUT shift functionality
261 * @pruss: the pruss instance
267 int pruss_cfg_xfr_enable(struct pruss *pruss, enum pru_type pru_type, in pruss_cfg_xfr_enable() argument
280 return -EINVAL; in pruss_cfg_xfr_enable()
285 return pruss_cfg_update(pruss, PRUSS_CFG_SPP, mask, set); in pruss_cfg_xfr_enable()
302 static int pruss_clk_mux_setup(struct pruss *pruss, struct clk *clk_mux, in pruss_clk_mux_setup() argument
306 struct device *dev = pruss->dev; in pruss_clk_mux_setup()
318 return -ENODEV; in pruss_clk_mux_setup()
323 dev_err(dev, "mux-clock %pOF must have parents\n", clk_mux_np); in pruss_clk_mux_setup()
324 ret = -EINVAL; in pruss_clk_mux_setup()
331 ret = -ENOMEM; in pruss_clk_mux_setup()
340 ret = -ENOMEM; in pruss_clk_mux_setup()
348 reg = pruss->cfg_base + reg_offset; in pruss_clk_mux_setup()
381 static int pruss_clk_init(struct pruss *pruss, struct device_node *cfg_node) in pruss_clk_init() argument
383 struct device *dev = pruss->dev; in pruss_clk_init()
390 return dev_err_probe(dev, -ENODEV, in pruss_clk_init()
394 if (data && data->has_core_mux_clock) { in pruss_clk_init()
395 ret = pruss_clk_mux_setup(pruss, pruss->core_clk_mux, in pruss_clk_init()
396 "coreclk-mux", clks_np); in pruss_clk_init()
399 "failed to setup coreclk-mux\n"); in pruss_clk_init()
402 ret = pruss_clk_mux_setup(pruss, pruss->iep_clk_mux, "iepclk-mux", in pruss_clk_init()
405 return dev_err_probe(dev, ret, "failed to setup iepclk-mux\n"); in pruss_clk_init()
410 static int pruss_of_setup_memories(struct device *dev, struct pruss *pruss) in pruss_of_setup_memories() argument
420 return dev_err_probe(dev, -ENODEV, in pruss_of_setup_memories()
429 * On AM437x one of two PRUSS units don't contain Shared RAM, in pruss_of_setup_memories()
432 if (data && data->has_no_sharedram && i == PRUSS_MEM_SHRD_RAM2) in pruss_of_setup_memories()
435 index = of_property_match_string(child, "reg-names", in pruss_of_setup_memories()
441 return -EINVAL; in pruss_of_setup_memories()
443 pruss->mem_regions[i].va = devm_ioremap(dev, res.start, in pruss_of_setup_memories()
445 if (!pruss->mem_regions[i].va) in pruss_of_setup_memories()
446 return dev_err_probe(dev, -ENOMEM, in pruss_of_setup_memories()
449 pruss->mem_regions[i].pa = res.start; in pruss_of_setup_memories()
450 pruss->mem_regions[i].size = resource_size(&res); in pruss_of_setup_memories()
453 mem_names[i], &pruss->mem_regions[i].pa, in pruss_of_setup_memories()
454 pruss->mem_regions[i].size, pruss->mem_regions[i].va); in pruss_of_setup_memories()
466 static int pruss_cfg_of_init(struct device *dev, struct pruss *pruss) in pruss_cfg_of_init() argument
475 return dev_err_probe(dev, -ENODEV, in pruss_cfg_of_init()
479 return -ENOMEM; in pruss_cfg_of_init()
481 pruss->cfg_base = devm_ioremap(dev, res.start, resource_size(&res)); in pruss_cfg_of_init()
482 if (!pruss->cfg_base) in pruss_cfg_of_init()
483 return -ENOMEM; in pruss_cfg_of_init()
487 regmap_conf.max_register = resource_size(&res) - 4; in pruss_cfg_of_init()
489 pruss->cfg_regmap = devm_regmap_init_mmio(dev, pruss->cfg_base, in pruss_cfg_of_init()
492 if (IS_ERR(pruss->cfg_regmap)) in pruss_cfg_of_init()
493 return dev_err_probe(dev, PTR_ERR(pruss->cfg_regmap), in pruss_cfg_of_init()
496 ret = pruss_clk_init(pruss, child); in pruss_cfg_of_init()
505 struct device *dev = &pdev->dev; in pruss_probe()
506 struct pruss *pruss; in pruss_probe() local
515 pruss = devm_kzalloc(dev, sizeof(*pruss), GFP_KERNEL); in pruss_probe()
516 if (!pruss) in pruss_probe()
517 return -ENOMEM; in pruss_probe()
519 pruss->dev = dev; in pruss_probe()
520 mutex_init(&pruss->lock); in pruss_probe()
522 ret = pruss_of_setup_memories(dev, pruss); in pruss_probe()
526 platform_set_drvdata(pdev, pruss); in pruss_probe()
535 ret = pruss_cfg_of_init(dev, pruss); in pruss_probe()
556 struct device *dev = &pdev->dev; in pruss_remove()
564 /* instance-specific driver private data */
578 { .compatible = "ti,am3356-pruss" },
579 { .compatible = "ti,am4376-pruss0", .data = &am437x_pruss0_data, },
580 { .compatible = "ti,am4376-pruss1", .data = &am437x_pruss1_data, },
581 { .compatible = "ti,am5728-pruss" },
582 { .compatible = "ti,k2g-pruss" },
583 { .compatible = "ti,am654-icssg", .data = &am65x_j721e_pruss_data, },
584 { .compatible = "ti,j721e-icssg", .data = &am65x_j721e_pruss_data, },
585 { .compatible = "ti,am642-icssg", .data = &am65x_j721e_pruss_data, },
586 { .compatible = "ti,am625-pruss", .data = &am65x_j721e_pruss_data, },
593 .name = "pruss",
601 MODULE_AUTHOR("Suman Anna <s-anna@ti.com>");
602 MODULE_DESCRIPTION("PRU-ICSS Subsystem Driver");