• Home
  • Raw
  • Download

Lines Matching +full:cs +full:- +full:3

4  * Copyright (C) 2005-2006 Nokia Corporation
9 * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com>
32 #include <linux/omap-gpmc.h>
35 #include <linux/platform_data/mtd-nand-omap2.h>
37 #include <asm/mach-types.h>
39 #define DEVICE_NAME "omap-gpmc"
145 #define GPMC_CONFIG1_CLKACTIVATIONTIME(val) ((val & 3) << 25)
148 #define GPMC_CONFIG1_PAGE_LEN(val) ((val & 3) << 23)
153 #define GPMC_CONFIG1_WAIT_MON_TIME(val) ((val & 3) << 18)
156 #define GPMC_CONFIG1_WAIT_PIN_SEL(val) ((val & 3) << 16)
157 #define GPMC_CONFIG1_DEVICESIZE(val) ((val & 3) << 12)
161 #define GPMC_CONFIG1_DEVICETYPE(val) ((val & 3) << 10)
163 #define GPMC_CONFIG1_MUXTYPE(val) ((val & 3) << 8)
165 #define GPMC_CONFIG1_FCLK_DIV(val) (val & 3)
168 #define GPMC_CONFIG1_FCLK_DIV4 (GPMC_CONFIG1_FCLK_DIV(3))
206 /* Structure to save gpmc cs context */
246 /* Define chip-selects as reserved by default until probe completes */
267 void gpmc_cs_write_reg(int cs, int idx, u32 val) in gpmc_cs_write_reg() argument
271 reg_addr = gpmc_base + GPMC_CS0_OFFSET + (cs * GPMC_CS_SIZE) + idx; in gpmc_cs_write_reg()
275 static u32 gpmc_cs_read_reg(int cs, int idx) in gpmc_cs_read_reg() argument
279 reg_addr = gpmc_base + GPMC_CS0_OFFSET + (cs * GPMC_CS_SIZE) + idx; in gpmc_cs_read_reg()
295 * gpmc_get_clk_period - get period of selected clock domain in ps
296 * @cs Chip Select Region.
299 * GPMC_CS_CONFIG1 GPMCFCLKDIVIDER for cs has to be setup
302 static unsigned long gpmc_get_clk_period(int cs, enum gpmc_clk_domain cd) in gpmc_get_clk_period() argument
312 l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1); in gpmc_get_clk_period()
318 /* FALL-THROUGH */ in gpmc_get_clk_period()
327 static unsigned int gpmc_ns_to_clk_ticks(unsigned int time_ns, int cs, in gpmc_ns_to_clk_ticks() argument
333 tick_ps = gpmc_get_clk_period(cs, cd); in gpmc_ns_to_clk_ticks()
335 return (time_ns * 1000 + tick_ps - 1) / tick_ps; in gpmc_ns_to_clk_ticks()
340 return gpmc_ns_to_clk_ticks(time_ns, /* any CS */ 0, GPMC_CD_FCLK); in gpmc_ns_to_ticks()
350 return (time_ps + tick_ps - 1) / tick_ps; in gpmc_ps_to_ticks()
353 static unsigned int gpmc_clk_ticks_to_ns(unsigned int ticks, int cs, in gpmc_clk_ticks_to_ns() argument
356 return ticks * gpmc_get_clk_period(cs, cd) / 1000; in gpmc_clk_ticks_to_ns()
361 return gpmc_clk_ticks_to_ns(ticks, /* any CS */ 0, GPMC_CD_FCLK); in gpmc_ticks_to_ns()
376 static inline void gpmc_cs_modify_reg(int cs, int reg, u32 mask, bool value) in gpmc_cs_modify_reg() argument
380 l = gpmc_cs_read_reg(cs, reg); in gpmc_cs_modify_reg()
385 gpmc_cs_write_reg(cs, reg, l); in gpmc_cs_modify_reg()
388 static void gpmc_cs_bool_timings(int cs, const struct gpmc_bool_timings *p) in gpmc_cs_bool_timings() argument
390 gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG1, in gpmc_cs_bool_timings()
392 p->time_para_granularity); in gpmc_cs_bool_timings()
393 gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG2, in gpmc_cs_bool_timings()
394 GPMC_CONFIG2_CSEXTRADELAY, p->cs_extra_delay); in gpmc_cs_bool_timings()
395 gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG3, in gpmc_cs_bool_timings()
396 GPMC_CONFIG3_ADVEXTRADELAY, p->adv_extra_delay); in gpmc_cs_bool_timings()
397 gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG4, in gpmc_cs_bool_timings()
398 GPMC_CONFIG4_OEEXTRADELAY, p->oe_extra_delay); in gpmc_cs_bool_timings()
399 gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG4, in gpmc_cs_bool_timings()
400 GPMC_CONFIG4_WEEXTRADELAY, p->we_extra_delay); in gpmc_cs_bool_timings()
401 gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG6, in gpmc_cs_bool_timings()
403 p->cycle2cyclesamecsen); in gpmc_cs_bool_timings()
404 gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG6, in gpmc_cs_bool_timings()
406 p->cycle2cyclediffcsen); in gpmc_cs_bool_timings()
411 * get_gpmc_timing_reg - read a timing parameter and print DTS settings for it.
412 * @cs: Chip Select Region
423 * tick format: gpmc,name = <value> /&zwj;* x ns -- y ns; x ticks *&zwj;/
424 * Where x ns -- y ns result in the same tick value.
432 int cs, int reg, int st_bit, int end_bit, int max, in get_gpmc_timing_reg() argument
444 l = gpmc_cs_read_reg(cs, reg); in get_gpmc_timing_reg()
445 nr_bits = end_bit - st_bit + 1; in get_gpmc_timing_reg()
446 mask = (1 << nr_bits) - 1; in get_gpmc_timing_reg()
461 time_ns_min = gpmc_clk_ticks_to_ns(l - 1, cs, cd) + 1; in get_gpmc_timing_reg()
462 time_ns = gpmc_clk_ticks_to_ns(l, cs, cd); in get_gpmc_timing_reg()
463 pr_info("gpmc,%s = <%u>; /* %u ns - %u ns; %i ticks%s*/\n", in get_gpmc_timing_reg()
475 #define GPMC_PRINT_CONFIG(cs, config) \ argument
476 pr_info("cs%i %s: 0x%08x\n", cs, #config, \
477 gpmc_cs_read_reg(cs, config))
479 get_gpmc_timing_reg(cs, (reg), (st), (end), 0, field, GPMC_CD_FCLK, 0, 1, 0)
481 get_gpmc_timing_reg(cs, (reg), (st), (end), (max), field, GPMC_CD_FCLK, 0, 1, 0)
483 get_gpmc_timing_reg(cs, (reg), (st), (end), 0, field, GPMC_CD_FCLK, 0, 1, 1)
485 get_gpmc_timing_reg(cs, (reg), (st), (end), (max), field, GPMC_CD_FCLK, (shift), 1, 1)
487 get_gpmc_timing_reg(cs, (reg), (st), (end), 0, field, GPMC_CD_FCLK, 0, 0, 0)
489 get_gpmc_timing_reg(cs, (reg), (st), (end), 0, field, (cd), 0, 0, 0)
491 get_gpmc_timing_reg(cs, (reg), (st), (end), (max), field, (cd), 0, 0, 0)
493 static void gpmc_show_regs(int cs, const char *desc) in gpmc_show_regs() argument
495 pr_info("gpmc cs%i %s:\n", cs, desc); in gpmc_show_regs()
496 GPMC_PRINT_CONFIG(cs, GPMC_CS_CONFIG1); in gpmc_show_regs()
497 GPMC_PRINT_CONFIG(cs, GPMC_CS_CONFIG2); in gpmc_show_regs()
498 GPMC_PRINT_CONFIG(cs, GPMC_CS_CONFIG3); in gpmc_show_regs()
499 GPMC_PRINT_CONFIG(cs, GPMC_CS_CONFIG4); in gpmc_show_regs()
500 GPMC_PRINT_CONFIG(cs, GPMC_CS_CONFIG5); in gpmc_show_regs()
501 GPMC_PRINT_CONFIG(cs, GPMC_CS_CONFIG6); in gpmc_show_regs()
505 * Note that gpmc,wait-pin handing wrongly assumes bit 8 is available,
508 static void gpmc_cs_show_timings(int cs, const char *desc) in gpmc_cs_show_timings() argument
510 gpmc_show_regs(cs, desc); in gpmc_cs_show_timings()
512 pr_info("gpmc cs%i access configuration:\n", cs); in gpmc_cs_show_timings()
513 GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG1, 4, 4, "time-para-granularity"); in gpmc_cs_show_timings()
514 GPMC_GET_RAW(GPMC_CS_CONFIG1, 8, 9, "mux-add-data"); in gpmc_cs_show_timings()
516 GPMC_CONFIG1_DEVICESIZE_MAX, "device-width"); in gpmc_cs_show_timings()
517 GPMC_GET_RAW(GPMC_CS_CONFIG1, 16, 17, "wait-pin"); in gpmc_cs_show_timings()
518 GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG1, 21, 21, "wait-on-write"); in gpmc_cs_show_timings()
519 GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG1, 22, 22, "wait-on-read"); in gpmc_cs_show_timings()
522 "burst-length"); in gpmc_cs_show_timings()
523 GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG1, 27, 27, "sync-write"); in gpmc_cs_show_timings()
524 GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG1, 28, 28, "burst-write"); in gpmc_cs_show_timings()
525 GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG1, 29, 29, "gpmc,sync-read"); in gpmc_cs_show_timings()
526 GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG1, 30, 30, "burst-read"); in gpmc_cs_show_timings()
527 GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG1, 31, 31, "burst-wrap"); in gpmc_cs_show_timings()
529 GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG2, 7, 7, "cs-extra-delay"); in gpmc_cs_show_timings()
531 GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG3, 7, 7, "adv-extra-delay"); in gpmc_cs_show_timings()
533 GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG4, 23, 23, "we-extra-delay"); in gpmc_cs_show_timings()
534 GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG4, 7, 7, "oe-extra-delay"); in gpmc_cs_show_timings()
536 GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG6, 7, 7, "cycle2cycle-samecsen"); in gpmc_cs_show_timings()
537 GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG6, 6, 6, "cycle2cycle-diffcsen"); in gpmc_cs_show_timings()
539 pr_info("gpmc cs%i timings configuration:\n", cs); in gpmc_cs_show_timings()
540 GPMC_GET_TICKS(GPMC_CS_CONFIG2, 0, 3, "cs-on-ns"); in gpmc_cs_show_timings()
541 GPMC_GET_TICKS(GPMC_CS_CONFIG2, 8, 12, "cs-rd-off-ns"); in gpmc_cs_show_timings()
542 GPMC_GET_TICKS(GPMC_CS_CONFIG2, 16, 20, "cs-wr-off-ns"); in gpmc_cs_show_timings()
544 GPMC_GET_TICKS(GPMC_CS_CONFIG3, 0, 3, "adv-on-ns"); in gpmc_cs_show_timings()
545 GPMC_GET_TICKS(GPMC_CS_CONFIG3, 8, 12, "adv-rd-off-ns"); in gpmc_cs_show_timings()
546 GPMC_GET_TICKS(GPMC_CS_CONFIG3, 16, 20, "adv-wr-off-ns"); in gpmc_cs_show_timings()
548 GPMC_GET_TICKS(GPMC_CS_CONFIG3, 4, 6, "adv-aad-mux-on-ns"); in gpmc_cs_show_timings()
550 "adv-aad-mux-rd-off-ns"); in gpmc_cs_show_timings()
552 "adv-aad-mux-wr-off-ns"); in gpmc_cs_show_timings()
555 GPMC_GET_TICKS(GPMC_CS_CONFIG4, 0, 3, "oe-on-ns"); in gpmc_cs_show_timings()
556 GPMC_GET_TICKS(GPMC_CS_CONFIG4, 8, 12, "oe-off-ns"); in gpmc_cs_show_timings()
558 GPMC_GET_TICKS(GPMC_CS_CONFIG4, 4, 6, "oe-aad-mux-on-ns"); in gpmc_cs_show_timings()
559 GPMC_GET_TICKS(GPMC_CS_CONFIG4, 13, 15, "oe-aad-mux-off-ns"); in gpmc_cs_show_timings()
561 GPMC_GET_TICKS(GPMC_CS_CONFIG4, 16, 19, "we-on-ns"); in gpmc_cs_show_timings()
562 GPMC_GET_TICKS(GPMC_CS_CONFIG4, 24, 28, "we-off-ns"); in gpmc_cs_show_timings()
564 GPMC_GET_TICKS(GPMC_CS_CONFIG5, 0, 4, "rd-cycle-ns"); in gpmc_cs_show_timings()
565 GPMC_GET_TICKS(GPMC_CS_CONFIG5, 8, 12, "wr-cycle-ns"); in gpmc_cs_show_timings()
566 GPMC_GET_TICKS(GPMC_CS_CONFIG5, 16, 20, "access-ns"); in gpmc_cs_show_timings()
568 GPMC_GET_TICKS(GPMC_CS_CONFIG5, 24, 27, "page-burst-access-ns"); in gpmc_cs_show_timings()
570 GPMC_GET_TICKS(GPMC_CS_CONFIG6, 0, 3, "bus-turnaround-ns"); in gpmc_cs_show_timings()
571 GPMC_GET_TICKS(GPMC_CS_CONFIG6, 8, 11, "cycle2cycle-delay-ns"); in gpmc_cs_show_timings()
575 "wait-monitoring-ns", GPMC_CD_CLK); in gpmc_cs_show_timings()
578 "clk-activation-ns", GPMC_CD_FCLK); in gpmc_cs_show_timings()
580 GPMC_GET_TICKS(GPMC_CS_CONFIG6, 16, 19, "wr-data-mux-bus-ns"); in gpmc_cs_show_timings()
581 GPMC_GET_TICKS(GPMC_CS_CONFIG6, 24, 28, "wr-access-ns"); in gpmc_cs_show_timings()
584 static inline void gpmc_cs_show_timings(int cs, const char *desc) in gpmc_cs_show_timings() argument
590 * set_gpmc_timing_reg - set a single timing parameter for Chip Select Region.
594 * @cs: Chip Select Region.
603 * @return: 0 on success, -1 on error.
605 static int set_gpmc_timing_reg(int cs, int reg, int st_bit, int end_bit, int max, in set_gpmc_timing_reg() argument
614 ticks = gpmc_ns_to_clk_ticks(time, cs, cd); in set_gpmc_timing_reg()
615 nr_bits = end_bit - st_bit + 1; in set_gpmc_timing_reg()
616 mask = (1 << nr_bits) - 1; in set_gpmc_timing_reg()
622 pr_err("%s: GPMC CS%d: %s %d ns, %d ticks > %d ticks\n", in set_gpmc_timing_reg()
623 __func__, cs, name, time, ticks, max); in set_gpmc_timing_reg()
625 return -1; in set_gpmc_timing_reg()
628 l = gpmc_cs_read_reg(cs, reg); in set_gpmc_timing_reg()
631 "GPMC CS%d: %-17s: %3d ticks, %3lu ns (was %3i ticks) %3d ns\n", in set_gpmc_timing_reg()
632 cs, name, ticks, gpmc_get_clk_period(cs, cd) * ticks / 1000, in set_gpmc_timing_reg()
637 gpmc_cs_write_reg(cs, reg, l); in set_gpmc_timing_reg()
643 if (set_gpmc_timing_reg(cs, (reg), (st), (end), (max), \
644 t->field, (cd), #field) < 0) \
645 return -1
651 * gpmc_calc_waitmonitoring_divider - calculate proper GPMCFCLKDIVIDER based on WAITMONITORINGTIME
653 * read --> don't sample bus too early
654 * write --> data is longer on bus
663 * @return: -1 on failure to scale, else proper divider > 0.
670 div += GPMC_CONFIG1_WAITMONITORINGTIME_MAX - 1; in gpmc_calc_waitmonitoring_divider()
674 return -1; in gpmc_calc_waitmonitoring_divider()
683 * gpmc_calc_divider - calculate GPMC_FCLK divider for sync_clk GPMC_CLK period.
686 * Else, returns -1.
693 return -1; in gpmc_calc_divider()
701 * gpmc_cs_set_timings - program timing parameters for Chip Select Region.
702 * @cs: Chip Select Region.
705 * @return: 0 on success, -1 on error.
707 int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t, in gpmc_cs_set_timings() argument
713 div = gpmc_calc_divider(t->sync_clk); in gpmc_cs_set_timings()
720 * Calculate GPMCFCLKDIVIDER independent of gpmc,sync-clk-ps in DT for in gpmc_cs_set_timings()
730 if (!s->sync_read && !s->sync_write && in gpmc_cs_set_timings()
731 (s->wait_on_read || s->wait_on_write) in gpmc_cs_set_timings()
734 div = gpmc_calc_waitmonitoring_divider(t->wait_monitoring); in gpmc_cs_set_timings()
736 pr_err("%s: waitmonitoringtime %3d ns too large for greatest gpmcfclkdivider.\n", in gpmc_cs_set_timings()
738 t->wait_monitoring in gpmc_cs_set_timings()
740 return -1; in gpmc_cs_set_timings()
744 GPMC_SET_ONE(GPMC_CS_CONFIG2, 0, 3, cs_on); in gpmc_cs_set_timings()
748 GPMC_SET_ONE(GPMC_CS_CONFIG3, 0, 3, adv_on); in gpmc_cs_set_timings()
757 GPMC_SET_ONE(GPMC_CS_CONFIG4, 0, 3, oe_on); in gpmc_cs_set_timings()
772 GPMC_SET_ONE(GPMC_CS_CONFIG6, 0, 3, bus_turnaround); in gpmc_cs_set_timings()
780 l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1); in gpmc_cs_set_timings()
782 l |= (div - 1); in gpmc_cs_set_timings()
783 gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, l); in gpmc_cs_set_timings()
793 pr_info("GPMC CS%d CLK period is %lu ns (div %d)\n", in gpmc_cs_set_timings()
794 cs, (div * gpmc_get_fclk_period()) / 1000, div); in gpmc_cs_set_timings()
797 gpmc_cs_bool_timings(cs, &t->bool_timings); in gpmc_cs_set_timings()
798 gpmc_cs_show_timings(cs, "after gpmc_cs_set_timings"); in gpmc_cs_set_timings()
803 static int gpmc_cs_set_memconf(int cs, u32 base, u32 size) in gpmc_cs_set_memconf() argument
812 if (base & (size - 1)) in gpmc_cs_set_memconf()
813 return -EINVAL; in gpmc_cs_set_memconf()
816 mask = (1 << GPMC_SECTION_SHIFT) - size; in gpmc_cs_set_memconf()
820 l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG7); in gpmc_cs_set_memconf()
825 gpmc_cs_write_reg(cs, GPMC_CS_CONFIG7, l); in gpmc_cs_set_memconf()
830 static void gpmc_cs_enable_mem(int cs) in gpmc_cs_enable_mem() argument
834 l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG7); in gpmc_cs_enable_mem()
836 gpmc_cs_write_reg(cs, GPMC_CS_CONFIG7, l); in gpmc_cs_enable_mem()
839 static void gpmc_cs_disable_mem(int cs) in gpmc_cs_disable_mem() argument
843 l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG7); in gpmc_cs_disable_mem()
845 gpmc_cs_write_reg(cs, GPMC_CS_CONFIG7, l); in gpmc_cs_disable_mem()
848 static void gpmc_cs_get_memconf(int cs, u32 *base, u32 *size) in gpmc_cs_get_memconf() argument
853 l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG7); in gpmc_cs_get_memconf()
856 *size = (1 << GPMC_SECTION_SHIFT) - (mask << GPMC_CHUNK_SHIFT); in gpmc_cs_get_memconf()
859 static int gpmc_cs_mem_enabled(int cs) in gpmc_cs_mem_enabled() argument
863 l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG7); in gpmc_cs_mem_enabled()
867 static void gpmc_cs_set_reserved(int cs, int reserved) in gpmc_cs_set_reserved() argument
869 struct gpmc_cs_data *gpmc = &gpmc_cs[cs]; in gpmc_cs_set_reserved()
871 gpmc->flags |= GPMC_CS_RESERVED; in gpmc_cs_set_reserved()
874 static bool gpmc_cs_reserved(int cs) in gpmc_cs_reserved() argument
876 struct gpmc_cs_data *gpmc = &gpmc_cs[cs]; in gpmc_cs_reserved()
878 return gpmc->flags & GPMC_CS_RESERVED; in gpmc_cs_reserved()
881 static void gpmc_cs_set_name(int cs, const char *name) in gpmc_cs_set_name() argument
883 struct gpmc_cs_data *gpmc = &gpmc_cs[cs]; in gpmc_cs_set_name()
885 gpmc->name = name; in gpmc_cs_set_name()
888 static const char *gpmc_cs_get_name(int cs) in gpmc_cs_get_name() argument
890 struct gpmc_cs_data *gpmc = &gpmc_cs[cs]; in gpmc_cs_get_name()
892 return gpmc->name; in gpmc_cs_get_name()
899 size = (size - 1) >> (GPMC_CHUNK_SHIFT - 1); in gpmc_mem_align()
900 order = GPMC_CHUNK_SHIFT - 1; in gpmc_mem_align()
909 static int gpmc_cs_insert_mem(int cs, unsigned long base, unsigned long size) in gpmc_cs_insert_mem() argument
911 struct gpmc_cs_data *gpmc = &gpmc_cs[cs]; in gpmc_cs_insert_mem()
912 struct resource *res = &gpmc->mem; in gpmc_cs_insert_mem()
917 res->start = base; in gpmc_cs_insert_mem()
918 res->end = base + size - 1; in gpmc_cs_insert_mem()
925 static int gpmc_cs_delete_mem(int cs) in gpmc_cs_delete_mem() argument
927 struct gpmc_cs_data *gpmc = &gpmc_cs[cs]; in gpmc_cs_delete_mem()
928 struct resource *res = &gpmc->mem; in gpmc_cs_delete_mem()
933 res->start = 0; in gpmc_cs_delete_mem()
934 res->end = 0; in gpmc_cs_delete_mem()
941 * gpmc_cs_remap - remaps a chip-select physical base address
942 * @cs: chip-select to remap
943 * @base: physical base address to re-map chip-select to
945 * Re-maps a chip-select to a new physical base address specified by
949 static int gpmc_cs_remap(int cs, u32 base) in gpmc_cs_remap() argument
954 if (cs >= gpmc_cs_num) { in gpmc_cs_remap()
955 pr_err("%s: requested chip-select is disabled\n", __func__); in gpmc_cs_remap()
956 return -ENODEV; in gpmc_cs_remap()
964 base &= ~(SZ_16M - 1); in gpmc_cs_remap()
966 gpmc_cs_get_memconf(cs, &old_base, &size); in gpmc_cs_remap()
970 ret = gpmc_cs_delete_mem(cs); in gpmc_cs_remap()
974 ret = gpmc_cs_insert_mem(cs, base, size); in gpmc_cs_remap()
978 ret = gpmc_cs_set_memconf(cs, base, size); in gpmc_cs_remap()
983 int gpmc_cs_request(int cs, unsigned long size, unsigned long *base) in gpmc_cs_request() argument
985 struct gpmc_cs_data *gpmc = &gpmc_cs[cs]; in gpmc_cs_request()
986 struct resource *res = &gpmc->mem; in gpmc_cs_request()
987 int r = -1; in gpmc_cs_request()
989 if (cs >= gpmc_cs_num) { in gpmc_cs_request()
990 pr_err("%s: requested chip-select is disabled\n", __func__); in gpmc_cs_request()
991 return -ENODEV; in gpmc_cs_request()
995 return -ENOMEM; in gpmc_cs_request()
998 if (gpmc_cs_reserved(cs)) { in gpmc_cs_request()
999 r = -EBUSY; in gpmc_cs_request()
1002 if (gpmc_cs_mem_enabled(cs)) in gpmc_cs_request()
1003 r = adjust_resource(res, res->start & ~(size - 1), size); in gpmc_cs_request()
1010 /* Disable CS while changing base address and size mask */ in gpmc_cs_request()
1011 gpmc_cs_disable_mem(cs); in gpmc_cs_request()
1013 r = gpmc_cs_set_memconf(cs, res->start, resource_size(res)); in gpmc_cs_request()
1019 /* Enable CS */ in gpmc_cs_request()
1020 gpmc_cs_enable_mem(cs); in gpmc_cs_request()
1021 *base = res->start; in gpmc_cs_request()
1022 gpmc_cs_set_reserved(cs, 1); in gpmc_cs_request()
1029 void gpmc_cs_free(int cs) in gpmc_cs_free() argument
1031 struct gpmc_cs_data *gpmc = &gpmc_cs[cs]; in gpmc_cs_free()
1032 struct resource *res = &gpmc->mem; in gpmc_cs_free()
1035 if (cs >= gpmc_cs_num || cs < 0 || !gpmc_cs_reserved(cs)) { in gpmc_cs_free()
1036 printk(KERN_ERR "Trying to free non-reserved GPMC CS%d\n", cs); in gpmc_cs_free()
1041 gpmc_cs_disable_mem(cs); in gpmc_cs_free()
1042 if (res->flags) in gpmc_cs_free()
1044 gpmc_cs_set_reserved(cs, 0); in gpmc_cs_free()
1050 * gpmc_configure - write request to configure gpmc
1071 return -EINVAL; in gpmc_configure()
1091 * gpmc_omap_get_nand_ops - Get the GPMC NAND interface
1093 * @cs: GPMC chip select number on which the NAND sits. The
1096 * Returns NULL on error e.g. invalid cs.
1098 struct gpmc_nand_ops *gpmc_omap_get_nand_ops(struct gpmc_nand_regs *reg, int cs) in gpmc_omap_get_nand_ops() argument
1102 if (cs >= gpmc_cs_num) in gpmc_omap_get_nand_ops()
1105 reg->gpmc_nand_command = gpmc_base + GPMC_CS0_OFFSET + in gpmc_omap_get_nand_ops()
1106 GPMC_CS_NAND_COMMAND + GPMC_CS_SIZE * cs; in gpmc_omap_get_nand_ops()
1107 reg->gpmc_nand_address = gpmc_base + GPMC_CS0_OFFSET + in gpmc_omap_get_nand_ops()
1108 GPMC_CS_NAND_ADDRESS + GPMC_CS_SIZE * cs; in gpmc_omap_get_nand_ops()
1109 reg->gpmc_nand_data = gpmc_base + GPMC_CS0_OFFSET + in gpmc_omap_get_nand_ops()
1110 GPMC_CS_NAND_DATA + GPMC_CS_SIZE * cs; in gpmc_omap_get_nand_ops()
1111 reg->gpmc_prefetch_config1 = gpmc_base + GPMC_PREFETCH_CONFIG1; in gpmc_omap_get_nand_ops()
1112 reg->gpmc_prefetch_config2 = gpmc_base + GPMC_PREFETCH_CONFIG2; in gpmc_omap_get_nand_ops()
1113 reg->gpmc_prefetch_control = gpmc_base + GPMC_PREFETCH_CONTROL; in gpmc_omap_get_nand_ops()
1114 reg->gpmc_prefetch_status = gpmc_base + GPMC_PREFETCH_STATUS; in gpmc_omap_get_nand_ops()
1115 reg->gpmc_ecc_config = gpmc_base + GPMC_ECC_CONFIG; in gpmc_omap_get_nand_ops()
1116 reg->gpmc_ecc_control = gpmc_base + GPMC_ECC_CONTROL; in gpmc_omap_get_nand_ops()
1117 reg->gpmc_ecc_size_config = gpmc_base + GPMC_ECC_SIZE_CONFIG; in gpmc_omap_get_nand_ops()
1118 reg->gpmc_ecc1_result = gpmc_base + GPMC_ECC1_RESULT; in gpmc_omap_get_nand_ops()
1121 reg->gpmc_bch_result0[i] = gpmc_base + GPMC_ECC_BCH_RESULT_0 + in gpmc_omap_get_nand_ops()
1123 reg->gpmc_bch_result1[i] = gpmc_base + GPMC_ECC_BCH_RESULT_1 + in gpmc_omap_get_nand_ops()
1125 reg->gpmc_bch_result2[i] = gpmc_base + GPMC_ECC_BCH_RESULT_2 + in gpmc_omap_get_nand_ops()
1127 reg->gpmc_bch_result3[i] = gpmc_base + GPMC_ECC_BCH_RESULT_3 + in gpmc_omap_get_nand_ops()
1129 reg->gpmc_bch_result4[i] = gpmc_base + GPMC_ECC_BCH_RESULT_4 + in gpmc_omap_get_nand_ops()
1131 reg->gpmc_bch_result5[i] = gpmc_base + GPMC_ECC_BCH_RESULT_5 + in gpmc_omap_get_nand_ops()
1133 reg->gpmc_bch_result6[i] = gpmc_base + GPMC_ECC_BCH_RESULT_6 + in gpmc_omap_get_nand_ops()
1156 t_ces = 3; in gpmc_omap_onenand_calc_sync_timings()
1159 t_ach = 3; in gpmc_omap_onenand_calc_sync_timings()
1195 if (!s->sync_write) { in gpmc_omap_onenand_calc_sync_timings()
1220 int gpmc_omap_onenand_set_timings(struct device *dev, int cs, int freq, in gpmc_omap_onenand_set_timings() argument
1228 gpmc_read_settings_dt(dev->of_node, &gpmc_s); in gpmc_omap_onenand_set_timings()
1230 info->sync_read = gpmc_s.sync_read; in gpmc_omap_onenand_set_timings()
1231 info->sync_write = gpmc_s.sync_write; in gpmc_omap_onenand_set_timings()
1232 info->burst_len = gpmc_s.burst_len; in gpmc_omap_onenand_set_timings()
1239 ret = gpmc_cs_program_settings(cs, &gpmc_s); in gpmc_omap_onenand_set_timings()
1243 return gpmc_cs_set_timings(cs, &gpmc_t, &gpmc_s); in gpmc_omap_onenand_set_timings()
1268 hwirq += 8 - GPMC_NR_NAND_IRQS; in gpmc_irq_endis()
1282 gpmc_irq_endis(p->hwirq, false); in gpmc_irq_disable()
1287 gpmc_irq_endis(p->hwirq, true); in gpmc_irq_enable()
1292 gpmc_irq_endis(d->hwirq, false); in gpmc_irq_mask()
1297 gpmc_irq_endis(d->hwirq, true); in gpmc_irq_unmask()
1309 hwirq += 8 - GPMC_NR_NAND_IRQS; in gpmc_irq_edge_config()
1322 unsigned int hwirq = d->hwirq; in gpmc_irq_ack()
1326 hwirq += 8 - GPMC_NR_NAND_IRQS; in gpmc_irq_ack()
1335 if (d->hwirq < GPMC_NR_NAND_IRQS) in gpmc_irq_set_type()
1336 return -EINVAL; in gpmc_irq_set_type()
1340 gpmc_irq_edge_config(d->hwirq, false); in gpmc_irq_set_type()
1342 gpmc_irq_edge_config(d->hwirq, true); in gpmc_irq_set_type()
1344 return -EINVAL; in gpmc_irq_set_type()
1352 struct gpmc_device *gpmc = d->host_data; in gpmc_irq_map()
1357 irq_set_chip_and_handler(virq, &gpmc->irq_chip, in gpmc_irq_map()
1360 irq_set_chip_and_handler(virq, &gpmc->irq_chip, in gpmc_irq_map()
1384 for (hwirq = 0; hwirq < gpmc->nirqs; hwirq++) { in gpmc_handle_irq()
1387 regvalx >>= 8 - GPMC_NR_NAND_IRQS; in gpmc_handle_irq()
1392 dev_warn(gpmc->dev, in gpmc_handle_irq()
1418 gpmc->irq_chip.name = "gpmc"; in gpmc_setup_irq()
1419 gpmc->irq_chip.irq_enable = gpmc_irq_enable; in gpmc_setup_irq()
1420 gpmc->irq_chip.irq_disable = gpmc_irq_disable; in gpmc_setup_irq()
1421 gpmc->irq_chip.irq_ack = gpmc_irq_ack; in gpmc_setup_irq()
1422 gpmc->irq_chip.irq_mask = gpmc_irq_mask; in gpmc_setup_irq()
1423 gpmc->irq_chip.irq_unmask = gpmc_irq_unmask; in gpmc_setup_irq()
1424 gpmc->irq_chip.irq_set_type = gpmc_irq_set_type; in gpmc_setup_irq()
1426 gpmc_irq_domain = irq_domain_add_linear(gpmc->dev->of_node, in gpmc_setup_irq()
1427 gpmc->nirqs, in gpmc_setup_irq()
1431 dev_err(gpmc->dev, "IRQ domain add failed\n"); in gpmc_setup_irq()
1432 return -ENODEV; in gpmc_setup_irq()
1435 rc = request_irq(gpmc->irq, gpmc_handle_irq, 0, "gpmc", gpmc); in gpmc_setup_irq()
1437 dev_err(gpmc->dev, "failed to request irq %d: %d\n", in gpmc_setup_irq()
1438 gpmc->irq, rc); in gpmc_setup_irq()
1450 free_irq(gpmc->irq, gpmc); in gpmc_free_irq()
1452 for (hwirq = 0; hwirq < gpmc->nirqs; hwirq++) in gpmc_free_irq()
1463 int cs; in gpmc_mem_exit() local
1465 for (cs = 0; cs < gpmc_cs_num; cs++) { in gpmc_mem_exit()
1466 if (!gpmc_cs_mem_enabled(cs)) in gpmc_mem_exit()
1468 gpmc_cs_delete_mem(cs); in gpmc_mem_exit()
1475 int cs; in gpmc_mem_init() local
1481 for (cs = 0; cs < gpmc_cs_num; cs++) { in gpmc_mem_init()
1484 if (!gpmc_cs_mem_enabled(cs)) in gpmc_mem_init()
1486 gpmc_cs_get_memconf(cs, &base, &size); in gpmc_mem_init()
1487 if (gpmc_cs_insert_mem(cs, base, size)) { in gpmc_mem_init()
1488 pr_warn("%s: disabling cs %d mapped at 0x%x-0x%x\n", in gpmc_mem_init()
1489 __func__, cs, base, base + size); in gpmc_mem_init()
1490 gpmc_cs_disable_mem(cs); in gpmc_mem_init()
1502 temp = (temp + div - 1) / div; in gpmc_round_ps_to_sync_clk()
1514 temp = dev_t->t_avdp_r; in gpmc_calc_sync_read_timings()
1521 temp = max_t(u32, temp, gpmc_t->clk_activation + dev_t->t_avdh); in gpmc_calc_sync_read_timings()
1522 temp = max_t(u32, gpmc_t->adv_on + gpmc_ticks_to_ps(1), temp); in gpmc_calc_sync_read_timings()
1524 gpmc_t->adv_rd_off = gpmc_round_ps_to_ticks(temp); in gpmc_calc_sync_read_timings()
1527 temp = dev_t->t_oeasu; /* XXX: remove this ? */ in gpmc_calc_sync_read_timings()
1529 temp = max_t(u32, temp, gpmc_t->clk_activation + dev_t->t_ach); in gpmc_calc_sync_read_timings()
1530 temp = max_t(u32, temp, gpmc_t->adv_rd_off + in gpmc_calc_sync_read_timings()
1531 gpmc_ticks_to_ps(dev_t->cyc_aavdh_oe)); in gpmc_calc_sync_read_timings()
1533 gpmc_t->oe_on = gpmc_round_ps_to_ticks(temp); in gpmc_calc_sync_read_timings()
1540 temp = max_t(u32, dev_t->t_iaa, dev_t->cyc_iaa * gpmc_t->sync_clk); in gpmc_calc_sync_read_timings()
1541 temp += gpmc_t->clk_activation; in gpmc_calc_sync_read_timings()
1542 if (dev_t->cyc_oe) in gpmc_calc_sync_read_timings()
1543 temp = max_t(u32, temp, gpmc_t->oe_on + in gpmc_calc_sync_read_timings()
1544 gpmc_ticks_to_ps(dev_t->cyc_oe)); in gpmc_calc_sync_read_timings()
1545 gpmc_t->access = gpmc_round_ps_to_ticks(temp); in gpmc_calc_sync_read_timings()
1547 gpmc_t->oe_off = gpmc_t->access + gpmc_ticks_to_ps(1); in gpmc_calc_sync_read_timings()
1548 gpmc_t->cs_rd_off = gpmc_t->oe_off; in gpmc_calc_sync_read_timings()
1551 temp = max_t(u32, dev_t->t_cez_r, dev_t->t_oez); in gpmc_calc_sync_read_timings()
1552 temp = gpmc_round_ps_to_sync_clk(temp, gpmc_t->sync_clk) + in gpmc_calc_sync_read_timings()
1553 gpmc_t->access; in gpmc_calc_sync_read_timings()
1555 if (dev_t->t_ce_rdyz) in gpmc_calc_sync_read_timings()
1556 temp = max_t(u32, temp, gpmc_t->cs_rd_off + dev_t->t_ce_rdyz); in gpmc_calc_sync_read_timings()
1557 gpmc_t->rd_cycle = gpmc_round_ps_to_ticks(temp); in gpmc_calc_sync_read_timings()
1569 temp = dev_t->t_avdp_w; in gpmc_calc_sync_write_timings()
1572 gpmc_t->clk_activation + dev_t->t_avdh); in gpmc_calc_sync_write_timings()
1573 temp = max_t(u32, gpmc_t->adv_on + gpmc_ticks_to_ps(1), temp); in gpmc_calc_sync_write_timings()
1575 gpmc_t->adv_wr_off = gpmc_round_ps_to_ticks(temp); in gpmc_calc_sync_write_timings()
1578 temp = max_t(u32, dev_t->t_weasu, in gpmc_calc_sync_write_timings()
1579 gpmc_t->clk_activation + dev_t->t_rdyo); in gpmc_calc_sync_write_timings()
1585 gpmc_t->adv_wr_off + dev_t->t_aavdh); in gpmc_calc_sync_write_timings()
1586 temp = max_t(u32, temp, gpmc_t->adv_wr_off + in gpmc_calc_sync_write_timings()
1587 gpmc_ticks_to_ps(dev_t->cyc_aavdh_we)); in gpmc_calc_sync_write_timings()
1589 gpmc_t->wr_data_mux_bus = gpmc_round_ps_to_ticks(temp); in gpmc_calc_sync_write_timings()
1593 gpmc_t->we_on = gpmc_round_ps_to_ticks(dev_t->t_weasu); in gpmc_calc_sync_write_timings()
1595 gpmc_t->we_on = gpmc_t->wr_data_mux_bus; in gpmc_calc_sync_write_timings()
1599 gpmc_t->wr_access = gpmc_t->access; in gpmc_calc_sync_write_timings()
1602 temp = gpmc_t->we_on + dev_t->t_wpl; in gpmc_calc_sync_write_timings()
1604 gpmc_t->wr_access + gpmc_ticks_to_ps(1)); in gpmc_calc_sync_write_timings()
1606 gpmc_t->we_on + gpmc_ticks_to_ps(dev_t->cyc_wpl)); in gpmc_calc_sync_write_timings()
1607 gpmc_t->we_off = gpmc_round_ps_to_ticks(temp); in gpmc_calc_sync_write_timings()
1609 gpmc_t->cs_wr_off = gpmc_round_ps_to_ticks(gpmc_t->we_off + in gpmc_calc_sync_write_timings()
1610 dev_t->t_wph); in gpmc_calc_sync_write_timings()
1613 temp = gpmc_round_ps_to_sync_clk(dev_t->t_cez_w, gpmc_t->sync_clk); in gpmc_calc_sync_write_timings()
1614 temp += gpmc_t->wr_access; in gpmc_calc_sync_write_timings()
1616 if (dev_t->t_ce_rdyz) in gpmc_calc_sync_write_timings()
1618 gpmc_t->cs_wr_off + dev_t->t_ce_rdyz); in gpmc_calc_sync_write_timings()
1619 gpmc_t->wr_cycle = gpmc_round_ps_to_ticks(temp); in gpmc_calc_sync_write_timings()
1631 temp = dev_t->t_avdp_r; in gpmc_calc_async_read_timings()
1633 temp = max_t(u32, gpmc_t->adv_on + gpmc_ticks_to_ps(1), temp); in gpmc_calc_async_read_timings()
1634 gpmc_t->adv_rd_off = gpmc_round_ps_to_ticks(temp); in gpmc_calc_async_read_timings()
1637 temp = dev_t->t_oeasu; in gpmc_calc_async_read_timings()
1640 gpmc_t->adv_rd_off + dev_t->t_aavdh); in gpmc_calc_async_read_timings()
1641 gpmc_t->oe_on = gpmc_round_ps_to_ticks(temp); in gpmc_calc_async_read_timings()
1644 temp = max_t(u32, dev_t->t_iaa, /* XXX: remove t_iaa in async ? */ in gpmc_calc_async_read_timings()
1645 gpmc_t->oe_on + dev_t->t_oe); in gpmc_calc_async_read_timings()
1647 gpmc_t->cs_on + dev_t->t_ce); in gpmc_calc_async_read_timings()
1649 gpmc_t->adv_on + dev_t->t_aa); in gpmc_calc_async_read_timings()
1650 gpmc_t->access = gpmc_round_ps_to_ticks(temp); in gpmc_calc_async_read_timings()
1652 gpmc_t->oe_off = gpmc_t->access + gpmc_ticks_to_ps(1); in gpmc_calc_async_read_timings()
1653 gpmc_t->cs_rd_off = gpmc_t->oe_off; in gpmc_calc_async_read_timings()
1656 temp = max_t(u32, dev_t->t_rd_cycle, in gpmc_calc_async_read_timings()
1657 gpmc_t->cs_rd_off + dev_t->t_cez_r); in gpmc_calc_async_read_timings()
1658 temp = max_t(u32, temp, gpmc_t->oe_off + dev_t->t_oez); in gpmc_calc_async_read_timings()
1659 gpmc_t->rd_cycle = gpmc_round_ps_to_ticks(temp); in gpmc_calc_async_read_timings()
1671 temp = dev_t->t_avdp_w; in gpmc_calc_async_write_timings()
1673 temp = max_t(u32, gpmc_t->adv_on + gpmc_ticks_to_ps(1), temp); in gpmc_calc_async_write_timings()
1674 gpmc_t->adv_wr_off = gpmc_round_ps_to_ticks(temp); in gpmc_calc_async_write_timings()
1677 temp = dev_t->t_weasu; in gpmc_calc_async_write_timings()
1679 temp = max_t(u32, temp, gpmc_t->adv_wr_off + dev_t->t_aavdh); in gpmc_calc_async_write_timings()
1680 temp = max_t(u32, temp, gpmc_t->adv_wr_off + in gpmc_calc_async_write_timings()
1681 gpmc_ticks_to_ps(dev_t->cyc_aavdh_we)); in gpmc_calc_async_write_timings()
1683 gpmc_t->wr_data_mux_bus = gpmc_round_ps_to_ticks(temp); in gpmc_calc_async_write_timings()
1687 gpmc_t->we_on = gpmc_round_ps_to_ticks(dev_t->t_weasu); in gpmc_calc_async_write_timings()
1689 gpmc_t->we_on = gpmc_t->wr_data_mux_bus; in gpmc_calc_async_write_timings()
1692 temp = gpmc_t->we_on + dev_t->t_wpl; in gpmc_calc_async_write_timings()
1693 gpmc_t->we_off = gpmc_round_ps_to_ticks(temp); in gpmc_calc_async_write_timings()
1695 gpmc_t->cs_wr_off = gpmc_round_ps_to_ticks(gpmc_t->we_off + in gpmc_calc_async_write_timings()
1696 dev_t->t_wph); in gpmc_calc_async_write_timings()
1699 temp = max_t(u32, dev_t->t_wr_cycle, in gpmc_calc_async_write_timings()
1700 gpmc_t->cs_wr_off + dev_t->t_cez_w); in gpmc_calc_async_write_timings()
1701 gpmc_t->wr_cycle = gpmc_round_ps_to_ticks(temp); in gpmc_calc_async_write_timings()
1711 gpmc_t->sync_clk = gpmc_calc_divider(dev_t->clk) * in gpmc_calc_sync_common_timings()
1714 gpmc_t->page_burst_access = gpmc_round_ps_to_sync_clk( in gpmc_calc_sync_common_timings()
1715 dev_t->t_bacc, in gpmc_calc_sync_common_timings()
1716 gpmc_t->sync_clk); in gpmc_calc_sync_common_timings()
1718 temp = max_t(u32, dev_t->t_ces, dev_t->t_avds); in gpmc_calc_sync_common_timings()
1719 gpmc_t->clk_activation = gpmc_round_ps_to_ticks(temp); in gpmc_calc_sync_common_timings()
1721 if (gpmc_calc_divider(gpmc_t->sync_clk) != 1) in gpmc_calc_sync_common_timings()
1724 if (dev_t->ce_xdelay) in gpmc_calc_sync_common_timings()
1725 gpmc_t->bool_timings.cs_extra_delay = true; in gpmc_calc_sync_common_timings()
1726 if (dev_t->avd_xdelay) in gpmc_calc_sync_common_timings()
1727 gpmc_t->bool_timings.adv_extra_delay = true; in gpmc_calc_sync_common_timings()
1728 if (dev_t->oe_xdelay) in gpmc_calc_sync_common_timings()
1729 gpmc_t->bool_timings.oe_extra_delay = true; in gpmc_calc_sync_common_timings()
1730 if (dev_t->we_xdelay) in gpmc_calc_sync_common_timings()
1731 gpmc_t->bool_timings.we_extra_delay = true; in gpmc_calc_sync_common_timings()
1743 gpmc_t->cs_on = gpmc_round_ps_to_ticks(dev_t->t_ceasu); in gpmc_calc_common_timings()
1746 temp = dev_t->t_avdasu; in gpmc_calc_common_timings()
1747 if (dev_t->t_ce_avd) in gpmc_calc_common_timings()
1749 gpmc_t->cs_on + dev_t->t_ce_avd); in gpmc_calc_common_timings()
1750 gpmc_t->adv_on = gpmc_round_ps_to_ticks(temp); in gpmc_calc_common_timings()
1764 t->cs_on /= 1000; in gpmc_convert_ps_to_ns()
1765 t->cs_rd_off /= 1000; in gpmc_convert_ps_to_ns()
1766 t->cs_wr_off /= 1000; in gpmc_convert_ps_to_ns()
1767 t->adv_on /= 1000; in gpmc_convert_ps_to_ns()
1768 t->adv_rd_off /= 1000; in gpmc_convert_ps_to_ns()
1769 t->adv_wr_off /= 1000; in gpmc_convert_ps_to_ns()
1770 t->we_on /= 1000; in gpmc_convert_ps_to_ns()
1771 t->we_off /= 1000; in gpmc_convert_ps_to_ns()
1772 t->oe_on /= 1000; in gpmc_convert_ps_to_ns()
1773 t->oe_off /= 1000; in gpmc_convert_ps_to_ns()
1774 t->page_burst_access /= 1000; in gpmc_convert_ps_to_ns()
1775 t->access /= 1000; in gpmc_convert_ps_to_ns()
1776 t->rd_cycle /= 1000; in gpmc_convert_ps_to_ns()
1777 t->wr_cycle /= 1000; in gpmc_convert_ps_to_ns()
1778 t->bus_turnaround /= 1000; in gpmc_convert_ps_to_ns()
1779 t->cycle2cycle_delay /= 1000; in gpmc_convert_ps_to_ns()
1780 t->wait_monitoring /= 1000; in gpmc_convert_ps_to_ns()
1781 t->clk_activation /= 1000; in gpmc_convert_ps_to_ns()
1782 t->wr_access /= 1000; in gpmc_convert_ps_to_ns()
1783 t->wr_data_mux_bus /= 1000; in gpmc_convert_ps_to_ns()
1793 mux = gpmc_s->mux_add_data ? true : false; in gpmc_calc_timings()
1794 sync = (gpmc_s->sync_read || gpmc_s->sync_write); in gpmc_calc_timings()
1801 if (gpmc_s && gpmc_s->sync_read) in gpmc_calc_timings()
1806 if (gpmc_s && gpmc_s->sync_write) in gpmc_calc_timings()
1818 * gpmc_cs_program_settings - programs non-timing related settings
1819 * @cs: GPMC chip-select to program
1822 * Programs non-timing related settings for a GPMC chip-select, such as
1823 * bus-width, burst configuration, etc. Function should be called once
1824 * for each chip-select that is being used and must be called before
1829 int gpmc_cs_program_settings(int cs, struct gpmc_settings *p) in gpmc_cs_program_settings() argument
1833 if ((!p->device_width) || (p->device_width > GPMC_DEVWIDTH_16BIT)) { in gpmc_cs_program_settings()
1834 pr_err("%s: invalid width %d!", __func__, p->device_width); in gpmc_cs_program_settings()
1835 return -EINVAL; in gpmc_cs_program_settings()
1838 /* Address-data multiplexing not supported for NAND devices */ in gpmc_cs_program_settings()
1839 if (p->device_nand && p->mux_add_data) { in gpmc_cs_program_settings()
1841 return -EINVAL; in gpmc_cs_program_settings()
1844 if ((p->mux_add_data > GPMC_MUX_AD) || in gpmc_cs_program_settings()
1845 ((p->mux_add_data == GPMC_MUX_AAD) && in gpmc_cs_program_settings()
1848 return -EINVAL; in gpmc_cs_program_settings()
1852 if (p->burst_read || p->burst_write) { in gpmc_cs_program_settings()
1853 switch (p->burst_len) { in gpmc_cs_program_settings()
1859 pr_err("%s: invalid page/burst-length (%d)\n", in gpmc_cs_program_settings()
1860 __func__, p->burst_len); in gpmc_cs_program_settings()
1861 return -EINVAL; in gpmc_cs_program_settings()
1865 if (p->wait_pin > gpmc_nr_waitpins) { in gpmc_cs_program_settings()
1866 pr_err("%s: invalid wait-pin (%d)\n", __func__, p->wait_pin); in gpmc_cs_program_settings()
1867 return -EINVAL; in gpmc_cs_program_settings()
1870 config1 = GPMC_CONFIG1_DEVICESIZE((p->device_width - 1)); in gpmc_cs_program_settings()
1872 if (p->sync_read) in gpmc_cs_program_settings()
1874 if (p->sync_write) in gpmc_cs_program_settings()
1876 if (p->wait_on_read) in gpmc_cs_program_settings()
1878 if (p->wait_on_write) in gpmc_cs_program_settings()
1880 if (p->wait_on_read || p->wait_on_write) in gpmc_cs_program_settings()
1881 config1 |= GPMC_CONFIG1_WAIT_PIN_SEL(p->wait_pin); in gpmc_cs_program_settings()
1882 if (p->device_nand) in gpmc_cs_program_settings()
1884 if (p->mux_add_data) in gpmc_cs_program_settings()
1885 config1 |= GPMC_CONFIG1_MUXTYPE(p->mux_add_data); in gpmc_cs_program_settings()
1886 if (p->burst_read) in gpmc_cs_program_settings()
1888 if (p->burst_write) in gpmc_cs_program_settings()
1890 if (p->burst_read || p->burst_write) { in gpmc_cs_program_settings()
1891 config1 |= GPMC_CONFIG1_PAGE_LEN(p->burst_len >> 3); in gpmc_cs_program_settings()
1892 config1 |= p->burst_wrap ? GPMC_CONFIG1_WRAPBURST_SUPP : 0; in gpmc_cs_program_settings()
1895 gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, config1); in gpmc_cs_program_settings()
1902 { .compatible = "ti,omap2420-gpmc" },
1903 { .compatible = "ti,omap2430-gpmc" },
1904 { .compatible = "ti,omap3430-gpmc" }, /* omap3430 & omap3630 */
1905 { .compatible = "ti,omap4430-gpmc" }, /* omap4430 & omap4460 & omap543x */
1906 { .compatible = "ti,am3352-gpmc" }, /* am335x devices */
1911 * gpmc_read_settings_dt - read gpmc settings from device-tree
1912 * @np: pointer to device-tree node for a gpmc child device
1915 * Reads the GPMC settings for a GPMC child device from device-tree and
1924 p->sync_read = of_property_read_bool(np, "gpmc,sync-read"); in gpmc_read_settings_dt()
1925 p->sync_write = of_property_read_bool(np, "gpmc,sync-write"); in gpmc_read_settings_dt()
1926 of_property_read_u32(np, "gpmc,device-width", &p->device_width); in gpmc_read_settings_dt()
1927 of_property_read_u32(np, "gpmc,mux-add-data", &p->mux_add_data); in gpmc_read_settings_dt()
1929 if (!of_property_read_u32(np, "gpmc,burst-length", &p->burst_len)) { in gpmc_read_settings_dt()
1930 p->burst_wrap = of_property_read_bool(np, "gpmc,burst-wrap"); in gpmc_read_settings_dt()
1931 p->burst_read = of_property_read_bool(np, "gpmc,burst-read"); in gpmc_read_settings_dt()
1932 p->burst_write = of_property_read_bool(np, "gpmc,burst-write"); in gpmc_read_settings_dt()
1933 if (!p->burst_read && !p->burst_write) in gpmc_read_settings_dt()
1934 pr_warn("%s: page/burst-length set but not used!\n", in gpmc_read_settings_dt()
1938 if (!of_property_read_u32(np, "gpmc,wait-pin", &p->wait_pin)) { in gpmc_read_settings_dt()
1939 p->wait_on_read = of_property_read_bool(np, in gpmc_read_settings_dt()
1940 "gpmc,wait-on-read"); in gpmc_read_settings_dt()
1941 p->wait_on_write = of_property_read_bool(np, in gpmc_read_settings_dt()
1942 "gpmc,wait-on-write"); in gpmc_read_settings_dt()
1943 if (!p->wait_on_read && !p->wait_on_write) in gpmc_read_settings_dt()
1960 of_property_read_u32(np, "gpmc,sync-clk-ps", &gpmc_t->sync_clk); in gpmc_read_timings_dt()
1963 of_property_read_u32(np, "gpmc,cs-on-ns", &gpmc_t->cs_on); in gpmc_read_timings_dt()
1964 of_property_read_u32(np, "gpmc,cs-rd-off-ns", &gpmc_t->cs_rd_off); in gpmc_read_timings_dt()
1965 of_property_read_u32(np, "gpmc,cs-wr-off-ns", &gpmc_t->cs_wr_off); in gpmc_read_timings_dt()
1968 of_property_read_u32(np, "gpmc,adv-on-ns", &gpmc_t->adv_on); in gpmc_read_timings_dt()
1969 of_property_read_u32(np, "gpmc,adv-rd-off-ns", &gpmc_t->adv_rd_off); in gpmc_read_timings_dt()
1970 of_property_read_u32(np, "gpmc,adv-wr-off-ns", &gpmc_t->adv_wr_off); in gpmc_read_timings_dt()
1971 of_property_read_u32(np, "gpmc,adv-aad-mux-on-ns", in gpmc_read_timings_dt()
1972 &gpmc_t->adv_aad_mux_on); in gpmc_read_timings_dt()
1973 of_property_read_u32(np, "gpmc,adv-aad-mux-rd-off-ns", in gpmc_read_timings_dt()
1974 &gpmc_t->adv_aad_mux_rd_off); in gpmc_read_timings_dt()
1975 of_property_read_u32(np, "gpmc,adv-aad-mux-wr-off-ns", in gpmc_read_timings_dt()
1976 &gpmc_t->adv_aad_mux_wr_off); in gpmc_read_timings_dt()
1979 of_property_read_u32(np, "gpmc,we-on-ns", &gpmc_t->we_on); in gpmc_read_timings_dt()
1980 of_property_read_u32(np, "gpmc,we-off-ns", &gpmc_t->we_off); in gpmc_read_timings_dt()
1983 of_property_read_u32(np, "gpmc,oe-on-ns", &gpmc_t->oe_on); in gpmc_read_timings_dt()
1984 of_property_read_u32(np, "gpmc,oe-off-ns", &gpmc_t->oe_off); in gpmc_read_timings_dt()
1985 of_property_read_u32(np, "gpmc,oe-aad-mux-on-ns", in gpmc_read_timings_dt()
1986 &gpmc_t->oe_aad_mux_on); in gpmc_read_timings_dt()
1987 of_property_read_u32(np, "gpmc,oe-aad-mux-off-ns", in gpmc_read_timings_dt()
1988 &gpmc_t->oe_aad_mux_off); in gpmc_read_timings_dt()
1991 of_property_read_u32(np, "gpmc,page-burst-access-ns", in gpmc_read_timings_dt()
1992 &gpmc_t->page_burst_access); in gpmc_read_timings_dt()
1993 of_property_read_u32(np, "gpmc,access-ns", &gpmc_t->access); in gpmc_read_timings_dt()
1994 of_property_read_u32(np, "gpmc,rd-cycle-ns", &gpmc_t->rd_cycle); in gpmc_read_timings_dt()
1995 of_property_read_u32(np, "gpmc,wr-cycle-ns", &gpmc_t->wr_cycle); in gpmc_read_timings_dt()
1996 of_property_read_u32(np, "gpmc,bus-turnaround-ns", in gpmc_read_timings_dt()
1997 &gpmc_t->bus_turnaround); in gpmc_read_timings_dt()
1998 of_property_read_u32(np, "gpmc,cycle2cycle-delay-ns", in gpmc_read_timings_dt()
1999 &gpmc_t->cycle2cycle_delay); in gpmc_read_timings_dt()
2000 of_property_read_u32(np, "gpmc,wait-monitoring-ns", in gpmc_read_timings_dt()
2001 &gpmc_t->wait_monitoring); in gpmc_read_timings_dt()
2002 of_property_read_u32(np, "gpmc,clk-activation-ns", in gpmc_read_timings_dt()
2003 &gpmc_t->clk_activation); in gpmc_read_timings_dt()
2006 of_property_read_u32(np, "gpmc,wr-access-ns", &gpmc_t->wr_access); in gpmc_read_timings_dt()
2007 of_property_read_u32(np, "gpmc,wr-data-mux-bus-ns", in gpmc_read_timings_dt()
2008 &gpmc_t->wr_data_mux_bus); in gpmc_read_timings_dt()
2011 p = &gpmc_t->bool_timings; in gpmc_read_timings_dt()
2013 p->cycle2cyclediffcsen = in gpmc_read_timings_dt()
2014 of_property_read_bool(np, "gpmc,cycle2cycle-diffcsen"); in gpmc_read_timings_dt()
2015 p->cycle2cyclesamecsen = in gpmc_read_timings_dt()
2016 of_property_read_bool(np, "gpmc,cycle2cycle-samecsen"); in gpmc_read_timings_dt()
2017 p->we_extra_delay = of_property_read_bool(np, "gpmc,we-extra-delay"); in gpmc_read_timings_dt()
2018 p->oe_extra_delay = of_property_read_bool(np, "gpmc,oe-extra-delay"); in gpmc_read_timings_dt()
2019 p->adv_extra_delay = of_property_read_bool(np, "gpmc,adv-extra-delay"); in gpmc_read_timings_dt()
2020 p->cs_extra_delay = of_property_read_bool(np, "gpmc,cs-extra-delay"); in gpmc_read_timings_dt()
2021 p->time_para_granularity = in gpmc_read_timings_dt()
2022 of_property_read_bool(np, "gpmc,time-para-granularity"); in gpmc_read_timings_dt()
2026 * gpmc_probe_generic_child - configures the gpmc for a child device
2028 * @child: pointer to device-tree node for child device
2030 * Allocates and configures a GPMC chip-select for a child device.
2041 int ret, cs; in gpmc_probe_generic_child() local
2046 if (of_property_read_u32(child, "reg", &cs) < 0) { in gpmc_probe_generic_child()
2047 dev_err(&pdev->dev, "%pOF has no 'reg' property\n", in gpmc_probe_generic_child()
2049 return -ENODEV; in gpmc_probe_generic_child()
2053 dev_err(&pdev->dev, "%pOF has malformed 'reg' property\n", in gpmc_probe_generic_child()
2055 return -ENODEV; in gpmc_probe_generic_child()
2063 name = gpmc_cs_get_name(cs); in gpmc_probe_generic_child()
2064 if (name && of_node_cmp(child->name, name) == 0) in gpmc_probe_generic_child()
2067 ret = gpmc_cs_request(cs, resource_size(&res), &base); in gpmc_probe_generic_child()
2069 dev_err(&pdev->dev, "cannot request GPMC CS %d\n", cs); in gpmc_probe_generic_child()
2072 gpmc_cs_set_name(cs, child->name); in gpmc_probe_generic_child()
2083 WARN(1, "enable GPMC debug to configure .dts timings for CS%i\n", in gpmc_probe_generic_child()
2084 cs); in gpmc_probe_generic_child()
2085 gpmc_cs_show_timings(cs, in gpmc_probe_generic_child()
2090 /* CS must be disabled while making changes to gpmc configuration */ in gpmc_probe_generic_child()
2091 gpmc_cs_disable_mem(cs); in gpmc_probe_generic_child()
2094 * FIXME: gpmc_cs_request() will map the CS to an arbitary in gpmc_probe_generic_child()
2096 * device-tree we want the NOR flash to be mapped to the in gpmc_probe_generic_child()
2097 * location specified in the device-tree blob. So remap the in gpmc_probe_generic_child()
2098 * CS to this location. Once DT migration is complete should in gpmc_probe_generic_child()
2101 ret = gpmc_cs_remap(cs, res.start); in gpmc_probe_generic_child()
2103 dev_err(&pdev->dev, "cannot remap GPMC CS %d to %pa\n", in gpmc_probe_generic_child()
2104 cs, &res.start); in gpmc_probe_generic_child()
2106 dev_info(&pdev->dev, in gpmc_probe_generic_child()
2107 "GPMC CS %d start cannot be lesser than 0x%x\n", in gpmc_probe_generic_child()
2108 cs, GPMC_MEM_START); in gpmc_probe_generic_child()
2110 dev_info(&pdev->dev, in gpmc_probe_generic_child()
2111 "GPMC CS %d end cannot be greater than 0x%x\n", in gpmc_probe_generic_child()
2112 cs, GPMC_MEM_END); in gpmc_probe_generic_child()
2117 if (of_node_cmp(child->name, "nand") == 0) { in gpmc_probe_generic_child()
2120 dev_warn(&pdev->dev, in gpmc_probe_generic_child()
2122 ret = -EINVAL; in gpmc_probe_generic_child()
2127 if (of_node_cmp(child->name, "onenand") == 0) { in gpmc_probe_generic_child()
2130 dev_warn(&pdev->dev, in gpmc_probe_generic_child()
2132 ret = -EINVAL; in gpmc_probe_generic_child()
2137 if (of_device_is_compatible(child, "ti,omap2-nand")) { in gpmc_probe_generic_child()
2140 of_property_read_u32(child, "nand-bus-width", &val); in gpmc_probe_generic_child()
2149 dev_err(&pdev->dev, "%s: invalid 'nand-bus-width'\n", in gpmc_probe_generic_child()
2150 child->name); in gpmc_probe_generic_child()
2151 ret = -EINVAL; in gpmc_probe_generic_child()
2159 ret = of_property_read_u32(child, "bank-width", in gpmc_probe_generic_child()
2162 dev_err(&pdev->dev, in gpmc_probe_generic_child()
2163 "%pOF has no 'gpmc,device-width' property\n", in gpmc_probe_generic_child()
2173 waitpin_desc = gpiochip_request_own_desc(&gpmc->gpio_chip, in gpmc_probe_generic_child()
2176 dev_err(&pdev->dev, "invalid wait-pin: %d\n", wait_pin); in gpmc_probe_generic_child()
2182 gpmc_cs_show_timings(cs, "before gpmc_cs_program_settings"); in gpmc_probe_generic_child()
2184 ret = gpmc_cs_program_settings(cs, &gpmc_s); in gpmc_probe_generic_child()
2188 ret = gpmc_cs_set_timings(cs, &gpmc_t, &gpmc_s); in gpmc_probe_generic_child()
2190 dev_err(&pdev->dev, "failed to set gpmc timings for: %s\n", in gpmc_probe_generic_child()
2191 child->name); in gpmc_probe_generic_child()
2195 /* Clear limited address i.e. enable A26-A11 */ in gpmc_probe_generic_child()
2200 /* Enable CS region */ in gpmc_probe_generic_child()
2201 gpmc_cs_enable_mem(cs); in gpmc_probe_generic_child()
2206 if (!of_platform_device_create(child, NULL, &pdev->dev)) in gpmc_probe_generic_child()
2212 if (of_platform_default_populate(child, NULL, &pdev->dev)) in gpmc_probe_generic_child()
2219 dev_err(&pdev->dev, "failed to create gpmc child %s\n", child->name); in gpmc_probe_generic_child()
2220 ret = -ENODEV; in gpmc_probe_generic_child()
2225 gpmc_cs_free(cs); in gpmc_probe_generic_child()
2234 of_match_device(gpmc_dt_ids, &pdev->dev); in gpmc_probe_dt()
2239 ret = of_property_read_u32(pdev->dev.of_node, "gpmc,num-cs", in gpmc_probe_dt()
2242 pr_err("%s: number of chip-selects not defined\n", __func__); in gpmc_probe_dt()
2245 pr_err("%s: all chip-selects are disabled\n", __func__); in gpmc_probe_dt()
2246 return -EINVAL; in gpmc_probe_dt()
2248 pr_err("%s: number of supported chip-selects cannot be > %d\n", in gpmc_probe_dt()
2250 return -EINVAL; in gpmc_probe_dt()
2253 ret = of_property_read_u32(pdev->dev.of_node, "gpmc,num-waitpins", in gpmc_probe_dt()
2268 for_each_available_child_of_node(pdev->dev.of_node, child) { in gpmc_probe_dt_children()
2270 if (!child->name) in gpmc_probe_dt_children()
2275 dev_err(&pdev->dev, "failed to probe DT child '%s': %d\n", in gpmc_probe_dt_children()
2276 child->name, ret); in gpmc_probe_dt_children()
2309 return -EINVAL; /* we're input only */ in gpmc_gpio_direction_output()
2332 gpmc->gpio_chip.parent = gpmc->dev; in gpmc_gpio_init()
2333 gpmc->gpio_chip.owner = THIS_MODULE; in gpmc_gpio_init()
2334 gpmc->gpio_chip.label = DEVICE_NAME; in gpmc_gpio_init()
2335 gpmc->gpio_chip.ngpio = gpmc_nr_waitpins; in gpmc_gpio_init()
2336 gpmc->gpio_chip.get_direction = gpmc_gpio_get_direction; in gpmc_gpio_init()
2337 gpmc->gpio_chip.direction_input = gpmc_gpio_direction_input; in gpmc_gpio_init()
2338 gpmc->gpio_chip.direction_output = gpmc_gpio_direction_output; in gpmc_gpio_init()
2339 gpmc->gpio_chip.set = gpmc_gpio_set; in gpmc_gpio_init()
2340 gpmc->gpio_chip.get = gpmc_gpio_get; in gpmc_gpio_init()
2341 gpmc->gpio_chip.base = -1; in gpmc_gpio_init()
2343 ret = devm_gpiochip_add_data(gpmc->dev, &gpmc->gpio_chip, NULL); in gpmc_gpio_init()
2345 dev_err(gpmc->dev, "could not register gpio chip: %d\n", ret); in gpmc_gpio_init()
2359 gpmc = devm_kzalloc(&pdev->dev, sizeof(*gpmc), GFP_KERNEL); in gpmc_probe()
2361 return -ENOMEM; in gpmc_probe()
2363 gpmc->dev = &pdev->dev; in gpmc_probe()
2368 return -ENOENT; in gpmc_probe()
2370 phys_base = res->start; in gpmc_probe()
2373 gpmc_base = devm_ioremap_resource(&pdev->dev, res); in gpmc_probe()
2379 dev_err(&pdev->dev, "Failed to get resource: irq\n"); in gpmc_probe()
2380 return -ENOENT; in gpmc_probe()
2383 gpmc->irq = res->start; in gpmc_probe()
2385 gpmc_l3_clk = devm_clk_get(&pdev->dev, "fck"); in gpmc_probe()
2387 dev_err(&pdev->dev, "Failed to get GPMC fck\n"); in gpmc_probe()
2392 dev_err(&pdev->dev, "Invalid GPMC fck clock rate\n"); in gpmc_probe()
2393 return -EINVAL; in gpmc_probe()
2396 if (pdev->dev.of_node) { in gpmc_probe()
2405 pm_runtime_enable(&pdev->dev); in gpmc_probe()
2406 pm_runtime_get_sync(&pdev->dev); in gpmc_probe()
2411 * FIXME: Once device-tree migration is complete the below flags in gpmc_probe()
2412 * should be populated based upon the device-tree compatible in gpmc_probe()
2415 * devices support the addr-addr-data multiplex protocol. in gpmc_probe()
2418 * - OMAP24xx = 2.0 in gpmc_probe()
2419 * - OMAP3xxx = 5.0 in gpmc_probe()
2420 * - OMAP44xx/54xx/AM335x = 6.0 in gpmc_probe()
2426 dev_info(gpmc->dev, "GPMC revision %d.%d\n", GPMC_REVISION_MAJOR(l), in gpmc_probe()
2434 gpmc->nirqs = GPMC_NR_NAND_IRQS + gpmc_nr_waitpins; in gpmc_probe()
2437 dev_err(gpmc->dev, "gpmc_setup_irq failed\n"); in gpmc_probe()
2447 pm_runtime_put_sync(&pdev->dev); in gpmc_probe()
2448 pm_runtime_disable(&pdev->dev); in gpmc_probe()
2459 pm_runtime_put_sync(&pdev->dev); in gpmc_remove()
2460 pm_runtime_disable(&pdev->dev); in gpmc_remove()