VisionFive2 Linux kernel

StarFive Tech Linux Kernel for VisionFive (JH7110) boards (mirror)

More than 9999 Commits   33 Branches   55 Tags
8e8e69d67e5fa (Thomas Gleixner    2019-05-29 07:17:59 -0700   1) // SPDX-License-Identifier: GPL-2.0-only
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500   2) /*
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500   3)  * Copyright (c) 2017, National Instruments Corp.
30a2ac9a8bb5f (Nava kishore Manne 2021-02-11 10:41:48 +0530   4)  * Copyright (c) 2017, Xilinx Inc
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500   5)  *
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500   6)  * FPGA Bridge Driver for the Xilinx LogiCORE Partial Reconfiguration
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500   7)  * Decoupler IP Core.
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500   8)  */
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500   9) 
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500  10) #include <linux/clk.h>
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500  11) #include <linux/io.h>
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500  12) #include <linux/kernel.h>
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500  13) #include <linux/of_device.h>
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500  14) #include <linux/module.h>
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500  15) #include <linux/fpga/fpga-bridge.h>
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500  16) 
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500  17) #define CTRL_CMD_DECOUPLE	BIT(0)
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500  18) #define CTRL_CMD_COUPLE		0
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500  19) #define CTRL_OFFSET		0
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500  20) 
30a2ac9a8bb5f (Nava kishore Manne 2021-02-11 10:41:48 +0530  21) struct xlnx_config_data {
30a2ac9a8bb5f (Nava kishore Manne 2021-02-11 10:41:48 +0530  22) 	const char *name;
30a2ac9a8bb5f (Nava kishore Manne 2021-02-11 10:41:48 +0530  23) };
30a2ac9a8bb5f (Nava kishore Manne 2021-02-11 10:41:48 +0530  24) 
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500  25) struct xlnx_pr_decoupler_data {
30a2ac9a8bb5f (Nava kishore Manne 2021-02-11 10:41:48 +0530  26) 	const struct xlnx_config_data *ipconfig;
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500  27) 	void __iomem *io_base;
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500  28) 	struct clk *clk;
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500  29) };
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500  30) 
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500  31) static inline void xlnx_pr_decoupler_write(struct xlnx_pr_decoupler_data *d,
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500  32) 					   u32 offset, u32 val)
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500  33) {
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500  34) 	writel(val, d->io_base + offset);
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500  35) }
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500  36) 
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500  37) static inline u32 xlnx_pr_decouple_read(const struct xlnx_pr_decoupler_data *d,
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500  38) 					u32 offset)
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500  39) {
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500  40) 	return readl(d->io_base + offset);
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500  41) }
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500  42) 
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500  43) static int xlnx_pr_decoupler_enable_set(struct fpga_bridge *bridge, bool enable)
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500  44) {
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500  45) 	int err;
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500  46) 	struct xlnx_pr_decoupler_data *priv = bridge->priv;
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500  47) 
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500  48) 	err = clk_enable(priv->clk);
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500  49) 	if (err)
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500  50) 		return err;
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500  51) 
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500  52) 	if (enable)
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500  53) 		xlnx_pr_decoupler_write(priv, CTRL_OFFSET, CTRL_CMD_COUPLE);
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500  54) 	else
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500  55) 		xlnx_pr_decoupler_write(priv, CTRL_OFFSET, CTRL_CMD_DECOUPLE);
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500  56) 
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500  57) 	clk_disable(priv->clk);
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500  58) 
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500  59) 	return 0;
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500  60) }
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500  61) 
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500  62) static int xlnx_pr_decoupler_enable_show(struct fpga_bridge *bridge)
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500  63) {
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500  64) 	const struct xlnx_pr_decoupler_data *priv = bridge->priv;
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500  65) 	u32 status;
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500  66) 	int err;
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500  67) 
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500  68) 	err = clk_enable(priv->clk);
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500  69) 	if (err)
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500  70) 		return err;
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500  71) 
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500  72) 	status = readl(priv->io_base);
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500  73) 
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500  74) 	clk_disable(priv->clk);
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500  75) 
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500  76) 	return !status;
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500  77) }
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500  78) 
d8d9d936464a9 (Bhumika Goyal      2017-09-21 09:52:41 -0500  79) static const struct fpga_bridge_ops xlnx_pr_decoupler_br_ops = {
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500  80) 	.enable_set = xlnx_pr_decoupler_enable_set,
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500  81) 	.enable_show = xlnx_pr_decoupler_enable_show,
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500  82) };
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500  83) 
30a2ac9a8bb5f (Nava kishore Manne 2021-02-11 10:41:48 +0530  84) static const struct xlnx_config_data decoupler_config = {
30a2ac9a8bb5f (Nava kishore Manne 2021-02-11 10:41:48 +0530  85) 	.name = "Xilinx PR Decoupler",
30a2ac9a8bb5f (Nava kishore Manne 2021-02-11 10:41:48 +0530  86) };
30a2ac9a8bb5f (Nava kishore Manne 2021-02-11 10:41:48 +0530  87) 
30a2ac9a8bb5f (Nava kishore Manne 2021-02-11 10:41:48 +0530  88) static const struct xlnx_config_data shutdown_config = {
30a2ac9a8bb5f (Nava kishore Manne 2021-02-11 10:41:48 +0530  89) 	.name = "Xilinx DFX AXI Shutdown Manager",
30a2ac9a8bb5f (Nava kishore Manne 2021-02-11 10:41:48 +0530  90) };
30a2ac9a8bb5f (Nava kishore Manne 2021-02-11 10:41:48 +0530  91) 
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500  92) static const struct of_device_id xlnx_pr_decoupler_of_match[] = {
30a2ac9a8bb5f (Nava kishore Manne 2021-02-11 10:41:48 +0530  93) 	{ .compatible = "xlnx,pr-decoupler-1.00", .data = &decoupler_config },
30a2ac9a8bb5f (Nava kishore Manne 2021-02-11 10:41:48 +0530  94) 	{ .compatible = "xlnx,pr-decoupler", .data = &decoupler_config },
30a2ac9a8bb5f (Nava kishore Manne 2021-02-11 10:41:48 +0530  95) 	{ .compatible = "xlnx,dfx-axi-shutdown-manager-1.00",
30a2ac9a8bb5f (Nava kishore Manne 2021-02-11 10:41:48 +0530  96) 					.data = &shutdown_config },
30a2ac9a8bb5f (Nava kishore Manne 2021-02-11 10:41:48 +0530  97) 	{ .compatible = "xlnx,dfx-axi-shutdown-manager",
30a2ac9a8bb5f (Nava kishore Manne 2021-02-11 10:41:48 +0530  98) 					.data = &shutdown_config },
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500  99) 	{},
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500 100) };
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500 101) MODULE_DEVICE_TABLE(of, xlnx_pr_decoupler_of_match);
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500 102) 
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500 103) static int xlnx_pr_decoupler_probe(struct platform_device *pdev)
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500 104) {
30a2ac9a8bb5f (Nava kishore Manne 2021-02-11 10:41:48 +0530 105) 	struct device_node *np = pdev->dev.of_node;
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500 106) 	struct xlnx_pr_decoupler_data *priv;
371cd1b1fdabb (Alan Tull          2018-05-16 18:49:56 -0500 107) 	struct fpga_bridge *br;
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500 108) 	int err;
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500 109) 	struct resource *res;
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500 110) 
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500 111) 	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500 112) 	if (!priv)
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500 113) 		return -ENOMEM;
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500 114) 
30a2ac9a8bb5f (Nava kishore Manne 2021-02-11 10:41:48 +0530 115) 	if (np) {
30a2ac9a8bb5f (Nava kishore Manne 2021-02-11 10:41:48 +0530 116) 		const struct of_device_id *match;
30a2ac9a8bb5f (Nava kishore Manne 2021-02-11 10:41:48 +0530 117) 
30a2ac9a8bb5f (Nava kishore Manne 2021-02-11 10:41:48 +0530 118) 		match = of_match_node(xlnx_pr_decoupler_of_match, np);
30a2ac9a8bb5f (Nava kishore Manne 2021-02-11 10:41:48 +0530 119) 		if (match && match->data)
30a2ac9a8bb5f (Nava kishore Manne 2021-02-11 10:41:48 +0530 120) 			priv->ipconfig = match->data;
30a2ac9a8bb5f (Nava kishore Manne 2021-02-11 10:41:48 +0530 121) 	}
30a2ac9a8bb5f (Nava kishore Manne 2021-02-11 10:41:48 +0530 122) 
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500 123) 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500 124) 	priv->io_base = devm_ioremap_resource(&pdev->dev, res);
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500 125) 	if (IS_ERR(priv->io_base))
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500 126) 		return PTR_ERR(priv->io_base);
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500 127) 
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500 128) 	priv->clk = devm_clk_get(&pdev->dev, "aclk");
b5c6ecfd471ea (Michal Simek       2021-02-04 14:36:11 +0100 129) 	if (IS_ERR(priv->clk))
b5c6ecfd471ea (Michal Simek       2021-02-04 14:36:11 +0100 130) 		return dev_err_probe(&pdev->dev, PTR_ERR(priv->clk),
b5c6ecfd471ea (Michal Simek       2021-02-04 14:36:11 +0100 131) 				     "input clock not found\n");
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500 132) 
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500 133) 	err = clk_prepare_enable(priv->clk);
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500 134) 	if (err) {
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500 135) 		dev_err(&pdev->dev, "unable to enable clock\n");
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500 136) 		return err;
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500 137) 	}
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500 138) 
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500 139) 	clk_disable(priv->clk);
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500 140) 
30a2ac9a8bb5f (Nava kishore Manne 2021-02-11 10:41:48 +0530 141) 	br = devm_fpga_bridge_create(&pdev->dev, priv->ipconfig->name,
213befe049c70 (Alan Tull          2018-10-15 17:20:02 -0500 142) 				     &xlnx_pr_decoupler_br_ops, priv);
371cd1b1fdabb (Alan Tull          2018-05-16 18:49:56 -0500 143) 	if (!br) {
371cd1b1fdabb (Alan Tull          2018-05-16 18:49:56 -0500 144) 		err = -ENOMEM;
371cd1b1fdabb (Alan Tull          2018-05-16 18:49:56 -0500 145) 		goto err_clk;
371cd1b1fdabb (Alan Tull          2018-05-16 18:49:56 -0500 146) 	}
371cd1b1fdabb (Alan Tull          2018-05-16 18:49:56 -0500 147) 
371cd1b1fdabb (Alan Tull          2018-05-16 18:49:56 -0500 148) 	platform_set_drvdata(pdev, br);
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500 149) 
371cd1b1fdabb (Alan Tull          2018-05-16 18:49:56 -0500 150) 	err = fpga_bridge_register(br);
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500 151) 	if (err) {
30a2ac9a8bb5f (Nava kishore Manne 2021-02-11 10:41:48 +0530 152) 		dev_err(&pdev->dev, "unable to register %s",
30a2ac9a8bb5f (Nava kishore Manne 2021-02-11 10:41:48 +0530 153) 			priv->ipconfig->name);
371cd1b1fdabb (Alan Tull          2018-05-16 18:49:56 -0500 154) 		goto err_clk;
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500 155) 	}
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500 156) 
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500 157) 	return 0;
371cd1b1fdabb (Alan Tull          2018-05-16 18:49:56 -0500 158) 
371cd1b1fdabb (Alan Tull          2018-05-16 18:49:56 -0500 159) err_clk:
371cd1b1fdabb (Alan Tull          2018-05-16 18:49:56 -0500 160) 	clk_unprepare(priv->clk);
371cd1b1fdabb (Alan Tull          2018-05-16 18:49:56 -0500 161) 
371cd1b1fdabb (Alan Tull          2018-05-16 18:49:56 -0500 162) 	return err;
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500 163) }
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500 164) 
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500 165) static int xlnx_pr_decoupler_remove(struct platform_device *pdev)
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500 166) {
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500 167) 	struct fpga_bridge *bridge = platform_get_drvdata(pdev);
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500 168) 	struct xlnx_pr_decoupler_data *p = bridge->priv;
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500 169) 
371cd1b1fdabb (Alan Tull          2018-05-16 18:49:56 -0500 170) 	fpga_bridge_unregister(bridge);
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500 171) 
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500 172) 	clk_unprepare(p->clk);
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500 173) 
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500 174) 	return 0;
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500 175) }
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500 176) 
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500 177) static struct platform_driver xlnx_pr_decoupler_driver = {
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500 178) 	.probe = xlnx_pr_decoupler_probe,
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500 179) 	.remove = xlnx_pr_decoupler_remove,
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500 180) 	.driver = {
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500 181) 		.name = "xlnx_pr_decoupler",
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500 182) 		.of_match_table = of_match_ptr(xlnx_pr_decoupler_of_match),
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500 183) 	},
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500 184) };
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500 185) 
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500 186) module_platform_driver(xlnx_pr_decoupler_driver);
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500 187) 
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500 188) MODULE_DESCRIPTION("Xilinx Partial Reconfiguration Decoupler");
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500 189) MODULE_AUTHOR("Moritz Fischer <mdf@kernel.org>");
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500 190) MODULE_AUTHOR("Michal Simek <michal.simek@xilinx.com>");
7e961c12be424 (Moritz Fischer     2017-03-24 10:33:21 -0500 191) MODULE_LICENSE("GPL v2");