Loading drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c +5 −1 Original line number Diff line number Diff line Loading @@ -251,6 +251,7 @@ int ethqos_handle_prv_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { struct stmmac_priv *pdata = netdev_priv(dev); struct ifr_data_struct req; struct pps_cfg eth_pps_cfg; int ret = 0; if (copy_from_user(&req, ifr->ifr_ifru.ifru_data, Loading @@ -259,7 +260,10 @@ int ethqos_handle_prv_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) switch (req.cmd) { case ETHQOS_CONFIG_PPSOUT_CMD: ret = ppsout_config(pdata, &req); if (copy_from_user(ð_pps_cfg, (void __user *)req.ptr, sizeof(struct pps_cfg))) return -EFAULT; ret = ppsout_config(pdata, ð_pps_cfg); break; case ETHQOS_AVB_ALGORITHM: dwmac_qcom_program_avb_algorithm(pdata, &req); Loading drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.h +3 −1 Original line number Diff line number Diff line Loading @@ -194,7 +194,7 @@ int create_pps_interrupt_device_node(dev_t *pps_dev_t, bool qcom_ethqos_is_phy_link_up(struct qcom_ethqos *ethqos); void *qcom_ethqos_get_priv(struct qcom_ethqos *ethqos); int ppsout_config(struct stmmac_priv *priv, struct ifr_data_struct *req); int ppsout_config(struct stmmac_priv *priv, struct pps_cfg *eth_pps_cfg); u16 dwmac_qcom_select_queue(struct net_device *dev, struct sk_buff *skb, Loading Loading @@ -225,6 +225,8 @@ u16 dwmac_qcom_select_queue(struct net_device *dev, #define IP_PKT_INT_MOD 32 #define PTP_INT_MOD 1 #define PPS_19_2_FREQ 19200000 enum dwmac_qcom_queue_operating_mode { DWMAC_QCOM_QDISABLED = 0X0, DWMAC_QCOM_QAVB, Loading drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-pps.c +30 −62 Original line number Diff line number Diff line Loading @@ -84,36 +84,6 @@ static u32 pps_config_sub_second_increment(void __iomem *ioaddr, return data; } static u32 pps_config_default_addend(void __iomem *ioaddr, struct stmmac_priv *priv, u32 ptp_clock) { u64 temp; /* formula is : * addend = 2^32/freq_div_ratio; * * where, freq_div_ratio = DWC_ETH_QOS_SYSCLOCK/50MHz * * hence, addend = ((2^32) * 50MHz)/DWC_ETH_QOS_SYSCLOCK; * * NOTE: DWC_ETH_QOS_SYSCLOCK should be >= 50MHz to * achive 20ns accuracy. * * 2^x * y == (y << x), hence * 2^32 * 50000000 ==> (50000000 << 32) */ if (ptp_clock == 250000000) { // If PTP_CLOCK == SYS_CLOCK, best we can do is 2^32 - 1 priv->default_addend = 0xFFFFFFFF; } else { temp = (u64)((u64)ptp_clock << 32); priv->default_addend = div_u64(temp, priv->plat->clk_ptp_rate); } priv->hw->ptp->config_addend(ioaddr, priv->default_addend); return 1; } int ppsout_stop(struct stmmac_priv *priv, struct pps_cfg *eth_pps_cfg) { u32 val; Loading Loading @@ -190,23 +160,19 @@ static void ethqos_unregister_pps_isr(struct stmmac_priv *priv, int ch) } } int ppsout_config(struct stmmac_priv *priv, struct ifr_data_struct *req) int ppsout_config(struct stmmac_priv *priv, struct pps_cfg *eth_pps_cfg) { int interval, width; u32 sub_second_inc, value; void __iomem *ioaddr = priv->ioaddr; u32 val; struct pps_cfg eth_pps_cfg; if (copy_from_user(ð_pps_cfg, (void __user *)req->ptr, sizeof(struct pps_cfg))) return -EFAULT; u64 temp; if (!eth_pps_cfg.ppsout_start) { ppsout_stop(priv, ð_pps_cfg); if (eth_pps_cfg.ppsout_ch == DWC_ETH_QOS_PPS_CH_2 || eth_pps_cfg.ppsout_ch == DWC_ETH_QOS_PPS_CH_3) ethqos_unregister_pps_isr(priv, eth_pps_cfg.ppsout_ch); if (!eth_pps_cfg->ppsout_start) { ppsout_stop(priv, eth_pps_cfg); if (eth_pps_cfg->ppsout_ch == DWC_ETH_QOS_PPS_CH_2 || eth_pps_cfg->ppsout_ch == DWC_ETH_QOS_PPS_CH_3) ethqos_unregister_pps_isr(priv, eth_pps_cfg->ppsout_ch); return 0; } Loading @@ -218,40 +184,42 @@ int ppsout_config(struct stmmac_priv *priv, struct ifr_data_struct *req) val = readl_relaxed(ioaddr + MAC_PPS_CONTROL); sub_second_inc = pps_config_sub_second_increment (priv->ptpaddr, eth_pps_cfg.ptpclk_freq, (priv->ptpaddr, eth_pps_cfg->ptpclk_freq, priv->plat->has_gmac4); pps_config_default_addend(priv->ptpaddr, priv, eth_pps_cfg.ptpclk_freq); val &= ~PPSX_MASK(eth_pps_cfg.ppsout_ch); temp = (u64)((u64)eth_pps_cfg->ptpclk_freq << 32); priv->default_addend = div_u64(temp, priv->plat->clk_ptp_rate); priv->hw->ptp->config_addend(priv->ptpaddr, priv->default_addend); val &= ~PPSX_MASK(eth_pps_cfg->ppsout_ch); val |= PPSCMDX(eth_pps_cfg.ppsout_ch, 0x2); val |= TRGTMODSELX(eth_pps_cfg.ppsout_ch, 0x2); val |= PPSCMDX(eth_pps_cfg->ppsout_ch, 0x2); val |= TRGTMODSELX(eth_pps_cfg->ppsout_ch, 0x2); val |= PPSEN0; if (eth_pps_cfg.ppsout_ch == DWC_ETH_QOS_PPS_CH_2 || eth_pps_cfg.ppsout_ch == DWC_ETH_QOS_PPS_CH_3) ethqos_register_pps_isr(priv, eth_pps_cfg.ppsout_ch); if (eth_pps_cfg->ppsout_ch == DWC_ETH_QOS_PPS_CH_2 || eth_pps_cfg->ppsout_ch == DWC_ETH_QOS_PPS_CH_3) ethqos_register_pps_isr(priv, eth_pps_cfg->ppsout_ch); writel_relaxed(0, ioaddr + MAC_PPSX_TARGET_TIME_SEC(eth_pps_cfg.ppsout_ch)); MAC_PPSX_TARGET_TIME_SEC(eth_pps_cfg->ppsout_ch)); writel_relaxed(0, ioaddr + MAC_PPSX_TARGET_TIME_NSEC(eth_pps_cfg.ppsout_ch)); MAC_PPSX_TARGET_TIME_NSEC(eth_pps_cfg->ppsout_ch)); interval = ((eth_pps_cfg.ptpclk_freq + eth_pps_cfg.ppsout_freq / 2) / eth_pps_cfg.ppsout_freq); interval = ((eth_pps_cfg->ptpclk_freq + eth_pps_cfg->ppsout_freq / 2) / eth_pps_cfg->ppsout_freq); width = ((interval * eth_pps_cfg.ppsout_duty) + 50) / 100 - 1; width = ((interval * eth_pps_cfg->ppsout_duty) + 50) / 100 - 1; if (width >= interval) width = interval - 1; if (width < 0) width = 0; writel_relaxed(interval, ioaddr + MAC_PPSX_INTERVAL(eth_pps_cfg.ppsout_ch)); MAC_PPSX_INTERVAL(eth_pps_cfg->ppsout_ch)); writel_relaxed(width, ioaddr + MAC_PPSX_WIDTH(eth_pps_cfg.ppsout_ch)); writel_relaxed(width, ioaddr + MAC_PPSX_WIDTH(eth_pps_cfg->ppsout_ch)); writel_relaxed(val, ioaddr + MAC_PPS_CONTROL); Loading @@ -261,7 +229,6 @@ int ppsout_config(struct stmmac_priv *priv, struct ifr_data_struct *req) int ethqos_init_pps(struct stmmac_priv *priv) { u32 value; struct ifr_data_struct req = {0}; struct pps_cfg eth_pps_cfg = {0}; priv->ptpaddr = priv->ioaddr + PTP_GMAC4_OFFSET; Loading @@ -272,13 +239,14 @@ int ethqos_init_pps(struct stmmac_priv *priv) /*Configuaring PPS0 PPS output frequency to default 19.2 Mhz*/ eth_pps_cfg.ppsout_ch = 0; eth_pps_cfg.ptpclk_freq = 62500000; eth_pps_cfg.ppsout_freq = 19200000; eth_pps_cfg.ptpclk_freq = priv->plat->clk_ptp_req_rate; eth_pps_cfg.ppsout_freq = PPS_19_2_FREQ; eth_pps_cfg.ppsout_start = 1; eth_pps_cfg.ppsout_duty = 50; req.ptr = (void *)ð_pps_cfg; ppsout_config(priv, &req); ppsout_config(priv, ð_pps_cfg); return 0; } Loading Loading
drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c +5 −1 Original line number Diff line number Diff line Loading @@ -251,6 +251,7 @@ int ethqos_handle_prv_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { struct stmmac_priv *pdata = netdev_priv(dev); struct ifr_data_struct req; struct pps_cfg eth_pps_cfg; int ret = 0; if (copy_from_user(&req, ifr->ifr_ifru.ifru_data, Loading @@ -259,7 +260,10 @@ int ethqos_handle_prv_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) switch (req.cmd) { case ETHQOS_CONFIG_PPSOUT_CMD: ret = ppsout_config(pdata, &req); if (copy_from_user(ð_pps_cfg, (void __user *)req.ptr, sizeof(struct pps_cfg))) return -EFAULT; ret = ppsout_config(pdata, ð_pps_cfg); break; case ETHQOS_AVB_ALGORITHM: dwmac_qcom_program_avb_algorithm(pdata, &req); Loading
drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.h +3 −1 Original line number Diff line number Diff line Loading @@ -194,7 +194,7 @@ int create_pps_interrupt_device_node(dev_t *pps_dev_t, bool qcom_ethqos_is_phy_link_up(struct qcom_ethqos *ethqos); void *qcom_ethqos_get_priv(struct qcom_ethqos *ethqos); int ppsout_config(struct stmmac_priv *priv, struct ifr_data_struct *req); int ppsout_config(struct stmmac_priv *priv, struct pps_cfg *eth_pps_cfg); u16 dwmac_qcom_select_queue(struct net_device *dev, struct sk_buff *skb, Loading Loading @@ -225,6 +225,8 @@ u16 dwmac_qcom_select_queue(struct net_device *dev, #define IP_PKT_INT_MOD 32 #define PTP_INT_MOD 1 #define PPS_19_2_FREQ 19200000 enum dwmac_qcom_queue_operating_mode { DWMAC_QCOM_QDISABLED = 0X0, DWMAC_QCOM_QAVB, Loading
drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-pps.c +30 −62 Original line number Diff line number Diff line Loading @@ -84,36 +84,6 @@ static u32 pps_config_sub_second_increment(void __iomem *ioaddr, return data; } static u32 pps_config_default_addend(void __iomem *ioaddr, struct stmmac_priv *priv, u32 ptp_clock) { u64 temp; /* formula is : * addend = 2^32/freq_div_ratio; * * where, freq_div_ratio = DWC_ETH_QOS_SYSCLOCK/50MHz * * hence, addend = ((2^32) * 50MHz)/DWC_ETH_QOS_SYSCLOCK; * * NOTE: DWC_ETH_QOS_SYSCLOCK should be >= 50MHz to * achive 20ns accuracy. * * 2^x * y == (y << x), hence * 2^32 * 50000000 ==> (50000000 << 32) */ if (ptp_clock == 250000000) { // If PTP_CLOCK == SYS_CLOCK, best we can do is 2^32 - 1 priv->default_addend = 0xFFFFFFFF; } else { temp = (u64)((u64)ptp_clock << 32); priv->default_addend = div_u64(temp, priv->plat->clk_ptp_rate); } priv->hw->ptp->config_addend(ioaddr, priv->default_addend); return 1; } int ppsout_stop(struct stmmac_priv *priv, struct pps_cfg *eth_pps_cfg) { u32 val; Loading Loading @@ -190,23 +160,19 @@ static void ethqos_unregister_pps_isr(struct stmmac_priv *priv, int ch) } } int ppsout_config(struct stmmac_priv *priv, struct ifr_data_struct *req) int ppsout_config(struct stmmac_priv *priv, struct pps_cfg *eth_pps_cfg) { int interval, width; u32 sub_second_inc, value; void __iomem *ioaddr = priv->ioaddr; u32 val; struct pps_cfg eth_pps_cfg; if (copy_from_user(ð_pps_cfg, (void __user *)req->ptr, sizeof(struct pps_cfg))) return -EFAULT; u64 temp; if (!eth_pps_cfg.ppsout_start) { ppsout_stop(priv, ð_pps_cfg); if (eth_pps_cfg.ppsout_ch == DWC_ETH_QOS_PPS_CH_2 || eth_pps_cfg.ppsout_ch == DWC_ETH_QOS_PPS_CH_3) ethqos_unregister_pps_isr(priv, eth_pps_cfg.ppsout_ch); if (!eth_pps_cfg->ppsout_start) { ppsout_stop(priv, eth_pps_cfg); if (eth_pps_cfg->ppsout_ch == DWC_ETH_QOS_PPS_CH_2 || eth_pps_cfg->ppsout_ch == DWC_ETH_QOS_PPS_CH_3) ethqos_unregister_pps_isr(priv, eth_pps_cfg->ppsout_ch); return 0; } Loading @@ -218,40 +184,42 @@ int ppsout_config(struct stmmac_priv *priv, struct ifr_data_struct *req) val = readl_relaxed(ioaddr + MAC_PPS_CONTROL); sub_second_inc = pps_config_sub_second_increment (priv->ptpaddr, eth_pps_cfg.ptpclk_freq, (priv->ptpaddr, eth_pps_cfg->ptpclk_freq, priv->plat->has_gmac4); pps_config_default_addend(priv->ptpaddr, priv, eth_pps_cfg.ptpclk_freq); val &= ~PPSX_MASK(eth_pps_cfg.ppsout_ch); temp = (u64)((u64)eth_pps_cfg->ptpclk_freq << 32); priv->default_addend = div_u64(temp, priv->plat->clk_ptp_rate); priv->hw->ptp->config_addend(priv->ptpaddr, priv->default_addend); val &= ~PPSX_MASK(eth_pps_cfg->ppsout_ch); val |= PPSCMDX(eth_pps_cfg.ppsout_ch, 0x2); val |= TRGTMODSELX(eth_pps_cfg.ppsout_ch, 0x2); val |= PPSCMDX(eth_pps_cfg->ppsout_ch, 0x2); val |= TRGTMODSELX(eth_pps_cfg->ppsout_ch, 0x2); val |= PPSEN0; if (eth_pps_cfg.ppsout_ch == DWC_ETH_QOS_PPS_CH_2 || eth_pps_cfg.ppsout_ch == DWC_ETH_QOS_PPS_CH_3) ethqos_register_pps_isr(priv, eth_pps_cfg.ppsout_ch); if (eth_pps_cfg->ppsout_ch == DWC_ETH_QOS_PPS_CH_2 || eth_pps_cfg->ppsout_ch == DWC_ETH_QOS_PPS_CH_3) ethqos_register_pps_isr(priv, eth_pps_cfg->ppsout_ch); writel_relaxed(0, ioaddr + MAC_PPSX_TARGET_TIME_SEC(eth_pps_cfg.ppsout_ch)); MAC_PPSX_TARGET_TIME_SEC(eth_pps_cfg->ppsout_ch)); writel_relaxed(0, ioaddr + MAC_PPSX_TARGET_TIME_NSEC(eth_pps_cfg.ppsout_ch)); MAC_PPSX_TARGET_TIME_NSEC(eth_pps_cfg->ppsout_ch)); interval = ((eth_pps_cfg.ptpclk_freq + eth_pps_cfg.ppsout_freq / 2) / eth_pps_cfg.ppsout_freq); interval = ((eth_pps_cfg->ptpclk_freq + eth_pps_cfg->ppsout_freq / 2) / eth_pps_cfg->ppsout_freq); width = ((interval * eth_pps_cfg.ppsout_duty) + 50) / 100 - 1; width = ((interval * eth_pps_cfg->ppsout_duty) + 50) / 100 - 1; if (width >= interval) width = interval - 1; if (width < 0) width = 0; writel_relaxed(interval, ioaddr + MAC_PPSX_INTERVAL(eth_pps_cfg.ppsout_ch)); MAC_PPSX_INTERVAL(eth_pps_cfg->ppsout_ch)); writel_relaxed(width, ioaddr + MAC_PPSX_WIDTH(eth_pps_cfg.ppsout_ch)); writel_relaxed(width, ioaddr + MAC_PPSX_WIDTH(eth_pps_cfg->ppsout_ch)); writel_relaxed(val, ioaddr + MAC_PPS_CONTROL); Loading @@ -261,7 +229,6 @@ int ppsout_config(struct stmmac_priv *priv, struct ifr_data_struct *req) int ethqos_init_pps(struct stmmac_priv *priv) { u32 value; struct ifr_data_struct req = {0}; struct pps_cfg eth_pps_cfg = {0}; priv->ptpaddr = priv->ioaddr + PTP_GMAC4_OFFSET; Loading @@ -272,13 +239,14 @@ int ethqos_init_pps(struct stmmac_priv *priv) /*Configuaring PPS0 PPS output frequency to default 19.2 Mhz*/ eth_pps_cfg.ppsout_ch = 0; eth_pps_cfg.ptpclk_freq = 62500000; eth_pps_cfg.ppsout_freq = 19200000; eth_pps_cfg.ptpclk_freq = priv->plat->clk_ptp_req_rate; eth_pps_cfg.ppsout_freq = PPS_19_2_FREQ; eth_pps_cfg.ppsout_start = 1; eth_pps_cfg.ppsout_duty = 50; req.ptr = (void *)ð_pps_cfg; ppsout_config(priv, &req); ppsout_config(priv, ð_pps_cfg); return 0; } Loading