[centec]: Add centec arm64 architecture support for E530 (#4641)
summary of E530 platfrom: - CPU: CTC5236, arm64 - LAN switch chip set: CENTEC CTC7132 (TsingMa). TsingMa is a purpose built device to address the challenge in the recent network evolution such as Cloud computing. CTC7132 provides 440Gbps I/O bandwidth and 400Gcore bandwidth, the CTC7132 family combines a feature-rich switch core and an embedded ARM A53 CPU Core running at 800MHz/1.2GHz. CTC7132 supports a variety of port configurations, such as QSGMII and USXGMII-M, providing full-rate port capability from 100M to 100G. - device E530-48T4X: 48 * 10/100/1000 Base-T Ports, 4 * 10GE SFP+ Ports. - device E530-24X2C: 24 * 10 GE SFP+ Ports, 2 * 100GE QSFP28 Ports. add new files in three directories: device/centec/arm64-centec_e530_24x2c-r0 device/centec/arm64-centec_e530_48t4x_p-r0 platform/centec-arm64 Co-authored-by: taocy <taocy2@centecnetworks.com> Co-authored-by: Gu Xianghong <gxh2001757@163.com> Co-authored-by: shil <shil@centecnetworks.com>
This commit is contained in:
parent
9e100257d0
commit
08f3b9720b
@ -187,6 +187,10 @@ if [[ $CONFIGURED_ARCH == armhf || $CONFIGURED_ARCH == arm64 ]]; then
|
|||||||
sudo chmod +x $FILESYSTEM_ROOT/etc/initramfs-tools/hooks/uboot-utils
|
sudo chmod +x $FILESYSTEM_ROOT/etc/initramfs-tools/hooks/uboot-utils
|
||||||
cat files/initramfs-tools/modules.arm | sudo tee -a $FILESYSTEM_ROOT/etc/initramfs-tools/modules > /dev/null
|
cat files/initramfs-tools/modules.arm | sudo tee -a $FILESYSTEM_ROOT/etc/initramfs-tools/modules > /dev/null
|
||||||
fi
|
fi
|
||||||
|
# Update initramfs for load platform specific modules
|
||||||
|
if [ -f platform/$CONFIGURED_PLATFORM/modules ]; then
|
||||||
|
cat platform/$CONFIGURED_PLATFORM/modules | sudo tee -a $FILESYSTEM_ROOT/etc/initramfs-tools/modules > /dev/null
|
||||||
|
fi
|
||||||
|
|
||||||
## Install docker
|
## Install docker
|
||||||
echo '[INFO] Install docker'
|
echo '[INFO] Install docker'
|
||||||
|
@ -0,0 +1,70 @@
|
|||||||
|
{# Default values which will be used if no actual configura available #}
|
||||||
|
{% set default_cable = '40m' %}
|
||||||
|
{% set default_ports_num = 54 -%}
|
||||||
|
|
||||||
|
{# Port configuration to cable length look-up table #}
|
||||||
|
{# Each record describes mapping of DUT (DUT port) role and neighbor role to cable length #}
|
||||||
|
{# Roles described in the minigraph #}
|
||||||
|
{% set ports2cable = {
|
||||||
|
'torrouter_server' : '5m',
|
||||||
|
'leafrouter_torrouter' : '40m',
|
||||||
|
'spinerouter_leafrouter' : '300m'
|
||||||
|
}
|
||||||
|
%}
|
||||||
|
|
||||||
|
{%- macro cable_length(port_name) -%}
|
||||||
|
{%- set cable_len = [] -%}
|
||||||
|
{%- for local_port in DEVICE_NEIGHBOR -%}
|
||||||
|
{%- if local_port == port_name -%}
|
||||||
|
{%- if DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] -%}
|
||||||
|
{%- set neighbor = DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] -%}
|
||||||
|
{%- set neighbor_role = neighbor.type -%}
|
||||||
|
{%- set roles1 = switch_role + '_' + neighbor_role %}
|
||||||
|
{%- set roles2 = neighbor_role + '_' + switch_role -%}
|
||||||
|
{%- set roles1 = roles1 | lower -%}
|
||||||
|
{%- set roles2 = roles2 | lower -%}
|
||||||
|
{%- if roles1 in ports2cable -%}
|
||||||
|
{%- if cable_len.append(ports2cable[roles1]) -%}{%- endif -%}
|
||||||
|
{%- elif roles2 in ports2cable -%}
|
||||||
|
{%- if cable_len.append(ports2cable[roles2]) -%}{%- endif -%}
|
||||||
|
{%- endif -%}
|
||||||
|
{%- endif -%}
|
||||||
|
{%- endif -%}
|
||||||
|
{%- endfor -%}
|
||||||
|
{%- if cable_len -%}
|
||||||
|
{{ cable_len.0 }}
|
||||||
|
{%- else -%}
|
||||||
|
{{ default_cable }}
|
||||||
|
{%- endif -%}
|
||||||
|
{% endmacro %}
|
||||||
|
|
||||||
|
{%- if DEVICE_METADATA is defined %}
|
||||||
|
{%- set switch_role = DEVICE_METADATA['localhost']['type'] %}
|
||||||
|
{%- endif -%}
|
||||||
|
|
||||||
|
{# Generate list of ports if not defined #}
|
||||||
|
{% if PORT is not defined %}
|
||||||
|
{% set PORT = [] %}
|
||||||
|
{% for port_idx in range(1,default_ports_num+1) %}
|
||||||
|
{% if PORT.append("Ethernet%d" % (port_idx)) %}{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif -%}
|
||||||
|
|
||||||
|
{% set port_names_list = [] %}
|
||||||
|
{% for port in PORT %}
|
||||||
|
{%- if port_names_list.append(port) %}{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% set port_names = port_names_list | join(',') -%}
|
||||||
|
|
||||||
|
{
|
||||||
|
"CABLE_LENGTH": {
|
||||||
|
"AZURE": {
|
||||||
|
{% for port in PORT %}
|
||||||
|
{% set cable = cable_length(port) -%}
|
||||||
|
"{{ port }}": "{{ cable }}"{%- if not loop.last -%},{% endif %}
|
||||||
|
|
||||||
|
{% endfor %}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,21 @@
|
|||||||
|
# PG lossless profiles.
|
||||||
|
# speed cable size xon xoff threshold
|
||||||
|
1000 5m 34816 18432 16384 0
|
||||||
|
10000 5m 34816 18432 16384 0
|
||||||
|
25000 5m 34816 18432 16384 0
|
||||||
|
40000 5m 34816 18432 16384 0
|
||||||
|
50000 5m 34816 18432 16384 0
|
||||||
|
100000 5m 36864 18432 18432 0
|
||||||
|
1000 40m 36864 18432 18432 0
|
||||||
|
10000 40m 36864 18432 18432 0
|
||||||
|
25000 40m 39936 18432 21504 0
|
||||||
|
40000 40m 41984 18432 23552 0
|
||||||
|
50000 40m 41984 18432 23552 0
|
||||||
|
100000 40m 54272 18432 35840 0
|
||||||
|
1000 300m 49152 18432 30720 0
|
||||||
|
10000 300m 49152 18432 30720 0
|
||||||
|
25000 300m 71680 18432 53248 0
|
||||||
|
40000 300m 94208 18432 75776 0
|
||||||
|
50000 300m 94208 18432 75776 0
|
||||||
|
100000 300m 184320 18432 165888 0
|
||||||
|
|
@ -0,0 +1,27 @@
|
|||||||
|
# name lanes alias speed
|
||||||
|
Ethernet1 0 eth-0-1 10000
|
||||||
|
Ethernet2 1 eth-0-2 10000
|
||||||
|
Ethernet3 2 eth-0-3 10000
|
||||||
|
Ethernet4 3 eth-0-4 10000
|
||||||
|
Ethernet5 8 eth-0-5 10000
|
||||||
|
Ethernet6 9 eth-0-6 10000
|
||||||
|
Ethernet7 10 eth-0-7 10000
|
||||||
|
Ethernet8 11 eth-0-8 10000
|
||||||
|
Ethernet9 20 eth-0-9 10000
|
||||||
|
Ethernet10 21 eth-0-10 10000
|
||||||
|
Ethernet11 22 eth-0-11 10000
|
||||||
|
Ethernet12 23 eth-0-12 10000
|
||||||
|
Ethernet13 12 eth-0-13 10000
|
||||||
|
Ethernet14 13 eth-0-14 10000
|
||||||
|
Ethernet15 14 eth-0-15 10000
|
||||||
|
Ethernet16 15 eth-0-16 10000
|
||||||
|
Ethernet17 24 eth-0-17 10000
|
||||||
|
Ethernet18 25 eth-0-18 10000
|
||||||
|
Ethernet19 26 eth-0-19 10000
|
||||||
|
Ethernet20 27 eth-0-20 10000
|
||||||
|
Ethernet21 28 eth-0-21 10000
|
||||||
|
Ethernet22 29 eth-0-22 10000
|
||||||
|
Ethernet23 30 eth-0-23 10000
|
||||||
|
Ethernet24 31 eth-0-24 10000
|
||||||
|
Ethernet25 61,60,63,62 eth-0-25 100000
|
||||||
|
Ethernet26 45,44,47,46 eth-0-26 100000
|
@ -0,0 +1 @@
|
|||||||
|
{%- include 'qos_config.j2' %}
|
@ -0,0 +1,2 @@
|
|||||||
|
SAI_INIT_CONFIG_FILE=/etc/centec/E530-24x2c-chip-profile.txt
|
||||||
|
SAI_HW_PORT_PROFILE_ID_CONFIG_FILE=/etc/centec/E530-24x2c-datapath-cfg.txt
|
1
device/centec/arm64-centec_e530_24x2c-r0/default_sku
Normal file
1
device/centec/arm64-centec_e530_24x2c-r0/default_sku
Normal file
@ -0,0 +1 @@
|
|||||||
|
E530-24x2c l2
|
1
device/centec/arm64-centec_e530_24x2c-r0/fancontrol
Normal file
1
device/centec/arm64-centec_e530_24x2c-r0/fancontrol
Normal file
@ -0,0 +1 @@
|
|||||||
|
# Configuration file generated by pwmconfig, changes will be lost
|
22
device/centec/arm64-centec_e530_24x2c-r0/plugins/eeprom.py
Normal file
22
device/centec/arm64-centec_e530_24x2c-r0/plugins/eeprom.py
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
#############################################################################
|
||||||
|
# Centec E550-24X8Y2C
|
||||||
|
#
|
||||||
|
# Platform and model specific eeprom subclass, inherits from the base class,
|
||||||
|
# and provides the followings:
|
||||||
|
# - the eeprom format definition
|
||||||
|
# - specific encoder/decoder if there is special need
|
||||||
|
#############################################################################
|
||||||
|
|
||||||
|
try:
|
||||||
|
from sonic_eeprom import eeprom_tlvinfo
|
||||||
|
except ImportError, e:
|
||||||
|
raise ImportError (str(e) + "- required module not found")
|
||||||
|
|
||||||
|
|
||||||
|
class board(eeprom_tlvinfo.TlvInfoDecoder):
|
||||||
|
|
||||||
|
def __init__(self, name, path, cpld_root, ro):
|
||||||
|
self.eeprom_path = "/dev/mtd3"
|
||||||
|
super(board, self).__init__(self.eeprom_path, 0, '', True)
|
@ -0,0 +1,98 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
#
|
||||||
|
# led_control.py
|
||||||
|
#
|
||||||
|
# Platform-specific LED control functionality for SONiC
|
||||||
|
#
|
||||||
|
|
||||||
|
try:
|
||||||
|
from sonic_led.led_control_base import LedControlBase
|
||||||
|
import syslog
|
||||||
|
from socket import *
|
||||||
|
from select import *
|
||||||
|
except ImportError, e:
|
||||||
|
raise ImportError(str(e) + " - required module not found")
|
||||||
|
|
||||||
|
|
||||||
|
def DBG_PRINT(str):
|
||||||
|
syslog.openlog("centec-led")
|
||||||
|
syslog.syslog(syslog.LOG_INFO, str)
|
||||||
|
syslog.closelog()
|
||||||
|
|
||||||
|
|
||||||
|
class LedControl(LedControlBase):
|
||||||
|
"""Platform specific LED control class"""
|
||||||
|
|
||||||
|
|
||||||
|
# Helper method to map SONiC port name to index
|
||||||
|
def _port_name_to_index(self, port_name):
|
||||||
|
# Strip "Ethernet" off port name
|
||||||
|
if not port_name.startswith(self.SONIC_PORT_NAME_PREFIX):
|
||||||
|
return -1
|
||||||
|
|
||||||
|
port_idx = int(port_name[len(self.SONIC_PORT_NAME_PREFIX):])
|
||||||
|
return port_idx
|
||||||
|
|
||||||
|
def _port_state_to_mode(self, port_idx, state):
|
||||||
|
if state == "up":
|
||||||
|
return self.LED_MODE_UP[0] if (port_idx < 25) else self.LED_MODE_UP[1]
|
||||||
|
else:
|
||||||
|
return self.LED_MODE_DOWN[0] if (port_idx < 25) else self.LED_MODE_DOWN[1]
|
||||||
|
|
||||||
|
def _port_led_mode_update(self, port_idx, ledMode):
|
||||||
|
with open(self.f_led.format("port{}".format(port_idx)), 'w') as led_file:
|
||||||
|
led_file.write(str(ledMode))
|
||||||
|
|
||||||
|
def _initSystemLed(self):
|
||||||
|
try:
|
||||||
|
with open(self.f_led.format("system"), 'w') as led_file:
|
||||||
|
led_file.write("1")
|
||||||
|
DBG_PRINT("init system led to normal")
|
||||||
|
with open(self.f_led.format("idn"), 'w') as led_file:
|
||||||
|
led_file.write("1")
|
||||||
|
DBG_PRINT("init idn led to off")
|
||||||
|
except IOError as e:
|
||||||
|
DBG_PRINT(str(e))
|
||||||
|
|
||||||
|
def _initPanelLed(self):
|
||||||
|
with open(self.f_led.format("port1"), 'r') as led_file:
|
||||||
|
shouldInit = (int(led_file.read()) == 0)
|
||||||
|
|
||||||
|
if shouldInit == True:
|
||||||
|
for idx in range(1, 27):
|
||||||
|
defmode = self._port_state_to_mode(idx, "down")
|
||||||
|
with open(self.f_led.format("port{}".format(idx)), 'w') as led_file:
|
||||||
|
led_file.write(str(defmode))
|
||||||
|
DBG_PRINT("init port{} led to mode={}".format(idx, defmode))
|
||||||
|
|
||||||
|
def _initDefaultConfig(self):
|
||||||
|
DBG_PRINT("start init led")
|
||||||
|
|
||||||
|
self._initSystemLed()
|
||||||
|
self._initPanelLed()
|
||||||
|
|
||||||
|
DBG_PRINT("init led done")
|
||||||
|
|
||||||
|
|
||||||
|
# Concrete implementation of port_link_state_change() method
|
||||||
|
def port_link_state_change(self, portname, state):
|
||||||
|
port_idx = self._port_name_to_index(portname)
|
||||||
|
ledMode = self._port_state_to_mode(port_idx, state)
|
||||||
|
with open(self.f_led.format("port{}".format(port_idx)), 'r') as led_file:
|
||||||
|
saveMode = int(led_file.read())
|
||||||
|
|
||||||
|
if ledMode == saveMode:
|
||||||
|
return
|
||||||
|
|
||||||
|
self._port_led_mode_update(port_idx, ledMode)
|
||||||
|
DBG_PRINT("update {} led mode from {} to {}".format(portname, saveMode, ledMode))
|
||||||
|
|
||||||
|
|
||||||
|
# Constructor
|
||||||
|
def __init__(self):
|
||||||
|
self.SONIC_PORT_NAME_PREFIX = "Ethernet"
|
||||||
|
self.LED_MODE_UP = [11, 11]
|
||||||
|
self.LED_MODE_DOWN = [7, 7]
|
||||||
|
|
||||||
|
self.f_led = "/sys/class/leds/{}/brightness"
|
||||||
|
self._initDefaultConfig()
|
72
device/centec/arm64-centec_e530_24x2c-r0/plugins/psuutil.py
Normal file
72
device/centec/arm64-centec_e530_24x2c-r0/plugins/psuutil.py
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
#############################################################################
|
||||||
|
# Centec
|
||||||
|
#
|
||||||
|
# Module contains an implementation of SONiC PSU Base API and
|
||||||
|
# provides the PSUs status which are available in the platform
|
||||||
|
#
|
||||||
|
#############################################################################
|
||||||
|
|
||||||
|
try:
|
||||||
|
from sonic_psu.psu_base import PsuBase
|
||||||
|
except ImportError as e:
|
||||||
|
raise ImportError (str(e) + "- required module not found")
|
||||||
|
|
||||||
|
class PsuUtil(PsuBase):
|
||||||
|
"""Platform-specific PSUutil class"""
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
PsuBase.__init__(self)
|
||||||
|
|
||||||
|
self.psu_path = "/sys/class/psu/psu{}/"
|
||||||
|
self.psu_presence = "psu_presence"
|
||||||
|
self.psu_oper_status = "psu_status"
|
||||||
|
|
||||||
|
def get_num_psus(self):
|
||||||
|
"""
|
||||||
|
Retrieves the number of PSUs available on the device
|
||||||
|
|
||||||
|
:return: An integer, the number of PSUs available on the device
|
||||||
|
"""
|
||||||
|
return 2
|
||||||
|
|
||||||
|
def get_psu_status(self, index):
|
||||||
|
"""
|
||||||
|
Retrieves the oprational status of power supply unit (PSU) defined
|
||||||
|
by 1-based index <index>
|
||||||
|
|
||||||
|
:param index: An integer, 1-based index of the PSU of which to query status
|
||||||
|
:return: Boolean, True if PSU is operating properly, False if PSU is faulty
|
||||||
|
"""
|
||||||
|
if index is None:
|
||||||
|
return False
|
||||||
|
|
||||||
|
status = 0
|
||||||
|
try:
|
||||||
|
with open(self.psu_path.format(index) + self.psu_oper_status, 'r') as power_status:
|
||||||
|
status = int(power_status.read())
|
||||||
|
except IOError:
|
||||||
|
return False
|
||||||
|
|
||||||
|
return status == 1
|
||||||
|
|
||||||
|
def get_psu_presence(self, index):
|
||||||
|
"""
|
||||||
|
Retrieves the presence status of power supply unit (PSU) defined
|
||||||
|
by 1-based index <index>
|
||||||
|
|
||||||
|
:param index: An integer, 1-based index of the PSU of which to query status
|
||||||
|
:return: Boolean, True if PSU is plugged, False if not
|
||||||
|
"""
|
||||||
|
if index is None:
|
||||||
|
return False
|
||||||
|
|
||||||
|
status = 0
|
||||||
|
try:
|
||||||
|
with open(self.psu_path.format(index) + self.psu_presence, 'r') as presence_status:
|
||||||
|
status = int(presence_status.read())
|
||||||
|
except IOError:
|
||||||
|
return False
|
||||||
|
|
||||||
|
return status == 1
|
163
device/centec/arm64-centec_e530_24x2c-r0/plugins/sfputil.py
Normal file
163
device/centec/arm64-centec_e530_24x2c-r0/plugins/sfputil.py
Normal file
@ -0,0 +1,163 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
# sfputil.py
|
||||||
|
#
|
||||||
|
# Platform-specific SFP transceiver interface for SONiC
|
||||||
|
#
|
||||||
|
|
||||||
|
try:
|
||||||
|
import time
|
||||||
|
from socket import *
|
||||||
|
from select import *
|
||||||
|
from sonic_sfp.sfputilbase import SfpUtilBase
|
||||||
|
except ImportError as e:
|
||||||
|
raise ImportError("%s - required module not found" % str(e))
|
||||||
|
|
||||||
|
|
||||||
|
def DBG_PRINT(str):
|
||||||
|
print str + "\n"
|
||||||
|
|
||||||
|
SFP_STATUS_INSERTED = '1'
|
||||||
|
SFP_STATUS_REMOVED = '0'
|
||||||
|
|
||||||
|
class SfpUtil(SfpUtilBase):
|
||||||
|
"""Platform-specific SfpUtil class"""
|
||||||
|
|
||||||
|
@property
|
||||||
|
def port_start(self):
|
||||||
|
return self.PORT_START
|
||||||
|
|
||||||
|
@property
|
||||||
|
def port_end(self):
|
||||||
|
return self.PORT_END
|
||||||
|
|
||||||
|
@property
|
||||||
|
def sfp_base(self):
|
||||||
|
return self.SFP_BASE
|
||||||
|
|
||||||
|
@property
|
||||||
|
def qsfp_ports(self):
|
||||||
|
return range(25, self.PORTS_IN_BLOCK + 1)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def port_to_eeprom_mapping(self):
|
||||||
|
return self.eeprom_mapping
|
||||||
|
|
||||||
|
def is_logical_port(self, port_name):
|
||||||
|
return True
|
||||||
|
|
||||||
|
def get_eeprom_data(self, port):
|
||||||
|
ret = None
|
||||||
|
port_num = self.get_logical_to_physical(port)[0]
|
||||||
|
if port_num < self.port_start or port_num > self.port_end:
|
||||||
|
return ret
|
||||||
|
if port_num < self.sfp_base:
|
||||||
|
return ret
|
||||||
|
try:
|
||||||
|
with open(self.eeprom_mapping[port_num], 'r') as eeprom_file:
|
||||||
|
ret = eeprom_file.read()
|
||||||
|
except IOError as e:
|
||||||
|
DBG_PRINT(str(e))
|
||||||
|
|
||||||
|
return ret
|
||||||
|
|
||||||
|
# todo
|
||||||
|
#def _get_port_eeprom_path(self, port_num, devid):
|
||||||
|
# pass
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.SONIC_PORT_NAME_PREFIX = "Ethernet"
|
||||||
|
self.PORT_START = 1
|
||||||
|
self.PORT_END = 26
|
||||||
|
self.SFP_BASE = 1
|
||||||
|
self.PORTS_IN_BLOCK = 26
|
||||||
|
self.logical = []
|
||||||
|
self.physical_to_logical = {}
|
||||||
|
self.logical_to_physical = {}
|
||||||
|
|
||||||
|
|
||||||
|
self.eeprom_mapping = {}
|
||||||
|
self.f_sfp_present = "/sys/class/sfp/sfp{}/sfp_presence"
|
||||||
|
self.f_sfp_enable = "/sys/class/sfp/sfp{}/sfp_enable"
|
||||||
|
for x in range(self.port_start, self.sfp_base):
|
||||||
|
self.eeprom_mapping[x] = None
|
||||||
|
for x in range(self.sfp_base, self.port_end + 1):
|
||||||
|
self.eeprom_mapping[x] = "/sys/class/sfp/sfp{}/sfp_eeprom".format(x - self.sfp_base + 1)
|
||||||
|
self.presence = {}
|
||||||
|
for x in range(self.sfp_base, self.port_end + 1):
|
||||||
|
self.presence[x] = False;
|
||||||
|
|
||||||
|
SfpUtilBase.__init__(self)
|
||||||
|
|
||||||
|
for x in range(self.sfp_base, self.port_end + 1):
|
||||||
|
self.logical.append('Ethernet' + str(x))
|
||||||
|
|
||||||
|
def get_presence(self, port_num):
|
||||||
|
# Check for invalid port_num
|
||||||
|
if port_num < self.port_start or port_num > self.port_end:
|
||||||
|
return False
|
||||||
|
if port_num < self.sfp_base:
|
||||||
|
return False
|
||||||
|
try:
|
||||||
|
with open(self.f_sfp_present.format(port_num - self.sfp_base + 1), 'r') as sfp_file:
|
||||||
|
return 1 == int(sfp_file.read())
|
||||||
|
except IOError as e:
|
||||||
|
DBG_PRINT(str(e))
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
def get_low_power_mode(self, port_num):
|
||||||
|
# Check for invalid port_num
|
||||||
|
if port_num < self.port_start or port_num > self.port_end:
|
||||||
|
return False
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
def set_low_power_mode(self, port_num, lpmode):
|
||||||
|
# Check for invalid port_num
|
||||||
|
if port_num < self.port_start or port_num > self.port_end:
|
||||||
|
return False
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
def reset(self, port_num):
|
||||||
|
# Check for invalid port_num
|
||||||
|
if port_num < self.port_start or port_num > self.port_end:
|
||||||
|
return False
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def read_porttab_mappings(self, porttabfile):
|
||||||
|
for x in range(self.sfp_base, self.port_end + 1):
|
||||||
|
self.logical_to_physical['Ethernet' + str(x)] = [x]
|
||||||
|
self.physical_to_logical[x] = ['Ethernet' + str(x)]
|
||||||
|
|
||||||
|
data = {'valid':0, 'last':0}
|
||||||
|
def get_transceiver_change_event(self, timeout=2000):
|
||||||
|
now = time.time()
|
||||||
|
port_dict = {}
|
||||||
|
|
||||||
|
if timeout < 1000:
|
||||||
|
timeout = 1000
|
||||||
|
timeout = (timeout) / float(1000) # Convert to secs
|
||||||
|
|
||||||
|
if now < (self.data['last'] + timeout) and self.data['valid']:
|
||||||
|
return True, {}
|
||||||
|
|
||||||
|
for x in range(self.sfp_base, self.port_end + 1):
|
||||||
|
presence = self.get_presence(x)
|
||||||
|
if presence != self.presence[x]:
|
||||||
|
self.presence[x] = presence
|
||||||
|
if presence:
|
||||||
|
port_dict[x] = SFP_STATUS_INSERTED
|
||||||
|
else:
|
||||||
|
port_dict[x] = SFP_STATUS_REMOVED
|
||||||
|
|
||||||
|
if bool(port_dict):
|
||||||
|
self.data['last'] = now
|
||||||
|
self.data['valid'] = 1
|
||||||
|
return True, port_dict
|
||||||
|
else:
|
||||||
|
time.sleep(0.5)
|
||||||
|
return True, {}
|
@ -0,0 +1,70 @@
|
|||||||
|
{# Default values which will be used if no actual configura available #}
|
||||||
|
{% set default_cable = '40m' %}
|
||||||
|
{% set default_ports_num = 54 -%}
|
||||||
|
|
||||||
|
{# Port configuration to cable length look-up table #}
|
||||||
|
{# Each record describes mapping of DUT (DUT port) role and neighbor role to cable length #}
|
||||||
|
{# Roles described in the minigraph #}
|
||||||
|
{% set ports2cable = {
|
||||||
|
'torrouter_server' : '5m',
|
||||||
|
'leafrouter_torrouter' : '40m',
|
||||||
|
'spinerouter_leafrouter' : '300m'
|
||||||
|
}
|
||||||
|
%}
|
||||||
|
|
||||||
|
{%- macro cable_length(port_name) -%}
|
||||||
|
{%- set cable_len = [] -%}
|
||||||
|
{%- for local_port in DEVICE_NEIGHBOR -%}
|
||||||
|
{%- if local_port == port_name -%}
|
||||||
|
{%- if DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] -%}
|
||||||
|
{%- set neighbor = DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] -%}
|
||||||
|
{%- set neighbor_role = neighbor.type -%}
|
||||||
|
{%- set roles1 = switch_role + '_' + neighbor_role %}
|
||||||
|
{%- set roles2 = neighbor_role + '_' + switch_role -%}
|
||||||
|
{%- set roles1 = roles1 | lower -%}
|
||||||
|
{%- set roles2 = roles2 | lower -%}
|
||||||
|
{%- if roles1 in ports2cable -%}
|
||||||
|
{%- if cable_len.append(ports2cable[roles1]) -%}{%- endif -%}
|
||||||
|
{%- elif roles2 in ports2cable -%}
|
||||||
|
{%- if cable_len.append(ports2cable[roles2]) -%}{%- endif -%}
|
||||||
|
{%- endif -%}
|
||||||
|
{%- endif -%}
|
||||||
|
{%- endif -%}
|
||||||
|
{%- endfor -%}
|
||||||
|
{%- if cable_len -%}
|
||||||
|
{{ cable_len.0 }}
|
||||||
|
{%- else -%}
|
||||||
|
{{ default_cable }}
|
||||||
|
{%- endif -%}
|
||||||
|
{% endmacro %}
|
||||||
|
|
||||||
|
{%- if DEVICE_METADATA is defined %}
|
||||||
|
{%- set switch_role = DEVICE_METADATA['localhost']['type'] %}
|
||||||
|
{%- endif -%}
|
||||||
|
|
||||||
|
{# Generate list of ports if not defined #}
|
||||||
|
{% if PORT is not defined %}
|
||||||
|
{% set PORT = [] %}
|
||||||
|
{% for port_idx in range(1,default_ports_num+1) %}
|
||||||
|
{% if PORT.append("Ethernet%d" % (port_idx)) %}{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif -%}
|
||||||
|
|
||||||
|
{% set port_names_list = [] %}
|
||||||
|
{% for port in PORT %}
|
||||||
|
{%- if port_names_list.append(port) %}{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% set port_names = port_names_list | join(',') -%}
|
||||||
|
|
||||||
|
{
|
||||||
|
"CABLE_LENGTH": {
|
||||||
|
"AZURE": {
|
||||||
|
{% for port in PORT %}
|
||||||
|
{% set cable = cable_length(port) -%}
|
||||||
|
"{{ port }}": "{{ cable }}"{%- if not loop.last -%},{% endif %}
|
||||||
|
|
||||||
|
{% endfor %}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,21 @@
|
|||||||
|
# PG lossless profiles.
|
||||||
|
# speed cable size xon xoff threshold
|
||||||
|
1000 5m 34816 18432 16384 0
|
||||||
|
10000 5m 34816 18432 16384 0
|
||||||
|
25000 5m 34816 18432 16384 0
|
||||||
|
40000 5m 34816 18432 16384 0
|
||||||
|
50000 5m 34816 18432 16384 0
|
||||||
|
100000 5m 36864 18432 18432 0
|
||||||
|
1000 40m 36864 18432 18432 0
|
||||||
|
10000 40m 36864 18432 18432 0
|
||||||
|
25000 40m 39936 18432 21504 0
|
||||||
|
40000 40m 41984 18432 23552 0
|
||||||
|
50000 40m 41984 18432 23552 0
|
||||||
|
100000 40m 54272 18432 35840 0
|
||||||
|
1000 300m 49152 18432 30720 0
|
||||||
|
10000 300m 49152 18432 30720 0
|
||||||
|
25000 300m 71680 18432 53248 0
|
||||||
|
40000 300m 94208 18432 75776 0
|
||||||
|
50000 300m 94208 18432 75776 0
|
||||||
|
100000 300m 184320 18432 165888 0
|
||||||
|
|
@ -0,0 +1,53 @@
|
|||||||
|
# name lanes alias speed
|
||||||
|
Ethernet1 1 eth-0-1 1000
|
||||||
|
Ethernet2 0 eth-0-2 1000
|
||||||
|
Ethernet3 3 eth-0-3 1000
|
||||||
|
Ethernet4 2 eth-0-4 1000
|
||||||
|
Ethernet5 5 eth-0-5 1000
|
||||||
|
Ethernet6 4 eth-0-6 1000
|
||||||
|
Ethernet7 7 eth-0-7 1000
|
||||||
|
Ethernet8 6 eth-0-8 1000
|
||||||
|
Ethernet9 17 eth-0-9 1000
|
||||||
|
Ethernet10 16 eth-0-10 1000
|
||||||
|
Ethernet11 19 eth-0-11 1000
|
||||||
|
Ethernet12 18 eth-0-12 1000
|
||||||
|
Ethernet13 21 eth-0-13 1000
|
||||||
|
Ethernet14 20 eth-0-14 1000
|
||||||
|
Ethernet15 23 eth-0-15 1000
|
||||||
|
Ethernet16 22 eth-0-16 1000
|
||||||
|
Ethernet17 9 eth-0-17 1000
|
||||||
|
Ethernet18 8 eth-0-18 1000
|
||||||
|
Ethernet19 11 eth-0-19 1000
|
||||||
|
Ethernet20 10 eth-0-20 1000
|
||||||
|
Ethernet21 33 eth-0-21 1000
|
||||||
|
Ethernet22 32 eth-0-22 1000
|
||||||
|
Ethernet23 35 eth-0-23 1000
|
||||||
|
Ethernet24 34 eth-0-24 1000
|
||||||
|
Ethernet25 37 eth-0-25 1000
|
||||||
|
Ethernet26 36 eth-0-26 1000
|
||||||
|
Ethernet27 39 eth-0-27 1000
|
||||||
|
Ethernet28 38 eth-0-28 1000
|
||||||
|
Ethernet29 41 eth-0-29 1000
|
||||||
|
Ethernet30 40 eth-0-30 1000
|
||||||
|
Ethernet31 43 eth-0-31 1000
|
||||||
|
Ethernet32 42 eth-0-32 1000
|
||||||
|
Ethernet33 25 eth-0-33 1000
|
||||||
|
Ethernet34 24 eth-0-34 1000
|
||||||
|
Ethernet35 27 eth-0-35 1000
|
||||||
|
Ethernet36 26 eth-0-36 1000
|
||||||
|
Ethernet37 49 eth-0-37 1000
|
||||||
|
Ethernet38 48 eth-0-38 1000
|
||||||
|
Ethernet39 51 eth-0-39 1000
|
||||||
|
Ethernet40 50 eth-0-40 1000
|
||||||
|
Ethernet41 53 eth-0-41 1000
|
||||||
|
Ethernet42 52 eth-0-42 1000
|
||||||
|
Ethernet43 55 eth-0-43 1000
|
||||||
|
Ethernet44 54 eth-0-44 1000
|
||||||
|
Ethernet45 57 eth-0-45 1000
|
||||||
|
Ethernet46 56 eth-0-46 1000
|
||||||
|
Ethernet47 59 eth-0-47 1000
|
||||||
|
Ethernet48 58 eth-0-48 1000
|
||||||
|
Ethernet49 13 eth-0-49 10000
|
||||||
|
Ethernet50 12 eth-0-50 10000
|
||||||
|
Ethernet51 15 eth-0-51 10000
|
||||||
|
Ethernet52 14 eth-0-52 10000
|
@ -0,0 +1 @@
|
|||||||
|
{%- include 'qos_config.j2' %}
|
@ -0,0 +1,2 @@
|
|||||||
|
SAI_INIT_CONFIG_FILE=/etc/centec/E530-48t4x-p-chip-profile.txt
|
||||||
|
SAI_HW_PORT_PROFILE_ID_CONFIG_FILE=/etc/centec/E530-48t4x-p-datapath.txt
|
1
device/centec/arm64-centec_e530_48t4x_p-r0/default_sku
Normal file
1
device/centec/arm64-centec_e530_48t4x_p-r0/default_sku
Normal file
@ -0,0 +1 @@
|
|||||||
|
E530-48t4x-p l2
|
1
device/centec/arm64-centec_e530_48t4x_p-r0/fancontrol
Normal file
1
device/centec/arm64-centec_e530_48t4x_p-r0/fancontrol
Normal file
@ -0,0 +1 @@
|
|||||||
|
# Configuration file generated by pwmconfig, changes will be lost
|
22
device/centec/arm64-centec_e530_48t4x_p-r0/plugins/eeprom.py
Normal file
22
device/centec/arm64-centec_e530_48t4x_p-r0/plugins/eeprom.py
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
#############################################################################
|
||||||
|
# Centec E550-24X8Y2C
|
||||||
|
#
|
||||||
|
# Platform and model specific eeprom subclass, inherits from the base class,
|
||||||
|
# and provides the followings:
|
||||||
|
# - the eeprom format definition
|
||||||
|
# - specific encoder/decoder if there is special need
|
||||||
|
#############################################################################
|
||||||
|
|
||||||
|
try:
|
||||||
|
from sonic_eeprom import eeprom_tlvinfo
|
||||||
|
except ImportError, e:
|
||||||
|
raise ImportError (str(e) + "- required module not found")
|
||||||
|
|
||||||
|
|
||||||
|
class board(eeprom_tlvinfo.TlvInfoDecoder):
|
||||||
|
|
||||||
|
def __init__(self, name, path, cpld_root, ro):
|
||||||
|
self.eeprom_path = "/dev/mtd3"
|
||||||
|
super(board, self).__init__(self.eeprom_path, 0, '', True)
|
@ -0,0 +1,98 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
#
|
||||||
|
# led_control.py
|
||||||
|
#
|
||||||
|
# Platform-specific LED control functionality for SONiC
|
||||||
|
#
|
||||||
|
|
||||||
|
try:
|
||||||
|
from sonic_led.led_control_base import LedControlBase
|
||||||
|
import syslog
|
||||||
|
from socket import *
|
||||||
|
from select import *
|
||||||
|
except ImportError, e:
|
||||||
|
raise ImportError(str(e) + " - required module not found")
|
||||||
|
|
||||||
|
|
||||||
|
def DBG_PRINT(str):
|
||||||
|
syslog.openlog("centec-led")
|
||||||
|
syslog.syslog(syslog.LOG_INFO, str)
|
||||||
|
syslog.closelog()
|
||||||
|
|
||||||
|
|
||||||
|
class LedControl(LedControlBase):
|
||||||
|
"""Platform specific LED control class"""
|
||||||
|
|
||||||
|
|
||||||
|
# Helper method to map SONiC port name to index
|
||||||
|
def _port_name_to_index(self, port_name):
|
||||||
|
# Strip "Ethernet" off port name
|
||||||
|
if not port_name.startswith(self.SONIC_PORT_NAME_PREFIX):
|
||||||
|
return -1
|
||||||
|
|
||||||
|
port_idx = int(port_name[len(self.SONIC_PORT_NAME_PREFIX):])
|
||||||
|
return port_idx
|
||||||
|
|
||||||
|
def _port_state_to_mode(self, port_idx, state):
|
||||||
|
if state == "up":
|
||||||
|
return self.LED_MODE_UP[0] if (port_idx < 49) else self.LED_MODE_UP[1]
|
||||||
|
else:
|
||||||
|
return self.LED_MODE_DOWN[0] if (port_idx < 49) else self.LED_MODE_DOWN[1]
|
||||||
|
|
||||||
|
def _port_led_mode_update(self, port_idx, ledMode):
|
||||||
|
with open(self.f_led.format("port{}".format(port_idx)), 'w') as led_file:
|
||||||
|
led_file.write(str(ledMode))
|
||||||
|
|
||||||
|
def _initSystemLed(self):
|
||||||
|
try:
|
||||||
|
with open(self.f_led.format("system"), 'w') as led_file:
|
||||||
|
led_file.write("1")
|
||||||
|
DBG_PRINT("init system led to normal")
|
||||||
|
with open(self.f_led.format("idn"), 'w') as led_file:
|
||||||
|
led_file.write("1")
|
||||||
|
DBG_PRINT("init idn led to off")
|
||||||
|
except IOError as e:
|
||||||
|
DBG_PRINT(str(e))
|
||||||
|
|
||||||
|
def _initPanelLed(self):
|
||||||
|
with open(self.f_led.format("port1"), 'r') as led_file:
|
||||||
|
shouldInit = (int(led_file.read()) == 0)
|
||||||
|
|
||||||
|
if shouldInit == True:
|
||||||
|
for idx in range(1, 53):
|
||||||
|
defmode = self._port_state_to_mode(idx, "down")
|
||||||
|
with open(self.f_led.format("port{}".format(idx)), 'w') as led_file:
|
||||||
|
led_file.write(str(defmode))
|
||||||
|
DBG_PRINT("init port{} led to mode={}".format(idx, defmode))
|
||||||
|
|
||||||
|
def _initDefaultConfig(self):
|
||||||
|
DBG_PRINT("start init led")
|
||||||
|
|
||||||
|
self._initSystemLed()
|
||||||
|
self._initPanelLed()
|
||||||
|
|
||||||
|
DBG_PRINT("init led done")
|
||||||
|
|
||||||
|
|
||||||
|
# Concrete implementation of port_link_state_change() method
|
||||||
|
def port_link_state_change(self, portname, state):
|
||||||
|
port_idx = self._port_name_to_index(portname)
|
||||||
|
ledMode = self._port_state_to_mode(port_idx, state)
|
||||||
|
with open(self.f_led.format("port{}".format(port_idx)), 'r') as led_file:
|
||||||
|
saveMode = int(led_file.read())
|
||||||
|
|
||||||
|
if ledMode == saveMode:
|
||||||
|
return
|
||||||
|
|
||||||
|
self._port_led_mode_update(port_idx, ledMode)
|
||||||
|
DBG_PRINT("update {} led mode from {} to {}".format(portname, saveMode, ledMode))
|
||||||
|
|
||||||
|
|
||||||
|
# Constructor
|
||||||
|
def __init__(self):
|
||||||
|
self.SONIC_PORT_NAME_PREFIX = "Ethernet"
|
||||||
|
self.LED_MODE_UP = [2, 11]
|
||||||
|
self.LED_MODE_DOWN = [1, 7]
|
||||||
|
|
||||||
|
self.f_led = "/sys/class/leds/{}/brightness"
|
||||||
|
self._initDefaultConfig()
|
@ -0,0 +1,72 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
#############################################################################
|
||||||
|
# Centec
|
||||||
|
#
|
||||||
|
# Module contains an implementation of SONiC PSU Base API and
|
||||||
|
# provides the PSUs status which are available in the platform
|
||||||
|
#
|
||||||
|
#############################################################################
|
||||||
|
|
||||||
|
try:
|
||||||
|
from sonic_psu.psu_base import PsuBase
|
||||||
|
except ImportError as e:
|
||||||
|
raise ImportError (str(e) + "- required module not found")
|
||||||
|
|
||||||
|
class PsuUtil(PsuBase):
|
||||||
|
"""Platform-specific PSUutil class"""
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
PsuBase.__init__(self)
|
||||||
|
|
||||||
|
self.psu_path = "/sys/class/psu/psu{}/"
|
||||||
|
self.psu_presence = "psu_presence"
|
||||||
|
self.psu_oper_status = "psu_status"
|
||||||
|
|
||||||
|
def get_num_psus(self):
|
||||||
|
"""
|
||||||
|
Retrieves the number of PSUs available on the device
|
||||||
|
|
||||||
|
:return: An integer, the number of PSUs available on the device
|
||||||
|
"""
|
||||||
|
return 2
|
||||||
|
|
||||||
|
def get_psu_status(self, index):
|
||||||
|
"""
|
||||||
|
Retrieves the oprational status of power supply unit (PSU) defined
|
||||||
|
by 1-based index <index>
|
||||||
|
|
||||||
|
:param index: An integer, 1-based index of the PSU of which to query status
|
||||||
|
:return: Boolean, True if PSU is operating properly, False if PSU is faulty
|
||||||
|
"""
|
||||||
|
if index is None:
|
||||||
|
return False
|
||||||
|
|
||||||
|
status = 0
|
||||||
|
try:
|
||||||
|
with open(self.psu_path.format(index) + self.psu_oper_status, 'r') as power_status:
|
||||||
|
status = int(power_status.read())
|
||||||
|
except IOError:
|
||||||
|
return False
|
||||||
|
|
||||||
|
return status == 1
|
||||||
|
|
||||||
|
def get_psu_presence(self, index):
|
||||||
|
"""
|
||||||
|
Retrieves the presence status of power supply unit (PSU) defined
|
||||||
|
by 1-based index <index>
|
||||||
|
|
||||||
|
:param index: An integer, 1-based index of the PSU of which to query status
|
||||||
|
:return: Boolean, True if PSU is plugged, False if not
|
||||||
|
"""
|
||||||
|
if index is None:
|
||||||
|
return False
|
||||||
|
|
||||||
|
status = 0
|
||||||
|
try:
|
||||||
|
with open(self.psu_path.format(index) + self.psu_presence, 'r') as presence_status:
|
||||||
|
status = int(presence_status.read())
|
||||||
|
except IOError:
|
||||||
|
return False
|
||||||
|
|
||||||
|
return status == 1
|
138
device/centec/arm64-centec_e530_48t4x_p-r0/plugins/sfputil.py
Normal file
138
device/centec/arm64-centec_e530_48t4x_p-r0/plugins/sfputil.py
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
# sfputil.py
|
||||||
|
#
|
||||||
|
# Platform-specific SFP transceiver interface for SONiC
|
||||||
|
#
|
||||||
|
|
||||||
|
try:
|
||||||
|
import time
|
||||||
|
from socket import *
|
||||||
|
from select import *
|
||||||
|
from sonic_sfp.sfputilbase import SfpUtilBase
|
||||||
|
except ImportError as e:
|
||||||
|
raise ImportError("%s - required module not found" % str(e))
|
||||||
|
|
||||||
|
|
||||||
|
def DBG_PRINT(str):
|
||||||
|
print str + "\n"
|
||||||
|
|
||||||
|
|
||||||
|
class SfpUtil(SfpUtilBase):
|
||||||
|
"""Platform-specific SfpUtil class"""
|
||||||
|
|
||||||
|
@property
|
||||||
|
def port_start(self):
|
||||||
|
return self.PORT_START
|
||||||
|
|
||||||
|
@property
|
||||||
|
def port_end(self):
|
||||||
|
return self.PORT_END
|
||||||
|
|
||||||
|
@property
|
||||||
|
def sfp_base(self):
|
||||||
|
return self.SFP_BASE
|
||||||
|
|
||||||
|
@property
|
||||||
|
def qsfp_ports(self):
|
||||||
|
return ()
|
||||||
|
|
||||||
|
@property
|
||||||
|
def port_to_eeprom_mapping(self):
|
||||||
|
return self.eeprom_mapping
|
||||||
|
|
||||||
|
def is_logical_port(self, port_name):
|
||||||
|
return True
|
||||||
|
|
||||||
|
def get_logical_to_physical(self, port_name):
|
||||||
|
if not port_name.startswith(self.SONIC_PORT_NAME_PREFIX):
|
||||||
|
return None
|
||||||
|
|
||||||
|
port_idx = int(port_name[len(self.SONIC_PORT_NAME_PREFIX):])
|
||||||
|
|
||||||
|
return [port_idx]
|
||||||
|
|
||||||
|
def get_eeprom_data(self, port):
|
||||||
|
ret = None
|
||||||
|
port_num = self.get_logical_to_physical(port)[0]
|
||||||
|
if port_num < self.port_start or port_num > self.port_end:
|
||||||
|
return ret
|
||||||
|
if port_num < self.sfp_base:
|
||||||
|
return ret
|
||||||
|
try:
|
||||||
|
with open(self.eeprom_mapping[port_num], 'r') as eeprom_file:
|
||||||
|
ret = eeprom_file.read()
|
||||||
|
except IOError as e:
|
||||||
|
DBG_PRINT(str(e))
|
||||||
|
|
||||||
|
return ret
|
||||||
|
|
||||||
|
# todo
|
||||||
|
#def _get_port_eeprom_path(self, port_num, devid):
|
||||||
|
# pass
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.SONIC_PORT_NAME_PREFIX = "Ethernet"
|
||||||
|
self.PORT_START = 1
|
||||||
|
self.PORT_END = 52
|
||||||
|
self.SFP_BASE = 49
|
||||||
|
self.PORTS_IN_BLOCK = 52
|
||||||
|
|
||||||
|
self.eeprom_mapping = {}
|
||||||
|
self.f_sfp_present = "/sys/class/sfp/sfp{}/sfp_presence"
|
||||||
|
self.f_sfp_enable = "/sys/class/sfp/sfp{}/sfp_enable"
|
||||||
|
for x in range(self.port_start, self.sfp_base):
|
||||||
|
self.eeprom_mapping[x] = None
|
||||||
|
for x in range(self.sfp_base, self.port_end + 1):
|
||||||
|
self.eeprom_mapping[x] = "/sys/class/sfp/sfp{}/sfp_eeprom".format(x - self.sfp_base + 1)
|
||||||
|
self.presence = {}
|
||||||
|
for x in range(self.sfp_base, self.port_end + 1):
|
||||||
|
self.presence[x] = False;
|
||||||
|
|
||||||
|
SfpUtilBase.__init__(self)
|
||||||
|
|
||||||
|
def get_presence(self, port_num):
|
||||||
|
# Check for invalid port_num
|
||||||
|
if port_num < self.port_start or port_num > self.port_end:
|
||||||
|
return False
|
||||||
|
if port_num < self.sfp_base:
|
||||||
|
return False
|
||||||
|
try:
|
||||||
|
with open(self.f_sfp_present.format(port_num - self.sfp_base + 1), 'r') as sfp_file:
|
||||||
|
return 1 == int(sfp_file.read())
|
||||||
|
except IOError as e:
|
||||||
|
DBG_PRINT(str(e))
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
def get_low_power_mode(self, port_num):
|
||||||
|
# Check for invalid port_num
|
||||||
|
if port_num < self.port_start or port_num > self.port_end:
|
||||||
|
return False
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
def set_low_power_mode(self, port_num, lpmode):
|
||||||
|
# Check for invalid port_num
|
||||||
|
if port_num < self.port_start or port_num > self.port_end:
|
||||||
|
return False
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
def reset(self, port_num):
|
||||||
|
# Check for invalid port_num
|
||||||
|
if port_num < self.port_start or port_num > self.port_end:
|
||||||
|
return False
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
def get_transceiver_change_event(self, timeout=0):
|
||||||
|
port_dict = {}
|
||||||
|
while True:
|
||||||
|
for x in range(self.sfp_base, self.port_end + 1):
|
||||||
|
presence = self.get_presence(x)
|
||||||
|
if presence != self.presence[x]:
|
||||||
|
self.presence[x] = presence
|
||||||
|
port_dict[x] = presence
|
||||||
|
return True, port_dict
|
||||||
|
time.sleep(0.5)
|
7
platform/centec-arm64/docker-ptf-centec.mk
Executable file
7
platform/centec-arm64/docker-ptf-centec.mk
Executable file
@ -0,0 +1,7 @@
|
|||||||
|
# docker image for docker-ptf-centec
|
||||||
|
|
||||||
|
DOCKER_PTF_CENTEC = docker-ptf-centec.gz
|
||||||
|
$(DOCKER_PTF_CENTEC)_PATH = $(DOCKERS_PATH)/docker-ptf-saithrift
|
||||||
|
$(DOCKER_PTF_CENTEC)_DEPENDS += $(PYTHON_SAITHRIFT)
|
||||||
|
$(DOCKER_PTF_CENTEC)_LOAD_DOCKERS += $(DOCKER_PTF)
|
||||||
|
SONIC_DOCKER_IMAGES += $(DOCKER_PTF_CENTEC)
|
15
platform/centec-arm64/docker-saiserver-centec.mk
Executable file
15
platform/centec-arm64/docker-saiserver-centec.mk
Executable file
@ -0,0 +1,15 @@
|
|||||||
|
# docker image for centec saiserver
|
||||||
|
|
||||||
|
DOCKER_SAISERVER_CENTEC = docker-saiserver-centec.gz
|
||||||
|
$(DOCKER_SAISERVER_CENTEC)_PATH = $(PLATFORM_PATH)/docker-saiserver-centec
|
||||||
|
$(DOCKER_SAISERVER_CENTEC)_DEPENDS += $(SAISERVER)
|
||||||
|
$(DOCKER_SAISERVER_CENTEC)_FILES += $(DSSERVE) $(BCMCMD)
|
||||||
|
$(DOCKER_SAISERVER_CENTEC)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_STRETCH)
|
||||||
|
SONIC_DOCKER_IMAGES += $(DOCKER_SAISERVER_CENTEC)
|
||||||
|
|
||||||
|
$(DOCKER_SAISERVER_CENTEC)_CONTAINER_NAME = saiserver
|
||||||
|
$(DOCKER_SAISERVER_CENTEC)_RUN_OPT += --privileged -t
|
||||||
|
$(DOCKER_SAISERVER_CENTEC)_RUN_OPT += -v /host/machine.conf:/etc/machine.conf
|
||||||
|
$(DOCKER_SAISERVER_CENTEC)_RUN_OPT += -v /var/run/docker-saiserver:/var/run/sswsyncd
|
||||||
|
$(DOCKER_SAISERVER_CENTEC)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro
|
||||||
|
$(DOCKER_SAISERVER_CENTEC)_RUN_OPT += -v /host/warmboot:/var/warmboot
|
24
platform/centec-arm64/docker-syncd-centec-rpc.mk
Executable file
24
platform/centec-arm64/docker-syncd-centec-rpc.mk
Executable file
@ -0,0 +1,24 @@
|
|||||||
|
# docker image for centec syncd with rpc
|
||||||
|
|
||||||
|
DOCKER_SYNCD_CENTEC_RPC = docker-syncd-centec-rpc.gz
|
||||||
|
$(DOCKER_SYNCD_CENTEC_RPC)_PATH = $(PLATFORM_PATH)/docker-syncd-centec-rpc
|
||||||
|
$(DOCKER_SYNCD_CENTEC_RPC)_DEPENDS += $(SYNCD_RPC) $(LIBTHRIFT)
|
||||||
|
$(DOCKER_SYNCD_CENTEC_RPC)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT)
|
||||||
|
ifeq ($(INSTALL_DEBUG_TOOLS), y)
|
||||||
|
$(DOCKER_SYNCD_CENTEC_RPC)_DEPENDS += $(SYNCD_RPC_DBG) \
|
||||||
|
$(LIBSWSSCOMMON_DBG) \
|
||||||
|
$(LIBSAIMETADATA_DBG) \
|
||||||
|
$(LIBSAIREDIS_DBG)
|
||||||
|
endif
|
||||||
|
$(DOCKER_SYNCD_CENTEC_RPC)_LOAD_DOCKERS += $(DOCKER_SYNCD_BASE)
|
||||||
|
SONIC_DOCKER_IMAGES += $(DOCKER_SYNCD_CENTEC_RPC)
|
||||||
|
SONIC_STRETCH_DOCKERS += $(DOCKER_SYNCD_CENTEC_RPC)
|
||||||
|
ifeq ($(ENABLE_SYNCD_RPC),y)
|
||||||
|
SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_SYNCD_CENTEC_RPC)
|
||||||
|
endif
|
||||||
|
|
||||||
|
$(DOCKER_SYNCD_CENTEC_RPC)_CONTAINER_NAME = syncd
|
||||||
|
$(DOCKER_SYNCD_CENTEC_RPC)_RUN_OPT += --privileged -t
|
||||||
|
$(DOCKER_SYNCD_CENTEC_RPC)_RUN_OPT += -v /host/machine.conf:/etc/machine.conf
|
||||||
|
$(DOCKER_SYNCD_CENTEC_RPC)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro
|
||||||
|
$(DOCKER_SYNCD_CENTEC_RPC)_RUN_OPT += -v /host/warmboot:/var/warmboot
|
51
platform/centec-arm64/docker-syncd-centec-rpc/Dockerfile.j2
Executable file
51
platform/centec-arm64/docker-syncd-centec-rpc/Dockerfile.j2
Executable file
@ -0,0 +1,51 @@
|
|||||||
|
FROM docker-syncd-centec
|
||||||
|
|
||||||
|
## Make apt-get non-interactive
|
||||||
|
ENV DEBIAN_FRONTEND=noninteractive
|
||||||
|
|
||||||
|
COPY \
|
||||||
|
{% for deb in docker_syncd_centec_rpc_debs.split(' ') -%}
|
||||||
|
debs/{{ deb }}{{' '}}
|
||||||
|
{%- endfor -%}
|
||||||
|
debs/
|
||||||
|
|
||||||
|
RUN apt-get purge -y syncd
|
||||||
|
|
||||||
|
RUN dpkg_apt() { [ -f $1 ] && { dpkg -i $1 || apt-get -y install -f; } || return 1; } ; \
|
||||||
|
{% for deb in docker_syncd_centec_rpc_debs.split(' ') -%}
|
||||||
|
dpkg_apt debs/{{ deb }}{{'; '}}
|
||||||
|
{%- endfor %}
|
||||||
|
|
||||||
|
## Pre-install the fundamental packages
|
||||||
|
RUN apt-get update \
|
||||||
|
&& apt-get -y install \
|
||||||
|
net-tools \
|
||||||
|
python-pip \
|
||||||
|
build-essential \
|
||||||
|
libssl-dev \
|
||||||
|
libffi-dev \
|
||||||
|
python-dev \
|
||||||
|
wget \
|
||||||
|
cmake \
|
||||||
|
&& wget https://github.com/nanomsg/nanomsg/archive/1.0.0.tar.gz \
|
||||||
|
&& tar xvfz 1.0.0.tar.gz \
|
||||||
|
&& cd nanomsg-1.0.0 \
|
||||||
|
&& mkdir -p build \
|
||||||
|
&& cmake . \
|
||||||
|
&& make install \
|
||||||
|
&& ldconfig \
|
||||||
|
&& cd .. \
|
||||||
|
&& rm -fr nanomsg-1.0.0 \
|
||||||
|
&& rm -f 1.0.0.tar.gz \
|
||||||
|
&& pip install cffi==1.7.0 \
|
||||||
|
&& pip install --upgrade cffi==1.7.0 \
|
||||||
|
&& pip install nnpy \
|
||||||
|
&& mkdir -p /opt \
|
||||||
|
&& cd /opt \
|
||||||
|
&& wget https://raw.githubusercontent.com/p4lang/ptf/master/ptf_nn/ptf_nn_agent.py \
|
||||||
|
&& apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y \
|
||||||
|
&& rm -rf /root/deps
|
||||||
|
|
||||||
|
COPY ["ptf_nn_agent.conf", "/etc/supervisor/conf.d/"]
|
||||||
|
|
||||||
|
ENTRYPOINT ["/usr/bin/supervisord"]
|
10
platform/centec-arm64/docker-syncd-centec-rpc/ptf_nn_agent.conf
Executable file
10
platform/centec-arm64/docker-syncd-centec-rpc/ptf_nn_agent.conf
Executable file
@ -0,0 +1,10 @@
|
|||||||
|
[program:ptf_nn_agent]
|
||||||
|
command=/usr/bin/python /opt/ptf_nn_agent.py --device-socket 1@tcp://0.0.0.0:10900 -i 1-3@Ethernet12 --set-iface-rcv-buffer=109430400
|
||||||
|
process_name=ptf_nn_agent
|
||||||
|
stdout_logfile=/tmp/ptf_nn_agent.out.log
|
||||||
|
stderr_logfile=/tmp/ptf_nn_agent.err.log
|
||||||
|
redirect_stderr=false
|
||||||
|
autostart=true
|
||||||
|
autorestart=true
|
||||||
|
startsecs=1
|
||||||
|
numprocs=1
|
17
platform/centec-arm64/docker-syncd-centec.mk
Executable file
17
platform/centec-arm64/docker-syncd-centec.mk
Executable file
@ -0,0 +1,17 @@
|
|||||||
|
# docker image for centec syncd
|
||||||
|
|
||||||
|
DOCKER_SYNCD_PLATFORM_CODE = centec
|
||||||
|
include $(PLATFORM_PATH)/../template/docker-syncd-base.mk
|
||||||
|
|
||||||
|
$(DOCKER_SYNCD_BASE)_DEPENDS += $(SYNCD) $(PYTHON_SDK_API)
|
||||||
|
$(DOCKER_SYNCD_CENTEC)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT)
|
||||||
|
$(DOCKER_SYNCD_BASE)_DBG_DEPENDS += $(SYNCD_DBG) \
|
||||||
|
$(LIBSWSSCOMMON_DBG) \
|
||||||
|
$(LIBSAIMETADATA_DBG) \
|
||||||
|
$(LIBSAIREDIS_DBG)
|
||||||
|
|
||||||
|
$(DOCKER_SYNCD_BASE)_RUN_OPT += -v /host/warmboot:/var/warmboot
|
||||||
|
$(DOCKER_SYNCD_CENTEC)_RUN_OPT += --privileged -t
|
||||||
|
$(DOCKER_SYNCD_CENTEC)_RUN_OPT += -v /host/machine.conf:/etc/machine.conf
|
||||||
|
$(DOCKER_SYNCD_CENTEC)_RUN_OPT += -v /var/run/docker-syncd:/var/run/sswsyncd
|
||||||
|
$(DOCKER_SYNCD_CENTEC)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro
|
37
platform/centec-arm64/docker-syncd-centec/Dockerfile.j2
Executable file
37
platform/centec-arm64/docker-syncd-centec/Dockerfile.j2
Executable file
@ -0,0 +1,37 @@
|
|||||||
|
FROM docker-config-engine-stretch
|
||||||
|
|
||||||
|
ARG docker_container_name
|
||||||
|
RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf
|
||||||
|
|
||||||
|
## Make apt-get non-interactive
|
||||||
|
ENV DEBIAN_FRONTEND=noninteractive
|
||||||
|
|
||||||
|
RUN apt-get update
|
||||||
|
|
||||||
|
COPY \
|
||||||
|
{% for deb in docker_syncd_centec_debs.split(' ') -%}
|
||||||
|
debs/{{ deb }}{{' '}}
|
||||||
|
{%- endfor -%}
|
||||||
|
debs/
|
||||||
|
|
||||||
|
RUN apt-get update \
|
||||||
|
&& apt-get -y install \
|
||||||
|
net-tools \
|
||||||
|
iputils-ping
|
||||||
|
|
||||||
|
RUN apt-get -y install libpcap-dev libxml2-dev python-dev swig libsensors4-dev libjemalloc1 nfs-common
|
||||||
|
|
||||||
|
RUN dpkg -i \
|
||||||
|
{% for deb in docker_syncd_centec_debs.split(' ') -%}
|
||||||
|
debs/{{ deb }}{{' '}}
|
||||||
|
{%- endfor %}
|
||||||
|
|
||||||
|
COPY ["supervisord.conf", "/etc/supervisor/conf.d/"]
|
||||||
|
COPY ["files/supervisor-proc-exit-listener", "/usr/bin/"]
|
||||||
|
COPY ["critical_processes", "/etc/supervisor/"]
|
||||||
|
|
||||||
|
## Clean up
|
||||||
|
RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y
|
||||||
|
RUN rm -rf /debs
|
||||||
|
|
||||||
|
ENTRYPOINT ["/usr/bin/supervisord"]
|
@ -0,0 +1 @@
|
|||||||
|
syncd
|
37
platform/centec-arm64/docker-syncd-centec/supervisord.conf
Executable file
37
platform/centec-arm64/docker-syncd-centec/supervisord.conf
Executable file
@ -0,0 +1,37 @@
|
|||||||
|
[supervisord]
|
||||||
|
logfile_maxbytes=1MB
|
||||||
|
logfile_backups=2
|
||||||
|
nodaemon=true
|
||||||
|
|
||||||
|
[eventlistener:dependent-startup]
|
||||||
|
command=python -m supervisord_dependent_startup
|
||||||
|
autostart=true
|
||||||
|
autorestart=unexpected
|
||||||
|
startretries=0
|
||||||
|
exitcodes=0,3
|
||||||
|
events=PROCESS_STATE
|
||||||
|
|
||||||
|
[eventlistener:supervisor-proc-exit-listener]
|
||||||
|
command=/usr/bin/supervisor-proc-exit-listener --container-name syncd
|
||||||
|
events=PROCESS_STATE_EXITED
|
||||||
|
autostart=true
|
||||||
|
autorestart=unexpected
|
||||||
|
|
||||||
|
[program:rsyslogd]
|
||||||
|
command=/usr/sbin/rsyslogd -n -iNONE
|
||||||
|
priority=1
|
||||||
|
autostart=false
|
||||||
|
autorestart=false
|
||||||
|
stdout_logfile=syslog
|
||||||
|
stderr_logfile=syslog
|
||||||
|
dependent_startup=true
|
||||||
|
|
||||||
|
[program:syncd]
|
||||||
|
command=/usr/bin/syncd_start.sh
|
||||||
|
priority=3
|
||||||
|
autostart=false
|
||||||
|
autorestart=false
|
||||||
|
stdout_logfile=syslog
|
||||||
|
stderr_logfile=syslog
|
||||||
|
dependent_startup=true
|
||||||
|
dependent_startup_wait_for=rsyslogd:running
|
12
platform/centec-arm64/docker-syncd-centec/syncd.sh
Executable file
12
platform/centec-arm64/docker-syncd-centec/syncd.sh
Executable file
@ -0,0 +1,12 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
function clean_up {
|
||||||
|
service syncd stop
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
|
||||||
|
trap clean_up SIGTERM SIGKILL
|
||||||
|
|
||||||
|
service syncd start
|
||||||
|
|
||||||
|
read
|
20
platform/centec-arm64/libsaithrift-dev.mk
Executable file
20
platform/centec-arm64/libsaithrift-dev.mk
Executable file
@ -0,0 +1,20 @@
|
|||||||
|
# libsaithrift-dev package
|
||||||
|
|
||||||
|
SAI_VER = 0.9.4
|
||||||
|
|
||||||
|
LIBSAITHRIFT_DEV = libsaithrift-dev_$(SAI_VER)_$(CONFIGURED_ARCH).deb
|
||||||
|
$(LIBSAITHRIFT_DEV)_SRC_PATH = $(SRC_PATH)/sonic-sairedis/SAI
|
||||||
|
$(LIBSAITHRIFT_DEV)_DEPENDS += $(LIBTHRIFT) $(LIBTHRIFT_DEV) $(PYTHON_THRIFT) $(THRIFT_COMPILER) $(CENTEC_SAI)
|
||||||
|
$(LIBSAITHRIFT_DEV)_RDEPENDS += $(LIBTHRIFT) $(CENTEC_SAI)
|
||||||
|
SONIC_DPKG_DEBS += $(LIBSAITHRIFT_DEV)
|
||||||
|
|
||||||
|
PYTHON_SAITHRIFT = python-saithrift_$(SAI_VER)_$(CONFIGURED_ARCH).deb
|
||||||
|
$(eval $(call add_extra_package,$(LIBSAITHRIFT_DEV),$(PYTHON_SAITHRIFT)))
|
||||||
|
|
||||||
|
SAISERVER = saiserver_$(SAI_VER)_$(CONFIGURED_ARCH).deb
|
||||||
|
$(SAISERVER)_RDEPENDS += $(LIBTHRIFT) $(CENTEC_SAI)
|
||||||
|
$(eval $(call add_extra_package,$(LIBSAITHRIFT_DEV),$(SAISERVER)))
|
||||||
|
|
||||||
|
SAISERVER_DBG = saiserver-dbg_$(SAI_VER)_$(CONFIGURED_ARCH).deb
|
||||||
|
$(SAISERVER_DBG)_RDEPENDS += $(SAISERVER)
|
||||||
|
$(eval $(call add_extra_package,$(LIBSAITHRIFT_DEV),$(SAISERVER_DBG)))
|
22
platform/centec-arm64/modules
Normal file
22
platform/centec-arm64/modules
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
pinctrl-ctc
|
||||||
|
mtdblock
|
||||||
|
ofpart
|
||||||
|
spi-ctc-qspi
|
||||||
|
spi-nor
|
||||||
|
m25p80
|
||||||
|
i2c-ctc
|
||||||
|
i2c-dev
|
||||||
|
rtc-sd2405
|
||||||
|
ctc5236_switch
|
||||||
|
ctc5236_mdio
|
||||||
|
ctcmac
|
||||||
|
ctcmac_test
|
||||||
|
ctc5236-mc
|
||||||
|
ctc_wdt
|
||||||
|
ehci-ctc
|
||||||
|
sdhci-ctc5236
|
||||||
|
gpio-ctc
|
||||||
|
pwm-ctc
|
||||||
|
ext4
|
||||||
|
overlay
|
||||||
|
squashfs
|
18
platform/centec-arm64/one-image.mk
Executable file
18
platform/centec-arm64/one-image.mk
Executable file
@ -0,0 +1,18 @@
|
|||||||
|
# sonic centec one image installer
|
||||||
|
|
||||||
|
SONIC_ONE_IMAGE = sonic-centec-arm64.bin
|
||||||
|
$(SONIC_ONE_IMAGE)_MACHINE = centec-arm64
|
||||||
|
$(SONIC_ONE_IMAGE)_IMAGE_TYPE = onie
|
||||||
|
|
||||||
|
$(SONIC_ONE_IMAGE)_INSTALLS += $(SYSTEMD_SONIC_GENERATOR)
|
||||||
|
$(SONIC_ONE_IMAGE)_INSTALLS += $(TSINGMA_BSP_MODULE)
|
||||||
|
$(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(CENTEC_E530_48T4X_P_PLATFORM_MODULE)
|
||||||
|
$(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(CENTEC_E530_24X2C_PLATFORM_MODULE)
|
||||||
|
|
||||||
|
ifeq ($(INSTALL_DEBUG_TOOLS),y)
|
||||||
|
$(SONIC_ONE_IMAGE)_DOCKERS += $(SONIC_INSTALL_DOCKER_DBG_IMAGES)
|
||||||
|
$(SONIC_ONE_IMAGE)_DOCKERS += $(filter-out $(patsubst %-$(DBG_IMAGE_MARK).gz,%.gz, $(SONIC_INSTALL_DOCKER_DBG_IMAGES)), $(SONIC_INSTALL_DOCKER_IMAGES))
|
||||||
|
else
|
||||||
|
$(SONIC_ONE_IMAGE)_DOCKERS = $(SONIC_INSTALL_DOCKER_IMAGES)
|
||||||
|
endif
|
||||||
|
SONIC_INSTALLERS += $(SONIC_ONE_IMAGE)
|
18
platform/centec-arm64/platform-modules-centec-e530.mk
Normal file
18
platform/centec-arm64/platform-modules-centec-e530.mk
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# Centec E530-48T4X-P Platform modules
|
||||||
|
|
||||||
|
|
||||||
|
CENTEC_E530_48T4X_P_PLATFORM_MODULE_VERSION =1.1
|
||||||
|
CENTEC_E530_24X2C_PLATFORM_MODULE_VERSION =1.1
|
||||||
|
|
||||||
|
export CENTEC_E530_48T4X_P_PLATFORM_MODULE_VERSION
|
||||||
|
|
||||||
|
CENTEC_E530_48T4X_P_PLATFORM_MODULE = platform-modules-e530-48t4x-p_$(CENTEC_E530_48T4X_P_PLATFORM_MODULE_VERSION)_arm64.deb
|
||||||
|
|
||||||
|
$(CENTEC_E530_48T4X_P_PLATFORM_MODULE)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-modules-e530
|
||||||
|
$(CENTEC_E530_48T4X_P_PLATFORM_MODULE)_PLATFORM = arm64-centec_e530_48t4x_p-r0
|
||||||
|
$(CENTEC_E530_48T4X_P_PLATFORM_MODULE)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON)
|
||||||
|
SONIC_DPKG_DEBS += $(CENTEC_E530_48T4X_P_PLATFORM_MODULE)
|
||||||
|
|
||||||
|
CENTEC_E530_24X2C_PLATFORM_MODULE = platform-modules-e530-24x2c_$(CENTEC_E530_24X2C_PLATFORM_MODULE_VERSION)_arm64.deb
|
||||||
|
$(CENTEC_E530_24X2C_PLATFORM_MODULE)_PLATFORM = arm64-centec_e530_24x2c-r0
|
||||||
|
$(eval $(call add_extra_package,$(CENTEC_E530_48T4X_P_PLATFORM_MODULE),$(CENTEC_E530_24X2C_PLATFORM_MODULE)))
|
46
platform/centec-arm64/platform.conf
Executable file
46
platform/centec-arm64/platform.conf
Executable file
@ -0,0 +1,46 @@
|
|||||||
|
# Copyright (C) Centec Inc
|
||||||
|
|
||||||
|
# over ride default behaviour
|
||||||
|
|
||||||
|
echo "Preparing for installation ... "
|
||||||
|
|
||||||
|
demo_mnt=/mnt
|
||||||
|
|
||||||
|
hw_load() {
|
||||||
|
echo "ext4load mmc 0:2 \$loadaddr onie_uimage"
|
||||||
|
}
|
||||||
|
|
||||||
|
create_partition() {
|
||||||
|
echo y | mkfs.ext4 -L CTC-SYSTEM /dev/mmcblk0p1
|
||||||
|
}
|
||||||
|
|
||||||
|
mount_partition() {
|
||||||
|
echo "mount flash"
|
||||||
|
mount -t ext4 /dev/mmcblk0p1 $demo_mnt
|
||||||
|
}
|
||||||
|
|
||||||
|
bootloader_menu_config() {
|
||||||
|
mkdir -p $demo_mnt/boot
|
||||||
|
mount -t ext4 /dev/mmcblk0p2 $demo_mnt/boot
|
||||||
|
|
||||||
|
rm $demo_mnt/boot/centec-e530.itb -rf
|
||||||
|
cp $demo_mnt/$image_dir/boot/sonic_arm64.fit $demo_mnt/boot/centec-e530.itb
|
||||||
|
cd $demo_mnt/boot
|
||||||
|
rm onie_uimage -rf
|
||||||
|
ln -s centec-e530.itb onie_uimage
|
||||||
|
cd -
|
||||||
|
sync
|
||||||
|
umount -l $demo_mnt/boot
|
||||||
|
|
||||||
|
hw_load_str="$(hw_load)"
|
||||||
|
|
||||||
|
(cat <<EOF
|
||||||
|
hw_load $hw_load_str
|
||||||
|
copy_img echo "Loading Demo $platform image..." && run hw_load
|
||||||
|
nos_bootcmd run copy_img && setenv bootargs quiet console=\$consoledev,\$baudrate root=/dev/mmcblk0p1 rw rootwait rootfstype=ext4 loopfstype=squashfs loop=$image_dir/fs.squashfs && bootm \$loadaddr
|
||||||
|
EOF
|
||||||
|
) > /tmp/env.txt
|
||||||
|
|
||||||
|
fw_setenv -f -s /tmp/env.txt
|
||||||
|
fw_setenv -f image_dir $image_dir
|
||||||
|
}
|
18
platform/centec-arm64/rules.mk
Executable file
18
platform/centec-arm64/rules.mk
Executable file
@ -0,0 +1,18 @@
|
|||||||
|
include $(PLATFORM_PATH)/sai.mk
|
||||||
|
include $(PLATFORM_PATH)/docker-syncd-centec.mk
|
||||||
|
include $(PLATFORM_PATH)/docker-syncd-centec-rpc.mk
|
||||||
|
include $(PLATFORM_PATH)/one-image.mk
|
||||||
|
include $(PLATFORM_PATH)/libsaithrift-dev.mk
|
||||||
|
include $(PLATFORM_PATH)/docker-ptf-centec.mk
|
||||||
|
include $(PLATFORM_PATH)/tsingma-bsp.mk
|
||||||
|
include $(PLATFORM_PATH)/platform-modules-centec-e530.mk
|
||||||
|
|
||||||
|
SONIC_ALL += $(SONIC_ONE_IMAGE) \
|
||||||
|
$(DOCKER_FPM)
|
||||||
|
# $(DOCKER_SYNCD_CENTEC_RPC)
|
||||||
|
|
||||||
|
# Inject centec sai into sairedis
|
||||||
|
$(LIBSAIREDIS)_DEPENDS += $(CENTEC_SAI) $(LIBSAITHRIFT_DEV_CENTEC)
|
||||||
|
|
||||||
|
# Runtime dependency on centec sai is set only for syncd
|
||||||
|
$(SYNCD)_RDEPENDS += $(CENTEC_SAI)
|
8
platform/centec-arm64/sai.mk
Executable file
8
platform/centec-arm64/sai.mk
Executable file
@ -0,0 +1,8 @@
|
|||||||
|
# Centec SAI
|
||||||
|
|
||||||
|
export CENTEC_SAI_VERSION = 1.6.3-1
|
||||||
|
export CENTEC_SAI = libsai_$(CENTEC_SAI_VERSION)_$(PLATFORM_ARCH).deb
|
||||||
|
|
||||||
|
$(CENTEC_SAI)_URL = https://github.com/CentecNetworks/sonic-binaries/raw/master/$(PLATFORM_ARCH)/sai/$(CENTEC_SAI)
|
||||||
|
SONIC_ONLINE_DEBS += $(CENTEC_SAI)
|
||||||
|
|
@ -0,0 +1 @@
|
|||||||
|
obj-m := centec_e530_24x2c_platform.o
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,13 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=Centec modules init
|
||||||
|
After=local-fs.target
|
||||||
|
Before=syncd.service
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=oneshot
|
||||||
|
ExecStart=-/etc/init.d/platform-modules-e530-24x2c start
|
||||||
|
ExecStop=-/etc/init.d/platform-modules-e530-24x2c stop
|
||||||
|
RemainAfterExit=yes
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
15
platform/centec-arm64/sonic-platform-modules-e530/24x2c/setup.py
Executable file
15
platform/centec-arm64/sonic-platform-modules-e530/24x2c/setup.py
Executable file
@ -0,0 +1,15 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
import os
|
||||||
|
from setuptools import setup
|
||||||
|
os.listdir
|
||||||
|
|
||||||
|
setup(
|
||||||
|
name='24x2c',
|
||||||
|
version='1.1',
|
||||||
|
description='Module to initialize centec e530-24x2c platforms',
|
||||||
|
|
||||||
|
packages=['24x2c'],
|
||||||
|
package_dir={'24x2c': '24x2c/classes'},
|
||||||
|
)
|
||||||
|
|
@ -0,0 +1 @@
|
|||||||
|
obj-m := centec_e530_48t4x_p_platform.o
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,13 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=Centec modules init
|
||||||
|
After=local-fs.target
|
||||||
|
Before=syncd.service
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=oneshot
|
||||||
|
ExecStart=-/etc/init.d/platform-modules-e530-48t4x-p start
|
||||||
|
ExecStop=-/etc/init.d/platform-modules-e530-48t4x-p stop
|
||||||
|
RemainAfterExit=yes
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
15
platform/centec-arm64/sonic-platform-modules-e530/48t4x_p/setup.py
Executable file
15
platform/centec-arm64/sonic-platform-modules-e530/48t4x_p/setup.py
Executable file
@ -0,0 +1,15 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
import os
|
||||||
|
from setuptools import setup
|
||||||
|
os.listdir
|
||||||
|
|
||||||
|
setup(
|
||||||
|
name='48t4x_p',
|
||||||
|
version='1.1',
|
||||||
|
description='Module to initialize centec e530-48t4x-p platforms',
|
||||||
|
|
||||||
|
packages=['48t4x_p'],
|
||||||
|
package_dir={'48t4x_p': '48t4x_p/classes'},
|
||||||
|
)
|
||||||
|
|
15
platform/centec-arm64/sonic-platform-modules-e530/LICENSE
Normal file
15
platform/centec-arm64/sonic-platform-modules-e530/LICENSE
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
Copyright (C) 2019 Centec, Inc
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 2
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
@ -0,0 +1 @@
|
|||||||
|
platform drivers for Centec E530 for the SONiC project
|
@ -0,0 +1,11 @@
|
|||||||
|
sonic-centec-platform-modules (1.1) unstable; urgency=low
|
||||||
|
|
||||||
|
* Add support for centec e530-48t4x-p and e530-24x2c
|
||||||
|
|
||||||
|
-- shil <shil@centecnetworks.com> Fri, 15 Nov 2019 13:36:54 +0800
|
||||||
|
|
||||||
|
sonic-centec-platform-modules (1.0) unstable; urgency=low
|
||||||
|
|
||||||
|
* Initial release
|
||||||
|
|
||||||
|
-- shil <shil@centecnetworks.com> Fri, 15 Nov 2019 13:35:06 +0800
|
@ -0,0 +1 @@
|
|||||||
|
9
|
@ -0,0 +1,16 @@
|
|||||||
|
Source: sonic-centec-platform-modules
|
||||||
|
Section: main
|
||||||
|
Priority: extra
|
||||||
|
Maintainer: shil <shil@centecnetworks.com>
|
||||||
|
Build-Depends: debhelper (>= 8.0.0), bzip2
|
||||||
|
Standards-Version: 3.9.3
|
||||||
|
|
||||||
|
Package: platform-modules-e530-48t4x-p
|
||||||
|
Architecture: arm64
|
||||||
|
Depends: linux-image-4.19.0-9-2-arm64-unsigned
|
||||||
|
Description: kernel modules for platform devices such as fan, led, sfp
|
||||||
|
|
||||||
|
Package: platform-modules-e530-24x2c
|
||||||
|
Architecture: arm64
|
||||||
|
Depends: linux-image-4.19.0-9-2-arm64-unsigned
|
||||||
|
Description: kernel modules for platform devices such as fan, led, sfp
|
@ -0,0 +1,61 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# This script load/unload centec kernel modules
|
||||||
|
|
||||||
|
### BEGIN INIT INFO
|
||||||
|
# Provides: platform-modules-e530-24x2c
|
||||||
|
# Required-Start:
|
||||||
|
# Required-Stop:
|
||||||
|
# Should-Start:
|
||||||
|
# Should-Stop:
|
||||||
|
# Default-Start: S
|
||||||
|
# Default-Stop: 0 6
|
||||||
|
# Short-Description: Load Centec kernel modules
|
||||||
|
### END INIT INFO
|
||||||
|
|
||||||
|
|
||||||
|
function load_kernel_modules()
|
||||||
|
{
|
||||||
|
depmod -a
|
||||||
|
modprobe centec_e530_24x2c_platform
|
||||||
|
modprobe dal
|
||||||
|
modprobe tun
|
||||||
|
modprobe tap
|
||||||
|
}
|
||||||
|
|
||||||
|
function remove_kernel_modules()
|
||||||
|
{
|
||||||
|
modprobe -r tap
|
||||||
|
modprobe -r tun
|
||||||
|
modprobe -r dal
|
||||||
|
modprobe -r centec_e530_24x2c_platform
|
||||||
|
}
|
||||||
|
|
||||||
|
case "$1" in
|
||||||
|
start)
|
||||||
|
echo -n "Load Centec kernel modules... "
|
||||||
|
|
||||||
|
load_kernel_modules
|
||||||
|
|
||||||
|
echo "done."
|
||||||
|
;;
|
||||||
|
|
||||||
|
stop)
|
||||||
|
echo -n "Unload Centec kernel modules... "
|
||||||
|
|
||||||
|
remove_kernel_modules
|
||||||
|
|
||||||
|
echo "done."
|
||||||
|
;;
|
||||||
|
|
||||||
|
force-reload|restart)
|
||||||
|
echo "Not supported"
|
||||||
|
;;
|
||||||
|
|
||||||
|
*)
|
||||||
|
echo "Usage: /etc/init.d/platform-modules-e530-24x2c {start|stop}"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
exit 0
|
||||||
|
|
@ -0,0 +1,3 @@
|
|||||||
|
../../centec/centec-dal/dal.ko /lib/modules/4.19.0-9-2-arm64/kernel/extra
|
||||||
|
24x2c/modules/centec_e530_24x2c_platform.ko /lib/modules/4.19.0-9-2-arm64/kernel/extra
|
||||||
|
24x2c/service/24x2c_platform.service /lib/systemd/system
|
@ -0,0 +1,2 @@
|
|||||||
|
systemctl enable 24x2c_platform.service
|
||||||
|
systemctl start 24x2c_platform.service
|
@ -0,0 +1,61 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# This script load/unload centec kernel modules
|
||||||
|
|
||||||
|
### BEGIN INIT INFO
|
||||||
|
# Provides: platform-modules-e530-48t4x-p
|
||||||
|
# Required-Start:
|
||||||
|
# Required-Stop:
|
||||||
|
# Should-Start:
|
||||||
|
# Should-Stop:
|
||||||
|
# Default-Start: S
|
||||||
|
# Default-Stop: 0 6
|
||||||
|
# Short-Description: Load Centec kernel modules
|
||||||
|
### END INIT INFO
|
||||||
|
|
||||||
|
|
||||||
|
function load_kernel_modules()
|
||||||
|
{
|
||||||
|
depmod -a
|
||||||
|
modprobe centec_e530_48t4x_p_platform
|
||||||
|
modprobe dal
|
||||||
|
modprobe tun
|
||||||
|
modprobe tap
|
||||||
|
}
|
||||||
|
|
||||||
|
function remove_kernel_modules()
|
||||||
|
{
|
||||||
|
modprobe -r tap
|
||||||
|
modprobe -r tun
|
||||||
|
modprobe -r dal
|
||||||
|
modprobe -r centec_e530_48t4x_p_platform
|
||||||
|
}
|
||||||
|
|
||||||
|
case "$1" in
|
||||||
|
start)
|
||||||
|
echo -n "Load Centec kernel modules... "
|
||||||
|
|
||||||
|
load_kernel_modules
|
||||||
|
|
||||||
|
echo "done."
|
||||||
|
;;
|
||||||
|
|
||||||
|
stop)
|
||||||
|
echo -n "Unload Centec kernel modules... "
|
||||||
|
|
||||||
|
remove_kernel_modules
|
||||||
|
|
||||||
|
echo "done."
|
||||||
|
;;
|
||||||
|
|
||||||
|
force-reload|restart)
|
||||||
|
echo "Not supported"
|
||||||
|
;;
|
||||||
|
|
||||||
|
*)
|
||||||
|
echo "Usage: /etc/init.d/platform-modules-e530-48t4x-p {start|stop}"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
exit 0
|
||||||
|
|
@ -0,0 +1,3 @@
|
|||||||
|
../../centec/centec-dal/dal.ko /lib/modules/4.19.0-9-2-arm64/kernel/extra
|
||||||
|
48t4x_p/modules/centec_e530_48t4x_p_platform.ko /lib/modules/4.19.0-9-2-arm64/kernel/extra
|
||||||
|
48t4x_p/service/48t4x_p_platform.service /lib/systemd/system
|
@ -0,0 +1,2 @@
|
|||||||
|
systemctl enable 48t4x_p_platform.service
|
||||||
|
systemctl start 48t4x_p_platform.service
|
91
platform/centec-arm64/sonic-platform-modules-e530/debian/rules
Executable file
91
platform/centec-arm64/sonic-platform-modules-e530/debian/rules
Executable file
@ -0,0 +1,91 @@
|
|||||||
|
#!/usr/bin/make -f
|
||||||
|
# -*- makefile -*-
|
||||||
|
# Sample debian/rules that uses debhelper.
|
||||||
|
# This file was originally written by Joey Hess and Craig Small.
|
||||||
|
# As a special exception, when this file is copied by dh-make into a
|
||||||
|
# dh-make output file, you may use that output file without restriction.
|
||||||
|
# This special exception was added by Craig Small in version 0.37 of dh-make.
|
||||||
|
|
||||||
|
include /usr/share/dpkg/pkg-info.mk
|
||||||
|
|
||||||
|
# Uncomment this to turn on verbose mode.
|
||||||
|
#export DH_VERBOSE=1
|
||||||
|
|
||||||
|
export INSTALL_MOD_DIR:=extra
|
||||||
|
|
||||||
|
PYTHON ?= python2
|
||||||
|
|
||||||
|
PACKAGE_PRE_NAME := sonic-platform-modules-e530
|
||||||
|
KVERSION ?= $(shell uname -r)
|
||||||
|
KERNEL_SRC := /lib/modules/$(KVERSION)
|
||||||
|
MOD_SRC_DIR:= $(shell pwd)
|
||||||
|
MODULE_DIRS:= 48t4x_p 24x2c
|
||||||
|
MODULE_DIR := modules
|
||||||
|
UTILS_DIR := utils
|
||||||
|
SERVICE_DIR := service
|
||||||
|
CLASSES_DIR := classes
|
||||||
|
CONF_DIR := conf
|
||||||
|
KDAL_DIR := ../../centec/centec-dal/
|
||||||
|
|
||||||
|
%:
|
||||||
|
dh $@ --with systemd,python2,python3 --buildsystem=pybuild
|
||||||
|
|
||||||
|
clean:
|
||||||
|
dh_testdir
|
||||||
|
dh_testroot
|
||||||
|
dh_clean
|
||||||
|
|
||||||
|
build:
|
||||||
|
#make modules -C $(KERNEL_SRC)/build M=$(MODULE_SRC)
|
||||||
|
(for mod in $(KDAL_DIR); do \
|
||||||
|
make modules -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/$${mod}/; \
|
||||||
|
done)
|
||||||
|
(for mod in $(MODULE_DIRS); do \
|
||||||
|
make modules -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/$${mod}/modules; \
|
||||||
|
$(PYTHON) $${mod}/setup.py build; \
|
||||||
|
done)
|
||||||
|
|
||||||
|
binary: binary-arch binary-indep
|
||||||
|
# Nothing to do
|
||||||
|
|
||||||
|
binary-arch:
|
||||||
|
# Nothing to do
|
||||||
|
|
||||||
|
#install: build
|
||||||
|
#dh_testdir
|
||||||
|
#dh_testroot
|
||||||
|
#dh_clean -k
|
||||||
|
#dh_installdirs
|
||||||
|
|
||||||
|
binary-indep:
|
||||||
|
dh_testdir
|
||||||
|
dh_installdirs
|
||||||
|
|
||||||
|
# Custom package commands
|
||||||
|
(for mod in $(MODULE_DIRS); do \
|
||||||
|
dh_installdirs -p$(PACKAGE_PRE_NAME)-$${mod} $(KERNEL_SRC)/$(INSTALL_MOD_DIR); \
|
||||||
|
dh_installdirs -p$(PACKAGE_PRE_NAME)-$${mod} usr/local/bin; \
|
||||||
|
dh_installdirs -p$(PACKAGE_PRE_NAME)-$${mod} lib/systemd/system; \
|
||||||
|
cp $(MOD_SRC_DIR)/$${mod}/$(MODULE_DIR)/*.ko debian/$(PACKAGE_PRE_NAME)-$${mod}/$(KERNEL_SRC)/$(INSTALL_MOD_DIR); \
|
||||||
|
cp $(MOD_SRC_DIR)/$(KDAL_DIR)/*.ko debian/$(PACKAGE_PRE_NAME)-$${mod}/$(KERNEL_SRC)/$(INSTALL_MOD_DIR); \
|
||||||
|
cp $(MOD_SRC_DIR)/$${mod}/$(UTILS_DIR)/* debian/$(PACKAGE_PRE_NAME)-$${mod}/usr/local/bin/; \
|
||||||
|
cp $(MOD_SRC_DIR)/$${mod}/$(SERVICE_DIR)/*.service debian/$(PACKAGE_PRE_NAME)-$${mod}/lib/systemd/system/; \
|
||||||
|
$(PYTHON) $${mod}/setup.py install --root=$(MOD_SRC_DIR)/debian/$(PACKAGE_PRE_NAME)-$${mod} --install-layout=deb; \
|
||||||
|
done)
|
||||||
|
# Resuming debhelper scripts
|
||||||
|
dh_testroot
|
||||||
|
dh_install
|
||||||
|
dh_installchangelogs
|
||||||
|
dh_installdocs
|
||||||
|
dh_systemd_enable
|
||||||
|
dh_installinit
|
||||||
|
dh_systemd_start
|
||||||
|
dh_link
|
||||||
|
dh_fixperms
|
||||||
|
dh_compress
|
||||||
|
dh_strip
|
||||||
|
dh_installdeb
|
||||||
|
dh_gencontrol
|
||||||
|
dh_md5sums
|
||||||
|
dh_builddeb
|
||||||
|
.PHONY: build binary binary-arch binary-indep clean
|
62
platform/centec-arm64/sonic_fit.its
Normal file
62
platform/centec-arm64/sonic_fit.its
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
/*
|
||||||
|
*Copyright 2018 CENTEC
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/dts-v1/;
|
||||||
|
|
||||||
|
/ {
|
||||||
|
description = "arm64 kernel, initramfs and FDT blob";
|
||||||
|
#address-cells = <1>;
|
||||||
|
|
||||||
|
images {
|
||||||
|
kernel_ctc {
|
||||||
|
description = "ARM64 Kernel";
|
||||||
|
data = /incbin/("./vmlinuz-4.19.0-9-2-arm64");
|
||||||
|
type = "kernel";
|
||||||
|
arch = "arm64";
|
||||||
|
os = "linux";
|
||||||
|
compression = "none";
|
||||||
|
load = <0x80080000>;
|
||||||
|
entry = <0x80080000>;
|
||||||
|
hash {
|
||||||
|
algo = "crc32";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
initramfs {
|
||||||
|
description = "initramfs";
|
||||||
|
data = /incbin/("./initrd.img-4.19.0-9-2-arm64");
|
||||||
|
type = "ramdisk";
|
||||||
|
arch = "arm64";
|
||||||
|
os = "linux";
|
||||||
|
compression = "gzip";
|
||||||
|
load = <0x85000000>;
|
||||||
|
entry = <0x85000000>;
|
||||||
|
hash {
|
||||||
|
algo = "crc32";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
ctc_fdt {
|
||||||
|
description = "dtb for tm_ctc5236";
|
||||||
|
data = /incbin/("./e530-ctc5236.dtb");
|
||||||
|
type = "flat_dt";
|
||||||
|
arch = "arm64";
|
||||||
|
os = "linux";
|
||||||
|
compression = "none";
|
||||||
|
load = <0x88000000>;
|
||||||
|
hash {
|
||||||
|
algo = "crc32";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
configurations {
|
||||||
|
default = "e530-ctc5236";
|
||||||
|
|
||||||
|
e530-ctc5236 {
|
||||||
|
description = "config for tm_ctc5236";
|
||||||
|
kernel = "kernel_ctc";
|
||||||
|
ramdisk = "initramfs";
|
||||||
|
fdt = "ctc_fdt";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
12
platform/centec-arm64/tsingma-bsp.mk
Normal file
12
platform/centec-arm64/tsingma-bsp.mk
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
# Centec TsingMa BSP Platform modules
|
||||||
|
|
||||||
|
|
||||||
|
TSINGMA_BSP_MODULE_VERSION = 1.0
|
||||||
|
|
||||||
|
export TSINGMA_BSP_MODULE_VERSION
|
||||||
|
|
||||||
|
TSINGMA_BSP_MODULE = tsingma-bsp_$(TSINGMA_BSP_MODULE_VERSION)_$(PLATFORM_ARCH).deb
|
||||||
|
|
||||||
|
$(TSINGMA_BSP_MODULE)_SRC_PATH = $(PLATFORM_PATH)/tsingma-bsp
|
||||||
|
$(TSINGMA_BSP_MODULE)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON)
|
||||||
|
SONIC_DPKG_DEBS += $(TSINGMA_BSP_MODULE)
|
15
platform/centec-arm64/tsingma-bsp/LICENSE
Normal file
15
platform/centec-arm64/tsingma-bsp/LICENSE
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
Copyright (C) 2019 Centec, Inc
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 2
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
1
platform/centec-arm64/tsingma-bsp/README.md
Normal file
1
platform/centec-arm64/tsingma-bsp/README.md
Normal file
@ -0,0 +1 @@
|
|||||||
|
platform drivers for Centec TsingMa soc
|
5
platform/centec-arm64/tsingma-bsp/debian/changelog
Normal file
5
platform/centec-arm64/tsingma-bsp/debian/changelog
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
tsingma-bsp (1.0) unstable; urgency=low
|
||||||
|
|
||||||
|
* Initial release
|
||||||
|
|
||||||
|
-- shil <shil@centecnetworks.com> Wed, 24 Jun 2020 14:20:58 +0800
|
1
platform/centec-arm64/tsingma-bsp/debian/compat
Normal file
1
platform/centec-arm64/tsingma-bsp/debian/compat
Normal file
@ -0,0 +1 @@
|
|||||||
|
9
|
11
platform/centec-arm64/tsingma-bsp/debian/control
Normal file
11
platform/centec-arm64/tsingma-bsp/debian/control
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
Source: tsingma-bsp
|
||||||
|
Section: main
|
||||||
|
Priority: extra
|
||||||
|
Maintainer: shil <shil@centecnetworks.com>
|
||||||
|
Build-Depends: debhelper (>= 8.0.0), bzip2
|
||||||
|
Standards-Version: 3.9.3
|
||||||
|
|
||||||
|
Package: tsingma-bsp
|
||||||
|
Architecture: arm64
|
||||||
|
Depends: linux-image-4.19.0-9-2-arm64-unsigned
|
||||||
|
Description: kernel modules for tsingma bsp
|
66
platform/centec-arm64/tsingma-bsp/debian/rules
Normal file
66
platform/centec-arm64/tsingma-bsp/debian/rules
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
#!/usr/bin/make -f
|
||||||
|
# -*- makefile -*-
|
||||||
|
# Sample debian/rules that uses debhelper.
|
||||||
|
# This file was originally written by Joey Hess and Craig Small.
|
||||||
|
# As a special exception, when this file is copied by dh-make into a
|
||||||
|
# dh-make output file, you may use that output file without restriction.
|
||||||
|
# This special exception was added by Craig Small in version 0.37 of dh-make.
|
||||||
|
|
||||||
|
include /usr/share/dpkg/pkg-info.mk
|
||||||
|
|
||||||
|
# Uncomment this to turn on verbose mode.
|
||||||
|
#export DH_VERBOSE=1
|
||||||
|
|
||||||
|
PACKAGE_PRE_NAME := tsingma-bsp
|
||||||
|
KVERSION ?= $(shell uname -r)
|
||||||
|
KERNEL_SRC := /lib/modules/$(KVERSION)
|
||||||
|
MOD_SRC_DIR:= $(shell pwd)
|
||||||
|
MODULE_DIRS:= ctc5236-mc ctc5236_switch ctcmac ctc_wdt ehci-ctc gpio-ctc i2c-ctc pinctrl-ctc pwm-ctc rtc-sd2405 sdhci-ctc5236 spi-ctc-qspi
|
||||||
|
DTS_DIR := ctc-dts
|
||||||
|
MODULE_DIR := src
|
||||||
|
UTILS_DIR := utils
|
||||||
|
SERVICE_DIR := service
|
||||||
|
CLASSES_DIR := classes
|
||||||
|
CONF_DIR := conf
|
||||||
|
|
||||||
|
%:
|
||||||
|
dh $@ --with systemd,python2,python3 --buildsystem=pybuild
|
||||||
|
|
||||||
|
clean:
|
||||||
|
dh_testdir
|
||||||
|
dh_testroot
|
||||||
|
dh_clean
|
||||||
|
|
||||||
|
build:
|
||||||
|
(for mod in $(MODULE_DIRS); do \
|
||||||
|
make modules -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/$(MODULE_DIR)/$${mod}; \
|
||||||
|
done)
|
||||||
|
make -C $(MOD_SRC_DIR)/$(MODULE_DIR)/$(DTS_DIR)
|
||||||
|
|
||||||
|
binary: binary-arch binary-indep
|
||||||
|
# Nothing to do
|
||||||
|
|
||||||
|
binary-arch:
|
||||||
|
# Nothing to do
|
||||||
|
|
||||||
|
binary-indep:
|
||||||
|
dh_testdir
|
||||||
|
dh_installdirs
|
||||||
|
|
||||||
|
# Resuming debhelper scripts
|
||||||
|
dh_testroot
|
||||||
|
dh_install
|
||||||
|
dh_installchangelogs
|
||||||
|
dh_installdocs
|
||||||
|
dh_systemd_enable
|
||||||
|
dh_installinit
|
||||||
|
dh_systemd_start
|
||||||
|
dh_link
|
||||||
|
dh_fixperms
|
||||||
|
dh_compress
|
||||||
|
dh_strip
|
||||||
|
dh_installdeb
|
||||||
|
dh_gencontrol
|
||||||
|
dh_md5sums
|
||||||
|
dh_builddeb
|
||||||
|
.PHONY: build binary binary-arch binary-indep clean
|
49
platform/centec-arm64/tsingma-bsp/debian/tsingma-bsp.init
Normal file
49
platform/centec-arm64/tsingma-bsp/debian/tsingma-bsp.init
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# This script config centec tsingma soc
|
||||||
|
|
||||||
|
### BEGIN INIT INFO
|
||||||
|
# Provides: tsingma-bsp
|
||||||
|
# Required-Start:
|
||||||
|
# Required-Stop:
|
||||||
|
# Should-Start:
|
||||||
|
# Should-Stop:
|
||||||
|
# Default-Start: S
|
||||||
|
# Default-Stop: 0 6
|
||||||
|
# Short-Description: Config Centec TsingMa SOC
|
||||||
|
### END INIT INFO
|
||||||
|
|
||||||
|
|
||||||
|
function config_tsingma_soc()
|
||||||
|
{
|
||||||
|
hwaddr=`fw_printenv ethaddr | awk -F = '{print $2}'`
|
||||||
|
if [ "$hwaddr" != "" ]; then
|
||||||
|
ifconfig eth0 hw ether $hwaddr
|
||||||
|
fi
|
||||||
|
modprobe tun
|
||||||
|
modprobe tap
|
||||||
|
}
|
||||||
|
|
||||||
|
case "$1" in
|
||||||
|
start)
|
||||||
|
echo -n "Config Centec TsingMa SOC... "
|
||||||
|
|
||||||
|
config_tsingma_soc
|
||||||
|
|
||||||
|
echo "done."
|
||||||
|
;;
|
||||||
|
|
||||||
|
stop)
|
||||||
|
echo "done."
|
||||||
|
;;
|
||||||
|
|
||||||
|
force-reload|restart)
|
||||||
|
echo "Not supported"
|
||||||
|
;;
|
||||||
|
|
||||||
|
*)
|
||||||
|
echo "Usage: /etc/init.d/tsingma-bsp {start|stop}"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
exit 0
|
17
platform/centec-arm64/tsingma-bsp/debian/tsingma-bsp.install
Normal file
17
platform/centec-arm64/tsingma-bsp/debian/tsingma-bsp.install
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
src/ctc5236-mc/ctc5236-mc.ko /lib/modules/4.19.0-9-2-arm64/kernel/extra
|
||||||
|
src/pwm-ctc/pwm-ctc.ko /lib/modules/4.19.0-9-2-arm64/kernel/extra
|
||||||
|
src/ctc5236_switch/ctc5236_switch.ko /lib/modules/4.19.0-9-2-arm64/kernel/extra
|
||||||
|
src/pinctrl-ctc/pinctrl-ctc.ko /lib/modules/4.19.0-9-2-arm64/kernel/extra
|
||||||
|
src/ctc_wdt/ctc_wdt.ko /lib/modules/4.19.0-9-2-arm64/kernel/extra
|
||||||
|
src/ctcmac/ctcmac.ko /lib/modules/4.19.0-9-2-arm64/kernel/extra
|
||||||
|
src/ctcmac/ctcmac_test.ko /lib/modules/4.19.0-9-2-arm64/kernel/extra
|
||||||
|
src/ctcmac/ctc5236_mdio.ko /lib/modules/4.19.0-9-2-arm64/kernel/extra
|
||||||
|
src/i2c-ctc/i2c-ctc.ko /lib/modules/4.19.0-9-2-arm64/kernel/extra
|
||||||
|
src/gpio-ctc/gpio-ctc.ko /lib/modules/4.19.0-9-2-arm64/kernel/extra
|
||||||
|
src/ehci-ctc/ehci-ctc.ko /lib/modules/4.19.0-9-2-arm64/kernel/extra
|
||||||
|
src/rtc-sd2405/rtc-sd2405.ko /lib/modules/4.19.0-9-2-arm64/kernel/extra
|
||||||
|
src/sdhci-ctc5236/sdhci-ctc5236.ko /lib/modules/4.19.0-9-2-arm64/kernel/extra
|
||||||
|
src/spi-ctc-qspi/spi-ctc-qspi.ko /lib/modules/4.19.0-9-2-arm64/kernel/extra
|
||||||
|
src/ctc-dts/e530-ctc5236.dtb /boot/
|
||||||
|
src/config/fw_env.config /etc/
|
||||||
|
src/config/tsingma-bsp.service /lib/systemd/system
|
@ -0,0 +1,2 @@
|
|||||||
|
systemctl enable tsingma-bsp.service
|
||||||
|
systemctl start tsingma-bsp.service
|
@ -0,0 +1,2 @@
|
|||||||
|
# MTD device name Device offset Env. size Flash sector size
|
||||||
|
/dev/mtd1 0x00000000 0x00010000 0x00001000
|
@ -0,0 +1,13 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=Centec tsingma bsp init
|
||||||
|
After=local-fs.target
|
||||||
|
Before=syncd.service
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=oneshot
|
||||||
|
ExecStart=-/etc/init.d/tsingma-bsp start
|
||||||
|
ExecStop=-/etc/init.d/tsingma-bsp stop
|
||||||
|
RemainAfterExit=yes
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
4
platform/centec-arm64/tsingma-bsp/src/ctc-dts/Makefile
Normal file
4
platform/centec-arm64/tsingma-bsp/src/ctc-dts/Makefile
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
e530-ctc5236.dtb: e530-ctc5236.dts ctc5236.dtsi ctc5236-clock.dtsi
|
||||||
|
cpp -nostdinc -I. -undef -x assembler-with-cpp e530-ctc5236.dts > tmp.dts
|
||||||
|
dtc -O dtb -o e530-ctc5236.dtb tmp.dts
|
||||||
|
rm tmp.dts -rf
|
22
platform/centec-arm64/tsingma-bsp/src/ctc-dts/arm-gic.h
Normal file
22
platform/centec-arm64/tsingma-bsp/src/ctc-dts/arm-gic.h
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
/*
|
||||||
|
* This header provides constants for the ARM GIC.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _DT_BINDINGS_INTERRUPT_CONTROLLER_ARM_GIC_H
|
||||||
|
#define _DT_BINDINGS_INTERRUPT_CONTROLLER_ARM_GIC_H
|
||||||
|
|
||||||
|
#include "irq.h"
|
||||||
|
|
||||||
|
/* interrupt specifier cell 0 */
|
||||||
|
|
||||||
|
#define GIC_SPI 0
|
||||||
|
#define GIC_PPI 1
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Interrupt specifier cell 2.
|
||||||
|
* The flags in irq.h are valid, plus those below.
|
||||||
|
*/
|
||||||
|
#define GIC_CPU_MASK_RAW(x) ((x) << 8)
|
||||||
|
#define GIC_CPU_MASK_SIMPLE(num) GIC_CPU_MASK_RAW((1 << (num)) - 1)
|
||||||
|
|
||||||
|
#endif
|
25
platform/centec-arm64/tsingma-bsp/src/ctc-dts/ctc5236-clks.h
Normal file
25
platform/centec-arm64/tsingma-bsp/src/ctc-dts/ctc5236-clks.h
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
/*
|
||||||
|
* ctc5236 clock tree IDs
|
||||||
|
*
|
||||||
|
* (C) Copyright 2004-2017 Centec Networks (suzhou) Co., LTD.
|
||||||
|
*
|
||||||
|
* Jay Cao <caoj@centecnetworks.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation version 2.
|
||||||
|
*
|
||||||
|
* This program is distributed "as is" WITHOUT ANY WARRANTY of any
|
||||||
|
* kind, whether express or implied; without even the implied warranty
|
||||||
|
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __CTC5236_CLKS_H
|
||||||
|
#define __CTC5236_CLKs_H
|
||||||
|
|
||||||
|
#define CLKID_UNUSED 0
|
||||||
|
#define CLKID_PLL_FIXED 1
|
||||||
|
#define CLKID_UART0 2
|
||||||
|
|
||||||
|
#endif /* __CTC5236_CLKS_H */
|
@ -0,0 +1,63 @@
|
|||||||
|
/*
|
||||||
|
* dts file for Centec CTC5236(TsingMa) SoC
|
||||||
|
*
|
||||||
|
* (C) Copyright 2004-2017 Centec Networks (suzhou) Co., LTD.
|
||||||
|
*
|
||||||
|
* Jay Cao <caoj@centecnetworks.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*/
|
||||||
|
|
||||||
|
osc: oscillator {
|
||||||
|
#clock-cells = <0>;
|
||||||
|
compatible = "fixed-clock";
|
||||||
|
clock-frequency = <50000000>;
|
||||||
|
};
|
||||||
|
|
||||||
|
sup_clk: sup_clk_12m {
|
||||||
|
#clock-cells = <0>;
|
||||||
|
compatible = "fixed-clock";
|
||||||
|
clock-frequency = <1200000000>;
|
||||||
|
clock-output-names = "sup_clk";
|
||||||
|
};
|
||||||
|
|
||||||
|
uart_clk: uart_clk_20m {
|
||||||
|
#clock-cells = <0>;
|
||||||
|
compatible = "fixed-clock";
|
||||||
|
clock-frequency = <20000000>;
|
||||||
|
clock-output-names = "uart_clk";
|
||||||
|
};
|
||||||
|
|
||||||
|
i2c_clk: clkm {
|
||||||
|
#clock-cells = <0>;
|
||||||
|
compatible = "fixed-clock";
|
||||||
|
clock-frequency = <50000000>;
|
||||||
|
clock-output-names = "i2c_clk";
|
||||||
|
};
|
||||||
|
wdog_clk:wdog_clk{
|
||||||
|
#clock-cells = <0>;
|
||||||
|
compatible = "fixed-clock";
|
||||||
|
clock-frequency = <1000000>;
|
||||||
|
clock-output-names = "wdog_clk";
|
||||||
|
};
|
||||||
|
timer_clk:timer_clk{
|
||||||
|
#clock-cells = <0>;
|
||||||
|
compatible = "fixed-clock";
|
||||||
|
clock-frequency = <500000000>;
|
||||||
|
clock-output-names = "timer_clk";
|
||||||
|
};
|
||||||
|
mmc_clk:mmc_clk{
|
||||||
|
#clock-cells = <0>;
|
||||||
|
compatible = "fixed-clock";
|
||||||
|
clock-frequency = <100000000>;
|
||||||
|
clock-output-names = "mmc_clk";
|
||||||
|
};
|
||||||
|
spi_clk:spi_clk{
|
||||||
|
#clock-cells = <0>;
|
||||||
|
compatible = "fixed-clock";
|
||||||
|
clock-frequency = <100000000>;
|
||||||
|
clock-output-names = "spi_clk";
|
||||||
|
};
|
376
platform/centec-arm64/tsingma-bsp/src/ctc-dts/ctc5236.dtsi
Normal file
376
platform/centec-arm64/tsingma-bsp/src/ctc-dts/ctc5236.dtsi
Normal file
@ -0,0 +1,376 @@
|
|||||||
|
/*
|
||||||
|
* dts file for Centec CTC5236(TsingMa) SoC
|
||||||
|
*
|
||||||
|
* (C) Copyright 2004-2017 Centec Networks (suzhou) Co., LTD.
|
||||||
|
*
|
||||||
|
* Jay Cao <caoj@centecnetworks.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "arm-gic.h"
|
||||||
|
#include "ctc5236-clks.h"
|
||||||
|
#include "../pinctrl-ctc/pinctrl-ctc.h"
|
||||||
|
|
||||||
|
/ {
|
||||||
|
compatible = "centec,ctc5236";
|
||||||
|
#address-cells = <2>;
|
||||||
|
#size-cells = <2>;
|
||||||
|
interrupt-parent = <&gic>;
|
||||||
|
|
||||||
|
cpus {
|
||||||
|
#address-cells = <2>;
|
||||||
|
#size-cells = <0>;
|
||||||
|
|
||||||
|
cpu-map {
|
||||||
|
cluster0 {
|
||||||
|
core0 {
|
||||||
|
cpu = <&cpu0>;
|
||||||
|
};
|
||||||
|
core1 {
|
||||||
|
cpu = <&cpu1>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
cpu0: cpu@0 {
|
||||||
|
device_type = "cpu";
|
||||||
|
compatible = "arm,cortex-a53", "arm,armv8";
|
||||||
|
reg = <0 0x000>;
|
||||||
|
enable-method = "spin-table";
|
||||||
|
cpu-release-addr = <0 0x0010fff0>;
|
||||||
|
};
|
||||||
|
|
||||||
|
cpu1: cpu@1 {
|
||||||
|
device_type = "cpu";
|
||||||
|
compatible = "arm,cortex-a53", "arm,armv8";
|
||||||
|
reg = <0 0x001>;
|
||||||
|
enable-method = "spin-table";
|
||||||
|
cpu-release-addr = <0 0x0010fff0>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
gic: interrupt-controller@31201000 {
|
||||||
|
compatible = "arm,gic-400";
|
||||||
|
#interrupt-cells = <3>;
|
||||||
|
interrupt-controller;
|
||||||
|
reg = <0x0 0x31201000 0 0x1000>,
|
||||||
|
<0x0 0x31202000 0 0x2000>,
|
||||||
|
<0x0 0x31204000 0 0x2000>,
|
||||||
|
<0x0 0x31206000 0 0x2000>;
|
||||||
|
interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>;
|
||||||
|
};
|
||||||
|
|
||||||
|
timer {
|
||||||
|
compatible = "arm,armv8-timer";
|
||||||
|
interrupt-parent = <&gic>;
|
||||||
|
interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
|
||||||
|
<GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
|
||||||
|
<GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
|
||||||
|
<GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>;
|
||||||
|
};
|
||||||
|
|
||||||
|
soc: soc {
|
||||||
|
compatible = "simple-bus";
|
||||||
|
#address-cells = <2>;
|
||||||
|
#size-cells = <2>;
|
||||||
|
ranges;
|
||||||
|
|
||||||
|
#include "ctc5236-clock.dtsi"
|
||||||
|
ocram: sram@00100000 {
|
||||||
|
compatible = "mmio-sram";
|
||||||
|
reg = <0x0 0x00100000 0x0 0x10000>;
|
||||||
|
};
|
||||||
|
|
||||||
|
memory-controller@30600000 {
|
||||||
|
compatible = "ctc,ctc5236-ddr-ctrl";
|
||||||
|
reg = <0x0 0x30600000 0x0 0x100000>;
|
||||||
|
interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>;
|
||||||
|
};
|
||||||
|
|
||||||
|
sysctrl: sysctrl@33200000 {
|
||||||
|
compatible = "ctc,ctc5236-sysctrl", "syscon";
|
||||||
|
reg = <0x0 0x33200000 0x0 0x100000>;
|
||||||
|
little-endian;
|
||||||
|
};
|
||||||
|
|
||||||
|
serial0: serial@33000000 {
|
||||||
|
compatible = "arm,pl011","arm,primecell";
|
||||||
|
reg = <0x0 0x33000000 0x0 0x1000>;
|
||||||
|
interrupts = <GIC_SPI 25 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>;
|
||||||
|
clocks = <&uart_clk>, <&sup_clk>;
|
||||||
|
clock-names = "uart_clk", "apb_pclk";
|
||||||
|
status="disabled";
|
||||||
|
};
|
||||||
|
serial1: serial@33001000 {
|
||||||
|
compatible = "arm,pl011","arm,primecell";
|
||||||
|
reg = <0x0 0x33001000 0x0 0x1000>;
|
||||||
|
interrupts = <GIC_SPI 26 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>;
|
||||||
|
clocks = <&uart_clk>, <&sup_clk>;
|
||||||
|
clock-names = "uart_clk", "apb_pclk";
|
||||||
|
status="disabled";
|
||||||
|
};
|
||||||
|
serial2: serial@33002000 {
|
||||||
|
compatible = "arm,pl011","arm,primecell";
|
||||||
|
reg = <0x0 0x33002000 0x0 0x1000>;
|
||||||
|
interrupts = <GIC_SPI 27 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>;
|
||||||
|
clocks = <&uart_clk>, <&sup_clk>;
|
||||||
|
clock-names = "uart_clk", "apb_pclk";
|
||||||
|
status="disabled";
|
||||||
|
};
|
||||||
|
mdio: mdio@33620000 {
|
||||||
|
compatible = "ctc,mdio";
|
||||||
|
reg = <0x0 0x33620000 0x0 0x10000>;
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <0>;
|
||||||
|
status = "disabled";
|
||||||
|
};
|
||||||
|
|
||||||
|
enet0: ethernet@33410000 {
|
||||||
|
compatible = "ctc,mac";
|
||||||
|
device_type = "network";
|
||||||
|
#address-cells = <2>;
|
||||||
|
#size-cells = <2>;
|
||||||
|
interrupt-parent = <&gic>;
|
||||||
|
status = "disabled";
|
||||||
|
index = <0x00>;
|
||||||
|
reg = <0x0 0x33410000 0x0 0x10000>,
|
||||||
|
<0x0 0x33400000 0x0 0x10000>;
|
||||||
|
interrupts = <GIC_SPI 40 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>,
|
||||||
|
<GIC_SPI 41 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>,
|
||||||
|
<GIC_SPI 44 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>;
|
||||||
|
ctc,sysctrl = <&sysctrl>;
|
||||||
|
};
|
||||||
|
|
||||||
|
enet1: ethernet@33420000 {
|
||||||
|
compatible = "ctc,mac";
|
||||||
|
device_type = "network";
|
||||||
|
#address-cells = <2>;
|
||||||
|
#size-cells = <2>;
|
||||||
|
interrupt-parent = <&gic>;
|
||||||
|
status = "disabled";
|
||||||
|
index = <0x01>;
|
||||||
|
reg = <0x0 0x33420000 0x0 0x10000>,
|
||||||
|
<0x0 0x33400000 0x0 0x10000>;
|
||||||
|
interrupts = <GIC_SPI 42 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>,
|
||||||
|
<GIC_SPI 43 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>,
|
||||||
|
<GIC_SPI 44 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>;
|
||||||
|
ctc,sysctrl = <&sysctrl>;
|
||||||
|
};
|
||||||
|
|
||||||
|
ehci0: usb@30500000 {
|
||||||
|
compatible = "ctc-ehci";
|
||||||
|
reg = <0x0 0x30500000 0x0 0x1000>;
|
||||||
|
interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
|
||||||
|
status = "disabled";
|
||||||
|
};
|
||||||
|
|
||||||
|
ohci0: usb@30580000 {
|
||||||
|
compatible = "generic-ohci";
|
||||||
|
reg = <0x0 0x30580000 0x0 0x1000>;
|
||||||
|
interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
|
||||||
|
status = "disabled";
|
||||||
|
};
|
||||||
|
|
||||||
|
spi: spi@33100000 {
|
||||||
|
compatible = "arm,pl022","arm,primecell";
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <0>;
|
||||||
|
reg = <0x0 0x33100000 0x0 0x100000>;
|
||||||
|
clocks = <&spi_clk>, <&sup_clk>;
|
||||||
|
clock-names = "spi_clk", "apb_pclk";
|
||||||
|
num-cs = <4>;
|
||||||
|
interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
|
||||||
|
ctc,sysctrl = <&sysctrl>;
|
||||||
|
status ="disabled";
|
||||||
|
};
|
||||||
|
|
||||||
|
qspi: qspi@10000000 {
|
||||||
|
compatible = "ctc, igdaxi001a-qspi";
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <0>;
|
||||||
|
reg = <0x0 0x10000000 0x0 0x10000>;
|
||||||
|
pclk = <500000000>;
|
||||||
|
num-cs = <2>;
|
||||||
|
idle-cycle = <2>;
|
||||||
|
post-cycle = <1>;
|
||||||
|
pre-cycle = <2>;
|
||||||
|
interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
|
||||||
|
status = "disabled";
|
||||||
|
};
|
||||||
|
switch: switch@31100000 {
|
||||||
|
compatible = "centec,dal-localbus";
|
||||||
|
reg = <0x0 0x31100000 0x0 0x1000>,
|
||||||
|
<0x0 0x33290000 0x0 0x10000>;
|
||||||
|
interrupts = <GIC_SPI 128 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>,
|
||||||
|
<GIC_SPI 129 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>,
|
||||||
|
<GIC_SPI 130 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>,
|
||||||
|
<GIC_SPI 131 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>,
|
||||||
|
<GIC_SPI 132 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>,
|
||||||
|
<GIC_SPI 133 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>,
|
||||||
|
<GIC_SPI 134 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>,
|
||||||
|
<GIC_SPI 135 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>;
|
||||||
|
status ="disabled";
|
||||||
|
};
|
||||||
|
switch1: switch1@31101000 {
|
||||||
|
compatible = "centec,switch";
|
||||||
|
reg = <0x0 0x31101000 0x0 0x1000>;
|
||||||
|
status ="disabled";
|
||||||
|
};
|
||||||
|
|
||||||
|
i2c0: i2c0@33700000{
|
||||||
|
compatible = "ctc,i2c";
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <0>;
|
||||||
|
reg = <0x0 0x33700000 0x0 0x1000>;
|
||||||
|
interrupts = <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>;
|
||||||
|
clocks = <&i2c_clk>;
|
||||||
|
status ="disabled";
|
||||||
|
};
|
||||||
|
|
||||||
|
i2c1: i2c1@33701000{
|
||||||
|
compatible = "ctc,i2c";
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <0>;
|
||||||
|
reg = <0x0 0x33701000 0x0 0x1000>;
|
||||||
|
interrupts = <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>;
|
||||||
|
clocks = <&i2c_clk>;
|
||||||
|
status ="disabled";
|
||||||
|
};
|
||||||
|
|
||||||
|
pcie: pcie@20000000 {
|
||||||
|
compatible = "centec,ctc5236-pcie";
|
||||||
|
reg = <0x0 0x20000000 0x0 0x10000000
|
||||||
|
0x0 0x30000000 0x0 0x1000>;
|
||||||
|
reg-names = "cfg", "ctrl";
|
||||||
|
#address-cells = <3>;
|
||||||
|
#size-cells = <2>;
|
||||||
|
#interrupt-cells = <1>;
|
||||||
|
device_type = "pci";
|
||||||
|
interrupt-parent = <&gic>;
|
||||||
|
interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>,
|
||||||
|
<GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>,
|
||||||
|
<GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>;
|
||||||
|
interrupt-names = "msi","aer","pme";
|
||||||
|
msi-parent = <&pcie>;
|
||||||
|
bus-range = <0 0xff>;
|
||||||
|
ranges = <0x43000000 0 0x00000000 0 0x40000000 0 0x40000000>;
|
||||||
|
num-lanes = <1>;
|
||||||
|
ctc,sysctrl = <&sysctrl>;
|
||||||
|
status ="disabled";
|
||||||
|
};
|
||||||
|
|
||||||
|
wtd0: wtd0@33500000{
|
||||||
|
compatible = "arm,sp805-wdt", "arm,primecell";
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <0>;
|
||||||
|
reg = <0x0 0x33500000 0x0 0x1000>;
|
||||||
|
clocks = <&wdog_clk>, <&sup_clk>;
|
||||||
|
clock-names = "wdog_clk", "apb_pclk";
|
||||||
|
ctc,sysctrl = <&sysctrl>;
|
||||||
|
interrupts = <GIC_SPI 38 IRQ_TYPE_EDGE_RISING>;
|
||||||
|
status="disabled";
|
||||||
|
};
|
||||||
|
wtd1: wtd1@33501000{
|
||||||
|
compatible = "arm,sp805-wdt", "arm,primecell";
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <0>;
|
||||||
|
reg = <0x0 0x33501000 0x0 0x1000>;
|
||||||
|
clocks = <&wdog_clk>, <&sup_clk>;
|
||||||
|
clock-names = "wdog_clk", "apb_pclk";
|
||||||
|
ctc,sysctrl = <&sysctrl>;
|
||||||
|
interrupts = <GIC_SPI 39 IRQ_TYPE_EDGE_RISING>;
|
||||||
|
status="disabled";
|
||||||
|
};
|
||||||
|
|
||||||
|
sdhci: sdhci@30400000 {
|
||||||
|
compatible = "centec,ctc5236-sdhci";
|
||||||
|
status = "disabled";
|
||||||
|
interrupt-parent = <&gic>;
|
||||||
|
interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>;
|
||||||
|
clocks = <&mmc_clk>;
|
||||||
|
clock-names = "mmc_clk";
|
||||||
|
ctc,sysctrl = <&sysctrl>;
|
||||||
|
reg = <0x0 0x30400000 0x0 0x1000>;
|
||||||
|
};
|
||||||
|
|
||||||
|
timer0: timer0@33600000{
|
||||||
|
compatible = "snps,dw-apb-timer";
|
||||||
|
reg = <0x0 0x33600000 0x0 0x20>;
|
||||||
|
clocks = <&timer_clk>;
|
||||||
|
clock-names = "timer";
|
||||||
|
interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>;
|
||||||
|
DivNum = <0x3c>;
|
||||||
|
status="disabled";
|
||||||
|
};
|
||||||
|
timer1: timer1@33600020{
|
||||||
|
compatible = "snps,dw-apb-timer";
|
||||||
|
reg = <0x0 0x33600020 0x0 0x20>;
|
||||||
|
clocks = <&timer_clk>;
|
||||||
|
clock-names = "timer";
|
||||||
|
interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>;
|
||||||
|
DivNum = <0x3c>;
|
||||||
|
status="disabled";
|
||||||
|
};
|
||||||
|
|
||||||
|
pwm: pwm@33200240{
|
||||||
|
compatible = "centec-pwm";
|
||||||
|
ctc,sysctrl = <&sysctrl>;
|
||||||
|
#pwm-cells = <2>;
|
||||||
|
|
||||||
|
status="disabled";
|
||||||
|
};
|
||||||
|
|
||||||
|
fan: fan-ctc5236 {
|
||||||
|
compatible = "fan-ctc5236";
|
||||||
|
pwms = <&pwm 0 1000000>,
|
||||||
|
<&pwm 1 1000000>,
|
||||||
|
<&pwm 2 1000000>,
|
||||||
|
<&pwm 3 1000000>;
|
||||||
|
pwm-names = "pwm1","pwm2","pwm3","pwm4";
|
||||||
|
};
|
||||||
|
|
||||||
|
gpio0: gpio@33610000 {
|
||||||
|
compatible = "ctc,apb-gpio";
|
||||||
|
reg = <0x0 0x33610000 0x0 0x10000>;
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <0>;
|
||||||
|
|
||||||
|
porta: gpio-port@0 {
|
||||||
|
compatible = "ctc,apb-gpio-porta";
|
||||||
|
gpio-controller;
|
||||||
|
#gpio-cells = <2>;
|
||||||
|
ctc,nr-gpios = <16>;
|
||||||
|
reg = <0>;
|
||||||
|
interrupt-controller;
|
||||||
|
#interrupt-cells = <2>;
|
||||||
|
interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>;
|
||||||
|
};
|
||||||
|
portb: gpio-port@1 {
|
||||||
|
compatible = "ctc,apb-gpio-portb";
|
||||||
|
gpio-controller;
|
||||||
|
#gpio-cells = <2>;
|
||||||
|
ctc,nr-gpios = <18>;
|
||||||
|
reg = <1>;
|
||||||
|
interrupt-controller;
|
||||||
|
#interrupt-cells = <2>;
|
||||||
|
interrupts = <GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
pinctrl: pinctrl {
|
||||||
|
compatible = "ctc,ctc5236-pinctrl";
|
||||||
|
#address-cells = <0x2>;
|
||||||
|
#size-cells = <0x2>;
|
||||||
|
ctc,pinctrl-bank0 = <16>;
|
||||||
|
ctc,pinctrl-bank1 = <8>;
|
||||||
|
ctc,sysctrl = <&sysctrl>;
|
||||||
|
status = "okay";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
212
platform/centec-arm64/tsingma-bsp/src/ctc-dts/e530-ctc5236.dts
Normal file
212
platform/centec-arm64/tsingma-bsp/src/ctc-dts/e530-ctc5236.dts
Normal file
@ -0,0 +1,212 @@
|
|||||||
|
/*
|
||||||
|
* dts file for Centec CTC5236(TsingMa) SoC E530-24X2C Board
|
||||||
|
*
|
||||||
|
* (C) Copyright 2004-2018 Centec Networks (suzhou) Co., LTD.
|
||||||
|
*
|
||||||
|
* liuht <liuht@centecnetworks.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/dts-v1/;
|
||||||
|
#include "ctc5236.dtsi"
|
||||||
|
|
||||||
|
|
||||||
|
/ {
|
||||||
|
model = " CTC5236(TsingMa) E530 Board";
|
||||||
|
compatible = "ctc5236,e530-ctc5236";
|
||||||
|
|
||||||
|
memory {
|
||||||
|
device_type = "memory";
|
||||||
|
reg = <0 0x80000000 0x0 0x40000000>;
|
||||||
|
};
|
||||||
|
|
||||||
|
chosen {
|
||||||
|
stdout-path = "serial0:115200n8";
|
||||||
|
};
|
||||||
|
|
||||||
|
aliases {
|
||||||
|
serial0 = &serial0;
|
||||||
|
serial1 = &serial1;
|
||||||
|
ethernet0 = &enet0;
|
||||||
|
ethernet1 = &enet1;
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
&serial0 {
|
||||||
|
status = "okay";
|
||||||
|
};
|
||||||
|
|
||||||
|
&serial1 {
|
||||||
|
status = "okay";
|
||||||
|
};
|
||||||
|
|
||||||
|
&mdio {
|
||||||
|
status = "okay";
|
||||||
|
phy0: ethernet-phy@0 {
|
||||||
|
index = <0x00>;
|
||||||
|
reg = <0x00>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
&enet0 {
|
||||||
|
status = "okay";
|
||||||
|
phy-handle = <&phy0>;
|
||||||
|
auto-nego-mode= "sgmii-mac";
|
||||||
|
};
|
||||||
|
|
||||||
|
&qspi {
|
||||||
|
status = "okay";
|
||||||
|
|
||||||
|
qspiflash: mx25u3235f@0 {
|
||||||
|
compatible = "jedec,spi-nor";
|
||||||
|
reg = <0x0>;
|
||||||
|
spi-cpha;
|
||||||
|
spi-cpol;
|
||||||
|
spi-max-frequency = <25000000>;
|
||||||
|
|
||||||
|
partitions {
|
||||||
|
compatible = "fixed-partitions";
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <1>;
|
||||||
|
|
||||||
|
partition@0 {
|
||||||
|
label = "u-boot";
|
||||||
|
reg = <0x0 0x300000>;
|
||||||
|
};
|
||||||
|
partition@300000 {
|
||||||
|
label = "uboot-env";
|
||||||
|
reg = <0x300000 0x10000>;
|
||||||
|
};
|
||||||
|
partition@310000 {
|
||||||
|
label = "system";
|
||||||
|
reg = <0x310000 0x10000>;
|
||||||
|
};
|
||||||
|
partition@320000 {
|
||||||
|
label = "hw-info";
|
||||||
|
reg = <0x320000 0x10000>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
&spi {
|
||||||
|
status = "disabled";
|
||||||
|
pinctrl-names = "default";
|
||||||
|
pinctrl-0 = <&spi_pin>;
|
||||||
|
|
||||||
|
clock0: ad9559@1 {
|
||||||
|
compatible = "analog,ad9559";
|
||||||
|
reg = <1>;
|
||||||
|
spi-max-frequency = <25000000>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
&switch {
|
||||||
|
status = "okay";
|
||||||
|
};
|
||||||
|
|
||||||
|
&switch1 {
|
||||||
|
status = "okay";
|
||||||
|
};
|
||||||
|
|
||||||
|
&i2c0{
|
||||||
|
status = "okay";
|
||||||
|
clock-frequency = <400000>;
|
||||||
|
|
||||||
|
eeprom_0:eeprom_0@57 {
|
||||||
|
compatible = "atmel,24c64";
|
||||||
|
reg = <0x57>;
|
||||||
|
pagesize = <32>;
|
||||||
|
};
|
||||||
|
|
||||||
|
rtc_0:rtc_0@32{
|
||||||
|
compatible = "sd2405";
|
||||||
|
reg = <0x32>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
&i2c1{
|
||||||
|
status = "okay";
|
||||||
|
clock-frequency = <400000>;
|
||||||
|
};
|
||||||
|
|
||||||
|
&ehci0 {
|
||||||
|
status = "okay";
|
||||||
|
};
|
||||||
|
|
||||||
|
&ohci0 {
|
||||||
|
status = "okay";
|
||||||
|
};
|
||||||
|
|
||||||
|
&wtd0{
|
||||||
|
status = "okay";
|
||||||
|
};
|
||||||
|
|
||||||
|
&wtd1{
|
||||||
|
status = "disabled";
|
||||||
|
};
|
||||||
|
|
||||||
|
&sdhci {
|
||||||
|
bus-width = <8>;
|
||||||
|
max-frequency = <100000000>;
|
||||||
|
non-removable;
|
||||||
|
no-sd;
|
||||||
|
no-sdio;
|
||||||
|
voltage-ranges = <3300 3300>;
|
||||||
|
status = "okay";
|
||||||
|
};
|
||||||
|
|
||||||
|
&timer0 {
|
||||||
|
status = "okay";
|
||||||
|
};
|
||||||
|
|
||||||
|
&soc {
|
||||||
|
ctc-irq@0 {
|
||||||
|
compatible = "centec,ctc-irq";
|
||||||
|
device_type = "ctc-irq";
|
||||||
|
interrupt-parent=<&porta>;
|
||||||
|
interrupts = < 0 IRQ_TYPE_LEVEL_LOW>,
|
||||||
|
< 1 IRQ_TYPE_LEVEL_LOW>,
|
||||||
|
<15 IRQ_TYPE_LEVEL_LOW>,
|
||||||
|
< 6 IRQ_TYPE_LEVEL_HIGH>,
|
||||||
|
< 7 IRQ_TYPE_LEVEL_HIGH>;
|
||||||
|
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
&pwm {
|
||||||
|
pinctrl-names = "default";
|
||||||
|
pinctrl-0 = <&pwm0_pin>;
|
||||||
|
status = "okay";
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
&pinctrl {
|
||||||
|
spi {
|
||||||
|
spi_pin: spi_pin {
|
||||||
|
status = "disabled";
|
||||||
|
ctc,pins = <0 0 PIN_FUNC_SPI>,
|
||||||
|
<0 2 PIN_FUNC_SPI>,
|
||||||
|
<0 3 PIN_FUNC_SPI>,
|
||||||
|
<0 5 PIN_FUNC_SPI>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
pwm0 {
|
||||||
|
pwm0_pin: pwm0_pin {
|
||||||
|
ctc,pins = <0 8 PIN_FUNC_PWM>,
|
||||||
|
<0 9 PIN_FUNC_PWM>,
|
||||||
|
<0 10 PIN_FUNC_PWM>,
|
||||||
|
<0 11 PIN_FUNC_PWM>,
|
||||||
|
<0 12 PIN_FUNC_PWM>,
|
||||||
|
<0 13 PIN_FUNC_PWM>,
|
||||||
|
<0 14 PIN_FUNC_PWM>,
|
||||||
|
<0 15 PIN_FUNC_PWM>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
19
platform/centec-arm64/tsingma-bsp/src/ctc-dts/irq.h
Normal file
19
platform/centec-arm64/tsingma-bsp/src/ctc-dts/irq.h
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
/*
|
||||||
|
* This header provides constants for most IRQ bindings.
|
||||||
|
*
|
||||||
|
* Most IRQ bindings include a flags cell as part of the IRQ specifier.
|
||||||
|
* In most cases, the format of the flags cell uses the standard values
|
||||||
|
* defined in this header.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _DT_BINDINGS_INTERRUPT_CONTROLLER_IRQ_H
|
||||||
|
#define _DT_BINDINGS_INTERRUPT_CONTROLLER_IRQ_H
|
||||||
|
|
||||||
|
#define IRQ_TYPE_NONE 0
|
||||||
|
#define IRQ_TYPE_EDGE_RISING 1
|
||||||
|
#define IRQ_TYPE_EDGE_FALLING 2
|
||||||
|
#define IRQ_TYPE_EDGE_BOTH (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)
|
||||||
|
#define IRQ_TYPE_LEVEL_HIGH 4
|
||||||
|
#define IRQ_TYPE_LEVEL_LOW 8
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1 @@
|
|||||||
|
obj-m = ctc5236-mc.o
|
279
platform/centec-arm64/tsingma-bsp/src/ctc5236-mc/ctc5236-mc.c
Normal file
279
platform/centec-arm64/tsingma-bsp/src/ctc5236-mc/ctc5236-mc.c
Normal file
@ -0,0 +1,279 @@
|
|||||||
|
/* Centec TsingMa Memory Controller Driver
|
||||||
|
*
|
||||||
|
* Author: lius <lius@centecnetworks.com>
|
||||||
|
*
|
||||||
|
* Copyright 2002-2019, Centec Networks (Suzhou) Co., Ltd.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#include <linux/types.h>
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/ctype.h>
|
||||||
|
#include <linux/interrupt.h>
|
||||||
|
#include <linux/platform_device.h>
|
||||||
|
#include <linux/of_platform.h>
|
||||||
|
#include <linux/uaccess.h>
|
||||||
|
#include <linux/init.h>
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/slab.h>
|
||||||
|
#include <linux/io.h>
|
||||||
|
|
||||||
|
struct ctc5236_mc {
|
||||||
|
struct device *dev;
|
||||||
|
void __iomem *base;
|
||||||
|
int irq;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/* DDR interrupt enable register */
|
||||||
|
#define DDR_ERR_INT_EN 0xF0
|
||||||
|
|
||||||
|
/* DDR interrupt status register */
|
||||||
|
#define DDR_ERR_INT_STATUS 0xF4
|
||||||
|
|
||||||
|
/* over top-bound info register*/
|
||||||
|
#define DDR_ERR_INT_OVER_TOPBOUND_L 0xF8
|
||||||
|
#define DDR_ERR_INT_OVER_TOPBOUND_H 0xFC
|
||||||
|
|
||||||
|
#define DDR_PORT0_ERR_INT_STATUS 0x1
|
||||||
|
#define DDR_PORT1_ERR_INT_STATUS 0x2
|
||||||
|
#define DDR_PORT2_ERR_INT_STATUS 0x3
|
||||||
|
#define DDR_PORT3_ERR_INT_STATUS 0x4
|
||||||
|
#define DDR_ERR_ECC_INT_STATUS 0x10000
|
||||||
|
#define DDR_ERR_WR_PORT_REC_UNDERFLOW 0x20000
|
||||||
|
#define DDR_ERR_WR_PORT_REC_OVERFLOW 0x40000
|
||||||
|
#define DDR_ERR_RD_PORT_REC_UNDERFLOW 0x80000
|
||||||
|
#define DDR_ERR_RD_PORT_REC_OVERFLOW 0x100000
|
||||||
|
|
||||||
|
#define DDR_PORT0_STATUS 0xB0
|
||||||
|
#define DDR_PORT1_STATUS 0xB4
|
||||||
|
#define DDR_PORT2_STATUS 0xB8
|
||||||
|
#define DDR_PORT3_STATUS 0xBC
|
||||||
|
|
||||||
|
#define DDR_ERR_OVER_TOPBOUND 0x20000
|
||||||
|
#define DDR_ERR_WCMDQ_OVER 0x40000
|
||||||
|
#define DDR_ERR_WCMDQ_UNDER 0x80000
|
||||||
|
#define DDR_ERR_WDATAQ_OVER 0x100000
|
||||||
|
#define DDR_ERR_WDATAQ_UNDER 0x200000
|
||||||
|
#define DDR_ERR_WESPQ_OVER 0x400000
|
||||||
|
#define DDR_ERR_WESPQ_UNDER 0x800000
|
||||||
|
#define DDR_ERR_WINFOQ_OVER 0x1000000
|
||||||
|
#define DDR_ERR_WINFOQ_UNDER 0x2000000
|
||||||
|
#define DDR_ERR_RCMDQ_OVER 0x4000000
|
||||||
|
#define DDR_ERR_RCMDQ_UNDER 0x8000000
|
||||||
|
#define DDR_ERR_RDATAQ_OVER 0x10000000
|
||||||
|
#define DDR_ERR_RDATAQ_UNDER 0x20000000
|
||||||
|
#define DDR_ERR_RESPQ_OVER 0x40000000
|
||||||
|
#define DDR_ERR_RESPQ_UNDER 0x80000000
|
||||||
|
|
||||||
|
#define DDR_PORT0_BASE 0xB0
|
||||||
|
#define DDR_PORT1_BASE 0xB4
|
||||||
|
#define DDR_PORT2_BASE 0xB8
|
||||||
|
#define DDR_PORT3_BASE 0xBc
|
||||||
|
|
||||||
|
#define DDR_PORT0 0
|
||||||
|
#define DDR_PORT1 1
|
||||||
|
#define DDR_PORT2 2
|
||||||
|
#define DDR_PORT3 3
|
||||||
|
|
||||||
|
static int port_err_status(int status, int port, void *dev_id)
|
||||||
|
{
|
||||||
|
int id = port;
|
||||||
|
unsigned long temp = 0;
|
||||||
|
unsigned int addr_h = 0;
|
||||||
|
unsigned int addr_l = 0;
|
||||||
|
struct ctc5236_mc *mci = dev_id;
|
||||||
|
|
||||||
|
/*the reason of port interrupt */
|
||||||
|
if (status & DDR_ERR_OVER_TOPBOUND) {
|
||||||
|
/* get low 32-bit address */
|
||||||
|
addr_l = readl(mci->base + DDR_ERR_INT_OVER_TOPBOUND_L);
|
||||||
|
/* get high 2-bit address */
|
||||||
|
addr_h = readl(mci->base + DDR_ERR_INT_OVER_TOPBOUND_H);
|
||||||
|
temp = (addr_l | (((unsigned long)((addr_h >> 12) & 0x3)) << 32)
|
||||||
|
);
|
||||||
|
|
||||||
|
pr_emerg("ERROR:port%d is out of top-bound range!\n"
|
||||||
|
"The error address is 0x%p\n",
|
||||||
|
id, (void *)temp);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status & DDR_ERR_WCMDQ_OVER)
|
||||||
|
pr_err("ERROR:port%d write command queue is overflow!\n", id);
|
||||||
|
|
||||||
|
if (status & DDR_ERR_WCMDQ_UNDER)
|
||||||
|
pr_err("ERROR:port%d write command queue is underflow!\n", id);
|
||||||
|
|
||||||
|
if (status & DDR_ERR_WDATAQ_OVER)
|
||||||
|
pr_err("ERROR:port%d write data queue is overflow!\n", id);
|
||||||
|
|
||||||
|
if (status & DDR_ERR_WDATAQ_UNDER)
|
||||||
|
pr_err("ERROR:port%d write data queue is underflow!\n", id);
|
||||||
|
|
||||||
|
if (status & DDR_ERR_WESPQ_OVER)
|
||||||
|
pr_err("ERROR:port%d write response queue is overflow!\n", id);
|
||||||
|
|
||||||
|
if (status & DDR_ERR_WESPQ_UNDER)
|
||||||
|
pr_err("ERROR:port%d write response queue is underflow!\n", id);
|
||||||
|
|
||||||
|
if (status & DDR_ERR_WINFOQ_OVER)
|
||||||
|
pr_err("ERROR:port%d write info queue is overflow!\n", id);
|
||||||
|
|
||||||
|
if (status & DDR_ERR_WINFOQ_UNDER)
|
||||||
|
pr_err("ERROR:port%d write info queue is underflow!\n", id);
|
||||||
|
|
||||||
|
if (status & DDR_ERR_RCMDQ_OVER)
|
||||||
|
pr_err("ERROR:port%d read command queue is overflow!\n", id);
|
||||||
|
|
||||||
|
if (status & DDR_ERR_RCMDQ_UNDER)
|
||||||
|
pr_err("ERROR:port%d read command queue is underflow!\n", id);
|
||||||
|
|
||||||
|
if (status & DDR_ERR_RDATAQ_OVER)
|
||||||
|
pr_err("ERROR:port%d read data queue is overflow!\n", id);
|
||||||
|
|
||||||
|
if (status & DDR_ERR_RDATAQ_UNDER)
|
||||||
|
pr_err("ERROR:port%d read data queue is underflow!\n", id);
|
||||||
|
|
||||||
|
if (status & DDR_ERR_RESPQ_OVER)
|
||||||
|
pr_err("ERROR:port%d read response queue is overflow!\n", id);
|
||||||
|
|
||||||
|
if (status & DDR_ERR_RESPQ_UNDER)
|
||||||
|
pr_err("ERROR:port%d read response queue is underflow!\n", id);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static irqreturn_t ctc_mc_err_handler(int irq, void *dev_id)
|
||||||
|
{
|
||||||
|
struct ctc5236_mc *mci = dev_id;
|
||||||
|
unsigned int status;
|
||||||
|
unsigned int ret = 0;
|
||||||
|
|
||||||
|
/* get interrupt status */
|
||||||
|
status = readl(mci->base + DDR_ERR_INT_STATUS);
|
||||||
|
|
||||||
|
if (status & DDR_PORT0_ERR_INT_STATUS) {
|
||||||
|
ret = readl(mci->base + DDR_PORT0_BASE);
|
||||||
|
port_err_status(ret, DDR_PORT0, mci);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status & DDR_PORT1_ERR_INT_STATUS) {
|
||||||
|
ret = readl(mci->base + DDR_PORT1_BASE);
|
||||||
|
port_err_status(ret, DDR_PORT1, mci);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status & DDR_PORT2_ERR_INT_STATUS) {
|
||||||
|
ret = readl(mci->base + DDR_PORT2_BASE);
|
||||||
|
port_err_status(ret, DDR_PORT2, mci);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status & DDR_PORT3_ERR_INT_STATUS) {
|
||||||
|
ret = readl(mci->base + DDR_PORT3_BASE);
|
||||||
|
port_err_status(ret, DDR_PORT3, mci);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status & DDR_ERR_ECC_INT_STATUS)
|
||||||
|
pr_err("ERROR:The ecc more than 1-bit error !\n");
|
||||||
|
|
||||||
|
if (status & DDR_ERR_WR_PORT_REC_UNDERFLOW)
|
||||||
|
pr_err("ERROR:MPARB wr_port_rec FIFO is underflow!\n");
|
||||||
|
|
||||||
|
if (status & DDR_ERR_WR_PORT_REC_OVERFLOW)
|
||||||
|
pr_err("ERROR:MPARB wr_port_rec FIFO is overflow!\n");
|
||||||
|
|
||||||
|
if (status & DDR_ERR_RD_PORT_REC_UNDERFLOW)
|
||||||
|
pr_err("ERROR:MPARB rd_port_rec FIFO is underflow!\n");
|
||||||
|
|
||||||
|
if (status & DDR_ERR_RD_PORT_REC_OVERFLOW)
|
||||||
|
pr_err("ERROR:MPARB rd_port_rec FIFO is underflow!\n");
|
||||||
|
|
||||||
|
/* disable DDR interrupt */
|
||||||
|
writel(0x0, mci->base + DDR_ERR_INT_EN);
|
||||||
|
|
||||||
|
return IRQ_HANDLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct of_device_id ctc5236_ddr_ctrl_of_match[] = {
|
||||||
|
{
|
||||||
|
.compatible = "ctc,ctc5236-ddr-ctrl",
|
||||||
|
},
|
||||||
|
{},
|
||||||
|
};
|
||||||
|
|
||||||
|
MODULE_DEVICE_TABLE(of, ctc5236_ddr_ctrl_of_match);
|
||||||
|
|
||||||
|
static int ctc5236_mc_probe(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
const struct of_device_id *id;
|
||||||
|
struct ctc5236_mc *mci;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
id = of_match_device(ctc5236_ddr_ctrl_of_match, &pdev->dev);
|
||||||
|
if (!id)
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
|
mci = kzalloc(sizeof(*mci), GFP_KERNEL);
|
||||||
|
if (!mci)
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
|
mci->base = devm_ioremap_resource(&pdev->dev, pdev->resource);
|
||||||
|
if (IS_ERR(mci->base))
|
||||||
|
return PTR_ERR(mci->base);
|
||||||
|
|
||||||
|
mci->irq = platform_get_irq(pdev, 0);
|
||||||
|
ret =
|
||||||
|
devm_request_irq(&pdev->dev, mci->irq, ctc_mc_err_handler, 0,
|
||||||
|
dev_name(&pdev->dev), mci);
|
||||||
|
if (ret < 0) {
|
||||||
|
dev_err(&pdev->dev, "Unable to request irq %d\n", mci->irq);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
err:
|
||||||
|
dev_err(&pdev->dev, "Probe Failed!\n");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ctc5236_mc_remove(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
struct ctc5236_mc *mci = platform_get_drvdata(pdev);
|
||||||
|
|
||||||
|
devm_iounmap(&pdev->dev, mci->base);
|
||||||
|
devm_free_irq(&pdev->dev, mci->irq, mci);
|
||||||
|
|
||||||
|
kfree(mci);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct platform_driver ctc5236_mc_driver = {
|
||||||
|
.probe = ctc5236_mc_probe,
|
||||||
|
.remove = ctc5236_mc_remove,
|
||||||
|
.driver = {
|
||||||
|
.name = "ctc5236_mc",
|
||||||
|
.of_match_table = ctc5236_ddr_ctrl_of_match,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static int __init ctc5236_mc_init(void)
|
||||||
|
{
|
||||||
|
return platform_driver_register(&ctc5236_mc_driver);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __exit ctc5236_mc_exit(void)
|
||||||
|
{
|
||||||
|
platform_driver_unregister(&ctc5236_mc_driver);
|
||||||
|
}
|
||||||
|
|
||||||
|
module_init(ctc5236_mc_init);
|
||||||
|
module_exit(ctc5236_mc_exit);
|
||||||
|
|
||||||
|
MODULE_LICENSE("GPL");
|
||||||
|
MODULE_AUTHOR("Centec Network");
|
||||||
|
MODULE_DESCRIPTION("Centec TsingMa memory controller driver");
|
@ -0,0 +1 @@
|
|||||||
|
obj-m = ctc5236_switch.o
|
@ -0,0 +1,324 @@
|
|||||||
|
/* (C) Copyright 2004-2017 Centec Networks (suzhou) Co., LTD.
|
||||||
|
* Wangyb <wangyb@centecnetworks.com>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-2.0+
|
||||||
|
*/
|
||||||
|
#include <linux/io.h>
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/of.h>
|
||||||
|
#include <linux/platform_device.h>
|
||||||
|
#include <linux/regmap.h>
|
||||||
|
#include <linux/delay.h>
|
||||||
|
#include <../include/ctc5236_switch.h>
|
||||||
|
|
||||||
|
struct ctc_access_t *access;
|
||||||
|
|
||||||
|
#define SWITCH_DTS_OFFSET 0x1000
|
||||||
|
|
||||||
|
int ctc5236_switch_read(u32 offset, u32 len, u32 *p_value)
|
||||||
|
{
|
||||||
|
union ctc_switch_cmd_status_u_t cmd_status_u;
|
||||||
|
u32 timeout = 0x6400;
|
||||||
|
u32 cmd_len = 0;
|
||||||
|
u8 index = 0;
|
||||||
|
|
||||||
|
if (!p_value) {
|
||||||
|
pr_err("switch read:value buffer is NULL!\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* switch only have 16 databuf, len must not exceed 16 */
|
||||||
|
if (len > 16 || len == 0) {
|
||||||
|
pr_err("switch read: length error! len = %d\n", len);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
/* cmdDataLen must be power of 2 */
|
||||||
|
if ((len & (len - 1)) == 0) {
|
||||||
|
cmd_len = len;
|
||||||
|
} else {
|
||||||
|
cmd_len = len;
|
||||||
|
do {
|
||||||
|
cmd_len++;
|
||||||
|
} while ((cmd_len <= 16) && (cmd_len & (cmd_len - 1)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 1. write CmdStatusReg */
|
||||||
|
memset(&cmd_status_u, 0, sizeof(union ctc_switch_cmd_status_u_t));
|
||||||
|
cmd_status_u.cmd_status.cmdReadType = 1;
|
||||||
|
/* normal operate only support 1 entry */
|
||||||
|
cmd_status_u.cmd_status.cmdEntryWords = (len == 16) ? 0 : len;
|
||||||
|
cmd_status_u.cmd_status.cmdDataLen = len;
|
||||||
|
writel(cmd_status_u.val, &access->cmd_status);
|
||||||
|
/* 2. write AddrReg */
|
||||||
|
writel(offset, &access->addr);
|
||||||
|
/* 3. polling status and check */
|
||||||
|
cmd_status_u.val = readl(&access->cmd_status);
|
||||||
|
while (!(cmd_status_u.cmd_status.reqProcDone) && (--timeout))
|
||||||
|
cmd_status_u.val = readl(&access->cmd_status);
|
||||||
|
/* 4. check cmd done */
|
||||||
|
if (!(cmd_status_u.cmd_status.reqProcDone)) {
|
||||||
|
pr_err("switch read error! cmd_status = %x\n",
|
||||||
|
cmd_status_u.val);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
/* 5. check pcie read status */
|
||||||
|
if (cmd_status_u.cmd_status.reqProcError != 0) {
|
||||||
|
pr_err("pci read error! cmd_status = %x, offset = 0x%x\n",
|
||||||
|
cmd_status_u.val, offset);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 6. read data from buffer */
|
||||||
|
for (index = 0; index < len; index++)
|
||||||
|
p_value[index] = readl(&access->data[index]);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ctc5236_switch_write(u32 offset, u32 len, u32 *p_value)
|
||||||
|
{
|
||||||
|
union ctc_switch_cmd_status_u_t cmd_status_u;
|
||||||
|
u32 timeout = 0x6400; /* need to be confirmed */
|
||||||
|
u32 cmd_len = 0;
|
||||||
|
u8 index = 0;
|
||||||
|
|
||||||
|
if (!p_value) {
|
||||||
|
pr_err("switch write:value buffer is NULL!\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* switch only have 16 databuf, len must not exceed 16 */
|
||||||
|
if (len > 16 || len == 0) {
|
||||||
|
pr_err("switch write length error! len = %d\n", len);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* cmdDataLen must be power of 2 */
|
||||||
|
if ((len & (len - 1)) == 0) {
|
||||||
|
cmd_len = len;
|
||||||
|
} else {
|
||||||
|
cmd_len = len;
|
||||||
|
do {
|
||||||
|
cmd_len++;
|
||||||
|
} while ((cmd_len <= 16) && (cmd_len & (cmd_len - 1)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 1. write CmdStatusReg */
|
||||||
|
memset(&cmd_status_u, 0, sizeof(struct ctc_switch_cmd_status_t));
|
||||||
|
cmd_status_u.cmd_status.cmdReadType = 0;
|
||||||
|
cmd_status_u.cmd_status.cmdEntryWords = (len == 16) ? 0 : len;
|
||||||
|
/* Notice: for 1 entry op, cmdDatalen eq cmdEntryWords,
|
||||||
|
* but for mutil entry, len = cmd_len
|
||||||
|
*/
|
||||||
|
cmd_status_u.cmd_status.cmdDataLen = len;
|
||||||
|
writel(cmd_status_u.val, &access->cmd_status);
|
||||||
|
/* 2. write AddrReg */
|
||||||
|
writel(offset, &access->addr);
|
||||||
|
/* 3. write data into databuffer */
|
||||||
|
for (index = 0; index < len; index++)
|
||||||
|
writel(p_value[index], &access->data[index]);
|
||||||
|
|
||||||
|
/* 4. polling status and check */
|
||||||
|
cmd_status_u.val = readl(&access->cmd_status);
|
||||||
|
while (!(cmd_status_u.cmd_status.reqProcDone) && (--timeout))
|
||||||
|
cmd_status_u.val = readl(&access->cmd_status);
|
||||||
|
|
||||||
|
/* 5. check cmd done */
|
||||||
|
if (!(cmd_status_u.cmd_status.reqProcDone)) {
|
||||||
|
pr_err("switch write error! cmd_status = %x\n",
|
||||||
|
cmd_status_u.val);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 6. check switch read status */
|
||||||
|
if (cmd_status_u.cmd_status.reqProcError != 0) {
|
||||||
|
pr_err("switch write error! cmd_status = %x, offset=0x%x\n",
|
||||||
|
cmd_status_u.val, offset);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
_sys_tsingma_peri_get_temp_with_code(u8 lchip, u32 temp_code, u32 *p_temp_val)
|
||||||
|
{
|
||||||
|
u16 temp_mapping_tbl[SYS_TSINGMA_TEMP_TABLE_NUM + 1] = {
|
||||||
|
804, 801, 798, 795, 792, 790, 787, 784, 781, 778,
|
||||||
|
775, 772, 769, 766, 763, 761, 758, 755, 752, 749,
|
||||||
|
746, 743, 740, 737, 734, 731, 728, 725, 722, 719,
|
||||||
|
717, 714, 711, 708, 705, 702, 699, 696, 693, 690,
|
||||||
|
687, 684, 681, 678, 675, 672, 669, 666, 663, 660,
|
||||||
|
658, 655, 652, 649, 646, 643, 640, 637, 634, 631,
|
||||||
|
628, 625, 622, 619, 616, 613, 610, 607, 604, 601,
|
||||||
|
599, 596, 593, 590, 587, 584, 581, 578, 575, 572,
|
||||||
|
569, 566, 563, 560, 557, 554, 551, 548, 545, 542,
|
||||||
|
540, 537, 534, 531, 528, 525, 522, 519, 516, 513,
|
||||||
|
510, 507, 504, 501, 498, 495, 492, 489, 486, 483,
|
||||||
|
481, 478, 475, 472, 469, 466, 463, 460, 457, 454,
|
||||||
|
451, 448, 445, 442, 439, 436, 433, 430, 427, 424,
|
||||||
|
421, 418, 415, 412, 409, 406, 403, 400, 397, 394,
|
||||||
|
391, 388, 385, 382, 379, 376, 373, 370, 367, 364,
|
||||||
|
361, 358, 355, 352, 349, 346, 343, 340, 337, 334,
|
||||||
|
331, 328, 325, 322, 319, 316, 0
|
||||||
|
};
|
||||||
|
u8 index = 0;
|
||||||
|
|
||||||
|
for (index = 0; index < SYS_TSINGMA_TEMP_TABLE_NUM; index++) {
|
||||||
|
if ((temp_code <= temp_mapping_tbl[index])
|
||||||
|
&& (temp_code > temp_mapping_tbl[index + 1])) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (index < 39)
|
||||||
|
*p_temp_val = 40 - index + (1 << 31);
|
||||||
|
else
|
||||||
|
*p_temp_val = index - 40;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int get_switch_temperature(void)
|
||||||
|
{
|
||||||
|
int temperature;
|
||||||
|
u32 value, offset, p_value = 0;
|
||||||
|
u32 timeout = SYS_TSINGMA_SENSOR_TIMEOUT;
|
||||||
|
|
||||||
|
value = 0x310c7;
|
||||||
|
offset = 0xf * 4;
|
||||||
|
ctc5236_switch_write(OMCMEM_BASE + offset, 1, &value);
|
||||||
|
|
||||||
|
/*config RTHMC_RST=1 */
|
||||||
|
/*mask_write tbl-reg OmcMem 0x10 offset 0x0 0x00000010 0x00000010 */
|
||||||
|
offset = 0x10 * 4;
|
||||||
|
ctc5236_switch_read(OMCMEM_BASE + offset, 1, &value);
|
||||||
|
value |= BIT(4);
|
||||||
|
ctc5236_switch_write(OMCMEM_BASE + offset, 1, &value);
|
||||||
|
|
||||||
|
/*wait RTHMC_RST=1 */
|
||||||
|
/*read tbl-reg OmcMem 0x10 offset 0x0 */
|
||||||
|
timeout = SYS_TSINGMA_SENSOR_TIMEOUT;
|
||||||
|
offset = 0x10 * 4;
|
||||||
|
while (timeout) {
|
||||||
|
timeout--;
|
||||||
|
ctc5236_switch_read(OMCMEM_BASE + offset, 1, &value);
|
||||||
|
if ((BIT(4) & value) == 0)
|
||||||
|
break;
|
||||||
|
msleep(1);
|
||||||
|
}
|
||||||
|
if (timeout == 0)
|
||||||
|
return 0xffff;
|
||||||
|
|
||||||
|
/*config ENBIAS=1£¬ENVR=1£¬ENAD=1 */
|
||||||
|
/*mask_write tbl-reg OmcMem 0x11 offset 0x0 0x02000007 0x03000007 */
|
||||||
|
offset = 0x11 * 4;
|
||||||
|
ctc5236_switch_read(OMCMEM_BASE + offset, 1, &value);
|
||||||
|
value |= BIT(0) | BIT(1) | BIT(2) | BIT(25);
|
||||||
|
value &= ~BIT(24);
|
||||||
|
ctc5236_switch_write(OMCMEM_BASE + offset, 1, &value);
|
||||||
|
|
||||||
|
msleep(1);
|
||||||
|
|
||||||
|
/*set RTHM_MODE=1,RSAMPLE_DONE_INTEN=1,RDUMMY_THMRD=1,RV_SAMPLE_EN=1 */
|
||||||
|
/*mask_write tbl-reg OmcMem 0x10 offset 0x0 0x00000203 0x00000003 */
|
||||||
|
/*mask_write tbl-reg OmcMem 0x8 offset 0x0 0x00000004 0x00000004 */
|
||||||
|
/*mask_write tbl-reg OmcMem 0x12 offset 0x0 0x00000001 0x00000001 */
|
||||||
|
offset = 0x10 * 4;
|
||||||
|
ctc5236_switch_read(OMCMEM_BASE + offset, 1, &value);
|
||||||
|
value |= BIT(0) | BIT(1) | BIT(9);
|
||||||
|
ctc5236_switch_write(OMCMEM_BASE + offset, 1, &value);
|
||||||
|
offset = 0x8 * 4;
|
||||||
|
ctc5236_switch_read(OMCMEM_BASE + offset, 1, &value);
|
||||||
|
value |= BIT(2);
|
||||||
|
ctc5236_switch_write(OMCMEM_BASE + offset, 1, &value);
|
||||||
|
offset = 0x12 * 4;
|
||||||
|
ctc5236_switch_read(OMCMEM_BASE + offset, 1, &value);
|
||||||
|
value |= BIT(0);
|
||||||
|
ctc5236_switch_write(OMCMEM_BASE + offset, 1, &value);
|
||||||
|
|
||||||
|
/*mask_write tbl-reg OmcMem 0x10 offset 0x0 0x00000001 0x00000001 */
|
||||||
|
offset = 0x10 * 4;
|
||||||
|
ctc5236_switch_read(OMCMEM_BASE + offset, 1, &value);
|
||||||
|
value |= BIT(0);
|
||||||
|
ctc5236_switch_write(OMCMEM_BASE + offset, 1, &value);
|
||||||
|
|
||||||
|
msleep(1);
|
||||||
|
|
||||||
|
/*mask_write tbl-reg OmcMem 0x12 offset 0x0 0x00000001 0x00000001 */
|
||||||
|
offset = 0x12 * 4;
|
||||||
|
ctc5236_switch_read(OMCMEM_BASE + offset, 1, &value);
|
||||||
|
value |= BIT(0);
|
||||||
|
ctc5236_switch_write(OMCMEM_BASE + offset, 1, &value);
|
||||||
|
|
||||||
|
/*Wait((mask_read tbl-reg OmcMem 0xa offset 0x0 0x00000004) =1) */
|
||||||
|
timeout = SYS_TSINGMA_SENSOR_TIMEOUT;
|
||||||
|
offset = 0xa * 4;
|
||||||
|
while (timeout) {
|
||||||
|
timeout--;
|
||||||
|
ctc5236_switch_read(OMCMEM_BASE + offset, 1, &value);
|
||||||
|
if (value & BIT(2))
|
||||||
|
break;
|
||||||
|
|
||||||
|
msleep(1);
|
||||||
|
}
|
||||||
|
if (timeout == 0)
|
||||||
|
return 0xffff;
|
||||||
|
|
||||||
|
/*mask_write tbl-reg OmcMem 0x11 offset 0x0 0x00000006 0x00000006 */
|
||||||
|
offset = 0x11 * 4;
|
||||||
|
ctc5236_switch_read(OMCMEM_BASE + offset, 1, &value);
|
||||||
|
value |= BIT(1) | BIT(2);
|
||||||
|
ctc5236_switch_write(OMCMEM_BASE + offset, 1, &value);
|
||||||
|
|
||||||
|
msleep(10);
|
||||||
|
|
||||||
|
/*read-reg OmcMem 0xd offset 0x0 */
|
||||||
|
offset = 0xd * 4;
|
||||||
|
ctc5236_switch_read(OMCMEM_BASE + offset, 1, &value);
|
||||||
|
_sys_tsingma_peri_get_temp_with_code(0, value, &p_value);
|
||||||
|
temperature = p_value & ~BIT(31);
|
||||||
|
if ((p_value & BIT(31)) == 0)
|
||||||
|
return temperature;
|
||||||
|
else
|
||||||
|
return -temperature;
|
||||||
|
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(get_switch_temperature);
|
||||||
|
|
||||||
|
static int ctc_switch_probe(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
struct resource *iomem;
|
||||||
|
void __iomem *ioaddr;
|
||||||
|
resource_size_t start;
|
||||||
|
|
||||||
|
iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||||
|
|
||||||
|
start = iomem->start - 0x1000;
|
||||||
|
ioaddr = devm_ioremap(&pdev->dev, start, resource_size(iomem));
|
||||||
|
if (IS_ERR(ioaddr))
|
||||||
|
return -1;
|
||||||
|
access = (struct ctc_access_t *) ioaddr;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct of_device_id ctc_switch_of_match[] = {
|
||||||
|
{.compatible = "centec,switch"},
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
MODULE_DEVICE_TABLE(of, ctc_switch_of_match);
|
||||||
|
|
||||||
|
static struct platform_driver ctc_switch_driver = {
|
||||||
|
.driver = {
|
||||||
|
.name = "ctc-switch",
|
||||||
|
.of_match_table = ctc_switch_of_match,
|
||||||
|
},
|
||||||
|
.probe = ctc_switch_probe,
|
||||||
|
};
|
||||||
|
|
||||||
|
module_platform_driver(ctc_switch_driver);
|
||||||
|
|
||||||
|
MODULE_LICENSE("GPL");
|
||||||
|
MODULE_ALIAS("platform:switch");
|
1
platform/centec-arm64/tsingma-bsp/src/ctc_wdt/Makefile
Normal file
1
platform/centec-arm64/tsingma-bsp/src/ctc_wdt/Makefile
Normal file
@ -0,0 +1 @@
|
|||||||
|
obj-m = ctc_wdt.o
|
398
platform/centec-arm64/tsingma-bsp/src/ctc_wdt/ctc_wdt.c
Normal file
398
platform/centec-arm64/tsingma-bsp/src/ctc_wdt/ctc_wdt.c
Normal file
@ -0,0 +1,398 @@
|
|||||||
|
/* drivers/char/watchdog/ctc-wdt.c
|
||||||
|
*
|
||||||
|
* Watchdog driver for CTC TSINGMA, based on ARM SP805 watchdog module
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010 ST Microelectronics
|
||||||
|
* Viresh Kumar <vireshk@kernel.org>
|
||||||
|
*
|
||||||
|
* This file is licensed under the terms of the GNU General Public
|
||||||
|
* License version 2 or later. This program is licensed "as is" without any
|
||||||
|
* warranty of any kind, whether express or implied.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/device.h>
|
||||||
|
#include <linux/resource.h>
|
||||||
|
#include <linux/amba/bus.h>
|
||||||
|
#include <linux/bitops.h>
|
||||||
|
#include <linux/clk.h>
|
||||||
|
#include <linux/io.h>
|
||||||
|
#include <linux/ioport.h>
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/math64.h>
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/moduleparam.h>
|
||||||
|
#include <linux/pm.h>
|
||||||
|
#include <linux/slab.h>
|
||||||
|
#include <linux/spinlock.h>
|
||||||
|
#include <linux/types.h>
|
||||||
|
#include <linux/watchdog.h>
|
||||||
|
#include <linux/delay.h>
|
||||||
|
#include <linux/interrupt.h>
|
||||||
|
#include "../include/sysctl.h"
|
||||||
|
#include <linux/regmap.h>
|
||||||
|
#include <linux/mfd/syscon.h>
|
||||||
|
|
||||||
|
/* default timeout in seconds */
|
||||||
|
#define DEFAULT_TIMEOUT 60
|
||||||
|
|
||||||
|
#define MODULE_NAME "ctc-wdt"
|
||||||
|
|
||||||
|
/* watchdog register offsets and masks */
|
||||||
|
#define WDTLOAD 0x000
|
||||||
|
#define LOAD_MIN 0x00000001
|
||||||
|
#define LOAD_MAX 0xFFFFFFFF
|
||||||
|
#define WDTVALUE 0x004
|
||||||
|
#define WDTCONTROL 0x008
|
||||||
|
/* control register masks */
|
||||||
|
#define INT_ENABLE (1 << 0)
|
||||||
|
#define RESET_ENABLE (1 << 1)
|
||||||
|
#define WDTINTCLR 0x00C
|
||||||
|
#define WDTRIS 0x010
|
||||||
|
#define WDTMIS 0x014
|
||||||
|
#define INT_MASK (1 << 0)
|
||||||
|
#define WDTLOCK 0xC00
|
||||||
|
#define UNLOCK 0x1ACCE551
|
||||||
|
#define LOCK 0x00000001
|
||||||
|
|
||||||
|
/* TsingMa SoC */
|
||||||
|
#define WDTCLK_MAX 500000000UL
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct ctc_wdt: ctc wdt device structure
|
||||||
|
* @wdd: instance of struct watchdog_device
|
||||||
|
* @lock: spin lock protecting dev structure and io access
|
||||||
|
* @base: base address of wdt
|
||||||
|
* @clk: clock structure of wdt
|
||||||
|
* @adev: amba device structure of wdt
|
||||||
|
* @status: current status of wdt
|
||||||
|
* @load_val: load value to be set for current timeout
|
||||||
|
*/
|
||||||
|
struct ctc_wdt {
|
||||||
|
struct watchdog_device wdd;
|
||||||
|
spinlock_t lock;
|
||||||
|
void __iomem *base;
|
||||||
|
struct clk *clk;
|
||||||
|
struct amba_device *adev;
|
||||||
|
unsigned int load_val;
|
||||||
|
struct regmap *regmap_base;
|
||||||
|
};
|
||||||
|
|
||||||
|
static bool nowayout = WATCHDOG_NOWAYOUT;
|
||||||
|
module_param(nowayout, bool, 0);
|
||||||
|
MODULE_PARM_DESC(nowayout,
|
||||||
|
"Set to 1 to keep watchdog running after device release");
|
||||||
|
|
||||||
|
/* This routine finds load value that will reset system in required timeout */
|
||||||
|
static int wdt_setload(struct watchdog_device *wdd, unsigned int timeout)
|
||||||
|
{
|
||||||
|
struct ctc_wdt *wdt = watchdog_get_drvdata(wdd);
|
||||||
|
u64 load, rate;
|
||||||
|
|
||||||
|
rate = clk_get_rate(wdt->clk);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ctc wdt runs counter with given value twice, after the end of first
|
||||||
|
* counter it gives an interrupt and then starts counter again. If
|
||||||
|
* interrupt already occurred then it resets the system. This is why
|
||||||
|
* load is half of what should be required.
|
||||||
|
*/
|
||||||
|
load = div_u64(rate, 2) * timeout - 1;
|
||||||
|
|
||||||
|
load = (load > LOAD_MAX) ? LOAD_MAX : load;
|
||||||
|
load = (load < LOAD_MIN) ? LOAD_MIN : load;
|
||||||
|
|
||||||
|
spin_lock(&wdt->lock);
|
||||||
|
wdt->load_val = load;
|
||||||
|
/* roundup timeout to closest positive integer value */
|
||||||
|
wdd->timeout = div_u64((load + 1) * 2 + (rate / 2), rate);
|
||||||
|
spin_unlock(&wdt->lock);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* returns number of seconds left for reset to occur */
|
||||||
|
static unsigned int wdt_timeleft(struct watchdog_device *wdd)
|
||||||
|
{
|
||||||
|
struct ctc_wdt *wdt = watchdog_get_drvdata(wdd);
|
||||||
|
u64 load, rate;
|
||||||
|
|
||||||
|
rate = clk_get_rate(wdt->clk);
|
||||||
|
|
||||||
|
spin_lock(&wdt->lock);
|
||||||
|
load = readl_relaxed(wdt->base + WDTVALUE);
|
||||||
|
|
||||||
|
/*If the interrupt is inactive then time left is WDTValue + WDTLoad. */
|
||||||
|
if (!(readl_relaxed(wdt->base + WDTRIS) & INT_MASK))
|
||||||
|
load += wdt->load_val + 1;
|
||||||
|
spin_unlock(&wdt->lock);
|
||||||
|
|
||||||
|
return div_u64(load, rate);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int wdt_config(struct watchdog_device *wdd, bool ping)
|
||||||
|
{
|
||||||
|
struct ctc_wdt *wdt = watchdog_get_drvdata(wdd);
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (!ping) {
|
||||||
|
|
||||||
|
ret = clk_prepare_enable(wdt->clk);
|
||||||
|
if (ret) {
|
||||||
|
dev_err(&wdt->adev->dev, "clock enable fail");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
spin_lock(&wdt->lock);
|
||||||
|
|
||||||
|
writel_relaxed(UNLOCK, wdt->base + WDTLOCK);
|
||||||
|
writel_relaxed(wdt->load_val, wdt->base + WDTLOAD);
|
||||||
|
writel_relaxed(INT_MASK, wdt->base + WDTINTCLR);
|
||||||
|
|
||||||
|
if (!ping)
|
||||||
|
writel_relaxed(INT_ENABLE | RESET_ENABLE, wdt->base +
|
||||||
|
WDTCONTROL);
|
||||||
|
|
||||||
|
writel_relaxed(LOCK, wdt->base + WDTLOCK);
|
||||||
|
|
||||||
|
/* Flush posted writes. */
|
||||||
|
readl_relaxed(wdt->base + WDTLOCK);
|
||||||
|
spin_unlock(&wdt->lock);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int wdt_ping(struct watchdog_device *wdd)
|
||||||
|
{
|
||||||
|
return wdt_config(wdd, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* enables watchdog timers reset */
|
||||||
|
static int wdt_enable(struct watchdog_device *wdd)
|
||||||
|
{
|
||||||
|
return wdt_config(wdd, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* disables watchdog timers reset */
|
||||||
|
static int wdt_disable(struct watchdog_device *wdd)
|
||||||
|
{
|
||||||
|
struct ctc_wdt *wdt = watchdog_get_drvdata(wdd);
|
||||||
|
|
||||||
|
spin_lock(&wdt->lock);
|
||||||
|
|
||||||
|
writel_relaxed(UNLOCK, wdt->base + WDTLOCK);
|
||||||
|
writel_relaxed(0, wdt->base + WDTCONTROL);
|
||||||
|
writel_relaxed(LOCK, wdt->base + WDTLOCK);
|
||||||
|
|
||||||
|
/* Flush posted writes. */
|
||||||
|
readl_relaxed(wdt->base + WDTLOCK);
|
||||||
|
spin_unlock(&wdt->lock);
|
||||||
|
|
||||||
|
clk_disable_unprepare(wdt->clk);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int wdt_restart(struct watchdog_device *wdd, unsigned long action,
|
||||||
|
void *cmd)
|
||||||
|
{
|
||||||
|
struct ctc_wdt *wdt = watchdog_get_drvdata(wdd);
|
||||||
|
|
||||||
|
spin_lock(&wdt->lock);
|
||||||
|
|
||||||
|
writel_relaxed(UNLOCK, wdt->base + WDTLOCK);
|
||||||
|
writel_relaxed(0, wdt->base + WDTCONTROL);
|
||||||
|
writel_relaxed(1, wdt->base + WDTLOAD);
|
||||||
|
writel_relaxed(INT_ENABLE | RESET_ENABLE, wdt->base + WDTCONTROL);
|
||||||
|
writel_relaxed(LOCK, wdt->base + WDTLOCK);
|
||||||
|
|
||||||
|
spin_unlock(&wdt->lock);
|
||||||
|
|
||||||
|
mdelay(100);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int wdt_set_pretimeout(struct watchdog_device *wdd,
|
||||||
|
unsigned int new_pretimeout)
|
||||||
|
{
|
||||||
|
struct ctc_wdt *wdt = watchdog_get_drvdata(wdd);
|
||||||
|
u64 load, rate;
|
||||||
|
|
||||||
|
rate = clk_get_rate(wdt->clk);
|
||||||
|
|
||||||
|
load = rate * new_pretimeout - 1;
|
||||||
|
load = (load > LOAD_MAX) ? LOAD_MAX : load;
|
||||||
|
load = (load < LOAD_MIN) ? LOAD_MIN : load;
|
||||||
|
|
||||||
|
spin_lock(&wdt->lock);
|
||||||
|
wdt->load_val = load;
|
||||||
|
/* roundup timeout to closest positive integer value */
|
||||||
|
wdd->pretimeout = div_u64((load + 1) + (rate / 2), rate);
|
||||||
|
|
||||||
|
spin_unlock(&wdt->lock);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static irqreturn_t ctc_wdt_irq(int irq, void *dev_id)
|
||||||
|
{
|
||||||
|
struct ctc_wdt *wdt = dev_id;
|
||||||
|
|
||||||
|
watchdog_notify_pretimeout(&wdt->wdd);
|
||||||
|
|
||||||
|
return IRQ_HANDLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct watchdog_info wdt_info = {
|
||||||
|
.options =
|
||||||
|
WDIOF_MAGICCLOSE | WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING |
|
||||||
|
WDIOF_PRETIMEOUT,
|
||||||
|
.identity = MODULE_NAME,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct watchdog_ops wdt_ops = {
|
||||||
|
.owner = THIS_MODULE,
|
||||||
|
.start = wdt_enable,
|
||||||
|
.stop = wdt_disable,
|
||||||
|
.ping = wdt_ping,
|
||||||
|
.set_timeout = wdt_setload,
|
||||||
|
.get_timeleft = wdt_timeleft,
|
||||||
|
.restart = wdt_restart,
|
||||||
|
.set_pretimeout = wdt_set_pretimeout,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int ctc_wdt_probe(struct amba_device *adev, const struct amba_id *id)
|
||||||
|
{
|
||||||
|
struct ctc_wdt *wdt;
|
||||||
|
int ret = 0;
|
||||||
|
u64 rate;
|
||||||
|
unsigned int fdc;
|
||||||
|
|
||||||
|
wdt = devm_kzalloc(&adev->dev, sizeof(*wdt), GFP_KERNEL);
|
||||||
|
if (!wdt) {
|
||||||
|
ret = -ENOMEM;
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
wdt->base = devm_ioremap_resource(&adev->dev, &adev->res);
|
||||||
|
if (IS_ERR(wdt->base))
|
||||||
|
return PTR_ERR(wdt->base);
|
||||||
|
|
||||||
|
wdt->clk = devm_clk_get(&adev->dev, NULL);
|
||||||
|
if (IS_ERR(wdt->clk)) {
|
||||||
|
dev_warn(&adev->dev, "Clock not found\n");
|
||||||
|
ret = PTR_ERR(wdt->clk);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
wdt->regmap_base = syscon_regmap_lookup_by_phandle(adev->dev.of_node,
|
||||||
|
"ctc,sysctrl");
|
||||||
|
if (IS_ERR(wdt->regmap_base))
|
||||||
|
return PTR_ERR(wdt->regmap_base);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TsingMa SoC wdt reference clock is obtained by clockSub frequency
|
||||||
|
* division,which is 500Mhz.So we need to set the frequency division
|
||||||
|
* register according to the configured clock.
|
||||||
|
*/
|
||||||
|
|
||||||
|
rate = clk_get_rate(wdt->clk);
|
||||||
|
if (rate < 0 || rate > WDTCLK_MAX) {
|
||||||
|
dev_err(&adev->dev, "Clock out of range\n");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
fdc = div_u64(WDTCLK_MAX, rate);
|
||||||
|
regmap_write(wdt->regmap_base, offsetof(struct SysCtl_regs, SysWdt0Cnt),
|
||||||
|
fdc);
|
||||||
|
regmap_write(wdt->regmap_base, offsetof(struct SysCtl_regs, SysWdt1Cnt),
|
||||||
|
fdc);
|
||||||
|
wdt->adev = adev;
|
||||||
|
wdt->wdd.info = &wdt_info;
|
||||||
|
wdt->wdd.ops = &wdt_ops;
|
||||||
|
wdt->wdd.parent = &adev->dev;
|
||||||
|
|
||||||
|
spin_lock_init(&wdt->lock);
|
||||||
|
watchdog_set_nowayout(&wdt->wdd, nowayout);
|
||||||
|
watchdog_set_drvdata(&wdt->wdd, wdt);
|
||||||
|
wdt_setload(&wdt->wdd, DEFAULT_TIMEOUT);
|
||||||
|
ret = devm_request_irq(&adev->dev, adev->irq[0], ctc_wdt_irq,
|
||||||
|
0, "ctc-wdt", wdt);
|
||||||
|
if (ret < 0) {
|
||||||
|
dev_err(&adev->dev, "devm_request_irq() failed: %d\n", ret);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
ret = watchdog_register_device(&wdt->wdd);
|
||||||
|
if (ret) {
|
||||||
|
dev_err(&adev->dev, "watchdog_register_device() failed: %d\n",
|
||||||
|
ret);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
amba_set_drvdata(adev, wdt);
|
||||||
|
|
||||||
|
dev_info(&adev->dev, "registration successful\n");
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
err:
|
||||||
|
dev_err(&adev->dev, "Probe Failed!!!\n");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ctc_wdt_remove(struct amba_device *adev)
|
||||||
|
{
|
||||||
|
struct ctc_wdt *wdt = amba_get_drvdata(adev);
|
||||||
|
|
||||||
|
watchdog_unregister_device(&wdt->wdd);
|
||||||
|
watchdog_set_drvdata(&wdt->wdd, NULL);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int __maybe_unused ctc_wdt_suspend(struct device *dev)
|
||||||
|
{
|
||||||
|
struct ctc_wdt *wdt = dev_get_drvdata(dev);
|
||||||
|
|
||||||
|
if (watchdog_active(&wdt->wdd))
|
||||||
|
return wdt_disable(&wdt->wdd);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int __maybe_unused ctc_wdt_resume(struct device *dev)
|
||||||
|
{
|
||||||
|
struct ctc_wdt *wdt = dev_get_drvdata(dev);
|
||||||
|
|
||||||
|
if (watchdog_active(&wdt->wdd))
|
||||||
|
return wdt_enable(&wdt->wdd);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static SIMPLE_DEV_PM_OPS(ctc_wdt_dev_pm_ops, ctc_wdt_suspend, ctc_wdt_resume);
|
||||||
|
|
||||||
|
static struct amba_id ctc_wdt_ids[] = {
|
||||||
|
/* Centec TsingMa SoC WDT ID */
|
||||||
|
{
|
||||||
|
.id = 0x001bb824,
|
||||||
|
.mask = 0x00ffffff,
|
||||||
|
},
|
||||||
|
{0, 0},
|
||||||
|
};
|
||||||
|
|
||||||
|
MODULE_DEVICE_TABLE(amba, ctc_wdt_ids);
|
||||||
|
|
||||||
|
static struct amba_driver ctc_wdt_driver = {
|
||||||
|
.drv = {
|
||||||
|
.name = MODULE_NAME,
|
||||||
|
.pm = &ctc_wdt_dev_pm_ops,
|
||||||
|
},
|
||||||
|
.id_table = ctc_wdt_ids,
|
||||||
|
.probe = ctc_wdt_probe,
|
||||||
|
.remove = ctc_wdt_remove,
|
||||||
|
};
|
||||||
|
|
||||||
|
module_amba_driver(ctc_wdt_driver);
|
||||||
|
|
||||||
|
MODULE_AUTHOR("lius <lius@centecnetworks.com>");
|
||||||
|
MODULE_DESCRIPTION("ARM CTC Watchdog Driver");
|
||||||
|
MODULE_LICENSE("GPL");
|
3
platform/centec-arm64/tsingma-bsp/src/ctcmac/Makefile
Normal file
3
platform/centec-arm64/tsingma-bsp/src/ctcmac/Makefile
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
KBUILD_EXTRA_SYMBOLS = /sonic/platform/centec-arm64/tsingma-bsp/src/ctc5236_switch/Module.symvers
|
||||||
|
|
||||||
|
obj-m = ctcmac.o ctcmac_test.o ctc5236_mdio.o
|
195
platform/centec-arm64/tsingma-bsp/src/ctcmac/ctc5236_mdio.c
Normal file
195
platform/centec-arm64/tsingma-bsp/src/ctcmac/ctc5236_mdio.c
Normal file
@ -0,0 +1,195 @@
|
|||||||
|
/* Centec cpu_mac Ethernet Driver -- cpu_mac controller implementation
|
||||||
|
* Provides Bus interface for MIIM regs
|
||||||
|
*
|
||||||
|
* Author: liuht <liuht@centecnetworks.com>
|
||||||
|
*
|
||||||
|
* Copyright 2002-2018, Centec Networks (Suzhou) Co., Ltd.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/string.h>
|
||||||
|
#include <linux/errno.h>
|
||||||
|
#include <linux/unistd.h>
|
||||||
|
#include <linux/slab.h>
|
||||||
|
#include <linux/interrupt.h>
|
||||||
|
#include <linux/delay.h>
|
||||||
|
#include <linux/netdevice.h>
|
||||||
|
#include <linux/etherdevice.h>
|
||||||
|
#include <linux/skbuff.h>
|
||||||
|
#include <linux/if_vlan.h>
|
||||||
|
#include <linux/spinlock.h>
|
||||||
|
#include <linux/mm.h>
|
||||||
|
#include <linux/of_address.h>
|
||||||
|
#include <linux/of_irq.h>
|
||||||
|
#include <linux/of_mdio.h>
|
||||||
|
#include <linux/of_platform.h>
|
||||||
|
#include <linux/ip.h>
|
||||||
|
#include <linux/tcp.h>
|
||||||
|
#include <linux/udp.h>
|
||||||
|
#include <linux/in.h>
|
||||||
|
#include <linux/net_tstamp.h>
|
||||||
|
#include <linux/mii.h>
|
||||||
|
#include <linux/iopoll.h>
|
||||||
|
|
||||||
|
#include <asm/io.h>
|
||||||
|
|
||||||
|
#include "ctcmac.h"
|
||||||
|
#include "ctcmac_reg.h"
|
||||||
|
|
||||||
|
struct ctc_mdio_priv {
|
||||||
|
void __iomem *map;
|
||||||
|
struct mdio_soc_regs *mdio_reg;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int ctc_mdio_write(struct mii_bus *bus, int mii_id, int reg, u16 value)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
u32 cmd = 0;
|
||||||
|
u32 tmp = 0;
|
||||||
|
struct ctc_mdio_priv *priv = (struct ctc_mdio_priv *)bus->priv;
|
||||||
|
|
||||||
|
cmd = CTCMAC_MDIO_CMD_REGAD(reg) | CTCMAC_MDIO_CMD_PHYAD(mii_id)
|
||||||
|
| CTCMAC_MDIO_CMD_OPCODE(1) | CTCMAC_MDIO_CMD_DATA(value);
|
||||||
|
|
||||||
|
writel(cmd, &priv->mdio_reg->mdio_soc_cmd_0[0]);
|
||||||
|
writel(1, &priv->mdio_reg->mdio_soc_cmd_0[1]);
|
||||||
|
|
||||||
|
ret = readl_poll_timeout(&priv->mdio_reg->mdio_soc_status_0,
|
||||||
|
tmp, tmp & CTCMAC_MDIO_STAT(1), 1000, 10000);
|
||||||
|
|
||||||
|
if (ret < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ctc_mdio_read(struct mii_bus *bus, int mii_id, int reg)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
u32 cmd = 0;
|
||||||
|
u32 status;
|
||||||
|
int value = 0;
|
||||||
|
struct ctc_mdio_priv *priv = (struct ctc_mdio_priv *)bus->priv;
|
||||||
|
|
||||||
|
cmd = CTCMAC_MDIO_CMD_REGAD(reg) | CTCMAC_MDIO_CMD_PHYAD(mii_id)
|
||||||
|
| CTCMAC_MDIO_CMD_OPCODE(2);
|
||||||
|
|
||||||
|
writel(cmd, &priv->mdio_reg->mdio_soc_cmd_0[0]);
|
||||||
|
writel(1, &priv->mdio_reg->mdio_soc_cmd_0[1]);
|
||||||
|
|
||||||
|
ret = readl_poll_timeout(&priv->mdio_reg->mdio_soc_status_0,
|
||||||
|
status, status & CTCMAC_MDIO_STAT(1), 1000,
|
||||||
|
10000);
|
||||||
|
if (ret < 0) {
|
||||||
|
pr_err("ctc_mdio_read1\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
value = (readl(&priv->mdio_reg->mdio_soc_status_0) & 0xffff);
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ctc_mdio_reset(struct mii_bus *bus)
|
||||||
|
{
|
||||||
|
struct ctc_mdio_priv *priv = (struct ctc_mdio_priv *)bus->priv;
|
||||||
|
|
||||||
|
writel(0x91f, &priv->mdio_reg->mdio_soc_cfg_0);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct of_device_id ctc_mdio_match[] = {
|
||||||
|
{
|
||||||
|
.compatible = "ctc,mdio",
|
||||||
|
},
|
||||||
|
{},
|
||||||
|
};
|
||||||
|
|
||||||
|
MODULE_DEVICE_TABLE(of, ctc_mdio_match);
|
||||||
|
|
||||||
|
static int ctc_mdio_probe(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
struct device_node *np = pdev->dev.of_node;
|
||||||
|
struct resource res;
|
||||||
|
struct ctc_mdio_priv *priv;
|
||||||
|
struct mii_bus *new_bus;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
new_bus = mdiobus_alloc_size(sizeof(*priv));
|
||||||
|
if (!new_bus)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
priv = new_bus->priv;
|
||||||
|
new_bus->name = "CTC MII Bus", new_bus->read = &ctc_mdio_read;
|
||||||
|
new_bus->write = &ctc_mdio_write;
|
||||||
|
new_bus->reset = &ctc_mdio_reset;
|
||||||
|
|
||||||
|
err = of_address_to_resource(np, 0, &res);
|
||||||
|
if (err < 0) {
|
||||||
|
pr_err("Of address to resource fail %d!\n", err);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf(new_bus->id, MII_BUS_ID_SIZE, "%s@%llx", np->name,
|
||||||
|
(unsigned long long)res.start);
|
||||||
|
|
||||||
|
priv->map = of_iomap(np, 0);
|
||||||
|
if (!priv->map) {
|
||||||
|
err = -ENOMEM;
|
||||||
|
pr_err("of iomap fail %d!\n", err);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
priv->mdio_reg = (struct mdio_soc_regs *)priv->map;
|
||||||
|
new_bus->parent = &pdev->dev;
|
||||||
|
platform_set_drvdata(pdev, new_bus);
|
||||||
|
|
||||||
|
err = of_mdiobus_register(new_bus, np);
|
||||||
|
if (err) {
|
||||||
|
pr_err("register mdio bus fail %d!\n", err);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
error:
|
||||||
|
if (priv->map)
|
||||||
|
iounmap(priv->map);
|
||||||
|
|
||||||
|
kfree(new_bus);
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ctc_mdio_remove(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
struct device *device = &pdev->dev;
|
||||||
|
struct mii_bus *bus = dev_get_drvdata(device);
|
||||||
|
struct ctc_mdio_priv *priv = bus->priv;
|
||||||
|
|
||||||
|
mdiobus_unregister(bus);
|
||||||
|
|
||||||
|
iounmap(priv->map);
|
||||||
|
mdiobus_free(bus);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct platform_driver ctc_mdio_driver = {
|
||||||
|
.driver = {
|
||||||
|
.name = "ctc_mdio",
|
||||||
|
.of_match_table = ctc_mdio_match,
|
||||||
|
},
|
||||||
|
.probe = ctc_mdio_probe,
|
||||||
|
.remove = ctc_mdio_remove,
|
||||||
|
};
|
||||||
|
|
||||||
|
module_platform_driver(ctc_mdio_driver);
|
||||||
|
|
||||||
|
MODULE_LICENSE("GPL");
|
2697
platform/centec-arm64/tsingma-bsp/src/ctcmac/ctcmac.c
Normal file
2697
platform/centec-arm64/tsingma-bsp/src/ctcmac/ctcmac.c
Normal file
File diff suppressed because it is too large
Load Diff
307
platform/centec-arm64/tsingma-bsp/src/ctcmac/ctcmac.h
Normal file
307
platform/centec-arm64/tsingma-bsp/src/ctcmac/ctcmac.h
Normal file
@ -0,0 +1,307 @@
|
|||||||
|
/*
|
||||||
|
* Centec cpu_mac Ethernet Driver -- cpu_mac controller implementation
|
||||||
|
* Provides Bus interface for MIIM regs
|
||||||
|
*
|
||||||
|
* Author: liuht <liuht@centecnetworks.com>
|
||||||
|
*
|
||||||
|
* Copyright 2002-2017, Centec Networks (Suzhou) Co., Ltd.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __CTCMAC_H
|
||||||
|
#define __CTCMAC_H
|
||||||
|
|
||||||
|
#define TX_TIMEOUT (5 * HZ)
|
||||||
|
|
||||||
|
#define CTCMAC_DEFAULT_MTU 1500
|
||||||
|
#define CTCMAC_MIN_PKT_LEN 64
|
||||||
|
|
||||||
|
#define CTCMAC_TX_QUEUE_MAX 1
|
||||||
|
#define CTCMAC_RX_QUEUE_MAX 2
|
||||||
|
|
||||||
|
#define CTCMAC0_EXSRAM_BASE 0x0
|
||||||
|
#define CTCMAC1_EXSRAM_BASE 0x1800
|
||||||
|
#define CTCMAC_MAX_RING_SIZE 1023
|
||||||
|
#define CTCMAC_TX_RING_SIZE 1023
|
||||||
|
#define CTCMAC_RX_RING_SIZE 1023
|
||||||
|
#define CTCMAC_RX_BUFF_ALLOC 16
|
||||||
|
#define CTCMAC_INTERNAL_RING_SIZE 64
|
||||||
|
|
||||||
|
/* The maximum number of packets to be handled in one call of gfar_poll */
|
||||||
|
#define CTCMAC_NAIP_RX_WEIGHT 16
|
||||||
|
#define CTCMAC_NAIP_TX_WEIGHT 16
|
||||||
|
|
||||||
|
#define CTCMAC_RXB_SIZE 1024
|
||||||
|
#define CTCMAC_SKBFRAG_SIZE (CTCMAC_RXB_SIZE \
|
||||||
|
+ SKB_DATA_ALIGN(sizeof(struct skb_shared_info)))
|
||||||
|
#define CTCMAC_RXB_TRUESIZE 2048
|
||||||
|
#define BUF_ALIGNMENT 256
|
||||||
|
#define CTCMAC_JUMBO_FRAME_SIZE 9600
|
||||||
|
|
||||||
|
#define CTCMAC_TOKEN_PER_PKT 10
|
||||||
|
#define CTCMAC_TIMER_COMPENSATE 1
|
||||||
|
|
||||||
|
#define CTCMAC_NOR_RX1_R BIT(7)
|
||||||
|
#define CTCMAC_NOR_RX0_R BIT(6)
|
||||||
|
#define CTCMAC_NOR_RX1_D BIT(5)
|
||||||
|
#define CTCMAC_NOR_RX0_D BIT(4)
|
||||||
|
#define CTCMAC_NOR_TX_D BIT(3)
|
||||||
|
#define CTCMAC_NOR_AN_D BIT(2)
|
||||||
|
#define CTCMAC_NOR_LINK_DOWN BIT(1)
|
||||||
|
#define CTCMAC_NOR_LINK_UP BIT(0)
|
||||||
|
|
||||||
|
#define CTC_DDR_BASE 0x80000000
|
||||||
|
|
||||||
|
#define CSA_SGMII_MD_MASK 0x00000008
|
||||||
|
#define CSA_EN 0x00000001
|
||||||
|
|
||||||
|
/*Mask*/
|
||||||
|
/*CTCMAC_SGMII_CFG*/
|
||||||
|
#define CSC_REP_MASK 0x1fc00000
|
||||||
|
#define CSC_SMP_MASK 0x1fc00000
|
||||||
|
/*CTCMAC_SGMII_MON*/
|
||||||
|
#define CSM_ANST_MASK 0x00000007
|
||||||
|
|
||||||
|
#define CSC_1000M 0x00000000
|
||||||
|
#define CSC_100M 0x02400000
|
||||||
|
#define CSC_10M 0x18c00000
|
||||||
|
|
||||||
|
#define CTCMAC_DESC_INT_NUM 1
|
||||||
|
|
||||||
|
#define CTCMAC_SUPPORTED (SUPPORTED_10baseT_Full \
|
||||||
|
| SUPPORTED_100baseT_Full \
|
||||||
|
| SUPPORTED_1000baseT_Full \
|
||||||
|
| SUPPORTED_Autoneg)
|
||||||
|
|
||||||
|
#define CTCMAC_STATS_LEN (sizeof(struct ctcmac_pkt_stats) / sizeof(u64))
|
||||||
|
|
||||||
|
struct ctcmac_skb_cb {
|
||||||
|
unsigned int bytes_sent; /* bytes-on-wire (i.e. no FCB) */
|
||||||
|
};
|
||||||
|
|
||||||
|
#define CTCMAC_CB(skb) ((struct ctcmac_skb_cb *)((skb)->cb))
|
||||||
|
|
||||||
|
enum ctcmac_irqinfo_id {
|
||||||
|
CTCMAC_NORMAL = 0,
|
||||||
|
CTCMAC_FUNC,
|
||||||
|
CTCMAC_UNIT,
|
||||||
|
CTCMAC_NUM_IRQS
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ctcmac_dev_state {
|
||||||
|
CTCMAC_DOWN = 1,
|
||||||
|
CTCMAC_RESETTING
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ctcmac_int_type {
|
||||||
|
CTCMAC_INT_PACKET = 1,
|
||||||
|
CTCMAC_INT_DESC,
|
||||||
|
CTCMAC_INT_MAX
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ctcmac_autoneg {
|
||||||
|
CTCMAC_AUTONEG_1000BASEX_M,
|
||||||
|
CTCMAC_AUTONEG_PHY_M,
|
||||||
|
CTCMAC_AUTONEG_MAC_M,
|
||||||
|
CTCMAC_AUTONEG_DISABLE,
|
||||||
|
CTCMAC_AUTONEG_MAX
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Per TX queue stats */
|
||||||
|
struct txq_stats {
|
||||||
|
unsigned long tx_packets;
|
||||||
|
unsigned long tx_bytes;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ctcmac_tx_buff {
|
||||||
|
void *vaddr;
|
||||||
|
dma_addr_t dma;
|
||||||
|
u32 len;
|
||||||
|
u32 offset;
|
||||||
|
u8 alloc;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ctcmac_priv_tx_q {
|
||||||
|
spinlock_t txlock __aligned(SMP_CACHE_BYTES);
|
||||||
|
struct ctcmac_tx_buff tx_buff[CTCMAC_MAX_RING_SIZE + 1];
|
||||||
|
unsigned int num_txbdfree;
|
||||||
|
u16 tx_ring_size;
|
||||||
|
u16 qindex;
|
||||||
|
u16 next_to_alloc;
|
||||||
|
u16 next_to_clean;
|
||||||
|
struct txq_stats stats;
|
||||||
|
struct net_device *dev;
|
||||||
|
struct sk_buff **tx_skbuff;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*Per RX queue stats */
|
||||||
|
struct rxq_stats {
|
||||||
|
unsigned long rx_packets;
|
||||||
|
unsigned long rx_bytes;
|
||||||
|
unsigned long rx_dropped;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ctcmac_rx_buff {
|
||||||
|
dma_addr_t dma;
|
||||||
|
struct page *page;
|
||||||
|
unsigned int page_offset;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ctcmac_priv_rx_q {
|
||||||
|
struct ctcmac_rx_buff *rx_buff __aligned(SMP_CACHE_BYTES);
|
||||||
|
struct net_device *ndev;
|
||||||
|
struct device *dev;
|
||||||
|
u16 rx_ring_size;
|
||||||
|
u16 qindex;
|
||||||
|
u16 next_to_clean;
|
||||||
|
u16 next_to_use;
|
||||||
|
u16 next_to_alloc;
|
||||||
|
struct sk_buff *skb;
|
||||||
|
struct rxq_stats stats;
|
||||||
|
u32 pps_limit;
|
||||||
|
u32 token, token_max;
|
||||||
|
u32 rx_trigger;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ctcmac_irqinfo {
|
||||||
|
unsigned int irq;
|
||||||
|
char name[32];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ctcmac_desc_cfg {
|
||||||
|
u8 err_type; /*used when err == 1 */
|
||||||
|
u8 err;
|
||||||
|
u8 eop;
|
||||||
|
u8 sop;
|
||||||
|
u32 size;
|
||||||
|
u32 addr_high;
|
||||||
|
u32 addr_low;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ctcmac_private {
|
||||||
|
spinlock_t reglock __aligned(SMP_CACHE_BYTES);
|
||||||
|
struct device *dev;
|
||||||
|
struct net_device *ndev;
|
||||||
|
void __iomem *iobase;
|
||||||
|
struct cpu_mac_regs __iomem *cpumac_reg;
|
||||||
|
struct cpu_mac_mems __iomem *cpumac_mem;
|
||||||
|
struct cpu_mac_unit_regs *cpumacu_reg;
|
||||||
|
u32 device_flags;
|
||||||
|
int irq_num;
|
||||||
|
int index;
|
||||||
|
|
||||||
|
struct ctcmac_priv_tx_q *tx_queue[CTCMAC_TX_QUEUE_MAX];
|
||||||
|
struct ctcmac_priv_rx_q *rx_queue[CTCMAC_RX_QUEUE_MAX];
|
||||||
|
|
||||||
|
unsigned long state;
|
||||||
|
unsigned int num_tx_queues;
|
||||||
|
unsigned int num_rx_queues;
|
||||||
|
|
||||||
|
/* PHY stuff */
|
||||||
|
phy_interface_t interface;
|
||||||
|
struct device_node *phy_node;
|
||||||
|
struct mii_bus *mii_bus;
|
||||||
|
int oldspeed;
|
||||||
|
int oldlink;
|
||||||
|
int oldduplex;
|
||||||
|
|
||||||
|
struct work_struct reset_task;
|
||||||
|
struct platform_device *ofdev;
|
||||||
|
struct napi_struct napi_rx;
|
||||||
|
struct napi_struct napi_tx;
|
||||||
|
struct ctcmac_irqinfo irqinfo[CTCMAC_NUM_IRQS];
|
||||||
|
|
||||||
|
int hwts_rx_en;
|
||||||
|
int hwts_tx_en;
|
||||||
|
u32 autoneg_mode;
|
||||||
|
u32 supported;
|
||||||
|
u32 msg_enable;
|
||||||
|
u32 int_type;
|
||||||
|
u8 dfe_enable;
|
||||||
|
struct timer_list token_timer;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ctcmac_pkt_stats {
|
||||||
|
u64 rx_good_ucast_bytes;
|
||||||
|
u64 rx_good_ucast_pkt;
|
||||||
|
u64 rx_good_mcast_bytes;
|
||||||
|
u64 rx_good_mcast_pkt;
|
||||||
|
u64 rx_good_bcast_bytes;
|
||||||
|
u64 rx_good_bcast_pkt;
|
||||||
|
u64 rx_good_pause_bytes;
|
||||||
|
u64 rx_good_pause_pkt;
|
||||||
|
u64 rx_good_pfc_bytes;
|
||||||
|
u64 rx_good_pfc_pkt;
|
||||||
|
u64 rx_good_control_bytes;
|
||||||
|
u64 rx_good_control_pkt;
|
||||||
|
u64 rx_fcs_error_bytes;
|
||||||
|
u64 rx_fcs_error_pkt;
|
||||||
|
u64 rx_mac_overrun_bytes;
|
||||||
|
u64 rx_mac_overrun_pkt;
|
||||||
|
u64 rx_good_63B_bytes;
|
||||||
|
u64 rx_good_63B_pkt;
|
||||||
|
u64 rx_bad_63B_bytes;
|
||||||
|
u64 rx_bad_63B_pkt;
|
||||||
|
u64 rx_good_mtu2B_bytes;
|
||||||
|
u64 rx_good_mtu2B_pkt;
|
||||||
|
u64 rx_bad_mtu2B_bytes;
|
||||||
|
u64 rx_bad_mtu2B_pkt;
|
||||||
|
u64 rx_good_jumbo_bytes;
|
||||||
|
u64 rx_good_jumbo_pkt;
|
||||||
|
u64 rx_bad_jumbo_bytes;
|
||||||
|
u64 rx_bad_jumbo_pkt;
|
||||||
|
u64 rx_64B_bytes;
|
||||||
|
u64 rx_64B_pkt;
|
||||||
|
u64 rx_127B_bytes;
|
||||||
|
u64 rx_127B_pkt;
|
||||||
|
u64 rx_255B_bytes;
|
||||||
|
u64 rx_255B_pkt;
|
||||||
|
u64 rx_511B_bytes;
|
||||||
|
u64 rx_511B_pkt;
|
||||||
|
u64 rx_1023B_bytes;
|
||||||
|
u64 rx_1023B_pkt;
|
||||||
|
u64 rx_mtu1B_bytes;
|
||||||
|
u64 rx_mtu1B_pkt;
|
||||||
|
u64 tx_ucast_bytes;
|
||||||
|
u64 tx_ucast_pkt;
|
||||||
|
u64 tx_mcast_bytes;
|
||||||
|
u64 tx_mcast_pkt;
|
||||||
|
u64 tx_bcast_bytes;
|
||||||
|
u64 tx_bcast_pkt;
|
||||||
|
u64 tx_pause_bytes;
|
||||||
|
u64 tx_pause_pkt;
|
||||||
|
u64 tx_control_bytes;
|
||||||
|
u64 tx_control_pkt;
|
||||||
|
u64 tx_fcs_error_bytes;
|
||||||
|
u64 tx_fcs_error_pkt;
|
||||||
|
u64 tx_underrun_bytes;
|
||||||
|
u64 tx_underrun_pkt;
|
||||||
|
u64 tx_63B_bytes;
|
||||||
|
u64 tx_63B_pkt;
|
||||||
|
u64 tx_64B_bytes;
|
||||||
|
u64 tx_64B_pkt;
|
||||||
|
u64 tx_127B_bytes;
|
||||||
|
u64 tx_127B_pkt;
|
||||||
|
u64 tx_255B_bytes;
|
||||||
|
u64 tx_255B_pkt;
|
||||||
|
u64 tx_511B_bytes;
|
||||||
|
u64 tx_511B_pkt;
|
||||||
|
u64 tx_1023B_bytes;
|
||||||
|
u64 tx_1023B_pkt;
|
||||||
|
u64 tx_mtu1_bytes;
|
||||||
|
u64 tx_mtu1_pkt;
|
||||||
|
u64 tx_mtu2_bytes;
|
||||||
|
u64 tx_mtu2_pkt;
|
||||||
|
u64 tx_jumbo_bytes;
|
||||||
|
u64 tx_jumbo_pkt;
|
||||||
|
u64 mtu1;
|
||||||
|
u64 mtu2;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
5288
platform/centec-arm64/tsingma-bsp/src/ctcmac/ctcmac_reg.h
Normal file
5288
platform/centec-arm64/tsingma-bsp/src/ctcmac/ctcmac_reg.h
Normal file
File diff suppressed because it is too large
Load Diff
2116
platform/centec-arm64/tsingma-bsp/src/ctcmac/ctcmac_test.c
Normal file
2116
platform/centec-arm64/tsingma-bsp/src/ctcmac/ctcmac_test.c
Normal file
File diff suppressed because it is too large
Load Diff
1
platform/centec-arm64/tsingma-bsp/src/ehci-ctc/Makefile
Normal file
1
platform/centec-arm64/tsingma-bsp/src/ehci-ctc/Makefile
Normal file
@ -0,0 +1 @@
|
|||||||
|
obj-m = ehci-ctc.o
|
423
platform/centec-arm64/tsingma-bsp/src/ehci-ctc/ehci-ctc.c
Normal file
423
platform/centec-arm64/tsingma-bsp/src/ehci-ctc/ehci-ctc.c
Normal file
@ -0,0 +1,423 @@
|
|||||||
|
/*
|
||||||
|
* Centec platform ehci driver
|
||||||
|
*
|
||||||
|
* Copyright 2018 Liuht <liuht@centecnetworks.com>
|
||||||
|
*
|
||||||
|
* Licensed under the GNU/GPL. See COPYING for details.
|
||||||
|
*/
|
||||||
|
#include <linux/acpi.h>
|
||||||
|
#include <linux/clk.h>
|
||||||
|
#include <linux/dma-mapping.h>
|
||||||
|
#include <linux/err.h>
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/hrtimer.h>
|
||||||
|
#include <linux/io.h>
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/of.h>
|
||||||
|
#include <linux/phy/phy.h>
|
||||||
|
#include <linux/platform_device.h>
|
||||||
|
#include <linux/reset.h>
|
||||||
|
#include <linux/usb.h>
|
||||||
|
#include <linux/usb/hcd.h>
|
||||||
|
#include <linux/usb/ehci_pdriver.h>
|
||||||
|
|
||||||
|
#include "ehci.h"
|
||||||
|
|
||||||
|
#define DRIVER_DESC "Centec EHCI platform driver"
|
||||||
|
#define EHCI_MAX_CLKS 4
|
||||||
|
#define EHCI_MAX_RSTS 4
|
||||||
|
#define hcd_to_ehci_priv(h) ((struct ehci_ctc_priv *)hcd_to_ehci(h)->priv)
|
||||||
|
|
||||||
|
struct ehci_ctc_priv {
|
||||||
|
struct clk *clks[EHCI_MAX_CLKS];
|
||||||
|
struct reset_control *rsts[EHCI_MAX_RSTS];
|
||||||
|
struct phy **phys;
|
||||||
|
int num_phys;
|
||||||
|
bool reset_on_resume;
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char hcd_name[] = "ehci-ctc";
|
||||||
|
|
||||||
|
static int ehci_ctc_reset(struct usb_hcd *hcd)
|
||||||
|
{
|
||||||
|
struct platform_device *pdev = to_platform_device(hcd->self.controller);
|
||||||
|
struct usb_ehci_pdata *pdata = dev_get_platdata(&pdev->dev);
|
||||||
|
struct ehci_hcd *ehci = hcd_to_ehci(hcd);
|
||||||
|
int retval;
|
||||||
|
|
||||||
|
ehci->has_synopsys_hc_bug = pdata->has_synopsys_hc_bug;
|
||||||
|
|
||||||
|
if (pdata->pre_setup) {
|
||||||
|
retval = pdata->pre_setup(hcd);
|
||||||
|
if (retval < 0)
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
ehci->caps = hcd->regs + pdata->caps_offset;
|
||||||
|
retval = ehci_setup(hcd);
|
||||||
|
if (retval)
|
||||||
|
return retval;
|
||||||
|
|
||||||
|
if (pdata->no_io_watchdog)
|
||||||
|
ehci->need_io_watchdog = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ehci_ctc_power_on(struct platform_device *dev)
|
||||||
|
{
|
||||||
|
struct usb_hcd *hcd = platform_get_drvdata(dev);
|
||||||
|
struct ehci_ctc_priv *priv = hcd_to_ehci_priv(hcd);
|
||||||
|
int clk, ret, phy_num;
|
||||||
|
|
||||||
|
for (clk = 0; clk < EHCI_MAX_CLKS && priv->clks[clk]; clk++) {
|
||||||
|
ret = clk_prepare_enable(priv->clks[clk]);
|
||||||
|
if (ret)
|
||||||
|
goto err_disable_clks;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (phy_num = 0; phy_num < priv->num_phys; phy_num++) {
|
||||||
|
ret = phy_init(priv->phys[phy_num]);
|
||||||
|
if (ret)
|
||||||
|
goto err_exit_phy;
|
||||||
|
ret = phy_power_on(priv->phys[phy_num]);
|
||||||
|
if (ret) {
|
||||||
|
phy_exit(priv->phys[phy_num]);
|
||||||
|
goto err_exit_phy;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
err_exit_phy:
|
||||||
|
while (--phy_num >= 0) {
|
||||||
|
phy_power_off(priv->phys[phy_num]);
|
||||||
|
phy_exit(priv->phys[phy_num]);
|
||||||
|
}
|
||||||
|
err_disable_clks:
|
||||||
|
while (--clk >= 0)
|
||||||
|
clk_disable_unprepare(priv->clks[clk]);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ehci_ctc_power_off(struct platform_device *dev)
|
||||||
|
{
|
||||||
|
struct usb_hcd *hcd = platform_get_drvdata(dev);
|
||||||
|
struct ehci_ctc_priv *priv = hcd_to_ehci_priv(hcd);
|
||||||
|
int clk, phy_num;
|
||||||
|
|
||||||
|
for (phy_num = 0; phy_num < priv->num_phys; phy_num++) {
|
||||||
|
phy_power_off(priv->phys[phy_num]);
|
||||||
|
phy_exit(priv->phys[phy_num]);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (clk = EHCI_MAX_CLKS - 1; clk >= 0; clk--)
|
||||||
|
if (priv->clks[clk])
|
||||||
|
clk_disable_unprepare(priv->clks[clk]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct hc_driver __read_mostly ehci_ctc_hc_driver;
|
||||||
|
|
||||||
|
static const struct ehci_driver_overrides platform_overrides __initconst = {
|
||||||
|
.reset = ehci_ctc_reset,
|
||||||
|
.extra_priv_size = sizeof(struct ehci_ctc_priv),
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct usb_ehci_pdata ehci_ctc_defaults = {
|
||||||
|
.caps_offset = 0x100,
|
||||||
|
.dma_mask_64 = 1,
|
||||||
|
.power_on = ehci_ctc_power_on,
|
||||||
|
.power_suspend = ehci_ctc_power_off,
|
||||||
|
.power_off = ehci_ctc_power_off,
|
||||||
|
};
|
||||||
|
|
||||||
|
#define KERN_CTC KERN_ERR
|
||||||
|
static int ehci_ctc_probe(struct platform_device *dev)
|
||||||
|
{
|
||||||
|
struct usb_hcd *hcd;
|
||||||
|
struct resource *res_mem;
|
||||||
|
struct usb_ehci_pdata *pdata = dev_get_platdata(&dev->dev);
|
||||||
|
struct ehci_ctc_priv *priv;
|
||||||
|
struct ehci_hcd *ehci;
|
||||||
|
int err, irq, phy_num, clk = 0, rst;
|
||||||
|
|
||||||
|
if (usb_disabled())
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Use reasonable defaults so platforms don't have to provide these
|
||||||
|
* with DT probing on ARM.
|
||||||
|
*/
|
||||||
|
if (!pdata)
|
||||||
|
pdata = &ehci_ctc_defaults;
|
||||||
|
|
||||||
|
err = dma_coerce_mask_and_coherent(&dev->dev,
|
||||||
|
pdata->dma_mask_64 ?
|
||||||
|
DMA_BIT_MASK(64) : DMA_BIT_MASK(32));
|
||||||
|
if (err) {
|
||||||
|
dev_err(&dev->dev, "Error: DMA mask configuration failed\n");
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
irq = platform_get_irq(dev, 0);
|
||||||
|
if (irq < 0) {
|
||||||
|
dev_err(&dev->dev, "no irq provided");
|
||||||
|
return irq;
|
||||||
|
}
|
||||||
|
|
||||||
|
hcd = usb_create_hcd(&ehci_ctc_hc_driver, &dev->dev,
|
||||||
|
dev_name(&dev->dev));
|
||||||
|
if (!hcd)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
platform_set_drvdata(dev, hcd);
|
||||||
|
dev->dev.platform_data = pdata;
|
||||||
|
priv = hcd_to_ehci_priv(hcd);
|
||||||
|
ehci = hcd_to_ehci(hcd);
|
||||||
|
if (pdata == &ehci_ctc_defaults && dev->dev.of_node) {
|
||||||
|
if (of_property_read_bool(dev->dev.of_node, "big-endian-regs"))
|
||||||
|
ehci->big_endian_mmio = 1;
|
||||||
|
|
||||||
|
if (of_property_read_bool(dev->dev.of_node, "big-endian-desc"))
|
||||||
|
ehci->big_endian_desc = 1;
|
||||||
|
|
||||||
|
if (of_property_read_bool(dev->dev.of_node, "big-endian"))
|
||||||
|
ehci->big_endian_mmio = ehci->big_endian_desc = 1;
|
||||||
|
|
||||||
|
if (of_property_read_bool(dev->dev.of_node,
|
||||||
|
"needs-reset-on-resume"))
|
||||||
|
priv->reset_on_resume = true;
|
||||||
|
|
||||||
|
if (of_property_read_bool(dev->dev.of_node,
|
||||||
|
"has-transaction-translator"))
|
||||||
|
hcd->has_tt = 1;
|
||||||
|
|
||||||
|
priv->num_phys = of_count_phandle_with_args(dev->dev.of_node,
|
||||||
|
"phys",
|
||||||
|
"#phy-cells");
|
||||||
|
|
||||||
|
if (priv->num_phys > 0) {
|
||||||
|
priv->phys = devm_kcalloc(&dev->dev, priv->num_phys,
|
||||||
|
sizeof(struct phy *),
|
||||||
|
GFP_KERNEL);
|
||||||
|
if (!priv->phys)
|
||||||
|
return -ENOMEM;
|
||||||
|
} else
|
||||||
|
priv->num_phys = 0;
|
||||||
|
|
||||||
|
for (phy_num = 0; phy_num < priv->num_phys; phy_num++) {
|
||||||
|
priv->phys[phy_num] =
|
||||||
|
devm_of_phy_get_by_index(&dev->dev,
|
||||||
|
dev->dev.of_node, phy_num);
|
||||||
|
if (IS_ERR(priv->phys[phy_num])) {
|
||||||
|
err = PTR_ERR(priv->phys[phy_num]);
|
||||||
|
goto err_put_hcd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (clk = 0; clk < EHCI_MAX_CLKS; clk++) {
|
||||||
|
priv->clks[clk] = of_clk_get(dev->dev.of_node, clk);
|
||||||
|
if (IS_ERR(priv->clks[clk])) {
|
||||||
|
err = PTR_ERR(priv->clks[clk]);
|
||||||
|
if (err == -EPROBE_DEFER)
|
||||||
|
goto err_put_clks;
|
||||||
|
priv->clks[clk] = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (rst = 0; rst < EHCI_MAX_RSTS; rst++) {
|
||||||
|
priv->rsts[rst] =
|
||||||
|
devm_reset_control_get_shared_by_index(&dev->dev, rst);
|
||||||
|
if (IS_ERR(priv->rsts[rst])) {
|
||||||
|
err = PTR_ERR(priv->rsts[rst]);
|
||||||
|
if (err == -EPROBE_DEFER)
|
||||||
|
goto err_reset;
|
||||||
|
priv->rsts[rst] = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = reset_control_deassert(priv->rsts[rst]);
|
||||||
|
if (err)
|
||||||
|
goto err_reset;
|
||||||
|
}
|
||||||
|
if (pdata->big_endian_desc)
|
||||||
|
ehci->big_endian_desc = 1;
|
||||||
|
if (pdata->big_endian_mmio)
|
||||||
|
ehci->big_endian_mmio = 1;
|
||||||
|
if (pdata->has_tt)
|
||||||
|
hcd->has_tt = 1;
|
||||||
|
if (pdata->reset_on_resume)
|
||||||
|
priv->reset_on_resume = true;
|
||||||
|
|
||||||
|
#ifndef CONFIG_USB_EHCI_BIG_ENDIAN_MMIO
|
||||||
|
if (ehci->big_endian_mmio) {
|
||||||
|
dev_err(&dev->dev,
|
||||||
|
"Error: CONFIG_USB_EHCI_BIG_ENDIAN_MMIO not set\n");
|
||||||
|
err = -EINVAL;
|
||||||
|
goto err_reset;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#ifndef CONFIG_USB_EHCI_BIG_ENDIAN_DESC
|
||||||
|
if (ehci->big_endian_desc) {
|
||||||
|
dev_err(&dev->dev,
|
||||||
|
"Error: CONFIG_USB_EHCI_BIG_ENDIAN_DESC not set\n");
|
||||||
|
err = -EINVAL;
|
||||||
|
goto err_reset;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (pdata->power_on) {
|
||||||
|
err = pdata->power_on(dev);
|
||||||
|
if (err < 0)
|
||||||
|
goto err_reset;
|
||||||
|
}
|
||||||
|
res_mem = platform_get_resource(dev, IORESOURCE_MEM, 0);
|
||||||
|
hcd->regs = devm_ioremap_resource(&dev->dev, res_mem);
|
||||||
|
if (IS_ERR(hcd->regs)) {
|
||||||
|
err = PTR_ERR(hcd->regs);
|
||||||
|
goto err_power;
|
||||||
|
}
|
||||||
|
hcd->rsrc_start = res_mem->start;
|
||||||
|
hcd->rsrc_len = resource_size(res_mem);
|
||||||
|
err = usb_add_hcd(hcd, irq, IRQF_SHARED);
|
||||||
|
if (err)
|
||||||
|
goto err_power;
|
||||||
|
device_wakeup_enable(hcd->self.controller);
|
||||||
|
platform_set_drvdata(dev, hcd);
|
||||||
|
return err;
|
||||||
|
|
||||||
|
err_power:
|
||||||
|
if (pdata->power_off)
|
||||||
|
pdata->power_off(dev);
|
||||||
|
err_reset:
|
||||||
|
while (--rst >= 0)
|
||||||
|
reset_control_assert(priv->rsts[rst]);
|
||||||
|
err_put_clks:
|
||||||
|
while (--clk >= 0)
|
||||||
|
clk_put(priv->clks[clk]);
|
||||||
|
err_put_hcd:
|
||||||
|
if (pdata == &ehci_ctc_defaults)
|
||||||
|
dev->dev.platform_data = NULL;
|
||||||
|
|
||||||
|
usb_put_hcd(hcd);
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ehci_ctc_remove(struct platform_device *dev)
|
||||||
|
{
|
||||||
|
struct usb_hcd *hcd = platform_get_drvdata(dev);
|
||||||
|
struct usb_ehci_pdata *pdata = dev_get_platdata(&dev->dev);
|
||||||
|
struct ehci_ctc_priv *priv = hcd_to_ehci_priv(hcd);
|
||||||
|
int clk, rst;
|
||||||
|
|
||||||
|
usb_remove_hcd(hcd);
|
||||||
|
|
||||||
|
if (pdata->power_off)
|
||||||
|
pdata->power_off(dev);
|
||||||
|
|
||||||
|
for (rst = 0; rst < EHCI_MAX_RSTS && priv->rsts[rst]; rst++)
|
||||||
|
reset_control_assert(priv->rsts[rst]);
|
||||||
|
|
||||||
|
for (clk = 0; clk < EHCI_MAX_CLKS && priv->clks[clk]; clk++)
|
||||||
|
clk_put(priv->clks[clk]);
|
||||||
|
|
||||||
|
usb_put_hcd(hcd);
|
||||||
|
|
||||||
|
if (pdata == &ehci_ctc_defaults)
|
||||||
|
dev->dev.platform_data = NULL;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_PM_SLEEP
|
||||||
|
static int ehci_ctc_suspend(struct device *dev)
|
||||||
|
{
|
||||||
|
struct usb_hcd *hcd = dev_get_drvdata(dev);
|
||||||
|
struct usb_ehci_pdata *pdata = dev_get_platdata(dev);
|
||||||
|
struct platform_device *pdev = to_platform_device(dev);
|
||||||
|
bool do_wakeup = device_may_wakeup(dev);
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = ehci_suspend(hcd, do_wakeup);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
if (pdata->power_suspend)
|
||||||
|
pdata->power_suspend(pdev);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ehci_ctc_resume(struct device *dev)
|
||||||
|
{
|
||||||
|
struct usb_hcd *hcd = dev_get_drvdata(dev);
|
||||||
|
struct usb_ehci_pdata *pdata = dev_get_platdata(dev);
|
||||||
|
struct platform_device *pdev = to_platform_device(dev);
|
||||||
|
struct ehci_ctc_priv *priv = hcd_to_ehci_priv(hcd);
|
||||||
|
|
||||||
|
if (pdata->power_on) {
|
||||||
|
int err = pdata->power_on(pdev);
|
||||||
|
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
ehci_resume(hcd, priv->reset_on_resume);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_PM_SLEEP */
|
||||||
|
|
||||||
|
static const struct of_device_id ctc_ehci_ids[] = {
|
||||||
|
{.compatible = "ctc-ehci",},
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
MODULE_DEVICE_TABLE(of, ctc_ehci_ids);
|
||||||
|
|
||||||
|
static const struct platform_device_id ehci_ctc_table[] = {
|
||||||
|
{"ehci-ctc", 0},
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
MODULE_DEVICE_TABLE(platform, ehci_ctc_table);
|
||||||
|
|
||||||
|
static SIMPLE_DEV_PM_OPS(ehci_ctc_pm_ops, ehci_ctc_suspend, ehci_ctc_resume);
|
||||||
|
|
||||||
|
static struct platform_driver ehci_ctc_driver = {
|
||||||
|
.id_table = ehci_ctc_table,
|
||||||
|
.probe = ehci_ctc_probe,
|
||||||
|
.remove = ehci_ctc_remove,
|
||||||
|
.shutdown = usb_hcd_platform_shutdown,
|
||||||
|
.driver = {
|
||||||
|
.name = "ehci-ctc",
|
||||||
|
.pm = &ehci_ctc_pm_ops,
|
||||||
|
.of_match_table = ctc_ehci_ids,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static int __init ehci_ctc_init(void)
|
||||||
|
{
|
||||||
|
if (usb_disabled())
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
|
pr_info("%s: " DRIVER_DESC "\n", hcd_name);
|
||||||
|
|
||||||
|
ehci_init_driver(&ehci_ctc_hc_driver, &platform_overrides);
|
||||||
|
return platform_driver_register(&ehci_ctc_driver);
|
||||||
|
}
|
||||||
|
|
||||||
|
module_init(ehci_ctc_init);
|
||||||
|
|
||||||
|
static void __exit ehci_ctc_cleanup(void)
|
||||||
|
{
|
||||||
|
platform_driver_unregister(&ehci_ctc_driver);
|
||||||
|
}
|
||||||
|
|
||||||
|
module_exit(ehci_ctc_cleanup);
|
||||||
|
|
||||||
|
MODULE_DESCRIPTION(DRIVER_DESC);
|
||||||
|
MODULE_AUTHOR("Hauke Mehrtens");
|
||||||
|
MODULE_AUTHOR("Alan Stern");
|
||||||
|
MODULE_LICENSE("GPL");
|
894
platform/centec-arm64/tsingma-bsp/src/ehci-ctc/ehci.h
Normal file
894
platform/centec-arm64/tsingma-bsp/src/ehci-ctc/ehci.h
Normal file
@ -0,0 +1,894 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0+
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2001-2002 by David Brownell
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __LINUX_EHCI_HCD_H
|
||||||
|
#define __LINUX_EHCI_HCD_H
|
||||||
|
|
||||||
|
/* definitions used for the EHCI driver */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* __hc32 and __hc16 are "Host Controller" types, they may be equivalent to
|
||||||
|
* __leXX (normally) or __beXX (given EHCI_BIG_ENDIAN_DESC), depending on
|
||||||
|
* the host controller implementation.
|
||||||
|
*
|
||||||
|
* To facilitate the strongest possible byte-order checking from "sparse"
|
||||||
|
* and so on, we use __leXX unless that's not practical.
|
||||||
|
*/
|
||||||
|
#ifdef CONFIG_USB_EHCI_BIG_ENDIAN_DESC
|
||||||
|
typedef __u32 __bitwise __hc32;
|
||||||
|
typedef __u16 __bitwise __hc16;
|
||||||
|
#else
|
||||||
|
#define __hc32 __le32
|
||||||
|
#define __hc16 __le16
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* statistics can be kept for tuning/monitoring */
|
||||||
|
#ifdef CONFIG_DYNAMIC_DEBUG
|
||||||
|
#define EHCI_STATS
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct ehci_stats {
|
||||||
|
/* irq usage */
|
||||||
|
unsigned long normal;
|
||||||
|
unsigned long error;
|
||||||
|
unsigned long iaa;
|
||||||
|
unsigned long lost_iaa;
|
||||||
|
|
||||||
|
/* termination of urbs from core */
|
||||||
|
unsigned long complete;
|
||||||
|
unsigned long unlink;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Scheduling and budgeting information for periodic transfers, for both
|
||||||
|
* high-speed devices and full/low-speed devices lying behind a TT.
|
||||||
|
*/
|
||||||
|
struct ehci_per_sched {
|
||||||
|
struct usb_device *udev; /* access to the TT */
|
||||||
|
struct usb_host_endpoint *ep;
|
||||||
|
struct list_head ps_list; /* node on ehci_tt's ps_list */
|
||||||
|
u16 tt_usecs; /* time on the FS/LS bus */
|
||||||
|
u16 cs_mask; /* C-mask and S-mask bytes */
|
||||||
|
u16 period; /* actual period in frames */
|
||||||
|
u16 phase; /* actual phase, frame part */
|
||||||
|
u8 bw_phase; /* same, for bandwidth
|
||||||
|
reservation */
|
||||||
|
u8 phase_uf; /* uframe part of the phase */
|
||||||
|
u8 usecs, c_usecs; /* times on the HS bus */
|
||||||
|
u8 bw_uperiod; /* period in microframes, for
|
||||||
|
bandwidth reservation */
|
||||||
|
u8 bw_period; /* same, in frames */
|
||||||
|
};
|
||||||
|
#define NO_FRAME 29999 /* frame not assigned yet */
|
||||||
|
|
||||||
|
/* ehci_hcd->lock guards shared data against other CPUs:
|
||||||
|
* ehci_hcd: async, unlink, periodic (and shadow), ...
|
||||||
|
* usb_host_endpoint: hcpriv
|
||||||
|
* ehci_qh: qh_next, qtd_list
|
||||||
|
* ehci_qtd: qtd_list
|
||||||
|
*
|
||||||
|
* Also, hold this lock when talking to HC registers or
|
||||||
|
* when updating hw_* fields in shared qh/qtd/... structures.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define EHCI_MAX_ROOT_PORTS 15 /* see HCS_N_PORTS */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ehci_rh_state values of EHCI_RH_RUNNING or above mean that the
|
||||||
|
* controller may be doing DMA. Lower values mean there's no DMA.
|
||||||
|
*/
|
||||||
|
enum ehci_rh_state {
|
||||||
|
EHCI_RH_HALTED,
|
||||||
|
EHCI_RH_SUSPENDED,
|
||||||
|
EHCI_RH_RUNNING,
|
||||||
|
EHCI_RH_STOPPING
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Timer events, ordered by increasing delay length.
|
||||||
|
* Always update event_delays_ns[] and event_handlers[] (defined in
|
||||||
|
* ehci-timer.c) in parallel with this list.
|
||||||
|
*/
|
||||||
|
enum ehci_hrtimer_event {
|
||||||
|
EHCI_HRTIMER_POLL_ASS, /* Poll for async schedule off */
|
||||||
|
EHCI_HRTIMER_POLL_PSS, /* Poll for periodic schedule off */
|
||||||
|
EHCI_HRTIMER_POLL_DEAD, /* Wait for dead controller to stop */
|
||||||
|
EHCI_HRTIMER_UNLINK_INTR, /* Wait for interrupt QH unlink */
|
||||||
|
EHCI_HRTIMER_FREE_ITDS, /* Wait for unused iTDs and siTDs */
|
||||||
|
EHCI_HRTIMER_ACTIVE_UNLINK, /* Wait while unlinking an active QH */
|
||||||
|
EHCI_HRTIMER_START_UNLINK_INTR, /* Unlink empty interrupt QHs */
|
||||||
|
EHCI_HRTIMER_ASYNC_UNLINKS, /* Unlink empty async QHs */
|
||||||
|
EHCI_HRTIMER_IAA_WATCHDOG, /* Handle lost IAA interrupts */
|
||||||
|
EHCI_HRTIMER_DISABLE_PERIODIC, /* Wait to disable periodic sched */
|
||||||
|
EHCI_HRTIMER_DISABLE_ASYNC, /* Wait to disable async sched */
|
||||||
|
EHCI_HRTIMER_IO_WATCHDOG, /* Check for missing IRQs */
|
||||||
|
EHCI_HRTIMER_NUM_EVENTS /* Must come last */
|
||||||
|
};
|
||||||
|
#define EHCI_HRTIMER_NO_EVENT 99
|
||||||
|
|
||||||
|
struct ehci_hcd { /* one per controller */
|
||||||
|
/* timing support */
|
||||||
|
enum ehci_hrtimer_event next_hrtimer_event;
|
||||||
|
unsigned enabled_hrtimer_events;
|
||||||
|
ktime_t hr_timeouts[EHCI_HRTIMER_NUM_EVENTS];
|
||||||
|
struct hrtimer hrtimer;
|
||||||
|
|
||||||
|
int PSS_poll_count;
|
||||||
|
int ASS_poll_count;
|
||||||
|
int died_poll_count;
|
||||||
|
|
||||||
|
/* glue to PCI and HCD framework */
|
||||||
|
struct ehci_caps __iomem *caps;
|
||||||
|
struct ehci_regs __iomem *regs;
|
||||||
|
struct ehci_dbg_port __iomem *debug;
|
||||||
|
|
||||||
|
__u32 hcs_params; /* cached register copy */
|
||||||
|
spinlock_t lock;
|
||||||
|
enum ehci_rh_state rh_state;
|
||||||
|
|
||||||
|
/* general schedule support */
|
||||||
|
bool scanning:1;
|
||||||
|
bool need_rescan:1;
|
||||||
|
bool intr_unlinking:1;
|
||||||
|
bool iaa_in_progress:1;
|
||||||
|
bool async_unlinking:1;
|
||||||
|
bool shutdown:1;
|
||||||
|
struct ehci_qh *qh_scan_next;
|
||||||
|
|
||||||
|
/* async schedule support */
|
||||||
|
struct ehci_qh *async;
|
||||||
|
struct ehci_qh *dummy; /* For AMD quirk use */
|
||||||
|
struct list_head async_unlink;
|
||||||
|
struct list_head async_idle;
|
||||||
|
unsigned async_unlink_cycle;
|
||||||
|
unsigned async_count; /* async activity count */
|
||||||
|
__hc32 old_current; /* Test for QH becoming */
|
||||||
|
__hc32 old_token; /* inactive during unlink */
|
||||||
|
|
||||||
|
/* periodic schedule support */
|
||||||
|
#define DEFAULT_I_TDPS 1024 /* some HCs can do less */
|
||||||
|
unsigned periodic_size;
|
||||||
|
__hc32 *periodic; /* hw periodic table */
|
||||||
|
dma_addr_t periodic_dma;
|
||||||
|
struct list_head intr_qh_list;
|
||||||
|
unsigned i_thresh; /* uframes HC might cache */
|
||||||
|
|
||||||
|
union ehci_shadow *pshadow; /* mirror hw periodic table */
|
||||||
|
struct list_head intr_unlink_wait;
|
||||||
|
struct list_head intr_unlink;
|
||||||
|
unsigned intr_unlink_wait_cycle;
|
||||||
|
unsigned intr_unlink_cycle;
|
||||||
|
unsigned now_frame; /* frame from HC hardware */
|
||||||
|
unsigned last_iso_frame; /* last frame scanned for iso */
|
||||||
|
unsigned intr_count; /* intr activity count */
|
||||||
|
unsigned isoc_count; /* isoc activity count */
|
||||||
|
unsigned periodic_count; /* periodic activity count */
|
||||||
|
unsigned uframe_periodic_max; /* max periodic time per uframe */
|
||||||
|
|
||||||
|
|
||||||
|
/* list of itds & sitds completed while now_frame was still active */
|
||||||
|
struct list_head cached_itd_list;
|
||||||
|
struct ehci_itd *last_itd_to_free;
|
||||||
|
struct list_head cached_sitd_list;
|
||||||
|
struct ehci_sitd *last_sitd_to_free;
|
||||||
|
|
||||||
|
/* per root hub port */
|
||||||
|
unsigned long reset_done[EHCI_MAX_ROOT_PORTS];
|
||||||
|
|
||||||
|
/* bit vectors (one bit per port) */
|
||||||
|
unsigned long bus_suspended; /* which ports were
|
||||||
|
already suspended at the start of a bus suspend */
|
||||||
|
unsigned long companion_ports; /* which ports are
|
||||||
|
dedicated to the companion controller */
|
||||||
|
unsigned long owned_ports; /* which ports are
|
||||||
|
owned by the companion during a bus suspend */
|
||||||
|
unsigned long port_c_suspend; /* which ports have
|
||||||
|
the change-suspend feature turned on */
|
||||||
|
unsigned long suspended_ports; /* which ports are
|
||||||
|
suspended */
|
||||||
|
unsigned long resuming_ports; /* which ports have
|
||||||
|
started to resume */
|
||||||
|
|
||||||
|
/* per-HC memory pools (could be per-bus, but ...) */
|
||||||
|
struct dma_pool *qh_pool; /* qh per active urb */
|
||||||
|
struct dma_pool *qtd_pool; /* one or more per qh */
|
||||||
|
struct dma_pool *itd_pool; /* itd per iso urb */
|
||||||
|
struct dma_pool *sitd_pool; /* sitd per split iso urb */
|
||||||
|
|
||||||
|
unsigned random_frame;
|
||||||
|
unsigned long next_statechange;
|
||||||
|
ktime_t last_periodic_enable;
|
||||||
|
u32 command;
|
||||||
|
|
||||||
|
/* SILICON QUIRKS */
|
||||||
|
unsigned no_selective_suspend:1;
|
||||||
|
unsigned has_fsl_port_bug:1; /* FreeScale */
|
||||||
|
unsigned has_fsl_hs_errata:1; /* Freescale HS quirk */
|
||||||
|
unsigned has_fsl_susp_errata:1; /* NXP SUSP quirk */
|
||||||
|
unsigned big_endian_mmio:1;
|
||||||
|
unsigned big_endian_desc:1;
|
||||||
|
unsigned big_endian_capbase:1;
|
||||||
|
unsigned has_amcc_usb23:1;
|
||||||
|
unsigned need_io_watchdog:1;
|
||||||
|
unsigned amd_pll_fix:1;
|
||||||
|
unsigned use_dummy_qh:1; /* AMD Frame List table quirk*/
|
||||||
|
unsigned has_synopsys_hc_bug:1; /* Synopsys HC */
|
||||||
|
unsigned frame_index_bug:1; /* MosChip (AKA NetMos) */
|
||||||
|
unsigned need_oc_pp_cycle:1; /* MPC834X port power */
|
||||||
|
unsigned imx28_write_fix:1; /* For Freescale i.MX28 */
|
||||||
|
|
||||||
|
/* required for usb32 quirk */
|
||||||
|
#define OHCI_CTRL_HCFS (3 << 6)
|
||||||
|
#define OHCI_USB_OPER (2 << 6)
|
||||||
|
#define OHCI_USB_SUSPEND (3 << 6)
|
||||||
|
|
||||||
|
#define OHCI_HCCTRL_OFFSET 0x4
|
||||||
|
#define OHCI_HCCTRL_LEN 0x4
|
||||||
|
__hc32 *ohci_hcctrl_reg;
|
||||||
|
unsigned has_hostpc:1;
|
||||||
|
unsigned has_tdi_phy_lpm:1;
|
||||||
|
unsigned has_ppcd:1; /* support per-port change bits */
|
||||||
|
u8 sbrn; /* packed release number */
|
||||||
|
|
||||||
|
/* irq statistics */
|
||||||
|
#ifdef EHCI_STATS
|
||||||
|
struct ehci_stats stats;
|
||||||
|
# define COUNT(x) ((x)++)
|
||||||
|
#else
|
||||||
|
# define COUNT(x)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* debug files */
|
||||||
|
#ifdef CONFIG_DYNAMIC_DEBUG
|
||||||
|
struct dentry *debug_dir;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* bandwidth usage */
|
||||||
|
#define EHCI_BANDWIDTH_SIZE 64
|
||||||
|
#define EHCI_BANDWIDTH_FRAMES (EHCI_BANDWIDTH_SIZE >> 3)
|
||||||
|
u8 bandwidth[EHCI_BANDWIDTH_SIZE];
|
||||||
|
/* us allocated per uframe */
|
||||||
|
u8 tt_budget[EHCI_BANDWIDTH_SIZE];
|
||||||
|
/* us budgeted per uframe */
|
||||||
|
struct list_head tt_list;
|
||||||
|
|
||||||
|
/* platform-specific data -- must come last */
|
||||||
|
unsigned long priv[0] __aligned(sizeof(s64));
|
||||||
|
};
|
||||||
|
|
||||||
|
/* convert between an HCD pointer and the corresponding EHCI_HCD */
|
||||||
|
static inline struct ehci_hcd *hcd_to_ehci(struct usb_hcd *hcd)
|
||||||
|
{
|
||||||
|
return (struct ehci_hcd *) (hcd->hcd_priv);
|
||||||
|
}
|
||||||
|
static inline struct usb_hcd *ehci_to_hcd(struct ehci_hcd *ehci)
|
||||||
|
{
|
||||||
|
return container_of((void *) ehci, struct usb_hcd, hcd_priv);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include <linux/usb/ehci_def.h>
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#define QTD_NEXT(ehci, dma) cpu_to_hc32(ehci, (u32)dma)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* EHCI Specification 0.95 Section 3.5
|
||||||
|
* QTD: describe data transfer components (buffer, direction, ...)
|
||||||
|
* See Fig 3-6 "Queue Element Transfer Descriptor Block Diagram".
|
||||||
|
*
|
||||||
|
* These are associated only with "QH" (Queue Head) structures,
|
||||||
|
* used with control, bulk, and interrupt transfers.
|
||||||
|
*/
|
||||||
|
struct ehci_qtd {
|
||||||
|
/* first part defined by EHCI spec */
|
||||||
|
__hc32 hw_next; /* see EHCI 3.5.1 */
|
||||||
|
__hc32 hw_alt_next; /* see EHCI 3.5.2 */
|
||||||
|
__hc32 hw_token; /* see EHCI 3.5.3 */
|
||||||
|
#define QTD_TOGGLE (1 << 31) /* data toggle */
|
||||||
|
#define QTD_LENGTH(tok) (((tok)>>16) & 0x7fff)
|
||||||
|
#define QTD_IOC (1 << 15) /* interrupt on complete */
|
||||||
|
#define QTD_CERR(tok) (((tok)>>10) & 0x3)
|
||||||
|
#define QTD_PID(tok) (((tok)>>8) & 0x3)
|
||||||
|
#define QTD_STS_ACTIVE (1 << 7) /* HC may execute this */
|
||||||
|
#define QTD_STS_HALT (1 << 6) /* halted on error */
|
||||||
|
#define QTD_STS_DBE (1 << 5) /* data buffer error (in HC) */
|
||||||
|
#define QTD_STS_BABBLE (1 << 4) /* device was babbling (qtd halted) */
|
||||||
|
#define QTD_STS_XACT (1 << 3) /* device gave illegal response */
|
||||||
|
#define QTD_STS_MMF (1 << 2) /* incomplete split transaction */
|
||||||
|
#define QTD_STS_STS (1 << 1) /* split transaction state */
|
||||||
|
#define QTD_STS_PING (1 << 0) /* issue PING? */
|
||||||
|
|
||||||
|
#define ACTIVE_BIT(ehci) cpu_to_hc32(ehci, QTD_STS_ACTIVE)
|
||||||
|
#define HALT_BIT(ehci) cpu_to_hc32(ehci, QTD_STS_HALT)
|
||||||
|
#define STATUS_BIT(ehci) cpu_to_hc32(ehci, QTD_STS_STS)
|
||||||
|
|
||||||
|
__hc32 hw_buf[5]; /* see EHCI 3.5.4 */
|
||||||
|
__hc32 hw_buf_hi[5]; /* Appendix B */
|
||||||
|
|
||||||
|
/* the rest is HCD-private */
|
||||||
|
dma_addr_t qtd_dma; /* qtd address */
|
||||||
|
struct list_head qtd_list; /* sw qtd list */
|
||||||
|
struct urb *urb; /* qtd's urb */
|
||||||
|
size_t length; /* length of buffer */
|
||||||
|
} __aligned(32);
|
||||||
|
|
||||||
|
/* mask NakCnt+T in qh->hw_alt_next */
|
||||||
|
#define QTD_MASK(ehci) cpu_to_hc32(ehci, ~0x1f)
|
||||||
|
|
||||||
|
#define IS_SHORT_READ(token) (QTD_LENGTH(token) != 0 && QTD_PID(token) == 1)
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* type tag from {qh,itd,sitd,fstn}->hw_next */
|
||||||
|
#define Q_NEXT_TYPE(ehci, dma) ((dma) & cpu_to_hc32(ehci, 3 << 1))
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Now the following defines are not converted using the
|
||||||
|
* cpu_to_le32() macro anymore, since we have to support
|
||||||
|
* "dynamic" switching between be and le support, so that the driver
|
||||||
|
* can be used on one system with SoC EHCI controller using big-endian
|
||||||
|
* descriptors as well as a normal little-endian PCI EHCI controller.
|
||||||
|
*/
|
||||||
|
/* values for that type tag */
|
||||||
|
#define Q_TYPE_ITD (0 << 1)
|
||||||
|
#define Q_TYPE_QH (1 << 1)
|
||||||
|
#define Q_TYPE_SITD (2 << 1)
|
||||||
|
#define Q_TYPE_FSTN (3 << 1)
|
||||||
|
|
||||||
|
/* next async queue entry, or pointer to interrupt/periodic QH */
|
||||||
|
#define QH_NEXT(ehci, dma) \
|
||||||
|
(cpu_to_hc32(ehci, (((u32) dma) & ~0x01f) | Q_TYPE_QH))
|
||||||
|
|
||||||
|
/* for periodic/async schedules and qtd lists, mark end of list */
|
||||||
|
#define EHCI_LIST_END(ehci) cpu_to_hc32(ehci, 1) /* "null pointer" to hw */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Entries in periodic shadow table are pointers to one of four kinds
|
||||||
|
* of data structure. That's dictated by the hardware; a type tag is
|
||||||
|
* encoded in the low bits of the hardware's periodic schedule. Use
|
||||||
|
* Q_NEXT_TYPE to get the tag.
|
||||||
|
*
|
||||||
|
* For entries in the async schedule, the type tag always says "qh".
|
||||||
|
*/
|
||||||
|
union ehci_shadow {
|
||||||
|
struct ehci_qh *qh; /* Q_TYPE_QH */
|
||||||
|
struct ehci_itd *itd; /* Q_TYPE_ITD */
|
||||||
|
struct ehci_sitd *sitd; /* Q_TYPE_SITD */
|
||||||
|
struct ehci_fstn *fstn; /* Q_TYPE_FSTN */
|
||||||
|
__hc32 *hw_next; /* (all types) */
|
||||||
|
void *ptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* EHCI Specification 0.95 Section 3.6
|
||||||
|
* QH: describes control/bulk/interrupt endpoints
|
||||||
|
* See Fig 3-7 "Queue Head Structure Layout".
|
||||||
|
*
|
||||||
|
* These appear in both the async and (for interrupt) periodic schedules.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* first part defined by EHCI spec */
|
||||||
|
struct ehci_qh_hw {
|
||||||
|
__hc32 hw_next; /* see EHCI 3.6.1 */
|
||||||
|
__hc32 hw_info1; /* see EHCI 3.6.2 */
|
||||||
|
#define QH_CONTROL_EP (1 << 27) /* FS/LS control endpoint */
|
||||||
|
#define QH_HEAD (1 << 15) /* Head of async reclamation list */
|
||||||
|
#define QH_TOGGLE_CTL (1 << 14) /* Data toggle control */
|
||||||
|
#define QH_HIGH_SPEED (2 << 12) /* Endpoint speed */
|
||||||
|
#define QH_LOW_SPEED (1 << 12)
|
||||||
|
#define QH_FULL_SPEED (0 << 12)
|
||||||
|
#define QH_INACTIVATE (1 << 7) /* Inactivate on next transaction */
|
||||||
|
__hc32 hw_info2; /* see EHCI 3.6.2 */
|
||||||
|
#define QH_SMASK 0x000000ff
|
||||||
|
#define QH_CMASK 0x0000ff00
|
||||||
|
#define QH_HUBADDR 0x007f0000
|
||||||
|
#define QH_HUBPORT 0x3f800000
|
||||||
|
#define QH_MULT 0xc0000000
|
||||||
|
__hc32 hw_current; /* qtd list - see EHCI 3.6.4 */
|
||||||
|
|
||||||
|
/* qtd overlay (hardware parts of a struct ehci_qtd) */
|
||||||
|
__hc32 hw_qtd_next;
|
||||||
|
__hc32 hw_alt_next;
|
||||||
|
__hc32 hw_token;
|
||||||
|
__hc32 hw_buf[5];
|
||||||
|
__hc32 hw_buf_hi[5];
|
||||||
|
} __aligned(32);
|
||||||
|
|
||||||
|
struct ehci_qh {
|
||||||
|
struct ehci_qh_hw *hw; /* Must come first */
|
||||||
|
/* the rest is HCD-private */
|
||||||
|
dma_addr_t qh_dma; /* address of qh */
|
||||||
|
union ehci_shadow qh_next; /* ptr to qh; or periodic */
|
||||||
|
struct list_head qtd_list; /* sw qtd list */
|
||||||
|
struct list_head intr_node; /* list of intr QHs */
|
||||||
|
struct ehci_qtd *dummy;
|
||||||
|
struct list_head unlink_node;
|
||||||
|
struct ehci_per_sched ps; /* scheduling info */
|
||||||
|
|
||||||
|
unsigned unlink_cycle;
|
||||||
|
|
||||||
|
u8 qh_state;
|
||||||
|
#define QH_STATE_LINKED 1 /* HC sees this */
|
||||||
|
#define QH_STATE_UNLINK 2 /* HC may still see this */
|
||||||
|
#define QH_STATE_IDLE 3 /* HC doesn't see this */
|
||||||
|
#define QH_STATE_UNLINK_WAIT 4 /* LINKED and on unlink q */
|
||||||
|
#define QH_STATE_COMPLETING 5 /* don't touch token.HALT */
|
||||||
|
|
||||||
|
u8 xacterrs; /* XactErr retry counter */
|
||||||
|
#define QH_XACTERR_MAX 32 /* XactErr retry limit */
|
||||||
|
|
||||||
|
u8 unlink_reason;
|
||||||
|
#define QH_UNLINK_HALTED 0x01 /* Halt flag is set */
|
||||||
|
#define QH_UNLINK_SHORT_READ 0x02 /* Recover from a short read */
|
||||||
|
#define QH_UNLINK_DUMMY_OVERLAY 0x04 /* QH overlayed the dummy TD */
|
||||||
|
#define QH_UNLINK_SHUTDOWN 0x08 /* The HC isn't running */
|
||||||
|
#define QH_UNLINK_QUEUE_EMPTY 0x10 /* Reached end of the queue */
|
||||||
|
#define QH_UNLINK_REQUESTED 0x20 /* Disable, reset, or dequeue */
|
||||||
|
|
||||||
|
u8 gap_uf; /* uframes split/csplit gap */
|
||||||
|
|
||||||
|
unsigned is_out:1; /* bulk or intr OUT */
|
||||||
|
unsigned clearing_tt:1; /* Clear-TT-Buf in progress */
|
||||||
|
unsigned dequeue_during_giveback:1;
|
||||||
|
unsigned should_be_inactive:1;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* description of one iso transaction (up to 3 KB data if highspeed) */
|
||||||
|
struct ehci_iso_packet {
|
||||||
|
/* These will be copied to iTD when scheduling */
|
||||||
|
u64 bufp; /* itd->hw_bufp{,_hi}[pg] |= */
|
||||||
|
__hc32 transaction; /* itd->hw_transaction[i] |= */
|
||||||
|
u8 cross; /* buf crosses pages */
|
||||||
|
/* for full speed OUT splits */
|
||||||
|
u32 buf1;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* temporary schedule data for packets from iso urbs (both speeds)
|
||||||
|
* each packet is one logical usb transaction to the device (not TT),
|
||||||
|
* beginning at stream->next_uframe
|
||||||
|
*/
|
||||||
|
struct ehci_iso_sched {
|
||||||
|
struct list_head td_list;
|
||||||
|
unsigned span;
|
||||||
|
unsigned first_packet;
|
||||||
|
struct ehci_iso_packet packet[0];
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ehci_iso_stream - groups all (s)itds for this endpoint.
|
||||||
|
* acts like a qh would, if EHCI had them for ISO.
|
||||||
|
*/
|
||||||
|
struct ehci_iso_stream {
|
||||||
|
/* first field matches ehci_hq, but is NULL */
|
||||||
|
struct ehci_qh_hw *hw;
|
||||||
|
|
||||||
|
u8 bEndpointAddress;
|
||||||
|
u8 highspeed;
|
||||||
|
struct list_head td_list; /* queued itds/sitds */
|
||||||
|
struct list_head free_list; /* list of unused itds/sitds */
|
||||||
|
|
||||||
|
/* output of (re)scheduling */
|
||||||
|
struct ehci_per_sched ps; /* scheduling info */
|
||||||
|
unsigned next_uframe;
|
||||||
|
__hc32 splits;
|
||||||
|
|
||||||
|
/* the rest is derived from the endpoint descriptor,
|
||||||
|
* including the extra info for hw_bufp[0..2]
|
||||||
|
*/
|
||||||
|
u16 uperiod; /* period in uframes */
|
||||||
|
u16 maxp;
|
||||||
|
unsigned bandwidth;
|
||||||
|
|
||||||
|
/* This is used to initialize iTD's hw_bufp fields */
|
||||||
|
__hc32 buf0;
|
||||||
|
__hc32 buf1;
|
||||||
|
__hc32 buf2;
|
||||||
|
|
||||||
|
/* this is used to initialize sITD's tt info */
|
||||||
|
__hc32 address;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* EHCI Specification 0.95 Section 3.3
|
||||||
|
* Fig 3-4 "Isochronous Transaction Descriptor (iTD)"
|
||||||
|
*
|
||||||
|
* Schedule records for high speed iso xfers
|
||||||
|
*/
|
||||||
|
struct ehci_itd {
|
||||||
|
/* first part defined by EHCI spec */
|
||||||
|
__hc32 hw_next; /* see EHCI 3.3.1 */
|
||||||
|
__hc32 hw_transaction[8]; /* see EHCI 3.3.2 */
|
||||||
|
#define EHCI_ISOC_ACTIVE (1<<31) /* activate transfer this slot */
|
||||||
|
#define EHCI_ISOC_BUF_ERR (1<<30) /* Data buffer error */
|
||||||
|
#define EHCI_ISOC_BABBLE (1<<29) /* babble detected */
|
||||||
|
#define EHCI_ISOC_XACTERR (1<<28) /* XactErr - transaction error */
|
||||||
|
#define EHCI_ITD_LENGTH(tok) (((tok)>>16) & 0x0fff)
|
||||||
|
#define EHCI_ITD_IOC (1 << 15) /* interrupt on complete */
|
||||||
|
|
||||||
|
#define ITD_ACTIVE(ehci) cpu_to_hc32(ehci, EHCI_ISOC_ACTIVE)
|
||||||
|
|
||||||
|
__hc32 hw_bufp[7]; /* see EHCI 3.3.3 */
|
||||||
|
__hc32 hw_bufp_hi[7]; /* Appendix B */
|
||||||
|
|
||||||
|
/* the rest is HCD-private */
|
||||||
|
dma_addr_t itd_dma; /* for this itd */
|
||||||
|
union ehci_shadow itd_next; /* ptr to periodic q entry */
|
||||||
|
|
||||||
|
struct urb *urb;
|
||||||
|
struct ehci_iso_stream *stream; /* endpoint's queue */
|
||||||
|
struct list_head itd_list; /* list of stream's itds */
|
||||||
|
|
||||||
|
/* any/all hw_transactions here may be used by that urb */
|
||||||
|
unsigned frame; /* where scheduled */
|
||||||
|
unsigned pg;
|
||||||
|
unsigned index[8]; /* in urb->iso_frame_desc */
|
||||||
|
} __aligned(32);
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* EHCI Specification 0.95 Section 3.4
|
||||||
|
* siTD, aka split-transaction isochronous Transfer Descriptor
|
||||||
|
* ... describe full speed iso xfers through TT in hubs
|
||||||
|
* see Figure 3-5 "Split-transaction Isochronous Transaction Descriptor (siTD)
|
||||||
|
*/
|
||||||
|
struct ehci_sitd {
|
||||||
|
/* first part defined by EHCI spec */
|
||||||
|
__hc32 hw_next;
|
||||||
|
/* uses bit field macros above - see EHCI 0.95 Table 3-8 */
|
||||||
|
__hc32 hw_fullspeed_ep; /* EHCI table 3-9 */
|
||||||
|
__hc32 hw_uframe; /* EHCI table 3-10 */
|
||||||
|
__hc32 hw_results; /* EHCI table 3-11 */
|
||||||
|
#define SITD_IOC (1 << 31) /* interrupt on completion */
|
||||||
|
#define SITD_PAGE (1 << 30) /* buffer 0/1 */
|
||||||
|
#define SITD_LENGTH(x) (((x) >> 16) & 0x3ff)
|
||||||
|
#define SITD_STS_ACTIVE (1 << 7) /* HC may execute this */
|
||||||
|
#define SITD_STS_ERR (1 << 6) /* error from TT */
|
||||||
|
#define SITD_STS_DBE (1 << 5) /* data buffer error (in HC) */
|
||||||
|
#define SITD_STS_BABBLE (1 << 4) /* device was babbling */
|
||||||
|
#define SITD_STS_XACT (1 << 3) /* illegal IN response */
|
||||||
|
#define SITD_STS_MMF (1 << 2) /* incomplete split transaction */
|
||||||
|
#define SITD_STS_STS (1 << 1) /* split transaction state */
|
||||||
|
|
||||||
|
#define SITD_ACTIVE(ehci) cpu_to_hc32(ehci, SITD_STS_ACTIVE)
|
||||||
|
|
||||||
|
__hc32 hw_buf[2]; /* EHCI table 3-12 */
|
||||||
|
__hc32 hw_backpointer; /* EHCI table 3-13 */
|
||||||
|
__hc32 hw_buf_hi[2]; /* Appendix B */
|
||||||
|
|
||||||
|
/* the rest is HCD-private */
|
||||||
|
dma_addr_t sitd_dma;
|
||||||
|
union ehci_shadow sitd_next; /* ptr to periodic q entry */
|
||||||
|
|
||||||
|
struct urb *urb;
|
||||||
|
struct ehci_iso_stream *stream; /* endpoint's queue */
|
||||||
|
struct list_head sitd_list; /* list of stream's sitds */
|
||||||
|
unsigned frame;
|
||||||
|
unsigned index;
|
||||||
|
} __aligned(32);
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* EHCI Specification 0.96 Section 3.7
|
||||||
|
* Periodic Frame Span Traversal Node (FSTN)
|
||||||
|
*
|
||||||
|
* Manages split interrupt transactions (using TT) that span frame boundaries
|
||||||
|
* into uframes 0/1; see 4.12.2.2. In those uframes, a "save place" FSTN
|
||||||
|
* makes the HC jump (back) to a QH to scan for fs/ls QH completions until
|
||||||
|
* it hits a "restore" FSTN; then it returns to finish other uframe 0/1 work.
|
||||||
|
*/
|
||||||
|
struct ehci_fstn {
|
||||||
|
__hc32 hw_next; /* any periodic q entry */
|
||||||
|
__hc32 hw_prev; /* qh or EHCI_LIST_END */
|
||||||
|
|
||||||
|
/* the rest is HCD-private */
|
||||||
|
dma_addr_t fstn_dma;
|
||||||
|
union ehci_shadow fstn_next; /* ptr to periodic q entry */
|
||||||
|
} __aligned(32);
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* USB-2.0 Specification Sections 11.14 and 11.18
|
||||||
|
* Scheduling and budgeting split transactions using TTs
|
||||||
|
*
|
||||||
|
* A hub can have a single TT for all its ports, or multiple TTs (one for each
|
||||||
|
* port). The bandwidth and budgeting information for the full/low-speed bus
|
||||||
|
* below each TT is self-contained and independent of the other TTs or the
|
||||||
|
* high-speed bus.
|
||||||
|
*
|
||||||
|
* "Bandwidth" refers to the number of microseconds on the FS/LS bus allocated
|
||||||
|
* to an interrupt or isochronous endpoint for each frame. "Budget" refers to
|
||||||
|
* the best-case estimate of the number of full-speed bytes allocated to an
|
||||||
|
* endpoint for each microframe within an allocated frame.
|
||||||
|
*
|
||||||
|
* Removal of an endpoint invalidates a TT's budget. Instead of trying to
|
||||||
|
* keep an up-to-date record, we recompute the budget when it is needed.
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct ehci_tt {
|
||||||
|
u16 bandwidth[EHCI_BANDWIDTH_FRAMES];
|
||||||
|
|
||||||
|
struct list_head tt_list; /* List of all ehci_tt's */
|
||||||
|
struct list_head ps_list; /* Items using this TT */
|
||||||
|
struct usb_tt *usb_tt;
|
||||||
|
int tt_port; /* TT port number */
|
||||||
|
};
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Prepare the PORTSC wakeup flags during controller suspend/resume */
|
||||||
|
|
||||||
|
#define ehci_prepare_ports_for_controller_suspend(ehci, do_wakeup) \
|
||||||
|
ehci_adjust_port_wakeup_flags(ehci, true, do_wakeup)
|
||||||
|
|
||||||
|
#define ehci_prepare_ports_for_controller_resume(ehci) \
|
||||||
|
ehci_adjust_port_wakeup_flags(ehci, false, false)
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifdef CONFIG_USB_EHCI_ROOT_HUB_TT
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Some EHCI controllers have a Transaction Translator built into the
|
||||||
|
* root hub. This is a non-standard feature. Each controller will need
|
||||||
|
* to add code to the following inline functions, and call them as
|
||||||
|
* needed (mostly in root hub code).
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define ehci_is_TDI(e) (ehci_to_hcd(e)->has_tt)
|
||||||
|
|
||||||
|
/* Returns the speed of a device attached to a port on the root hub. */
|
||||||
|
static inline unsigned int
|
||||||
|
ehci_port_speed(struct ehci_hcd *ehci, unsigned int portsc)
|
||||||
|
{
|
||||||
|
if (ehci_is_TDI(ehci)) {
|
||||||
|
switch ((portsc >> (ehci->has_hostpc ? 25 : 26)) & 3) {
|
||||||
|
case 0:
|
||||||
|
return 0;
|
||||||
|
case 1:
|
||||||
|
return USB_PORT_STAT_LOW_SPEED;
|
||||||
|
case 2:
|
||||||
|
default:
|
||||||
|
return USB_PORT_STAT_HIGH_SPEED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return USB_PORT_STAT_HIGH_SPEED;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define ehci_is_TDI(e) (0)
|
||||||
|
|
||||||
|
#define ehci_port_speed(ehci, portsc) USB_PORT_STAT_HIGH_SPEED
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifdef CONFIG_PPC_83xx
|
||||||
|
/* Some Freescale processors have an erratum in which the TT
|
||||||
|
* port number in the queue head was 0..N-1 instead of 1..N.
|
||||||
|
*/
|
||||||
|
#define ehci_has_fsl_portno_bug(e) ((e)->has_fsl_port_bug)
|
||||||
|
#else
|
||||||
|
#define ehci_has_fsl_portno_bug(e) (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define PORTSC_FSL_PFSC 24 /* Port Force Full-Speed Connect */
|
||||||
|
|
||||||
|
#if defined(CONFIG_PPC_85xx)
|
||||||
|
/* Some Freescale processors have an erratum (USB A-005275) in which
|
||||||
|
* incoming packets get corrupted in HS mode
|
||||||
|
*/
|
||||||
|
#define ehci_has_fsl_hs_errata(e) ((e)->has_fsl_hs_errata)
|
||||||
|
#else
|
||||||
|
#define ehci_has_fsl_hs_errata(e) (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Some Freescale/NXP processors have an erratum (USB A-005697)
|
||||||
|
* in which we need to wait for 10ms for bus to enter suspend mode
|
||||||
|
* after setting SUSP bit.
|
||||||
|
*/
|
||||||
|
#define ehci_has_fsl_susp_errata(e) ((e)->has_fsl_susp_errata)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* While most USB host controllers implement their registers in
|
||||||
|
* little-endian format, a minority (celleb companion chip) implement
|
||||||
|
* them in big endian format.
|
||||||
|
*
|
||||||
|
* This attempts to support either format at compile time without a
|
||||||
|
* runtime penalty, or both formats with the additional overhead
|
||||||
|
* of checking a flag bit.
|
||||||
|
*
|
||||||
|
* ehci_big_endian_capbase is a special quirk for controllers that
|
||||||
|
* implement the HC capability registers as separate registers and not
|
||||||
|
* as fields of a 32-bit register.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef CONFIG_USB_EHCI_BIG_ENDIAN_MMIO
|
||||||
|
#define ehci_big_endian_mmio(e) ((e)->big_endian_mmio)
|
||||||
|
#define ehci_big_endian_capbase(e) ((e)->big_endian_capbase)
|
||||||
|
#else
|
||||||
|
#define ehci_big_endian_mmio(e) 0
|
||||||
|
#define ehci_big_endian_capbase(e) 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Big-endian read/write functions are arch-specific.
|
||||||
|
* Other arches can be added if/when they're needed.
|
||||||
|
*/
|
||||||
|
#if defined(CONFIG_ARM) && defined(CONFIG_ARCH_IXP4XX)
|
||||||
|
#define readl_be(addr) __raw_readl((__force unsigned *)addr)
|
||||||
|
#define writel_be(val, addr) __raw_writel(val, (__force unsigned *)addr)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static inline unsigned int ehci_readl(const struct ehci_hcd *ehci,
|
||||||
|
__u32 __iomem *regs)
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_USB_EHCI_BIG_ENDIAN_MMIO
|
||||||
|
return ehci_big_endian_mmio(ehci) ?
|
||||||
|
readl_be(regs) :
|
||||||
|
readl(regs);
|
||||||
|
#else
|
||||||
|
return readl(regs);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_SOC_IMX28
|
||||||
|
static inline void imx28_ehci_writel(const unsigned int val,
|
||||||
|
volatile __u32 __iomem *addr)
|
||||||
|
{
|
||||||
|
__asm__ ("swp %0, %0, [%1]" : : "r"(val), "r"(addr));
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
static inline void imx28_ehci_writel(const unsigned int val,
|
||||||
|
volatile __u32 __iomem *addr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
static inline void ehci_writel(const struct ehci_hcd *ehci,
|
||||||
|
const unsigned int val, __u32 __iomem *regs)
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_USB_EHCI_BIG_ENDIAN_MMIO
|
||||||
|
ehci_big_endian_mmio(ehci) ?
|
||||||
|
writel_be(val, regs) :
|
||||||
|
writel(val, regs);
|
||||||
|
#else
|
||||||
|
if (ehci->imx28_write_fix)
|
||||||
|
imx28_ehci_writel(val, regs);
|
||||||
|
else
|
||||||
|
writel(val, regs);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* On certain ppc-44x SoC there is a HW issue, that could only worked around with
|
||||||
|
* explicit suspend/operate of OHCI. This function hereby makes sense only on that arch.
|
||||||
|
* Other common bits are dependent on has_amcc_usb23 quirk flag.
|
||||||
|
*/
|
||||||
|
#ifdef CONFIG_44x
|
||||||
|
static inline void set_ohci_hcfs(struct ehci_hcd *ehci, int operational)
|
||||||
|
{
|
||||||
|
u32 hc_control;
|
||||||
|
|
||||||
|
hc_control = (readl_be(ehci->ohci_hcctrl_reg) & ~OHCI_CTRL_HCFS);
|
||||||
|
if (operational)
|
||||||
|
hc_control |= OHCI_USB_OPER;
|
||||||
|
else
|
||||||
|
hc_control |= OHCI_USB_SUSPEND;
|
||||||
|
|
||||||
|
writel_be(hc_control, ehci->ohci_hcctrl_reg);
|
||||||
|
(void) readl_be(ehci->ohci_hcctrl_reg);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
static inline void set_ohci_hcfs(struct ehci_hcd *ehci, int operational)
|
||||||
|
{ }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The AMCC 440EPx not only implements its EHCI registers in big-endian
|
||||||
|
* format, but also its DMA data structures (descriptors).
|
||||||
|
*
|
||||||
|
* EHCI controllers accessed through PCI work normally (little-endian
|
||||||
|
* everywhere), so we won't bother supporting a BE-only mode for now.
|
||||||
|
*/
|
||||||
|
#ifdef CONFIG_USB_EHCI_BIG_ENDIAN_DESC
|
||||||
|
#define ehci_big_endian_desc(e) ((e)->big_endian_desc)
|
||||||
|
|
||||||
|
/* cpu to ehci */
|
||||||
|
static inline __hc32 cpu_to_hc32(const struct ehci_hcd *ehci, const u32 x)
|
||||||
|
{
|
||||||
|
return ehci_big_endian_desc(ehci)
|
||||||
|
? (__force __hc32)cpu_to_be32(x)
|
||||||
|
: (__force __hc32)cpu_to_le32(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ehci to cpu */
|
||||||
|
static inline u32 hc32_to_cpu(const struct ehci_hcd *ehci, const __hc32 x)
|
||||||
|
{
|
||||||
|
return ehci_big_endian_desc(ehci)
|
||||||
|
? be32_to_cpu((__force __be32)x)
|
||||||
|
: le32_to_cpu((__force __le32)x);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline u32 hc32_to_cpup(const struct ehci_hcd *ehci, const __hc32 *x)
|
||||||
|
{
|
||||||
|
return ehci_big_endian_desc(ehci)
|
||||||
|
? be32_to_cpup((__force __be32 *)x)
|
||||||
|
: le32_to_cpup((__force __le32 *)x);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
/* cpu to ehci */
|
||||||
|
static inline __hc32 cpu_to_hc32(const struct ehci_hcd *ehci, const u32 x)
|
||||||
|
{
|
||||||
|
return cpu_to_le32(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ehci to cpu */
|
||||||
|
static inline u32 hc32_to_cpu(const struct ehci_hcd *ehci, const __hc32 x)
|
||||||
|
{
|
||||||
|
return le32_to_cpu(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline u32 hc32_to_cpup(const struct ehci_hcd *ehci, const __hc32 *x)
|
||||||
|
{
|
||||||
|
return le32_to_cpup(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#define ehci_dbg(ehci, fmt, args...) \
|
||||||
|
dev_dbg(ehci_to_hcd(ehci)->self.controller, fmt, ## args)
|
||||||
|
#define ehci_err(ehci, fmt, args...) \
|
||||||
|
dev_err(ehci_to_hcd(ehci)->self.controller, fmt, ## args)
|
||||||
|
#define ehci_info(ehci, fmt, args...) \
|
||||||
|
dev_info(ehci_to_hcd(ehci)->self.controller, fmt, ## args)
|
||||||
|
#define ehci_warn(ehci, fmt, args...) \
|
||||||
|
dev_warn(ehci_to_hcd(ehci)->self.controller, fmt, ## args)
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Declarations of things exported for use by ehci platform drivers */
|
||||||
|
|
||||||
|
struct ehci_driver_overrides {
|
||||||
|
size_t extra_priv_size;
|
||||||
|
int (*reset)(struct usb_hcd *hcd);
|
||||||
|
int (*port_power)(struct usb_hcd *hcd,
|
||||||
|
int portnum, bool enable);
|
||||||
|
};
|
||||||
|
|
||||||
|
extern void ehci_init_driver(struct hc_driver *drv,
|
||||||
|
const struct ehci_driver_overrides *over);
|
||||||
|
extern int ehci_setup(struct usb_hcd *hcd);
|
||||||
|
extern int ehci_handshake(struct ehci_hcd *ehci, void __iomem *ptr,
|
||||||
|
u32 mask, u32 done, int usec);
|
||||||
|
extern int ehci_reset(struct ehci_hcd *ehci);
|
||||||
|
|
||||||
|
extern int ehci_suspend(struct usb_hcd *hcd, bool do_wakeup);
|
||||||
|
extern int ehci_resume(struct usb_hcd *hcd, bool force_reset);
|
||||||
|
extern void ehci_adjust_port_wakeup_flags(struct ehci_hcd *ehci,
|
||||||
|
bool suspending, bool do_wakeup);
|
||||||
|
|
||||||
|
extern int ehci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
|
||||||
|
u16 wIndex, char *buf, u16 wLength);
|
||||||
|
|
||||||
|
#endif /* __LINUX_EHCI_HCD_H */
|
1
platform/centec-arm64/tsingma-bsp/src/gpio-ctc/Makefile
Normal file
1
platform/centec-arm64/tsingma-bsp/src/gpio-ctc/Makefile
Normal file
@ -0,0 +1 @@
|
|||||||
|
obj-m = gpio-ctc.o
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user