usb: musb: ux500: move channel number knowledge into the driver
[firefly-linux-kernel-4.4.55.git] / arch / arm / mach-ux500 / usb.c
1 /*
2  * Copyright (C) ST-Ericsson SA 2011
3  *
4  * Author: Mian Yousaf Kaukab <mian.yousaf.kaukab@stericsson.com>
5  * License terms: GNU General Public License (GPL) version 2
6  */
7 #include <linux/platform_device.h>
8 #include <linux/usb/musb.h>
9 #include <linux/dma-mapping.h>
10 #include <linux/platform_data/usb-musb-ux500.h>
11 #include <linux/platform_data/dma-ste-dma40.h>
12
13 #include "db8500-regs.h"
14
15 #define MUSB_DMA40_RX_CH { \
16                 .mode = STEDMA40_MODE_LOGICAL, \
17                 .dir = STEDMA40_PERIPH_TO_MEM, \
18         }
19
20 #define MUSB_DMA40_TX_CH { \
21                 .mode = STEDMA40_MODE_LOGICAL, \
22                 .dir = STEDMA40_MEM_TO_PERIPH, \
23         }
24
25 static struct stedma40_chan_cfg musb_dma_rx_ch[UX500_MUSB_DMA_NUM_RX_TX_CHANNELS]
26         = {
27         MUSB_DMA40_RX_CH,
28         MUSB_DMA40_RX_CH,
29         MUSB_DMA40_RX_CH,
30         MUSB_DMA40_RX_CH,
31         MUSB_DMA40_RX_CH,
32         MUSB_DMA40_RX_CH,
33         MUSB_DMA40_RX_CH,
34         MUSB_DMA40_RX_CH
35 };
36
37 static struct stedma40_chan_cfg musb_dma_tx_ch[UX500_MUSB_DMA_NUM_RX_TX_CHANNELS]
38         = {
39         MUSB_DMA40_TX_CH,
40         MUSB_DMA40_TX_CH,
41         MUSB_DMA40_TX_CH,
42         MUSB_DMA40_TX_CH,
43         MUSB_DMA40_TX_CH,
44         MUSB_DMA40_TX_CH,
45         MUSB_DMA40_TX_CH,
46         MUSB_DMA40_TX_CH,
47 };
48
49 static void *ux500_dma_rx_param_array[UX500_MUSB_DMA_NUM_RX_TX_CHANNELS] = {
50         &musb_dma_rx_ch[0],
51         &musb_dma_rx_ch[1],
52         &musb_dma_rx_ch[2],
53         &musb_dma_rx_ch[3],
54         &musb_dma_rx_ch[4],
55         &musb_dma_rx_ch[5],
56         &musb_dma_rx_ch[6],
57         &musb_dma_rx_ch[7]
58 };
59
60 static void *ux500_dma_tx_param_array[UX500_MUSB_DMA_NUM_RX_TX_CHANNELS] = {
61         &musb_dma_tx_ch[0],
62         &musb_dma_tx_ch[1],
63         &musb_dma_tx_ch[2],
64         &musb_dma_tx_ch[3],
65         &musb_dma_tx_ch[4],
66         &musb_dma_tx_ch[5],
67         &musb_dma_tx_ch[6],
68         &musb_dma_tx_ch[7]
69 };
70
71 static struct ux500_musb_board_data musb_board_data = {
72         .dma_rx_param_array = ux500_dma_rx_param_array,
73         .dma_tx_param_array = ux500_dma_tx_param_array,
74         .dma_filter = stedma40_filter,
75 };
76
77 static u64 ux500_musb_dmamask = DMA_BIT_MASK(32);
78
79 static struct musb_hdrc_config musb_hdrc_config = {
80         .multipoint     = true,
81         .dyn_fifo       = true,
82         .num_eps        = 16,
83         .ram_bits       = 16,
84 };
85
86 static struct musb_hdrc_platform_data musb_platform_data = {
87         .mode = MUSB_OTG,
88         .config = &musb_hdrc_config,
89         .board_data = &musb_board_data,
90 };
91
92 static struct resource usb_resources[] = {
93         [0] = {
94                 .name   = "usb-mem",
95                 .flags  =  IORESOURCE_MEM,
96         },
97
98         [1] = {
99                 .name   = "mc", /* hard-coded in musb */
100                 .flags  = IORESOURCE_IRQ,
101         },
102 };
103
104 struct platform_device ux500_musb_device = {
105         .name = "musb-ux500",
106         .id = 0,
107         .dev = {
108                 .platform_data = &musb_platform_data,
109                 .dma_mask = &ux500_musb_dmamask,
110                 .coherent_dma_mask = DMA_BIT_MASK(32),
111         },
112         .num_resources = ARRAY_SIZE(usb_resources),
113         .resource = usb_resources,
114 };
115
116 static inline void ux500_usb_dma_update_rx_ch_config(int *dev_type)
117 {
118         u32 idx;
119
120         for (idx = 0; idx < UX500_MUSB_DMA_NUM_RX_TX_CHANNELS; idx++)
121                 musb_dma_rx_ch[idx].dev_type = dev_type[idx];
122 }
123
124 static inline void ux500_usb_dma_update_tx_ch_config(int *dev_type)
125 {
126         u32 idx;
127
128         for (idx = 0; idx < UX500_MUSB_DMA_NUM_RX_TX_CHANNELS; idx++)
129                 musb_dma_tx_ch[idx].dev_type = dev_type[idx];
130 }
131
132 void ux500_add_usb(struct device *parent, resource_size_t base, int irq,
133                    int *dma_rx_cfg, int *dma_tx_cfg)
134 {
135         ux500_musb_device.resource[0].start = base;
136         ux500_musb_device.resource[0].end = base + SZ_64K - 1;
137         ux500_musb_device.resource[1].start = irq;
138         ux500_musb_device.resource[1].end = irq;
139
140         ux500_usb_dma_update_rx_ch_config(dma_rx_cfg);
141         ux500_usb_dma_update_tx_ch_config(dma_tx_cfg);
142
143         ux500_musb_device.dev.parent = parent;
144
145         platform_device_register(&ux500_musb_device);
146 }