Compare commits
24 Commits
master
...
snic10e-et
Author | SHA1 | Date | |
---|---|---|---|
7e0984e70f | |||
ad6a039808 | |||
34ee966cba | |||
8d73f4e647 | |||
4f8715bdbf | |||
d803c68954 | |||
b5d1f3cbc3 | |||
15977758ba | |||
319b41636f | |||
99afb6ba21 | |||
47890af657 | |||
0ea1b55c49 | |||
6e303ca958 | |||
c316f05f21 | |||
a78fd8e4b7 | |||
665d617447 | |||
fea3bae7b1 | |||
b1ce6e7731 | |||
dc24dcbe61 | |||
796917cb6e | |||
d8c455f988 | |||
0e6edfac4a | |||
3c4ceb938e | |||
b669600823 |
@ -22,6 +22,10 @@ do_sysinfo_octeon() {
|
||||
return 0
|
||||
;;
|
||||
|
||||
"SNIC10E"*)
|
||||
name="snic10e"
|
||||
;;
|
||||
|
||||
"ITUS_SHIELD"*)
|
||||
name="itus,shield-router"
|
||||
;;
|
||||
|
@ -24,8 +24,9 @@ CONFIG_BLK_DEV_SD=y
|
||||
CONFIG_BLK_MQ_PCI=y
|
||||
CONFIG_BLK_SCSI_REQUEST=y
|
||||
CONFIG_BUILTIN_DTB=y
|
||||
# CONFIG_CAVIUM_CN63XXP1 is not set
|
||||
CONFIG_CAVIUM_CN63XXP1=y
|
||||
CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE=0
|
||||
CONFIG_CAVIUM_OCTEON2=y
|
||||
CONFIG_CAVIUM_OCTEON_LOCK_L2=y
|
||||
CONFIG_CAVIUM_OCTEON_LOCK_L2_EXCEPTION=y
|
||||
CONFIG_CAVIUM_OCTEON_LOCK_L2_INTERRUPT=y
|
||||
@ -158,6 +159,7 @@ CONFIG_HZ_250=y
|
||||
CONFIG_HZ_PERIODIC=y
|
||||
CONFIG_IMAGE_CMDLINE_HACK=y
|
||||
CONFIG_I2C=y
|
||||
CONFIG_I2C_BOARDINFO=y
|
||||
CONFIG_I2C_OCTEON=y
|
||||
CONFIG_INITRAMFS_SOURCE=""
|
||||
CONFIG_IRQCHIP=y
|
||||
@ -204,8 +206,10 @@ CONFIG_MTD_PHYSMAP=y
|
||||
CONFIG_MTD_SPI_NOR=y
|
||||
CONFIG_MTD_SPI_NOR_USE_4K_SECTORS=y
|
||||
CONFIG_NEED_DMA_MAP_STATE=y
|
||||
CONFIG_NET_DEVLINK=y
|
||||
CONFIG_NET_DSA=y
|
||||
CONFIG_NET_FLOW_LIMIT=y
|
||||
CONFIG_NET_SWITCHDEV=y
|
||||
CONFIG_NLS=y
|
||||
CONFIG_NLS_CODEPAGE_437=y
|
||||
CONFIG_NLS_ISO8859_1=y
|
||||
@ -226,22 +230,25 @@ CONFIG_OF_GPIO=y
|
||||
CONFIG_OF_IRQ=y
|
||||
CONFIG_OF_KOBJ=y
|
||||
CONFIG_OF_MDIO=y
|
||||
CONFIG_OF_MEMORY_ACCESSOR=y
|
||||
CONFIG_OF_NET=y
|
||||
CONFIG_PADATA=y
|
||||
# CONFIG_PARTITION_ADVANCED is not set
|
||||
CONFIG_PCI=y
|
||||
CONFIG_PCI_DOMAINS=y
|
||||
CONFIG_PCI_DRIVERS_LEGACY=y
|
||||
CONFIG_PCIEAER=y
|
||||
CONFIG_PCIEPORTBUS=y
|
||||
CONFIG_PCI_DOMAINS=y
|
||||
CONFIG_PCI_DRIVERS_LEGACY=y
|
||||
CONFIG_PERF_USE_VMALLOC=y
|
||||
CONFIG_PGTABLE_LEVELS=3
|
||||
CONFIG_PHYLIB=y
|
||||
CONFIG_PHYLINK=y
|
||||
CONFIG_PHYS_ADDR_T_64BIT=y
|
||||
CONFIG_POSIX_MQUEUE=y
|
||||
CONFIG_POSIX_MQUEUE_SYSCTL=y
|
||||
CONFIG_QUEUED_RWLOCKS=y
|
||||
CONFIG_QUEUED_SPINLOCKS=y
|
||||
CONFIG_RAS=y
|
||||
CONFIG_RCU_NEED_SEGCBLIST=y
|
||||
CONFIG_RCU_STALL_COMMON=y
|
||||
CONFIG_RELAY=y
|
||||
@ -259,6 +266,7 @@ CONFIG_SPARSEMEM=y
|
||||
CONFIG_SPARSEMEM_STATIC=y
|
||||
CONFIG_SPI=y
|
||||
CONFIG_SPI_MASTER=y
|
||||
CONFIG_SPI_MEM=y
|
||||
CONFIG_SPI_OCTEON=y
|
||||
CONFIG_SRCU=y
|
||||
CONFIG_SWIOTLB=y
|
||||
@ -294,6 +302,7 @@ CONFIG_USE_OF=y
|
||||
CONFIG_VFAT_FS=y
|
||||
CONFIG_VITESSE_PHY=y
|
||||
CONFIG_VM_EVENT_COUNTERS=y
|
||||
CONFIG_VSC848X_PHY=y
|
||||
CONFIG_WATCHDOG_CORE=y
|
||||
CONFIG_WEAK_ORDERING=y
|
||||
CONFIG_XPS=y
|
||||
|
@ -0,0 +1,847 @@
|
||||
/dts-v1/;
|
||||
/*
|
||||
* Cavium Inc. (Small) NIC10e board
|
||||
*/
|
||||
/ {
|
||||
model = "cavium,snic10e";
|
||||
compatible = "cavium,snic10e";
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
interrupt-parent = <&ciu>;
|
||||
|
||||
soc@0 {
|
||||
compatible = "simple-bus";
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
ranges; /* Direct mapping */
|
||||
|
||||
ciu: interrupt-controller@1070000000000 {
|
||||
compatible = "cavium,octeon-3860-ciu";
|
||||
interrupt-controller;
|
||||
/* Interrupts are specified by two parts:
|
||||
* 1) Controller register (0 or 1)
|
||||
* 2) Bit within the register (0..63)
|
||||
*/
|
||||
#interrupt-cells = <2>;
|
||||
reg = <0x10700 0x00000000 0x0 0x7000>;
|
||||
};
|
||||
|
||||
gpio: gpio-controller@1070000000800 {
|
||||
#gpio-cells = <2>;
|
||||
compatible = "cavium,octeon-3860-gpio";
|
||||
reg = <0x10700 0x00000800 0x0 0x100>;
|
||||
gpio-controller;
|
||||
/* Interrupts are specified by two parts:
|
||||
* 1) GPIO pin number (0..15)
|
||||
* 2) Triggering (1 - edge rising
|
||||
* 2 - edge falling
|
||||
* 4 - level active high
|
||||
* 8 - level active low)
|
||||
*/
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <2>;
|
||||
/* The GPIO pins connect to 16 consecutive CUI bits */
|
||||
interrupts = <0 16>; /* <0 17> <0 18> <0 19>
|
||||
<0 20> <0 21> <0 22> <0 23>
|
||||
<0 24> <0 25> <0 26> <0 27>
|
||||
<0 28> <0 29> <0 30> <0 31>; */
|
||||
};
|
||||
|
||||
twsi0: i2c@1180000001000 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
compatible = "cavium,octeon-3860-twsi";
|
||||
reg = <0x11800 0x00001000 0x0 0x200>;
|
||||
interrupts = <0 45>;
|
||||
/* NOTE: In order to get the proper delay between
|
||||
* i2c bus transactions for the SFP we need to either
|
||||
* slow the bus down to no more than 30KHz or else
|
||||
* somehow insert a delay between transactions. Only
|
||||
* U-Boot is capable of inserting the appropriate delay
|
||||
* at this time.
|
||||
*/
|
||||
clock-frequency = <30000>;
|
||||
|
||||
tmp@4c {
|
||||
compatible = "ti,tmp421";
|
||||
reg = <0x4c>;
|
||||
};
|
||||
sfp0: eeprom@50 {
|
||||
compatible = "atmel,24c01";
|
||||
reg = <0x50>;
|
||||
};
|
||||
tlv-eeprom@53 {
|
||||
compatible = "atmel,24c256";
|
||||
reg = <0x53>;
|
||||
pagesize = <64>;
|
||||
};
|
||||
};
|
||||
|
||||
twsi1: i2c@1180000001200 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
compatible = "cavium,octeon-3860-twsi";
|
||||
reg = <0x11800 0x00001200 0x0 0x200>;
|
||||
interrupts = <0 59>;
|
||||
/* NOTE: In order to get the proper delay between
|
||||
* i2c bus transactions for the SFP we need to either
|
||||
* slow the bus down to no more than 30KHz or else
|
||||
* somehow insert a delay between transactions. Only
|
||||
* U-Boot is capable of inserting the appropriate delay
|
||||
* at this time.
|
||||
*/
|
||||
clock-frequency = <30000>;
|
||||
|
||||
sfp1: eeprom@50 {
|
||||
compatible = "atmel,24c01";
|
||||
reg = <0x50>;
|
||||
};
|
||||
gpio1: gpio@20 {
|
||||
reg = <0x20>;
|
||||
compatible = "nxp,pca9554";
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
interrupt-parent = <&gpio>;
|
||||
interrupt = <13 2>; /* OCTEON GPIO 13, falling edge */
|
||||
#interrupt-cells = <1>;
|
||||
cavium,phy-trim = "0,ti";
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
smi0: mdio@1180000001800 {
|
||||
compatible = "cavium,octeon-3860-mdio";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
reg = <0x11800 0x00001800 0x0 0x40>;
|
||||
status = "disabled";
|
||||
mphyA: ethernet-phy-nexus@A {
|
||||
reg = <0>;
|
||||
/* The Vitesse VSC8488 is a dual-PHY where
|
||||
* some of the configuration is common across
|
||||
* both of the phy devices such as the reset
|
||||
* line and the base MDIO address.
|
||||
*/
|
||||
compatible = "vitesse,vsc8488-nexus", "ethernet-phy-nexus";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
ranges;
|
||||
cavium,phy-trim = "0,vitesse";
|
||||
|
||||
/* Hardware reset signal */
|
||||
reset = <&gpio 17 0>;
|
||||
|
||||
phy0: ethernet-phy@0 {
|
||||
/* Absolute address */
|
||||
reg = <0>;
|
||||
compatible = "vitesse,vsc8488", "ethernet-phy-ieee802.3-c45";
|
||||
interrupt-parent = <&gpio>;
|
||||
interrupts = <13 8>;
|
||||
|
||||
mod_abs = <0>;
|
||||
/* TX Fault GPIO line */
|
||||
tx_fault = <1>;
|
||||
/* GPIO that enables output */
|
||||
txon = <4>;
|
||||
/* INT A GPIO output */
|
||||
inta = <5>;
|
||||
|
||||
/* Optional equalization value to
|
||||
* program into the PHY XS XAUI Rx
|
||||
* Equalization control register.
|
||||
* It is broken up into one nibble for
|
||||
* each lane with lane 0 using bits
|
||||
* 12 - 15.
|
||||
* Use the following table:
|
||||
* 0x0 - 0dB
|
||||
* 0x1 - 1.41dB
|
||||
* 0x2 - 2.24dB
|
||||
* 0x3 - 2.83dB
|
||||
* 0x5 - 4.48dB
|
||||
* 0x6 - 5.39dB
|
||||
* 0x7 - 6.07dB
|
||||
* 0x9 - 6.18dB
|
||||
* 0xA - 7.08dB (default)
|
||||
* 0xB - 7.79dB
|
||||
* 0xD - 9.96dB
|
||||
* 0xE - 10.84dB
|
||||
* 0xF - 11.55dB
|
||||
*
|
||||
* This is board specific and should
|
||||
* only be defined by the hardware
|
||||
* vendor.
|
||||
*/
|
||||
vitesse,rx_equalization = <0x0000>;
|
||||
/* Optional transmit pre-emphasis
|
||||
* control. This sets the
|
||||
* PHY XS XAUI TX pre-emphasis control
|
||||
* register.
|
||||
*
|
||||
* It uses bits 13-14 for lane 0,
|
||||
* 10-11 for lane 1, 7-8 for lane 2
|
||||
* and 4-5 for lane 3.
|
||||
*
|
||||
* Bits 2-3 are the LOS threshold
|
||||
* setting and bit 1 enables
|
||||
* the XAUI output high swing mode.
|
||||
*
|
||||
* Use the following table for
|
||||
* pre-emphasis:
|
||||
* 0b00 - 0dB
|
||||
* 0b01 - 2.5dB
|
||||
* 0b10 - 6dB (default)
|
||||
* 0b11 - 12dB
|
||||
*
|
||||
* Use the following table for the LOS
|
||||
* threshold setting:
|
||||
*
|
||||
* 0b00 - 50mV - 175mV (default)
|
||||
* 0b01 - 60mV - 185mV
|
||||
* 0b10 - 70mV - 195mV
|
||||
* 0b11 - 80mV - 205mV
|
||||
*/
|
||||
vitesse,tx_preemphasis = <0x0000>;
|
||||
|
||||
/* TX output driver slew rate control
|
||||
* is bits 8-11 where 0x0 is the minimum
|
||||
* and 0xF is the maximum.
|
||||
* Default is 0xA.
|
||||
*
|
||||
* The TX output driver C(-1)
|
||||
* coefficient is bits 0-4 where
|
||||
* 0b00000 is the minimum (-4ma) and
|
||||
* 0b11111 is the maximum (4ma). The
|
||||
* default 0x 0b01111.
|
||||
*/
|
||||
vitesse,txout_driver_ctrl1 = <0x0A0F>;
|
||||
|
||||
/* The TX output driver C(0) coefficient
|
||||
* is bits 8-12 with 0b00000 being the
|
||||
* minimum (0mA) and 0b11111 being
|
||||
* the maximum (16mA). The default is
|
||||
* 0b10011
|
||||
*
|
||||
* The C(+1) coefficient is bits 0-5
|
||||
* with 0b000000 being the minimum
|
||||
* (-0.25mA) and 0b111111 being the
|
||||
* maximum (-16mA). The default is
|
||||
* 0b000000.
|
||||
*/
|
||||
/*vitesse,txout_driver_ctrl2 = <0x1300>;*/
|
||||
|
||||
/* DC_AGC_LOS_CONFIG1:
|
||||
* 15: Suppress_Coarse_Adj_on_LOS_Clear
|
||||
* 0: DC offset correction performed using coarse
|
||||
* resolution mode (default)
|
||||
* 1: DC offset correction performed using fine resolution
|
||||
* mode when correction resumes after LOPC/LOS alarms
|
||||
* clear. This guarantees there will be no big jumps in
|
||||
* the offset at the expense of taking longer to reach
|
||||
* optimal setting.
|
||||
* 14: Force_DC2_Fine_Adj:
|
||||
* Forces the DC offset correction to operate in fine
|
||||
* resolution adjustment mode at times when the algorithm.
|
||||
* 0: DC offset correction makes coarse adjustments when
|
||||
* correction mode is first enabled (default)
|
||||
* 1: DC offset correction performed using fine resolution
|
||||
* at all times. This is slower.
|
||||
* 13: Force_DC1_Fine_Adj:
|
||||
* Forces the DC offset correction to operate in fine
|
||||
* resolution adjustment mode at times when the algorithm.
|
||||
* 0: DC offset correction makes coarse adjustments when
|
||||
* correction mode is first enabled (default)
|
||||
* 1: DC offset correction performed using fine resolution
|
||||
* at all times. This is slower.
|
||||
* 12: Force_DC0_Fine_Adj:
|
||||
* Forces the DC offset correction to operate in fine
|
||||
* resolution adjustment mode at times when the algorithm.
|
||||
* 0: DC offset correction makes coarse adjustments when
|
||||
* correction mode is first enabled (default)
|
||||
* 1: DC offset correction performed using fine resolution
|
||||
* at all times. This is slower.
|
||||
* 10: Skip_DC2_Adj, 1 = skip DC2 offset correction
|
||||
* 9: Skip_DC1_Adj, 1 = skip DC1 offset correction
|
||||
* 8: Skip_DC0_Adj, 1 = skip DC0 offset correction
|
||||
*
|
||||
* 6-4: DC_Offset_Alarm_Mode (default 1)
|
||||
* Selects the alarm condition that will halt the DC offset
|
||||
* correction logic when the alarm(s) are set.
|
||||
* 111: reserved
|
||||
* 110: reserved
|
||||
* 101: LOPC and software LOS detection
|
||||
* 100: LOPC and hardware LOS detection
|
||||
* 011: Software LOS detection
|
||||
* 010: Hardware LOS detection
|
||||
* 001: LOPC
|
||||
* 000: Never. DC offset correction will continue to make
|
||||
* fine resolution adjustments to the offsets even
|
||||
* when LOPC and LOS alarms are present.
|
||||
*
|
||||
* 3: AGC_Enable
|
||||
* Selects when hardware AGC adjustment logic and LOS
|
||||
* detection logic is enabled (default 1)
|
||||
* 0: disabled
|
||||
* 1: enabled
|
||||
* 2: AGC_Suspend
|
||||
* Suspends the LOS detection logic and AGC logic
|
||||
* from making adjustments to the gain. Bit valid only
|
||||
* if AGC_Enable=1
|
||||
* 0: AGC adjustment enabled (default)
|
||||
* 1: AGC adjustment suspended
|
||||
* 1: DC_Offset_Adj_Enable
|
||||
* Select when the hardware DC offset correction logic is
|
||||
* enabled.
|
||||
* 0: disable
|
||||
* 1: enable (default)
|
||||
* 0: DC_Offset_Adj_Suspend
|
||||
* Suspends the DC offset correction logic from making
|
||||
* adjustments to all offset settings. Bit valid only if
|
||||
* DC_Offset_Adj_Enable=1
|
||||
* 0: DC offset correction enabled (default)
|
||||
* 1: DC offset correction suspended
|
||||
*
|
||||
* This setting is only applied for
|
||||
* passive copper.
|
||||
*/
|
||||
vitesse,copper_dc_agc_los_config1 = <0x000A>;
|
||||
|
||||
/* Disable aggressive track phase during
|
||||
* firmware convergence if 0, enabled
|
||||
* otherwise (default).
|
||||
*
|
||||
* This setting is only applied for
|
||||
* passive copper.
|
||||
*/
|
||||
vitesse,copper_agg_track_phase = <0>;
|
||||
|
||||
/* AGC_Config4
|
||||
*
|
||||
* 13-8: Ampl_Tolerance
|
||||
* This defines the hysterisis
|
||||
* built in to the AGC adjustment
|
||||
* circuit. The VGA gain will not
|
||||
* be adjusted as long as the
|
||||
* measured input amplitude is
|
||||
* Inp_Ampl_Target +/- Amnpl_Tolerance.
|
||||
* Default is 4.
|
||||
* 7-0: Inp_Ampl_Target
|
||||
* This is the target amplitude
|
||||
* desired to be measured at the
|
||||
* peak detector when measuring
|
||||
* input amplitude. The VGA gain
|
||||
* is adjusted to achieve this
|
||||
* target setting.
|
||||
* Default is 0x6E.
|
||||
*
|
||||
* This setting is only applied for
|
||||
* passive copper.
|
||||
*/
|
||||
vitesse,copper_agc_config4 = <0x0496>;
|
||||
|
||||
/* The Vitesse 10G PHY does not
|
||||
* automatically read the SFP EEPROM
|
||||
* so the host needs to do it to put
|
||||
* the PHY in the proper mode for
|
||||
* copper or optical.
|
||||
*/
|
||||
sfp-eeprom = <&sfp0>;
|
||||
};
|
||||
|
||||
phy1: ethernet-phy@1 {
|
||||
/* Absolute address */
|
||||
reg = <0x1>;
|
||||
compatible = "vitesse,vsc8488", "ethernet-phy-ieee802.3-c45";
|
||||
interrupt-parent = <&gpio>;
|
||||
interrupts = <13 8>;
|
||||
|
||||
mod_abs = <9>;
|
||||
/* TX Fault GPIO line */
|
||||
tx_fault = <8>;
|
||||
/* GPIO that enables output */
|
||||
txon = <10>;
|
||||
/* INT A GPIO output */
|
||||
inta = <5>;
|
||||
|
||||
/* Optional equalization value to
|
||||
* program into the PHY XS XAUI Rx
|
||||
* Equalization control register.
|
||||
* It is broken up into one nibble for
|
||||
* each lane with lane 0 using bits
|
||||
* 12 - 15.
|
||||
* Use the following table:
|
||||
* 0x0 - 0dB
|
||||
* 0x1 - 1.41dB
|
||||
* 0x2 - 2.24dB
|
||||
* 0x3 - 2.83dB
|
||||
* 0x5 - 4.48dB
|
||||
* 0x6 - 5.39dB
|
||||
* 0x7 - 6.07dB
|
||||
* 0x9 - 6.18dB
|
||||
* 0xA - 7.08dB (default)
|
||||
* 0xB - 7.79dB
|
||||
* 0xD - 9.96dB
|
||||
* 0xE - 10.84dB
|
||||
* 0xF - 11.55dB
|
||||
*
|
||||
* This is board specific and should
|
||||
* only be defined by the hardware
|
||||
* vendor.
|
||||
*/
|
||||
rx_equalization = <0x0000>;
|
||||
/* Optional transmit pre-emphasis
|
||||
* control. This sets the
|
||||
* PHY XS XAUI TX pre-emphasis control
|
||||
* register.
|
||||
*
|
||||
* It uses bits 13-14 for lane 0,
|
||||
* 10-11 for lane 1, 7-8 for lane 2
|
||||
* and 4-5 for lane 3.
|
||||
*
|
||||
* Bits 2-3 are the LOS threshold
|
||||
* setting and bit 1 enables
|
||||
* the XAUI output high swing mode.
|
||||
*
|
||||
* Use the following table for
|
||||
* pre-emphasis:
|
||||
* 0b00 - 0dB
|
||||
* 0b01 - 2.5dB
|
||||
* 0b10 - 6dB (default)
|
||||
* 0b11 - 12dB
|
||||
*
|
||||
* Use the following table for the LOS
|
||||
* threshold setting:
|
||||
*
|
||||
* 0b00 - 50mV - 175mV (default)
|
||||
* 0b01 - 60mV - 185mV
|
||||
* 0b10 - 70mV - 195mV
|
||||
* 0b11 - 80mV - 205mV
|
||||
*/
|
||||
tx_preemphasis = <0x0000>;
|
||||
|
||||
/* TX output driver slew rate control
|
||||
* is bits 8-11 where 0x0 is the minimum
|
||||
* and 0xF is the maximum.
|
||||
* Default is 0xA.
|
||||
*
|
||||
* The TX output driver C(-1)
|
||||
* coefficient is bits 0-4 where
|
||||
* 0b00000 is the minimum (-4ma) and
|
||||
* 0b11111 is the maximum (4ma). The
|
||||
* default 0x 0b01111.
|
||||
*/
|
||||
txout_driver_ctrl1 = <0x0A0F>;
|
||||
|
||||
/* The TX output driver C(0) coefficient
|
||||
* is bits 8-12 with 0b00000 being the
|
||||
* minimum (0mA) and 0b11111 being
|
||||
* the maximum (16mA). The default is
|
||||
* 0b10011
|
||||
*
|
||||
* The C(+1) coefficient is bits 0-5
|
||||
* with 0b000000 being the minimum
|
||||
* (-0.25mA) and 0b111111 being the
|
||||
* maximum (-16mA). The default is
|
||||
* 0b000000.
|
||||
*/
|
||||
/*txout_driver_ctrl2 = <0x1300>;*/
|
||||
|
||||
/* DC_AGC_LOS_CONFIG1:
|
||||
* 15: Suppress_Coarse_Adj_on_LOS_Clear
|
||||
* 0: DC offset correction performed using coarse
|
||||
* resolution mode (default)
|
||||
* 1: DC offset correction performed using fine resolution
|
||||
* mode when correction resumes after LOPC/LOS alarms
|
||||
* clear. This guarantees there will be no big jumps in
|
||||
* the offset at the expense of taking longer to reach
|
||||
* optimal setting.
|
||||
* 14: Force_DC2_Fine_Adj:
|
||||
* Forces the DC offset correction to operate in fine
|
||||
* resolution adjustment mode at times when the algorithm.
|
||||
* 0: DC offset correction makes coarse adjustments when
|
||||
* correction mode is first enabled (default)
|
||||
* 1: DC offset correction performed using fine resolution
|
||||
* at all times. This is slower.
|
||||
* 13: Force_DC1_Fine_Adj:
|
||||
* Forces the DC offset correction to operate in fine
|
||||
* resolution adjustment mode at times when the algorithm.
|
||||
* 0: DC offset correction makes coarse adjustments when
|
||||
* correction mode is first enabled (default)
|
||||
* 1: DC offset correction performed using fine resolution
|
||||
* at all times. This is slower.
|
||||
* 12: Force_DC0_Fine_Adj:
|
||||
* Forces the DC offset correction to operate in fine
|
||||
* resolution adjustment mode at times when the algorithm.
|
||||
* 0: DC offset correction makes coarse adjustments when
|
||||
* correction mode is first enabled (default)
|
||||
* 1: DC offset correction performed using fine resolution
|
||||
* at all times. This is slower.
|
||||
* 10: Skip_DC2_Adj, 1 = skip DC2 offset correction
|
||||
* 9: Skip_DC1_Adj, 1 = skip DC1 offset correction
|
||||
* 8: Skip_DC0_Adj, 1 = skip DC0 offset correction
|
||||
*
|
||||
* 6-4: DC_Offset_Alarm_Mode (default 1)
|
||||
* Selects the alarm condition that will halt the DC offset
|
||||
* correction logic when the alarm(s) are set.
|
||||
* 111: reserved
|
||||
* 110: reserved
|
||||
* 101: LOPC and software LOS detection
|
||||
* 100: LOPC and hardware LOS detection
|
||||
* 011: Software LOS detection
|
||||
* 010: Hardware LOS detection
|
||||
* 001: LOPC
|
||||
* 000: Never. DC offset correction will continue to make
|
||||
* fine resolution adjustments to the offsets even
|
||||
* when LOPC and LOS alarms are present.
|
||||
*
|
||||
* 3: AGC_Enable
|
||||
* Selects when hardware AGC adjustment logic and LOS
|
||||
* detection logic is enabled (default 1)
|
||||
* 0: disabled
|
||||
* 1: enabled
|
||||
* 2: AGC_Suspend
|
||||
* Suspends the LOS detection logic and AGC logic
|
||||
* from making adjustments to the gain. Bit valid only
|
||||
* if AGC_Enable=1
|
||||
* 0: AGC adjustment enabled (default)
|
||||
* 1: AGC adjustment suspended
|
||||
* 1: DC_Offset_Adj_Enable
|
||||
* Select when the hardware DC offset correction logic is
|
||||
* enabled.
|
||||
* 0: disable
|
||||
* 1: enable (default)
|
||||
* 0: DC_Offset_Adj_Suspend
|
||||
* Suspends the DC offset correction logic from making
|
||||
* adjustments to all offset settings. Bit valid only if
|
||||
* DC_Offset_Adj_Enable=1
|
||||
* 0: DC offset correction enabled (default)
|
||||
* 1: DC offset correction suspended
|
||||
*
|
||||
* This setting is only applied for
|
||||
* passive copper.
|
||||
*/
|
||||
vitesse,copper_dc_agc_los_config1 = <0x000A>;
|
||||
|
||||
/* Disable aggressive track phase during
|
||||
* firmware convergence if 0, enabled
|
||||
* otherwise (default).
|
||||
*
|
||||
* This setting is only applied for
|
||||
* passive copper.
|
||||
*/
|
||||
vitesse,copper_agg_track_phase = <0>;
|
||||
|
||||
/* AGC_Config4
|
||||
*
|
||||
* 13-8: Ampl_Tolerance
|
||||
* This defines the hysterisis
|
||||
* built in to the AGC adjustment
|
||||
* circuit. The VGA gain will not
|
||||
* be adjusted as long as the
|
||||
* measured input amplitude is
|
||||
* Inp_Ampl_Target +/- Amnpl_Tolerance.
|
||||
* Default is 4.
|
||||
* 7-0: Inp_Ampl_Target
|
||||
* This is the target amplitude
|
||||
* desired to be measured at the
|
||||
* peak detector when measuring
|
||||
* input amplitude. The VGA gain
|
||||
* is adjusted to achieve this
|
||||
* target setting.
|
||||
* Default is 0x6E.
|
||||
*
|
||||
* This setting is only applied for
|
||||
* passive copper.
|
||||
*/
|
||||
vitesse,copper_agc_config4 = <0x0496>;
|
||||
|
||||
/* The Vitesse 10G PHY does not
|
||||
* automatically read the SFP EEPROM
|
||||
* so the host needs to do it to put
|
||||
* the PHY in the proper mode for
|
||||
* copper or optical.
|
||||
*/
|
||||
sfp-eeprom = <&sfp1>;
|
||||
};
|
||||
};
|
||||
mphyB: ethernet-phy-nexus@B {
|
||||
reg = <0>;
|
||||
/* The TI TLK10232 is a dual-PHY where
|
||||
* some of the configuration is common across
|
||||
* both of the phy devices such as the reset
|
||||
* line and the base MDIO address.
|
||||
*/
|
||||
compatible = "ti,tlk10232-nexus", "ethernet-phy-nexus";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
ranges;
|
||||
cavium,phy-trim = "0,ti";
|
||||
|
||||
/* Hardware reset signal open-drain active low on GPIO 17, must not be driven high. */
|
||||
reset = <&gpio 17 2>;
|
||||
|
||||
phy11: ethernet-phy@0 {
|
||||
/* Absolute address */
|
||||
reg = <0>;
|
||||
compatible = "ti,tlk10232", "ethernet-phy-ieee802.3-c45";
|
||||
|
||||
/* The TI 10G PHY does not
|
||||
* automatically read the SFP EEPROM
|
||||
* so the host needs to do it to put
|
||||
* the PHY in the proper mode for
|
||||
* copper or optical.
|
||||
*/
|
||||
sfp-eeprom = <&sfp0>;
|
||||
|
||||
/* TX fault input signal for PHY from SFP+ */
|
||||
tx-fault = <&gpio1 4 0>;
|
||||
/* TX disable for PHY to SFP+ */
|
||||
tx-disable = <&gpio1 5 0>;
|
||||
/* MOD ABS signal for PHY from SFP+ */
|
||||
mod-abs = <&gpio1 6 0>;
|
||||
/* RX los of singal for PHY from SFP+ */
|
||||
rx-los = <&gpio1 7 0>;
|
||||
};
|
||||
|
||||
phy10: ethernet-phy@1 {
|
||||
/* Absolute address */
|
||||
reg = <0x1>;
|
||||
compatible = "ti,tlk10232", "ethernet-phy-ieee802.3-c45";
|
||||
|
||||
/* The TI 10G PHY does not
|
||||
* automatically read the SFP EEPROM
|
||||
* so the host needs to do it to put
|
||||
* the PHY in the proper mode for
|
||||
* copper or optical.
|
||||
*/
|
||||
sfp-eeprom = <&sfp1>;
|
||||
/* TX fault input signal for PHY */
|
||||
tx-fault = <&gpio1 0 0>;
|
||||
/* TX disable for PHY */
|
||||
tx-disable = <&gpio1 1 0>;
|
||||
/* MOD ABS signal for PHY */
|
||||
mod-abs = <&gpio1 2 0>;
|
||||
/* RX los of singal for PHY */
|
||||
rx-los = <&gpio1 3 0>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
pip: pip@11800a0000000 {
|
||||
compatible = "cavium,octeon-3860-pip";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
reg = <0x11800 0xa0000000 0x0 0x2000>;
|
||||
|
||||
interface@A {
|
||||
compatible = "cavium,octeon-3860-pip-interface";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
reg = <0>; /* interface */
|
||||
cavium,phy-trim = "0,vitesse";
|
||||
|
||||
ethernet@0 {
|
||||
compatible = "cavium,octeon-3860-pip-port";
|
||||
reg = <0x0>; /* Port */
|
||||
local-mac-address = [ 00 00 00 00 00 00 ];
|
||||
phy-handle = <&phy0>;
|
||||
};
|
||||
};
|
||||
interface@B {
|
||||
compatible = "cavium,octeon-3860-pip-interface";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
reg = <1>; /* interface */
|
||||
cavium,phy-trim = "0,vitesse";
|
||||
|
||||
ethernet@0 {
|
||||
compatible = "cavium,octeon-3860-pip-port";
|
||||
reg = <0x0>; /* Port */
|
||||
local-mac-address = [ 00 00 00 00 00 00 ];
|
||||
phy-handle = <&phy1>;
|
||||
};
|
||||
};
|
||||
interface@C {
|
||||
compatible = "cavium,octeon-3860-pip-interface";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
reg = <0>; /* interface */
|
||||
cavium,phy-trim = "0,ti";
|
||||
|
||||
ethernet@0 {
|
||||
compatible = "cavium,octeon-3860-pip-port";
|
||||
reg = <0x0>; /* Port */
|
||||
local-mac-address = [ 00 00 00 00 00 00 ];
|
||||
phy-handle = <&phy10>;
|
||||
};
|
||||
};
|
||||
interface@D {
|
||||
compatible = "cavium,octeon-3860-pip-interface";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
reg = <1>; /* interface */
|
||||
cavium,phy-trim = "0,ti";
|
||||
|
||||
ethernet@0 {
|
||||
compatible = "cavium,octeon-3860-pip-port";
|
||||
reg = <0x0>; /* Port */
|
||||
local-mac-address = [ 00 00 00 00 00 00 ];
|
||||
phy-handle = <&phy11>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
uart0: serial@1180000000800 {
|
||||
compatible = "cavium,octeon-3860-uart","ns16550";
|
||||
reg = <0x11800 0x00000800 0x0 0x400>;
|
||||
clock-frequency = <400000000>;
|
||||
current-speed = <115200>;
|
||||
reg-shift = <3>;
|
||||
interrupts = <0 34>;
|
||||
};
|
||||
|
||||
uart1: serial@1180000000c00 {
|
||||
compatible = "cavium,octeon-3860-uart","ns16550";
|
||||
reg = <0x11800 0x00000c00 0x0 0x400>;
|
||||
clock-frequency = <400000000>;
|
||||
current-speed = <115200>;
|
||||
reg-shift = <3>;
|
||||
interrupts = <0 35>;
|
||||
};
|
||||
|
||||
bootbus: bootbus@1180000000000 {
|
||||
compatible = "cavium,octeon-3860-bootbus";
|
||||
reg = <0x11800 0x00000000 0x0 0x200>;
|
||||
/* The chip select number and offset */
|
||||
#address-cells = <2>;
|
||||
/* The size of the chip select region */
|
||||
#size-cells = <1>;
|
||||
ranges = <0 0 0 0x1f400000 0xc00000>,
|
||||
<1 0 0x10000 0x30000000 0>,
|
||||
<2 0 0 0x1f000000 0x100000>,
|
||||
<3 0 0x10000 0x50000000 0>,
|
||||
<4 0 0x10000 0x60000000 0>,
|
||||
<5 0 0x10000 0x70000000 0>,
|
||||
<6 0 0x10000 0x80000000 0>,
|
||||
<7 0 0x10000 0x90000000 0>;
|
||||
|
||||
cavium,cs-config@0 {
|
||||
compatible = "cavium,octeon-3860-bootbus-config";
|
||||
cavium,cs-index = <0>;
|
||||
cavium,t-adr = <10>;
|
||||
cavium,t-ce = <50>;
|
||||
cavium,t-oe = <50>;
|
||||
cavium,t-we = <35>;
|
||||
cavium,t-rd-hld = <25>;
|
||||
cavium,t-wr-hld = <35>;
|
||||
cavium,t-pause = <0>;
|
||||
cavium,t-wait = <300>;
|
||||
cavium,t-page = <25>;
|
||||
cavium,t-rd-dly = <0>;
|
||||
|
||||
cavium,pages = <0>;
|
||||
cavium,bus-width = <8>;
|
||||
};
|
||||
cavium,cs-config@2 {
|
||||
compatible = "cavium,octeon-3860-bootbus-config";
|
||||
cavium,cs-index = <2>;
|
||||
cavium,t-adr = <0>;
|
||||
cavium,t-ce = <50>;
|
||||
cavium,t-oe = <20>;
|
||||
cavium,t-we = <46>;
|
||||
cavium,t-rd-hld = <8>;
|
||||
cavium,t-wr-hld = <10>;
|
||||
cavium,t-pause = <0>;
|
||||
cavium,t-wait = <0>;
|
||||
cavium,t-page = <1>;
|
||||
cavium,t-ale = <1>;
|
||||
cavium,t-rd-dly = <0>;
|
||||
|
||||
cavium,pages = <0>;
|
||||
cavium,bus-width = <8>;
|
||||
};
|
||||
flash0: nor@0,0 {
|
||||
compatible = "cfi-flash";
|
||||
reg = <0 0 0x800000>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
partition@0 {
|
||||
label = "bootloader";
|
||||
reg = <0x0 0x1c0000>;
|
||||
read-only;
|
||||
};
|
||||
partition@1c0000 {
|
||||
label = "kernel";
|
||||
reg = <0x1c0000 0x63e000>;
|
||||
};
|
||||
partition@7fe000 {
|
||||
label = "environment";
|
||||
reg = <0x7fe0000 0x2000>;
|
||||
read-only;
|
||||
};
|
||||
};
|
||||
psram0: psram@2,0 {
|
||||
compatible = "micron,mt45w1mw16pd";
|
||||
reg = <2 0x20 0x20>, <2 0 0x20>;
|
||||
};
|
||||
};
|
||||
|
||||
dma0: dma-engine@1180000000100 {
|
||||
compatible = "cavium,octeon-5750-bootbus-dma";
|
||||
reg = <0x11800 0x00000100 0x0 0x8>;
|
||||
interrupts = <0 63>;
|
||||
};
|
||||
dma1: dma-engine@1180000000108 {
|
||||
compatible = "cavium,octeon-5750-bootbus-dma";
|
||||
reg = <0x11800 0x00000108 0x0 0x8>;
|
||||
interrupts = <0 63>;
|
||||
};
|
||||
nand-flash-interface@1070001000000 {
|
||||
compatible = "cavium,octeon-5230-nand";
|
||||
reg = <0x10700 0x1000000 0x0 0x100 0x11800 0x168 0x0 0x20>;
|
||||
#address-cells = <0x1>;
|
||||
#size-cells = <0x0>;
|
||||
interrupts = <0x0 0x3f>;
|
||||
flash@1 {
|
||||
compatible = "nand-flash";
|
||||
reg = <0x1>;
|
||||
nand-ecc-mode = "soft";
|
||||
nand-ecc-size = <0x200>;
|
||||
nand-ecc-bytes = <0x7>;
|
||||
nand-bus-width = <0x8>;
|
||||
};
|
||||
};
|
||||
};
|
||||
gpio-leds {
|
||||
compatible = "gpio-leds";
|
||||
|
||||
d1a {
|
||||
label = "bottom";
|
||||
gpios = <&gpio 1 0>;
|
||||
default-state = "keep";
|
||||
cavium,phy-trim = "0,ti";
|
||||
};
|
||||
d1b-t {
|
||||
label = "top";
|
||||
gpios = <&gpio 2 0>;
|
||||
default-state = "keep";
|
||||
cavium,phy-trim = "0,ti";
|
||||
};
|
||||
d1b-v {
|
||||
label = "top";
|
||||
gpios = <&gpio 2 0>;
|
||||
default-state = "keep";
|
||||
cavium,phy-trim = "0,vitesse";
|
||||
};
|
||||
};
|
||||
|
||||
aliases {
|
||||
pip = &pip;
|
||||
smi0 = &smi0;
|
||||
twsi0 = &twsi0;
|
||||
twsi1 = &twsi1;
|
||||
uart0 = &uart0;
|
||||
uart1 = &uart1;
|
||||
flash0 = &flash0;
|
||||
};
|
||||
};
|
@ -65,6 +65,16 @@ define Device/ubnt_edgerouter-4
|
||||
endef
|
||||
TARGET_DEVICES += ubnt_edgerouter-4
|
||||
|
||||
define Device/snic10e
|
||||
DEVICE_VENDOR := Cavium
|
||||
DEVICE_MODEL := snic10e
|
||||
DEVICE_DTS := snic10e
|
||||
DEVICE_PACKAGES += kmod-gpio-button-hotplug kmod-leds-gpio kmod-of-mdio kmod-sfp kmod-usb3 kmod-usb-storage-uas
|
||||
KERNEL := kernel-bin | append-dtb-to-elf
|
||||
KERNEL_DEPENDS := $$(wildcard $(DTS_DIR)/$(DEVICE_DTS).dts)
|
||||
endef
|
||||
|
||||
TARGET_DEVICES += snic10e
|
||||
ERLITE_CMDLINE:=-mtdparts=phys_mapped_flash:512k(boot0)ro,512k(boot1)ro,64k(eeprom)ro root=/dev/sda2 rootfstype=squashfs,ext4 rootwait
|
||||
define Device/ubnt_edgerouter-lite
|
||||
DEVICE_VENDOR := Ubiquiti
|
||||
|
829
target/linux/octeon/patches-5.4/0001_add_vsc_phy.patch
Normal file
829
target/linux/octeon/patches-5.4/0001_add_vsc_phy.patch
Normal file
@ -0,0 +1,829 @@
|
||||
From: Abhishek Paliwal <abhishek.paliwal@aricent.com>
|
||||
Date: Fri, 13 Feb 2015 15:04:55 +0530
|
||||
Subject: netdev/phy: Add driver for Vitesse vsc848x single, dual and quad 10G
|
||||
phys
|
||||
|
||||
From: David Daney <david.daney@cavium.com>
|
||||
|
||||
These phys implement the standard IEEE 802.3 clause 45 registers but
|
||||
require additional configuration. Some of these registers in the multi-phy
|
||||
devices are shared among all phys such as the GPIO registers.
|
||||
|
||||
Additionally, this PHY does not automatically access the SFP+ serial EEPROM so
|
||||
it is up to the PHY driver to parse it and change certain parameters in the
|
||||
PHY according to the type of module installed and the length of the cable, if
|
||||
copper.
|
||||
|
||||
This module has support for the vsc8488, vsc8486 and vsc8484 Vitesse devices
|
||||
but thus far has only been tested with the vsc8488 dual PHY.
|
||||
|
||||
netdev/phy: Clean up structure names in vsc848x.c
|
||||
Cut-and-paste snafu left some bad names, no functional change.
|
||||
|
||||
Signed-off-by: David Daney <david.daney@cavium.com>
|
||||
Signed-off-by: Aaron Williams <aaron.williams@cavium.com>
|
||||
Signed-off-by: Leonid Rosenboim <lrosenboim@caviumnetworks.com>
|
||||
Signed-off-by: Abhishek Paliwal <abhishek.paliwal@aricent.com>
|
||||
[Rebased on kernel 5.4 by Martin Kennedy <hurricos@gmail.com>]
|
||||
Signed-off-by: Martin Kennedy <hurricos@gmail.com>
|
||||
--- a/drivers/net/phy/Kconfig
|
||||
+++ b/drivers/net/phy/Kconfig
|
||||
@@ -54,6 +54,13 @@ config VITESSE_PHY
|
||||
---help---
|
||||
Currently supports the vsc8244
|
||||
|
||||
+config VSC848X_PHY
|
||||
+ tristate "Drivers for the Vitesse 10G PHYs"
|
||||
+ depends on OF_MEMORY_ACCESSOR
|
||||
+ help
|
||||
+ Driver for Vitesse vsc848x single, dual and quad 10G PHY devices.
|
||||
+ Currently supports the vsc8488, vsc8486 and vsc8484 chips
|
||||
+
|
||||
config SMSC_PHY
|
||||
tristate "Drivers for SMSC PHYs"
|
||||
---help---
|
||||
--- a/drivers/net/phy/Makefile
|
||||
+++ b/drivers/net/phy/Makefile
|
||||
@@ -108,4 +108,5 @@
|
||||
obj-$(CONFIG_STE10XP) += ste10Xp.o
|
||||
obj-$(CONFIG_TERANETICS_PHY) += teranetics.o
|
||||
obj-$(CONFIG_VITESSE_PHY) += vitesse.o
|
||||
+obj-$(CONFIG_VSC848X_PHY) += vsc848x.o
|
||||
obj-$(CONFIG_XILINX_GMII2RGMII) += xilinx_gmii2rgmii.o
|
||||
--- /dev/null
|
||||
+++ b/drivers/net/phy/vsc848x.c
|
||||
@@ -0,0 +1,774 @@
|
||||
+/*
|
||||
+ * 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) 2012 Cavium, Inc.
|
||||
+ */
|
||||
+
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/of_mdio.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/init.h>
|
||||
+#include <linux/phy.h>
|
||||
+#include <linux/memory.h>
|
||||
+#include <linux/mutex.h>
|
||||
+#include <linux/of_memory_accessor.h>
|
||||
+#include <linux/delay.h>
|
||||
+#include <linux/ctype.h>
|
||||
+
|
||||
+#define PMD_RX_SIGNAL_DETECT (MII_ADDR_C45 | 0x01000a)
|
||||
+#define PMA_TXOUTCTRL2 (MII_ADDR_C45 | 0x018014)
|
||||
+#define EDC_EYE_QUALITY (MII_ADDR_C45 | 0x018034)
|
||||
+/* EDC Firmware State Machine Status and Lib Force
|
||||
+ * 15: library force enable
|
||||
+ * 14:8 - Library number
|
||||
+ * 7:5 - N/A
|
||||
+ * 4 - State force
|
||||
+ * 3:0 - FW state (1=reset, 2=wait for alarm to clear, 3 = convergence,
|
||||
+ * 4 = tracking, 5 = freeze)
|
||||
+ */
|
||||
+#define EDC_FW_SM_STATUS (MII_ADDR_C45 | 0x018036)
|
||||
+
|
||||
+#define BASER_PCS_STATUS (MII_ADDR_C45 | 0x030020)
|
||||
+#define XGXS_LANE_STATUS (MII_ADDR_C45 | 0x040018)
|
||||
+#define EWIS_INTR_PEND1 (MII_ADDR_C45 | 0x02EE00)
|
||||
+#define EWIS_INTR_MASKA_1 (MII_ADDR_C45 | 0x02EE01)
|
||||
+#define EWIS_INTR_MASKB_1 (MII_ADDR_C45 | 0x02EE02)
|
||||
+#define EWIS_INTR_STAT2 (MII_ADDR_C45 | 0x02EE03)
|
||||
+#define EWIS_INTR_PEND2 (MII_ADDR_C45 | 0x02EE04)
|
||||
+#define EWIS_INTR_MASKA_2 (MII_ADDR_C45 | 0x02EE05)
|
||||
+#define EWIS_INTR_MASKB_2 (MII_ADDR_C45 | 0x02EE06)
|
||||
+#define EWIS_FAULT_MASK (MII_ADDR_C45 | 0x02EE07)
|
||||
+#define EWIS_INTR_PEND3 (MII_ADDR_C45 | 0x02EE08)
|
||||
+#define EWIS_INTR_MASKA_3 (MII_ADDR_C45 | 0x02EE09)
|
||||
+#define EWIS_INTR_MASKB_3 (MII_ADDR_C45 | 0x02EE0A)
|
||||
+
|
||||
+/* Device ID
|
||||
+ * 15:0 - device ID
|
||||
+ */
|
||||
+#define GBL_DEVICE_ID (MII_ADDR_C45 | 0x1e0000)
|
||||
+/* Device revision
|
||||
+ * 15:04 - reserved
|
||||
+ * 03:00 - revision ID
|
||||
+ */
|
||||
+#define GBL_DEVICE_REVISION (MII_ADDR_C45 | 0x1e0001)
|
||||
+/* Block Level Software Reset
|
||||
+ * 15:14 - reserved
|
||||
+ * 13: - software reset EDC 1 (1 = reset, autoclears)
|
||||
+ * 12: - software reset EDC 0 (1 = reset, autoclears)
|
||||
+ * 11:10 - reserved
|
||||
+ * 09: - Software reset channel 1 (1 = reset, autoclears)
|
||||
+ * 08: - Software reset channel 0 (1 = reset, autoclears)
|
||||
+ * 07: - Microprocessor reset (0 = normal operation, 1 = reset)
|
||||
+ * 06: - Software reset BIU (1 = reset, autoclears)
|
||||
+ * 05: - Software reset TWS slave (1 = reset, autoclears)
|
||||
+ * 04: - Software reset TWS master (1 = reset, autoclears)
|
||||
+ * 03: - Software reset MDIO (1 = reset, autoclears)
|
||||
+ * 02: - Software reset UART (1 = reset, autoclears)
|
||||
+ * 01: - Global register reset (1 = reset, autoclears)
|
||||
+ * 00: - Software reset chip (1 = reset, autoclears)
|
||||
+ */
|
||||
+#define GBL_BLOCK_LVL_SW_RESET (MII_ADDR_C45 | 0x1e0002)
|
||||
+#define GBL_GPIO_0_CONFIG1_STATUS (MII_ADDR_C45 | 0x1e0100)
|
||||
+#define GBL_GPIO_0_CONFIG2 (MII_ADDR_C45 | 0x1e0101)
|
||||
+#define GBL_DEVICE_ID (MII_ADDR_C45 | 0x1e0000)
|
||||
+#define GBL_FW_CHECKSUM (MII_ADDR_C45 | 0x1e7fe0)
|
||||
+#define GBL_FW_WATCHDOG (MII_ADDR_C45 | 0x1e7fe1)
|
||||
+#define GBL_FW_VERSION (MII_ADDR_C45 | 0x1e7fe2)
|
||||
+#define GBL_FW_VAR_ACC_CTRL (MII_ADDR_C45 | 0x1e7fe3)
|
||||
+#define GBL_FW_VAR_ACC_DATA (MII_ADDR_C45 | 0x1e7fe4)
|
||||
+
|
||||
+/* The Vitesse VSC848X series are 10G PHYs.
|
||||
+ *
|
||||
+ * Some of these devices contain multiple PHYs in a single package and
|
||||
+ * some features are controlled by a global set of registers shared between
|
||||
+ * all of the PHY devices. Because of this a nexus is used to handle all
|
||||
+ * of the PHYs on the same device.
|
||||
+ *
|
||||
+ * Unlike some PHY devices, it is up to the driver to read the SFP module
|
||||
+ * serial EEPROM in order to put the PHY into the right mode. The VSC848X
|
||||
+ * does not provide an I2C interface so the PHY driver relies on the
|
||||
+ * external AT24 I2C EEPROM driver to read the module whenever it is inserted.
|
||||
+ *
|
||||
+ */
|
||||
+
|
||||
+/* Enable LOPC detection (see 0x5B for target state)
|
||||
+ * 15:12 - channel 3
|
||||
+ * 11:08 - channel 2
|
||||
+ * 07:04 - channel 1
|
||||
+ * 03:00 - channel 0
|
||||
+ * 1 = enable (default), 0 = disable
|
||||
+ */
|
||||
+#define FW_VAR_ENABLE_LOPC 0x58
|
||||
+/* While in tracking mode, go to this state in response to LOPC assertion
|
||||
+ * 1 = reset, 2 = wait (default), 3 = converging, 4 = tracking, 5 = freeze
|
||||
+ */
|
||||
+#define FW_VAR_LOPC_ASSERT_MODE 0x5B
|
||||
+/* While in freeze mode, enable state transition upon deassertion of LOPC (see
|
||||
+ * 0x61 for target state)
|
||||
+ * 1 - reset, 2 = wait, 3 = converging, 4 = tracking (default), 5 = freeze
|
||||
+ */
|
||||
+#define FW_VAR_FREEZE_DEASSERT_MODE 0x61
|
||||
+/* Current functional mode
|
||||
+ * See VITESSE_FUNC_MODE_XXX below for values
|
||||
+ * NOTE: When the firmware is done servicing the mode change request, bit 4
|
||||
+ * will be set to 1.
|
||||
+ */
|
||||
+#define FW_VAR_FUNCTIONAL_MODE 0x94
|
||||
+/* Current state of graded SPSA process
|
||||
+ * 3: channel 3
|
||||
+ * 2: channel 2
|
||||
+ * 1: channel 1
|
||||
+ * 0: channel 0
|
||||
+ * 1 = busy, 2 = done
|
||||
+ */
|
||||
+#define FW_VAR_GRADED_SPSA_STATE 0x95
|
||||
+/* BerScore at start of SPSA cycle */
|
||||
+#define FW_VAR_BERSCORE_START 0x96
|
||||
+/* BerScore at end of SPSA cycle */
|
||||
+#define FW_VAR_BERSCORE_END 0x97
|
||||
+/* Enable/Disable aggressive track phase on entering tracking state
|
||||
+ * 15:12 - channel 3
|
||||
+ * 11:08 - channel 2
|
||||
+ * 07:04 - channel 1
|
||||
+ * 03:00 - channel 0
|
||||
+ * 0 = disable, 1 = enable (default)
|
||||
+ */
|
||||
+#define FW_VAR_AGG_TRACKING 0xAF
|
||||
+
|
||||
+/* Modes for the PHY firmware */
|
||||
+#define VITESSE_FUNC_MODE_LIMITING 2 /* Optical */
|
||||
+#define VITESSE_FUNC_MODE_COPPER 3 /* Copper */
|
||||
+#define VITESSE_FUNC_MODE_LINEAR 4
|
||||
+#define VITESSE_FUNC_MODE_KR 5
|
||||
+#define VITESSE_FUNC_MODE_ZR 7
|
||||
+#define VITESSE_FUNC_MODE_1G 8
|
||||
+
|
||||
+
|
||||
+struct vsc848x_nexus_mdiobus {
|
||||
+ struct mii_bus *mii_bus;
|
||||
+ struct mii_bus *parent_mii_bus;
|
||||
+ int reg_offset;
|
||||
+ struct mutex lock; /* Lock used for global register sequences */
|
||||
+ int phy_irq[PHY_MAX_ADDR];
|
||||
+};
|
||||
+
|
||||
+struct vsc848x_phy_info {
|
||||
+ int sfp_conn; /* Module connected? */
|
||||
+ int tx_en_gpio; /* GPIO that enables transmit */
|
||||
+ int mod_abs_gpio; /* Module Absent GPIO line */
|
||||
+ int tx_fault_gpio; /* TX Fault GPIO line */
|
||||
+ int inta_gpio, intb_gpio; /* Interrupt GPIO line (output) */
|
||||
+ uint8_t mode; /* Mode for module */
|
||||
+ uint8_t channel; /* channel in multi-phy devices */
|
||||
+ struct device_node *sfp_node; /* EEPROM NODE for SFP */
|
||||
+ struct memory_accessor *macc; /* memory access routines for EEPROM */
|
||||
+ struct vsc848x_nexus_mdiobus *nexus; /* Nexus for lock */
|
||||
+};
|
||||
+
|
||||
+/**
|
||||
+ * Maps GPIO lines to the global GPIO config registers.
|
||||
+ *
|
||||
+ * Please see the data sheet since the configuration for each GPIO line is
|
||||
+ * different.
|
||||
+ */
|
||||
+static const struct {
|
||||
+ uint32_t config1_status_reg;
|
||||
+ uint32_t config2_reg;
|
||||
+} vcs848x_gpio_to_reg[12] = {
|
||||
+ { (MII_ADDR_C45 | 0x1e0100), (MII_ADDR_C45 | 0x1e0101) }, /* 0 */
|
||||
+ { (MII_ADDR_C45 | 0x1e0102), (MII_ADDR_C45 | 0x1e0103) }, /* 1 */
|
||||
+ { (MII_ADDR_C45 | 0x1e0104), (MII_ADDR_C45 | 0x1e0105) }, /* 2 */
|
||||
+ { (MII_ADDR_C45 | 0x1e0106), (MII_ADDR_C45 | 0x1e0107) }, /* 3 */
|
||||
+ { (MII_ADDR_C45 | 0x1e0108), (MII_ADDR_C45 | 0x1e0109) }, /* 4 */
|
||||
+ { (MII_ADDR_C45 | 0x1e010A), (MII_ADDR_C45 | 0x1e010B) }, /* 5 */
|
||||
+ { (MII_ADDR_C45 | 0x1e0124), (MII_ADDR_C45 | 0x1e0125) }, /* 6 */
|
||||
+ { (MII_ADDR_C45 | 0x1e0126), (MII_ADDR_C45 | 0x1e0127) }, /* 7 */
|
||||
+ { (MII_ADDR_C45 | 0x1e0128), (MII_ADDR_C45 | 0x1e0129) }, /* 8 */
|
||||
+ { (MII_ADDR_C45 | 0x1e012a), (MII_ADDR_C45 | 0x1e012b) }, /* 9 */
|
||||
+ { (MII_ADDR_C45 | 0x1e012c), (MII_ADDR_C45 | 0x1e012d) }, /* 10 */
|
||||
+ { (MII_ADDR_C45 | 0x1e012e), (MII_ADDR_C45 | 0x1e012f) }, /* 11 */
|
||||
+};
|
||||
+
|
||||
+static int vsc848x_probe(struct phy_device *phydev)
|
||||
+{
|
||||
+ struct vsc848x_phy_info *dev_info;
|
||||
+ int ret;
|
||||
+
|
||||
+ dev_info = devm_kzalloc(&phydev->dev, sizeof(*dev_info), GFP_KERNEL);
|
||||
+ if (dev_info == NULL)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ phydev->priv = dev_info;
|
||||
+ dev_info->mode = VITESSE_FUNC_MODE_LIMITING; /* Default to optical */
|
||||
+ phydev->priv = dev_info;
|
||||
+ dev_info->nexus = phydev->bus->priv;
|
||||
+
|
||||
+ ret = of_property_read_u32(phydev->dev.of_node, "mod_abs",
|
||||
+ &dev_info->mod_abs_gpio);
|
||||
+ if (ret) {
|
||||
+ dev_err(&phydev->dev, "%s has invalid mod_abs address\n",
|
||||
+ phydev->dev.of_node->full_name);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ ret = of_property_read_u32(phydev->dev.of_node, "tx_fault",
|
||||
+ &dev_info->tx_fault_gpio);
|
||||
+ if (ret) {
|
||||
+ dev_err(&phydev->dev, "%s has invalid tx_fault address\n",
|
||||
+ phydev->dev.of_node->full_name);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ ret = of_property_read_u32(phydev->dev.of_node, "inta",
|
||||
+ &dev_info->inta_gpio);
|
||||
+ if (ret)
|
||||
+ dev_info->inta_gpio = -1;
|
||||
+
|
||||
+ ret = of_property_read_u32(phydev->dev.of_node, "intb",
|
||||
+ &dev_info->intb_gpio);
|
||||
+ if (ret)
|
||||
+ dev_info->intb_gpio = -1;
|
||||
+
|
||||
+ ret = of_property_read_u32(phydev->dev.of_node, "txon",
|
||||
+ &dev_info->tx_en_gpio);
|
||||
+ if (ret) {
|
||||
+ dev_err(&phydev->dev, "%s has invalid txon gpio address\n",
|
||||
+ phydev->dev.of_node->full_name);
|
||||
+ return -ENXIO;
|
||||
+ }
|
||||
+
|
||||
+ dev_info->sfp_node = of_parse_phandle(phydev->dev.of_node,
|
||||
+ "sfp-eeprom", 0);
|
||||
+ if (!dev_info->sfp_node) {
|
||||
+ dev_err(&phydev->dev, "%s has invalid sfp-eeprom node\n",
|
||||
+ phydev->dev.of_node->full_name);
|
||||
+ return -ENXIO;
|
||||
+ }
|
||||
+
|
||||
+ dev_info->macc = of_memory_accessor_get(dev_info->sfp_node);
|
||||
+
|
||||
+ ret = phy_read(phydev, GBL_DEVICE_ID);
|
||||
+ if (ret < 0) {
|
||||
+ dev_err(&phydev->dev, "%s error reading PHY\n",
|
||||
+ phydev->dev.of_node->full_name);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ /* Check how many devices are in the package to figure out the channel
|
||||
+ * number.
|
||||
+ */
|
||||
+ switch (ret) {
|
||||
+ case 0x8487: /* Single */
|
||||
+ case 0x8486:
|
||||
+ dev_info->channel = 0;
|
||||
+ break;
|
||||
+ case 0x8488: /* Dual */
|
||||
+ dev_info->channel = phydev->addr & 1;
|
||||
+ break;
|
||||
+ case 0x8484: /* Quad */
|
||||
+ dev_info->channel = phydev->addr & 3;
|
||||
+ break;
|
||||
+ default:
|
||||
+ dev_err(&phydev->dev, "%s Unknown Vitesse PHY model %04x\n",
|
||||
+ phydev->dev.of_node->full_name, ret);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void vsc848x_remove(struct phy_device *phydev)
|
||||
+{
|
||||
+ struct vsc848x_phy_info *dev_info = phydev->priv;
|
||||
+
|
||||
+ dev_info(&phydev->dev, "%s Exiting\n", phydev->dev.of_node->full_name);
|
||||
+
|
||||
+ of_memory_accessor_put(dev_info->sfp_node);
|
||||
+
|
||||
+ kfree(dev_info);
|
||||
+}
|
||||
+
|
||||
+static int vsc848x_config_init(struct phy_device *phydev)
|
||||
+{
|
||||
+ phydev->supported = SUPPORTED_10000baseR_FEC;
|
||||
+ phydev->advertising = ADVERTISED_10000baseR_FEC;
|
||||
+ phydev->state = PHY_NOLINK;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int vsc848x_config_aneg(struct phy_device *phydev)
|
||||
+{
|
||||
+ return -EINVAL;
|
||||
+}
|
||||
+
|
||||
+static int vsc848x_write_global_var(struct phy_device *phydev, uint8_t channel,
|
||||
+ uint8_t addr, uint16_t value)
|
||||
+{
|
||||
+ struct vsc848x_phy_info *dev_info = phydev->priv;
|
||||
+ int timeout = 1000;
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ mutex_lock(&(dev_info->nexus->lock));
|
||||
+
|
||||
+ /* Wait for firmware download to complete */
|
||||
+ timeout = 100000;
|
||||
+ do {
|
||||
+ ret = phy_read(phydev, MII_ADDR_C45 | 0x1e7fe0);
|
||||
+ if (ret < 0)
|
||||
+ goto error;
|
||||
+ if (ret == 3)
|
||||
+ break;
|
||||
+ udelay(100);
|
||||
+ } while (timeout-- > 0);
|
||||
+ if (timeout <= 0) {
|
||||
+ dev_err(&phydev->dev, "%s Timeout waiting for PHY firmware to load\n",
|
||||
+ phydev->dev.of_node->full_name);
|
||||
+ ret = -EIO;
|
||||
+ goto error;
|
||||
+ }
|
||||
+
|
||||
+ do {
|
||||
+ ret = phy_read(phydev, (MII_ADDR_C45 | 0x1e7fe3));
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+ if (ret == 0)
|
||||
+ break;
|
||||
+ mdelay(1);
|
||||
+ } while (timeout-- > 0);
|
||||
+ if (timeout <= 0) {
|
||||
+ dev_err(&phydev->dev, "%s timed out waiting to write global\n",
|
||||
+ phydev->dev.of_node->full_name);
|
||||
+ ret = -EIO;
|
||||
+ goto error;
|
||||
+ }
|
||||
+ ret = phy_write(phydev, (MII_ADDR_C45 | 0x1e7fe4), value);
|
||||
+ if (ret < 0)
|
||||
+ goto error;
|
||||
+
|
||||
+ ret = phy_write(phydev, (MII_ADDR_C45 | 0x1e7fe3),
|
||||
+ 0x8000 | ((channel & 3) << 8) | addr);
|
||||
+ if (ret < 0)
|
||||
+ goto error;
|
||||
+
|
||||
+ /* Wait for value to be written */
|
||||
+ do {
|
||||
+ ret = phy_read(phydev, (MII_ADDR_C45 | 0x1e7fe3));
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+ if (ret == 0)
|
||||
+ break;
|
||||
+ mdelay(1);
|
||||
+ } while (timeout-- > 0);
|
||||
+ if (timeout <= 0) {
|
||||
+ dev_err(&phydev->dev, "%s timed out waiting to write global\n",
|
||||
+ phydev->dev.of_node->full_name);
|
||||
+ ret = -EIO;
|
||||
+ goto error;
|
||||
+ }
|
||||
+ ret = 0;
|
||||
+
|
||||
+error:
|
||||
+ mutex_unlock(&(dev_info->nexus->lock));
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * Dumps out the contents of the SFP EEPROM when errors are detected
|
||||
+ *
|
||||
+ * @param eeprom - contents of SFP+ EEPROM
|
||||
+ */
|
||||
+static void dump_sfp_eeprom(const uint8_t eeprom[64])
|
||||
+{
|
||||
+ int addr = 0;
|
||||
+ int i;
|
||||
+ char line[17];
|
||||
+ line[16] = '\0';
|
||||
+
|
||||
+ pr_info("SFP+ EEPROM contents:\n");
|
||||
+ while (addr < 64) {
|
||||
+ pr_info(" %02x: ", addr);
|
||||
+ for (i = 0; i < 16; i++)
|
||||
+ pr_cont("%02x ", eeprom[addr + i]);
|
||||
+ for (i = 0; i < 16; i++) {
|
||||
+ if (!isprint(eeprom[addr + i]) ||
|
||||
+ eeprom[addr + i] >= 0x80)
|
||||
+ line[i] = '.';
|
||||
+ else
|
||||
+ line[i] = eeprom[addr + i];
|
||||
+ }
|
||||
+ pr_cont(" %s\n", line);
|
||||
+ addr += 16;
|
||||
+ }
|
||||
+ pr_info("\n");
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * Read the SFP+ module EEPROM and program the Vitesse PHY accordingly.
|
||||
+ *
|
||||
+ * @param phydev - Phy device
|
||||
+ *
|
||||
+ * @returns 0 for success, error otherwise.
|
||||
+ */
|
||||
+static int vsc848x_read_sfp(struct phy_device *phydev)
|
||||
+{
|
||||
+ struct vsc848x_phy_info *dev_info = phydev->priv;
|
||||
+ uint8_t sfp_buffer[64];
|
||||
+ ssize_t size;
|
||||
+ uint8_t csum;
|
||||
+ uint8_t mode = VITESSE_FUNC_MODE_LIMITING;
|
||||
+ const char *mode_str = "Unknown";
|
||||
+ int i;
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ /* For details on the SFP+ EEPROM contents see the SFF-8472
|
||||
+ * Diagnostic Monitoring Interface for Optical Transceivers.
|
||||
+ *
|
||||
+ * This is based on revision 11.1, October 26, 2012.
|
||||
+ */
|
||||
+ if (!dev_info->macc) {
|
||||
+ dev_info->macc = of_memory_accessor_get(dev_info->sfp_node);
|
||||
+ if (!dev_info->macc) {
|
||||
+ dev_info(&phydev->dev,
|
||||
+ "Could not connect to sfp memory accessor %s\n",
|
||||
+ dev_info->sfp_node->full_name);
|
||||
+ return -ENODEV;
|
||||
+ }
|
||||
+ }
|
||||
+ size = dev_info->macc->read(dev_info->macc,
|
||||
+ (char *)sfp_buffer, 0, sizeof(sfp_buffer));
|
||||
+ if (size != sizeof(sfp_buffer)) {
|
||||
+ dev_err(&phydev->dev, "%s cannot read SFP module EEPROM\n",
|
||||
+ phydev->dev.of_node->full_name);
|
||||
+ return -ENODEV;
|
||||
+ }
|
||||
+
|
||||
+ /* Validate SFP checksum */
|
||||
+ csum = 0;
|
||||
+ for (i = 0; i < 63; i++)
|
||||
+ csum += sfp_buffer[i];
|
||||
+ if (csum != sfp_buffer[63]) {
|
||||
+ dev_err(&phydev->dev, "%s SFP EEPROM checksum bad, calculated 0x%02x, should be 0x%02x\n",
|
||||
+ phydev->dev.of_node->full_name, csum, sfp_buffer[63]);
|
||||
+ dump_sfp_eeprom(sfp_buffer);
|
||||
+ return -ENXIO;
|
||||
+ }
|
||||
+
|
||||
+ /* Make sure it's a SFP or SFP+ module */
|
||||
+ if (sfp_buffer[0] != 3) {
|
||||
+ dev_err(&phydev->dev, "%s module is not SFP or SFP+\n",
|
||||
+ phydev->dev.of_node->full_name);
|
||||
+ dump_sfp_eeprom(sfp_buffer);
|
||||
+ return -ENXIO;
|
||||
+ }
|
||||
+
|
||||
+ /* Check connector type */
|
||||
+ switch (sfp_buffer[2]) {
|
||||
+ case 0x01: /* SC */
|
||||
+ mode = VITESSE_FUNC_MODE_LIMITING;
|
||||
+ break;
|
||||
+ case 0x07: /* LC */
|
||||
+ mode = VITESSE_FUNC_MODE_LIMITING;
|
||||
+ break;
|
||||
+ case 0x0B: /* Optical pigtail */
|
||||
+ mode = VITESSE_FUNC_MODE_LIMITING;
|
||||
+ break;
|
||||
+ case 0x21: /* Copper pigtail */
|
||||
+ case 0x22: /* RJ45 */
|
||||
+ mode = VITESSE_FUNC_MODE_COPPER;
|
||||
+ break;
|
||||
+ default:
|
||||
+ dev_err(&phydev->dev, "%s Unknown Connector Type 0x%x\n",
|
||||
+ phydev->dev.of_node->full_name, sfp_buffer[2]);
|
||||
+ dump_sfp_eeprom(sfp_buffer);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ if (mode == VITESSE_FUNC_MODE_LIMITING) {
|
||||
+ if (mode_str[3] & 0x10)
|
||||
+ mode_str = "10GBase-SR";
|
||||
+ else if (mode_str[3] & 0x20)
|
||||
+ mode_str = "10GBase-LR";
|
||||
+ else if (mode_str[3] & 0x40)
|
||||
+ mode_str = "10GBase-LRM";
|
||||
+ else if (mode_str[3] & 0x80)
|
||||
+ mode_str = "10GBase-ER";
|
||||
+ else
|
||||
+ dev_err(&phydev->dev, "%s unknown SFP compatibility\n"
|
||||
+ "type ID: 0x%02x, extended ID: 0x%02x, Connector type code: 0x%02x\n"
|
||||
+ "Transceiver compatibility code: (%02x) %02x %02x %02x %02x %02x %02x %02x %02x\n",
|
||||
+ phydev->dev.of_node->full_name, sfp_buffer[0],
|
||||
+ sfp_buffer[1], sfp_buffer[2], sfp_buffer[36],
|
||||
+ sfp_buffer[3], sfp_buffer[4], sfp_buffer[5],
|
||||
+ sfp_buffer[6], sfp_buffer[7], sfp_buffer[8],
|
||||
+ sfp_buffer[9], sfp_buffer[10]);
|
||||
+ } else if (mode == VITESSE_FUNC_MODE_COPPER) {
|
||||
+ if (sfp_buffer[8] & 0x4) {
|
||||
+ mode_str = "10G Passive Copper";
|
||||
+ } else if (sfp_buffer[8] & 0x8) {
|
||||
+ mode_str = "10G Active Copper";
|
||||
+ mode = VITESSE_FUNC_MODE_LIMITING;
|
||||
+ } else {
|
||||
+ dev_err(&phydev->dev, "%s Unknown SFP+ copper cable capability 0x%02x\n"
|
||||
+ "Transceiver compatibility code: (%02x) %02x %02x %02x %02x %02x %02x %02x %02x\n",
|
||||
+ phydev->dev.of_node->full_name, sfp_buffer[8],
|
||||
+ sfp_buffer[36], sfp_buffer[3], sfp_buffer[4],
|
||||
+ sfp_buffer[5], sfp_buffer[6], sfp_buffer[7],
|
||||
+ sfp_buffer[8], sfp_buffer[9], sfp_buffer[10]);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+ } else {
|
||||
+ dev_err(&phydev->dev, "%s Unsupported phy mode %d\n",
|
||||
+ phydev->dev.of_node->full_name, mode);
|
||||
+ dump_sfp_eeprom(sfp_buffer);
|
||||
+ }
|
||||
+
|
||||
+ vsc848x_write_global_var(phydev, dev_info->channel, 0x94, mode);
|
||||
+
|
||||
+ /* Adjust PMA_TXOUTCTRL2 based on cable length. Vitesse recommends
|
||||
+ * 0x1606 for copper cable lengths 5M and longer.
|
||||
+ *
|
||||
+ * The default value is 0x1300.
|
||||
+ */
|
||||
+ if (mode == VITESSE_FUNC_MODE_COPPER) {
|
||||
+ if (sfp_buffer[18] >= 5)
|
||||
+ ret = phy_write(phydev, PMA_TXOUTCTRL2, 0x1606);
|
||||
+ else
|
||||
+ ret = phy_write(phydev, PMA_TXOUTCTRL2, 0x1300);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ /* Reset the state machine */
|
||||
+ ret = phy_write(phydev, MII_ADDR_C45 | 0x18034, 0x11);
|
||||
+
|
||||
+ dev_info(&phydev->dev, "%s configured for %s\n",
|
||||
+ phydev->dev.of_node->full_name, mode_str);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int vsc848x_read_status(struct phy_device *phydev)
|
||||
+{
|
||||
+ struct vsc848x_phy_info *dev_info = phydev->priv;
|
||||
+ int rx_signal_detect;
|
||||
+ int pcs_status;
|
||||
+ int xgxs_lane_status;
|
||||
+ int value;
|
||||
+ int sfp_conn;
|
||||
+ int ret;
|
||||
+
|
||||
+ /* Check if a module is plugged in */
|
||||
+ value = phy_read(phydev, vcs848x_gpio_to_reg[dev_info->mod_abs_gpio]
|
||||
+ .config1_status_reg);
|
||||
+ if (value < 0)
|
||||
+ return value;
|
||||
+
|
||||
+ sfp_conn = !(value & 0x400);
|
||||
+
|
||||
+ if (sfp_conn != dev_info->sfp_conn) {
|
||||
+ /* We detect a module being plugged in */
|
||||
+ if (sfp_conn) {
|
||||
+ ret = vsc848x_read_sfp(phydev);
|
||||
+ if (ret < 0)
|
||||
+ goto no_link;
|
||||
+ dev_info->sfp_conn = sfp_conn;
|
||||
+ } else {
|
||||
+ dev_info(&phydev->dev, "%s module unplugged\n",
|
||||
+ phydev->dev.of_node->full_name);
|
||||
+ dev_info->sfp_conn = sfp_conn;
|
||||
+ goto no_link;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ rx_signal_detect = phy_read(phydev, PMD_RX_SIGNAL_DETECT);
|
||||
+ if (rx_signal_detect < 0)
|
||||
+ return rx_signal_detect;
|
||||
+
|
||||
+ if ((rx_signal_detect & 1) == 0)
|
||||
+ goto no_link;
|
||||
+
|
||||
+ pcs_status = phy_read(phydev, BASER_PCS_STATUS);
|
||||
+ if (pcs_status < 0)
|
||||
+ return pcs_status;
|
||||
+
|
||||
+ if ((pcs_status & 1) == 0)
|
||||
+ goto no_link;
|
||||
+
|
||||
+ xgxs_lane_status = phy_read(phydev, XGXS_LANE_STATUS);
|
||||
+ if (xgxs_lane_status < 0)
|
||||
+ return xgxs_lane_status;
|
||||
+
|
||||
+ if ((xgxs_lane_status & 0x1000) == 0)
|
||||
+ goto no_link;
|
||||
+
|
||||
+ phydev->speed = 10000;
|
||||
+ phydev->link = 1;
|
||||
+ phydev->duplex = 1;
|
||||
+ return 0;
|
||||
+no_link:
|
||||
+ phydev->link = 0;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static struct of_device_id vsc848x_match[] = {
|
||||
+ {
|
||||
+ .compatible = "vitesse,vsc8488",
|
||||
+ },
|
||||
+ {
|
||||
+ .compatible = "vitesse,vsc8486",
|
||||
+ },
|
||||
+ {
|
||||
+ .compatible = "vitesse,vsc8484",
|
||||
+ },
|
||||
+ {},
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, vsc848x_match);
|
||||
+
|
||||
+static struct phy_driver vsc848x_phy_driver = {
|
||||
+ .phy_id = 0x00070400,
|
||||
+ .phy_id_mask = 0xfffffff0,
|
||||
+ .name = "Vitesse VSC848X",
|
||||
+ .config_init = vsc848x_config_init,
|
||||
+ .probe = vsc848x_probe,
|
||||
+ .remove = vsc848x_remove,
|
||||
+ .config_aneg = vsc848x_config_aneg,
|
||||
+ .read_status = vsc848x_read_status,
|
||||
+ .driver = {
|
||||
+ .owner = THIS_MODULE,
|
||||
+ .of_match_table = vsc848x_match,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+/* Phy nexus support below. */
|
||||
+
|
||||
+static int vsc848x_nexus_read(struct mii_bus *bus, int phy_id, int regnum)
|
||||
+{
|
||||
+ struct vsc848x_nexus_mdiobus *p = bus->priv;
|
||||
+ return p->parent_mii_bus->read(p->parent_mii_bus,
|
||||
+ phy_id + p->reg_offset,
|
||||
+ regnum);
|
||||
+}
|
||||
+
|
||||
+static int vsc848x_nexus_write(struct mii_bus *bus, int phy_id,
|
||||
+ int regnum, u16 val)
|
||||
+{
|
||||
+ struct vsc848x_nexus_mdiobus *p = bus->priv;
|
||||
+ return p->parent_mii_bus->write(p->parent_mii_bus,
|
||||
+ phy_id + p->reg_offset,
|
||||
+ regnum, val);
|
||||
+}
|
||||
+
|
||||
+static int vsc848x_nexus_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct vsc848x_nexus_mdiobus *bus;
|
||||
+ const char *bus_id;
|
||||
+ int len;
|
||||
+ int err = 0;
|
||||
+
|
||||
+ bus = devm_kzalloc(&pdev->dev, sizeof(*bus), GFP_KERNEL);
|
||||
+ if (!bus)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ bus->parent_mii_bus = container_of(pdev->dev.parent,
|
||||
+ struct mii_bus, dev);
|
||||
+
|
||||
+ /* The PHY nexux must have a reg property in the range [0-31] */
|
||||
+ err = of_property_read_u32(pdev->dev.of_node, "reg", &bus->reg_offset);
|
||||
+ if (err) {
|
||||
+ dev_err(&pdev->dev, "%s has invalid PHY address\n",
|
||||
+ pdev->dev.of_node->full_name);
|
||||
+ return err;
|
||||
+ }
|
||||
+
|
||||
+ bus->mii_bus = mdiobus_alloc();
|
||||
+ if (!bus->mii_bus)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ bus->mii_bus->priv = bus;
|
||||
+ bus->mii_bus->irq = bus->phy_irq;
|
||||
+ bus->mii_bus->name = "vsc848x_nexus";
|
||||
+ bus_id = bus->parent_mii_bus->id;
|
||||
+ len = strlen(bus_id);
|
||||
+ if (len > MII_BUS_ID_SIZE - 4)
|
||||
+ bus_id += len - (MII_BUS_ID_SIZE - 4);
|
||||
+ snprintf(bus->mii_bus->id, MII_BUS_ID_SIZE, "%s:%02x",
|
||||
+ bus_id, bus->reg_offset);
|
||||
+ bus->mii_bus->parent = &pdev->dev;
|
||||
+
|
||||
+ bus->mii_bus->read = vsc848x_nexus_read;
|
||||
+ bus->mii_bus->write = vsc848x_nexus_write;
|
||||
+ mutex_init(&bus->lock);
|
||||
+
|
||||
+ dev_set_drvdata(&pdev->dev, bus);
|
||||
+
|
||||
+ err = of_mdiobus_register(bus->mii_bus, pdev->dev.of_node);
|
||||
+ if (err) {
|
||||
+ dev_err(&pdev->dev, "Error registering with device tree\n");
|
||||
+ goto fail_register;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+fail_register:
|
||||
+ dev_err(&pdev->dev, "Failed to register\n");
|
||||
+ mdiobus_free(bus->mii_bus);
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
+static int vsc848x_nexus_remove(struct platform_device *pdev)
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static struct of_device_id vsc848x_nexus_match[] = {
|
||||
+ {
|
||||
+ .compatible = "vitesse,vsc8488-nexus",
|
||||
+ },
|
||||
+ {
|
||||
+ .compatible = "vitesse,vsc8486-nexus",
|
||||
+ },
|
||||
+ {
|
||||
+ .compatible = "vitesse,vsc8484-nexus",
|
||||
+ },
|
||||
+ {},
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, vsc848x_nexus_match);
|
||||
+
|
||||
+static struct platform_driver vsc848x_nexus_driver = {
|
||||
+ .driver = {
|
||||
+ .name = "vsc848x-nexus",
|
||||
+ .owner = THIS_MODULE,
|
||||
+ .of_match_table = vsc848x_nexus_match,
|
||||
+ },
|
||||
+ .probe = vsc848x_nexus_probe,
|
||||
+ .remove = vsc848x_nexus_remove,
|
||||
+};
|
||||
+
|
||||
+static int __init vsc848x_mod_init(void)
|
||||
+{
|
||||
+ int rv;
|
||||
+
|
||||
+ rv = platform_driver_register(&vsc848x_nexus_driver);
|
||||
+ if (rv)
|
||||
+ return rv;
|
||||
+
|
||||
+ rv = phy_driver_register(&vsc848x_phy_driver);
|
||||
+
|
||||
+ return rv;
|
||||
+}
|
||||
+module_init(vsc848x_mod_init);
|
||||
+
|
||||
+static void __exit vsc848x_mod_exit(void)
|
||||
+{
|
||||
+ phy_driver_unregister(&vsc848x_phy_driver);
|
||||
+ platform_driver_unregister(&vsc848x_nexus_driver);
|
||||
+}
|
||||
+module_exit(vsc848x_mod_exit);
|
||||
+
|
||||
+MODULE_DESCRIPTION("Driver for Vitesse VSC848X PHY");
|
||||
+MODULE_AUTHOR("David Daney and Aaron Williams");
|
||||
+MODULE_LICENSE("GPL");
|
@ -0,0 +1,310 @@
|
||||
From: Abhishek Paliwal <abhishek.paliwal@aricent.com>
|
||||
Date: Fri, 13 Feb 2015 12:47:36 +0530
|
||||
Subject: of: Add of_memory_accessor to map device tree node to memory accessor
|
||||
functions.
|
||||
|
||||
From: Aaron Williams <aaron.williams@cavium.com>
|
||||
|
||||
Currently there is no easy way to map a device tree node to a memory
|
||||
accessor function for devices like I2C EEPROMs. For example, the Vitesse
|
||||
vsc848x 10G PHY driver needs to be able to use the I2C at24 serial EEPROM
|
||||
memory accessor function in order to read the SFP+ eeprom.
|
||||
|
||||
This provides a way where the vsc848x module can parse its device tree and
|
||||
easily gain the accessor functions for the eeprom through a phandle.
|
||||
|
||||
This may be useful for any module which provides memory accessor functions.
|
||||
|
||||
Signed-off-by: Aaron Williams <aaron.williams@cavium.com>
|
||||
Signed-off-by: Leonid Rosenboim <lrosenboim@caviumnetworks.com>
|
||||
Signed-off-by: Abhishek Paliwal <abhishek.paliwal@aricent.com>
|
||||
--- a/drivers/of/Kconfig
|
||||
+++ b/drivers/of/Kconfig
|
||||
@@ -107,4 +107,10 @@
|
||||
# arches should select this if DMA is coherent by default for OF devices
|
||||
bool
|
||||
|
||||
+config OF_MEMORY_ACCESSOR
|
||||
+ def_bool y
|
||||
+ help
|
||||
+ OpenFirmware memory accessor support for accessing devices like
|
||||
+ i2c and SPI eeproms.
|
||||
+
|
||||
endif # OF
|
||||
|
||||
--- a/drivers/of/Makefile
|
||||
+++ b/drivers/of/Makefile
|
||||
@@ -16,3 +16,4 @@
|
||||
obj-$(CONFIG_OF_NUMA) += of_numa.o
|
||||
|
||||
obj-$(CONFIG_OF_UNITTEST) += unittest-data/
|
||||
+obj-$(CONFIG_OF_MEMORY_ACCESSOR) += of_memory_accessor.o
|
||||
--- /dev/null
|
||||
+++ b/drivers/of/of_memory_accessor.c
|
||||
@@ -0,0 +1,192 @@
|
||||
+/*
|
||||
+ * Memory accessor OF helpers
|
||||
+ *
|
||||
+ * 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) 2012 Cavium Inc.
|
||||
+ */
|
||||
+
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/device.h>
|
||||
+#include <linux/slab.h>
|
||||
+#include <linux/mutex.h>
|
||||
+#include <linux/mod_devicetable.h>
|
||||
+#include <linux/of_memory_accessor.h>
|
||||
+#include <linux/list.h>
|
||||
+#include <linux/memory.h>
|
||||
+
|
||||
+struct of_macc_entry {
|
||||
+ struct list_head list;
|
||||
+ struct device *dev;
|
||||
+ struct memory_accessor *macc;
|
||||
+ int ref;
|
||||
+};
|
||||
+
|
||||
+static DEFINE_MUTEX(lock);
|
||||
+static LIST_HEAD(macc_list);
|
||||
+
|
||||
+/**
|
||||
+ * Adds a mapping of a device node to a memory accessor
|
||||
+ *
|
||||
+ * @param[in] dev - device
|
||||
+ * @param[in] macc - memory accessor
|
||||
+ *
|
||||
+ * @returns 0 for success or -ENOMEM
|
||||
+ */
|
||||
+int of_memory_accessor_register(struct device *dev,
|
||||
+ struct memory_accessor *macc)
|
||||
+{
|
||||
+ struct of_macc_entry *mentry;
|
||||
+
|
||||
+ mentry = kmalloc(sizeof(*mentry), GFP_KERNEL);
|
||||
+ if (mentry == NULL)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ mentry->dev = dev;
|
||||
+ mentry->macc = macc;
|
||||
+ mentry->ref = 0;
|
||||
+
|
||||
+ mutex_lock(&lock);
|
||||
+
|
||||
+ list_add(&(mentry->list), &macc_list);
|
||||
+
|
||||
+ mutex_unlock(&lock);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+EXPORT_SYMBOL(of_memory_accessor_register);
|
||||
+
|
||||
+/**
|
||||
+ * removes the mapping of a device node to a memory accessor
|
||||
+ *
|
||||
+ * @param[in] devnode - device node to remove
|
||||
+ *
|
||||
+ * @returns 0 for success or -ENODEV if device node not found, -EBUSY if still
|
||||
+ * in use
|
||||
+ */
|
||||
+
|
||||
+int of_memory_accessor_remove(struct device *dev)
|
||||
+{
|
||||
+ struct of_macc_entry *mentry;
|
||||
+ struct list_head *pos, *q;
|
||||
+ int ret = -ENODEV;
|
||||
+
|
||||
+ mutex_lock(&lock);
|
||||
+
|
||||
+ list_for_each_safe(pos, q, &macc_list) {
|
||||
+ mentry = list_entry(pos, struct of_macc_entry, list);
|
||||
+ if (mentry->dev == dev) {
|
||||
+ if (mentry->ref > 0) {
|
||||
+ ret = -EBUSY;
|
||||
+ goto done;
|
||||
+ }
|
||||
+ list_del(pos);
|
||||
+ kfree(mentry);
|
||||
+ ret = 0;
|
||||
+ goto done;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* Not found */
|
||||
+done:
|
||||
+ mutex_unlock(&lock);
|
||||
+ return ret;
|
||||
+}
|
||||
+EXPORT_SYMBOL(of_memory_accessor_remove);
|
||||
+
|
||||
+/**
|
||||
+ * Returns the memory accessor for a device node and increments a reference
|
||||
+ * count
|
||||
+ *
|
||||
+ * @param[in] devnode - device node to look up
|
||||
+ *
|
||||
+ * @returns memory accessor for device node or NULL if none found.
|
||||
+ */
|
||||
+struct memory_accessor *
|
||||
+of_memory_accessor_get(const struct device_node *devnode)
|
||||
+{
|
||||
+ struct of_macc_entry *mentry;
|
||||
+ struct list_head *pos;
|
||||
+ struct memory_accessor *macc = NULL;
|
||||
+
|
||||
+ mutex_lock(&lock);
|
||||
+
|
||||
+ list_for_each(pos, &macc_list) {
|
||||
+ mentry = list_entry(pos, struct of_macc_entry, list);
|
||||
+ if (mentry->dev->of_node == devnode) {
|
||||
+ macc = mentry->macc;
|
||||
+ if (!mentry->ref) {
|
||||
+ if (!try_module_get(mentry->dev->driver->owner)) {
|
||||
+ macc = NULL;
|
||||
+ pr_info("Warning: module for %s not found!",
|
||||
+ mentry->dev->of_node->full_name);
|
||||
+ }
|
||||
+ }
|
||||
+ mentry->ref++;
|
||||
+ goto done;
|
||||
+ }
|
||||
+ }
|
||||
+done:
|
||||
+ mutex_unlock(&lock);
|
||||
+ return macc;
|
||||
+}
|
||||
+EXPORT_SYMBOL(of_memory_accessor_get);
|
||||
+
|
||||
+/**
|
||||
+ * Decrements the reference count for the memory accessor attached to the
|
||||
+ * device node.
|
||||
+ *
|
||||
+ * @param[in] devnode - device node to look up
|
||||
+ *
|
||||
+ * @returns 0 for success or -ENODEV if the device node was not found.
|
||||
+ */
|
||||
+int of_memory_accessor_put(const struct device_node *devnode)
|
||||
+{
|
||||
+ struct of_macc_entry *mentry;
|
||||
+ struct list_head *pos;
|
||||
+ int ret = -ENODEV;
|
||||
+
|
||||
+ mutex_lock(&lock);
|
||||
+ list_for_each(pos, &macc_list) {
|
||||
+ mentry = list_entry(pos, struct of_macc_entry, list);
|
||||
+ if (mentry->dev->of_node == devnode) {
|
||||
+ if (mentry->ref > 0)
|
||||
+ mentry->ref--;
|
||||
+ if (!mentry->ref)
|
||||
+ module_put(mentry->dev->driver->owner);
|
||||
+
|
||||
+ module_put(THIS_MODULE);
|
||||
+ ret = 0;
|
||||
+ goto done;
|
||||
+ }
|
||||
+ }
|
||||
+done:
|
||||
+ mutex_unlock(&lock);
|
||||
+ return ret;
|
||||
+}
|
||||
+EXPORT_SYMBOL(of_memory_accessor_put);
|
||||
+
|
||||
+static void __exit of_memory_accessor_exit(void)
|
||||
+{
|
||||
+ struct of_macc_entry *mentry;
|
||||
+ struct list_head *pos, *q;
|
||||
+
|
||||
+ list_for_each_safe(pos, q, &macc_list) {
|
||||
+ mentry = list_entry(pos, struct of_macc_entry, list);
|
||||
+ if (mentry->ref)
|
||||
+ module_put(mentry->dev->driver->owner);
|
||||
+ list_del(pos);
|
||||
+ kfree(mentry);
|
||||
+ }
|
||||
+
|
||||
+ /* Not found */
|
||||
+ mutex_destroy(&lock);
|
||||
+ list_del(&macc_list);
|
||||
+}
|
||||
+module_exit(of_memory_accessor_exit);
|
||||
+
|
||||
+MODULE_DESCRIPTION("Driver for mapping device nodes to memory accessors");
|
||||
+MODULE_AUTHOR("Aaron Williams");
|
||||
+MODULE_LICENSE("GPL");
|
||||
--- /dev/null
|
||||
+++ b/include/linux/of_memory_accessor.h
|
||||
@@ -0,0 +1,71 @@
|
||||
+#ifndef _LINUX_OF_MEMORY_ACCESSOR_H
|
||||
+#define _LINUX_OF_MEMORY_ACCESSOR_H
|
||||
+/*
|
||||
+ * Memory accessor OF helpers
|
||||
+ *
|
||||
+ * 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) 2012 Cavium Inc.
|
||||
+ */
|
||||
+
|
||||
+#include <linux/of.h>
|
||||
+#include <linux/memory.h>
|
||||
+
|
||||
+/**
|
||||
+ * Adds a mapping of a device node to a memory accessor
|
||||
+ *
|
||||
+ * @param[in] dev - device
|
||||
+ * @param[in] macc - memory accessor
|
||||
+ *
|
||||
+ * @returns 0 for success or -ENOMEM
|
||||
+ */
|
||||
+#ifdef CONFIG_OF_MEMORY_ACCESSOR
|
||||
+int of_memory_accessor_register(struct device *dev,
|
||||
+ struct memory_accessor *macc);
|
||||
+#else
|
||||
+static inline int of_memory_accessor_register(struct device *dev,
|
||||
+ struct memory_accessor *macc)
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
+/**
|
||||
+ * removes the mapping of a device node to a memory accessor
|
||||
+ *
|
||||
+ * @param[in] devnode - device node to remove
|
||||
+ *
|
||||
+ * @returns 0 for success or 1 if device node not found
|
||||
+ */
|
||||
+#ifdef CONFIG_OF_MEMORY_ACCESSOR
|
||||
+int of_memory_accessor_remove(struct device *dev);
|
||||
+#else
|
||||
+static inline int of_memory_accessor_remove(struct device *dev)
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
+/**
|
||||
+ * Returns the memory accessor for a device node
|
||||
+ *
|
||||
+ * @param[in] devnode - device node to look up
|
||||
+ *
|
||||
+ * @returns memory accessor for device node or NULL if none found.
|
||||
+ */
|
||||
+struct memory_accessor *
|
||||
+of_memory_accessor_get(const struct device_node *devnode);
|
||||
+
|
||||
+/**
|
||||
+ * Decrements the reference count for the memory accessor attached to the
|
||||
+ * device node.
|
||||
+ *
|
||||
+ * @param[in] devnode - device node to look up
|
||||
+ *
|
||||
+ * @returns 0 for success or -1 if the device node was not found.
|
||||
+ */
|
||||
+int of_memory_accessor_put(const struct device_node *devnode);
|
||||
+
|
||||
+#endif /* _LINUX_OF_MEMORY_ACCESSOR_H */
|
@ -0,0 +1,42 @@
|
||||
From: Abhishek Paliwal <abhishek.paliwal@aricent.com>
|
||||
Date: Fri, 13 Feb 2015 12:48:16 +0530
|
||||
Subject: misc/at24: Register memory accessor functions with of_memory_accessor
|
||||
|
||||
From: Aaron Williams <aaron.williams@cavium.com>
|
||||
|
||||
The at24 module will now register its memory accessor functions with its
|
||||
device tree entry so that other modules may call these functions based on
|
||||
the device tree node.
|
||||
|
||||
Signed-off-by: Aaron Williams <aaron.williams@cavium.com>
|
||||
Signed-off-by: Leonid Rosenboim <lrosenboim@caviumnetworks.com>
|
||||
Signed-off-by: Abhishek Paliwal <abhishek.paliwal@aricent.com>
|
||||
--- a/drivers/misc/eeprom/at24.c
|
||||
+++ b/drivers/misc/eeprom/at24.c
|
||||
@@ -23,6 +23,7 @@
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
+#include <linux/of_memory_accessor.h>
|
||||
|
||||
/* Address pointer is 16 bit. */
|
||||
#define AT24_FLAG_ADDR16 BIT(7)
|
||||
@@ -720,6 +721,9 @@ static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id)
|
||||
byte_len, client->name,
|
||||
writable ? "writable" : "read-only", at24->write_max);
|
||||
|
||||
+ if (client->dev.of_node)
|
||||
+ of_memory_accessor_register(&client->dev, &at24->macc);
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -728,5 +732,8 @@ static int at24_remove(struct i2c_client *client)
|
||||
pm_runtime_disable(&client->dev);
|
||||
pm_runtime_set_suspended(&client->dev);
|
||||
|
||||
+ if (client->dev.of_node)
|
||||
+ of_memory_accessor_remove(&client->dev);
|
||||
+
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
--- a/arch/mips/include/asm/octeon/cvmx-bootinfo.h
|
||||
+++ b/arch/mips/include/asm/octeon/cvmx-bootinfo.h
|
||||
@@ -253,6 +253,7 @@ enum cvmx_board_types_enum {
|
||||
CVMX_BOARD_TYPE_REDWING = 43,
|
||||
CVMX_BOARD_TYPE_NIC68_4 = 44,
|
||||
CVMX_BOARD_TYPE_NIC10E_66 = 45,
|
||||
+ CVMX_BOARD_TYPE_SNIC10E = 50,
|
||||
CVMX_BOARD_TYPE_MAX,
|
||||
|
||||
/*
|
||||
@@ -366,6 +367,7 @@ static inline const char *cvmx_board_type_to_string(enum
|
||||
ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_REDWING)
|
||||
ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_NIC68_4)
|
||||
ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_NIC10E_66)
|
||||
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_SNIC10E)
|
||||
ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_MAX)
|
||||
|
||||
/* Customer boards listed here */
|
79
target/linux/octeon/patches-5.4/703-debug-it-all.patch
Normal file
79
target/linux/octeon/patches-5.4/703-debug-it-all.patch
Normal file
@ -0,0 +1,79 @@
|
||||
--- a/arch/mips/cavium-octeon/executive/cvmx-helper.c
|
||||
+++ b/arch/mips/cavium-octeon/executive/cvmx-helper.c
|
||||
@@ -1041,12 +1041,14 @@ int cvmx_helper_initialize_packet_io_global(void)
|
||||
result |= __cvmx_helper_interface_setup_ipd(interface);
|
||||
result |= __cvmx_helper_interface_setup_pko(interface);
|
||||
}
|
||||
-
|
||||
+ cvmx_dprintf("Gets past end of interfaces setup\n");
|
||||
result |= __cvmx_helper_global_setup_ipd();
|
||||
result |= __cvmx_helper_global_setup_pko();
|
||||
|
||||
+ cvmx_dprintf("Sets up global helpers\n");
|
||||
/* Enable any flow control and backpressure */
|
||||
result |= __cvmx_helper_global_setup_backpressure();
|
||||
+ cvmx_dprintf("Sets up backpressure helpers\n");
|
||||
|
||||
#if CVMX_HELPER_ENABLE_IPD
|
||||
result |= cvmx_helper_ipd_and_packet_input_enable();
|
||||
--- a/drivers/staging/octeon/ethernet.c
|
||||
+++ b/drivers/staging/octeon/ethernet.c
|
||||
@@ -700,6 +700,7 @@ static int cvm_oct_probe(struct platform_device *pdev)
|
||||
cvm_oct_configure_common_hw();
|
||||
|
||||
cvmx_helper_initialize_packet_io_global();
|
||||
+ pr_err("OK, we got out of packet_io_global()\n");
|
||||
|
||||
if (receive_group_order) {
|
||||
if (receive_group_order > 4)
|
||||
@@ -709,9 +710,11 @@ static int cvm_oct_probe(struct platform_device *pdev)
|
||||
pow_receive_groups = BIT(pow_receive_group);
|
||||
}
|
||||
|
||||
+ pr_err("We got through receive_group_order\n");
|
||||
/* Change the input group for all ports before input is enabled */
|
||||
num_interfaces = cvmx_helper_get_number_of_interfaces();
|
||||
for (interface = 0; interface < num_interfaces; interface++) {
|
||||
+ pr_err("We are starting on interface %d\n", interface);
|
||||
int num_ports = cvmx_helper_ports_on_interface(interface);
|
||||
int port;
|
||||
|
||||
@@ -752,14 +755,14 @@ static int cvm_oct_probe(struct platform_device *pdev)
|
||||
pip_prt_tagx.s.grptag = 0;
|
||||
pip_prt_tagx.s.grp = pow_receive_group;
|
||||
}
|
||||
-
|
||||
+ pr_err("COULD IT BE CSR WRITES???\n");
|
||||
cvmx_write_csr(CVMX_PIP_PRT_TAGX(port),
|
||||
pip_prt_tagx.u64);
|
||||
}
|
||||
}
|
||||
-
|
||||
+ pr_err("COULD it be cvmx_helper_ipd_and_packet_input_enable???\n");
|
||||
cvmx_helper_ipd_and_packet_input_enable();
|
||||
-
|
||||
+ pr_err("COULD it be this memset??\n");
|
||||
memset(cvm_oct_device, 0, sizeof(cvm_oct_device));
|
||||
|
||||
/*
|
||||
@@ -804,6 +807,7 @@ static int cvm_oct_probe(struct platform_device *pdev)
|
||||
}
|
||||
}
|
||||
|
||||
+ pr_err("OK, we got THIS far, all the way to the interface init. Which is weird, we shoulda crashed by now\n");
|
||||
num_interfaces = cvmx_helper_get_number_of_interfaces();
|
||||
for (interface = 0; interface < num_interfaces; interface++) {
|
||||
cvmx_helper_interface_mode_t imode =
|
||||
@@ -860,8 +864,10 @@ static int cvm_oct_probe(struct platform_device *pdev)
|
||||
break;
|
||||
|
||||
case CVMX_HELPER_INTERFACE_MODE_XAUI:
|
||||
- dev->netdev_ops = &cvm_oct_xaui_netdev_ops;
|
||||
- strscpy(dev->name, "xaui%d", sizeof(dev->name));
|
||||
+ if (of_device_is_available(priv->of_node)) {
|
||||
+ dev->netdev_ops = &cvm_oct_xaui_netdev_ops;
|
||||
+ strscpy(dev->name, "xaui%d", sizeof(dev->name));
|
||||
+ }
|
||||
break;
|
||||
|
||||
case CVMX_HELPER_INTERFACE_MODE_LOOP:
|
48
target/linux/octeon/patches-5.4/704-more-debugs.patch
Normal file
48
target/linux/octeon/patches-5.4/704-more-debugs.patch
Normal file
@ -0,0 +1,48 @@
|
||||
--- a/arch/mips/cavium-octeon/executive/cvmx-helper.c
|
||||
+++ b/arch/mips/cavium-octeon/executive/cvmx-helper.c
|
||||
@@ -971,6 +971,7 @@ int cvmx_helper_ipd_and_packet_input_enable(void)
|
||||
int interface;
|
||||
|
||||
/* Enable IPD */
|
||||
+ cvmx_dprintf("COULD IT BE cvmx_ipd_enable???\n");
|
||||
cvmx_ipd_enable();
|
||||
|
||||
/*
|
||||
@@ -978,13 +979,16 @@ int cvmx_helper_ipd_and_packet_input_enable(void)
|
||||
* that at this point IPD/PIP must be fully functional and PKO
|
||||
* must be disabled
|
||||
*/
|
||||
+ cvmx_dprintf("COULD IT BE getting no of interfaces????\n");
|
||||
num_interfaces = cvmx_helper_get_number_of_interfaces();
|
||||
for (interface = 0; interface < num_interfaces; interface++) {
|
||||
+ cvmx_dprintf("COULD IT BE interface # %d ??ces????\n", interface);
|
||||
if (cvmx_helper_ports_on_interface(interface) > 0)
|
||||
__cvmx_helper_packet_hardware_enable(interface);
|
||||
}
|
||||
|
||||
/* Finally enable PKO now that the entire path is up and running */
|
||||
+ cvmx_dprintf("COULD IT BE PKO???\n");
|
||||
cvmx_pko_enable();
|
||||
|
||||
if ((OCTEON_IS_MODEL(OCTEON_CN31XX_PASS1)
|
||||
--- a/arch/mips/include/asm/octeon/cvmx-ipd.h
|
||||
+++ b/arch/mips/include/asm/octeon/cvmx-ipd.h
|
||||
@@ -129,15 +129,18 @@ static inline void cvmx_ipd_config(uint64_t mbuff_size,
|
||||
static inline void cvmx_ipd_enable(void)
|
||||
{
|
||||
union cvmx_ipd_ctl_status ipd_reg;
|
||||
+ cvmx_dprintf("COULD IT BE THIS ONE CSR READ IN cvmx_ipd_enable ??\n");
|
||||
ipd_reg.u64 = cvmx_read_csr(CVMX_IPD_CTL_STATUS);
|
||||
if (ipd_reg.s.ipd_en) {
|
||||
cvmx_dprintf
|
||||
("Warning: Enabling IPD when IPD already enabled.\n");
|
||||
}
|
||||
+ cvmx_dprintf("OK IT PASSED THE READ. BUT THERE'S THIS CVMX_ENABLE_LEN_M8_FIX THAT COULD APPLY??\n");
|
||||
ipd_reg.s.ipd_en = 1;
|
||||
#if CVMX_ENABLE_LEN_M8_FIX
|
||||
if (!OCTEON_IS_MODEL(OCTEON_CN38XX_PASS2))
|
||||
ipd_reg.s.len_m8 = TRUE;
|
||||
#endif
|
||||
+ cvmx_dprintf("COULD IT BE THIS ONE CSR WRITE??? IN cvmx_ipd_enable ??\n");
|
||||
cvmx_write_csr(CVMX_IPD_CTL_STATUS, ipd_reg.u64);
|
||||
}
|
186
target/linux/octeon/patches-5.4/705-last-debugs.patch
Normal file
186
target/linux/octeon/patches-5.4/705-last-debugs.patch
Normal file
@ -0,0 +1,186 @@
|
||||
diff --git a/arch/mips/cavium-octeon/executive/cvmx-helper-xaui.c b/arch/mips/cavium-octeon/executive/cvmx-helper-xaui.c
|
||||
index 93a498d05184..27733d710355 100644
|
||||
--- a/arch/mips/cavium-octeon/executive/cvmx-helper-xaui.c
|
||||
+++ b/arch/mips/cavium-octeon/executive/cvmx-helper-xaui.c
|
||||
@@ -121,58 +121,80 @@ int __cvmx_helper_xaui_enable(int interface)
|
||||
union cvmx_gmxx_tx_int_en gmx_tx_int_en;
|
||||
union cvmx_pcsxx_int_en_reg pcsx_int_en_reg;
|
||||
|
||||
+ cvmx_dprintf("COULD IT BE THE FEATURE CHECK FOR PKND??\n");
|
||||
/* Setup PKND */
|
||||
if (octeon_has_feature(OCTEON_FEATURE_PKND)) {
|
||||
+ cvmx_dprintf("COULD IT BE THE FIRST CSR READ??\n");
|
||||
gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(0, interface));
|
||||
+ cvmx_dprintf("COULD IT BE THE second CSR READ??\n");
|
||||
gmx_cfg.s.pknd = cvmx_helper_get_ipd_port(interface, 0);
|
||||
+ cvmx_dprintf("COULD IT BE THE third CSR /write READ??\n");
|
||||
cvmx_write_csr(CVMX_GMXX_PRTX_CFG(0, interface), gmx_cfg.u64);
|
||||
}
|
||||
|
||||
/* (1) Interface has already been enabled. */
|
||||
|
||||
/* (2) Disable GMX. */
|
||||
+ cvmx_dprintf("step2 start!?? could it be the csr read??\n");
|
||||
xauiMiscCtl.u64 = cvmx_read_csr(CVMX_PCSXX_MISC_CTL_REG(interface));
|
||||
xauiMiscCtl.s.gmxeno = 1;
|
||||
+ cvmx_dprintf("step2 could it be the csr write to disable gmx??\n");
|
||||
cvmx_write_csr(CVMX_PCSXX_MISC_CTL_REG(interface), xauiMiscCtl.u64);
|
||||
|
||||
/* (3) Disable GMX and PCSX interrupts. */
|
||||
+ cvmx_dprintf("step3 start. could it be the csr read??\n");
|
||||
gmx_rx_int_en.u64 = cvmx_read_csr(CVMX_GMXX_RXX_INT_EN(0, interface));
|
||||
+ cvmx_dprintf("step3 start. could it be the write for disabling interrupts???\n");
|
||||
cvmx_write_csr(CVMX_GMXX_RXX_INT_EN(0, interface), 0x0);
|
||||
+ cvmx_dprintf("step3 start. could it be read for setting up the gmx_tx_int_en???\n");
|
||||
gmx_tx_int_en.u64 = cvmx_read_csr(CVMX_GMXX_TX_INT_EN(interface));
|
||||
+ cvmx_dprintf("step3 start. could it be the cvmx_gmxx write???\n");
|
||||
cvmx_write_csr(CVMX_GMXX_TX_INT_EN(interface), 0x0);
|
||||
+ cvmx_dprintf("step3 start almost done. show up tell us about the PCSXX write???\n");
|
||||
pcsx_int_en_reg.u64 = cvmx_read_csr(CVMX_PCSXX_INT_EN_REG(interface));
|
||||
+ cvmx_dprintf("step3, this final csr write?\n");
|
||||
cvmx_write_csr(CVMX_PCSXX_INT_EN_REG(interface), 0x0);
|
||||
|
||||
/* (4) Bring up the PCSX and GMX reconciliation layer. */
|
||||
/* (4)a Set polarity and lane swapping. */
|
||||
/* (4)b */
|
||||
+ cvmx_dprintf("4.1\n");
|
||||
gmxXauiTxCtl.u64 = cvmx_read_csr(CVMX_GMXX_TX_XAUI_CTL(interface));
|
||||
/* Enable better IFG packing and improves performance */
|
||||
gmxXauiTxCtl.s.dic_en = 1;
|
||||
gmxXauiTxCtl.s.uni_en = 0;
|
||||
+ cvmx_dprintf("4.2\n");
|
||||
cvmx_write_csr(CVMX_GMXX_TX_XAUI_CTL(interface), gmxXauiTxCtl.u64);
|
||||
|
||||
/* (4)c Aply reset sequence */
|
||||
+ cvmx_dprintf("4.3\n");
|
||||
xauiCtl.u64 = cvmx_read_csr(CVMX_PCSXX_CONTROL1_REG(interface));
|
||||
xauiCtl.s.lo_pwr = 0;
|
||||
|
||||
/* Issuing a reset here seems to hang some CN68XX chips. */
|
||||
if (!OCTEON_IS_MODEL(OCTEON_CN68XX_PASS1_X) &&
|
||||
- !OCTEON_IS_MODEL(OCTEON_CN68XX_PASS2_X))
|
||||
+ !OCTEON_IS_MODEL(OCTEON_CN68XX_PASS2_X) &&
|
||||
+ 0)
|
||||
xauiCtl.s.reset = 1;
|
||||
|
||||
+ cvmx_dprintf("4.4\n");
|
||||
cvmx_write_csr(CVMX_PCSXX_CONTROL1_REG(interface), xauiCtl.u64);
|
||||
|
||||
+ cvmx_dprintf("4.5\n");
|
||||
/* Wait for PCS to come out of reset */
|
||||
if (CVMX_WAIT_FOR_FIELD64
|
||||
(CVMX_PCSXX_CONTROL1_REG(interface), union cvmx_pcsxx_control1_reg,
|
||||
reset, ==, 0, 10000))
|
||||
return -1;
|
||||
+
|
||||
+ cvmx_dprintf("4.6\n");
|
||||
/* Wait for PCS to be aligned */
|
||||
if (CVMX_WAIT_FOR_FIELD64
|
||||
(CVMX_PCSXX_10GBX_STATUS_REG(interface),
|
||||
union cvmx_pcsxx_10gbx_status_reg, alignd, ==, 1, 10000))
|
||||
return -1;
|
||||
+
|
||||
+ cvmx_dprintf("4.7\n");
|
||||
/* Wait for RX to be ready */
|
||||
if (CVMX_WAIT_FOR_FIELD64
|
||||
(CVMX_GMXX_RX_XAUI_CTL(interface), union cvmx_gmxx_rx_xaui_ctl,
|
||||
@@ -180,8 +202,11 @@ int __cvmx_helper_xaui_enable(int interface)
|
||||
return -1;
|
||||
|
||||
/* (6) Configure GMX */
|
||||
+ cvmx_dprintf("6.1\n");
|
||||
gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(0, interface));
|
||||
+
|
||||
gmx_cfg.s.en = 0;
|
||||
+ cvmx_dprintf("6.2\n");
|
||||
cvmx_write_csr(CVMX_GMXX_PRTX_CFG(0, interface), gmx_cfg.u64);
|
||||
|
||||
/* Wait for GMX RX to be idle */
|
||||
@@ -189,62 +214,87 @@ int __cvmx_helper_xaui_enable(int interface)
|
||||
(CVMX_GMXX_PRTX_CFG(0, interface), union cvmx_gmxx_prtx_cfg,
|
||||
rx_idle, ==, 1, 10000))
|
||||
return -1;
|
||||
+ cvmx_dprintf("6.3\n");
|
||||
/* Wait for GMX TX to be idle */
|
||||
if (CVMX_WAIT_FOR_FIELD64
|
||||
(CVMX_GMXX_PRTX_CFG(0, interface), union cvmx_gmxx_prtx_cfg,
|
||||
tx_idle, ==, 1, 10000))
|
||||
return -1;
|
||||
|
||||
+ cvmx_dprintf("6.4\n");
|
||||
/* GMX configure */
|
||||
gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(0, interface));
|
||||
gmx_cfg.s.speed = 1;
|
||||
gmx_cfg.s.speed_msb = 0;
|
||||
gmx_cfg.s.slottime = 1;
|
||||
+ cvmx_dprintf("6.5\n");
|
||||
cvmx_write_csr(CVMX_GMXX_TX_PRTS(interface), 1);
|
||||
+ cvmx_dprintf("6.6\n");
|
||||
cvmx_write_csr(CVMX_GMXX_TXX_SLOT(0, interface), 512);
|
||||
+ cvmx_dprintf("6.7\n");
|
||||
cvmx_write_csr(CVMX_GMXX_TXX_BURST(0, interface), 8192);
|
||||
+ cvmx_dprintf("6.8\n");
|
||||
cvmx_write_csr(CVMX_GMXX_PRTX_CFG(0, interface), gmx_cfg.u64);
|
||||
|
||||
/* (7) Clear out any error state */
|
||||
+ cvmx_dprintf("7.1\n");
|
||||
cvmx_write_csr(CVMX_GMXX_RXX_INT_REG(0, interface),
|
||||
cvmx_read_csr(CVMX_GMXX_RXX_INT_REG(0, interface)));
|
||||
+ cvmx_dprintf("7.2\n");
|
||||
cvmx_write_csr(CVMX_GMXX_TX_INT_REG(interface),
|
||||
cvmx_read_csr(CVMX_GMXX_TX_INT_REG(interface)));
|
||||
+ cvmx_dprintf("7.3\n");
|
||||
cvmx_write_csr(CVMX_PCSXX_INT_REG(interface),
|
||||
cvmx_read_csr(CVMX_PCSXX_INT_REG(interface)));
|
||||
|
||||
+ cvmx_dprintf("7.4\n");
|
||||
/* Wait for receive link */
|
||||
if (CVMX_WAIT_FOR_FIELD64
|
||||
(CVMX_PCSXX_STATUS1_REG(interface), union cvmx_pcsxx_status1_reg,
|
||||
rcv_lnk, ==, 1, 10000))
|
||||
return -1;
|
||||
+ cvmx_dprintf("7.5\n");
|
||||
if (CVMX_WAIT_FOR_FIELD64
|
||||
(CVMX_PCSXX_STATUS2_REG(interface), union cvmx_pcsxx_status2_reg,
|
||||
xmtflt, ==, 0, 10000))
|
||||
return -1;
|
||||
+ cvmx_dprintf("7.6\n");
|
||||
if (CVMX_WAIT_FOR_FIELD64
|
||||
(CVMX_PCSXX_STATUS2_REG(interface), union cvmx_pcsxx_status2_reg,
|
||||
rcvflt, ==, 0, 10000))
|
||||
return -1;
|
||||
|
||||
+ cvmx_dprintf("7.7\n");
|
||||
cvmx_write_csr(CVMX_GMXX_RXX_INT_EN(0, interface), gmx_rx_int_en.u64);
|
||||
+ cvmx_dprintf("7.8\n");
|
||||
cvmx_write_csr(CVMX_GMXX_TX_INT_EN(interface), gmx_tx_int_en.u64);
|
||||
+ cvmx_dprintf("7.9\n");
|
||||
cvmx_write_csr(CVMX_PCSXX_INT_EN_REG(interface), pcsx_int_en_reg.u64);
|
||||
|
||||
/* (8) Enable packet reception */
|
||||
xauiMiscCtl.s.gmxeno = 0;
|
||||
+ cvmx_dprintf("8.1\n");
|
||||
cvmx_write_csr(CVMX_PCSXX_MISC_CTL_REG(interface), xauiMiscCtl.u64);
|
||||
|
||||
+ cvmx_dprintf("8.2\n");
|
||||
gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(0, interface));
|
||||
gmx_cfg.s.en = 1;
|
||||
+ cvmx_dprintf("8.3\n");
|
||||
cvmx_write_csr(CVMX_GMXX_PRTX_CFG(0, interface), gmx_cfg.u64);
|
||||
|
||||
+ cvmx_dprintf("8.4\n");
|
||||
__cvmx_interrupt_pcsx_intx_en_reg_enable(0, interface);
|
||||
+ cvmx_dprintf("8.5\n");
|
||||
__cvmx_interrupt_pcsx_intx_en_reg_enable(1, interface);
|
||||
+ cvmx_dprintf("8.6\n");
|
||||
__cvmx_interrupt_pcsx_intx_en_reg_enable(2, interface);
|
||||
+ cvmx_dprintf("8.7\n");
|
||||
__cvmx_interrupt_pcsx_intx_en_reg_enable(3, interface);
|
||||
+ cvmx_dprintf("8.8\n");
|
||||
__cvmx_interrupt_pcsxx_int_en_reg_enable(interface);
|
||||
+ cvmx_dprintf("8.9\n");
|
||||
__cvmx_interrupt_gmxx_enable(interface);
|
||||
+ cvmx_dprintf("8.10\n");
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user