blob: b4974ed2a6cd8e418235bf37e1cdc5bed3d77351 [file] [log] [blame]
Jana Rapavaf93022c2011-12-05 11:07:00 +02001/*
2 * Copyright (C) 2011 Jana Rapava <fermata7@gmail.com>
3 * Copyright (C) 2011 CompuLab, Ltd. <www.compulab.co.il>
4 *
5 * Authors: Jana Rapava <fermata7@gmail.com>
6 * Igor Grinberg <grinberg@compulab.co.il>
7 *
8 * Based on:
9 * linux/drivers/usb/otg/ulpi_viewport.c
10 *
11 * Original Copyright follow:
12 * Copyright (C) 2011 Google, Inc.
13 *
14 * This software is licensed under the terms of the GNU General Public
15 * License version 2, as published by the Free Software Foundation, and
16 * may be copied, distributed, and modified under those terms.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 */
24
25#include <common.h>
26#include <asm/io.h>
27#include <usb/ulpi.h>
28
29/* ULPI viewport control bits */
30#define ULPI_SS (1 << 27)
31#define ULPI_RWCTRL (1 << 29)
32#define ULPI_RWRUN (1 << 30)
33#define ULPI_WU (1 << 31)
34
35/*
36 * Wait for the ULPI request to complete
37 *
38 * @ulpi_viewport - the address of the viewport
39 * @mask - expected value to wait for
40 *
41 * returns 0 on mask match, ULPI_ERROR on time out.
42 */
Govindraj.R3e6e8092012-02-06 03:55:31 +000043static int ulpi_wait(struct ulpi_viewport *ulpi_vp, u32 mask)
Jana Rapavaf93022c2011-12-05 11:07:00 +020044{
45 int timeout = CONFIG_USB_ULPI_TIMEOUT;
46
47 /* Wait for the bits in mask to become zero. */
48 while (--timeout) {
Govindraj.R3e6e8092012-02-06 03:55:31 +000049 if ((readl(ulpi_vp->viewport_addr) & mask) == 0)
Jana Rapavaf93022c2011-12-05 11:07:00 +020050 return 0;
51
52 udelay(1);
53 }
54
55 return ULPI_ERROR;
56}
57
58/*
59 * Wake the ULPI PHY up for communication
60 *
61 * returns 0 on success.
62 */
Govindraj.R3e6e8092012-02-06 03:55:31 +000063static int ulpi_wakeup(struct ulpi_viewport *ulpi_vp)
Jana Rapavaf93022c2011-12-05 11:07:00 +020064{
65 int err;
66
Govindraj.R3e6e8092012-02-06 03:55:31 +000067 if (readl(ulpi_vp->viewport_addr) & ULPI_SS)
Jana Rapavaf93022c2011-12-05 11:07:00 +020068 return 0; /* already awake */
69
Govindraj.R3e6e8092012-02-06 03:55:31 +000070 writel(ULPI_WU, ulpi_vp->viewport_addr);
Jana Rapavaf93022c2011-12-05 11:07:00 +020071
Govindraj.R3e6e8092012-02-06 03:55:31 +000072 err = ulpi_wait(ulpi_vp, ULPI_WU);
Jana Rapavaf93022c2011-12-05 11:07:00 +020073 if (err)
74 printf("ULPI wakeup timed out\n");
75
76 return err;
77}
78
79/*
80 * Issue a ULPI read/write request
81 *
82 * @value - the ULPI request
83 */
Govindraj.R3e6e8092012-02-06 03:55:31 +000084static int ulpi_request(struct ulpi_viewport *ulpi_vp, u32 value)
Jana Rapavaf93022c2011-12-05 11:07:00 +020085{
86 int err;
87
Govindraj.R3e6e8092012-02-06 03:55:31 +000088 err = ulpi_wakeup(ulpi_vp);
Jana Rapavaf93022c2011-12-05 11:07:00 +020089 if (err)
90 return err;
91
Govindraj.R3e6e8092012-02-06 03:55:31 +000092 writel(value, ulpi_vp->viewport_addr);
Jana Rapavaf93022c2011-12-05 11:07:00 +020093
Govindraj.R3e6e8092012-02-06 03:55:31 +000094 err = ulpi_wait(ulpi_vp, ULPI_RWRUN);
Jana Rapavaf93022c2011-12-05 11:07:00 +020095 if (err)
96 printf("ULPI request timed out\n");
97
98 return err;
99}
100
Govindraj.R3e6e8092012-02-06 03:55:31 +0000101int ulpi_write(struct ulpi_viewport *ulpi_vp, u8 *reg, u32 value)
Jana Rapavaf93022c2011-12-05 11:07:00 +0200102{
103 u32 val = ULPI_RWRUN | ULPI_RWCTRL | ((u32)reg << 16) | (value & 0xff);
104
Govindraj.R3e6e8092012-02-06 03:55:31 +0000105 val |= (ulpi_vp->port_num & 0x7) << 24;
106 return ulpi_request(ulpi_vp, val);
Jana Rapavaf93022c2011-12-05 11:07:00 +0200107}
108
Govindraj.R3e6e8092012-02-06 03:55:31 +0000109u32 ulpi_read(struct ulpi_viewport *ulpi_vp, u8 *reg)
Jana Rapavaf93022c2011-12-05 11:07:00 +0200110{
Igor Grinberg42561012011-12-12 12:08:33 +0200111 int err;
Jana Rapavaf93022c2011-12-05 11:07:00 +0200112 u32 val = ULPI_RWRUN | ((u32)reg << 16);
113
Govindraj.R3e6e8092012-02-06 03:55:31 +0000114 val |= (ulpi_vp->port_num & 0x7) << 24;
115 err = ulpi_request(ulpi_vp, val);
Jana Rapavaf93022c2011-12-05 11:07:00 +0200116 if (err)
117 return err;
118
Govindraj.R3e6e8092012-02-06 03:55:31 +0000119 return (readl(ulpi_vp->viewport_addr) >> 8) & 0xff;
Jana Rapavaf93022c2011-12-05 11:07:00 +0200120}