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