Linux Audio

Check our new training course

Loading...
Note: File does not exist in v6.8.
  1#include <linux/delay.h>
  2#include <linux/timer.h>
  3#include <linux/io.h>
  4#include <linux/errno.h>
  5
  6#include <mach/cputype.h>
  7
  8#ifdef CONFIG_ARCH_MMP
  9
 10#define UTMI_REVISION		0x0
 11#define UTMI_CTRL		0x4
 12#define UTMI_PLL		0x8
 13#define UTMI_TX			0xc
 14#define UTMI_RX			0x10
 15#define UTMI_IVREF		0x14
 16#define UTMI_T0			0x18
 17#define UTMI_T1			0x1c
 18#define UTMI_T2			0x20
 19#define UTMI_T3			0x24
 20#define UTMI_T4			0x28
 21#define UTMI_T5			0x2c
 22#define UTMI_RESERVE		0x30
 23#define UTMI_USB_INT		0x34
 24#define UTMI_DBG_CTL		0x38
 25#define UTMI_OTG_ADDON		0x3c
 26
 27/* For UTMICTRL Register */
 28#define UTMI_CTRL_USB_CLK_EN			(1 << 31)
 29/* pxa168 */
 30#define UTMI_CTRL_SUSPEND_SET1			(1 << 30)
 31#define UTMI_CTRL_SUSPEND_SET2			(1 << 29)
 32#define UTMI_CTRL_RXBUF_PDWN			(1 << 24)
 33#define UTMI_CTRL_TXBUF_PDWN			(1 << 11)
 34
 35#define UTMI_CTRL_INPKT_DELAY_SHIFT		30
 36#define UTMI_CTRL_INPKT_DELAY_SOF_SHIFT		28
 37#define UTMI_CTRL_PU_REF_SHIFT			20
 38#define UTMI_CTRL_ARC_PULLDN_SHIFT		12
 39#define UTMI_CTRL_PLL_PWR_UP_SHIFT		1
 40#define UTMI_CTRL_PWR_UP_SHIFT			0
 41/* For UTMI_PLL Register */
 42#define UTMI_PLL_CLK_BLK_EN_SHIFT		24
 43#define UTMI_PLL_FBDIV_SHIFT			4
 44#define UTMI_PLL_REFDIV_SHIFT			0
 45#define UTMI_PLL_FBDIV_MASK			0x00000FF0
 46#define UTMI_PLL_REFDIV_MASK			0x0000000F
 47#define UTMI_PLL_ICP_MASK			0x00007000
 48#define UTMI_PLL_KVCO_MASK			0x00031000
 49#define UTMI_PLL_PLLCALI12_SHIFT		29
 50#define UTMI_PLL_PLLCALI12_MASK			(0x3 << 29)
 51#define UTMI_PLL_PLLVDD18_SHIFT			27
 52#define UTMI_PLL_PLLVDD18_MASK			(0x3 << 27)
 53#define UTMI_PLL_PLLVDD12_SHIFT			25
 54#define UTMI_PLL_PLLVDD12_MASK			(0x3 << 25)
 55#define UTMI_PLL_KVCO_SHIFT			15
 56#define UTMI_PLL_ICP_SHIFT			12
 57/* For UTMI_TX Register */
 58#define UTMI_TX_REG_EXT_FS_RCAL_SHIFT		27
 59#define UTMI_TX_REG_EXT_FS_RCAL_MASK		(0xf << 27)
 60#define UTMI_TX_REG_EXT_FS_RCAL_EN_MASK		26
 61#define UTMI_TX_REG_EXT_FS_RCAL_EN		(0x1 << 26)
 62#define UTMI_TX_LOW_VDD_EN_SHIFT		11
 63#define UTMI_TX_IMPCAL_VTH_SHIFT		14
 64#define UTMI_TX_IMPCAL_VTH_MASK			(0x7 << 14)
 65#define UTMI_TX_CK60_PHSEL_SHIFT		17
 66#define UTMI_TX_CK60_PHSEL_MASK			(0xf << 17)
 67#define UTMI_TX_TXVDD12_SHIFT                   22
 68#define UTMI_TX_TXVDD12_MASK			(0x3 << 22)
 69#define UTMI_TX_AMP_SHIFT			0
 70#define UTMI_TX_AMP_MASK			(0x7 << 0)
 71/* For UTMI_RX Register */
 72#define UTMI_RX_SQ_THRESH_SHIFT			4
 73#define UTMI_RX_SQ_THRESH_MASK			(0xf << 4)
 74#define UTMI_REG_SQ_LENGTH_SHIFT		15
 75#define UTMI_REG_SQ_LENGTH_MASK			(0x3 << 15)
 76
 77#define REG_RCAL_START				0x00001000
 78#define VCOCAL_START				0x00200000
 79#define KVCO_EXT				0x00400000
 80#define PLL_READY				0x00800000
 81#define CLK_BLK_EN				0x01000000
 82#endif
 83
 84static unsigned int u2o_read(unsigned int base, unsigned int offset)
 85{
 86	return readl(base + offset);
 87}
 88
 89static void u2o_set(unsigned int base, unsigned int offset, unsigned int value)
 90{
 91	unsigned int reg;
 92
 93	reg = readl(base + offset);
 94	reg |= value;
 95	writel(reg, base + offset);
 96	readl(base + offset);
 97}
 98
 99static void u2o_clear(unsigned int base, unsigned int offset,
100	unsigned int value)
101{
102	unsigned int reg;
103
104	reg = readl(base + offset);
105	reg &= ~value;
106	writel(reg, base + offset);
107	readl(base + offset);
108}
109
110static void u2o_write(unsigned int base, unsigned int offset,
111	unsigned int value)
112{
113	writel(value, base + offset);
114	readl(base + offset);
115}
116
117#ifdef CONFIG_ARCH_MMP
118int mv_udc_phy_init(unsigned int base)
119{
120	unsigned long timeout;
121
122	/* Initialize the USB PHY power */
123	if (cpu_is_pxa910()) {
124		u2o_set(base, UTMI_CTRL, (1 << UTMI_CTRL_INPKT_DELAY_SOF_SHIFT)
125			| (1 << UTMI_CTRL_PU_REF_SHIFT));
126	}
127
128	u2o_set(base, UTMI_CTRL, 1 << UTMI_CTRL_PLL_PWR_UP_SHIFT);
129	u2o_set(base, UTMI_CTRL, 1 << UTMI_CTRL_PWR_UP_SHIFT);
130
131	/* UTMI_PLL settings */
132	u2o_clear(base, UTMI_PLL, UTMI_PLL_PLLVDD18_MASK
133		| UTMI_PLL_PLLVDD12_MASK | UTMI_PLL_PLLCALI12_MASK
134		| UTMI_PLL_FBDIV_MASK | UTMI_PLL_REFDIV_MASK
135		| UTMI_PLL_ICP_MASK | UTMI_PLL_KVCO_MASK);
136
137	u2o_set(base, UTMI_PLL, (0xee << UTMI_PLL_FBDIV_SHIFT)
138		| (0xb << UTMI_PLL_REFDIV_SHIFT)
139		| (3 << UTMI_PLL_PLLVDD18_SHIFT)
140		| (3 << UTMI_PLL_PLLVDD12_SHIFT)
141		| (3 << UTMI_PLL_PLLCALI12_SHIFT)
142		| (1 << UTMI_PLL_ICP_SHIFT) | (3 << UTMI_PLL_KVCO_SHIFT));
143
144	/* UTMI_TX */
145	u2o_clear(base, UTMI_TX, UTMI_TX_REG_EXT_FS_RCAL_EN_MASK
146		| UTMI_TX_TXVDD12_MASK
147		| UTMI_TX_CK60_PHSEL_MASK | UTMI_TX_IMPCAL_VTH_MASK
148		| UTMI_TX_REG_EXT_FS_RCAL_MASK | UTMI_TX_AMP_MASK);
149	u2o_set(base, UTMI_TX, (3 << UTMI_TX_TXVDD12_SHIFT)
150		| (4 << UTMI_TX_CK60_PHSEL_SHIFT)
151		| (4 << UTMI_TX_IMPCAL_VTH_SHIFT)
152		| (8 << UTMI_TX_REG_EXT_FS_RCAL_SHIFT)
153		| (3 << UTMI_TX_AMP_SHIFT));
154
155	/* UTMI_RX */
156	u2o_clear(base, UTMI_RX, UTMI_RX_SQ_THRESH_MASK
157		| UTMI_REG_SQ_LENGTH_MASK);
158	if (cpu_is_pxa168())
159		u2o_set(base, UTMI_RX, (7 << UTMI_RX_SQ_THRESH_SHIFT)
160			| (2 << UTMI_REG_SQ_LENGTH_SHIFT));
161	else
162		u2o_set(base, UTMI_RX, (0x7 << UTMI_RX_SQ_THRESH_SHIFT)
163			| (2 << UTMI_REG_SQ_LENGTH_SHIFT));
164
165	/* UTMI_IVREF */
166	if (cpu_is_pxa168())
167		/*
168		 * fixing Microsoft Altair board interface with NEC hub issue -
169		 * Set UTMI_IVREF from 0x4a3 to 0x4bf
170		 */
171		u2o_write(base, UTMI_IVREF, 0x4bf);
172
173	/* calibrate */
174	timeout = jiffies + 100;
175	while ((u2o_read(base, UTMI_PLL) & PLL_READY) == 0) {
176		if (time_after(jiffies, timeout))
177			return -ETIME;
178		cpu_relax();
179	}
180
181	/* toggle VCOCAL_START bit of UTMI_PLL */
182	udelay(200);
183	u2o_set(base, UTMI_PLL, VCOCAL_START);
184	udelay(40);
185	u2o_clear(base, UTMI_PLL, VCOCAL_START);
186
187	/* toggle REG_RCAL_START bit of UTMI_TX */
188	udelay(200);
189	u2o_set(base, UTMI_TX, REG_RCAL_START);
190	udelay(40);
191	u2o_clear(base, UTMI_TX, REG_RCAL_START);
192	udelay(200);
193
194	/* make sure phy is ready */
195	timeout = jiffies + 100;
196	while ((u2o_read(base, UTMI_PLL) & PLL_READY) == 0) {
197		if (time_after(jiffies, timeout))
198			return -ETIME;
199		cpu_relax();
200	}
201
202	if (cpu_is_pxa168()) {
203		u2o_set(base, UTMI_RESERVE, 1 << 5);
204		/* Turn on UTMI PHY OTG extension */
205		u2o_write(base, UTMI_OTG_ADDON, 1);
206	}
207	return 0;
208}
209#else
210int mv_udc_phy_init(unsigned int base)
211{
212	return 0;
213}
214#endif