Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * linux/arch/arm/mach-omap2/usb-tusb6010.c
0004  *
0005  * Copyright (C) 2006 Nokia Corporation
0006  */
0007 
0008 #include <linux/err.h>
0009 #include <linux/string.h>
0010 #include <linux/types.h>
0011 #include <linux/errno.h>
0012 #include <linux/delay.h>
0013 #include <linux/platform_device.h>
0014 #include <linux/gpio.h>
0015 #include <linux/export.h>
0016 #include <linux/platform_data/usb-omap.h>
0017 
0018 #include <linux/usb/musb.h>
0019 
0020 #include "gpmc.h"
0021 
0022 static u8       async_cs, sync_cs;
0023 static unsigned     refclk_psec;
0024 
0025 static struct gpmc_settings tusb_async = {
0026     .wait_on_read   = true,
0027     .wait_on_write  = true,
0028     .device_width   = GPMC_DEVWIDTH_16BIT,
0029     .mux_add_data   = GPMC_MUX_AD,
0030 };
0031 
0032 static struct gpmc_settings tusb_sync = {
0033     .burst_read = true,
0034     .burst_write    = true,
0035     .sync_read  = true,
0036     .sync_write = true,
0037     .wait_on_read   = true,
0038     .wait_on_write  = true,
0039     .burst_len  = GPMC_BURST_16,
0040     .device_width   = GPMC_DEVWIDTH_16BIT,
0041     .mux_add_data   = GPMC_MUX_AD,
0042 };
0043 
0044 /* NOTE:  timings are from tusb 6010 datasheet Rev 1.8, 12-Sept 2006 */
0045 
0046 static int tusb_set_async_mode(unsigned sysclk_ps)
0047 {
0048     struct gpmc_device_timings dev_t;
0049     struct gpmc_timings t;
0050     unsigned        t_acsnh_advnh = sysclk_ps + 3000;
0051 
0052     memset(&dev_t, 0, sizeof(dev_t));
0053 
0054     dev_t.t_ceasu = 8 * 1000;
0055     dev_t.t_avdasu = t_acsnh_advnh - 7000;
0056     dev_t.t_ce_avd = 1000;
0057     dev_t.t_avdp_r = t_acsnh_advnh;
0058     dev_t.t_oeasu = t_acsnh_advnh + 1000;
0059     dev_t.t_oe = 300;
0060     dev_t.t_cez_r = 7000;
0061     dev_t.t_cez_w = dev_t.t_cez_r;
0062     dev_t.t_avdp_w = t_acsnh_advnh;
0063     dev_t.t_weasu = t_acsnh_advnh + 1000;
0064     dev_t.t_wpl = 300;
0065     dev_t.cyc_aavdh_we = 1;
0066 
0067     gpmc_calc_timings(&t, &tusb_async, &dev_t);
0068 
0069     return gpmc_cs_set_timings(async_cs, &t, &tusb_async);
0070 }
0071 
0072 static int tusb_set_sync_mode(unsigned sysclk_ps)
0073 {
0074     struct gpmc_device_timings dev_t;
0075     struct gpmc_timings t;
0076     unsigned        t_scsnh_advnh = sysclk_ps + 3000;
0077 
0078     memset(&dev_t, 0, sizeof(dev_t));
0079 
0080     dev_t.clk = 11100;
0081     dev_t.t_bacc = 1000;
0082     dev_t.t_ces = 1000;
0083     dev_t.t_ceasu = 8 * 1000;
0084     dev_t.t_avdasu = t_scsnh_advnh - 7000;
0085     dev_t.t_ce_avd = 1000;
0086     dev_t.t_avdp_r = t_scsnh_advnh;
0087     dev_t.cyc_aavdh_oe = 3;
0088     dev_t.cyc_oe = 5;
0089     dev_t.t_ce_rdyz = 7000;
0090     dev_t.t_avdp_w = t_scsnh_advnh;
0091     dev_t.cyc_aavdh_we = 3;
0092     dev_t.cyc_wpl = 6;
0093 
0094     gpmc_calc_timings(&t, &tusb_sync, &dev_t);
0095 
0096     return gpmc_cs_set_timings(sync_cs, &t, &tusb_sync);
0097 }
0098 
0099 /* tusb driver calls this when it changes the chip's clocking */
0100 int tusb6010_platform_retime(unsigned is_refclk)
0101 {
0102     static const char   error[] =
0103         KERN_ERR "tusb6010 %s retime error %d\n";
0104 
0105     unsigned    sysclk_ps;
0106     int     status;
0107 
0108     if (!refclk_psec)
0109         return -ENODEV;
0110 
0111     sysclk_ps = is_refclk ? refclk_psec : TUSB6010_OSCCLK_60;
0112 
0113     status = tusb_set_async_mode(sysclk_ps);
0114     if (status < 0) {
0115         printk(error, "async", status);
0116         goto done;
0117     }
0118     status = tusb_set_sync_mode(sysclk_ps);
0119     if (status < 0)
0120         printk(error, "sync", status);
0121 done:
0122     return status;
0123 }
0124 EXPORT_SYMBOL_GPL(tusb6010_platform_retime);
0125 
0126 static struct resource tusb_resources[] = {
0127     /* Order is significant!  The start/end fields
0128      * are updated during setup..
0129      */
0130     { /* Asynchronous access */
0131         .flags  = IORESOURCE_MEM,
0132     },
0133     { /* Synchronous access */
0134         .flags  = IORESOURCE_MEM,
0135     },
0136     { /* IRQ */
0137         .name   = "mc",
0138         .flags  = IORESOURCE_IRQ,
0139     },
0140 };
0141 
0142 static u64 tusb_dmamask = ~(u32)0;
0143 
0144 static struct platform_device tusb_device = {
0145     .name       = "musb-tusb",
0146     .id     = -1,
0147     .dev = {
0148         .dma_mask       = &tusb_dmamask,
0149         .coherent_dma_mask  = 0xffffffff,
0150     },
0151     .num_resources  = ARRAY_SIZE(tusb_resources),
0152     .resource   = tusb_resources,
0153 };
0154 
0155 
0156 /* this may be called only from board-*.c setup code */
0157 int __init
0158 tusb6010_setup_interface(struct musb_hdrc_platform_data *data,
0159         unsigned ps_refclk, unsigned waitpin,
0160         unsigned async, unsigned sync,
0161         unsigned irq, unsigned dmachan)
0162 {
0163     int     status;
0164     static char error[] __initdata =
0165         KERN_ERR "tusb6010 init error %d, %d\n";
0166 
0167     /* ASYNC region, primarily for PIO */
0168     status = gpmc_cs_request(async, SZ_16M, (unsigned long *)
0169                 &tusb_resources[0].start);
0170     if (status < 0) {
0171         printk(error, 1, status);
0172         return status;
0173     }
0174     tusb_resources[0].end = tusb_resources[0].start + 0x9ff;
0175     tusb_async.wait_pin = waitpin;
0176     async_cs = async;
0177 
0178     status = gpmc_cs_program_settings(async_cs, &tusb_async);
0179     if (status < 0)
0180         return status;
0181 
0182     /* SYNC region, primarily for DMA */
0183     status = gpmc_cs_request(sync, SZ_16M, (unsigned long *)
0184                 &tusb_resources[1].start);
0185     if (status < 0) {
0186         printk(error, 2, status);
0187         return status;
0188     }
0189     tusb_resources[1].end = tusb_resources[1].start + 0x9ff;
0190     tusb_sync.wait_pin = waitpin;
0191     sync_cs = sync;
0192 
0193     status = gpmc_cs_program_settings(sync_cs, &tusb_sync);
0194     if (status < 0)
0195         return status;
0196 
0197     /* IRQ */
0198     status = gpio_request_one(irq, GPIOF_IN, "TUSB6010 irq");
0199     if (status < 0) {
0200         printk(error, 3, status);
0201         return status;
0202     }
0203     tusb_resources[2].start = gpio_to_irq(irq);
0204 
0205     /* set up memory timings ... can speed them up later */
0206     if (!ps_refclk) {
0207         printk(error, 4, status);
0208         return -ENODEV;
0209     }
0210     refclk_psec = ps_refclk;
0211     status = tusb6010_platform_retime(1);
0212     if (status < 0) {
0213         printk(error, 5, status);
0214         return status;
0215     }
0216 
0217     /* finish device setup ... */
0218     if (!data) {
0219         printk(error, 6, status);
0220         return -ENODEV;
0221     }
0222     tusb_device.dev.platform_data = data;
0223 
0224     /* so far so good ... register the device */
0225     status = platform_device_register(&tusb_device);
0226     if (status < 0) {
0227         printk(error, 7, status);
0228         return status;
0229     }
0230     return 0;
0231 }