V_01-00-43

1. Supported GPIO configuration save and restoration.
This commit is contained in:
TC956X 2022-02-22 16:45:36 +09:00 committed by jianzhou
parent ffcc08ecdb
commit bfc5c6175c
4 changed files with 162 additions and 9 deletions

View File

@ -1,7 +1,7 @@
# Toshiba Electronic Devices & Storage Corporation TC956X PCIe Ethernet Host Driver
Release Date: 14 Feb 2022
Release Date: 22 Feb 2022
Release Version: V_01-00-42 : Limited-tested version
Release Version: V_01-00-43 : Limited-tested version
TC956X PCIe EMAC driver is based on "Fedora 30, kernel-5.4.19".
@ -463,3 +463,8 @@ TC956X PCIe EMAC driver is based on "Fedora 30, kernel-5.4.19".
## TC956X_Host_Driver_20220214_V_01-00-42:
1. Reset assert and clock disable support during Link Down.
## TC956X_Host_Driver_20220222_V_01-00-43:
1. Supported GPIO configuration save and restoration.

View File

@ -134,14 +134,17 @@
* 24 Jan 2022 : 1. Set Clock control and Reset control register to default value on driver unload.
* 2. Version update
* VERSION : 01-00-38
* 31 Jan 2022 : 1. Version update
* 31 Jan 2022 : 1. Version update
* VERSION : 01-00-39
* 02 Feb 2022 : 1. Version update
* 02 Feb 2022 : 1. Version update
* VERSION : 01-00-40
* 04 Feb 2022 : 1. Version update
* 04 Feb 2022 : 1. Version update
* VERSION : 01-00-41
* 14 Feb 2022 : 1. Version update
* 14 Feb 2022 : 1. Version update
* VERSION : 01-00-42
* 22 Feb 2022 : 1. GPIO configuration restoration supported during resume.
* 2. Version update
* VERSION : 01-00-43
*/
#include <linux/clk-provider.h>
@ -206,7 +209,7 @@ static unsigned int mac1_txq1_size = TX_QUEUE1_SIZE;
unsigned int mac0_en_lp_pause_frame_cnt = DISABLE;
unsigned int mac1_en_lp_pause_frame_cnt = DISABLE;
static const struct tc956x_version tc956x_drv_version = {0, 1, 0, 0, 4, 2};
static const struct tc956x_version tc956x_drv_version = {0, 1, 0, 0, 4, 3};
static int tc956xmac_pm_usage_counter; /* Device Usage Counter */
struct mutex tc956x_pm_suspend_lock; /* This mutex is shared between all available EMAC ports. */
@ -3206,6 +3209,11 @@ static int tc956x_pcie_resume(struct device *dev)
tc956xmac_pm_set_power(priv, RESUME);
/* Restore the GPIO settings which was saved during GPIO configuration */
ret = tc956x_gpio_restore_configuration(priv);
if (ret < 0)
KPRINT_INFO("GPIO configuration restoration failed\n");
DBGPR_FUNC(&(pdev->dev), "%s : Port %d - Platform Resume", __func__, priv->port_num);
ret = tc956x_platform_resume(priv);
if (ret) {

View File

@ -132,6 +132,9 @@
* 14 Feb 2022 : 1. Reset assert and clock disable support during Link Down.
* 2. Version update.
* VERSION : 01-00-42
* 22 Feb 2022 : 1. Supported GPIO configuration save and restoration
* 2. Version update.
* VERSION : 01-00-43
*/
#ifndef __TC956XMAC_H__
@ -187,7 +190,7 @@
#define IRQ_DEV_NAME(x) (((x) == RM_PF0_ID) ? ("eth0") : ("eth1"))
#define WOL_IRQ_DEV_NAME(x) (((x) == RM_PF0_ID) ? ("eth0_wol") : ("eth1_wol"))
#define DRV_MODULE_VERSION "V_01-00-42"
#define DRV_MODULE_VERSION "V_01-00-43"
#define TC956X_FW_MAX_SIZE (64*1024)
#define ATR_AXI4_SLV_BASE 0x0800
@ -501,6 +504,11 @@ struct tc956x_cbs_params {
u32 percentage;
};
struct tc956x_gpio_config {
u8 config; /* 1: configured, 0: not configured*/
u8 out_val; /* 0 or 1 */
};
struct tc956xmac_priv {
/* Frequently used values are kept adjacent for cache effect */
u32 tx_coal_frames;
@ -668,6 +676,8 @@ struct tc956xmac_priv {
u32 pm_saved_linkdown_rst; /* Save and restore Resets during link-down sequence */
u32 pm_saved_linkdown_clk; /* Save and restore Clocks during link-down sequence */
bool port_link_down; /* Flag to save per port link down state */
struct tc956x_gpio_config saved_gpio_config[GPIO_12 + 1]; /* Only GPIO0- GPIO06, GPI010-GPIO12 are used */
};
struct tc956x_version {
@ -1032,5 +1042,5 @@ static inline int tc956x_platform_resume(struct tc956xmac_priv *priv) { return 0
#endif
int tc956x_GPIO_OutputConfigPin(struct tc956xmac_priv *priv, u32 gpio_pin, u8 out_value);
int tc956x_gpio_restore_configuration(struct tc956xmac_priv *priv);
#endif /* __TC956XMAC_H__ */

View File

@ -107,6 +107,8 @@
* VERSION : 01-00-41
* 14 Feb 2022 : 1. Reset assert and clock disable support during Link Down.
* VERSION : 01-00-42
* 22 Feb 2022 : 1. Supported GPIO configuration save and restoration
* VERSION : 01-00-43
*/
#include <linux/clk.h>
@ -907,6 +909,8 @@ int tc956x_GPIO_OutputConfigPin(struct tc956xmac_priv *priv, u32 gpio_pin, u8 ou
return -EPERM;
}
priv->saved_gpio_config[gpio_pin].config = 1;
/* Write data to GPIO pin */
if(gpio_pin < GPIO_32) {
config = 1 << gpio_pin;
@ -926,6 +930,8 @@ int tc956x_GPIO_OutputConfigPin(struct tc956xmac_priv *priv, u32 gpio_pin, u8 ou
writel(val, priv->ioaddr + GPIOO1_OFFSET);
}
priv->saved_gpio_config[gpio_pin].out_val = out_value;
/* Configure the GPIO pin in output direction */
if(gpio_pin < GPIO_32) {
config = ~(1 << gpio_pin) ;
@ -940,6 +946,128 @@ int tc956x_GPIO_OutputConfigPin(struct tc956xmac_priv *priv, u32 gpio_pin, u8 ou
return 0;
}
/**
* tc956x_gpio_restore_configuration - to restore the saved configuration of GPIO
* @priv: driver private structure
* @remarks : Only GPIO0- GPIO06, GPI010-GPIO12 are allowed
*/
int tc956x_gpio_restore_configuration(struct tc956xmac_priv *priv)
{
u32 config, val, gpio_pin, out_value;
DBGPR_FUNC(priv->device, "-->%s", __func__);
for (gpio_pin = 0; gpio_pin <= GPIO_12; gpio_pin++) {
/* Restore only the GPIOs which were configured/saved */
if (!(priv->saved_gpio_config[gpio_pin].config))
continue;
DBGPR_FUNC(priv->device, "%s : Restoring GPIO configuration for pin: %d, val: %d",
__func__, gpio_pin, priv->saved_gpio_config[gpio_pin].out_val);
/* Only GPIO0- GPIO06, GPI010-GPIO12 are allowed */
switch (gpio_pin) {
case GPIO_00:
val = readl(priv->ioaddr + NFUNCEN4_OFFSET);
val &= ~NFUNCEN4_GPIO_00;
val |= (NFUNCEN_FUNC0 << NFUNCEN4_GPIO_00_SHIFT);
writel(val, priv->ioaddr + NFUNCEN4_OFFSET);
break;
case GPIO_01:
val = readl(priv->ioaddr + NFUNCEN4_OFFSET);
val &= ~NFUNCEN4_GPIO_01;
val |= (NFUNCEN_FUNC0 << NFUNCEN4_GPIO_01_SHIFT);
writel(val, priv->ioaddr + NFUNCEN4_OFFSET);
break;
case GPIO_02:
val = readl(priv->ioaddr + NFUNCEN4_OFFSET);
val &= ~NFUNCEN4_GPIO_02;
val |= (NFUNCEN_FUNC0 << NFUNCEN4_GPIO_02_SHIFT);
writel(val, priv->ioaddr + NFUNCEN4_OFFSET);
break;
case GPIO_03:
val = readl(priv->ioaddr + NFUNCEN4_OFFSET);
val &= ~NFUNCEN4_GPIO_03;
val |= (NFUNCEN_FUNC0 << NFUNCEN4_GPIO_03_SHIFT);
writel(val, priv->ioaddr + NFUNCEN4_OFFSET);
break;
case GPIO_04:
val = readl(priv->ioaddr + NFUNCEN4_OFFSET);
val &= ~NFUNCEN4_GPIO_04;
val |= (NFUNCEN_FUNC0 << NFUNCEN4_GPIO_04_SHIFT);
writel(val, priv->ioaddr + NFUNCEN4_OFFSET);
break;
case GPIO_05:
val = readl(priv->ioaddr + NFUNCEN4_OFFSET);
val &= ~NFUNCEN4_GPIO_05;
val |= (NFUNCEN_FUNC0 << NFUNCEN4_GPIO_05_SHIFT);
writel(val, priv->ioaddr + NFUNCEN4_OFFSET);
break;
case GPIO_06:
val = readl(priv->ioaddr + NFUNCEN4_OFFSET);
val &= ~NFUNCEN4_GPIO_06;
val |= (NFUNCEN_FUNC0 << NFUNCEN4_GPIO_06_SHIFT);
writel(val, priv->ioaddr + NFUNCEN4_OFFSET);
break;
case GPIO_10:
val = readl(priv->ioaddr + NFUNCEN5_OFFSET);
val &= ~NFUNCEN5_GPIO_10;
val |= (NFUNCEN_FUNC0 << NFUNCEN5_GPIO_10_SHIFT);
writel(val, priv->ioaddr + NFUNCEN5_OFFSET);
break;
case GPIO_11:
val = readl(priv->ioaddr + NFUNCEN5_OFFSET);
val &= ~NFUNCEN5_GPIO_11;
val |= (NFUNCEN_FUNC0 << NFUNCEN5_GPIO_11_SHIFT);
writel(val, priv->ioaddr + NFUNCEN5_OFFSET);
break;
case GPIO_12:
val = readl(priv->ioaddr + NFUNCEN6_OFFSET);
val &= ~NFUNCEN6_GPIO_12;
val |= (NFUNCEN_FUNC0 << NFUNCEN6_GPIO_12_SHIFT);
writel(val, priv->ioaddr + NFUNCEN6_OFFSET);
break;
default :
netdev_err(priv->dev, "Invalid GPIO pin - %d\n", gpio_pin);
return -EPERM;
}
out_value = priv->saved_gpio_config[gpio_pin].out_val;
/* Write data to GPIO pin */
if(gpio_pin < GPIO_32) {
config = 1 << gpio_pin;
val = readl(priv->ioaddr + GPIOO0_OFFSET);
val &= ~config;
if(out_value)
val |= config;
writel(val, priv->ioaddr + GPIOO0_OFFSET);
} else {
config = 1 << (gpio_pin - GPIO_32);
val = readl(priv->ioaddr + GPIOO1_OFFSET);
val &= ~config;
if(out_value)
val |= config;
writel(val, priv->ioaddr + GPIOO1_OFFSET);
}
/* Configure the GPIO pin in output direction */
if(gpio_pin < GPIO_32) {
config = ~(1 << gpio_pin) ;
val = readl(priv->ioaddr + GPIOE0_OFFSET);
writel(val & config, priv->ioaddr + GPIOE0_OFFSET);
} else {
config = ~(1 << (gpio_pin - GPIO_32)) ;
val = readl(priv->ioaddr + GPIOE1_OFFSET);
writel(val & config, priv->ioaddr + GPIOE1_OFFSET);
}
}
return 0;
}
/**
* tc956xmac_wol_interrupt - ISR to handle WoL PHY interrupt
* @irq: interrupt number.
@ -10943,6 +11071,8 @@ int tc956xmac_dvr_probe(struct device *device,
priv->dev = ndev;
priv->ioaddr = res->addr;
memset(priv->saved_gpio_config, 0, sizeof(struct tc956x_gpio_config) * (GPIO_12 + 1));
ret = tc956x_platform_probe(priv, res);
if (ret) {
dev_err(priv->device, "Platform probe error %d\n", ret);