Rayagond Kokatanur | 891434b | 2013-03-26 04:43:10 +0000 | [diff] [blame] | 1 | /******************************************************************************* |
| 2 | Copyright (C) 2013 Vayavya Labs Pvt Ltd |
| 3 | |
| 4 | This implements all the API for managing HW timestamp & PTP. |
| 5 | |
| 6 | This program is free software; you can redistribute it and/or modify it |
| 7 | under the terms and conditions of the GNU General Public License, |
| 8 | version 2, as published by the Free Software Foundation. |
| 9 | |
| 10 | This program is distributed in the hope it will be useful, but WITHOUT |
| 11 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| 12 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
| 13 | more details. |
| 14 | |
| 15 | You should have received a copy of the GNU General Public License along with |
| 16 | this program; if not, write to the Free Software Foundation, Inc., |
| 17 | 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. |
| 18 | |
| 19 | The full GNU General Public License is included in this distribution in |
| 20 | the file called "COPYING". |
| 21 | |
| 22 | Author: Rayagond Kokatanur <rayagond@vayavyalabs.com> |
| 23 | Author: Giuseppe Cavallaro <peppe.cavallaro@st.com> |
| 24 | *******************************************************************************/ |
| 25 | |
| 26 | #include <linux/io.h> |
| 27 | #include <linux/delay.h> |
| 28 | #include "common.h" |
| 29 | #include "stmmac_ptp.h" |
| 30 | |
| 31 | static void stmmac_config_hw_tstamping(void __iomem *ioaddr, u32 data) |
| 32 | { |
| 33 | writel(data, ioaddr + PTP_TCR); |
| 34 | } |
| 35 | |
Phil Reid | 19d857c | 2015-12-14 11:32:01 +0800 | [diff] [blame^] | 36 | static u32 stmmac_config_sub_second_increment(void __iomem *ioaddr, |
| 37 | u32 ptp_clock) |
Rayagond Kokatanur | 891434b | 2013-03-26 04:43:10 +0000 | [diff] [blame] | 38 | { |
| 39 | u32 value = readl(ioaddr + PTP_TCR); |
| 40 | unsigned long data; |
| 41 | |
| 42 | /* Convert the ptp_clock to nano second |
Phil Reid | 19d857c | 2015-12-14 11:32:01 +0800 | [diff] [blame^] | 43 | * formula = (2/ptp_clock) * 1000000000 |
Rayagond Kokatanur | 891434b | 2013-03-26 04:43:10 +0000 | [diff] [blame] | 44 | * where, ptp_clock = 50MHz. |
| 45 | */ |
Phil Reid | 19d857c | 2015-12-14 11:32:01 +0800 | [diff] [blame^] | 46 | data = (2000000000ULL / ptp_clock); |
Rayagond Kokatanur | 891434b | 2013-03-26 04:43:10 +0000 | [diff] [blame] | 47 | |
| 48 | /* 0.465ns accuracy */ |
Sonic Zhang | 0cf9158 | 2013-09-03 13:55:07 +0800 | [diff] [blame] | 49 | if (!(value & PTP_TCR_TSCTRLSSR)) |
| 50 | data = (data * 1000) / 465; |
Rayagond Kokatanur | 891434b | 2013-03-26 04:43:10 +0000 | [diff] [blame] | 51 | |
| 52 | writel(data, ioaddr + PTP_SSIR); |
Phil Reid | 19d857c | 2015-12-14 11:32:01 +0800 | [diff] [blame^] | 53 | |
| 54 | return data; |
Rayagond Kokatanur | 891434b | 2013-03-26 04:43:10 +0000 | [diff] [blame] | 55 | } |
| 56 | |
| 57 | static int stmmac_init_systime(void __iomem *ioaddr, u32 sec, u32 nsec) |
| 58 | { |
| 59 | int limit; |
| 60 | u32 value; |
| 61 | |
| 62 | writel(sec, ioaddr + PTP_STSUR); |
| 63 | writel(nsec, ioaddr + PTP_STNSUR); |
| 64 | /* issue command to initialize the system time value */ |
| 65 | value = readl(ioaddr + PTP_TCR); |
| 66 | value |= PTP_TCR_TSINIT; |
| 67 | writel(value, ioaddr + PTP_TCR); |
| 68 | |
| 69 | /* wait for present system time initialize to complete */ |
| 70 | limit = 10; |
| 71 | while (limit--) { |
| 72 | if (!(readl(ioaddr + PTP_TCR) & PTP_TCR_TSINIT)) |
| 73 | break; |
| 74 | mdelay(10); |
| 75 | } |
| 76 | if (limit < 0) |
| 77 | return -EBUSY; |
| 78 | |
| 79 | return 0; |
| 80 | } |
| 81 | |
| 82 | static int stmmac_config_addend(void __iomem *ioaddr, u32 addend) |
| 83 | { |
| 84 | u32 value; |
| 85 | int limit; |
| 86 | |
| 87 | writel(addend, ioaddr + PTP_TAR); |
| 88 | /* issue command to update the addend value */ |
| 89 | value = readl(ioaddr + PTP_TCR); |
| 90 | value |= PTP_TCR_TSADDREG; |
| 91 | writel(value, ioaddr + PTP_TCR); |
| 92 | |
| 93 | /* wait for present addend update to complete */ |
| 94 | limit = 10; |
| 95 | while (limit--) { |
| 96 | if (!(readl(ioaddr + PTP_TCR) & PTP_TCR_TSADDREG)) |
| 97 | break; |
| 98 | mdelay(10); |
| 99 | } |
| 100 | if (limit < 0) |
| 101 | return -EBUSY; |
| 102 | |
| 103 | return 0; |
| 104 | } |
| 105 | |
Rayagond Kokatanur | 92ba688 | 2013-03-26 04:43:11 +0000 | [diff] [blame] | 106 | static int stmmac_adjust_systime(void __iomem *ioaddr, u32 sec, u32 nsec, |
| 107 | int add_sub) |
| 108 | { |
| 109 | u32 value; |
| 110 | int limit; |
| 111 | |
| 112 | writel(sec, ioaddr + PTP_STSUR); |
| 113 | writel(((add_sub << PTP_STNSUR_ADDSUB_SHIFT) | nsec), |
| 114 | ioaddr + PTP_STNSUR); |
| 115 | /* issue command to initialize the system time value */ |
| 116 | value = readl(ioaddr + PTP_TCR); |
| 117 | value |= PTP_TCR_TSUPDT; |
| 118 | writel(value, ioaddr + PTP_TCR); |
| 119 | |
| 120 | /* wait for present system time adjust/update to complete */ |
| 121 | limit = 10; |
| 122 | while (limit--) { |
| 123 | if (!(readl(ioaddr + PTP_TCR) & PTP_TCR_TSUPDT)) |
| 124 | break; |
| 125 | mdelay(10); |
| 126 | } |
| 127 | if (limit < 0) |
| 128 | return -EBUSY; |
| 129 | |
| 130 | return 0; |
| 131 | } |
| 132 | |
| 133 | static u64 stmmac_get_systime(void __iomem *ioaddr) |
| 134 | { |
| 135 | u64 ns; |
| 136 | |
| 137 | ns = readl(ioaddr + PTP_STNSR); |
| 138 | /* convert sec time value to nanosecond */ |
| 139 | ns += readl(ioaddr + PTP_STSR) * 1000000000ULL; |
| 140 | |
| 141 | return ns; |
| 142 | } |
| 143 | |
Rayagond Kokatanur | 891434b | 2013-03-26 04:43:10 +0000 | [diff] [blame] | 144 | const struct stmmac_hwtimestamp stmmac_ptp = { |
| 145 | .config_hw_tstamping = stmmac_config_hw_tstamping, |
| 146 | .init_systime = stmmac_init_systime, |
| 147 | .config_sub_second_increment = stmmac_config_sub_second_increment, |
| 148 | .config_addend = stmmac_config_addend, |
Rayagond Kokatanur | 92ba688 | 2013-03-26 04:43:11 +0000 | [diff] [blame] | 149 | .adjust_systime = stmmac_adjust_systime, |
| 150 | .get_systime = stmmac_get_systime, |
Rayagond Kokatanur | 891434b | 2013-03-26 04:43:10 +0000 | [diff] [blame] | 151 | }; |