[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
|
||||
cat files/initramfs-tools/modules.arm | sudo tee -a $FILESYSTEM_ROOT/etc/initramfs-tools/modules > /dev/null
|
||||
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
|
||||
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