Merge branch 'master' of github.com:christinaa/rpi-open-firmware
[rpi-open-firmware.git] / drivers / BCM2708UsbPhy.cc
1 /*
2 * VideoCore4_Drivers
3 * Copyright (c) 2017 Authors of rpi-open-firmware
4 *
5 * USB PHY initialization driver.
6 */
7
8 #include <drivers/IODevice.hpp>
9 #include <drivers/BCM2708PowerManagement.hpp>
10
11 #define FLAG_BUSY (1 << 31)
12
13 struct BCM2708UsbPhy : IODevice {
14 IODriverConstructor(BCM2708UsbPhy);
15
16 void wait() {
17 while(USB_GMDIOCSR & FLAG_BUSY);
18 }
19
20 void write_bare(int reg, uint16_t value, int type) {
21 reg &= 0x1F;
22
23 /* precede MDIO access */
24 USB_GMDIOGEN = 0xFFFFFFFF;
25 wait();
26
27 /* write the actual value, with flags */
28 USB_GMDIOGEN = type | (reg << 18) | value;
29 wait();
30
31 /* dummy write due to errata; see BCM2835 peripheral manual */
32 USB_GMDIOGEN = 0;
33 wait();
34 }
35
36 uint16_t usb_read(int reg) {
37 write_bare(reg, 0, 0x60020000);
38 return USB_MDIO_CSR & 0x3FF;
39 }
40
41 virtual void usb_write(int reg, uint16_t value) {
42 IODriverLog("Writing 0x%X to reg 0x%X", value, reg);
43 write_bare(reg, value, 0x50020000);
44 }
45
46 virtual void start() override {
47 IODriverLog("starting ...");
48
49 USB_GMDIOCSR = (1 << 18);
50
51 usb_write(0x15, 4369/*cond ? 4569 : 272*/);
52 usb_write(0x19, 0x4);
53 usb_write(0x18, 0x10);
54 usb_write(0x1D, 0x4);
55 usb_write(0x17, 5682);
56
57 while(!usb_read(0x1B) & 0x7);
58
59 usb_write(0x1E, 0x01);
60
61 usb_write(0x1D, 0x5000);
62 usb_write(0x19, 0xC004);
63 usb_write(0x32, 0x1C2F);
64 usb_write(34, 256);
65 usb_write(36, 0x10);
66 usb_write(0x19, 0x04);
67
68 IODriverLog("started");
69
70 IODevice::start();
71 }
72
73 virtual void init() override {
74 setName("BCM2708UsbPhy");
75 setTag('USBP');
76 }
77 };
78
79 IODriverCreateSingletonInstance(BCM2708UsbPhy);
80
This page took 0.078522 seconds and 5 git commands to generate.