diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2017-05-09 13:01:15 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-05-09 13:01:15 -0400 |
commit | 0160e00ae8e987be8822745fb166aa76451c9bcc (patch) | |
tree | deca2d09a729155ed0cb631f2bc8f557e634ab06 /drivers/reset/reset-imx7.c | |
parent | c81ee18e97e4e3162169a749eb7f2b79b3510c7a (diff) | |
parent | b6942b68f85ed3161c91741791ec6f1779574919 (diff) |
Merge tag 'armsoc-drivers' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
Pull ARM SoC driver updates from Olof Johansson:
"Driver updates for ARM SoCs:
Reset subsystem, merged through arm-soc by tradition:
- Make bool drivers explicitly non-modular
- New support for i.MX7 and Arria10 reset controllers
PATA driver for Palmchip BK371 (acked by Tejun)
Power domain drivers for i.MX (GPC, GPCv2)
- Moved out of mach-imx for GPC
- Bunch of tweaks, fixes, etc
PMC support for Tegra186
SoC detection support for Renesas RZ/G1H and RZ/G1N
Move Tegra flow controller driver from mach directory to drivers/soc
- (Power management / CPU power driver)
Misc smaller tweaks for other platforms"
* tag 'armsoc-drivers' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (60 commits)
soc: pm-domain: Fix the mangled urls
soc: renesas: rcar-sysc: Add support for R-Car H3 ES2.0
soc: renesas: rcar-sysc: Add support for fixing up power area tables
soc: renesas: Register SoC device early
soc: imx: gpc: add workaround for i.MX6QP to the GPC PD driver
dt-bindings: imx-gpc: add i.MX6 QuadPlus compatible
soc: imx: gpc: add defines for domain index
soc: imx: Add GPCv2 power gating driver
dt-bindings: Add GPCv2 power gating driver
ARM/clk: move the ICST library to drivers/clk
ARM: plat-versatile: remove stale clock header
ARM: keystone: Drop PM domain support for k2g
soc: ti: Add ti_sci_pm_domains driver
dt-bindings: Add TI SCI PM Domains
PM / Domains: Do not check if simple providers have phandle cells
PM / Domains: Add generic data pointer to genpd data struct
soc/tegra: Add initial flowctrl support for Tegra132/210
soc/tegra: flowctrl: Add basic platform driver
soc/tegra: Move Tegra flowctrl driver
ARM: tegra: Remove unnecessary inclusion of flowctrl header
...
Diffstat (limited to 'drivers/reset/reset-imx7.c')
-rw-r--r-- | drivers/reset/reset-imx7.c | 158 |
1 files changed, 158 insertions, 0 deletions
diff --git a/drivers/reset/reset-imx7.c b/drivers/reset/reset-imx7.c new file mode 100644 index 000000000000..4db177bc89bc --- /dev/null +++ b/drivers/reset/reset-imx7.c | |||
@@ -0,0 +1,158 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2017, Impinj, Inc. | ||
3 | * | ||
4 | * i.MX7 System Reset Controller (SRC) driver | ||
5 | * | ||
6 | * Author: Andrey Smirnov <andrew.smirnov@gmail.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; version 2 of the License. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | */ | ||
17 | |||
18 | #include <linux/mfd/syscon.h> | ||
19 | #include <linux/platform_device.h> | ||
20 | #include <linux/reset-controller.h> | ||
21 | #include <linux/regmap.h> | ||
22 | #include <dt-bindings/reset/imx7-reset.h> | ||
23 | |||
24 | struct imx7_src { | ||
25 | struct reset_controller_dev rcdev; | ||
26 | struct regmap *regmap; | ||
27 | }; | ||
28 | |||
29 | enum imx7_src_registers { | ||
30 | SRC_A7RCR0 = 0x0004, | ||
31 | SRC_M4RCR = 0x000c, | ||
32 | SRC_ERCR = 0x0014, | ||
33 | SRC_HSICPHY_RCR = 0x001c, | ||
34 | SRC_USBOPHY1_RCR = 0x0020, | ||
35 | SRC_USBOPHY2_RCR = 0x0024, | ||
36 | SRC_MIPIPHY_RCR = 0x0028, | ||
37 | SRC_PCIEPHY_RCR = 0x002c, | ||
38 | SRC_DDRC_RCR = 0x1000, | ||
39 | }; | ||
40 | |||
41 | struct imx7_src_signal { | ||
42 | unsigned int offset, bit; | ||
43 | }; | ||
44 | |||
45 | static const struct imx7_src_signal imx7_src_signals[IMX7_RESET_NUM] = { | ||
46 | [IMX7_RESET_A7_CORE_POR_RESET0] = { SRC_A7RCR0, BIT(0) }, | ||
47 | [IMX7_RESET_A7_CORE_POR_RESET1] = { SRC_A7RCR0, BIT(1) }, | ||
48 | [IMX7_RESET_A7_CORE_RESET0] = { SRC_A7RCR0, BIT(4) }, | ||
49 | [IMX7_RESET_A7_CORE_RESET1] = { SRC_A7RCR0, BIT(5) }, | ||
50 | [IMX7_RESET_A7_DBG_RESET0] = { SRC_A7RCR0, BIT(8) }, | ||
51 | [IMX7_RESET_A7_DBG_RESET1] = { SRC_A7RCR0, BIT(9) }, | ||
52 | [IMX7_RESET_A7_ETM_RESET0] = { SRC_A7RCR0, BIT(12) }, | ||
53 | [IMX7_RESET_A7_ETM_RESET1] = { SRC_A7RCR0, BIT(13) }, | ||
54 | [IMX7_RESET_A7_SOC_DBG_RESET] = { SRC_A7RCR0, BIT(20) }, | ||
55 | [IMX7_RESET_A7_L2RESET] = { SRC_A7RCR0, BIT(21) }, | ||
56 | [IMX7_RESET_SW_M4C_RST] = { SRC_M4RCR, BIT(1) }, | ||
57 | [IMX7_RESET_SW_M4P_RST] = { SRC_M4RCR, BIT(2) }, | ||
58 | [IMX7_RESET_EIM_RST] = { SRC_ERCR, BIT(0) }, | ||
59 | [IMX7_RESET_HSICPHY_PORT_RST] = { SRC_HSICPHY_RCR, BIT(1) }, | ||
60 | [IMX7_RESET_USBPHY1_POR] = { SRC_USBOPHY1_RCR, BIT(0) }, | ||
61 | [IMX7_RESET_USBPHY1_PORT_RST] = { SRC_USBOPHY1_RCR, BIT(1) }, | ||
62 | [IMX7_RESET_USBPHY2_POR] = { SRC_USBOPHY2_RCR, BIT(0) }, | ||
63 | [IMX7_RESET_USBPHY2_PORT_RST] = { SRC_USBOPHY2_RCR, BIT(1) }, | ||
64 | [IMX7_RESET_MIPI_PHY_MRST] = { SRC_MIPIPHY_RCR, BIT(1) }, | ||
65 | [IMX7_RESET_MIPI_PHY_SRST] = { SRC_MIPIPHY_RCR, BIT(2) }, | ||
66 | [IMX7_RESET_PCIEPHY] = { SRC_PCIEPHY_RCR, BIT(2) | BIT(1) }, | ||
67 | [IMX7_RESET_PCIEPHY_PERST] = { SRC_PCIEPHY_RCR, BIT(3) }, | ||
68 | [IMX7_RESET_PCIE_CTRL_APPS_EN] = { SRC_PCIEPHY_RCR, BIT(6) }, | ||
69 | [IMX7_RESET_DDRC_PRST] = { SRC_DDRC_RCR, BIT(0) }, | ||
70 | [IMX7_RESET_DDRC_CORE_RST] = { SRC_DDRC_RCR, BIT(1) }, | ||
71 | }; | ||
72 | |||
73 | static struct imx7_src *to_imx7_src(struct reset_controller_dev *rcdev) | ||
74 | { | ||
75 | return container_of(rcdev, struct imx7_src, rcdev); | ||
76 | } | ||
77 | |||
78 | static int imx7_reset_set(struct reset_controller_dev *rcdev, | ||
79 | unsigned long id, bool assert) | ||
80 | { | ||
81 | struct imx7_src *imx7src = to_imx7_src(rcdev); | ||
82 | const struct imx7_src_signal *signal = &imx7_src_signals[id]; | ||
83 | unsigned int value = 0; | ||
84 | |||
85 | switch (id) { | ||
86 | case IMX7_RESET_PCIEPHY: | ||
87 | /* | ||
88 | * wait for more than 10us to release phy g_rst and | ||
89 | * btnrst | ||
90 | */ | ||
91 | if (!assert) | ||
92 | udelay(10); | ||
93 | break; | ||
94 | |||
95 | case IMX7_RESET_PCIE_CTRL_APPS_EN: | ||
96 | value = (assert) ? 0 : signal->bit; | ||
97 | break; | ||
98 | } | ||
99 | |||
100 | return regmap_update_bits(imx7src->regmap, | ||
101 | signal->offset, signal->bit, value); | ||
102 | } | ||
103 | |||
104 | static int imx7_reset_assert(struct reset_controller_dev *rcdev, | ||
105 | unsigned long id) | ||
106 | { | ||
107 | return imx7_reset_set(rcdev, id, true); | ||
108 | } | ||
109 | |||
110 | static int imx7_reset_deassert(struct reset_controller_dev *rcdev, | ||
111 | unsigned long id) | ||
112 | { | ||
113 | return imx7_reset_set(rcdev, id, false); | ||
114 | } | ||
115 | |||
116 | static const struct reset_control_ops imx7_reset_ops = { | ||
117 | .assert = imx7_reset_assert, | ||
118 | .deassert = imx7_reset_deassert, | ||
119 | }; | ||
120 | |||
121 | static int imx7_reset_probe(struct platform_device *pdev) | ||
122 | { | ||
123 | struct imx7_src *imx7src; | ||
124 | struct device *dev = &pdev->dev; | ||
125 | struct regmap_config config = { .name = "src" }; | ||
126 | |||
127 | imx7src = devm_kzalloc(dev, sizeof(*imx7src), GFP_KERNEL); | ||
128 | if (!imx7src) | ||
129 | return -ENOMEM; | ||
130 | |||
131 | imx7src->regmap = syscon_node_to_regmap(dev->of_node); | ||
132 | if (IS_ERR(imx7src->regmap)) { | ||
133 | dev_err(dev, "Unable to get imx7-src regmap"); | ||
134 | return PTR_ERR(imx7src->regmap); | ||
135 | } | ||
136 | regmap_attach_dev(dev, imx7src->regmap, &config); | ||
137 | |||
138 | imx7src->rcdev.owner = THIS_MODULE; | ||
139 | imx7src->rcdev.nr_resets = IMX7_RESET_NUM; | ||
140 | imx7src->rcdev.ops = &imx7_reset_ops; | ||
141 | imx7src->rcdev.of_node = dev->of_node; | ||
142 | |||
143 | return devm_reset_controller_register(dev, &imx7src->rcdev); | ||
144 | } | ||
145 | |||
146 | static const struct of_device_id imx7_reset_dt_ids[] = { | ||
147 | { .compatible = "fsl,imx7d-src", }, | ||
148 | { /* sentinel */ }, | ||
149 | }; | ||
150 | |||
151 | static struct platform_driver imx7_reset_driver = { | ||
152 | .probe = imx7_reset_probe, | ||
153 | .driver = { | ||
154 | .name = KBUILD_MODNAME, | ||
155 | .of_match_table = imx7_reset_dt_ids, | ||
156 | }, | ||
157 | }; | ||
158 | builtin_platform_driver(imx7_reset_driver); | ||