| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * GPMC support functions |
|---|
| 3 | 4 | * |
|---|
| .. | .. |
|---|
| 7 | 8 | * |
|---|
| 8 | 9 | * Copyright (C) 2009 Texas Instruments |
|---|
| 9 | 10 | * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com> |
|---|
| 10 | | - * |
|---|
| 11 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 12 | | - * it under the terms of the GNU General Public License version 2 as |
|---|
| 13 | | - * published by the Free Software Foundation. |
|---|
| 14 | 11 | */ |
|---|
| 15 | 12 | #include <linux/irq.h> |
|---|
| 16 | 13 | #include <linux/kernel.h> |
|---|
| .. | .. |
|---|
| 22 | 19 | #include <linux/io.h> |
|---|
| 23 | 20 | #include <linux/gpio/driver.h> |
|---|
| 24 | 21 | #include <linux/gpio/consumer.h> /* GPIO descriptor enum */ |
|---|
| 22 | +#include <linux/gpio/machine.h> |
|---|
| 25 | 23 | #include <linux/interrupt.h> |
|---|
| 26 | 24 | #include <linux/irqdomain.h> |
|---|
| 27 | 25 | #include <linux/platform_device.h> |
|---|
| .. | .. |
|---|
| 31 | 29 | #include <linux/of_platform.h> |
|---|
| 32 | 30 | #include <linux/omap-gpmc.h> |
|---|
| 33 | 31 | #include <linux/pm_runtime.h> |
|---|
| 32 | +#include <linux/sizes.h> |
|---|
| 34 | 33 | |
|---|
| 35 | 34 | #include <linux/platform_data/mtd-nand-omap2.h> |
|---|
| 36 | | - |
|---|
| 37 | | -#include <asm/mach-types.h> |
|---|
| 38 | 35 | |
|---|
| 39 | 36 | #define DEVICE_NAME "omap-gpmc" |
|---|
| 40 | 37 | |
|---|
| .. | .. |
|---|
| 110 | 107 | #define ENABLE_PREFETCH (0x1 << 7) |
|---|
| 111 | 108 | #define DMA_MPU_MODE 2 |
|---|
| 112 | 109 | |
|---|
| 113 | | -#define GPMC_REVISION_MAJOR(l) ((l >> 4) & 0xf) |
|---|
| 114 | | -#define GPMC_REVISION_MINOR(l) (l & 0xf) |
|---|
| 110 | +#define GPMC_REVISION_MAJOR(l) (((l) >> 4) & 0xf) |
|---|
| 111 | +#define GPMC_REVISION_MINOR(l) ((l) & 0xf) |
|---|
| 115 | 112 | |
|---|
| 116 | 113 | #define GPMC_HAS_WR_ACCESS 0x1 |
|---|
| 117 | 114 | #define GPMC_HAS_WR_DATA_MUX_BUS 0x2 |
|---|
| .. | .. |
|---|
| 142 | 139 | #define GPMC_CONFIG1_WRITEMULTIPLE_SUPP (1 << 28) |
|---|
| 143 | 140 | #define GPMC_CONFIG1_WRITETYPE_ASYNC (0 << 27) |
|---|
| 144 | 141 | #define GPMC_CONFIG1_WRITETYPE_SYNC (1 << 27) |
|---|
| 145 | | -#define GPMC_CONFIG1_CLKACTIVATIONTIME(val) ((val & 3) << 25) |
|---|
| 142 | +#define GPMC_CONFIG1_CLKACTIVATIONTIME(val) (((val) & 3) << 25) |
|---|
| 146 | 143 | /** CLKACTIVATIONTIME Max Ticks */ |
|---|
| 147 | 144 | #define GPMC_CONFIG1_CLKACTIVATIONTIME_MAX 2 |
|---|
| 148 | | -#define GPMC_CONFIG1_PAGE_LEN(val) ((val & 3) << 23) |
|---|
| 145 | +#define GPMC_CONFIG1_PAGE_LEN(val) (((val) & 3) << 23) |
|---|
| 149 | 146 | /** ATTACHEDDEVICEPAGELENGTH Max Value */ |
|---|
| 150 | 147 | #define GPMC_CONFIG1_ATTACHEDDEVICEPAGELENGTH_MAX 2 |
|---|
| 151 | 148 | #define GPMC_CONFIG1_WAIT_READ_MON (1 << 22) |
|---|
| 152 | 149 | #define GPMC_CONFIG1_WAIT_WRITE_MON (1 << 21) |
|---|
| 153 | | -#define GPMC_CONFIG1_WAIT_MON_TIME(val) ((val & 3) << 18) |
|---|
| 150 | +#define GPMC_CONFIG1_WAIT_MON_TIME(val) (((val) & 3) << 18) |
|---|
| 154 | 151 | /** WAITMONITORINGTIME Max Ticks */ |
|---|
| 155 | 152 | #define GPMC_CONFIG1_WAITMONITORINGTIME_MAX 2 |
|---|
| 156 | | -#define GPMC_CONFIG1_WAIT_PIN_SEL(val) ((val & 3) << 16) |
|---|
| 157 | | -#define GPMC_CONFIG1_DEVICESIZE(val) ((val & 3) << 12) |
|---|
| 153 | +#define GPMC_CONFIG1_WAIT_PIN_SEL(val) (((val) & 3) << 16) |
|---|
| 154 | +#define GPMC_CONFIG1_DEVICESIZE(val) (((val) & 3) << 12) |
|---|
| 158 | 155 | #define GPMC_CONFIG1_DEVICESIZE_16 GPMC_CONFIG1_DEVICESIZE(1) |
|---|
| 159 | 156 | /** DEVICESIZE Max Value */ |
|---|
| 160 | 157 | #define GPMC_CONFIG1_DEVICESIZE_MAX 1 |
|---|
| 161 | | -#define GPMC_CONFIG1_DEVICETYPE(val) ((val & 3) << 10) |
|---|
| 158 | +#define GPMC_CONFIG1_DEVICETYPE(val) (((val) & 3) << 10) |
|---|
| 162 | 159 | #define GPMC_CONFIG1_DEVICETYPE_NOR GPMC_CONFIG1_DEVICETYPE(0) |
|---|
| 163 | | -#define GPMC_CONFIG1_MUXTYPE(val) ((val & 3) << 8) |
|---|
| 160 | +#define GPMC_CONFIG1_MUXTYPE(val) (((val) & 3) << 8) |
|---|
| 164 | 161 | #define GPMC_CONFIG1_TIME_PARA_GRAN (1 << 4) |
|---|
| 165 | | -#define GPMC_CONFIG1_FCLK_DIV(val) (val & 3) |
|---|
| 162 | +#define GPMC_CONFIG1_FCLK_DIV(val) ((val) & 3) |
|---|
| 166 | 163 | #define GPMC_CONFIG1_FCLK_DIV2 (GPMC_CONFIG1_FCLK_DIV(1)) |
|---|
| 167 | 164 | #define GPMC_CONFIG1_FCLK_DIV3 (GPMC_CONFIG1_FCLK_DIV(2)) |
|---|
| 168 | 165 | #define GPMC_CONFIG1_FCLK_DIV4 (GPMC_CONFIG1_FCLK_DIV(3)) |
|---|
| .. | .. |
|---|
| 246 | 243 | /* Define chip-selects as reserved by default until probe completes */ |
|---|
| 247 | 244 | static unsigned int gpmc_cs_num = GPMC_CS_NUM; |
|---|
| 248 | 245 | static unsigned int gpmc_nr_waitpins; |
|---|
| 249 | | -static resource_size_t phys_base, mem_size; |
|---|
| 250 | | -static unsigned gpmc_capability; |
|---|
| 246 | +static unsigned int gpmc_capability; |
|---|
| 251 | 247 | static void __iomem *gpmc_base; |
|---|
| 252 | 248 | |
|---|
| 253 | 249 | static struct clk *gpmc_l3_clk; |
|---|
| .. | .. |
|---|
| 293 | 289 | |
|---|
| 294 | 290 | /** |
|---|
| 295 | 291 | * gpmc_get_clk_period - get period of selected clock domain in ps |
|---|
| 296 | | - * @cs Chip Select Region. |
|---|
| 297 | | - * @cd Clock Domain. |
|---|
| 292 | + * @cs: Chip Select Region. |
|---|
| 293 | + * @cd: Clock Domain. |
|---|
| 298 | 294 | * |
|---|
| 299 | 295 | * GPMC_CS_CONFIG1 GPMCFCLKDIVIDER for cs has to be setup |
|---|
| 300 | 296 | * prior to calling this function with GPMC_CD_CLK. |
|---|
| 301 | 297 | */ |
|---|
| 302 | 298 | static unsigned long gpmc_get_clk_period(int cs, enum gpmc_clk_domain cd) |
|---|
| 303 | 299 | { |
|---|
| 304 | | - |
|---|
| 305 | 300 | unsigned long tick_ps = gpmc_get_fclk_period(); |
|---|
| 306 | 301 | u32 l; |
|---|
| 307 | 302 | int div; |
|---|
| .. | .. |
|---|
| 315 | 310 | tick_ps *= div; |
|---|
| 316 | 311 | break; |
|---|
| 317 | 312 | case GPMC_CD_FCLK: |
|---|
| 318 | | - /* FALL-THROUGH */ |
|---|
| 319 | 313 | default: |
|---|
| 320 | 314 | break; |
|---|
| 321 | 315 | } |
|---|
| 322 | 316 | |
|---|
| 323 | 317 | return tick_ps; |
|---|
| 324 | | - |
|---|
| 325 | 318 | } |
|---|
| 326 | 319 | |
|---|
| 327 | 320 | static unsigned int gpmc_ns_to_clk_ticks(unsigned int time_ns, int cs, |
|---|
| .. | .. |
|---|
| 413 | 406 | * @reg: GPMC_CS_CONFIGn register offset. |
|---|
| 414 | 407 | * @st_bit: Start Bit |
|---|
| 415 | 408 | * @end_bit: End Bit. Must be >= @st_bit. |
|---|
| 416 | | - * @ma:x Maximum parameter value (before optional @shift). |
|---|
| 409 | + * @max: Maximum parameter value (before optional @shift). |
|---|
| 417 | 410 | * If 0, maximum is as high as @st_bit and @end_bit allow. |
|---|
| 418 | 411 | * @name: DTS node name, w/o "gpmc," |
|---|
| 419 | 412 | * @cd: Clock Domain of timing parameter. |
|---|
| .. | .. |
|---|
| 513 | 506 | GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG1, 4, 4, "time-para-granularity"); |
|---|
| 514 | 507 | GPMC_GET_RAW(GPMC_CS_CONFIG1, 8, 9, "mux-add-data"); |
|---|
| 515 | 508 | GPMC_GET_RAW_SHIFT_MAX(GPMC_CS_CONFIG1, 12, 13, 1, |
|---|
| 516 | | - GPMC_CONFIG1_DEVICESIZE_MAX, "device-width"); |
|---|
| 509 | + GPMC_CONFIG1_DEVICESIZE_MAX, "device-width"); |
|---|
| 517 | 510 | GPMC_GET_RAW(GPMC_CS_CONFIG1, 16, 17, "wait-pin"); |
|---|
| 518 | 511 | GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG1, 21, 21, "wait-on-write"); |
|---|
| 519 | 512 | GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG1, 22, 22, "wait-on-read"); |
|---|
| .. | .. |
|---|
| 627 | 620 | |
|---|
| 628 | 621 | l = gpmc_cs_read_reg(cs, reg); |
|---|
| 629 | 622 | #ifdef CONFIG_OMAP_GPMC_DEBUG |
|---|
| 630 | | - pr_info( |
|---|
| 631 | | - "GPMC CS%d: %-17s: %3d ticks, %3lu ns (was %3i ticks) %3d ns\n", |
|---|
| 632 | | - cs, name, ticks, gpmc_get_clk_period(cs, cd) * ticks / 1000, |
|---|
| 623 | + pr_info("GPMC CS%d: %-17s: %3d ticks, %3lu ns (was %3i ticks) %3d ns\n", |
|---|
| 624 | + cs, name, ticks, gpmc_get_clk_period(cs, cd) * ticks / 1000, |
|---|
| 633 | 625 | (l >> st_bit) & mask, time); |
|---|
| 634 | 626 | #endif |
|---|
| 635 | 627 | l &= ~(mask << st_bit); |
|---|
| .. | .. |
|---|
| 638 | 630 | |
|---|
| 639 | 631 | return 0; |
|---|
| 640 | 632 | } |
|---|
| 641 | | - |
|---|
| 642 | | -#define GPMC_SET_ONE_CD_MAX(reg, st, end, max, field, cd) \ |
|---|
| 643 | | - if (set_gpmc_timing_reg(cs, (reg), (st), (end), (max), \ |
|---|
| 644 | | - t->field, (cd), #field) < 0) \ |
|---|
| 645 | | - return -1 |
|---|
| 646 | | - |
|---|
| 647 | | -#define GPMC_SET_ONE(reg, st, end, field) \ |
|---|
| 648 | | - GPMC_SET_ONE_CD_MAX(reg, st, end, 0, field, GPMC_CD_FCLK) |
|---|
| 649 | 633 | |
|---|
| 650 | 634 | /** |
|---|
| 651 | 635 | * gpmc_calc_waitmonitoring_divider - calculate proper GPMCFCLKDIVIDER based on WAITMONITORINGTIME |
|---|
| .. | .. |
|---|
| 664 | 648 | */ |
|---|
| 665 | 649 | static int gpmc_calc_waitmonitoring_divider(unsigned int wait_monitoring) |
|---|
| 666 | 650 | { |
|---|
| 667 | | - |
|---|
| 668 | 651 | int div = gpmc_ns_to_ticks(wait_monitoring); |
|---|
| 669 | 652 | |
|---|
| 670 | 653 | div += GPMC_CONFIG1_WAITMONITORINGTIME_MAX - 1; |
|---|
| .. | .. |
|---|
| 676 | 659 | div = 1; |
|---|
| 677 | 660 | |
|---|
| 678 | 661 | return div; |
|---|
| 679 | | - |
|---|
| 680 | 662 | } |
|---|
| 681 | 663 | |
|---|
| 682 | 664 | /** |
|---|
| .. | .. |
|---|
| 707 | 689 | int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t, |
|---|
| 708 | 690 | const struct gpmc_settings *s) |
|---|
| 709 | 691 | { |
|---|
| 710 | | - int div; |
|---|
| 692 | + int div, ret; |
|---|
| 711 | 693 | u32 l; |
|---|
| 712 | 694 | |
|---|
| 713 | 695 | div = gpmc_calc_divider(t->sync_clk); |
|---|
| 714 | 696 | if (div < 0) |
|---|
| 715 | | - return div; |
|---|
| 697 | + return -EINVAL; |
|---|
| 716 | 698 | |
|---|
| 717 | 699 | /* |
|---|
| 718 | 700 | * See if we need to change the divider for waitmonitoringtime. |
|---|
| .. | .. |
|---|
| 730 | 712 | if (!s->sync_read && !s->sync_write && |
|---|
| 731 | 713 | (s->wait_on_read || s->wait_on_write) |
|---|
| 732 | 714 | ) { |
|---|
| 733 | | - |
|---|
| 734 | 715 | div = gpmc_calc_waitmonitoring_divider(t->wait_monitoring); |
|---|
| 735 | 716 | if (div < 0) { |
|---|
| 736 | 717 | pr_err("%s: waitmonitoringtime %3d ns too large for greatest gpmcfclkdivider.\n", |
|---|
| 737 | 718 | __func__, |
|---|
| 738 | 719 | t->wait_monitoring |
|---|
| 739 | 720 | ); |
|---|
| 740 | | - return -1; |
|---|
| 721 | + return -ENXIO; |
|---|
| 741 | 722 | } |
|---|
| 742 | 723 | } |
|---|
| 743 | 724 | |
|---|
| 744 | | - GPMC_SET_ONE(GPMC_CS_CONFIG2, 0, 3, cs_on); |
|---|
| 745 | | - GPMC_SET_ONE(GPMC_CS_CONFIG2, 8, 12, cs_rd_off); |
|---|
| 746 | | - GPMC_SET_ONE(GPMC_CS_CONFIG2, 16, 20, cs_wr_off); |
|---|
| 725 | + ret = 0; |
|---|
| 726 | + ret |= set_gpmc_timing_reg(cs, GPMC_CS_CONFIG2, 0, 3, 0, t->cs_on, |
|---|
| 727 | + GPMC_CD_FCLK, "cs_on"); |
|---|
| 728 | + ret |= set_gpmc_timing_reg(cs, GPMC_CS_CONFIG2, 8, 12, 0, t->cs_rd_off, |
|---|
| 729 | + GPMC_CD_FCLK, "cs_rd_off"); |
|---|
| 730 | + ret |= set_gpmc_timing_reg(cs, GPMC_CS_CONFIG2, 16, 20, 0, t->cs_wr_off, |
|---|
| 731 | + GPMC_CD_FCLK, "cs_wr_off"); |
|---|
| 732 | + if (ret) |
|---|
| 733 | + return -ENXIO; |
|---|
| 747 | 734 | |
|---|
| 748 | | - GPMC_SET_ONE(GPMC_CS_CONFIG3, 0, 3, adv_on); |
|---|
| 749 | | - GPMC_SET_ONE(GPMC_CS_CONFIG3, 8, 12, adv_rd_off); |
|---|
| 750 | | - GPMC_SET_ONE(GPMC_CS_CONFIG3, 16, 20, adv_wr_off); |
|---|
| 735 | + ret |= set_gpmc_timing_reg(cs, GPMC_CS_CONFIG3, 0, 3, 0, t->adv_on, |
|---|
| 736 | + GPMC_CD_FCLK, "adv_on"); |
|---|
| 737 | + ret |= set_gpmc_timing_reg(cs, GPMC_CS_CONFIG3, 8, 12, 0, t->adv_rd_off, |
|---|
| 738 | + GPMC_CD_FCLK, "adv_rd_off"); |
|---|
| 739 | + ret |= set_gpmc_timing_reg(cs, GPMC_CS_CONFIG3, 16, 20, 0, t->adv_wr_off, |
|---|
| 740 | + GPMC_CD_FCLK, "adv_wr_off"); |
|---|
| 741 | + if (ret) |
|---|
| 742 | + return -ENXIO; |
|---|
| 743 | + |
|---|
| 751 | 744 | if (gpmc_capability & GPMC_HAS_MUX_AAD) { |
|---|
| 752 | | - GPMC_SET_ONE(GPMC_CS_CONFIG3, 4, 6, adv_aad_mux_on); |
|---|
| 753 | | - GPMC_SET_ONE(GPMC_CS_CONFIG3, 24, 26, adv_aad_mux_rd_off); |
|---|
| 754 | | - GPMC_SET_ONE(GPMC_CS_CONFIG3, 28, 30, adv_aad_mux_wr_off); |
|---|
| 745 | + ret |= set_gpmc_timing_reg(cs, GPMC_CS_CONFIG3, 4, 6, 0, |
|---|
| 746 | + t->adv_aad_mux_on, GPMC_CD_FCLK, |
|---|
| 747 | + "adv_aad_mux_on"); |
|---|
| 748 | + ret |= set_gpmc_timing_reg(cs, GPMC_CS_CONFIG3, 24, 26, 0, |
|---|
| 749 | + t->adv_aad_mux_rd_off, GPMC_CD_FCLK, |
|---|
| 750 | + "adv_aad_mux_rd_off"); |
|---|
| 751 | + ret |= set_gpmc_timing_reg(cs, GPMC_CS_CONFIG3, 28, 30, 0, |
|---|
| 752 | + t->adv_aad_mux_wr_off, GPMC_CD_FCLK, |
|---|
| 753 | + "adv_aad_mux_wr_off"); |
|---|
| 754 | + if (ret) |
|---|
| 755 | + return -ENXIO; |
|---|
| 755 | 756 | } |
|---|
| 756 | 757 | |
|---|
| 757 | | - GPMC_SET_ONE(GPMC_CS_CONFIG4, 0, 3, oe_on); |
|---|
| 758 | | - GPMC_SET_ONE(GPMC_CS_CONFIG4, 8, 12, oe_off); |
|---|
| 758 | + ret |= set_gpmc_timing_reg(cs, GPMC_CS_CONFIG4, 0, 3, 0, t->oe_on, |
|---|
| 759 | + GPMC_CD_FCLK, "oe_on"); |
|---|
| 760 | + ret |= set_gpmc_timing_reg(cs, GPMC_CS_CONFIG4, 8, 12, 0, t->oe_off, |
|---|
| 761 | + GPMC_CD_FCLK, "oe_off"); |
|---|
| 759 | 762 | if (gpmc_capability & GPMC_HAS_MUX_AAD) { |
|---|
| 760 | | - GPMC_SET_ONE(GPMC_CS_CONFIG4, 4, 6, oe_aad_mux_on); |
|---|
| 761 | | - GPMC_SET_ONE(GPMC_CS_CONFIG4, 13, 15, oe_aad_mux_off); |
|---|
| 763 | + ret |= set_gpmc_timing_reg(cs, GPMC_CS_CONFIG4, 4, 6, 0, |
|---|
| 764 | + t->oe_aad_mux_on, GPMC_CD_FCLK, |
|---|
| 765 | + "oe_aad_mux_on"); |
|---|
| 766 | + ret |= set_gpmc_timing_reg(cs, GPMC_CS_CONFIG4, 13, 15, 0, |
|---|
| 767 | + t->oe_aad_mux_off, GPMC_CD_FCLK, |
|---|
| 768 | + "oe_aad_mux_off"); |
|---|
| 762 | 769 | } |
|---|
| 763 | | - GPMC_SET_ONE(GPMC_CS_CONFIG4, 16, 19, we_on); |
|---|
| 764 | | - GPMC_SET_ONE(GPMC_CS_CONFIG4, 24, 28, we_off); |
|---|
| 770 | + ret |= set_gpmc_timing_reg(cs, GPMC_CS_CONFIG4, 16, 19, 0, t->we_on, |
|---|
| 771 | + GPMC_CD_FCLK, "we_on"); |
|---|
| 772 | + ret |= set_gpmc_timing_reg(cs, GPMC_CS_CONFIG4, 24, 28, 0, t->we_off, |
|---|
| 773 | + GPMC_CD_FCLK, "we_off"); |
|---|
| 774 | + if (ret) |
|---|
| 775 | + return -ENXIO; |
|---|
| 765 | 776 | |
|---|
| 766 | | - GPMC_SET_ONE(GPMC_CS_CONFIG5, 0, 4, rd_cycle); |
|---|
| 767 | | - GPMC_SET_ONE(GPMC_CS_CONFIG5, 8, 12, wr_cycle); |
|---|
| 768 | | - GPMC_SET_ONE(GPMC_CS_CONFIG5, 16, 20, access); |
|---|
| 777 | + ret |= set_gpmc_timing_reg(cs, GPMC_CS_CONFIG5, 0, 4, 0, t->rd_cycle, |
|---|
| 778 | + GPMC_CD_FCLK, "rd_cycle"); |
|---|
| 779 | + ret |= set_gpmc_timing_reg(cs, GPMC_CS_CONFIG5, 8, 12, 0, t->wr_cycle, |
|---|
| 780 | + GPMC_CD_FCLK, "wr_cycle"); |
|---|
| 781 | + ret |= set_gpmc_timing_reg(cs, GPMC_CS_CONFIG5, 16, 20, 0, t->access, |
|---|
| 782 | + GPMC_CD_FCLK, "access"); |
|---|
| 783 | + ret |= set_gpmc_timing_reg(cs, GPMC_CS_CONFIG5, 24, 27, 0, |
|---|
| 784 | + t->page_burst_access, GPMC_CD_FCLK, |
|---|
| 785 | + "page_burst_access"); |
|---|
| 786 | + if (ret) |
|---|
| 787 | + return -ENXIO; |
|---|
| 769 | 788 | |
|---|
| 770 | | - GPMC_SET_ONE(GPMC_CS_CONFIG5, 24, 27, page_burst_access); |
|---|
| 789 | + ret |= set_gpmc_timing_reg(cs, GPMC_CS_CONFIG6, 0, 3, 0, |
|---|
| 790 | + t->bus_turnaround, GPMC_CD_FCLK, |
|---|
| 791 | + "bus_turnaround"); |
|---|
| 792 | + ret |= set_gpmc_timing_reg(cs, GPMC_CS_CONFIG6, 8, 11, 0, |
|---|
| 793 | + t->cycle2cycle_delay, GPMC_CD_FCLK, |
|---|
| 794 | + "cycle2cycle_delay"); |
|---|
| 795 | + if (ret) |
|---|
| 796 | + return -ENXIO; |
|---|
| 771 | 797 | |
|---|
| 772 | | - GPMC_SET_ONE(GPMC_CS_CONFIG6, 0, 3, bus_turnaround); |
|---|
| 773 | | - GPMC_SET_ONE(GPMC_CS_CONFIG6, 8, 11, cycle2cycle_delay); |
|---|
| 774 | | - |
|---|
| 775 | | - if (gpmc_capability & GPMC_HAS_WR_DATA_MUX_BUS) |
|---|
| 776 | | - GPMC_SET_ONE(GPMC_CS_CONFIG6, 16, 19, wr_data_mux_bus); |
|---|
| 777 | | - if (gpmc_capability & GPMC_HAS_WR_ACCESS) |
|---|
| 778 | | - GPMC_SET_ONE(GPMC_CS_CONFIG6, 24, 28, wr_access); |
|---|
| 798 | + if (gpmc_capability & GPMC_HAS_WR_DATA_MUX_BUS) { |
|---|
| 799 | + ret |= set_gpmc_timing_reg(cs, GPMC_CS_CONFIG6, 16, 19, 0, |
|---|
| 800 | + t->wr_data_mux_bus, GPMC_CD_FCLK, |
|---|
| 801 | + "wr_data_mux_bus"); |
|---|
| 802 | + if (ret) |
|---|
| 803 | + return -ENXIO; |
|---|
| 804 | + } |
|---|
| 805 | + if (gpmc_capability & GPMC_HAS_WR_ACCESS) { |
|---|
| 806 | + ret |= set_gpmc_timing_reg(cs, GPMC_CS_CONFIG6, 24, 28, 0, |
|---|
| 807 | + t->wr_access, GPMC_CD_FCLK, |
|---|
| 808 | + "wr_access"); |
|---|
| 809 | + if (ret) |
|---|
| 810 | + return -ENXIO; |
|---|
| 811 | + } |
|---|
| 779 | 812 | |
|---|
| 780 | 813 | l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1); |
|---|
| 781 | 814 | l &= ~0x03; |
|---|
| 782 | 815 | l |= (div - 1); |
|---|
| 783 | 816 | gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, l); |
|---|
| 784 | 817 | |
|---|
| 785 | | - GPMC_SET_ONE_CD_MAX(GPMC_CS_CONFIG1, 18, 19, |
|---|
| 786 | | - GPMC_CONFIG1_WAITMONITORINGTIME_MAX, |
|---|
| 787 | | - wait_monitoring, GPMC_CD_CLK); |
|---|
| 788 | | - GPMC_SET_ONE_CD_MAX(GPMC_CS_CONFIG1, 25, 26, |
|---|
| 789 | | - GPMC_CONFIG1_CLKACTIVATIONTIME_MAX, |
|---|
| 790 | | - clk_activation, GPMC_CD_FCLK); |
|---|
| 818 | + ret = 0; |
|---|
| 819 | + ret |= set_gpmc_timing_reg(cs, GPMC_CS_CONFIG1, 18, 19, |
|---|
| 820 | + GPMC_CONFIG1_WAITMONITORINGTIME_MAX, |
|---|
| 821 | + t->wait_monitoring, GPMC_CD_CLK, |
|---|
| 822 | + "wait_monitoring"); |
|---|
| 823 | + ret |= set_gpmc_timing_reg(cs, GPMC_CS_CONFIG1, 25, 26, |
|---|
| 824 | + GPMC_CONFIG1_CLKACTIVATIONTIME_MAX, |
|---|
| 825 | + t->clk_activation, GPMC_CD_FCLK, |
|---|
| 826 | + "clk_activation"); |
|---|
| 827 | + if (ret) |
|---|
| 828 | + return -ENXIO; |
|---|
| 791 | 829 | |
|---|
| 792 | 830 | #ifdef CONFIG_OMAP_GPMC_DEBUG |
|---|
| 793 | 831 | pr_info("GPMC CS%d CLK period is %lu ns (div %d)\n", |
|---|
| .. | .. |
|---|
| 878 | 916 | return gpmc->flags & GPMC_CS_RESERVED; |
|---|
| 879 | 917 | } |
|---|
| 880 | 918 | |
|---|
| 881 | | -static void gpmc_cs_set_name(int cs, const char *name) |
|---|
| 882 | | -{ |
|---|
| 883 | | - struct gpmc_cs_data *gpmc = &gpmc_cs[cs]; |
|---|
| 884 | | - |
|---|
| 885 | | - gpmc->name = name; |
|---|
| 886 | | -} |
|---|
| 887 | | - |
|---|
| 888 | | -static const char *gpmc_cs_get_name(int cs) |
|---|
| 889 | | -{ |
|---|
| 890 | | - struct gpmc_cs_data *gpmc = &gpmc_cs[cs]; |
|---|
| 891 | | - |
|---|
| 892 | | - return gpmc->name; |
|---|
| 893 | | -} |
|---|
| 894 | | - |
|---|
| 895 | 919 | static unsigned long gpmc_mem_align(unsigned long size) |
|---|
| 896 | 920 | { |
|---|
| 897 | 921 | int order; |
|---|
| .. | .. |
|---|
| 935 | 959 | spin_unlock(&gpmc_mem_lock); |
|---|
| 936 | 960 | |
|---|
| 937 | 961 | return r; |
|---|
| 938 | | -} |
|---|
| 939 | | - |
|---|
| 940 | | -/** |
|---|
| 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 |
|---|
| 944 | | - * |
|---|
| 945 | | - * Re-maps a chip-select to a new physical base address specified by |
|---|
| 946 | | - * "base". Returns 0 on success and appropriate negative error code |
|---|
| 947 | | - * on failure. |
|---|
| 948 | | - */ |
|---|
| 949 | | -static int gpmc_cs_remap(int cs, u32 base) |
|---|
| 950 | | -{ |
|---|
| 951 | | - int ret; |
|---|
| 952 | | - u32 old_base, size; |
|---|
| 953 | | - |
|---|
| 954 | | - if (cs >= gpmc_cs_num) { |
|---|
| 955 | | - pr_err("%s: requested chip-select is disabled\n", __func__); |
|---|
| 956 | | - return -ENODEV; |
|---|
| 957 | | - } |
|---|
| 958 | | - |
|---|
| 959 | | - /* |
|---|
| 960 | | - * Make sure we ignore any device offsets from the GPMC partition |
|---|
| 961 | | - * allocated for the chip select and that the new base confirms |
|---|
| 962 | | - * to the GPMC 16MB minimum granularity. |
|---|
| 963 | | - */ |
|---|
| 964 | | - base &= ~(SZ_16M - 1); |
|---|
| 965 | | - |
|---|
| 966 | | - gpmc_cs_get_memconf(cs, &old_base, &size); |
|---|
| 967 | | - if (base == old_base) |
|---|
| 968 | | - return 0; |
|---|
| 969 | | - |
|---|
| 970 | | - ret = gpmc_cs_delete_mem(cs); |
|---|
| 971 | | - if (ret < 0) |
|---|
| 972 | | - return ret; |
|---|
| 973 | | - |
|---|
| 974 | | - ret = gpmc_cs_insert_mem(cs, base, size); |
|---|
| 975 | | - if (ret < 0) |
|---|
| 976 | | - return ret; |
|---|
| 977 | | - |
|---|
| 978 | | - ret = gpmc_cs_set_memconf(cs, base, size); |
|---|
| 979 | | - |
|---|
| 980 | | - return ret; |
|---|
| 981 | 962 | } |
|---|
| 982 | 963 | |
|---|
| 983 | 964 | int gpmc_cs_request(int cs, unsigned long size, unsigned long *base) |
|---|
| .. | .. |
|---|
| 1033 | 1014 | |
|---|
| 1034 | 1015 | spin_lock(&gpmc_mem_lock); |
|---|
| 1035 | 1016 | if (cs >= gpmc_cs_num || cs < 0 || !gpmc_cs_reserved(cs)) { |
|---|
| 1036 | | - printk(KERN_ERR "Trying to free non-reserved GPMC CS%d\n", cs); |
|---|
| 1037 | | - BUG(); |
|---|
| 1017 | + WARN(1, "Trying to free non-reserved GPMC CS%d\n", cs); |
|---|
| 1038 | 1018 | spin_unlock(&gpmc_mem_lock); |
|---|
| 1039 | 1019 | return; |
|---|
| 1040 | 1020 | } |
|---|
| .. | .. |
|---|
| 1092 | 1072 | |
|---|
| 1093 | 1073 | /** |
|---|
| 1094 | 1074 | * gpmc_omap_get_nand_ops - Get the GPMC NAND interface |
|---|
| 1095 | | - * @regs: the GPMC NAND register map exclusive for NAND use. |
|---|
| 1075 | + * @reg: the GPMC NAND register map exclusive for NAND use. |
|---|
| 1096 | 1076 | * @cs: GPMC chip select number on which the NAND sits. The |
|---|
| 1097 | 1077 | * register map returned will be specific to this chip select. |
|---|
| 1098 | 1078 | * |
|---|
| .. | .. |
|---|
| 1247 | 1227 | } |
|---|
| 1248 | 1228 | EXPORT_SYMBOL_GPL(gpmc_omap_onenand_set_timings); |
|---|
| 1249 | 1229 | |
|---|
| 1250 | | -int gpmc_get_client_irq(unsigned irq_config) |
|---|
| 1230 | +int gpmc_get_client_irq(unsigned int irq_config) |
|---|
| 1251 | 1231 | { |
|---|
| 1252 | 1232 | if (!gpmc_irq_domain) { |
|---|
| 1253 | 1233 | pr_warn("%s called before GPMC IRQ domain available\n", |
|---|
| .. | .. |
|---|
| 1470 | 1450 | continue; |
|---|
| 1471 | 1451 | gpmc_cs_delete_mem(cs); |
|---|
| 1472 | 1452 | } |
|---|
| 1473 | | - |
|---|
| 1474 | 1453 | } |
|---|
| 1475 | 1454 | |
|---|
| 1476 | 1455 | static void gpmc_mem_init(void) |
|---|
| .. | .. |
|---|
| 1639 | 1618 | /* oe_on */ |
|---|
| 1640 | 1619 | temp = dev_t->t_oeasu; |
|---|
| 1641 | 1620 | if (mux) |
|---|
| 1642 | | - temp = max_t(u32, temp, |
|---|
| 1643 | | - gpmc_t->adv_rd_off + dev_t->t_aavdh); |
|---|
| 1621 | + temp = max_t(u32, temp, gpmc_t->adv_rd_off + dev_t->t_aavdh); |
|---|
| 1644 | 1622 | gpmc_t->oe_on = gpmc_round_ps_to_ticks(temp); |
|---|
| 1645 | 1623 | |
|---|
| 1646 | 1624 | /* access */ |
|---|
| 1647 | 1625 | temp = max_t(u32, dev_t->t_iaa, /* XXX: remove t_iaa in async ? */ |
|---|
| 1648 | | - gpmc_t->oe_on + dev_t->t_oe); |
|---|
| 1649 | | - temp = max_t(u32, temp, |
|---|
| 1650 | | - gpmc_t->cs_on + dev_t->t_ce); |
|---|
| 1651 | | - temp = max_t(u32, temp, |
|---|
| 1652 | | - gpmc_t->adv_on + dev_t->t_aa); |
|---|
| 1626 | + gpmc_t->oe_on + dev_t->t_oe); |
|---|
| 1627 | + temp = max_t(u32, temp, gpmc_t->cs_on + dev_t->t_ce); |
|---|
| 1628 | + temp = max_t(u32, temp, gpmc_t->adv_on + dev_t->t_aa); |
|---|
| 1653 | 1629 | gpmc_t->access = gpmc_round_ps_to_ticks(temp); |
|---|
| 1654 | 1630 | |
|---|
| 1655 | 1631 | gpmc_t->oe_off = gpmc_t->access + gpmc_ticks_to_ps(1); |
|---|
| .. | .. |
|---|
| 1758 | 1734 | return 0; |
|---|
| 1759 | 1735 | } |
|---|
| 1760 | 1736 | |
|---|
| 1761 | | -/* TODO: remove this function once all peripherals are confirmed to |
|---|
| 1737 | +/* |
|---|
| 1738 | + * TODO: remove this function once all peripherals are confirmed to |
|---|
| 1762 | 1739 | * work with generic timing. Simultaneously gpmc_cs_set_timings() |
|---|
| 1763 | 1740 | * has to be modified to handle timings in ps instead of ns |
|---|
| 1764 | | -*/ |
|---|
| 1741 | + */ |
|---|
| 1765 | 1742 | static void gpmc_convert_ps_to_ns(struct gpmc_timings *t) |
|---|
| 1766 | 1743 | { |
|---|
| 1767 | 1744 | t->cs_on /= 1000; |
|---|
| .. | .. |
|---|
| 1909 | 1886 | { .compatible = "ti,am3352-gpmc" }, /* am335x devices */ |
|---|
| 1910 | 1887 | { } |
|---|
| 1911 | 1888 | }; |
|---|
| 1889 | + |
|---|
| 1890 | +static void gpmc_cs_set_name(int cs, const char *name) |
|---|
| 1891 | +{ |
|---|
| 1892 | + struct gpmc_cs_data *gpmc = &gpmc_cs[cs]; |
|---|
| 1893 | + |
|---|
| 1894 | + gpmc->name = name; |
|---|
| 1895 | +} |
|---|
| 1896 | + |
|---|
| 1897 | +static const char *gpmc_cs_get_name(int cs) |
|---|
| 1898 | +{ |
|---|
| 1899 | + struct gpmc_cs_data *gpmc = &gpmc_cs[cs]; |
|---|
| 1900 | + |
|---|
| 1901 | + return gpmc->name; |
|---|
| 1902 | +} |
|---|
| 1903 | + |
|---|
| 1904 | +/** |
|---|
| 1905 | + * gpmc_cs_remap - remaps a chip-select physical base address |
|---|
| 1906 | + * @cs: chip-select to remap |
|---|
| 1907 | + * @base: physical base address to re-map chip-select to |
|---|
| 1908 | + * |
|---|
| 1909 | + * Re-maps a chip-select to a new physical base address specified by |
|---|
| 1910 | + * "base". Returns 0 on success and appropriate negative error code |
|---|
| 1911 | + * on failure. |
|---|
| 1912 | + */ |
|---|
| 1913 | +static int gpmc_cs_remap(int cs, u32 base) |
|---|
| 1914 | +{ |
|---|
| 1915 | + int ret; |
|---|
| 1916 | + u32 old_base, size; |
|---|
| 1917 | + |
|---|
| 1918 | + if (cs >= gpmc_cs_num) { |
|---|
| 1919 | + pr_err("%s: requested chip-select is disabled\n", __func__); |
|---|
| 1920 | + return -ENODEV; |
|---|
| 1921 | + } |
|---|
| 1922 | + |
|---|
| 1923 | + /* |
|---|
| 1924 | + * Make sure we ignore any device offsets from the GPMC partition |
|---|
| 1925 | + * allocated for the chip select and that the new base confirms |
|---|
| 1926 | + * to the GPMC 16MB minimum granularity. |
|---|
| 1927 | + */ |
|---|
| 1928 | + base &= ~(SZ_16M - 1); |
|---|
| 1929 | + |
|---|
| 1930 | + gpmc_cs_get_memconf(cs, &old_base, &size); |
|---|
| 1931 | + if (base == old_base) |
|---|
| 1932 | + return 0; |
|---|
| 1933 | + |
|---|
| 1934 | + ret = gpmc_cs_delete_mem(cs); |
|---|
| 1935 | + if (ret < 0) |
|---|
| 1936 | + return ret; |
|---|
| 1937 | + |
|---|
| 1938 | + ret = gpmc_cs_insert_mem(cs, base, size); |
|---|
| 1939 | + if (ret < 0) |
|---|
| 1940 | + return ret; |
|---|
| 1941 | + |
|---|
| 1942 | + ret = gpmc_cs_set_memconf(cs, base, size); |
|---|
| 1943 | + |
|---|
| 1944 | + return ret; |
|---|
| 1945 | +} |
|---|
| 1912 | 1946 | |
|---|
| 1913 | 1947 | /** |
|---|
| 1914 | 1948 | * gpmc_read_settings_dt - read gpmc settings from device-tree |
|---|
| .. | .. |
|---|
| 2064 | 2098 | * timings. |
|---|
| 2065 | 2099 | */ |
|---|
| 2066 | 2100 | name = gpmc_cs_get_name(cs); |
|---|
| 2067 | | - if (name && of_node_cmp(child->name, name) == 0) |
|---|
| 2101 | + if (name && of_node_name_eq(child, name)) |
|---|
| 2068 | 2102 | goto no_timings; |
|---|
| 2069 | 2103 | |
|---|
| 2070 | 2104 | ret = gpmc_cs_request(cs, resource_size(&res), &base); |
|---|
| .. | .. |
|---|
| 2072 | 2106 | dev_err(&pdev->dev, "cannot request GPMC CS %d\n", cs); |
|---|
| 2073 | 2107 | return ret; |
|---|
| 2074 | 2108 | } |
|---|
| 2075 | | - gpmc_cs_set_name(cs, child->name); |
|---|
| 2109 | + gpmc_cs_set_name(cs, child->full_name); |
|---|
| 2076 | 2110 | |
|---|
| 2077 | 2111 | gpmc_read_settings_dt(child, &gpmc_s); |
|---|
| 2078 | 2112 | gpmc_read_timings_dt(child, &gpmc_t); |
|---|
| .. | .. |
|---|
| 2094 | 2128 | gpmc_cs_disable_mem(cs); |
|---|
| 2095 | 2129 | |
|---|
| 2096 | 2130 | /* |
|---|
| 2097 | | - * FIXME: gpmc_cs_request() will map the CS to an arbitary |
|---|
| 2131 | + * FIXME: gpmc_cs_request() will map the CS to an arbitrary |
|---|
| 2098 | 2132 | * location in the gpmc address space. When booting with |
|---|
| 2099 | 2133 | * device-tree we want the NOR flash to be mapped to the |
|---|
| 2100 | 2134 | * location specified in the device-tree blob. So remap the |
|---|
| .. | .. |
|---|
| 2117 | 2151 | goto err; |
|---|
| 2118 | 2152 | } |
|---|
| 2119 | 2153 | |
|---|
| 2120 | | - if (of_node_cmp(child->name, "nand") == 0) { |
|---|
| 2154 | + if (of_node_name_eq(child, "nand")) { |
|---|
| 2121 | 2155 | /* Warn about older DT blobs with no compatible property */ |
|---|
| 2122 | 2156 | if (!of_property_read_bool(child, "compatible")) { |
|---|
| 2123 | 2157 | dev_warn(&pdev->dev, |
|---|
| .. | .. |
|---|
| 2127 | 2161 | } |
|---|
| 2128 | 2162 | } |
|---|
| 2129 | 2163 | |
|---|
| 2130 | | - if (of_node_cmp(child->name, "onenand") == 0) { |
|---|
| 2164 | + if (of_node_name_eq(child, "onenand")) { |
|---|
| 2131 | 2165 | /* Warn about older DT blobs with no compatible property */ |
|---|
| 2132 | 2166 | if (!of_property_read_bool(child, "compatible")) { |
|---|
| 2133 | 2167 | dev_warn(&pdev->dev, |
|---|
| .. | .. |
|---|
| 2149 | 2183 | gpmc_s.device_width = GPMC_DEVWIDTH_16BIT; |
|---|
| 2150 | 2184 | break; |
|---|
| 2151 | 2185 | default: |
|---|
| 2152 | | - dev_err(&pdev->dev, "%s: invalid 'nand-bus-width'\n", |
|---|
| 2153 | | - child->name); |
|---|
| 2186 | + dev_err(&pdev->dev, "%pOFn: invalid 'nand-bus-width'\n", |
|---|
| 2187 | + child); |
|---|
| 2154 | 2188 | ret = -EINVAL; |
|---|
| 2155 | 2189 | goto err; |
|---|
| 2156 | 2190 | } |
|---|
| .. | .. |
|---|
| 2174 | 2208 | unsigned int wait_pin = gpmc_s.wait_pin; |
|---|
| 2175 | 2209 | |
|---|
| 2176 | 2210 | waitpin_desc = gpiochip_request_own_desc(&gpmc->gpio_chip, |
|---|
| 2177 | | - wait_pin, "WAITPIN"); |
|---|
| 2211 | + wait_pin, "WAITPIN", |
|---|
| 2212 | + GPIO_ACTIVE_HIGH, |
|---|
| 2213 | + GPIOD_IN); |
|---|
| 2178 | 2214 | if (IS_ERR(waitpin_desc)) { |
|---|
| 2179 | 2215 | dev_err(&pdev->dev, "invalid wait-pin: %d\n", wait_pin); |
|---|
| 2180 | 2216 | ret = PTR_ERR(waitpin_desc); |
|---|
| .. | .. |
|---|
| 2190 | 2226 | |
|---|
| 2191 | 2227 | ret = gpmc_cs_set_timings(cs, &gpmc_t, &gpmc_s); |
|---|
| 2192 | 2228 | if (ret) { |
|---|
| 2193 | | - dev_err(&pdev->dev, "failed to set gpmc timings for: %s\n", |
|---|
| 2194 | | - child->name); |
|---|
| 2229 | + dev_err(&pdev->dev, "failed to set gpmc timings for: %pOFn\n", |
|---|
| 2230 | + child); |
|---|
| 2195 | 2231 | goto err_cs; |
|---|
| 2196 | 2232 | } |
|---|
| 2197 | 2233 | |
|---|
| .. | .. |
|---|
| 2219 | 2255 | |
|---|
| 2220 | 2256 | err_child_fail: |
|---|
| 2221 | 2257 | |
|---|
| 2222 | | - dev_err(&pdev->dev, "failed to create gpmc child %s\n", child->name); |
|---|
| 2258 | + dev_err(&pdev->dev, "failed to create gpmc child %pOFn\n", child); |
|---|
| 2223 | 2259 | ret = -ENODEV; |
|---|
| 2224 | 2260 | |
|---|
| 2225 | 2261 | err_cs: |
|---|
| .. | .. |
|---|
| 2269 | 2305 | struct device_node *child; |
|---|
| 2270 | 2306 | |
|---|
| 2271 | 2307 | for_each_available_child_of_node(pdev->dev.of_node, child) { |
|---|
| 2272 | | - |
|---|
| 2273 | | - if (!child->name) |
|---|
| 2274 | | - continue; |
|---|
| 2275 | | - |
|---|
| 2276 | 2308 | ret = gpmc_probe_generic_child(pdev, child); |
|---|
| 2277 | 2309 | if (ret) { |
|---|
| 2278 | | - dev_err(&pdev->dev, "failed to probe DT child '%s': %d\n", |
|---|
| 2279 | | - child->name, ret); |
|---|
| 2310 | + dev_err(&pdev->dev, "failed to probe DT child '%pOFn': %d\n", |
|---|
| 2311 | + child, ret); |
|---|
| 2280 | 2312 | } |
|---|
| 2281 | 2313 | } |
|---|
| 2282 | 2314 | } |
|---|
| .. | .. |
|---|
| 2367 | 2399 | platform_set_drvdata(pdev, gpmc); |
|---|
| 2368 | 2400 | |
|---|
| 2369 | 2401 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
|---|
| 2370 | | - if (res == NULL) |
|---|
| 2402 | + if (!res) |
|---|
| 2371 | 2403 | return -ENOENT; |
|---|
| 2372 | | - |
|---|
| 2373 | | - phys_base = res->start; |
|---|
| 2374 | | - mem_size = resource_size(res); |
|---|
| 2375 | 2404 | |
|---|
| 2376 | 2405 | gpmc_base = devm_ioremap_resource(&pdev->dev, res); |
|---|
| 2377 | 2406 | if (IS_ERR(gpmc_base)) |
|---|