diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-07-19 20:13:56 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-07-19 20:13:56 -0400 |
commit | 8362fd64f07eaef7155c94fca8dee91c4f99a666 (patch) | |
tree | 2d16af7d7b8cbb5765727493f796d453580fc107 /drivers/bus/ti-sysc.c | |
parent | 24e44913aa746098349370a0f279733c0cadcba7 (diff) | |
parent | 8c0993621c3e5fa52e5425ef2a0f67a0cde07092 (diff) |
Merge tag 'armsoc-drivers' of git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc
Pull ARM SoC-related driver updates from Olof Johansson:
"Various driver updates for platforms and a couple of the small driver
subsystems we merge through our tree:
- A driver for SCU (system control) on NXP i.MX8QXP
- Qualcomm Always-on Subsystem messaging driver (AOSS QMP)
- Qualcomm PM support for MSM8998
- Support for a newer version of DRAM PHY driver for Broadcom (DPFE)
- Reset controller support for Bitmain BM1880
- TI SCI (System Control Interface) support for CPU control on AM654
processors
- More TI sysc refactoring and rework"
* tag 'armsoc-drivers' of git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc: (84 commits)
reset: remove redundant null check on pointer dev
soc: rockchip: work around clang warning
dt-bindings: reset: imx7: Fix the spelling of 'indices'
soc: imx: Add i.MX8MN SoC driver support
soc: aspeed: lpc-ctrl: Fix probe error handling
soc: qcom: geni: Add support for ACPI
firmware: ti_sci: Fix gcc unused-but-set-variable warning
firmware: ti_sci: Use the correct style for SPDX License Identifier
soc: imx8: Use existing of_root directly
soc: imx8: Fix potential kernel dump in error path
firmware/psci: psci_checker: Park kthreads before stopping them
memory: move jedec_ddr.h from include/memory to drivers/memory/
memory: move jedec_ddr_data.c from lib/ to drivers/memory/
MAINTAINERS: Remove myself as qcom maintainer
soc: aspeed: lpc-ctrl: make parameter optional
soc: qcom: apr: Don't use reg for domain id
soc: qcom: fix QCOM_AOSS_QMP dependency and build errors
memory: tegra: Fix -Wunused-const-variable
firmware: tegra: Early resume BPMP
soc/tegra: Select pinctrl for Tegra194
...
Diffstat (limited to 'drivers/bus/ti-sysc.c')
-rw-r--r-- | drivers/bus/ti-sysc.c | 454 |
1 files changed, 379 insertions, 75 deletions
diff --git a/drivers/bus/ti-sysc.c b/drivers/bus/ti-sysc.c index b72741668c92..e6deabd8305d 100644 --- a/drivers/bus/ti-sysc.c +++ b/drivers/bus/ti-sysc.c | |||
@@ -71,6 +71,9 @@ static const char * const clock_names[SYSC_MAX_CLOCKS] = { | |||
71 | * @name: name if available | 71 | * @name: name if available |
72 | * @revision: interconnect target module revision | 72 | * @revision: interconnect target module revision |
73 | * @needs_resume: runtime resume needed on resume from suspend | 73 | * @needs_resume: runtime resume needed on resume from suspend |
74 | * @clk_enable_quirk: module specific clock enable quirk | ||
75 | * @clk_disable_quirk: module specific clock disable quirk | ||
76 | * @reset_done_quirk: module specific reset done quirk | ||
74 | */ | 77 | */ |
75 | struct sysc { | 78 | struct sysc { |
76 | struct device *dev; | 79 | struct device *dev; |
@@ -89,10 +92,14 @@ struct sysc { | |||
89 | struct ti_sysc_cookie cookie; | 92 | struct ti_sysc_cookie cookie; |
90 | const char *name; | 93 | const char *name; |
91 | u32 revision; | 94 | u32 revision; |
92 | bool enabled; | 95 | unsigned int enabled:1; |
93 | bool needs_resume; | 96 | unsigned int needs_resume:1; |
94 | bool child_needs_resume; | 97 | unsigned int child_needs_resume:1; |
98 | unsigned int disable_on_idle:1; | ||
95 | struct delayed_work idle_work; | 99 | struct delayed_work idle_work; |
100 | void (*clk_enable_quirk)(struct sysc *sysc); | ||
101 | void (*clk_disable_quirk)(struct sysc *sysc); | ||
102 | void (*reset_done_quirk)(struct sysc *sysc); | ||
96 | }; | 103 | }; |
97 | 104 | ||
98 | static void sysc_parse_dts_quirks(struct sysc *ddata, struct device_node *np, | 105 | static void sysc_parse_dts_quirks(struct sysc *ddata, struct device_node *np, |
@@ -100,6 +107,20 @@ static void sysc_parse_dts_quirks(struct sysc *ddata, struct device_node *np, | |||
100 | 107 | ||
101 | static void sysc_write(struct sysc *ddata, int offset, u32 value) | 108 | static void sysc_write(struct sysc *ddata, int offset, u32 value) |
102 | { | 109 | { |
110 | if (ddata->cfg.quirks & SYSC_QUIRK_16BIT) { | ||
111 | writew_relaxed(value & 0xffff, ddata->module_va + offset); | ||
112 | |||
113 | /* Only i2c revision has LO and HI register with stride of 4 */ | ||
114 | if (ddata->offsets[SYSC_REVISION] >= 0 && | ||
115 | offset == ddata->offsets[SYSC_REVISION]) { | ||
116 | u16 hi = value >> 16; | ||
117 | |||
118 | writew_relaxed(hi, ddata->module_va + offset + 4); | ||
119 | } | ||
120 | |||
121 | return; | ||
122 | } | ||
123 | |||
103 | writel_relaxed(value, ddata->module_va + offset); | 124 | writel_relaxed(value, ddata->module_va + offset); |
104 | } | 125 | } |
105 | 126 | ||
@@ -109,7 +130,14 @@ static u32 sysc_read(struct sysc *ddata, int offset) | |||
109 | u32 val; | 130 | u32 val; |
110 | 131 | ||
111 | val = readw_relaxed(ddata->module_va + offset); | 132 | val = readw_relaxed(ddata->module_va + offset); |
112 | val |= (readw_relaxed(ddata->module_va + offset + 4) << 16); | 133 | |
134 | /* Only i2c revision has LO and HI register with stride of 4 */ | ||
135 | if (ddata->offsets[SYSC_REVISION] >= 0 && | ||
136 | offset == ddata->offsets[SYSC_REVISION]) { | ||
137 | u16 tmp = readw_relaxed(ddata->module_va + offset + 4); | ||
138 | |||
139 | val |= tmp << 16; | ||
140 | } | ||
113 | 141 | ||
114 | return val; | 142 | return val; |
115 | } | 143 | } |
@@ -132,6 +160,26 @@ static u32 sysc_read_revision(struct sysc *ddata) | |||
132 | return sysc_read(ddata, offset); | 160 | return sysc_read(ddata, offset); |
133 | } | 161 | } |
134 | 162 | ||
163 | static u32 sysc_read_sysconfig(struct sysc *ddata) | ||
164 | { | ||
165 | int offset = ddata->offsets[SYSC_SYSCONFIG]; | ||
166 | |||
167 | if (offset < 0) | ||
168 | return 0; | ||
169 | |||
170 | return sysc_read(ddata, offset); | ||
171 | } | ||
172 | |||
173 | static u32 sysc_read_sysstatus(struct sysc *ddata) | ||
174 | { | ||
175 | int offset = ddata->offsets[SYSC_SYSSTATUS]; | ||
176 | |||
177 | if (offset < 0) | ||
178 | return 0; | ||
179 | |||
180 | return sysc_read(ddata, offset); | ||
181 | } | ||
182 | |||
135 | static int sysc_add_named_clock_from_child(struct sysc *ddata, | 183 | static int sysc_add_named_clock_from_child(struct sysc *ddata, |
136 | const char *name, | 184 | const char *name, |
137 | const char *optfck_name) | 185 | const char *optfck_name) |
@@ -422,6 +470,30 @@ static void sysc_disable_opt_clocks(struct sysc *ddata) | |||
422 | } | 470 | } |
423 | } | 471 | } |
424 | 472 | ||
473 | static void sysc_clkdm_deny_idle(struct sysc *ddata) | ||
474 | { | ||
475 | struct ti_sysc_platform_data *pdata; | ||
476 | |||
477 | if (ddata->legacy_mode) | ||
478 | return; | ||
479 | |||
480 | pdata = dev_get_platdata(ddata->dev); | ||
481 | if (pdata && pdata->clkdm_deny_idle) | ||
482 | pdata->clkdm_deny_idle(ddata->dev, &ddata->cookie); | ||
483 | } | ||
484 | |||
485 | static void sysc_clkdm_allow_idle(struct sysc *ddata) | ||
486 | { | ||
487 | struct ti_sysc_platform_data *pdata; | ||
488 | |||
489 | if (ddata->legacy_mode) | ||
490 | return; | ||
491 | |||
492 | pdata = dev_get_platdata(ddata->dev); | ||
493 | if (pdata && pdata->clkdm_allow_idle) | ||
494 | pdata->clkdm_allow_idle(ddata->dev, &ddata->cookie); | ||
495 | } | ||
496 | |||
425 | /** | 497 | /** |
426 | * sysc_init_resets - init rstctrl reset line if configured | 498 | * sysc_init_resets - init rstctrl reset line if configured |
427 | * @ddata: device driver data | 499 | * @ddata: device driver data |
@@ -431,7 +503,7 @@ static void sysc_disable_opt_clocks(struct sysc *ddata) | |||
431 | static int sysc_init_resets(struct sysc *ddata) | 503 | static int sysc_init_resets(struct sysc *ddata) |
432 | { | 504 | { |
433 | ddata->rsts = | 505 | ddata->rsts = |
434 | devm_reset_control_array_get_optional_exclusive(ddata->dev); | 506 | devm_reset_control_get_optional(ddata->dev, "rstctrl"); |
435 | if (IS_ERR(ddata->rsts)) | 507 | if (IS_ERR(ddata->rsts)) |
436 | return PTR_ERR(ddata->rsts); | 508 | return PTR_ERR(ddata->rsts); |
437 | 509 | ||
@@ -694,8 +766,11 @@ static int sysc_ioremap(struct sysc *ddata) | |||
694 | ddata->offsets[SYSC_SYSCONFIG], | 766 | ddata->offsets[SYSC_SYSCONFIG], |
695 | ddata->offsets[SYSC_SYSSTATUS]); | 767 | ddata->offsets[SYSC_SYSSTATUS]); |
696 | 768 | ||
769 | if (size < SZ_1K) | ||
770 | size = SZ_1K; | ||
771 | |||
697 | if ((size + sizeof(u32)) > ddata->module_size) | 772 | if ((size + sizeof(u32)) > ddata->module_size) |
698 | return -EINVAL; | 773 | size = ddata->module_size; |
699 | } | 774 | } |
700 | 775 | ||
701 | ddata->module_va = devm_ioremap(ddata->dev, | 776 | ddata->module_va = devm_ioremap(ddata->dev, |
@@ -794,7 +869,9 @@ static void sysc_show_registers(struct sysc *ddata) | |||
794 | } | 869 | } |
795 | 870 | ||
796 | #define SYSC_IDLE_MASK (SYSC_NR_IDLEMODES - 1) | 871 | #define SYSC_IDLE_MASK (SYSC_NR_IDLEMODES - 1) |
872 | #define SYSC_CLOCACT_ICK 2 | ||
797 | 873 | ||
874 | /* Caller needs to manage sysc_clkdm_deny_idle() and sysc_clkdm_allow_idle() */ | ||
798 | static int sysc_enable_module(struct device *dev) | 875 | static int sysc_enable_module(struct device *dev) |
799 | { | 876 | { |
800 | struct sysc *ddata; | 877 | struct sysc *ddata; |
@@ -805,23 +882,34 @@ static int sysc_enable_module(struct device *dev) | |||
805 | if (ddata->offsets[SYSC_SYSCONFIG] == -ENODEV) | 882 | if (ddata->offsets[SYSC_SYSCONFIG] == -ENODEV) |
806 | return 0; | 883 | return 0; |
807 | 884 | ||
808 | /* | ||
809 | * TODO: Need to prevent clockdomain autoidle? | ||
810 | * See clkdm_deny_idle() in arch/mach-omap2/omap_hwmod.c | ||
811 | */ | ||
812 | |||
813 | regbits = ddata->cap->regbits; | 885 | regbits = ddata->cap->regbits; |
814 | reg = sysc_read(ddata, ddata->offsets[SYSC_SYSCONFIG]); | 886 | reg = sysc_read(ddata, ddata->offsets[SYSC_SYSCONFIG]); |
815 | 887 | ||
888 | /* Set CLOCKACTIVITY, we only use it for ick */ | ||
889 | if (regbits->clkact_shift >= 0 && | ||
890 | (ddata->cfg.quirks & SYSC_QUIRK_USE_CLOCKACT || | ||
891 | ddata->cfg.sysc_val & BIT(regbits->clkact_shift))) | ||
892 | reg |= SYSC_CLOCACT_ICK << regbits->clkact_shift; | ||
893 | |||
816 | /* Set SIDLE mode */ | 894 | /* Set SIDLE mode */ |
817 | idlemodes = ddata->cfg.sidlemodes; | 895 | idlemodes = ddata->cfg.sidlemodes; |
818 | if (!idlemodes || regbits->sidle_shift < 0) | 896 | if (!idlemodes || regbits->sidle_shift < 0) |
819 | goto set_midle; | 897 | goto set_midle; |
820 | 898 | ||
821 | best_mode = fls(ddata->cfg.sidlemodes) - 1; | 899 | if (ddata->cfg.quirks & (SYSC_QUIRK_SWSUP_SIDLE | |
822 | if (best_mode > SYSC_IDLE_MASK) { | 900 | SYSC_QUIRK_SWSUP_SIDLE_ACT)) { |
823 | dev_err(dev, "%s: invalid sidlemode\n", __func__); | 901 | best_mode = SYSC_IDLE_NO; |
824 | return -EINVAL; | 902 | } else { |
903 | best_mode = fls(ddata->cfg.sidlemodes) - 1; | ||
904 | if (best_mode > SYSC_IDLE_MASK) { | ||
905 | dev_err(dev, "%s: invalid sidlemode\n", __func__); | ||
906 | return -EINVAL; | ||
907 | } | ||
908 | |||
909 | /* Set WAKEUP */ | ||
910 | if (regbits->enwkup_shift >= 0 && | ||
911 | ddata->cfg.sysc_val & BIT(regbits->enwkup_shift)) | ||
912 | reg |= BIT(regbits->enwkup_shift); | ||
825 | } | 913 | } |
826 | 914 | ||
827 | reg &= ~(SYSC_IDLE_MASK << regbits->sidle_shift); | 915 | reg &= ~(SYSC_IDLE_MASK << regbits->sidle_shift); |
@@ -832,7 +920,7 @@ set_midle: | |||
832 | /* Set MIDLE mode */ | 920 | /* Set MIDLE mode */ |
833 | idlemodes = ddata->cfg.midlemodes; | 921 | idlemodes = ddata->cfg.midlemodes; |
834 | if (!idlemodes || regbits->midle_shift < 0) | 922 | if (!idlemodes || regbits->midle_shift < 0) |
835 | return 0; | 923 | goto set_autoidle; |
836 | 924 | ||
837 | best_mode = fls(ddata->cfg.midlemodes) - 1; | 925 | best_mode = fls(ddata->cfg.midlemodes) - 1; |
838 | if (best_mode > SYSC_IDLE_MASK) { | 926 | if (best_mode > SYSC_IDLE_MASK) { |
@@ -844,6 +932,14 @@ set_midle: | |||
844 | reg |= best_mode << regbits->midle_shift; | 932 | reg |= best_mode << regbits->midle_shift; |
845 | sysc_write(ddata, ddata->offsets[SYSC_SYSCONFIG], reg); | 933 | sysc_write(ddata, ddata->offsets[SYSC_SYSCONFIG], reg); |
846 | 934 | ||
935 | set_autoidle: | ||
936 | /* Autoidle bit must enabled separately if available */ | ||
937 | if (regbits->autoidle_shift >= 0 && | ||
938 | ddata->cfg.sysc_val & BIT(regbits->autoidle_shift)) { | ||
939 | reg |= 1 << regbits->autoidle_shift; | ||
940 | sysc_write(ddata, ddata->offsets[SYSC_SYSCONFIG], reg); | ||
941 | } | ||
942 | |||
847 | return 0; | 943 | return 0; |
848 | } | 944 | } |
849 | 945 | ||
@@ -861,6 +957,7 @@ static int sysc_best_idle_mode(u32 idlemodes, u32 *best_mode) | |||
861 | return 0; | 957 | return 0; |
862 | } | 958 | } |
863 | 959 | ||
960 | /* Caller needs to manage sysc_clkdm_deny_idle() and sysc_clkdm_allow_idle() */ | ||
864 | static int sysc_disable_module(struct device *dev) | 961 | static int sysc_disable_module(struct device *dev) |
865 | { | 962 | { |
866 | struct sysc *ddata; | 963 | struct sysc *ddata; |
@@ -872,11 +969,6 @@ static int sysc_disable_module(struct device *dev) | |||
872 | if (ddata->offsets[SYSC_SYSCONFIG] == -ENODEV) | 969 | if (ddata->offsets[SYSC_SYSCONFIG] == -ENODEV) |
873 | return 0; | 970 | return 0; |
874 | 971 | ||
875 | /* | ||
876 | * TODO: Need to prevent clockdomain autoidle? | ||
877 | * See clkdm_deny_idle() in arch/mach-omap2/omap_hwmod.c | ||
878 | */ | ||
879 | |||
880 | regbits = ddata->cap->regbits; | 972 | regbits = ddata->cap->regbits; |
881 | reg = sysc_read(ddata, ddata->offsets[SYSC_SYSCONFIG]); | 973 | reg = sysc_read(ddata, ddata->offsets[SYSC_SYSCONFIG]); |
882 | 974 | ||
@@ -901,14 +993,21 @@ set_sidle: | |||
901 | if (!idlemodes || regbits->sidle_shift < 0) | 993 | if (!idlemodes || regbits->sidle_shift < 0) |
902 | return 0; | 994 | return 0; |
903 | 995 | ||
904 | ret = sysc_best_idle_mode(idlemodes, &best_mode); | 996 | if (ddata->cfg.quirks & SYSC_QUIRK_SWSUP_SIDLE) { |
905 | if (ret) { | 997 | best_mode = SYSC_IDLE_FORCE; |
906 | dev_err(dev, "%s: invalid sidlemode\n", __func__); | 998 | } else { |
907 | return ret; | 999 | ret = sysc_best_idle_mode(idlemodes, &best_mode); |
1000 | if (ret) { | ||
1001 | dev_err(dev, "%s: invalid sidlemode\n", __func__); | ||
1002 | return ret; | ||
1003 | } | ||
908 | } | 1004 | } |
909 | 1005 | ||
910 | reg &= ~(SYSC_IDLE_MASK << regbits->sidle_shift); | 1006 | reg &= ~(SYSC_IDLE_MASK << regbits->sidle_shift); |
911 | reg |= best_mode << regbits->sidle_shift; | 1007 | reg |= best_mode << regbits->sidle_shift; |
1008 | if (regbits->autoidle_shift >= 0 && | ||
1009 | ddata->cfg.sysc_val & BIT(regbits->autoidle_shift)) | ||
1010 | reg |= 1 << regbits->autoidle_shift; | ||
912 | sysc_write(ddata, ddata->offsets[SYSC_SYSCONFIG], reg); | 1011 | sysc_write(ddata, ddata->offsets[SYSC_SYSCONFIG], reg); |
913 | 1012 | ||
914 | return 0; | 1013 | return 0; |
@@ -932,6 +1031,9 @@ static int __maybe_unused sysc_runtime_suspend_legacy(struct device *dev, | |||
932 | dev_err(dev, "%s: could not idle: %i\n", | 1031 | dev_err(dev, "%s: could not idle: %i\n", |
933 | __func__, error); | 1032 | __func__, error); |
934 | 1033 | ||
1034 | if (ddata->disable_on_idle) | ||
1035 | reset_control_assert(ddata->rsts); | ||
1036 | |||
935 | return 0; | 1037 | return 0; |
936 | } | 1038 | } |
937 | 1039 | ||
@@ -941,6 +1043,9 @@ static int __maybe_unused sysc_runtime_resume_legacy(struct device *dev, | |||
941 | struct ti_sysc_platform_data *pdata; | 1043 | struct ti_sysc_platform_data *pdata; |
942 | int error; | 1044 | int error; |
943 | 1045 | ||
1046 | if (ddata->disable_on_idle) | ||
1047 | reset_control_deassert(ddata->rsts); | ||
1048 | |||
944 | pdata = dev_get_platdata(ddata->dev); | 1049 | pdata = dev_get_platdata(ddata->dev); |
945 | if (!pdata) | 1050 | if (!pdata) |
946 | return 0; | 1051 | return 0; |
@@ -966,14 +1071,16 @@ static int __maybe_unused sysc_runtime_suspend(struct device *dev) | |||
966 | if (!ddata->enabled) | 1071 | if (!ddata->enabled) |
967 | return 0; | 1072 | return 0; |
968 | 1073 | ||
1074 | sysc_clkdm_deny_idle(ddata); | ||
1075 | |||
969 | if (ddata->legacy_mode) { | 1076 | if (ddata->legacy_mode) { |
970 | error = sysc_runtime_suspend_legacy(dev, ddata); | 1077 | error = sysc_runtime_suspend_legacy(dev, ddata); |
971 | if (error) | 1078 | if (error) |
972 | return error; | 1079 | goto err_allow_idle; |
973 | } else { | 1080 | } else { |
974 | error = sysc_disable_module(dev); | 1081 | error = sysc_disable_module(dev); |
975 | if (error) | 1082 | if (error) |
976 | return error; | 1083 | goto err_allow_idle; |
977 | } | 1084 | } |
978 | 1085 | ||
979 | sysc_disable_main_clocks(ddata); | 1086 | sysc_disable_main_clocks(ddata); |
@@ -983,6 +1090,12 @@ static int __maybe_unused sysc_runtime_suspend(struct device *dev) | |||
983 | 1090 | ||
984 | ddata->enabled = false; | 1091 | ddata->enabled = false; |
985 | 1092 | ||
1093 | err_allow_idle: | ||
1094 | sysc_clkdm_allow_idle(ddata); | ||
1095 | |||
1096 | if (ddata->disable_on_idle) | ||
1097 | reset_control_assert(ddata->rsts); | ||
1098 | |||
986 | return error; | 1099 | return error; |
987 | } | 1100 | } |
988 | 1101 | ||
@@ -996,10 +1109,15 @@ static int __maybe_unused sysc_runtime_resume(struct device *dev) | |||
996 | if (ddata->enabled) | 1109 | if (ddata->enabled) |
997 | return 0; | 1110 | return 0; |
998 | 1111 | ||
1112 | if (ddata->disable_on_idle) | ||
1113 | reset_control_deassert(ddata->rsts); | ||
1114 | |||
1115 | sysc_clkdm_deny_idle(ddata); | ||
1116 | |||
999 | if (sysc_opt_clks_needed(ddata)) { | 1117 | if (sysc_opt_clks_needed(ddata)) { |
1000 | error = sysc_enable_opt_clocks(ddata); | 1118 | error = sysc_enable_opt_clocks(ddata); |
1001 | if (error) | 1119 | if (error) |
1002 | return error; | 1120 | goto err_allow_idle; |
1003 | } | 1121 | } |
1004 | 1122 | ||
1005 | error = sysc_enable_main_clocks(ddata); | 1123 | error = sysc_enable_main_clocks(ddata); |
@@ -1018,6 +1136,8 @@ static int __maybe_unused sysc_runtime_resume(struct device *dev) | |||
1018 | 1136 | ||
1019 | ddata->enabled = true; | 1137 | ddata->enabled = true; |
1020 | 1138 | ||
1139 | sysc_clkdm_allow_idle(ddata); | ||
1140 | |||
1021 | return 0; | 1141 | return 0; |
1022 | 1142 | ||
1023 | err_main_clocks: | 1143 | err_main_clocks: |
@@ -1025,6 +1145,8 @@ err_main_clocks: | |||
1025 | err_opt_clocks: | 1145 | err_opt_clocks: |
1026 | if (sysc_opt_clks_needed(ddata)) | 1146 | if (sysc_opt_clks_needed(ddata)) |
1027 | sysc_disable_opt_clocks(ddata); | 1147 | sysc_disable_opt_clocks(ddata); |
1148 | err_allow_idle: | ||
1149 | sysc_clkdm_allow_idle(ddata); | ||
1028 | 1150 | ||
1029 | return error; | 1151 | return error; |
1030 | } | 1152 | } |
@@ -1106,8 +1228,10 @@ static const struct sysc_revision_quirk sysc_revision_quirks[] = { | |||
1106 | 0), | 1228 | 0), |
1107 | SYSC_QUIRK("timer", 0, 0, 0x10, -1, 0x4fff1301, 0xffff00ff, | 1229 | SYSC_QUIRK("timer", 0, 0, 0x10, -1, 0x4fff1301, 0xffff00ff, |
1108 | 0), | 1230 | 0), |
1231 | SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x00000046, 0xffffffff, | ||
1232 | SYSC_QUIRK_SWSUP_SIDLE | SYSC_QUIRK_LEGACY_IDLE), | ||
1109 | SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x00000052, 0xffffffff, | 1233 | SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x00000052, 0xffffffff, |
1110 | SYSC_QUIRK_SWSUP_SIDLE_ACT | SYSC_QUIRK_LEGACY_IDLE), | 1234 | SYSC_QUIRK_SWSUP_SIDLE | SYSC_QUIRK_LEGACY_IDLE), |
1111 | /* Uarts on omap4 and later */ | 1235 | /* Uarts on omap4 and later */ |
1112 | SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x50411e03, 0xffff00ff, | 1236 | SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x50411e03, 0xffff00ff, |
1113 | SYSC_QUIRK_SWSUP_SIDLE_ACT | SYSC_QUIRK_LEGACY_IDLE), | 1237 | SYSC_QUIRK_SWSUP_SIDLE_ACT | SYSC_QUIRK_LEGACY_IDLE), |
@@ -1119,6 +1243,22 @@ static const struct sysc_revision_quirk sysc_revision_quirks[] = { | |||
1119 | SYSC_QUIRK_EXT_OPT_CLOCK | SYSC_QUIRK_NO_RESET_ON_INIT | | 1243 | SYSC_QUIRK_EXT_OPT_CLOCK | SYSC_QUIRK_NO_RESET_ON_INIT | |
1120 | SYSC_QUIRK_SWSUP_SIDLE), | 1244 | SYSC_QUIRK_SWSUP_SIDLE), |
1121 | 1245 | ||
1246 | /* Quirks that need to be set based on detected module */ | ||
1247 | SYSC_QUIRK("hdq1w", 0, 0, 0x14, 0x18, 0x00000006, 0xffffffff, | ||
1248 | SYSC_MODULE_QUIRK_HDQ1W), | ||
1249 | SYSC_QUIRK("hdq1w", 0, 0, 0x14, 0x18, 0x0000000a, 0xffffffff, | ||
1250 | SYSC_MODULE_QUIRK_HDQ1W), | ||
1251 | SYSC_QUIRK("i2c", 0, 0, 0x20, 0x10, 0x00000036, 0x000000ff, | ||
1252 | SYSC_MODULE_QUIRK_I2C), | ||
1253 | SYSC_QUIRK("i2c", 0, 0, 0x20, 0x10, 0x0000003c, 0x000000ff, | ||
1254 | SYSC_MODULE_QUIRK_I2C), | ||
1255 | SYSC_QUIRK("i2c", 0, 0, 0x20, 0x10, 0x00000040, 0x000000ff, | ||
1256 | SYSC_MODULE_QUIRK_I2C), | ||
1257 | SYSC_QUIRK("i2c", 0, 0, 0x10, 0x90, 0x5040000a, 0xfffff0f0, | ||
1258 | SYSC_MODULE_QUIRK_I2C), | ||
1259 | SYSC_QUIRK("wdt", 0, 0, 0x10, 0x14, 0x502a0500, 0xfffff0f0, | ||
1260 | SYSC_MODULE_QUIRK_WDT), | ||
1261 | |||
1122 | #ifdef DEBUG | 1262 | #ifdef DEBUG |
1123 | SYSC_QUIRK("adc", 0, 0, 0x10, -1, 0x47300001, 0xffffffff, 0), | 1263 | SYSC_QUIRK("adc", 0, 0, 0x10, -1, 0x47300001, 0xffffffff, 0), |
1124 | SYSC_QUIRK("atl", 0, 0, -1, -1, 0x0a070100, 0xffffffff, 0), | 1264 | SYSC_QUIRK("atl", 0, 0, -1, -1, 0x0a070100, 0xffffffff, 0), |
@@ -1132,11 +1272,8 @@ static const struct sysc_revision_quirk sysc_revision_quirks[] = { | |||
1132 | SYSC_QUIRK("dwc3", 0, 0, 0x10, -1, 0x500a0200, 0xffffffff, 0), | 1272 | SYSC_QUIRK("dwc3", 0, 0, 0x10, -1, 0x500a0200, 0xffffffff, 0), |
1133 | SYSC_QUIRK("epwmss", 0, 0, 0x4, -1, 0x47400001, 0xffffffff, 0), | 1273 | SYSC_QUIRK("epwmss", 0, 0, 0x4, -1, 0x47400001, 0xffffffff, 0), |
1134 | SYSC_QUIRK("gpu", 0, 0x1fc00, 0x1fc10, -1, 0, 0, 0), | 1274 | SYSC_QUIRK("gpu", 0, 0x1fc00, 0x1fc10, -1, 0, 0, 0), |
1135 | SYSC_QUIRK("hdq1w", 0, 0, 0x14, 0x18, 0x00000006, 0xffffffff, 0), | ||
1136 | SYSC_QUIRK("hdq1w", 0, 0, 0x14, 0x18, 0x0000000a, 0xffffffff, 0), | ||
1137 | SYSC_QUIRK("hsi", 0, 0, 0x10, 0x14, 0x50043101, 0xffffffff, 0), | 1275 | SYSC_QUIRK("hsi", 0, 0, 0x10, 0x14, 0x50043101, 0xffffffff, 0), |
1138 | SYSC_QUIRK("iss", 0, 0, 0x10, -1, 0x40000101, 0xffffffff, 0), | 1276 | SYSC_QUIRK("iss", 0, 0, 0x10, -1, 0x40000101, 0xffffffff, 0), |
1139 | SYSC_QUIRK("i2c", 0, 0, 0x10, 0x90, 0x5040000a, 0xfffff0f0, 0), | ||
1140 | SYSC_QUIRK("lcdc", 0, 0, 0x54, -1, 0x4f201000, 0xffffffff, 0), | 1277 | SYSC_QUIRK("lcdc", 0, 0, 0x54, -1, 0x4f201000, 0xffffffff, 0), |
1141 | SYSC_QUIRK("mcasp", 0, 0, 0x4, -1, 0x44306302, 0xffffffff, 0), | 1278 | SYSC_QUIRK("mcasp", 0, 0, 0x4, -1, 0x44306302, 0xffffffff, 0), |
1142 | SYSC_QUIRK("mcasp", 0, 0, 0x4, -1, 0x44307b02, 0xffffffff, 0), | 1279 | SYSC_QUIRK("mcasp", 0, 0, 0x4, -1, 0x44307b02, 0xffffffff, 0), |
@@ -1172,7 +1309,6 @@ static const struct sysc_revision_quirk sysc_revision_quirks[] = { | |||
1172 | SYSC_QUIRK("usb_host_hs", 0, 0, 0x10, -1, 0x50700101, 0xffffffff, 0), | 1309 | SYSC_QUIRK("usb_host_hs", 0, 0, 0x10, -1, 0x50700101, 0xffffffff, 0), |
1173 | SYSC_QUIRK("usb_otg_hs", 0, 0x400, 0x404, 0x408, 0x00000050, | 1310 | SYSC_QUIRK("usb_otg_hs", 0, 0x400, 0x404, 0x408, 0x00000050, |
1174 | 0xffffffff, 0), | 1311 | 0xffffffff, 0), |
1175 | SYSC_QUIRK("wdt", 0, 0, 0x10, 0x14, 0x502a0500, 0xfffff0f0, 0), | ||
1176 | SYSC_QUIRK("vfpe", 0, 0, 0x104, -1, 0x4d001200, 0xffffffff, 0), | 1312 | SYSC_QUIRK("vfpe", 0, 0, 0x104, -1, 0x4d001200, 0xffffffff, 0), |
1177 | #endif | 1313 | #endif |
1178 | }; | 1314 | }; |
@@ -1245,6 +1381,121 @@ static void sysc_init_revision_quirks(struct sysc *ddata) | |||
1245 | } | 1381 | } |
1246 | } | 1382 | } |
1247 | 1383 | ||
1384 | /* 1-wire needs module's internal clocks enabled for reset */ | ||
1385 | static void sysc_clk_enable_quirk_hdq1w(struct sysc *ddata) | ||
1386 | { | ||
1387 | int offset = 0x0c; /* HDQ_CTRL_STATUS */ | ||
1388 | u16 val; | ||
1389 | |||
1390 | val = sysc_read(ddata, offset); | ||
1391 | val |= BIT(5); | ||
1392 | sysc_write(ddata, offset, val); | ||
1393 | } | ||
1394 | |||
1395 | /* I2C needs extra enable bit toggling for reset */ | ||
1396 | static void sysc_clk_quirk_i2c(struct sysc *ddata, bool enable) | ||
1397 | { | ||
1398 | int offset; | ||
1399 | u16 val; | ||
1400 | |||
1401 | /* I2C_CON, omap2/3 is different from omap4 and later */ | ||
1402 | if ((ddata->revision & 0xffffff00) == 0x001f0000) | ||
1403 | offset = 0x24; | ||
1404 | else | ||
1405 | offset = 0xa4; | ||
1406 | |||
1407 | /* I2C_EN */ | ||
1408 | val = sysc_read(ddata, offset); | ||
1409 | if (enable) | ||
1410 | val |= BIT(15); | ||
1411 | else | ||
1412 | val &= ~BIT(15); | ||
1413 | sysc_write(ddata, offset, val); | ||
1414 | } | ||
1415 | |||
1416 | static void sysc_clk_enable_quirk_i2c(struct sysc *ddata) | ||
1417 | { | ||
1418 | sysc_clk_quirk_i2c(ddata, true); | ||
1419 | } | ||
1420 | |||
1421 | static void sysc_clk_disable_quirk_i2c(struct sysc *ddata) | ||
1422 | { | ||
1423 | sysc_clk_quirk_i2c(ddata, false); | ||
1424 | } | ||
1425 | |||
1426 | /* Watchdog timer needs a disable sequence after reset */ | ||
1427 | static void sysc_reset_done_quirk_wdt(struct sysc *ddata) | ||
1428 | { | ||
1429 | int wps, spr, error; | ||
1430 | u32 val; | ||
1431 | |||
1432 | wps = 0x34; | ||
1433 | spr = 0x48; | ||
1434 | |||
1435 | sysc_write(ddata, spr, 0xaaaa); | ||
1436 | error = readl_poll_timeout(ddata->module_va + wps, val, | ||
1437 | !(val & 0x10), 100, | ||
1438 | MAX_MODULE_SOFTRESET_WAIT); | ||
1439 | if (error) | ||
1440 | dev_warn(ddata->dev, "wdt disable spr failed\n"); | ||
1441 | |||
1442 | sysc_write(ddata, wps, 0x5555); | ||
1443 | error = readl_poll_timeout(ddata->module_va + wps, val, | ||
1444 | !(val & 0x10), 100, | ||
1445 | MAX_MODULE_SOFTRESET_WAIT); | ||
1446 | if (error) | ||
1447 | dev_warn(ddata->dev, "wdt disable wps failed\n"); | ||
1448 | } | ||
1449 | |||
1450 | static void sysc_init_module_quirks(struct sysc *ddata) | ||
1451 | { | ||
1452 | if (ddata->legacy_mode || !ddata->name) | ||
1453 | return; | ||
1454 | |||
1455 | if (ddata->cfg.quirks & SYSC_MODULE_QUIRK_HDQ1W) { | ||
1456 | ddata->clk_enable_quirk = sysc_clk_enable_quirk_hdq1w; | ||
1457 | |||
1458 | return; | ||
1459 | } | ||
1460 | |||
1461 | if (ddata->cfg.quirks & SYSC_MODULE_QUIRK_I2C) { | ||
1462 | ddata->clk_enable_quirk = sysc_clk_enable_quirk_i2c; | ||
1463 | ddata->clk_disable_quirk = sysc_clk_disable_quirk_i2c; | ||
1464 | |||
1465 | return; | ||
1466 | } | ||
1467 | |||
1468 | if (ddata->cfg.quirks & SYSC_MODULE_QUIRK_WDT) | ||
1469 | ddata->reset_done_quirk = sysc_reset_done_quirk_wdt; | ||
1470 | } | ||
1471 | |||
1472 | static int sysc_clockdomain_init(struct sysc *ddata) | ||
1473 | { | ||
1474 | struct ti_sysc_platform_data *pdata = dev_get_platdata(ddata->dev); | ||
1475 | struct clk *fck = NULL, *ick = NULL; | ||
1476 | int error; | ||
1477 | |||
1478 | if (!pdata || !pdata->init_clockdomain) | ||
1479 | return 0; | ||
1480 | |||
1481 | switch (ddata->nr_clocks) { | ||
1482 | case 2: | ||
1483 | ick = ddata->clocks[SYSC_ICK]; | ||
1484 | /* fallthrough */ | ||
1485 | case 1: | ||
1486 | fck = ddata->clocks[SYSC_FCK]; | ||
1487 | break; | ||
1488 | case 0: | ||
1489 | return 0; | ||
1490 | } | ||
1491 | |||
1492 | error = pdata->init_clockdomain(ddata->dev, fck, ick, &ddata->cookie); | ||
1493 | if (!error || error == -ENODEV) | ||
1494 | return 0; | ||
1495 | |||
1496 | return error; | ||
1497 | } | ||
1498 | |||
1248 | /* | 1499 | /* |
1249 | * Note that pdata->init_module() typically does a reset first. After | 1500 | * Note that pdata->init_module() typically does a reset first. After |
1250 | * pdata->init_module() is done, PM runtime can be used for the interconnect | 1501 | * pdata->init_module() is done, PM runtime can be used for the interconnect |
@@ -1255,7 +1506,7 @@ static int sysc_legacy_init(struct sysc *ddata) | |||
1255 | struct ti_sysc_platform_data *pdata = dev_get_platdata(ddata->dev); | 1506 | struct ti_sysc_platform_data *pdata = dev_get_platdata(ddata->dev); |
1256 | int error; | 1507 | int error; |
1257 | 1508 | ||
1258 | if (!ddata->legacy_mode || !pdata || !pdata->init_module) | 1509 | if (!pdata || !pdata->init_module) |
1259 | return 0; | 1510 | return 0; |
1260 | 1511 | ||
1261 | error = pdata->init_module(ddata->dev, ddata->mdata, &ddata->cookie); | 1512 | error = pdata->init_module(ddata->dev, ddata->mdata, &ddata->cookie); |
@@ -1280,7 +1531,7 @@ static int sysc_legacy_init(struct sysc *ddata) | |||
1280 | */ | 1531 | */ |
1281 | static int sysc_rstctrl_reset_deassert(struct sysc *ddata, bool reset) | 1532 | static int sysc_rstctrl_reset_deassert(struct sysc *ddata, bool reset) |
1282 | { | 1533 | { |
1283 | int error; | 1534 | int error, val; |
1284 | 1535 | ||
1285 | if (!ddata->rsts) | 1536 | if (!ddata->rsts) |
1286 | return 0; | 1537 | return 0; |
@@ -1291,37 +1542,68 @@ static int sysc_rstctrl_reset_deassert(struct sysc *ddata, bool reset) | |||
1291 | return error; | 1542 | return error; |
1292 | } | 1543 | } |
1293 | 1544 | ||
1294 | return reset_control_deassert(ddata->rsts); | 1545 | error = reset_control_deassert(ddata->rsts); |
1546 | if (error == -EEXIST) | ||
1547 | return 0; | ||
1548 | |||
1549 | error = readx_poll_timeout(reset_control_status, ddata->rsts, val, | ||
1550 | val == 0, 100, MAX_MODULE_SOFTRESET_WAIT); | ||
1551 | |||
1552 | return error; | ||
1295 | } | 1553 | } |
1296 | 1554 | ||
1555 | /* | ||
1556 | * Note that the caller must ensure the interconnect target module is enabled | ||
1557 | * before calling reset. Otherwise reset will not complete. | ||
1558 | */ | ||
1297 | static int sysc_reset(struct sysc *ddata) | 1559 | static int sysc_reset(struct sysc *ddata) |
1298 | { | 1560 | { |
1299 | int offset = ddata->offsets[SYSC_SYSCONFIG]; | 1561 | int sysc_offset, syss_offset, sysc_val, rstval, quirks, error = 0; |
1300 | int val; | 1562 | u32 sysc_mask, syss_done; |
1563 | |||
1564 | sysc_offset = ddata->offsets[SYSC_SYSCONFIG]; | ||
1565 | syss_offset = ddata->offsets[SYSC_SYSSTATUS]; | ||
1566 | quirks = ddata->cfg.quirks; | ||
1301 | 1567 | ||
1302 | if (ddata->legacy_mode || offset < 0 || | 1568 | if (ddata->legacy_mode || sysc_offset < 0 || |
1569 | ddata->cap->regbits->srst_shift < 0 || | ||
1303 | ddata->cfg.quirks & SYSC_QUIRK_NO_RESET_ON_INIT) | 1570 | ddata->cfg.quirks & SYSC_QUIRK_NO_RESET_ON_INIT) |
1304 | return 0; | 1571 | return 0; |
1305 | 1572 | ||
1306 | /* | 1573 | sysc_mask = BIT(ddata->cap->regbits->srst_shift); |
1307 | * Currently only support reset status in sysstatus. | ||
1308 | * Warn and return error in all other cases | ||
1309 | */ | ||
1310 | if (!ddata->cfg.syss_mask) { | ||
1311 | dev_err(ddata->dev, "No ti,syss-mask. Reset failed\n"); | ||
1312 | return -EINVAL; | ||
1313 | } | ||
1314 | 1574 | ||
1315 | val = sysc_read(ddata, offset); | 1575 | if (ddata->cfg.quirks & SYSS_QUIRK_RESETDONE_INVERTED) |
1316 | val |= (0x1 << ddata->cap->regbits->srst_shift); | 1576 | syss_done = 0; |
1317 | sysc_write(ddata, offset, val); | 1577 | else |
1578 | syss_done = ddata->cfg.syss_mask; | ||
1579 | |||
1580 | if (ddata->clk_disable_quirk) | ||
1581 | ddata->clk_disable_quirk(ddata); | ||
1582 | |||
1583 | sysc_val = sysc_read_sysconfig(ddata); | ||
1584 | sysc_val |= sysc_mask; | ||
1585 | sysc_write(ddata, sysc_offset, sysc_val); | ||
1586 | |||
1587 | if (ddata->clk_enable_quirk) | ||
1588 | ddata->clk_enable_quirk(ddata); | ||
1318 | 1589 | ||
1319 | /* Poll on reset status */ | 1590 | /* Poll on reset status */ |
1320 | offset = ddata->offsets[SYSC_SYSSTATUS]; | 1591 | if (syss_offset >= 0) { |
1592 | error = readx_poll_timeout(sysc_read_sysstatus, ddata, rstval, | ||
1593 | (rstval & ddata->cfg.syss_mask) == | ||
1594 | syss_done, | ||
1595 | 100, MAX_MODULE_SOFTRESET_WAIT); | ||
1596 | |||
1597 | } else if (ddata->cfg.quirks & SYSC_QUIRK_RESET_STATUS) { | ||
1598 | error = readx_poll_timeout(sysc_read_sysconfig, ddata, rstval, | ||
1599 | !(rstval & sysc_mask), | ||
1600 | 100, MAX_MODULE_SOFTRESET_WAIT); | ||
1601 | } | ||
1602 | |||
1603 | if (ddata->reset_done_quirk) | ||
1604 | ddata->reset_done_quirk(ddata); | ||
1321 | 1605 | ||
1322 | return readl_poll_timeout(ddata->module_va + offset, val, | 1606 | return error; |
1323 | (val & ddata->cfg.syss_mask) == 0x0, | ||
1324 | 100, MAX_MODULE_SOFTRESET_WAIT); | ||
1325 | } | 1607 | } |
1326 | 1608 | ||
1327 | /* | 1609 | /* |
@@ -1334,12 +1616,8 @@ static int sysc_init_module(struct sysc *ddata) | |||
1334 | { | 1616 | { |
1335 | int error = 0; | 1617 | int error = 0; |
1336 | bool manage_clocks = true; | 1618 | bool manage_clocks = true; |
1337 | bool reset = true; | ||
1338 | |||
1339 | if (ddata->cfg.quirks & SYSC_QUIRK_NO_RESET_ON_INIT) | ||
1340 | reset = false; | ||
1341 | 1619 | ||
1342 | error = sysc_rstctrl_reset_deassert(ddata, reset); | 1620 | error = sysc_rstctrl_reset_deassert(ddata, false); |
1343 | if (error) | 1621 | if (error) |
1344 | return error; | 1622 | return error; |
1345 | 1623 | ||
@@ -1347,7 +1625,13 @@ static int sysc_init_module(struct sysc *ddata) | |||
1347 | (SYSC_QUIRK_NO_IDLE | SYSC_QUIRK_NO_IDLE_ON_INIT)) | 1625 | (SYSC_QUIRK_NO_IDLE | SYSC_QUIRK_NO_IDLE_ON_INIT)) |
1348 | manage_clocks = false; | 1626 | manage_clocks = false; |
1349 | 1627 | ||
1628 | error = sysc_clockdomain_init(ddata); | ||
1629 | if (error) | ||
1630 | return error; | ||
1631 | |||
1350 | if (manage_clocks) { | 1632 | if (manage_clocks) { |
1633 | sysc_clkdm_deny_idle(ddata); | ||
1634 | |||
1351 | error = sysc_enable_opt_clocks(ddata); | 1635 | error = sysc_enable_opt_clocks(ddata); |
1352 | if (error) | 1636 | if (error) |
1353 | return error; | 1637 | return error; |
@@ -1357,23 +1641,43 @@ static int sysc_init_module(struct sysc *ddata) | |||
1357 | goto err_opt_clocks; | 1641 | goto err_opt_clocks; |
1358 | } | 1642 | } |
1359 | 1643 | ||
1644 | if (!(ddata->cfg.quirks & SYSC_QUIRK_NO_RESET_ON_INIT)) { | ||
1645 | error = sysc_rstctrl_reset_deassert(ddata, true); | ||
1646 | if (error) | ||
1647 | goto err_main_clocks; | ||
1648 | } | ||
1649 | |||
1360 | ddata->revision = sysc_read_revision(ddata); | 1650 | ddata->revision = sysc_read_revision(ddata); |
1361 | sysc_init_revision_quirks(ddata); | 1651 | sysc_init_revision_quirks(ddata); |
1652 | sysc_init_module_quirks(ddata); | ||
1362 | 1653 | ||
1363 | error = sysc_legacy_init(ddata); | 1654 | if (ddata->legacy_mode) { |
1364 | if (error) | 1655 | error = sysc_legacy_init(ddata); |
1365 | goto err_main_clocks; | 1656 | if (error) |
1657 | goto err_main_clocks; | ||
1658 | } | ||
1659 | |||
1660 | if (!ddata->legacy_mode && manage_clocks) { | ||
1661 | error = sysc_enable_module(ddata->dev); | ||
1662 | if (error) | ||
1663 | goto err_main_clocks; | ||
1664 | } | ||
1366 | 1665 | ||
1367 | error = sysc_reset(ddata); | 1666 | error = sysc_reset(ddata); |
1368 | if (error) | 1667 | if (error) |
1369 | dev_err(ddata->dev, "Reset failed with %d\n", error); | 1668 | dev_err(ddata->dev, "Reset failed with %d\n", error); |
1370 | 1669 | ||
1670 | if (!ddata->legacy_mode && manage_clocks) | ||
1671 | sysc_disable_module(ddata->dev); | ||
1672 | |||
1371 | err_main_clocks: | 1673 | err_main_clocks: |
1372 | if (manage_clocks) | 1674 | if (manage_clocks) |
1373 | sysc_disable_main_clocks(ddata); | 1675 | sysc_disable_main_clocks(ddata); |
1374 | err_opt_clocks: | 1676 | err_opt_clocks: |
1375 | if (manage_clocks) | 1677 | if (manage_clocks) { |
1376 | sysc_disable_opt_clocks(ddata); | 1678 | sysc_disable_opt_clocks(ddata); |
1679 | sysc_clkdm_allow_idle(ddata); | ||
1680 | } | ||
1377 | 1681 | ||
1378 | return error; | 1682 | return error; |
1379 | } | 1683 | } |
@@ -1663,9 +1967,6 @@ static struct dev_pm_domain sysc_child_pm_domain = { | |||
1663 | */ | 1967 | */ |
1664 | static void sysc_legacy_idle_quirk(struct sysc *ddata, struct device *child) | 1968 | static void sysc_legacy_idle_quirk(struct sysc *ddata, struct device *child) |
1665 | { | 1969 | { |
1666 | if (!ddata->legacy_mode) | ||
1667 | return; | ||
1668 | |||
1669 | if (ddata->cfg.quirks & SYSC_QUIRK_LEGACY_IDLE) | 1970 | if (ddata->cfg.quirks & SYSC_QUIRK_LEGACY_IDLE) |
1670 | dev_pm_domain_set(child, &sysc_child_pm_domain); | 1971 | dev_pm_domain_set(child, &sysc_child_pm_domain); |
1671 | } | 1972 | } |
@@ -2005,6 +2306,7 @@ static const struct sysc_capabilities sysc_dra7_mcan = { | |||
2005 | .type = TI_SYSC_DRA7_MCAN, | 2306 | .type = TI_SYSC_DRA7_MCAN, |
2006 | .sysc_mask = SYSC_DRA7_MCAN_ENAWAKEUP | SYSC_OMAP4_SOFTRESET, | 2307 | .sysc_mask = SYSC_DRA7_MCAN_ENAWAKEUP | SYSC_OMAP4_SOFTRESET, |
2007 | .regbits = &sysc_regbits_dra7_mcan, | 2308 | .regbits = &sysc_regbits_dra7_mcan, |
2309 | .mod_quirks = SYSS_QUIRK_RESETDONE_INVERTED, | ||
2008 | }; | 2310 | }; |
2009 | 2311 | ||
2010 | static int sysc_init_pdata(struct sysc *ddata) | 2312 | static int sysc_init_pdata(struct sysc *ddata) |
@@ -2012,20 +2314,22 @@ static int sysc_init_pdata(struct sysc *ddata) | |||
2012 | struct ti_sysc_platform_data *pdata = dev_get_platdata(ddata->dev); | 2314 | struct ti_sysc_platform_data *pdata = dev_get_platdata(ddata->dev); |
2013 | struct ti_sysc_module_data *mdata; | 2315 | struct ti_sysc_module_data *mdata; |
2014 | 2316 | ||
2015 | if (!pdata || !ddata->legacy_mode) | 2317 | if (!pdata) |
2016 | return 0; | 2318 | return 0; |
2017 | 2319 | ||
2018 | mdata = devm_kzalloc(ddata->dev, sizeof(*mdata), GFP_KERNEL); | 2320 | mdata = devm_kzalloc(ddata->dev, sizeof(*mdata), GFP_KERNEL); |
2019 | if (!mdata) | 2321 | if (!mdata) |
2020 | return -ENOMEM; | 2322 | return -ENOMEM; |
2021 | 2323 | ||
2022 | mdata->name = ddata->legacy_mode; | 2324 | if (ddata->legacy_mode) { |
2023 | mdata->module_pa = ddata->module_pa; | 2325 | mdata->name = ddata->legacy_mode; |
2024 | mdata->module_size = ddata->module_size; | 2326 | mdata->module_pa = ddata->module_pa; |
2025 | mdata->offsets = ddata->offsets; | 2327 | mdata->module_size = ddata->module_size; |
2026 | mdata->nr_offsets = SYSC_MAX_REGS; | 2328 | mdata->offsets = ddata->offsets; |
2027 | mdata->cap = ddata->cap; | 2329 | mdata->nr_offsets = SYSC_MAX_REGS; |
2028 | mdata->cfg = &ddata->cfg; | 2330 | mdata->cap = ddata->cap; |
2331 | mdata->cfg = &ddata->cfg; | ||
2332 | } | ||
2029 | 2333 | ||
2030 | ddata->mdata = mdata; | 2334 | ddata->mdata = mdata; |
2031 | 2335 | ||
@@ -2145,7 +2449,7 @@ static int sysc_probe(struct platform_device *pdev) | |||
2145 | } | 2449 | } |
2146 | 2450 | ||
2147 | if (!of_get_available_child_count(ddata->dev->of_node)) | 2451 | if (!of_get_available_child_count(ddata->dev->of_node)) |
2148 | reset_control_assert(ddata->rsts); | 2452 | ddata->disable_on_idle = true; |
2149 | 2453 | ||
2150 | return 0; | 2454 | return 0; |
2151 | 2455 | ||