pinmux-common.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright (c) 2010-2013, NVIDIA CORPORATION. All rights reserved.
  4. * Copyright (c) 2011 The Chromium OS Authors.
  5. */
  6. #include <common.h>
  7. #include <asm/io.h>
  8. #include <asm/arch/pinmux.h>
  9. /* return 1 if a pingrp is in range */
  10. #define pmux_pingrp_isvalid(pin) (((pin) >= 0) && ((pin) < PMUX_PINGRP_COUNT))
  11. /* return 1 if a pmux_func is in range */
  12. #define pmux_func_isvalid(func) \
  13. (((func) >= 0) && ((func) < PMUX_FUNC_COUNT))
  14. /* return 1 if a pin_pupd_is in range */
  15. #define pmux_pin_pupd_isvalid(pupd) \
  16. (((pupd) >= PMUX_PULL_NORMAL) && ((pupd) <= PMUX_PULL_UP))
  17. /* return 1 if a pin_tristate_is in range */
  18. #define pmux_pin_tristate_isvalid(tristate) \
  19. (((tristate) >= PMUX_TRI_NORMAL) && ((tristate) <= PMUX_TRI_TRISTATE))
  20. #ifdef TEGRA_PMX_PINS_HAVE_E_INPUT
  21. /* return 1 if a pin_io_is in range */
  22. #define pmux_pin_io_isvalid(io) \
  23. (((io) >= PMUX_PIN_OUTPUT) && ((io) <= PMUX_PIN_INPUT))
  24. #endif
  25. #ifdef TEGRA_PMX_PINS_HAVE_LOCK
  26. /* return 1 if a pin_lock is in range */
  27. #define pmux_pin_lock_isvalid(lock) \
  28. (((lock) >= PMUX_PIN_LOCK_DISABLE) && ((lock) <= PMUX_PIN_LOCK_ENABLE))
  29. #endif
  30. #ifdef TEGRA_PMX_PINS_HAVE_OD
  31. /* return 1 if a pin_od is in range */
  32. #define pmux_pin_od_isvalid(od) \
  33. (((od) >= PMUX_PIN_OD_DISABLE) && ((od) <= PMUX_PIN_OD_ENABLE))
  34. #endif
  35. #ifdef TEGRA_PMX_PINS_HAVE_IO_RESET
  36. /* return 1 if a pin_ioreset_is in range */
  37. #define pmux_pin_ioreset_isvalid(ioreset) \
  38. (((ioreset) >= PMUX_PIN_IO_RESET_DISABLE) && \
  39. ((ioreset) <= PMUX_PIN_IO_RESET_ENABLE))
  40. #endif
  41. #ifdef TEGRA_PMX_PINS_HAVE_RCV_SEL
  42. /* return 1 if a pin_rcv_sel_is in range */
  43. #define pmux_pin_rcv_sel_isvalid(rcv_sel) \
  44. (((rcv_sel) >= PMUX_PIN_RCV_SEL_NORMAL) && \
  45. ((rcv_sel) <= PMUX_PIN_RCV_SEL_HIGH))
  46. #endif
  47. #ifdef TEGRA_PMX_PINS_HAVE_E_IO_HV
  48. /* return 1 if a pin_e_io_hv is in range */
  49. #define pmux_pin_e_io_hv_isvalid(e_io_hv) \
  50. (((e_io_hv) >= PMUX_PIN_E_IO_HV_NORMAL) && \
  51. ((e_io_hv) <= PMUX_PIN_E_IO_HV_HIGH))
  52. #endif
  53. #ifdef TEGRA_PMX_GRPS_HAVE_LPMD
  54. #define pmux_lpmd_isvalid(lpm) \
  55. (((lpm) >= PMUX_LPMD_X8) && ((lpm) <= PMUX_LPMD_X))
  56. #endif
  57. #if defined(TEGRA_PMX_PINS_HAVE_SCHMT) || defined(TEGRA_PMX_GRPS_HAVE_SCHMT)
  58. #define pmux_schmt_isvalid(schmt) \
  59. (((schmt) >= PMUX_SCHMT_DISABLE) && ((schmt) <= PMUX_SCHMT_ENABLE))
  60. #endif
  61. #if defined(TEGRA_PMX_PINS_HAVE_HSM) || defined(TEGRA_PMX_GRPS_HAVE_HSM)
  62. #define pmux_hsm_isvalid(hsm) \
  63. (((hsm) >= PMUX_HSM_DISABLE) && ((hsm) <= PMUX_HSM_ENABLE))
  64. #endif
  65. #define _R(offset) (u32 *)((unsigned long)NV_PA_APB_MISC_BASE + (offset))
  66. #if defined(CONFIG_TEGRA20)
  67. #define MUX_REG(grp) _R(0x80 + ((tegra_soc_pingroups[grp].ctl_id / 16) * 4))
  68. #define MUX_SHIFT(grp) ((tegra_soc_pingroups[grp].ctl_id % 16) * 2)
  69. #define PULL_REG(grp) _R(0xa0 + ((tegra_soc_pingroups[grp].pull_id / 16) * 4))
  70. #define PULL_SHIFT(grp) ((tegra_soc_pingroups[grp].pull_id % 16) * 2)
  71. #define TRI_REG(grp) _R(0x14 + (((grp) / 32) * 4))
  72. #define TRI_SHIFT(grp) ((grp) % 32)
  73. #else
  74. #define REG(pin) _R(0x3000 + ((pin) * 4))
  75. #define MUX_REG(pin) REG(pin)
  76. #define MUX_SHIFT(pin) 0
  77. #define PULL_REG(pin) REG(pin)
  78. #define PULL_SHIFT(pin) 2
  79. #define TRI_REG(pin) REG(pin)
  80. #define TRI_SHIFT(pin) 4
  81. #endif /* CONFIG_TEGRA20 */
  82. #define DRV_REG(group) _R(TEGRA_PMX_SOC_DRV_GROUP_BASE_REG + ((group) * 4))
  83. #define MIPIPADCTRL_REG(group) _R(TEGRA_PMX_SOC_MIPIPADCTRL_BASE_REG + ((group) * 4))
  84. /*
  85. * We could force arch-tegraNN/pinmux.h to define all of these. However,
  86. * that's a lot of defines, and for now it's manageable to just put a
  87. * special case here. It's possible this decision will change with future
  88. * SoCs.
  89. */
  90. #ifdef CONFIG_TEGRA210
  91. #define IO_SHIFT 6
  92. #define LOCK_SHIFT 7
  93. #ifdef TEGRA_PMX_PINS_HAVE_HSM
  94. #define HSM_SHIFT 9
  95. #endif
  96. #define E_IO_HV_SHIFT 10
  97. #define OD_SHIFT 11
  98. #ifdef TEGRA_PMX_PINS_HAVE_SCHMT
  99. #define SCHMT_SHIFT 12
  100. #endif
  101. #else
  102. #define IO_SHIFT 5
  103. #define OD_SHIFT 6
  104. #define LOCK_SHIFT 7
  105. #define IO_RESET_SHIFT 8
  106. #define RCV_SEL_SHIFT 9
  107. #endif
  108. #ifdef TEGRA_PMX_SOC_HAS_IO_CLAMPING
  109. /* This register/field only exists on Tegra114 and later */
  110. #define APB_MISC_PP_PINMUX_GLOBAL_0 0x40
  111. #define CLAMP_INPUTS_WHEN_TRISTATED 1
  112. void pinmux_set_tristate_input_clamping(void)
  113. {
  114. u32 *reg = _R(APB_MISC_PP_PINMUX_GLOBAL_0);
  115. setbits_le32(reg, CLAMP_INPUTS_WHEN_TRISTATED);
  116. }
  117. void pinmux_clear_tristate_input_clamping(void)
  118. {
  119. u32 *reg = _R(APB_MISC_PP_PINMUX_GLOBAL_0);
  120. clrbits_le32(reg, CLAMP_INPUTS_WHEN_TRISTATED);
  121. }
  122. #endif
  123. void pinmux_set_func(enum pmux_pingrp pin, enum pmux_func func)
  124. {
  125. u32 *reg = MUX_REG(pin);
  126. int i, mux = -1;
  127. u32 val;
  128. if (func == PMUX_FUNC_DEFAULT)
  129. return;
  130. /* Error check on pin and func */
  131. assert(pmux_pingrp_isvalid(pin));
  132. assert(pmux_func_isvalid(func));
  133. if (func >= PMUX_FUNC_RSVD1) {
  134. mux = (func - PMUX_FUNC_RSVD1) & 3;
  135. } else {
  136. /* Search for the appropriate function */
  137. for (i = 0; i < 4; i++) {
  138. if (tegra_soc_pingroups[pin].funcs[i] == func) {
  139. mux = i;
  140. break;
  141. }
  142. }
  143. }
  144. assert(mux != -1);
  145. val = readl(reg);
  146. val &= ~(3 << MUX_SHIFT(pin));
  147. val |= (mux << MUX_SHIFT(pin));
  148. writel(val, reg);
  149. }
  150. void pinmux_set_pullupdown(enum pmux_pingrp pin, enum pmux_pull pupd)
  151. {
  152. u32 *reg = PULL_REG(pin);
  153. u32 val;
  154. /* Error check on pin and pupd */
  155. assert(pmux_pingrp_isvalid(pin));
  156. assert(pmux_pin_pupd_isvalid(pupd));
  157. val = readl(reg);
  158. val &= ~(3 << PULL_SHIFT(pin));
  159. val |= (pupd << PULL_SHIFT(pin));
  160. writel(val, reg);
  161. }
  162. static void pinmux_set_tristate(enum pmux_pingrp pin, int tri)
  163. {
  164. u32 *reg = TRI_REG(pin);
  165. u32 val;
  166. /* Error check on pin */
  167. assert(pmux_pingrp_isvalid(pin));
  168. assert(pmux_pin_tristate_isvalid(tri));
  169. val = readl(reg);
  170. if (tri == PMUX_TRI_TRISTATE)
  171. val |= (1 << TRI_SHIFT(pin));
  172. else
  173. val &= ~(1 << TRI_SHIFT(pin));
  174. writel(val, reg);
  175. }
  176. void pinmux_tristate_enable(enum pmux_pingrp pin)
  177. {
  178. pinmux_set_tristate(pin, PMUX_TRI_TRISTATE);
  179. }
  180. void pinmux_tristate_disable(enum pmux_pingrp pin)
  181. {
  182. pinmux_set_tristate(pin, PMUX_TRI_NORMAL);
  183. }
  184. #ifdef TEGRA_PMX_PINS_HAVE_E_INPUT
  185. void pinmux_set_io(enum pmux_pingrp pin, enum pmux_pin_io io)
  186. {
  187. u32 *reg = REG(pin);
  188. u32 val;
  189. if (io == PMUX_PIN_NONE)
  190. return;
  191. /* Error check on pin and io */
  192. assert(pmux_pingrp_isvalid(pin));
  193. assert(pmux_pin_io_isvalid(io));
  194. val = readl(reg);
  195. if (io == PMUX_PIN_INPUT)
  196. val |= (io & 1) << IO_SHIFT;
  197. else
  198. val &= ~(1 << IO_SHIFT);
  199. writel(val, reg);
  200. }
  201. #endif
  202. #ifdef TEGRA_PMX_PINS_HAVE_LOCK
  203. static void pinmux_set_lock(enum pmux_pingrp pin, enum pmux_pin_lock lock)
  204. {
  205. u32 *reg = REG(pin);
  206. u32 val;
  207. if (lock == PMUX_PIN_LOCK_DEFAULT)
  208. return;
  209. /* Error check on pin and lock */
  210. assert(pmux_pingrp_isvalid(pin));
  211. assert(pmux_pin_lock_isvalid(lock));
  212. val = readl(reg);
  213. if (lock == PMUX_PIN_LOCK_ENABLE) {
  214. val |= (1 << LOCK_SHIFT);
  215. } else {
  216. if (val & (1 << LOCK_SHIFT))
  217. printf("%s: Cannot clear LOCK bit!\n", __func__);
  218. val &= ~(1 << LOCK_SHIFT);
  219. }
  220. writel(val, reg);
  221. return;
  222. }
  223. #endif
  224. #ifdef TEGRA_PMX_PINS_HAVE_OD
  225. static void pinmux_set_od(enum pmux_pingrp pin, enum pmux_pin_od od)
  226. {
  227. u32 *reg = REG(pin);
  228. u32 val;
  229. if (od == PMUX_PIN_OD_DEFAULT)
  230. return;
  231. /* Error check on pin and od */
  232. assert(pmux_pingrp_isvalid(pin));
  233. assert(pmux_pin_od_isvalid(od));
  234. val = readl(reg);
  235. if (od == PMUX_PIN_OD_ENABLE)
  236. val |= (1 << OD_SHIFT);
  237. else
  238. val &= ~(1 << OD_SHIFT);
  239. writel(val, reg);
  240. return;
  241. }
  242. #endif
  243. #ifdef TEGRA_PMX_PINS_HAVE_IO_RESET
  244. static void pinmux_set_ioreset(enum pmux_pingrp pin,
  245. enum pmux_pin_ioreset ioreset)
  246. {
  247. u32 *reg = REG(pin);
  248. u32 val;
  249. if (ioreset == PMUX_PIN_IO_RESET_DEFAULT)
  250. return;
  251. /* Error check on pin and ioreset */
  252. assert(pmux_pingrp_isvalid(pin));
  253. assert(pmux_pin_ioreset_isvalid(ioreset));
  254. val = readl(reg);
  255. if (ioreset == PMUX_PIN_IO_RESET_ENABLE)
  256. val |= (1 << IO_RESET_SHIFT);
  257. else
  258. val &= ~(1 << IO_RESET_SHIFT);
  259. writel(val, reg);
  260. return;
  261. }
  262. #endif
  263. #ifdef TEGRA_PMX_PINS_HAVE_RCV_SEL
  264. static void pinmux_set_rcv_sel(enum pmux_pingrp pin,
  265. enum pmux_pin_rcv_sel rcv_sel)
  266. {
  267. u32 *reg = REG(pin);
  268. u32 val;
  269. if (rcv_sel == PMUX_PIN_RCV_SEL_DEFAULT)
  270. return;
  271. /* Error check on pin and rcv_sel */
  272. assert(pmux_pingrp_isvalid(pin));
  273. assert(pmux_pin_rcv_sel_isvalid(rcv_sel));
  274. val = readl(reg);
  275. if (rcv_sel == PMUX_PIN_RCV_SEL_HIGH)
  276. val |= (1 << RCV_SEL_SHIFT);
  277. else
  278. val &= ~(1 << RCV_SEL_SHIFT);
  279. writel(val, reg);
  280. return;
  281. }
  282. #endif
  283. #ifdef TEGRA_PMX_PINS_HAVE_E_IO_HV
  284. static void pinmux_set_e_io_hv(enum pmux_pingrp pin,
  285. enum pmux_pin_e_io_hv e_io_hv)
  286. {
  287. u32 *reg = REG(pin);
  288. u32 val;
  289. if (e_io_hv == PMUX_PIN_E_IO_HV_DEFAULT)
  290. return;
  291. /* Error check on pin and e_io_hv */
  292. assert(pmux_pingrp_isvalid(pin));
  293. assert(pmux_pin_e_io_hv_isvalid(e_io_hv));
  294. val = readl(reg);
  295. if (e_io_hv == PMUX_PIN_E_IO_HV_HIGH)
  296. val |= (1 << E_IO_HV_SHIFT);
  297. else
  298. val &= ~(1 << E_IO_HV_SHIFT);
  299. writel(val, reg);
  300. return;
  301. }
  302. #endif
  303. #ifdef TEGRA_PMX_PINS_HAVE_SCHMT
  304. static void pinmux_set_schmt(enum pmux_pingrp pin, enum pmux_schmt schmt)
  305. {
  306. u32 *reg = REG(grp);
  307. u32 val;
  308. /* NONE means unspecified/do not change/use POR value */
  309. if (schmt == PMUX_SCHMT_NONE)
  310. return;
  311. /* Error check pad */
  312. assert(pmux_pingrp_isvalid(pin));
  313. assert(pmux_schmt_isvalid(schmt));
  314. val = readl(reg);
  315. if (schmt == PMUX_SCHMT_ENABLE)
  316. val |= (1 << SCHMT_SHIFT);
  317. else
  318. val &= ~(1 << SCHMT_SHIFT);
  319. writel(val, reg);
  320. return;
  321. }
  322. #endif
  323. #ifdef TEGRA_PMX_PINS_HAVE_HSM
  324. static void pinmux_set_hsm(enum pmux_pingrp pin, enum pmux_hsm hsm)
  325. {
  326. u32 *reg = REG(grp);
  327. u32 val;
  328. /* NONE means unspecified/do not change/use POR value */
  329. if (hsm == PMUX_HSM_NONE)
  330. return;
  331. /* Error check pad */
  332. assert(pmux_pingrp_isvalid(pin));
  333. assert(pmux_hsm_isvalid(hsm));
  334. val = readl(reg);
  335. if (hsm == PMUX_HSM_ENABLE)
  336. val |= (1 << HSM_SHIFT);
  337. else
  338. val &= ~(1 << HSM_SHIFT);
  339. writel(val, reg);
  340. return;
  341. }
  342. #endif
  343. static void pinmux_config_pingrp(const struct pmux_pingrp_config *config)
  344. {
  345. enum pmux_pingrp pin = config->pingrp;
  346. pinmux_set_func(pin, config->func);
  347. pinmux_set_pullupdown(pin, config->pull);
  348. pinmux_set_tristate(pin, config->tristate);
  349. #ifdef TEGRA_PMX_PINS_HAVE_E_INPUT
  350. pinmux_set_io(pin, config->io);
  351. #endif
  352. #ifdef TEGRA_PMX_PINS_HAVE_LOCK
  353. pinmux_set_lock(pin, config->lock);
  354. #endif
  355. #ifdef TEGRA_PMX_PINS_HAVE_OD
  356. pinmux_set_od(pin, config->od);
  357. #endif
  358. #ifdef TEGRA_PMX_PINS_HAVE_IO_RESET
  359. pinmux_set_ioreset(pin, config->ioreset);
  360. #endif
  361. #ifdef TEGRA_PMX_PINS_HAVE_RCV_SEL
  362. pinmux_set_rcv_sel(pin, config->rcv_sel);
  363. #endif
  364. #ifdef TEGRA_PMX_PINS_HAVE_E_IO_HV
  365. pinmux_set_e_io_hv(pin, config->e_io_hv);
  366. #endif
  367. #ifdef TEGRA_PMX_PINS_HAVE_SCHMT
  368. pinmux_set_schmt(pin, config->schmt);
  369. #endif
  370. #ifdef TEGRA_PMX_PINS_HAVE_HSM
  371. pinmux_set_hsm(pin, config->hsm);
  372. #endif
  373. }
  374. void pinmux_config_pingrp_table(const struct pmux_pingrp_config *config,
  375. int len)
  376. {
  377. int i;
  378. for (i = 0; i < len; i++)
  379. pinmux_config_pingrp(&config[i]);
  380. }
  381. #ifdef TEGRA_PMX_SOC_HAS_DRVGRPS
  382. #define pmux_drvgrp_isvalid(pd) (((pd) >= 0) && ((pd) < PMUX_DRVGRP_COUNT))
  383. #define pmux_slw_isvalid(slw) \
  384. (((slw) >= PMUX_SLWF_MIN) && ((slw) <= PMUX_SLWF_MAX))
  385. #define pmux_drv_isvalid(drv) \
  386. (((drv) >= PMUX_DRVUP_MIN) && ((drv) <= PMUX_DRVUP_MAX))
  387. #ifdef TEGRA_PMX_GRPS_HAVE_HSM
  388. #define HSM_SHIFT 2
  389. #endif
  390. #ifdef TEGRA_PMX_GRPS_HAVE_SCHMT
  391. #define SCHMT_SHIFT 3
  392. #endif
  393. #ifdef TEGRA_PMX_GRPS_HAVE_LPMD
  394. #define LPMD_SHIFT 4
  395. #define LPMD_MASK (3 << LPMD_SHIFT)
  396. #endif
  397. /*
  398. * Note that the following DRV* and SLW* defines are accurate for many drive
  399. * groups on many SoCs. We really need a per-group data structure to solve
  400. * this, since the fields are in different positions/sizes in different
  401. * registers (for different groups).
  402. *
  403. * On Tegra30/114/124, the DRV*_SHIFT values vary.
  404. * On Tegra30, the SLW*_SHIFT values vary.
  405. * On Tegra30/114/124/210, the DRV*_MASK values vary, although the values
  406. * below are wide enough to cover the widest fields, and hopefully don't
  407. * interfere with any other fields.
  408. * On Tegra30, the SLW*_MASK values vary, but we can't use a value that's
  409. * wide enough to cover all cases, since that would cause the field to
  410. * overlap with other fields in the narrower cases.
  411. */
  412. #define DRVDN_SHIFT 12
  413. #define DRVDN_MASK (0x7F << DRVDN_SHIFT)
  414. #define DRVUP_SHIFT 20
  415. #define DRVUP_MASK (0x7F << DRVUP_SHIFT)
  416. #define SLWR_SHIFT 28
  417. #define SLWR_MASK (3 << SLWR_SHIFT)
  418. #define SLWF_SHIFT 30
  419. #define SLWF_MASK (3 << SLWF_SHIFT)
  420. static void pinmux_set_drvup_slwf(enum pmux_drvgrp grp, int slwf)
  421. {
  422. u32 *reg = DRV_REG(grp);
  423. u32 val;
  424. /* NONE means unspecified/do not change/use POR value */
  425. if (slwf == PMUX_SLWF_NONE)
  426. return;
  427. /* Error check on pad and slwf */
  428. assert(pmux_drvgrp_isvalid(grp));
  429. assert(pmux_slw_isvalid(slwf));
  430. val = readl(reg);
  431. val &= ~SLWF_MASK;
  432. val |= (slwf << SLWF_SHIFT);
  433. writel(val, reg);
  434. return;
  435. }
  436. static void pinmux_set_drvdn_slwr(enum pmux_drvgrp grp, int slwr)
  437. {
  438. u32 *reg = DRV_REG(grp);
  439. u32 val;
  440. /* NONE means unspecified/do not change/use POR value */
  441. if (slwr == PMUX_SLWR_NONE)
  442. return;
  443. /* Error check on pad and slwr */
  444. assert(pmux_drvgrp_isvalid(grp));
  445. assert(pmux_slw_isvalid(slwr));
  446. val = readl(reg);
  447. val &= ~SLWR_MASK;
  448. val |= (slwr << SLWR_SHIFT);
  449. writel(val, reg);
  450. return;
  451. }
  452. static void pinmux_set_drvup(enum pmux_drvgrp grp, int drvup)
  453. {
  454. u32 *reg = DRV_REG(grp);
  455. u32 val;
  456. /* NONE means unspecified/do not change/use POR value */
  457. if (drvup == PMUX_DRVUP_NONE)
  458. return;
  459. /* Error check on pad and drvup */
  460. assert(pmux_drvgrp_isvalid(grp));
  461. assert(pmux_drv_isvalid(drvup));
  462. val = readl(reg);
  463. val &= ~DRVUP_MASK;
  464. val |= (drvup << DRVUP_SHIFT);
  465. writel(val, reg);
  466. return;
  467. }
  468. static void pinmux_set_drvdn(enum pmux_drvgrp grp, int drvdn)
  469. {
  470. u32 *reg = DRV_REG(grp);
  471. u32 val;
  472. /* NONE means unspecified/do not change/use POR value */
  473. if (drvdn == PMUX_DRVDN_NONE)
  474. return;
  475. /* Error check on pad and drvdn */
  476. assert(pmux_drvgrp_isvalid(grp));
  477. assert(pmux_drv_isvalid(drvdn));
  478. val = readl(reg);
  479. val &= ~DRVDN_MASK;
  480. val |= (drvdn << DRVDN_SHIFT);
  481. writel(val, reg);
  482. return;
  483. }
  484. #ifdef TEGRA_PMX_GRPS_HAVE_LPMD
  485. static void pinmux_set_lpmd(enum pmux_drvgrp grp, enum pmux_lpmd lpmd)
  486. {
  487. u32 *reg = DRV_REG(grp);
  488. u32 val;
  489. /* NONE means unspecified/do not change/use POR value */
  490. if (lpmd == PMUX_LPMD_NONE)
  491. return;
  492. /* Error check pad and lpmd value */
  493. assert(pmux_drvgrp_isvalid(grp));
  494. assert(pmux_lpmd_isvalid(lpmd));
  495. val = readl(reg);
  496. val &= ~LPMD_MASK;
  497. val |= (lpmd << LPMD_SHIFT);
  498. writel(val, reg);
  499. return;
  500. }
  501. #endif
  502. #ifdef TEGRA_PMX_GRPS_HAVE_SCHMT
  503. static void pinmux_set_schmt(enum pmux_drvgrp grp, enum pmux_schmt schmt)
  504. {
  505. u32 *reg = DRV_REG(grp);
  506. u32 val;
  507. /* NONE means unspecified/do not change/use POR value */
  508. if (schmt == PMUX_SCHMT_NONE)
  509. return;
  510. /* Error check pad */
  511. assert(pmux_drvgrp_isvalid(grp));
  512. assert(pmux_schmt_isvalid(schmt));
  513. val = readl(reg);
  514. if (schmt == PMUX_SCHMT_ENABLE)
  515. val |= (1 << SCHMT_SHIFT);
  516. else
  517. val &= ~(1 << SCHMT_SHIFT);
  518. writel(val, reg);
  519. return;
  520. }
  521. #endif
  522. #ifdef TEGRA_PMX_GRPS_HAVE_HSM
  523. static void pinmux_set_hsm(enum pmux_drvgrp grp, enum pmux_hsm hsm)
  524. {
  525. u32 *reg = DRV_REG(grp);
  526. u32 val;
  527. /* NONE means unspecified/do not change/use POR value */
  528. if (hsm == PMUX_HSM_NONE)
  529. return;
  530. /* Error check pad */
  531. assert(pmux_drvgrp_isvalid(grp));
  532. assert(pmux_hsm_isvalid(hsm));
  533. val = readl(reg);
  534. if (hsm == PMUX_HSM_ENABLE)
  535. val |= (1 << HSM_SHIFT);
  536. else
  537. val &= ~(1 << HSM_SHIFT);
  538. writel(val, reg);
  539. return;
  540. }
  541. #endif
  542. static void pinmux_config_drvgrp(const struct pmux_drvgrp_config *config)
  543. {
  544. enum pmux_drvgrp grp = config->drvgrp;
  545. pinmux_set_drvup_slwf(grp, config->slwf);
  546. pinmux_set_drvdn_slwr(grp, config->slwr);
  547. pinmux_set_drvup(grp, config->drvup);
  548. pinmux_set_drvdn(grp, config->drvdn);
  549. #ifdef TEGRA_PMX_GRPS_HAVE_LPMD
  550. pinmux_set_lpmd(grp, config->lpmd);
  551. #endif
  552. #ifdef TEGRA_PMX_GRPS_HAVE_SCHMT
  553. pinmux_set_schmt(grp, config->schmt);
  554. #endif
  555. #ifdef TEGRA_PMX_GRPS_HAVE_HSM
  556. pinmux_set_hsm(grp, config->hsm);
  557. #endif
  558. }
  559. void pinmux_config_drvgrp_table(const struct pmux_drvgrp_config *config,
  560. int len)
  561. {
  562. int i;
  563. for (i = 0; i < len; i++)
  564. pinmux_config_drvgrp(&config[i]);
  565. }
  566. #endif /* TEGRA_PMX_SOC_HAS_DRVGRPS */
  567. #ifdef TEGRA_PMX_SOC_HAS_MIPI_PAD_CTRL_GRPS
  568. #define pmux_mipipadctrlgrp_isvalid(pd) (((pd) >= 0) && ((pd) < PMUX_MIPIPADCTRLGRP_COUNT))
  569. static void pinmux_mipipadctrl_set_func(enum pmux_mipipadctrlgrp grp,
  570. enum pmux_func func)
  571. {
  572. u32 *reg = MIPIPADCTRL_REG(grp);
  573. int i, mux = -1;
  574. u32 val;
  575. if (func == PMUX_FUNC_DEFAULT)
  576. return;
  577. /* Error check grp and func */
  578. assert(pmux_mipipadctrlgrp_isvalid(grp));
  579. assert(pmux_func_isvalid(func));
  580. if (func >= PMUX_FUNC_RSVD1) {
  581. mux = (func - PMUX_FUNC_RSVD1) & 1;
  582. } else {
  583. /* Search for the appropriate function */
  584. for (i = 0; i < 2; i++) {
  585. if (tegra_soc_mipipadctrl_groups[grp].funcs[i]
  586. == func) {
  587. mux = i;
  588. break;
  589. }
  590. }
  591. }
  592. assert(mux != -1);
  593. val = readl(reg);
  594. val &= ~(1 << 1);
  595. val |= (mux << 1);
  596. writel(val, reg);
  597. }
  598. static void pinmux_config_mipipadctrlgrp(const struct pmux_mipipadctrlgrp_config *config)
  599. {
  600. enum pmux_mipipadctrlgrp grp = config->grp;
  601. pinmux_mipipadctrl_set_func(grp, config->func);
  602. }
  603. void pinmux_config_mipipadctrlgrp_table(
  604. const struct pmux_mipipadctrlgrp_config *config, int len)
  605. {
  606. int i;
  607. for (i = 0; i < len; i++)
  608. pinmux_config_mipipadctrlgrp(&config[i]);
  609. }
  610. #endif /* TEGRA_PMX_SOC_HAS_MIPI_PAD_CTRL_GRPS */