Prepare for GPMC driver conversion
Subsystems (6)
v4 cover Prepare for GPMC driver conversion
Hi,
Objective of this series is to make things easy for GPMC driver conversion series by separating out more things from driver conversion series.
This series,
1. Unifies NAND platform initialization functions
2. Prepares OneNAND platform code for gpmc driver migration
3. Handles additional timings in Kernel
This series is based on 3.5-rc1 & made on top of
[PATCH v2 00/10] Prepare for GPMC driver conversion (w.r.t MTD) {http://www.mail-archive.com/linux-omap at vger.kernel.org/msg70096.html}
These changes has been tested with omap3evm & beagle board. Relevant GPMC peripherals that got tested by this were NAND (beagle) and OneNAND (using local patches for omap3evm)
Regards
Afzal
v4:
1. Reorganize OneNAND set_sync/async functions in a better way v3:
1. Refactor OneNAND set_sync/async functions to separate out timing and configurations
2. Handle bool type timings too
3. Swap patches 2 & 3 due to dependency of OneNAND change on newly added bool type timings
v2:
1. Make use of timing api for setting clock activation time, and remove direct writing to register for clock activation. Peripherals making use of it were tusb6010 & onenand
2. Move ensuring that async mode in OneNAND has been setup from set_sync to setup function, improve commit message
Afzal Mohammed (3):
ARM: OMAP2+: nand: unify init functions
ARM: OMAP2+: gpmc: handle additional timings
ARM: OMAP2+: onenand: prepare for gpmc driver migration
arch/arm/mach-omap2/board-devkit8000.c | 8 +- arch/arm/mach-omap2/board-flash.c | 45 ++++---- arch/arm/mach-omap2/board-flash.h | 6 +- arch/arm/mach-omap2/board-igep0020.c | 2 +- arch/arm/mach-omap2/board-ldp.c | 4 +- arch/arm/mach-omap2/board-omap3beagle.c | 8 +- arch/arm/mach-omap2/board-omap3touchbook.c | 8 +- arch/arm/mach-omap2/board-overo.c | 7 +- arch/arm/mach-omap2/board-zoom.c | 5 +- arch/arm/mach-omap2/common-board-devices.c | 46 -------- arch/arm/mach-omap2/common-board-devices.h | 1 - arch/arm/mach-omap2/gpmc-onenand.c | 156 +++++++++++++++------------- arch/arm/mach-omap2/gpmc.c | 45 ++++++++ arch/arm/mach-omap2/usb-tusb6010.c | 3 +- arch/arm/plat-omap/include/plat/gpmc.h | 19 ++++ 15 files changed, 207 insertions(+), 156 deletions(-)
Signature · 1 line
1.7.10.2
PATCH v4 1/3 ARM: OMAP2+: nand: unify init functions
Helper function for updating nand platform data has been added the capability to take timing structure arguement. Usage of omap_nand_flash_init() has been replaced by modifed one, omap_nand_flash_init was doing things similar to board_nand_init except that NAND CS# were being acquired based on bootloader setting. As CS# is hardwired for a given board, acquiring gpmc CS# has been removed, and updated with the value on board.
NAND CS# used in beagle board was found to be CS0. Thomas Weber <[email protected]> reported that value of devkit8000 to be CS0. Overo board was found to be using CS0 based on u-boot, while google grep says omap3touchbook too has CS0.
--- arch/arm/mach-omap2/board-devkit8000.c | 8 +++-- arch/arm/mach-omap2/board-flash.c | 45 ++++++++++++++------------- arch/arm/mach-omap2/board-flash.h | 6 ++-- arch/arm/mach-omap2/board-igep0020.c | 2 +- arch/arm/mach-omap2/board-ldp.c | 4 +-- arch/arm/mach-omap2/board-omap3beagle.c | 8 +++-- arch/arm/mach-omap2/board-omap3touchbook.c | 8 +++-- arch/arm/mach-omap2/board-overo.c | 7 +++-- arch/arm/mach-omap2/board-zoom.c | 5 +-- arch/arm/mach-omap2/common-board-devices.c | 46 ---------------------------- arch/arm/mach-omap2/common-board-devices.h | 1 - 11 files changed, 56 insertions(+), 84 deletions(-)
arch/arm/mach-omap2/board-devkit8000.c +6 -2
@@ -59,8 +59,11 @@#include "mux.h" #include "hsmmc.h" +#include "board-flash.h" #include "common-board-devices.h" +#define NAND_CS 0 +#define OMAP_DM9000_GPIO_IRQ 25#define OMAP3_DEVKIT_TS_GPIO 27
@@ -628,8 +631,9 @@ static void __init devkit8000_init(void)usb_musb_init (NULL );usbhs_init (&usbhs_bdata); -omap_nand_flash_init (NAND_BUSWIDTH_16 , devkit8000_nand_partitions, -ARRAY_SIZE (devkit8000_nand_partitions)); +board_nand_init (devkit8000_nand_partitions, +ARRAY_SIZE (devkit8000_nand_partitions),NAND_CS , +NAND_BUSWIDTH_16 ,NULL );/* Ensure SDRC pins are mux'd for self-refresh */ omap_mux_init_signal ("sdrc_cke0" ,OMAP_PIN_OUTPUT );
arch/arm/mach-omap2/board-flash.c +23 -22
69 lines not on this page · raw message
arch/arm/mach-omap2/board-flash.h +4 -2
@@ -40,12 +40,14 @@ static inline void board_flash_init(struct flash_partitions part[],#if defined(CONFIG_MTD_NAND_OMAP2 ) || \ defined(CONFIG_MTD_NAND_OMAP2_MODULE )extern void board_nand_init (struct mtd_partition *nand_parts, -u8 nr_parts,u8 cs,int nand_type); +u8 nr_parts,u8 cs,int nand_type,struct gpmc_timings *gpmc_t); +extern struct gpmc_timings nand_default_timings[];#else static inline void board_nand_init (struct mtd_partition *nand_parts, -u8 nr_parts,u8 cs,int nand_type) +u8 nr_parts,u8 cs,int nand_type,struct gpmc_timings *gpmc_t) { } +#define nand_default_timings NULL#endif #if defined(CONFIG_MTD_ONENAND_OMAP2) || \
arch/arm/mach-omap2/board-igep0020.c +1 -1
@@ -175,7 +175,7 @@ static void __init igep_flash_init(void)pr_info ("IGEP: initializing NAND memory device\n" );board_nand_init (igep_flash_partitions,ARRAY_SIZE (igep_flash_partitions), -0 ,NAND_BUSWIDTH_16 ); +0 ,NAND_BUSWIDTH_16 , nand_default_timings); }else if (mux ==IGEP_SYSBOOT_ONENAND ) {pr_info ("IGEP: initializing OneNAND memory device\n" ); board_onenand_init(igep_flash_partitions,
arch/arm/mach-omap2/board-ldp.c +2 -2
@@ -427,8 +427,8 @@ static void __init omap_ldp_init(void)omap_serial_init ();omap_sdrc_init (NULL ,NULL );usb_musb_init (NULL ); -board_nand_init (ldp_nand_partitions, -ARRAY_SIZE (ldp_nand_partitions),ZOOM_NAND_CS ,0 ); +board_nand_init (ldp_nand_partitions,ARRAY_SIZE (ldp_nand_partitions), +ZOOM_NAND_CS ,0 , nand_default_timings);omap_hsmmc_init (mmc);ldp_display_init ();
arch/arm/mach-omap2/board-omap3beagle.c +6 -2
@@ -51,8 +51,11 @@#include "mux.h" #include "hsmmc.h" #include "pm.h" +#include "board-flash.h" #include "common-board-devices.h" +#define NAND_CS 0 +/* * OMAP3 Beagle revision * Run time detection of Beagle revision is done by reading GPIO.
@@ -521,8 +524,9 @@ static void __init omap3_beagle_init(void)usb_musb_init (NULL );usbhs_init (&usbhs_bdata); -omap_nand_flash_init (NAND_BUSWIDTH_16 , omap3beagle_nand_partitions, -ARRAY_SIZE (omap3beagle_nand_partitions)); +board_nand_init (omap3beagle_nand_partitions, +ARRAY_SIZE (omap3beagle_nand_partitions),NAND_CS , +NAND_BUSWIDTH_16 ,NULL );/* Ensure msecure is mux'd to be able to set the RTC. */ omap_mux_init_signal ("sys_drm_msecure" ,OMAP_PIN_OFF_OUTPUT_HIGH );
arch/arm/mach-omap2/board-omap3touchbook.c +6 -2
@@ -52,6 +52,7 @@#include "mux.h" #include "hsmmc.h" +#include "board-flash.h" #include "common-board-devices.h" #include <asm/setup.h>
@@ -61,6 +62,8 @@#define TB_BL_PWM_TIMER 9#define TB_KILL_POWER_GPIO 168 +#define NAND_CS 0 +static unsigned long touchbook_revision;static struct mtd_partition omap3touchbook_nand_partitions[] = {
@@ -370,8 +373,9 @@ static void __init omap3_touchbook_init(void)omap_ads7846_init (4 ,OMAP3_TS_GPIO ,310 , &ads7846_pdata);usb_musb_init (NULL );usbhs_init (&usbhs_bdata); -omap_nand_flash_init (NAND_BUSWIDTH_16 , omap3touchbook_nand_partitions, -ARRAY_SIZE (omap3touchbook_nand_partitions)); +board_nand_init (omap3touchbook_nand_partitions, +ARRAY_SIZE (omap3touchbook_nand_partitions),NAND_CS , +NAND_BUSWIDTH_16 ,NULL );/* Ensure SDRC pins are mux'd for self-refresh */ omap_mux_init_signal ("sdrc_cke0" ,OMAP_PIN_OUTPUT );
arch/arm/mach-omap2/board-overo.c +5 -2
@@ -57,8 +57,11 @@#include "mux.h" #include "sdram-micron-mt46h32m32lf-6.h" #include "hsmmc.h" +#include "board-flash.h" #include "common-board-devices.h" +#define NAND_CS 0 +#define OVERO_GPIO_BT_XGATE 15#define OVERO_GPIO_W2W_NRESET 16#define OVERO_GPIO_PENDOWN 114
@@ -500,8 +503,8 @@ static void __init overo_init(void)omap_serial_init ();omap_sdrc_init (mt46h32m32lf6_sdrc_params, mt46h32m32lf6_sdrc_params); -omap_nand_flash_init (0 , overo_nand_partitions, -ARRAY_SIZE (overo_nand_partitions)); +board_nand_init (overo_nand_partitions, +ARRAY_SIZE (overo_nand_partitions),NAND_CS ,0 ,NULL );usb_musb_init (NULL );usbhs_init (&usbhs_bdata);overo_spi_init ();
arch/arm/mach-omap2/board-zoom.c +3 -2
@@ -114,8 +114,9 @@ static void __init omap_zoom_init(void)usbhs_init (&usbhs_bdata); } -board_nand_init (zoom_nand_partitions,ARRAY_SIZE (zoom_nand_partitions), -ZOOM_NAND_CS ,NAND_BUSWIDTH_16 ); +board_nand_init (zoom_nand_partitions, +ARRAY_SIZE (zoom_nand_partitions),ZOOM_NAND_CS , +NAND_BUSWIDTH_16 , nand_default_timings);zoom_debugboard_init ();zoom_peripherals_init ();
arch/arm/mach-omap2/common-board-devices.c +0 -46
49 lines not on this page · raw message
arch/arm/mach-omap2/common-board-devices.h +0 -1
@@ -10,6 +10,5 @@ struct ads7846_platform_data;void omap_ads7846_init (int bus_num,int gpio_pendown,int gpio_debounce,struct ads7846_platform_data *board_pdata); -void omap_nand_flash_init (int opts,struct mtd_partition *parts,int n_parts);#endif /* __OMAP_COMMON_BOARD_DEVICES__ */
Signature · 1 line
1.7.10.2
PATCH v4 1/3 ARM: OMAP2+: nand: unify init functions
Quoted 9 lines · Afzal Mohammed
Helper function for updating nand platform data has been added the capability to take timing structure arguement. Usage of
omap_nand_flash_init()has been replaced by modifed one,omap_nand_flash_initwas doing things similar toboard_nand_initexcept that NAND CS# were being acquired based on bootloader setting. As CS# is hardwired for a given board, acquiring gpmc CS# has been removed, and updated with the value on board.
Quoted 7 lines
NAND CS# used in beagle board was found to be CS0. Thomas Weber <[email protected]> reported that value of devkit8000 to be CS0. Overo board was found to be using CS0 based on u-boot, while google grep says omap3touchbook too has CS0.
Signed-off-by Afzal Mohammed <[email protected]>
Looks good.
Cheers
Jon
PATCH v4 1/3 ARM: OMAP2+: nand: unify init functions
Hi Jon,
Quoted 10 lines · Jon
Quoted 9 lines · Afzal Mohammed
Helper function for updating nand platform data has been added the capability to take timing structure arguement. Usage of
omap_nand_flash_init()has been replaced by modifed one,omap_nand_flash_initwas doing things similar toboard_nand_initexcept that NAND CS# were being acquired based on bootloader setting. As CS# is hardwired for a given board, acquiring gpmc CS# has been removed, and updated with the value on board.
Quoted 7 lines
Quoted 5 lines
NAND CS# used in beagle board was found to be CS0. Thomas Weber <[email protected]> reported that value of devkit8000 to be CS0. Overo board was found to be using CS0 based on u-boot, while google grep says omap3touchbook too has CS0.
Reviewed-by Jon Hunter <[email protected]>
Thanks,
Afzal
PATCH v4 2/3 ARM: OMAP2+: gpmc: handle additional timings
In reply to Afzal MohammedConfigure busturnaround, cycle2cycledelay, waitmonitoringtime, clkactivationtime in gpmc_cs_set_timings(). This is done so that boards can configure these parameters of gpmc in Kernel instead of relying on bootloader. Also configure bool type timings like extradelay.
This needed change to two existing users that were configuring clk activation time by directly writing to registers. Thanks to Tony for making me aware of the issue & being kind enough to test this change.
---
v3:
Handle bool type timings too
v2:
Make use of timing api for setting clock activation time, and
remove direct writing to register for clock activation. Peripherals making use of it were tusb6010 & onenand
arch/arm/mach-omap2/gpmc-onenand.c | 3 ++- arch/arm/mach-omap2/gpmc.c | 45 ++++++++++++++++++++++++++++++++ arch/arm/mach-omap2/usb-tusb6010.c | 3 ++- arch/arm/plat-omap/include/plat/gpmc.h | 19 ++++++++++++++ 4 files changed, 68 insertions(+), 2 deletions(-)
arch/arm/mach-omap2/gpmc-onenand.c +2 -1
@@ -329,6 +329,8 @@ static int omap2_onenand_set_sync_mode(struct omap_onenand_platform_data *cfg, t.rd_cycle =gpmc_ticks_to_ns (fclk_offset + (latency +1 ) * div + ticks_cez); + t.clk_activation = fclk_offset_ns; +/* Write */ if (sync_write) { t.adv_wr_off = t.adv_rd_off;
@@ -362,7 +364,6 @@ static int omap2_onenand_set_sync_mode(struct omap_onenand_platform_data *cfg, (sync_read ?GPMC_CONFIG1_READTYPE_SYNC :0 ) | (sync_write ?GPMC_CONFIG1_WRITEMULTIPLE_SUPP :0 ) | (sync_write ?GPMC_CONFIG1_WRITETYPE_SYNC :0 ) | -GPMC_CONFIG1_CLKACTIVATIONTIME (fclk_offset) | GPMC_CONFIG1_PAGE_LEN(2) | (cpu_is_omap34xx() ? 0 : (GPMC_CONFIG1_WAIT_READ_MON |
arch/arm/mach-omap2/gpmc.c +45 -0
69 lines not on this page · raw message
arch/arm/mach-omap2/usb-tusb6010.c +2 -1
@@ -174,6 +174,8 @@ static int tusb_set_sync_mode(unsigned sysclk_ps, unsigned fclk_ps) tmp = t.cs_wr_off *1000 +7000 /* t_scsn_rdy_z */ ; t.wr_cycle =next_clk (t.cs_wr_off, tmp, fclk_ps); + t.clk_activation =gpmc_ticks_to_ns (1 ); +return gpmc_cs_set_timings (sync_cs, &t); }
@@ -283,7 +285,6 @@ tusb6010_setup_interface(struct musb_hdrc_platform_data *data, | GPMC_CONFIG1_READTYPE_SYNC |GPMC_CONFIG1_WRITEMULTIPLE_SUPP |GPMC_CONFIG1_WRITETYPE_SYNC - |GPMC_CONFIG1_CLKACTIVATIONTIME (1 ) |GPMC_CONFIG1_PAGE_LEN (2 ) |GPMC_CONFIG1_WAIT_READ_MON |GPMC_CONFIG1_WAIT_WRITE_MON
arch/arm/plat-omap/include/plat/gpmc.h +19 -0
@@ -96,6 +96,17 @@ enum omap_ecc { OMAP_ECC_BCH8_CODE_HW, /* 8-bit BCH ecc code */ }; +/* bool type time settings */ +struct gpmc_bool_timings { +bool cycle2cyclediffcsen; +bool cycle2cyclesamecsen; +bool we_extra_delay; +bool oe_extra_delay; +bool adv_extra_delay; +bool cs_extra_delay; +bool time_para_granularity; +}; +/* * Note that all values in this struct are in nanoseconds except sync_clk * (which is in picoseconds), while the register values are in gpmc_fck cycles.
@@ -128,9 +139,17 @@ struct gpmc_timings {u16 rd_cycle;/* Total read cycle time */ u16 wr_cycle;/* Total write cycle time */ +u16 bus_turnaround; +u16 cycle2cycle_delay; + +u16 wait_monitoring; +u16 clk_activation; +/* The following are only on OMAP3430 */ u16 wr_access;/* WRACCESSTIME */ u16 wr_data_mux_bus;/* WRDATAONADMUXBUS */ + +struct gpmc_bool_timings bool_timings; };struct gpmc_nand_regs {
Signature · 1 line
1.7.10.2
PATCH v4 3/3 ARM: OMAP2+: onenand: prepare for gpmc driver migration
In reply to Afzal MohammedReorganize gpmc-onenand initialization so that changes required for gpmc driver migration can be made smooth.
Ensuring sync read/write are disabled in onenand cannot be expected to work properly unless GPMC is setup, this has been removed.
Refactor set_async_mode & set_sync_mode functions to separate out timing calculation & actual configuration (GPMC & OneNAND side).
Thanks to Jon for his suggestions.
---
v4:
Reorganize set_sync/async functions in a better way v3:
Refactor set_sync/async functions to separate out timing and
configurations
v2:
Move ensuring that async mode in OneNAND has been setup from
set_sync to setup function, improve commit message
arch/arm/mach-omap2/gpmc-onenand.c | 153 +++++++++++++++++++----------------- 1 file changed, 83 insertions(+), 70 deletions(-)
arch/arm/mach-omap2/gpmc-onenand.c +83 -70
@@ -15,6 +15,7 @@#include <linux/platform_device.h> #include <linux/mtd/onenand_regs.h> #include <linux/io.h> +#include <linux/err.h> #include <asm/mach/flash.h>
@@ -25,6 +26,7 @@#define ONENAND_IO_SIZE SZ_128K +static int hf, vhf, sync_read, sync_write, latency;static struct omap_onenand_platform_data *gpmc_onenand_data;static struct resource gpmc_onenand_resource = {
@@ -38,11 +40,9 @@ static struct platform_device gpmc_onenand_device = { .resource = &gpmc_onenand_resource, }; -static int omap2_onenand_set_async_mode (int cs,void __iomem *onenand_base) +static struct gpmc_timings omap2_onenand_calc_async_timings (void ) {struct gpmc_timings t; -u32 reg; -int err;const int t_cer =15 ;const int t_avdp =12 ;
@@ -55,11 +55,6 @@ static int omap2_onenand_set_async_mode(int cs, void __iomem *onenand_base)const int t_wpl =40 ;const int t_wph =30 ; -/* Ensure sync read and sync write are disabled */ - reg =readw (onenand_base +ONENAND_REG_SYS_CFG1 ); - reg &= ~ONENAND_SYS_CFG1_SYNC_READ & ~ONENAND_SYS_CFG1_SYNC_WRITE ; -writew (reg, onenand_base +ONENAND_REG_SYS_CFG1 ); -memset (&t,0 ,sizeof (t)); t.sync_clk =0 ; t.cs_on =0 ;
@@ -86,25 +81,30 @@ static int omap2_onenand_set_async_mode(int cs, void __iomem *onenand_base) t.cs_wr_off = t.we_off +gpmc_round_ns_to_ticks (t_wph); t.wr_cycle = t.cs_wr_off +gpmc_round_ns_to_ticks (t_cez); +return t; +} + +static int gpmc_set_async_mode (int cs,struct gpmc_timings *t) +{/* Configure GPMC for asynchronous read */ gpmc_cs_write_reg (cs,GPMC_CS_CONFIG1 ,GPMC_CONFIG1_DEVICESIZE_16 |GPMC_CONFIG1_MUXADDDATA ); - err =gpmc_cs_set_timings (cs, &t); -if (err) -return err; +return gpmc_cs_set_timings (cs, t); +} + +static void omap2_onenand_set_async_mode (void __iomem *onenand_base) +{ +u32 reg;/* Ensure sync read and sync write are disabled */ reg =readw (onenand_base +ONENAND_REG_SYS_CFG1 ); reg &= ~ONENAND_SYS_CFG1_SYNC_READ & ~ONENAND_SYS_CFG1_SYNC_WRITE ;writew (reg, onenand_base +ONENAND_REG_SYS_CFG1 ); - -return 0 ; } -static void set_onenand_cfg (void __iomem *onenand_base,int latency, -int sync_read,int sync_write,int hf,int vhf) +static void set_onenand_cfg (void __iomem *onenand_base) {u32 reg;
@@ -172,9 +172,9 @@ static int omap2_onenand_get_freq(struct omap_onenand_platform_data *cfg,return freq; } -static int omap2_onenand_set_sync_mode (struct omap_onenand_platform_data *cfg, -void __iomem *onenand_base, -int *freq_ptr) +static struct gpmc_timings +omap2_onenand_calc_sync_timings (struct omap_onenand_platform_data *cfg, +int freq,bool clk_dep) {struct gpmc_timings t;const int t_cer =15 ;
@@ -184,28 +184,15 @@ static int omap2_onenand_set_sync_mode(struct omap_onenand_platform_data *cfg,const int t_wpl =40 ;const int t_wph =30 ;int min_gpmc_clk_period, t_ces, t_avds, t_avdh, t_ach, t_aavdh, t_rdyo; -int div, fclk_offset_ns, fclk_offset, gpmc_clk_ns, latency; -int first_time =0 , hf =0 , vhf =0 , sync_read =0 , sync_write =0 ; -int err, ticks_cez; -int cs = cfg->cs, freq = *freq_ptr; -u32 reg; -bool clk_dep = false; +int div, fclk_offset_ns, fclk_offset, gpmc_clk_ns; +int ticks_cez; +int cs = cfg->cs;if (cfg->flags &ONENAND_SYNC_READ ) { sync_read =1 ; }else if (cfg->flags &ONENAND_SYNC_READWRITE ) { sync_read =1 ; sync_write =1 ; - }else -return omap2_onenand_set_async_mode (cs, onenand_base); - -if (!freq) { -/* Very first call freq is not known */ - err =omap2_onenand_set_async_mode (cs, onenand_base); -if (err) -return err; - freq =omap2_onenand_get_freq (cfg, onenand_base, &clk_dep); - first_time =1 ; }switch (freq) {
@@ -279,36 +266,16 @@ static int omap2_onenand_set_sync_mode(struct omap_onenand_platform_data *cfg, } } -if (first_time) -set_onenand_cfg (onenand_base, latency, - sync_read, sync_write, hf, vhf); +/* Set synchronous read timings */ +memset (&t,0 ,sizeof (t));if (div ==1 ) { - reg =gpmc_cs_read_reg (cs,GPMC_CS_CONFIG2 ); - reg |= (1 <<7 ); -gpmc_cs_write_reg (cs,GPMC_CS_CONFIG2 , reg); - reg =gpmc_cs_read_reg (cs,GPMC_CS_CONFIG3 ); - reg |= (1 <<7 ); -gpmc_cs_write_reg (cs,GPMC_CS_CONFIG3 , reg); - reg =gpmc_cs_read_reg (cs,GPMC_CS_CONFIG4 ); - reg |= (1 <<7 ); - reg |= (1 <<23 ); -gpmc_cs_write_reg (cs,GPMC_CS_CONFIG4 , reg); - }else { - reg =gpmc_cs_read_reg (cs,GPMC_CS_CONFIG2 ); - reg &= ~(1 <<7 ); -gpmc_cs_write_reg (cs,GPMC_CS_CONFIG2 , reg); - reg =gpmc_cs_read_reg (cs,GPMC_CS_CONFIG3 ); - reg &= ~(1 <<7 ); -gpmc_cs_write_reg (cs,GPMC_CS_CONFIG3 , reg); - reg =gpmc_cs_read_reg (cs,GPMC_CS_CONFIG4 ); - reg &= ~(1 <<7 ); - reg &= ~(1 <<23 ); -gpmc_cs_write_reg (cs,GPMC_CS_CONFIG4 , reg); + t.bool_timings.cs_extra_delay = true; + t.bool_timings.adv_extra_delay = true; + t.bool_timings.oe_extra_delay = true; + t.bool_timings.we_extra_delay = true; } -/* Set synchronous read timings */ -memset (&t,0 ,sizeof (t)); t.sync_clk = min_gpmc_clk_period; t.cs_on =0 ; t.adv_on =0 ;
@@ -357,6 +324,11 @@ static int omap2_onenand_set_sync_mode(struct omap_onenand_platform_data *cfg, } } +return t; +} + +static int gpmc_set_sync_mode (int cs,struct gpmc_timings *t) +{/* Configure GPMC for synchronous read */ gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, GPMC_CONFIG1_WRAPBURST_SUPP |
@@ -372,11 +344,45 @@ static int omap2_onenand_set_sync_mode(struct omap_onenand_platform_data *cfg,GPMC_CONFIG1_DEVICETYPE_NOR | GPMC_CONFIG1_MUXADDDATA); - err =gpmc_cs_set_timings (cs, &t); -if (err) -return err; +return gpmc_cs_set_timings (cs, t); +} + +static int omap2_onenand_setup_async (void __iomem *onenand_base) +{ +struct gpmc_timings t; +int ret; -set_onenand_cfg (onenand_base, latency, sync_read, sync_write, hf, vhf); + t =omap2_onenand_calc_async_timings (); + + ret =gpmc_set_async_mode (gpmc_onenand_data->cs, &t); +if (IS_ERR_VALUE (ret)) +return ret; + +omap2_onenand_set_async_mode (onenand_base); + +return 0 ; +} + +static int omap2_onenand_setup_sync (void __iomem *onenand_base,int *freq_ptr) +{ +int ret, freq = *freq_ptr; +struct gpmc_timings t; +bool clk_dep = false; + +if (!freq) { +/* Very first call freq is not known */ + freq =omap2_onenand_get_freq (gpmc_onenand_data, + onenand_base, &clk_dep); +set_onenand_cfg (onenand_base); + } + + t =omap2_onenand_calc_sync_timings (gpmc_onenand_data, freq, clk_dep); + + ret =gpmc_set_sync_mode (gpmc_onenand_data->cs, &t); +if (IS_ERR_VALUE (ret)) +return ret; + +set_onenand_cfg (onenand_base); *freq_ptr = freq;
@@ -386,15 +392,22 @@ static int omap2_onenand_set_sync_mode(struct omap_onenand_platform_data *cfg,static int gpmc_onenand_setup (void __iomem *onenand_base,int *freq_ptr) {struct device *dev = &gpmc_onenand_device.dev; +unsigned l =ONENAND_SYNC_READ |ONENAND_SYNC_READWRITE ; +int ret; -/* Set sync timings in GPMC */ -if (omap2_onenand_set_sync_mode (gpmc_onenand_data, onenand_base, - freq_ptr) <0 ) { -dev_err (dev,"Unable to set synchronous mode\n" ); -return -EINVAL ; + ret =omap2_onenand_setup_async (onenand_base); +if (ret) { +dev_err (dev,"unable to set to async mode\n" ); +return ret; } -return 0 ; +if (!(gpmc_onenand_data->flags & l)) +return 0 ; + + ret =omap2_onenand_setup_sync (onenand_base, freq_ptr); +if (ret) +dev_err (dev,"unable to set to sync mode\n" ); +return ret; }void __init gpmc_onenand_init (struct omap_onenand_platform_data *_onenand_data)
Signature · 1 line
1.7.10.2
PATCH v4 3/3 ARM: OMAP2+: onenand: prepare for gpmc driver migration
Hi Afzal,
Looks much better!
Quoted 41 lines · Afzal Mohammed
Reorganize gpmc-onenand initialization so that changes required for gpmc driver migration can be made smooth.
Ensuring sync read/write are disabled in onenand cannot be expected to work properly unless GPMC is setup, this has been removed.
Refactor
set_async_mode&set_sync_modefunctions to separate out timing calculation & actual configuration (GPMC & OneNAND side).Thanks to Jon for his suggestions.
Signed-off-by Afzal Mohammed <[email protected]>---
v4:
Reorganize set_sync/async functions in a better way v3:
Refactor set_sync/async functions to separate out timing and
configurations
v2:
Move ensuring that async mode in OneNAND has been setup from
set_syncto setup function, improve commit messagearch/arm/mach-omap2/gpmc-onenand.c | 153 +++++++++++++++++++----------------- 1 file changed, 83 insertions(+), 70 deletions(-)arch/arm/mach-omap2/gpmc-onenand.c +1
-0@@ -15,6 +15,7 @@#include <linux/platform_device.h> #include <linux/mtd/onenand_regs.h> #include <linux/io.h> +#include <linux/err.h> #include <asm/mach/flash.h>
arch/arm/mach-omap2/gpmc-onenand.c line 29
Quoted 4 lines
arch/arm/mach-omap2/gpmc-onenand.c +1
-0@@ -25,6 +26,7 @@#define ONENAND_IO_SIZE SZ_128K +static int hf, vhf, sync_read, sync_write, latency;
I am wondering if we can remove hf, vhf, sync_read/write variables completely. We already have flags from sync_read/write and so we could just use the cfg->flags variable and remove sync_read/write variables.
At the same time, we could create flags for ONENAND_FREQ_HF and ONENAND_FREQ_VHF or something like that. It could be nice to store the latency in onenand_data too. In other words, keep all the configuration in one place.
Otherwise looks good.
Cheers
Jon
PATCH v4 3/3 ARM: OMAP2+: onenand: prepare for gpmc driver migration
Hi Jon,
Quoted 7 lines · Jon
Quoted 1 line · Afzal Mohammed
+static int hf, vhf,
sync_read,sync_write, latency;I am wondering if we can remove hf, vhf, sync_read/write variables completely. We already have flags from sync_read/write and so we could just use the
cfg->flagsvariable and remove sync_read/write variables.
For default frequency, sync_write can get turned off, so flag may or may not be same as sync_write
Quoted 5 lines
At the same time, we could create flags for
ONENAND_FREQ_HFandONENAND_FREQ_VHFor something like that. It could be nice to store the latency inonenand_datatoo. In other words, keep all the configuration in one place.
I have a feeling as though platform data fields should not be altered once platform device is registered (as platform data being specific to the board, thinking further, should they be const?, except for a case where it is created by a common helper function for multiple boards with varying capabilities of peripheral).
Other than sync_read, all others like hf, vhf, latency, sync_write are updated during driver callback, so if we are going to put these in platform private data fields, platform private data fields has to be updated after platform device is registered.
Regards
Afzal
PATCH v4 3/3 ARM: OMAP2+: onenand: prepare for gpmc driver migration
Hi Afzal,
Quoted 5 lines · Afzal
Hi Jon,
Quoted 1 line · Jon
On 06/22/2012 04:01 AM, Afzal Mohammed wrote:
Quoted 8 lines
Quoted 5 lines
Quoted 1 line
+static int hf, vhf,
sync_read,sync_write, latency;I am wondering if we can remove hf, vhf, sync_read/write variables completely. We already have flags from sync_read/write and so we could just use the
cfg->flagsvariable and remove sync_read/write variables.For default frequency,
sync_writecan get turned off, so flag may or may not be same assync_write
Good point. I missed that.
Quoted 12 lines
Quoted 5 lines
At the same time, we could create flags for
ONENAND_FREQ_HFandONENAND_FREQ_VHFor something like that. It could be nice to store the latency inonenand_datatoo. In other words, keep all the configuration in one place.I have a feeling as though platform data fields should not be altered once platform device is registered (as platform data being specific to the board, thinking further, should they be const?, except for a case where it is created by a common helper function for multiple boards with varying capabilities of peripheral).
Quoted 4 lines
Other than
sync_read, all others like hf, vhf, latency,sync_writeare updated during driver callback, so if we are going to put these in platform private data fields, platform private data fields has to be updated after platform device is registered.
May be this is splitting hairs then but I wonder if we should just have a single global variable called onenand_flags for storing the current state of sync_read, sync_write, vhf and hf. At least this would be only one global instead of 4. Not a big deal.
Cheers
Jon
PATCH v4 3/3 ARM: OMAP2+: onenand: prepare for gpmc driver migration
Hi Afzal,
Quoted 36 lines · Jon Hunter
Hi Afzal,
Quoted 5 lines · Afzal
Hi Jon,
Quoted 1 line · Jon
On 06/22/2012 04:01 AM, Afzal Mohammed wrote:
Quoted 8 lines
Quoted 5 lines
Quoted 1 line
+static int hf, vhf,
sync_read,sync_write, latency;I am wondering if we can remove hf, vhf, sync_read/write variables completely. We already have flags from sync_read/write and so we could just use the
cfg->flagsvariable and remove sync_read/write variables.For default frequency,
sync_writecan get turned off, so flag may or may not be same assync_writeGood point. I missed that.
Quoted 12 lines
Quoted 5 lines
At the same time, we could create flags for
ONENAND_FREQ_HFandONENAND_FREQ_VHFor something like that. It could be nice to store the latency inonenand_datatoo. In other words, keep all the configuration in one place.I have a feeling as though platform data fields should not be altered once platform device is registered (as platform data being specific to the board, thinking further, should they be const?, except for a case where it is created by a common helper function for multiple boards with varying capabilities of peripheral).
Quoted 4 lines
Other than
sync_read, all others like hf, vhf, latency,sync_writeare updated during driver callback, so if we are going to put these in platform private data fields, platform private data fields has to be updated after platform device is registered.
Quoted 4 lines
May be this is splitting hairs then but I wonder if we should just have a single global variable called
onenand_flagsfor storing the current state ofsync_read,sync_write, vhf and hf. At least this would be only one global instead of 4. Not a big deal.
Apart from the above minor nit-pick, please add ...
Cheers
Jon
PATCH v4 3/3 ARM: OMAP2+: onenand: prepare for gpmc driver migration
Hi Jon,
Quoted 5 lines · Jon
Quoted 3 lines · Jon Hunter
a single global variable called
onenand_flagsfor storing the current state ofsync_read,sync_write, vhf and hf. At least this would be only one global instead of 4. Not a big deal.
V5 has been posted with above changes
Quoted 1 line
Reviewed-by Jon Hunter <[email protected]>
Thanks
Afzal