ARM: rockchip: rk3228: implement function rk3228_restart
[firefly-linux-kernel-4.4.55.git] / arch / arm / mach-omap2 / gpmc-smc91x.c
1 /*
2  * linux/arch/arm/mach-omap2/gpmc-smc91x.c
3  *
4  * Copyright (C) 2009 Nokia Corporation
5  * Contact:     Tony Lindgren
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License version 2 as
9  * published by the Free Software Foundation.
10  */
11
12 #include <linux/kernel.h>
13 #include <linux/platform_device.h>
14 #include <linux/gpio.h>
15 #include <linux/delay.h>
16 #include <linux/interrupt.h>
17 #include <linux/io.h>
18 #include <linux/smc91x.h>
19
20 #include "gpmc.h"
21 #include "gpmc-smc91x.h"
22
23 #include "soc.h"
24
25 static struct omap_smc91x_platform_data *gpmc_cfg;
26
27 static struct resource gpmc_smc91x_resources[] = {
28         [0] = {
29                 .flags          = IORESOURCE_MEM,
30         },
31         [1] = {
32                 .flags          = IORESOURCE_IRQ,
33         },
34 };
35
36 static struct smc91x_platdata gpmc_smc91x_info = {
37         .flags  = SMC91X_USE_16BIT | SMC91X_NOWAIT | SMC91X_IO_SHIFT_0,
38         .leda   = RPC_LED_100_10,
39         .ledb   = RPC_LED_TX_RX,
40 };
41
42 static struct platform_device gpmc_smc91x_device = {
43         .name           = "smc91x",
44         .id             = -1,
45         .dev            = {
46                 .platform_data = &gpmc_smc91x_info,
47         },
48         .num_resources  = ARRAY_SIZE(gpmc_smc91x_resources),
49         .resource       = gpmc_smc91x_resources,
50 };
51
52 static struct gpmc_settings smc91x_settings = {
53         .device_width = GPMC_DEVWIDTH_16BIT,
54 };
55
56 /*
57  * Set the gpmc timings for smc91c96. The timings are taken
58  * from the data sheet available at:
59  * http://www.smsc.com/main/catalog/lan91c96.html
60  * REVISIT: Level shifters can add at least to the access latency.
61  */
62 static int smc91c96_gpmc_retime(void)
63 {
64         struct gpmc_timings t;
65         struct gpmc_device_timings dev_t;
66         const int t3 = 10;      /* Figure 12.2 read and 12.4 write */
67         const int t4_r = 20;    /* Figure 12.2 read */
68         const int t4_w = 5;     /* Figure 12.4 write */
69         const int t5 = 25;      /* Figure 12.2 read */
70         const int t6 = 15;      /* Figure 12.2 read */
71         const int t7 = 5;       /* Figure 12.4 write */
72         const int t8 = 5;       /* Figure 12.4 write */
73         const int t20 = 185;    /* Figure 12.2 read and 12.4 write */
74
75         /*
76          * FIXME: Calculate the address and data bus muxed timings.
77          * Note that at least adv_rd_off needs to be changed according
78          * to omap3430 TRM Figure 11-11. Are the sdp boards using the
79          * FPGA in between smc91x and omap as the timings are different
80          * from above?
81          */
82         if (gpmc_cfg->flags & GPMC_MUX_ADD_DATA)
83                 return 0;
84
85         memset(&dev_t, 0, sizeof(dev_t));
86
87         dev_t.t_oeasu = t3 * 1000;
88         dev_t.t_oe = t5 * 1000;
89         dev_t.t_cez_r = t4_r * 1000;
90         dev_t.t_oez = t6 * 1000;
91         dev_t.t_rd_cycle = (t20 - t3) * 1000;
92
93         dev_t.t_weasu = t3 * 1000;
94         dev_t.t_wpl = t7 * 1000;
95         dev_t.t_wph = t8 * 1000;
96         dev_t.t_cez_w = t4_w * 1000;
97         dev_t.t_wr_cycle = (t20 - t3) * 1000;
98
99         gpmc_calc_timings(&t, &smc91x_settings, &dev_t);
100
101         return gpmc_cs_set_timings(gpmc_cfg->cs, &t);
102 }
103
104 /*
105  * Initialize smc91x device connected to the GPMC. Note that we
106  * assume that pin multiplexing is done in the board-*.c file,
107  * or in the bootloader.
108  */
109 void __init gpmc_smc91x_init(struct omap_smc91x_platform_data *board_data)
110 {
111         unsigned long cs_mem_base;
112         int ret;
113
114         gpmc_cfg = board_data;
115
116         if (gpmc_cfg->flags & GPMC_TIMINGS_SMC91C96)
117                 gpmc_cfg->retime = smc91c96_gpmc_retime;
118
119         if (gpmc_cs_request(gpmc_cfg->cs, SZ_16M, &cs_mem_base) < 0) {
120                 printk(KERN_ERR "Failed to request GPMC mem for smc91x\n");
121                 return;
122         }
123
124         gpmc_smc91x_resources[0].start = cs_mem_base + 0x300;
125         gpmc_smc91x_resources[0].end = cs_mem_base + 0x30f;
126         gpmc_smc91x_resources[1].flags |= (gpmc_cfg->flags & IRQF_TRIGGER_MASK);
127
128         if (gpmc_cfg->flags & GPMC_MUX_ADD_DATA)
129                 smc91x_settings.mux_add_data = GPMC_MUX_AD;
130         if (gpmc_cfg->flags & GPMC_READ_MON)
131                 smc91x_settings.wait_on_read = true;
132         if (gpmc_cfg->flags & GPMC_WRITE_MON)
133                 smc91x_settings.wait_on_write = true;
134         if (gpmc_cfg->wait_pin)
135                 smc91x_settings.wait_pin = gpmc_cfg->wait_pin;
136         ret = gpmc_cs_program_settings(gpmc_cfg->cs, &smc91x_settings);
137         if (ret < 0)
138                 goto free1;
139
140         if (gpmc_cfg->retime) {
141                 ret = gpmc_cfg->retime();
142                 if (ret != 0)
143                         goto free1;
144         }
145
146         if (gpio_request_one(gpmc_cfg->gpio_irq, GPIOF_IN, "SMC91X irq") < 0)
147                 goto free1;
148
149         gpmc_smc91x_resources[1].start = gpio_to_irq(gpmc_cfg->gpio_irq);
150
151         if (gpmc_cfg->gpio_pwrdwn) {
152                 ret = gpio_request_one(gpmc_cfg->gpio_pwrdwn,
153                                        GPIOF_OUT_INIT_LOW, "SMC91X powerdown");
154                 if (ret)
155                         goto free2;
156         }
157
158         if (gpmc_cfg->gpio_reset) {
159                 ret = gpio_request_one(gpmc_cfg->gpio_reset,
160                                        GPIOF_OUT_INIT_LOW, "SMC91X reset");
161                 if (ret)
162                         goto free3;
163
164                 gpio_set_value(gpmc_cfg->gpio_reset, 1);
165                 msleep(100);
166                 gpio_set_value(gpmc_cfg->gpio_reset, 0);
167         }
168
169         if (platform_device_register(&gpmc_smc91x_device) < 0) {
170                 printk(KERN_ERR "Unable to register smc91x device\n");
171                 gpio_free(gpmc_cfg->gpio_reset);
172                 goto free3;
173         }
174
175         return;
176
177 free3:
178         if (gpmc_cfg->gpio_pwrdwn)
179                 gpio_free(gpmc_cfg->gpio_pwrdwn);
180 free2:
181         gpio_free(gpmc_cfg->gpio_irq);
182 free1:
183         gpmc_cs_free(gpmc_cfg->cs);
184
185         printk(KERN_ERR "Could not initialize smc91x\n");
186 }