sh_pfc.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638
  1. /*
  2. * Pinmuxed GPIO support for SuperH.
  3. * Copy from linux kernel driver/sh/pfc.c
  4. *
  5. * Copyright (C) 2008 Magnus Damm
  6. *
  7. * This file is subject to the terms and conditions of the GNU General Public
  8. * License. See the file "COPYING" in the main directory of this archive
  9. * for more details.
  10. */
  11. #include <common.h>
  12. #include <log.h>
  13. #include <malloc.h>
  14. #include <asm/bitops.h>
  15. #include <asm/io.h>
  16. #include <sh_pfc.h>
  17. #include <linux/bug.h>
  18. static struct pinmux_info *gpioc;
  19. #define pfc_phys_to_virt(p, a) ((void *)a)
  20. static int enum_in_range(pinmux_enum_t enum_id, struct pinmux_range *r)
  21. {
  22. if (enum_id < r->begin)
  23. return 0;
  24. if (enum_id > r->end)
  25. return 0;
  26. return 1;
  27. }
  28. static unsigned long gpio_read_raw_reg(void *mapped_reg,
  29. unsigned long reg_width)
  30. {
  31. switch (reg_width) {
  32. case 8:
  33. return readb(mapped_reg);
  34. case 16:
  35. return readw(mapped_reg);
  36. case 32:
  37. return readl(mapped_reg);
  38. }
  39. BUG();
  40. return 0;
  41. }
  42. static void gpio_write_raw_reg(void *mapped_reg,
  43. unsigned long reg_width,
  44. unsigned long data)
  45. {
  46. switch (reg_width) {
  47. case 8:
  48. writeb(data, mapped_reg);
  49. return;
  50. case 16:
  51. writew(data, mapped_reg);
  52. return;
  53. case 32:
  54. writel(data, mapped_reg);
  55. return;
  56. }
  57. BUG();
  58. }
  59. static int gpio_read_bit(struct pinmux_data_reg *dr,
  60. unsigned long offset,
  61. unsigned long in_pos)
  62. {
  63. unsigned long pos;
  64. pos = dr->reg_width - (in_pos + 1);
  65. debug("read_bit: addr = %lx, pos = %ld, r_width = %ld\n",
  66. dr->reg + offset, pos, dr->reg_width);
  67. return (gpio_read_raw_reg(dr->mapped_reg + offset,
  68. dr->reg_width) >> pos) & 1;
  69. }
  70. static void gpio_write_bit(struct pinmux_data_reg *dr,
  71. unsigned long in_pos, unsigned long value)
  72. {
  73. unsigned long pos;
  74. pos = dr->reg_width - (in_pos + 1);
  75. debug("write_bit addr = %lx, value = %d, pos = %ld, "
  76. "r_width = %ld\n",
  77. dr->reg, !!value, pos, dr->reg_width);
  78. if (value)
  79. __set_bit(pos, &dr->reg_shadow);
  80. else
  81. __clear_bit(pos, &dr->reg_shadow);
  82. gpio_write_raw_reg(dr->mapped_reg, dr->reg_width, dr->reg_shadow);
  83. }
  84. static void config_reg_helper(struct pinmux_info *gpioc,
  85. struct pinmux_cfg_reg *crp,
  86. unsigned long in_pos,
  87. #if 0
  88. void __iomem **mapped_regp,
  89. #else
  90. void **mapped_regp,
  91. #endif
  92. unsigned long *maskp,
  93. unsigned long *posp)
  94. {
  95. int k;
  96. *mapped_regp = pfc_phys_to_virt(gpioc, crp->reg);
  97. if (crp->field_width) {
  98. *maskp = (1 << crp->field_width) - 1;
  99. *posp = crp->reg_width - ((in_pos + 1) * crp->field_width);
  100. } else {
  101. *maskp = (1 << crp->var_field_width[in_pos]) - 1;
  102. *posp = crp->reg_width;
  103. for (k = 0; k <= in_pos; k++)
  104. *posp -= crp->var_field_width[k];
  105. }
  106. }
  107. static int read_config_reg(struct pinmux_info *gpioc,
  108. struct pinmux_cfg_reg *crp,
  109. unsigned long field)
  110. {
  111. void *mapped_reg;
  112. unsigned long mask, pos;
  113. config_reg_helper(gpioc, crp, field, &mapped_reg, &mask, &pos);
  114. debug("read_reg: addr = %lx, field = %ld, "
  115. "r_width = %ld, f_width = %ld\n",
  116. crp->reg, field, crp->reg_width, crp->field_width);
  117. return (gpio_read_raw_reg(mapped_reg, crp->reg_width) >> pos) & mask;
  118. }
  119. static void write_config_reg(struct pinmux_info *gpioc,
  120. struct pinmux_cfg_reg *crp,
  121. unsigned long field, unsigned long value)
  122. {
  123. void *mapped_reg;
  124. unsigned long mask, pos, data;
  125. config_reg_helper(gpioc, crp, field, &mapped_reg, &mask, &pos);
  126. debug("write_reg addr = %lx, value = %ld, field = %ld, "
  127. "r_width = %ld, f_width = %ld\n",
  128. crp->reg, value, field, crp->reg_width, crp->field_width);
  129. mask = ~(mask << pos);
  130. value = value << pos;
  131. data = gpio_read_raw_reg(mapped_reg, crp->reg_width);
  132. data &= mask;
  133. data |= value;
  134. if (gpioc->unlock_reg)
  135. gpio_write_raw_reg(pfc_phys_to_virt(gpioc, gpioc->unlock_reg),
  136. 32, ~data);
  137. gpio_write_raw_reg(mapped_reg, crp->reg_width, data);
  138. }
  139. static int setup_data_reg(struct pinmux_info *gpioc, unsigned gpio)
  140. {
  141. struct pinmux_gpio *gpiop = &gpioc->gpios[gpio];
  142. struct pinmux_data_reg *data_reg;
  143. int k, n;
  144. if (!enum_in_range(gpiop->enum_id, &gpioc->data))
  145. return -1;
  146. k = 0;
  147. while (1) {
  148. data_reg = gpioc->data_regs + k;
  149. if (!data_reg->reg_width)
  150. break;
  151. data_reg->mapped_reg = pfc_phys_to_virt(gpioc, data_reg->reg);
  152. for (n = 0; n < data_reg->reg_width; n++) {
  153. if (data_reg->enum_ids[n] == gpiop->enum_id) {
  154. gpiop->flags &= ~PINMUX_FLAG_DREG;
  155. gpiop->flags |= (k << PINMUX_FLAG_DREG_SHIFT);
  156. gpiop->flags &= ~PINMUX_FLAG_DBIT;
  157. gpiop->flags |= (n << PINMUX_FLAG_DBIT_SHIFT);
  158. return 0;
  159. }
  160. }
  161. k++;
  162. }
  163. BUG();
  164. return -1;
  165. }
  166. static void setup_data_regs(struct pinmux_info *gpioc)
  167. {
  168. struct pinmux_data_reg *drp;
  169. int k;
  170. for (k = gpioc->first_gpio; k <= gpioc->last_gpio; k++)
  171. setup_data_reg(gpioc, k);
  172. k = 0;
  173. while (1) {
  174. drp = gpioc->data_regs + k;
  175. if (!drp->reg_width)
  176. break;
  177. drp->reg_shadow = gpio_read_raw_reg(drp->mapped_reg,
  178. drp->reg_width);
  179. k++;
  180. }
  181. }
  182. static int get_data_reg(struct pinmux_info *gpioc, unsigned gpio,
  183. struct pinmux_data_reg **drp, int *bitp)
  184. {
  185. struct pinmux_gpio *gpiop = &gpioc->gpios[gpio];
  186. int k, n;
  187. if (!enum_in_range(gpiop->enum_id, &gpioc->data))
  188. return -1;
  189. k = (gpiop->flags & PINMUX_FLAG_DREG) >> PINMUX_FLAG_DREG_SHIFT;
  190. n = (gpiop->flags & PINMUX_FLAG_DBIT) >> PINMUX_FLAG_DBIT_SHIFT;
  191. *drp = gpioc->data_regs + k;
  192. *bitp = n;
  193. return 0;
  194. }
  195. static int get_config_reg(struct pinmux_info *gpioc, pinmux_enum_t enum_id,
  196. struct pinmux_cfg_reg **crp,
  197. int *fieldp, int *valuep,
  198. unsigned long **cntp)
  199. {
  200. struct pinmux_cfg_reg *config_reg;
  201. unsigned long r_width, f_width, curr_width, ncomb;
  202. int k, m, n, pos, bit_pos;
  203. k = 0;
  204. while (1) {
  205. config_reg = gpioc->cfg_regs + k;
  206. r_width = config_reg->reg_width;
  207. f_width = config_reg->field_width;
  208. if (!r_width)
  209. break;
  210. pos = 0;
  211. m = 0;
  212. for (bit_pos = 0; bit_pos < r_width; bit_pos += curr_width) {
  213. if (f_width)
  214. curr_width = f_width;
  215. else
  216. curr_width = config_reg->var_field_width[m];
  217. ncomb = 1 << curr_width;
  218. for (n = 0; n < ncomb; n++) {
  219. if (config_reg->enum_ids[pos + n] == enum_id) {
  220. *crp = config_reg;
  221. *fieldp = m;
  222. *valuep = n;
  223. *cntp = &config_reg->cnt[m];
  224. return 0;
  225. }
  226. }
  227. pos += ncomb;
  228. m++;
  229. }
  230. k++;
  231. }
  232. return -1;
  233. }
  234. static int get_gpio_enum_id(struct pinmux_info *gpioc, unsigned gpio,
  235. int pos, pinmux_enum_t *enum_idp)
  236. {
  237. pinmux_enum_t enum_id = gpioc->gpios[gpio].enum_id;
  238. pinmux_enum_t *data = gpioc->gpio_data;
  239. int k;
  240. if (!enum_in_range(enum_id, &gpioc->data)) {
  241. if (!enum_in_range(enum_id, &gpioc->mark)) {
  242. debug("non data/mark enum_id for gpio %d\n", gpio);
  243. return -1;
  244. }
  245. }
  246. if (pos) {
  247. *enum_idp = data[pos + 1];
  248. return pos + 1;
  249. }
  250. for (k = 0; k < gpioc->gpio_data_size; k++) {
  251. if (data[k] == enum_id) {
  252. *enum_idp = data[k + 1];
  253. return k + 1;
  254. }
  255. }
  256. debug("cannot locate data/mark enum_id for gpio %d\n", gpio);
  257. return -1;
  258. }
  259. enum { GPIO_CFG_DRYRUN, GPIO_CFG_REQ, GPIO_CFG_FREE };
  260. static int pinmux_config_gpio(struct pinmux_info *gpioc, unsigned gpio,
  261. int pinmux_type, int cfg_mode)
  262. {
  263. struct pinmux_cfg_reg *cr = NULL;
  264. pinmux_enum_t enum_id;
  265. struct pinmux_range *range;
  266. int in_range, pos, field, value;
  267. unsigned long *cntp;
  268. switch (pinmux_type) {
  269. case PINMUX_TYPE_FUNCTION:
  270. range = NULL;
  271. break;
  272. case PINMUX_TYPE_OUTPUT:
  273. range = &gpioc->output;
  274. break;
  275. case PINMUX_TYPE_INPUT:
  276. range = &gpioc->input;
  277. break;
  278. case PINMUX_TYPE_INPUT_PULLUP:
  279. range = &gpioc->input_pu;
  280. break;
  281. case PINMUX_TYPE_INPUT_PULLDOWN:
  282. range = &gpioc->input_pd;
  283. break;
  284. default:
  285. goto out_err;
  286. }
  287. pos = 0;
  288. enum_id = 0;
  289. field = 0;
  290. value = 0;
  291. while (1) {
  292. pos = get_gpio_enum_id(gpioc, gpio, pos, &enum_id);
  293. if (pos <= 0)
  294. goto out_err;
  295. if (!enum_id)
  296. break;
  297. /* first check if this is a function enum */
  298. in_range = enum_in_range(enum_id, &gpioc->function);
  299. if (!in_range) {
  300. /* not a function enum */
  301. if (range) {
  302. /*
  303. * other range exists, so this pin is
  304. * a regular GPIO pin that now is being
  305. * bound to a specific direction.
  306. *
  307. * for this case we only allow function enums
  308. * and the enums that match the other range.
  309. */
  310. in_range = enum_in_range(enum_id, range);
  311. /*
  312. * special case pass through for fixed
  313. * input-only or output-only pins without
  314. * function enum register association.
  315. */
  316. if (in_range && enum_id == range->force)
  317. continue;
  318. } else {
  319. /*
  320. * no other range exists, so this pin
  321. * must then be of the function type.
  322. *
  323. * allow function type pins to select
  324. * any combination of function/in/out
  325. * in their MARK lists.
  326. */
  327. in_range = 1;
  328. }
  329. }
  330. if (!in_range)
  331. continue;
  332. if (get_config_reg(gpioc, enum_id, &cr,
  333. &field, &value, &cntp) != 0)
  334. goto out_err;
  335. switch (cfg_mode) {
  336. case GPIO_CFG_DRYRUN:
  337. if (!*cntp ||
  338. (read_config_reg(gpioc, cr, field) != value))
  339. continue;
  340. break;
  341. case GPIO_CFG_REQ:
  342. write_config_reg(gpioc, cr, field, value);
  343. *cntp = *cntp + 1;
  344. break;
  345. case GPIO_CFG_FREE:
  346. *cntp = *cntp - 1;
  347. break;
  348. }
  349. }
  350. return 0;
  351. out_err:
  352. return -1;
  353. }
  354. #if 0
  355. static DEFINE_SPINLOCK(gpio_lock);
  356. static struct pinmux_info *chip_to_pinmux(struct gpio_chip *chip)
  357. {
  358. return container_of(chip, struct pinmux_info, chip);
  359. }
  360. #endif
  361. static int sh_gpio_request(unsigned offset)
  362. {
  363. struct pinmux_data_reg *dummy;
  364. int i, ret, pinmux_type;
  365. ret = -1;
  366. if (!gpioc)
  367. goto err_out;
  368. if ((gpioc->gpios[offset].flags & PINMUX_FLAG_TYPE) != PINMUX_TYPE_NONE)
  369. goto err_out;
  370. /* setup pin function here if no data is associated with pin */
  371. if (get_data_reg(gpioc, offset, &dummy, &i) != 0)
  372. pinmux_type = PINMUX_TYPE_FUNCTION;
  373. else
  374. pinmux_type = PINMUX_TYPE_GPIO;
  375. if (pinmux_type == PINMUX_TYPE_FUNCTION) {
  376. if (pinmux_config_gpio(gpioc, offset,
  377. pinmux_type,
  378. GPIO_CFG_DRYRUN) != 0)
  379. goto err_out;
  380. if (pinmux_config_gpio(gpioc, offset,
  381. pinmux_type,
  382. GPIO_CFG_REQ) != 0)
  383. BUG();
  384. }
  385. gpioc->gpios[offset].flags &= ~PINMUX_FLAG_TYPE;
  386. gpioc->gpios[offset].flags |= pinmux_type;
  387. ret = 0;
  388. err_out:
  389. return ret;
  390. }
  391. static void sh_gpio_free(unsigned offset)
  392. {
  393. int pinmux_type;
  394. if (!gpioc)
  395. return;
  396. pinmux_type = gpioc->gpios[offset].flags & PINMUX_FLAG_TYPE;
  397. pinmux_config_gpio(gpioc, offset, pinmux_type, GPIO_CFG_FREE);
  398. gpioc->gpios[offset].flags &= ~PINMUX_FLAG_TYPE;
  399. gpioc->gpios[offset].flags |= PINMUX_TYPE_NONE;
  400. }
  401. static int pinmux_direction(struct pinmux_info *gpioc,
  402. unsigned gpio, int new_pinmux_type)
  403. {
  404. int pinmux_type;
  405. int ret = -1;
  406. if (!gpioc)
  407. goto err_out;
  408. pinmux_type = gpioc->gpios[gpio].flags & PINMUX_FLAG_TYPE;
  409. switch (pinmux_type) {
  410. case PINMUX_TYPE_GPIO:
  411. break;
  412. case PINMUX_TYPE_OUTPUT:
  413. case PINMUX_TYPE_INPUT:
  414. case PINMUX_TYPE_INPUT_PULLUP:
  415. case PINMUX_TYPE_INPUT_PULLDOWN:
  416. pinmux_config_gpio(gpioc, gpio, pinmux_type, GPIO_CFG_FREE);
  417. break;
  418. default:
  419. goto err_out;
  420. }
  421. if (pinmux_config_gpio(gpioc, gpio,
  422. new_pinmux_type,
  423. GPIO_CFG_DRYRUN) != 0)
  424. goto err_out;
  425. if (pinmux_config_gpio(gpioc, gpio,
  426. new_pinmux_type,
  427. GPIO_CFG_REQ) != 0)
  428. BUG();
  429. gpioc->gpios[gpio].flags &= ~PINMUX_FLAG_TYPE;
  430. gpioc->gpios[gpio].flags |= new_pinmux_type;
  431. ret = 0;
  432. err_out:
  433. return ret;
  434. }
  435. static int sh_gpio_direction_input(unsigned offset)
  436. {
  437. return pinmux_direction(gpioc, offset, PINMUX_TYPE_INPUT);
  438. }
  439. static void sh_gpio_set_value(struct pinmux_info *gpioc,
  440. unsigned gpio, int value)
  441. {
  442. struct pinmux_data_reg *dr = NULL;
  443. int bit = 0;
  444. if (!gpioc || get_data_reg(gpioc, gpio, &dr, &bit) != 0)
  445. BUG();
  446. else
  447. gpio_write_bit(dr, bit, value);
  448. }
  449. static int sh_gpio_direction_output(unsigned offset, int value)
  450. {
  451. sh_gpio_set_value(gpioc, offset, value);
  452. return pinmux_direction(gpioc, offset, PINMUX_TYPE_OUTPUT);
  453. }
  454. static int sh_gpio_get_value(struct pinmux_info *gpioc, unsigned gpio)
  455. {
  456. struct pinmux_data_reg *dr = NULL;
  457. int bit = 0, offset = 0;
  458. if (!gpioc || get_data_reg(gpioc, gpio, &dr, &bit) != 0)
  459. return -1;
  460. #if defined(CONFIG_RCAR_GEN3)
  461. if ((gpioc->gpios[gpio].flags & PINMUX_FLAG_TYPE) == PINMUX_TYPE_INPUT)
  462. offset += 4;
  463. #endif
  464. return gpio_read_bit(dr, offset, bit);
  465. }
  466. static int sh_gpio_get(unsigned offset)
  467. {
  468. return sh_gpio_get_value(gpioc, offset);
  469. }
  470. static void sh_gpio_set(unsigned offset, int value)
  471. {
  472. sh_gpio_set_value(gpioc, offset, value);
  473. }
  474. int register_pinmux(struct pinmux_info *pip)
  475. {
  476. if (pip != NULL) {
  477. gpioc = pip;
  478. debug("%s deregistering\n", pip->name);
  479. setup_data_regs(gpioc);
  480. }
  481. return 0;
  482. }
  483. int unregister_pinmux(struct pinmux_info *pip)
  484. {
  485. debug("%s deregistering\n", pip->name);
  486. if (gpioc != pip)
  487. return -1;
  488. gpioc = NULL;
  489. return 0;
  490. }
  491. int gpio_request(unsigned gpio, const char *label)
  492. {
  493. sh_gpio_request(gpio);
  494. return 0;
  495. }
  496. int gpio_free(unsigned gpio)
  497. {
  498. sh_gpio_free(gpio);
  499. return 0;
  500. }
  501. int gpio_direction_input(unsigned gpio)
  502. {
  503. return sh_gpio_direction_input(gpio);
  504. }
  505. int gpio_direction_output(unsigned gpio, int value)
  506. {
  507. return sh_gpio_direction_output(gpio, value);
  508. }
  509. void gpio_set_value(unsigned gpio, int value)
  510. {
  511. sh_gpio_set(gpio, value);
  512. }
  513. int gpio_get_value(unsigned gpio)
  514. {
  515. return sh_gpio_get(gpio);
  516. }