pinmux-common.c 17 KB

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