2 * board-mapphone-emu_uart.c
4 * Copyright (C) 2009 Motorola, Inc.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 /* Date Author Comment
22 * =========== ============== ==============================================
23 * Jun-26-2009 Motorola Initial revision.
26 #include <linux/kernel.h>
27 #include <linux/init.h>
28 #include <linux/interrupt.h>
29 #include <linux/module.h>
30 #include <linux/device.h>
31 #include <linux/delay.h>
32 #include <linux/dma-mapping.h>
33 #include <linux/platform_device.h>
34 #include <linux/err.h>
35 #include <linux/clk.h>
38 #include <linux/spi/spi.h>
39 #include <plat/system.h>
40 #include <linux/irq.h>
43 #include <plat/clock.h>
44 #include <plat/board-mapphone-emu_uart.h>
45 #include <plat/hardware.h>
46 #include <plat/omap34xx.h>
49 * Register definitions for CPCAP related SPI register
51 #define OMAP2_MCSPI_MAX_FREQ 48000000
53 #define OMAP2_MCSPI_REVISION 0x00
54 #define OMAP2_MCSPI_SYSCONFIG 0x10
55 #define OMAP2_MCSPI_SYSSTATUS 0x14
56 #define OMAP2_MCSPI_IRQSTATUS 0x18
57 #define OMAP2_MCSPI_IRQENABLE 0x1c
58 #define OMAP2_MCSPI_WAKEUPENABLE 0x20
59 #define OMAP2_MCSPI_SYST 0x24
60 #define OMAP2_MCSPI_MODULCTRL 0x28
62 /* per-channel banks, 0x14 bytes each, first is: */
63 #define OMAP2_MCSPI_CHCONF0 0x2c
64 #define OMAP2_MCSPI_CHSTAT0 0x30
65 #define OMAP2_MCSPI_CHCTRL0 0x34
66 #define OMAP2_MCSPI_TX0 0x38
67 #define OMAP2_MCSPI_RX0 0x3c
69 /* per-register bitmasks: */
71 #define OMAP2_MCSPI_SYSCONFIG_AUTOIDLE (1 << 0)
72 #define OMAP2_MCSPI_SYSCONFIG_SOFTRESET (1 << 1)
73 #define OMAP2_AFTR_RST_SET_MASTER (0 << 2)
75 #define OMAP2_MCSPI_SYSSTATUS_RESETDONE (1 << 0)
76 #define OMAP2_MCSPI_SYS_CON_LVL_1 1
77 #define OMAP2_MCSPI_SYS_CON_LVL_2 2
79 #define OMAP2_MCSPI_MODULCTRL_SINGLE (1 << 0)
80 #define OMAP2_MCSPI_MODULCTRL_MS (1 << 2)
81 #define OMAP2_MCSPI_MODULCTRL_STEST (1 << 3)
83 #define OMAP2_MCSPI_CHCONF_PHA (1 << 0)
84 #define OMAP2_MCSPI_CHCONF_POL (1 << 1)
85 #define OMAP2_MCSPI_CHCONF_CLKD_MASK (0x0f << 2)
86 #define OMAP2_MCSPI_CHCONF_EPOL (1 << 6)
87 #define OMAP2_MCSPI_CHCONF_WL_MASK (0x1f << 7)
88 #define OMAP2_MCSPI_CHCONF_TRM_RX_ONLY (0x01 << 12)
89 #define OMAP2_MCSPI_CHCONF_TRM_TX_ONLY (0x02 << 12)
90 #define OMAP2_MCSPI_CHCONF_TRM_MASK (0x03 << 12)
91 #define OMAP2_MCSPI_CHCONF_TRM_TXRX (~OMAP2_MCSPI_CHCONF_TRM_MASK)
92 #define OMAP2_MCSPI_CHCONF_DMAW (1 << 14)
93 #define OMAP2_MCSPI_CHCONF_DMAR (1 << 15)
94 #define OMAP2_MCSPI_CHCONF_DPE0 (1 << 16)
95 #define OMAP2_MCSPI_CHCONF_DPE1 (1 << 17)
96 #define OMAP2_MCSPI_CHCONF_IS (1 << 18)
97 #define OMAP2_MCSPI_CHCONF_TURBO (1 << 19)
98 #define OMAP2_MCSPI_CHCONF_FORCE (1 << 20)
99 #define OMAP2_MCSPI_CHCONF_TCS0 (1 << 25)
100 #define OMAP2_MCSPI_CHCONF_TCS1 (1 << 26)
101 #define OMAP2_MCSPI_CHCONF_TCS_MASK (0x03 << 25)
103 #define OMAP2_MCSPI_SYSCFG_WKUP (1 << 2)
104 #define OMAP2_MCSPI_SYSCFG_IDL (2 << 3)
105 #define OMAP2_MCSPI_SYSCFG_CLK (2 << 8)
106 #define OMAP2_MCSPI_WAKEUP_EN (1 << 1)
107 #define OMAP2_MCSPI_IRQ_WKS (1 << 16)
108 #define OMAP2_MCSPI_CHSTAT_RXS (1 << 0)
109 #define OMAP2_MCSPI_CHSTAT_TXS (1 << 1)
110 #define OMAP2_MCSPI_CHSTAT_EOT (1 << 2)
112 #define OMAP2_MCSPI_CHCTRL_EN (1 << 0)
113 #define OMAP2_MCSPI_MODE_IS_MASTER 0
114 #define OMAP2_MCSPI_MODE_IS_SLAVE 1
115 #define OMAP_MCSPI_WAKEUP_ENABLE 1
117 /*mcspi base address: (0x48098000)1st SPI, (0x4809A00) 2nd SPI*/
118 #define OMAP_MCSPI_BASE 0x48098000
121 #define CLOCK_DIV 12 /* 2^(12)=4096 48000000/4096<19200 */
125 #define WRITE_CPCAP 1
128 #define CM_ICLKEN1_CORE 0x48004A10
129 #define CM_FCLKEN1_CORE 0x48004A00
130 #define OMAP2_MCSPI_EN_MCSPI1 (1 << 18)
133 #define RAW_MOD_REG_BIT(val, mask, set) do { \
148 static bool emu_uart_is_active
= FALSE
;
150 /* Although SPI driver is provided through linux system as implemented above,
151 * it can not cover some special situation.
153 * During Debug phase, OMAP may need to acess CPCAP by SPI
154 * to configure or check related register when boot up is not finished.
155 * However, at this time, spi driver integrated in linux system may not
156 * be initialized properly.
158 * So we provode the following SPI driver with common API for access capcap
159 * by SPI directly, i.e. we will skip the linux system driver,
160 * but access SPI hardware directly to configure read/write specially for
163 * So developer should be very careful to use these APIs:
165 * read_cpcap_register_raw()
166 * write_cpcap_register_raw()
168 * Pay attention: Only use them when boot up phase.
169 * Rasons are as follows:
170 * 1. Although we provide protection on these two APIs for concurrency and
171 * race conditions, it may impact the performance of system
172 * because it will mask all interrupts during access.
173 * 2. Calling these APIs will reset all SPI registers, and may make previous
174 * data lost during run time.
176 * So, if developer wants to access CPCAP after boot up is finished,
177 * we suggest they should use poweric interface.
180 static inline void raw_writel_reg(u32 value
, u32 reg
)
182 unsigned int absolute_reg
= (u32
)OMAP_MCSPI_BASE
+ reg
;
183 #if defined(LOCAL_DEVELOPER_DEBUG)
184 printk(KERN_ERR
" raw write reg =0x%x value=0x%x \n", absolute_reg
,
187 omap_writel(value
, absolute_reg
);
190 static inline u32
raw_readl_reg(u32 reg
)
193 unsigned int absolute_reg
= (u32
)OMAP_MCSPI_BASE
+ reg
;
194 result
= omap_readl(absolute_reg
);
195 #if defined(LOCAL_DEVELOPER_DEBUG)
196 printk(KERN_ERR
" raw read reg =0x%x result =0x%x \n",
197 absolute_reg
, result
);
202 static void raw_omap_mcspi_wakeup_enable(int level
)
206 /* configure SYSCONFIG register... */
207 if (level
== LEVEL1
) {
208 result
= raw_readl_reg(OMAP2_MCSPI_SYSCONFIG
);
210 result
| OMAP2_MCSPI_SYSCFG_WKUP
|
211 OMAP2_MCSPI_SYSCFG_IDL
| OMAP2_MCSPI_SYSCFG_CLK
|
212 OMAP2_MCSPI_SYSCONFIG_AUTOIDLE
;
213 raw_writel_reg(result
, OMAP2_MCSPI_SYSCONFIG
);
216 if (level
== LEVEL2
) {
217 result
= raw_readl_reg(OMAP2_MCSPI_SYSCONFIG
);
219 result
| OMAP2_MCSPI_SYSCFG_WKUP
|
220 OMAP2_MCSPI_SYSCFG_IDL
|
221 OMAP2_MCSPI_SYSCONFIG_AUTOIDLE
;
222 RAW_MOD_REG_BIT(result
, OMAP2_MCSPI_SYSCFG_CLK
, 0);
223 raw_writel_reg(result
, OMAP2_MCSPI_SYSCONFIG
);
226 /* configure wakeupenable register... */
227 raw_writel_reg(OMAP2_MCSPI_WAKEUP_EN
, OMAP2_MCSPI_WAKEUPENABLE
);
229 /* configure enable interrupt register... */
230 result
= raw_readl_reg(OMAP2_MCSPI_IRQENABLE
);
231 result
= result
| OMAP2_MCSPI_IRQ_WKS
;
232 raw_writel_reg(result
, OMAP2_MCSPI_IRQENABLE
);
235 static void raw_omap2_mcspi_set_master_mode(void)
239 /* configure MCSPI_MODULCTRL register... */
240 result
= raw_readl_reg(OMAP2_MCSPI_MODULCTRL
);
242 RAW_MOD_REG_BIT(result
, OMAP2_MCSPI_MODULCTRL_STEST
, 0);
243 RAW_MOD_REG_BIT(result
, OMAP2_MCSPI_MODULCTRL_MS
,
244 OMAP2_MCSPI_MODE_IS_MASTER
);
245 RAW_MOD_REG_BIT(result
, OMAP2_MCSPI_MODULCTRL_SINGLE
, 1);
247 raw_writel_reg(result
, OMAP2_MCSPI_MODULCTRL
);
250 static void raw_omap2_mcspi_channel_config(void)
254 /* select channel 0... otherwise 0x14*channel_num */
255 result
= raw_readl_reg(OMAP2_MCSPI_CHCONF0
);
257 /* TCS Chip select Timing(2.5 clock cycles) */
258 result
&= ~(OMAP2_MCSPI_CHCONF_TCS_MASK
);
259 result
|= OMAP2_MCSPI_CHCONF_TCS1
;
261 /* configure master mode... */
262 result
&= ~OMAP2_MCSPI_CHCONF_IS
;
263 result
&= ~OMAP2_MCSPI_CHCONF_DPE1
;
264 result
|= OMAP2_MCSPI_CHCONF_DPE0
;
266 /* configure wordlength */
267 result
&= ~OMAP2_MCSPI_CHCONF_WL_MASK
;
268 result
|= (WORD_LEN
- 1) << 7;
270 /* configure active high */
271 result
&= ~OMAP2_MCSPI_CHCONF_EPOL
;
273 /* set clock divisor */
274 result
&= ~OMAP2_MCSPI_CHCONF_CLKD_MASK
;
275 result
|= CLOCK_DIV
<< 2;
277 /* configure mode polarity=0 phase=0 */
278 result
&= ~OMAP2_MCSPI_CHCONF_POL
;
279 result
&= ~OMAP2_MCSPI_CHCONF_PHA
;
281 raw_writel_reg(result
, OMAP2_MCSPI_CHCONF0
);
285 static void raw_mcspi_setup(void)
287 raw_omap_mcspi_wakeup_enable(LEVEL1
);
288 raw_omap2_mcspi_set_master_mode();
289 raw_omap2_mcspi_channel_config();
290 raw_omap_mcspi_wakeup_enable(LEVEL2
);
293 static int raw_mcspi_reset(void)
295 unsigned long timeout
;
298 raw_omap_mcspi_wakeup_enable(LEVEL1
);
300 raw_writel_reg(OMAP2_MCSPI_SYSCONFIG_SOFTRESET
,
301 OMAP2_MCSPI_SYSCONFIG
);
303 timeout
= jiffies
+ msecs_to_jiffies(1000);
306 tmp
= raw_readl_reg(OMAP2_MCSPI_SYSSTATUS
);
307 if (time_after(jiffies
, timeout
)) {
308 printk(KERN_ERR
"SPI Error: Reset is time out!\n");
311 } while (!(tmp
& OMAP2_MCSPI_SYSSTATUS_RESETDONE
));
313 /*configure all modules in reset master mode */
314 raw_writel_reg(OMAP2_AFTR_RST_SET_MASTER
, OMAP2_MCSPI_MODULCTRL
);
316 /* call wakeup function to set sysconfig as per pm activity */
317 raw_omap_mcspi_wakeup_enable(LEVEL1
);
318 raw_omap_mcspi_wakeup_enable(LEVEL2
);
323 static void raw_omap2_mcspi_force_cs(int enable_tag
)
326 result
= raw_readl_reg(OMAP2_MCSPI_CHCONF0
);
328 * Manual spim_csx assertion to keep spim_csx for channel x active
329 * RW 0x0 between SPI words (single channel master mode only).
331 RAW_MOD_REG_BIT(result
, OMAP2_MCSPI_CHCONF_FORCE
, enable_tag
);
332 raw_writel_reg(result
, OMAP2_MCSPI_CHCONF0
);
335 static void raw_omap2_mcspi_set_enable(int enable
)
339 result
= enable
? OMAP2_MCSPI_CHCTRL_EN
: 0;
340 raw_writel_reg(result
, OMAP2_MCSPI_CHCTRL0
);
344 static int raw_mcspi_wait_for_reg_bit(unsigned long reg
, unsigned long bit
)
346 unsigned long timeout
;
348 timeout
= jiffies
+ msecs_to_jiffies(1000);
350 while (!(raw_readl_reg(reg
) & bit
)) {
351 if (time_after(jiffies
, timeout
))
358 static void parser_cpcap(struct cpcap_dev
*dev
)
360 if (dev
->access_flag
== WRITE_CPCAP
) {
361 tx
[3] = ((dev
->address
>> 6) & 0x000000FF) | 0x80;
362 tx
[2] = (dev
->address
<< 2) & 0x000000FF;
363 tx
[1] = (dev
->value
>> 8) & 0x000000FF;
364 tx
[0] = dev
->value
& 0x000000FF;
366 tx
[3] = ((dev
->address
>> 6) & 0x000000FF);
367 tx
[2] = (dev
->address
<< 2) & 0x000000FF;
373 static void raw_omap2_mcspi_txrx_pio(struct cpcap_dev
*dev
)
378 /* config tranmission mode --- tx rx together */
379 result
= raw_readl_reg(OMAP2_MCSPI_CHCONF0
);
380 result
&= ~OMAP2_MCSPI_CHCONF_TRM_MASK
;
381 raw_writel_reg(result
, OMAP2_MCSPI_CHCONF0
);
383 /* enable the mcspi port! */
384 raw_omap2_mcspi_set_enable(1);
388 memcpy((void *)&tx_32bit
, (void *)tx
, 4);
390 if (raw_mcspi_wait_for_reg_bit(OMAP2_MCSPI_CHSTAT0
,
391 OMAP2_MCSPI_CHSTAT_TXS
) < 0) {
392 printk(KERN_ERR
"SPI Error: TXS timed out\n");
395 raw_writel_reg(tx_32bit
, OMAP2_MCSPI_TX0
);
397 if (raw_mcspi_wait_for_reg_bit(OMAP2_MCSPI_CHSTAT0
,
398 OMAP2_MCSPI_CHSTAT_RXS
) < 0) {
399 printk(KERN_ERR
"SPI Error: RXS timed out\n");
403 result
= raw_readl_reg(OMAP2_MCSPI_RX0
);
405 dev
->result
= result
;
408 /* disable the mcspi port! */
409 raw_omap2_mcspi_set_enable(0);
412 static void raw_mcspi_run(struct cpcap_dev
*dev
)
414 raw_omap_mcspi_wakeup_enable(LEVEL1
);
415 raw_omap2_mcspi_set_master_mode();
416 raw_omap2_mcspi_channel_config();
417 raw_omap2_mcspi_force_cs(1);
418 raw_omap2_mcspi_txrx_pio(dev
);
419 raw_omap2_mcspi_force_cs(0);
420 raw_omap_mcspi_wakeup_enable(LEVEL2
);
423 static void raw_omap_mcspi_enable_IFclock(void)
427 result
= omap_readl(CM_FCLKEN1_CORE
);
428 RAW_MOD_REG_BIT(result
, OMAP2_MCSPI_EN_MCSPI1
, 1);
429 omap_writel(result
, CM_FCLKEN1_CORE
);
431 result
= omap_readl(CM_ICLKEN1_CORE
);
432 RAW_MOD_REG_BIT(result
, OMAP2_MCSPI_EN_MCSPI1
, 1);
433 omap_writel(result
, CM_ICLKEN1_CORE
);
438 * write_cpcap_register_raw is for cpcap spi write directly
439 * @return 0 on success; less than zero on failure.
441 static int write_cpcap_register_raw(u16 addr
, u16 val
)
444 unsigned long intr_flags
;
445 struct cpcap_dev cpcap_write
;
447 #ifdef CONFIG_EMU_UART_DEBUG
448 if (is_emu_uart_active() && (addr
== 897 || addr
== 411))
452 local_irq_save(intr_flags
);
453 raw_omap_mcspi_enable_IFclock();
455 result
= raw_mcspi_reset();
457 local_irq_restore(intr_flags
);
458 printk(KERN_ERR
"reset failed !\n");
464 cpcap_write
.address
= addr
;
465 cpcap_write
.value
= val
;
466 cpcap_write
.access_flag
= WRITE_CPCAP
;
467 raw_mcspi_run(&cpcap_write
);
469 local_irq_restore(intr_flags
);
475 * read_cpcap_register_raw is for cpcap spi read directly,
476 * read result is in val
477 * @return 0 on success; less than zero on failure.
479 static int read_cpcap_register_raw(u16 addr
, u16
*val
)
482 unsigned long intr_flag
;
483 struct cpcap_dev cpcap_read
;
485 local_irq_save(intr_flag
);
486 raw_omap_mcspi_enable_IFclock();
488 result
= raw_mcspi_reset();
490 local_irq_restore(intr_flag
);
491 printk(KERN_ERR
"reset failed !\n");
497 cpcap_read
.address
= addr
;
498 cpcap_read
.access_flag
= READ_CPCAP
;
499 raw_mcspi_run(&cpcap_read
);
500 *val
= cpcap_read
.result
;
502 local_irq_restore(intr_flag
);
508 * Check if the writting is allowed. If MiniUSB port has already been
509 * configured as UART3, we should ignore some SCM register writting.
511 int is_emu_uart_iomux_reg(unsigned short offset
)
513 if ((emu_uart_is_active
) && \
514 ((offset
>= 0x1A2 && offset
< 0x1BA) || (offset
== 0x19E)))
520 bool is_emu_uart_active(void)
522 return emu_uart_is_active
;
525 static void write_omap_mux_register(u16 offset
, u8 mode
, u8 input_en
)
527 u16 tmp_val
, reg_val
;
528 u32 reg
= OMAP343X_CTRL_BASE
+ offset
;
530 reg_val
= mode
| (input_en
<< 8);
531 tmp_val
= omap_readw(reg
) & ~(0x0007 | (1 << 8));
532 reg_val
= reg_val
| tmp_val
;
533 omap_writew(reg_val
, reg
);
536 void activate_emu_uart(void)
541 read_cpcap_register_raw(18, &tmp
);
542 printk(KERN_ALERT
"Reading CPCAP vendor_version: 0x%04X\n", tmp
);
545 * Configure OMAP SCM to set all ULPI pin of USB OTG to SAFE MODE
547 for (i
= 0; i
< 0x18; i
+= 2)
548 write_omap_mux_register(0x1A2 + i
, 7, 0);
552 * Configure CPCAP to route UART3 to USB port; Switch VBUSIN to supply
553 * UART/USB transeiver and set VBUS standby mode 3
555 write_cpcap_register_raw(897, 0x0101);
556 write_cpcap_register_raw(411, 0x014C);
559 * Configure OMAP SCM to set ULPI port as UART3 function
562 * Set UART3 RX pin in safe mode
564 write_omap_mux_register(0x19E, 7, 0);
566 * Route UART3 TX to ULPIDATA0, RX to ULPIDATA1
568 write_omap_mux_register(0x1AA, 2, 0);
569 write_omap_mux_register(0x1AC, 2, 1);
571 emu_uart_is_active
= TRUE
;
573 (KERN_ALERT
"WARNING: MiniUSB port works in UART3 mode,"
574 "the USB functionality UNAVAILABLE!\n");