1 /* 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 */ 43 static int ulpi_wait(struct ulpi_viewport *ulpi_vp, u32 mask) 44 { 45 int timeout = CONFIG_USB_ULPI_TIMEOUT; 46 47 /* Wait for the bits in mask to become zero. */ 48 while (--timeout) { 49 if ((readl(ulpi_vp->viewport_addr) & mask) == 0) 50 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 */ 63 static int ulpi_wakeup(struct ulpi_viewport *ulpi_vp) 64 { 65 int err; 66 67 if (readl(ulpi_vp->viewport_addr) & ULPI_SS) 68 return 0; /* already awake */ 69 70 writel(ULPI_WU, ulpi_vp->viewport_addr); 71 72 err = ulpi_wait(ulpi_vp, ULPI_WU); 73 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 */ 84 static int ulpi_request(struct ulpi_viewport *ulpi_vp, u32 value) 85 { 86 int err; 87 88 err = ulpi_wakeup(ulpi_vp); 89 if (err) 90 return err; 91 92 writel(value, ulpi_vp->viewport_addr); 93 94 err = ulpi_wait(ulpi_vp, ULPI_RWRUN); 95 if (err) 96 printf("ULPI request timed out\n"); 97 98 return err; 99 } 100 101 int ulpi_write(struct ulpi_viewport *ulpi_vp, u8 *reg, u32 value) 102 { 103 u32 val = ULPI_RWRUN | ULPI_RWCTRL | ((u32)reg << 16) | (value & 0xff); 104 105 val |= (ulpi_vp->port_num & 0x7) << 24; 106 return ulpi_request(ulpi_vp, val); 107 } 108 109 u32 ulpi_read(struct ulpi_viewport *ulpi_vp, u8 *reg) 110 { 111 int err; 112 u32 val = ULPI_RWRUN | ((u32)reg << 16); 113 114 val |= (ulpi_vp->port_num & 0x7) << 24; 115 err = ulpi_request(ulpi_vp, val); 116 if (err) 117 return err; 118 119 return (readl(ulpi_vp->viewport_addr) >> 8) & 0xff; 120 } 121