* [PATCH 0/3] Ubiquiti EdgeRouter/EdgeRouter Pro support
@ 2014-05-29 10:10 ` Alex Smith
0 siblings, 0 replies; 21+ messages in thread
From: Alex Smith @ 2014-05-29 10:10 UTC (permalink / raw)
To: linux-mips; +Cc: David Daney, Alex Smith
This patch series adds support for the Ubiquiti EdgeRouter and
EdgeRouter Pro (ER-8 and ERPro-8).
The first 2 patches enable the Ethernet interfaces on the boards to be
detected correctly. The 3rd patch enables the {E,O}HCI controllers by
probing them via DT rather than registering them in platform code,
which was only done for CN63XX and therefore would not be done on the
EdgeRouters (CN61XX).
Alex Smith (1):
MIPS: octeon: Add interface mode detection for Octeon II
David Daney (2):
staging: octeon-ethernet: Move PHY activation to .ndo_open().
usb host/MIPS: Remove hard-coded OCTEON platform information.
.../cavium-octeon/executive/cvmx-helper-sgmii.c | 12 +-
arch/mips/cavium-octeon/executive/cvmx-helper.c | 166 +++++++++++++++++++++
arch/mips/cavium-octeon/octeon-platform.c | 102 -------------
drivers/staging/octeon/ethernet-mdio.c | 79 +++++++---
drivers/staging/octeon/ethernet-rgmii.c | 23 ++-
drivers/staging/octeon/ethernet-sgmii.c | 87 ++++++-----
drivers/staging/octeon/ethernet-xaui.c | 83 +++++++----
drivers/staging/octeon/ethernet.c | 2 +-
drivers/staging/octeon/octeon-ethernet.h | 4 +
drivers/usb/host/ehci-octeon.c | 17 ++-
drivers/usb/host/octeon2-common.c | 47 +++++-
drivers/usb/host/ohci-octeon.c | 17 ++-
12 files changed, 424 insertions(+), 215 deletions(-)
--
1.9.3
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 0/3] Ubiquiti EdgeRouter/EdgeRouter Pro support
@ 2014-05-29 10:10 ` Alex Smith
0 siblings, 0 replies; 21+ messages in thread
From: Alex Smith @ 2014-05-29 10:10 UTC (permalink / raw)
To: linux-mips; +Cc: David Daney, Alex Smith
This patch series adds support for the Ubiquiti EdgeRouter and
EdgeRouter Pro (ER-8 and ERPro-8).
The first 2 patches enable the Ethernet interfaces on the boards to be
detected correctly. The 3rd patch enables the {E,O}HCI controllers by
probing them via DT rather than registering them in platform code,
which was only done for CN63XX and therefore would not be done on the
EdgeRouters (CN61XX).
Alex Smith (1):
MIPS: octeon: Add interface mode detection for Octeon II
David Daney (2):
staging: octeon-ethernet: Move PHY activation to .ndo_open().
usb host/MIPS: Remove hard-coded OCTEON platform information.
.../cavium-octeon/executive/cvmx-helper-sgmii.c | 12 +-
arch/mips/cavium-octeon/executive/cvmx-helper.c | 166 +++++++++++++++++++++
arch/mips/cavium-octeon/octeon-platform.c | 102 -------------
drivers/staging/octeon/ethernet-mdio.c | 79 +++++++---
drivers/staging/octeon/ethernet-rgmii.c | 23 ++-
drivers/staging/octeon/ethernet-sgmii.c | 87 ++++++-----
drivers/staging/octeon/ethernet-xaui.c | 83 +++++++----
drivers/staging/octeon/ethernet.c | 2 +-
drivers/staging/octeon/octeon-ethernet.h | 4 +
drivers/usb/host/ehci-octeon.c | 17 ++-
drivers/usb/host/octeon2-common.c | 47 +++++-
drivers/usb/host/ohci-octeon.c | 17 ++-
12 files changed, 424 insertions(+), 215 deletions(-)
--
1.9.3
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 1/3] MIPS: octeon: Add interface mode detection for Octeon II
@ 2014-05-29 10:10 ` Alex Smith
0 siblings, 0 replies; 21+ messages in thread
From: Alex Smith @ 2014-05-29 10:10 UTC (permalink / raw)
To: linux-mips; +Cc: David Daney, Alex Smith
Add interface mode detection for Octeon II. This is necessary to detect
the interface modes correctly on the UBNT E200 board. Code is taken
from the UBNT GPL source release, with some alterations: SRIO, ILK and
RXAUI interface modes are removed and instead return disabled as these
modes are not currently supported.
Tested-by: David Daney <david.daney@cavium.com>
Signed-off-by: Alex Smith <alex.smith@imgtec.com>
---
arch/mips/cavium-octeon/executive/cvmx-helper.c | 166 ++++++++++++++++++++++++
1 file changed, 166 insertions(+)
diff --git a/arch/mips/cavium-octeon/executive/cvmx-helper.c b/arch/mips/cavium-octeon/executive/cvmx-helper.c
index 8553ad5..7e5cf7a 100644
--- a/arch/mips/cavium-octeon/executive/cvmx-helper.c
+++ b/arch/mips/cavium-octeon/executive/cvmx-helper.c
@@ -106,6 +106,158 @@ int cvmx_helper_ports_on_interface(int interface)
EXPORT_SYMBOL_GPL(cvmx_helper_ports_on_interface);
/**
+ * @INTERNAL
+ * Return interface mode for CN68xx.
+ */
+static cvmx_helper_interface_mode_t __cvmx_get_mode_cn68xx(int interface)
+{
+ union cvmx_mio_qlmx_cfg qlm_cfg;
+ switch (interface) {
+ case 0:
+ qlm_cfg.u64 = cvmx_read_csr(CVMX_MIO_QLMX_CFG(0));
+ /* QLM is disabled when QLM SPD is 15. */
+ if (qlm_cfg.s.qlm_spd == 15)
+ return CVMX_HELPER_INTERFACE_MODE_DISABLED;
+
+ if (qlm_cfg.s.qlm_cfg == 2)
+ return CVMX_HELPER_INTERFACE_MODE_SGMII;
+ else if (qlm_cfg.s.qlm_cfg == 3)
+ return CVMX_HELPER_INTERFACE_MODE_XAUI;
+ else
+ return CVMX_HELPER_INTERFACE_MODE_DISABLED;
+ case 2:
+ case 3:
+ case 4:
+ qlm_cfg.u64 = cvmx_read_csr(CVMX_MIO_QLMX_CFG(interface));
+ /* QLM is disabled when QLM SPD is 15. */
+ if (qlm_cfg.s.qlm_spd == 15)
+ return CVMX_HELPER_INTERFACE_MODE_DISABLED;
+
+ if (qlm_cfg.s.qlm_cfg == 2)
+ return CVMX_HELPER_INTERFACE_MODE_SGMII;
+ else if (qlm_cfg.s.qlm_cfg == 3)
+ return CVMX_HELPER_INTERFACE_MODE_XAUI;
+ else
+ return CVMX_HELPER_INTERFACE_MODE_DISABLED;
+ case 7:
+ qlm_cfg.u64 = cvmx_read_csr(CVMX_MIO_QLMX_CFG(3));
+ /* QLM is disabled when QLM SPD is 15. */
+ if (qlm_cfg.s.qlm_spd == 15) {
+ return CVMX_HELPER_INTERFACE_MODE_DISABLED;
+ } else if (qlm_cfg.s.qlm_cfg != 0) {
+ qlm_cfg.u64 = cvmx_read_csr(CVMX_MIO_QLMX_CFG(1));
+ if (qlm_cfg.s.qlm_cfg != 0)
+ return CVMX_HELPER_INTERFACE_MODE_DISABLED;
+ }
+ return CVMX_HELPER_INTERFACE_MODE_NPI;
+ case 8:
+ return CVMX_HELPER_INTERFACE_MODE_LOOP;
+ default:
+ return CVMX_HELPER_INTERFACE_MODE_DISABLED;
+ }
+}
+
+/**
+ * @INTERNAL
+ * Return interface mode for an Octeon II
+ */
+static cvmx_helper_interface_mode_t __cvmx_get_mode_octeon2(int interface)
+{
+ union cvmx_gmxx_inf_mode mode;
+
+ if (OCTEON_IS_MODEL(OCTEON_CN68XX))
+ return __cvmx_get_mode_cn68xx(interface);
+
+ if (interface == 2)
+ return CVMX_HELPER_INTERFACE_MODE_NPI;
+
+ if (interface == 3)
+ return CVMX_HELPER_INTERFACE_MODE_LOOP;
+
+ /* Only present in CN63XX & CN66XX Octeon model */
+ if ((OCTEON_IS_MODEL(OCTEON_CN63XX) &&
+ (interface == 4 || interface == 5)) ||
+ (OCTEON_IS_MODEL(OCTEON_CN66XX) &&
+ interface >= 4 && interface <= 7)) {
+ return CVMX_HELPER_INTERFACE_MODE_DISABLED;
+ }
+
+ if (OCTEON_IS_MODEL(OCTEON_CN66XX)) {
+ union cvmx_mio_qlmx_cfg mio_qlm_cfg;
+
+ /* QLM2 is SGMII0 and QLM1 is SGMII1 */
+ if (interface == 0)
+ mio_qlm_cfg.u64 = cvmx_read_csr(CVMX_MIO_QLMX_CFG(2));
+ else if (interface == 1)
+ mio_qlm_cfg.u64 = cvmx_read_csr(CVMX_MIO_QLMX_CFG(1));
+ else
+ return CVMX_HELPER_INTERFACE_MODE_DISABLED;
+
+ if (mio_qlm_cfg.s.qlm_spd == 15)
+ return CVMX_HELPER_INTERFACE_MODE_DISABLED;
+
+ if (mio_qlm_cfg.s.qlm_cfg == 9)
+ return CVMX_HELPER_INTERFACE_MODE_SGMII;
+ else if (mio_qlm_cfg.s.qlm_cfg == 11)
+ return CVMX_HELPER_INTERFACE_MODE_XAUI;
+ else
+ return CVMX_HELPER_INTERFACE_MODE_DISABLED;
+ } else if (OCTEON_IS_MODEL(OCTEON_CN61XX)) {
+ union cvmx_mio_qlmx_cfg qlm_cfg;
+
+ if (interface == 0) {
+ qlm_cfg.u64 = cvmx_read_csr(CVMX_MIO_QLMX_CFG(2));
+ if (qlm_cfg.s.qlm_cfg == 2)
+ return CVMX_HELPER_INTERFACE_MODE_SGMII;
+ else if (qlm_cfg.s.qlm_cfg == 3)
+ return CVMX_HELPER_INTERFACE_MODE_XAUI;
+ else
+ return CVMX_HELPER_INTERFACE_MODE_DISABLED;
+ } else if (interface == 1) {
+ qlm_cfg.u64 = cvmx_read_csr(CVMX_MIO_QLMX_CFG(0));
+ if (qlm_cfg.s.qlm_cfg == 2)
+ return CVMX_HELPER_INTERFACE_MODE_SGMII;
+ else if (qlm_cfg.s.qlm_cfg == 3)
+ return CVMX_HELPER_INTERFACE_MODE_XAUI;
+ else
+ return CVMX_HELPER_INTERFACE_MODE_DISABLED;
+ }
+ } else if (OCTEON_IS_MODEL(OCTEON_CNF71XX)) {
+ if (interface == 0) {
+ union cvmx_mio_qlmx_cfg qlm_cfg;
+ qlm_cfg.u64 = cvmx_read_csr(CVMX_MIO_QLMX_CFG(0));
+ if (qlm_cfg.s.qlm_cfg == 2)
+ return CVMX_HELPER_INTERFACE_MODE_SGMII;
+ }
+ return CVMX_HELPER_INTERFACE_MODE_DISABLED;
+ }
+
+ if (interface == 1 && OCTEON_IS_MODEL(OCTEON_CN63XX))
+ return CVMX_HELPER_INTERFACE_MODE_DISABLED;
+
+ mode.u64 = cvmx_read_csr(CVMX_GMXX_INF_MODE(interface));
+
+ if (OCTEON_IS_MODEL(OCTEON_CN63XX)) {
+ switch (mode.cn63xx.mode) {
+ case 0:
+ return CVMX_HELPER_INTERFACE_MODE_SGMII;
+ case 1:
+ return CVMX_HELPER_INTERFACE_MODE_XAUI;
+ default:
+ return CVMX_HELPER_INTERFACE_MODE_DISABLED;
+ }
+ } else {
+ if (!mode.s.en)
+ return CVMX_HELPER_INTERFACE_MODE_DISABLED;
+
+ if (mode.s.type)
+ return CVMX_HELPER_INTERFACE_MODE_GMII;
+ else
+ return CVMX_HELPER_INTERFACE_MODE_RGMII;
+ }
+}
+
+/**
* Get the operating mode of an interface. Depending on the Octeon
* chip and configuration, this function returns an enumeration
* of the type of packet I/O supported by an interface.
@@ -118,6 +270,20 @@ EXPORT_SYMBOL_GPL(cvmx_helper_ports_on_interface);
cvmx_helper_interface_mode_t cvmx_helper_interface_get_mode(int interface)
{
union cvmx_gmxx_inf_mode mode;
+
+ if (interface < 0 ||
+ interface >= cvmx_helper_get_number_of_interfaces())
+ return CVMX_HELPER_INTERFACE_MODE_DISABLED;
+
+ /*
+ * Octeon II models
+ */
+ if (OCTEON_IS_MODEL(OCTEON_CN6XXX) || OCTEON_IS_MODEL(OCTEON_CNF71XX))
+ return __cvmx_get_mode_octeon2(interface);
+
+ /*
+ * Octeon and Octeon Plus models
+ */
if (interface == 2)
return CVMX_HELPER_INTERFACE_MODE_NPI;
--
1.9.3
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 1/3] MIPS: octeon: Add interface mode detection for Octeon II
@ 2014-05-29 10:10 ` Alex Smith
0 siblings, 0 replies; 21+ messages in thread
From: Alex Smith @ 2014-05-29 10:10 UTC (permalink / raw)
To: linux-mips; +Cc: David Daney, Alex Smith
Add interface mode detection for Octeon II. This is necessary to detect
the interface modes correctly on the UBNT E200 board. Code is taken
from the UBNT GPL source release, with some alterations: SRIO, ILK and
RXAUI interface modes are removed and instead return disabled as these
modes are not currently supported.
Tested-by: David Daney <david.daney@cavium.com>
Signed-off-by: Alex Smith <alex.smith@imgtec.com>
---
arch/mips/cavium-octeon/executive/cvmx-helper.c | 166 ++++++++++++++++++++++++
1 file changed, 166 insertions(+)
diff --git a/arch/mips/cavium-octeon/executive/cvmx-helper.c b/arch/mips/cavium-octeon/executive/cvmx-helper.c
index 8553ad5..7e5cf7a 100644
--- a/arch/mips/cavium-octeon/executive/cvmx-helper.c
+++ b/arch/mips/cavium-octeon/executive/cvmx-helper.c
@@ -106,6 +106,158 @@ int cvmx_helper_ports_on_interface(int interface)
EXPORT_SYMBOL_GPL(cvmx_helper_ports_on_interface);
/**
+ * @INTERNAL
+ * Return interface mode for CN68xx.
+ */
+static cvmx_helper_interface_mode_t __cvmx_get_mode_cn68xx(int interface)
+{
+ union cvmx_mio_qlmx_cfg qlm_cfg;
+ switch (interface) {
+ case 0:
+ qlm_cfg.u64 = cvmx_read_csr(CVMX_MIO_QLMX_CFG(0));
+ /* QLM is disabled when QLM SPD is 15. */
+ if (qlm_cfg.s.qlm_spd == 15)
+ return CVMX_HELPER_INTERFACE_MODE_DISABLED;
+
+ if (qlm_cfg.s.qlm_cfg == 2)
+ return CVMX_HELPER_INTERFACE_MODE_SGMII;
+ else if (qlm_cfg.s.qlm_cfg == 3)
+ return CVMX_HELPER_INTERFACE_MODE_XAUI;
+ else
+ return CVMX_HELPER_INTERFACE_MODE_DISABLED;
+ case 2:
+ case 3:
+ case 4:
+ qlm_cfg.u64 = cvmx_read_csr(CVMX_MIO_QLMX_CFG(interface));
+ /* QLM is disabled when QLM SPD is 15. */
+ if (qlm_cfg.s.qlm_spd == 15)
+ return CVMX_HELPER_INTERFACE_MODE_DISABLED;
+
+ if (qlm_cfg.s.qlm_cfg == 2)
+ return CVMX_HELPER_INTERFACE_MODE_SGMII;
+ else if (qlm_cfg.s.qlm_cfg == 3)
+ return CVMX_HELPER_INTERFACE_MODE_XAUI;
+ else
+ return CVMX_HELPER_INTERFACE_MODE_DISABLED;
+ case 7:
+ qlm_cfg.u64 = cvmx_read_csr(CVMX_MIO_QLMX_CFG(3));
+ /* QLM is disabled when QLM SPD is 15. */
+ if (qlm_cfg.s.qlm_spd == 15) {
+ return CVMX_HELPER_INTERFACE_MODE_DISABLED;
+ } else if (qlm_cfg.s.qlm_cfg != 0) {
+ qlm_cfg.u64 = cvmx_read_csr(CVMX_MIO_QLMX_CFG(1));
+ if (qlm_cfg.s.qlm_cfg != 0)
+ return CVMX_HELPER_INTERFACE_MODE_DISABLED;
+ }
+ return CVMX_HELPER_INTERFACE_MODE_NPI;
+ case 8:
+ return CVMX_HELPER_INTERFACE_MODE_LOOP;
+ default:
+ return CVMX_HELPER_INTERFACE_MODE_DISABLED;
+ }
+}
+
+/**
+ * @INTERNAL
+ * Return interface mode for an Octeon II
+ */
+static cvmx_helper_interface_mode_t __cvmx_get_mode_octeon2(int interface)
+{
+ union cvmx_gmxx_inf_mode mode;
+
+ if (OCTEON_IS_MODEL(OCTEON_CN68XX))
+ return __cvmx_get_mode_cn68xx(interface);
+
+ if (interface == 2)
+ return CVMX_HELPER_INTERFACE_MODE_NPI;
+
+ if (interface == 3)
+ return CVMX_HELPER_INTERFACE_MODE_LOOP;
+
+ /* Only present in CN63XX & CN66XX Octeon model */
+ if ((OCTEON_IS_MODEL(OCTEON_CN63XX) &&
+ (interface == 4 || interface == 5)) ||
+ (OCTEON_IS_MODEL(OCTEON_CN66XX) &&
+ interface >= 4 && interface <= 7)) {
+ return CVMX_HELPER_INTERFACE_MODE_DISABLED;
+ }
+
+ if (OCTEON_IS_MODEL(OCTEON_CN66XX)) {
+ union cvmx_mio_qlmx_cfg mio_qlm_cfg;
+
+ /* QLM2 is SGMII0 and QLM1 is SGMII1 */
+ if (interface == 0)
+ mio_qlm_cfg.u64 = cvmx_read_csr(CVMX_MIO_QLMX_CFG(2));
+ else if (interface == 1)
+ mio_qlm_cfg.u64 = cvmx_read_csr(CVMX_MIO_QLMX_CFG(1));
+ else
+ return CVMX_HELPER_INTERFACE_MODE_DISABLED;
+
+ if (mio_qlm_cfg.s.qlm_spd == 15)
+ return CVMX_HELPER_INTERFACE_MODE_DISABLED;
+
+ if (mio_qlm_cfg.s.qlm_cfg == 9)
+ return CVMX_HELPER_INTERFACE_MODE_SGMII;
+ else if (mio_qlm_cfg.s.qlm_cfg == 11)
+ return CVMX_HELPER_INTERFACE_MODE_XAUI;
+ else
+ return CVMX_HELPER_INTERFACE_MODE_DISABLED;
+ } else if (OCTEON_IS_MODEL(OCTEON_CN61XX)) {
+ union cvmx_mio_qlmx_cfg qlm_cfg;
+
+ if (interface == 0) {
+ qlm_cfg.u64 = cvmx_read_csr(CVMX_MIO_QLMX_CFG(2));
+ if (qlm_cfg.s.qlm_cfg == 2)
+ return CVMX_HELPER_INTERFACE_MODE_SGMII;
+ else if (qlm_cfg.s.qlm_cfg == 3)
+ return CVMX_HELPER_INTERFACE_MODE_XAUI;
+ else
+ return CVMX_HELPER_INTERFACE_MODE_DISABLED;
+ } else if (interface == 1) {
+ qlm_cfg.u64 = cvmx_read_csr(CVMX_MIO_QLMX_CFG(0));
+ if (qlm_cfg.s.qlm_cfg == 2)
+ return CVMX_HELPER_INTERFACE_MODE_SGMII;
+ else if (qlm_cfg.s.qlm_cfg == 3)
+ return CVMX_HELPER_INTERFACE_MODE_XAUI;
+ else
+ return CVMX_HELPER_INTERFACE_MODE_DISABLED;
+ }
+ } else if (OCTEON_IS_MODEL(OCTEON_CNF71XX)) {
+ if (interface == 0) {
+ union cvmx_mio_qlmx_cfg qlm_cfg;
+ qlm_cfg.u64 = cvmx_read_csr(CVMX_MIO_QLMX_CFG(0));
+ if (qlm_cfg.s.qlm_cfg == 2)
+ return CVMX_HELPER_INTERFACE_MODE_SGMII;
+ }
+ return CVMX_HELPER_INTERFACE_MODE_DISABLED;
+ }
+
+ if (interface == 1 && OCTEON_IS_MODEL(OCTEON_CN63XX))
+ return CVMX_HELPER_INTERFACE_MODE_DISABLED;
+
+ mode.u64 = cvmx_read_csr(CVMX_GMXX_INF_MODE(interface));
+
+ if (OCTEON_IS_MODEL(OCTEON_CN63XX)) {
+ switch (mode.cn63xx.mode) {
+ case 0:
+ return CVMX_HELPER_INTERFACE_MODE_SGMII;
+ case 1:
+ return CVMX_HELPER_INTERFACE_MODE_XAUI;
+ default:
+ return CVMX_HELPER_INTERFACE_MODE_DISABLED;
+ }
+ } else {
+ if (!mode.s.en)
+ return CVMX_HELPER_INTERFACE_MODE_DISABLED;
+
+ if (mode.s.type)
+ return CVMX_HELPER_INTERFACE_MODE_GMII;
+ else
+ return CVMX_HELPER_INTERFACE_MODE_RGMII;
+ }
+}
+
+/**
* Get the operating mode of an interface. Depending on the Octeon
* chip and configuration, this function returns an enumeration
* of the type of packet I/O supported by an interface.
@@ -118,6 +270,20 @@ EXPORT_SYMBOL_GPL(cvmx_helper_ports_on_interface);
cvmx_helper_interface_mode_t cvmx_helper_interface_get_mode(int interface)
{
union cvmx_gmxx_inf_mode mode;
+
+ if (interface < 0 ||
+ interface >= cvmx_helper_get_number_of_interfaces())
+ return CVMX_HELPER_INTERFACE_MODE_DISABLED;
+
+ /*
+ * Octeon II models
+ */
+ if (OCTEON_IS_MODEL(OCTEON_CN6XXX) || OCTEON_IS_MODEL(OCTEON_CNF71XX))
+ return __cvmx_get_mode_octeon2(interface);
+
+ /*
+ * Octeon and Octeon Plus models
+ */
if (interface == 2)
return CVMX_HELPER_INTERFACE_MODE_NPI;
--
1.9.3
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 2/3] staging: octeon-ethernet: Move PHY activation to .ndo_open().
@ 2014-05-29 10:10 ` Alex Smith
0 siblings, 0 replies; 21+ messages in thread
From: Alex Smith @ 2014-05-29 10:10 UTC (permalink / raw)
To: linux-mips; +Cc: David Daney, Alex Smith, devel
From: David Daney <david.daney@cavium.com>
This prevents PHY not found types of errors for PHY drivers that are
probed after the Ethernet driver is probed, because the ifconfig UP is
done from userspace after all drivers have been probed.
Also avoid the cvmx-helper-board.c PHY code if a real PHY driver is
present, this allows a bootloader supplied device tree to specify the
PHY information rather than having to modify the code for each
different board.
Tested-by: Alex Smith <alex.smith@imgtec.com>
Signed-off-by: David Daney <david.daney@cavium.com>
Signed-off-by: Alex Smith <alex.smith@imgtec.com>
Cc: devel@driverdev.osuosl.org
---
.../cavium-octeon/executive/cvmx-helper-sgmii.c | 12 ++-
drivers/staging/octeon/ethernet-mdio.c | 79 ++++++++++++++------
drivers/staging/octeon/ethernet-rgmii.c | 23 ++++--
drivers/staging/octeon/ethernet-sgmii.c | 87 +++++++++++++---------
drivers/staging/octeon/ethernet-xaui.c | 83 +++++++++++++--------
drivers/staging/octeon/ethernet.c | 2 +-
drivers/staging/octeon/octeon-ethernet.h | 4 +
7 files changed, 189 insertions(+), 101 deletions(-)
diff --git a/arch/mips/cavium-octeon/executive/cvmx-helper-sgmii.c b/arch/mips/cavium-octeon/executive/cvmx-helper-sgmii.c
index 45f18cc..6f9609e 100644
--- a/arch/mips/cavium-octeon/executive/cvmx-helper-sgmii.c
+++ b/arch/mips/cavium-octeon/executive/cvmx-helper-sgmii.c
@@ -317,10 +317,14 @@ static int __cvmx_helper_sgmii_hardware_init(int interface, int num_ports)
for (index = 0; index < num_ports; index++) {
int ipd_port = cvmx_helper_get_ipd_port(interface, index);
__cvmx_helper_sgmii_hardware_init_one_time(interface, index);
- __cvmx_helper_sgmii_link_set(ipd_port,
- __cvmx_helper_sgmii_link_get
- (ipd_port));
-
+ /* Linux kernel driver will call ....link_set with the
+ * proper link state. In the simulator there is no
+ * link state polling and hence it is set from
+ * here.
+ */
+ if (cvmx_sysinfo_get()->board_type == CVMX_BOARD_TYPE_SIM)
+ __cvmx_helper_sgmii_link_set(ipd_port,
+ __cvmx_helper_sgmii_link_get(ipd_port));
}
return 0;
diff --git a/drivers/staging/octeon/ethernet-mdio.c b/drivers/staging/octeon/ethernet-mdio.c
index 3f067f1..ebfa9c9 100644
--- a/drivers/staging/octeon/ethernet-mdio.c
+++ b/drivers/staging/octeon/ethernet-mdio.c
@@ -116,7 +116,34 @@ int cvm_oct_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
return phy_mii_ioctl(priv->phydev, rq, cmd);
}
-static void cvm_oct_adjust_link(struct net_device *dev)
+static void cvm_oct_note_carrier(struct octeon_ethernet *priv,
+ cvmx_helper_link_info_t li)
+{
+ if (li.s.link_up) {
+ pr_notice_ratelimited("%s: %u Mbps %s duplex, port %d\n",
+ netdev_name(priv->netdev), li.s.speed,
+ (li.s.full_duplex) ? "Full" : "Half",
+ priv->port);
+ } else {
+ pr_notice_ratelimited("%s: Link down\n",
+ netdev_name(priv->netdev));
+ }
+}
+
+void cvm_oct_set_carrier(struct octeon_ethernet *priv,
+ cvmx_helper_link_info_t link_info)
+{
+ cvm_oct_note_carrier(priv, link_info);
+ if (link_info.s.link_up) {
+ if (!netif_carrier_ok(priv->netdev))
+ netif_carrier_on(priv->netdev);
+ } else {
+ if (netif_carrier_ok(priv->netdev))
+ netif_carrier_off(priv->netdev);
+ }
+}
+
+void cvm_oct_adjust_link(struct net_device *dev)
{
struct octeon_ethernet *priv = netdev_priv(dev);
cvmx_helper_link_info_t link_info;
@@ -127,28 +154,32 @@ static void cvm_oct_adjust_link(struct net_device *dev)
link_info.s.link_up = priv->last_link ? 1 : 0;
link_info.s.full_duplex = priv->phydev->duplex ? 1 : 0;
link_info.s.speed = priv->phydev->speed;
+
cvmx_helper_link_set(priv->port, link_info);
- if (priv->last_link) {
- netif_carrier_on(dev);
- if (priv->queue != -1)
- printk_ratelimited("%s: %u Mbps %s duplex, "
- "port %2d, queue %2d\n", dev->name,
- priv->phydev->speed,
- priv->phydev->duplex ? "Full" : "Half",
- priv->port, priv->queue);
- else
- printk_ratelimited("%s: %u Mbps %s duplex, "
- "port %2d, POW\n", dev->name,
- priv->phydev->speed,
- priv->phydev->duplex ? "Full" : "Half",
- priv->port);
- } else {
- netif_carrier_off(dev);
- printk_ratelimited("%s: Link down\n", dev->name);
- }
+ cvm_oct_note_carrier(priv, link_info);
}
}
+int cvm_oct_common_stop(struct net_device *dev)
+{
+ struct octeon_ethernet *priv = netdev_priv(dev);
+ cvmx_helper_link_info_t link_info;
+
+ priv->poll = NULL;
+
+ if (priv->phydev)
+ phy_disconnect(priv->phydev);
+ priv->phydev = NULL;
+
+ if (priv->last_link) {
+ link_info.u64 = 0;
+ priv->last_link = 0;
+
+ cvmx_helper_link_set(priv->port, link_info);
+ cvm_oct_note_carrier(priv, link_info);
+ }
+ return 0;
+}
/**
* cvm_oct_phy_setup_device - setup the PHY
@@ -163,11 +194,11 @@ int cvm_oct_phy_setup_device(struct net_device *dev)
struct device_node *phy_node;
if (!priv->of_node)
- return 0;
+ goto no_phy;
phy_node = of_parse_phandle(priv->of_node, "phy-handle", 0);
if (!phy_node)
- return 0;
+ goto no_phy;
priv->phydev = of_phy_connect(dev, phy_node, cvm_oct_adjust_link, 0,
PHY_INTERFACE_MODE_GMII);
@@ -179,4 +210,10 @@ int cvm_oct_phy_setup_device(struct net_device *dev)
phy_start_aneg(priv->phydev);
return 0;
+no_phy:
+ /* If there is no phy, assume a direct MAC connection and that
+ * the link is up.
+ */
+ netif_carrier_on(dev);
+ return 0;
}
diff --git a/drivers/staging/octeon/ethernet-rgmii.c b/drivers/staging/octeon/ethernet-rgmii.c
index 0ec0da3..651be7e 100644
--- a/drivers/staging/octeon/ethernet-rgmii.c
+++ b/drivers/staging/octeon/ethernet-rgmii.c
@@ -36,6 +36,7 @@
#include "ethernet-defines.h"
#include "octeon-ethernet.h"
#include "ethernet-util.h"
+#include "ethernet-mdio.h"
#include <asm/octeon/cvmx-helper.h>
@@ -302,15 +303,28 @@ int cvm_oct_rgmii_open(struct net_device *dev)
int interface = INTERFACE(priv->port);
int index = INDEX(priv->port);
cvmx_helper_link_info_t link_info;
+ int rv;
+
+ rv = cvm_oct_phy_setup_device(dev);
+ if (rv)
+ return rv;
gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
gmx_cfg.s.en = 1;
cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64);
if (!octeon_is_simulation()) {
- link_info = cvmx_helper_link_get(priv->port);
- if (!link_info.s.link_up)
- netif_carrier_off(dev);
+ if (priv->phydev) {
+ int r = phy_read_status(priv->phydev);
+ if (r == 0 && priv->phydev->link == 0)
+ netif_carrier_off(dev);
+ cvm_oct_adjust_link(dev);
+ } else {
+ link_info = cvmx_helper_link_get(priv->port);
+ if (!link_info.s.link_up)
+ netif_carrier_off(dev);
+ priv->poll = cvm_oct_rgmii_poll;
+ }
}
return 0;
@@ -326,7 +340,7 @@ int cvm_oct_rgmii_stop(struct net_device *dev)
gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
gmx_cfg.s.en = 0;
cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64);
- return 0;
+ return cvm_oct_common_stop(dev);
}
static void cvm_oct_rgmii_immediate_poll(struct work_struct *work)
@@ -384,7 +398,6 @@ int cvm_oct_rgmii_init(struct net_device *dev)
gmx_rx_int_en.s.phy_spd = 1;
cvmx_write_csr(CVMX_GMXX_RXX_INT_EN(index, interface),
gmx_rx_int_en.u64);
- priv->poll = cvm_oct_rgmii_poll;
}
}
diff --git a/drivers/staging/octeon/ethernet-sgmii.c b/drivers/staging/octeon/ethernet-sgmii.c
index d3e8243..e187844 100644
--- a/drivers/staging/octeon/ethernet-sgmii.c
+++ b/drivers/staging/octeon/ethernet-sgmii.c
@@ -24,6 +24,7 @@
* This file may also be available under a different license from Cavium.
* Contact Cavium Networks for more information
**********************************************************************/
+#include <linux/phy.h>
#include <linux/kernel.h>
#include <linux/netdevice.h>
#include <linux/ratelimit.h>
@@ -34,45 +35,12 @@
#include "ethernet-defines.h"
#include "octeon-ethernet.h"
#include "ethernet-util.h"
+#include "ethernet-mdio.h"
#include <asm/octeon/cvmx-helper.h>
#include <asm/octeon/cvmx-gmxx-defs.h>
-int cvm_oct_sgmii_open(struct net_device *dev)
-{
- union cvmx_gmxx_prtx_cfg gmx_cfg;
- struct octeon_ethernet *priv = netdev_priv(dev);
- int interface = INTERFACE(priv->port);
- int index = INDEX(priv->port);
- cvmx_helper_link_info_t link_info;
-
- gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
- gmx_cfg.s.en = 1;
- cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64);
-
- if (!octeon_is_simulation()) {
- link_info = cvmx_helper_link_get(priv->port);
- if (!link_info.s.link_up)
- netif_carrier_off(dev);
- }
-
- return 0;
-}
-
-int cvm_oct_sgmii_stop(struct net_device *dev)
-{
- union cvmx_gmxx_prtx_cfg gmx_cfg;
- struct octeon_ethernet *priv = netdev_priv(dev);
- int interface = INTERFACE(priv->port);
- int index = INDEX(priv->port);
-
- gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
- gmx_cfg.s.en = 0;
- cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64);
- return 0;
-}
-
static void cvm_oct_sgmii_poll(struct net_device *dev)
{
struct octeon_ethernet *priv = netdev_priv(dev);
@@ -109,13 +77,58 @@ static void cvm_oct_sgmii_poll(struct net_device *dev)
}
}
-int cvm_oct_sgmii_init(struct net_device *dev)
+int cvm_oct_sgmii_open(struct net_device *dev)
{
+ union cvmx_gmxx_prtx_cfg gmx_cfg;
struct octeon_ethernet *priv = netdev_priv(dev);
+ int interface = INTERFACE(priv->port);
+ int index = INDEX(priv->port);
+ cvmx_helper_link_info_t link_info;
+ int rv;
+
+ rv = cvm_oct_phy_setup_device(dev);
+ if (rv)
+ return rv;
+
+ gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
+ gmx_cfg.s.en = 1;
+ cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64);
+
+ if (octeon_is_simulation())
+ return 0;
+
+ if (priv->phydev) {
+ int r = phy_read_status(priv->phydev);
+ if (r == 0 && priv->phydev->link == 0)
+ netif_carrier_off(dev);
+ cvm_oct_adjust_link(dev);
+ } else {
+ link_info = cvmx_helper_link_get(priv->port);
+ if (!link_info.s.link_up)
+ netif_carrier_off(dev);
+ priv->poll = cvm_oct_sgmii_poll;
+ cvm_oct_sgmii_poll(dev);
+ }
+ return 0;
+}
+
+int cvm_oct_sgmii_stop(struct net_device *dev)
+{
+ union cvmx_gmxx_prtx_cfg gmx_cfg;
+ struct octeon_ethernet *priv = netdev_priv(dev);
+ int interface = INTERFACE(priv->port);
+ int index = INDEX(priv->port);
+
+ gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
+ gmx_cfg.s.en = 0;
+ cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64);
+ return cvm_oct_common_stop(dev);
+}
+
+int cvm_oct_sgmii_init(struct net_device *dev)
+{
cvm_oct_common_init(dev);
dev->netdev_ops->ndo_stop(dev);
- if (!octeon_is_simulation() && priv->phydev == NULL)
- priv->poll = cvm_oct_sgmii_poll;
/* FIXME: Need autoneg logic */
return 0;
diff --git a/drivers/staging/octeon/ethernet-xaui.c b/drivers/staging/octeon/ethernet-xaui.c
index 419f8c3..20b3533 100644
--- a/drivers/staging/octeon/ethernet-xaui.c
+++ b/drivers/staging/octeon/ethernet-xaui.c
@@ -24,6 +24,7 @@
* This file may also be available under a different license from Cavium.
* Contact Cavium Networks for more information
**********************************************************************/
+#include <linux/phy.h>
#include <linux/kernel.h>
#include <linux/netdevice.h>
#include <linux/ratelimit.h>
@@ -34,44 +35,12 @@
#include "ethernet-defines.h"
#include "octeon-ethernet.h"
#include "ethernet-util.h"
+#include "ethernet-mdio.h"
#include <asm/octeon/cvmx-helper.h>
#include <asm/octeon/cvmx-gmxx-defs.h>
-int cvm_oct_xaui_open(struct net_device *dev)
-{
- union cvmx_gmxx_prtx_cfg gmx_cfg;
- struct octeon_ethernet *priv = netdev_priv(dev);
- int interface = INTERFACE(priv->port);
- int index = INDEX(priv->port);
- cvmx_helper_link_info_t link_info;
-
- gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
- gmx_cfg.s.en = 1;
- cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64);
-
- if (!octeon_is_simulation()) {
- link_info = cvmx_helper_link_get(priv->port);
- if (!link_info.s.link_up)
- netif_carrier_off(dev);
- }
- return 0;
-}
-
-int cvm_oct_xaui_stop(struct net_device *dev)
-{
- union cvmx_gmxx_prtx_cfg gmx_cfg;
- struct octeon_ethernet *priv = netdev_priv(dev);
- int interface = INTERFACE(priv->port);
- int index = INDEX(priv->port);
-
- gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
- gmx_cfg.s.en = 0;
- cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64);
- return 0;
-}
-
static void cvm_oct_xaui_poll(struct net_device *dev)
{
struct octeon_ethernet *priv = netdev_priv(dev);
@@ -108,6 +77,54 @@ static void cvm_oct_xaui_poll(struct net_device *dev)
}
}
+int cvm_oct_xaui_open(struct net_device *dev)
+{
+ union cvmx_gmxx_prtx_cfg gmx_cfg;
+ struct octeon_ethernet *priv = netdev_priv(dev);
+ int interface = INTERFACE(priv->port);
+ int index = INDEX(priv->port);
+ cvmx_helper_link_info_t link_info;
+ int rv;
+
+ rv = cvm_oct_phy_setup_device(dev);
+ if (rv)
+ return rv;
+
+ gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
+ gmx_cfg.s.en = 1;
+ cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64);
+
+ if (octeon_is_simulation())
+ return 0;
+
+ if (priv->phydev) {
+ int r = phy_read_status(priv->phydev);
+ if (r == 0 && priv->phydev->link == 0)
+ netif_carrier_off(dev);
+ cvm_oct_adjust_link(dev);
+ } else {
+ link_info = cvmx_helper_link_get(priv->port);
+ if (!link_info.s.link_up)
+ netif_carrier_off(dev);
+ priv->poll = cvm_oct_xaui_poll;
+ cvm_oct_xaui_poll(dev);
+ }
+ return 0;
+}
+
+int cvm_oct_xaui_stop(struct net_device *dev)
+{
+ union cvmx_gmxx_prtx_cfg gmx_cfg;
+ struct octeon_ethernet *priv = netdev_priv(dev);
+ int interface = INTERFACE(priv->port);
+ int index = INDEX(priv->port);
+
+ gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
+ gmx_cfg.s.en = 0;
+ cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64);
+ return cvm_oct_common_stop(dev);
+}
+
int cvm_oct_xaui_init(struct net_device *dev)
{
struct octeon_ethernet *priv = netdev_priv(dev);
diff --git a/drivers/staging/octeon/ethernet.c b/drivers/staging/octeon/ethernet.c
index da9dd6b..2aa7235 100644
--- a/drivers/staging/octeon/ethernet.c
+++ b/drivers/staging/octeon/ethernet.c
@@ -471,7 +471,6 @@ int cvm_oct_common_init(struct net_device *dev)
dev->features |= NETIF_F_LLTX;
dev->ethtool_ops = &cvm_oct_ethtool_ops;
- cvm_oct_phy_setup_device(dev);
cvm_oct_set_mac_filter(dev);
dev->netdev_ops->ndo_change_mtu(dev, dev->mtu);
@@ -722,6 +721,7 @@ static int cvm_oct_probe(struct platform_device *pdev)
/* Initialize the device private structure. */
priv = netdev_priv(dev);
+ priv->netdev = dev;
priv->of_node = cvm_oct_node_for_port(pip, interface,
port_index);
diff --git a/drivers/staging/octeon/octeon-ethernet.h b/drivers/staging/octeon/octeon-ethernet.h
index 4cf3884..d0e3211 100644
--- a/drivers/staging/octeon/octeon-ethernet.h
+++ b/drivers/staging/octeon/octeon-ethernet.h
@@ -44,6 +44,8 @@ struct octeon_ethernet {
int queue;
/* Hardware fetch and add to count outstanding tx buffers */
int fau;
+ /* My netdev. */
+ struct net_device *netdev;
/*
* Type of port. This is one of the enums in
* cvmx_helper_interface_mode_t
@@ -85,6 +87,8 @@ extern int cvm_oct_xaui_stop(struct net_device *dev);
extern int cvm_oct_common_init(struct net_device *dev);
extern void cvm_oct_common_uninit(struct net_device *dev);
+void cvm_oct_adjust_link(struct net_device *dev);
+int cvm_oct_common_stop(struct net_device *dev);
extern int always_use_pow;
extern int pow_send_group;
--
1.9.3
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 2/3] staging: octeon-ethernet: Move PHY activation to .ndo_open().
@ 2014-05-29 10:10 ` Alex Smith
0 siblings, 0 replies; 21+ messages in thread
From: Alex Smith @ 2014-05-29 10:10 UTC (permalink / raw)
To: linux-mips; +Cc: David Daney, Alex Smith, devel
From: David Daney <david.daney@cavium.com>
This prevents PHY not found types of errors for PHY drivers that are
probed after the Ethernet driver is probed, because the ifconfig UP is
done from userspace after all drivers have been probed.
Also avoid the cvmx-helper-board.c PHY code if a real PHY driver is
present, this allows a bootloader supplied device tree to specify the
PHY information rather than having to modify the code for each
different board.
Tested-by: Alex Smith <alex.smith@imgtec.com>
Signed-off-by: David Daney <david.daney@cavium.com>
Signed-off-by: Alex Smith <alex.smith@imgtec.com>
Cc: devel@driverdev.osuosl.org
---
.../cavium-octeon/executive/cvmx-helper-sgmii.c | 12 ++-
drivers/staging/octeon/ethernet-mdio.c | 79 ++++++++++++++------
drivers/staging/octeon/ethernet-rgmii.c | 23 ++++--
drivers/staging/octeon/ethernet-sgmii.c | 87 +++++++++++++---------
drivers/staging/octeon/ethernet-xaui.c | 83 +++++++++++++--------
drivers/staging/octeon/ethernet.c | 2 +-
drivers/staging/octeon/octeon-ethernet.h | 4 +
7 files changed, 189 insertions(+), 101 deletions(-)
diff --git a/arch/mips/cavium-octeon/executive/cvmx-helper-sgmii.c b/arch/mips/cavium-octeon/executive/cvmx-helper-sgmii.c
index 45f18cc..6f9609e 100644
--- a/arch/mips/cavium-octeon/executive/cvmx-helper-sgmii.c
+++ b/arch/mips/cavium-octeon/executive/cvmx-helper-sgmii.c
@@ -317,10 +317,14 @@ static int __cvmx_helper_sgmii_hardware_init(int interface, int num_ports)
for (index = 0; index < num_ports; index++) {
int ipd_port = cvmx_helper_get_ipd_port(interface, index);
__cvmx_helper_sgmii_hardware_init_one_time(interface, index);
- __cvmx_helper_sgmii_link_set(ipd_port,
- __cvmx_helper_sgmii_link_get
- (ipd_port));
-
+ /* Linux kernel driver will call ....link_set with the
+ * proper link state. In the simulator there is no
+ * link state polling and hence it is set from
+ * here.
+ */
+ if (cvmx_sysinfo_get()->board_type == CVMX_BOARD_TYPE_SIM)
+ __cvmx_helper_sgmii_link_set(ipd_port,
+ __cvmx_helper_sgmii_link_get(ipd_port));
}
return 0;
diff --git a/drivers/staging/octeon/ethernet-mdio.c b/drivers/staging/octeon/ethernet-mdio.c
index 3f067f1..ebfa9c9 100644
--- a/drivers/staging/octeon/ethernet-mdio.c
+++ b/drivers/staging/octeon/ethernet-mdio.c
@@ -116,7 +116,34 @@ int cvm_oct_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
return phy_mii_ioctl(priv->phydev, rq, cmd);
}
-static void cvm_oct_adjust_link(struct net_device *dev)
+static void cvm_oct_note_carrier(struct octeon_ethernet *priv,
+ cvmx_helper_link_info_t li)
+{
+ if (li.s.link_up) {
+ pr_notice_ratelimited("%s: %u Mbps %s duplex, port %d\n",
+ netdev_name(priv->netdev), li.s.speed,
+ (li.s.full_duplex) ? "Full" : "Half",
+ priv->port);
+ } else {
+ pr_notice_ratelimited("%s: Link down\n",
+ netdev_name(priv->netdev));
+ }
+}
+
+void cvm_oct_set_carrier(struct octeon_ethernet *priv,
+ cvmx_helper_link_info_t link_info)
+{
+ cvm_oct_note_carrier(priv, link_info);
+ if (link_info.s.link_up) {
+ if (!netif_carrier_ok(priv->netdev))
+ netif_carrier_on(priv->netdev);
+ } else {
+ if (netif_carrier_ok(priv->netdev))
+ netif_carrier_off(priv->netdev);
+ }
+}
+
+void cvm_oct_adjust_link(struct net_device *dev)
{
struct octeon_ethernet *priv = netdev_priv(dev);
cvmx_helper_link_info_t link_info;
@@ -127,28 +154,32 @@ static void cvm_oct_adjust_link(struct net_device *dev)
link_info.s.link_up = priv->last_link ? 1 : 0;
link_info.s.full_duplex = priv->phydev->duplex ? 1 : 0;
link_info.s.speed = priv->phydev->speed;
+
cvmx_helper_link_set(priv->port, link_info);
- if (priv->last_link) {
- netif_carrier_on(dev);
- if (priv->queue != -1)
- printk_ratelimited("%s: %u Mbps %s duplex, "
- "port %2d, queue %2d\n", dev->name,
- priv->phydev->speed,
- priv->phydev->duplex ? "Full" : "Half",
- priv->port, priv->queue);
- else
- printk_ratelimited("%s: %u Mbps %s duplex, "
- "port %2d, POW\n", dev->name,
- priv->phydev->speed,
- priv->phydev->duplex ? "Full" : "Half",
- priv->port);
- } else {
- netif_carrier_off(dev);
- printk_ratelimited("%s: Link down\n", dev->name);
- }
+ cvm_oct_note_carrier(priv, link_info);
}
}
+int cvm_oct_common_stop(struct net_device *dev)
+{
+ struct octeon_ethernet *priv = netdev_priv(dev);
+ cvmx_helper_link_info_t link_info;
+
+ priv->poll = NULL;
+
+ if (priv->phydev)
+ phy_disconnect(priv->phydev);
+ priv->phydev = NULL;
+
+ if (priv->last_link) {
+ link_info.u64 = 0;
+ priv->last_link = 0;
+
+ cvmx_helper_link_set(priv->port, link_info);
+ cvm_oct_note_carrier(priv, link_info);
+ }
+ return 0;
+}
/**
* cvm_oct_phy_setup_device - setup the PHY
@@ -163,11 +194,11 @@ int cvm_oct_phy_setup_device(struct net_device *dev)
struct device_node *phy_node;
if (!priv->of_node)
- return 0;
+ goto no_phy;
phy_node = of_parse_phandle(priv->of_node, "phy-handle", 0);
if (!phy_node)
- return 0;
+ goto no_phy;
priv->phydev = of_phy_connect(dev, phy_node, cvm_oct_adjust_link, 0,
PHY_INTERFACE_MODE_GMII);
@@ -179,4 +210,10 @@ int cvm_oct_phy_setup_device(struct net_device *dev)
phy_start_aneg(priv->phydev);
return 0;
+no_phy:
+ /* If there is no phy, assume a direct MAC connection and that
+ * the link is up.
+ */
+ netif_carrier_on(dev);
+ return 0;
}
diff --git a/drivers/staging/octeon/ethernet-rgmii.c b/drivers/staging/octeon/ethernet-rgmii.c
index 0ec0da3..651be7e 100644
--- a/drivers/staging/octeon/ethernet-rgmii.c
+++ b/drivers/staging/octeon/ethernet-rgmii.c
@@ -36,6 +36,7 @@
#include "ethernet-defines.h"
#include "octeon-ethernet.h"
#include "ethernet-util.h"
+#include "ethernet-mdio.h"
#include <asm/octeon/cvmx-helper.h>
@@ -302,15 +303,28 @@ int cvm_oct_rgmii_open(struct net_device *dev)
int interface = INTERFACE(priv->port);
int index = INDEX(priv->port);
cvmx_helper_link_info_t link_info;
+ int rv;
+
+ rv = cvm_oct_phy_setup_device(dev);
+ if (rv)
+ return rv;
gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
gmx_cfg.s.en = 1;
cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64);
if (!octeon_is_simulation()) {
- link_info = cvmx_helper_link_get(priv->port);
- if (!link_info.s.link_up)
- netif_carrier_off(dev);
+ if (priv->phydev) {
+ int r = phy_read_status(priv->phydev);
+ if (r == 0 && priv->phydev->link == 0)
+ netif_carrier_off(dev);
+ cvm_oct_adjust_link(dev);
+ } else {
+ link_info = cvmx_helper_link_get(priv->port);
+ if (!link_info.s.link_up)
+ netif_carrier_off(dev);
+ priv->poll = cvm_oct_rgmii_poll;
+ }
}
return 0;
@@ -326,7 +340,7 @@ int cvm_oct_rgmii_stop(struct net_device *dev)
gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
gmx_cfg.s.en = 0;
cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64);
- return 0;
+ return cvm_oct_common_stop(dev);
}
static void cvm_oct_rgmii_immediate_poll(struct work_struct *work)
@@ -384,7 +398,6 @@ int cvm_oct_rgmii_init(struct net_device *dev)
gmx_rx_int_en.s.phy_spd = 1;
cvmx_write_csr(CVMX_GMXX_RXX_INT_EN(index, interface),
gmx_rx_int_en.u64);
- priv->poll = cvm_oct_rgmii_poll;
}
}
diff --git a/drivers/staging/octeon/ethernet-sgmii.c b/drivers/staging/octeon/ethernet-sgmii.c
index d3e8243..e187844 100644
--- a/drivers/staging/octeon/ethernet-sgmii.c
+++ b/drivers/staging/octeon/ethernet-sgmii.c
@@ -24,6 +24,7 @@
* This file may also be available under a different license from Cavium.
* Contact Cavium Networks for more information
**********************************************************************/
+#include <linux/phy.h>
#include <linux/kernel.h>
#include <linux/netdevice.h>
#include <linux/ratelimit.h>
@@ -34,45 +35,12 @@
#include "ethernet-defines.h"
#include "octeon-ethernet.h"
#include "ethernet-util.h"
+#include "ethernet-mdio.h"
#include <asm/octeon/cvmx-helper.h>
#include <asm/octeon/cvmx-gmxx-defs.h>
-int cvm_oct_sgmii_open(struct net_device *dev)
-{
- union cvmx_gmxx_prtx_cfg gmx_cfg;
- struct octeon_ethernet *priv = netdev_priv(dev);
- int interface = INTERFACE(priv->port);
- int index = INDEX(priv->port);
- cvmx_helper_link_info_t link_info;
-
- gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
- gmx_cfg.s.en = 1;
- cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64);
-
- if (!octeon_is_simulation()) {
- link_info = cvmx_helper_link_get(priv->port);
- if (!link_info.s.link_up)
- netif_carrier_off(dev);
- }
-
- return 0;
-}
-
-int cvm_oct_sgmii_stop(struct net_device *dev)
-{
- union cvmx_gmxx_prtx_cfg gmx_cfg;
- struct octeon_ethernet *priv = netdev_priv(dev);
- int interface = INTERFACE(priv->port);
- int index = INDEX(priv->port);
-
- gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
- gmx_cfg.s.en = 0;
- cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64);
- return 0;
-}
-
static void cvm_oct_sgmii_poll(struct net_device *dev)
{
struct octeon_ethernet *priv = netdev_priv(dev);
@@ -109,13 +77,58 @@ static void cvm_oct_sgmii_poll(struct net_device *dev)
}
}
-int cvm_oct_sgmii_init(struct net_device *dev)
+int cvm_oct_sgmii_open(struct net_device *dev)
{
+ union cvmx_gmxx_prtx_cfg gmx_cfg;
struct octeon_ethernet *priv = netdev_priv(dev);
+ int interface = INTERFACE(priv->port);
+ int index = INDEX(priv->port);
+ cvmx_helper_link_info_t link_info;
+ int rv;
+
+ rv = cvm_oct_phy_setup_device(dev);
+ if (rv)
+ return rv;
+
+ gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
+ gmx_cfg.s.en = 1;
+ cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64);
+
+ if (octeon_is_simulation())
+ return 0;
+
+ if (priv->phydev) {
+ int r = phy_read_status(priv->phydev);
+ if (r == 0 && priv->phydev->link == 0)
+ netif_carrier_off(dev);
+ cvm_oct_adjust_link(dev);
+ } else {
+ link_info = cvmx_helper_link_get(priv->port);
+ if (!link_info.s.link_up)
+ netif_carrier_off(dev);
+ priv->poll = cvm_oct_sgmii_poll;
+ cvm_oct_sgmii_poll(dev);
+ }
+ return 0;
+}
+
+int cvm_oct_sgmii_stop(struct net_device *dev)
+{
+ union cvmx_gmxx_prtx_cfg gmx_cfg;
+ struct octeon_ethernet *priv = netdev_priv(dev);
+ int interface = INTERFACE(priv->port);
+ int index = INDEX(priv->port);
+
+ gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
+ gmx_cfg.s.en = 0;
+ cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64);
+ return cvm_oct_common_stop(dev);
+}
+
+int cvm_oct_sgmii_init(struct net_device *dev)
+{
cvm_oct_common_init(dev);
dev->netdev_ops->ndo_stop(dev);
- if (!octeon_is_simulation() && priv->phydev == NULL)
- priv->poll = cvm_oct_sgmii_poll;
/* FIXME: Need autoneg logic */
return 0;
diff --git a/drivers/staging/octeon/ethernet-xaui.c b/drivers/staging/octeon/ethernet-xaui.c
index 419f8c3..20b3533 100644
--- a/drivers/staging/octeon/ethernet-xaui.c
+++ b/drivers/staging/octeon/ethernet-xaui.c
@@ -24,6 +24,7 @@
* This file may also be available under a different license from Cavium.
* Contact Cavium Networks for more information
**********************************************************************/
+#include <linux/phy.h>
#include <linux/kernel.h>
#include <linux/netdevice.h>
#include <linux/ratelimit.h>
@@ -34,44 +35,12 @@
#include "ethernet-defines.h"
#include "octeon-ethernet.h"
#include "ethernet-util.h"
+#include "ethernet-mdio.h"
#include <asm/octeon/cvmx-helper.h>
#include <asm/octeon/cvmx-gmxx-defs.h>
-int cvm_oct_xaui_open(struct net_device *dev)
-{
- union cvmx_gmxx_prtx_cfg gmx_cfg;
- struct octeon_ethernet *priv = netdev_priv(dev);
- int interface = INTERFACE(priv->port);
- int index = INDEX(priv->port);
- cvmx_helper_link_info_t link_info;
-
- gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
- gmx_cfg.s.en = 1;
- cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64);
-
- if (!octeon_is_simulation()) {
- link_info = cvmx_helper_link_get(priv->port);
- if (!link_info.s.link_up)
- netif_carrier_off(dev);
- }
- return 0;
-}
-
-int cvm_oct_xaui_stop(struct net_device *dev)
-{
- union cvmx_gmxx_prtx_cfg gmx_cfg;
- struct octeon_ethernet *priv = netdev_priv(dev);
- int interface = INTERFACE(priv->port);
- int index = INDEX(priv->port);
-
- gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
- gmx_cfg.s.en = 0;
- cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64);
- return 0;
-}
-
static void cvm_oct_xaui_poll(struct net_device *dev)
{
struct octeon_ethernet *priv = netdev_priv(dev);
@@ -108,6 +77,54 @@ static void cvm_oct_xaui_poll(struct net_device *dev)
}
}
+int cvm_oct_xaui_open(struct net_device *dev)
+{
+ union cvmx_gmxx_prtx_cfg gmx_cfg;
+ struct octeon_ethernet *priv = netdev_priv(dev);
+ int interface = INTERFACE(priv->port);
+ int index = INDEX(priv->port);
+ cvmx_helper_link_info_t link_info;
+ int rv;
+
+ rv = cvm_oct_phy_setup_device(dev);
+ if (rv)
+ return rv;
+
+ gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
+ gmx_cfg.s.en = 1;
+ cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64);
+
+ if (octeon_is_simulation())
+ return 0;
+
+ if (priv->phydev) {
+ int r = phy_read_status(priv->phydev);
+ if (r == 0 && priv->phydev->link == 0)
+ netif_carrier_off(dev);
+ cvm_oct_adjust_link(dev);
+ } else {
+ link_info = cvmx_helper_link_get(priv->port);
+ if (!link_info.s.link_up)
+ netif_carrier_off(dev);
+ priv->poll = cvm_oct_xaui_poll;
+ cvm_oct_xaui_poll(dev);
+ }
+ return 0;
+}
+
+int cvm_oct_xaui_stop(struct net_device *dev)
+{
+ union cvmx_gmxx_prtx_cfg gmx_cfg;
+ struct octeon_ethernet *priv = netdev_priv(dev);
+ int interface = INTERFACE(priv->port);
+ int index = INDEX(priv->port);
+
+ gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
+ gmx_cfg.s.en = 0;
+ cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64);
+ return cvm_oct_common_stop(dev);
+}
+
int cvm_oct_xaui_init(struct net_device *dev)
{
struct octeon_ethernet *priv = netdev_priv(dev);
diff --git a/drivers/staging/octeon/ethernet.c b/drivers/staging/octeon/ethernet.c
index da9dd6b..2aa7235 100644
--- a/drivers/staging/octeon/ethernet.c
+++ b/drivers/staging/octeon/ethernet.c
@@ -471,7 +471,6 @@ int cvm_oct_common_init(struct net_device *dev)
dev->features |= NETIF_F_LLTX;
dev->ethtool_ops = &cvm_oct_ethtool_ops;
- cvm_oct_phy_setup_device(dev);
cvm_oct_set_mac_filter(dev);
dev->netdev_ops->ndo_change_mtu(dev, dev->mtu);
@@ -722,6 +721,7 @@ static int cvm_oct_probe(struct platform_device *pdev)
/* Initialize the device private structure. */
priv = netdev_priv(dev);
+ priv->netdev = dev;
priv->of_node = cvm_oct_node_for_port(pip, interface,
port_index);
diff --git a/drivers/staging/octeon/octeon-ethernet.h b/drivers/staging/octeon/octeon-ethernet.h
index 4cf3884..d0e3211 100644
--- a/drivers/staging/octeon/octeon-ethernet.h
+++ b/drivers/staging/octeon/octeon-ethernet.h
@@ -44,6 +44,8 @@ struct octeon_ethernet {
int queue;
/* Hardware fetch and add to count outstanding tx buffers */
int fau;
+ /* My netdev. */
+ struct net_device *netdev;
/*
* Type of port. This is one of the enums in
* cvmx_helper_interface_mode_t
@@ -85,6 +87,8 @@ extern int cvm_oct_xaui_stop(struct net_device *dev);
extern int cvm_oct_common_init(struct net_device *dev);
extern void cvm_oct_common_uninit(struct net_device *dev);
+void cvm_oct_adjust_link(struct net_device *dev);
+int cvm_oct_common_stop(struct net_device *dev);
extern int always_use_pow;
extern int pow_send_group;
--
1.9.3
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 3/3] usb host/MIPS: Remove hard-coded OCTEON platform information.
@ 2014-05-29 10:10 ` Alex Smith
0 siblings, 0 replies; 21+ messages in thread
From: Alex Smith @ 2014-05-29 10:10 UTC (permalink / raw)
To: linux-mips; +Cc: David Daney, Alex Smith, linux-usb
From: David Daney <david.daney@cavium.com>
The device tree will *always* have correct ehci/ohci clock
configuration, so use it. This allows us to remove a big chunk of
platform configuration code from octeon-platform.c.
Tested-by: Alex Smith <alex.smith@imgtec.com>
Signed-off-by: David Daney <david.daney@cavium.com>
Signed-off-by: Alex Smith <alex.smith@imgtec.com>
Cc: linux-usb@vger.kernel.org
---
arch/mips/cavium-octeon/octeon-platform.c | 102 ------------------------------
drivers/usb/host/ehci-octeon.c | 17 +++--
drivers/usb/host/octeon2-common.c | 47 ++++++++++++--
drivers/usb/host/ohci-octeon.c | 17 +++--
4 files changed, 69 insertions(+), 114 deletions(-)
diff --git a/arch/mips/cavium-octeon/octeon-platform.c b/arch/mips/cavium-octeon/octeon-platform.c
index 6df0f4d..f8cced4 100644
--- a/arch/mips/cavium-octeon/octeon-platform.c
+++ b/arch/mips/cavium-octeon/octeon-platform.c
@@ -66,108 +66,6 @@ out:
}
device_initcall(octeon_rng_device_init);
-#ifdef CONFIG_USB
-
-static int __init octeon_ehci_device_init(void)
-{
- struct platform_device *pd;
- int ret = 0;
-
- struct resource usb_resources[] = {
- {
- .flags = IORESOURCE_MEM,
- }, {
- .flags = IORESOURCE_IRQ,
- }
- };
-
- /* Only Octeon2 has ehci/ohci */
- if (!OCTEON_IS_MODEL(OCTEON_CN63XX))
- return 0;
-
- if (octeon_is_simulation() || usb_disabled())
- return 0; /* No USB in the simulator. */
-
- pd = platform_device_alloc("octeon-ehci", 0);
- if (!pd) {
- ret = -ENOMEM;
- goto out;
- }
-
- usb_resources[0].start = 0x00016F0000000000ULL;
- usb_resources[0].end = usb_resources[0].start + 0x100;
-
- usb_resources[1].start = OCTEON_IRQ_USB0;
- usb_resources[1].end = OCTEON_IRQ_USB0;
-
- ret = platform_device_add_resources(pd, usb_resources,
- ARRAY_SIZE(usb_resources));
- if (ret)
- goto fail;
-
- ret = platform_device_add(pd);
- if (ret)
- goto fail;
-
- return ret;
-fail:
- platform_device_put(pd);
-out:
- return ret;
-}
-device_initcall(octeon_ehci_device_init);
-
-static int __init octeon_ohci_device_init(void)
-{
- struct platform_device *pd;
- int ret = 0;
-
- struct resource usb_resources[] = {
- {
- .flags = IORESOURCE_MEM,
- }, {
- .flags = IORESOURCE_IRQ,
- }
- };
-
- /* Only Octeon2 has ehci/ohci */
- if (!OCTEON_IS_MODEL(OCTEON_CN63XX))
- return 0;
-
- if (octeon_is_simulation() || usb_disabled())
- return 0; /* No USB in the simulator. */
-
- pd = platform_device_alloc("octeon-ohci", 0);
- if (!pd) {
- ret = -ENOMEM;
- goto out;
- }
-
- usb_resources[0].start = 0x00016F0000000400ULL;
- usb_resources[0].end = usb_resources[0].start + 0x100;
-
- usb_resources[1].start = OCTEON_IRQ_USB0;
- usb_resources[1].end = OCTEON_IRQ_USB0;
-
- ret = platform_device_add_resources(pd, usb_resources,
- ARRAY_SIZE(usb_resources));
- if (ret)
- goto fail;
-
- ret = platform_device_add(pd);
- if (ret)
- goto fail;
-
- return ret;
-fail:
- platform_device_put(pd);
-out:
- return ret;
-}
-device_initcall(octeon_ohci_device_init);
-
-#endif /* CONFIG_USB */
-
static struct of_device_id __initdata octeon_ids[] = {
{ .compatible = "simple-bus", },
{ .compatible = "cavium,octeon-6335-uctl", },
diff --git a/drivers/usb/host/ehci-octeon.c b/drivers/usb/host/ehci-octeon.c
index 9051439..e1a264f5 100644
--- a/drivers/usb/host/ehci-octeon.c
+++ b/drivers/usb/host/ehci-octeon.c
@@ -19,14 +19,14 @@
#define OCTEON_EHCI_HCD_NAME "octeon-ehci"
/* Common clock init code. */
-void octeon2_usb_clocks_start(void);
+void octeon2_usb_clocks_start(struct device *dev);
void octeon2_usb_clocks_stop(void);
-static void ehci_octeon_start(void)
+static void ehci_octeon_start(struct device *dev)
{
union cvmx_uctlx_ehci_ctl ehci_ctl;
- octeon2_usb_clocks_start();
+ octeon2_usb_clocks_start(dev);
ehci_ctl.u64 = cvmx_read_csr(CVMX_UCTLX_EHCI_CTL(0));
/* Use 64-bit addressing. */
@@ -134,7 +134,7 @@ static int ehci_octeon_drv_probe(struct platform_device *pdev)
goto err1;
}
- ehci_octeon_start();
+ ehci_octeon_start(&pdev->dev);
ehci = hcd_to_ehci(hcd);
@@ -175,6 +175,14 @@ static int ehci_octeon_drv_remove(struct platform_device *pdev)
return 0;
}
+static struct of_device_id ehci_octeon_match[] = {
+ {
+ .compatible = "cavium,octeon-6335-ehci",
+ },
+ {},
+};
+MODULE_DEVICE_TABLE(of, ehci_octeon_match);
+
static struct platform_driver ehci_octeon_driver = {
.probe = ehci_octeon_drv_probe,
.remove = ehci_octeon_drv_remove,
@@ -182,6 +190,7 @@ static struct platform_driver ehci_octeon_driver = {
.driver = {
.name = OCTEON_EHCI_HCD_NAME,
.owner = THIS_MODULE,
+ .of_match_table = ehci_octeon_match,
}
};
diff --git a/drivers/usb/host/octeon2-common.c b/drivers/usb/host/octeon2-common.c
index d9df423..3c7c13a 100644
--- a/drivers/usb/host/octeon2-common.c
+++ b/drivers/usb/host/octeon2-common.c
@@ -6,9 +6,11 @@
* Copyright (C) 2010, 2011 Cavium Networks
*/
+#include <linux/device.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/delay.h>
+#include <linux/of.h>
#include <asm/octeon/octeon.h>
#include <asm/octeon/cvmx-uctlx-defs.h>
@@ -17,13 +19,15 @@ static DEFINE_MUTEX(octeon2_usb_clocks_mutex);
static int octeon2_usb_clock_start_cnt;
-void octeon2_usb_clocks_start(void)
+void octeon2_usb_clocks_start(struct device *dev)
{
u64 div;
union cvmx_uctlx_if_ena if_ena;
union cvmx_uctlx_clk_rst_ctl clk_rst_ctl;
union cvmx_uctlx_uphy_ctl_status uphy_ctl_status;
union cvmx_uctlx_uphy_portx_ctl_status port_ctl_status;
+ u32 clock_rate = 12000000;
+ bool is_crystal_clock = false;
int i;
unsigned long io_clk_64_to_ns;
@@ -36,6 +40,28 @@ void octeon2_usb_clocks_start(void)
io_clk_64_to_ns = 64000000000ull / octeon_get_io_clock_rate();
+ if (dev->of_node) {
+ struct device_node *uctl_node;
+ const char *clock_type;
+
+ uctl_node = of_get_parent(dev->of_node);
+ if (!uctl_node) {
+ dev_err(dev, "No UCTL device node\n");
+ goto exit;
+ }
+ i = of_property_read_u32(uctl_node,
+ "refclk-frequency", &clock_rate);
+ if (i) {
+ dev_err(dev, "No UCTL \"refclk-frequency\"\n");
+ goto exit;
+ }
+ i = of_property_read_string(uctl_node,
+ "refclk-type", &clock_type);
+
+ if (!i && strcmp("crystal", clock_type) == 0)
+ is_crystal_clock = true;
+ }
+
/*
* Step 1: Wait for voltages stable. That surely happened
* before starting the kernel.
@@ -66,9 +92,22 @@ void octeon2_usb_clocks_start(void)
cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64);
/* 3b */
- /* 12MHz crystal. */
- clk_rst_ctl.s.p_refclk_sel = 0;
- clk_rst_ctl.s.p_refclk_div = 0;
+ clk_rst_ctl.s.p_refclk_sel = is_crystal_clock ? 0 : 1;
+ switch (clock_rate) {
+ default:
+ pr_err("Invalid UCTL clock rate of %u, using 12000000 instead\n",
+ clock_rate);
+ /* Fall through */
+ case 12000000:
+ clk_rst_ctl.s.p_refclk_div = 0;
+ break;
+ case 24000000:
+ clk_rst_ctl.s.p_refclk_div = 1;
+ break;
+ case 48000000:
+ clk_rst_ctl.s.p_refclk_div = 2;
+ break;
+ }
cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64);
/* 3c */
diff --git a/drivers/usb/host/ohci-octeon.c b/drivers/usb/host/ohci-octeon.c
index 15af895..2127290 100644
--- a/drivers/usb/host/ohci-octeon.c
+++ b/drivers/usb/host/ohci-octeon.c
@@ -19,14 +19,14 @@
#define OCTEON_OHCI_HCD_NAME "octeon-ohci"
/* Common clock init code. */
-void octeon2_usb_clocks_start(void);
+void octeon2_usb_clocks_start(struct device *dev);
void octeon2_usb_clocks_stop(void);
-static void ohci_octeon_hw_start(void)
+static void ohci_octeon_hw_start(struct device *dev)
{
union cvmx_uctlx_ohci_ctl ohci_ctl;
- octeon2_usb_clocks_start();
+ octeon2_usb_clocks_start(dev);
ohci_ctl.u64 = cvmx_read_csr(CVMX_UCTLX_OHCI_CTL(0));
ohci_ctl.s.l2c_addr_msb = 0;
@@ -144,7 +144,7 @@ static int ohci_octeon_drv_probe(struct platform_device *pdev)
goto err1;
}
- ohci_octeon_hw_start();
+ ohci_octeon_hw_start(&pdev->dev);
hcd->regs = reg_base;
@@ -189,6 +189,14 @@ static int ohci_octeon_drv_remove(struct platform_device *pdev)
return 0;
}
+static struct of_device_id ohci_octeon_match[] = {
+ {
+ .compatible = "cavium,octeon-6335-ohci",
+ },
+ {},
+};
+MODULE_DEVICE_TABLE(of, ohci_octeon_match);
+
static struct platform_driver ohci_octeon_driver = {
.probe = ohci_octeon_drv_probe,
.remove = ohci_octeon_drv_remove,
@@ -196,6 +204,7 @@ static struct platform_driver ohci_octeon_driver = {
.driver = {
.name = OCTEON_OHCI_HCD_NAME,
.owner = THIS_MODULE,
+ .of_match_table = ohci_octeon_match,
}
};
--
1.9.3
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 3/3] usb host/MIPS: Remove hard-coded OCTEON platform information.
@ 2014-05-29 10:10 ` Alex Smith
0 siblings, 0 replies; 21+ messages in thread
From: Alex Smith @ 2014-05-29 10:10 UTC (permalink / raw)
To: linux-mips; +Cc: David Daney, Alex Smith, linux-usb
From: David Daney <david.daney@cavium.com>
The device tree will *always* have correct ehci/ohci clock
configuration, so use it. This allows us to remove a big chunk of
platform configuration code from octeon-platform.c.
Tested-by: Alex Smith <alex.smith@imgtec.com>
Signed-off-by: David Daney <david.daney@cavium.com>
Signed-off-by: Alex Smith <alex.smith@imgtec.com>
Cc: linux-usb@vger.kernel.org
---
arch/mips/cavium-octeon/octeon-platform.c | 102 ------------------------------
drivers/usb/host/ehci-octeon.c | 17 +++--
drivers/usb/host/octeon2-common.c | 47 ++++++++++++--
drivers/usb/host/ohci-octeon.c | 17 +++--
4 files changed, 69 insertions(+), 114 deletions(-)
diff --git a/arch/mips/cavium-octeon/octeon-platform.c b/arch/mips/cavium-octeon/octeon-platform.c
index 6df0f4d..f8cced4 100644
--- a/arch/mips/cavium-octeon/octeon-platform.c
+++ b/arch/mips/cavium-octeon/octeon-platform.c
@@ -66,108 +66,6 @@ out:
}
device_initcall(octeon_rng_device_init);
-#ifdef CONFIG_USB
-
-static int __init octeon_ehci_device_init(void)
-{
- struct platform_device *pd;
- int ret = 0;
-
- struct resource usb_resources[] = {
- {
- .flags = IORESOURCE_MEM,
- }, {
- .flags = IORESOURCE_IRQ,
- }
- };
-
- /* Only Octeon2 has ehci/ohci */
- if (!OCTEON_IS_MODEL(OCTEON_CN63XX))
- return 0;
-
- if (octeon_is_simulation() || usb_disabled())
- return 0; /* No USB in the simulator. */
-
- pd = platform_device_alloc("octeon-ehci", 0);
- if (!pd) {
- ret = -ENOMEM;
- goto out;
- }
-
- usb_resources[0].start = 0x00016F0000000000ULL;
- usb_resources[0].end = usb_resources[0].start + 0x100;
-
- usb_resources[1].start = OCTEON_IRQ_USB0;
- usb_resources[1].end = OCTEON_IRQ_USB0;
-
- ret = platform_device_add_resources(pd, usb_resources,
- ARRAY_SIZE(usb_resources));
- if (ret)
- goto fail;
-
- ret = platform_device_add(pd);
- if (ret)
- goto fail;
-
- return ret;
-fail:
- platform_device_put(pd);
-out:
- return ret;
-}
-device_initcall(octeon_ehci_device_init);
-
-static int __init octeon_ohci_device_init(void)
-{
- struct platform_device *pd;
- int ret = 0;
-
- struct resource usb_resources[] = {
- {
- .flags = IORESOURCE_MEM,
- }, {
- .flags = IORESOURCE_IRQ,
- }
- };
-
- /* Only Octeon2 has ehci/ohci */
- if (!OCTEON_IS_MODEL(OCTEON_CN63XX))
- return 0;
-
- if (octeon_is_simulation() || usb_disabled())
- return 0; /* No USB in the simulator. */
-
- pd = platform_device_alloc("octeon-ohci", 0);
- if (!pd) {
- ret = -ENOMEM;
- goto out;
- }
-
- usb_resources[0].start = 0x00016F0000000400ULL;
- usb_resources[0].end = usb_resources[0].start + 0x100;
-
- usb_resources[1].start = OCTEON_IRQ_USB0;
- usb_resources[1].end = OCTEON_IRQ_USB0;
-
- ret = platform_device_add_resources(pd, usb_resources,
- ARRAY_SIZE(usb_resources));
- if (ret)
- goto fail;
-
- ret = platform_device_add(pd);
- if (ret)
- goto fail;
-
- return ret;
-fail:
- platform_device_put(pd);
-out:
- return ret;
-}
-device_initcall(octeon_ohci_device_init);
-
-#endif /* CONFIG_USB */
-
static struct of_device_id __initdata octeon_ids[] = {
{ .compatible = "simple-bus", },
{ .compatible = "cavium,octeon-6335-uctl", },
diff --git a/drivers/usb/host/ehci-octeon.c b/drivers/usb/host/ehci-octeon.c
index 9051439..e1a264f5 100644
--- a/drivers/usb/host/ehci-octeon.c
+++ b/drivers/usb/host/ehci-octeon.c
@@ -19,14 +19,14 @@
#define OCTEON_EHCI_HCD_NAME "octeon-ehci"
/* Common clock init code. */
-void octeon2_usb_clocks_start(void);
+void octeon2_usb_clocks_start(struct device *dev);
void octeon2_usb_clocks_stop(void);
-static void ehci_octeon_start(void)
+static void ehci_octeon_start(struct device *dev)
{
union cvmx_uctlx_ehci_ctl ehci_ctl;
- octeon2_usb_clocks_start();
+ octeon2_usb_clocks_start(dev);
ehci_ctl.u64 = cvmx_read_csr(CVMX_UCTLX_EHCI_CTL(0));
/* Use 64-bit addressing. */
@@ -134,7 +134,7 @@ static int ehci_octeon_drv_probe(struct platform_device *pdev)
goto err1;
}
- ehci_octeon_start();
+ ehci_octeon_start(&pdev->dev);
ehci = hcd_to_ehci(hcd);
@@ -175,6 +175,14 @@ static int ehci_octeon_drv_remove(struct platform_device *pdev)
return 0;
}
+static struct of_device_id ehci_octeon_match[] = {
+ {
+ .compatible = "cavium,octeon-6335-ehci",
+ },
+ {},
+};
+MODULE_DEVICE_TABLE(of, ehci_octeon_match);
+
static struct platform_driver ehci_octeon_driver = {
.probe = ehci_octeon_drv_probe,
.remove = ehci_octeon_drv_remove,
@@ -182,6 +190,7 @@ static struct platform_driver ehci_octeon_driver = {
.driver = {
.name = OCTEON_EHCI_HCD_NAME,
.owner = THIS_MODULE,
+ .of_match_table = ehci_octeon_match,
}
};
diff --git a/drivers/usb/host/octeon2-common.c b/drivers/usb/host/octeon2-common.c
index d9df423..3c7c13a 100644
--- a/drivers/usb/host/octeon2-common.c
+++ b/drivers/usb/host/octeon2-common.c
@@ -6,9 +6,11 @@
* Copyright (C) 2010, 2011 Cavium Networks
*/
+#include <linux/device.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/delay.h>
+#include <linux/of.h>
#include <asm/octeon/octeon.h>
#include <asm/octeon/cvmx-uctlx-defs.h>
@@ -17,13 +19,15 @@ static DEFINE_MUTEX(octeon2_usb_clocks_mutex);
static int octeon2_usb_clock_start_cnt;
-void octeon2_usb_clocks_start(void)
+void octeon2_usb_clocks_start(struct device *dev)
{
u64 div;
union cvmx_uctlx_if_ena if_ena;
union cvmx_uctlx_clk_rst_ctl clk_rst_ctl;
union cvmx_uctlx_uphy_ctl_status uphy_ctl_status;
union cvmx_uctlx_uphy_portx_ctl_status port_ctl_status;
+ u32 clock_rate = 12000000;
+ bool is_crystal_clock = false;
int i;
unsigned long io_clk_64_to_ns;
@@ -36,6 +40,28 @@ void octeon2_usb_clocks_start(void)
io_clk_64_to_ns = 64000000000ull / octeon_get_io_clock_rate();
+ if (dev->of_node) {
+ struct device_node *uctl_node;
+ const char *clock_type;
+
+ uctl_node = of_get_parent(dev->of_node);
+ if (!uctl_node) {
+ dev_err(dev, "No UCTL device node\n");
+ goto exit;
+ }
+ i = of_property_read_u32(uctl_node,
+ "refclk-frequency", &clock_rate);
+ if (i) {
+ dev_err(dev, "No UCTL \"refclk-frequency\"\n");
+ goto exit;
+ }
+ i = of_property_read_string(uctl_node,
+ "refclk-type", &clock_type);
+
+ if (!i && strcmp("crystal", clock_type) == 0)
+ is_crystal_clock = true;
+ }
+
/*
* Step 1: Wait for voltages stable. That surely happened
* before starting the kernel.
@@ -66,9 +92,22 @@ void octeon2_usb_clocks_start(void)
cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64);
/* 3b */
- /* 12MHz crystal. */
- clk_rst_ctl.s.p_refclk_sel = 0;
- clk_rst_ctl.s.p_refclk_div = 0;
+ clk_rst_ctl.s.p_refclk_sel = is_crystal_clock ? 0 : 1;
+ switch (clock_rate) {
+ default:
+ pr_err("Invalid UCTL clock rate of %u, using 12000000 instead\n",
+ clock_rate);
+ /* Fall through */
+ case 12000000:
+ clk_rst_ctl.s.p_refclk_div = 0;
+ break;
+ case 24000000:
+ clk_rst_ctl.s.p_refclk_div = 1;
+ break;
+ case 48000000:
+ clk_rst_ctl.s.p_refclk_div = 2;
+ break;
+ }
cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64);
/* 3c */
diff --git a/drivers/usb/host/ohci-octeon.c b/drivers/usb/host/ohci-octeon.c
index 15af895..2127290 100644
--- a/drivers/usb/host/ohci-octeon.c
+++ b/drivers/usb/host/ohci-octeon.c
@@ -19,14 +19,14 @@
#define OCTEON_OHCI_HCD_NAME "octeon-ohci"
/* Common clock init code. */
-void octeon2_usb_clocks_start(void);
+void octeon2_usb_clocks_start(struct device *dev);
void octeon2_usb_clocks_stop(void);
-static void ohci_octeon_hw_start(void)
+static void ohci_octeon_hw_start(struct device *dev)
{
union cvmx_uctlx_ohci_ctl ohci_ctl;
- octeon2_usb_clocks_start();
+ octeon2_usb_clocks_start(dev);
ohci_ctl.u64 = cvmx_read_csr(CVMX_UCTLX_OHCI_CTL(0));
ohci_ctl.s.l2c_addr_msb = 0;
@@ -144,7 +144,7 @@ static int ohci_octeon_drv_probe(struct platform_device *pdev)
goto err1;
}
- ohci_octeon_hw_start();
+ ohci_octeon_hw_start(&pdev->dev);
hcd->regs = reg_base;
@@ -189,6 +189,14 @@ static int ohci_octeon_drv_remove(struct platform_device *pdev)
return 0;
}
+static struct of_device_id ohci_octeon_match[] = {
+ {
+ .compatible = "cavium,octeon-6335-ohci",
+ },
+ {},
+};
+MODULE_DEVICE_TABLE(of, ohci_octeon_match);
+
static struct platform_driver ohci_octeon_driver = {
.probe = ohci_octeon_drv_probe,
.remove = ohci_octeon_drv_remove,
@@ -196,6 +204,7 @@ static struct platform_driver ohci_octeon_driver = {
.driver = {
.name = OCTEON_OHCI_HCD_NAME,
.owner = THIS_MODULE,
+ .of_match_table = ohci_octeon_match,
}
};
--
1.9.3
^ permalink raw reply related [flat|nested] 21+ messages in thread
* Re: [PATCH 3/3] usb host/MIPS: Remove hard-coded OCTEON platform information.
@ 2014-05-29 15:03 ` Alan Stern
0 siblings, 0 replies; 21+ messages in thread
From: Alan Stern @ 2014-05-29 15:03 UTC (permalink / raw)
To: Alex Smith; +Cc: linux-mips, David Daney, linux-usb
On Thu, 29 May 2014, Alex Smith wrote:
> From: David Daney <david.daney@cavium.com>
>
> The device tree will *always* have correct ehci/ohci clock
> configuration, so use it. This allows us to remove a big chunk of
> platform configuration code from octeon-platform.c.
Instead of doing this, how about moving the octeon2_usb_clocks_start()
and _stop() routines into octeon-platform.c, and then using the
ehci-platform and ohci-platform drivers instead of special-purpose
ehci-octeon and ohci-octeon drivers?
Alan Stern
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 3/3] usb host/MIPS: Remove hard-coded OCTEON platform information.
@ 2014-05-29 15:03 ` Alan Stern
0 siblings, 0 replies; 21+ messages in thread
From: Alan Stern @ 2014-05-29 15:03 UTC (permalink / raw)
To: Alex Smith; +Cc: linux-mips, David Daney, linux-usb
On Thu, 29 May 2014, Alex Smith wrote:
> From: David Daney <david.daney@cavium.com>
>
> The device tree will *always* have correct ehci/ohci clock
> configuration, so use it. This allows us to remove a big chunk of
> platform configuration code from octeon-platform.c.
Instead of doing this, how about moving the octeon2_usb_clocks_start()
and _stop() routines into octeon-platform.c, and then using the
ehci-platform and ohci-platform drivers instead of special-purpose
ehci-octeon and ohci-octeon drivers?
Alan Stern
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 3/3] usb host/MIPS: Remove hard-coded OCTEON platform information.
2014-05-29 15:03 ` Alan Stern
(?)
@ 2014-05-29 16:55 ` Florian Fainelli
2014-05-29 17:37 ` Greg KH
-1 siblings, 1 reply; 21+ messages in thread
From: Florian Fainelli @ 2014-05-29 16:55 UTC (permalink / raw)
To: Alan Stern; +Cc: Alex Smith, Linux-MIPS, David Daney, linux-usb
2014-05-29 8:03 GMT-07:00 Alan Stern <stern@rowland.harvard.edu>:
> On Thu, 29 May 2014, Alex Smith wrote:
>
>> From: David Daney <david.daney@cavium.com>
>>
>> The device tree will *always* have correct ehci/ohci clock
>> configuration, so use it. This allows us to remove a big chunk of
>> platform configuration code from octeon-platform.c.
>
> Instead of doing this, how about moving the octeon2_usb_clocks_start()
> and _stop() routines into octeon-platform.c, and then using the
> ehci-platform and ohci-platform drivers instead of special-purpose
> ehci-octeon and ohci-octeon drivers?
How about they get their changes in now, and eventually they cleanup
the octeon driver in the future? My personal experience with that sort
of request, is that I had to come up with 50+ patches to clean up the
Kconfig mess that USB drivers had back then and I still have not
re-submitted the bcm63xx USB patchset.
It is fair to pinpoint what *should* be improved and what the next
steps could look like, it is not fair to ask people submitting changes
to come up with a much bigger task before their patches can be merged.
--
Florian
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 3/3] usb host/MIPS: Remove hard-coded OCTEON platform information.
2014-05-29 16:55 ` Florian Fainelli
@ 2014-05-29 17:37 ` Greg KH
2014-05-29 17:59 ` David Daney
0 siblings, 1 reply; 21+ messages in thread
From: Greg KH @ 2014-05-29 17:37 UTC (permalink / raw)
To: Florian Fainelli
Cc: Alan Stern, Alex Smith, Linux-MIPS, David Daney, linux-usb
On Thu, May 29, 2014 at 09:55:08AM -0700, Florian Fainelli wrote:
> 2014-05-29 8:03 GMT-07:00 Alan Stern <stern@rowland.harvard.edu>:
> > On Thu, 29 May 2014, Alex Smith wrote:
> >
> >> From: David Daney <david.daney@cavium.com>
> >>
> >> The device tree will *always* have correct ehci/ohci clock
> >> configuration, so use it. This allows us to remove a big chunk of
> >> platform configuration code from octeon-platform.c.
> >
> > Instead of doing this, how about moving the octeon2_usb_clocks_start()
> > and _stop() routines into octeon-platform.c, and then using the
> > ehci-platform and ohci-platform drivers instead of special-purpose
> > ehci-octeon and ohci-octeon drivers?
>
> How about they get their changes in now, and eventually they cleanup
> the octeon driver in the future?
Nope, sorry, we don't do that for kernel development, you know that.
> My personal experience with that sort of request, is that I had to
> come up with 50+ patches to clean up the Kconfig mess that USB drivers
> had back then and I still have not re-submitted the bcm63xx USB
> patchset.
Well, that's not our fault you haven't resent them :)
> It is fair to pinpoint what *should* be improved and what the next
> steps could look like, it is not fair to ask people submitting changes
> to come up with a much bigger task before their patches can be merged.
Of course it is, that's how we do Linux development, again, you know
this.
greg k-h
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 3/3] usb host/MIPS: Remove hard-coded OCTEON platform information.
2014-05-29 17:37 ` Greg KH
@ 2014-05-29 17:59 ` David Daney
2014-05-29 20:55 ` Alan Stern
0 siblings, 1 reply; 21+ messages in thread
From: David Daney @ 2014-05-29 17:59 UTC (permalink / raw)
To: Greg KH
Cc: Florian Fainelli, Alan Stern, Alex Smith, Linux-MIPS, David Daney,
linux-usb
On 05/29/2014 10:37 AM, Greg KH wrote:
> On Thu, May 29, 2014 at 09:55:08AM -0700, Florian Fainelli wrote:
>> 2014-05-29 8:03 GMT-07:00 Alan Stern <stern@rowland.harvard.edu>:
>>> On Thu, 29 May 2014, Alex Smith wrote:
>>>
>>>> From: David Daney <david.daney@cavium.com>
>>>>
>>>> The device tree will *always* have correct ehci/ohci clock
>>>> configuration, so use it. This allows us to remove a big chunk of
>>>> platform configuration code from octeon-platform.c.
>>>
>>> Instead of doing this, how about moving the octeon2_usb_clocks_start()
>>> and _stop() routines into octeon-platform.c, and then using the
>>> ehci-platform and ohci-platform drivers instead of special-purpose
>>> ehci-octeon and ohci-octeon drivers?
>>
>> How about they get their changes in now, and eventually they cleanup
>> the octeon driver in the future?
>
> Nope, sorry, we don't do that for kernel development, you know that.
>
>> My personal experience with that sort of request, is that I had to
>> come up with 50+ patches to clean up the Kconfig mess that USB drivers
>> had back then and I still have not re-submitted the bcm63xx USB
>> patchset.
>
> Well, that's not our fault you haven't resent them :)
>
>> It is fair to pinpoint what *should* be improved and what the next
>> steps could look like, it is not fair to ask people submitting changes
>> to come up with a much bigger task before their patches can be merged.
>
> Of course it is, that's how we do Linux development, again, you know
> this.
>
Several points of clarification:
1) I wrote the patch in question, not Florian.
2) I agree that OCTEON ehci/ohci support could probably be refactored
along the lines of Alan's suggestion.
3) This patch is a relatively minor change to an *existing* driver
rather than a completely new thing that hasn't yet been merged.
4) There is a lot of precedent for merging minor enhancements and bug
fixes instead of requiring a complete refactoring of *existing* code.
All that said, I haven't dug into the ehci-platform and ohci-platform
enough to be able to opine on the best course of action in this
particular case. I hope to be able to make a more educated follow-up
next week.
David Daney
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 3/3] usb host/MIPS: Remove hard-coded OCTEON platform information.
2014-05-29 17:59 ` David Daney
@ 2014-05-29 20:55 ` Alan Stern
2014-05-29 21:26 ` David Daney
0 siblings, 1 reply; 21+ messages in thread
From: Alan Stern @ 2014-05-29 20:55 UTC (permalink / raw)
To: David Daney
Cc: Greg KH, Florian Fainelli, Alex Smith, Linux-MIPS, David Daney,
linux-usb
On Thu, 29 May 2014, David Daney wrote:
> Several points of clarification:
>
> 1) I wrote the patch in question, not Florian.
>
> 2) I agree that OCTEON ehci/ohci support could probably be refactored
> along the lines of Alan's suggestion.
>
> 3) This patch is a relatively minor change to an *existing* driver
> rather than a completely new thing that hasn't yet been merged.
>
> 4) There is a lot of precedent for merging minor enhancements and bug
> fixes instead of requiring a complete refactoring of *existing* code.
>
> All that said, I haven't dug into the ehci-platform and ohci-platform
> enough to be able to opine on the best course of action in this
> particular case. I hope to be able to make a more educated follow-up
> next week.
Moving these into the respective platform drivers shouldn't be a big
deal. Below is a totally untested preliminary pass -- I'm pleased that
it removes a lot more lines than it adds.
This first attempt leaves a few matters unresolved:
The EHCI DMA mask is coerced to 32 bits by ehci-platform.c.
Maybe this should be controllable by a flag in the
usb_ehci_pdata structure.
The timing of the calls to octeon_[eo]hci_hw_start() might
be wrong. The patch does it before the memory resources
are mapped, rather than afterward as it is done now. I don't
know if this will matter.
The clock management is awkward at best. But it's about the
same as what we do now.
Anyway, it shouldn't be hard to fix this up and get it working, and
then rebase your patch on top of it.
Alan Stern
arch/mips/cavium-octeon/octeon-platform.c | 274 +++++++++++++++++++++++++++++-
arch/mips/configs/cavium_octeon_defconfig | 3
drivers/usb/host/Kconfig | 18 +
drivers/usb/host/Makefile | 1
drivers/usb/host/ehci-hcd.c | 5
drivers/usb/host/ehci-octeon.c | 188 --------------------
drivers/usb/host/octeon2-common.c | 200 ---------------------
drivers/usb/host/ohci-hcd.c | 5
drivers/usb/host/ohci-octeon.c | 202 ----------------------
9 files changed, 285 insertions(+), 611 deletions(-)
Index: usb-3.15/arch/mips/cavium-octeon/octeon-platform.c
===================================================================
--- usb-3.15.orig/arch/mips/cavium-octeon/octeon-platform.c
+++ usb-3.15/arch/mips/cavium-octeon/octeon-platform.c
@@ -7,22 +7,27 @@
* Copyright (C) 2008 Wind River Systems
*/
+#include <linux/delay.h>
#include <linux/init.h>
#include <linux/irq.h>
#include <linux/i2c.h>
#include <linux/usb.h>
#include <linux/dma-mapping.h>
#include <linux/module.h>
+#include <linux/mutex.h>
#include <linux/slab.h>
#include <linux/platform_device.h>
#include <linux/of_platform.h>
#include <linux/of_fdt.h>
#include <linux/libfdt.h>
+#include <linux/usb/ehci_pdriver.h>
+#include <linux/usb/ohci_pdriver.h>
#include <asm/octeon/octeon.h>
#include <asm/octeon/cvmx-rnm-defs.h>
#include <asm/octeon/cvmx-helper.h>
#include <asm/octeon/cvmx-helper-board.h>
+#include <asm/octeon/cvmx-uctlx-defs.h>
/* Octeon Random Number Generator. */
static int __init octeon_rng_device_init(void)
@@ -68,6 +73,229 @@ device_initcall(octeon_rng_device_init);
#ifdef CONFIG_USB
+static DEFINE_MUTEX(octeon2_usb_clocks_mutex);
+
+static int octeon2_usb_clock_start_cnt;
+
+static void octeon2_usb_clocks_start(void)
+{
+ u64 div;
+ union cvmx_uctlx_if_ena if_ena;
+ union cvmx_uctlx_clk_rst_ctl clk_rst_ctl;
+ union cvmx_uctlx_uphy_ctl_status uphy_ctl_status;
+ union cvmx_uctlx_uphy_portx_ctl_status port_ctl_status;
+ int i;
+ unsigned long io_clk_64_to_ns;
+
+
+ mutex_lock(&octeon2_usb_clocks_mutex);
+
+ octeon2_usb_clock_start_cnt++;
+ if (octeon2_usb_clock_start_cnt != 1)
+ goto exit;
+
+ io_clk_64_to_ns = 64000000000ull / octeon_get_io_clock_rate();
+
+ /*
+ * Step 1: Wait for voltages stable. That surely happened
+ * before starting the kernel.
+ *
+ * Step 2: Enable SCLK of UCTL by writing UCTL0_IF_ENA[EN] = 1
+ */
+ if_ena.u64 = 0;
+ if_ena.s.en = 1;
+ cvmx_write_csr(CVMX_UCTLX_IF_ENA(0), if_ena.u64);
+
+ /* Step 3: Configure the reference clock, PHY, and HCLK */
+ clk_rst_ctl.u64 = cvmx_read_csr(CVMX_UCTLX_CLK_RST_CTL(0));
+
+ /*
+ * If the UCTL looks like it has already been started, skip
+ * the initialization, otherwise bus errors are obtained.
+ */
+ if (clk_rst_ctl.s.hrst)
+ goto end_clock;
+ /* 3a */
+ clk_rst_ctl.s.p_por = 1;
+ clk_rst_ctl.s.hrst = 0;
+ clk_rst_ctl.s.p_prst = 0;
+ clk_rst_ctl.s.h_clkdiv_rst = 0;
+ clk_rst_ctl.s.o_clkdiv_rst = 0;
+ clk_rst_ctl.s.h_clkdiv_en = 0;
+ clk_rst_ctl.s.o_clkdiv_en = 0;
+ cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64);
+
+ /* 3b */
+ /* 12MHz crystal. */
+ clk_rst_ctl.s.p_refclk_sel = 0;
+ clk_rst_ctl.s.p_refclk_div = 0;
+ cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64);
+
+ /* 3c */
+ div = octeon_get_io_clock_rate() / 130000000ull;
+
+ switch (div) {
+ case 0:
+ div = 1;
+ break;
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ break;
+ case 5:
+ div = 4;
+ break;
+ case 6:
+ case 7:
+ div = 6;
+ break;
+ case 8:
+ case 9:
+ case 10:
+ case 11:
+ div = 8;
+ break;
+ default:
+ div = 12;
+ break;
+ }
+ clk_rst_ctl.s.h_div = div;
+ cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64);
+ /* Read it back, */
+ clk_rst_ctl.u64 = cvmx_read_csr(CVMX_UCTLX_CLK_RST_CTL(0));
+ clk_rst_ctl.s.h_clkdiv_en = 1;
+ cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64);
+ /* 3d */
+ clk_rst_ctl.s.h_clkdiv_rst = 1;
+ cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64);
+
+ /* 3e: delay 64 io clocks */
+ ndelay(io_clk_64_to_ns);
+
+ /*
+ * Step 4: Program the power-on reset field in the UCTL
+ * clock-reset-control register.
+ */
+ clk_rst_ctl.s.p_por = 0;
+ cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64);
+
+ /* Step 5: Wait 1 ms for the PHY clock to start. */
+ mdelay(1);
+
+ /*
+ * Step 6: Program the reset input from automatic test
+ * equipment field in the UPHY CSR
+ */
+ uphy_ctl_status.u64 = cvmx_read_csr(CVMX_UCTLX_UPHY_CTL_STATUS(0));
+ uphy_ctl_status.s.ate_reset = 1;
+ cvmx_write_csr(CVMX_UCTLX_UPHY_CTL_STATUS(0), uphy_ctl_status.u64);
+
+ /* Step 7: Wait for at least 10ns. */
+ ndelay(10);
+
+ /* Step 8: Clear the ATE_RESET field in the UPHY CSR. */
+ uphy_ctl_status.s.ate_reset = 0;
+ cvmx_write_csr(CVMX_UCTLX_UPHY_CTL_STATUS(0), uphy_ctl_status.u64);
+
+ /*
+ * Step 9: Wait for at least 20ns for UPHY to output PHY clock
+ * signals and OHCI_CLK48
+ */
+ ndelay(20);
+
+ /* Step 10: Configure the OHCI_CLK48 and OHCI_CLK12 clocks. */
+ /* 10a */
+ clk_rst_ctl.s.o_clkdiv_rst = 1;
+ cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64);
+
+ /* 10b */
+ clk_rst_ctl.s.o_clkdiv_en = 1;
+ cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64);
+
+ /* 10c */
+ ndelay(io_clk_64_to_ns);
+
+ /*
+ * Step 11: Program the PHY reset field:
+ * UCTL0_CLK_RST_CTL[P_PRST] = 1
+ */
+ clk_rst_ctl.s.p_prst = 1;
+ cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64);
+
+ /* Step 12: Wait 1 uS. */
+ udelay(1);
+
+ /* Step 13: Program the HRESET_N field: UCTL0_CLK_RST_CTL[HRST] = 1 */
+ clk_rst_ctl.s.hrst = 1;
+ cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64);
+
+end_clock:
+ /* Now we can set some other registers. */
+
+ for (i = 0; i <= 1; i++) {
+ port_ctl_status.u64 =
+ cvmx_read_csr(CVMX_UCTLX_UPHY_PORTX_CTL_STATUS(i, 0));
+ /* Set txvreftune to 15 to obtain compliant 'eye' diagram. */
+ port_ctl_status.s.txvreftune = 15;
+ port_ctl_status.s.txrisetune = 1;
+ port_ctl_status.s.txpreemphasistune = 1;
+ cvmx_write_csr(CVMX_UCTLX_UPHY_PORTX_CTL_STATUS(i, 0),
+ port_ctl_status.u64);
+ }
+
+ /* Set uSOF cycle period to 60,000 bits. */
+ cvmx_write_csr(CVMX_UCTLX_EHCI_FLA(0), 0x20ull);
+exit:
+ mutex_unlock(&octeon2_usb_clocks_mutex);
+}
+
+static void octeon2_usb_clocks_stop(void)
+{
+ mutex_lock(&octeon2_usb_clocks_mutex);
+ octeon2_usb_clock_start_cnt--;
+ mutex_unlock(&octeon2_usb_clocks_mutex);
+}
+
+static int octeon_ehci_power_on(struct platform_device *pdev)
+{
+ octeon2_usb_clocks_start();
+ return 0;
+}
+
+static void octeon_ehci_power_off(struct platform_device *pdev)
+{
+ octeon2_usb_clocks_stop();
+}
+
+static struct usb_ehci_pdata octeon_ehci_pdata = {
+ /* Octeon EHCI matches CPU endianness. */
+#ifdef __BIG_ENDIAN
+ .big_endian_mmio = 1;
+#endif
+ .power_on = octeon_ehci_power_on;
+ .power_off = octeon_ehci_power_off;
+};
+
+static void __init octeon_ehci_hw_start(void)
+{
+ union cvmx_uctlx_ehci_ctl ehci_ctl;
+
+ octeon2_usb_clocks_start();
+
+ ehci_ctl.u64 = cvmx_read_csr(CVMX_UCTLX_EHCI_CTL(0));
+ /* Use 64-bit addressing. */
+ ehci_ctl.s.ehci_64b_addr_en = 1;
+ ehci_ctl.s.l2c_addr_msb = 0;
+ ehci_ctl.s.l2c_buff_emod = 1; /* Byte swapped. */
+ ehci_ctl.s.l2c_desc_emod = 1; /* Byte swapped. */
+ cvmx_write_csr(CVMX_UCTLX_EHCI_CTL(0), ehci_ctl.u64);
+
+ octeon2_usb_clocks_stop();
+}
+
+static u64 octeon_ehci_dma_mask = DMA_BIT_MASK(64);
+
static int __init octeon_ehci_device_init(void)
{
struct platform_device *pd;
@@ -88,7 +316,7 @@ static int __init octeon_ehci_device_ini
if (octeon_is_simulation() || usb_disabled())
return 0; /* No USB in the simulator. */
- pd = platform_device_alloc("octeon-ehci", 0);
+ pd = platform_device_alloc("ehci-platform", 0);
if (!pd) {
ret = -ENOMEM;
goto out;
@@ -105,6 +333,10 @@ static int __init octeon_ehci_device_ini
if (ret)
goto fail;
+ pd->dev.dma_mask = &octeon_ehci_dma_mask;
+ pd->dev.platform_data = &octeon_ehci_pdata;
+ octeon_ehci_hw_start();
+
ret = platform_device_add(pd);
if (ret)
goto fail;
@@ -117,6 +349,41 @@ out:
}
device_initcall(octeon_ehci_device_init);
+static int octeon_ohci_power_on(struct platform_device *pdev)
+{
+ octeon2_usb_clocks_start();
+ return 0;
+}
+
+static void octeon_ohci_power_off(struct platform_device *pdev)
+{
+ octeon2_usb_clocks_stop();
+}
+
+static struct usb_ohci_pdata octeon_ohci_pdata = {
+ /* Octeon OHCI matches CPU endianness. */
+#ifdef __BIG_ENDIAN
+ .big_endian_mmio = 1;
+#endif
+ .power_on = octeon_ohci_power_on;
+ .power_off = octeon_ohci_power_off;
+};
+
+static void __init octeon_ohci_hw_start(void)
+{
+ union cvmx_uctlx_ohci_ctl ohci_ctl;
+
+ octeon2_usb_clocks_start();
+
+ ohci_ctl.u64 = cvmx_read_csr(CVMX_UCTLX_OHCI_CTL(0));
+ ohci_ctl.s.l2c_addr_msb = 0;
+ ohci_ctl.s.l2c_buff_emod = 1; /* Byte swapped. */
+ ohci_ctl.s.l2c_desc_emod = 1; /* Byte swapped. */
+ cvmx_write_csr(CVMX_UCTLX_OHCI_CTL(0), ohci_ctl.u64);
+
+ octeon2_usb_clocks_stop();
+}
+
static int __init octeon_ohci_device_init(void)
{
struct platform_device *pd;
@@ -137,7 +404,7 @@ static int __init octeon_ohci_device_ini
if (octeon_is_simulation() || usb_disabled())
return 0; /* No USB in the simulator. */
- pd = platform_device_alloc("octeon-ohci", 0);
+ pd = platform_device_alloc("ohci-platform", 0);
if (!pd) {
ret = -ENOMEM;
goto out;
@@ -154,6 +421,9 @@ static int __init octeon_ohci_device_ini
if (ret)
goto fail;
+ pd->dev.platform_data = &octeon_ohci_pdata;
+ octeon_ohci_hw_start();
+
ret = platform_device_add(pd);
if (ret)
goto fail;
Index: usb-3.15/arch/mips/configs/cavium_octeon_defconfig
===================================================================
--- usb-3.15.orig/arch/mips/configs/cavium_octeon_defconfig
+++ usb-3.15/arch/mips/configs/cavium_octeon_defconfig
@@ -120,6 +120,9 @@ CONFIG_SPI_OCTEON=y
# CONFIG_HWMON is not set
CONFIG_WATCHDOG=y
# CONFIG_USB_SUPPORT is not set
+CONFIG_USB_EHCI_BIG_ENDIAN_MMIO=y
+CONFIG_USB_OHCI_BIG_ENDIAN_MMIO=y
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
CONFIG_RTC_CLASS=y
CONFIG_RTC_DRV_DS1307=y
CONFIG_STAGING=y
Index: usb-3.15/drivers/usb/host/Makefile
===================================================================
--- usb-3.15.orig/drivers/usb/host/Makefile
+++ usb-3.15/drivers/usb/host/Makefile
@@ -65,7 +65,6 @@ obj-$(CONFIG_USB_ISP1760_HCD) += isp1760
obj-$(CONFIG_USB_HWA_HCD) += hwa-hc.o
obj-$(CONFIG_USB_IMX21_HCD) += imx21-hcd.o
obj-$(CONFIG_USB_FSL_MPH_DR_OF) += fsl-mph-dr-of.o
-obj-$(CONFIG_USB_OCTEON2_COMMON) += octeon2-common.o
obj-$(CONFIG_USB_HCD_BCMA) += bcma-hcd.o
obj-$(CONFIG_USB_HCD_SSB) += ssb-hcd.o
obj-$(CONFIG_USB_FUSBH200_HCD) += fusbh200-hcd.o
Index: usb-3.15/drivers/usb/host/ehci-hcd.c
===================================================================
--- usb-3.15.orig/drivers/usb/host/ehci-hcd.c
+++ usb-3.15/drivers/usb/host/ehci-hcd.c
@@ -1270,11 +1270,6 @@ MODULE_LICENSE ("GPL");
#define XILINX_OF_PLATFORM_DRIVER ehci_hcd_xilinx_of_driver
#endif
-#ifdef CONFIG_USB_OCTEON_EHCI
-#include "ehci-octeon.c"
-#define PLATFORM_DRIVER ehci_octeon_driver
-#endif
-
#ifdef CONFIG_TILE_USB
#include "ehci-tilegx.c"
#define PLATFORM_DRIVER ehci_hcd_tilegx_driver
Index: usb-3.15/drivers/usb/host/ehci-octeon.c
===================================================================
--- usb-3.15.orig/drivers/usb/host/ehci-octeon.c
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- * EHCI HCD glue for Cavium Octeon II SOCs.
- *
- * Loosely based on ehci-au1xxx.c
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2010 Cavium Networks
- *
- */
-
-#include <linux/platform_device.h>
-
-#include <asm/octeon/octeon.h>
-#include <asm/octeon/cvmx-uctlx-defs.h>
-
-#define OCTEON_EHCI_HCD_NAME "octeon-ehci"
-
-/* Common clock init code. */
-void octeon2_usb_clocks_start(void);
-void octeon2_usb_clocks_stop(void);
-
-static void ehci_octeon_start(void)
-{
- union cvmx_uctlx_ehci_ctl ehci_ctl;
-
- octeon2_usb_clocks_start();
-
- ehci_ctl.u64 = cvmx_read_csr(CVMX_UCTLX_EHCI_CTL(0));
- /* Use 64-bit addressing. */
- ehci_ctl.s.ehci_64b_addr_en = 1;
- ehci_ctl.s.l2c_addr_msb = 0;
- ehci_ctl.s.l2c_buff_emod = 1; /* Byte swapped. */
- ehci_ctl.s.l2c_desc_emod = 1; /* Byte swapped. */
- cvmx_write_csr(CVMX_UCTLX_EHCI_CTL(0), ehci_ctl.u64);
-}
-
-static void ehci_octeon_stop(void)
-{
- octeon2_usb_clocks_stop();
-}
-
-static const struct hc_driver ehci_octeon_hc_driver = {
- .description = hcd_name,
- .product_desc = "Octeon EHCI",
- .hcd_priv_size = sizeof(struct ehci_hcd),
-
- /*
- * generic hardware linkage
- */
- .irq = ehci_irq,
- .flags = HCD_MEMORY | HCD_USB2 | HCD_BH,
-
- /*
- * basic lifecycle operations
- */
- .reset = ehci_setup,
- .start = ehci_run,
- .stop = ehci_stop,
- .shutdown = ehci_shutdown,
-
- /*
- * managing i/o requests and associated device resources
- */
- .urb_enqueue = ehci_urb_enqueue,
- .urb_dequeue = ehci_urb_dequeue,
- .endpoint_disable = ehci_endpoint_disable,
- .endpoint_reset = ehci_endpoint_reset,
-
- /*
- * scheduling support
- */
- .get_frame_number = ehci_get_frame,
-
- /*
- * root hub support
- */
- .hub_status_data = ehci_hub_status_data,
- .hub_control = ehci_hub_control,
- .bus_suspend = ehci_bus_suspend,
- .bus_resume = ehci_bus_resume,
- .relinquish_port = ehci_relinquish_port,
- .port_handed_over = ehci_port_handed_over,
-
- .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
-};
-
-static u64 ehci_octeon_dma_mask = DMA_BIT_MASK(64);
-
-static int ehci_octeon_drv_probe(struct platform_device *pdev)
-{
- struct usb_hcd *hcd;
- struct ehci_hcd *ehci;
- struct resource *res_mem;
- int irq;
- int ret;
-
- if (usb_disabled())
- return -ENODEV;
-
- irq = platform_get_irq(pdev, 0);
- if (irq < 0) {
- dev_err(&pdev->dev, "No irq assigned\n");
- return -ENODEV;
- }
-
- res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (res_mem == NULL) {
- dev_err(&pdev->dev, "No register space assigned\n");
- return -ENODEV;
- }
-
- /*
- * We can DMA from anywhere. But the descriptors must be in
- * the lower 4GB.
- */
- pdev->dev.dma_mask = &ehci_octeon_dma_mask;
- ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
- if (ret)
- return ret;
-
- hcd = usb_create_hcd(&ehci_octeon_hc_driver, &pdev->dev, "octeon");
- if (!hcd)
- return -ENOMEM;
-
- hcd->rsrc_start = res_mem->start;
- hcd->rsrc_len = resource_size(res_mem);
-
- hcd->regs = devm_ioremap_resource(&pdev->dev, res_mem);
- if (IS_ERR(hcd->regs)) {
- ret = PTR_ERR(hcd->regs);
- goto err1;
- }
-
- ehci_octeon_start();
-
- ehci = hcd_to_ehci(hcd);
-
- /* Octeon EHCI matches CPU endianness. */
-#ifdef __BIG_ENDIAN
- ehci->big_endian_mmio = 1;
-#endif
-
- ehci->caps = hcd->regs;
-
- ret = usb_add_hcd(hcd, irq, IRQF_SHARED);
- if (ret) {
- dev_dbg(&pdev->dev, "failed to add hcd with err %d\n", ret);
- goto err2;
- }
- device_wakeup_enable(hcd->self.controller);
-
- platform_set_drvdata(pdev, hcd);
-
- return 0;
-err2:
- ehci_octeon_stop();
-
-err1:
- usb_put_hcd(hcd);
- return ret;
-}
-
-static int ehci_octeon_drv_remove(struct platform_device *pdev)
-{
- struct usb_hcd *hcd = platform_get_drvdata(pdev);
-
- usb_remove_hcd(hcd);
-
- ehci_octeon_stop();
- usb_put_hcd(hcd);
-
- return 0;
-}
-
-static struct platform_driver ehci_octeon_driver = {
- .probe = ehci_octeon_drv_probe,
- .remove = ehci_octeon_drv_remove,
- .shutdown = usb_hcd_platform_shutdown,
- .driver = {
- .name = OCTEON_EHCI_HCD_NAME,
- .owner = THIS_MODULE,
- }
-};
-
-MODULE_ALIAS("platform:" OCTEON_EHCI_HCD_NAME);
Index: usb-3.15/drivers/usb/host/octeon2-common.c
===================================================================
--- usb-3.15.orig/drivers/usb/host/octeon2-common.c
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2010, 2011 Cavium Networks
- */
-
-#include <linux/module.h>
-#include <linux/mutex.h>
-#include <linux/delay.h>
-
-#include <asm/octeon/octeon.h>
-#include <asm/octeon/cvmx-uctlx-defs.h>
-
-static DEFINE_MUTEX(octeon2_usb_clocks_mutex);
-
-static int octeon2_usb_clock_start_cnt;
-
-void octeon2_usb_clocks_start(void)
-{
- u64 div;
- union cvmx_uctlx_if_ena if_ena;
- union cvmx_uctlx_clk_rst_ctl clk_rst_ctl;
- union cvmx_uctlx_uphy_ctl_status uphy_ctl_status;
- union cvmx_uctlx_uphy_portx_ctl_status port_ctl_status;
- int i;
- unsigned long io_clk_64_to_ns;
-
-
- mutex_lock(&octeon2_usb_clocks_mutex);
-
- octeon2_usb_clock_start_cnt++;
- if (octeon2_usb_clock_start_cnt != 1)
- goto exit;
-
- io_clk_64_to_ns = 64000000000ull / octeon_get_io_clock_rate();
-
- /*
- * Step 1: Wait for voltages stable. That surely happened
- * before starting the kernel.
- *
- * Step 2: Enable SCLK of UCTL by writing UCTL0_IF_ENA[EN] = 1
- */
- if_ena.u64 = 0;
- if_ena.s.en = 1;
- cvmx_write_csr(CVMX_UCTLX_IF_ENA(0), if_ena.u64);
-
- /* Step 3: Configure the reference clock, PHY, and HCLK */
- clk_rst_ctl.u64 = cvmx_read_csr(CVMX_UCTLX_CLK_RST_CTL(0));
-
- /*
- * If the UCTL looks like it has already been started, skip
- * the initialization, otherwise bus errors are obtained.
- */
- if (clk_rst_ctl.s.hrst)
- goto end_clock;
- /* 3a */
- clk_rst_ctl.s.p_por = 1;
- clk_rst_ctl.s.hrst = 0;
- clk_rst_ctl.s.p_prst = 0;
- clk_rst_ctl.s.h_clkdiv_rst = 0;
- clk_rst_ctl.s.o_clkdiv_rst = 0;
- clk_rst_ctl.s.h_clkdiv_en = 0;
- clk_rst_ctl.s.o_clkdiv_en = 0;
- cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64);
-
- /* 3b */
- /* 12MHz crystal. */
- clk_rst_ctl.s.p_refclk_sel = 0;
- clk_rst_ctl.s.p_refclk_div = 0;
- cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64);
-
- /* 3c */
- div = octeon_get_io_clock_rate() / 130000000ull;
-
- switch (div) {
- case 0:
- div = 1;
- break;
- case 1:
- case 2:
- case 3:
- case 4:
- break;
- case 5:
- div = 4;
- break;
- case 6:
- case 7:
- div = 6;
- break;
- case 8:
- case 9:
- case 10:
- case 11:
- div = 8;
- break;
- default:
- div = 12;
- break;
- }
- clk_rst_ctl.s.h_div = div;
- cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64);
- /* Read it back, */
- clk_rst_ctl.u64 = cvmx_read_csr(CVMX_UCTLX_CLK_RST_CTL(0));
- clk_rst_ctl.s.h_clkdiv_en = 1;
- cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64);
- /* 3d */
- clk_rst_ctl.s.h_clkdiv_rst = 1;
- cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64);
-
- /* 3e: delay 64 io clocks */
- ndelay(io_clk_64_to_ns);
-
- /*
- * Step 4: Program the power-on reset field in the UCTL
- * clock-reset-control register.
- */
- clk_rst_ctl.s.p_por = 0;
- cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64);
-
- /* Step 5: Wait 1 ms for the PHY clock to start. */
- mdelay(1);
-
- /*
- * Step 6: Program the reset input from automatic test
- * equipment field in the UPHY CSR
- */
- uphy_ctl_status.u64 = cvmx_read_csr(CVMX_UCTLX_UPHY_CTL_STATUS(0));
- uphy_ctl_status.s.ate_reset = 1;
- cvmx_write_csr(CVMX_UCTLX_UPHY_CTL_STATUS(0), uphy_ctl_status.u64);
-
- /* Step 7: Wait for at least 10ns. */
- ndelay(10);
-
- /* Step 8: Clear the ATE_RESET field in the UPHY CSR. */
- uphy_ctl_status.s.ate_reset = 0;
- cvmx_write_csr(CVMX_UCTLX_UPHY_CTL_STATUS(0), uphy_ctl_status.u64);
-
- /*
- * Step 9: Wait for at least 20ns for UPHY to output PHY clock
- * signals and OHCI_CLK48
- */
- ndelay(20);
-
- /* Step 10: Configure the OHCI_CLK48 and OHCI_CLK12 clocks. */
- /* 10a */
- clk_rst_ctl.s.o_clkdiv_rst = 1;
- cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64);
-
- /* 10b */
- clk_rst_ctl.s.o_clkdiv_en = 1;
- cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64);
-
- /* 10c */
- ndelay(io_clk_64_to_ns);
-
- /*
- * Step 11: Program the PHY reset field:
- * UCTL0_CLK_RST_CTL[P_PRST] = 1
- */
- clk_rst_ctl.s.p_prst = 1;
- cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64);
-
- /* Step 12: Wait 1 uS. */
- udelay(1);
-
- /* Step 13: Program the HRESET_N field: UCTL0_CLK_RST_CTL[HRST] = 1 */
- clk_rst_ctl.s.hrst = 1;
- cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64);
-
-end_clock:
- /* Now we can set some other registers. */
-
- for (i = 0; i <= 1; i++) {
- port_ctl_status.u64 =
- cvmx_read_csr(CVMX_UCTLX_UPHY_PORTX_CTL_STATUS(i, 0));
- /* Set txvreftune to 15 to obtain compliant 'eye' diagram. */
- port_ctl_status.s.txvreftune = 15;
- port_ctl_status.s.txrisetune = 1;
- port_ctl_status.s.txpreemphasistune = 1;
- cvmx_write_csr(CVMX_UCTLX_UPHY_PORTX_CTL_STATUS(i, 0),
- port_ctl_status.u64);
- }
-
- /* Set uSOF cycle period to 60,000 bits. */
- cvmx_write_csr(CVMX_UCTLX_EHCI_FLA(0), 0x20ull);
-exit:
- mutex_unlock(&octeon2_usb_clocks_mutex);
-}
-EXPORT_SYMBOL(octeon2_usb_clocks_start);
-
-void octeon2_usb_clocks_stop(void)
-{
- mutex_lock(&octeon2_usb_clocks_mutex);
- octeon2_usb_clock_start_cnt--;
- mutex_unlock(&octeon2_usb_clocks_mutex);
-}
-EXPORT_SYMBOL(octeon2_usb_clocks_stop);
Index: usb-3.15/drivers/usb/host/ohci-hcd.c
===================================================================
--- usb-3.15.orig/drivers/usb/host/ohci-hcd.c
+++ usb-3.15/drivers/usb/host/ohci-hcd.c
@@ -1208,11 +1208,6 @@ MODULE_LICENSE ("GPL");
#define PLATFORM_DRIVER ohci_hcd_jz4740_driver
#endif
-#ifdef CONFIG_USB_OCTEON_OHCI
-#include "ohci-octeon.c"
-#define PLATFORM_DRIVER ohci_octeon_driver
-#endif
-
#ifdef CONFIG_TILE_USB
#include "ohci-tilegx.c"
#define PLATFORM_DRIVER ohci_hcd_tilegx_driver
Index: usb-3.15/drivers/usb/host/ohci-octeon.c
===================================================================
--- usb-3.15.orig/drivers/usb/host/ohci-octeon.c
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * EHCI HCD glue for Cavium Octeon II SOCs.
- *
- * Loosely based on ehci-au1xxx.c
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2010 Cavium Networks
- *
- */
-
-#include <linux/platform_device.h>
-
-#include <asm/octeon/octeon.h>
-#include <asm/octeon/cvmx-uctlx-defs.h>
-
-#define OCTEON_OHCI_HCD_NAME "octeon-ohci"
-
-/* Common clock init code. */
-void octeon2_usb_clocks_start(void);
-void octeon2_usb_clocks_stop(void);
-
-static void ohci_octeon_hw_start(void)
-{
- union cvmx_uctlx_ohci_ctl ohci_ctl;
-
- octeon2_usb_clocks_start();
-
- ohci_ctl.u64 = cvmx_read_csr(CVMX_UCTLX_OHCI_CTL(0));
- ohci_ctl.s.l2c_addr_msb = 0;
- ohci_ctl.s.l2c_buff_emod = 1; /* Byte swapped. */
- ohci_ctl.s.l2c_desc_emod = 1; /* Byte swapped. */
- cvmx_write_csr(CVMX_UCTLX_OHCI_CTL(0), ohci_ctl.u64);
-
-}
-
-static void ohci_octeon_hw_stop(void)
-{
- /* Undo ohci_octeon_start() */
- octeon2_usb_clocks_stop();
-}
-
-static int ohci_octeon_start(struct usb_hcd *hcd)
-{
- struct ohci_hcd *ohci = hcd_to_ohci(hcd);
- int ret;
-
- ret = ohci_init(ohci);
-
- if (ret < 0)
- return ret;
-
- ret = ohci_run(ohci);
-
- if (ret < 0) {
- ohci_err(ohci, "can't start %s", hcd->self.bus_name);
- ohci_stop(hcd);
- return ret;
- }
-
- return 0;
-}
-
-static const struct hc_driver ohci_octeon_hc_driver = {
- .description = hcd_name,
- .product_desc = "Octeon OHCI",
- .hcd_priv_size = sizeof(struct ohci_hcd),
-
- /*
- * generic hardware linkage
- */
- .irq = ohci_irq,
- .flags = HCD_USB11 | HCD_MEMORY,
-
- /*
- * basic lifecycle operations
- */
- .start = ohci_octeon_start,
- .stop = ohci_stop,
- .shutdown = ohci_shutdown,
-
- /*
- * managing i/o requests and associated device resources
- */
- .urb_enqueue = ohci_urb_enqueue,
- .urb_dequeue = ohci_urb_dequeue,
- .endpoint_disable = ohci_endpoint_disable,
-
- /*
- * scheduling support
- */
- .get_frame_number = ohci_get_frame,
-
- /*
- * root hub support
- */
- .hub_status_data = ohci_hub_status_data,
- .hub_control = ohci_hub_control,
-
- .start_port_reset = ohci_start_port_reset,
-};
-
-static int ohci_octeon_drv_probe(struct platform_device *pdev)
-{
- struct usb_hcd *hcd;
- struct ohci_hcd *ohci;
- void *reg_base;
- struct resource *res_mem;
- int irq;
- int ret;
-
- if (usb_disabled())
- return -ENODEV;
-
- irq = platform_get_irq(pdev, 0);
- if (irq < 0) {
- dev_err(&pdev->dev, "No irq assigned\n");
- return -ENODEV;
- }
-
- res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (res_mem == NULL) {
- dev_err(&pdev->dev, "No register space assigned\n");
- return -ENODEV;
- }
-
- /* Ohci is a 32-bit device. */
- ret = dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
- if (ret)
- return ret;
-
- hcd = usb_create_hcd(&ohci_octeon_hc_driver, &pdev->dev, "octeon");
- if (!hcd)
- return -ENOMEM;
-
- hcd->rsrc_start = res_mem->start;
- hcd->rsrc_len = resource_size(res_mem);
-
- reg_base = devm_ioremap_resource(&pdev->dev, res_mem);
- if (IS_ERR(reg_base)) {
- ret = PTR_ERR(reg_base);
- goto err1;
- }
-
- ohci_octeon_hw_start();
-
- hcd->regs = reg_base;
-
- ohci = hcd_to_ohci(hcd);
-
- /* Octeon OHCI matches CPU endianness. */
-#ifdef __BIG_ENDIAN
- ohci->flags |= OHCI_QUIRK_BE_MMIO;
-#endif
-
- ohci_hcd_init(ohci);
-
- ret = usb_add_hcd(hcd, irq, IRQF_SHARED);
- if (ret) {
- dev_dbg(&pdev->dev, "failed to add hcd with err %d\n", ret);
- goto err2;
- }
-
- device_wakeup_enable(hcd->self.controller);
-
- platform_set_drvdata(pdev, hcd);
-
- return 0;
-
-err2:
- ohci_octeon_hw_stop();
-
-err1:
- usb_put_hcd(hcd);
- return ret;
-}
-
-static int ohci_octeon_drv_remove(struct platform_device *pdev)
-{
- struct usb_hcd *hcd = platform_get_drvdata(pdev);
-
- usb_remove_hcd(hcd);
-
- ohci_octeon_hw_stop();
- usb_put_hcd(hcd);
-
- return 0;
-}
-
-static struct platform_driver ohci_octeon_driver = {
- .probe = ohci_octeon_drv_probe,
- .remove = ohci_octeon_drv_remove,
- .shutdown = usb_hcd_platform_shutdown,
- .driver = {
- .name = OCTEON_OHCI_HCD_NAME,
- .owner = THIS_MODULE,
- }
-};
-
-MODULE_ALIAS("platform:" OCTEON_OHCI_HCD_NAME);
Index: usb-3.15/drivers/usb/host/Kconfig
===================================================================
--- usb-3.15.orig/drivers/usb/host/Kconfig
+++ usb-3.15/drivers/usb/host/Kconfig
@@ -263,11 +263,15 @@ config USB_EHCI_HCD_PLATFORM
If unsure, say N.
config USB_OCTEON_EHCI
- bool "Octeon on-chip EHCI support"
+ bool "Octeon on-chip EHCI support (DEPRECATED)"
depends on CAVIUM_OCTEON_SOC
default n
select USB_EHCI_BIG_ENDIAN_MMIO
+ select USB_EHCI_HCD_PLATFORM
help
+ This option is deprecated now and the driver was removed, use
+ USB_EHCI_HCD_PLATFORM instead.
+
Enable support for the Octeon II SOC's on-chip EHCI
controller. It is needed for high-speed (480Mbit/sec)
USB 2.0 device support. All CN6XXX based chips with USB are
@@ -516,12 +520,16 @@ config USB_OHCI_HCD_PLATFORM
If unsure, say N.
config USB_OCTEON_OHCI
- bool "Octeon on-chip OHCI support"
+ bool "Octeon on-chip OHCI support (DEPRECATED)"
depends on CAVIUM_OCTEON_SOC
default USB_OCTEON_EHCI
select USB_OHCI_BIG_ENDIAN_MMIO
select USB_OHCI_LITTLE_ENDIAN
+ select USB_OHCI_HCD_PLATFORM
help
+ This option is deprecated now and the driver was removed, use
+ USB_OHCI_HCD_PLATFORM instead.
+
Enable support for the Octeon II SOC's on-chip OHCI
controller. It is needed for low-speed USB 1.0 device
support. All CN6XXX based chips with USB are supported.
@@ -695,12 +703,6 @@ config USB_IMX21_HCD
To compile this driver as a module, choose M here: the
module will be called "imx21-hcd".
-
-
-config USB_OCTEON2_COMMON
- bool
- default y if USB_OCTEON_EHCI || USB_OCTEON_OHCI
-
config USB_HCD_BCMA
tristate "BCMA usb host driver"
depends on BCMA
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 3/3] usb host/MIPS: Remove hard-coded OCTEON platform information.
2014-05-29 20:55 ` Alan Stern
@ 2014-05-29 21:26 ` David Daney
0 siblings, 0 replies; 21+ messages in thread
From: David Daney @ 2014-05-29 21:26 UTC (permalink / raw)
To: Alan Stern
Cc: Greg KH, Florian Fainelli, Alex Smith, Linux-MIPS, David Daney,
linux-usb
On 05/29/2014 01:55 PM, Alan Stern wrote:
> On Thu, 29 May 2014, David Daney wrote:
>
>> Several points of clarification:
>>
>> 1) I wrote the patch in question, not Florian.
>>
>> 2) I agree that OCTEON ehci/ohci support could probably be refactored
>> along the lines of Alan's suggestion.
>>
>> 3) This patch is a relatively minor change to an *existing* driver
>> rather than a completely new thing that hasn't yet been merged.
>>
>> 4) There is a lot of precedent for merging minor enhancements and bug
>> fixes instead of requiring a complete refactoring of *existing* code.
>>
>> All that said, I haven't dug into the ehci-platform and ohci-platform
>> enough to be able to opine on the best course of action in this
>> particular case. I hope to be able to make a more educated follow-up
>> next week.
>
> Moving these into the respective platform drivers shouldn't be a big
> deal. Below is a totally untested preliminary pass -- I'm pleased that
> it removes a lot more lines than it adds.
>
> This first attempt leaves a few matters unresolved:
>
> The EHCI DMA mask is coerced to 32 bits by ehci-platform.c.
> Maybe this should be controllable by a flag in the
> usb_ehci_pdata structure.
>
> The timing of the calls to octeon_[eo]hci_hw_start() might
> be wrong. The patch does it before the memory resources
> are mapped, rather than afterward as it is done now. I don't
> know if this will matter.
>
> The clock management is awkward at best. But it's about the
> same as what we do now.
>
> Anyway, it shouldn't be hard to fix this up and get it working, and
> then rebase your patch on top of it.
>
> Alan Stern
>
>
>
> arch/mips/cavium-octeon/octeon-platform.c | 274 +++++++++++++++++++++++++++++-
> arch/mips/configs/cavium_octeon_defconfig | 3
> drivers/usb/host/Kconfig | 18 +
> drivers/usb/host/Makefile | 1
> drivers/usb/host/ehci-hcd.c | 5
> drivers/usb/host/ehci-octeon.c | 188 --------------------
> drivers/usb/host/octeon2-common.c | 200 ---------------------
> drivers/usb/host/ohci-hcd.c | 5
> drivers/usb/host/ohci-octeon.c | 202 ----------------------
> 9 files changed, 285 insertions(+), 611 deletions(-)
>
Thanks Alan,
That goes beyond the call of duty!
I will try to test (and improve if necessary) this patch.
David Daney
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [1/3] MIPS: octeon: Add interface mode detection for Octeon II
2014-05-29 10:10 ` Alex Smith
(?)
@ 2014-06-04 14:47 ` Aaro Koskinen
2014-06-04 15:58 ` Alex Smith
-1 siblings, 1 reply; 21+ messages in thread
From: Aaro Koskinen @ 2014-06-04 14:47 UTC (permalink / raw)
To: Alex Smith, David Daney; +Cc: linux-mips
On Thu, May 29, 2014 at 11:10:01AM +0100, Alex Smith wrote:
> Add interface mode detection for Octeon II. This is necessary to detect
> the interface modes correctly on the UBNT E200 board. Code is taken
> from the UBNT GPL source release, with some alterations: SRIO, ILK and
> RXAUI interface modes are removed and instead return disabled as these
> modes are not currently supported.
>
> Tested-by: David Daney <david.daney@cavium.com>
> Signed-off-by: Alex Smith <alex.smith@imgtec.com>
I tried booting ebb6800 board with these patches.
It hangs somewhere in __cvmx_helper_xaui_enable() with XAUI port. Looking
at the UBNT GPL package, xaui init is quite different with 68XX specific
code paths. Maybe those bits should be added too, or then disable XAUI
support as well?
A.
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [1/3] MIPS: octeon: Add interface mode detection for Octeon II
@ 2014-06-04 15:58 ` Alex Smith
0 siblings, 0 replies; 21+ messages in thread
From: Alex Smith @ 2014-06-04 15:58 UTC (permalink / raw)
To: Aaro Koskinen, David Daney; +Cc: linux-mips
On 04/06/14 15:47, Aaro Koskinen wrote:
> On Thu, May 29, 2014 at 11:10:01AM +0100, Alex Smith wrote:
>> Add interface mode detection for Octeon II. This is necessary to detect
>> the interface modes correctly on the UBNT E200 board. Code is taken
>> from the UBNT GPL source release, with some alterations: SRIO, ILK and
>> RXAUI interface modes are removed and instead return disabled as these
>> modes are not currently supported.
>>
>> Tested-by: David Daney <david.daney@cavium.com>
>> Signed-off-by: Alex Smith <alex.smith@imgtec.com>
>
> I tried booting ebb6800 board with these patches.
>
> It hangs somewhere in __cvmx_helper_xaui_enable() with XAUI port. Looking
> at the UBNT GPL package, xaui init is quite different with 68XX specific
> code paths. Maybe those bits should be added too, or then disable XAUI
> support as well?
Probably the best thing to do for now would be to disable it. Does it
boot successfully for you if you switch CVMX_HELPER_INTERFACE_MODE_XAUI
to disabled?
Alex
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [1/3] MIPS: octeon: Add interface mode detection for Octeon II
@ 2014-06-04 15:58 ` Alex Smith
0 siblings, 0 replies; 21+ messages in thread
From: Alex Smith @ 2014-06-04 15:58 UTC (permalink / raw)
To: Aaro Koskinen, David Daney; +Cc: linux-mips
On 04/06/14 15:47, Aaro Koskinen wrote:
> On Thu, May 29, 2014 at 11:10:01AM +0100, Alex Smith wrote:
>> Add interface mode detection for Octeon II. This is necessary to detect
>> the interface modes correctly on the UBNT E200 board. Code is taken
>> from the UBNT GPL source release, with some alterations: SRIO, ILK and
>> RXAUI interface modes are removed and instead return disabled as these
>> modes are not currently supported.
>>
>> Tested-by: David Daney <david.daney@cavium.com>
>> Signed-off-by: Alex Smith <alex.smith@imgtec.com>
>
> I tried booting ebb6800 board with these patches.
>
> It hangs somewhere in __cvmx_helper_xaui_enable() with XAUI port. Looking
> at the UBNT GPL package, xaui init is quite different with 68XX specific
> code paths. Maybe those bits should be added too, or then disable XAUI
> support as well?
Probably the best thing to do for now would be to disable it. Does it
boot successfully for you if you switch CVMX_HELPER_INTERFACE_MODE_XAUI
to disabled?
Alex
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [1/3] MIPS: octeon: Add interface mode detection for Octeon II
@ 2014-06-04 17:12 ` David Daney
0 siblings, 0 replies; 21+ messages in thread
From: David Daney @ 2014-06-04 17:12 UTC (permalink / raw)
To: Alex Smith; +Cc: Aaro Koskinen, David Daney, linux-mips
On 06/04/2014 08:58 AM, Alex Smith wrote:
> On 04/06/14 15:47, Aaro Koskinen wrote:
>> On Thu, May 29, 2014 at 11:10:01AM +0100, Alex Smith wrote:
>>> Add interface mode detection for Octeon II. This is necessary to detect
>>> the interface modes correctly on the UBNT E200 board. Code is taken
>>> from the UBNT GPL source release, with some alterations: SRIO, ILK and
>>> RXAUI interface modes are removed and instead return disabled as these
>>> modes are not currently supported.
>>>
>>> Tested-by: David Daney <david.daney@cavium.com>
>>> Signed-off-by: Alex Smith <alex.smith@imgtec.com>
>>
>> I tried booting ebb6800 board with these patches.
There seem to be problems (I think in the interrupt controller code) for
cn68xx based systems in the kernel.org kernel. So I couldn't get it to
boot on my ebb6800 even to the point it tries to initialize the
networking hardware.
Therefore ...
>>
>> It hangs somewhere in __cvmx_helper_xaui_enable() with XAUI port. Looking
>> at the UBNT GPL package, xaui init is quite different with 68XX specific
>> code paths. Maybe those bits should be added too, or then disable XAUI
>> support as well?
>
> Probably the best thing to do for now would be to disable it. Does it
> boot successfully for you if you switch CVMX_HELPER_INTERFACE_MODE_XAUI
> to disabled?
... I don't think it matters. The patch Alex et al. came up with is an
improvement over what is already there. The fact that there are still
some configurations that don't work can be addressed with follow-on patches.
If I misunderstand the situation, please let me know, and we can work
towards something better.
David Daney
>
> Alex
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [1/3] MIPS: octeon: Add interface mode detection for Octeon II
@ 2014-06-04 17:12 ` David Daney
0 siblings, 0 replies; 21+ messages in thread
From: David Daney @ 2014-06-04 17:12 UTC (permalink / raw)
To: Alex Smith; +Cc: Aaro Koskinen, David Daney, linux-mips
On 06/04/2014 08:58 AM, Alex Smith wrote:
> On 04/06/14 15:47, Aaro Koskinen wrote:
>> On Thu, May 29, 2014 at 11:10:01AM +0100, Alex Smith wrote:
>>> Add interface mode detection for Octeon II. This is necessary to detect
>>> the interface modes correctly on the UBNT E200 board. Code is taken
>>> from the UBNT GPL source release, with some alterations: SRIO, ILK and
>>> RXAUI interface modes are removed and instead return disabled as these
>>> modes are not currently supported.
>>>
>>> Tested-by: David Daney <david.daney@cavium.com>
>>> Signed-off-by: Alex Smith <alex.smith@imgtec.com>
>>
>> I tried booting ebb6800 board with these patches.
There seem to be problems (I think in the interrupt controller code) for
cn68xx based systems in the kernel.org kernel. So I couldn't get it to
boot on my ebb6800 even to the point it tries to initialize the
networking hardware.
Therefore ...
>>
>> It hangs somewhere in __cvmx_helper_xaui_enable() with XAUI port. Looking
>> at the UBNT GPL package, xaui init is quite different with 68XX specific
>> code paths. Maybe those bits should be added too, or then disable XAUI
>> support as well?
>
> Probably the best thing to do for now would be to disable it. Does it
> boot successfully for you if you switch CVMX_HELPER_INTERFACE_MODE_XAUI
> to disabled?
... I don't think it matters. The patch Alex et al. came up with is an
improvement over what is already there. The fact that there are still
some configurations that don't work can be addressed with follow-on patches.
If I misunderstand the situation, please let me know, and we can work
towards something better.
David Daney
>
> Alex
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [1/3] MIPS: octeon: Add interface mode detection for Octeon II
2014-06-04 17:12 ` David Daney
(?)
@ 2014-06-04 18:53 ` Aaro Koskinen
-1 siblings, 0 replies; 21+ messages in thread
From: Aaro Koskinen @ 2014-06-04 18:53 UTC (permalink / raw)
To: David Daney; +Cc: Alex Smith, Aaro Koskinen, David Daney, linux-mips
Hi,
On Wed, Jun 04, 2014 at 10:12:39AM -0700, David Daney wrote:
> On 06/04/2014 08:58 AM, Alex Smith wrote:
> >On 04/06/14 15:47, Aaro Koskinen wrote:
> >>On Thu, May 29, 2014 at 11:10:01AM +0100, Alex Smith wrote:
> >>>Add interface mode detection for Octeon II. This is necessary to detect
> >>>the interface modes correctly on the UBNT E200 board. Code is taken
> >>>from the UBNT GPL source release, with some alterations: SRIO, ILK and
> >>>RXAUI interface modes are removed and instead return disabled as these
> >>>modes are not currently supported.
> >>>
> >>>Tested-by: David Daney <david.daney@cavium.com>
> >>>Signed-off-by: Alex Smith <alex.smith@imgtec.com>
> >>
> >>I tried booting ebb6800 board with these patches.
>
> There seem to be problems (I think in the interrupt controller code) for
> cn68xx based systems in the kernel.org kernel. So I couldn't get it to boot
> on my ebb6800 even to the point it tries to initialize the networking
> hardware.
I tested two boards with 3.15-rc8. They boot fine to shell, it's just
modprobing octeon-ethernet that is causing issues.
> >>It hangs somewhere in __cvmx_helper_xaui_enable() with XAUI port. Looking
> >>at the UBNT GPL package, xaui init is quite different with 68XX specific
> >>code paths. Maybe those bits should be added too, or then disable XAUI
> >>support as well?
> >
> >Probably the best thing to do for now would be to disable it. Does it
> >boot successfully for you if you switch CVMX_HELPER_INTERFACE_MODE_XAUI
> >to disabled?
>
> ... I don't think it matters. The patch Alex et al. came up with is an
> improvement over what is already there. The fact that there are still some
> configurations that don't work can be addressed with follow-on patches.
Fair enough; previously octeon-ethernet panic()ed on ebb6800 and now it
silently hangs - so it's not really any serious regression.
If these patches already make it work on ER Pro then good, at least
it's a some kind of improvement towards a proper Octeon II support.
A.
^ permalink raw reply [flat|nested] 21+ messages in thread
end of thread, other threads:[~2014-06-04 18:53 UTC | newest]
Thread overview: 21+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-05-29 10:10 [PATCH 0/3] Ubiquiti EdgeRouter/EdgeRouter Pro support Alex Smith
2014-05-29 10:10 ` Alex Smith
2014-05-29 10:10 ` [PATCH 1/3] MIPS: octeon: Add interface mode detection for Octeon II Alex Smith
2014-05-29 10:10 ` Alex Smith
2014-06-04 14:47 ` [1/3] " Aaro Koskinen
2014-06-04 15:58 ` Alex Smith
2014-06-04 15:58 ` Alex Smith
2014-06-04 17:12 ` David Daney
2014-06-04 17:12 ` David Daney
2014-06-04 18:53 ` Aaro Koskinen
2014-05-29 10:10 ` [PATCH 2/3] staging: octeon-ethernet: Move PHY activation to .ndo_open() Alex Smith
2014-05-29 10:10 ` Alex Smith
2014-05-29 10:10 ` [PATCH 3/3] usb host/MIPS: Remove hard-coded OCTEON platform information Alex Smith
2014-05-29 10:10 ` Alex Smith
2014-05-29 15:03 ` Alan Stern
2014-05-29 15:03 ` Alan Stern
2014-05-29 16:55 ` Florian Fainelli
2014-05-29 17:37 ` Greg KH
2014-05-29 17:59 ` David Daney
2014-05-29 20:55 ` Alan Stern
2014-05-29 21:26 ` David Daney
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.