mirror of
https://github.com/LuckfoxTECH/luckfox-pico.git
synced 2026-01-19 09:52:31 +01:00
project:build.sh: Added fastboot support; custom modifications to U-Boot and kernel implemented using patches.
project:cfg:BoardConfig_IPC: Added fastboot BoardConfig file and firmware post-scripts, distinguishing between the BoardConfigs for Luckfox Pico Pro and Luckfox Pico Max. project:app: Added fastboot_client and rk_smart_door for quick boot applications; updated rkipc app to adapt to the latest media library. media:samples: Added more usage examples. media:rockit: Fixed bugs; removed support for retrieving data frames from VPSS. media:isp: Updated rkaiq library and related tools to support connection to RKISP_Tuner. sysdrv:Makefile: Added support for compiling drv_ko on Luckfox Pico Ultra W using Ubuntu; added support for custom root filesystem. sysdrv:tools:board: Updated Buildroot optional mirror sources, updated some software versions, and stored device tree files and configuration files that undergo multiple modifications for U-Boot and kernel separately. sysdrv:source:mcu: Used RISC-V MCU SDK with RT-Thread system, mainly for initializing camera AE during quick boot. sysdrv:source:uboot: Added support for fastboot; added high baud rate DDR bin for serial firmware upgrades. sysdrv:source:kernel: Upgraded to version 5.10.160; increased NPU frequency for RV1106G3; added support for fastboot. Signed-off-by: luckfox-eng29 <eng29@luckfox.com>
This commit is contained in:
@@ -101,6 +101,11 @@ struct aer_stats {
|
||||
#define ERR_COR_ID(d) (d & 0xffff)
|
||||
#define ERR_UNCOR_ID(d) (d >> 16)
|
||||
|
||||
#define AER_ERR_STATUS_MASK (PCI_ERR_ROOT_UNCOR_RCV | \
|
||||
PCI_ERR_ROOT_COR_RCV | \
|
||||
PCI_ERR_ROOT_MULTI_COR_RCV | \
|
||||
PCI_ERR_ROOT_MULTI_UNCOR_RCV)
|
||||
|
||||
static int pcie_aer_disable;
|
||||
static pci_ers_result_t aer_root_reset(struct pci_dev *dev);
|
||||
|
||||
@@ -300,7 +305,8 @@ int pci_aer_raw_clear_status(struct pci_dev *dev)
|
||||
return -EIO;
|
||||
|
||||
port_type = pci_pcie_type(dev);
|
||||
if (port_type == PCI_EXP_TYPE_ROOT_PORT) {
|
||||
if (port_type == PCI_EXP_TYPE_ROOT_PORT ||
|
||||
port_type == PCI_EXP_TYPE_RC_EC) {
|
||||
pci_read_config_dword(dev, aer + PCI_ERR_ROOT_STATUS, &status);
|
||||
pci_write_config_dword(dev, aer + PCI_ERR_ROOT_STATUS, status);
|
||||
}
|
||||
@@ -532,7 +538,7 @@ static const char *aer_agent_string[] = {
|
||||
struct pci_dev *pdev = to_pci_dev(dev); \
|
||||
u64 *stats = pdev->aer_stats->stats_array; \
|
||||
\
|
||||
for (i = 0; i < ARRAY_SIZE(strings_array); i++) { \
|
||||
for (i = 0; i < ARRAY_SIZE(pdev->aer_stats->stats_array); i++) {\
|
||||
if (strings_array[i]) \
|
||||
str += sprintf(str, "%s %llu\n", \
|
||||
strings_array[i], stats[i]); \
|
||||
@@ -595,7 +601,8 @@ static umode_t aer_stats_attrs_are_visible(struct kobject *kobj,
|
||||
if ((a == &dev_attr_aer_rootport_total_err_cor.attr ||
|
||||
a == &dev_attr_aer_rootport_total_err_fatal.attr ||
|
||||
a == &dev_attr_aer_rootport_total_err_nonfatal.attr) &&
|
||||
pci_pcie_type(pdev) != PCI_EXP_TYPE_ROOT_PORT)
|
||||
((pci_pcie_type(pdev) != PCI_EXP_TYPE_ROOT_PORT) &&
|
||||
(pci_pcie_type(pdev) != PCI_EXP_TYPE_RC_EC)))
|
||||
return 0;
|
||||
|
||||
return a->mode;
|
||||
@@ -1034,6 +1041,7 @@ EXPORT_SYMBOL_GPL(aer_recover_queue);
|
||||
*/
|
||||
int aer_get_device_error_info(struct pci_dev *dev, struct aer_err_info *info)
|
||||
{
|
||||
int type = pci_pcie_type(dev);
|
||||
int aer = dev->aer_cap;
|
||||
int temp;
|
||||
|
||||
@@ -1052,8 +1060,8 @@ int aer_get_device_error_info(struct pci_dev *dev, struct aer_err_info *info)
|
||||
&info->mask);
|
||||
if (!(info->status & ~info->mask))
|
||||
return 0;
|
||||
} else if (pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT ||
|
||||
pci_pcie_type(dev) == PCI_EXP_TYPE_DOWNSTREAM ||
|
||||
} else if (type == PCI_EXP_TYPE_ROOT_PORT ||
|
||||
type == PCI_EXP_TYPE_DOWNSTREAM ||
|
||||
info->severity == AER_NONFATAL) {
|
||||
|
||||
/* Link is still healthy for IO reads */
|
||||
@@ -1187,7 +1195,7 @@ static irqreturn_t aer_irq(int irq, void *context)
|
||||
struct aer_err_source e_src = {};
|
||||
|
||||
pci_read_config_dword(rp, aer + PCI_ERR_ROOT_STATUS, &e_src.status);
|
||||
if (!(e_src.status & (PCI_ERR_ROOT_UNCOR_RCV|PCI_ERR_ROOT_COR_RCV)))
|
||||
if (!(e_src.status & AER_ERR_STATUS_MASK))
|
||||
return IRQ_NONE;
|
||||
|
||||
pci_read_config_dword(rp, aer + PCI_ERR_ROOT_ERR_SRC, &e_src.id);
|
||||
@@ -1205,6 +1213,7 @@ static int set_device_error_reporting(struct pci_dev *dev, void *data)
|
||||
int type = pci_pcie_type(dev);
|
||||
|
||||
if ((type == PCI_EXP_TYPE_ROOT_PORT) ||
|
||||
(type == PCI_EXP_TYPE_RC_EC) ||
|
||||
(type == PCI_EXP_TYPE_UPSTREAM) ||
|
||||
(type == PCI_EXP_TYPE_DOWNSTREAM)) {
|
||||
if (enable)
|
||||
@@ -1329,6 +1338,16 @@ static int aer_probe(struct pcie_device *dev)
|
||||
struct device *device = &dev->device;
|
||||
struct pci_dev *port = dev->port;
|
||||
|
||||
BUILD_BUG_ON(ARRAY_SIZE(aer_correctable_error_string) <
|
||||
AER_MAX_TYPEOF_COR_ERRS);
|
||||
BUILD_BUG_ON(ARRAY_SIZE(aer_uncorrectable_error_string) <
|
||||
AER_MAX_TYPEOF_UNCOR_ERRS);
|
||||
|
||||
/* Limit to Root Ports or Root Complex Event Collectors */
|
||||
if ((pci_pcie_type(port) != PCI_EXP_TYPE_RC_EC) &&
|
||||
(pci_pcie_type(port) != PCI_EXP_TYPE_ROOT_PORT))
|
||||
return -ENODEV;
|
||||
|
||||
rpc = devm_kzalloc(device, sizeof(struct aer_rpc), GFP_KERNEL);
|
||||
if (!rpc)
|
||||
return -ENOMEM;
|
||||
@@ -1350,41 +1369,60 @@ static int aer_probe(struct pcie_device *dev)
|
||||
}
|
||||
|
||||
/**
|
||||
* aer_root_reset - reset link on Root Port
|
||||
* @dev: pointer to Root Port's pci_dev data structure
|
||||
* aer_root_reset - reset Root Port hierarchy or RCEC
|
||||
* @dev: pointer to Root Port or RCEC
|
||||
*
|
||||
* Invoked by Port Bus driver when performing link reset at Root Port.
|
||||
* Invoked by Port Bus driver when performing reset.
|
||||
*/
|
||||
static pci_ers_result_t aer_root_reset(struct pci_dev *dev)
|
||||
{
|
||||
int aer = dev->aer_cap;
|
||||
int type = pci_pcie_type(dev);
|
||||
struct pci_dev *root;
|
||||
int aer;
|
||||
struct pci_host_bridge *host = pci_find_host_bridge(dev->bus);
|
||||
u32 reg32;
|
||||
int rc;
|
||||
|
||||
root = dev; /* device with Root Error registers */
|
||||
aer = root->aer_cap;
|
||||
|
||||
/* Disable Root's interrupt in response to error messages */
|
||||
pci_read_config_dword(dev, aer + PCI_ERR_ROOT_COMMAND, ®32);
|
||||
reg32 &= ~ROOT_PORT_INTR_ON_MESG_MASK;
|
||||
pci_write_config_dword(dev, aer + PCI_ERR_ROOT_COMMAND, reg32);
|
||||
if ((host->native_aer || pcie_ports_native) && aer) {
|
||||
/* Disable Root's interrupt in response to error messages */
|
||||
pci_read_config_dword(root, aer + PCI_ERR_ROOT_COMMAND, ®32);
|
||||
reg32 &= ~ROOT_PORT_INTR_ON_MESG_MASK;
|
||||
pci_write_config_dword(root, aer + PCI_ERR_ROOT_COMMAND, reg32);
|
||||
}
|
||||
|
||||
rc = pci_bus_error_reset(dev);
|
||||
pci_info(dev, "Root Port link has been reset\n");
|
||||
if (type == PCI_EXP_TYPE_RC_EC) {
|
||||
if (pcie_has_flr(dev)) {
|
||||
rc = pcie_flr(dev);
|
||||
pci_info(dev, "has been reset (%d)\n", rc);
|
||||
} else {
|
||||
pci_info(dev, "not reset (no FLR support)\n");
|
||||
rc = -ENOTTY;
|
||||
}
|
||||
} else {
|
||||
rc = pci_bus_error_reset(dev);
|
||||
pci_info(dev, "Root Port link has been reset (%d)\n", rc);
|
||||
}
|
||||
|
||||
/* Clear Root Error Status */
|
||||
pci_read_config_dword(dev, aer + PCI_ERR_ROOT_STATUS, ®32);
|
||||
pci_write_config_dword(dev, aer + PCI_ERR_ROOT_STATUS, reg32);
|
||||
if ((host->native_aer || pcie_ports_native) && aer) {
|
||||
/* Clear Root Error Status */
|
||||
pci_read_config_dword(root, aer + PCI_ERR_ROOT_STATUS, ®32);
|
||||
pci_write_config_dword(root, aer + PCI_ERR_ROOT_STATUS, reg32);
|
||||
|
||||
/* Enable Root Port's interrupt in response to error messages */
|
||||
pci_read_config_dword(dev, aer + PCI_ERR_ROOT_COMMAND, ®32);
|
||||
reg32 |= ROOT_PORT_INTR_ON_MESG_MASK;
|
||||
pci_write_config_dword(dev, aer + PCI_ERR_ROOT_COMMAND, reg32);
|
||||
/* Enable Root Port's interrupt in response to error messages */
|
||||
pci_read_config_dword(root, aer + PCI_ERR_ROOT_COMMAND, ®32);
|
||||
reg32 |= ROOT_PORT_INTR_ON_MESG_MASK;
|
||||
pci_write_config_dword(root, aer + PCI_ERR_ROOT_COMMAND, reg32);
|
||||
}
|
||||
|
||||
return rc ? PCI_ERS_RESULT_DISCONNECT : PCI_ERS_RESULT_RECOVERED;
|
||||
}
|
||||
|
||||
static struct pcie_port_service_driver aerdriver = {
|
||||
.name = "aer",
|
||||
.port_type = PCI_EXP_TYPE_ROOT_PORT,
|
||||
.port_type = PCIE_ANY_PORT,
|
||||
.service = PCIE_PORT_SERVICE_AER,
|
||||
|
||||
.probe = aer_probe,
|
||||
|
||||
@@ -146,38 +146,68 @@ out:
|
||||
return 0;
|
||||
}
|
||||
|
||||
pci_ers_result_t pcie_do_recovery(struct pci_dev *dev,
|
||||
pci_channel_state_t state,
|
||||
pci_ers_result_t (*reset_link)(struct pci_dev *pdev))
|
||||
/**
|
||||
* pci_walk_bridge - walk bridges potentially AER affected
|
||||
* @bridge: bridge which may be a Port or an RCEC
|
||||
* @cb: callback to be called for each device found
|
||||
* @userdata: arbitrary pointer to be passed to callback
|
||||
*
|
||||
* If the device provided is a bridge, walk the subordinate bus, including
|
||||
* any bridged devices on buses under this bus. Call the provided callback
|
||||
* on each device found.
|
||||
*
|
||||
* If the device provided has no subordinate bus, e.g., an RCEC, call the
|
||||
* callback on the device itself.
|
||||
*/
|
||||
static void pci_walk_bridge(struct pci_dev *bridge,
|
||||
int (*cb)(struct pci_dev *, void *),
|
||||
void *userdata)
|
||||
{
|
||||
if (bridge->subordinate)
|
||||
pci_walk_bus(bridge->subordinate, cb, userdata);
|
||||
else
|
||||
cb(bridge, userdata);
|
||||
}
|
||||
|
||||
pci_ers_result_t pcie_do_recovery(struct pci_dev *dev,
|
||||
pci_channel_state_t state,
|
||||
pci_ers_result_t (*reset_subordinates)(struct pci_dev *pdev))
|
||||
{
|
||||
int type = pci_pcie_type(dev);
|
||||
struct pci_dev *bridge;
|
||||
pci_ers_result_t status = PCI_ERS_RESULT_CAN_RECOVER;
|
||||
struct pci_bus *bus;
|
||||
|
||||
/*
|
||||
* Error recovery runs on all subordinates of the first downstream port.
|
||||
* If the downstream port detected the error, it is cleared at the end.
|
||||
* If the error was detected by a Root Port, Downstream Port, or
|
||||
* RCEC, recovery runs on the device itself. For Ports, that also
|
||||
* includes any subordinate devices.
|
||||
*
|
||||
* If it was detected by another device (Endpoint, etc), recovery
|
||||
* runs on the device and anything else under the same Port, i.e.,
|
||||
* everything under "bridge".
|
||||
*/
|
||||
if (!(pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT ||
|
||||
pci_pcie_type(dev) == PCI_EXP_TYPE_DOWNSTREAM))
|
||||
dev = dev->bus->self;
|
||||
bus = dev->subordinate;
|
||||
if (type == PCI_EXP_TYPE_ROOT_PORT ||
|
||||
type == PCI_EXP_TYPE_DOWNSTREAM ||
|
||||
type == PCI_EXP_TYPE_RC_EC)
|
||||
bridge = dev;
|
||||
else
|
||||
bridge = pci_upstream_bridge(dev);
|
||||
|
||||
pci_dbg(dev, "broadcast error_detected message\n");
|
||||
pci_dbg(bridge, "broadcast error_detected message\n");
|
||||
if (state == pci_channel_io_frozen) {
|
||||
pci_walk_bus(bus, report_frozen_detected, &status);
|
||||
status = reset_link(dev);
|
||||
if (status != PCI_ERS_RESULT_RECOVERED) {
|
||||
pci_warn(dev, "link reset failed\n");
|
||||
pci_walk_bridge(bridge, report_frozen_detected, &status);
|
||||
if (reset_subordinates(bridge) != PCI_ERS_RESULT_RECOVERED) {
|
||||
pci_warn(bridge, "subordinate device reset failed\n");
|
||||
goto failed;
|
||||
}
|
||||
} else {
|
||||
pci_walk_bus(bus, report_normal_detected, &status);
|
||||
pci_walk_bridge(bridge, report_normal_detected, &status);
|
||||
}
|
||||
|
||||
if (status == PCI_ERS_RESULT_CAN_RECOVER) {
|
||||
status = PCI_ERS_RESULT_RECOVERED;
|
||||
pci_dbg(dev, "broadcast mmio_enabled message\n");
|
||||
pci_walk_bus(bus, report_mmio_enabled, &status);
|
||||
pci_dbg(bridge, "broadcast mmio_enabled message\n");
|
||||
pci_walk_bridge(bridge, report_mmio_enabled, &status);
|
||||
}
|
||||
|
||||
if (status == PCI_ERS_RESULT_NEED_RESET) {
|
||||
@@ -187,27 +217,27 @@ pci_ers_result_t pcie_do_recovery(struct pci_dev *dev,
|
||||
* drivers' slot_reset callbacks?
|
||||
*/
|
||||
status = PCI_ERS_RESULT_RECOVERED;
|
||||
pci_dbg(dev, "broadcast slot_reset message\n");
|
||||
pci_walk_bus(bus, report_slot_reset, &status);
|
||||
pci_dbg(bridge, "broadcast slot_reset message\n");
|
||||
pci_walk_bridge(bridge, report_slot_reset, &status);
|
||||
}
|
||||
|
||||
if (status != PCI_ERS_RESULT_RECOVERED)
|
||||
goto failed;
|
||||
|
||||
pci_dbg(dev, "broadcast resume message\n");
|
||||
pci_walk_bus(bus, report_resume, &status);
|
||||
pci_dbg(bridge, "broadcast resume message\n");
|
||||
pci_walk_bridge(bridge, report_resume, &status);
|
||||
|
||||
if (pcie_aer_is_native(dev))
|
||||
pcie_clear_device_status(dev);
|
||||
pci_aer_clear_nonfatal_status(dev);
|
||||
pci_info(dev, "device recovery successful\n");
|
||||
if (pcie_aer_is_native(bridge))
|
||||
pcie_clear_device_status(bridge);
|
||||
pci_aer_clear_nonfatal_status(bridge);
|
||||
pci_info(bridge, "device recovery successful\n");
|
||||
return status;
|
||||
|
||||
failed:
|
||||
pci_uevent_ers(dev, PCI_ERS_RESULT_DISCONNECT);
|
||||
pci_uevent_ers(bridge, PCI_ERS_RESULT_DISCONNECT);
|
||||
|
||||
/* TODO: Should kernel panic here? */
|
||||
pci_info(dev, "device recovery failed\n");
|
||||
pci_info(bridge, "device recovery failed\n");
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -101,12 +101,14 @@ static const struct dev_pm_ops pcie_portdrv_pm_ops = {
|
||||
static int pcie_portdrv_probe(struct pci_dev *dev,
|
||||
const struct pci_device_id *id)
|
||||
{
|
||||
int type = pci_pcie_type(dev);
|
||||
int status;
|
||||
|
||||
if (!pci_is_pcie(dev) ||
|
||||
((pci_pcie_type(dev) != PCI_EXP_TYPE_ROOT_PORT) &&
|
||||
(pci_pcie_type(dev) != PCI_EXP_TYPE_UPSTREAM) &&
|
||||
(pci_pcie_type(dev) != PCI_EXP_TYPE_DOWNSTREAM)))
|
||||
((type != PCI_EXP_TYPE_ROOT_PORT) &&
|
||||
(type != PCI_EXP_TYPE_UPSTREAM) &&
|
||||
(type != PCI_EXP_TYPE_DOWNSTREAM) &&
|
||||
(type != PCI_EXP_TYPE_RC_EC)))
|
||||
return -ENODEV;
|
||||
|
||||
status = pcie_port_device_register(dev);
|
||||
@@ -195,6 +197,8 @@ static const struct pci_device_id port_pci_ids[] = {
|
||||
{ PCI_DEVICE_CLASS(((PCI_CLASS_BRIDGE_PCI << 8) | 0x00), ~0) },
|
||||
/* subtractive decode PCI-to-PCI bridge, class type is 060401h */
|
||||
{ PCI_DEVICE_CLASS(((PCI_CLASS_BRIDGE_PCI << 8) | 0x01), ~0) },
|
||||
/* handle any Root Complex Event Collector */
|
||||
{ PCI_DEVICE_CLASS(((PCI_CLASS_SYSTEM_RCEC << 8) | 0x00), ~0) },
|
||||
{ },
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user